aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2016-08-10 15:58:24 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2016-09-19 13:08:35 -0400
commit3132e49ecef9dab43d858d8e7066662c6a1efb16 (patch)
tree48a987372d1e75667b487b1bb8770b7a7b01851a /fs/nfs
parent2813b626e395f9de1ca0549c1c7d2217c1ce80ea (diff)
pnfs: track multiple layout types in fsinfo structure
Current NFSv4.1/pNFS client assumes that MDS supports only one layout type. While it's true for most existing servers, nevertheless, this can be change in the near future. For now, this patch just plumbs in the ability to track a list of layouts in the fsinfo structure. The existing behavior of the client is preserved, by having it just select the first entry in the list. Signed-off-by: Tigran Mkrtchyan <tigran.mkrtchyan@desy.de> Signed-off-by: Jeff Layton <jlayton@poochiereds.net> Reviewed-by: J. Bruce Fields <bfields@fieldses.org> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/client.c2
-rw-r--r--fs/nfs/nfs4xdr.c23
-rw-r--r--fs/nfs/pnfs.c27
-rw-r--r--fs/nfs/pnfs.h4
4 files changed, 29 insertions, 27 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 1e106780a237..0c1b3a002dc2 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -785,7 +785,7 @@ int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs
785 } 785 }
786 786
787 fsinfo.fattr = fattr; 787 fsinfo.fattr = fattr;
788 fsinfo.layouttype = 0; 788 memset(fsinfo.layouttype, 0, sizeof(fsinfo.layouttype));
789 error = clp->rpc_ops->fsinfo(server, mntfh, &fsinfo); 789 error = clp->rpc_ops->fsinfo(server, mntfh, &fsinfo);
790 if (error < 0) 790 if (error < 0)
791 goto out_error; 791 goto out_error;
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 7bd3a5c09d31..41a02f994976 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -4725,14 +4725,13 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
4725} 4725}
4726 4726
4727/* 4727/*
4728 * Decode potentially multiple layout types. Currently we only support 4728 * Decode potentially multiple layout types.
4729 * one layout driver per file system.
4730 */ 4729 */
4731static int decode_first_pnfs_layout_type(struct xdr_stream *xdr, 4730static int decode_pnfs_layout_types(struct xdr_stream *xdr,
4732 uint32_t *layouttype) 4731 uint32_t *layouttype)
4733{ 4732{
4734 __be32 *p; 4733 __be32 *p;
4735 int num; 4734 uint32_t num, i;
4736 4735
4737 p = xdr_inline_decode(xdr, 4); 4736 p = xdr_inline_decode(xdr, 4);
4738 if (unlikely(!p)) 4737 if (unlikely(!p))
@@ -4741,18 +4740,17 @@ static int decode_first_pnfs_layout_type(struct xdr_stream *xdr,
4741 4740
4742 /* pNFS is not supported by the underlying file system */ 4741 /* pNFS is not supported by the underlying file system */
4743 if (num == 0) { 4742 if (num == 0) {
4744 *layouttype = 0;
4745 return 0; 4743 return 0;
4746 } 4744 }
4747 if (num > 1) 4745 if (num > NFS_MAX_LAYOUT_TYPES)
4748 printk(KERN_INFO "NFS: %s: Warning: Multiple pNFS layout " 4746 printk(KERN_INFO "NFS: %s: Warning: Too many (%d) pNFS layout types\n", __func__, num);
4749 "drivers per filesystem not supported\n", __func__);
4750 4747
4751 /* Decode and set first layout type, move xdr->p past unused types */ 4748 /* Decode and set first layout type, move xdr->p past unused types */
4752 p = xdr_inline_decode(xdr, num * 4); 4749 p = xdr_inline_decode(xdr, num * 4);
4753 if (unlikely(!p)) 4750 if (unlikely(!p))
4754 goto out_overflow; 4751 goto out_overflow;
4755 *layouttype = be32_to_cpup(p); 4752 for(i = 0; i < num && i < NFS_MAX_LAYOUT_TYPES; i++)
4753 layouttype[i] = be32_to_cpup(p++);
4756 return 0; 4754 return 0;
4757out_overflow: 4755out_overflow:
4758 print_overflow_msg(__func__, xdr); 4756 print_overflow_msg(__func__, xdr);
@@ -4772,10 +4770,9 @@ static int decode_attr_pnfstype(struct xdr_stream *xdr, uint32_t *bitmap,
4772 if (unlikely(bitmap[1] & (FATTR4_WORD1_FS_LAYOUT_TYPES - 1U))) 4770 if (unlikely(bitmap[1] & (FATTR4_WORD1_FS_LAYOUT_TYPES - 1U)))
4773 return -EIO; 4771 return -EIO;
4774 if (bitmap[1] & FATTR4_WORD1_FS_LAYOUT_TYPES) { 4772 if (bitmap[1] & FATTR4_WORD1_FS_LAYOUT_TYPES) {
4775 status = decode_first_pnfs_layout_type(xdr, layouttype); 4773 status = decode_pnfs_layout_types(xdr, layouttype);
4776 bitmap[1] &= ~FATTR4_WORD1_FS_LAYOUT_TYPES; 4774 bitmap[1] &= ~FATTR4_WORD1_FS_LAYOUT_TYPES;
4777 } else 4775 }
4778 *layouttype = 0;
4779 return status; 4776 return status;
4780} 4777}
4781 4778
@@ -4856,7 +4853,7 @@ static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
4856 status = decode_attr_time_delta(xdr, bitmap, &fsinfo->time_delta); 4853 status = decode_attr_time_delta(xdr, bitmap, &fsinfo->time_delta);
4857 if (status != 0) 4854 if (status != 0)
4858 goto xdr_error; 4855 goto xdr_error;
4859 status = decode_attr_pnfstype(xdr, bitmap, &fsinfo->layouttype); 4856 status = decode_attr_pnfstype(xdr, bitmap, fsinfo->layouttype);
4860 if (status != 0) 4857 if (status != 0)
4861 goto xdr_error; 4858 goto xdr_error;
4862 4859
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 2c93a85eda51..a6a683fbd230 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -102,32 +102,37 @@ unset_pnfs_layoutdriver(struct nfs_server *nfss)
102 * Try to set the server's pnfs module to the pnfs layout type specified by id. 102 * Try to set the server's pnfs module to the pnfs layout type specified by id.
103 * Currently only one pNFS layout driver per filesystem is supported. 103 * Currently only one pNFS layout driver per filesystem is supported.
104 * 104 *
105 * @id layout type. Zero (illegal layout type) indicates pNFS not in use. 105 * @ids array of layout types supported by MDS.
106 */ 106 */
107void 107void
108set_pnfs_layoutdriver(struct nfs_server *server, const struct nfs_fh *mntfh, 108set_pnfs_layoutdriver(struct nfs_server *server, const struct nfs_fh *mntfh,
109 u32 id) 109 u32 *ids)
110{ 110{
111 struct pnfs_layoutdriver_type *ld_type = NULL; 111 struct pnfs_layoutdriver_type *ld_type = NULL;
112 u32 id;
112 113
113 if (id == 0)
114 goto out_no_driver;
115 if (!(server->nfs_client->cl_exchange_flags & 114 if (!(server->nfs_client->cl_exchange_flags &
116 (EXCHGID4_FLAG_USE_NON_PNFS | EXCHGID4_FLAG_USE_PNFS_MDS))) { 115 (EXCHGID4_FLAG_USE_NON_PNFS | EXCHGID4_FLAG_USE_PNFS_MDS))) {
117 printk(KERN_ERR "NFS: %s: id %u cl_exchange_flags 0x%x\n", 116 printk(KERN_ERR "NFS: %s: cl_exchange_flags 0x%x\n",
118 __func__, id, server->nfs_client->cl_exchange_flags); 117 __func__, server->nfs_client->cl_exchange_flags);
119 goto out_no_driver; 118 goto out_no_driver;
120 } 119 }
120
121 id = ids[0];
122 if (!id)
123 goto out_no_driver;
124
121 ld_type = find_pnfs_driver(id); 125 ld_type = find_pnfs_driver(id);
122 if (!ld_type) { 126 if (!ld_type) {
123 request_module("%s-%u", LAYOUT_NFSV4_1_MODULE_PREFIX, id); 127 request_module("%s-%u", LAYOUT_NFSV4_1_MODULE_PREFIX, id);
124 ld_type = find_pnfs_driver(id); 128 ld_type = find_pnfs_driver(id);
125 if (!ld_type) {
126 dprintk("%s: No pNFS module found for %u.\n",
127 __func__, id);
128 goto out_no_driver;
129 }
130 } 129 }
130
131 if (!ld_type) {
132 dprintk("%s: No pNFS module found for %u.\n", __func__, id);
133 goto out_no_driver;
134 }
135
131 server->pnfs_curr_ld = ld_type; 136 server->pnfs_curr_ld = ld_type;
132 if (ld_type->set_layoutdriver 137 if (ld_type->set_layoutdriver
133 && ld_type->set_layoutdriver(server, mntfh)) { 138 && ld_type->set_layoutdriver(server, mntfh)) {
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 31d99b2927b0..be515e6a3823 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -236,7 +236,7 @@ void pnfs_get_layout_hdr(struct pnfs_layout_hdr *lo);
236void pnfs_put_lseg(struct pnfs_layout_segment *lseg); 236void pnfs_put_lseg(struct pnfs_layout_segment *lseg);
237void pnfs_put_lseg_locked(struct pnfs_layout_segment *lseg); 237void pnfs_put_lseg_locked(struct pnfs_layout_segment *lseg);
238 238
239void set_pnfs_layoutdriver(struct nfs_server *, const struct nfs_fh *, u32); 239void set_pnfs_layoutdriver(struct nfs_server *, const struct nfs_fh *, u32 *);
240void unset_pnfs_layoutdriver(struct nfs_server *); 240void unset_pnfs_layoutdriver(struct nfs_server *);
241void pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *, struct nfs_page *); 241void pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *, struct nfs_page *);
242int pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc); 242int pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc);
@@ -657,7 +657,7 @@ pnfs_wait_on_layoutreturn(struct inode *ino, struct rpc_task *task)
657} 657}
658 658
659static inline void set_pnfs_layoutdriver(struct nfs_server *s, 659static inline void set_pnfs_layoutdriver(struct nfs_server *s,
660 const struct nfs_fh *mntfh, u32 id) 660 const struct nfs_fh *mntfh, u32 *ids)
661{ 661{
662} 662}
663 663