nfs42: serialize LAYOUTSTATS calls of the same file
authorPeng Tao <tao.peng@primarydata.com>
Tue, 23 Jun 2015 11:52:03 +0000 (19:52 +0800)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Wed, 24 Jun 2015 14:53:11 +0000 (10:53 -0400)
There is no need to report concurrently.

Reviewed-by: Jeff Layton <jeff.layton@primarydata.com>
Signed-off-by: Peng Tao <tao.peng@primarydata.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
fs/nfs/nfs42proc.c
fs/nfs/pnfs.c
include/linux/nfs_fs.h

index ee0248340a429b01ef48331e3832582316f6c8cf..06c74cd9387566ff57c2b8a23109b7895d215755 100644 (file)
@@ -204,6 +204,9 @@ nfs42_layoutstat_release(void *calldata)
                nfss->pnfs_curr_ld->cleanup_layoutstats(data);
 
        pnfs_put_layout_hdr(NFS_I(data->args.inode)->layout);
+       smp_mb__before_atomic();
+       clear_bit(NFS_INO_LAYOUTSTATS, &NFS_I(data->args.inode)->flags);
+       smp_mb__after_atomic();
        nfs_iput_and_deactive(data->inode);
        kfree(data->args.devinfo);
        kfree(data);
index 6279cff7df74aaf56bf476206395fa838b91616f..5b5224341bcd13b7a88b395a42aa77d809905004 100644 (file)
@@ -2257,6 +2257,7 @@ pnfs_report_layoutstat(struct inode *inode)
 {
        struct pnfs_layoutdriver_type *ld = NFS_SERVER(inode)->pnfs_curr_ld;
        struct nfs_server *server = NFS_SERVER(inode);
+       struct nfs_inode *nfsi = NFS_I(inode);
        struct nfs42_layoutstat_data *data;
        struct pnfs_layout_hdr *hdr;
        int status = 0;
@@ -2264,6 +2265,9 @@ pnfs_report_layoutstat(struct inode *inode)
        if (!pnfs_enabled_sb(server) || !ld->prepare_layoutstats)
                goto out;
 
+       if (test_and_set_bit(NFS_INO_LAYOUTSTATS, &nfsi->flags))
+               goto out;
+
        spin_lock(&inode->i_lock);
        if (!NFS_I(inode)->layout) {
                spin_unlock(&inode->i_lock);
@@ -2296,6 +2300,9 @@ out_free:
        kfree(data);
 out_put:
        pnfs_put_layout_hdr(hdr);
+       smp_mb__before_atomic();
+       clear_bit(NFS_INO_LAYOUTSTATS, &nfsi->flags);
+       smp_mb__after_atomic();
        goto out;
 }
 EXPORT_SYMBOL_GPL(pnfs_report_layoutstat);
index b95f914ce083891325b6b8defa3f9995851cf76b..f91b5ade30c98fe8b03d06bc40deb0c434edb633 100644 (file)
@@ -219,6 +219,7 @@ struct nfs_inode {
 #define NFS_INO_COMMIT         (7)             /* inode is committing unstable writes */
 #define NFS_INO_LAYOUTCOMMIT   (9)             /* layoutcommit required */
 #define NFS_INO_LAYOUTCOMMITTING (10)          /* layoutcommit inflight */
+#define NFS_INO_LAYOUTSTATS    (11)            /* layoutstats inflight */
 
 static inline struct nfs_inode *NFS_I(const struct inode *inode)
 {