diff options
-rw-r--r-- | fs/nfs/nfs4_fs.h | 6 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 40 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 12 |
3 files changed, 50 insertions, 8 deletions
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 2b141c5758ec..df9e36319499 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
@@ -178,6 +178,7 @@ struct nfs4_state_recovery_ops { | |||
178 | int state_flag_bit; | 178 | int state_flag_bit; |
179 | int (*recover_open)(struct nfs4_state_owner *, struct nfs4_state *); | 179 | int (*recover_open)(struct nfs4_state_owner *, struct nfs4_state *); |
180 | int (*recover_lock)(struct nfs4_state *, struct file_lock *); | 180 | int (*recover_lock)(struct nfs4_state *, struct file_lock *); |
181 | int (*establish_clid)(struct nfs_client *, struct rpc_cred *); | ||
181 | }; | 182 | }; |
182 | 183 | ||
183 | struct nfs4_state_maintenance_ops { | 184 | struct nfs4_state_maintenance_ops { |
@@ -200,6 +201,7 @@ extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struc | |||
200 | extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *); | 201 | extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *); |
201 | extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *); | 202 | extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *); |
202 | extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *); | 203 | extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *); |
204 | extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *); | ||
203 | extern int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait); | 205 | extern int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait); |
204 | extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *); | 206 | extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *); |
205 | extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *); | 207 | extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *); |
@@ -207,8 +209,8 @@ extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fh | |||
207 | extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, | 209 | extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, |
208 | struct nfs4_fs_locations *fs_locations, struct page *page); | 210 | struct nfs4_fs_locations *fs_locations, struct page *page); |
209 | 211 | ||
210 | extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops; | 212 | extern struct nfs4_state_recovery_ops *nfs4_reboot_recovery_ops[]; |
211 | extern struct nfs4_state_recovery_ops nfs4_nograce_recovery_ops; | 213 | extern struct nfs4_state_recovery_ops *nfs4_nograce_recovery_ops[]; |
212 | #if defined(CONFIG_NFS_V4_1) | 214 | #if defined(CONFIG_NFS_V4_1) |
213 | extern int nfs4_setup_sequence(struct nfs_client *clp, | 215 | extern int nfs4_setup_sequence(struct nfs_client *clp, |
214 | struct nfs4_sequence_args *args, struct nfs4_sequence_res *res, | 216 | struct nfs4_sequence_args *args, struct nfs4_sequence_res *res, |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index f862a66e5fb9..dd46339095ce 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -4780,19 +4780,41 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp, | |||
4780 | 4780 | ||
4781 | #endif /* CONFIG_NFS_V4_1 */ | 4781 | #endif /* CONFIG_NFS_V4_1 */ |
4782 | 4782 | ||
4783 | struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops = { | 4783 | struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = { |
4784 | .owner_flag_bit = NFS_OWNER_RECLAIM_REBOOT, | 4784 | .owner_flag_bit = NFS_OWNER_RECLAIM_REBOOT, |
4785 | .state_flag_bit = NFS_STATE_RECLAIM_REBOOT, | 4785 | .state_flag_bit = NFS_STATE_RECLAIM_REBOOT, |
4786 | .recover_open = nfs4_open_reclaim, | 4786 | .recover_open = nfs4_open_reclaim, |
4787 | .recover_lock = nfs4_lock_reclaim, | 4787 | .recover_lock = nfs4_lock_reclaim, |
4788 | .establish_clid = nfs4_init_clientid, | ||
4788 | }; | 4789 | }; |
4789 | 4790 | ||
4790 | struct nfs4_state_recovery_ops nfs4_nograce_recovery_ops = { | 4791 | #if defined(CONFIG_NFS_V4_1) |
4792 | struct nfs4_state_recovery_ops nfs41_reboot_recovery_ops = { | ||
4793 | .owner_flag_bit = NFS_OWNER_RECLAIM_REBOOT, | ||
4794 | .state_flag_bit = NFS_STATE_RECLAIM_REBOOT, | ||
4795 | .recover_open = nfs4_open_reclaim, | ||
4796 | .recover_lock = nfs4_lock_reclaim, | ||
4797 | .establish_clid = nfs4_proc_exchange_id, | ||
4798 | }; | ||
4799 | #endif /* CONFIG_NFS_V4_1 */ | ||
4800 | |||
4801 | struct nfs4_state_recovery_ops nfs40_nograce_recovery_ops = { | ||
4802 | .owner_flag_bit = NFS_OWNER_RECLAIM_NOGRACE, | ||
4803 | .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE, | ||
4804 | .recover_open = nfs4_open_expired, | ||
4805 | .recover_lock = nfs4_lock_expired, | ||
4806 | .establish_clid = nfs4_init_clientid, | ||
4807 | }; | ||
4808 | |||
4809 | #if defined(CONFIG_NFS_V4_1) | ||
4810 | struct nfs4_state_recovery_ops nfs41_nograce_recovery_ops = { | ||
4791 | .owner_flag_bit = NFS_OWNER_RECLAIM_NOGRACE, | 4811 | .owner_flag_bit = NFS_OWNER_RECLAIM_NOGRACE, |
4792 | .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE, | 4812 | .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE, |
4793 | .recover_open = nfs4_open_expired, | 4813 | .recover_open = nfs4_open_expired, |
4794 | .recover_lock = nfs4_lock_expired, | 4814 | .recover_lock = nfs4_lock_expired, |
4815 | .establish_clid = nfs4_proc_exchange_id, | ||
4795 | }; | 4816 | }; |
4817 | #endif /* CONFIG_NFS_V4_1 */ | ||
4796 | 4818 | ||
4797 | struct nfs4_state_maintenance_ops nfs40_state_renewal_ops = { | 4819 | struct nfs4_state_maintenance_ops nfs40_state_renewal_ops = { |
4798 | .sched_state_renewal = nfs4_proc_async_renew, | 4820 | .sched_state_renewal = nfs4_proc_async_renew, |
@@ -4812,6 +4834,20 @@ struct nfs4_state_maintenance_ops nfs41_state_renewal_ops = { | |||
4812 | * Per minor version reboot and network partition recovery ops | 4834 | * Per minor version reboot and network partition recovery ops |
4813 | */ | 4835 | */ |
4814 | 4836 | ||
4837 | struct nfs4_state_recovery_ops *nfs4_reboot_recovery_ops[] = { | ||
4838 | &nfs40_reboot_recovery_ops, | ||
4839 | #if defined(CONFIG_NFS_V4_1) | ||
4840 | &nfs41_reboot_recovery_ops, | ||
4841 | #endif | ||
4842 | }; | ||
4843 | |||
4844 | struct nfs4_state_recovery_ops *nfs4_nograce_recovery_ops[] = { | ||
4845 | &nfs40_nograce_recovery_ops, | ||
4846 | #if defined(CONFIG_NFS_V4_1) | ||
4847 | &nfs41_nograce_recovery_ops, | ||
4848 | #endif | ||
4849 | }; | ||
4850 | |||
4815 | struct nfs4_state_maintenance_ops *nfs4_state_renewal_ops[] = { | 4851 | struct nfs4_state_maintenance_ops *nfs4_state_renewal_ops[] = { |
4816 | &nfs40_state_renewal_ops, | 4852 | &nfs40_state_renewal_ops, |
4817 | #if defined(CONFIG_NFS_V4_1) | 4853 | #if defined(CONFIG_NFS_V4_1) |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index da940abcfaa5..e17bd4412174 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -60,7 +60,7 @@ const nfs4_stateid zero_stateid; | |||
60 | 60 | ||
61 | static LIST_HEAD(nfs4_clientid_list); | 61 | static LIST_HEAD(nfs4_clientid_list); |
62 | 62 | ||
63 | static int nfs4_init_client(struct nfs_client *clp, struct rpc_cred *cred) | 63 | int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) |
64 | { | 64 | { |
65 | unsigned short port; | 65 | unsigned short port; |
66 | int status; | 66 | int status; |
@@ -1098,11 +1098,13 @@ out: | |||
1098 | static int nfs4_reclaim_lease(struct nfs_client *clp) | 1098 | static int nfs4_reclaim_lease(struct nfs_client *clp) |
1099 | { | 1099 | { |
1100 | struct rpc_cred *cred; | 1100 | struct rpc_cred *cred; |
1101 | struct nfs4_state_recovery_ops *ops = | ||
1102 | nfs4_reboot_recovery_ops[clp->cl_minorversion]; | ||
1101 | int status = -ENOENT; | 1103 | int status = -ENOENT; |
1102 | 1104 | ||
1103 | cred = nfs4_get_setclientid_cred(clp); | 1105 | cred = nfs4_get_setclientid_cred(clp); |
1104 | if (cred != NULL) { | 1106 | if (cred != NULL) { |
1105 | status = nfs4_init_client(clp, cred); | 1107 | status = ops->establish_clid(clp, cred); |
1106 | put_rpccred(cred); | 1108 | put_rpccred(cred); |
1107 | /* Handle case where the user hasn't set up machine creds */ | 1109 | /* Handle case where the user hasn't set up machine creds */ |
1108 | if (status == -EACCES && cred == clp->cl_machine_cred) { | 1110 | if (status == -EACCES && cred == clp->cl_machine_cred) { |
@@ -1208,7 +1210,8 @@ static void nfs4_state_manager(struct nfs_client *clp) | |||
1208 | } | 1210 | } |
1209 | /* First recover reboot state... */ | 1211 | /* First recover reboot state... */ |
1210 | if (test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) { | 1212 | if (test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) { |
1211 | status = nfs4_do_reclaim(clp, &nfs4_reboot_recovery_ops); | 1213 | status = nfs4_do_reclaim(clp, |
1214 | nfs4_reboot_recovery_ops[clp->cl_minorversion]); | ||
1212 | if (status == -NFS4ERR_STALE_CLIENTID) | 1215 | if (status == -NFS4ERR_STALE_CLIENTID) |
1213 | continue; | 1216 | continue; |
1214 | if (test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) | 1217 | if (test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) |
@@ -1219,7 +1222,8 @@ static void nfs4_state_manager(struct nfs_client *clp) | |||
1219 | 1222 | ||
1220 | /* Now recover expired state... */ | 1223 | /* Now recover expired state... */ |
1221 | if (test_and_clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) { | 1224 | if (test_and_clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) { |
1222 | status = nfs4_do_reclaim(clp, &nfs4_nograce_recovery_ops); | 1225 | status = nfs4_do_reclaim(clp, |
1226 | nfs4_nograce_recovery_ops[clp->cl_minorversion]); | ||
1223 | if (status < 0) { | 1227 | if (status < 0) { |
1224 | set_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state); | 1228 | set_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state); |
1225 | if (status == -NFS4ERR_STALE_CLIENTID) | 1229 | if (status == -NFS4ERR_STALE_CLIENTID) |