diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-15 17:22:45 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-15 17:22:45 -0400 |
| commit | 6d50ff91d9780263160262daeb6adfdda8ddbc6c (patch) | |
| tree | e8e56a75dc03ac71bdfffcf1b97eebd6720e1580 | |
| parent | eccd02f32a2c25139da2d5e72ebab1fee7b5baab (diff) | |
| parent | 0429c2b5c1c4c8ba6cd563c1964baf3ed238df26 (diff) | |
Merge tag 'locks-v4.1-1' of git://git.samba.org/jlayton/linux
Pull file locking related changes from Jeff Layton:
"This set is mostly minor cleanups to the overhaul that went in last
cycle. The other noticeable items are the changes to the lm_get_owner
and lm_put_owner prototypes, and the fact that we no longer need to
use the i_lock to protect the i_flctx pointer"
* tag 'locks-v4.1-1' of git://git.samba.org/jlayton/linux:
locks: use cmpxchg to assign i_flctx pointer
locks: get rid of WE_CAN_BREAK_LSLK_NOW dead code
locks: change lm_get_owner and lm_put_owner prototypes
locks: don't allocate a lock context for an F_UNLCK request
locks: Add lockdep assertion for blocked_lock_lock
locks: remove extraneous IS_POSIX and IS_FLOCK tests
locks: Remove unnecessary IS_POSIX test
| -rw-r--r-- | fs/locks.c | 56 | ||||
| -rw-r--r-- | fs/nfsd/nfs4state.c | 18 | ||||
| -rw-r--r-- | include/linux/fs.h | 4 |
3 files changed, 39 insertions, 39 deletions
diff --git a/fs/locks.c b/fs/locks.c index 40bc384728c0..52b780fb5258 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
| @@ -203,11 +203,11 @@ static struct kmem_cache *flctx_cache __read_mostly; | |||
| 203 | static struct kmem_cache *filelock_cache __read_mostly; | 203 | static struct kmem_cache *filelock_cache __read_mostly; |
| 204 | 204 | ||
| 205 | static struct file_lock_context * | 205 | static struct file_lock_context * |
| 206 | locks_get_lock_context(struct inode *inode) | 206 | locks_get_lock_context(struct inode *inode, int type) |
| 207 | { | 207 | { |
| 208 | struct file_lock_context *new; | 208 | struct file_lock_context *new; |
| 209 | 209 | ||
| 210 | if (likely(inode->i_flctx)) | 210 | if (likely(inode->i_flctx) || type == F_UNLCK) |
| 211 | goto out; | 211 | goto out; |
| 212 | 212 | ||
| 213 | new = kmem_cache_alloc(flctx_cache, GFP_KERNEL); | 213 | new = kmem_cache_alloc(flctx_cache, GFP_KERNEL); |
| @@ -223,14 +223,7 @@ locks_get_lock_context(struct inode *inode) | |||
| 223 | * Assign the pointer if it's not already assigned. If it is, then | 223 | * Assign the pointer if it's not already assigned. If it is, then |
| 224 | * free the context we just allocated. | 224 | * free the context we just allocated. |
| 225 | */ | 225 | */ |
| 226 | spin_lock(&inode->i_lock); | 226 | if (cmpxchg(&inode->i_flctx, NULL, new)) |
| 227 | if (likely(!inode->i_flctx)) { | ||
| 228 | inode->i_flctx = new; | ||
| 229 | new = NULL; | ||
| 230 | } | ||
| 231 | spin_unlock(&inode->i_lock); | ||
| 232 | |||
| 233 | if (new) | ||
| 234 | kmem_cache_free(flctx_cache, new); | 227 | kmem_cache_free(flctx_cache, new); |
| 235 | out: | 228 | out: |
| 236 | return inode->i_flctx; | 229 | return inode->i_flctx; |
| @@ -276,8 +269,10 @@ void locks_release_private(struct file_lock *fl) | |||
| 276 | } | 269 | } |
| 277 | 270 | ||
| 278 | if (fl->fl_lmops) { | 271 | if (fl->fl_lmops) { |
| 279 | if (fl->fl_lmops->lm_put_owner) | 272 | if (fl->fl_lmops->lm_put_owner) { |
| 280 | fl->fl_lmops->lm_put_owner(fl); | 273 | fl->fl_lmops->lm_put_owner(fl->fl_owner); |
| 274 | fl->fl_owner = NULL; | ||
| 275 | } | ||
| 281 | fl->fl_lmops = NULL; | 276 | fl->fl_lmops = NULL; |
| 282 | } | 277 | } |
| 283 | } | 278 | } |
| @@ -333,7 +328,7 @@ void locks_copy_conflock(struct file_lock *new, struct file_lock *fl) | |||
| 333 | 328 | ||
| 334 | if (fl->fl_lmops) { | 329 | if (fl->fl_lmops) { |
| 335 | if (fl->fl_lmops->lm_get_owner) | 330 | if (fl->fl_lmops->lm_get_owner) |
| 336 | fl->fl_lmops->lm_get_owner(new, fl); | 331 | fl->fl_lmops->lm_get_owner(fl->fl_owner); |
| 337 | } | 332 | } |
| 338 | } | 333 | } |
| 339 | EXPORT_SYMBOL(locks_copy_conflock); | 334 | EXPORT_SYMBOL(locks_copy_conflock); |
| @@ -592,11 +587,15 @@ posix_owner_key(struct file_lock *fl) | |||
| 592 | 587 | ||
| 593 | static void locks_insert_global_blocked(struct file_lock *waiter) | 588 | static void locks_insert_global_blocked(struct file_lock *waiter) |
| 594 | { | 589 | { |
| 590 | lockdep_assert_held(&blocked_lock_lock); | ||
| 591 | |||
| 595 | hash_add(blocked_hash, &waiter->fl_link, posix_owner_key(waiter)); | 592 | hash_add(blocked_hash, &waiter->fl_link, posix_owner_key(waiter)); |
| 596 | } | 593 | } |
| 597 | 594 | ||
| 598 | static void locks_delete_global_blocked(struct file_lock *waiter) | 595 | static void locks_delete_global_blocked(struct file_lock *waiter) |
| 599 | { | 596 | { |
| 597 | lockdep_assert_held(&blocked_lock_lock); | ||
| 598 | |||
| 600 | hash_del(&waiter->fl_link); | 599 | hash_del(&waiter->fl_link); |
| 601 | } | 600 | } |
| 602 | 601 | ||
| @@ -730,7 +729,7 @@ static int posix_locks_conflict(struct file_lock *caller_fl, struct file_lock *s | |||
| 730 | /* POSIX locks owned by the same process do not conflict with | 729 | /* POSIX locks owned by the same process do not conflict with |
| 731 | * each other. | 730 | * each other. |
| 732 | */ | 731 | */ |
| 733 | if (!IS_POSIX(sys_fl) || posix_same_owner(caller_fl, sys_fl)) | 732 | if (posix_same_owner(caller_fl, sys_fl)) |
| 734 | return (0); | 733 | return (0); |
| 735 | 734 | ||
| 736 | /* Check whether they overlap */ | 735 | /* Check whether they overlap */ |
| @@ -748,7 +747,7 @@ static int flock_locks_conflict(struct file_lock *caller_fl, struct file_lock *s | |||
| 748 | /* FLOCK locks referring to the same filp do not conflict with | 747 | /* FLOCK locks referring to the same filp do not conflict with |
| 749 | * each other. | 748 | * each other. |
| 750 | */ | 749 | */ |
| 751 | if (!IS_FLOCK(sys_fl) || (caller_fl->fl_file == sys_fl->fl_file)) | 750 | if (caller_fl->fl_file == sys_fl->fl_file) |
| 752 | return (0); | 751 | return (0); |
| 753 | if ((caller_fl->fl_type & LOCK_MAND) || (sys_fl->fl_type & LOCK_MAND)) | 752 | if ((caller_fl->fl_type & LOCK_MAND) || (sys_fl->fl_type & LOCK_MAND)) |
| 754 | return 0; | 753 | return 0; |
| @@ -838,6 +837,8 @@ static int posix_locks_deadlock(struct file_lock *caller_fl, | |||
| 838 | { | 837 | { |
| 839 | int i = 0; | 838 | int i = 0; |
| 840 | 839 | ||
| 840 | lockdep_assert_held(&blocked_lock_lock); | ||
| 841 | |||
| 841 | /* | 842 | /* |
| 842 | * This deadlock detector can't reasonably detect deadlocks with | 843 | * This deadlock detector can't reasonably detect deadlocks with |
| 843 | * FL_OFDLCK locks, since they aren't owned by a process, per-se. | 844 | * FL_OFDLCK locks, since they aren't owned by a process, per-se. |
| @@ -871,9 +872,12 @@ static int flock_lock_file(struct file *filp, struct file_lock *request) | |||
| 871 | bool found = false; | 872 | bool found = false; |
| 872 | LIST_HEAD(dispose); | 873 | LIST_HEAD(dispose); |
| 873 | 874 | ||
| 874 | ctx = locks_get_lock_context(inode); | 875 | ctx = locks_get_lock_context(inode, request->fl_type); |
| 875 | if (!ctx) | 876 | if (!ctx) { |
| 876 | return -ENOMEM; | 877 | if (request->fl_type != F_UNLCK) |
| 878 | return -ENOMEM; | ||
| 879 | return (request->fl_flags & FL_EXISTS) ? -ENOENT : 0; | ||
| 880 | } | ||
| 877 | 881 | ||
| 878 | if (!(request->fl_flags & FL_ACCESS) && (request->fl_type != F_UNLCK)) { | 882 | if (!(request->fl_flags & FL_ACCESS) && (request->fl_type != F_UNLCK)) { |
| 879 | new_fl = locks_alloc_lock(); | 883 | new_fl = locks_alloc_lock(); |
| @@ -939,9 +943,9 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
| 939 | bool added = false; | 943 | bool added = false; |
| 940 | LIST_HEAD(dispose); | 944 | LIST_HEAD(dispose); |
| 941 | 945 | ||
| 942 | ctx = locks_get_lock_context(inode); | 946 | ctx = locks_get_lock_context(inode, request->fl_type); |
| 943 | if (!ctx) | 947 | if (!ctx) |
| 944 | return -ENOMEM; | 948 | return (request->fl_type == F_UNLCK) ? 0 : -ENOMEM; |
| 945 | 949 | ||
| 946 | /* | 950 | /* |
| 947 | * We may need two file_lock structures for this operation, | 951 | * We may need two file_lock structures for this operation, |
| @@ -964,8 +968,6 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
| 964 | */ | 968 | */ |
| 965 | if (request->fl_type != F_UNLCK) { | 969 | if (request->fl_type != F_UNLCK) { |
| 966 | list_for_each_entry(fl, &ctx->flc_posix, fl_list) { | 970 | list_for_each_entry(fl, &ctx->flc_posix, fl_list) { |
| 967 | if (!IS_POSIX(fl)) | ||
| 968 | continue; | ||
| 969 | if (!posix_locks_conflict(request, fl)) | 971 | if (!posix_locks_conflict(request, fl)) |
| 970 | continue; | 972 | continue; |
| 971 | if (conflock) | 973 | if (conflock) |
| @@ -1605,7 +1607,8 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **pr | |||
| 1605 | lease = *flp; | 1607 | lease = *flp; |
| 1606 | trace_generic_add_lease(inode, lease); | 1608 | trace_generic_add_lease(inode, lease); |
| 1607 | 1609 | ||
| 1608 | ctx = locks_get_lock_context(inode); | 1610 | /* Note that arg is never F_UNLCK here */ |
| 1611 | ctx = locks_get_lock_context(inode, arg); | ||
| 1609 | if (!ctx) | 1612 | if (!ctx) |
| 1610 | return -ENOMEM; | 1613 | return -ENOMEM; |
| 1611 | 1614 | ||
| @@ -2555,15 +2558,10 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl, | |||
| 2555 | : (fl->fl_type == F_WRLCK) ? "WRITE" : "READ "); | 2558 | : (fl->fl_type == F_WRLCK) ? "WRITE" : "READ "); |
| 2556 | } | 2559 | } |
| 2557 | if (inode) { | 2560 | if (inode) { |
| 2558 | #ifdef WE_CAN_BREAK_LSLK_NOW | 2561 | /* userspace relies on this representation of dev_t */ |
| 2559 | seq_printf(f, "%d %s:%ld ", fl_pid, | ||
| 2560 | inode->i_sb->s_id, inode->i_ino); | ||
| 2561 | #else | ||
| 2562 | /* userspace relies on this representation of dev_t ;-( */ | ||
| 2563 | seq_printf(f, "%d %02x:%02x:%ld ", fl_pid, | 2562 | seq_printf(f, "%d %02x:%02x:%ld ", fl_pid, |
| 2564 | MAJOR(inode->i_sb->s_dev), | 2563 | MAJOR(inode->i_sb->s_dev), |
| 2565 | MINOR(inode->i_sb->s_dev), inode->i_ino); | 2564 | MINOR(inode->i_sb->s_dev), inode->i_ino); |
| 2566 | #endif | ||
| 2567 | } else { | 2565 | } else { |
| 2568 | seq_printf(f, "%d <none>:0 ", fl_pid); | 2566 | seq_printf(f, "%d <none>:0 ", fl_pid); |
| 2569 | } | 2567 | } |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 8ba1d888f1e6..326a545ea7b2 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
| @@ -4932,20 +4932,22 @@ nfs4_transform_lock_offset(struct file_lock *lock) | |||
| 4932 | lock->fl_end = OFFSET_MAX; | 4932 | lock->fl_end = OFFSET_MAX; |
| 4933 | } | 4933 | } |
| 4934 | 4934 | ||
| 4935 | static void nfsd4_fl_get_owner(struct file_lock *dst, struct file_lock *src) | 4935 | static fl_owner_t |
| 4936 | nfsd4_fl_get_owner(fl_owner_t owner) | ||
| 4936 | { | 4937 | { |
| 4937 | struct nfs4_lockowner *lo = (struct nfs4_lockowner *)src->fl_owner; | 4938 | struct nfs4_lockowner *lo = (struct nfs4_lockowner *)owner; |
| 4938 | dst->fl_owner = (fl_owner_t)lockowner(nfs4_get_stateowner(&lo->lo_owner)); | 4939 | |
| 4940 | nfs4_get_stateowner(&lo->lo_owner); | ||
| 4941 | return owner; | ||
| 4939 | } | 4942 | } |
| 4940 | 4943 | ||
| 4941 | static void nfsd4_fl_put_owner(struct file_lock *fl) | 4944 | static void |
| 4945 | nfsd4_fl_put_owner(fl_owner_t owner) | ||
| 4942 | { | 4946 | { |
| 4943 | struct nfs4_lockowner *lo = (struct nfs4_lockowner *)fl->fl_owner; | 4947 | struct nfs4_lockowner *lo = (struct nfs4_lockowner *)owner; |
| 4944 | 4948 | ||
| 4945 | if (lo) { | 4949 | if (lo) |
| 4946 | nfs4_put_stateowner(&lo->lo_owner); | 4950 | nfs4_put_stateowner(&lo->lo_owner); |
| 4947 | fl->fl_owner = NULL; | ||
| 4948 | } | ||
| 4949 | } | 4951 | } |
| 4950 | 4952 | ||
| 4951 | static const struct lock_manager_operations nfsd_posix_mng_ops = { | 4953 | static const struct lock_manager_operations nfsd_posix_mng_ops = { |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 4d9acc91de12..90a1207231ea 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -915,8 +915,8 @@ struct file_lock_operations { | |||
| 915 | struct lock_manager_operations { | 915 | struct lock_manager_operations { |
| 916 | int (*lm_compare_owner)(struct file_lock *, struct file_lock *); | 916 | int (*lm_compare_owner)(struct file_lock *, struct file_lock *); |
| 917 | unsigned long (*lm_owner_key)(struct file_lock *); | 917 | unsigned long (*lm_owner_key)(struct file_lock *); |
| 918 | void (*lm_get_owner)(struct file_lock *, struct file_lock *); | 918 | fl_owner_t (*lm_get_owner)(fl_owner_t); |
| 919 | void (*lm_put_owner)(struct file_lock *); | 919 | void (*lm_put_owner)(fl_owner_t); |
| 920 | void (*lm_notify)(struct file_lock *); /* unblock callback */ | 920 | void (*lm_notify)(struct file_lock *); /* unblock callback */ |
| 921 | int (*lm_grant)(struct file_lock *, int); | 921 | int (*lm_grant)(struct file_lock *, int); |
| 922 | bool (*lm_break)(struct file_lock *); | 922 | bool (*lm_break)(struct file_lock *); |
