summaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4xdr.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2016-09-15 14:40:49 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2016-09-19 13:11:13 -0400
commitca440c383a588091cae9fbce610b86a6e9d961ad (patch)
tree07fe5e65d81652746607babd8553e1316cd10a79 /fs/nfs/nfs4xdr.c
parent496b77a5c5ce8cd36b5fb78b8811f015643a6541 (diff)
pnfs: add a new mechanism to select a layout driver according to an ordered list
Currently, the layout driver selection code always chooses the first one from the list. That's not really ideal however, as the server can send the list of layout types in any order that it likes. It's up to the client to select the best one for its needs. This patch adds an ordered list of preferred driver types and has the selection code sort the list of available layout drivers according to it. Any unrecognized layout type is sorted to the end of the list. For now, the order of preference is hardcoded, but it should be possible to make this configurable in the future. Signed-off-by: Jeff Layton <jlayton@redhat.com> Reviewed-by: J. Bruce Fields <bfields@fieldses.org> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r--fs/nfs/nfs4xdr.c31
1 files changed, 18 insertions, 13 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 41a02f994976..17b4e059c588 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -4728,29 +4728,34 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
4728 * Decode potentially multiple layout types. 4728 * Decode potentially multiple layout types.
4729 */ 4729 */
4730static int decode_pnfs_layout_types(struct xdr_stream *xdr, 4730static int decode_pnfs_layout_types(struct xdr_stream *xdr,
4731 uint32_t *layouttype) 4731 struct nfs_fsinfo *fsinfo)
4732{ 4732{
4733 __be32 *p; 4733 __be32 *p;
4734 uint32_t num, i; 4734 uint32_t i;
4735 4735
4736 p = xdr_inline_decode(xdr, 4); 4736 p = xdr_inline_decode(xdr, 4);
4737 if (unlikely(!p)) 4737 if (unlikely(!p))
4738 goto out_overflow; 4738 goto out_overflow;
4739 num = be32_to_cpup(p); 4739 fsinfo->nlayouttypes = be32_to_cpup(p);
4740 4740
4741 /* pNFS is not supported by the underlying file system */ 4741 /* pNFS is not supported by the underlying file system */
4742 if (num == 0) { 4742 if (fsinfo->nlayouttypes == 0)
4743 return 0; 4743 return 0;
4744 }
4745 if (num > NFS_MAX_LAYOUT_TYPES)
4746 printk(KERN_INFO "NFS: %s: Warning: Too many (%d) pNFS layout types\n", __func__, num);
4747 4744
4748 /* Decode and set first layout type, move xdr->p past unused types */ 4745 /* Decode and set first layout type, move xdr->p past unused types */
4749 p = xdr_inline_decode(xdr, num * 4); 4746 p = xdr_inline_decode(xdr, fsinfo->nlayouttypes * 4);
4750 if (unlikely(!p)) 4747 if (unlikely(!p))
4751 goto out_overflow; 4748 goto out_overflow;
4752 for(i = 0; i < num && i < NFS_MAX_LAYOUT_TYPES; i++) 4749
4753 layouttype[i] = be32_to_cpup(p++); 4750 /* If we get too many, then just cap it at the max */
4751 if (fsinfo->nlayouttypes > NFS_MAX_LAYOUT_TYPES) {
4752 printk(KERN_INFO "NFS: %s: Warning: Too many (%u) pNFS layout types\n",
4753 __func__, fsinfo->nlayouttypes);
4754 fsinfo->nlayouttypes = NFS_MAX_LAYOUT_TYPES;
4755 }
4756
4757 for(i = 0; i < fsinfo->nlayouttypes; ++i)
4758 fsinfo->layouttype[i] = be32_to_cpup(p++);
4754 return 0; 4759 return 0;
4755out_overflow: 4760out_overflow:
4756 print_overflow_msg(__func__, xdr); 4761 print_overflow_msg(__func__, xdr);
@@ -4762,7 +4767,7 @@ out_overflow:
4762 * Note we must ensure that layouttype is set in any non-error case. 4767 * Note we must ensure that layouttype is set in any non-error case.
4763 */ 4768 */
4764static int decode_attr_pnfstype(struct xdr_stream *xdr, uint32_t *bitmap, 4769static int decode_attr_pnfstype(struct xdr_stream *xdr, uint32_t *bitmap,
4765 uint32_t *layouttype) 4770 struct nfs_fsinfo *fsinfo)
4766{ 4771{
4767 int status = 0; 4772 int status = 0;
4768 4773
@@ -4770,7 +4775,7 @@ static int decode_attr_pnfstype(struct xdr_stream *xdr, uint32_t *bitmap,
4770 if (unlikely(bitmap[1] & (FATTR4_WORD1_FS_LAYOUT_TYPES - 1U))) 4775 if (unlikely(bitmap[1] & (FATTR4_WORD1_FS_LAYOUT_TYPES - 1U)))
4771 return -EIO; 4776 return -EIO;
4772 if (bitmap[1] & FATTR4_WORD1_FS_LAYOUT_TYPES) { 4777 if (bitmap[1] & FATTR4_WORD1_FS_LAYOUT_TYPES) {
4773 status = decode_pnfs_layout_types(xdr, layouttype); 4778 status = decode_pnfs_layout_types(xdr, fsinfo);
4774 bitmap[1] &= ~FATTR4_WORD1_FS_LAYOUT_TYPES; 4779 bitmap[1] &= ~FATTR4_WORD1_FS_LAYOUT_TYPES;
4775 } 4780 }
4776 return status; 4781 return status;
@@ -4853,7 +4858,7 @@ static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
4853 status = decode_attr_time_delta(xdr, bitmap, &fsinfo->time_delta); 4858 status = decode_attr_time_delta(xdr, bitmap, &fsinfo->time_delta);
4854 if (status != 0) 4859 if (status != 0)
4855 goto xdr_error; 4860 goto xdr_error;
4856 status = decode_attr_pnfstype(xdr, bitmap, fsinfo->layouttype); 4861 status = decode_attr_pnfstype(xdr, bitmap, fsinfo);
4857 if (status != 0) 4862 if (status != 0)
4858 goto xdr_error; 4863 goto xdr_error;
4859 4864