aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 46623ac3ce86..cc33a1c32cfb 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -63,6 +63,7 @@ static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinf
63static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *); 63static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *);
64static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry); 64static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry);
65static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception); 65static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception);
66static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs4_client *clp);
66extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus); 67extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus);
67extern struct rpc_procinfo nfs4_procedures[]; 68extern struct rpc_procinfo nfs4_procedures[];
68 69
@@ -765,6 +766,15 @@ out:
765 return -EACCES; 766 return -EACCES;
766} 767}
767 768
769int nfs4_recover_expired_lease(struct nfs_server *server)
770{
771 struct nfs4_client *clp = server->nfs4_state;
772
773 if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
774 nfs4_schedule_state_recovery(clp);
775 return nfs4_wait_clnt_recover(server->client, clp);
776}
777
768/* 778/*
769 * OPEN_EXPIRED: 779 * OPEN_EXPIRED:
770 * reclaim state on the server after a network partition. 780 * reclaim state on the server after a network partition.
@@ -840,6 +850,9 @@ static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred
840 int open_flags = flags & (FMODE_READ|FMODE_WRITE); 850 int open_flags = flags & (FMODE_READ|FMODE_WRITE);
841 int err; 851 int err;
842 852
853 err = nfs4_recover_expired_lease(server);
854 if (err != 0)
855 return err;
843 /* Protect against reboot recovery - NOTE ORDER! */ 856 /* Protect against reboot recovery - NOTE ORDER! */
844 down_read(&clp->cl_sem); 857 down_read(&clp->cl_sem);
845 /* Protect against delegation recall */ 858 /* Protect against delegation recall */
@@ -921,12 +934,16 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
921 int status; 934 int status;
922 935
923 /* Protect against reboot recovery conflicts */ 936 /* Protect against reboot recovery conflicts */
924 down_read(&clp->cl_sem);
925 status = -ENOMEM; 937 status = -ENOMEM;
926 if (!(sp = nfs4_get_state_owner(server, cred))) { 938 if (!(sp = nfs4_get_state_owner(server, cred))) {
927 dprintk("nfs4_do_open: nfs4_get_state_owner failed!\n"); 939 dprintk("nfs4_do_open: nfs4_get_state_owner failed!\n");
928 goto out_err; 940 goto out_err;
929 } 941 }
942 status = nfs4_recover_expired_lease(server);
943 if (status != 0)
944 goto out_err;
945 down_read(&clp->cl_sem);
946 status = -ENOMEM;
930 opendata = nfs4_opendata_alloc(dentry, sp, flags, sattr); 947 opendata = nfs4_opendata_alloc(dentry, sp, flags, sattr);
931 if (opendata == NULL) 948 if (opendata == NULL)
932 goto err_put_state_owner; 949 goto err_put_state_owner;
@@ -2897,6 +2914,7 @@ nfs4_proc_setclientid_confirm(struct nfs4_client *clp)
2897 spin_lock(&clp->cl_lock); 2914 spin_lock(&clp->cl_lock);
2898 clp->cl_lease_time = fsinfo.lease_time * HZ; 2915 clp->cl_lease_time = fsinfo.lease_time * HZ;
2899 clp->cl_last_renewal = now; 2916 clp->cl_last_renewal = now;
2917 clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
2900 spin_unlock(&clp->cl_lock); 2918 spin_unlock(&clp->cl_lock);
2901 } 2919 }
2902 return status; 2920 return status;