pnfs: add a common GETDEVICELIST implementation
authorChristoph Hellwig <hch@lst.de>
Wed, 3 Sep 2014 04:27:58 +0000 (21:27 -0700)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Wed, 10 Sep 2014 19:47:04 +0000 (12:47 -0700)
At a simple helper to issue a GETDEVICELIST operation and pre-load
the device id cache based on the result.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
fs/nfs/pnfs.h
fs/nfs/pnfs_dev.c

index ce89ae3..3eeca49 100644 (file)
@@ -277,6 +277,8 @@ bool nfs4_put_deviceid_node(struct nfs4_deviceid_node *);
 void nfs4_mark_deviceid_unavailable(struct nfs4_deviceid_node *node);
 bool nfs4_test_deviceid_unavailable(struct nfs4_deviceid_node *node);
 void nfs4_deviceid_purge_client(const struct nfs_client *);
+int nfs4_deviceid_getdevicelist(struct nfs_server *server,
+               const struct nfs_fh *fh);
 
 static inline struct pnfs_layout_segment *
 pnfs_get_lseg(struct pnfs_layout_segment *lseg)
index 791f8b3..82c2836 100644 (file)
@@ -359,3 +359,32 @@ nfs4_deviceid_mark_client_invalid(struct nfs_client *clp)
        rcu_read_unlock();
 }
 
+int
+nfs4_deviceid_getdevicelist(struct nfs_server *server,
+               const struct nfs_fh *fh)
+{
+       struct pnfs_devicelist *dlist;
+       struct nfs4_deviceid_node *d;
+       int error = 0, i;
+
+       dlist = kzalloc(sizeof(struct pnfs_devicelist), GFP_NOFS);
+       if (!dlist)
+               return -ENOMEM;
+
+       while (!dlist->eof) {
+               error = nfs4_proc_getdevicelist(server, fh, dlist);
+               if (error)
+                       break;
+
+               for (i = 0; i < dlist->num_devs; i++) {
+                       d = nfs4_find_get_deviceid(server, &dlist->dev_id[i],
+                                       NULL, GFP_NOFS);
+                       if (d)
+                               nfs4_put_deviceid_node(d);
+               }
+       }
+
+       kfree(dlist);
+       return error;
+}
+EXPORT_SYMBOL_GPL(nfs4_deviceid_getdevicelist);