]> git.hungrycats.org Git - linux/commitdiff
[PATCH] direct-to-BIO writeback for writeback-mode ext3
authorAndrew Morton <akpm@zip.com.au>
Sun, 2 Jun 2002 10:23:19 +0000 (03:23 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Sun, 2 Jun 2002 10:23:19 +0000 (03:23 -0700)
Turn on direct-to-BIO writeback for ext3 in data=writeback mode.

fs/ext3/inode.c
fs/ext3/namei.c
include/linux/ext3_fs.h
include/linux/ext3_jbd.h

index 7e3e8aed1ba44a8544897383f6f39e7633f9191f..aad5acd5d3811b6356c6f2a6680aec8db14380e4 100644 (file)
@@ -1389,6 +1389,34 @@ struct address_space_operations ext3_aops = {
        releasepage:    ext3_releasepage,       /* BKL not held.  Don't need */
 };
 
+/* For writeback mode, we can use mpage_writepages() */
+
+static int
+ext3_writepages(struct address_space *mapping, int *nr_to_write)
+{
+       int ret;
+       int err;
+
+       ret = write_mapping_buffers(mapping);
+       err = mpage_writepages(mapping, nr_to_write, ext3_get_block);
+       if (!ret)
+               ret = err;
+       return ret;
+}
+
+struct address_space_operations ext3_writeback_aops = {
+       readpage:       ext3_readpage,          /* BKL not held.  Don't need */
+       readpages:      ext3_readpages,         /* BKL not held.  Don't need */
+       writepage:      ext3_writepage,         /* BKL not held.  We take it */
+       writepages:     ext3_writepages,        /* BKL not held.  Don't need */
+       sync_page:      block_sync_page,
+       prepare_write:  ext3_prepare_write,     /* BKL not held.  We take it */
+       commit_write:   ext3_commit_write,      /* BKL not held.  We take it */
+       bmap:           ext3_bmap,              /* BKL held */
+       flushpage:      ext3_flushpage,         /* BKL not held.  Don't need */
+       releasepage:    ext3_releasepage,       /* BKL not held.  Don't need */
+};
+
 /*
  * ext3_block_truncate_page() zeroes out a mapping from file offset `from'
  * up to the end of the block which corresponds to `from'.
@@ -2159,7 +2187,10 @@ void ext3_read_inode(struct inode * inode)
        else if (S_ISREG(inode->i_mode)) {
                inode->i_op = &ext3_file_inode_operations;
                inode->i_fop = &ext3_file_operations;
-               inode->i_mapping->a_ops = &ext3_aops;
+               if (ext3_should_writeback_data(inode))
+                       inode->i_mapping->a_ops = &ext3_writeback_aops;
+               else
+                       inode->i_mapping->a_ops = &ext3_aops;
        } else if (S_ISDIR(inode->i_mode)) {
                inode->i_op = &ext3_dir_inode_operations;
                inode->i_fop = &ext3_dir_operations;
@@ -2168,7 +2199,10 @@ void ext3_read_inode(struct inode * inode)
                        inode->i_op = &ext3_fast_symlink_inode_operations;
                else {
                        inode->i_op = &page_symlink_inode_operations;
-                       inode->i_mapping->a_ops = &ext3_aops;
+                       if (ext3_should_writeback_data(inode))
+                               inode->i_mapping->a_ops = &ext3_writeback_aops;
+                       else
+                               inode->i_mapping->a_ops = &ext3_aops;
                }
        } else 
                init_special_inode(inode, inode->i_mode,
index a5a4ff23ece9bd00f3c56143a748bfc740fe3bbb..693bdd30ccbf5cc15aa716dbb3723af172a879f6 100644 (file)
@@ -510,7 +510,10 @@ static int ext3_create (struct inode * dir, struct dentry * dentry, int mode)
        if (!IS_ERR(inode)) {
                inode->i_op = &ext3_file_inode_operations;
                inode->i_fop = &ext3_file_operations;
-               inode->i_mapping->a_ops = &ext3_aops;
+               if (ext3_should_writeback_data(inode))
+                       inode->i_mapping->a_ops = &ext3_writeback_aops;
+               else
+                       inode->i_mapping->a_ops = &ext3_aops;
                ext3_mark_inode_dirty(handle, inode);
                err = ext3_add_nondir(handle, dentry, inode);
        }
@@ -985,7 +988,10 @@ static int ext3_symlink (struct inode * dir,
 
        if (l > sizeof (EXT3_I(inode)->i_data)) {
                inode->i_op = &page_symlink_inode_operations;
-               inode->i_mapping->a_ops = &ext3_aops;
+               if (ext3_should_writeback_data(inode))
+                       inode->i_mapping->a_ops = &ext3_writeback_aops;
+               else
+                       inode->i_mapping->a_ops = &ext3_aops;
                /*
                 * page_symlink() calls into ext3_prepare/commit_write.
                 * We have a transaction open.  All is sweetness.  It also sets
index f8630de86518c1efa22a9e916589eb08ff3d90f1..5847e06c102088c5a4ff95c86c3fa9448f51e2fd 100644 (file)
@@ -695,6 +695,7 @@ extern struct file_operations ext3_file_operations;
 
 /* inode.c */
 extern struct address_space_operations ext3_aops;
+extern struct address_space_operations ext3_writeback_aops;
 
 /* namei.c */
 extern struct inode_operations ext3_dir_inode_operations;
index ece9ec115665f3220f04059976f3fff81a954a84..05645eb7afca8325bd538cc1c52f1b3fe6ba19a7 100644 (file)
@@ -299,5 +299,10 @@ static inline int ext3_should_order_data(struct inode *inode)
        return (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA);
 }
 
+static inline int ext3_should_writeback_data(struct inode *inode)
+{
+       return !ext3_should_journal_data(inode) &&
+                       !ext3_should_order_data(inode);
+}
 
 #endif /* _LINUX_EXT3_JBD_H */