diff options
Diffstat (limited to 'fs/locks.c')
| -rw-r--r-- | fs/locks.c | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/fs/locks.c b/fs/locks.c index 56f996e98bbc..4d9e71d43e7e 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
| @@ -142,7 +142,7 @@ int lease_break_time = 45; | |||
| 142 | static LIST_HEAD(file_lock_list); | 142 | static LIST_HEAD(file_lock_list); |
| 143 | static LIST_HEAD(blocked_list); | 143 | static LIST_HEAD(blocked_list); |
| 144 | 144 | ||
| 145 | static kmem_cache_t *filelock_cache; | 145 | static kmem_cache_t *filelock_cache __read_mostly; |
| 146 | 146 | ||
| 147 | /* Allocate an empty lock structure. */ | 147 | /* Allocate an empty lock structure. */ |
| 148 | static struct file_lock *locks_alloc_lock(void) | 148 | static struct file_lock *locks_alloc_lock(void) |
| @@ -533,12 +533,7 @@ static void locks_delete_block(struct file_lock *waiter) | |||
| 533 | static void locks_insert_block(struct file_lock *blocker, | 533 | static void locks_insert_block(struct file_lock *blocker, |
| 534 | struct file_lock *waiter) | 534 | struct file_lock *waiter) |
| 535 | { | 535 | { |
| 536 | if (!list_empty(&waiter->fl_block)) { | 536 | BUG_ON(!list_empty(&waiter->fl_block)); |
| 537 | printk(KERN_ERR "locks_insert_block: removing duplicated lock " | ||
| 538 | "(pid=%d %Ld-%Ld type=%d)\n", waiter->fl_pid, | ||
| 539 | waiter->fl_start, waiter->fl_end, waiter->fl_type); | ||
| 540 | __locks_delete_block(waiter); | ||
| 541 | } | ||
| 542 | list_add_tail(&waiter->fl_block, &blocker->fl_block); | 537 | list_add_tail(&waiter->fl_block, &blocker->fl_block); |
| 543 | waiter->fl_next = blocker; | 538 | waiter->fl_next = blocker; |
| 544 | if (IS_POSIX(blocker)) | 539 | if (IS_POSIX(blocker)) |
| @@ -797,9 +792,7 @@ out: | |||
| 797 | return error; | 792 | return error; |
| 798 | } | 793 | } |
| 799 | 794 | ||
| 800 | EXPORT_SYMBOL(posix_lock_file); | 795 | static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request, struct file_lock *conflock) |
| 801 | |||
| 802 | static int __posix_lock_file(struct inode *inode, struct file_lock *request) | ||
| 803 | { | 796 | { |
| 804 | struct file_lock *fl; | 797 | struct file_lock *fl; |
| 805 | struct file_lock *new_fl, *new_fl2; | 798 | struct file_lock *new_fl, *new_fl2; |
| @@ -823,6 +816,8 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request) | |||
| 823 | continue; | 816 | continue; |
| 824 | if (!posix_locks_conflict(request, fl)) | 817 | if (!posix_locks_conflict(request, fl)) |
| 825 | continue; | 818 | continue; |
| 819 | if (conflock) | ||
| 820 | locks_copy_lock(conflock, fl); | ||
| 826 | error = -EAGAIN; | 821 | error = -EAGAIN; |
| 827 | if (!(request->fl_flags & FL_SLEEP)) | 822 | if (!(request->fl_flags & FL_SLEEP)) |
| 828 | goto out; | 823 | goto out; |
| @@ -992,8 +987,24 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request) | |||
| 992 | */ | 987 | */ |
| 993 | int posix_lock_file(struct file *filp, struct file_lock *fl) | 988 | int posix_lock_file(struct file *filp, struct file_lock *fl) |
| 994 | { | 989 | { |
| 995 | return __posix_lock_file(filp->f_dentry->d_inode, fl); | 990 | return __posix_lock_file_conf(filp->f_dentry->d_inode, fl, NULL); |
| 991 | } | ||
| 992 | EXPORT_SYMBOL(posix_lock_file); | ||
| 993 | |||
| 994 | /** | ||
| 995 | * posix_lock_file_conf - Apply a POSIX-style lock to a file | ||
| 996 | * @filp: The file to apply the lock to | ||
| 997 | * @fl: The lock to be applied | ||
| 998 | * @conflock: Place to return a copy of the conflicting lock, if found. | ||
| 999 | * | ||
| 1000 | * Except for the conflock parameter, acts just like posix_lock_file. | ||
| 1001 | */ | ||
| 1002 | int posix_lock_file_conf(struct file *filp, struct file_lock *fl, | ||
| 1003 | struct file_lock *conflock) | ||
| 1004 | { | ||
| 1005 | return __posix_lock_file_conf(filp->f_dentry->d_inode, fl, conflock); | ||
| 996 | } | 1006 | } |
| 1007 | EXPORT_SYMBOL(posix_lock_file_conf); | ||
| 997 | 1008 | ||
| 998 | /** | 1009 | /** |
| 999 | * posix_lock_file_wait - Apply a POSIX-style lock to a file | 1010 | * posix_lock_file_wait - Apply a POSIX-style lock to a file |
| @@ -1009,7 +1020,7 @@ int posix_lock_file_wait(struct file *filp, struct file_lock *fl) | |||
| 1009 | int error; | 1020 | int error; |
| 1010 | might_sleep (); | 1021 | might_sleep (); |
| 1011 | for (;;) { | 1022 | for (;;) { |
| 1012 | error = __posix_lock_file(filp->f_dentry->d_inode, fl); | 1023 | error = posix_lock_file(filp, fl); |
| 1013 | if ((error != -EAGAIN) || !(fl->fl_flags & FL_SLEEP)) | 1024 | if ((error != -EAGAIN) || !(fl->fl_flags & FL_SLEEP)) |
| 1014 | break; | 1025 | break; |
| 1015 | error = wait_event_interruptible(fl->fl_wait, !fl->fl_next); | 1026 | error = wait_event_interruptible(fl->fl_wait, !fl->fl_next); |
| @@ -1081,7 +1092,7 @@ int locks_mandatory_area(int read_write, struct inode *inode, | |||
| 1081 | fl.fl_end = offset + count - 1; | 1092 | fl.fl_end = offset + count - 1; |
| 1082 | 1093 | ||
| 1083 | for (;;) { | 1094 | for (;;) { |
| 1084 | error = __posix_lock_file(inode, &fl); | 1095 | error = __posix_lock_file_conf(inode, &fl, NULL); |
| 1085 | if (error != -EAGAIN) | 1096 | if (error != -EAGAIN) |
| 1086 | break; | 1097 | break; |
| 1087 | if (!(fl.fl_flags & FL_SLEEP)) | 1098 | if (!(fl.fl_flags & FL_SLEEP)) |
| @@ -1694,7 +1705,7 @@ again: | |||
| 1694 | error = filp->f_op->lock(filp, cmd, file_lock); | 1705 | error = filp->f_op->lock(filp, cmd, file_lock); |
| 1695 | else { | 1706 | else { |
| 1696 | for (;;) { | 1707 | for (;;) { |
| 1697 | error = __posix_lock_file(inode, file_lock); | 1708 | error = posix_lock_file(filp, file_lock); |
| 1698 | if ((error != -EAGAIN) || (cmd == F_SETLK)) | 1709 | if ((error != -EAGAIN) || (cmd == F_SETLK)) |
| 1699 | break; | 1710 | break; |
| 1700 | error = wait_event_interruptible(file_lock->fl_wait, | 1711 | error = wait_event_interruptible(file_lock->fl_wait, |
| @@ -1837,7 +1848,7 @@ again: | |||
| 1837 | error = filp->f_op->lock(filp, cmd, file_lock); | 1848 | error = filp->f_op->lock(filp, cmd, file_lock); |
| 1838 | else { | 1849 | else { |
| 1839 | for (;;) { | 1850 | for (;;) { |
| 1840 | error = __posix_lock_file(inode, file_lock); | 1851 | error = posix_lock_file(filp, file_lock); |
| 1841 | if ((error != -EAGAIN) || (cmd == F_SETLK64)) | 1852 | if ((error != -EAGAIN) || (cmd == F_SETLK64)) |
| 1842 | break; | 1853 | break; |
| 1843 | error = wait_event_interruptible(file_lock->fl_wait, | 1854 | error = wait_event_interruptible(file_lock->fl_wait, |
