]> git.hungrycats.org Git - linux/commitdiff
[PATCH] ext3_commit_write speedup
authorAndrew Morton <akpm@digeo.com>
Thu, 3 Apr 2003 00:29:28 +0000 (16:29 -0800)
committerLinus Torvalds <torvalds@home.transmeta.com>
Thu, 3 Apr 2003 00:29:28 +0000 (16:29 -0800)
For an appending write, ext3_commit_write() will call the expensive
ext3_mark_inode_dirty() twice.  Once in generic_commit_write()'s extension of
i_size and once in ext3_commit_write() itself where i_disksize is updated.

But by updating i_disksize _before_ calling generic_commit_write() these can
be piggybacked.

The patch takes the overhead of a write() from 1.96 microseconds down to
1.63.

fs/ext3/inode.c

index ab6c9572ee243cecab344249c310aa09f6e3cde7..68554298db42070d7dc19e9e9bd1127f44e11c6b 100644 (file)
@@ -1165,6 +1165,12 @@ static int ext3_commit_write(struct file *file, struct page *page,
                if (pos > inode->i_size)
                        inode->i_size = pos;
                EXT3_I(inode)->i_state |= EXT3_STATE_JDATA;
+               if (inode->i_size > EXT3_I(inode)->i_disksize) {
+                       EXT3_I(inode)->i_disksize = inode->i_size;
+                       ret2 = ext3_mark_inode_dirty(handle, inode);
+                       if (!ret) 
+                               ret = ret2;
+               }
        } else {
                if (ext3_should_order_data(inode)) {
                        ret = walk_page_buffers(handle, page_buffers(page),
@@ -1172,14 +1178,18 @@ static int ext3_commit_write(struct file *file, struct page *page,
                }
                /* Be careful here if generic_commit_write becomes a
                 * required invocation after block_prepare_write. */
-               if (ret == 0)
+               if (ret == 0) {
+                       /*
+                        * generic_commit_write() will run mark_inode_dirty()
+                        * if i_size changes.  So let's piggyback the
+                        * i_disksize mark_inode_dirty into that.
+                        */
+                       loff_t 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 (inode->i_size > EXT3_I(inode)->i_disksize) {
-               EXT3_I(inode)->i_disksize = inode->i_size;
-               ret2 = ext3_mark_inode_dirty(handle, inode);
-               if (!ret) 
-                       ret = ret2;
+               }
        }
        ret2 = ext3_journal_stop(handle);
        unlock_kernel();