NFSv4.1/pnfs: Separate out metadata and data consistency for pNFS
authorTrond Myklebust <trond.myklebust@primarydata.com>
Wed, 25 Mar 2015 18:14:42 +0000 (14:14 -0400)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Fri, 27 Mar 2015 16:39:38 +0000 (12:39 -0400)
The LAYOUTCOMMIT operation means different things to different layout types.
For blocks and objects, it is both a data and metadata consistency operation.
For files and flexfiles, it is only a metadata consistency operation.

This patch separates out the 2 cases, allowing the files/flexfiles layout
drivers to optimise away the data consistency calls to layoutcommit.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
fs/nfs/blocklayout/blocklayout.c
fs/nfs/filelayout/filelayout.c
fs/nfs/flexfilelayout/flexfilelayout.c
fs/nfs/nfs4file.c
fs/nfs/objlayout/objio_osd.c
fs/nfs/pnfs.c
fs/nfs/pnfs.h
fs/nfs/pnfs_nfs.c
fs/nfs/write.c

index 1cac3c175d1870e63126c37ba4e1c377b5ffe5ca..d2554fe140a3e106fa93bf8d2f048fcad66a2730 100644 (file)
@@ -890,6 +890,7 @@ static struct pnfs_layoutdriver_type blocklayout_type = {
        .free_deviceid_node             = bl_free_deviceid_node,
        .pg_read_ops                    = &bl_pg_read_ops,
        .pg_write_ops                   = &bl_pg_write_ops,
+       .sync                           = pnfs_generic_sync,
 };
 
 static int __init nfs4blocklayout_init(void)
index a317b007e4361798b7f2df7d63a1faa6273f8b69..a46bf6de9ce455a97ef18275efe4906ac10e12ed 100644 (file)
@@ -1139,6 +1139,7 @@ static struct pnfs_layoutdriver_type filelayout_type = {
        .write_pagelist         = filelayout_write_pagelist,
        .alloc_deviceid_node    = filelayout_alloc_deviceid_node,
        .free_deviceid_node     = filelayout_free_deviceid_node,
+       .sync                   = pnfs_nfs_generic_sync,
 };
 
 static int __init nfs4filelayout_init(void)
index 92d2943e54f8f7dd0db1e2cd7aafb02bad4c3b70..f3ff66e4fb6ab0aabc8cd35d43333c66c82a5e96 100644 (file)
@@ -1509,6 +1509,7 @@ static struct pnfs_layoutdriver_type flexfilelayout_type = {
        .write_pagelist         = ff_layout_write_pagelist,
        .alloc_deviceid_node    = ff_layout_alloc_deviceid_node,
        .encode_layoutreturn    = ff_layout_encode_layoutreturn,
+       .sync                   = pnfs_nfs_generic_sync,
 };
 
 static int __init nfs4flexfilelayout_init(void)
index befe7a2c62843f31512fa4b98130d6f7a93d0c49..866842b048ef3f200e31caa5f974af519caf6001 100644 (file)
@@ -112,7 +112,7 @@ nfs4_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
                mutex_lock(&inode->i_mutex);
                ret = nfs_file_fsync_commit(file, start, end, datasync);
                if (!ret)
-                       ret = pnfs_layoutcommit_inode(inode, true);
+                       ret = pnfs_sync_inode(inode, !!datasync);
                mutex_unlock(&inode->i_mutex);
                /*
                 * If nfs_file_fsync_commit detected a server reboot, then
index 8b5e0e687d5e91607f8fa20d5e0bdfaed9d00a84..5aaed363556a66e7bd5bb43d4619d037108f5421 100644 (file)
@@ -637,6 +637,8 @@ static struct pnfs_layoutdriver_type objlayout_type = {
        .pg_read_ops             = &objio_pg_read_ops,
        .pg_write_ops            = &objio_pg_write_ops,
 
+       .sync                    = pnfs_generic_sync,
+
        .free_deviceid_node      = objio_free_deviceid_node,
 
        .encode_layoutcommit     = objlayout_encode_layoutcommit,
index c2ce2db771b7d2f2d47d57ea74e10fe7950e0d1e..3f0affebcf059252760582a0c6131b0930196250 100644 (file)
@@ -2231,6 +2231,13 @@ clear_layoutcommitting:
 }
 EXPORT_SYMBOL_GPL(pnfs_layoutcommit_inode);
 
+int
+pnfs_generic_sync(struct inode *inode, bool datasync)
+{
+       return pnfs_layoutcommit_inode(inode, true);
+}
+EXPORT_SYMBOL_GPL(pnfs_generic_sync);
+
 struct nfs4_threshold *pnfs_mdsthreshold_alloc(void)
 {
        struct nfs4_threshold *thp;
index 66bf5e1cf93d7c87c9600040d3966a6b79e00969..231eb23c22da00d453ccdfc7f55db47617f1484d 100644 (file)
@@ -155,6 +155,8 @@ struct pnfs_layoutdriver_type {
                               int how,
                               struct nfs_commit_info *cinfo);
 
+       int (*sync)(struct inode *inode, bool datasync);
+
        /*
         * Return PNFS_ATTEMPTED to indicate the layout code has attempted
         * I/O, else return PNFS_NOT_ATTEMPTED to fall back to normal NFS
@@ -267,6 +269,8 @@ bool pnfs_roc_drain(struct inode *ino, u32 *barrier, struct rpc_task *task);
 void pnfs_set_layoutcommit(struct inode *, struct pnfs_layout_segment *, loff_t);
 void pnfs_cleanup_layoutcommit(struct nfs4_layoutcommit_data *data);
 int pnfs_layoutcommit_inode(struct inode *inode, bool sync);
+int pnfs_generic_sync(struct inode *inode, bool datasync);
+int pnfs_nfs_generic_sync(struct inode *inode, bool datasync);
 int _pnfs_return_layout(struct inode *);
 int pnfs_commit_and_return_layout(struct inode *);
 void pnfs_ld_write_done(struct nfs_pgio_header *);
@@ -488,6 +492,14 @@ pnfs_ld_read_whole_page(struct inode *inode)
        return NFS_SERVER(inode)->pnfs_curr_ld->flags & PNFS_READ_WHOLE_PAGE;
 }
 
+static inline int
+pnfs_sync_inode(struct inode *inode, bool datasync)
+{
+       if (!pnfs_enabled_sb(NFS_SERVER(inode)))
+               return 0;
+       return NFS_SERVER(inode)->pnfs_curr_ld->sync(inode, datasync);
+}
+
 static inline bool
 pnfs_layoutcommit_outstanding(struct inode *inode)
 {
@@ -570,6 +582,12 @@ pnfs_ld_read_whole_page(struct inode *inode)
        return false;
 }
 
+static inline int
+pnfs_sync_inode(struct inode *inode, bool datasync)
+{
+       return 0;
+}
+
 static inline bool
 pnfs_roc(struct inode *ino)
 {
index 54e36b38fb5f89310287635e0838601ad07cf34a..64d2a5932f7b588d08e42d230c7ec5f6a25b21ae 100644 (file)
@@ -868,3 +868,13 @@ pnfs_layout_mark_request_commit(struct nfs_page *req,
        nfs_request_add_commit_list(req, list, cinfo);
 }
 EXPORT_SYMBOL_GPL(pnfs_layout_mark_request_commit);
+
+int
+pnfs_nfs_generic_sync(struct inode *inode, bool datasync)
+{
+       if (datasync)
+               return 0;
+       return pnfs_layoutcommit_inode(inode, true);
+}
+EXPORT_SYMBOL_GPL(pnfs_nfs_generic_sync);
+
index 849ed784d6ac1fc6b923c32278e089f87575b8db..7f933a39f3854f5b3ae4e8a64a23fc7b67763470 100644 (file)
@@ -1840,17 +1840,16 @@ EXPORT_SYMBOL_GPL(nfs_write_inode);
  */
 int nfs_wb_all(struct inode *inode)
 {
-       struct writeback_control wbc = {
-               .sync_mode = WB_SYNC_ALL,
-               .nr_to_write = LONG_MAX,
-               .range_start = 0,
-               .range_end = LLONG_MAX,
-       };
        int ret;
 
        trace_nfs_writeback_inode_enter(inode);
 
-       ret = sync_inode(inode, &wbc);
+       ret = filemap_write_and_wait(inode->i_mapping);
+       if (!ret) {
+               ret = nfs_commit_inode(inode, FLUSH_SYNC);
+               if (!ret)
+                       pnfs_sync_inode(inode, true);
+       }
 
        trace_nfs_writeback_inode_exit(inode, ret);
        return ret;