aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/nfs4_fs.h5
-rw-r--r--fs/nfs/nfs4proc.c38
-rw-r--r--fs/nfs/nfs4renewd.c7
-rw-r--r--fs/nfs/nfs4state.c16
4 files changed, 41 insertions, 25 deletions
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 75fe646c28ab..4a9c53e0793c 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -213,8 +213,8 @@ extern ssize_t nfs4_listxattr(struct dentry *, char *, size_t);
213extern int nfs4_map_errors(int err); 213extern int nfs4_map_errors(int err);
214extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short); 214extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short);
215extern int nfs4_proc_setclientid_confirm(struct nfs4_client *); 215extern int nfs4_proc_setclientid_confirm(struct nfs4_client *);
216extern int nfs4_proc_async_renew(struct nfs4_client *); 216extern int nfs4_proc_async_renew(struct nfs4_client *, struct rpc_cred *);
217extern int nfs4_proc_renew(struct nfs4_client *); 217extern int nfs4_proc_renew(struct nfs4_client *, struct rpc_cred *);
218extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state); 218extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state);
219extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *); 219extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
220extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *); 220extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);
@@ -240,6 +240,7 @@ extern struct nfs4_client *nfs4_get_client(struct in_addr *);
240extern void nfs4_put_client(struct nfs4_client *clp); 240extern void nfs4_put_client(struct nfs4_client *clp);
241extern int nfs4_init_client(struct nfs4_client *clp); 241extern int nfs4_init_client(struct nfs4_client *clp);
242extern struct nfs4_client *nfs4_find_client(struct in_addr *); 242extern struct nfs4_client *nfs4_find_client(struct in_addr *);
243struct rpc_cred *nfs4_get_renew_cred(struct nfs4_client *clp);
243extern u32 nfs4_alloc_lockowner_id(struct nfs4_client *); 244extern u32 nfs4_alloc_lockowner_id(struct nfs4_client *);
244 245
245extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *); 246extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index cc33a1c32cfb..e38401931291 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -850,9 +850,14 @@ static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred
850 int open_flags = flags & (FMODE_READ|FMODE_WRITE); 850 int open_flags = flags & (FMODE_READ|FMODE_WRITE);
851 int err; 851 int err;
852 852
853 err = -ENOMEM;
854 if (!(sp = nfs4_get_state_owner(server, cred))) {
855 dprintk("%s: nfs4_get_state_owner failed!\n", __FUNCTION__);
856 return err;
857 }
853 err = nfs4_recover_expired_lease(server); 858 err = nfs4_recover_expired_lease(server);
854 if (err != 0) 859 if (err != 0)
855 return err; 860 goto out_put_state_owner;
856 /* Protect against reboot recovery - NOTE ORDER! */ 861 /* Protect against reboot recovery - NOTE ORDER! */
857 down_read(&clp->cl_sem); 862 down_read(&clp->cl_sem);
858 /* Protect against delegation recall */ 863 /* Protect against delegation recall */
@@ -862,10 +867,6 @@ static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred
862 if (delegation == NULL || (delegation->type & open_flags) != open_flags) 867 if (delegation == NULL || (delegation->type & open_flags) != open_flags)
863 goto out_err; 868 goto out_err;
864 err = -ENOMEM; 869 err = -ENOMEM;
865 if (!(sp = nfs4_get_state_owner(server, cred))) {
866 dprintk("%s: nfs4_get_state_owner failed!\n", __FUNCTION__);
867 goto out_err;
868 }
869 state = nfs4_get_open_state(inode, sp); 870 state = nfs4_get_open_state(inode, sp);
870 if (state == NULL) 871 if (state == NULL)
871 goto out_err; 872 goto out_err;
@@ -877,13 +878,13 @@ static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred
877 spin_unlock(&inode->i_lock); 878 spin_unlock(&inode->i_lock);
878 goto out_ok; 879 goto out_ok;
879 } else if (state->state != 0) 880 } else if (state->state != 0)
880 goto out_err; 881 goto out_put_open_state;
881 882
882 lock_kernel(); 883 lock_kernel();
883 err = _nfs4_do_access(inode, cred, open_flags); 884 err = _nfs4_do_access(inode, cred, open_flags);
884 unlock_kernel(); 885 unlock_kernel();
885 if (err != 0) 886 if (err != 0)
886 goto out_err; 887 goto out_put_open_state;
887 set_bit(NFS_DELEGATED_STATE, &state->flags); 888 set_bit(NFS_DELEGATED_STATE, &state->flags);
888 update_open_stateid(state, &delegation->stateid, open_flags); 889 update_open_stateid(state, &delegation->stateid, open_flags);
889out_ok: 890out_ok:
@@ -891,17 +892,16 @@ out_ok:
891 up_read(&nfsi->rwsem); 892 up_read(&nfsi->rwsem);
892 up_read(&clp->cl_sem); 893 up_read(&clp->cl_sem);
893 *res = state; 894 *res = state;
894 return 0; 895 return 0;
896out_put_open_state:
897 nfs4_put_open_state(state);
895out_err: 898out_err:
896 if (sp != NULL) {
897 if (state != NULL)
898 nfs4_put_open_state(state);
899 nfs4_put_state_owner(sp);
900 }
901 up_read(&nfsi->rwsem); 899 up_read(&nfsi->rwsem);
902 up_read(&clp->cl_sem); 900 up_read(&clp->cl_sem);
903 if (err != -EACCES) 901 if (err != -EACCES)
904 nfs_inode_return_delegation(inode); 902 nfs_inode_return_delegation(inode);
903out_put_state_owner:
904 nfs4_put_state_owner(sp);
905 return err; 905 return err;
906} 906}
907 907
@@ -941,7 +941,7 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
941 } 941 }
942 status = nfs4_recover_expired_lease(server); 942 status = nfs4_recover_expired_lease(server);
943 if (status != 0) 943 if (status != 0)
944 goto out_err; 944 goto err_put_state_owner;
945 down_read(&clp->cl_sem); 945 down_read(&clp->cl_sem);
946 status = -ENOMEM; 946 status = -ENOMEM;
947 opendata = nfs4_opendata_alloc(dentry, sp, flags, sattr); 947 opendata = nfs4_opendata_alloc(dentry, sp, flags, sattr);
@@ -2518,26 +2518,24 @@ static const struct rpc_call_ops nfs4_renew_ops = {
2518 .rpc_call_done = nfs4_renew_done, 2518 .rpc_call_done = nfs4_renew_done,
2519}; 2519};
2520 2520
2521int 2521int nfs4_proc_async_renew(struct nfs4_client *clp, struct rpc_cred *cred)
2522nfs4_proc_async_renew(struct nfs4_client *clp)
2523{ 2522{
2524 struct rpc_message msg = { 2523 struct rpc_message msg = {
2525 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW], 2524 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW],
2526 .rpc_argp = clp, 2525 .rpc_argp = clp,
2527 .rpc_cred = clp->cl_cred, 2526 .rpc_cred = cred,
2528 }; 2527 };
2529 2528
2530 return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT, 2529 return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT,
2531 &nfs4_renew_ops, (void *)jiffies); 2530 &nfs4_renew_ops, (void *)jiffies);
2532} 2531}
2533 2532
2534int 2533int nfs4_proc_renew(struct nfs4_client *clp, struct rpc_cred *cred)
2535nfs4_proc_renew(struct nfs4_client *clp)
2536{ 2534{
2537 struct rpc_message msg = { 2535 struct rpc_message msg = {
2538 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW], 2536 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW],
2539 .rpc_argp = clp, 2537 .rpc_argp = clp,
2540 .rpc_cred = clp->cl_cred, 2538 .rpc_cred = cred,
2541 }; 2539 };
2542 unsigned long now = jiffies; 2540 unsigned long now = jiffies;
2543 int status; 2541 int status;
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c
index f62c2f7a4ffb..5d764d8e6d8a 100644
--- a/fs/nfs/nfs4renewd.c
+++ b/fs/nfs/nfs4renewd.c
@@ -62,6 +62,7 @@ void
62nfs4_renew_state(void *data) 62nfs4_renew_state(void *data)
63{ 63{
64 struct nfs4_client *clp = (struct nfs4_client *)data; 64 struct nfs4_client *clp = (struct nfs4_client *)data;
65 struct rpc_cred *cred;
65 long lease, timeout; 66 long lease, timeout;
66 unsigned long last, now; 67 unsigned long last, now;
67 68
@@ -77,7 +78,8 @@ nfs4_renew_state(void *data)
77 timeout = (2 * lease) / 3 + (long)last - (long)now; 78 timeout = (2 * lease) / 3 + (long)last - (long)now;
78 /* Are we close to a lease timeout? */ 79 /* Are we close to a lease timeout? */
79 if (time_after(now, last + lease/3)) { 80 if (time_after(now, last + lease/3)) {
80 if (list_empty(&clp->cl_state_owners)) { 81 cred = nfs4_get_renew_cred(clp);
82 if (cred == NULL) {
81 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); 83 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
82 spin_unlock(&clp->cl_lock); 84 spin_unlock(&clp->cl_lock);
83 nfs_expire_all_delegations(clp); 85 nfs_expire_all_delegations(clp);
@@ -85,7 +87,8 @@ nfs4_renew_state(void *data)
85 } 87 }
86 spin_unlock(&clp->cl_lock); 88 spin_unlock(&clp->cl_lock);
87 /* Queue an asynchronous RENEW. */ 89 /* Queue an asynchronous RENEW. */
88 nfs4_proc_async_renew(clp); 90 nfs4_proc_async_renew(clp, cred);
91 put_rpccred(cred);
89 timeout = (2 * lease) / 3; 92 timeout = (2 * lease) / 3;
90 spin_lock(&clp->cl_lock); 93 spin_lock(&clp->cl_lock);
91 } else 94 } else
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index f2148376f1a7..18f6ed1a0b54 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -232,6 +232,20 @@ nfs4_client_grab_unused(struct nfs4_client *clp, struct rpc_cred *cred)
232 return sp; 232 return sp;
233} 233}
234 234
235struct rpc_cred *nfs4_get_renew_cred(struct nfs4_client *clp)
236{
237 struct nfs4_state_owner *sp;
238 struct rpc_cred *cred = NULL;
239
240 list_for_each_entry(sp, &clp->cl_state_owners, so_list) {
241 if (list_empty(&sp->so_states))
242 continue;
243 cred = get_rpccred(sp->so_cred);
244 break;
245 }
246 return cred;
247}
248
235static struct nfs4_state_owner * 249static struct nfs4_state_owner *
236nfs4_find_state_owner(struct nfs4_client *clp, struct rpc_cred *cred) 250nfs4_find_state_owner(struct nfs4_client *clp, struct rpc_cred *cred)
237{ 251{
@@ -899,7 +913,7 @@ static int reclaimer(void *ptr)
899 if (list_empty(&clp->cl_superblocks)) 913 if (list_empty(&clp->cl_superblocks))
900 goto out; 914 goto out;
901restart_loop: 915restart_loop:
902 status = nfs4_proc_renew(clp); 916 status = nfs4_proc_renew(clp, clp->cl_cred);
903 switch (status) { 917 switch (status) {
904 case 0: 918 case 0:
905 case -NFS4ERR_CB_PATH_DOWN: 919 case -NFS4ERR_CB_PATH_DOWN: