/* 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
#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;
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);
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);
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;
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;
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;
/*
* 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 = {
/*
* 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 = {
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"
} \
} 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;
}
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);
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;
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;
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;
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;
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;
bitmap[2] = {0},
type;
int status, fmode = 0;
- uint64_t fileid;
if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
goto xdr_error;
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;
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:
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)
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);
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 */
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))
attrlen, recvd);
return -EINVAL;
}
- xdr_read_pages(xdr, attrlen);
+ if (attrlen <= *acl_len)
+ xdr_read_pages(xdr, attrlen);
*acl_len = attrlen;
} else
status = -EOPNOTSUPP;
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;
READ_BUF(len);
return -NFSERR_CLID_INUSE;
} else
- return -nfs4_stat_to_errno(nfserr);
+ return -nfs_stat_to_errno(nfserr);
return 0;
}
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;
}
* 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;
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;
}
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;
}
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};
* 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++) {
.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[] = {
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
};