pnfs: add pnfs_report_layoutstat helper function
authorPeng Tao <tao.peng@primarydata.com>
Tue, 23 Jun 2015 11:51:57 +0000 (19:51 +0800)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Wed, 24 Jun 2015 14:17:37 +0000 (10:17 -0400)
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
fs/nfs/pnfs.h

index a0530418255f5824dcbcee215db36ff1aeff19f2..ee0248340a429b01ef48331e3832582316f6c8cf 100644 (file)
@@ -198,6 +198,10 @@ static void
 nfs42_layoutstat_release(void *calldata)
 {
        struct nfs42_layoutstat_data *data = calldata;
+       struct nfs_server *nfss = NFS_SERVER(data->args.inode);
+
+       if (nfss->pnfs_curr_ld->cleanup_layoutstats)
+               nfss->pnfs_curr_ld->cleanup_layoutstats(data);
 
        pnfs_put_layout_hdr(NFS_I(data->args.inode)->layout);
        nfs_iput_and_deactive(data->inode);
index d47c188682b163b15e72dd933deb96ba6540b72f..6279cff7df74aaf56bf476206395fa838b91616f 100644 (file)
@@ -35,6 +35,7 @@
 #include "iostat.h"
 #include "nfs4trace.h"
 #include "delegation.h"
+#include "nfs42.h"
 
 #define NFSDBG_FACILITY                NFSDBG_PNFS
 #define PNFS_LAYOUTGET_RETRY_TIMEOUT (120*HZ)
@@ -2250,3 +2251,51 @@ struct nfs4_threshold *pnfs_mdsthreshold_alloc(void)
        }
        return thp;
 }
+
+int
+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 nfs42_layoutstat_data *data;
+       struct pnfs_layout_hdr *hdr;
+       int status = 0;
+
+       if (!pnfs_enabled_sb(server) || !ld->prepare_layoutstats)
+               goto out;
+
+       spin_lock(&inode->i_lock);
+       if (!NFS_I(inode)->layout) {
+               spin_unlock(&inode->i_lock);
+               goto out;
+       }
+       hdr = NFS_I(inode)->layout;
+       pnfs_get_layout_hdr(hdr);
+       spin_unlock(&inode->i_lock);
+
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       if (!data) {
+               status = -ENOMEM;
+               goto out_put;
+       }
+
+       data->args.fh = NFS_FH(inode);
+       data->args.inode = inode;
+       nfs4_stateid_copy(&data->args.stateid, &hdr->plh_stateid);
+       status = ld->prepare_layoutstats(&data->args);
+       if (status)
+               goto out_free;
+
+       status = nfs42_proc_layoutstats_generic(NFS_SERVER(inode), data);
+
+out:
+       dprintk("%s returns %d\n", __func__, status);
+       return status;
+
+out_free:
+       kfree(data);
+out_put:
+       pnfs_put_layout_hdr(hdr);
+       goto out;
+}
+EXPORT_SYMBOL_GPL(pnfs_report_layoutstat);
index 1e6308f82fc3d5887de850e72226233e4f2138d2..0a4723945db21c5e4c305aa685414218684dfd37 100644 (file)
@@ -178,6 +178,8 @@ struct pnfs_layoutdriver_type {
        void (*encode_layoutcommit) (struct pnfs_layout_hdr *lo,
                                     struct xdr_stream *xdr,
                                     const struct nfs4_layoutcommit_args *args);
+       int (*prepare_layoutstats) (struct nfs42_layoutstat_args *args);
+       void (*cleanup_layoutstats) (struct nfs42_layoutstat_data *data);
 };
 
 struct pnfs_layout_hdr {
@@ -290,6 +292,7 @@ int pnfs_write_done_resend_to_mds(struct nfs_pgio_header *);
 struct nfs4_threshold *pnfs_mdsthreshold_alloc(void);
 void pnfs_error_mark_layout_for_return(struct inode *inode,
                                       struct pnfs_layout_segment *lseg);
+int pnfs_report_layoutstat(struct inode *inode);
 
 /* nfs4_deviceid_flags */
 enum {