aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4state.c
diff options
context:
space:
mode:
authorBenny Halevy <bhalevy@panasas.com>2008-12-15 12:42:03 -0500
committerJ. Bruce Fields <bfields@citi.umich.edu>2009-01-07 17:38:31 -0500
commit87df4de8073f922a1f643b9fa6ba0412d5529ecf (patch)
tree8a7e5d7c5d531ac277c2e0026329f589ccdae101 /fs/nfsd/nfs4state.c
parent4e65ebf08951326709817e654c149d0a94982e01 (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/nfsd/nfs4state.c')
-rw-r--r--fs/nfsd/nfs4state.c42
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
2419static inline u64
2420end_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 */
2429static inline u64
2430last_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:
2617static int 2637static int
2618check_lock_length(u64 offset, u64 length) 2638check_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 /*