Commit be6b809b authored by Trond Myklebust's avatar Trond Myklebust

[PATCH] A basic NFSv4 client for 2.5.x

In NFSv3, an RPC is retried if the special error NFSERR_JUKEBOX is
received.  This generic bit of postprocessing happens invisibly for
synchronous RPC's, but in the async case, the ->tk_exit callback
must call nfs_async_handle_jukebox() by hand.

In NFSv4, we also need generic postprocessing of async RPC's, but
the details are different.  Therefore, we don't want to call
nfs_async_handle_jukebox(); we want to call a different, NFSv4-specific
routine.  Therefore, we want to move calls to nfs_async_handle_jukebox()
out of the "generic" NFS code and into NFSv3-specific routines.  This
has already been done for async READ and WRITE in the preceding patches,
but there is still one outstanding case: the async REMOVE in sillyrename.

This patch removes nfs_async_handle_jukebox() from the async sillyrename
path, and puts in the NFSv3 ->unlink_done() rpc_op.
parent c44ca040
......@@ -392,16 +392,20 @@ nfs3_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir, struct qstr
return 0;
}
static void
nfs3_proc_unlink_done(struct dentry *dir, struct rpc_message *msg)
static int
nfs3_proc_unlink_done(struct dentry *dir, struct rpc_task *task)
{
struct rpc_message *msg = &task->tk_msg;
struct nfs_fattr *dir_attr;
if (nfs_async_handle_jukebox(task))
return 1;
if (msg->rpc_argp) {
dir_attr = (struct nfs_fattr*)msg->rpc_resp;
nfs_refresh_inode(dir->d_inode, dir_attr);
kfree(msg->rpc_argp);
}
return 0;
}
static int
......
......@@ -312,13 +312,16 @@ nfs_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir, struct qstr *
return 0;
}
static void
nfs_proc_unlink_done(struct dentry *dir, struct rpc_message *msg)
static int
nfs_proc_unlink_done(struct dentry *dir, struct rpc_task *task)
{
struct rpc_message *msg = &task->tk_msg;
if (msg->rpc_argp) {
NFS_CACHEINV(dir->d_inode);
kfree(msg->rpc_argp);
}
return 0;
}
static int
......
......@@ -123,13 +123,12 @@ nfs_async_unlink_done(struct rpc_task *task)
struct dentry *dir = data->dir;
struct inode *dir_i;
if (nfs_async_handle_jukebox(task))
return;
if (!dir)
return;
dir_i = dir->d_inode;
nfs_zap_caches(dir_i);
NFS_PROTO(dir_i)->unlink_done(dir, &task->tk_msg);
if (NFS_PROTO(dir_i)->unlink_done(dir, task))
return;
put_rpccred(data->cred);
data->cred = NULL;
dput(dir);
......
......@@ -375,7 +375,7 @@ struct nfs_rpc_ops {
int (*remove) (struct inode *, struct qstr *);
int (*unlink_setup) (struct rpc_message *,
struct dentry *, struct qstr *);
void (*unlink_done) (struct dentry *, struct rpc_message *);
int (*unlink_done) (struct dentry *, struct rpc_task *);
int (*rename) (struct inode *, struct qstr *,
struct inode *, struct qstr *);
int (*link) (struct inode *, struct inode *, struct qstr *);
......
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