Commit 2ca4be61 authored by Trond Myklebust's avatar Trond Myklebust

NFSv4: Add nfs4_state_recovery_ops

 We want to reuse the same code to recover the NFSv4 state after a server
 reboot, a network partition, or a failover situation.

 Add a structure to contain those operations will that depend on the recovery
 scenario under consideration.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 4800a811
......@@ -263,7 +263,7 @@ static int _nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *st
return status;
}
int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state)
static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state)
{
struct nfs_server *server = NFS_SERVER(state->inode);
struct nfs4_exception exception = { };
......@@ -2558,7 +2558,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *r
return status;
}
int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
{
return _nfs4_do_setlk(state, F_SETLK, request, 1);
}
......@@ -2632,6 +2632,11 @@ nfs4_proc_lock(struct file *filp, int cmd, struct file_lock *request)
return status;
}
struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops = {
.recover_open = nfs4_open_reclaim,
.recover_lock = nfs4_lock_reclaim,
};
struct nfs_rpc_ops nfs_v4_clientops = {
.version = 4, /* protocol version */
.dentry_ops = &nfs4_dentry_operations,
......
......@@ -765,7 +765,7 @@ nfs4_schedule_state_recovery(struct nfs4_client *clp)
schedule_work(&clp->cl_recoverd);
}
static int nfs4_reclaim_locks(struct nfs4_state *state)
static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_state *state)
{
struct inode *inode = state->inode;
struct file_lock *fl;
......@@ -776,7 +776,7 @@ static int nfs4_reclaim_locks(struct nfs4_state *state)
continue;
if (((struct nfs_open_context *)fl->fl_file->private_data)->state != state)
continue;
status = nfs4_lock_reclaim(state, fl);
status = ops->recover_lock(state, fl);
if (status >= 0)
continue;
switch (status) {
......@@ -798,7 +798,7 @@ static int nfs4_reclaim_locks(struct nfs4_state *state)
return status;
}
static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp)
static int nfs4_reclaim_open_state(struct nfs4_state_recovery_ops *ops, struct nfs4_state_owner *sp)
{
struct nfs4_state *state;
struct nfs4_lock_state *lock;
......@@ -815,11 +815,11 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp)
list_for_each_entry(state, &sp->so_states, open_states) {
if (state->state == 0)
continue;
status = nfs4_open_reclaim(sp, state);
status = ops->recover_open(sp, state);
list_for_each_entry(lock, &state->lock_states, ls_locks)
lock->ls_flags &= ~NFS_LOCK_INITIALIZED;
if (status >= 0) {
status = nfs4_reclaim_locks(state);
status = nfs4_reclaim_locks(ops, state);
if (status < 0)
goto out_err;
list_for_each_entry(lock, &state->lock_states, ls_locks) {
......@@ -860,6 +860,7 @@ static int reclaimer(void *ptr)
struct reclaimer_args *args = (struct reclaimer_args *)ptr;
struct nfs4_client *clp = args->clp;
struct nfs4_state_owner *sp;
struct nfs4_state_recovery_ops *ops;
int status = 0;
daemonize("%u.%u.%u.%u-reclaim", NIPQUAD(clp->cl_addr));
......@@ -878,6 +879,7 @@ static int reclaimer(void *ptr)
status = nfs4_proc_renew(clp);
if (status == 0 || status == -NFS4ERR_CB_PATH_DOWN)
goto out;
ops = &nfs4_reboot_recovery_ops;
status = __nfs4_init_client(clp);
if (status)
goto out_error;
......@@ -885,7 +887,7 @@ static int reclaimer(void *ptr)
nfs_delegation_mark_reclaim(clp);
/* Note: list is protected by exclusive lock on cl->cl_sem */
list_for_each_entry(sp, &clp->cl_state_owners, so_list) {
status = nfs4_reclaim_open_state(sp);
status = nfs4_reclaim_open_state(ops, sp);
if (status < 0) {
if (status == -NFS4ERR_STALE_CLIENTID)
goto restart_loop;
......
......@@ -673,6 +673,11 @@ struct nfs4_exception {
int retry;
};
struct nfs4_state_recovery_ops {
int (*recover_open)(struct nfs4_state_owner *, struct nfs4_state *);
int (*recover_lock)(struct nfs4_state *, struct file_lock *);
};
extern struct dentry_operations nfs4_dentry_operations;
extern struct inode_operations nfs4_dir_inode_operations;
......@@ -680,13 +685,13 @@ extern struct inode_operations nfs4_dir_inode_operations;
extern int nfs4_map_errors(int err);
extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short);
extern int nfs4_proc_setclientid_confirm(struct nfs4_client *);
extern int nfs4_open_reclaim(struct nfs4_state_owner *, struct nfs4_state *);
extern int nfs4_proc_async_renew(struct nfs4_client *);
extern int nfs4_proc_renew(struct nfs4_client *);
extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state, mode_t mode);
extern struct inode *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
extern int nfs4_open_revalidate(struct inode *, struct dentry *, int);
extern int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request);
extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;
/* nfs4renewd.c */
extern void nfs4_schedule_state_renewal(struct nfs4_client *);
......
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