fs/nfs/nfs4proc.c | 43 +++++++---------- fs/nfs/nfs4xdr.c | 120 ++++++++++++++++++++++++++++++++++++++++++------ include/linux/nfs4.h | 1 include/linux/nfs_xdr.h | 6 ++ 4 files changed, 130 insertions(+), 40 deletions(-) diff -u --recursive --new-file --show-c-function linux-2.6.5-22-decompoundify_create/fs/nfs/nfs4proc.c linux-2.6.5-23-decompoundify_pathconf/fs/nfs/nfs4proc.c --- linux-2.6.5-22-decompoundify_create/fs/nfs/nfs4proc.c 2004-03-24 00:48:32.000000000 -0500 +++ linux-2.6.5-23-decompoundify_pathconf/fs/nfs/nfs4proc.c 2004-03-24 00:48:37.000000000 -0500 @@ -119,15 +119,13 @@ u32 nfs4_pathconf_bitmap[2] = { static inline void __nfs4_setup_getattr(struct nfs4_compound *cp, u32 *bitmap, struct nfs_fattr *fattr, - struct nfs_fsstat *fsstat, - struct nfs_pathconf *pathconf) + struct nfs_fsstat *fsstat) { struct nfs4_getattr *getattr = GET_OP(cp, getattr); - getattr->gt_bmval = bitmap; - getattr->gt_attrs = fattr; + getattr->gt_bmval = bitmap; + getattr->gt_attrs = fattr; getattr->gt_fsstat = fsstat; - getattr->gt_pathconf = pathconf; OPNUM(cp) = OP_GETATTR; cp->req_nops++; @@ -137,8 +135,7 @@ static void nfs4_setup_getattr(struct nfs4_compound *cp, struct nfs_fattr *fattr) { - __nfs4_setup_getattr(cp, nfs4_fattr_bitmap, fattr, - NULL, NULL); + __nfs4_setup_getattr(cp, nfs4_fattr_bitmap, fattr, NULL); } static void @@ -146,15 +143,7 @@ nfs4_setup_statfs(struct nfs4_compound * struct nfs_fsstat *fsstat) { __nfs4_setup_getattr(cp, nfs4_statfs_bitmap, - NULL, fsstat, NULL); -} - -static void -nfs4_setup_pathconf(struct nfs4_compound *cp, - struct nfs_pathconf *pathconf) -{ - __nfs4_setup_getattr(cp, nfs4_pathconf_bitmap, - NULL, NULL, pathconf); + NULL, fsstat); } static void @@ -1380,17 +1369,21 @@ static int nfs4_proc_fsinfo(struct nfs_s return nfs4_map_errors(nfs4_do_fsinfo(server, fhandle, fsinfo)); } -static int -nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle, - struct nfs_pathconf *pathconf) +static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle, + struct nfs_pathconf *pathconf) { - struct nfs4_compound compound; - struct nfs4_op ops[2]; + struct nfs4_pathconf_arg args = { + .fh = fhandle, + .bitmask = nfs4_pathconf_bitmap, + }; + struct rpc_message msg = { + .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_PATHCONF], + .rpc_argp = &args, + .rpc_resp = pathconf, + }; - nfs4_setup_compound(&compound, ops, server, "statfs"); - nfs4_setup_putfh(&compound, fhandle); - nfs4_setup_pathconf(&compound, pathconf); - return nfs4_map_errors(nfs4_call_compound(&compound, NULL, 0)); + pathconf->fattr->valid = 0; + return nfs4_map_errors(rpc_call_sync(server->client, &msg, 0)); } static void diff -u --recursive --new-file --show-c-function linux-2.6.5-22-decompoundify_create/fs/nfs/nfs4xdr.c linux-2.6.5-23-decompoundify_pathconf/fs/nfs/nfs4xdr.c --- linux-2.6.5-22-decompoundify_create/fs/nfs/nfs4xdr.c 2004-03-24 00:48:32.000000000 -0500 +++ linux-2.6.5-23-decompoundify_pathconf/fs/nfs/nfs4xdr.c 2004-03-24 00:48:37.000000000 -0500 @@ -319,6 +319,12 @@ static int nfs_stat_to_errno(int); decode_create_maxsz + \ decode_getattr_maxsz + \ decode_getfh_maxsz) +#define NFS4_enc_pathconf_sz (compound_encode_hdr_maxsz + \ + encode_putfh_maxsz + \ + encode_getattr_maxsz) +#define NFS4_dec_pathconf_sz (compound_decode_hdr_maxsz + \ + decode_putfh_maxsz + \ + decode_getattr_maxsz) @@ -1659,6 +1665,27 @@ nfs4_xdr_enc_fsinfo(struct rpc_rqst *req } /* + * a PATHCONF request + */ +static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, uint32_t *p, const struct nfs4_pathconf_arg *args) +{ + extern u32 nfs4_pathconf_bitmap[2]; + struct xdr_stream xdr; + struct compound_hdr hdr = { + .nops = 2, + }; + int status; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_compound_hdr(&xdr, &hdr); + status = encode_putfh(&xdr, args->fh); + if (!status) + status = encode_getattr_one(&xdr, + args->bitmask[0] & nfs4_pathconf_bitmap[0]); + return status; +} + +/* * a RENEW request */ static int @@ -1911,6 +1938,40 @@ static int decode_attr_fileid(struct xdr return 0; } +static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxlink) +{ + uint32_t *p; + int status = 0; + + *maxlink = 1; + if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXLINK - 1U))) + return -EIO; + if (likely(bitmap[0] & FATTR4_WORD0_MAXLINK)) { + READ_BUF(4); + READ32(*maxlink); + bitmap[0] &= ~FATTR4_WORD0_MAXLINK; + } + dprintk("%s: maxlink=%u\n", __FUNCTION__, *maxlink); + return status; +} + +static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxname) +{ + uint32_t *p; + int status = 0; + + *maxname = 1024; + if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXNAME - 1U))) + return -EIO; + if (likely(bitmap[0] & FATTR4_WORD0_MAXNAME)) { + READ_BUF(4); + READ32(*maxname); + bitmap[0] &= ~FATTR4_WORD0_MAXNAME; + } + dprintk("%s: maxname=%u\n", __FUNCTION__, *maxname); + return status; +} + static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *mode) { uint32_t *p; @@ -2188,7 +2249,6 @@ static int decode_create(struct xdr_stre } extern uint32_t nfs4_fsstat_bitmap[2]; -extern uint32_t nfs4_pathconf_bitmap[2]; static int decode_getattr(struct xdr_stream *xdr, struct nfs4_getattr *getattr, @@ -2196,7 +2256,6 @@ decode_getattr(struct xdr_stream *xdr, s { struct nfs_fattr *nfp = getattr->gt_attrs; struct nfs_fsstat *fsstat = getattr->gt_fsstat; - struct nfs_pathconf *pathconf = getattr->gt_pathconf; uint32_t attrlen, dummy32, bmlen, bmval0 = 0, bmval1 = 0, @@ -2298,18 +2357,6 @@ decode_getattr(struct xdr_stream *xdr, s READ64(fsstat->tfiles); dprintk("read_attrs: files_tot=0x%Lx\n", (long long) fsstat->tfiles); } - if (bmval0 & FATTR4_WORD0_MAXLINK) { - READ_BUF(4); - len += 4; - READ32(pathconf->max_link); - dprintk("read_attrs: maxlink=%d\n", pathconf->max_link); - } - if (bmval0 & FATTR4_WORD0_MAXNAME) { - READ_BUF(4); - len += 4; - READ32(pathconf->max_namelen); - dprintk("read_attrs: maxname=%d\n", pathconf->max_namelen); - } if (bmval1 & FATTR4_WORD1_MODE) { READ_BUF(4); @@ -2418,6 +2465,32 @@ decode_getattr(struct xdr_stream *xdr, s DECODE_TAIL; } +static int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf) +{ + uint32_t *savep; + uint32_t attrlen, + bitmap[2] = {0}; + int status; + + if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) + goto xdr_error; + if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) + goto xdr_error; + if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0) + goto xdr_error; + + if ((status = decode_attr_maxlink(xdr, bitmap, &pathconf->max_link)) != 0) + goto xdr_error; + if ((status = decode_attr_maxname(xdr, bitmap, &pathconf->max_namelen)) != 0) + goto xdr_error; + + status = verify_attr_len(xdr, savep, attrlen); +xdr_error: + if (status != 0) + printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status); + return status; +} + static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, const struct nfs_server *server) { uint32_t *savep; @@ -3561,6 +3634,24 @@ nfs4_xdr_dec_fsinfo(struct rpc_rqst *req } /* + * PATHCONF request + */ +static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, uint32_t *p, struct nfs_pathconf *pathconf) +{ + struct xdr_stream xdr; + struct compound_hdr hdr; + int status; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + status = decode_compound_hdr(&xdr, &hdr); + if (!status) + status = decode_putfh(&xdr); + if (!status) + status = decode_pathconf(&xdr, pathconf); + return status; +} + +/* * Decode RENEW response */ static int @@ -3762,6 +3853,7 @@ struct rpc_procinfo nfs4_procedures[] = PROC(RENAME, enc_rename, dec_rename), PROC(LINK, enc_link, dec_link), PROC(CREATE, enc_create, dec_create), + PROC(PATHCONF, enc_pathconf, dec_pathconf), }; struct rpc_version nfs_version4 = { diff -u --recursive --new-file --show-c-function linux-2.6.5-22-decompoundify_create/include/linux/nfs4.h linux-2.6.5-23-decompoundify_pathconf/include/linux/nfs4.h --- linux-2.6.5-22-decompoundify_create/include/linux/nfs4.h 2004-03-24 00:48:32.000000000 -0500 +++ linux-2.6.5-23-decompoundify_pathconf/include/linux/nfs4.h 2004-03-24 00:48:37.000000000 -0500 @@ -311,6 +311,7 @@ enum { NFSPROC4_CLNT_RENAME, NFSPROC4_CLNT_LINK, NFSPROC4_CLNT_CREATE, + NFSPROC4_CLNT_PATHCONF, }; #endif diff -u --recursive --new-file --show-c-function linux-2.6.5-22-decompoundify_create/include/linux/nfs_xdr.h linux-2.6.5-23-decompoundify_pathconf/include/linux/nfs_xdr.h --- linux-2.6.5-22-decompoundify_create/include/linux/nfs_xdr.h 2004-03-24 00:48:32.000000000 -0500 +++ linux-2.6.5-23-decompoundify_pathconf/include/linux/nfs_xdr.h 2004-03-24 00:48:37.000000000 -0500 @@ -534,7 +534,6 @@ struct nfs4_getattr { u32 * gt_bmval; /* request */ struct nfs_fattr * gt_attrs; /* response */ struct nfs_fsstat * gt_fsstat; /* response */ - struct nfs_pathconf * gt_pathconf; /* response */ }; struct nfs4_getattr_arg { @@ -590,6 +589,11 @@ struct nfs4_open_confirm { char * oc_stateid; /* request */ }; +struct nfs4_pathconf_arg { + const struct nfs_fh * fh; + const u32 * bitmask; +}; + struct nfs4_putfh { struct nfs_fh * pf_fhandle; /* request */ };