aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfsd/nfs4state.c62
1 files changed, 49 insertions, 13 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index c65a27b76a9d..74e822ec34cb 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -206,7 +206,7 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f
206 dp->dl_recall.cbr_dp = NULL; 206 dp->dl_recall.cbr_dp = NULL;
207 dp->dl_recall.cbr_ident = cb->cb_ident; 207 dp->dl_recall.cbr_ident = cb->cb_ident;
208 dp->dl_recall.cbr_trunc = 0; 208 dp->dl_recall.cbr_trunc = 0;
209 dp->dl_stateid.si_boot = boot_time; 209 dp->dl_stateid.si_boot = get_seconds();
210 dp->dl_stateid.si_stateownerid = current_delegid++; 210 dp->dl_stateid.si_stateownerid = current_delegid++;
211 dp->dl_stateid.si_fileid = 0; 211 dp->dl_stateid.si_fileid = 0;
212 dp->dl_stateid.si_generation = 0; 212 dp->dl_stateid.si_generation = 0;
@@ -1883,7 +1883,7 @@ init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *
1883 stp->st_stateowner = sop; 1883 stp->st_stateowner = sop;
1884 get_nfs4_file(fp); 1884 get_nfs4_file(fp);
1885 stp->st_file = fp; 1885 stp->st_file = fp;
1886 stp->st_stateid.si_boot = boot_time; 1886 stp->st_stateid.si_boot = get_seconds();
1887 stp->st_stateid.si_stateownerid = sop->so_id; 1887 stp->st_stateid.si_stateownerid = sop->so_id;
1888 stp->st_stateid.si_fileid = fp->fi_id; 1888 stp->st_stateid.si_fileid = fp->fi_id;
1889 stp->st_stateid.si_generation = 0; 1889 stp->st_stateid.si_generation = 0;
@@ -2739,12 +2739,42 @@ nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stateid *stp)
2739static int 2739static int
2740STALE_STATEID(stateid_t *stateid) 2740STALE_STATEID(stateid_t *stateid)
2741{ 2741{
2742 if (stateid->si_boot == boot_time) 2742 if (time_after((unsigned long)boot_time,
2743 return 0; 2743 (unsigned long)stateid->si_boot)) {
2744 dprintk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n", 2744 dprintk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n",
2745 stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid, 2745 stateid->si_boot, stateid->si_stateownerid,
2746 stateid->si_generation); 2746 stateid->si_fileid, stateid->si_generation);
2747 return 1; 2747 return 1;
2748 }
2749 return 0;
2750}
2751
2752static int
2753EXPIRED_STATEID(stateid_t *stateid)
2754{
2755 if (time_before((unsigned long)boot_time,
2756 ((unsigned long)stateid->si_boot)) &&
2757 time_before((stateid->si_boot + lease_time), get_seconds())) {
2758 dprintk("NFSD: expired stateid (%08x/%08x/%08x/%08x)!\n",
2759 stateid->si_boot, stateid->si_stateownerid,
2760 stateid->si_fileid, stateid->si_generation);
2761 return 1;
2762 }
2763 return 0;
2764}
2765
2766static __be32
2767stateid_error_map(stateid_t *stateid)
2768{
2769 if (STALE_STATEID(stateid))
2770 return nfserr_stale_stateid;
2771 if (EXPIRED_STATEID(stateid))
2772 return nfserr_expired;
2773
2774 dprintk("NFSD: bad stateid (%08x/%08x/%08x/%08x)!\n",
2775 stateid->si_boot, stateid->si_stateownerid,
2776 stateid->si_fileid, stateid->si_generation);
2777 return nfserr_bad_stateid;
2748} 2778}
2749 2779
2750static inline int 2780static inline int
@@ -2868,8 +2898,10 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
2868 status = nfserr_bad_stateid; 2898 status = nfserr_bad_stateid;
2869 if (is_delegation_stateid(stateid)) { 2899 if (is_delegation_stateid(stateid)) {
2870 dp = find_delegation_stateid(ino, stateid); 2900 dp = find_delegation_stateid(ino, stateid);
2871 if (!dp) 2901 if (!dp) {
2902 status = stateid_error_map(stateid);
2872 goto out; 2903 goto out;
2904 }
2873 status = check_stateid_generation(stateid, &dp->dl_stateid, 2905 status = check_stateid_generation(stateid, &dp->dl_stateid,
2874 flags); 2906 flags);
2875 if (status) 2907 if (status)
@@ -2882,8 +2914,10 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
2882 *filpp = dp->dl_vfs_file; 2914 *filpp = dp->dl_vfs_file;
2883 } else { /* open or lock stateid */ 2915 } else { /* open or lock stateid */
2884 stp = find_stateid(stateid, flags); 2916 stp = find_stateid(stateid, flags);
2885 if (!stp) 2917 if (!stp) {
2918 status = stateid_error_map(stateid);
2886 goto out; 2919 goto out;
2920 }
2887 if (nfs4_check_fh(current_fh, stp)) 2921 if (nfs4_check_fh(current_fh, stp))
2888 goto out; 2922 goto out;
2889 if (!stp->st_stateowner->so_confirmed) 2923 if (!stp->st_stateowner->so_confirmed)
@@ -2957,7 +2991,7 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
2957 */ 2991 */
2958 sop = search_close_lru(stateid->si_stateownerid, flags); 2992 sop = search_close_lru(stateid->si_stateownerid, flags);
2959 if (sop == NULL) 2993 if (sop == NULL)
2960 return nfserr_bad_stateid; 2994 return stateid_error_map(stateid);
2961 *sopp = sop; 2995 *sopp = sop;
2962 goto check_replay; 2996 goto check_replay;
2963 } 2997 }
@@ -3228,8 +3262,10 @@ nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3228 if (!is_delegation_stateid(stateid)) 3262 if (!is_delegation_stateid(stateid))
3229 goto out; 3263 goto out;
3230 dp = find_delegation_stateid(inode, stateid); 3264 dp = find_delegation_stateid(inode, stateid);
3231 if (!dp) 3265 if (!dp) {
3266 status = stateid_error_map(stateid);
3232 goto out; 3267 goto out;
3268 }
3233 status = check_stateid_generation(stateid, &dp->dl_stateid, flags); 3269 status = check_stateid_generation(stateid, &dp->dl_stateid, flags);
3234 if (status) 3270 if (status)
3235 goto out; 3271 goto out;
@@ -3456,7 +3492,7 @@ alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struc
3456 stp->st_stateowner = sop; 3492 stp->st_stateowner = sop;
3457 get_nfs4_file(fp); 3493 get_nfs4_file(fp);
3458 stp->st_file = fp; 3494 stp->st_file = fp;
3459 stp->st_stateid.si_boot = boot_time; 3495 stp->st_stateid.si_boot = get_seconds();
3460 stp->st_stateid.si_stateownerid = sop->so_id; 3496 stp->st_stateid.si_stateownerid = sop->so_id;
3461 stp->st_stateid.si_fileid = fp->fi_id; 3497 stp->st_stateid.si_fileid = fp->fi_id;
3462 stp->st_stateid.si_generation = 0; 3498 stp->st_stateid.si_generation = 0;