Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=9ff8ec32e58875022447af619bec6e5aee7c77e4
Commit:     9ff8ec32e58875022447af619bec6e5aee7c77e4
Parent:     5561093e2cac9f7d2a77e39cc689b8d2b7f9b2bc
Author:     Steven Whitehouse <[EMAIL PROTECTED]>
AuthorDate: Fri Sep 28 13:49:05 2007 +0100
Committer:  Steven Whitehouse <[EMAIL PROTECTED]>
CommitDate: Fri Jan 25 08:07:25 2008 +0000

    [GFS2] Split gfs2_writepage into three cases
    
    This patch splits gfs2_writepage into separate functions for each of
    the three cases: writeback, ordered and journalled. As a result
    it becomes a lot easier to see what each one is doing. The common
    code is moved into gfs2_writepage_common.
    
    This fixes a performance bug where we were doing more work than
    strictly required in the ordered write case.
    
    Signed-off-by: Steven Whitehouse <[EMAIL PROTECTED]>
---
 fs/gfs2/lops.c        |   17 ++++---
 fs/gfs2/ops_address.c |  112 +++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 101 insertions(+), 28 deletions(-)

diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 6c27cea..e901f8f 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -556,17 +556,20 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct 
gfs2_log_element *le)
 
        lock_buffer(bd->bd_bh);
        gfs2_log_lock(sdp);
-       if (!list_empty(&bd->bd_list_tr))
-               goto out;
-       tr->tr_touched = 1;
-       if (gfs2_is_jdata(ip)) {
-               tr->tr_num_buf++;
-               list_add(&bd->bd_list_tr, &tr->tr_list_buf);
+       if (tr) {
+               if (!list_empty(&bd->bd_list_tr))
+                       goto out;
+               tr->tr_touched = 1;
+               if (gfs2_is_jdata(ip)) {
+                       tr->tr_num_buf++;
+                       list_add(&bd->bd_list_tr, &tr->tr_list_buf);
+               }
        }
        if (!list_empty(&le->le_list))
                goto out;
 
-       __glock_lo_add(sdp, &bd->bd_gl->gl_le);
+       if (tr)
+               __glock_lo_add(sdp, &bd->bd_gl->gl_le);
        if (gfs2_is_jdata(ip)) {
                gfs2_pin(sdp, bd->bd_bh);
                tr->tr_num_databuf_new++;
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index 207014f..4bf73ed 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -103,16 +103,15 @@ static int gfs2_get_block_direct(struct inode *inode, 
sector_t lblock,
 }
 
 /**
- * gfs2_writepage - Write complete page
- * @page: Page to write
- *
- * Returns: errno
+ * gfs2_writepage_common - Common bits of writepage
+ * @page: The page to be written
+ * @wbc: The writeback control
  *
- * Some of this is copied from block_write_full_page() although we still
- * call it to do most of the work.
+ * Returns: 1 if writepage is ok, otherwise an error code or zero if no error.
  */
 
-static int gfs2_writepage(struct page *page, struct writeback_control *wbc)
+static int gfs2_writepage_common(struct page *page,
+                                struct writeback_control *wbc)
 {
        struct inode *inode = page->mapping->host;
        struct gfs2_inode *ip = GFS2_I(inode);
@@ -120,23 +119,94 @@ static int gfs2_writepage(struct page *page, struct 
writeback_control *wbc)
        loff_t i_size = i_size_read(inode);
        pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
        unsigned offset;
-       int error;
-       int done_trans = 0;
+       int ret = -EIO;
 
-       if (gfs2_assert_withdraw(sdp, gfs2_glock_is_held_excl(ip->i_gl))) {
-               unlock_page(page);
-               return -EIO;
-       }
+       if (gfs2_assert_withdraw(sdp, gfs2_glock_is_held_excl(ip->i_gl)))
+               goto out;
+       ret = 0;
        if (current->journal_info)
-               goto out_ignore;
-
+               goto redirty;
        /* Is the page fully outside i_size? (truncate in progress) */
-        offset = i_size & (PAGE_CACHE_SIZE-1);
+       offset = i_size & (PAGE_CACHE_SIZE-1);
        if (page->index > end_index || (page->index == end_index && !offset)) {
                page->mapping->a_ops->invalidatepage(page, 0);
-               unlock_page(page);
-               return 0; /* don't care */
+               goto out;
        }
+       return 1;
+redirty:
+       redirty_page_for_writepage(wbc, page);
+out:
+       unlock_page(page);
+       return 0;
+}
+
+/**
+ * gfs2_writeback_writepage - Write page for writeback mappings
+ * @page: The page
+ * @wbc: The writeback control
+ *
+ */
+
+static int gfs2_writeback_writepage(struct page *page,
+                                   struct writeback_control *wbc)
+{
+       int ret;
+
+       ret = gfs2_writepage_common(page, wbc);
+       if (ret <= 0)
+               return ret;
+
+       ret = mpage_writepage(page, gfs2_get_block_noalloc, wbc);
+       if (ret == -EAGAIN)
+               ret = block_write_full_page(page, gfs2_get_block_noalloc, wbc);
+       return ret;
+}
+
+/**
+ * gfs2_ordered_writepage - Write page for ordered data files
+ * @page: The page to write
+ * @wbc: The writeback control
+ *
+ */
+
+static int gfs2_ordered_writepage(struct page *page,
+                                 struct writeback_control *wbc)
+{
+       struct inode *inode = page->mapping->host;
+       struct gfs2_inode *ip = GFS2_I(inode);
+       int ret;
+
+       ret = gfs2_writepage_common(page, wbc);
+       if (ret <= 0)
+               return ret;
+
+       if (!page_has_buffers(page)) {
+               create_empty_buffers(page, inode->i_sb->s_blocksize,
+                                    (1 << BH_Dirty)|(1 << BH_Uptodate));
+       }
+       gfs2_page_add_databufs(ip, page, 0, inode->i_sb->s_blocksize-1);
+       return block_write_full_page(page, gfs2_get_block_noalloc, wbc);
+}
+
+/**
+ * gfs2_jdata_writepage - Write complete page
+ * @page: Page to write
+ *
+ * Returns: errno
+ *
+ */
+
+static int gfs2_jdata_writepage(struct page *page, struct writeback_control 
*wbc)
+{
+       struct inode *inode = page->mapping->host;
+       struct gfs2_inode *ip = GFS2_I(inode);
+       struct gfs2_sbd *sdp = GFS2_SB(inode);
+       int error;
+       int done_trans = 0;
+
+       error = gfs2_writepage_common(page, wbc);
+       if (error <= 0)
+               return error;
 
        if (PageChecked(page)) {
                error = gfs2_trans_begin(sdp, RES_DINODE + 1, 0);
@@ -838,7 +908,7 @@ cannot_release:
 }
 
 static const struct address_space_operations gfs2_writeback_aops = {
-       .writepage = gfs2_writepage,
+       .writepage = gfs2_writeback_writepage,
        .writepages = gfs2_writeback_writepages,
        .readpage = gfs2_readpage,
        .readpages = gfs2_readpages,
@@ -852,7 +922,7 @@ static const struct address_space_operations 
gfs2_writeback_aops = {
 };
 
 static const struct address_space_operations gfs2_ordered_aops = {
-       .writepage = gfs2_writepage,
+       .writepage = gfs2_ordered_writepage,
        .readpage = gfs2_readpage,
        .readpages = gfs2_readpages,
        .sync_page = block_sync_page,
@@ -866,7 +936,7 @@ static const struct address_space_operations 
gfs2_ordered_aops = {
 };
 
 static const struct address_space_operations gfs2_jdata_aops = {
-       .writepage = gfs2_writepage,
+       .writepage = gfs2_jdata_writepage,
        .readpage = gfs2_readpage,
        .readpages = gfs2_readpages,
        .sync_page = block_sync_page,
-
To unsubscribe from this list: send the line "unsubscribe git-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