Example #1
0
File: fs.c Project: ren85/jos2006
// 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;
}	
Example #2
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.
	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;
	}
}
Example #3
0
File: fs.c Project: mainboy/xv6
// 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 ;
}
Example #4
0
File: fs.c Project: yaobaiwei/JOS
// 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;
	}
}
Example #5
0
File: fs.c Project: reesun/guavaos
// 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;
	}
}
Example #6
0
File: fs.c Project: darfux/jos
// 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;
	}
}