diff options
author | Benny Halevy <bhalevy@panasas.com> | 2008-12-15 12:42:03 -0500 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2009-01-07 17:38:31 -0500 |
commit | 87df4de8073f922a1f643b9fa6ba0412d5529ecf (patch) | |
tree | 8a7e5d7c5d531ac277c2e0026329f589ccdae101 /fs | |
parent | 4e65ebf08951326709817e654c149d0a94982e01 (diff) |
nfsd: last_byte_offset
refactor the nfs4 server lock code to use last_byte_offset
to compute the last byte covered by the lock. Check for overflow
so that the last byte is set to NFS4_MAX_UINT64 if offset + len
wraps around.
Also, use NFS4_MAX_UINT64 for ~(u64)0 where appropriate.
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfsd/nfs4state.c | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index e62d0e3df8b3..88db7d3ec120 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -2416,6 +2416,26 @@ out: | |||
2416 | #define LOCK_HASH_SIZE (1 << LOCK_HASH_BITS) | 2416 | #define LOCK_HASH_SIZE (1 << LOCK_HASH_BITS) |
2417 | #define LOCK_HASH_MASK (LOCK_HASH_SIZE - 1) | 2417 | #define LOCK_HASH_MASK (LOCK_HASH_SIZE - 1) |
2418 | 2418 | ||
2419 | static inline u64 | ||
2420 | end_offset(u64 start, u64 len) | ||
2421 | { | ||
2422 | u64 end; | ||
2423 | |||
2424 | end = start + len; | ||
2425 | return end >= start ? end: NFS4_MAX_UINT64; | ||
2426 | } | ||
2427 | |||
2428 | /* last octet in a range */ | ||
2429 | static inline u64 | ||
2430 | last_byte_offset(u64 start, u64 len) | ||
2431 | { | ||
2432 | u64 end; | ||
2433 | |||
2434 | BUG_ON(!len); | ||
2435 | end = start + len; | ||
2436 | return end > start ? end - 1: NFS4_MAX_UINT64; | ||
2437 | } | ||
2438 | |||
2419 | #define lockownerid_hashval(id) \ | 2439 | #define lockownerid_hashval(id) \ |
2420 | ((id) & LOCK_HASH_MASK) | 2440 | ((id) & LOCK_HASH_MASK) |
2421 | 2441 | ||
@@ -2519,8 +2539,8 @@ nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny) | |||
2519 | deny->ld_clientid.cl_id = 0; | 2539 | deny->ld_clientid.cl_id = 0; |
2520 | } | 2540 | } |
2521 | deny->ld_start = fl->fl_start; | 2541 | deny->ld_start = fl->fl_start; |
2522 | deny->ld_length = ~(u64)0; | 2542 | deny->ld_length = NFS4_MAX_UINT64; |
2523 | if (fl->fl_end != ~(u64)0) | 2543 | if (fl->fl_end != NFS4_MAX_UINT64) |
2524 | deny->ld_length = fl->fl_end - fl->fl_start + 1; | 2544 | deny->ld_length = fl->fl_end - fl->fl_start + 1; |
2525 | deny->ld_type = NFS4_READ_LT; | 2545 | deny->ld_type = NFS4_READ_LT; |
2526 | if (fl->fl_type != F_RDLCK) | 2546 | if (fl->fl_type != F_RDLCK) |
@@ -2617,7 +2637,7 @@ out: | |||
2617 | static int | 2637 | static int |
2618 | check_lock_length(u64 offset, u64 length) | 2638 | check_lock_length(u64 offset, u64 length) |
2619 | { | 2639 | { |
2620 | return ((length == 0) || ((length != ~(u64)0) && | 2640 | return ((length == 0) || ((length != NFS4_MAX_UINT64) && |
2621 | LOFF_OVERFLOW(offset, length))); | 2641 | LOFF_OVERFLOW(offset, length))); |
2622 | } | 2642 | } |
2623 | 2643 | ||
@@ -2737,11 +2757,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
2737 | file_lock.fl_lmops = &nfsd_posix_mng_ops; | 2757 | file_lock.fl_lmops = &nfsd_posix_mng_ops; |
2738 | 2758 | ||
2739 | file_lock.fl_start = lock->lk_offset; | 2759 | file_lock.fl_start = lock->lk_offset; |
2740 | if ((lock->lk_length == ~(u64)0) || | 2760 | file_lock.fl_end = last_byte_offset(lock->lk_offset, lock->lk_length); |
2741 | LOFF_OVERFLOW(lock->lk_offset, lock->lk_length)) | ||
2742 | file_lock.fl_end = ~(u64)0; | ||
2743 | else | ||
2744 | file_lock.fl_end = lock->lk_offset + lock->lk_length - 1; | ||
2745 | nfs4_transform_lock_offset(&file_lock); | 2761 | nfs4_transform_lock_offset(&file_lock); |
2746 | 2762 | ||
2747 | /* | 2763 | /* |
@@ -2858,10 +2874,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
2858 | file_lock.fl_lmops = &nfsd_posix_mng_ops; | 2874 | file_lock.fl_lmops = &nfsd_posix_mng_ops; |
2859 | 2875 | ||
2860 | file_lock.fl_start = lockt->lt_offset; | 2876 | file_lock.fl_start = lockt->lt_offset; |
2861 | if ((lockt->lt_length == ~(u64)0) || LOFF_OVERFLOW(lockt->lt_offset, lockt->lt_length)) | 2877 | file_lock.fl_end = last_byte_offset(lockt->lt_offset, lockt->lt_length); |
2862 | file_lock.fl_end = ~(u64)0; | ||
2863 | else | ||
2864 | file_lock.fl_end = lockt->lt_offset + lockt->lt_length - 1; | ||
2865 | 2878 | ||
2866 | nfs4_transform_lock_offset(&file_lock); | 2879 | nfs4_transform_lock_offset(&file_lock); |
2867 | 2880 | ||
@@ -2917,10 +2930,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
2917 | file_lock.fl_lmops = &nfsd_posix_mng_ops; | 2930 | file_lock.fl_lmops = &nfsd_posix_mng_ops; |
2918 | file_lock.fl_start = locku->lu_offset; | 2931 | file_lock.fl_start = locku->lu_offset; |
2919 | 2932 | ||
2920 | if ((locku->lu_length == ~(u64)0) || LOFF_OVERFLOW(locku->lu_offset, locku->lu_length)) | 2933 | file_lock.fl_end = last_byte_offset(locku->lu_offset, locku->lu_length); |
2921 | file_lock.fl_end = ~(u64)0; | ||
2922 | else | ||
2923 | file_lock.fl_end = locku->lu_offset + locku->lu_length - 1; | ||
2924 | nfs4_transform_lock_offset(&file_lock); | 2934 | nfs4_transform_lock_offset(&file_lock); |
2925 | 2935 | ||
2926 | /* | 2936 | /* |