diff options
-rw-r--r-- | fs/nfsd/nfs4state.c | 62 |
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) | |||
2739 | static int | 2739 | static int |
2740 | STALE_STATEID(stateid_t *stateid) | 2740 | STALE_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 | |||
2752 | static int | ||
2753 | EXPIRED_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 | |||
2766 | static __be32 | ||
2767 | stateid_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 | ||
2750 | static inline int | 2780 | static 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; |