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