aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Adamson <andros@netapp.com>2010-10-20 00:17:57 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-10-24 18:07:09 -0400
commit504913fbc84c00bba7224d73e4aab525c1731f7d (patch)
tree714cbd975b3786486a93df5aa8cca27dc626033f
parent9449925273933d19235d7d36c1fd970841d055de (diff)
NFS: ask for layouttypes during v4 fsinfo call
This information will be used to determine which layout driver, if any, to use for subsequent IO on this filesystem. Each driver is assigned an integer id, with 0 reserved to indicate no driver. The server can in theory return multiple ids. However, our current client implementation only notes the first entry and ignores the rest. Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> Signed-off-by: Fred Isaman <iisaman@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/nfs4proc.c1
-rw-r--r--fs/nfs/nfs4xdr.c58
-rw-r--r--include/linux/nfs_xdr.h1
3 files changed, 60 insertions, 0 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index e87fe612ca18..a5f1edb45b47 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -130,6 +130,7 @@ const u32 nfs4_fsinfo_bitmap[2] = { FATTR4_WORD0_MAXFILESIZE
130 | FATTR4_WORD0_MAXWRITE 130 | FATTR4_WORD0_MAXWRITE
131 | FATTR4_WORD0_LEASE_TIME, 131 | FATTR4_WORD0_LEASE_TIME,
132 FATTR4_WORD1_TIME_DELTA 132 FATTR4_WORD1_TIME_DELTA
133 | FATTR4_WORD1_FS_LAYOUT_TYPES
133}; 134};
134 135
135const u32 nfs4_fs_locations_bitmap[2] = { 136const u32 nfs4_fs_locations_bitmap[2] = {
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index bd2101d918c8..8b4dfa393f0f 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -3978,6 +3978,61 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
3978 return decode_getfattr_generic(xdr, fattr, NULL, server, may_sleep); 3978 return decode_getfattr_generic(xdr, fattr, NULL, server, may_sleep);
3979} 3979}
3980 3980
3981/*
3982 * Decode potentially multiple layout types. Currently we only support
3983 * one layout driver per file system.
3984 */
3985static int decode_first_pnfs_layout_type(struct xdr_stream *xdr,
3986 uint32_t *layouttype)
3987{
3988 uint32_t *p;
3989 int num;
3990
3991 p = xdr_inline_decode(xdr, 4);
3992 if (unlikely(!p))
3993 goto out_overflow;
3994 num = be32_to_cpup(p);
3995
3996 /* pNFS is not supported by the underlying file system */
3997 if (num == 0) {
3998 *layouttype = 0;
3999 return 0;
4000 }
4001 if (num > 1)
4002 printk(KERN_INFO "%s: Warning: Multiple pNFS layout drivers "
4003 "per filesystem not supported\n", __func__);
4004
4005 /* Decode and set first layout type, move xdr->p past unused types */
4006 p = xdr_inline_decode(xdr, num * 4);
4007 if (unlikely(!p))
4008 goto out_overflow;
4009 *layouttype = be32_to_cpup(p);
4010 return 0;
4011out_overflow:
4012 print_overflow_msg(__func__, xdr);
4013 return -EIO;
4014}
4015
4016/*
4017 * The type of file system exported.
4018 * Note we must ensure that layouttype is set in any non-error case.
4019 */
4020static int decode_attr_pnfstype(struct xdr_stream *xdr, uint32_t *bitmap,
4021 uint32_t *layouttype)
4022{
4023 int status = 0;
4024
4025 dprintk("%s: bitmap is %x\n", __func__, bitmap[1]);
4026 if (unlikely(bitmap[1] & (FATTR4_WORD1_FS_LAYOUT_TYPES - 1U)))
4027 return -EIO;
4028 if (bitmap[1] & FATTR4_WORD1_FS_LAYOUT_TYPES) {
4029 status = decode_first_pnfs_layout_type(xdr, layouttype);
4030 bitmap[1] &= ~FATTR4_WORD1_FS_LAYOUT_TYPES;
4031 } else
4032 *layouttype = 0;
4033 return status;
4034}
4035
3981static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) 4036static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
3982{ 4037{
3983 __be32 *savep; 4038 __be32 *savep;
@@ -4006,6 +4061,9 @@ static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
4006 status = decode_attr_time_delta(xdr, bitmap, &fsinfo->time_delta); 4061 status = decode_attr_time_delta(xdr, bitmap, &fsinfo->time_delta);
4007 if (status != 0) 4062 if (status != 0)
4008 goto xdr_error; 4063 goto xdr_error;
4064 status = decode_attr_pnfstype(xdr, bitmap, &fsinfo->layouttype);
4065 if (status != 0)
4066 goto xdr_error;
4009 4067
4010 status = verify_attr_len(xdr, savep, attrlen); 4068 status = verify_attr_len(xdr, savep, attrlen);
4011xdr_error: 4069xdr_error:
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index da7a1300dc60..065f9d105d05 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -114,6 +114,7 @@ struct nfs_fsinfo {
114 __u64 maxfilesize; 114 __u64 maxfilesize;
115 struct timespec time_delta; /* server time granularity */ 115 struct timespec time_delta; /* server time granularity */
116 __u32 lease_time; /* in seconds */ 116 __u32 lease_time; /* in seconds */
117 __u32 layouttype; /* supported pnfs layout driver */
117}; 118};
118 119
119struct nfs_fsstat { 120struct nfs_fsstat {