Messages in this thread Patch in this message | | | Date | Sun, 10 Jan 1999 15:53:38 +0100 (MET) | From | Daniel Pirkl <> | Subject | ufs & buffer cache - request for comments |
| |
Hallo everyone!
I am trying to resolve one bug in ufs. I would like to ask you for help and for comments.
UFS suport fragmentation of block - each block could be divided into several small fragments. At the end of files we don't allocate whole block, but only a few fragments. The problem appears, whe we need to add one fragment to the end of the some file, but requested fragment is already allocated - it is a part of another file. In this case we must move fragments inside last block of the file to another place.
Here is a patch. It seems working, but it may contain some bug.
Daniel
******************************************************************************** Daniel Pirkl, Charles University (Prague), Faculty of Mathematics and Physics hostel: kolej 17.listopadu, pokoj B601, Patkova 3, Praha 8 - Troja email: daniel.pirkl@email.cz, www: http://www.ms.mff.cuni.cz/~dpir3257/ ********************************************************************************
diff -urN linux-2.2.0-pre6/fs/buffer.c linux/fs/buffer.c --- linux-2.2.0-pre6/fs/buffer.c Fri Jan 8 00:06:59 1999 +++ linux/fs/buffer.c Sun Jan 10 15:26:49 1999 @@ -567,6 +567,21 @@ bh->b_pprev = bhp; } } +} + +void swap_buffers(struct buffer_head * bh1, struct buffer_head * bh2) +{ + int tmp; + + remove_from_queues(bh1); + remove_from_queues(bh2); + + tmp = bh1->b_blocknr; + bh1->b_blocknr = bh2->b_blocknr; + bh2->b_blocknr = tmp; + + insert_into_queues(bh1); + insert_into_queues(bh2); } struct buffer_head * find_buffer(kdev_t dev, int block, int size) diff -urN linux-2.2.0-pre6/fs/ufs/balloc.c linux/fs/ufs/balloc.c --- linux-2.2.0-pre6/fs/ufs/balloc.c Fri Oct 16 20:53:19 1998 +++ linux/fs/ufs/balloc.c Sun Jan 10 15:04:07 1999 @@ -241,7 +241,7 @@ struct super_block * sb; struct ufs_sb_private_info * uspi; struct ufs_super_block_first * usb1; - struct buffer_head * bh; + struct buffer_head * bh, * bh2; unsigned cgno, oldcount, newcount, tmp, request, i, result; unsigned swab; @@ -360,14 +360,20 @@ if (result) { for (i = 0; i < oldcount; i++) { bh = bread (sb->s_dev, tmp + i, sb->s_blocksize); - mark_buffer_clean (bh); - bh->b_blocknr = result + i; - mark_buffer_dirty (bh, 0); + bh2 = getblk (sb->s_dev, result + i, sb->s_blocksize); + memset (bh2->b_data, 0, sb->s_blocksize); + swap_buffers(bh, bh2); + mark_buffer_dirty (bh, 1); + mark_buffer_uptodate (bh2, 1); + mark_buffer_dirty (bh2, 1); if (IS_SYNC(inode)) { ll_rw_block (WRITE, 1, &bh); wait_on_buffer (bh); + ll_rw_block (WRITE, 1, &bh2); + wait_on_buffer (bh2); } brelse (bh); + brelse (bh2); } *p = SWAB32(result); *err = 0; diff -urN linux-2.2.0-pre6/include/linux/fs.h linux/include/linux/fs.h --- linux-2.2.0-pre6/include/linux/fs.h Sat Jan 9 00:54:33 1999 +++ linux/include/linux/fs.h Sun Jan 10 13:37:54 1999 @@ -844,6 +844,7 @@ extern struct buffer_head * bread(kdev_t dev, int block, int size); extern struct buffer_head * breada(kdev_t dev,int block, int size, unsigned int pos, unsigned int filesize); +extern void swap_buffers(struct buffer_head *, struct buffer_head *); extern int brw_page(int, struct page *, kdev_t, int [], int, int); diff -urN linux-2.2.0-pre6/kernel/ksyms.c linux/kernel/ksyms.c --- linux-2.2.0-pre6/kernel/ksyms.c Wed Jan 6 18:41:00 1999 +++ linux/kernel/ksyms.c Sun Jan 10 13:30:15 1999 @@ -154,6 +154,7 @@ EXPORT_SYMBOL(ll_rw_block); EXPORT_SYMBOL(__wait_on_buffer); EXPORT_SYMBOL(mark_buffer_uptodate); +EXPORT_SYMBOL(swap_buffers); EXPORT_SYMBOL(add_blkdev_randomness); EXPORT_SYMBOL(generic_file_read); EXPORT_SYMBOL(generic_file_write);
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |