ChangeSet 1.2231.1.244, 2005/03/28 20:24:10-08:00, [EMAIL PROTECTED]

        [PATCH] ext3 writeback "nobh" option
        
        Add a `nobh' mount option to ext3 in writeback mode: avoid attaching
        buffer_head to data pages, like ext2.
        
        Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
        Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>



 fs/ext3/inode.c         |   37 +++++++++++++++++++++++++++++++++----
 fs/ext3/super.c         |   19 ++++++++++++++++++-
 include/linux/ext3_fs.h |    1 +
 3 files changed, 52 insertions(+), 5 deletions(-)


diff -Nru a/fs/ext3/inode.c b/fs/ext3/inode.c
--- a/fs/ext3/inode.c   2005-03-28 22:02:36 -08:00
+++ b/fs/ext3/inode.c   2005-03-28 22:02:36 -08:00
@@ -1016,7 +1016,10 @@
                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 @@
        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 @@
                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;
@@ -1484,6 +1496,8 @@
        journal_t *journal = EXT3_JOURNAL(page->mapping->host);
 
        WARN_ON(PageChecked(page));
+       if (!page_has_buffers(page))
+               return 0;
        return journal_try_to_free_buffers(journal, page, wait);
 }
 
@@ -1646,12 +1660,27 @@
        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);
diff -Nru a/fs/ext3/super.c b/fs/ext3/super.c
--- a/fs/ext3/super.c   2005-03-28 22:02:36 -08:00
+++ b/fs/ext3/super.c   2005-03-28 22:02:36 -08:00
@@ -576,7 +576,7 @@
        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 @@
        {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 @@
                        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\" "
@@ -1569,6 +1573,19 @@
                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.
diff -Nru a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
--- a/include/linux/ext3_fs.h   2005-03-28 22:02:36 -08:00
+++ b/include/linux/ext3_fs.h   2005-03-28 22:02:36 -08:00
@@ -357,6 +357,7 @@
 #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
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to