static int remove_block(ospfs_inode_t *oi) { // current number of blocks in file uint32_t n = ospfs_size2nblocks(oi->oi_size); //the nth block is the one to remove if (n < 0 || n > OSPFS_MAXFILEBLKS) return -EIO; if (n == 0) return 0; n--; //just remove n and free the block if (n < OSPFS_NDIRECT) { free_block(oi->oi_direct[n]); oi->oi_direct[n] = 0; } // we have single indirection else if (n < OSPFS_NDIRECT + OSPFS_NINDIRECT) { // actual indirect block in memory uint32_t* indirect_block = (uint32_t *) ospfs_block(oi->oi_indirect); // free the direct block, data block is simply unbound after freeing the direct block free_block(indirect_block[direct_index(n)]); // set the block number of n in the indirect block to 0 indirect_block[direct_index(n)] = 0; // if we freed the last block indirected to, we free the indirect block and variable as well if (!direct_index(n)) { free_block(oi->oi_indirect); oi->oi_indirect = 0; } } // ugh, double indirection else { uint32_t* indirect2_block = (uint32_t *) ospfs_block(oi->oi_indirect2); uint32_t* indirect_block = (uint32_t *) ospfs_block(indirect2_block[indir_index(n)]); // free the direct block free_block(indirect_block[direct_index(n)]); indirect_block[direct_index(n)] = 0; if (direct_index(n) == 0) { free_block(indirect2_block[indir_index(n)]); indirect2_block[indir_index(n)] = 0; } if (indir_index(n) == 0) { free_block(oi->oi_indirect2); oi->oi_indirect2 = 0; } } oi->oi_size = oi->oi_size - OSPFS_BLKSIZE; return 0; }
static int remove_block(ospfs_inode_t *oi) { // current number of blocks in file uint32_t n = ospfs_size2nblocks(oi->oi_size); if(indir2_index(n)==0) { uint32_t *id2_block = ospfs_block(oi->oi_indirect2); uint32_t id2_off = indir_index(n); uint32_t *id_block = ospfs_block(id2_block[id2_off]); uint32_t d_off = direct_index(n); if(d_off == 0)//d_off == 0 means the direct is null which should make id2_block[id2_off] null { id2_block[id2_off] = NULL; if(id2_off == 0) oi->oi_indirect2 = NULL; } free_block(id_block[d_off]); id_block[d_off] = NULL; } else if(indir_index(n)==0) { uint32_t *id_block = ospfs_block(oi->oi_indirect); uint32_t d_off = direct_index(n); if(d_off == 0)//d_off == 0 means the direct is null which should make id2_block[id2_off] null { oi->oi_indirect = NULL; } free_block(id_block[d_off]); id_block[d_off] = NULL; } else { uint32_t d_off = direct_index(n); free_block(oi->oi_direct[d_off]); oi->oi_direct[d_off] = NULL; } /* EXERCISE: Your code here */ oi->oi_size = (n-1)*OSPFS_BLKSIZE; return 0; // Replace this line }
static int remove_block(ospfs_inode_t *oi) { // current number of blocks in file uint32_t n = ospfs_size2nblocks(oi->oi_size); /* EXERCISE: Your code here */ if(n < 0) return -EIO; else if(n == 0) return 0; int index = n-1; if(index < OSPFS_NDIRECT){ free_block(oi->oi_direct[index]); oi->oi_direct[index] = 0; } else if(index < OSPFS_NDIRECT + OSPFS_NINDIRECT && index > OSPFS_NDIRECT){ uint32_t* indirect_block = (uint32_t *)ospfs_block(oi->oi_indirect); free_block(indirect_block[direct_index(index)]); indirect_block[direct_index(index)] = 0; free_block(oi->oi_indirect); oi->oi_indirect = 0; } else if(index < OSPFS_MAXFILEBLKS){ uint32_t * indirect2_block = (uint32_t *) ospfs_block(oi->oi_indirect2); uint32_t * indirect_block = (uint32_t *) ospfs_block(indirect2_block[indir_index(index)]); free_block(indirect_block[direct_index(index)]); indirect_block[direct_index(index)] = 0; free_block(indirect2_block[indir_index(index)]); indirect2_block[indir_index(index)] = 0; free_block(oi->oi_indirect2); oi->oi_indirect2 = 0; } else return -EIO; oi->oi_size -= OSPFS_BLKSIZE; return 0; }
static int add_block(ospfs_inode_t *oi) { // current number of blocks in file uint32_t n = ospfs_size2nblocks(oi->oi_size); // keep track of allocations to free in case of -ENOSPC uint32_t *allocated[2] = { 0, 0 }; /* EXERCISE: Your code here */ int32_t direct = direct_index(n); int32_t ind = indir_index(n); int32_t ind2 = indir2_index(n); uint32_t addblock = 0; // case 1 - direct block if(ind == -1 && ind2 == -1) { addblock = allocate_block(); // check alloc success if(addblock == 0) { return -ENOSPC; } oi->oi_direct[n] = addblock; } // case 2 - indirect block else if(ind == 0 && ind2 == -1) { return -ENOSPC; } // case 3 - indirect2 block else if(ind2 == 0) { return -ENOSPC; } else return -EIO; // Replace this line oi->oi_size += OSPFS_BLKSIZE; }
static int remove_block(ospfs_inode_t *oi) { // current number of blocks in file uint32_t n = ospfs_size2nblocks(oi->oi_size); if (n < 0) return -EIO; // no blocks to remove else if (n == 0) return 0; n = n - 1; // index starts at 0 // direct block range if (n < OSPFS_NDIRECT) { // free direct block free_block(oi->oi_direct[n]); oi->oi_direct[n] = 0; } // indirect block range else if (n < OSPFS_NDIRECT + OSPFS_NINDIRECT) { uint32_t* indir = (uint32_t *) ospfs_block(oi->oi_indirect); // free direct block free_block(indir[direct_index(n)]); indir[direct_index(n)] = 0; // free indirect block if possible if (direct_index(n) == 0) { free_block(oi->oi_indirect); oi->oi_indirect = 0; } } // indirect^2 block range else if (n < OSPFS_MAXFILEBLKS) { uint32_t* indir2 = (uint32_t *) ospfs_block(oi->oi_indirect2); uint32_t* indir = (uint32_t *) ospfs_block(indir2[indir_index(n)]); // free direct block free_block(indir[direct_index(n)]); indir[direct_index(n)] = 0; // free indirect block if possible if (direct_index(n) == 0) { free_block(indir2[indir_index(n)]); indir2[indir_index(n)] = 0; } // free indirect^2 block if possible if (indir_index(n) == 0) { free_block(oi->oi_indirect2); oi->oi_indirect2 = 0; } } else return -EIO; // n > OSPFS_MAXFILEBLKS // update filesize oi->oi_size -= OSPFS_BLKSIZE; return 0; }
static int add_block(ospfs_inode_t *oi) { // current number of blocks in file uint32_t n = ospfs_size2nblocks(oi->oi_size); // keep track of allocations to free in case of -ENOSPC uint32_t allocated[2] = { 0, 0 }; uint32_t direct, indir; if (n < 0) return -EIO; // direct block range else if (n < OSPFS_NDIRECT) { // allocate block direct = allocate_block(); if (!direct) return -ENOSPC; memset(ospfs_block(direct), 0, OSPFS_BLKSIZE); // add block oi->oi_direct[n] = direct; } // indirect block range else if (n < OSPFS_NDIRECT + OSPFS_NINDIRECT) { // allocate new indirect block if necessary if (!oi->oi_indirect) { // allocate block allocated[0] = allocate_block(); if (!allocated[0]) return -ENOSPC; memset(ospfs_block(allocated[0]), 0, OSPFS_BLKSIZE); // set as indirect block oi->oi_indirect = allocated[0]; } // allocate direct block direct = allocate_block(); if (!direct) { if (allocated[0]) { free_block(allocated[0]); oi->oi_indirect = 0; } return -ENOSPC; } memset(ospfs_block(direct), 0, OSPFS_BLKSIZE); // add to indirect block ((uint32_t*) ospfs_block(oi->oi_indirect))[direct_index(n)] = direct; } // indirect^2 block range else if (n < OSPFS_MAXFILEBLKS) { // allocate new indirect^2 block if necessary if (!oi->oi_indirect2) { // allocate block allocated[0] = allocate_block(); if (!allocated[0]) return -ENOSPC; memset(ospfs_block(allocated[0]), 0, OSPFS_BLKSIZE); // set as indirect^2 block oi->oi_indirect2 = allocated[0]; } indir = ((uint32_t *) ospfs_block(oi->oi_indirect2))[indir_index(n)]; // allocate new indirect block if necessary if (!indir) { // allocate block allocated[1] = allocate_block(); if (!allocated[1]) { if (allocated[0]) free_block(allocated[0]); return -ENOSPC; } memset(ospfs_block(allocated[1]), 0, OSPFS_BLKSIZE); // add to indirect^2 blocks indir = allocated[1]; } // allocate direct block direct = allocate_block(); if (!direct) { if (allocated[0]) { free_block(allocated[0]); oi->oi_indirect2 = 0; } if (allocated[1]) free_block(allocated[1]); return -ENOSPC; } memset(ospfs_block(direct), 0, OSPFS_BLKSIZE); // add to indirect blocks ((uint32_t *) ospfs_block(indir))[direct_index(n)] = direct; } else return -ENOSPC; // n >= OSPFS_MAXFILEBLKS // update filesize oi->oi_size += OSPFS_BLKSIZE; return 0; }
static int add_block(ospfs_inode_t *oi) { // current number of blocks in file uint32_t n = ospfs_size2nblocks(oi->oi_size); /*// Number of direct block pointers in 'struct ospfs_inode'. #define OSPFS_NDIRECT 10 // Number of block pointers in an indirect block. #define OSPFS_NINDIRECT (OSPFS_BLKSIZE / 4) // Maximum number of blocks in a file. #define OSPFS_MAXFILEBLKS */ // keep track of allocations to free in case of -ENOSPC uint32_t *allocated[2] = { 0, 0 }; uint32_t id1, id2, d; /* EXERCISE: Your code here */ if(indir2_index(n)==0)//oi_indirect2 { uint32_t* id2_block = NULL; //which contains the table of indirect pointer if(oi->oi_indirect2 == NULL) { id2 = allocate_block(); if(id2 == 0)//allocation failure return -ENOSPC; allocated[0] = id2; oi->oi_indirect2 = allocated[0]; id2_block = ospfs_block(oi->oi_indirect2); memset(id2_block, 0, OSPFS_BLKSIZE); } else id2_block = ospfs_block(oi->oi_indirect2); uint32_t id2_off = indir_index(n); if(id2_block[id2_off] == NULL) { id1 = allocate_block(); if(id1 == 0)//which means we need to erase the allocation of block of indirect { if(allocated[0]) { free_block(oi->oi_indirect2); oi->oi_indirect2 = NULL; } return -ENOSPC; } allocated[1] = id1; id2_block[id2_off] = allocated[1]; } //then we traverse to the direct pointer uint32_t *d_block = ospfs_block(id2_block[id2_off]); uint32_t d_off = direct_index(n); //check if the d_off direct pointer is valid if((d_block[d_off] = allocate_block()) == 0) { if(allocated[0]) { free_block(allocated[0]); oi->oi_indirect2 = NULL; } if(allocated[1]) { free_block(allocated[1]); id2_block[id2_off] = NULL; } return -ENOSPC; } oi->oi_size = (n+1)*OSPFS_BLKSIZE; return 0; } else if(indir_index(n) == 0)//if for indirect block { uint32_t *id_block; if(oi->oi_indirect == NULL) { id1 = allocate_block(); if(id1 == 0)//allocation failure return -ENOSPC; allocated[0] = id1; oi->oi_indirect = allocated[0]; id_block = ospfs_block(oi->oi_indirect); memset(id_block, 0, OSPFS_BLKSIZE); } else id_block = ospfs_block(oi->oi_indirect); uint32_t d_off = direct_index(n); if((id_block[d_off] = allocate_block()) == 0) { if(allocated[0]) { free_block(allocated[0]); oi->oi_indirect = NULL; } return -ENOSPC; } oi->oi_size = (n+1)*OSPFS_BLKSIZE; return 0; } else { if((oi->oi_direct[n] = allocate_block()) == 0) return -ENOSPC; else { oi->oi_size = (n+1)*OSPFS_BLKSIZE; return 0; } //return -EIO; } }
static int remove_block(ospfs_inode_t *oi) { // current number of blocks in file uint32_t n = ospfs_size2nblocks(oi->oi_size); /* EXERCISE: Your code here */ //If file is empty if(n <= 0){ return -EIO; } if(indir2_index(n) == -1){ if(indir_index(n) == -1){ free_block(oi->oi_direct[n]); oi->oi_direct[n] = 0; }else if(indir_index(n) == 0){ //Indirect block should exist if(oi->oi_indirect <= 0){ return -EIO; } //Deallocate block uint32_t *indir_ptr = ospfs_block(oi->oi_indirect); free_block(indir_ptr[direct_index(n)]); indir_ptr[direct_index(n)] = 0; //Deallocate indirect block if have to if(n == OSPFS_NDIRECT+1){ free_block(oi->oi_indirect); oi->oi_indirect = 0; } } }else{ //Indirect2 block should exist if(oi->oi_indirect2 <= 0){ return -EIO; } //Deallocate block uint32_t *indir2_ptr = ospfs_block(oi->oi_indirect2); uint32_t *indir_ptr = ospfs_block(indir2_ptr[indir_index(n)]); free_block(indir_ptr[(n-OSPFS_NDIRECT-OSPFS_NINDIRECT) % OSPFS_NINDIRECT]); indir_ptr[(n-OSPFS_NDIRECT-OSPFS_NINDIRECT) % OSPFS_NINDIRECT] = 0; //Deallocate indirect block if have to if((n-OSPFS_NDIRECT-OSPFS_NINDIRECT) % OSPFS_NINDIRECT == 1){ free_block(indir2_ptr[indir_index(n)]); indir2_ptr[indir_index(n)] = 0; } //Deallocate indirect2 block if have to if(n == OSPFS_NDIRECT + OSPFS_NINDIRECT + 1){ free_block(oi->oi_indirect2); oi->oi_indirect2 = 0; } } oi->oi_size = OSPFS_BLKSIZE * (n-1); return 0; }
static int add_block(ospfs_inode_t *oi) { // current number of blocks in file uint32_t n = ospfs_size2nblocks(oi->oi_size); /* EXERCISE: Your code here */ //Max blocks already in use if(n >= OSPFS_MAXFILEBLKS){ return -ENOSPC; } uint32_t block = allocate_block(); if(block == 0){ return -ENOSPC; } zero_block(block); //Don't need indirect2 block if(indir2_index(n) == -1){ //Don't need indirect block if(indir_index(n) == -1){ oi->oi_direct[n] = block; //Need indirect block }else if(indir_index(n) == 0){ //Need to allocate new indirect block if(n == OSPFS_NDIRECT){ uint32_t indir = allocate_block(); if(indir == 0){ free_block(block); return -ENOSPC; } zero_block(indir); oi->oi_indirect = indir; } //Add in new block number into indirect block uint32_t *indir_ptr = ospfs_block(oi->oi_indirect); indir_ptr[direct_index(n)] = block; } //Need indirect2 block }else{ //Preset these values, so that if freed and unchanged nothing happens uint32_t indir = -1; uint32_t indir2 = -1; //Need to allocate new indirect2 block if(n == OSPFS_NDIRECT + OSPFS_NINDIRECT){ indir2 = allocate_block(); if(indir2 == 0){ free_block(block); return -ENOSPC; } zero_block(indir2); oi->oi_indirect2 = indir2; } uint32_t *indir2_ptr = ospfs_block(oi->oi_indirect2); //Need to allocate new indirect block if((n-OSPFS_NDIRECT-OSPFS_NINDIRECT) % OSPFS_NINDIRECT == 0){ uint32_t indir = allocate_block(); if(indir == 0){ free_block(block); free_block(indir2); return -ENOSPC; } zero_block(indir); indir2_ptr[indir_index(n)] = indir; }else{ indir = indir2_ptr[indir_index(n)]; } uint32_t *indir_ptr = ospfs_block(indir); indir_ptr[(n-OSPFS_NDIRECT-OSPFS_NINDIRECT) % OSPFS_NINDIRECT] = block; } oi->oi_size = OSPFS_BLKSIZE * (n+1); return 0; }
static int add_block(ospfs_inode_t *oi) { // current number of blocks in file uint32_t n = ospfs_size2nblocks(oi->oi_size); // keep track of allocations to free in case of -ENOSPC uint32_t *allocated[2] = { 0, 0 }; uint32_t direct, indirect; // direct block if (indir_index(n) == -1) { // allocate new direct block direct = allocate_block(); if (!direct) return -ENOSPC; // zeroes the allocated block memset(ospfs_block(direct), 0, OSPFS_BLKSIZE); // add to oi oi->oi_direct[n] = direct; } // singly indirect else if ((indir_index(n) == 0) && (indir2_index(n) == -1)) { // first time allocating indirect block // add oi->oi_indirect if (direct_index(n) == 0) { allocated[0] = allocate_block(); if (!allocated[0]) return -ENOSPC; // zeroes the allocated array memset(ospfs_block(allocated[0]), 0, OSPFS_BLKSIZE); oi->oi_indirect = allocated[0]; } // create block direct = allocate_block(); if (!direct) { free_block(allocated[0]); free_block(direct); oi->oi_indirect = 0; return -ENOSPC; } // zeroes the allocated array memset(ospfs_block(direct), 0, OSPFS_BLKSIZE); // add to oi ((uint32_t*) ospfs_block(oi->oi_indirect))[direct_index(n)] = direct; } // double indirection else { // first time doing double indirection if (n == (OSPFS_NINDIRECT + OSPFS_NDIRECT)) { allocated[0] = allocate_block(); if (!allocated[0]) return -ENOSPC; // zeroes the allocated array memset(ospfs_block(allocated[0]), 0, OSPFS_BLKSIZE); oi->oi_indirect2 = allocated[0]; } // allocate new indirect block if necessary if (direct_index(n) == 0) { allocated[1] = allocate_block(); if (!allocated[1]) { // free previously allocated double indirect block if (allocated[0]) { free_block(allocated[0]); oi->oi_indirect2 = 0; } return -ENOSPC; } // zeroes the allocated array memset(ospfs_block(allocated[1]), 0, OSPFS_BLKSIZE); } // create block direct = allocate_block(); if (!direct) { // if we allocated double indirect block if (!allocated[0]) { free_block(allocated[0]); free_block(allocated[1]); oi->oi_indirect2 = 0; return -ENOSPC; } // if we only allocated a single indirect block if (!allocated[1]) { free_block(allocated[1]); } } memset(ospfs_block(direct), 0, OSPFS_BLKSIZE); // add to oi ((uint32_t*) ospfs_block(oi->oi_indirect2))[indir_index(n)] = allocated[1]; ((uint32_t*) ((uint32_t*) ospfs_block(oi->oi_indirect2))[indir_index(n)])[direct_index(n)] = direct; } oi->oi_size = oi->oi_size + OSPFS_BLKSIZE; return 0; /* DONE: Your code here */ }
static int add_block(ospfs_inode_t *oi) { // current number of blocks in file uint32_t n = ospfs_size2nblocks(oi->oi_size); // keep track of allocations to free in case of -ENOSPC uint32_t allocated[2] = { 0, 0 }; uint32_t direct_block, indirect_block; /* EXERCISE: Your code here */ if(n < 0) return -EIO; else if(n < OSPFS_NDIRECT){ //direct block domain direct_block = allocate_block(); if(!direct_block) return -ENOSPC; memset(ospfs_block(direct_block), 0, OSPFS_BLKSIZE); oi->oi_direct[n] = direct_block; } else if(n < OSPFS_NDIRECT + OSPFS_NINDIRECT){//indirect block domain if(!oi->oi_indirect){ //allocate a new indirect block allocated[0] = allocate_block(); if(!allocated[0]) return -ENOSPC; memset(ospfs_block(allocated[0]), 0, OSPFS_BLKSIZE); oi->oi_indirect = allocated[0]; } direct_block = allocate_block(); if(!direct_block){ oi->oi_indirect = 0; free_block(allocated[0]); return -ENOSPC; } memset(ospfs_block(direct_block),0, OSPFS_BLKSIZE); ((uint32_t *)ospfs_block(oi->oi_indirect))[direct_index(n)] = direct_block; } else if(n > OSPFS_NDIRECT + OSPFS_NINDIRECT && n < OSPFS_MAXFILEBLKS){ // double indirect domain if(!oi->oi_indirect2){ allocated[1] = allocate_block(); if(!allocated[1]) return -ENOSPC; memset(ospfs_block(allocated[1]), 0, OSPFS_BLKSIZE); oi->oi_indirect2 = allocated[1]; } indirect_block = ((uint32_t *) ospfs_block(oi->oi_indirect2))[indir_index(n)]; if(!indirect_block){ allocated[0] = allocate_block(); if(!allocated[0]){ free_block(allocated[1]); return -ENOSPC; } memset(ospfs_block(allocated[0]),0, OSPFS_BLKSIZE); indirect_block = allocated[0]; } direct_block = allocate_block(); if(!direct_block){ free_block(allocated[0]); free_block(allocated[1]); oi->oi_indirect2 = 0; return -ENOSPC; } memset(ospfs_block(direct_block),0,OSPFS_BLKSIZE); ((uint32_t*) ospfs_block(indirect_block))[direct_index(n)] = direct_block; } else return -ENOSPC; oi->oi_size += OSPFS_BLKSIZE; return 0; }