Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4fdc17b2 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFS: Introduce struct nfs_removeargs+nfs_removeres



We need a common structure for setting up an unlink() rpc call in order to
fix the asynchronous unlink code.

Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 3062c532
Loading
Loading
Loading
Loading
+16 −3
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@
#define NFS_entry_sz		(NFS_filename_sz+3)

#define NFS_diropargs_sz	(NFS_fhandle_sz+NFS_filename_sz)
#define NFS_removeargs_sz	(NFS_fhandle_sz+NFS_filename_sz)
#define NFS_sattrargs_sz	(NFS_fhandle_sz+NFS_sattr_sz)
#define NFS_readlinkargs_sz	(NFS_fhandle_sz)
#define NFS_readargs_sz		(NFS_fhandle_sz+3)
@@ -66,7 +67,7 @@
 * Common NFS XDR functions as inlines
 */
static inline __be32 *
xdr_encode_fhandle(__be32 *p, struct nfs_fh *fhandle)
xdr_encode_fhandle(__be32 *p, const struct nfs_fh *fhandle)
{
	memcpy(p, fhandle->data, NFS2_FHSIZE);
	return p + XDR_QUADLEN(NFS2_FHSIZE);
@@ -204,7 +205,7 @@ nfs_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs_sattrargs *args)

/*
 * Encode directory ops argument
 * LOOKUP, REMOVE, RMDIR
 * LOOKUP, RMDIR
 */
static int
nfs_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs_diropargs *args)
@@ -215,6 +216,18 @@ nfs_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs_diropargs *args)
	return 0;
}

/*
 * Encode REMOVE argument
 */
static int
nfs_xdr_removeargs(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs *args)
{
	p = xdr_encode_fhandle(p, args->fh);
	p = xdr_encode_array(p, args->name.name, args->name.len);
	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
	return 0;
}

/*
 * Arguments to a READ call. Since we read data directly into the page
 * cache, we also set up the reply iovec here so that iov[1] points
@@ -705,7 +718,7 @@ struct rpc_procinfo nfs_procedures[] = {
    PROC(READ,		readargs,	readres, 3),
    PROC(WRITE,		writeargs,	writeres, 4),
    PROC(CREATE,	createargs,	diropres, 0),
    PROC(REMOVE,	diropargs,	stat, 0),
    PROC(REMOVE,	removeargs,	stat, 0),
    PROC(RENAME,	renameargs,	stat, 0),
    PROC(LINK,		linkargs,	stat, 0),
    PROC(SYMLINK,	symlinkargs,	stat, 0),
+17 −17
Original line number Diff line number Diff line
@@ -349,23 +349,23 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
static int
nfs3_proc_remove(struct inode *dir, struct qstr *name)
{
	struct nfs_fattr	dir_attr;
	struct nfs3_diropargs	arg = {
	struct nfs_removeargs arg = {
		.fh = NFS_FH(dir),
		.name		= name->name,
		.len		= name->len
		.name.len = name->len,
		.name.name = name->name,
	};
	struct nfs_removeres res;
	struct rpc_message msg = {
		.rpc_proc = &nfs3_procedures[NFS3PROC_REMOVE],
		.rpc_argp = &arg,
		.rpc_resp	= &dir_attr,
		.rpc_resp = &res,
	};
	int			status;

	dprintk("NFS call  remove %s\n", name->name);
	nfs_fattr_init(&dir_attr);
	nfs_fattr_init(&res.dir_attr);
	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
	nfs_post_op_update_inode(dir, &dir_attr);
	nfs_post_op_update_inode(dir, &res.dir_attr);
	dprintk("NFS reply remove: %d\n", status);
	return status;
}
@@ -374,17 +374,17 @@ static int
nfs3_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir, struct qstr *name)
{
	struct unlinkxdr {
		struct nfs3_diropargs arg;
		struct nfs_fattr res;
		struct nfs_removeargs arg;
		struct nfs_removeres res;
	} *ptr;

	ptr = kmalloc(sizeof(*ptr), GFP_KERNEL);
	if (!ptr)
		return -ENOMEM;
	ptr->arg.fh = NFS_FH(dir->d_inode);
	ptr->arg.name = name->name;
	ptr->arg.len = name->len;
	nfs_fattr_init(&ptr->res);
	ptr->arg.name.name = name->name;
	ptr->arg.name.len = name->len;
	nfs_fattr_init(&ptr->res.dir_attr);
	msg->rpc_proc = &nfs3_procedures[NFS3PROC_REMOVE];
	msg->rpc_argp = &ptr->arg;
	msg->rpc_resp = &ptr->res;
@@ -400,7 +400,7 @@ nfs3_proc_unlink_done(struct dentry *dir, struct rpc_task *task)
	if (nfs3_async_handle_jukebox(task, dir->d_inode))
		return 1;
	if (msg->rpc_argp) {
		dir_attr = (struct nfs_fattr*)msg->rpc_resp;
		dir_attr = &((struct nfs_removeres*)msg->rpc_resp)->dir_attr;
		nfs_post_op_update_inode(dir->d_inode, dir_attr);
		kfree(msg->rpc_argp);
	}
+22 −2
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@

#define NFS3_sattrargs_sz	(NFS3_fh_sz+NFS3_sattr_sz+3)
#define NFS3_diropargs_sz	(NFS3_fh_sz+NFS3_filename_sz)
#define NFS3_removeargs_sz	(NFS3_fh_sz+NFS3_filename_sz)
#define NFS3_accessargs_sz	(NFS3_fh_sz+1)
#define NFS3_readlinkargs_sz	(NFS3_fh_sz)
#define NFS3_readargs_sz	(NFS3_fh_sz+3)
@@ -65,6 +66,7 @@

#define NFS3_attrstat_sz	(1+NFS3_fattr_sz)
#define NFS3_wccstat_sz		(1+NFS3_wcc_data_sz)
#define NFS3_removeres_sz	(NFS3_wccstat_sz)
#define NFS3_lookupres_sz	(1+NFS3_fh_sz+(2 * NFS3_post_op_attr_sz))
#define NFS3_accessres_sz	(1+NFS3_post_op_attr_sz+1)
#define NFS3_readlinkres_sz	(1+NFS3_post_op_attr_sz+1)
@@ -106,7 +108,7 @@ static struct {
 * Common NFS XDR functions as inlines
 */
static inline __be32 *
xdr_encode_fhandle(__be32 *p, struct nfs_fh *fh)
xdr_encode_fhandle(__be32 *p, const struct nfs_fh *fh)
{
	return xdr_encode_array(p, fh->data, fh->size);
}
@@ -299,6 +301,18 @@ nfs3_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs3_diropargs *args)
	return 0;
}

/*
 * Encode REMOVE argument
 */
static int
nfs3_xdr_removeargs(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs *args)
{
	p = xdr_encode_fhandle(p, args->fh);
	p = xdr_encode_array(p, args->name.name, args->name.len);
	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
	return 0;
}

/*
 * Encode access() argument
 */
@@ -736,6 +750,12 @@ nfs3_xdr_wccstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
	return status;
}

static int
nfs3_xdr_removeres(struct rpc_rqst *req, __be32 *p, struct nfs_removeres *res)
{
	return nfs3_xdr_wccstat(req, p, &res->dir_attr);
}

/*
 * Decode LOOKUP reply
 */
@@ -1126,7 +1146,7 @@ struct rpc_procinfo nfs3_procedures[] = {
  PROC(MKDIR,		mkdirargs,	createres, 0),
  PROC(SYMLINK,		symlinkargs,	createres, 0),
  PROC(MKNOD,		mknodargs,	createres, 0),
  PROC(REMOVE,		diropargs,	wccstat, 0),
  PROC(REMOVE,		removeargs,	removeres, 0),
  PROC(RMDIR,		diropargs,	wccstat, 0),
  PROC(RENAME,		renameargs,	renameres, 0),
  PROC(LINK,		linkargs,	linkres, 0),
+15 −16
Original line number Diff line number Diff line
@@ -1925,15 +1925,14 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
static int _nfs4_proc_remove(struct inode *dir, struct qstr *name)
{
	struct nfs_server *server = NFS_SERVER(dir);
	struct nfs4_remove_arg args = {
	struct nfs_removeargs args = {
		.fh = NFS_FH(dir),
		.name = name,
		.name.len = name->len,
		.name.name = name->name,
		.bitmask = server->attr_bitmask,
	};
	struct nfs_fattr dir_attr;
	struct nfs4_remove_res	res = {
	struct nfs_removeres res = {
		.server = server,
		.dir_attr = &dir_attr,
	};
	struct rpc_message msg = {
		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE],
@@ -1942,11 +1941,11 @@ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name)
	};
	int			status;

	nfs_fattr_init(res.dir_attr);
	nfs_fattr_init(&res.dir_attr);
	status = rpc_call_sync(server->client, &msg, 0);
	if (status == 0) {
		update_changeattr(dir, &res.cinfo);
		nfs_post_op_update_inode(dir, res.dir_attr);
		nfs_post_op_update_inode(dir, &res.dir_attr);
	}
	return status;
}
@@ -1964,9 +1963,8 @@ static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
}

struct unlink_desc {
	struct nfs4_remove_arg	args;
	struct nfs4_remove_res	res;
	struct nfs_fattr dir_attr;
	struct nfs_removeargs args;
	struct nfs_removeres res;
};

static int nfs4_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir,
@@ -1980,10 +1978,11 @@ static int nfs4_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir,
		return -ENOMEM;
	
	up->args.fh = NFS_FH(dir->d_inode);
	up->args.name = name;
	up->args.name.len = name->len;
	up->args.name.name = name->name;
	up->args.bitmask = server->attr_bitmask;
	up->res.server = server;
	up->res.dir_attr = &up->dir_attr;
	nfs_fattr_init(&up->res.dir_attr);
	
	msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE];
	msg->rpc_argp = &up->args;
@@ -1999,7 +1998,7 @@ static int nfs4_proc_unlink_done(struct dentry *dir, struct rpc_task *task)
	if (msg->rpc_resp != NULL) {
		up = container_of(msg->rpc_resp, struct unlink_desc, res);
		update_changeattr(dir->d_inode, &up->res.cinfo);
		nfs_post_op_update_inode(dir->d_inode, up->res.dir_attr);
		nfs_post_op_update_inode(dir->d_inode, &up->res.dir_attr);
		kfree(up);
		msg->rpc_resp = NULL;
		msg->rpc_argp = NULL;
+4 −4
Original line number Diff line number Diff line
@@ -1435,7 +1435,7 @@ static int nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, __be32 *p, const struc
/*
 * Encode REMOVE request
 */
static int nfs4_xdr_enc_remove(struct rpc_rqst *req, __be32 *p, const struct nfs4_remove_arg *args)
static int nfs4_xdr_enc_remove(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs *args)
{
	struct xdr_stream xdr;
	struct compound_hdr hdr = {
@@ -1447,7 +1447,7 @@ static int nfs4_xdr_enc_remove(struct rpc_rqst *req, __be32 *p, const struct nfs
	encode_compound_hdr(&xdr, &hdr);
	if ((status = encode_putfh(&xdr, args->fh)) != 0)
		goto out;
	if ((status = encode_remove(&xdr, args->name)) != 0)
	if ((status = encode_remove(&xdr, &args->name)) != 0)
		goto out;
	status = encode_getfattr(&xdr, args->bitmask);
out:
@@ -3835,7 +3835,7 @@ static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, __be32 *p, struct nf
/*
 * Decode REMOVE response
 */
static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_remove_res *res)
static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, __be32 *p, struct nfs_removeres *res)
{
	struct xdr_stream xdr;
	struct compound_hdr hdr;
@@ -3848,7 +3848,7 @@ static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_re
		goto out;
	if ((status = decode_remove(&xdr, &res->cinfo)) != 0)
		goto out;
	decode_getfattr(&xdr, res->dir_attr, res->server);
	decode_getfattr(&xdr, &res->dir_attr, res->server);
out:
	return status;
}
Loading