Hi Andrew, Here is the simplified version of "nobh" support patch for ext3 writeback mode. I took out all the complicated logic and fallback to creating buffers in ext3_truncate_block_page() if needed.
Looks sane ? Can you include it in -mm tree ? Thanks, Badari
Signed-off-by: Badari Pulavarty <[EMAIL PROTECTED]> --- linux-2.6.11/fs/ext3/inode.c 2005-03-08 23:23:32.000000000 -0800 +++ linux-2.6.11.nobh/fs/ext3/inode.c 2005-03-08 23:34:38.000000000 -0800 @@ -1016,7 +1016,10 @@ retry: ret = PTR_ERR(handle); goto out; } - ret = block_prepare_write(page, from, to, ext3_get_block); + if (test_opt(inode->i_sb, NOBH)) + ret = nobh_prepare_write(page, from, to, ext3_get_block); + else + ret = block_prepare_write(page, from, to, ext3_get_block); if (ret) goto prepare_write_failed; @@ -1100,7 +1103,12 @@ static int ext3_writeback_commit_write(s new_i_size = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; if (new_i_size > EXT3_I(inode)->i_disksize) EXT3_I(inode)->i_disksize = new_i_size; - ret = generic_commit_write(file, page, from, to); + + if (test_opt(inode->i_sb, NOBH)) + ret = nobh_commit_write(file, page, from, to); + else + ret = generic_commit_write(file, page, from, to); + ret2 = ext3_journal_stop(handle); if (!ret) ret = ret2; @@ -1385,7 +1393,11 @@ static int ext3_writeback_writepage(stru goto out_fail; } - ret = block_write_full_page(page, ext3_get_block, wbc); + if (test_opt(inode->i_sb, NOBH)) + ret = nobh_writepage(page, ext3_get_block, wbc); + else + ret = block_write_full_page(page, ext3_get_block, wbc); + err = ext3_journal_stop(handle); if (!ret) ret = err; @@ -1646,13 +1658,28 @@ static int ext3_block_truncate_page(hand unsigned blocksize, iblock, length, pos; struct inode *inode = mapping->host; struct buffer_head *bh; - int err; + int err = 0; void *kaddr; blocksize = inode->i_sb->s_blocksize; length = blocksize - (offset & (blocksize - 1)); iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits); + /* + * For "nobh" option, we can only work if we don't need to + * read-in the page - otherwise we create buffers to do the IO. + */ + if (!page_has_buffers(page) && test_opt(inode->i_sb, NOBH)) { + if (PageUptodate(page)) { + kaddr = kmap_atomic(page, KM_USER0); + memset(kaddr + offset, 0, length); + flush_dcache_page(page); + kunmap_atomic(kaddr, KM_USER0); + set_page_dirty(page); + goto unlock; + } + } + if (!page_has_buffers(page)) create_empty_buffers(page, blocksize, 0); --- linux-2.6.11/fs/ext3/super.c 2005-03-01 23:38:38.000000000 -0800 +++ linux-2.6.11.nobh/fs/ext3/super.c 2005-03-08 08:06:09.000000000 -0800 @@ -576,7 +576,7 @@ enum { Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro, Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov, Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, - Opt_reservation, Opt_noreservation, Opt_noload, + Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, @@ -611,6 +611,7 @@ static match_table_t tokens = { {Opt_reservation, "reservation"}, {Opt_noreservation, "noreservation"}, {Opt_noload, "noload"}, + {Opt_nobh, "nobh"}, {Opt_commit, "commit=%u"}, {Opt_journal_update, "journal=update"}, {Opt_journal_inum, "journal=%u"}, @@ -924,6 +925,9 @@ clear_qf_name: match_int(&args[0], &option); *n_blocks_count = option; break; + case Opt_nobh: + set_opt(sbi->s_mount_opt, NOBH); + break; default: printk (KERN_ERR "EXT3-fs: Unrecognized mount option \"%s\" " @@ -1563,6 +1567,19 @@ static int ext3_fill_super (struct super break; } + if (test_opt(sb, NOBH)) { + if (sb->s_blocksize_bits != PAGE_CACHE_SHIFT) { + printk(KERN_WARNING "EXT3-fs: Ignoring nobh option " + "since filesystem blocksize doesn't match " + "pagesize\n"); + clear_opt(sbi->s_mount_opt, NOBH); + } + if (!(test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA)) { + printk(KERN_WARNING "EXT3-fs: Ignoring nobh option - " + "its supported only with writeback mode\n"); + clear_opt(sbi->s_mount_opt, NOBH); + } + } /* * The journal_load will have done any necessary log recovery, * so we can safely mount the rest of the filesystem now. --- linux-2.6.11/include/linux/ext3_fs.h 2005-03-01 23:38:10.000000000 -0800 +++ linux-2.6.11.nobh/include/linux/ext3_fs.h 2005-03-08 23:27:54.000000000 -0800 @@ -357,6 +357,7 @@ struct ext3_inode { #define EXT3_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */ #define EXT3_MOUNT_RESERVATION 0x10000 /* Preallocation */ #define EXT3_MOUNT_BARRIER 0x20000 /* Use block barriers */ +#define EXT3_MOUNT_NOBH 0x40000 /* No bufferheads */ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ #ifndef _LINUX_EXT2_FS_H