fs/nfs/nfs4proc.c | 17 +++- fs/nfs/nfs4xdr.c | 178 +++++++++++++++++++++++++++++------------------- include/linux/nfs_xdr.h | 5 + 3 files changed, 129 insertions(+), 71 deletions(-) diff -u --recursive --new-file --show-c-function linux-2.6.5-28-decompoundify_cleanup/fs/nfs/nfs4proc.c linux-2.6.5-29-cleanup_fsinfo/fs/nfs/nfs4proc.c --- linux-2.6.5-28-decompoundify_cleanup/fs/nfs/nfs4proc.c 2004-03-24 00:49:24.000000000 -0500 +++ linux-2.6.5-29-cleanup_fsinfo/fs/nfs/nfs4proc.c 2004-03-24 00:49:32.000000000 -0500 @@ -72,7 +72,7 @@ static inline int nfs4_map_errors(int er /* * This is our standard bitmap for GETATTR requests. */ -u32 nfs4_fattr_bitmap[2] = { +const u32 nfs4_fattr_bitmap[2] = { FATTR4_WORD0_TYPE | FATTR4_WORD0_CHANGE | FATTR4_WORD0_SIZE @@ -89,7 +89,7 @@ u32 nfs4_fattr_bitmap[2] = { | FATTR4_WORD1_TIME_MODIFY }; -u32 nfs4_statfs_bitmap[2] = { +const u32 nfs4_statfs_bitmap[2] = { FATTR4_WORD0_FILES_AVAIL | FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL, @@ -104,6 +104,13 @@ u32 nfs4_pathconf_bitmap[2] = { 0 }; +const u32 nfs4_fsinfo_bitmap[2] = { FATTR4_WORD0_MAXFILESIZE + | FATTR4_WORD0_MAXREAD + | FATTR4_WORD0_MAXWRITE + | FATTR4_WORD0_LEASE_TIME, + 0 +}; + static void nfs4_setup_readdir(u64 cookie, u32 *verifier, struct dentry *dentry, struct nfs4_readdir_arg *readdir) { @@ -1198,9 +1205,13 @@ static int nfs4_proc_statfs(struct nfs_s static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo) { + struct nfs4_fsinfo_arg args = { + .fh = fhandle, + .bitmask = nfs4_fsinfo_bitmap, + }; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FSINFO], - .rpc_argp = fhandle, + .rpc_argp = &args, .rpc_resp = fsinfo, }; diff -u --recursive --new-file --show-c-function linux-2.6.5-28-decompoundify_cleanup/fs/nfs/nfs4xdr.c linux-2.6.5-29-cleanup_fsinfo/fs/nfs/nfs4xdr.c --- linux-2.6.5-28-decompoundify_cleanup/fs/nfs/nfs4xdr.c 2004-03-24 00:49:24.000000000 -0500 +++ linux-2.6.5-29-cleanup_fsinfo/fs/nfs/nfs4xdr.c 2004-03-24 00:49:32.000000000 -0500 @@ -624,12 +624,12 @@ static int encode_getfattr(struct xdr_st bitmask[1] & nfs4_fattr_bitmap[1]); } -static int encode_fsinfo(struct xdr_stream *xdr) +static int encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask) { - return encode_getattr_one(xdr, FATTR4_WORD0_MAXFILESIZE - | FATTR4_WORD0_MAXREAD - | FATTR4_WORD0_MAXWRITE - | FATTR4_WORD0_LEASE_TIME); + extern u32 nfs4_fsinfo_bitmap[]; + + return encode_getattr_two(xdr, bitmask[0] & nfs4_fsinfo_bitmap[0], + bitmask[1] & nfs4_fsinfo_bitmap[1]); } static int encode_getfh(struct xdr_stream *xdr) @@ -1577,7 +1577,7 @@ out: /* * FSINFO request */ -static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, uint32_t *p, void *fhandle) +static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, uint32_t *p, struct nfs4_fsinfo_arg *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1587,9 +1587,9 @@ static int nfs4_xdr_enc_fsinfo(struct rp xdr_init_encode(&xdr, &req->rq_snd_buf, p); encode_compound_hdr(&xdr, &hdr); - status = encode_putfh(&xdr, fhandle); + status = encode_putfh(&xdr, args->fh); if (!status) - status = encode_fsinfo(&xdr); + status = encode_fsinfo(&xdr, args->bitmask); return status; } @@ -1675,6 +1675,7 @@ static int nfs4_xdr_enc_setclientid_conf struct compound_hdr hdr = { .nops = 3, }; + const u32 lease_bitmap[2] = { FATTR4_WORD0_LEASE_TIME, 0 }; int status; xdr_init_encode(&xdr, &req->rq_snd_buf, p); @@ -1683,7 +1684,7 @@ static int nfs4_xdr_enc_setclientid_conf if (!status) status = encode_putrootfh(&xdr); if (!status) - status = encode_fsinfo(&xdr); + status = encode_fsinfo(&xdr, lease_bitmap); return status; } @@ -1857,6 +1858,22 @@ static int decode_attr_fsid(struct xdr_s return 0; } +static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) +{ + uint32_t *p; + + *res = 60; + if (unlikely(bitmap[0] & (FATTR4_WORD0_LEASE_TIME - 1U))) + return -EIO; + if (likely(bitmap[0] & FATTR4_WORD0_LEASE_TIME)) { + READ_BUF(4); + READ32(*res); + bitmap[0] &= ~FATTR4_WORD0_LEASE_TIME; + } + dprintk("%s: file size=%u\n", __FUNCTION__, (unsigned int)*res); + return 0; +} + static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid) { uint32_t *p; @@ -1924,6 +1941,23 @@ static int decode_attr_files_total(struc return status; } +static int decode_attr_maxfilesize(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) +{ + uint32_t *p; + int status = 0; + + *res = 0; + if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXFILESIZE - 1U))) + return -EIO; + if (likely(bitmap[0] & FATTR4_WORD0_MAXFILESIZE)) { + READ_BUF(8); + READ64(*res); + bitmap[0] &= ~FATTR4_WORD0_MAXFILESIZE; + } + dprintk("%s: maxfilesize=%Lu\n", __FUNCTION__, (unsigned long long)*res); + return status; +} + static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxlink) { uint32_t *p; @@ -1958,6 +1992,48 @@ static int decode_attr_maxname(struct xd return status; } +static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) +{ + uint32_t *p; + int status = 0; + + *res = 1024; + if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXREAD - 1U))) + return -EIO; + if (likely(bitmap[0] & FATTR4_WORD0_MAXREAD)) { + uint64_t maxread; + READ_BUF(8); + READ64(maxread); + if (maxread > 0x7FFFFFFF) + maxread = 0x7FFFFFFF; + *res = (uint32_t)maxread; + bitmap[0] &= ~FATTR4_WORD0_MAXREAD; + } + dprintk("%s: maxread=%lu\n", __FUNCTION__, (unsigned long)*res); + return status; +} + +static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) +{ + uint32_t *p; + int status = 0; + + *res = 1024; + if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXWRITE - 1U))) + return -EIO; + if (likely(bitmap[0] & FATTR4_WORD0_MAXWRITE)) { + uint64_t maxwrite; + READ_BUF(8); + READ64(maxwrite); + if (maxwrite > 0x7FFFFFFF) + maxwrite = 0x7FFFFFFF; + *res = (uint32_t)maxwrite; + bitmap[0] &= ~FATTR4_WORD0_MAXWRITE; + } + dprintk("%s: maxwrite=%lu\n", __FUNCTION__, (unsigned long)*res); + return status; +} + static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *mode) { uint32_t *p; @@ -2407,69 +2483,35 @@ xdr_error: static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) { - uint32_t *p; - uint32_t len, attrlen, bmlen, bmval0 = 0, bmval1 = 0; + uint32_t *savep; + uint32_t attrlen, bitmap[2]; int status; - status = decode_op_hdr(xdr, OP_GETATTR); - if (status) - return status; - READ_BUF(4); - READ32(bmlen); - if (bmlen < 1) - return -EIO; - READ_BUF(bmlen << 2); - READ32(bmval0); - if (bmval0 & ~(FATTR4_WORD0_MAXFILESIZE|FATTR4_WORD0_MAXREAD| - FATTR4_WORD0_MAXWRITE|FATTR4_WORD0_LEASE_TIME)) - goto out_bad_bitmap; - if (bmlen > 1) { - READ32(bmval1); - if (bmval1 != 0 || bmlen > 2) - goto out_bad_bitmap; - } - READ_BUF(4); - READ32(attrlen); - READ_BUF(attrlen); + 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; + fsinfo->rtmult = fsinfo->wtmult = 512; /* ??? */ - fsinfo->lease_time = 60; - len = attrlen; - if (bmval0 & FATTR4_WORD0_LEASE_TIME) { - len -= 4; - READ32(fsinfo->lease_time); - dprintk("read_attrs: lease_time=%d\n", fsinfo->lease_time); - } - if (bmval0 & FATTR4_WORD0_MAXFILESIZE) { - len -= 8; - READ64(fsinfo->maxfilesize); - dprintk("read_attrs: maxfilesize=0x%Lx\n", (long long) fsinfo->maxfilesize); - } - if (bmval0 & FATTR4_WORD0_MAXREAD) { - len -= 8; - READ64(fsinfo->rtmax); - fsinfo->rtpref = fsinfo->dtpref = fsinfo->rtmax; - dprintk("read_attrs: maxread=%d\n", fsinfo->rtmax); - } - if (bmval0 & FATTR4_WORD0_MAXWRITE) { - len -= 8; - READ64(fsinfo->wtmax); - fsinfo->wtpref = fsinfo->wtmax; - dprintk("read_attrs: maxwrite=%d\n", fsinfo->wtmax); - } - if (len != 0) - goto out_bad_attrlen; - return 0; -out_bad_attrlen: - printk(KERN_NOTICE "%s: server attribute length %u does not match bitmap 0x%x/0x%x\n", - __FUNCTION__, (unsigned int)attrlen, - (unsigned int) bmval0, (unsigned int)bmval1); - return -EIO; -out_bad_bitmap: - printk(KERN_NOTICE "%s: server returned bad attribute bitmap 0x%x/0x%x\n", - __FUNCTION__, - (unsigned int)bmval0, (unsigned int)bmval1); - return -EIO; + if ((status = decode_attr_lease_time(xdr, bitmap, &fsinfo->lease_time)) != 0) + goto xdr_error; + if ((status = decode_attr_maxfilesize(xdr, bitmap, &fsinfo->maxfilesize)) != 0) + goto xdr_error; + if ((status = decode_attr_maxread(xdr, bitmap, &fsinfo->rtmax)) != 0) + goto xdr_error; + fsinfo->rtpref = fsinfo->dtpref = fsinfo->rtmax; + if ((status = decode_attr_maxwrite(xdr, bitmap, &fsinfo->wtmax)) != 0) + goto xdr_error; + fsinfo->wtpref = fsinfo->wtmax; + + 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_getfh(struct xdr_stream *xdr, struct nfs_fh *fh) diff -u --recursive --new-file --show-c-function linux-2.6.5-28-decompoundify_cleanup/include/linux/nfs_xdr.h linux-2.6.5-29-cleanup_fsinfo/include/linux/nfs_xdr.h --- linux-2.6.5-28-decompoundify_cleanup/include/linux/nfs_xdr.h 2004-03-24 00:49:24.000000000 -0500 +++ linux-2.6.5-29-cleanup_fsinfo/include/linux/nfs_xdr.h 2004-03-24 00:49:32.000000000 -0500 @@ -517,6 +517,11 @@ struct nfs4_create_res { struct nfs4_change_info dir_cinfo; }; +struct nfs4_fsinfo_arg { + const struct nfs_fh * fh; + const u32 * bitmask; +}; + struct nfs4_getattr_arg { const struct nfs_fh * fh; const u32 * bitmask;