// Remove any blocks currently used by file 'f', // but not necessary for a file of size 'newsize'. // For both the old and new sizes, figure out the number of blocks required, // and then clear the blocks from new_nblocks to old_nblocks. // If the new_nblocks is no more than NDIRECT, and the indirect block has // been allocated (f->f_indirect != 0), then free the indirect block too. // (Remember to clear the f->f_indirect pointer so you'll know // whether it's valid!) // Do not change f->f_size. static void file_truncate_blocks(struct File *f, off_t newsize) { int r, i; uint32_t old_nblocks, new_nblocks; // Hint: Use file_clear_block and/or free_block. // LAB 5: Your code here. if(newsize >= f->f_size) return; new_nblocks = newsize/BLKSIZE; if (newsize % BLKSIZE) new_nblocks++; old_nblocks = f->f_size/BLKSIZE; if (f->f_size % BLKSIZE) old_nblocks++; for(i=new_nblocks; i<old_nblocks; i++) if((r = file_clear_block(f, i)) < 0) panic("file_truncate_blocks - couldn't free blocks!"); if(new_nblocks <= NDIRECT && old_nblocks > NDIRECT){ free_block(f->f_indirect); f->f_indirect = 0; } return; }
// Remove any blocks currently used by file 'f', // but not necessary for a file of size 'newsize'. // For both the old and new sizes, figure out the number of blocks required, // and then clear the blocks from new_nblocks to old_nblocks. // If the new_nblocks is no more than NDIRECT, and the indirect block has // been allocated (f->f_indirect != 0), then free the indirect block too. // (Remember to clear the f->f_indirect pointer so you'll know // whether it's valid!) // Do not change f->f_size. static void file_truncate_blocks(struct File *f, off_t newsize) { int r; uint32_t bno, old_nblocks, new_nblocks; // Hint: Use file_clear_block and/or free_block. for (old_nblocks = 0; old_nblocks < f->f_size; old_nblocks += BLKSIZE) ; old_nblocks /= BLKSIZE; for (new_nblocks = 0; new_nblocks < newsize; new_nblocks += BLKSIZE) ; new_nblocks /= BLKSIZE; cprintf("truncate from %d[%d] -> %d[%d].\n", f->f_size, new_nblocks, f->f_size, old_nblocks); for (bno = new_nblocks; bno <= old_nblocks; bno++) if ((r = file_clear_block(f, bno)) < 0) panic("file clear block error: %e\n", r); // Yeah, we need to clear the extra block as well if (new_nblocks < NDIRECT) { if (f->f_indirect != 0) { free_block(f->f_indirect); f->f_indirect = 0; } while (new_nblocks < NDIRECT) f->f_direct[new_nblocks++] = 0; } }
// Remove any blocks currently used by file 'f', // but not necessary for a file of size 'newsize'. // For both the old and new sizes, figure out the number of blocks required, // and then clear the blocks from new_nblocks to old_nblocks. // If the new_nblocks is no more than NDIRECT, and the indirect block has // been allocated (f->f_indirect != 0), then free the indirect block too. // (Remember to clear the f->f_indirect pointer so you'll know // whether it's valid!) // Do not change f->f_size. static void file_truncate_blocks(struct File *f, off_t newsize) { int r; uint32_t bno, old_nblocks, new_nblocks; // Hint: Use file_clear_block and/or free_block. // LAB 5: Your code here. old_nblocks = ROUNDUP(f->f_size,BLKSIZE) / BLKSIZE; new_nblocks = ROUNDUP(newsize, BLKSIZE) / BLKSIZE; for( bno = new_nblocks; bno < old_nblocks; bno ++) file_clear_block(f,bno); if(f->f_indirect != 0 && new_nblocks <= NDIRECT){ free_block(f->f_indirect); f->f_indirect = 0; } return ; }
// Remove any blocks currently used by file 'f', // but not necessary for a file of size 'newsize'. // For both the old and new sizes, figure out the number of blocks required, // and then clear the blocks from new_nblocks to old_nblocks. // If the new_nblocks is no more than NDIRECT, and the indirect block has // been allocated (f->f_indirect != 0), then free the indirect block too. // (Remember to clear the f->f_indirect pointer so you'll know // whether it's valid!) // Do not change f->f_size. static void file_truncate_blocks(struct File *f, off_t newsize) { // Hint: Use file_clear_block and/or free_block. // LAB 5: Your code here. int r; uint32_t bno, old_nblocks, new_nblocks; old_nblocks = (f->f_size + BLKSIZE - 1) / BLKSIZE; new_nblocks = (newsize + BLKSIZE - 1) / BLKSIZE; for (bno = new_nblocks; bno < old_nblocks; bno++) if ((r = file_clear_block(f, bno)) < 0) cprintf("warning: file_clear_block: %e", r); if (new_nblocks <= NDIRECT && f->f_indirect) { free_block(f->f_indirect); f->f_indirect = 0; } }
// Remove any blocks currently used by file 'f', // but not necessary for a file of size 'newsize'. // For both the old and new sizes, figure out the number of blocks required, // and then clear the blocks from new_nblocks to old_nblocks. // If the new_nblocks is no more than NDIRECT, and the indirect block has // been allocated (f->f_indirect != 0), then free the indirect block too. // (Remember to clear the f->f_indirect pointer so you'll know // whether it's valid!) // Do not change f->f_size. static void file_truncate_blocks(struct File *f, off_t newsize) { int r; char *blk; uint32_t bno, old_nblocks, new_nblocks; // Hint: Use file_clear_block and/or free_block. // LAB 5: Your code here. assert(f->f_size > newsize); old_nblocks = f->f_size / BLKSIZE; if (f->f_size % BLKSIZE) ++old_nblocks; new_nblocks = newsize / BLKSIZE; for (bno = new_nblocks; bno < old_nblocks; bno++) { r = file_clear_block(f, bno); if (r) panic("file_clear_block(): %e\n", r); if (bno < NDIRECT) { f->f_direct[bno] = 0; } else { assert(f->f_indirect != 0); if (!va_is_mapped(diskaddr(f->f_indirect))) { r = read_block(f->f_indirect, &blk); if (r) panic("read_block(): %e\n", r); } *(blk + bno) = 0; } } if (new_nblocks <= NDIRECT && f->f_indirect) { free_block(f->f_indirect); f->f_indirect = 0; } }
// Remove any blocks currently used by file 'f', // but not necessary for a file of size 'newsize'. // For both the old and new sizes, figure out the number of blocks required, // and then clear the blocks from new_nblocks to old_nblocks. // If the new_nblocks is no more than NDIRECT, and the indirect block has // been allocated (f->f_indirect != 0), then free the indirect block too. // (Remember to clear the f->f_indirect pointer so you'll know // whether it's valid!) // Do not change f->f_size. static void file_truncate_blocks(struct File *f, off_t newsize) { int error; uint32_t old_nblocks, new_nblocks; // Hint: Use file_clear_block and/or free_block. // LAB 5: Your code here. // panic("file_truncate_blocks not implemented"); int oldsize = f->f_size; // but not necessary for a file of size 'newsize'. if(newsize>oldsize) return; // For both the old and new sizes, figure out the number of blocks required, // and then clear the blocks from new_nblocks to old_nblocks. new_nblocks = DIV_ROUNDUP(newsize, BLKSIZE); old_nblocks = DIV_ROUNDUP(oldsize, BLKSIZE); int filebno; for(filebno=new_nblocks; filebno<old_nblocks; filebno++) { error = file_clear_block(f, filebno); if(error< 0) panic("free blocks fail"); } // If the new_nblocks is no more than NDIRECT, and the indirect block has // been allocated (f->f_indirect != 0), then free the indirect block too. // (Remember to clear the f->f_indirect pointer so you'll know // whether it's valid!) // if(new_nblocks<=NDIRECT && old_nblocks>NDIRECT) // { // free_block(f->f_indirect); // f->f_indirect = 0; // } //for ex6 4mb challenge int fileIndNoOld=0, fileIndNoNew=0; if(old_nblocks-NDIRECT>0) { fileIndNoOld = DIV_ROUNDUP(old_nblocks-NDIRECT, INDRECTMOUNT); } if(new_nblocks-NDIRECT>0) { fileIndNoNew = DIV_ROUNDUP(new_nblocks-NDIRECT, INDRECTMOUNT); } else { fileIndNoNew=0; } char* tmpblk; if ((error = read_block(f->f_indirect, &tmpblk) < 0)) { panic("wrong in truncating %e\n", error); } int tmp = fileIndNoOld-1; while(tmp-->0) { if ((error = read_block(tmpblk[0], &tmpblk) < 0)) { panic("wrong in truncating %e\n", error); } } int parent; char* parentblk; tmp = fileIndNoOld-fileIndNoNew; while(tmp-->0) { parent = ((int*)tmpblk)[1]; if ((error = read_block(tmpblk[1], &parentblk) < 0)) { panic("wrong in truncating %e\n", error); } if(parent!=-1) {//we set in block_walk free_block(parentblk[0]); } else {//reach the tail free_block(f->f_indirect); } tmpblk = parentblk; } }