diff options
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 20 |
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 | |||
63 | static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *); | 63 | static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *); |
64 | static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry); | 64 | static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry); |
65 | static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception); | 65 | static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception); |
66 | static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs4_client *clp); | ||
66 | extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus); | 67 | extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus); |
67 | extern struct rpc_procinfo nfs4_procedures[]; | 68 | extern struct rpc_procinfo nfs4_procedures[]; |
68 | 69 | ||
@@ -765,6 +766,15 @@ out: | |||
765 | return -EACCES; | 766 | return -EACCES; |
766 | } | 767 | } |
767 | 768 | ||
769 | int 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; |