From a5a763da3427c81422e0874761688086df235c49 Mon Sep 17 00:00:00 2001 From: Nick1296 Date: Sun, 15 Jul 2018 17:16:02 +0200 Subject: [PATCH] FIxed a bug in the SimpleFS_remove triggered by many file in the same directory. Re formatted files --- bitmap.c | 126 +++--- bitmap.h | 26 +- common.h | 3 +- disk_driver.c | 475 ++++++++++---------- disk_driver.h | 39 +- shell.c | 984 +++++++++++++++++++++--------------------- simplefs.c | 993 +++++++++++++++++++++--------------------- simplefs.h | 133 +++--- simplefs_aux.c | 1099 ++++++++++++++++++++++------------------------- simplefs_aux.h | 5 +- simplefs_test.c | 1034 ++++++++++++++++++++++---------------------- 11 files changed, 2431 insertions(+), 2486 deletions(-) diff --git a/bitmap.c b/bitmap.c index 61f21e7..a111ef6 100755 --- a/bitmap.c +++ b/bitmap.c @@ -1,89 +1,89 @@ #include "bitmap.h" #include "common.h" -void BitMap_init(BitMap* b, int bitmap_blocks, int disk_blocks,int occupation){ - //initializing the bitmap - b->entries=(uint8_t*)b+sizeof(BitMap); - b->num_blocks=bitmap_blocks; - b->num_bits=disk_blocks; - uint8_t *bitmap=b->entries; - // we use a mask to sign the occupied blocks - uint8_t mask; - int j,i,write=occupation,written=0; - for(i=0;i>1; - mask+=128; - written++; - } - bitmap[i]=mask; - } +void BitMap_init(BitMap *b, int bitmap_blocks, int disk_blocks, int occupation) { + //initializing the bitmap + b->entries = (uint8_t *) b + sizeof(BitMap); + b->num_blocks = bitmap_blocks; + b->num_bits = disk_blocks; + uint8_t *bitmap = b->entries; + // we use a mask to sign the occupied blocks + uint8_t mask; + int j, i, write = occupation, written = 0; + for (i = 0; i < bitmap_blocks; i++) { + mask = 0; + for (j = 0; j < 8 && written < write; j++) { + mask = mask >> 1; + mask += 128; + written++; + } + bitmap[i] = mask; + } } // converts a block index to an index in the array, // and a the offset of the bit inside the array -BitMapEntryKey BitMap_blockToIndex(int num){ - BitMapEntryKey entry; - //we get the entry of the bit map which contains the info about the block - entry.entry_num=num/8; - // we get the displacement inside the block to locate the bit we need - entry.bit_num=num%8; - return entry; +BitMapEntryKey BitMap_blockToIndex(int num) { + BitMapEntryKey entry; + //we get the entry of the bit map which contains the info about the block + entry.entry_num = num / 8; + // we get the displacement inside the block to locate the bit we need + entry.bit_num = (uint8_t) (num % 8); + return entry; } // converts a bit to a linear index -int BitMap_indexToBlock(int entry, uint8_t bit_num){ - return entry*8+bit_num; +int BitMap_indexToBlock(int entry, uint8_t bit_num) { + return entry * 8 + bit_num; } // returns the index of the first bit having status "status" // in the bitmap bmap, and starts looking from position start // it returns -1 if it's not found -int BitMap_get(BitMap* bmap, int start, int status){ - int i,j,found=0; - int entry=start/8; - // bit that have been already checked/skipped - int checked=start; - //initial displacement in the entry - int starting_bit; - uint8_t mask; +int BitMap_get(BitMap *bmap, int start, int status) { + int i, j, found = 0; + int entry = start / 8; + // bit that have been already checked/skipped + int checked = start; + //initial displacement in the entry + int starting_bit; + uint8_t mask; - for(i=entry;inum_blocks && !found;i++){ - starting_bit=checked%8; - mask=128; - mask=mask>>starting_bit; - for(j=starting_bit;j<8 && checkednum_bits && !found;j++){ - found=((mask & bmap->entries[i])?1:0)==status; - if(!found){ - checked++; - mask=mask>>1; - } - } - } - if(found){ - return checked; - } - return FAILED; + for (i = entry; i < bmap->num_blocks && !found; i++) { + starting_bit = checked % 8; + mask = 128; + mask = mask >> starting_bit; + for (j = starting_bit; j < 8 && checked < bmap->num_bits && !found; j++) { + found = ((mask & bmap->entries[i]) ? 1 : 0) == status; + if (!found) { + checked++; + mask = mask >> 1; + } + } + } + if (found) { + return checked; + } + return FAILED; } // sets the bit at index pos in bmap to status -int BitMap_set(BitMap* bmap, int pos, int status){ - int entry=(pos)/8, bit=(pos)%8; - uint8_t mask=128; +int BitMap_set(BitMap *bmap, int pos, int status) { + int entry = (pos) / 8, bit = (pos) % 8; + uint8_t mask = 128; - mask=mask>>bit; - bmap->entries[entry]= (status)? bmap->entries[entry] | mask : bmap->entries[entry] & ~mask; + mask = mask >> bit; + bmap->entries[entry] = (status) ? bmap->entries[entry] | mask : bmap->entries[entry] & ~mask; - return status; + return status; } // return the status of the bit at index pos in bmap -int BitMap_test(BitMap* bmap, int pos){ - int entry=pos/8; - int bit=pos%8; - uint8_t mask=128; - mask=mask>>bit; - return (bmap->entries[entry] & mask)? 1:0; +int BitMap_test(BitMap *bmap, int pos) { + int entry = pos / 8; + int bit = pos % 8; + uint8_t mask = 128; + mask = mask >> bit; + return (bmap->entries[entry] & mask) ? 1 : 0; } diff --git a/bitmap.h b/bitmap.h index 339bcb5..3b7202f 100755 --- a/bitmap.h +++ b/bitmap.h @@ -2,21 +2,21 @@ #include -typedef struct _BitMap{ - int num_bits; - int num_blocks; - uint8_t* entries; -} BitMap; - -typedef struct _BitMapEntryKey{ - int entry_num; - uint8_t bit_num; +typedef struct _BitMap { + int num_bits; + int num_blocks; + uint8_t *entries; +} BitMap; + +typedef struct _BitMapEntryKey { + int entry_num; + uint8_t bit_num; } BitMapEntryKey; // initializes the bitmap given an empty BitMap, the number of bitmap_blocks, // the number of disk blocks covered and the number of already occupied disk blocks -void BitMap_init(BitMap* b, int bitmap_blocks, int disk_blocks, int occupation); +void BitMap_init(BitMap *b, int bitmap_blocks, int disk_blocks, int occupation); // converts a block index to an index in the array, // and a char that indicates the offset of the bit inside the array @@ -27,11 +27,11 @@ int BitMap_indexToBlock(int entry, uint8_t bit_num); // returns the index of the first bit having status "status" // in the bitmap bmap, and starts looking from position start -int BitMap_get(BitMap* bmap, int start, int status); +int BitMap_get(BitMap *bmap, int start, int status); // sets the bit at index pos in bmap to status // return status passed on success -int BitMap_set(BitMap* bmap, int pos, int status); +int BitMap_set(BitMap *bmap, int pos, int status); // return the status of the bit at index pos in bmap -int BitMap_test(BitMap* bmap, int pos); +int BitMap_test(BitMap *bmap, int pos); diff --git a/common.h b/common.h index 853041e..adb9daf 100755 --- a/common.h +++ b/common.h @@ -1,4 +1,5 @@ #pragma once + #include #include #include @@ -11,7 +12,7 @@ #include -#define CHECK_ERR(cond,msg) if (cond) { \ +#define CHECK_ERR(cond, msg) if (cond) { \ perror(msg); \ _exit(EXIT_FAILURE); \ } diff --git a/disk_driver.c b/disk_driver.c index 2766275..5526b0c 100755 --- a/disk_driver.c +++ b/disk_driver.c @@ -1,284 +1,285 @@ #include "disk_driver.h" -void DiskDriver_init(DiskDriver* disk, const char* filename, int num_blocks){ - int res,fd; - //checking if the file exists or if we need to format the drive - res=access(filename,F_OK); - CHECK_ERR(res==FAILED && errno!=ENOENT,"Can't test if the file exists"); - CHECK_ERR(res!=FAILED && res!=0,"Can't test if the file exists"); // TO VERIFY - - // opening the file and creating it if necessary - fd=open(filename,O_CREAT | O_RDWR,0666); - //checking if the open was successful - CHECK_ERR(fd==FAILED,"error opening the file"); - - //calculating the bitmap size (rounded up) - int bitmap_blocks=(num_blocks+7)/8; - //rounded up block occupation of DiskHeader and bitmap - int occupation=(sizeof(DiskHeader)+bitmap_blocks+sizeof(BitMap)+BLOCK_SIZE-1)/BLOCK_SIZE; - //now we need to prepare the file to be mmapped because it needs to have the same dimension of the mmapped array - //to do so we need to write something (/0) to the last byte of the file (num_blocks*BLOCK_SIZE) - //we have repositioned the file pointer to the last byte - - res=lseek(fd,(occupation*BLOCK_SIZE)-1,SEEK_SET); - CHECK_ERR(res==FAILED,"can't reposition pointer file"); - //now we write something so the file will actually have this dimension - res=write(fd,"\0",1); - CHECK_ERR(res==FAILED,"can't write into file"); - - //mmap the file - void* map=mmap(0,occupation*BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,fd,0); - CHECK_ERR(map==MAP_FAILED,"error mapping the file"); - - //creating and initializing the disk header - DiskHeader *d=(DiskHeader*)map; - d->num_blocks=num_blocks; - d->bitmap_blocks=(bitmap_blocks+sizeof(BitMap)+BLOCK_SIZE-1)/BLOCK_SIZE; - d->bitmap_entries=bitmap_blocks; - d->free_blocks=num_blocks-occupation; - d->first_free_block=occupation; - - //initializing the bitmap - BitMap_init((BitMap*)(map+sizeof(DiskHeader)),bitmap_blocks,num_blocks,occupation); - - //populating the disk driver - disk->header=(DiskHeader*)map; - disk->bmap=(BitMap*)(map+sizeof(DiskHeader)); - disk->fd=fd; +void DiskDriver_init(DiskDriver *disk, const char *filename, int num_blocks) { + int res, fd; + //checking if the file exists or if we need to format the drive + res = access(filename, F_OK); + CHECK_ERR(res == FAILED && errno != ENOENT, "Can't test if the file exists"); + CHECK_ERR(res != FAILED && res != 0, "Can't test if the file exists"); // TO VERIFY + + // opening the file and creating it if necessary + fd = open(filename, O_CREAT | O_RDWR, 0666); + //checking if the open was successful + CHECK_ERR(fd == FAILED, "error opening the file"); + + //calculating the bitmap size (rounded up) + int bitmap_blocks = (num_blocks + 7) / 8; + //rounded up block occupation of DiskHeader and bitmap + size_t occupation = (sizeof(DiskHeader) + bitmap_blocks + sizeof(BitMap) + BLOCK_SIZE - 1) / BLOCK_SIZE; + //now we need to prepare the file to be mmapped because it needs to have the same dimension of the mmapped array + //to do so we need to write something (/0) to the last byte of the file (num_blocks*BLOCK_SIZE) + //we have repositioned the file pointer to the last byte + + res = (int) lseek(fd, (occupation * BLOCK_SIZE) - 1, SEEK_SET); + CHECK_ERR(res == FAILED, "can't reposition pointer file"); + //now we write something so the file will actually have this dimension + res = (int) write(fd, "\0", 1); + CHECK_ERR(res == FAILED, "can't write into file"); + + //mmap the file + void *map = mmap(0, occupation * BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + CHECK_ERR(map == MAP_FAILED, "error mapping the file"); + + //creating and initializing the disk header + DiskHeader *d = (DiskHeader *) map; + d->num_blocks = num_blocks; + d->bitmap_blocks = (bitmap_blocks + sizeof(BitMap) + BLOCK_SIZE - 1) / BLOCK_SIZE; + d->bitmap_entries = bitmap_blocks; + d->free_blocks = (int) (num_blocks - occupation); + d->first_free_block = (int) occupation; + + //initializing the bitmap + BitMap_init((BitMap *) (map + sizeof(DiskHeader)), bitmap_blocks, num_blocks, (int) occupation); + + //populating the disk driver + disk->header = (DiskHeader *) map; + disk->bmap = (BitMap *) (map + sizeof(DiskHeader)); + disk->fd = fd; } // Reads the first block of the disk file // returns -1 if the block is free according to the bitmap // 0 otherwise -int DiskDriver_readFirstBlock(DiskDriver* disk, void* dest, int block_num){ - // Check if the parameters passed are valid - if(disk==NULL) return FAILED; - if(dest==NULL) return FAILED; - if(block_num<0) return FAILED; - - // Set the position to read from - int res; - res=lseek(disk->fd, block_num*BLOCK_SIZE, SEEK_SET); - if(res==-1) return FAILED; - - //now we read something so the file will actually have this dimension - res=read(disk->fd, dest, BLOCK_SIZE); - - // If the read was interrupted by an interrupt, then reading again - while(res==-1 && errno == EINTR){ - res=lseek(disk->fd, block_num*BLOCK_SIZE, SEEK_SET); - if(res==-1) return FAILED; - res=read(disk->fd ,dest, BLOCK_SIZE); - } - - if(res!=BLOCK_SIZE) return FAILED; - - return SUCCESS; +int DiskDriver_readFirstBlock(DiskDriver *disk, void *dest, int block_num) { + // Check if the parameters passed are valid + if (disk == NULL) return FAILED; + if (dest == NULL) return FAILED; + if (block_num < 0) return FAILED; + + // Set the position to read from + int res; + res = (int) lseek(disk->fd, block_num * BLOCK_SIZE, SEEK_SET); + if (res == -1) return FAILED; + + //now we read something so the file will actually have this dimension + res = (int) read(disk->fd, dest, BLOCK_SIZE); + + // If the read was interrupted by an interrupt, then reading again + while (res == -1 && errno == EINTR) { + res = (int) lseek(disk->fd, block_num * BLOCK_SIZE, SEEK_SET); + if (res == -1) return FAILED; + res = (int) read(disk->fd, dest, BLOCK_SIZE); + } + + if (res != BLOCK_SIZE) return FAILED; + + return SUCCESS; } //assuming that the file is already initialized loads the disk -int DiskDriver_load(DiskDriver* disk, const char* filename){ - int res,fd; //1= file already exists 0=file doesn't exists yet - //checking if the file exists or if we need to format the drive - res=access(filename,F_OK); - if(res==FAILED && errno==ENOENT){ - return FAILED; - }else{ - CHECK_ERR(res==FAILED,"Can't test if the file exists");\ - } - - // opening the file and creating it if necessary - fd=open(filename,O_RDWR,0666); - //checking if the open was successful - CHECK_ERR(fd==FAILED,"error opening the file"); - - // Copio fd del file disco nella struttura - disk->fd=fd; - - //reading the first block of the disk - void* block=malloc(BLOCK_SIZE); - res=DiskDriver_readFirstBlock(disk, block, 0); - CHECK_ERR(res==FAILED,"CAN't read the first block of disk"); - - //calculating the bitmap size (rounded up) - int bitmap_blocks=(((DiskHeader*)block)->num_blocks+7)/8; - //rounded up block occupation of DiskHeader and bitmap - int occupation=(sizeof(DiskHeader)+bitmap_blocks+sizeof(BitMap)+BLOCK_SIZE-1)/BLOCK_SIZE; - - //now we can dealloate the read block - free(block); - //mmap the file - void* map=mmap(0,occupation*BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,fd,0); - CHECK_ERR(map==MAP_FAILED && errno!=SIGBUS,"error mapping the file"); - - if(map==MAP_FAILED){ - return FAILED; - } - - //populating the disk driver - disk->header=(DiskHeader*)map; - disk->bmap=(BitMap*)(map+sizeof(DiskHeader)); - disk->bmap->entries=(uint8_t*)disk->bmap+sizeof(BitMap); - - return SUCCESS; +int DiskDriver_load(DiskDriver *disk, const char *filename) { + int res, fd; //1= file already exists 0=file doesn't exists yet + //checking if the file exists or if we need to format the drive + res = access(filename, F_OK); + if (res == FAILED && errno == ENOENT) { + return FAILED; + } else { + CHECK_ERR(res == FAILED, "Can't test if the file exists");\ + + } + + // opening the file and creating it if necessary + fd = open(filename, O_RDWR, 0666); + //checking if the open was successful + CHECK_ERR(fd == FAILED, "error opening the file"); + + // Copio fd del file disco nella struttura + disk->fd = fd; + + //reading the first block of the disk + void *block = malloc(BLOCK_SIZE); + res = DiskDriver_readFirstBlock(disk, block, 0); + CHECK_ERR(res == FAILED, "CAN't read the first block of disk"); + + //calculating the bitmap size (rounded up) + int bitmap_blocks = (((DiskHeader *) block)->num_blocks + 7) / 8; + //rounded up block occupation of DiskHeader and bitmap + size_t occupation = (sizeof(DiskHeader) + bitmap_blocks + sizeof(BitMap) + BLOCK_SIZE - 1) / BLOCK_SIZE; + + //now we can dealloate the read block + free(block); + //mmap the file + void *map = mmap(0, occupation * BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + CHECK_ERR(map == MAP_FAILED && errno != SIGBUS, "error mapping the file"); + + if (map == MAP_FAILED) { + return FAILED; + } + + //populating the disk driver + disk->header = (DiskHeader *) map; + disk->bmap = (BitMap *) (map + sizeof(DiskHeader)); + disk->bmap->entries = (uint8_t *) disk->bmap + sizeof(BitMap); + + return SUCCESS; } // Reads the block in position block_num // returns -1 if the block is free according to the bitmap // 0 otherwise -int DiskDriver_readBlock(DiskDriver* disk, void* dest, int block_num){ - // Check if the parameters passed are valid - if(disk==NULL) return FAILED; - if(dest==NULL) return FAILED; - if(block_num<0 || block_num>disk->header->num_blocks) return FAILED; - - // Set the position to read from - int res; - res=lseek(disk->fd, block_num*BLOCK_SIZE, SEEK_SET); - if(res==-1) return FAILED; - - //now we read something so the file will actually have this dimension - res=read(disk->fd, dest, BLOCK_SIZE); - - // If the read was interrupted by an interrupt, then reading again - while(res==-1 && errno == EINTR){ - res=lseek(disk->fd, block_num*BLOCK_SIZE, SEEK_SET); - if(res==-1) return FAILED; - res=read(disk->fd ,dest, BLOCK_SIZE); - } - - if(res!=BLOCK_SIZE) return FAILED; - - return SUCCESS; +int DiskDriver_readBlock(DiskDriver *disk, void *dest, int block_num) { + // Check if the parameters passed are valid + if (disk == NULL) return FAILED; + if (dest == NULL) return FAILED; + if (block_num < 0 || block_num > disk->header->num_blocks) return FAILED; + + // Set the position to read from + int res; + res = (int) lseek(disk->fd, block_num * BLOCK_SIZE, SEEK_SET); + if (res == -1) return FAILED; + + //now we read something so the file will actually have this dimension + res = (int) read(disk->fd, dest, BLOCK_SIZE); + + // If the read was interrupted by an interrupt, then reading again + while (res == -1 && errno == EINTR) { + res = (int) lseek(disk->fd, block_num * BLOCK_SIZE, SEEK_SET); + if (res == -1) return FAILED; + res = (int) read(disk->fd, dest, BLOCK_SIZE); + } + + if (res != BLOCK_SIZE) return FAILED; + + return SUCCESS; } // writes a block in position block_num, and alters the bitmap accordingly // returns -1 if operation not possible -int DiskDriver_writeBlock(DiskDriver* disk, void* src, int block_num){ - // Check if the parameters passed are valid - if(disk==NULL) return FAILED; - if(src==NULL) return FAILED; - if(block_num<0 || block_num>disk->header->num_blocks) return FAILED; - - // Change status and check if the status of the bitmap block has been changed correctly - int sucStatus=BitMap_set(disk->bmap, block_num, BLOCK_USED); - if(sucStatus!=BLOCK_USED) return FAILED; - - // Set the position to read from - int res; - res=lseek(disk->fd, block_num*BLOCK_SIZE, SEEK_SET); - if(res==-1) return FAILED; - - //now we write something so the file will actually have this dimension - res=write(disk->fd, src, BLOCK_SIZE); - - // If the write was interrupted by an interrupt, then writing again - while(res==-1 && errno == EINTR){ - res=lseek(disk->fd, block_num*BLOCK_SIZE, SEEK_SET); - if(res==-1) return FAILED; - res=write(disk->fd, src, BLOCK_SIZE); - } - - if(res!=BLOCK_SIZE) return FAILED; - - return SUCCESS; +int DiskDriver_writeBlock(DiskDriver *disk, void *src, int block_num) { + // Check if the parameters passed are valid + if (disk == NULL) return FAILED; + if (src == NULL) return FAILED; + if (block_num < 0 || block_num > disk->header->num_blocks) return FAILED; + + // Change status and check if the status of the bitmap block has been changed correctly + int sucStatus = BitMap_set(disk->bmap, block_num, BLOCK_USED); + if (sucStatus != BLOCK_USED) return FAILED; + + // Set the position to read from + int res; + res = (int) lseek(disk->fd, block_num * BLOCK_SIZE, SEEK_SET); + if (res == -1) return FAILED; + + //now we write something so the file will actually have this dimension + res = (int) write(disk->fd, src, BLOCK_SIZE); + + // If the write was interrupted by an interrupt, then writing again + while (res == -1 && errno == EINTR) { + res = (int) lseek(disk->fd, block_num * BLOCK_SIZE, SEEK_SET); + if (res == -1) return FAILED; + res = (int) write(disk->fd, src, BLOCK_SIZE); + } + + if (res != BLOCK_SIZE) return FAILED; + + return SUCCESS; } // frees a block in position block_num, and alters the bitmap accordingly // returns -1 if operation not possible -int DiskDriver_freeBlock(DiskDriver* disk, int block_num){ - // Check if the parameters passed are valid - if(disk==NULL) return FAILED; - if(block_num<0 || block_num>disk->header->num_blocks) return FAILED; - - int status=BitMap_test(disk->bmap,block_num); - if(status==BLOCK_FREE) return SUCCESS; - - // Change status and check if the status of the bitmap block - // has been changed correctly - int sucStatus=BitMap_set(disk->bmap, block_num, BLOCK_FREE); - if(sucStatus!=BLOCK_FREE) return FAILED; - - // Inc num of free block - disk->header->free_blocks++; - if(disk->header->first_free_block==-1){ - disk->header->first_free_block=block_num; - } - return SUCCESS; +int DiskDriver_freeBlock(DiskDriver *disk, int block_num) { + // Check if the parameters passed are valid + if (disk == NULL) return FAILED; + if (block_num < 0 || block_num > disk->header->num_blocks) return FAILED; + + int status = BitMap_test(disk->bmap, block_num); + if (status == BLOCK_FREE) return SUCCESS; + + // Change status and check if the status of the bitmap block + // has been changed correctly + int sucStatus = BitMap_set(disk->bmap, block_num, BLOCK_FREE); + if (sucStatus != BLOCK_FREE) return FAILED; + + // Inc num of free block + disk->header->free_blocks++; + if (disk->header->first_free_block == -1) { + disk->header->first_free_block = block_num; + } + return SUCCESS; } // returns the first free block in the disk from position (checking the bitmap) -int DiskDriver_getFreeBlock(DiskDriver* disk, int start){ - // Check if the parameter passed is valid - if(disk==NULL) return FAILED; - if(start<0 || start>disk->header->num_blocks) return FAILED; - - // Check if the block has not been used - int new_block, retStat; - new_block=disk->header->first_free_block; - //if there aren't free blocks - if(new_block==FAILED){ - new_block=BitMap_get(disk->bmap,0,BLOCK_FREE); - if(new_block==FAILED){ +int DiskDriver_getFreeBlock(DiskDriver *disk, int start) { + // Check if the parameter passed is valid + if (disk == NULL) return FAILED; + if (start < 0 || start > disk->header->num_blocks) return FAILED; + + // Check if the block has not been used + int new_block, retStat; + new_block = disk->header->first_free_block; + //if there aren't free blocks + if (new_block == FAILED) { + new_block = BitMap_get(disk->bmap, 0, BLOCK_FREE); + if (new_block == FAILED) { return FAILED; } - } - retStat=BitMap_test(disk->bmap, new_block); + } + retStat = BitMap_test(disk->bmap, new_block); - // If new_block is already used then find a new_block free - if(retStat==BLOCK_USED){ - new_block=BitMap_get(disk->bmap, start, BLOCK_FREE); - } + // If new_block is already used then find a new_block free + if (retStat == BLOCK_USED) { + new_block = BitMap_get(disk->bmap, start, BLOCK_FREE); + } - retStat=BitMap_get(disk->bmap, new_block+1, BLOCK_FREE); - if(retStat==FAILED){ - retStat=BitMap_get(disk->bmap,0,BLOCK_FREE); + retStat = BitMap_get(disk->bmap, new_block + 1, BLOCK_FREE); + if (retStat == FAILED) { + retStat = BitMap_get(disk->bmap, 0, BLOCK_FREE); } - disk->header->first_free_block=retStat; - // Dec num of free block - disk->header->free_blocks--; + disk->header->first_free_block = retStat; + // Dec num of free block + disk->header->free_blocks--; - return new_block; + return new_block; } // writes the data (flushing the mmaps) -int DiskDriver_flush(DiskDriver* disk){ - // Check if the parameter passed is valid - if(disk==NULL) return FAILED; +int DiskDriver_flush(DiskDriver *disk) { + // Check if the parameter passed is valid + if (disk == NULL) return FAILED; - //calculating the bitmap size (rounded up) - int bitmap_blocks=(disk->header->num_blocks+7)/8; - //rounded up block occupation of DiskHeader and bitmap - int occupation=(sizeof(DiskHeader)+bitmap_blocks+sizeof(BitMap)+BLOCK_SIZE-1)/BLOCK_SIZE; + //calculating the bitmap size (rounded up) + int bitmap_blocks = (disk->header->num_blocks + 7) / 8; + //rounded up block occupation of DiskHeader and bitmap + size_t occupation = (sizeof(DiskHeader) + bitmap_blocks + sizeof(BitMap) + BLOCK_SIZE - 1) / BLOCK_SIZE; - // Sync between map and file and check possible error - int res=msync(disk->header, occupation*BLOCK_SIZE, MS_SYNC); - if(res==-1) return FAILED; + // Sync between map and file and check possible error + int res = msync(disk->header, occupation * BLOCK_SIZE, MS_SYNC); + if (res == -1) return FAILED; - res=fsync(disk->fd); - if(res==-1) return FAILED; + res = fsync(disk->fd); + if (res == -1) return FAILED; - return SUCCESS; + return SUCCESS; } -void DiskDriver_shutdown(DiskDriver* disk){ - int res; +void DiskDriver_shutdown(DiskDriver *disk) { + int res; - //calculating the bitmap size (rounded up) - int bitmap_blocks=(disk->header->num_blocks+7)/8; - //rounded up block occupation of DiskHeader and bitmap - int occupation=(sizeof(DiskHeader)+bitmap_blocks+sizeof(BitMap)+BLOCK_SIZE-1)/BLOCK_SIZE; + //calculating the bitmap size (rounded up) + int bitmap_blocks = (disk->header->num_blocks + 7) / 8; + //rounded up block occupation of DiskHeader and bitmap + size_t occupation = (sizeof(DiskHeader) + bitmap_blocks + sizeof(BitMap) + BLOCK_SIZE - 1) / BLOCK_SIZE; - //flushing changes - res=DiskDriver_flush(disk); - CHECK_ERR(res==FAILED,"can't sync changes"); + //flushing changes + res = DiskDriver_flush(disk); + CHECK_ERR(res == FAILED, "can't sync changes"); - //unmapping the mappend memory - res=munmap(disk->header,occupation*BLOCK_SIZE); - CHECK_ERR(res==-1,"can't unmap the file"); + //unmapping the mappend memory + res = munmap(disk->header, occupation * BLOCK_SIZE); + CHECK_ERR(res == -1, "can't unmap the file"); - //closing the file - close(disk->fd); - CHECK_ERR(res==-1,"can't close the file"); + //closing the file + close(disk->fd); + CHECK_ERR(res == -1, "can't close the file"); } diff --git a/disk_driver.h b/disk_driver.h index 70d4f57..e9cb793 100755 --- a/disk_driver.h +++ b/disk_driver.h @@ -1,22 +1,23 @@ #pragma once + #include "bitmap.h" #include "common.h" // this is stored in the 1st block of the disk -typedef struct _DiskHeader{ - int num_blocks; // blocks used to store files and directories - int bitmap_blocks; // how many blocks used by the bitmap - int bitmap_entries; // how many bytes are needed to store the bitmap +typedef struct _DiskHeader { + int num_blocks; // blocks used to store files and directories + int bitmap_blocks; // how many blocks used by the bitmap + int bitmap_entries; // how many bytes are needed to store the bitmap - int free_blocks; // free blocks - int first_free_block;// first block index + int free_blocks; // free blocks + int first_free_block;// first block index } DiskHeader; -typedef struct _DiskDriver{ - DiskHeader* header; // mmapped - BitMap* bmap; // mmapped (bitmap) - int fd; // for us - // Manca il puntatore di dove iniziano i blocchi per scrivere i dati +typedef struct _DiskDriver { + DiskHeader *header; // mmapped + BitMap *bmap; // mmapped (bitmap) + int fd; // for us + // Manca il puntatore di dove iniziano i blocchi per scrivere i dati } DiskDriver; /** @@ -29,29 +30,29 @@ typedef struct _DiskDriver{ // calculates how big the bitmap should be // compiles a disk header, and fills in the bitmap of appropriate size // with all 0 (to denote the free space); -void DiskDriver_init(DiskDriver* disk, const char* filename, int num_blocks); +void DiskDriver_init(DiskDriver *disk, const char *filename, int num_blocks); //loads an already initialized disk -int DiskDriver_load(DiskDriver* disk, const char* filename); +int DiskDriver_load(DiskDriver *disk, const char *filename); // reads the block in position block_num // returns -1 if the block is free according to the bitmap // 0 otherwise -int DiskDriver_readBlock(DiskDriver* disk, void* dest, int block_num); +int DiskDriver_readBlock(DiskDriver *disk, void *dest, int block_num); // writes a block in position block_num, and alters the bitmap accordingly // returns -1 if operation not possible -int DiskDriver_writeBlock(DiskDriver* disk, void* src, int block_num); +int DiskDriver_writeBlock(DiskDriver *disk, void *src, int block_num); // frees a block in position block_num, and alters the bitmap accordingly // returns -1 if operation not possible -int DiskDriver_freeBlock(DiskDriver* disk, int block_num); +int DiskDriver_freeBlock(DiskDriver *disk, int block_num); // returns the first free block in the disk from position (checking the bitmap) -int DiskDriver_getFreeBlock(DiskDriver* disk, int start); +int DiskDriver_getFreeBlock(DiskDriver *disk, int start); // writes the data (flushing the mmaps) -int DiskDriver_flush(DiskDriver* disk); +int DiskDriver_flush(DiskDriver *disk); //cleaning up, used to close the file and the mapped object -void DiskDriver_shutdown(DiskDriver* disk); +void DiskDriver_shutdown(DiskDriver *disk); diff --git a/shell.c b/shell.c index 8c1e002..8b4fad5 100755 --- a/shell.c +++ b/shell.c @@ -10,78 +10,78 @@ // Permette la creazione o il caricamento di un disco // sul quale verrà memorizzato il nostro filesystem -int shell_init(SimpleFS* fs){ - // chiedo il nome del file che memorizza il disco - char* nameFile=(char*)malloc(sizeof(char)*FILENAME_MAX_LENGTH); - memset(nameFile, 0,FILENAME_MAX_LENGTH); - printf("inserisci il nome del file su disco -> "); - CHECK_ERR(fgets(nameFile,FILENAME_MAX_LENGTH,stdin)==NULL,"can't read input filename"); - while(strcmp(nameFile, "\n")==0){ - printf("inserisci il nome del file su disco -> "); - CHECK_ERR(fgets(nameFile,FILENAME_MAX_LENGTH,stdin)==NULL,"can't read input filename"); - } - nameFile[strlen(nameFile)-1]='\0'; - fs->filename = nameFile; - - int res; - char format; - fs->disk = (DiskDriver*)malloc(sizeof(DiskDriver)); - memset(fs->disk, 0, sizeof(DiskDriver)); - // carico il disco - res=DiskDriver_load(fs->disk,fs->filename); - - // se non riesco a caricarlo significa che non esiste un disco con quel nome - // allora chiedo se vuole crearlo - if(res==FAILED){ - printf("file non presente o filesystem non riconosiuto, formattare il file? (s,n)-> "); - scanf("%c", &format); - while(format!='s' && format!='n'){ +int shell_init(SimpleFS *fs) { + // chiedo il nome del file che memorizza il disco + char *nameFile = (char *) malloc(sizeof(char) * FILENAME_MAX_LENGTH); + memset(nameFile, 0, FILENAME_MAX_LENGTH); + printf("inserisci il nome del file su disco -> "); + CHECK_ERR(fgets(nameFile, FILENAME_MAX_LENGTH, stdin) == NULL, "can't read input filename"); + while (strcmp(nameFile, "\n") == 0) { + printf("inserisci il nome del file su disco -> "); + CHECK_ERR(fgets(nameFile, FILENAME_MAX_LENGTH, stdin) == NULL, "can't read input filename"); + } + nameFile[strlen(nameFile) - 1] = '\0'; + fs->filename = nameFile; + + int res; + char format; + fs->disk = (DiskDriver *) malloc(sizeof(DiskDriver)); + memset(fs->disk, 0, sizeof(DiskDriver)); + // carico il disco + res = DiskDriver_load(fs->disk, fs->filename); + + // se non riesco a caricarlo significa che non esiste un disco con quel nome + // allora chiedo se vuole crearlo + if (res == FAILED) { + printf("file non presente o filesystem non riconosiuto, formattare il file? (s,n)-> "); + scanf("%c", &format); + while (format != 's' && format != 'n') { //to get the \n left in stdin getchar(); - printf("file non presente o filesystem non riconosiuto, formattare il file? (s,n)-> "); - scanf("%c", &format); - printf("%c\n",format); - } - if(format!='s') return FAILED; - - printf("inserisci il numero di blocchi del \"disco\" -> "); - scanf("%d",&(fs->block_num)); - while(fs->block_num<0){ - printf("inserisci il numero di blocchi del \"disco\"-> "); - scanf("%d",&(fs->block_num)); - } - // to get '/n' left in stdin - getchar(); - // format the disk - SimpleFS_format(fs); - } - return SUCCESS; + printf("file non presente o filesystem non riconosiuto, formattare il file? (s,n)-> "); + scanf("%c", &format); + printf("%c\n", format); + } + if (format != 's') return FAILED; + + printf("inserisci il numero di blocchi del \"disco\" -> "); + scanf("%d", &(fs->block_num)); + while (fs->block_num < 0) { + printf("inserisci il numero di blocchi del \"disco\"-> "); + scanf("%d", &(fs->block_num)); + } + // to get '/n' left in stdin + getchar(); + // format the disk + SimpleFS_format(fs); + } + return SUCCESS; } // Fornisce informazioni sul disco -void shell_info(DiskDriver *disk){ - printf("\t Disk info:\n"); - printf("num blocks: %d\n",disk->header->num_blocks ); - printf("num bitmap blocks: %d\n",disk->header->bitmap_blocks ); - printf("bitmap entries: %d\n",disk->header->bitmap_entries ); - printf("num free blocks: %d\n",disk->header->free_blocks ); - printf("first free block: %d\n",disk->header->first_free_block ); +void shell_info(DiskDriver *disk) { + printf("\t Disk info:\n"); + printf("num blocks: %d\n", disk->header->num_blocks); + printf("num bitmap blocks: %d\n", disk->header->bitmap_blocks); + printf("bitmap entries: %d\n", disk->header->bitmap_entries); + printf("num free blocks: %d\n", disk->header->free_blocks); + printf("first free block: %d\n", disk->header->first_free_block); } // Fornisce le informazioni in riguardo alla // bitmap del disco -void bitmap_info(DiskDriver *disk){ - int i,j,printed=0,print; +void bitmap_info(DiskDriver *disk) { + int i, j, printed = 0, print; uint8_t mask; printf("\t Bitmap of disk info\n"); - print=disk->header->num_blocks; - for(i=0;i<(disk->header->num_blocks+7)/8;i++){ - mask=128; - printf("block %d:\n",i); - for(j=0;j<8 && printedbmap->entries[i])? '1' :'0')); - mask=mask>>1; + print = disk->header->num_blocks; + for (i = 0; i < (disk->header->num_blocks + 7) / 8; i++) { + mask = 128; + printf("block %d:\n", i); + for (j = 0; j < 8 && printed < print; j++) { + printf("%c", ((mask & disk->bmap->entries[i]) ? '1' : '0')); + mask = mask >> 1; printed++; } printf("\n"); @@ -89,463 +89,461 @@ void bitmap_info(DiskDriver *disk){ } // Funzione che pulisce la memori utilizzata dalla shell -void shell_shutdown(SimpleFS* fs, DirectoryHandle* dh){ - if(fs!=NULL){ - if(fs->disk!=NULL){ - if(fs->disk->header!=NULL) DiskDriver_shutdown(fs->disk); - free(fs->disk); - } - free(fs->filename); - free(fs); - } - if(dh!=NULL){ - free(dh->dcb); - free(dh->current_block); - free(dh); - } +void shell_shutdown(SimpleFS *fs, DirectoryHandle *dh) { + if (fs != NULL) { + if (fs->disk != NULL) { + if (fs->disk->header != NULL) DiskDriver_shutdown(fs->disk); + free(fs->disk); + } + free(fs->filename); + free(fs); + } + if (dh != NULL) { + free(dh->dcb); + free(dh->current_block); + free(dh); + } } -void parse_command(char* command, char* Mytoken, - char tok_buf[MAX_NUM_TOK][MAX_COMMAND_SIZE], int* tok_num_ptr){ - // Inizializzo le varibili e copio i parametri - int tok_num = 0; - char buf[MAX_COMMAND_SIZE]; - // Copio i comandi - strcpy(buf, command); - - if(strlen(buf)>1){ - // Tokenizzo buffer - char* token = strtok(buf, Mytoken); - while(token!=NULL){ - strcpy(tok_buf[tok_num], token); - tok_num++; - token = strtok(NULL, Mytoken); - } - } - // Copio il numero di token trovati - *tok_num_ptr = tok_num; +void parse_command(char *command, char *Mytoken, + char tok_buf[MAX_NUM_TOK][MAX_COMMAND_SIZE], int *tok_num_ptr) { + // Inizializzo le varibili e copio i parametri + int tok_num = 0; + char buf[MAX_COMMAND_SIZE]; + // Copio i comandi + strcpy(buf, command); + + if (strlen(buf) > 1) { + // Tokenizzo buffer + char *token = strtok(buf, Mytoken); + while (token != NULL) { + strcpy(tok_buf[tok_num], token); + tok_num++; + token = strtok(NULL, Mytoken); + } + } + // Copio il numero di token trovati + *tok_num_ptr = tok_num; } // Ottiene i comandi e gli argomenti degli stessi // insieriti dall'utente da riga di comando -void make_argv(char* argv[MAX_NUM_COMMAND], - char tok_buf[MAX_NUM_TOK][MAX_COMMAND_SIZE], - int tok_num) { - int i, j=0, len=0; - char* app; - char* now; - char* suc; - char* buffer; - memset(argv, 0, MAX_NUM_TOK+1); - // Scorro tutti i token - for(i=0; ifcb->fcb.size_in_bytes; - printf("da leggere: %d\n", daLeggere); - while(letti < daLeggere){ - memset(buffer, 0, dim_let*sizeof(char)); - if(daLeggere-letti >= dim_let) letti+=SimpleFS_read(fh, buffer, dim_let); - else letti+=SimpleFS_read(fh, buffer, daLeggere-letti); - printf("%s",buffer); - } - printf("letti: %d\n", letti); - // Libero la memoria occupata - free(buffer); - } - // Chiudo il file - SimpleFS_close(fh); - } - } - return i; +int do_cat(DirectoryHandle *dh, char *argv[MAX_NUM_COMMAND], int i_init) { + int i = i_init; + FileHandle *fh; + // Cerco di contenare tutti i file passati + for (; argv[i] != NULL && strcmp(argv[i], "\0") != 0; i++) { + // Apro il file e mi metto all'inizio dello stesso + fh = SimpleFS_openFile(dh, argv[i]); + if (fh == NULL) printf("Impossibile concatenare il file: %s\n", argv[i]); + else { + if (SimpleFS_seek(fh, 0) == FAILED) printf("Impossibile concatenare il file: %s\n", argv[i]); + else { + // Se tutto e' andato bene allora leggo l'intero contenuto del file + int letti = 0; + int dim_let = 512; + char *buffer = (char *) malloc(dim_let * sizeof(char)); + int daLeggere = fh->fcb->fcb.size_in_bytes; + printf("da leggere: %d\n", daLeggere); + while (letti < daLeggere) { + memset(buffer, 0, dim_let * sizeof(char)); + if (daLeggere - letti >= dim_let) letti += SimpleFS_read(fh, buffer, dim_let); + else letti += SimpleFS_read(fh, buffer, daLeggere - letti); + printf("%s", buffer); + } + printf("letti: %d\n", letti); + // Libero la memoria occupata + free(buffer); + } + // Chiudo il file + SimpleFS_close(fh); + } + } + return i; } -int do_copy_file(DirectoryHandle* dh, char* argv[MAX_NUM_COMMAND], int i_init){ - int toDisk=0, i=i_init, res, resS; - // Selezioni che consentono di selezionare la giusta operazione da fare - // secondo l'opzione scelta dall'utente - if(argv[i_init]!=NULL && strcmp(argv[i_init], "-to-disk")==0) toDisk=1; - if(argv[i_init]!=NULL && strcmp(argv[i_init], "-from-disk")==0) toDisk=2; - // Nel caso di opzione non scelta stampo l'help del comando - if(toDisk==0){ - if(argv[i_init]!=NULL && strcmp(argv[i_init], "--help")==0) printf("\ncp --help"); - else printf("\nNessuna opezione selezionata, copia annullata."); - printf("\nOpzioni selezionabili:" - "\n\t-to-disk per la copia verso SimpleFS" - "\n\t-from-disk per la copia da SimpleFS" - "\n\t--help" - "\n\nUso: cp [OPT] src dest\n\n"); - return i; - } - i++; - - // Copia di file dall'esterno verso il nostro filesystem - if(toDisk==1){ - // Cerco di aprire entrambi i file - int fd = open(argv[i], O_RDONLY); - if(fd==-1){ - printf("Impossibile aprire il file %s\n",argv[i]); - return i; - } - i++; - FileHandle* fh=SimpleFS_openFile(dh, argv[i]); - if(fh==NULL){ - fh=SimpleFS_createFile(dh, argv[i]); - if(fh==NULL){ - printf("Impossibile aprire dal Simplefs filesystem il file: %s\n",argv[i]); - return i; - } - } - - // Se tutto è andato a buon fine leggo il file passato come - // sorgente dall'inzio e lo scrivo su file destinazione - int daLeggere = lseek(fd, 0, SEEK_END); - lseek(fd, 0, SEEK_SET); - int num_letti=0; - char* buffer = (char*)malloc(BLOCK_SIZE*sizeof(char)); - // Iterazioni per leggere tutto il file - while(num_letti < daLeggere){ - memset(buffer, 0, BLOCK_SIZE); - res=read(fd, buffer, BLOCK_SIZE); - if(res == -1 && errno == EINTR) continue; - if(res>0){ - num_letti+=res; - resS=SimpleFS_write(fh, buffer, res); - if(resS==FAILED){ - printf("Impossibile scrivere su file\n"); - num_letti = daLeggere; - } - } - else num_letti = daLeggere; - printf("\r[%d/%d",num_letti, daLeggere); - fflush(stdout); - } - printf("]\n"); - - // Se la read è andata in errore comunico l'accaduto - if(res==-1 && errno != EINTR){ - if(resS!=FAILED){ - printf("Errore durante la scrittura del file su Simplefs\n"); - SimpleFS_close(fh); - } - close(fd); - printf("Errore durante la lettura del file dall'host\n"); - return i; - } - - // Se la write è andata in errore comunico l'accaduto - if(resS==FAILED){ - SimpleFS_close(fh); - printf("Errore durante la scrittura del file su Simplefs\n"); - return i; - } - - // Libero le risorse - close(fd); - SimpleFS_close(fh); - free(buffer); - } - - // Copia di file dall'interno verso l'esterno - if(toDisk==2){ - // Cerco di aprire entrambi i file - FileHandle* fh=SimpleFS_openFile(dh, argv[i]); - if(fh==NULL){ - printf("Impossibile aprire dal Simplefs filesystem il file: %s\n",argv[i]); - return i; - } - i++; - int fd = open(argv[i], O_WRONLY|O_DIRECTORY, 0666); - if(fd==-1){ - fd = open(argv[i], O_WRONLY|O_TRUNC|O_CREAT, 0666); - if(fd==-1){ - printf("Impossibile aprire il file: %s\n",argv[i]); - return i; - } - } - - // Se tutto è andato a buon fine leggo il file passato come - // sorgente dall'inzio e lo scrivo su file destinazione - if(SimpleFS_seek(fh, 0) == FAILED){ - printf("Impossibile leggere il file sorgente\n"); - return i; - } - char* buffer = (char*)malloc(BLOCK_SIZE*sizeof(char)); - resS=0; - int daLeggere = fh->fcb->fcb.size_in_bytes; - int attuale=0; - printf("\n["); - // Iterazioni per leggere tutto il file - while(resS < daLeggere){ - memset(buffer, '\0', BLOCK_SIZE); - res=resS; - if(daLeggere-resS > BLOCK_SIZE) resS+=SimpleFS_read(fh, buffer, BLOCK_SIZE); - else resS+=SimpleFS_read(fh, buffer, daLeggere-resS); - attuale = 0; - // Iterazione per scrivere correttamente i byte letti - // sul file destinazione - while(res < resS){ - res+=write(fd , buffer+attuale, resS-res); - attuale=res; - if(res == -1 && errno == EINTR) continue; - // In caso di errore diverso da interruzzione - // comunico che non posso scrivere - if(res == -1){ - printf("Impossibile scrivere su file\n"); - res = resS; - resS = daLeggere; - } - } - printf("\r[%d/%d",resS, daLeggere); - fflush(stdout); - } - printf("]\n"); - - // Se la write è andata in errore comunico l'accaduto - if(res==-1 && errno != EINTR){ - if(resS!=FAILED){ - printf("Errore durante la lettura del file su Simplefs\n"); - SimpleFS_close(fh); - } - close(fd); - printf("Errore durante la scrittura del file sull'host\n"); - return i; - } - - // Libero le risorse - close(fd); - SimpleFS_close(fh); - free(buffer); - } - - return i; -} +int do_copy_file(DirectoryHandle *dh, char *argv[MAX_NUM_COMMAND], int i_init) { + int toDisk = 0, i = i_init, res = FAILED, resS = FAILED; + // Selezioni che consentono di selezionare la giusta operazione da fare + // secondo l'opzione scelta dall'utente + if (argv[i_init] != NULL && strcmp(argv[i_init], "-to-disk") == 0) toDisk = 1; + if (argv[i_init] != NULL && strcmp(argv[i_init], "-from-disk") == 0) toDisk = 2; + // Nel caso di opzione non scelta stampo l'help del comando + if (toDisk == 0) { + if (argv[i_init] != NULL && strcmp(argv[i_init], "--help") == 0) printf("\ncp --help"); + else printf("\nNessuna opezione selezionata, copia annullata."); + printf("\nOpzioni selezionabili:" + "\n\t-to-disk per la copia verso SimpleFS" + "\n\t-from-disk per la copia da SimpleFS" + "\n\t--help" + "\n\nUso: cp [OPT] src dest\n\n"); + return i; + } + i++; + + // Copia di file dall'esterno verso il nostro filesystem + if (toDisk == 1) { + // Cerco di aprire entrambi i file + int fd = open(argv[i], O_RDONLY); + if (fd == -1) { + printf("Impossibile aprire il file %s\n", argv[i]); + return i; + } + i++; + FileHandle *fh = SimpleFS_openFile(dh, argv[i]); + if (fh == NULL) { + fh = SimpleFS_createFile(dh, argv[i]); + if (fh == NULL) { + printf("Impossibile aprire dal Simplefs filesystem il file: %s\n", argv[i]); + return i; + } + } -// penultimo spazio di argv vedere se contiene > ====> se contiene > l'ultimo spazio contiene file destinazione -int echo(char* argv[MAX_NUM_TOK +1],DirectoryHandle* d, int i_init){ - //variabili utili - int i=i_init; - int control=0;//variabile che se è settata a 1 mi indica che bisogna scrivere su file - char* result=malloc(sizeof(char)*MAX_COMMAND_SIZE); - FileHandle* fh; - int b_scritti; - - for(; argv[i]!= NULL && strcmp(argv[i],"\0") != 0; i++){ - //composizione stringa finale in result, se si trova '>' result dovrà essere scritto su file - if(strcmp(argv[i],">") != 0){ - result=strcat(result,argv[i]); - result=strcat(result," "); - }else{ - control=1; - i++; - //se manca file di destinazione - if(argv[i]==NULL){ - printf("file destinazione non presente.\n%s",result); - return i; - } - fh=SimpleFS_createFile(d,argv[i]); - if(fh==NULL){ - fh=SimpleFS_openFile(d,argv[i]); - if(fh==NULL){ - printf("errore sulla open del file\n"); - return i; - } - } - b_scritti=SimpleFS_write(fh,(void*)result,strlen(result)); - while(b_scritti==-1|| b_scritti!= strlen(result)){ - b_scritti=SimpleFS_write(fh,(void*)result+b_scritti ,strlen(result)-b_scritti); - } - SimpleFS_close(fh); - //Al completamento con esito positivo, la funzione deve aprire il file e restituire un numero intero non negativo che rappresenta - //la corretta esecuzione della funzione. - //Altrimenti, FAILED deve essere restituito. - //Nessun file deve essere creato o modificato se la funzione restituisce FAILED. - } - } - //uscito da questo ciclo, se c'era il '>', il file sarà gia stato scritto(con successo o insuccesso) e quindi non sarà necessario fare niente - //altrimenti sarà necessaria una printf di result - if(control!=1){ - //non devo mettere niente su nessun file==>printf - printf("\n %s \n",result); - } - free(result); - return i; -} + // Se tutto è andato a buon fine leggo il file passato come + // sorgente dall'inzio e lo scrivo su file destinazione + int daLeggere = (int) lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + int num_letti = 0; + char *buffer = (char *) malloc(BLOCK_SIZE * sizeof(char)); + // Iterazioni per leggere tutto il file + while (num_letti < daLeggere) { + memset(buffer, 0, BLOCK_SIZE); + res = (int) read(fd, buffer, BLOCK_SIZE); + if (res == -1 && errno == EINTR) continue; + if (res > 0) { + num_letti += res; + resS = SimpleFS_write(fh, buffer, res); + if (resS == FAILED) { + printf("Impossibile scrivere su file\n"); + num_letti = daLeggere; + } + } else num_letti = daLeggere; + printf("\r[%d/%d", num_letti, daLeggere); + fflush(stdout); + } + printf("]\n"); -int do_cmd(SimpleFS* fs, DirectoryHandle* dh, char tok_buf[MAX_NUM_TOK][MAX_COMMAND_SIZE], int tok_num){ - int i, j, res; - char* argv[MAX_NUM_COMMAND]; - memset(argv, 0, MAX_NUM_TOK+1); - // Ottengo i comandi con i loro argomenti - make_argv(argv, tok_buf, tok_num); - // Iterazioni che scorrono tutti i possibili comandi dati - for(i=0; argv[i]!=NULL; i++){ - if(argv[i]!=NULL && strcmp(argv[i], "help") == 0){ - printf("\n[progettoSO_shell] HELP\n" - "I comandi che puoi dare in questa semplice shell sono:\n" - "\t- /help per mostrare questo messaggio\n" - "\t- /ls per mostrare l'elenco dei file contenuti nella working directory\n" - "\t- /info per avere informazioni sul disco\n" - "\t- /info -bmap per avere informazioni sulla bitmap del disco\n" - "\t- /touch per creare un file vuoto\n" - "\t- /echo per scrivere un messaggio su un file\n" - "\t- /cat per concatenare i file e scriverli sullo schermo\n" - "\t- /mkdir per creare una nuova directory\n" - "\t- /cd per cambiare la directory di lavoro\n" - "\t- /rm per rimuovere un file o una directory," - " rimuove una directory in maniera ricorsiva se questa non e' vuota\n" - "\t- /cp per copiare un file da o verso SimpleFs\n\n"); - } - if(argv[i]!=NULL && strcmp(argv[i], "quit") == 0){ - shell_shutdown(fs, dh); - free(argv[i]); - return QUIT; - } - if(argv[i]!=NULL && strcmp(argv[i], "ls")==0){ - char* names; - res=SimpleFS_readDir(&names, dh); - if(res!=FAILED){ - printf("\n%s\n", names); - free(names); - } - else printf("Errore nell'esecuzione di ls\n"); - } - if(argv[i]!=NULL && strcmp(argv[i], "cd")==0){ - for(j=i+1; argv[j]!=NULL && strcmp(argv[j], "\0")!=0; j++){ - res=SimpleFS_changeDir(dh, argv[j]); - if(res==FAILED) printf("Errore nell'esecuzione di cd\n"); - } - i=j; - } - if(argv[i]!=NULL && strcmp(argv[i], "mkdir")==0){ - for(j=i+1; argv[j]!=NULL && strcmp(argv[j], "\0")!=0; j++){ - res=SimpleFS_mkDir(dh, argv[j]); - if(res==FAILED) printf("Errore nell'esecuzione di mkdir\n"); - } - i=j; - } - if(argv[i]!=NULL && strcmp(argv[i], "rm")==0){ - for(j=i+1; argv[j]!=NULL && strcmp(argv[j], "\0")!=0; j++){ - res=SimpleFS_remove(dh, argv[j]); - if(res==FAILED) printf("Errore nell'esecuzione di rm su file/directory: %s\n",argv[j]); - } - i=j; - } - if(argv[i]!=NULL && strcmp(argv[i], "touch")==0){ - for(j=i+1; argv[j]!=NULL && strcmp(argv[j], "\0")!=0; j++){ - FileHandle*fh=SimpleFS_createFile(dh, argv[j]); - if(fh==NULL) printf("Errore nell'esecuzione di touch su file: %s\n",argv[j]); - else SimpleFS_close(fh); - } - i=j; - } - if(argv[i]!=NULL && strcmp(argv[i], "cat")==0){ - i+=do_cat(dh, argv, i+1); - } - if(argv[i]!=NULL && strcmp(argv[i], "cp")==0){ - i+=do_copy_file(dh, argv, i+1); - } - if(argv[i]!=NULL && strcmp(argv[i], "info")==0){ - if(argv[i+1]!=NULL && strcmp(argv[i+1], "-bmap")==0){ - bitmap_info(fs->disk); - }else{ - shell_info(fs->disk); + // Se la read è andata in errore comunico l'accaduto + if (res == -1 && errno != EINTR) { + if (resS != FAILED) { + printf("Errore durante la scrittura del file su Simplefs\n"); + SimpleFS_close(fh); } - } - if(argv[i]!=NULL && strcmp(argv[i], "echo")==0){ - i+=echo(argv,dh, i+1); - } - } + close(fd); + printf("Errore durante la lettura del file dall'host\n"); + return i; + } - // Libero la memoria dai vari comandi - for(i=0; argv[i]!=NULL; i++) if(strcmp(argv[i], "\0")!=0) free(argv[i]); + // Se la write è andata in errore comunico l'accaduto + if (resS == FAILED) { + SimpleFS_close(fh); + printf("Errore durante la scrittura del file su Simplefs\n"); + return i; + } - return AGAIN; -} + // Libero le risorse + close(fd); + SimpleFS_close(fh); + free(buffer); + } -int main(int arg, char** args){ - //dichiarazione varibili utili - int res; - //questa variabile indica la funzione attualmente selezionata dall'utente - int control=1; - SimpleFS* fs=(SimpleFS*)malloc(sizeof(SimpleFS)); - DirectoryHandle* dh=NULL; + // Copia di file dall'interno verso l'esterno + if (toDisk == 2) { + // Cerco di aprire entrambi i file + FileHandle *fh = SimpleFS_openFile(dh, argv[i]); + if (fh == NULL) { + printf("Impossibile aprire dal Simplefs filesystem il file: %s\n", argv[i]); + return i; + } + i++; + int fd = open(argv[i], O_WRONLY | O_DIRECTORY, 0666); + if (fd == -1) { + fd = open(argv[i], O_WRONLY | O_TRUNC | O_CREAT, 0666); + if (fd == -1) { + printf("Impossibile aprire il file: %s\n", argv[i]); + return i; + } + } - //caricamento/inizializzazione del disco - res=shell_init(fs); - if(res==FAILED) shell_shutdown(fs, dh); - CHECK_ERR(res==FAILED,"can't initialize the disk(1)"); - dh=SimpleFS_init(fs,fs->disk); - if(dh==NULL) shell_shutdown(fs, dh); - CHECK_ERR(dh==NULL,"can't initialize the disk(2)"); + // Se tutto è andato a buon fine leggo il file passato come + // sorgente dall'inzio e lo scrivo su file destinazione + if (SimpleFS_seek(fh, 0) == FAILED) { + printf("Impossibile leggere il file sorgente\n"); + return i; + } + char *buffer = (char *) malloc(BLOCK_SIZE * sizeof(char)); + resS = 0; + int daLeggere = fh->fcb->fcb.size_in_bytes; + int attuale = 0; + printf("\n["); + // Iterazioni per leggere tutto il file + while (resS < daLeggere) { + memset(buffer, '\0', BLOCK_SIZE); + res = resS; + if (daLeggere - resS > BLOCK_SIZE) resS += SimpleFS_read(fh, buffer, BLOCK_SIZE); + else resS += SimpleFS_read(fh, buffer, daLeggere - resS); + attuale = 0; + // Iterazione per scrivere correttamente i byte letti + // sul file destinazione + while (res < resS) { + res += write(fd, buffer + attuale, (size_t) (resS - res)); + attuale = res; + if (res == -1 && errno == EINTR) continue; + // In caso di errore diverso da interruzzione + // comunico che non posso scrivere + if (res == -1) { + printf("Impossibile scrivere su file\n"); + res = resS; + resS = daLeggere; + } + } + printf("\r[%d/%d", resS, daLeggere); + fflush(stdout); + } + printf("]\n"); - //per ottenere i comandi inseriti dall'utente - char command[1024]; - char tok_buf[MAX_NUM_TOK][MAX_COMMAND_SIZE]; - int tok_num=0; - char* ret; + // Se la write è andata in errore comunico l'accaduto + if (res == -1 && errno != EINTR) { + if (resS != FAILED) { + printf("Errore durante la lettura del file su Simplefs\n"); + SimpleFS_close(fh); + } + close(fd); + printf("Errore durante la scrittura del file sull'host\n"); + return i; + } - printf("\n\tI comandi di questa shell inziano per '/', esempio /ls, /cd, /mkdir, ecc.\n\n"); + // Libero le risorse + close(fd); + SimpleFS_close(fh); + free(buffer); + } - while(control){ - printf("[progettoSO_shell:%s]>",dh->dcb->fcb.name); + return i; +} - //lettura dei comandi da tastiera - ret=fgets(command,MAX_COMMAND_SIZE,stdin); - if(ret==NULL) shell_shutdown(fs, dh); - CHECK_ERR(ret==NULL,"can't read command from input"); +// penultimo spazio di argv vedere se contiene > ====> se contiene > l'ultimo spazio contiene file destinazione +int echo(char *argv[MAX_NUM_TOK + 1], DirectoryHandle *d, int i_init) { + //variabili utili + int i = i_init; + int control = 0;//variabile che se è settata a 1 mi indica che bisogna scrivere su file + char *result = malloc(sizeof(char) * MAX_COMMAND_SIZE); + FileHandle *fh; + int b_scritti; + + for (; argv[i] != NULL && strcmp(argv[i], "\0") != 0; i++) { + //composizione stringa finale in result, se si trova '>' result dovrà essere scritto su file + if (strcmp(argv[i], ">") != 0) { + result = strcat(result, argv[i]); + result = strcat(result, " "); + } else { + control = 1; + i++; + //se manca file di destinazione + if (argv[i] == NULL) { + printf("file destinazione non presente.\n%s", result); + return i; + } + fh = SimpleFS_createFile(d, argv[i]); + if (fh == NULL) { + fh = SimpleFS_openFile(d, argv[i]); + if (fh == NULL) { + printf("errore sulla open del file\n"); + return i; + } + } + b_scritti = SimpleFS_write(fh, (void *) result, (int) strlen(result)); + while (b_scritti == -1 || b_scritti != strlen(result)) { + b_scritti = SimpleFS_write(fh, (void *) result + b_scritti, (int) (strlen(result) - b_scritti)); + } + SimpleFS_close(fh); + //Al completamento con esito positivo, la funzione deve aprire il file e restituire un numero intero non negativo che rappresenta + //la corretta esecuzione della funzione. + //Altrimenti, FAILED deve essere restituito. + //Nessun file deve essere creato o modificato se la funzione restituisce FAILED. + } + } + //uscito da questo ciclo, se c'era il '>', il file sarà gia stato scritto(con successo o insuccesso) e quindi non sarà necessario fare niente + //altrimenti sarà necessaria una printf di result + if (control != 1) { + //non devo mettere niente su nessun file==>printf + printf("\n %s \n", result); + } + free(result); + return i; +} - if(strchr(command, ';')!=NULL) parse_command(command,";",tok_buf,&tok_num); - else parse_command(command,"\n",tok_buf,&tok_num); +int do_cmd(SimpleFS *fs, DirectoryHandle *dh, char tok_buf[MAX_NUM_TOK][MAX_COMMAND_SIZE], int tok_num) { + int i, j, res; + char *argv[MAX_NUM_COMMAND]; + memset(argv, 0, MAX_NUM_TOK + 1); + // Ottengo i comandi con i loro argomenti + make_argv(argv, tok_buf, tok_num); + // Iterazioni che scorrono tutti i possibili comandi dati + for (i = 0; argv[i] != NULL; i++) { + if (argv[i] != NULL && strcmp(argv[i], "help") == 0) { + printf("\n[progettoSO_shell] HELP\n" + "I comandi che puoi dare in questa semplice shell sono:\n" + "\t- /help per mostrare questo messaggio\n" + "\t- /ls per mostrare l'elenco dei file contenuti nella working directory\n" + "\t- /info per avere informazioni sul disco\n" + "\t- /info -bmap per avere informazioni sulla bitmap del disco\n" + "\t- /touch per creare un file vuoto\n" + "\t- /echo per scrivere un messaggio su un file\n" + "\t- /cat per concatenare i file e scriverli sullo schermo\n" + "\t- /mkdir per creare una nuova directory\n" + "\t- /cd per cambiare la directory di lavoro\n" + "\t- /rm per rimuovere un file o una directory," + " rimuove una directory in maniera ricorsiva se questa non e' vuota\n" + "\t- /cp per copiare un file da o verso SimpleFs\n\n"); + } + if (argv[i] != NULL && strcmp(argv[i], "quit") == 0) { + shell_shutdown(fs, dh); + free(argv[i]); + return QUIT; + } + if (argv[i] != NULL && strcmp(argv[i], "ls") == 0) { + char *names; + res = SimpleFS_readDir(&names, dh); + if (res != FAILED) { + printf("\n%s\n", names); + free(names); + } else printf("Errore nell'esecuzione di ls\n"); + } + if (argv[i] != NULL && strcmp(argv[i], "cd") == 0) { + for (j = i + 1; argv[j] != NULL && strcmp(argv[j], "\0") != 0; j++) { + res = SimpleFS_changeDir(dh, argv[j]); + if (res == FAILED) printf("Errore nell'esecuzione di cd\n"); + } + i = j; + } + if (argv[i] != NULL && strcmp(argv[i], "mkdir") == 0) { + for (j = i + 1; argv[j] != NULL && strcmp(argv[j], "\0") != 0; j++) { + res = SimpleFS_mkDir(dh, argv[j]); + if (res == FAILED) printf("Errore nell'esecuzione di mkdir\n"); + } + i = j; + } + if (argv[i] != NULL && strcmp(argv[i], "rm") == 0) { + for (j = i + 1; argv[j] != NULL && strcmp(argv[j], "\0") != 0; j++) { + res = SimpleFS_remove(dh, argv[j]); + if (res == FAILED) printf("Errore nell'esecuzione di rm su file/directory: %s\n", argv[j]); + } + i = j; + } + if (argv[i] != NULL && strcmp(argv[i], "touch") == 0) { + for (j = i + 1; argv[j] != NULL && strcmp(argv[j], "\0") != 0; j++) { + FileHandle *fh = SimpleFS_createFile(dh, argv[j]); + if (fh == NULL) printf("Errore nell'esecuzione di touch su file: %s\n", argv[j]); + else SimpleFS_close(fh); + } + i = j; + } + if (argv[i] != NULL && strcmp(argv[i], "cat") == 0) { + i += do_cat(dh, argv, i + 1); + } + if (argv[i] != NULL && strcmp(argv[i], "cp") == 0) { + i += do_copy_file(dh, argv, i + 1); + } + if (argv[i] != NULL && strcmp(argv[i], "info") == 0) { + if (argv[i + 1] != NULL && strcmp(argv[i + 1], "-bmap") == 0) { + bitmap_info(fs->disk); + } else { + shell_info(fs->disk); + } + } + if (argv[i] != NULL && strcmp(argv[i], "echo") == 0) { + i += echo(argv, dh, i + 1); + } + } - // tok_num nullo allora ricomincio - if(tok_num<=0) continue; + // Libero la memoria dai vari comandi + for (i = 0; argv[i] != NULL; i++) if (strcmp(argv[i], "\0") != 0) free(argv[i]); - // Chiamo do_cmd che esegue i comandi - control=do_cmd(fs, dh, tok_buf, tok_num); + return AGAIN; +} - memset(command, 0, MAX_COMMAND_SIZE); - tok_num=0; - } +int main(int arg, char **args) { + //dichiarazione varibili utili + int res; + //questa variabile indica la funzione attualmente selezionata dall'utente + int control = 1; + SimpleFS *fs = (SimpleFS *) malloc(sizeof(SimpleFS)); + DirectoryHandle *dh = NULL; + + //caricamento/inizializzazione del disco + res = shell_init(fs); + if (res == FAILED) shell_shutdown(fs, dh); + CHECK_ERR(res == FAILED, "can't initialize the disk(1)"); + dh = SimpleFS_init(fs, fs->disk); + if (dh == NULL) shell_shutdown(fs, dh); + CHECK_ERR(dh == NULL, "can't initialize the disk(2)"); + + //per ottenere i comandi inseriti dall'utente + char command[1024]; + char tok_buf[MAX_NUM_TOK][MAX_COMMAND_SIZE]; + int tok_num = 0; + char *ret; + + printf("\n\tI comandi di questa shell inziano per '/', esempio /ls, /cd, /mkdir, ecc.\n\n"); + + while (control) { + printf("[progettoSO_shell:%s]>", dh->dcb->fcb.name); + + //lettura dei comandi da tastiera + ret = fgets(command, MAX_COMMAND_SIZE, stdin); + if (ret == NULL) shell_shutdown(fs, dh); + CHECK_ERR(ret == NULL, "can't read command from input"); + + if (strchr(command, ';') != NULL) parse_command(command, ";", tok_buf, &tok_num); + else parse_command(command, "\n", tok_buf, &tok_num); + + // tok_num nullo allora ricomincio + if (tok_num <= 0) continue; + + // Chiamo do_cmd che esegue i comandi + control = do_cmd(fs, dh, tok_buf, tok_num); + + memset(command, 0, MAX_COMMAND_SIZE); + tok_num = 0; + } - return 0; + return 0; } diff --git a/simplefs.c b/simplefs.c index 101eb6f..425a6ee 100644 --- a/simplefs.c +++ b/simplefs.c @@ -1,102 +1,103 @@ #include "simplefs.h" #include "simplefs_aux.h" -void SimpleFS_format(SimpleFS* fs){ +void SimpleFS_format(SimpleFS *fs) { //we check that we have been given valid data - if(fs==NULL){ + if (fs == NULL) { return; } - // disk initializing in which we clean the bitmap - DiskDriver_init(fs->disk,fs->filename,fs->block_num); - - // getting the root block - int rootblock=DiskDriver_getFreeBlock(fs->disk,0); - CHECK_ERR(rootblock==FAILED,"can't get the root block from the created disk"); - - // allocating the directory block - FirstDirectoryBlock *root=(FirstDirectoryBlock*)malloc(sizeof(FirstDirectoryBlock)); - //we set all to 0 to avoid clutter when we write the directory on disk - memset(root,0,sizeof(FirstDirectoryBlock)); - - // creating the block header - root->header.previous_block=MISSING; - root->header.next_block=MISSING; - root->header.block_in_file=CONTROL_BLOCK; - - // creating the directory CB - root->fcb.directory_block=MISSING; - root->header.block_in_disk=rootblock; - strncpy(root->fcb.name,"/",2); - root->fcb.size_in_blocks=1; - root->fcb.size_in_bytes=sizeof(FirstDirectoryBlock); - root->fcb.is_dir=DIRECTORY; - - //initializing the entries of the directory - root->num_entries=0; - int i=0; - for(i=0;i<(int)((BLOCK_SIZE-sizeof(BlockHeader)-sizeof(FileControlBlock)-sizeof(int))/sizeof(int));i++){ - root->file_blocks[i]=MISSING; - } - - int res; - //writing the directory on disk - res=DiskDriver_writeBlock(fs->disk,(void*) root,rootblock); - free(root); - CHECK_ERR(res==FAILED,"can't write to disk"); + // disk initializing in which we clean the bitmap + DiskDriver_init(fs->disk, fs->filename, fs->block_num); + + // getting the root block + int rootblock = DiskDriver_getFreeBlock(fs->disk, 0); + CHECK_ERR(rootblock == FAILED, "can't get the root block from the created disk"); + + // allocating the directory block + FirstDirectoryBlock *root = (FirstDirectoryBlock *) malloc(sizeof(FirstDirectoryBlock)); + //we set all to 0 to avoid clutter when we write the directory on disk + memset(root, 0, sizeof(FirstDirectoryBlock)); + + // creating the block header + root->header.previous_block = MISSING; + root->header.next_block = MISSING; + root->header.block_in_file = CONTROL_BLOCK; + + // creating the directory CB + root->fcb.directory_block = MISSING; + root->header.block_in_disk = rootblock; + strncpy(root->fcb.name, "/", 2); + root->fcb.size_in_blocks = 1; + root->fcb.size_in_bytes = sizeof(FirstDirectoryBlock); + root->fcb.is_dir = DIRECTORY; + + //initializing the entries of the directory + root->num_entries = 0; + int i = 0; + for (i = 0; + i < (int) ((BLOCK_SIZE - sizeof(BlockHeader) - sizeof(FileControlBlock) - sizeof(int)) / sizeof(int)); i++) { + root->file_blocks[i] = MISSING; + } + + int res; + //writing the directory on disk + res = DiskDriver_writeBlock(fs->disk, (void *) root, rootblock); + free(root); + CHECK_ERR(res == FAILED, "can't write to disk"); } // initializes a file system on an already made disk // returns a handle to the top level directory stored in the first block -DirectoryHandle* SimpleFS_init(SimpleFS* fs, DiskDriver* disk){ +DirectoryHandle *SimpleFS_init(SimpleFS *fs, DiskDriver *disk) { //we check that we have been given valid data - if(fs==NULL || disk==NULL){ + if (fs == NULL || disk == NULL) { return NULL; } - fs->disk=disk; - int res,current_block=disk->header->bitmap_blocks; - FirstDirectoryBlock* block=(FirstDirectoryBlock*) malloc(sizeof(FirstDirectoryBlock)); - - //we read the first block after the block used by the bitmap, which is the directory block - //remeber: we start from 0! - res=DiskDriver_readBlock(fs->disk,block,current_block); - if(res==FAILED){ + fs->disk = disk; + int res, current_block = disk->header->bitmap_blocks; + FirstDirectoryBlock *block = (FirstDirectoryBlock *) malloc(sizeof(FirstDirectoryBlock)); + + //we read the first block after the block used by the bitmap, which is the directory block + //remeber: we start from 0! + res = DiskDriver_readBlock(fs->disk, block, current_block); + if (res == FAILED) { free(block); return NULL; } - // we populate the handle according to the readed block - DirectoryHandle* handle=(DirectoryHandle*) malloc(sizeof(DirectoryHandle)); - handle->sfs=fs; - handle->current_block=(BlockHeader*)malloc(sizeof(BlockHeader)); - memcpy(handle->current_block,&(block->header),sizeof(BlockHeader)); - handle->dcb=block; - handle->directory=NULL; - handle->pos_in_dir=0; - handle->pos_in_block=0; - - return handle; + // we populate the handle according to the readed block + DirectoryHandle *handle = (DirectoryHandle *) malloc(sizeof(DirectoryHandle)); + handle->sfs = fs; + handle->current_block = (BlockHeader *) malloc(sizeof(BlockHeader)); + memcpy(handle->current_block, &(block->header), sizeof(BlockHeader)); + handle->dcb = block; + handle->directory = NULL; + handle->pos_in_dir = 0; + handle->pos_in_block = 0; + + return handle; } -FileHandle* SimpleFS_createFile(DirectoryHandle* d, const char* filename){ +FileHandle *SimpleFS_createFile(DirectoryHandle *d, const char *filename) { //we check that we have been given valid data - if(d==NULL || strlen(filename)==0){ + if (d == NULL || strlen(filename) == 0) { return NULL; } - //firstly we check if we have at least two free block in the disk - //one for the FirstFileBlock - //one for the data (that's the minimum space required for a file) - //one for an eventually needed new DirectoryBlock to register the file into the directory - if(d->sfs->disk->header->free_blocks<2){ - return NULL; - } - int res; + //firstly we check if we have at least two free block in the disk + //one for the FirstFileBlock + //one for the data (that's the minimum space required for a file) + //one for an eventually needed new DirectoryBlock to register the file into the directory + if (d->sfs->disk->header->free_blocks < 2) { + return NULL; + } + int res; - SearchResult *search=SimpleFS_search(d,filename); + SearchResult *search = SimpleFS_search(d, filename); //if the file already exists we return NULL - if(search->result==SUCCESS){ + if (search->result == SUCCESS) { free(search->element); - if(search->last_visited_dir_block!=NULL){ + if (search->last_visited_dir_block != NULL) { free(search->last_visited_dir_block); } free(search); @@ -104,296 +105,297 @@ FileHandle* SimpleFS_createFile(DirectoryHandle* d, const char* filename){ } //we can deallocate the SearchResult because it isn't needed anymore free(search); - FirstFileBlock* file=(FirstFileBlock*) malloc(sizeof(FirstFileBlock)); - //we get a free block from the disk - int file_block=DiskDriver_getFreeBlock(d->sfs->disk,0); - CHECK_ERR(file_block==FAILED,"full disk on file creation"); + FirstFileBlock *file = (FirstFileBlock *) malloc(sizeof(FirstFileBlock)); + //we get a free block from the disk + int file_block = DiskDriver_getFreeBlock(d->sfs->disk, 0); + CHECK_ERR(file_block == FAILED, "full disk on file creation"); // we clear our variable before initializing it - memset(file,0,sizeof(FirstFileBlock)); - //if we get to this point we can create the file - file->header.block_in_file=0; - file->header.next_block=MISSING; - file->header.previous_block=MISSING; - file->next_IndexBlock=MISSING; - file->num_entries=0; - file->fcb.is_dir=FILE; - file->header.block_in_disk=file_block; - file->fcb.directory_block=d->dcb->header.block_in_disk; - strncpy(file->fcb.name,filename,strlen(filename)); - file->fcb.size_in_blocks=0; - file->fcb.size_in_bytes=0; + memset(file, 0, sizeof(FirstFileBlock)); + //if we get to this point we can create the file + file->header.block_in_file = 0; + file->header.next_block = MISSING; + file->header.previous_block = MISSING; + file->next_IndexBlock = MISSING; + file->num_entries = 0; + file->fcb.is_dir = FILE; + file->header.block_in_disk = file_block; + file->fcb.directory_block = d->dcb->header.block_in_disk; + strncpy(file->fcb.name, filename, strlen(filename)); + file->fcb.size_in_blocks = 0; + file->fcb.size_in_bytes = 0; //initializing the entries of the index cointained in the fcb - file->num_entries=0; - memset(file->blocks,MISSING,sizeof(int)*((BLOCK_SIZE-sizeof(FileControlBlock) - sizeof(BlockHeader)-sizeof(int)-sizeof(int))/sizeof(int))); + file->num_entries = 0; + memset(file->blocks, MISSING, sizeof(int) * + ((BLOCK_SIZE - sizeof(FileControlBlock) - sizeof(BlockHeader) - sizeof(int) - + sizeof(int)) / sizeof(int))); - //we create the file on disk - res=DiskDriver_writeBlock(d->sfs->disk,file,file_block); - CHECK_ERR(res==FAILED,"can't write on the given free block"); + //we create the file on disk + res = DiskDriver_writeBlock(d->sfs->disk, file, file_block); + CHECK_ERR(res == FAILED, "can't write on the given free block"); - //we update the metadata into the directory - Dir_addentry(d,file_block); + //we update the metadata into the directory + Dir_addentry(d, file_block); - //after creating the file we create a file handle - FileHandle *fh=(FileHandle*)malloc(sizeof(FileHandle)); + //after creating the file we create a file handle + FileHandle *fh = (FileHandle *) malloc(sizeof(FileHandle)); //the current block in the creation is the header of the fcb - fh->current_block=(BlockHeader*)malloc(sizeof(BlockHeader)); - memcpy(fh->current_block,&(file->header),sizeof(BlockHeader)); + fh->current_block = (BlockHeader *) malloc(sizeof(BlockHeader)); + memcpy(fh->current_block, &(file->header), sizeof(BlockHeader)); //we allocate and initialize the current index block - fh->current_index_block=(BlockHeader*)malloc(sizeof(BlockHeader)); - fh->current_index_block->block_in_disk=file->header.block_in_disk; + fh->current_index_block = (BlockHeader *) malloc(sizeof(BlockHeader)); + fh->current_index_block->block_in_disk = file->header.block_in_disk; //we have 0 beacuse our index is the fcb - fh->current_index_block->block_in_file=0; - fh->current_index_block->next_block=MISSING; - fh->current_index_block->previous_block=MISSING; + fh->current_index_block->block_in_file = 0; + fh->current_index_block->next_block = MISSING; + fh->current_index_block->previous_block = MISSING; //we copy the FirstDirectoryBlock from the DirectoryHandle - fh->directory=(FirstDirectoryBlock*)malloc(sizeof(FirstDirectoryBlock)); - memcpy(fh->directory,d->dcb,sizeof(FirstDirectoryBlock)); - fh->fcb=file; - fh->pos_in_file=0; - fh->sfs=d->sfs; - return fh; + fh->directory = (FirstDirectoryBlock *) malloc(sizeof(FirstDirectoryBlock)); + memcpy(fh->directory, d->dcb, sizeof(FirstDirectoryBlock)); + fh->fcb = file; + fh->pos_in_file = 0; + fh->sfs = d->sfs; + return fh; } // reads in the (preallocated) blocks array, the name of all files in a directory -int SimpleFS_readDir(char** names, DirectoryHandle* d){ - - char isDir[] = " ->is dir\n "; - char isFile[] = " ->is file\n "; - char newLine[] = "\n "; - char str[] = "directory empty\n"; - - int FDB_max_elements=(BLOCK_SIZE-sizeof(BlockHeader)-sizeof(FileControlBlock)-sizeof(int))/sizeof(int); - int Dir_Block_max_elements=(BLOCK_SIZE-sizeof(BlockHeader))/sizeof(int); - int dir_entries=d->dcb->num_entries; - int i, res, pos=0; - - int dim_names = (dir_entries+1)*((25+FILENAME_MAX_LENGTH)*sizeof(char)); - *names = (char*)malloc(dim_names); - memset(*names, 0, dim_names); - - strncpy(*names, d->dcb->fcb.name, strlen(d->dcb->fcb.name)); - strcat(*names, newLine); - - if(dim_names==1*((FILENAME_MAX_LENGTH+25)*sizeof(char))){ - strcat(*names, str); - return SUCCESS; - } - FirstDirectoryBlock* file=(FirstDirectoryBlock*) malloc(sizeof(FirstDirectoryBlock)); - DirectoryBlock* db = (DirectoryBlock*)malloc(sizeof(DirectoryBlock)); - - // We search for all the files in the current directory block - for(i=0;isfs->disk, file, d->dcb->file_blocks[i]); - CHECK_ERR(res==FAILED, "Error read dir block in simplefs_readDir"); - } - else{ +int SimpleFS_readDir(char **names, DirectoryHandle *d) { + + char isDir[] = " ->is dir\n "; + char isFile[] = " ->is file\n "; + char newLine[] = "\n "; + char str[] = "directory empty\n"; + + int FDB_max_elements = (BLOCK_SIZE - sizeof(BlockHeader) - sizeof(FileControlBlock) - sizeof(int)) / sizeof(int); + int Dir_Block_max_elements = (BLOCK_SIZE - sizeof(BlockHeader)) / sizeof(int); + int dir_entries = d->dcb->num_entries; + int i, res, pos = 0; + + size_t dim_names = (dir_entries + 1) * ((25 + FILENAME_MAX_LENGTH) * sizeof(char)); + *names = (char *) malloc(dim_names); + memset(*names, 0, dim_names); + + strncpy(*names, d->dcb->fcb.name, strlen(d->dcb->fcb.name)); + strcat(*names, newLine); + + if (dim_names == 1 * ((FILENAME_MAX_LENGTH + 25) * sizeof(char))) { + strcat(*names, str); + return SUCCESS; + } + FirstDirectoryBlock *file = (FirstDirectoryBlock *) malloc(sizeof(FirstDirectoryBlock)); + DirectoryBlock *db = (DirectoryBlock *) malloc(sizeof(DirectoryBlock)); + + // We search for all the files in the current directory block + for (i = 0; i < dir_entries; i++) { + // We get the file + memset(file, 0, sizeof(FirstDirectoryBlock)); + if (i < FDB_max_elements) { + res = DiskDriver_readBlock(d->sfs->disk, file, d->dcb->file_blocks[i]); + CHECK_ERR(res == FAILED, "Error read dir block in simplefs_readDir"); + } else { // File contenuto nei DB della directory genitore - int logblock=((i-FDB_max_elements)/Dir_Block_max_elements)+1; + int logblock = ((i - FDB_max_elements) / Dir_Block_max_elements) + 1; int j, block = d->dcb->header.next_block; - if(pos!=logblock) memset(db, 0, sizeof(DirectoryBlock)); - for(j=0; jsfs->disk , db, block); - CHECK_ERR(res==FAILED, "Error on read of DirectoryBlock in simpleFS_readDir"); + if (pos != logblock) memset(db, 0, sizeof(DirectoryBlock)); + for (j = 0; j < logblock && pos != logblock; j++) { + res = DiskDriver_readBlock(d->sfs->disk, db, block); + CHECK_ERR(res == FAILED, "Error on read of DirectoryBlock in simpleFS_readDir"); block = db->header.next_block; - pos=j+1; + pos = j + 1; } - res=DiskDriver_readBlock(d->sfs->disk, file, db->file_blocks[(i-FDB_max_elements)%Dir_Block_max_elements]); - CHECK_ERR(res==FAILED, "Error read dir block in simplefs_readDir"); + res = DiskDriver_readBlock(d->sfs->disk, file, db->file_blocks[(i - FDB_max_elements) % Dir_Block_max_elements]); + CHECK_ERR(res == FAILED, "Error read dir block in simplefs_readDir"); } - // Copy data of files of current directory - sprintf((*names)+strlen(*names), "%d", file->fcb.size_in_bytes); - sprintf((*names)+strlen(*names), "%c", ' '); - strncat((*names)+strlen(*names), file->fcb.name, strlen(file->fcb.name)); - int len=strlen(*names); - if(file->fcb.is_dir==DIRECTORY) strncat((*names)+len, isDir, strlen(isDir)); - else strncat((*names)+len, isFile, strlen(isFile)); - } - - memset(*names+strlen(*names)-1, 0,1); - free(file); + // Copy data of files of current directory + sprintf((*names) + strlen(*names), "%d", file->fcb.size_in_bytes); + sprintf((*names) + strlen(*names), "%c", ' '); + strncat((*names) + strlen(*names), file->fcb.name, strlen(file->fcb.name)); + size_t len = strlen(*names); + if (file->fcb.is_dir == DIRECTORY) strncat((*names) + len, isDir, strlen(isDir)); + else strncat((*names) + len, isFile, strlen(isFile)); + } + + memset(*names + strlen(*names) - 1, 0, 1); + free(file); free(db); - return SUCCESS; + return SUCCESS; } // seeks for a directory in d. If dirname is equal to ".." it goes one level up // 0 on success, negative value on error // it does side effect on the provided handle -int SimpleFS_changeDir(DirectoryHandle* d, const char* dirname){ - // Check if passed parameters are valid - if(d == NULL || strlen(dirname)==0) return FAILED; +int SimpleFS_changeDir(DirectoryHandle *d, const char *dirname) { + // Check if passed parameters are valid + if (d == NULL || strlen(dirname) == 0) return FAILED; - int res; + int res; - // Check if the directory where want to move is the current workdir - if(strncmp(".", dirname, strlen(dirname))==0) return SUCCESS; + // Check if the directory where want to move is the current workdir + if (strncmp(".", dirname, strlen(dirname)) == 0) return SUCCESS; - // Check if the directory where want to move is the parent directory - if(strncmp("..", dirname, strlen(dirname))==0){ - // Check if workdir is root dir - if(d->directory==NULL) return SUCCESS; + // Check if the directory where want to move is the parent directory + if (strncmp("..", dirname, strlen(dirname)) == 0) { + // Check if workdir is root dir + if (d->directory == NULL) return SUCCESS; - // We populate the handle according to the content informations - DirectoryHandle* handle=(DirectoryHandle*) malloc(sizeof(DirectoryHandle)); - handle->sfs=d->sfs; - handle->dcb=(FirstDirectoryBlock*)malloc(sizeof(FirstDirectoryBlock)); - memset(handle->dcb,0,sizeof(FirstDirectoryBlock)); + // We populate the handle according to the content informations + DirectoryHandle *handle = (DirectoryHandle *) malloc(sizeof(DirectoryHandle)); + handle->sfs = d->sfs; + handle->dcb = (FirstDirectoryBlock *) malloc(sizeof(FirstDirectoryBlock)); + memset(handle->dcb, 0, sizeof(FirstDirectoryBlock)); - res=DiskDriver_readBlock(d->sfs->disk, handle->dcb, d->directory->header.block_in_disk); - CHECK_ERR(res==FAILED,"Error read parent directory"); + res = DiskDriver_readBlock(d->sfs->disk, handle->dcb, d->directory->header.block_in_disk); + CHECK_ERR(res == FAILED, "Error read parent directory"); - // Check if directory have parent directory - if(d->directory->fcb.directory_block!=MISSING){ - handle->directory = malloc(sizeof(FirstDirectoryBlock)); - memset(handle->directory, 0, sizeof(FirstDirectoryBlock)); - res=DiskDriver_readBlock(d->sfs->disk, handle->directory, d->directory->fcb.directory_block); - CHECK_ERR(res==FAILED,"Error read parent directory"); - } else handle->directory = NULL; + // Check if directory have parent directory + if (d->directory->fcb.directory_block != MISSING) { + handle->directory = malloc(sizeof(FirstDirectoryBlock)); + memset(handle->directory, 0, sizeof(FirstDirectoryBlock)); + res = DiskDriver_readBlock(d->sfs->disk, handle->directory, d->directory->fcb.directory_block); + CHECK_ERR(res == FAILED, "Error read parent directory"); + } else handle->directory = NULL; - free(d->dcb); - if(d->directory!=NULL){ + free(d->dcb); + if (d->directory != NULL) { free(d->directory); } - // Copy the calculated information - d->sfs = handle->sfs; - d->dcb=handle->dcb; - memcpy(d->current_block,&(d->dcb->header),sizeof(BlockHeader)); - d->pos_in_dir=0; - d->pos_in_block=0; - d->directory=handle->directory; + // Copy the calculated information + d->sfs = handle->sfs; + d->dcb = handle->dcb; + memcpy(d->current_block, &(d->dcb->header), sizeof(BlockHeader)); + d->pos_in_dir = 0; + d->pos_in_block = 0; + d->directory = handle->directory; - free(handle); + free(handle); - return SUCCESS; - } + return SUCCESS; + } - SearchResult *search=SimpleFS_search(d, dirname); + SearchResult *search = SimpleFS_search(d, dirname); //if the dir already exists we return FAILED - if(search->result==SUCCESS){ - FirstDirectoryBlock* file = ((FirstDirectoryBlock*)search->element); - - // we populate the handle according to the readed block - DirectoryHandle* handle=(DirectoryHandle*) malloc(sizeof(DirectoryHandle)); - memset(handle, 0, sizeof(DirectoryHandle)); - handle->sfs=d->sfs; - handle->dcb=file; - handle->pos_in_dir=0; - handle->pos_in_block=0; - - // Check if directory have parent directory - if(file->fcb.directory_block!=MISSING){ - handle->directory = malloc(sizeof(FirstDirectoryBlock)); - memset(handle->directory, 0, sizeof(FirstDirectoryBlock)); - res=DiskDriver_readBlock(d->sfs->disk, handle->directory, file->fcb.directory_block); - CHECK_ERR(res==FAILED,"Error read parent directory"); - } - else handle->directory = NULL; - - free(d->dcb); - if(d->directory!=NULL){ + if (search->result == SUCCESS) { + FirstDirectoryBlock *file = ((FirstDirectoryBlock *) search->element); + + // we populate the handle according to the readed block + DirectoryHandle *handle = (DirectoryHandle *) malloc(sizeof(DirectoryHandle)); + memset(handle, 0, sizeof(DirectoryHandle)); + handle->sfs = d->sfs; + handle->dcb = file; + handle->pos_in_dir = 0; + handle->pos_in_block = 0; + + // Check if directory have parent directory + if (file->fcb.directory_block != MISSING) { + handle->directory = malloc(sizeof(FirstDirectoryBlock)); + memset(handle->directory, 0, sizeof(FirstDirectoryBlock)); + res = DiskDriver_readBlock(d->sfs->disk, handle->directory, file->fcb.directory_block); + CHECK_ERR(res == FAILED, "Error read parent directory"); + } else handle->directory = NULL; + + free(d->dcb); + if (d->directory != NULL) { free(d->directory); } - // Copy the calculated information - d->sfs = handle->sfs; - memcpy(d->current_block,&(file->header),sizeof(BlockHeader)); - d->dcb=handle->dcb; - d->pos_in_dir=handle->pos_in_dir; - d->pos_in_block=handle->pos_in_block; - d->directory=handle->directory; + // Copy the calculated information + d->sfs = handle->sfs; + memcpy(d->current_block, &(file->header), sizeof(BlockHeader)); + d->dcb = handle->dcb; + d->pos_in_dir = handle->pos_in_dir; + d->pos_in_block = handle->pos_in_block; + d->directory = handle->directory; - free(handle); - if(search->last_visited_dir_block!=NULL) free(search->last_visited_dir_block); - free(search); + free(handle); + if (search->last_visited_dir_block != NULL) free(search->last_visited_dir_block); + free(search); - return SUCCESS; - }else free(search); + return SUCCESS; + } else free(search); - return FAILED; - } + return FAILED; +} // creates a new directory in the current one (stored in fs->current_directory_block) // 0 on success -1 on error -int SimpleFS_mkDir(DirectoryHandle* d, const char* dirname){ - // Check if passed parameters are valid - if(d == NULL || strlen(dirname)==0) return FAILED; +int SimpleFS_mkDir(DirectoryHandle *d, const char *dirname) { + // Check if passed parameters are valid + if (d == NULL || strlen(dirname) == 0) return FAILED; - SearchResult *search=SimpleFS_search(d, dirname); + SearchResult *search = SimpleFS_search(d, dirname); //if the dir already exists we return FAILED - if(search->result==SUCCESS){ + if (search->result == SUCCESS) { free(search->element); - if(search->last_visited_dir_block!=NULL){ + if (search->last_visited_dir_block != NULL) { free(search->last_visited_dir_block); } - free(search); + free(search); return FAILED; } - free(search); - - // getting the root block - int rootblock=DiskDriver_getFreeBlock(d->sfs->disk,0); - if(rootblock==FAILED) return FAILED; - - // allocating the directory block - FirstDirectoryBlock *root=(FirstDirectoryBlock*)malloc(sizeof(FirstDirectoryBlock)); - //we set all to 0 to avoid clutter when we write the directory on disk - memset(root,0,sizeof(FirstDirectoryBlock)); - - // creating the block header - root->header.previous_block=MISSING; - root->header.next_block=MISSING; - root->header.block_in_file=CONTROL_BLOCK; - - // creating the directory CB - root->fcb.directory_block=d->dcb->header.block_in_disk; - root->header.block_in_disk=rootblock; - strncpy(root->fcb.name, dirname, strlen(dirname)); - root->fcb.size_in_blocks=0; - root->fcb.size_in_bytes=0; - root->fcb.is_dir=DIRECTORY; - - //initializing the entries of the directory - root->num_entries=0; - memset(root->file_blocks,MISSING,((BLOCK_SIZE-sizeof(BlockHeader)-sizeof(FileControlBlock)-sizeof(int))/sizeof(int))*sizeof(int)); - - //we update the parent directory - Dir_addentry(d,root->header.block_in_disk); - int res; - //writing the directory on disk - res=DiskDriver_writeBlock(d->sfs->disk,(void*) root,rootblock); - free(root); - if(res==FAILED) return FAILED; - - res=DiskDriver_writeBlock(d->sfs->disk, d->dcb, d->dcb->header.block_in_disk); - if(res==FAILED) return FAILED; - - return SUCCESS; + free(search); + + // getting the root block + int rootblock = DiskDriver_getFreeBlock(d->sfs->disk, 0); + if (rootblock == FAILED) return FAILED; + + // allocating the directory block + FirstDirectoryBlock *root = (FirstDirectoryBlock *) malloc(sizeof(FirstDirectoryBlock)); + //we set all to 0 to avoid clutter when we write the directory on disk + memset(root, 0, sizeof(FirstDirectoryBlock)); + + // creating the block header + root->header.previous_block = MISSING; + root->header.next_block = MISSING; + root->header.block_in_file = CONTROL_BLOCK; + + // creating the directory CB + root->fcb.directory_block = d->dcb->header.block_in_disk; + root->header.block_in_disk = rootblock; + strncpy(root->fcb.name, dirname, strlen(dirname)); + root->fcb.size_in_blocks = 0; + root->fcb.size_in_bytes = 0; + root->fcb.is_dir = DIRECTORY; + + //initializing the entries of the directory + root->num_entries = 0; + memset(root->file_blocks, MISSING, + ((BLOCK_SIZE - sizeof(BlockHeader) - sizeof(FileControlBlock) - sizeof(int)) / sizeof(int)) * sizeof(int)); + + //we update the parent directory + Dir_addentry(d, root->header.block_in_disk); + int res; + //writing the directory on disk + res = DiskDriver_writeBlock(d->sfs->disk, (void *) root, rootblock); + free(root); + if (res == FAILED) return FAILED; + + res = DiskDriver_writeBlock(d->sfs->disk, d->dcb, d->dcb->header.block_in_disk); + if (res == FAILED) return FAILED; + + return SUCCESS; } // removes the file in the current directory // returns -1 on failure 0 on success // if a directory, it removes recursively all contained files -int SimpleFS_remove(DirectoryHandle* d, const char* filename){ - // Check if passed parameters are valid - if(d == NULL || strlen(filename)==0) return FAILED; +int SimpleFS_remove(DirectoryHandle *d, const char *filename) { + // Check if passed parameters are valid + if (d == NULL || strlen(filename) == 0) return FAILED; - int FDB_max_elements=(BLOCK_SIZE-sizeof(BlockHeader)-sizeof(FileControlBlock)-sizeof(int))/sizeof(int); - int Dir_Block_max_elements=(BLOCK_SIZE-sizeof(BlockHeader))/sizeof(int); - int dir_entries=d->dcb->num_entries; - int i, res; + int FDB_max_elements = (BLOCK_SIZE - sizeof(BlockHeader) - sizeof(FileControlBlock) - sizeof(int)) / sizeof(int); + int Dir_Block_max_elements = (BLOCK_SIZE - sizeof(BlockHeader)) / sizeof(int); + int dir_entries = d->dcb->num_entries; + int i, res; - if(dir_entries==0) return SUCCESS; + if (dir_entries == 0) return SUCCESS; // Chiamare search - SearchResult* sRes = SimpleFS_search(d, filename); - if(sRes->result==FAILED){ - if(sRes->last_visited_dir_block!=NULL){ + SearchResult *sRes = SimpleFS_search(d, filename); + if (sRes->result == FAILED) { + if (sRes->last_visited_dir_block != NULL) { free(sRes->last_visited_dir_block); } free(sRes); @@ -401,139 +403,156 @@ int SimpleFS_remove(DirectoryHandle* d, const char* filename){ } // Check if the target file is a directory - if(sRes->type==DIRECTORY){ - FirstDirectoryBlock* file=(FirstDirectoryBlock*)sRes->element; + if (sRes->type == DIRECTORY) { + FirstDirectoryBlock *file = (FirstDirectoryBlock *) sRes->element; // We populate the handle according to the content informations - DirectoryHandle* handle=(DirectoryHandle*) malloc(sizeof(DirectoryHandle)); + DirectoryHandle *handle = (DirectoryHandle *) malloc(sizeof(DirectoryHandle)); memset(handle, 0, sizeof(DirectoryHandle)); - handle->sfs=d->sfs; - handle->current_block=malloc(sizeof(BlockHeader)); - memcpy(handle->current_block,&(file->header),sizeof(BlockHeader)); - handle->dcb=file; + handle->sfs = d->sfs; + handle->current_block = malloc(sizeof(BlockHeader)); + memcpy(handle->current_block, &(file->header), sizeof(BlockHeader)); + handle->dcb = file; handle->directory = d->dcb; - handle->pos_in_dir=0; - handle->pos_in_block=0; + handle->pos_in_dir = 0; + handle->pos_in_block = 0; - // search eventuall child dir - res=SimpleFS_remove_rec(handle); - if(res==FAILED){ + // search eventual child dir + res = SimpleFS_remove_rec(handle); + if (res == FAILED) { free(file); free(handle->current_block); free(handle); - if(sRes->last_visited_dir_block!=NULL){ + if (sRes->last_visited_dir_block != NULL) { free(sRes->last_visited_dir_block); } free(sRes); return FAILED; } - - // Remove the files contained in the directory - DirectoryBlock* db = (DirectoryBlock*)malloc(sizeof(DirectoryBlock)); - FirstFileBlock* fh = (FirstFileBlock*)malloc(sizeof(FirstFileBlock)); - int z, pos=0; - - for(z=0; zdcb->num_entries; z++){ - if(z < FDB_max_elements){ - res=DiskDriver_readBlock(handle->sfs->disk, fh, handle->dcb->file_blocks[z]); - CHECK_ERR(res==FAILED, "Error read dir block in simplefs_remove"); - if(fh->fcb.is_dir==FILE) SimpleFS_removeFileOnDir(handle, (void*)fh, z); + // we fill the hole created by the removed directory + if (sRes->last_visited_dir_block == NULL) { + //if the last visited dirblock is NULL we are in the FDB + // we get the last element in the dir block and move it in place of the removed directory + for (i = sRes->pos_in_block; i < FDB_max_elements && handle->dcb->file_blocks[i] != MISSING; i++); + if (i - 1 > sRes->pos_in_block) { + handle->dcb->file_blocks[sRes->pos_in_block] = handle->dcb->file_blocks[i - 1]; + handle->dcb->file_blocks[i - 1] = MISSING; + } else { + handle->dcb->file_blocks[sRes->pos_in_block] = MISSING; + } + } else { + // we need to get in the last directory block to move the last entry in that block in place of the removed + // directory + memcpy(handle->current_block, &(sRes->last_visited_dir_block->header), sizeof(BlockHeader)); + DirectoryBlock *db = (DirectoryBlock *) malloc(sizeof(DirectoryBlock)); + res = DiskDriver_readBlock(handle->sfs->disk, db, sRes->dir_block_in_disk); + CHECK_ERR(res == FAILED, "can't read the last visited block") + while (handle->current_block->next_block != MISSING) { + res = DiskDriver_readBlock(handle->sfs->disk, db, handle->current_block->next_block); + CHECK_ERR(res == FAILED, "can't read the db") + memcpy(handle->current_block, &(db->header), sizeof(BlockHeader)); } - else{ - // File contenuto nei DB della directory genitore - int logblock=((z-FDB_max_elements)/Dir_Block_max_elements)+1; - int block = handle->dcb->header.next_block; - for(i=0; isfs->disk , db, block); - CHECK_ERR(res==FAILED, "Error on read of DirectoryBlock in simpleFS_remove"); - block = db->header.next_block; - pos=i+1; + // we get the last element in the last block + for (i = 0; i < Dir_Block_max_elements && db->file_blocks[i] != MISSING; i++); + if (db->header.block_in_disk == sRes->dir_block_in_disk) { + // if the last block visited is the last block in the directory we fill the hole only in this block + if (i - 1 > sRes->pos_in_block) { + db->file_blocks[sRes->pos_in_block] = db->file_blocks[i - 1]; + db->file_blocks[i - 1] = MISSING; + } else { + db->file_blocks[sRes->pos_in_block] = MISSING; } - res=DiskDriver_readBlock(handle->sfs->disk, fh, db->file_blocks[(z-FDB_max_elements)%Dir_Block_max_elements]); - CHECK_ERR(res==FAILED, "Error read dir block in simplefs_remove"); - if(fh->fcb.is_dir==FILE) SimpleFS_removeFileOnDir(handle, (void*)fh, z); + res = DiskDriver_writeBlock(handle->sfs->disk, db, db->header.block_in_disk); + CHECK_ERR(res == FAILED, "can't write the updated block"); + } else { + sRes->last_visited_dir_block->file_blocks[sRes->pos_in_block] = db->file_blocks[i - 1]; + res = DiskDriver_writeBlock(handle->sfs->disk, sRes->last_visited_dir_block, sRes->dir_block_in_disk); + CHECK_ERR(res == FAILED, "can't write the updated block"); } + //we check if we must deallocate the last directory block + if (db->file_blocks[0] == MISSING) { + // we deallocate the last block + res = DiskDriver_getFreeBlock(handle->sfs->disk, db->header.block_in_disk); + CHECK_ERR(res == FAILED, "can't free the last db") + res = DiskDriver_readBlock(handle->sfs->disk, db, handle->current_block->previous_block); + CHECK_ERR(res == FAILED, "can't read the previous db") + memcpy(handle->current_block, &(db->header), sizeof(BlockHeader)); + db->header.next_block = MISSING; + res = DiskDriver_writeBlock(handle->sfs->disk, db, db->header.block_in_disk); + CHECK_ERR(res == FAILED, "can't write the updated block"); + } + free(db); } - free(fh); - free(db); - // Remove that the directory in the parent directory - res=SimpleFS_removeChildDir(handle); - CHECK_ERR(res==FAILED, "Error in remove a child dir"); free(handle->current_block); free(handle); free(file); - if(sRes->last_visited_dir_block!=NULL){ + if (sRes->last_visited_dir_block != NULL) { free(sRes->last_visited_dir_block); } free(sRes); + d->dcb->num_entries--; // We write the updated FirstDirectoryBlock - res=DiskDriver_writeBlock(d->sfs->disk, d->dcb, d->dcb->header.block_in_disk); - if(res==FAILED) return FAILED; + res = DiskDriver_writeBlock(d->sfs->disk, d->dcb, d->dcb->header.block_in_disk); + if (res == FAILED) return FAILED; return SUCCESS; - }else{ + } else { // Elimino il file dalla directory in cui risiede SimpleFS_removeFileOnDir(d, sRes->element, sRes->pos_in_block); free(sRes->element); - if(sRes->last_visited_dir_block!=NULL){ + if (sRes->last_visited_dir_block != NULL) { free(sRes->last_visited_dir_block); } free(sRes); return SUCCESS; } - free(sRes->element); - if(sRes->last_visited_dir_block!=NULL){ - free(sRes->last_visited_dir_block); - } - free(sRes); - return FAILED; } -FileHandle* SimpleFS_openFile(DirectoryHandle* d, const char* filename){ +FileHandle *SimpleFS_openFile(DirectoryHandle *d, const char *filename) { //we check that we have been given valid data - if(d==NULL || strlen(filename)==0){ + if (d == NULL || strlen(filename) == 0) { return NULL; } //firstly we need to search the file we want to open - SearchResult *search=SimpleFS_search(d,filename); - if(search->result==FAILED){ - if(search->last_visited_dir_block!=NULL){ + SearchResult *search = SimpleFS_search(d, filename); + if (search->result == FAILED) { + if (search->last_visited_dir_block != NULL) { free(search->last_visited_dir_block); } free(search); return NULL; } //we create our handle - FileHandle *file=(FileHandle*)malloc(sizeof(FileHandle)); - file->fcb=(FirstFileBlock*)search->element; - file->pos_in_file=0; - file->sfs=d->sfs; - file->directory=(FirstDirectoryBlock*)malloc(sizeof(FirstDirectoryBlock)); - memcpy(file->directory,d->dcb,sizeof(FirstDirectoryBlock)); + FileHandle *file = (FileHandle *) malloc(sizeof(FileHandle)); + file->fcb = (FirstFileBlock *) search->element; + file->pos_in_file = 0; + file->sfs = d->sfs; + file->directory = (FirstDirectoryBlock *) malloc(sizeof(FirstDirectoryBlock)); + memcpy(file->directory, d->dcb, sizeof(FirstDirectoryBlock)); //the current block in the creation is the header of the fcb - file->current_block=(BlockHeader*)malloc(sizeof(BlockHeader)); - memcpy(file->current_block,&(((FirstFileBlock*)search->element)->header),sizeof(BlockHeader)); + file->current_block = (BlockHeader *) malloc(sizeof(BlockHeader)); + memcpy(file->current_block, &(((FirstFileBlock *) search->element)->header), sizeof(BlockHeader)); //we allocate and initialize the current index block - file->current_index_block=(BlockHeader*)malloc(sizeof(BlockHeader)); - file->current_index_block->block_in_disk=file->fcb->header.block_in_disk; + file->current_index_block = (BlockHeader *) malloc(sizeof(BlockHeader)); + file->current_index_block->block_in_disk = file->fcb->header.block_in_disk; //we have 0 beacuse our index is the fcb - file->current_index_block->block_in_file=0; - file->current_index_block->next_block=file->fcb->next_IndexBlock; - file->current_index_block->previous_block=MISSING; + file->current_index_block->block_in_file = 0; + file->current_index_block->next_block = file->fcb->next_IndexBlock; + file->current_index_block->previous_block = MISSING; // we cleanup the result of our search - if(search->last_visited_dir_block!=NULL){ + if (search->last_visited_dir_block != NULL) { free(search->last_visited_dir_block); } free(search); return file; } -void SimpleFS_close(FileHandle* f){ +void SimpleFS_close(FileHandle *f) { //we check that we have been given valid data - if(f==NULL){ + if (f == NULL) { return; } @@ -550,32 +569,32 @@ void SimpleFS_close(FileHandle* f){ } // returns pos on success -1 on error (file too short) -int SimpleFS_seek(FileHandle* f, int pos){ +int SimpleFS_seek(FileHandle *f, int pos) { //we check if the position is within the file dimension - if(f==NULL || pos<0 ||pos>f->fcb->fcb.size_in_bytes){ + if (f == NULL || pos < 0 || pos > f->fcb->fcb.size_in_bytes) { return FAILED; } //we calculate the block in which we need to move - int DB_max_elements=BLOCK_SIZE-sizeof(BlockHeader); - int block_in_file=(pos+DB_max_elements-1)/DB_max_elements; + int DB_max_elements = BLOCK_SIZE - sizeof(BlockHeader); + int block_in_file = (pos + DB_max_elements - 1) / DB_max_elements; int res; //we check if the block we need exists by checking on the index - int pos_in_disk=SimpleFS_getIndex(f,block_in_file); - if(pos_in_disk==FAILED){ + int pos_in_disk = SimpleFS_getIndex(f, block_in_file); + if (pos_in_disk == FAILED) { //the block doesn't exists return FAILED; - }else{ + } else { //we update the cursor position in the file - f->pos_in_file=pos; + f->pos_in_file = pos; //we read the block to get the BlockHeader - FileBlock* block=(FileBlock*)malloc(sizeof(FileBlock)); - res=DiskDriver_readBlock(f->sfs->disk,block,pos_in_disk); - if(res==FAILED){ + FileBlock *block = (FileBlock *) malloc(sizeof(FileBlock)); + res = DiskDriver_readBlock(f->sfs->disk, block, pos_in_disk); + if (res == FAILED) { free(block); - CHECK_ERR(res==FAILED,"can't read block while seeking"); + CHECK_ERR(res == FAILED, "can't read block while seeking"); } //we copy the BlockHeader in the current_block - memcpy(f->current_block,&(block->header),sizeof(BlockHeader)); + memcpy(f->current_block, &(block->header), sizeof(BlockHeader)); free(block); return pos; } @@ -585,16 +604,16 @@ int SimpleFS_seek(FileHandle* f, int pos){ // overwriting and allocating new space if necessary // returns the number of bytes written //the cursor at the end of the write points to the last byte written -int SimpleFS_write(FileHandle* f, void* data, int size){ +int SimpleFS_write(FileHandle *f, void *data, int size) { //we check that we have been given valid data - if(f==NULL || data==NULL || size<=0){ + if (f == NULL || data == NULL || size <= 0) { return 0; } //we calculate how many byte can fill a data block - int DB_max_elements=BLOCK_SIZE-sizeof(BlockHeader); - int bytes_written=0; + int DB_max_elements = BLOCK_SIZE - sizeof(BlockHeader); + int bytes_written = 0; //we calculate how many blocks we need to write - int blocks_needed=(size+DB_max_elements-1)/DB_max_elements; + int blocks_needed = (size + DB_max_elements - 1) / DB_max_elements; /* current position is stored in FileHandle as pos_in_file, * but we need to express it using current_block @@ -602,109 +621,105 @@ int SimpleFS_write(FileHandle* f, void* data, int size){ */ int displacement; //that's the result of our last write - int res=SUCCESS; + int res = SUCCESS; // this is the last block written or the fcb if we write in a blank file, - void* last_block=malloc(BLOCK_SIZE); - FileBlock* block=(FileBlock*)malloc(sizeof(FileBlock)); + void *last_block = malloc(BLOCK_SIZE); + FileBlock *block = (FileBlock *) malloc(sizeof(FileBlock)); //we must write on the current block first, but it could be the fcb - int current_block_written=0; + int current_block_written = 0; // we must check if there is a block after the current block of data to ber overwritten - int overwrite=1; + int overwrite = 1; //we check if the current block is the fcb or if the last block is full - if(f->current_block->block_in_file==0){ - current_block_written=1; - overwrite=0; + if (f->current_block->block_in_file == 0) { + current_block_written = 1; + overwrite = 0; //we initialize the last block to be able to link the FFB to the next data block - memcpy(last_block,f->fcb,BLOCK_SIZE); - }else if(f->pos_in_file==f->fcb->fcb.size_in_blocks*DB_max_elements){ - overwrite=0; - current_block_written=1; - res=DiskDriver_readBlock(f->sfs->disk,last_block,f->current_block->block_in_disk); - CHECK_ERR(res==FAILED,"can't read the current block"); + memcpy(last_block, f->fcb, BLOCK_SIZE); + } else if (f->pos_in_file == f->fcb->fcb.size_in_blocks * DB_max_elements) { + overwrite = 0; + current_block_written = 1; + res = DiskDriver_readBlock(f->sfs->disk, last_block, f->current_block->block_in_disk); + CHECK_ERR(res == FAILED, "can't read the current block"); } //we set the current size of the file and the position in the file accordin to the current block - f->fcb->fcb.size_in_blocks=(f->current_block->block_in_file>0)?f->current_block->block_in_file-1:0; - f->fcb->fcb.size_in_bytes=f->pos_in_file; + f->fcb->fcb.size_in_blocks = (f->current_block->block_in_file > 0) ? f->current_block->block_in_file - 1 : 0; + f->fcb->fcb.size_in_bytes = f->pos_in_file; - while(blocks_needed>0 && res!=FAILED){ + while (blocks_needed > 0 && res != FAILED) { //we clear our block in memory to avoid writing clutter on disk - memset(block,0,sizeof(FileBlock)); - if(current_block_written && !overwrite){ + memset(block, 0, sizeof(FileBlock)); + if (current_block_written && !overwrite) { //in this case we are writing at the beginning of the file //or need a new block to keep writing - res=DiskDriver_getFreeBlock(f->sfs->disk,f->current_block->block_in_disk); - if(res!=FAILED){ + res = DiskDriver_getFreeBlock(f->sfs->disk, f->current_block->block_in_disk); + if (res != FAILED) { //we initialize the new block - block->header.block_in_disk=res; - block->header.next_block=MISSING; - block->header.previous_block=f->current_block->block_in_disk; - block->header.block_in_file=f->current_block->block_in_file+1; + block->header.block_in_disk = res; + block->header.next_block = MISSING; + block->header.previous_block = f->current_block->block_in_disk; + block->header.block_in_file = f->current_block->block_in_file + 1; //we update the last written block - ((FileBlock*)last_block)->header.next_block=block->header.block_in_disk; + ((FileBlock *) last_block)->header.next_block = block->header.block_in_disk; //if the block is the ffb we update our in memory copy - if(f->current_block->block_in_file==0){ - f->fcb->header.next_block=block->header.block_in_disk; + if (f->current_block->block_in_file == 0) { + f->fcb->header.next_block = block->header.block_in_disk; } //we write the changes on the disk - res=DiskDriver_writeBlock(f->sfs->disk,last_block,((FileBlock*)last_block)->header.block_in_disk); + res = DiskDriver_writeBlock(f->sfs->disk, last_block, ((FileBlock *) last_block)->header.block_in_disk); //we update our current_block - memcpy(f->current_block,&(block->header),sizeof(BlockHeader)); - - //when allocating a new block our displacement is 0 - displacement=0; - + memcpy(f->current_block, &(block->header), sizeof(BlockHeader)); } - }else{ + } else { //if we get here we only need to load the block from disk - if(current_block_written && overwrite){ - res=DiskDriver_readBlock(f->sfs->disk,block,f->current_block->next_block); + if (current_block_written) { + res = DiskDriver_readBlock(f->sfs->disk, block, f->current_block->next_block); //we update our current_block - memcpy(f->current_block,&(block->header),sizeof(BlockHeader)); - }else{ - res=DiskDriver_readBlock(f->sfs->disk,block,f->current_block->block_in_disk); + memcpy(f->current_block, &(block->header), sizeof(BlockHeader)); + } else { + res = DiskDriver_readBlock(f->sfs->disk, block, f->current_block->block_in_disk); } } - if(overwrite==0 && current_block_written==1){ - displacement=0; - }else{ - displacement=(f->pos_in_file-DB_max_elements*(f->current_block->block_in_file-1)+bytes_written); + if (overwrite == 0 && current_block_written == 1) { + displacement = 0; + } else { + displacement = (f->pos_in_file - DB_max_elements * (f->current_block->block_in_file - 1) + bytes_written); } //now we need to write in the block - if(res!=FAILED){ - if(size-bytes_written>DB_max_elements-displacement){ + if (res != FAILED) { + if (size - bytes_written > DB_max_elements - displacement) { //we fill the block if we need to write more than one block - memcpy(block->data+displacement,data+bytes_written,DB_max_elements-displacement); - }else{ + memcpy(block->data + displacement, data + bytes_written, (size_t) DB_max_elements - displacement); + } else { //or we write only one portion of the block - memcpy(block->data+displacement,data+bytes_written,size-bytes_written); + memcpy(block->data + displacement, data + bytes_written, (size_t) size - bytes_written); } //if we have finished writing and we are overwriting blocks we break the chain - if(overwrite && blocks_needed-1==0){ - block->header.next_block=MISSING; + if (overwrite && blocks_needed - 1 == 0) { + block->header.next_block = MISSING; } //we write the block on disk - res=DiskDriver_writeBlock(f->sfs->disk,block,block->header.block_in_disk); + res = DiskDriver_writeBlock(f->sfs->disk, block, block->header.block_in_disk); //and if we allocated a new block we add it to the indexes - if(current_block_written && !overwrite && res!=FAILED){ - res=SimpleFS_addIndex(f,block->header.block_in_disk); + if (current_block_written && !overwrite && res != FAILED) { + res = SimpleFS_addIndex(f, block->header.block_in_disk); } //and we indicate that our current block has been written - current_block_written=1; + current_block_written = 1; //check if we need to overwrite the next blocks or allcocate them - if(f->current_block->next_block!=MISSING){ - overwrite=1; - }else{ - overwrite=0; + if (f->current_block->next_block != MISSING) { + overwrite = 1; + } else { + overwrite = 0; } //we update the cursor and the bytes written - if(res!=FAILED){ - if(size-bytes_written>DB_max_elements-displacement){ - bytes_written+=DB_max_elements-displacement; - }else{ - bytes_written+=size-bytes_written; + if (res != FAILED) { + if (size - bytes_written > DB_max_elements - displacement) { + bytes_written += DB_max_elements - displacement; + } else { + bytes_written += size - bytes_written; } //we update the size in blocks of the file f->fcb->fcb.size_in_blocks++; @@ -712,20 +727,20 @@ int SimpleFS_write(FileHandle* f, void* data, int size){ } } //we copy our current block in the last block, so we can link the next block if needed - memcpy(last_block,block,sizeof(FileBlock)); + memcpy(last_block, block, sizeof(FileBlock)); } - f->fcb->fcb.size_in_bytes+=bytes_written; - f->pos_in_file+=bytes_written; + f->fcb->fcb.size_in_bytes += bytes_written; + f->pos_in_file += bytes_written; //we remove the blocks after the actual block from the indexes and free them - if(f->current_block->next_block!=MISSING){ - SimpleFS_clearIndexes(f,block->header.block_in_file+1); - f->current_block->next_block=MISSING; + if (f->current_block->next_block != MISSING) { + SimpleFS_clearIndexes(f, block->header.block_in_file + 1); + f->current_block->next_block = MISSING; } //we write the changes on our Fcb - res=DiskDriver_writeBlock(f->sfs->disk,f->fcb,f->fcb->header.block_in_disk); - CHECK_ERR(res==FAILED,"can't write the chenges of the fcb"); + res = DiskDriver_writeBlock(f->sfs->disk, f->fcb, f->fcb->header.block_in_disk); + CHECK_ERR(res == FAILED, "can't write the chenges of the fcb"); free(block); free(last_block); return bytes_written; @@ -733,59 +748,57 @@ int SimpleFS_write(FileHandle* f, void* data, int size){ // reads in the file, at current position size bytes and stores them in data // returns the number of bytes read -int SimpleFS_read(FileHandle* f, void* data, int size){ +int SimpleFS_read(FileHandle *f, void *data, int size) { //we check that we have been given valid data - if(f==NULL || data==NULL || size<=0){ + if (f == NULL || data == NULL || size <= 0) { return 0; } - int bytes_read=0; - //we calcualte the bytes to read, which are the minimum between the size of the buffer and the size of the file - int bytes_to_read=((sizefcb->fcb.size_in_bytes-f->pos_in_file)?size:f->fcb->fcb.size_in_bytes-f->pos_in_file); - FileBlock *block=(FileBlock*)malloc(sizeof(FileBlock)); + int bytes_read = 0; + //we calculate the bytes to read, which are the minimum between the size of the buffer and the size of the file + int bytes_to_read = ((size < f->fcb->fcb.size_in_bytes - f->pos_in_file) ? size : f->fcb->fcb.size_in_bytes - + f->pos_in_file); + FileBlock *block = (FileBlock *) malloc(sizeof(FileBlock)); //we calculate the maximum number of elements in athe block - int DB_max_elements=BLOCK_SIZE-sizeof(BlockHeader); - //we calculate thedisplacement in the first block; + int DB_max_elements = BLOCK_SIZE - sizeof(BlockHeader); + //we calculate the displacement in the first block; int displacement; - int res=SUCCESS; + int res = SUCCESS; //now we start reading - while(bytes_readpos_in_file-DB_max_elements*(f->current_block->block_in_file-1)+bytes_read); - + while (bytes_read < bytes_to_read && res == SUCCESS) { + displacement = (f->pos_in_file - DB_max_elements * (f->current_block->block_in_file - 1) + bytes_read); //we clean our block in memory - memset(block,0,sizeof(FileBlock)); + memset(block, 0, sizeof(FileBlock)); // we read the current block - res=DiskDriver_readBlock(f->sfs->disk,block,f->current_block->block_in_disk); + res = DiskDriver_readBlock(f->sfs->disk, block, f->current_block->block_in_disk); //now we can read the data - if(bytes_to_read-bytes_read>DB_max_elements-displacement && res==SUCCESS){ + if (bytes_to_read - bytes_read > DB_max_elements - displacement && res == SUCCESS) { //we read all the block - memcpy(data+bytes_read,(block->data)+displacement,DB_max_elements-displacement); + memcpy(data + bytes_read, (block->data) + displacement, (size_t) DB_max_elements - displacement); //we update the number of bytes read - bytes_read+=DB_max_elements-displacement; - }else{ + bytes_read += DB_max_elements - displacement; + } else { //we read only one portion of the block - memcpy(data+bytes_read,block->data+displacement,bytes_to_read-bytes_read); + memcpy(data + bytes_read, block->data + displacement, (size_t) bytes_to_read - bytes_read); //we update the number of bytes read - bytes_read+=bytes_to_read-bytes_read; + bytes_read += bytes_to_read - bytes_read; } - - if(bytes_readcurrent_block->next_block==MISSING){ + if (f->current_block->next_block == MISSING) { //if the next block is missing we can't read further free(block); - f->pos_in_file+=bytes_read; + f->pos_in_file += bytes_read; return bytes_read; } - res=DiskDriver_readBlock(f->sfs->disk,block,f->current_block->next_block); - if(res!=FAILED){ + res = DiskDriver_readBlock(f->sfs->disk, block, f->current_block->next_block); + if (res != FAILED) { //we fetch the next_block - memcpy(f->current_block,block,sizeof(BlockHeader)); + memcpy(f->current_block, block, sizeof(BlockHeader)); } } } - //we update our position in the file - f->pos_in_file+=bytes_read; + f->pos_in_file += bytes_read; free(block); return bytes_read; } diff --git a/simplefs.h b/simplefs.h index e0fdee0..3017ef0 100755 --- a/simplefs.h +++ b/simplefs.h @@ -1,4 +1,5 @@ #pragma once + #include "bitmap.h" #include "disk_driver.h" #include "common.h" @@ -9,20 +10,20 @@ // header, occupies the first portion of each block in the disk // represents a chained list of blocks typedef struct _BlockHeader { - int previous_block; // chained list (previous block) - int next_block; // chained list (next_block) - int block_in_file; // position in the file, if 0 we have a file control block - int block_in_disk; // repeated position of the block on the disk + int previous_block; // chained list (previous block) + int next_block; // chained list (next_block) + int block_in_file; // position in the file, if 0 we have a file control block + int block_in_disk; // repeated position of the block on the disk } BlockHeader; // this is in the first block of a chain, after the header -typedef struct _FileControlBlock{ - int directory_block; // first block of the parent directory - char name[FILENAME_MAX_LENGTH]; - int size_in_bytes; - int size_in_blocks; - int is_dir; // 0 for file, 1 for dir +typedef struct _FileControlBlock { + int directory_block; // first block of the parent directory + char name[FILENAME_MAX_LENGTH]; + int size_in_bytes; + int size_in_blocks; + int is_dir; // 0 for file, 1 for dir } FileControlBlock; /******************* stuff on disk BEGIN *******************/ @@ -30,17 +31,17 @@ typedef struct _FileControlBlock{ // it has a header // an FCB storing file infos // and can contain some indexes -typedef struct _FirstFileBlock{ - BlockHeader header; - FileControlBlock fcb; - int num_entries; - int next_IndexBlock; - int blocks[(BLOCK_SIZE-sizeof(FileControlBlock) - sizeof(BlockHeader)-sizeof(int)-sizeof(int))/sizeof(int)] ; +typedef struct _FirstFileBlock { + BlockHeader header; + FileControlBlock fcb; + int num_entries; + int next_IndexBlock; + int blocks[(BLOCK_SIZE - sizeof(FileControlBlock) - sizeof(BlockHeader) - sizeof(int) - sizeof(int)) / sizeof(int)]; } FirstFileBlock; -typedef struct _Index{ - BlockHeader header; - int indexes[(BLOCK_SIZE-sizeof(BlockHeader))/sizeof(int)]; +typedef struct _Index { + BlockHeader header; + int indexes[(BLOCK_SIZE - sizeof(BlockHeader)) / sizeof(int)]; } Index; // int nextIndex; @@ -58,116 +59,116 @@ typedef struct _Index{ } BlockHeader; */ // this is one of the next physical blocks of a file -typedef struct _FileBlock{ - BlockHeader header; - char data[BLOCK_SIZE-sizeof(BlockHeader)]; +typedef struct _FileBlock { + BlockHeader header; + char data[BLOCK_SIZE - sizeof(BlockHeader)]; } FileBlock; // this is the first physical block of a directory -typedef struct _FirstDirectoryBlock{ - BlockHeader header; - FileControlBlock fcb; - int num_entries; - int file_blocks[ (BLOCK_SIZE - -sizeof(BlockHeader) - -sizeof(FileControlBlock) - -sizeof(int))/sizeof(int) ]; +typedef struct _FirstDirectoryBlock { + BlockHeader header; + FileControlBlock fcb; + int num_entries; + int file_blocks[(BLOCK_SIZE + - sizeof(BlockHeader) + - sizeof(FileControlBlock) + - sizeof(int)) / sizeof(int)]; } FirstDirectoryBlock; // this is remainder block of a directory -typedef struct _DirectoryBlock{ - BlockHeader header; - int file_blocks[ (BLOCK_SIZE-sizeof(BlockHeader))/sizeof(int) ]; +typedef struct _DirectoryBlock { + BlockHeader header; + int file_blocks[(BLOCK_SIZE - sizeof(BlockHeader)) / sizeof(int)]; } DirectoryBlock; /******************* stuff on disk END *******************/ -typedef struct _SimpleFS{ - DiskDriver* disk; - int block_num; - char* filename; +typedef struct _SimpleFS { + DiskDriver *disk; + int block_num; + char *filename; } SimpleFS; // this is a file handle, used to refer to open files -typedef struct _FileHandle{ - SimpleFS* sfs; // pointer to memory file system structure - FirstFileBlock* fcb; // pointer to the first block of the file(read it) - FirstDirectoryBlock* directory; // pointer to the directory where the file is stored - BlockHeader* current_block; // current block in the file - BlockHeader* current_index_block; // current block in the where the current block is saved - int pos_in_file; // position of the cursor +typedef struct _FileHandle { + SimpleFS *sfs; // pointer to memory file system structure + FirstFileBlock *fcb; // pointer to the first block of the file(read it) + FirstDirectoryBlock *directory; // pointer to the directory where the file is stored + BlockHeader *current_block; // current block in the file + BlockHeader *current_index_block; // current block in the where the current block is saved + int pos_in_file; // position of the cursor } FileHandle; -typedef struct _DirectoryHandle{ - SimpleFS* sfs; // pointer to memory file system structure - FirstDirectoryBlock* dcb; // pointer to the first block of the directory(read it) - FirstDirectoryBlock* directory; // pointer to the parent directory (null if top level) - BlockHeader* current_block; // current block in the directory - int pos_in_dir; // absolute position of the cursor in the directory - int pos_in_block; // relative position of the cursor in the block +typedef struct _DirectoryHandle { + SimpleFS *sfs; // pointer to memory file system structure + FirstDirectoryBlock *dcb; // pointer to the first block of the directory(read it) + FirstDirectoryBlock *directory; // pointer to the parent directory (null if top level) + BlockHeader *current_block; // current block in the directory + int pos_in_dir; // absolute position of the cursor in the directory + int pos_in_block; // relative position of the cursor in the block } DirectoryHandle; //result of a search operation in a given directory //the file or directory blocks, if missing are NULLs -typedef struct _SearchResult{ +typedef struct _SearchResult { int result; //SUCCESS or FAILED int type; // 0->file 1->directory int dir_block_in_disk; //block on disk containing the last visited directory block; int pos_in_block; //position of the result in the visited block - void* element; //the found element which will need to be casted according to the type of element + void *element; //the found element which will need to be casted according to the type of element DirectoryBlock *last_visited_dir_block; //if we need to add block to this directory if it's NULL we are in the dcb -}SearchResult; +} SearchResult; // initializes a file system on an already made disk // returns a handle to the top level directory stored in the first block -DirectoryHandle* SimpleFS_init(SimpleFS* fs, DiskDriver* disk); +DirectoryHandle *SimpleFS_init(SimpleFS *fs, DiskDriver *disk); // creates the inital structures, the top level directory // has name "/" and its control block is in the first position // it also clears the bitmap of occupied blocks on the disk // the current_directory_block is cached in the SimpleFS struct // and set to the top level directory -void SimpleFS_format(SimpleFS* fs); +void SimpleFS_format(SimpleFS *fs); // creates an empty file in the directory d // returns null on error (file existing, no free blocks) // an empty file consists only of a block of type FirstBlock -FileHandle* SimpleFS_createFile(DirectoryHandle* d, const char* filename); +FileHandle *SimpleFS_createFile(DirectoryHandle *d, const char *filename); // reads in the (preallocated) blocks array, the name of all files in a directory -int SimpleFS_readDir(char** names, DirectoryHandle* d); +int SimpleFS_readDir(char **names, DirectoryHandle *d); // opens a file in the directory d. The file should be exisiting -FileHandle* SimpleFS_openFile(DirectoryHandle* d, const char* filename); +FileHandle *SimpleFS_openFile(DirectoryHandle *d, const char *filename); // closes a file handle (destroyes it) -void SimpleFS_close(FileHandle* f); +void SimpleFS_close(FileHandle *f); // writes in the file, at current position for size bytes stored in data // overwriting and allocating new space if necessary // returns the number of bytes written -int SimpleFS_write(FileHandle* f, void* data, int size); +int SimpleFS_write(FileHandle *f, void *data, int size); // reads in the file, at current position size bytes stored in data // overwriting and allocating new space if necessary // returns the number of bytes read -int SimpleFS_read(FileHandle* f, void* data, int size); +int SimpleFS_read(FileHandle *f, void *data, int size); // returns the number of bytes read (moving the current pointer to pos) // returns pos on success -1 on error (file too short) -int SimpleFS_seek(FileHandle* f, int pos); +int SimpleFS_seek(FileHandle *f, int pos); // seeks for a directory in d. If dirname is equal to ".." it goes one level up // 0 on success, negative value on error // it does side effect on the provided handle - int SimpleFS_changeDir(DirectoryHandle* d, const char* dirname); +int SimpleFS_changeDir(DirectoryHandle *d, const char *dirname); // creates a new directory in the current one (stored in fs->current_directory_block) // 0 on success -1 on error -int SimpleFS_mkDir(DirectoryHandle* d, const char* dirname); +int SimpleFS_mkDir(DirectoryHandle *d, const char *dirname); // removes the file in the current directory // returns -1 on failure 0 on success // if a directory, it removes recursively all contained files -int SimpleFS_remove(DirectoryHandle* d, const char* filename); +int SimpleFS_remove(DirectoryHandle *d, const char *filename); diff --git a/simplefs_aux.c b/simplefs_aux.c index 216f637..5f58913 100644 --- a/simplefs_aux.c +++ b/simplefs_aux.c @@ -1,798 +1,743 @@ #include "simplefs_aux.h" // searches for a file or a directory given a DirectoryHandle and the element name -SearchResult* SimpleFS_search(DirectoryHandle* d, const char* name){ - //we check that we have been given valid data - if(d==NULL || strlen(name)==0){ +SearchResult *SimpleFS_search(DirectoryHandle *d, const char *name) { +//we check that we have been given valid data + if (d == NULL || strlen(name) == 0) { return NULL; } - // we will save our results and all our intermediate variables in here - SearchResult *result=(SearchResult*) malloc(sizeof(SearchResult)); - result->result=FAILED; - result->dir_block_in_disk=MISSING; - result->element=NULL; - result->last_visited_dir_block=NULL; - result->type=MISSING; +// we will save our results and all our intermediate variables in here + SearchResult *result = (SearchResult *) malloc(sizeof(SearchResult)); + result->result = FAILED; + result->dir_block_in_disk = MISSING; + result->element = NULL; + result->last_visited_dir_block = NULL; + result->type = MISSING; - //now we check if the file is already present in the given directory - int i,res; - //this variable is used to stop the search if we have already found a matching filename - int searching=1; +//now we check if the file is already present in the given directory + int i, res; +//this variable is used to stop the search if we have already found a matching filename + int searching = 1; - //we know how many entries has a directory but we don't know how many entries per block we have so we calculate it - int FDB_max_elements=(BLOCK_SIZE-sizeof(BlockHeader)-sizeof(FileControlBlock)-sizeof(int))/sizeof(int); - int Dir_Block_max_elements=(BLOCK_SIZE-sizeof(BlockHeader))/sizeof(int); +//we know how many entries has a directory but we don't know how many entries per block we have so we calculate it + int FDB_max_elements = (BLOCK_SIZE - sizeof(BlockHeader) - sizeof(FileControlBlock) - sizeof(int)) / sizeof(int); + int Dir_Block_max_elements = (BLOCK_SIZE - sizeof(BlockHeader)) / sizeof(int); - // in here we will save the read FirstFileBlock/FirstDirectoryBlock to check if has a matching file name - FirstFileBlock* element=malloc(sizeof(FirstFileBlock)); - //we save the number of entries in the directory - int dir_entries=d->dcb->num_entries; +// in here we will save the read FirstFileBlock/FirstDirectoryBlock to check if has a matching file name + FirstFileBlock *element = malloc(sizeof(FirstFileBlock)); +//we save the number of entries in the directory + int dir_entries = d->dcb->num_entries; - // we search for all the files in the current directory block - for(i=0;isfs->disk,element,d->dcb->file_blocks[i]); - if(res==FAILED){ + res = DiskDriver_readBlock(d->sfs->disk, element, d->dcb->file_blocks[i]); + if (res == FAILED) { free(element); free(result); - CHECK_ERR(res==FAILED,"the directory contains a free block in the entry list"); + CHECK_ERR(res == FAILED, "the directory contains a free block in the entry list"); } //we check if the file has the same name of the file we want to create - searching=strncmp(element->fcb.name,name,strlen(name)); + searching = strncmp(element->fcb.name, name, strlen(name)); } - if(searching==0){ - result->result=SUCCESS; - result->dir_block_in_disk=MISSING; - result->type=element->fcb.is_dir; - result->last_visited_dir_block=NULL; - result->element=element; - result->pos_in_block=i-1; + if (searching == 0) { + result->result = SUCCESS; + result->dir_block_in_disk = MISSING; + result->type = element->fcb.is_dir; + result->last_visited_dir_block = NULL; + result->element = element; + result->pos_in_block = i - 1; return result; } - //now we search in the other directory blocks which compose the directory list +//now we search in the other directory blocks which compose the directory list - int next_block=d->dcb->header.next_block; + int next_block = d->dcb->header.next_block; int dir_block_in_disk; - //we save the block in disk of the current directory block for future use - dir_block_in_disk=d->dcb->header.block_in_disk; - //we adjust the number of remaining entries - dir_entries-=FDB_max_elements; - //we start the search in the rest of the chained list - DirectoryBlock *dir=(DirectoryBlock*)malloc(sizeof(DirectoryBlock)); - while(next_block!=MISSING){ +//we save the block in disk of the current directory block for future use +//we adjust the number of remaining entries + dir_entries -= FDB_max_elements; +//we start the search in the rest of the chained list + DirectoryBlock *dir = (DirectoryBlock *) malloc(sizeof(DirectoryBlock)); + while (next_block != MISSING) { memset(dir, 0, sizeof(DirectoryBlock)); //we get the next directory block; - dir_block_in_disk=next_block; + dir_block_in_disk = next_block; // we clean our directory before getting the new one - memset(dir,0,sizeof(DirectoryBlock)); - res=DiskDriver_readBlock(d->sfs->disk,dir,next_block); + memset(dir, 0, sizeof(DirectoryBlock)); + res = DiskDriver_readBlock(d->sfs->disk, dir, next_block); - if(res==FAILED){ + if (res == FAILED) { free(element); free(dir); free(result); - CHECK_ERR(res==FAILED,"the directory contains a free block in the entry chain"); + CHECK_ERR(res == FAILED, "the directory contains a free block in the entry chain"); } //we search it - for(i=0;isfs->disk,element,dir->file_blocks[i]); - if(res==FAILED){ + res = DiskDriver_readBlock(d->sfs->disk, element, dir->file_blocks[i]); + if (res == FAILED) { free(element); free(dir); free(result); - CHECK_ERR(res==FAILED,"the directory contains a free block in the entry list"); + CHECK_ERR(res == FAILED, "the directory contains a free block in the entry list"); } //we check if the file has the same name of the file we want to create - searching=strncmp(element->fcb.name,name,strlen(name)); + searching = strncmp(element->fcb.name, name, strlen(name)); } - if(searching==0){ - result->type=element->fcb.is_dir; - result->dir_block_in_disk=dir_block_in_disk; - result->element=element; - result->last_visited_dir_block=dir; - result->result=SUCCESS; - result->pos_in_block=i; + if (searching == 0) { + result->type = element->fcb.is_dir; + result->dir_block_in_disk = dir_block_in_disk; + result->element = element; + result->last_visited_dir_block = dir; + result->result = SUCCESS; + result->pos_in_block = i; } //now we need to change block and to adjust the number of remaining entries to check - dir_entries-=Dir_Block_max_elements; - next_block=dir->header.next_block; + dir_entries -= Dir_Block_max_elements; + next_block = dir->header.next_block; } - if(element!=NULL) free(element); - if(dir!=NULL) free(dir); + if (element != NULL) free(element); + if (dir != NULL) free(dir); return result; } -void Dir_addentry(DirectoryHandle *d,int file_block){ - //we check that we have been given valid data - if(d==NULL || file_block<=0 || file_block>=d->sfs->disk->header->num_blocks){ - return ; +void Dir_addentry(DirectoryHandle *d, int file_block) { +//we check that we have been given valid data + if (d == NULL || file_block <= 0 || file_block >= d->sfs->disk->header->num_blocks) { + return; } - //we know how many entries has a directory but we don't know how many entries per block we have so we calculate it - int FDB_max_elements=(BLOCK_SIZE-sizeof(BlockHeader)-sizeof(FileControlBlock)-sizeof(int))/sizeof(int); - int Dir_Block_max_elements=(BLOCK_SIZE-sizeof(BlockHeader))/sizeof(int); +//we know how many entries has a directory but we don't know how many entries per block we have so we calculate it + int FDB_max_elements = (BLOCK_SIZE - sizeof(BlockHeader) - sizeof(FileControlBlock) - sizeof(int)) / sizeof(int); + int Dir_Block_max_elements = (BLOCK_SIZE - sizeof(BlockHeader)) / sizeof(int); int res; - //we use the current block, pos_in_block and pos_in_dir to determine the position where we - //must write the new file in the directory - //but it could be uninitialized! - DirectoryBlock *dir=(DirectoryBlock*)malloc(sizeof(DirectoryBlock)); - //we determine if the current block is uninitialized - if(d->current_block->next_block!=MISSING ){ - while(d->current_block->next_block!=MISSING){ - res=DiskDriver_readBlock(d->sfs->disk,dir,d->current_block->next_block); - CHECK_ERR(res==FAILED,"can't read the directory block"); - memcpy(d->current_block,&(dir->header),sizeof(BlockHeader)); +//we use the current block, pos_in_block and pos_in_dir to determine the position where we +//must write the new file in the directory +//but it could be uninitialized! + DirectoryBlock *dir = (DirectoryBlock *) malloc(sizeof(DirectoryBlock)); +//we determine if the current block is uninitialized + if (d->current_block->next_block != MISSING) { + while (d->current_block->next_block != MISSING) { + res = DiskDriver_readBlock(d->sfs->disk, dir, d->current_block->next_block); + CHECK_ERR(res == FAILED, "can't read the directory block"); + memcpy(d->current_block, &(dir->header), sizeof(BlockHeader)); } - }else{ + } else { //we check if we must load the current directory block - if(d->current_block->block_in_file!=0){ - res=DiskDriver_readBlock(d->sfs->disk,dir,d->current_block->block_in_disk); - CHECK_ERR(res==FAILED,"can't read the directory block"); + if (d->current_block->block_in_file != 0) { + res = DiskDriver_readBlock(d->sfs->disk, dir, d->current_block->block_in_disk); + CHECK_ERR(res == FAILED, "can't read the directory block"); } } - d->pos_in_dir=d->dcb->num_entries; - if(d->current_block->block_in_file==0){ - d->pos_in_block=d->pos_in_dir-1; - }else{ - d->pos_in_block=(d->pos_in_dir-FDB_max_elements-1)-Dir_Block_max_elements*(d->current_block->block_in_file-1); + d->pos_in_dir = d->dcb->num_entries; + if (d->current_block->block_in_file == 0) { + d->pos_in_block = d->pos_in_dir - 1; + } else { + d->pos_in_block = + (d->pos_in_dir - FDB_max_elements - 1) - Dir_Block_max_elements * (d->current_block->block_in_file - 1); } - //we get the index of the block in which we must update the data - int dir_block=d->current_block->block_in_file; +//we get the index of the block in which we must update the data + int dir_block = d->current_block->block_in_file; int dir_block_displacement; - if(d->dcb->num_entries==0){ - dir_block_displacement=0; - }else{ - dir_block_displacement=d->pos_in_block+1; + if (d->dcb->num_entries == 0) { + dir_block_displacement = 0; + } else { + dir_block_displacement = d->pos_in_block + 1; } - if(dir_block==0){ - if(dir_block_displacementdcb->file_blocks[dir_block_displacement]=file_block; - }else{ + d->dcb->file_blocks[dir_block_displacement] = file_block; + } else { //in this case we must allocate a directory block - dir_block_displacement=0; - - int new_dir_block=DiskDriver_getFreeBlock(d->sfs->disk,0); - CHECK_ERR(new_dir_block==FAILED,"full disk on directory update"); - dir->header.block_in_file=d->dcb->header.block_in_file+1; - dir->header.next_block=MISSING; - dir->header.block_in_disk=new_dir_block; - dir->header.previous_block=d->dcb->header.block_in_disk; + dir_block_displacement = 0; + + int new_dir_block = DiskDriver_getFreeBlock(d->sfs->disk, 0); + CHECK_ERR(new_dir_block == FAILED, "full disk on directory update"); + dir->header.block_in_file = d->dcb->header.block_in_file + 1; + dir->header.next_block = MISSING; + dir->header.block_in_disk = new_dir_block; + dir->header.previous_block = d->dcb->header.block_in_disk; //we set the chain to MISSING - memset(dir->file_blocks,MISSING,sizeof(int)*Dir_Block_max_elements); - dir->file_blocks[dir_block_displacement]=file_block; - d->dcb->header.next_block=new_dir_block; + memset(dir->file_blocks, MISSING, sizeof(int) * Dir_Block_max_elements); + dir->file_blocks[dir_block_displacement] = file_block; + d->dcb->header.next_block = new_dir_block; //we update the current_block - memcpy(d->current_block,&(dir->header),sizeof(BlockHeader)); - res=DiskDriver_writeBlock(d->sfs->disk,dir,new_dir_block); - CHECK_ERR(res==FAILED,"can't write the 2nd directory block"); + memcpy(d->current_block, &(dir->header), sizeof(BlockHeader)); + res = DiskDriver_writeBlock(d->sfs->disk, dir, new_dir_block); + CHECK_ERR(res == FAILED, "can't write the 2nd directory block"); } free(dir); - }else{ + } else { //we save the current block in disk because it could change - int current_block=d->current_block->block_in_disk; + int current_block = d->current_block->block_in_disk; // now we must check if in the last directory_block we have room for one more file - if(dir_block_displacementfile_blocks[dir_block_displacement]=file_block; - }else{ - int new_dir_block=DiskDriver_getFreeBlock(d->sfs->disk,0); - CHECK_ERR(new_dir_block==FAILED,"full disk on directory update"); - dir_block_displacement=0; - DirectoryBlock *new_dir=(DirectoryBlock*)malloc(sizeof(DirectoryBlock)); - new_dir->header.block_in_file=dir->header.block_in_file+1; - new_dir->header.block_in_disk=new_dir_block; - new_dir->header.next_block=MISSING; - new_dir->header.previous_block=d->current_block->block_in_disk; + dir->file_blocks[dir_block_displacement] = file_block; + } else { + int new_dir_block = DiskDriver_getFreeBlock(d->sfs->disk, 0); + CHECK_ERR(new_dir_block == FAILED, "full disk on directory update"); + dir_block_displacement = 0; + DirectoryBlock *new_dir = (DirectoryBlock *) malloc(sizeof(DirectoryBlock)); + new_dir->header.block_in_file = dir->header.block_in_file + 1; + new_dir->header.block_in_disk = new_dir_block; + new_dir->header.next_block = MISSING; + new_dir->header.previous_block = d->current_block->block_in_disk; //we set the chain to MISSING - memset(new_dir->file_blocks,MISSING,sizeof(int)*Dir_Block_max_elements); - new_dir->file_blocks[dir_block_displacement]=file_block; - dir->header.next_block=new_dir_block; + memset(new_dir->file_blocks, MISSING, sizeof(int) * Dir_Block_max_elements); + new_dir->file_blocks[dir_block_displacement] = file_block; + dir->header.next_block = new_dir_block; //we update the current_block - memcpy(d->current_block,&(new_dir->header),sizeof(BlockHeader)); + memcpy(d->current_block, &(new_dir->header), sizeof(BlockHeader)); //we write the new dir_block - res=DiskDriver_writeBlock(d->sfs->disk,new_dir,new_dir_block); + res = DiskDriver_writeBlock(d->sfs->disk, new_dir, new_dir_block); free(new_dir); - if(res==FAILED){ + if (res == FAILED) { free(dir); - CHECK_ERR(res==FAILED,"can't write the new dir_block on disk"); + CHECK_ERR(res == FAILED, "can't write the new dir_block on disk"); } } //we write the updated dir_block - res=DiskDriver_writeBlock(d->sfs->disk,dir,current_block); + res = DiskDriver_writeBlock(d->sfs->disk, dir, current_block); free(dir); - CHECK_ERR(res==FAILED,"can't write the updated dir_block on disk"); + CHECK_ERR(res == FAILED, "can't write the updated dir_block on disk"); } - //we update the metedata into the FDB +//we update the metedata into the FDB d->dcb->num_entries++; - //we update the metadata into the DirectoryHandle +//we update the metadata into the DirectoryHandle d->pos_in_dir++; - d->pos_in_block=dir_block_displacement; - //we write the updated FirstDirectoryBlock - res=DiskDriver_writeBlock(d->sfs->disk,d->dcb,d->dcb->header.block_in_disk); - CHECK_ERR(res==FAILED,"can't write the updated FirstDirectoryBlock on disk"); + d->pos_in_block = dir_block_displacement; +//we write the updated FirstDirectoryBlock + res = DiskDriver_writeBlock(d->sfs->disk, d->dcb, d->dcb->header.block_in_disk); + CHECK_ERR(res == FAILED, "can't write the updated FirstDirectoryBlock on disk"); } //remves one file, including the FCB, all the index block and all the indexes -int SimpleFS_removeFile(SimpleFS *sfs, int file){ - int i,res,stop=0; - int FFB_max_entries=(BLOCK_SIZE-sizeof(FileControlBlock) - sizeof(BlockHeader)-sizeof(int)-sizeof(int))/sizeof(int); - int IB_max_entries=(BLOCK_SIZE-sizeof(BlockHeader))/sizeof(int); +int SimpleFS_removeFile(SimpleFS *sfs, int file) { + int i, res, stop = 0; + int FFB_max_entries = + (BLOCK_SIZE - sizeof(FileControlBlock) - sizeof(BlockHeader) - sizeof(int) - sizeof(int)) / sizeof(int); + int IB_max_entries = (BLOCK_SIZE - sizeof(BlockHeader)) / sizeof(int); int next_IndexBlock; - //we load our FFB - FirstFileBlock *ffb=(FirstFileBlock*)malloc(sizeof(FirstFileBlock)); - res=DiskDriver_readBlock(sfs->disk,ffb,file); - if(res==FAILED){ +//we load our FFB + FirstFileBlock *ffb = (FirstFileBlock *) malloc(sizeof(FirstFileBlock)); + res = DiskDriver_readBlock(sfs->disk, ffb, file); + if (res == FAILED) { free(ffb); - CHECK_ERR(res==FAILED,"can't read the FFB to remove"); + CHECK_ERR(res == FAILED, "can't read the FFB to remove"); } - //firstly we deallocate the blocks indexed in our FileControlBlock - for(i=0;iblocks[i]!=MISSING){ - res=DiskDriver_freeBlock(sfs->disk,ffb->blocks[i]); - CHECK_ERR(res==FAILED,"can't deallocate a data block indexed in the ffb"); - }else{ - stop=1; +//firstly we deallocate the blocks indexed in our FileControlBlock + for (i = 0; i < FFB_max_entries && !stop; i++) { + if (ffb->blocks[i] != MISSING) { + res = DiskDriver_freeBlock(sfs->disk, ffb->blocks[i]); + CHECK_ERR(res == FAILED, "can't deallocate a data block indexed in the ffb"); + } else { + stop = 1; } } - //now we need to deallocate the ffb - res=DiskDriver_freeBlock(sfs->disk,file); - //now before destroying our ffb in memory we check if there are other IndexBlocks - if(ffb->next_IndexBlock==MISSING){ +//now we need to deallocate the ffb + res = DiskDriver_freeBlock(sfs->disk, file); + CHECK_ERR(res == FAILED, "can't deallocate the first file block") +//now before destroying our ffb in memory we check if there are other IndexBlocks + if (ffb->next_IndexBlock == MISSING) { free(ffb); return SUCCESS; } - //if we get here we need to deallocate the other IndexBlocks - //we load the first IndexBlock - Index* index=(Index*)malloc(sizeof(Index)); //////////////////////////////////////////////////////////////////////////////////// - next_IndexBlock=ffb->next_IndexBlock; - //now we can deallocate the ffb +//if we get here we need to deallocate the other IndexBlocks +//we load the first IndexBlock + Index *index = (Index *) malloc( + sizeof(Index)); + next_IndexBlock = ffb->next_IndexBlock; +//now we can deallocate the ffb free(ffb); - //now we deallocate all the data blocks in the index chain - while(next_IndexBlock!=MISSING){ +//now we deallocate all the data blocks in the index chain + while (next_IndexBlock != MISSING) { //if possible we load the next index block - memset(index,0,sizeof(Index)); - res=DiskDriver_readBlock(sfs->disk,index,next_IndexBlock); /////////////////////// ho la index popolata - //block in file dovrebbe gia essere inizializzata //////////////// - CHECK_ERR(res==FAILED,"can't load the next index block"); + memset(index, 0, sizeof(Index)); + res = DiskDriver_readBlock(sfs->disk, index, + next_IndexBlock); + //block in file dovrebbe gia essere inizializzata + CHECK_ERR(res == FAILED, "can't load the next index block"); //we deallocate all the data block in this index block - for(i=0;iindexes[i]!=MISSING){ - res=DiskDriver_freeBlock(sfs->disk,index->indexes[i]); - // TODO there's problem here! - CHECK_ERR(res==FAILED,"can't deallocate a block in the index chain"); - }else{ - stop=1; + for (i = 0; i < IB_max_entries && !stop; i++) { + if (index->indexes[i] != MISSING) { + res = DiskDriver_freeBlock(sfs->disk, index->indexes[i]); + CHECK_ERR(res == FAILED, "can't deallocate a block in the index chain"); + } else { + stop = 1; } } //now we deallocate the current index block - res=DiskDriver_freeBlock(sfs->disk,index->header.block_in_disk); //////////////////////////////////////////////////////////////////////////////////// - CHECK_ERR(res==FAILED,"can't deallocate the current index block"); + res = DiskDriver_freeBlock(sfs->disk, + index->header.block_in_disk); + CHECK_ERR(res == FAILED, "can't deallocate the current index block"); //we get the next index block - next_IndexBlock=index->header.next_block; //////////////////////////////////////////////////////////////////////////////////// + next_IndexBlock = index->header.next_block; } free(index); return SUCCESS; } -int SimpleFS_removeChildDir(DirectoryHandle* handle){ - int FDB_max_elements=(BLOCK_SIZE-sizeof(BlockHeader)-sizeof(FileControlBlock)-sizeof(int))/sizeof(int); - int Dir_Block_max_elements=(BLOCK_SIZE-sizeof(BlockHeader))/sizeof(int); - FirstDirectoryBlock* fdb=(FirstDirectoryBlock*) malloc(sizeof(FirstDirectoryBlock)); - DirectoryBlock* db = (DirectoryBlock*)malloc(sizeof(DirectoryBlock)); - DirectoryBlock* db1 = (DirectoryBlock*)malloc(sizeof(DirectoryBlock)); - int i, z, res, pos=0; - - // Removes all block occupied by passed directory - int app = handle->dcb->header.next_block; - while(app!=MISSING){ - res=DiskDriver_readBlock(handle->sfs->disk , db, app); - CHECK_ERR(res==FAILED, "Error on read of DirectoryBlock in simpleFS_remove"); - res=DiskDriver_freeBlock(handle->sfs->disk, app); - CHECK_ERR(res==FAILED, "Error on freeBlock in simpleFS_remove"); - app = db->header.next_block; - } - - // Remove passed directory in the parent directory - for(z=0; zdirectory->num_entries; z++){ - if(z < FDB_max_elements){ - if(handle->directory->file_blocks[z]==handle->dcb->header.block_in_disk){ - // free block target - res=DiskDriver_freeBlock(handle->sfs->disk, handle->dcb->header.block_in_disk); - CHECK_ERR(res==FAILED, "Error on freeBlock in simpleFS_remove"); - - // Obtain the fdb of parent directory - res=DiskDriver_readBlock(handle->sfs->disk , fdb, handle->directory->header.block_in_disk); - CHECK_ERR(res==FAILED, "Error on read of FirstDirectoryBlock in simpleFS_remove"); - if(handle->directory->num_entries > FDB_max_elements){ - // search the last directoryBlock used - app = fdb->header.next_block; - while(app!=MISSING){ - res=DiskDriver_readBlock(handle->sfs->disk , db, app); - CHECK_ERR(res==FAILED, "Error on read of DirectoryBlock in simpleFS_remove"); - app = db->header.next_block; - } - // Trovo l'ultimo blocco occupato - for(i=0; ifile_blocks[i]!=MISSING; i++); - handle->directory->file_blocks[z]=db->file_blocks[i-1]; - db->file_blocks[i-1]=MISSING; - - // We write the updated on file - res=DiskDriver_writeBlock(handle->sfs->disk, db, db->header.block_in_disk); - if(res==FAILED) return FAILED; - - }else{ - // search the last item in file_block of directory block - for(i=0; idirectory->num_entries && handle->directory->file_blocks[i]!=MISSING; i++); - if(i-1>0)handle->directory->file_blocks[z]=handle->directory->file_blocks[i-1]; - handle->directory->file_blocks[i-1]=MISSING; - } - handle->directory->num_entries--; - - // We write the updated on file - res=DiskDriver_writeBlock(handle->sfs->disk, handle->directory, handle->directory->header.block_in_disk); - if(res==FAILED) return FAILED; +int SimpleFS_removeFileOnDir(DirectoryHandle *dh, void *element, int pos_in_block) { + // reordering the list of file after removing one file + int i, res; + int FDB_max_elements = (BLOCK_SIZE - sizeof(BlockHeader) - sizeof(FileControlBlock) - sizeof(int)) / sizeof(int); + int Dir_Block_max_elements = (BLOCK_SIZE - sizeof(BlockHeader)) / sizeof(int); + DirectoryHandle *dir = dh; + DirectoryBlock *db = (DirectoryBlock *) malloc(sizeof(DirectoryBlock)); + DirectoryBlock *db1 = (DirectoryBlock *) malloc(sizeof(DirectoryBlock)); + FirstFileBlock *file = (FirstFileBlock *) element; + // removing the file + SimpleFS_removeFile(dh->sfs, file->header.block_in_disk); + + // if the file is in the FDB + if (dh->current_block->block_in_file == 0) { + + //if the file is in the FDB + if (dir->dcb->num_entries >= FDB_max_elements) { + memset(db, 0, sizeof(DirectoryBlock)); + int app = dir->dcb->header.next_block; + while (app != MISSING) { + res = DiskDriver_readBlock(dh->sfs->disk, db, app); + CHECK_ERR(res == FAILED, "Error on read of DirectoryBlock in simpleFS_remove"); + app = db->header.next_block; } + // search the last item in file_block of directory block + for (i = 0; i < Dir_Block_max_elements && db->file_blocks[i] != MISSING; i++); + dir->dcb->file_blocks[pos_in_block] = db->file_blocks[i - 1]; + db->file_blocks[i - 1] = MISSING; + // We write the updates on file + res = DiskDriver_writeBlock(dh->sfs->disk, db, db->header.block_in_disk); + if (res == FAILED) return FAILED; + } else { + // search the last item in file_block of directory block + for (i = pos_in_block; i < dir->dcb->num_entries && dir->dcb->file_blocks[i] != MISSING; i++); + if (i - 1 != 0) dir->dcb->file_blocks[pos_in_block] = dir->dcb->file_blocks[i - 1]; + dir->dcb->file_blocks[i - 1] = MISSING; } - else{ - // File contenuto nei DB della directory genitore - int logblock=(z/Dir_Block_max_elements)+1; - int block = handle->directory->header.next_block; - for(i=0; isfs->disk , db, block); - CHECK_ERR(res==FAILED, "Error on read of DirectoryBlock in simpleFS_remove"); - block = db->header.next_block; - pos=i; - } - if(db->file_blocks[(z-FDB_max_elements)%Dir_Block_max_elements]==handle->dcb->header.block_in_disk){ - // search the last directoryBlock used - app = fdb->header.next_block; - while(app!=MISSING){ - res=DiskDriver_readBlock(handle->sfs->disk , db, app); - CHECK_ERR(res==FAILED, "Error on read of DirectoryBlock in simpleFS_remove"); - app = db->header.next_block; - } - // search the last item in file_block of directory block - for(i=0; idirectory->num_entries && db1->file_blocks[i]!=MISSING; i++); - res=DiskDriver_freeBlock(handle->sfs->disk, handle->dcb->header.block_in_disk); - CHECK_ERR(res==FAILED, "Error on freeBlock in simpleFS_remove"); - db->file_blocks[(z-FDB_max_elements)%Dir_Block_max_elements]=db1->file_blocks[i-1]; - db1->file_blocks[i-1]=MISSING; - - // We write the updated on file - res=DiskDriver_writeBlock(handle->sfs->disk, db, db->header.block_in_disk); - if(res==FAILED) return FAILED; - res=DiskDriver_writeBlock(handle->sfs->disk, db1, db1->header.block_in_disk); - if(res==FAILED) return FAILED; - } + } else { + // if the file is in the Directory blocks + //we get the block in which the fie is stored + memset(db, 0, sizeof(DirectoryBlock)); + res = DiskDriver_readBlock(dh->sfs->disk, db, dir->current_block->block_in_disk); + CHECK_ERR(res == FAILED, "Error on read of DirectoryBlock in simpleFS_remove"); + //we get the last block with entries + memset(db1, 0, sizeof(DirectoryBlock)); + int app = dir->current_block->next_block; + while (app != MISSING) { + res = DiskDriver_readBlock(dir->sfs->disk, db1, app); + CHECK_ERR(res == FAILED, "Error on read of DirectoryBlock in simpleFS_remove"); + app = db1->header.next_block; } + // we get the last occupied entry + for (i = 0; i < Dir_Block_max_elements && db1->file_blocks[i] != MISSING; i++); + db->file_blocks[pos_in_block] = db1->file_blocks[i - 1]; + db1->file_blocks[i - 1] = MISSING; + if (i - 1 >= 0) { + // We write the updates on file + res = DiskDriver_writeBlock(dh->sfs->disk, db1, db1->header.block_in_disk); + CHECK_ERR(res == FAILED, "Error on write of DirectoryBlock in simpleFS_remove"); + } else { + // we free the last block used if there was olny the entry we have moved + res = DiskDriver_freeBlock(dir->sfs->disk, db1->header.block_in_disk); + CHECK_ERR(res == FAILED, "Error on read of DirectoryBlock in simpleFS_remove"); + //we get the new last block and update its header + res = DiskDriver_readBlock(dir->sfs->disk, db1, db1->header.previous_block); + CHECK_ERR(res == FAILED, "Error on read of DirectoryBlock in simpleFS_remove"); + db1->header.next_block = MISSING; + res = DiskDriver_writeBlock(dh->sfs->disk, db1, db1->header.block_in_disk); + CHECK_ERR(res == FAILED, "Error on write of DirectoryBlock in simpleFS_remove"); + } + //we write the updates on file + res = DiskDriver_writeBlock(dh->sfs->disk, db, db->header.block_in_disk); + if (res == FAILED) return FAILED; } free(db1); free(db); - free(fdb); + // we update our DCB metedata + dir->dcb->num_entries--; + // We write the updates on file + res = DiskDriver_writeBlock(dh->sfs->disk, dir->dcb, dir->dcb->header.block_in_disk); + if (res == FAILED) return FAILED; return SUCCESS; } -int SimpleFS_removeFileOnDir(DirectoryHandle* dh, void* element, int pos_in_block){ - // Ricompatto la lista dei file contenuti nella directory - // genitore del file - int i, res, pos=0; - int FDB_max_elements=(BLOCK_SIZE-sizeof(BlockHeader)-sizeof(FileControlBlock)-sizeof(int))/sizeof(int); - int Dir_Block_max_elements=(BLOCK_SIZE-sizeof(BlockHeader))/sizeof(int); - DirectoryHandle* dir = dh; - DirectoryBlock* db = (DirectoryBlock*)malloc(sizeof(DirectoryBlock)); - DirectoryBlock* db1 = (DirectoryBlock*)malloc(sizeof(DirectoryBlock)); - FirstFileBlock* file = (FirstFileBlock*)element; - // Rimuovo il file - SimpleFS_removeFile(dh->sfs, file->header.block_in_disk); - - if(pos_in_blocksfs->disk, dir->dcb->file_blocks[pos_in_block]); - CHECK_ERR(res==FAILED, "Error on freeBlock in simpleFS_remove"); - - // File contenuto nell'FDB della directory genitore - if(dir->dcb->num_entries >= FDB_max_elements){ - memset(db, 0, sizeof(DirectoryBlock)); - // TODO did this iteration below because currentBlock does not assume the values it should have. check with gdb - int app = dir->dcb->header.next_block; - while(app!=MISSING){ - res=DiskDriver_readBlock(dh->sfs->disk , db, app); - CHECK_ERR(res==FAILED, "Error on read of DirectoryBlock in simpleFS_remove"); - app = db->header.next_block; - } - // search the last item in file_block of directory block - for(i=0; ifile_blocks[i]!=MISSING; i++); - dir->dcb->file_blocks[pos_in_block]=db->file_blocks[i-1]; - db->file_blocks[i-1]=MISSING; - - // We write the updated on file - res=DiskDriver_writeBlock(dh->sfs->disk, db, db->header.block_in_disk); - if(res==FAILED) return FAILED; - }else{ - // search the last item in file_block of directory block - for(i=0; idcb->num_entries && dir->dcb->file_blocks[i]!=MISSING; i++); - if(i-1!=0) dir->dcb->file_blocks[pos_in_block]=dir->dcb->file_blocks[i-1]; - dir->dcb->file_blocks[i-1]=MISSING; - } - dir->dcb->num_entries--; - - // We write the updated on file - res=DiskDriver_writeBlock(dh->sfs->disk, dir->dcb, dir->dcb->header.block_in_disk); - if(res==FAILED) return FAILED; - }else{ - // File contenuto nei DB della directory genitore - int logblock=((pos_in_block-FDB_max_elements)/Dir_Block_max_elements)+1; - int block = dir->dcb->header.next_block; - for(i=0; isfs->disk , db, block); - CHECK_ERR(res==FAILED, "Error on read of DirectoryBlock in simpleFS_remove"); - block = db->header.next_block; - pos=i+1; - } - memset(db1, 0, sizeof(DirectoryBlock)); - // TODO did this iteration below because currentBlock does not assume the values it should have. check with gdb - int app = dh->dcb->header.next_block; - while(app!=MISSING){ - res=DiskDriver_readBlock(dh->sfs->disk , db1, app); - CHECK_ERR(res==FAILED, "Error on read of DirectoryBlock in simpleFS_remove"); - app = db1->header.next_block; - } - // Trovo l'ultimo blocco occupato - for(i=0; ifile_blocks[i]!=MISSING; i++); - res=DiskDriver_freeBlock(dh->sfs->disk,db->file_blocks[(pos_in_block-FDB_max_elements)%Dir_Block_max_elements]); - CHECK_ERR(res==FAILED, "Error on freeBlock in simpleFS_remove"); - db->file_blocks[pos_in_block]=db1->file_blocks[i-1]; - db1->file_blocks[i-1]=MISSING; - - // We write the updated on file - res=DiskDriver_writeBlock(dh->sfs->disk, db, db->header.block_in_disk); - if(res==FAILED) return FAILED; - res=DiskDriver_writeBlock(dh->sfs->disk, db1, db1->header.block_in_disk); - if(res==FAILED) return FAILED; - } - free(db1); - free(db); - - return SUCCESS; -} - // Removes files and directories recursively -int SimpleFS_remove_rec(DirectoryHandle* handle){ - // Check if passed parameters are valid - if(handle == NULL) return FAILED; - - int FDB_max_elements=(BLOCK_SIZE-sizeof(BlockHeader)-sizeof(FileControlBlock)-sizeof(int))/sizeof(int); - int Dir_Block_max_elements=(BLOCK_SIZE-sizeof(BlockHeader))/sizeof(int); - int i, res; - - // Remove the files contained in the directory - DirectoryBlock* db = (DirectoryBlock*)malloc(sizeof(DirectoryBlock)); - FirstDirectoryBlock* fh = (FirstDirectoryBlock*)malloc(sizeof(FirstDirectoryBlock)); - DirectoryHandle* hand = (DirectoryHandle*)malloc(sizeof(DirectoryBlock)); - int z, pos=0; - - for(z=0; zdcb->num_entries; z++){ - memset(fh, 0, sizeof(FirstDirectoryBlock)); - if(z < FDB_max_elements){ - res=DiskDriver_readBlock(handle->sfs->disk, fh, handle->dcb->file_blocks[z]); - CHECK_ERR(res==FAILED, "Error read dir block in simplefs_remove"); - if(fh->fcb.is_dir==FILE) SimpleFS_removeFileOnDir(handle, (void*)fh, z); - else{ +int SimpleFS_remove_rec(DirectoryHandle *handle) { + // Check if passed parameters are valid + if (handle == NULL) return FAILED; + + int FDB_max_elements = (BLOCK_SIZE - sizeof(BlockHeader) - sizeof(FileControlBlock) - sizeof(int)) / sizeof(int); + int Dir_Block_max_elements = (BLOCK_SIZE - sizeof(BlockHeader)) / sizeof(int); + int i, res; + +// Allocating needed structures + DirectoryBlock *db = (DirectoryBlock *) malloc(sizeof(DirectoryBlock)); + FirstDirectoryBlock *fh = (FirstDirectoryBlock *) malloc(sizeof(FirstDirectoryBlock)); + DirectoryHandle *hand = (DirectoryHandle *) malloc(sizeof(DirectoryBlock)); + + //we go to the end of the directory and traverse it backwards removing its content + while (handle->current_block->next_block != MISSING) { + memset(db, 0, sizeof(DirectoryBlock)); + res = DiskDriver_readBlock(handle->sfs->disk, db, handle->current_block->next_block); + CHECK_ERR(res == FAILED, "Error while traversing the directory") + memcpy(handle->current_block, &(db->header), sizeof(BlockHeader)); + } + //we traverse the directory backward removing its content + while (handle->current_block->block_in_file > 0) { + // we remove the file in the current directory block + for (i = 0; i < Dir_Block_max_elements && db->file_blocks[i] != MISSING; i++) { + memset(fh, 0, sizeof(FirstDirectoryBlock)); + // we read the FDB/FFB to check whether the element is a file or a directory + res = DiskDriver_readBlock(handle->sfs->disk, fh, db->file_blocks[i]); + CHECK_ERR(res == FAILED, "error reading file in dbs in remove_rec") + if (fh->fcb.is_dir == FILE) { + // if it's a file we remove it + res = SimpleFS_removeFile(handle->sfs, db->file_blocks[i]); + CHECK_ERR(res == FAILED, "error removing file in dbs in remove_rec") + } else { + //if it's a directory we create a handle and call SimpleFS_remove_rec in it memset(hand, 0, sizeof(DirectoryHandle)); - hand->sfs=handle->sfs; - hand->dcb=fh; - hand->directory=handle->dcb; - hand->current_block = &(fh->header); - hand->pos_in_block=0; - hand->pos_in_dir=0; - - if(hand->dcb->num_entries==0){ - res=DiskDriver_freeBlock(handle->sfs->disk, hand->dcb->header.block_in_disk); - CHECK_ERR(res==FAILED, "Failed to free block in simplefs_remove_rec"); - }else SimpleFS_remove_rec(hand); + hand->sfs = handle->sfs; + hand->dcb = fh; + hand->directory = handle->dcb; + hand->current_block = malloc(sizeof(BlockHeader)); + memcpy(hand->current_block, &(fh->header), sizeof(BlockHeader)); + hand->pos_in_block = 0; + hand->pos_in_dir = 0; + // we check if the directory it's empty and in that case we deallocate it directly + if (hand->dcb->num_entries == 0) { + res = DiskDriver_freeBlock(handle->sfs->disk, hand->dcb->header.block_in_disk); + CHECK_ERR(res == FAILED, "Failed to free block in simplefs_remove_rec"); + } else SimpleFS_remove_rec(hand); } } - else{ - // File contenuto nei DB della directory genitore - int logblock=((z-FDB_max_elements)/Dir_Block_max_elements)+1; - int block = handle->dcb->header.next_block; - for(i=0; isfs->disk , db, block); - CHECK_ERR(res==FAILED, "Error on read of DirectoryBlock in simpleFS_remove"); - block = db->header.next_block; - pos=i+1; - } - res=DiskDriver_readBlock(handle->sfs->disk, fh, db->file_blocks[(z-FDB_max_elements)%Dir_Block_max_elements]); - CHECK_ERR(res==FAILED, "Error read dir block in simplefs_remove"); - if(fh->fcb.is_dir==FILE) SimpleFS_removeFileOnDir(handle, (void*)fh, z); - else{ - memset(hand, 0, sizeof(DirectoryHandle)); - hand->sfs=handle->sfs; - hand->dcb=fh; - hand->directory=handle->dcb; - hand->current_block = &(fh->header); - hand->pos_in_block=0; - hand->pos_in_dir=0; - - if(hand->dcb->num_entries==0){ - res=DiskDriver_freeBlock(handle->sfs->disk, hand->dcb->header.block_in_disk); - CHECK_ERR(res==FAILED, "Failed to free block in simplefs_remove_rec"); - }else SimpleFS_remove_rec(hand); - } + // we deallocate the current Directory block + res = DiskDriver_freeBlock(handle->sfs->disk, handle->current_block->block_in_disk); + CHECK_ERR(res == FAILED, "Failed to free block in simplefs_remove_rec"); + // we go to the previous directory block + memset(db, 0, sizeof(DirectoryBlock)); + if (handle->current_block->block_in_file > 1) { + res = DiskDriver_readBlock(handle->sfs->disk, db, handle->current_block->previous_block); + CHECK_ERR(res == FAILED, "Error while traversing the directory") + memcpy(handle->current_block, &(db->header), sizeof(BlockHeader)); + } else { + memcpy(handle->current_block, &(handle->dcb->header), sizeof(BlockHeader)); } } - free(hand); - free(fh); + // we repeat the operations done in the directory block in the FDB + for (i = 0; i < FDB_max_elements && handle->dcb->file_blocks[i] != MISSING; i++) { + memset(fh, 0, sizeof(FirstDirectoryBlock)); + // we read the FDB/FFB to check whether the element is a file or a directory + res = DiskDriver_readBlock(handle->sfs->disk, fh, handle->dcb->file_blocks[i]); + CHECK_ERR(res == FAILED, "error reading file in dbs in remove_rec") + if (fh->fcb.is_dir == FILE) { + // if it's a file we remove it + res = SimpleFS_removeFile(handle->sfs, handle->dcb->file_blocks[i]); + CHECK_ERR(res == FAILED, "error removing file in dbs in remove_rec") + } else { + //if it's a directory we create a handle and call SimpleFS_remove_rec in it + memset(hand, 0, sizeof(DirectoryHandle)); + hand->sfs = handle->sfs; + hand->dcb = fh; + hand->directory = handle->dcb; + hand->current_block = malloc(sizeof(BlockHeader)); + memcpy(hand->current_block, &(fh->header), sizeof(BlockHeader)); + hand->pos_in_block = 0; + hand->pos_in_dir = 0; + // we check if the directory it's empty and in that case we deallocate it directly + if (hand->dcb->num_entries == 0) { + res = DiskDriver_freeBlock(handle->sfs->disk, hand->dcb->header.block_in_disk); + CHECK_ERR(res == FAILED, "Failed to free block in simplefs_remove_rec"); + } else SimpleFS_remove_rec(hand); + free(hand->current_block); + } + } + // now we deallocate the FDB which is now empty + res = DiskDriver_freeBlock(handle->sfs->disk, handle->dcb->header.block_in_disk); + CHECK_ERR(res == FAILED, "Failed to free block in simplefs_remove_rec"); + //we cleanup all the variables allocated free(db); + free(fh); + free(hand); - res=SimpleFS_removeChildDir(handle); - CHECK_ERR(res==FAILED, "Error in remove a child dir"); - - return SUCCESS; + return SUCCESS; } // we add a block in the index list of the file returning FAILED/SUCCESS -int SimpleFS_addIndex(FileHandle *f,int block){ - //we check that we have been given valid data - if(f==NULL || block<=0 || block>=f->sfs->disk->header->num_blocks){ +int SimpleFS_addIndex(FileHandle *f, int block) { +//we check that we have been given valid data + if (f == NULL || block <= 0 || block >= f->sfs->disk->header->num_blocks) { return FAILED; } - int i,res; - int FFB_max_entries=(BLOCK_SIZE-sizeof(FileControlBlock) - sizeof(BlockHeader)-sizeof(int)-sizeof(int))/sizeof(int); - int IB_max_entries=(BLOCK_SIZE-sizeof(BlockHeader))/sizeof(int); + int i, res; + int FFB_max_entries = + (BLOCK_SIZE - sizeof(FileControlBlock) - sizeof(BlockHeader) - sizeof(int) - sizeof(int)) / sizeof(int); + int IB_max_entries = (BLOCK_SIZE - sizeof(BlockHeader)) / sizeof(int); - //we use he current_index block to determine where we must put the new block - if(f->fcb->num_entries-FFB_max_entries<=0){ +//we use he current_index block to determine where we must put the new block + if (f->fcb->num_entries - FFB_max_entries <= 0) { //we search for a free spot in the FFB - for(i=0;ifcb->blocks[i]==MISSING){ - f->fcb->blocks[i]=block; + for (i = 0; i < FFB_max_entries; i++) { + if (f->fcb->blocks[i] == MISSING) { + f->fcb->blocks[i] = block; f->fcb->num_entries++; - res=DiskDriver_writeBlock(f->sfs->disk,f->fcb,f->fcb->header.block_in_disk); - CHECK_ERR(res==FAILED,"can't write the update to disk"); + res = DiskDriver_writeBlock(f->sfs->disk, f->fcb, f->fcb->header.block_in_disk); + CHECK_ERR(res == FAILED, "can't write the update to disk"); return SUCCESS; } } // if we get in here we need to allocate the 2nd index block - int new_index=DiskDriver_getFreeBlock(f->sfs->disk,0); - CHECK_ERR(new_index==FAILED,"can't get a new index block"); - Index *new_index_block=(Index*)malloc(sizeof(Index)); //////////////////////////////////////////////////////////////////////////////////// - new_index_block->header.block_in_disk=new_index; //////////////////////////////////////////////////////////////////////////////////// - new_index_block->header.next_block=MISSING; //////////////////////////////////////////////////////////////////////////////////// - new_index_block->header.previous_block=f->current_index_block->block_in_disk; //////////////////////////////////////////////////////////////////////////////////// - new_index_block->header.block_in_file=f->current_index_block->block_in_file +1;///////////////////////////////////////////////////////////////////////////////////// - new_index_block->indexes[0]=block; - for(i=1;iindexes[i]=MISSING; + int new_index = DiskDriver_getFreeBlock(f->sfs->disk, 0); + CHECK_ERR(new_index == FAILED, "can't get a new index block"); + Index *new_index_block = (Index *) malloc( + sizeof(Index)); + new_index_block->header.block_in_disk = new_index; + new_index_block->header.next_block = MISSING; + new_index_block->header.previous_block = f->current_index_block->block_in_disk; + new_index_block->header.block_in_file = f->current_index_block->block_in_file + + 1; + new_index_block->indexes[0] = block; + for (i = 1; i < IB_max_entries; i++) { + new_index_block->indexes[i] = MISSING; } //we update our current index block - memcpy(f->current_index_block,&(new_index_block->header),sizeof(BlockHeader)); + memcpy(f->current_index_block, &(new_index_block->header), sizeof(BlockHeader)); //now we write the new index block to disk - res=DiskDriver_writeBlock(f->sfs->disk,new_index_block,new_index); + res = DiskDriver_writeBlock(f->sfs->disk, new_index_block, new_index); free(new_index_block); - CHECK_ERR(res==FAILED,"can't write the 2nd index block"); + CHECK_ERR(res == FAILED, "can't write the 2nd index block"); //we update the FFB - f->fcb->next_IndexBlock=new_index; + f->fcb->next_IndexBlock = new_index; f->fcb->num_entries++; - res=DiskDriver_writeBlock(f->sfs->disk,f->fcb,f->fcb->header.block_in_disk); - CHECK_ERR(res==FAILED,"can't write the update to disk"); + res = DiskDriver_writeBlock(f->sfs->disk, f->fcb, f->fcb->header.block_in_disk); + CHECK_ERR(res == FAILED, "can't write the update to disk"); return SUCCESS; } - Index *index=(Index*)malloc(sizeof(Index)); //////////////////////////////////////////////////////////////////////////////////// - //if we get here we use the index block in current_index_block to add the index - res=DiskDriver_readBlock(f->sfs->disk,index,f->current_index_block->block_in_disk); - //block_in_file gia popolata in teoria - CHECK_ERR(res==FAILED,"can't load the current index block from disk"); - for(i=0;iindexes [i]==MISSING){ - index->indexes[i]=block; + Index *index = (Index *) malloc( + sizeof(Index)); +//if we get here we use the index block in current_index_block to add the index + res = DiskDriver_readBlock(f->sfs->disk, index, f->current_index_block->block_in_disk); + //block_in_file gia popolata in teoria + CHECK_ERR(res == FAILED, "can't load the current index block from disk"); + for (i = 0; i < IB_max_entries; i++) { + if (index->indexes[i] == MISSING) { + index->indexes[i] = block; f->fcb->num_entries++; - res=DiskDriver_writeBlock(f->sfs->disk,index,index->header.block_in_disk); //////////////////////////////////////////////////////////////////////////////////// + res = DiskDriver_writeBlock(f->sfs->disk, index, + index->header.block_in_disk); free(index); - CHECK_ERR(res==FAILED,"can't write the update to the current index block on disk"); - res=DiskDriver_writeBlock(f->sfs->disk,f->fcb,f->fcb->header.block_in_disk); - CHECK_ERR(res==FAILED,"can't write the update to disk"); + CHECK_ERR(res == FAILED, "can't write the update to the current index block on disk"); + res = DiskDriver_writeBlock(f->sfs->disk, f->fcb, f->fcb->header.block_in_disk); + CHECK_ERR(res == FAILED, "can't write the update to disk"); return SUCCESS; } } - //if we get here we need to allocate a new index block - int new_index=DiskDriver_getFreeBlock(f->sfs->disk,0); - CHECK_ERR(new_index==FAILED,"can't get a new index block"); - Index *new_index_block=(Index*)malloc(sizeof(Index)); //////////////////////////////////////////////////////////////////////////////////// - new_index_block->header.block_in_disk=new_index; //////////////////////////////////////////////////////////////////////////////////// - new_index_block->header.next_block=MISSING; - new_index_block->header.previous_block=f->current_index_block->block_in_disk; //////////////////////////////////////////////////////////////////////////// - new_index_block->header.block_in_file=f->current_index_block->block_in_file +1; //////////////////////////////////////////////////////////////////////////// - new_index_block->indexes[0]=block; - for(i=1;iindexes[i]=MISSING; +//if we get here we need to allocate a new index block + int new_index = DiskDriver_getFreeBlock(f->sfs->disk, 0); + CHECK_ERR(new_index == FAILED, "can't get a new index block"); + Index *new_index_block = (Index *) malloc( + sizeof(Index)); + new_index_block->header.block_in_disk = new_index; + new_index_block->header.next_block = MISSING; + new_index_block->header.previous_block = f->current_index_block->block_in_disk; + new_index_block->header.block_in_file = f->current_index_block->block_in_file + + 1; + new_index_block->indexes[0] = block; + for (i = 1; i < IB_max_entries; i++) { + new_index_block->indexes[i] = MISSING; } - //we update our current index block - memcpy(f->current_index_block,&(new_index_block->header),sizeof(BlockHeader)); - //now we write the new index block to disk - res=DiskDriver_writeBlock(f->sfs->disk,new_index_block,new_index); +//we update our current index block + memcpy(f->current_index_block, &(new_index_block->header), sizeof(BlockHeader)); +//now we write the new index block to disk + res = DiskDriver_writeBlock(f->sfs->disk, new_index_block, new_index); free(new_index_block); - CHECK_ERR(res==FAILED,"can't write the next index block"); - //we update the actual index block - index->header.next_block=new_index; - res=DiskDriver_writeBlock(f->sfs->disk,index,f->current_index_block->previous_block); + CHECK_ERR(res == FAILED, "can't write the next index block"); +//we update the actual index block + index->header.next_block = new_index; + res = DiskDriver_writeBlock(f->sfs->disk, index, f->current_index_block->previous_block); free(index); - CHECK_ERR(res==FAILED,"can't write the actual index block"); - // we update the FFB + CHECK_ERR(res == FAILED, "can't write the actual index block"); +// we update the FFB f->fcb->num_entries++; - res=DiskDriver_writeBlock(f->sfs->disk,f->fcb,f->fcb->header.block_in_disk); - CHECK_ERR(res==FAILED,"can't write the update to disk"); + res = DiskDriver_writeBlock(f->sfs->disk, f->fcb, f->fcb->header.block_in_disk); + CHECK_ERR(res == FAILED, "can't write the update to disk"); return SUCCESS; } //given the block num in the file it returns the block in disk/FAILED -int SimpleFS_getIndex(FileHandle *f,int block_in_file){ - //we check that we have been given valid data - if(f==NULL || block_in_file<0){ +int SimpleFS_getIndex(FileHandle *f, int block_in_file) { +//we check that we have been given valid data + if (f == NULL || block_in_file < 0) { return FAILED; } - int i,res,index_num,block_in_disk=FAILED; - int FFB_max_entries=(BLOCK_SIZE-sizeof(FileControlBlock) - sizeof(BlockHeader)-sizeof(int)-sizeof(int))/sizeof(int); - int IB_max_entries=(BLOCK_SIZE-sizeof(BlockHeader))/sizeof(int); - //firstly we need to get the number of the index which contains the block we need - if(block_in_filefcb->blocks[block_in_file-1]; - }else{ + block_in_disk = f->fcb->blocks[block_in_file - 1]; + } else { //if we get here we need to search in the other index blocks - Index *index=(Index*) malloc(sizeof(Index)); - if(f->current_index_block->block_in_filecurrent_index_block->block_in_file < index_num) { //we search for another index block after the current block - for(i=0;icurrent_index_block->next_block==MISSING){ + if (f->current_index_block->next_block == MISSING) { free(index); return FAILED; } //we read the index - res=DiskDriver_readBlock(f->sfs->disk,index,f->current_index_block->next_block); - if(res==FAILED){ + res = DiskDriver_readBlock(f->sfs->disk, index, f->current_index_block->next_block); + if (res == FAILED) { free(index); - CHECK_ERR(res==FAILED,"can't read the next index block"); + CHECK_ERR(res == FAILED, "can't read the next index block"); } //we update our current index block - memcpy(f->current_index_block,&(index->header),sizeof(BlockHeader)); + memcpy(f->current_index_block, &(index->header), sizeof(BlockHeader)); } - }else{ - if(f->current_index_block->block_in_file>index_num){ + } else { + if (f->current_index_block->block_in_file > index_num) { //we search for another index block before the current block - for(i=0;icurrent_index_block->previous_block==MISSING){ + if (f->current_index_block->previous_block == MISSING) { free(index); return FAILED; } //we read the index - res=DiskDriver_readBlock(f->sfs->disk,index,f->current_index_block->previous_block); - if(res==FAILED){ + res = DiskDriver_readBlock(f->sfs->disk, index, f->current_index_block->previous_block); + if (res == FAILED) { free(index); - CHECK_ERR(res==FAILED,"can't read the next index block"); + CHECK_ERR(res == FAILED, "can't read the next index block"); } //we update our current index block - memcpy(f->current_index_block,&(index->header),sizeof(BlockHeader)); + memcpy(f->current_index_block, &(index->header), sizeof(BlockHeader)); } - }else{ + } else { //if we get here we need to read only the current index block - res=DiskDriver_readBlock(f->sfs->disk,index,f->current_index_block->block_in_disk); - if(res==FAILED){ + res = DiskDriver_readBlock(f->sfs->disk, index, f->current_index_block->block_in_disk); + if (res == FAILED) { free(index); - CHECK_ERR(res==FAILED,"can't read the next index block"); + CHECK_ERR(res == FAILED, "can't read the next index block"); } } } //now we need to get the index from the found block - block_in_disk=index->indexes[(block_in_file-FFB_max_entries)-IB_max_entries*(f->current_index_block->block_in_file-1)-1]; + block_in_disk = index->indexes[(block_in_file - FFB_max_entries) - + IB_max_entries * (f->current_index_block->block_in_file - 1) - 1]; free(index); } return block_in_disk; } // this function clears the index list starting from the provided block in file -void SimpleFS_clearIndexes(FileHandle* f,int block_in_file){ - //we check that we have been given valid data - if(f==NULL || block_in_file<=0){ +void SimpleFS_clearIndexes(FileHandle *f, int block_in_file) { +//we check that we have been given valid data + if (f == NULL || block_in_file <= 0) { return; } - int i,res,stop=0; + int i, res, stop = 0; int displacement; - int FFB_max_entries=(BLOCK_SIZE-sizeof(FileControlBlock) - sizeof(BlockHeader)-sizeof(int)-sizeof(int))/sizeof(int); - int IB_max_entries=(BLOCK_SIZE-sizeof(BlockHeader))/sizeof(int); - - //we seek the block to adjust the current_index_block - res=SimpleFS_getIndex(f,block_in_file); - CHECK_ERR(res==FAILED,"can't clear find the first block to clear from indexes"); - Index *indexblock=(Index*)malloc(sizeof(Index)); //////////////////////////////////////////////////////////////////////////// - //c'è la read dovrebbe essere apposto block_in_file /////////////////////////// - //if we have the index in the FFB we start clearing from there - if(f->fcb->num_entries-FFB_max_entries<=0){ - displacement=block_in_file-1; - for(i=displacement;ifcb->blocks[i]==MISSING){ - stop=1; - }else{ - res=DiskDriver_freeBlock(f->sfs->disk,f->fcb->blocks[i]); - CHECK_ERR(res==FAILED,"can't free a block from disk"); - f->fcb->blocks[i]=MISSING; + int FFB_max_entries = + (BLOCK_SIZE - sizeof(FileControlBlock) - sizeof(BlockHeader) - sizeof(int) - sizeof(int)) / sizeof(int); + int IB_max_entries = (BLOCK_SIZE - sizeof(BlockHeader)) / sizeof(int); + +//we seek the block to adjust the current_index_block + res = SimpleFS_getIndex(f, block_in_file); + CHECK_ERR(res == FAILED, "can't clear find the first block to clear from indexes"); + Index *indexblock = (Index *) malloc( + sizeof(Index)); + //c'è la read dovrebbe essere apposto block_in_file +//if we have the index in the FFB we start clearing from there + if (f->fcb->num_entries - FFB_max_entries <= 0) { + displacement = block_in_file - 1; + for (i = displacement; i < FFB_max_entries && !stop; i++) { + if (f->fcb->blocks[i] == MISSING) { + stop = 1; + } else { + res = DiskDriver_freeBlock(f->sfs->disk, f->fcb->blocks[i]); + CHECK_ERR(res == FAILED, "can't free a block from disk"); + f->fcb->blocks[i] = MISSING; } } - }else{ + } else { //we load the current index block - res=DiskDriver_readBlock(f->sfs->disk,indexblock,f->current_index_block->block_in_disk); - CHECK_ERR(res==FAILED,"can't load the current index block"); - displacement=block_in_file-FFB_max_entries-IB_max_entries*(f->current_index_block->block_in_file-1)-1; - for(i=displacement;iindexes[i]==MISSING){ - stop=1; - }else{ - res=DiskDriver_freeBlock(f->sfs->disk,indexblock->indexes[i]); - CHECK_ERR(res==FAILED,"can't free a block from disk"); - indexblock->indexes[i]=MISSING; + res = DiskDriver_readBlock(f->sfs->disk, indexblock, f->current_index_block->block_in_disk); + CHECK_ERR(res == FAILED, "can't load the current index block"); + displacement = + block_in_file - FFB_max_entries - IB_max_entries * (f->current_index_block->block_in_file - 1) - 1; + for (i = displacement; i < IB_max_entries && !stop; i++) { + if (indexblock->indexes[i] == MISSING) { + stop = 1; + } else { + res = DiskDriver_freeBlock(f->sfs->disk, indexblock->indexes[i]); + CHECK_ERR(res == FAILED, "can't free a block from disk"); + indexblock->indexes[i] = MISSING; } } //we will remove any index blocks after the current block - indexblock->header.next_block=MISSING; + indexblock->header.next_block = MISSING; //we write the update on disk - res=DiskDriver_writeBlock(f->sfs->disk,indexblock,indexblock->header.block_in_disk); //////////////////////////////////////////////////////////////////////// - CHECK_ERR(res==FAILED,"can't write the index block on disk"); + res = DiskDriver_writeBlock(f->sfs->disk, indexblock, + indexblock->header.block_in_disk); + CHECK_ERR(res == FAILED, "can't write the index block on disk"); } - //now we update the number of entries - if(f->fcb->num_entries-FFB_max_entries<=0){ - f->fcb->num_entries=displacement-1; - }else{ - f->fcb->num_entries=f->current_index_block->block_in_file*IB_max_entries+displacement-1; +//now we update the number of entries + if (f->fcb->num_entries - FFB_max_entries <= 0) { + f->fcb->num_entries = displacement - 1; + } else { + f->fcb->num_entries = f->current_index_block->block_in_file * IB_max_entries + displacement - 1; } - //now we clear the eventual next index block which aren't used - while(f->current_index_block->next_block!=MISSING){ - res=DiskDriver_readBlock(f->sfs->disk,indexblock,f->current_index_block->next_block); - CHECK_ERR(res==FAILED,"can't load the current index block"); - for(i=0;iindexes[i]!=MISSING){ - res=DiskDriver_freeBlock(f->sfs->disk,indexblock->indexes[i]); - CHECK_ERR(res==FAILED,"can't free a block from disk"); +//now we clear the eventual next index block which aren't used + while (f->current_index_block->next_block != MISSING) { + res = DiskDriver_readBlock(f->sfs->disk, indexblock, f->current_index_block->next_block); + CHECK_ERR(res == FAILED, "can't load the current index block"); + for (i = 0; i < IB_max_entries; i++) { + if (indexblock->indexes[i] != MISSING) { + res = DiskDriver_freeBlock(f->sfs->disk, indexblock->indexes[i]); + CHECK_ERR(res == FAILED, "can't free a block from disk"); } } - res=DiskDriver_freeBlock(f->sfs->disk,indexblock->header.block_in_disk); ///////////////////////////////////////////////////////////////////// - CHECK_ERR(res==FAILED,"can't deallocate the index block") + res = DiskDriver_freeBlock(f->sfs->disk, + indexblock->header.block_in_disk); + CHECK_ERR(res == FAILED, "can't deallocate the index block") //we advance our current_index_block - memcpy(f->current_index_block,&(indexblock->header),sizeof(BlockHeader)); + memcpy(f->current_index_block, &(indexblock->header), sizeof(BlockHeader)); } free(indexblock); } diff --git a/simplefs_aux.h b/simplefs_aux.h index 61be465..52c4d3f 100644 --- a/simplefs_aux.h +++ b/simplefs_aux.h @@ -7,12 +7,9 @@ SearchResult* SimpleFS_search(DirectoryHandle* d, const char* name); // add a new entry in a directory structure void Dir_addentry(DirectoryHandle *d,int file_block); -// removes a file on disk +// removes a file on disk int SimpleFS_removeFile(SimpleFS *sfs, int file); -// removes passed directory from parent directory -int SimpleFS_removeChildDir(DirectoryHandle* handle); - // removes a file in directory structure int SimpleFS_removeFileOnDir(DirectoryHandle* dh, void* element, int pos_in_block); diff --git a/simplefs_test.c b/simplefs_test.c index 995c049..3c435bc 100755 --- a/simplefs_test.c +++ b/simplefs_test.c @@ -1,673 +1,661 @@ #include #include #include "simplefs.h" -#include -void disk_info(DiskDriver* disk){ +void disk_info(DiskDriver *disk) { printf("\t Disk summary\n"); - printf("disk blocks: %d\n",disk->header->num_blocks); - printf("disk free blocks: %d\n",disk->header->free_blocks); - printf("disk full blocks: %d\n",disk->header->num_blocks-disk->header->free_blocks); + printf("disk blocks: %d\n", disk->header->num_blocks); + printf("disk free blocks: %d\n", disk->header->free_blocks); + printf("disk full blocks: %d\n", disk->header->num_blocks - disk->header->free_blocks); } -void bitmap_info(DiskDriver *disk){ - int i,j,printed=0,print; - uint8_t mask; - printf("\t Bitmap info \n"); - print=disk->header->num_blocks; - for(i=0;i<(disk->header->num_blocks+7)/8;i++){ - mask=128; - printf("block %d:\n",i); - for(j=0;j<8 && printedbmap->entries[i])? '1' :'0')); - mask=mask>>1; - printed++; - } - printf("\n"); - } +void bitmap_info(DiskDriver *disk) { + int i, j, printed = 0, print; + uint8_t mask; + printf("\t Bitmap info \n"); + print = disk->header->num_blocks; + for (i = 0; i < (disk->header->num_blocks + 7) / 8; i++) { + mask = 128; + printf("block %d:\n", i); + for (j = 0; j < 8 && printed < print; j++) { + printf("%c", ((mask & disk->bmap->entries[i]) ? '1' : '0')); + mask = mask >> 1; + printed++; + } + printf("\n"); + } } //mode=0 writes on all blocks and and a non existent once //mode=1 read and frees all blocks -void driver_test(DiskDriver *disk, int mode){ +void driver_test(DiskDriver *disk, int mode) { - printf("\t DiskHeader info:\n"); - printf("num blocks: %d\n",disk->header->num_blocks ); - printf("num bitmap blocks: %d\n",disk->header->bitmap_blocks ); - printf("bitmap entries: %d\n",disk->header->bitmap_entries ); - printf("num free blocks: %d\n",disk->header->free_blocks ); - printf("first free block: %d\n",disk->header->first_free_block ); + printf("\t DiskHeader info:\n"); + printf("num blocks: %d\n", disk->header->num_blocks); + printf("num bitmap blocks: %d\n", disk->header->bitmap_blocks); + printf("bitmap entries: %d\n", disk->header->bitmap_entries); + printf("num free blocks: %d\n", disk->header->free_blocks); + printf("first free block: %d\n", disk->header->first_free_block); - disk_info(disk); + disk_info(disk); - printf("\t testing getFreeBlock\n"); + printf("\t testing getFreeBlock\n"); - int result, blockToWrite, i; - for(i=0; iheader->num_blocks && !mode; i++){ - // provare le altre funzioni - blockToWrite = DiskDriver_getFreeBlock(disk, i); - printf("disk_getFreeBlock result: %d\n", blockToWrite); + int result, blockToWrite, i; + for (i = 0; i < disk->header->num_blocks && !mode; i++) { + // provare le altre funzioni + blockToWrite = DiskDriver_getFreeBlock(disk, i); + printf("disk_getFreeBlock result: %d\n", blockToWrite); - printf("\t testing disk_write\n"); - char v[513] = ""; - result = DiskDriver_writeBlock(disk, v, blockToWrite); - printf("disk_write result: %d\n", result); - } + printf("\t testing disk_write\n"); + char v[513] = ""; + result = DiskDriver_writeBlock(disk, v, blockToWrite); + printf("disk_write result: %d\n", result); + } - printf("\t testing disk_flush\n"); - result = DiskDriver_flush(disk); - printf("flush result: %d\n", result); + printf("\t testing disk_flush\n"); + result = DiskDriver_flush(disk); + printf("flush result: %d\n", result); - if(mode) disk_info(disk); + if (mode) disk_info(disk); - for(i=0; iheader->num_blocks && mode; i++){ - printf("\t testing disk_read\n"); - char data[BLOCK_SIZE]; - result = DiskDriver_readBlock(disk, data, i); - printf("disk_read block num %d, result: %d\n", i, result); - printf("Data readed->%s<-end\n\n",data); - memset(data, 0, sizeof(data)); - } + for (i = 0; i < disk->header->num_blocks && mode; i++) { + printf("\t testing disk_read\n"); + char data[BLOCK_SIZE]; + result = DiskDriver_readBlock(disk, data, i); + printf("disk_read block num %d, result: %d\n", i, result); + printf("Data readed->%s<-end\n\n", data); + memset(data, 0, sizeof(data)); + } - if(mode) printf("\n\n\t testing disk_freeBlock\n"); + if (mode) printf("\n\n\t testing disk_freeBlock\n"); - for(i=disk->header->bitmap_blocks; iheader->num_blocks && mode; i++){ - result = DiskDriver_freeBlock(disk, i); - printf("libero il blocco: %d\nfreeBlock result: %d\n", i, result); + for (i = disk->header->bitmap_blocks; i < disk->header->num_blocks && mode; i++) { + result = DiskDriver_freeBlock(disk, i); + printf("libero il blocco: %d\nfreeBlock result: %d\n", i, result); - } + } - disk_info(disk); + disk_info(disk); - printf("\t testing disk_flush\n"); - result = DiskDriver_flush(disk); - printf("flush result: %d\n", result); + printf("\t testing disk_flush\n"); + result = DiskDriver_flush(disk); + printf("flush result: %d\n", result); - disk_info(disk); + disk_info(disk); } -void bitmap_test(DiskDriver *disk){ - printf("\t\t\t Testing bitmap module:\n"); - - printf("\t\t Testing BitMap_blockToIndex:\n"); - BitMapEntryKey t1,t2; - int b1=4,b2=11; - t1=BitMap_blockToIndex(b1); - printf("block: %d, entry_num: %d, bit_num: %d\n",b1,t1.entry_num,t1.bit_num); - t2=BitMap_blockToIndex(b2); - printf("block: %d, entry_num: %d, bit_num: %d\n",b2,t2.entry_num,t2.bit_num); - - printf("\t\t Testing BitMap_indexToBlock\n"); - b1=BitMap_indexToBlock(t1.entry_num,t1.bit_num); - printf("entry:%d, bit_num:%d, block: %d\n",t1.entry_num,t1.bit_num,b1); - b2=BitMap_indexToBlock(t2.entry_num,t2.bit_num); - printf("entry:%d, bit_num:%d, block: %d\n",t2.entry_num,t2.bit_num,b2); - - printf("\t\t Testing BitMap_get\n"); - b1=BitMap_get(disk->bmap,6,0); - printf("start:%d, status: %d, bit_num:%d\n",6,0,b1); - b2=BitMap_get(disk->bmap,8,0); - printf("start:%d, status:%d, bit_num:%d\n",8,0,b2); - - printf("\t\t Testing BitMap_test\n"); - b1=BitMap_test(disk->bmap,6); - printf("status:%d, bit_num:%d\n",6,b1); - b2=BitMap_test(disk->bmap,0); - printf("status:%d,bit_num:%d\n",0,b2); - - printf("\t\t Testing BitMap_set\n"); - BitMap_set(disk->bmap,10,1); - printf("status:%d, pos: %d\n",1,10); - BitMap_set(disk->bmap,5,1); - printf("status:%d, pos:%d\n",1,5); - disk_info(disk); - BitMap_set(disk->bmap,10,0); - printf("status:%d, pos: %d\n",0,10); - BitMap_set(disk->bmap,5,0); - printf("status:%d, pos:%d\n",0,5); - - disk_info(disk); +void bitmap_test(DiskDriver *disk) { + printf("\t\t\t Testing bitmap module:\n"); + + printf("\t\t Testing BitMap_blockToIndex:\n"); + BitMapEntryKey t1, t2; + int b1 = 4, b2 = 11; + t1 = BitMap_blockToIndex(b1); + printf("block: %d, entry_num: %d, bit_num: %d\n", b1, t1.entry_num, t1.bit_num); + t2 = BitMap_blockToIndex(b2); + printf("block: %d, entry_num: %d, bit_num: %d\n", b2, t2.entry_num, t2.bit_num); + + printf("\t\t Testing BitMap_indexToBlock\n"); + b1 = BitMap_indexToBlock(t1.entry_num, t1.bit_num); + printf("entry:%d, bit_num:%d, block: %d\n", t1.entry_num, t1.bit_num, b1); + b2 = BitMap_indexToBlock(t2.entry_num, t2.bit_num); + printf("entry:%d, bit_num:%d, block: %d\n", t2.entry_num, t2.bit_num, b2); + + printf("\t\t Testing BitMap_get\n"); + b1 = BitMap_get(disk->bmap, 6, 0); + printf("start:%d, status: %d, bit_num:%d\n", 6, 0, b1); + b2 = BitMap_get(disk->bmap, 8, 0); + printf("start:%d, status:%d, bit_num:%d\n", 8, 0, b2); + + printf("\t\t Testing BitMap_test\n"); + b1 = BitMap_test(disk->bmap, 6); + printf("status:%d, bit_num:%d\n", 6, b1); + b2 = BitMap_test(disk->bmap, 0); + printf("status:%d,bit_num:%d\n", 0, b2); + + printf("\t\t Testing BitMap_set\n"); + BitMap_set(disk->bmap, 10, 1); + printf("status:%d, pos: %d\n", 1, 10); + BitMap_set(disk->bmap, 5, 1); + printf("status:%d, pos:%d\n", 1, 5); + disk_info(disk); + BitMap_set(disk->bmap, 10, 0); + printf("status:%d, pos: %d\n", 0, 10); + BitMap_set(disk->bmap, 5, 0); + printf("status:%d, pos:%d\n", 0, 5); + + disk_info(disk); } -void diskdriver_test(DiskDriver* disk){ - - printf("\t\t\t Testing disk driver module:\n"); - printf("\t\t Testing disk_init:\n"); - //let's eliminate the previously created file if any - unlink("disk"); - //we create a new disk - DiskDriver_init(disk,"disk",10); - printf("associated file descriptor: %d\n",disk->fd); - driver_test(disk, 0); - //bitmap_test(&disk); - printf("disk drive shutdown\n"); - DiskDriver_shutdown(disk); - printf("\t\t Testing disk_load:\n"); - //now let's retest all the functions with an existing file - DiskDriver_load(disk,"disk"); - driver_test(disk, 1); - //bitmap_test(&disk); - printf("disk drive shutdown..."); - DiskDriver_shutdown(disk); - printf("done.\n"); +void diskdriver_test(DiskDriver *disk) { + + printf("\t\t\t Testing disk driver module:\n"); + printf("\t\t Testing disk_init:\n"); + //let's eliminate the previously created file if any + unlink("disk"); + //we create a new disk + DiskDriver_init(disk, "disk", 10); + printf("associated file descriptor: %d\n", disk->fd); + driver_test(disk, 0); + //bitmap_test(&disk); + printf("disk drive shutdown\n"); + DiskDriver_shutdown(disk); + printf("\t\t Testing disk_load:\n"); + //now let's retest all the functions with an existing file + DiskDriver_load(disk, "disk"); + driver_test(disk, 1); + //bitmap_test(&disk); + printf("disk drive shutdown..."); + DiskDriver_shutdown(disk); + printf("done.\n"); } -void format_test(SimpleFS* fs){ - printf("\t\t Testing SimpleFS_format:\n"); - SimpleFS_format(fs); - driver_test(fs->disk, 0); - DiskDriver_shutdown(fs->disk); - DiskDriver_load(fs->disk,fs->filename); - driver_test(fs->disk, 1); - DiskDriver_shutdown(fs->disk); +void format_test(SimpleFS *fs) { + printf("\t\t Testing SimpleFS_format:\n"); + SimpleFS_format(fs); + driver_test(fs->disk, 0); + DiskDriver_shutdown(fs->disk); + DiskDriver_load(fs->disk, fs->filename); + driver_test(fs->disk, 1); + DiskDriver_shutdown(fs->disk); } -void init_test(SimpleFS *fs){ - DirectoryHandle *dh; - int res; - printf("\t\t Testing SimpleFS_init:\n"); - SimpleFS_format(fs); - res=DiskDriver_load(fs->disk,fs->filename); - CHECK_ERR(res==FAILED,"can't load the fs"); - dh=SimpleFS_init(fs,fs->disk); - printf("now we print the directory handle\n"); - printf("simplefs: %p\n",dh->sfs); +void init_test(SimpleFS *fs) { + DirectoryHandle *dh; + int res; + printf("\t\t Testing SimpleFS_init:\n"); + SimpleFS_format(fs); + res = DiskDriver_load(fs->disk, fs->filename); + CHECK_ERR(res == FAILED, "can't load the fs"); + dh = SimpleFS_init(fs, fs->disk); + printf("now we print the directory handle\n"); + printf("simplefs: %p\n", dh->sfs); - printf("current_block: %p\n",dh->current_block); - printf("\t->prev block: %d\n",dh->current_block->previous_block); - printf("\t->next block: %d\n",dh->current_block->next_block); - printf("\t->block in file: %d\n",dh->current_block->block_in_file); + printf("current_block: %p\n", dh->current_block); + printf("\t->prev block: %d\n", dh->current_block->previous_block); + printf("\t->next block: %d\n", dh->current_block->next_block); + printf("\t->block in file: %d\n", dh->current_block->block_in_file); - printf("FirstDirectoryBlock: %p\n",dh->dcb); + printf("FirstDirectoryBlock: %p\n", dh->dcb); - printf("\t->FCB:\n"); - printf("\t\t->parent directory: %d\n",dh->dcb->fcb.directory_block); - printf("\t\t->name: %s\n",dh->dcb->fcb.name); - printf("\t\t->size in bytes: %d\n",dh->dcb->fcb.size_in_bytes); - printf("\t\t->size in blocks: %d\n",dh->dcb->fcb.size_in_blocks); - printf("\t\t->is dir: %d\n",dh->dcb->fcb.is_dir); + printf("\t->FCB:\n"); + printf("\t\t->parent directory: %d\n", dh->dcb->fcb.directory_block); + printf("\t\t->name: %s\n", dh->dcb->fcb.name); + printf("\t\t->size in bytes: %d\n", dh->dcb->fcb.size_in_bytes); + printf("\t\t->size in blocks: %d\n", dh->dcb->fcb.size_in_blocks); + printf("\t\t->is dir: %d\n", dh->dcb->fcb.is_dir); - printf("\t->num entries: %d\n",dh->dcb->num_entries); + printf("\t->num entries: %d\n", dh->dcb->num_entries); - printf("parent directory: %p\n",dh->directory); - printf("pos in block: %d\n",dh->pos_in_block); - printf("pos in dir: %d\n",dh->pos_in_dir); + printf("parent directory: %p\n", dh->directory); + printf("pos in block: %d\n", dh->pos_in_block); + printf("pos in dir: %d\n", dh->pos_in_dir); } -void createFile_openFile_closeFile_test(DirectoryHandle* dh){ + +void createFile_openFile_closeFile_test(DirectoryHandle *dh) { printf("\n\n\t\t Testing SimpleFS_createFile/openFile/closeFile\n\n"); - //firstly we create try to create two file with the same name to test if they are detected as files with the same name + //firstly we create try to create two file with the same name to test if they are detected as files with the same name printf("creating a file with 128 charaters name\n"); int i; char fname[128]; - for(i=0;i<127;i++){ - fname[i]='a'; + for (i = 0; i < 127; i++) { + fname[i] = 'a'; } - fname[127]='\0'; - FileHandle* fh=SimpleFS_createFile(dh,fname); - printf("result: %p\n",fh); + fname[127] = '\0'; + FileHandle *fh = SimpleFS_createFile(dh, fname); + printf("result: %p\n", fh); //cleanup of the allocated memory SimpleFS_close(fh); - SimpleFS_remove(dh,fname); + SimpleFS_remove(dh, fname); printf("we create a file with name: test\n"); - fh=SimpleFS_createFile(dh,"test"); - printf("result: %p\n",fh); + fh = SimpleFS_createFile(dh, "test"); + printf("result: %p\n", fh); //cleanup of the allocated memory SimpleFS_close(fh); - SimpleFS_remove(dh,"test"); - printf("creating a new file named test, for the 2nd time\n"); - fh=SimpleFS_createFile(dh,"test"); - printf("result: %p\n",fh); + SimpleFS_remove(dh, "test"); + printf("creating a new file named test, for the 2nd time\n"); + fh = SimpleFS_createFile(dh, "test"); + printf("result: %p\n", fh); - fh=SimpleFS_openFile(dh,"test"); - printf("opened file \"test\": %p\n",fh); + fh = SimpleFS_openFile(dh, "test"); + printf("opened file \"test\": %p\n", fh); printf("closing the file named \"test\"..."); SimpleFS_close(fh); printf("done\n"); - SimpleFS_remove(dh,"test"); + SimpleFS_remove(dh, "test"); } -void read_seek_write_test(DirectoryHandle* dh){ +void read_seek_write_test(DirectoryHandle *dh) { printf("\n\n\t\t Testing SimpleFS_write/SimpleFS_seek/SimpleFS_read\n\n"); - FileHandle *f=SimpleFS_createFile(dh,"rsw"); - char data1[1024],data2[1024]; - int i,res=1,out=0; - data1[1023]='\0'; - data2[1023]='\0'; - for(i=0;i<1023;i++){ - data1[i]='a'; + FileHandle *f = SimpleFS_createFile(dh, "rsw"); + char data1[1024], data2[1024]; + int i, res = 1, out = 0; + data1[1023] = '\0'; + data2[1023] = '\0'; + for (i = 0; i < 1023; i++) { + data1[i] = 'a'; } - memset(data2,0,1024*sizeof(char)); + memset(data2, 0, 1024 * sizeof(char)); printf("we read a void file\n"); - out=SimpleFS_read(f,data2,1024); - printf(":%s\n",data2); - printf("bytes read :%d\n",out); + out = SimpleFS_read(f, data2, 1024); + printf(":%s\n", data2); + printf("bytes read :%d\n", out); printf("we write a file then we read it and check if it's correct\n"); - out=SimpleFS_write(f,data1,1024); - printf("bytes written :%d\n",out); - res=SimpleFS_seek(f,0); - printf("seek result :%d\n",res); - out=SimpleFS_read(f,data2,1024); - printf(":%s\n",data2); - printf("bytes read :%d\n",out); - res=memcmp(data1,data2,1024*sizeof(char)); - printf("result :%d\n",res); - memset(data2,0,1024*sizeof(char)); + out = SimpleFS_write(f, data1, 1024); + printf("bytes written :%d\n", out); + res = SimpleFS_seek(f, 0); + printf("seek result :%d\n", res); + out = SimpleFS_read(f, data2, 1024); + printf(":%s\n", data2); + printf("bytes read :%d\n", out); + res = memcmp(data1, data2, 1024 * sizeof(char)); + printf("result :%d\n", res); + memset(data2, 0, 1024 * sizeof(char)); disk_info(f->sfs->disk); printf("now we move the cursor to 512 byte and we write and read\n"); - res=SimpleFS_seek(f,512); - printf("seek result :%d\n",res); - for(i=0;i<1023;i++){ - data1[i]='b'; + res = SimpleFS_seek(f, 512); + printf("seek result :%d\n", res); + for (i = 0; i < 1023; i++) { + data1[i] = 'b'; } - out=SimpleFS_write(f,data1,512); - printf("bytes written :%d\n",out); - res=SimpleFS_seek(f,512); - printf("seek result :%d\n",res); - out=SimpleFS_read(f,data2,512); - printf(":%s\n",data2); - printf("bytes read :%d\n",out); - res=memcmp(data1,data2,512*sizeof(char)); - printf("result :%d\n",res); - memset(data2,0,1024*sizeof(char)); + out = SimpleFS_write(f, data1, 512); + printf("bytes written :%d\n", out); + res = SimpleFS_seek(f, 512); + printf("seek result :%d\n", res); + out = SimpleFS_read(f, data2, 512); + printf(":%s\n", data2); + printf("bytes read :%d\n", out); + res = memcmp(data1, data2, 512 * sizeof(char)); + printf("result :%d\n", res); + memset(data2, 0, 1024 * sizeof(char)); disk_info(f->sfs->disk); printf("now we write another 512 bytes at the end of the file\n"); - res=SimpleFS_seek(f,1024); - printf("seek result :%d\n",res); - out=SimpleFS_write(f,data1+512,512); - printf("bytes written :%d\n",out); - res=SimpleFS_seek(f,1024); - printf("seek result :%d\n",res); - out=SimpleFS_read(f,data2+512,512); - printf(":%s\n",data2+512); - printf("bytes read :%d\n",out); - res=memcmp(data1+512,data2+512,512*sizeof(char)); - printf("result :%d\n",res); + res = SimpleFS_seek(f, 1024); + printf("seek result :%d\n", res); + out = SimpleFS_write(f, data1 + 512, 512); + printf("bytes written :%d\n", out); + res = SimpleFS_seek(f, 1024); + printf("seek result :%d\n", res); + out = SimpleFS_read(f, data2 + 512, 512); + printf(":%s\n", data2 + 512); + printf("bytes read :%d\n", out); + res = memcmp(data1 + 512, data2 + 512, 512 * sizeof(char)); + printf("result :%d\n", res); disk_info(f->sfs->disk); printf("we write a the begining of the file but we use less block than before\n"); - for(i=0;i<1023;i++){ - data1[i]='c'; - data2[i]='\0'; + for (i = 0; i < 1023; i++) { + data1[i] = 'c'; + data2[i] = '\0'; } - res=SimpleFS_seek(f,0); - printf("seek result :%d\n",res); - out=SimpleFS_write(f,data1,128); - printf("bytes written :%d\n",out); - res=SimpleFS_seek(f,0); - printf("seek result :%d\n",res); - out=SimpleFS_read(f,data2,128); - printf(":%s\n",data2); - printf("bytes read :%d\n",out); - res=memcmp(data1,data2,128*sizeof(char)); - printf("result :%d\n",res); + res = SimpleFS_seek(f, 0); + printf("seek result :%d\n", res); + out = SimpleFS_write(f, data1, 128); + printf("bytes written :%d\n", out); + res = SimpleFS_seek(f, 0); + printf("seek result :%d\n", res); + out = SimpleFS_read(f, data2, 128); + printf(":%s\n", data2); + printf("bytes read :%d\n", out); + res = memcmp(data1, data2, 128 * sizeof(char)); + printf("result :%d\n", res); disk_info(f->sfs->disk); printf("now we try to seek at the end of the file to test if it returns -1\n"); - res=SimpleFS_seek(f,2048); - printf("result :%d\n",res); + res = SimpleFS_seek(f, 2048); + printf("result :%d\n", res); SimpleFS_close(f); - SimpleFS_remove(dh,"rsw"); + SimpleFS_remove(dh, "rsw"); } -void readDir_test(DirectoryHandle *dh, int i){ - char* list; - int ret=SimpleFS_readDir(&list, dh); - if(ret==FAILED) printf("Errore in readDir_test\n"); - printf("\nList directory %d:\n%s\n\n",i,list); - free(list); +void readDir_test(DirectoryHandle *dh, int i) { + char *list; + int ret = SimpleFS_readDir(&list, dh); + if (ret == FAILED) printf("Errore in readDir_test\n"); + printf("\nList directory %d:\n%s\n\n", i, list); + free(list); } -void readDir_changeDir_mkDir_remove_test(DirectoryHandle* dh){ - printf("\n\n\t\tSimpleFS_readDir/changeDir/mkDir test\n\n"); - printf("SimpleFS_changeDir ..\n"); - int ret=SimpleFS_changeDir(dh, ".."); - if(ret==FAILED) printf("Errore in changeDir ..\n"); - readDir_test(dh,1); - char name[4]; - sprintf(name, "%d",9); - printf("SimpleFS_createFile 9\n"); - FileHandle* fh=SimpleFS_createFile(dh,name); - SimpleFS_close(fh); - readDir_test(dh,1); - SimpleFS_remove(dh,"9"); - printf("SimpleFS_mkDir ciao\n"); - ret=SimpleFS_mkDir(dh, "ciao"); - if(ret==FAILED) printf("Errore in mkDir_test1\n"); - if(ret!=FAILED) readDir_test(dh,2); - printf("SimpleFS_changeDir ciao\n"); - ret=SimpleFS_changeDir(dh, "ciao"); - if(ret==FAILED) printf("Errore in changeDir ciao\n"); - if(ret!=FAILED) readDir_test(dh,3); - sprintf(name, "%d",8); - printf("SimpleFS_createFile 8\n"); - fh=SimpleFS_createFile(dh,name); - SimpleFS_close(fh); - readDir_test(dh,4); - printf("SimpleFS_changeDir ..\n"); - ret=SimpleFS_changeDir(dh, ".."); - if(ret==FAILED) printf("Errore in changeDir ..\n"); - if(ret!=FAILED) readDir_test(dh,5); - - disk_info(dh->sfs->disk); - - printf("SimpleFS_changeDir ciao\n"); - ret=SimpleFS_changeDir(dh, "ciao"); - if(ret==FAILED) printf("Errore in changeDir ciao\n"); - if(ret!=FAILED) readDir_test(dh,6); - printf("SimpleFS_remove 8\n"); - ret=SimpleFS_remove(dh, name); - if(ret==FAILED) printf("Errore in remove 8\n"); - if(ret!=FAILED) readDir_test(dh,7); - printf("SimpleFS_changeDir ..\n"); - ret=SimpleFS_changeDir(dh, ".."); - if(ret==FAILED) printf("Errore in changeDir ..\n"); - if(ret!=FAILED) readDir_test(dh,8); - printf("SimpleFS_remove ciao\n"); - ret=SimpleFS_remove(dh, "ciao"); - if(ret==FAILED) printf("Errore in remove ciao\n"); - if(ret!=FAILED) readDir_test(dh,9); - - printf("SimpleFS_mkDir ciao\n"); - ret=SimpleFS_mkDir(dh, "ciao"); - if(ret==FAILED) printf("Errore in mkDir_test2\n"); - printf("SimpleFS_changeDir ciao\n"); - ret=SimpleFS_changeDir(dh, "ciao"); - if(ret==FAILED) printf("Errore in changeDir ciao\n"); - printf("SimpleFS_mkDir sotto ciao\n"); - ret=SimpleFS_mkDir(dh, "sotto ciao"); - sprintf(name, "%d",9); - printf("SimpleFS_createFile 9\n"); - fh=SimpleFS_createFile(dh,name); - SimpleFS_close(fh); - readDir_test(dh,12); - SimpleFS_remove(dh,name); - printf("SimpleFS_changeDir sotto ciao\n"); - ret=SimpleFS_changeDir(dh, "sotto ciao"); - sprintf(name, "%d",10); - printf("SimpleFS_createFile 10\n"); - fh=SimpleFS_createFile(dh,name); - SimpleFS_close(fh); - if(ret!=FAILED) readDir_test(dh,13); - SimpleFS_remove(dh,name); - printf("SimpleFS_changeDir ..\n"); - ret=SimpleFS_changeDir(dh, ".."); - if(ret==FAILED) printf("Errore in changeDir ..\n"); - if(ret!=FAILED) readDir_test(dh,14); - printf("SimpleFS_changeDir ..\n"); - ret=SimpleFS_changeDir(dh, ".."); - if(ret==FAILED) printf("Errore in changeDir ..\n"); - if(ret!=FAILED) readDir_test(dh,15); - - disk_info(dh->sfs->disk); - - printf("SimpleFS_remove ciao\n"); - ret=SimpleFS_remove(dh, "ciao"); - if(ret==FAILED) printf("Errore in remove ciao\n"); - if(ret!=FAILED) readDir_test(dh,16); - - disk_info(dh->sfs->disk); +void readDir_changeDir_mkDir_remove_test(DirectoryHandle *dh) { + printf("\n\n\t\tSimpleFS_readDir/changeDir/mkDir test\n\n"); + printf("SimpleFS_changeDir ..\n"); + int ret = SimpleFS_changeDir(dh, ".."); + if (ret == FAILED) printf("Errore in changeDir ..\n"); + readDir_test(dh, 1); + char name[4]; + sprintf(name, "%d", 9); + printf("SimpleFS_createFile 9\n"); + FileHandle *fh = SimpleFS_createFile(dh, name); + SimpleFS_close(fh); + readDir_test(dh, 1); + SimpleFS_remove(dh, "9"); + printf("SimpleFS_mkDir ciao\n"); + ret = SimpleFS_mkDir(dh, "ciao"); + if (ret == FAILED) printf("Errore in mkDir_test1\n"); + if (ret != FAILED) readDir_test(dh, 2); + printf("SimpleFS_changeDir ciao\n"); + ret = SimpleFS_changeDir(dh, "ciao"); + if (ret == FAILED) printf("Errore in changeDir ciao\n"); + if (ret != FAILED) readDir_test(dh, 3); + sprintf(name, "%d", 8); + printf("SimpleFS_createFile 8\n"); + fh = SimpleFS_createFile(dh, name); + SimpleFS_close(fh); + readDir_test(dh, 4); + printf("SimpleFS_changeDir ..\n"); + ret = SimpleFS_changeDir(dh, ".."); + if (ret == FAILED) printf("Errore in changeDir ..\n"); + if (ret != FAILED) readDir_test(dh, 5); + + disk_info(dh->sfs->disk); + + printf("SimpleFS_changeDir ciao\n"); + ret = SimpleFS_changeDir(dh, "ciao"); + if (ret == FAILED) printf("Errore in changeDir ciao\n"); + if (ret != FAILED) readDir_test(dh, 6); + printf("SimpleFS_remove 8\n"); + ret = SimpleFS_remove(dh, name); + if (ret == FAILED) printf("Errore in remove 8\n"); + if (ret != FAILED) readDir_test(dh, 7); + printf("SimpleFS_changeDir ..\n"); + ret = SimpleFS_changeDir(dh, ".."); + if (ret == FAILED) printf("Errore in changeDir ..\n"); + if (ret != FAILED) readDir_test(dh, 8); + printf("SimpleFS_remove ciao\n"); + ret = SimpleFS_remove(dh, "ciao"); + if (ret == FAILED) printf("Errore in remove ciao\n"); + if (ret != FAILED) readDir_test(dh, 9); + + printf("SimpleFS_mkDir ciao\n"); + ret = SimpleFS_mkDir(dh, "ciao"); + if (ret == FAILED) printf("Errore in mkDir_test2\n"); + printf("SimpleFS_changeDir ciao\n"); + ret = SimpleFS_changeDir(dh, "ciao"); + if (ret == FAILED) printf("Errore in changeDir ciao\n"); + printf("SimpleFS_mkDir sotto ciao\n"); + ret = SimpleFS_mkDir(dh, "sotto ciao"); + sprintf(name, "%d", 9); + printf("SimpleFS_createFile 9\n"); + fh = SimpleFS_createFile(dh, name); + SimpleFS_close(fh); + readDir_test(dh, 12); + SimpleFS_remove(dh, name); + printf("SimpleFS_changeDir sotto ciao\n"); + ret = SimpleFS_changeDir(dh, "sotto ciao"); + sprintf(name, "%d", 10); + printf("SimpleFS_createFile 10\n"); + fh = SimpleFS_createFile(dh, name); + SimpleFS_close(fh); + if (ret != FAILED) readDir_test(dh, 13); + SimpleFS_remove(dh, name); + printf("SimpleFS_changeDir ..\n"); + ret = SimpleFS_changeDir(dh, ".."); + if (ret == FAILED) printf("Errore in changeDir ..\n"); + if (ret != FAILED) readDir_test(dh, 14); + printf("SimpleFS_changeDir ..\n"); + ret = SimpleFS_changeDir(dh, ".."); + if (ret == FAILED) printf("Errore in changeDir ..\n"); + if (ret != FAILED) readDir_test(dh, 15); + + disk_info(dh->sfs->disk); + + printf("SimpleFS_remove ciao\n"); + ret = SimpleFS_remove(dh, "ciao"); + if (ret == FAILED) printf("Errore in remove ciao\n"); + if (ret != FAILED) readDir_test(dh, 16); + + disk_info(dh->sfs->disk); } -void cp_test(DirectoryHandle *dh){ +void cp_test(DirectoryHandle *dh) { printf("\n\n\t\t CP test\n\n"); disk_info(dh->sfs->disk); - readDir_test(dh,1); - printf("to test the FS we load a huge file from disk the real disk, we write it on our disk, we re-read it and check if it's correct\n"); - FileHandle *f=SimpleFS_createFile(dh,"test"); - int fd=open("./test/war_peace.txt",O_RDONLY,0666); - int dim = lseek(fd, 0, SEEK_END); + readDir_test(dh, 1); + printf( + "to test the FS we load a huge file from disk the real disk, we write it on our disk, we re-read it and check if it's correct\n"); + FileHandle *f = SimpleFS_createFile(dh, "test"); + int fd = open("./test/war_peace.txt", O_RDONLY, 0666); + int dim = (int) lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); - void *src=malloc(sizeof(char)*dim), *dst=malloc(sizeof(char)*dim); - read(fd,src,dim); - SimpleFS_write(f,src,dim*sizeof(char)); - SimpleFS_seek(f,0); - SimpleFS_read(f,dst,dim*sizeof(char)); - int res=memcmp(src,dst,dim*sizeof(char)); - printf("result: %d\n",res); + void *src = malloc(sizeof(char) * dim), *dst = malloc(sizeof(char) * dim); + read(fd, src, (size_t) dim); + SimpleFS_write(f, src, dim * sizeof(char)); + SimpleFS_seek(f, 0); + SimpleFS_read(f, dst, dim * sizeof(char)); + int res = memcmp(src, dst, dim * sizeof(char)); + printf("result: %d\n", res); SimpleFS_close(f); disk_info(dh->sfs->disk); - readDir_test(dh,1); + readDir_test(dh, 1); free(src); free(dst); printf("removing the file\n"); - SimpleFS_remove(dh,"test"); + SimpleFS_remove(dh, "test"); disk_info(dh->sfs->disk); - readDir_test(dh,1); + readDir_test(dh, 1); } -void cp_test_blocks(DirectoryHandle *dh){ - int finalres=0,res; +void cp_test_blocks(DirectoryHandle *dh) { + int finalres = 0, res; printf("to test the FS we load a file from disk we write it on our disk we re-read it and check if it's correct\n"); - printf("we use blocks of 512 bytes\n"); - FileHandle *f=SimpleFS_createFile(dh,"test1"); - int fd=open("./test/war_peace.txt",O_RDONLY,0666); - int i,dim = lseek(fd, 0, SEEK_END); + printf("we use blocks of 512 bytes\n"); + FileHandle *f = SimpleFS_createFile(dh, "test1"); + int fd = open("./test/war_peace.txt", O_RDONLY, 0666); + int i, dim = (int) lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); - int blocks=(dim+511)/512; - void *src=malloc(sizeof(char)*dim), *dst=malloc(sizeof(char)*dim); - for(i=0;isfs->disk); - - int i=0, ret=0, dim=800; - char name[4]; +void create_a_bigTree(DirectoryHandle *dh) { + printf("\n\n \t\t Creating a tree of nested direcories\n\n"); + disk_info(dh->sfs->disk); - for(i=0; isfs->disk); + disk_info(dh->sfs->disk); } -void remove_bigTree(DirectoryHandle* dh){ +void remove_bigTree(DirectoryHandle *dh) { - int ret=0; - readDir_test(dh,0); - printf("SimpleFS_remove 0\n"); - ret=SimpleFS_remove(dh, "0"); - if(ret==FAILED) printf("Errore in remove 0\n"); - if(ret!=FAILED) readDir_test(dh,0); + int ret = 0; + readDir_test(dh, 0); + printf("SimpleFS_remove 0\n"); + ret = SimpleFS_remove(dh, "0"); + if (ret == FAILED) printf("Errore in remove 0\n"); + if (ret != FAILED) readDir_test(dh, 0); - disk_info(dh->sfs->disk); + disk_info(dh->sfs->disk); } -void create_someDir(DirectoryHandle* dh){ +void create_someDir(DirectoryHandle *dh) { printf("\n\n\t\t Creating many directories in the same position\n\n"); - disk_info(dh->sfs->disk); - - int i=0, ret=0, dim=600; - char name[4]; - snprintf(name, 4*sizeof(char), "%d", i); - printf("SimpleFS_mkDir %s\n", name); - ret=SimpleFS_mkDir(dh, name); - if(ret==FAILED) printf("Errore in mkDir_test1\n"); - if(ret!=FAILED) readDir_test(dh,i); - printf("SimpleFS_changeDir %s\n",name); - ret=SimpleFS_changeDir(dh, name); - if(ret==FAILED) printf("Errore in changeDir %s\n", name); - - for(i=1; isfs->disk); + disk_info(dh->sfs->disk); + + int i = 0, ret = 0, dim = 600; + char name[4]; + snprintf(name, 4 * sizeof(char), "%d", i); + printf("SimpleFS_mkDir %s\n", name); + ret = SimpleFS_mkDir(dh, name); + if (ret == FAILED) printf("Errore in mkDir_test1\n"); + if (ret != FAILED) readDir_test(dh, i); + printf("SimpleFS_changeDir %s\n", name); + ret = SimpleFS_changeDir(dh, name); + if (ret == FAILED) printf("Errore in changeDir %s\n", name); + + for (i = 1; i < dim; i++) { + snprintf(name, 4 * sizeof(char), "%d", i); + //printf("SimpleFS_mkDir %s\n", name); + ret = SimpleFS_mkDir(dh, name); + if (ret == FAILED) printf("Errore in mkDir %s\n", name); + } + + if (ret != FAILED) readDir_test(dh, i); + + disk_info(dh->sfs->disk); } -void create_someFiles(DirectoryHandle* dh){ +void create_someFiles(DirectoryHandle *dh) { printf("\n\n\t\t Creating many files in the same position\n\n"); - int i=0, ret=0, dim=220,length=1024; - char name[4],data[length]; + int i = 0, ret = 0, dim = 220, length = 1024; + char name[4], data[length]; disk_info(dh->sfs->disk); - snprintf(name, 4*sizeof(char), "%d", i); - printf("SimpleFS_mkDir %s\n", name); - ret=SimpleFS_mkDir(dh, name); - if(ret==FAILED) printf("Errore in mkDir_test1\n"); - if(ret!=FAILED) readDir_test(dh,i); - printf("SimpleFS_changeDir %s\n",name); - ret=SimpleFS_changeDir(dh, name); - if(ret==FAILED) printf("Errore in changeDir %s\n", name); - - memset(data,65,sizeof(char)*length); - snprintf(name, 4*sizeof(char), "%d", i); + snprintf(name, 4 * sizeof(char), "%d", i); + printf("SimpleFS_mkDir %s\n", name); + ret = SimpleFS_mkDir(dh, name); + if (ret == FAILED) printf("Errore in mkDir_test1\n"); + if (ret != FAILED) readDir_test(dh, i); + printf("SimpleFS_changeDir %s\n", name); + ret = SimpleFS_changeDir(dh, name); + if (ret == FAILED) printf("Errore in changeDir %s\n", name); + + memset(data, 65, sizeof(char) * length); + snprintf(name, 4 * sizeof(char), "%d", i); FileHandle *f; - for(i=0; isfs->disk); } -void trunkedFile(DirectoryHandle *dh){ - printf("Test with trunced file to overwrite part of file."); - int finalres=0,res; - FileHandle *f=SimpleFS_openFile(dh,"test"); - // TODO command to create file for test this function - // cp war_peace.txt war_peace_trunc.txt - // truncate -s 1682569 war_peace_trunc.txt - int fd=open("./test/war_peace_trunc.txt",O_RDONLY,0666); - int i,dim = lseek(fd, 0, SEEK_END); +void trunkedFile(DirectoryHandle *dh) { + printf("Test with trunced file to overwrite part of file."); + int finalres = 0, res; + FileHandle *f = SimpleFS_openFile(dh, "test"); + //command to create file for test this function + // cp war_peace.txt war_peace_trunc.txt + // truncate -s 1682569 war_peace_trunc.txt + int fd = open("./test/war_peace_trunc.txt", O_RDONLY, 0666); + int i, dim = (int) lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); - int blocks=(dim+511)/512; - void *src=malloc(sizeof(char)*dim), *dst=malloc(sizeof(char)*dim); - int meta=f->fcb->fcb.size_in_bytes/2; - SimpleFS_seek(f, meta); - for(i=0;ifcb->fcb.size_in_bytes / 2; + SimpleFS_seek(f, meta); + for (i = 0; i < blocks; i++) { + read(fd, src + (512 * i), 512); + SimpleFS_write(f, src + (512 * i), 512 * sizeof(char)); + } + SimpleFS_seek(f, meta); + lseek(fd, 0, SEEK_SET); + for (i = 0; i < blocks; i++) { + read(fd, src + (512 * i), 512); + SimpleFS_read(f, dst + (512 * i), 512 * sizeof(char)); + res = memcmp(src + (512 * i), dst + (512 * i), 512 * sizeof(char)); + fprintf(stdout, "block %d,result: %d\n", i, res); + finalres |= res; + } + + printf("final result %d\n", finalres); SimpleFS_close(f); } int main(void) { - int res; - DiskDriver *disk=(DiskDriver*)malloc(sizeof(DiskDriver)); - SimpleFS *fs=(SimpleFS*)malloc(sizeof(SimpleFS)); - char diskname[]="./test/disk"; + int res; + DiskDriver *disk = (DiskDriver *) malloc(sizeof(DiskDriver)); + SimpleFS *fs = (SimpleFS *) malloc(sizeof(SimpleFS)); + char diskname[] = "./test/disk"; unlink(diskname); - fs->block_num=10000; - fs->filename=diskname; - fs->disk=disk; - - SimpleFS_format(fs); - res=DiskDriver_load(fs->disk,fs->filename); - CHECK_ERR(res==FAILED,"can't load the fs"); - DirectoryHandle *dh=SimpleFS_init(fs,disk); - disk_info(disk); - createFile_openFile_closeFile_test(dh); + fs->block_num = 20000; + fs->filename = diskname; + fs->disk = disk; + + SimpleFS_format(fs); + res = DiskDriver_load(fs->disk, fs->filename); + CHECK_ERR(res == FAILED, "can't load the fs"); + DirectoryHandle *dh = SimpleFS_init(fs, disk); + disk_info(disk); + createFile_openFile_closeFile_test(dh); read_seek_write_test(dh); - readDir_changeDir_mkDir_remove_test(dh); + readDir_changeDir_mkDir_remove_test(dh); cp_test(dh); // creating a tree of nested directories and deleting it //by deletion of the first directory which has been created - create_a_bigTree(dh); - DiskDriver_shutdown(disk); - res=DiskDriver_load(fs->disk,fs->filename); - CHECK_ERR(res==FAILED,"can't load the fs"); - dh=SimpleFS_init(fs,disk); - remove_bigTree(dh); - - //creating a tree of direcories in the same subdirectory - //and removing them y removing the direcorty which contains all of them - create_someDir(dh); - DiskDriver_shutdown(disk); - res=DiskDriver_load(fs->disk,fs->filename); - CHECK_ERR(res==FAILED,"can't load the fs"); - dh=SimpleFS_init(fs,disk); - remove_bigTree(dh); + create_a_bigTree(dh); + DiskDriver_shutdown(disk); + res = DiskDriver_load(fs->disk, fs->filename); + CHECK_ERR(res == FAILED, "can't load the fs"); + dh = SimpleFS_init(fs, disk); + remove_bigTree(dh); + + //creating a tree of directories in the same subdirectory + //and removing them y removing the directory which contains all of them + create_someDir(dh); + DiskDriver_shutdown(disk); + res = DiskDriver_load(fs->disk, fs->filename); + CHECK_ERR(res == FAILED, "can't load the fs"); + dh = SimpleFS_init(fs, disk); + remove_bigTree(dh); //creating a bunch of file and removing them //by removing the directory which contains them create_someFiles(dh); DiskDriver_shutdown(disk); - res=DiskDriver_load(fs->disk,fs->filename); - CHECK_ERR(res==FAILED,"can't load the fs"); - dh=SimpleFS_init(fs,disk); + res = DiskDriver_load(fs->disk, fs->filename); + CHECK_ERR(res == FAILED, "can't load the fs"); + dh = SimpleFS_init(fs, disk); remove_bigTree(dh); + cp_test_blocks(dh); + DiskDriver_shutdown(disk); + res = DiskDriver_load(fs->disk, fs->filename); + CHECK_ERR(res == FAILED, "can't load the fs"); + dh = SimpleFS_init(fs, disk); - /*char *src=(char*)malloc(sizeof(char)*512*200),*src2=(char*)malloc(sizeof(char)*1024); - m emset(src,65,*sizeof(char)*512*200); - memset(src,65,sizeof(char)*1024); - FileHandle *f=SimpleFS_createFile(dh,"test"); - SimpleFS_write(f,src,512*200); - SimpleFS_seek(f,512*100); - SimpleFS_write(f,src2,1024); - free(src); - free(src2);*/ - - /*cp_test_blocks(dh); - DiskDriver_shutdown(disk); - res=DiskDriver_load(fs->disk,fs->filename); - CHECK_ERR(res==FAILED,"can't load the fs"); - dh=SimpleFS_init(fs,disk); - trunkedFile(dh);*/ - - DiskDriver_shutdown(disk); - free(disk); - free(dh->dcb); + DiskDriver_shutdown(disk); + free(disk); + free(dh->dcb); free(dh->current_block); - free(dh); - free(fs); + free(dh); + free(fs); }