Commit c8e46334 authored by Trond Myklebust's avatar Trond Myklebust

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

REMOVE RPC calls.
parent fba5d3c4
...@@ -340,8 +340,7 @@ nfs4_setup_remove(struct nfs4_compound *cp, struct qstr *name, struct nfs4_chang ...@@ -340,8 +340,7 @@ nfs4_setup_remove(struct nfs4_compound *cp, struct qstr *name, struct nfs4_chang
{ {
struct nfs4_remove *remove = GET_OP(cp, remove); struct nfs4_remove *remove = GET_OP(cp, remove);
remove->rm_namelen = name->len; remove->name = name;
remove->rm_name = name->name;
remove->rm_cinfo = cinfo; remove->rm_cinfo = cinfo;
OPNUM(cp) = OP_REMOVE; OPNUM(cp) = OP_REMOVE;
...@@ -443,6 +442,14 @@ process_cinfo(struct nfs4_change_info *info, struct nfs_fattr *fattr) ...@@ -443,6 +442,14 @@ process_cinfo(struct nfs4_change_info *info, struct nfs_fattr *fattr)
} }
} }
static void update_changeattr(struct inode *inode, struct nfs4_change_info *cinfo)
{
struct nfs_inode *nfsi = NFS_I(inode);
if (cinfo->before == nfsi->change_attr && cinfo->atomic)
nfsi->change_attr = cinfo->after;
}
/* /*
* OPEN_RECLAIM: * OPEN_RECLAIM:
* reclaim state on the server after a reboot. * reclaim state on the server after a reboot.
...@@ -1218,26 +1225,23 @@ nfs4_proc_create(struct inode *dir, struct qstr *name, struct iattr *sattr, ...@@ -1218,26 +1225,23 @@ nfs4_proc_create(struct inode *dir, struct qstr *name, struct iattr *sattr,
return inode; return inode;
} }
static int static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
nfs4_proc_remove(struct inode *dir, struct qstr *name)
{ {
struct nfs4_compound compound; struct nfs4_remove_arg args = {
struct nfs4_op ops[3]; .fh = NFS_FH(dir),
struct nfs4_change_info dir_cinfo; .name = name,
struct nfs_fattr dir_attr; };
struct nfs4_change_info res;
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE],
.rpc_argp = &args,
.rpc_resp = &res,
};
int status; int status;
dir_attr.valid = 0; status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
nfs4_setup_compound(&compound, ops, NFS_SERVER(dir), "remove"); if (status == 0)
nfs4_setup_putfh(&compound, NFS_FH(dir)); update_changeattr(dir, &res);
nfs4_setup_remove(&compound, name, &dir_cinfo);
nfs4_setup_getattr(&compound, &dir_attr);
status = nfs4_call_compound(&compound, NULL, 0);
if (!status) {
process_cinfo(&dir_cinfo, &dir_attr);
nfs_refresh_inode(dir, &dir_attr);
}
return nfs4_map_errors(status); return nfs4_map_errors(status);
} }
......
...@@ -111,6 +111,8 @@ static int nfs_stat_to_errno(int); ...@@ -111,6 +111,8 @@ static int nfs_stat_to_errno(int);
(op_decode_hdr_maxsz) (op_decode_hdr_maxsz)
#define encode_lookup_maxsz (op_encode_hdr_maxsz + \ #define encode_lookup_maxsz (op_encode_hdr_maxsz + \
1 + ((3 + NFS4_FHSIZE) >> 2)) 1 + ((3 + NFS4_FHSIZE) >> 2))
#define encode_remove_maxsz (op_encode_hdr_maxsz + \
1 + ((3 + NFS4_MAXNAMLEN) >> 2))
#define NFS4_enc_compound_sz (1024) /* XXX: large enough? */ #define NFS4_enc_compound_sz (1024) /* XXX: large enough? */
#define NFS4_dec_compound_sz (1024) /* XXX: large enough? */ #define NFS4_dec_compound_sz (1024) /* XXX: large enough? */
#define NFS4_enc_read_sz (compound_encode_hdr_maxsz + \ #define NFS4_enc_read_sz (compound_encode_hdr_maxsz + \
...@@ -270,6 +272,12 @@ static int nfs_stat_to_errno(int); ...@@ -270,6 +272,12 @@ static int nfs_stat_to_errno(int);
decode_putrootfh_maxsz + \ decode_putrootfh_maxsz + \
decode_getattr_maxsz + \ decode_getattr_maxsz + \
decode_getfh_maxsz) decode_getfh_maxsz)
#define NFS4_enc_remove_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
encode_remove_maxsz)
#define NFS4_dec_remove_sz (compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
op_decode_hdr_maxsz + 5)
...@@ -927,15 +935,14 @@ encode_readlink(struct xdr_stream *xdr, struct nfs4_readlink *readlink, struct r ...@@ -927,15 +935,14 @@ encode_readlink(struct xdr_stream *xdr, struct nfs4_readlink *readlink, struct r
return 0; return 0;
} }
static int static int encode_remove(struct xdr_stream *xdr, const struct qstr *name)
encode_remove(struct xdr_stream *xdr, struct nfs4_remove *remove)
{ {
uint32_t *p; uint32_t *p;
RESERVE_SPACE(8 + remove->rm_namelen); RESERVE_SPACE(8 + name->len);
WRITE32(OP_REMOVE); WRITE32(OP_REMOVE);
WRITE32(remove->rm_namelen); WRITE32(name->len);
WRITEMEM(remove->rm_name, remove->rm_namelen); WRITEMEM(name->name, name->len);
return 0; return 0;
} }
...@@ -1106,7 +1113,7 @@ encode_compound(struct xdr_stream *xdr, struct nfs4_compound *cp, struct rpc_rqs ...@@ -1106,7 +1113,7 @@ encode_compound(struct xdr_stream *xdr, struct nfs4_compound *cp, struct rpc_rqs
status = encode_readlink(xdr, &cp->ops[i].u.readlink, req); status = encode_readlink(xdr, &cp->ops[i].u.readlink, req);
break; break;
case OP_REMOVE: case OP_REMOVE:
status = encode_remove(xdr, &cp->ops[i].u.remove); status = encode_remove(xdr, cp->ops[i].u.remove.name);
break; break;
case OP_RENAME: case OP_RENAME:
status = encode_rename(xdr, &cp->ops[i].u.rename); status = encode_rename(xdr, &cp->ops[i].u.rename);
...@@ -1208,6 +1215,24 @@ static int nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, uint32_t *p, const str ...@@ -1208,6 +1215,24 @@ static int nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, uint32_t *p, const str
return status; return status;
} }
/*
* Encode REMOVE request
*/
static int nfs4_xdr_enc_remove(struct rpc_rqst *req, uint32_t *p, const struct nfs4_remove_arg *args)
{
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);
if ((status = encode_putfh(&xdr, args->fh)) == 0)
status = encode_remove(&xdr, args->name);
return status;
}
/* /*
* Encode GETATTR request * Encode GETATTR request
*/ */
...@@ -2763,15 +2788,14 @@ decode_restorefh(struct xdr_stream *xdr) ...@@ -2763,15 +2788,14 @@ decode_restorefh(struct xdr_stream *xdr)
return decode_op_hdr(xdr, OP_RESTOREFH); return decode_op_hdr(xdr, OP_RESTOREFH);
} }
static int static int decode_remove(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
decode_remove(struct xdr_stream *xdr, struct nfs4_remove *remove)
{ {
int status; int status;
status = decode_op_hdr(xdr, OP_REMOVE); status = decode_op_hdr(xdr, OP_REMOVE);
if (status) if (status)
goto out; goto out;
status = decode_change_info(xdr, remove->rm_cinfo); status = decode_change_info(xdr, cinfo);
out: out:
return status; return status;
} }
...@@ -2938,7 +2962,7 @@ decode_compound(struct xdr_stream *xdr, struct nfs4_compound *cp, struct rpc_rqs ...@@ -2938,7 +2962,7 @@ decode_compound(struct xdr_stream *xdr, struct nfs4_compound *cp, struct rpc_rqs
status = decode_restorefh(xdr); status = decode_restorefh(xdr);
break; break;
case OP_REMOVE: case OP_REMOVE:
status = decode_remove(xdr, &op->u.remove); status = decode_remove(xdr, op->u.remove.rm_cinfo);
break; break;
case OP_RENAME: case OP_RENAME:
status = decode_rename(xdr, &op->u.rename); status = decode_rename(xdr, &op->u.rename);
...@@ -3065,6 +3089,24 @@ static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, uint32_t *p, struct ...@@ -3065,6 +3089,24 @@ static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, uint32_t *p, struct
return status; return status;
} }
/*
* Decode REMOVE response
*/
static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_change_info *cinfo)
{
struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
goto out;
if ((status = decode_putfh(&xdr)) == 0)
status = decode_remove(&xdr, cinfo);
out:
return status;
}
/* /*
* Decode GETATTR response * Decode GETATTR response
*/ */
...@@ -3576,6 +3618,7 @@ struct rpc_procinfo nfs4_procedures[] = { ...@@ -3576,6 +3618,7 @@ struct rpc_procinfo nfs4_procedures[] = {
PROC(GETATTR, enc_getattr, dec_getattr), PROC(GETATTR, enc_getattr, dec_getattr),
PROC(LOOKUP, enc_lookup, dec_lookup), PROC(LOOKUP, enc_lookup, dec_lookup),
PROC(LOOKUP_ROOT, enc_lookup_root, dec_lookup_root), PROC(LOOKUP_ROOT, enc_lookup_root, dec_lookup_root),
PROC(REMOVE, enc_remove, dec_remove),
}; };
struct rpc_version nfs_version4 = { struct rpc_version nfs_version4 = {
......
...@@ -307,6 +307,7 @@ enum { ...@@ -307,6 +307,7 @@ enum {
NFSPROC4_CLNT_GETATTR, NFSPROC4_CLNT_GETATTR,
NFSPROC4_CLNT_LOOKUP, NFSPROC4_CLNT_LOOKUP,
NFSPROC4_CLNT_LOOKUP_ROOT, NFSPROC4_CLNT_LOOKUP_ROOT,
NFSPROC4_CLNT_REMOVE,
}; };
#endif #endif
......
...@@ -607,11 +607,15 @@ struct nfs4_readlink { ...@@ -607,11 +607,15 @@ struct nfs4_readlink {
}; };
struct nfs4_remove { struct nfs4_remove {
u32 rm_namelen; /* request */ struct qstr * name; /* request */
const char * rm_name; /* request */
struct nfs4_change_info * rm_cinfo; /* response */ struct nfs4_change_info * rm_cinfo; /* response */
}; };
struct nfs4_remove_arg {
const struct nfs_fh * fh;
const struct qstr * name;
};
struct nfs4_rename { struct nfs4_rename {
u32 rn_oldnamelen; /* request */ u32 rn_oldnamelen; /* request */
const char * rn_oldname; /* request */ const char * rn_oldname; /* 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