X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=fs%2Fnfs%2Fnfs4xdr.c;fp=fs%2Fnfs%2Fnfs4xdr.c;h=4bbf5ef57785959dcb3ea555bcd68e3f45537c7e;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=99926067eca45888809dd91faa81ed4fad7dacae;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 99926067e..4bbf5ef57 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -58,7 +58,7 @@ /* Mapping from NFS error code to "errno" error code. */ #define errno_NFSERR_IO EIO -static int nfs4_stat_to_errno(int); +static int nfs_stat_to_errno(int); /* NFSv4 COMPOUND tags are only wanted for debugging purposes */ #ifdef DEBUG @@ -411,15 +411,6 @@ static int nfs4_stat_to_errno(int); #define NFS4_dec_setacl_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ op_decode_hdr_maxsz + nfs4_fattr_bitmap_maxsz) -#define NFS4_enc_fs_locations_sz \ - (compound_encode_hdr_maxsz + \ - encode_putfh_maxsz + \ - encode_getattr_maxsz) -#define NFS4_dec_fs_locations_sz \ - (compound_decode_hdr_maxsz + \ - decode_putfh_maxsz + \ - op_decode_hdr_maxsz + \ - nfs4_fattr_bitmap_maxsz) static struct { unsigned int mode; @@ -529,7 +520,7 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s if (iap->ia_valid & ATTR_MODE) len += 4; if (iap->ia_valid & ATTR_UID) { - owner_namelen = nfs_map_uid_to_name(server->nfs_client, iap->ia_uid, owner_name); + owner_namelen = nfs_map_uid_to_name(server->nfs4_state, iap->ia_uid, owner_name); if (owner_namelen < 0) { printk(KERN_WARNING "nfs: couldn't resolve uid %d to string\n", iap->ia_uid); @@ -541,7 +532,7 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s len += 4 + (XDR_QUADLEN(owner_namelen) << 2); } if (iap->ia_valid & ATTR_GID) { - owner_grouplen = nfs_map_gid_to_group(server->nfs_client, iap->ia_gid, owner_group); + owner_grouplen = nfs_map_gid_to_group(server->nfs4_state, iap->ia_gid, owner_group); if (owner_grouplen < 0) { printk(KERN_WARNING "nfs4: couldn't resolve gid %d to string\n", iap->ia_gid); @@ -731,13 +722,6 @@ static int encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask) bitmask[1] & nfs4_fsinfo_bitmap[1]); } -static int encode_fs_locations(struct xdr_stream *xdr, const u32* bitmask) -{ - return encode_getattr_two(xdr, - bitmask[0] & nfs4_fs_locations_bitmap[0], - bitmask[1] & nfs4_fs_locations_bitmap[1]); -} - static int encode_getfh(struct xdr_stream *xdr) { uint32_t *p; @@ -1160,7 +1144,7 @@ static int encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, con return 0; } -static int encode_renew(struct xdr_stream *xdr, const struct nfs_client *client_stateid) +static int encode_renew(struct xdr_stream *xdr, const struct nfs4_client *client_stateid) { uint32_t *p; @@ -1246,7 +1230,7 @@ static int encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclien return 0; } -static int encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_client *client_state) +static int encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs4_client *client_state) { uint32_t *p; @@ -1945,7 +1929,7 @@ static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, uint32_t *p, const str /* * a RENEW request */ -static int nfs4_xdr_enc_renew(struct rpc_rqst *req, uint32_t *p, struct nfs_client *clp) +static int nfs4_xdr_enc_renew(struct rpc_rqst *req, uint32_t *p, struct nfs4_client *clp) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1975,7 +1959,7 @@ static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, uint32_t *p, struct nf /* * a SETCLIENTID_CONFIRM request */ -static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, struct nfs_client *clp) +static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, struct nfs4_client *clp) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -2018,38 +2002,6 @@ out: return status; } -/* - * Encode FS_LOCATIONS request - */ -static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, uint32_t *p, struct nfs4_fs_locations_arg *args) -{ - struct xdr_stream xdr; - struct compound_hdr hdr = { - .nops = 3, - }; - struct rpc_auth *auth = req->rq_task->tk_auth; - int replen; - int status; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, &hdr); - if ((status = encode_putfh(&xdr, args->dir_fh)) != 0) - goto out; - if ((status = encode_lookup(&xdr, args->name)) != 0) - goto out; - if ((status = encode_fs_locations(&xdr, args->bitmask)) != 0) - goto out; - /* set up reply - * toplevel_status + OP_PUTFH + status - * + OP_LOOKUP + status + OP_GETATTR + status = 7 - */ - replen = (RPC_REPHDRSIZE + auth->au_rslack + 7) << 2; - xdr_inline_pages(&req->rq_rcv_buf, replen, &args->page, - 0, PAGE_SIZE); -out: - return status; -} - /* * START OF "GENERIC" DECODE ROUTINES. * These may look a little ugly since they are imported from a "generic" @@ -2084,7 +2036,7 @@ out: } \ } while (0) -static int decode_opaque_inline(struct xdr_stream *xdr, unsigned int *len, char **string) +static int decode_opaque_inline(struct xdr_stream *xdr, uint32_t *len, char **string) { uint32_t *p; @@ -2127,15 +2079,15 @@ static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) } READ32(nfserr); if (nfserr != NFS_OK) - return -nfs4_stat_to_errno(nfserr); + return -nfs_stat_to_errno(nfserr); return 0; } /* Dummy routine */ -static int decode_ace(struct xdr_stream *xdr, void *ace, struct nfs_client *clp) +static int decode_ace(struct xdr_stream *xdr, void *ace, struct nfs4_client *clp) { uint32_t *p; - unsigned int strlen; + uint32_t strlen; char *str; READ_BUF(12); @@ -2265,7 +2217,7 @@ static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, return 0; } -static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fsid *fsid) +static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_fsid *fsid) { uint32_t *p; @@ -2333,22 +2285,6 @@ static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t return 0; } -static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid) -{ - uint32_t *p; - - *fileid = 0; - if (unlikely(bitmap[1] & (FATTR4_WORD1_MOUNTED_ON_FILEID - 1U))) - return -EIO; - if (likely(bitmap[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)) { - READ_BUF(8); - READ64(*fileid); - bitmap[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; - } - dprintk("%s: fileid=%Lu\n", __FUNCTION__, (unsigned long long)*fileid); - return 0; -} - static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) { uint32_t *p; @@ -2400,116 +2336,6 @@ static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uin return status; } -static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path) -{ - int n; - uint32_t *p; - int status = 0; - - READ_BUF(4); - READ32(n); - if (n < 0) - goto out_eio; - if (n == 0) - goto root_path; - dprintk("path "); - path->ncomponents = 0; - while (path->ncomponents < n) { - struct nfs4_string *component = &path->components[path->ncomponents]; - status = decode_opaque_inline(xdr, &component->len, &component->data); - if (unlikely(status != 0)) - goto out_eio; - if (path->ncomponents != n) - dprintk("/"); - dprintk("%s", component->data); - if (path->ncomponents < NFS4_PATHNAME_MAXCOMPONENTS) - path->ncomponents++; - else { - dprintk("cannot parse %d components in path\n", n); - goto out_eio; - } - } -out: - dprintk("\n"); - return status; -root_path: -/* a root pathname is sent as a zero component4 */ - path->ncomponents = 1; - path->components[0].len=0; - path->components[0].data=NULL; - dprintk("path /\n"); - goto out; -out_eio: - dprintk(" status %d", status); - status = -EIO; - goto out; -} - -static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_fs_locations *res) -{ - int n; - uint32_t *p; - int status = -EIO; - - if (unlikely(bitmap[0] & (FATTR4_WORD0_FS_LOCATIONS -1U))) - goto out; - status = 0; - if (unlikely(!(bitmap[0] & FATTR4_WORD0_FS_LOCATIONS))) - goto out; - dprintk("%s: fsroot ", __FUNCTION__); - status = decode_pathname(xdr, &res->fs_path); - if (unlikely(status != 0)) - goto out; - READ_BUF(4); - READ32(n); - if (n <= 0) - goto out_eio; - res->nlocations = 0; - while (res->nlocations < n) { - int m; - struct nfs4_fs_location *loc = &res->locations[res->nlocations]; - - READ_BUF(4); - READ32(m); - if (m <= 0) - goto out_eio; - - loc->nservers = 0; - dprintk("%s: servers ", __FUNCTION__); - while (loc->nservers < m) { - struct nfs4_string *server = &loc->servers[loc->nservers]; - status = decode_opaque_inline(xdr, &server->len, &server->data); - if (unlikely(status != 0)) - goto out_eio; - dprintk("%s ", server->data); - if (loc->nservers < NFS4_FS_LOCATION_MAXSERVERS) - loc->nservers++; - else { - int i; - dprintk("%s: using first %d of %d servers returned for location %d\n", __FUNCTION__, NFS4_FS_LOCATION_MAXSERVERS, m, res->nlocations); - for (i = loc->nservers; i < m; i++) { - int len; - char *data; - status = decode_opaque_inline(xdr, &len, &data); - if (unlikely(status != 0)) - goto out_eio; - } - } - } - status = decode_pathname(xdr, &loc->rootpath); - if (unlikely(status != 0)) - goto out_eio; - if (res->nlocations < NFS4_FS_LOCATIONS_MAXENTRIES) - res->nlocations++; - } -out: - dprintk("%s: fs_locations done, error = %d\n", __FUNCTION__, status); - return status; -out_eio: - status = -EIO; - goto out; -} - static int decode_attr_maxfilesize(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) { uint32_t *p; @@ -2636,7 +2462,7 @@ static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t return 0; } -static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, int32_t *uid) +static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_client *clp, int32_t *uid) { uint32_t len, *p; @@ -2660,7 +2486,7 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nf return 0; } -static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, int32_t *gid) +static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_client *clp, int32_t *gid) { uint32_t len, *p; @@ -3015,7 +2841,6 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, cons bitmap[2] = {0}, type; int status, fmode = 0; - uint64_t fileid; if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) goto xdr_error; @@ -3038,22 +2863,18 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, cons goto xdr_error; if ((status = decode_attr_size(xdr, bitmap, &fattr->size)) != 0) goto xdr_error; - if ((status = decode_attr_fsid(xdr, bitmap, &fattr->fsid)) != 0) + if ((status = decode_attr_fsid(xdr, bitmap, &fattr->fsid_u.nfs4)) != 0) goto xdr_error; if ((status = decode_attr_fileid(xdr, bitmap, &fattr->fileid)) != 0) goto xdr_error; - if ((status = decode_attr_fs_locations(xdr, bitmap, container_of(fattr, - struct nfs4_fs_locations, - fattr))) != 0) - goto xdr_error; if ((status = decode_attr_mode(xdr, bitmap, &fattr->mode)) != 0) goto xdr_error; fattr->mode |= fmode; if ((status = decode_attr_nlink(xdr, bitmap, &fattr->nlink)) != 0) goto xdr_error; - if ((status = decode_attr_owner(xdr, bitmap, server->nfs_client, &fattr->uid)) != 0) + if ((status = decode_attr_owner(xdr, bitmap, server->nfs4_state, &fattr->uid)) != 0) goto xdr_error; - if ((status = decode_attr_group(xdr, bitmap, server->nfs_client, &fattr->gid)) != 0) + if ((status = decode_attr_group(xdr, bitmap, server->nfs4_state, &fattr->gid)) != 0) goto xdr_error; if ((status = decode_attr_rdev(xdr, bitmap, &fattr->rdev)) != 0) goto xdr_error; @@ -3065,10 +2886,6 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, cons goto xdr_error; if ((status = decode_attr_time_modify(xdr, bitmap, &fattr->mtime)) != 0) goto xdr_error; - if ((status = decode_attr_mounted_on_fileid(xdr, bitmap, &fileid)) != 0) - goto xdr_error; - if (fattr->fileid == 0 && fileid != 0) - fattr->fileid = fileid; if ((status = verify_attr_len(xdr, savep, attrlen)) == 0) fattr->valid = NFS_ATTR_FATTR | NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4; xdr_error: @@ -3254,7 +3071,7 @@ static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) if (decode_space_limit(xdr, &res->maxsize) < 0) return -EIO; } - return decode_ace(xdr, NULL, res->server->nfs_client); + return decode_ace(xdr, NULL, res->server->nfs4_state); } static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) @@ -3355,7 +3172,7 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n struct kvec *iov = rcvbuf->head; unsigned int nr, pglen = rcvbuf->page_len; uint32_t *end, *entry, *p, *kaddr; - uint32_t len, attrlen, xlen; + uint32_t len, attrlen; int hdrlen, recvd, status; status = decode_op_hdr(xdr, OP_READDIR); @@ -3377,10 +3194,10 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n BUG_ON(pglen + readdir->pgbase > PAGE_CACHE_SIZE); kaddr = p = (uint32_t *) kmap_atomic(page, KM_USER0); - end = p + ((pglen + readdir->pgbase) >> 2); + end = (uint32_t *) ((char *)p + pglen + readdir->pgbase); entry = p; for (nr = 0; *p++; nr++) { - if (end - p < 3) + if (p + 3 > end) goto short_pkt; dprintk("cookie = %Lu, ", *((unsigned long long *)p)); p += 2; /* cookie */ @@ -3389,19 +3206,18 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n printk(KERN_WARNING "NFS: giant filename in readdir (len 0x%x)\n", len); goto err_unmap; } - xlen = XDR_QUADLEN(len); - if (end - p < xlen + 1) - goto short_pkt; dprintk("filename = %*s\n", len, (char *)p); - p += xlen; - len = ntohl(*p++); /* bitmap length */ - if (end - p < len + 1) + p += XDR_QUADLEN(len); + if (p + 1 > end) goto short_pkt; + len = ntohl(*p++); /* bitmap length */ p += len; - attrlen = XDR_QUADLEN(ntohl(*p++)); - if (end - p < attrlen + 2) + if (p + 1 > end) goto short_pkt; + attrlen = XDR_QUADLEN(ntohl(*p++)); p += attrlen; /* attributes */ + if (p + 2 > end) + goto short_pkt; entry = p; } if (!nr && (entry[0] != 0 || entry[1] == 0)) @@ -3534,7 +3350,8 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, attrlen, recvd); return -EINVAL; } - xdr_read_pages(xdr, attrlen); + if (attrlen <= *acl_len) + xdr_read_pages(xdr, attrlen); *acl_len = attrlen; } else status = -EOPNOTSUPP; @@ -3565,7 +3382,7 @@ static int decode_setattr(struct xdr_stream *xdr, struct nfs_setattrres *res) return 0; } -static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp) +static int decode_setclientid(struct xdr_stream *xdr, struct nfs4_client *clp) { uint32_t *p; uint32_t opnum; @@ -3598,7 +3415,7 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp) READ_BUF(len); return -NFSERR_CLID_INUSE; } else - return -nfs4_stat_to_errno(nfserr); + return -nfs_stat_to_errno(nfserr); return 0; } @@ -4256,7 +4073,7 @@ static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, uint32_t *p, struct nfs_fsi if (!status) status = decode_fsinfo(&xdr, fsinfo); if (!status) - status = -nfs4_stat_to_errno(hdr.status); + status = -nfs_stat_to_errno(hdr.status); return status; } @@ -4335,7 +4152,7 @@ static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, uint32_t *p, void *dummy) * a SETCLIENTID request */ static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, uint32_t *p, - struct nfs_client *clp) + struct nfs4_client *clp) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -4346,7 +4163,7 @@ static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, uint32_t *p, if (!status) status = decode_setclientid(&xdr, clp); if (!status) - status = -nfs4_stat_to_errno(hdr.status); + status = -nfs_stat_to_errno(hdr.status); return status; } @@ -4368,7 +4185,7 @@ static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, s if (!status) status = decode_fsinfo(&xdr, fsinfo); if (!status) - status = -nfs4_stat_to_errno(hdr.status); + status = -nfs_stat_to_errno(hdr.status); return status; } @@ -4394,29 +4211,6 @@ out: return status; } -/* - * FS_LOCATIONS request - */ -static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, uint32_t *p, struct nfs4_fs_locations *res) -{ - 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 != 0) - goto out; - if ((status = decode_putfh(&xdr)) != 0) - goto out; - if ((status = decode_lookup(&xdr)) != 0) - goto out; - xdr_enter_page(&xdr, PAGE_SIZE); - status = decode_getfattr(&xdr, &res->fattr, res->server); -out: - return status; -} - uint32_t *nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus) { uint32_t bitmap[2] = {0}; @@ -4521,7 +4315,7 @@ static struct { * This one is used jointly by NFSv2 and NFSv3. */ static int -nfs4_stat_to_errno(int stat) +nfs_stat_to_errno(int stat) { int i; for (i = 0; nfs_errtbl[i].stat != -1; i++) { @@ -4550,8 +4344,6 @@ nfs4_stat_to_errno(int stat) .p_encode = (kxdrproc_t) nfs4_xdr_##argtype, \ .p_decode = (kxdrproc_t) nfs4_xdr_##restype, \ .p_bufsiz = MAX(NFS4_##argtype##_sz,NFS4_##restype##_sz) << 2, \ - .p_statidx = NFSPROC4_CLNT_##proc, \ - .p_name = #proc, \ } struct rpc_procinfo nfs4_procedures[] = { @@ -4588,12 +4380,11 @@ struct rpc_procinfo nfs4_procedures[] = { PROC(DELEGRETURN, enc_delegreturn, dec_delegreturn), PROC(GETACL, enc_getacl, dec_getacl), PROC(SETACL, enc_setacl, dec_setacl), - PROC(FS_LOCATIONS, enc_fs_locations, dec_fs_locations), }; struct rpc_version nfs_version4 = { .number = 4, - .nrprocs = ARRAY_SIZE(nfs4_procedures), + .nrprocs = sizeof(nfs4_procedures)/sizeof(nfs4_procedures[0]), .procs = nfs4_procedures };