Commit f3e5aa18 authored by Trond Myklebust's avatar Trond Myklebust

NFSv4: use the (more efficient) NFSv2/v3-like XDR scheme for generating

PATHCONF RPC calls.
parent 4e55f94b
...@@ -119,15 +119,13 @@ u32 nfs4_pathconf_bitmap[2] = { ...@@ -119,15 +119,13 @@ u32 nfs4_pathconf_bitmap[2] = {
static inline void static inline void
__nfs4_setup_getattr(struct nfs4_compound *cp, u32 *bitmap, __nfs4_setup_getattr(struct nfs4_compound *cp, u32 *bitmap,
struct nfs_fattr *fattr, struct nfs_fattr *fattr,
struct nfs_fsstat *fsstat, struct nfs_fsstat *fsstat)
struct nfs_pathconf *pathconf)
{ {
struct nfs4_getattr *getattr = GET_OP(cp, getattr); struct nfs4_getattr *getattr = GET_OP(cp, getattr);
getattr->gt_bmval = bitmap; getattr->gt_bmval = bitmap;
getattr->gt_attrs = fattr; getattr->gt_attrs = fattr;
getattr->gt_fsstat = fsstat; getattr->gt_fsstat = fsstat;
getattr->gt_pathconf = pathconf;
OPNUM(cp) = OP_GETATTR; OPNUM(cp) = OP_GETATTR;
cp->req_nops++; cp->req_nops++;
...@@ -137,8 +135,7 @@ static void ...@@ -137,8 +135,7 @@ static void
nfs4_setup_getattr(struct nfs4_compound *cp, nfs4_setup_getattr(struct nfs4_compound *cp,
struct nfs_fattr *fattr) struct nfs_fattr *fattr)
{ {
__nfs4_setup_getattr(cp, nfs4_fattr_bitmap, fattr, __nfs4_setup_getattr(cp, nfs4_fattr_bitmap, fattr, NULL);
NULL, NULL);
} }
static void static void
...@@ -146,15 +143,7 @@ nfs4_setup_statfs(struct nfs4_compound *cp, ...@@ -146,15 +143,7 @@ nfs4_setup_statfs(struct nfs4_compound *cp,
struct nfs_fsstat *fsstat) struct nfs_fsstat *fsstat)
{ {
__nfs4_setup_getattr(cp, nfs4_statfs_bitmap, __nfs4_setup_getattr(cp, nfs4_statfs_bitmap,
NULL, fsstat, NULL); NULL, fsstat);
}
static void
nfs4_setup_pathconf(struct nfs4_compound *cp,
struct nfs_pathconf *pathconf)
{
__nfs4_setup_getattr(cp, nfs4_pathconf_bitmap,
NULL, NULL, pathconf);
} }
static void static void
...@@ -1380,17 +1369,21 @@ static int nfs4_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, s ...@@ -1380,17 +1369,21 @@ static int nfs4_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, s
return nfs4_map_errors(nfs4_do_fsinfo(server, fhandle, fsinfo)); return nfs4_map_errors(nfs4_do_fsinfo(server, fhandle, fsinfo));
} }
static int static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
struct nfs_pathconf *pathconf) struct nfs_pathconf *pathconf)
{ {
struct nfs4_compound compound; struct nfs4_pathconf_arg args = {
struct nfs4_op ops[2]; .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"); pathconf->fattr->valid = 0;
nfs4_setup_putfh(&compound, fhandle); return nfs4_map_errors(rpc_call_sync(server->client, &msg, 0));
nfs4_setup_pathconf(&compound, pathconf);
return nfs4_map_errors(nfs4_call_compound(&compound, NULL, 0));
} }
static void static void
......
...@@ -319,6 +319,12 @@ static int nfs_stat_to_errno(int); ...@@ -319,6 +319,12 @@ static int nfs_stat_to_errno(int);
decode_create_maxsz + \ decode_create_maxsz + \
decode_getattr_maxsz + \ decode_getattr_maxsz + \
decode_getfh_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)
...@@ -1658,6 +1664,27 @@ nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, uint32_t *p, void *fhandle) ...@@ -1658,6 +1664,27 @@ nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, uint32_t *p, void *fhandle)
return status; return status;
} }
/*
* 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 * a RENEW request
*/ */
...@@ -1911,6 +1938,40 @@ static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t ...@@ -1911,6 +1938,40 @@ static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t
return 0; 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) static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *mode)
{ {
uint32_t *p; uint32_t *p;
...@@ -2184,7 +2245,6 @@ static int decode_create(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) ...@@ -2184,7 +2245,6 @@ static int decode_create(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
} }
extern uint32_t nfs4_fsstat_bitmap[2]; extern uint32_t nfs4_fsstat_bitmap[2];
extern uint32_t nfs4_pathconf_bitmap[2];
static int static int
decode_getattr(struct xdr_stream *xdr, struct nfs4_getattr *getattr, decode_getattr(struct xdr_stream *xdr, struct nfs4_getattr *getattr,
...@@ -2192,7 +2252,6 @@ decode_getattr(struct xdr_stream *xdr, struct nfs4_getattr *getattr, ...@@ -2192,7 +2252,6 @@ decode_getattr(struct xdr_stream *xdr, struct nfs4_getattr *getattr,
{ {
struct nfs_fattr *nfp = getattr->gt_attrs; struct nfs_fattr *nfp = getattr->gt_attrs;
struct nfs_fsstat *fsstat = getattr->gt_fsstat; struct nfs_fsstat *fsstat = getattr->gt_fsstat;
struct nfs_pathconf *pathconf = getattr->gt_pathconf;
uint32_t attrlen, dummy32, bmlen, uint32_t attrlen, dummy32, bmlen,
bmval0 = 0, bmval0 = 0,
bmval1 = 0, bmval1 = 0,
...@@ -2294,18 +2353,6 @@ decode_getattr(struct xdr_stream *xdr, struct nfs4_getattr *getattr, ...@@ -2294,18 +2353,6 @@ decode_getattr(struct xdr_stream *xdr, struct nfs4_getattr *getattr,
READ64(fsstat->tfiles); READ64(fsstat->tfiles);
dprintk("read_attrs: files_tot=0x%Lx\n", (long long) 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) { if (bmval1 & FATTR4_WORD1_MODE) {
READ_BUF(4); READ_BUF(4);
...@@ -2414,6 +2461,32 @@ decode_getattr(struct xdr_stream *xdr, struct nfs4_getattr *getattr, ...@@ -2414,6 +2461,32 @@ decode_getattr(struct xdr_stream *xdr, struct nfs4_getattr *getattr,
DECODE_TAIL; 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) static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, const struct nfs_server *server)
{ {
uint32_t *savep; uint32_t *savep;
...@@ -3556,6 +3629,24 @@ nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, uint32_t *p, struct nfs_fsinfo *fsinfo ...@@ -3556,6 +3629,24 @@ nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, uint32_t *p, struct nfs_fsinfo *fsinfo
return status; return status;
} }
/*
* 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 * Decode RENEW response
*/ */
...@@ -3758,6 +3849,7 @@ struct rpc_procinfo nfs4_procedures[] = { ...@@ -3758,6 +3849,7 @@ struct rpc_procinfo nfs4_procedures[] = {
PROC(RENAME, enc_rename, dec_rename), PROC(RENAME, enc_rename, dec_rename),
PROC(LINK, enc_link, dec_link), PROC(LINK, enc_link, dec_link),
PROC(CREATE, enc_create, dec_create), PROC(CREATE, enc_create, dec_create),
PROC(PATHCONF, enc_pathconf, dec_pathconf),
}; };
struct rpc_version nfs_version4 = { struct rpc_version nfs_version4 = {
......
...@@ -311,6 +311,7 @@ enum { ...@@ -311,6 +311,7 @@ enum {
NFSPROC4_CLNT_RENAME, NFSPROC4_CLNT_RENAME,
NFSPROC4_CLNT_LINK, NFSPROC4_CLNT_LINK,
NFSPROC4_CLNT_CREATE, NFSPROC4_CLNT_CREATE,
NFSPROC4_CLNT_PATHCONF,
}; };
#endif #endif
......
...@@ -534,7 +534,6 @@ struct nfs4_getattr { ...@@ -534,7 +534,6 @@ struct nfs4_getattr {
u32 * gt_bmval; /* request */ u32 * gt_bmval; /* request */
struct nfs_fattr * gt_attrs; /* response */ struct nfs_fattr * gt_attrs; /* response */
struct nfs_fsstat * gt_fsstat; /* response */ struct nfs_fsstat * gt_fsstat; /* response */
struct nfs_pathconf * gt_pathconf; /* response */
}; };
struct nfs4_getattr_arg { struct nfs4_getattr_arg {
...@@ -590,6 +589,11 @@ struct nfs4_open_confirm { ...@@ -590,6 +589,11 @@ struct nfs4_open_confirm {
char * oc_stateid; /* request */ char * oc_stateid; /* request */
}; };
struct nfs4_pathconf_arg {
const struct nfs_fh * fh;
const u32 * bitmask;
};
struct nfs4_putfh { struct nfs4_putfh {
struct nfs_fh * pf_fhandle; /* request */ struct nfs_fh * pf_fhandle; /* request */
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment