summaryrefslogtreecommitdiffstats
path: root/fs/locks.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2013-06-21 08:58:15 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-06-29 04:57:42 -0400
commit1c8c601a8c0dc59fe64907dcd9d512a3d181ddc7 (patch)
tree1a9c91de460a7c2f9fd6ad77060be484456e49b9 /fs/locks.c
parent889746917193ab3007a779d65231510715b20fb6 (diff)
locks: protect most of the file_lock handling with i_lock
Having a global lock that protects all of this code is a clear scalability problem. Instead of doing that, move most of the code to be protected by the i_lock instead. The exceptions are the global lists that the ->fl_link sits on, and the ->fl_block list. ->fl_link is what connects these structures to the global lists, so we must ensure that we hold those locks when iterating over or updating these lists. Furthermore, sound deadlock detection requires that we hold the blocked_list state steady while checking for loops. We also must ensure that the search and update to the list are atomic. For the checking and insertion side of the blocked_list, push the acquisition of the global lock into __posix_lock_file and ensure that checking and update of the blocked_list is done without dropping the lock in between. On the removal side, when waking up blocked lock waiters, take the global lock before walking the blocked list and dequeue the waiters from the global list prior to removal from the fl_block list. With this, deadlock detection should be race free while we minimize excessive file_lock_lock thrashing. Finally, in order to avoid a lock inversion problem when handling /proc/locks output we must ensure that manipulations of the fl_block list are also protected by the file_lock_lock. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/locks.c')
-rw-r--r--fs/locks.c164
1 files changed, 104 insertions, 60 deletions
diff --git a/fs/locks.c b/fs/locks.c
index 89d898bce166..ce302d43822b 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -153,27 +153,37 @@ int lease_break_time = 45;
153#define for_each_lock(inode, lockp) \ 153#define for_each_lock(inode, lockp) \
154 for (lockp = &inode->i_flock; *lockp != NULL; lockp = &(*lockp)->fl_next) 154 for (lockp = &inode->i_flock; *lockp != NULL; lockp = &(*lockp)->fl_next)
155 155
156/* The global file_lock_list is only used for displaying /proc/locks. */ 156/*
157 * The global file_lock_list is only used for displaying /proc/locks. Protected
158 * by the file_lock_lock.
159 */
157static LIST_HEAD(file_lock_list); 160static LIST_HEAD(file_lock_list);
158 161
159/* The blocked_list is used to find POSIX lock loops for deadlock detection. */ 162/*
163 * The blocked_list is used to find POSIX lock loops for deadlock detection.
164 * Protected by file_lock_lock.
165 */
160static LIST_HEAD(blocked_list); 166static LIST_HEAD(blocked_list);
161 167
162/* Protects the two list heads above, plus the inode->i_flock list */ 168/*
169 * This lock protects the blocked_list, and the file_lock_list. Generally, if
170 * you're accessing one of those lists, you want to be holding this lock.
171 *
172 * In addition, it also protects the fl->fl_block list, and the fl->fl_next
173 * pointer for file_lock structures that are acting as lock requests (in
174 * contrast to those that are acting as records of acquired locks).
175 *
176 * Note that when we acquire this lock in order to change the above fields,
177 * we often hold the i_lock as well. In certain cases, when reading the fields
178 * protected by this lock, we can skip acquiring it iff we already hold the
179 * i_lock.
180 *
181 * In particular, adding an entry to the fl_block list requires that you hold
182 * both the i_lock and the blocked_lock_lock (acquired in that order). Deleting
183 * an entry from the list however only requires the file_lock_lock.
184 */
163static DEFINE_SPINLOCK(file_lock_lock); 185static DEFINE_SPINLOCK(file_lock_lock);
164 186
165void lock_flocks(void)
166{
167 spin_lock(&file_lock_lock);
168}
169EXPORT_SYMBOL_GPL(lock_flocks);
170
171void unlock_flocks(void)
172{
173 spin_unlock(&file_lock_lock);
174}
175EXPORT_SYMBOL_GPL(unlock_flocks);
176
177static struct kmem_cache *filelock_cache __read_mostly; 187static struct kmem_cache *filelock_cache __read_mostly;
178 188
179static void locks_init_lock_heads(struct file_lock *fl) 189static void locks_init_lock_heads(struct file_lock *fl)
@@ -489,13 +499,17 @@ static int posix_same_owner(struct file_lock *fl1, struct file_lock *fl2)
489static inline void 499static inline void
490locks_insert_global_locks(struct file_lock *fl) 500locks_insert_global_locks(struct file_lock *fl)
491{ 501{
502 spin_lock(&file_lock_lock);
492 list_add_tail(&fl->fl_link, &file_lock_list); 503 list_add_tail(&fl->fl_link, &file_lock_list);
504 spin_unlock(&file_lock_lock);
493} 505}
494 506
495static inline void 507static inline void
496locks_delete_global_locks(struct file_lock *fl) 508locks_delete_global_locks(struct file_lock *fl)
497{ 509{
510 spin_lock(&file_lock_lock);
498 list_del_init(&fl->fl_link); 511 list_del_init(&fl->fl_link);
512 spin_unlock(&file_lock_lock);
499} 513}
500 514
501static inline void 515static inline void
@@ -512,6 +526,8 @@ locks_delete_global_blocked(struct file_lock *waiter)
512 526
513/* Remove waiter from blocker's block list. 527/* Remove waiter from blocker's block list.
514 * When blocker ends up pointing to itself then the list is empty. 528 * When blocker ends up pointing to itself then the list is empty.
529 *
530 * Must be called with file_lock_lock held.
515 */ 531 */
516static void __locks_delete_block(struct file_lock *waiter) 532static void __locks_delete_block(struct file_lock *waiter)
517{ 533{
@@ -520,37 +536,47 @@ static void __locks_delete_block(struct file_lock *waiter)
520 waiter->fl_next = NULL; 536 waiter->fl_next = NULL;
521} 537}
522 538
523/*
524 */
525static void locks_delete_block(struct file_lock *waiter) 539static void locks_delete_block(struct file_lock *waiter)
526{ 540{
527 lock_flocks(); 541 spin_lock(&file_lock_lock);
528 __locks_delete_block(waiter); 542 __locks_delete_block(waiter);
529 unlock_flocks(); 543 spin_unlock(&file_lock_lock);
530} 544}
531 545
532/* Insert waiter into blocker's block list. 546/* Insert waiter into blocker's block list.
533 * We use a circular list so that processes can be easily woken up in 547 * We use a circular list so that processes can be easily woken up in
534 * the order they blocked. The documentation doesn't require this but 548 * the order they blocked. The documentation doesn't require this but
535 * it seems like the reasonable thing to do. 549 * it seems like the reasonable thing to do.
550 *
551 * Must be called with file_lock_lock held!
536 */ 552 */
537static void locks_insert_block(struct file_lock *blocker, 553static void __locks_insert_block(struct file_lock *blocker,
538 struct file_lock *waiter) 554 struct file_lock *waiter)
539{ 555{
540 BUG_ON(!list_empty(&waiter->fl_block)); 556 BUG_ON(!list_empty(&waiter->fl_block));
541 waiter->fl_next = blocker; 557 waiter->fl_next = blocker;
542 list_add_tail(&waiter->fl_block, &blocker->fl_block); 558 list_add_tail(&waiter->fl_block, &blocker->fl_block);
543 if (IS_POSIX(blocker)) 559 if (IS_POSIX(blocker))
544 locks_insert_global_blocked(request); 560 locks_insert_global_blocked(waiter);
561}
562
563/* Must be called with i_lock held. */
564static void locks_insert_block(struct file_lock *blocker,
565 struct file_lock *waiter)
566{
567 spin_lock(&file_lock_lock);
568 __locks_insert_block(blocker, waiter);
569 spin_unlock(&file_lock_lock);
545} 570}
546 571
547/* 572/*
548 * Wake up processes blocked waiting for blocker. 573 * Wake up processes blocked waiting for blocker.
549 * 574 *
550 * Must be called with the file_lock_lock held! 575 * Must be called with the inode->i_lock held!
551 */ 576 */
552static void locks_wake_up_blocks(struct file_lock *blocker) 577static void locks_wake_up_blocks(struct file_lock *blocker)
553{ 578{
579 spin_lock(&file_lock_lock);
554 while (!list_empty(&blocker->fl_block)) { 580 while (!list_empty(&blocker->fl_block)) {
555 struct file_lock *waiter; 581 struct file_lock *waiter;
556 582
@@ -562,10 +588,13 @@ static void locks_wake_up_blocks(struct file_lock *blocker)
562 else 588 else
563 wake_up(&waiter->fl_wait); 589 wake_up(&waiter->fl_wait);
564 } 590 }
591 spin_unlock(&file_lock_lock);
565} 592}
566 593
567/* Insert file lock fl into an inode's lock list at the position indicated 594/* Insert file lock fl into an inode's lock list at the position indicated
568 * by pos. At the same time add the lock to the global file lock list. 595 * by pos. At the same time add the lock to the global file lock list.
596 *
597 * Must be called with the i_lock held!
569 */ 598 */
570static void locks_insert_lock(struct file_lock **pos, struct file_lock *fl) 599static void locks_insert_lock(struct file_lock **pos, struct file_lock *fl)
571{ 600{
@@ -583,6 +612,8 @@ static void locks_insert_lock(struct file_lock **pos, struct file_lock *fl)
583 * Wake up processes that are blocked waiting for this lock, 612 * Wake up processes that are blocked waiting for this lock,
584 * notify the FS that the lock has been cleared and 613 * notify the FS that the lock has been cleared and
585 * finally free the lock. 614 * finally free the lock.
615 *
616 * Must be called with the i_lock held!
586 */ 617 */
587static void locks_delete_lock(struct file_lock **thisfl_p) 618static void locks_delete_lock(struct file_lock **thisfl_p)
588{ 619{
@@ -652,8 +683,9 @@ void
652posix_test_lock(struct file *filp, struct file_lock *fl) 683posix_test_lock(struct file *filp, struct file_lock *fl)
653{ 684{
654 struct file_lock *cfl; 685 struct file_lock *cfl;
686 struct inode *inode = file_inode(filp);
655 687
656 lock_flocks(); 688 spin_lock(&inode->i_lock);
657 for (cfl = file_inode(filp)->i_flock; cfl; cfl = cfl->fl_next) { 689 for (cfl = file_inode(filp)->i_flock; cfl; cfl = cfl->fl_next) {
658 if (!IS_POSIX(cfl)) 690 if (!IS_POSIX(cfl))
659 continue; 691 continue;
@@ -666,7 +698,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
666 fl->fl_pid = pid_vnr(cfl->fl_nspid); 698 fl->fl_pid = pid_vnr(cfl->fl_nspid);
667 } else 699 } else
668 fl->fl_type = F_UNLCK; 700 fl->fl_type = F_UNLCK;
669 unlock_flocks(); 701 spin_unlock(&inode->i_lock);
670 return; 702 return;
671} 703}
672EXPORT_SYMBOL(posix_test_lock); 704EXPORT_SYMBOL(posix_test_lock);
@@ -710,6 +742,7 @@ static struct file_lock *what_owner_is_waiting_for(struct file_lock *block_fl)
710 return NULL; 742 return NULL;
711} 743}
712 744
745/* Must be called with the file_lock_lock held! */
713static int posix_locks_deadlock(struct file_lock *caller_fl, 746static int posix_locks_deadlock(struct file_lock *caller_fl,
714 struct file_lock *block_fl) 747 struct file_lock *block_fl)
715{ 748{
@@ -745,7 +778,7 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
745 return -ENOMEM; 778 return -ENOMEM;
746 } 779 }
747 780
748 lock_flocks(); 781 spin_lock(&inode->i_lock);
749 if (request->fl_flags & FL_ACCESS) 782 if (request->fl_flags & FL_ACCESS)
750 goto find_conflict; 783 goto find_conflict;
751 784
@@ -775,9 +808,9 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
775 * give it the opportunity to lock the file. 808 * give it the opportunity to lock the file.
776 */ 809 */
777 if (found) { 810 if (found) {
778 unlock_flocks(); 811 spin_unlock(&inode->i_lock);
779 cond_resched(); 812 cond_resched();
780 lock_flocks(); 813 spin_lock(&inode->i_lock);
781 } 814 }
782 815
783find_conflict: 816find_conflict:
@@ -804,7 +837,7 @@ find_conflict:
804 error = 0; 837 error = 0;
805 838
806out: 839out:
807 unlock_flocks(); 840 spin_unlock(&inode->i_lock);
808 if (new_fl) 841 if (new_fl)
809 locks_free_lock(new_fl); 842 locks_free_lock(new_fl);
810 return error; 843 return error;
@@ -834,7 +867,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str
834 new_fl2 = locks_alloc_lock(); 867 new_fl2 = locks_alloc_lock();
835 } 868 }
836 869
837 lock_flocks(); 870 spin_lock(&inode->i_lock);
838 /* 871 /*
839 * New lock request. Walk all POSIX locks and look for conflicts. If 872 * New lock request. Walk all POSIX locks and look for conflicts. If
840 * there are any, either return error or put the request on the 873 * there are any, either return error or put the request on the
@@ -852,11 +885,17 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str
852 error = -EAGAIN; 885 error = -EAGAIN;
853 if (!(request->fl_flags & FL_SLEEP)) 886 if (!(request->fl_flags & FL_SLEEP))
854 goto out; 887 goto out;
888 /*
889 * Deadlock detection and insertion into the blocked
890 * locks list must be done while holding the same lock!
891 */
855 error = -EDEADLK; 892 error = -EDEADLK;
856 if (posix_locks_deadlock(request, fl)) 893 spin_lock(&file_lock_lock);
857 goto out; 894 if (likely(!posix_locks_deadlock(request, fl))) {
858 error = FILE_LOCK_DEFERRED; 895 error = FILE_LOCK_DEFERRED;
859 locks_insert_block(fl, request); 896 __locks_insert_block(fl, request);
897 }
898 spin_unlock(&file_lock_lock);
860 goto out; 899 goto out;
861 } 900 }
862 } 901 }
@@ -1006,7 +1045,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str
1006 locks_wake_up_blocks(left); 1045 locks_wake_up_blocks(left);
1007 } 1046 }
1008 out: 1047 out:
1009 unlock_flocks(); 1048 spin_unlock(&inode->i_lock);
1010 /* 1049 /*
1011 * Free any unused locks. 1050 * Free any unused locks.
1012 */ 1051 */
@@ -1081,14 +1120,14 @@ int locks_mandatory_locked(struct inode *inode)
1081 /* 1120 /*
1082 * Search the lock list for this inode for any POSIX locks. 1121 * Search the lock list for this inode for any POSIX locks.
1083 */ 1122 */
1084 lock_flocks(); 1123 spin_lock(&inode->i_lock);
1085 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { 1124 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
1086 if (!IS_POSIX(fl)) 1125 if (!IS_POSIX(fl))
1087 continue; 1126 continue;
1088 if (fl->fl_owner != owner) 1127 if (fl->fl_owner != owner)
1089 break; 1128 break;
1090 } 1129 }
1091 unlock_flocks(); 1130 spin_unlock(&inode->i_lock);
1092 return fl ? -EAGAIN : 0; 1131 return fl ? -EAGAIN : 0;
1093} 1132}
1094 1133
@@ -1231,7 +1270,7 @@ int __break_lease(struct inode *inode, unsigned int mode)
1231 if (IS_ERR(new_fl)) 1270 if (IS_ERR(new_fl))
1232 return PTR_ERR(new_fl); 1271 return PTR_ERR(new_fl);
1233 1272
1234 lock_flocks(); 1273 spin_lock(&inode->i_lock);
1235 1274
1236 time_out_leases(inode); 1275 time_out_leases(inode);
1237 1276
@@ -1281,11 +1320,11 @@ restart:
1281 break_time++; 1320 break_time++;
1282 } 1321 }
1283 locks_insert_block(flock, new_fl); 1322 locks_insert_block(flock, new_fl);
1284 unlock_flocks(); 1323 spin_unlock(&inode->i_lock);
1285 error = wait_event_interruptible_timeout(new_fl->fl_wait, 1324 error = wait_event_interruptible_timeout(new_fl->fl_wait,
1286 !new_fl->fl_next, break_time); 1325 !new_fl->fl_next, break_time);
1287 lock_flocks(); 1326 spin_lock(&inode->i_lock);
1288 __locks_delete_block(new_fl); 1327 locks_delete_block(new_fl);
1289 if (error >= 0) { 1328 if (error >= 0) {
1290 if (error == 0) 1329 if (error == 0)
1291 time_out_leases(inode); 1330 time_out_leases(inode);
@@ -1302,7 +1341,7 @@ restart:
1302 } 1341 }
1303 1342
1304out: 1343out:
1305 unlock_flocks(); 1344 spin_unlock(&inode->i_lock);
1306 locks_free_lock(new_fl); 1345 locks_free_lock(new_fl);
1307 return error; 1346 return error;
1308} 1347}
@@ -1355,9 +1394,10 @@ EXPORT_SYMBOL(lease_get_mtime);
1355int fcntl_getlease(struct file *filp) 1394int fcntl_getlease(struct file *filp)
1356{ 1395{
1357 struct file_lock *fl; 1396 struct file_lock *fl;
1397 struct inode *inode = file_inode(filp);
1358 int type = F_UNLCK; 1398 int type = F_UNLCK;
1359 1399
1360 lock_flocks(); 1400 spin_lock(&inode->i_lock);
1361 time_out_leases(file_inode(filp)); 1401 time_out_leases(file_inode(filp));
1362 for (fl = file_inode(filp)->i_flock; fl && IS_LEASE(fl); 1402 for (fl = file_inode(filp)->i_flock; fl && IS_LEASE(fl);
1363 fl = fl->fl_next) { 1403 fl = fl->fl_next) {
@@ -1366,7 +1406,7 @@ int fcntl_getlease(struct file *filp)
1366 break; 1406 break;
1367 } 1407 }
1368 } 1408 }
1369 unlock_flocks(); 1409 spin_unlock(&inode->i_lock);
1370 return type; 1410 return type;
1371} 1411}
1372 1412
@@ -1460,7 +1500,7 @@ static int generic_delete_lease(struct file *filp, struct file_lock **flp)
1460 * The (input) flp->fl_lmops->lm_break function is required 1500 * The (input) flp->fl_lmops->lm_break function is required
1461 * by break_lease(). 1501 * by break_lease().
1462 * 1502 *
1463 * Called with file_lock_lock held. 1503 * Called with inode->i_lock held.
1464 */ 1504 */
1465int generic_setlease(struct file *filp, long arg, struct file_lock **flp) 1505int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
1466{ 1506{
@@ -1529,11 +1569,12 @@ static int __vfs_setlease(struct file *filp, long arg, struct file_lock **lease)
1529 1569
1530int vfs_setlease(struct file *filp, long arg, struct file_lock **lease) 1570int vfs_setlease(struct file *filp, long arg, struct file_lock **lease)
1531{ 1571{
1572 struct inode *inode = file_inode(filp);
1532 int error; 1573 int error;
1533 1574
1534 lock_flocks(); 1575 spin_lock(&inode->i_lock);
1535 error = __vfs_setlease(filp, arg, lease); 1576 error = __vfs_setlease(filp, arg, lease);
1536 unlock_flocks(); 1577 spin_unlock(&inode->i_lock);
1537 1578
1538 return error; 1579 return error;
1539} 1580}
@@ -1551,6 +1592,7 @@ static int do_fcntl_delete_lease(struct file *filp)
1551static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) 1592static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg)
1552{ 1593{
1553 struct file_lock *fl, *ret; 1594 struct file_lock *fl, *ret;
1595 struct inode *inode = file_inode(filp);
1554 struct fasync_struct *new; 1596 struct fasync_struct *new;
1555 int error; 1597 int error;
1556 1598
@@ -1564,10 +1606,10 @@ static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg)
1564 return -ENOMEM; 1606 return -ENOMEM;
1565 } 1607 }
1566 ret = fl; 1608 ret = fl;
1567 lock_flocks(); 1609 spin_lock(&inode->i_lock);
1568 error = __vfs_setlease(filp, arg, &ret); 1610 error = __vfs_setlease(filp, arg, &ret);
1569 if (error) { 1611 if (error) {
1570 unlock_flocks(); 1612 spin_unlock(&inode->i_lock);
1571 locks_free_lock(fl); 1613 locks_free_lock(fl);
1572 goto out_free_fasync; 1614 goto out_free_fasync;
1573 } 1615 }
@@ -1584,7 +1626,7 @@ static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg)
1584 new = NULL; 1626 new = NULL;
1585 1627
1586 error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); 1628 error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0);
1587 unlock_flocks(); 1629 spin_unlock(&inode->i_lock);
1588 1630
1589out_free_fasync: 1631out_free_fasync:
1590 if (new) 1632 if (new)
@@ -2108,7 +2150,7 @@ void locks_remove_flock(struct file *filp)
2108 fl.fl_ops->fl_release_private(&fl); 2150 fl.fl_ops->fl_release_private(&fl);
2109 } 2151 }
2110 2152
2111 lock_flocks(); 2153 spin_lock(&inode->i_lock);
2112 before = &inode->i_flock; 2154 before = &inode->i_flock;
2113 2155
2114 while ((fl = *before) != NULL) { 2156 while ((fl = *before) != NULL) {
@@ -2126,7 +2168,7 @@ void locks_remove_flock(struct file *filp)
2126 } 2168 }
2127 before = &fl->fl_next; 2169 before = &fl->fl_next;
2128 } 2170 }
2129 unlock_flocks(); 2171 spin_unlock(&inode->i_lock);
2130} 2172}
2131 2173
2132/** 2174/**
@@ -2140,12 +2182,12 @@ posix_unblock_lock(struct file_lock *waiter)
2140{ 2182{
2141 int status = 0; 2183 int status = 0;
2142 2184
2143 lock_flocks(); 2185 spin_lock(&file_lock_lock);
2144 if (waiter->fl_next) 2186 if (waiter->fl_next)
2145 __locks_delete_block(waiter); 2187 __locks_delete_block(waiter);
2146 else 2188 else
2147 status = -ENOENT; 2189 status = -ENOENT;
2148 unlock_flocks(); 2190 spin_unlock(&file_lock_lock);
2149 return status; 2191 return status;
2150} 2192}
2151EXPORT_SYMBOL(posix_unblock_lock); 2193EXPORT_SYMBOL(posix_unblock_lock);
@@ -2259,7 +2301,7 @@ static void *locks_start(struct seq_file *f, loff_t *pos)
2259{ 2301{
2260 loff_t *p = f->private; 2302 loff_t *p = f->private;
2261 2303
2262 lock_flocks(); 2304 spin_lock(&file_lock_lock);
2263 *p = (*pos + 1); 2305 *p = (*pos + 1);
2264 return seq_list_start(&file_lock_list, *pos); 2306 return seq_list_start(&file_lock_list, *pos);
2265} 2307}
@@ -2273,7 +2315,7 @@ static void *locks_next(struct seq_file *f, void *v, loff_t *pos)
2273 2315
2274static void locks_stop(struct seq_file *f, void *v) 2316static void locks_stop(struct seq_file *f, void *v)
2275{ 2317{
2276 unlock_flocks(); 2318 spin_unlock(&file_lock_lock);
2277} 2319}
2278 2320
2279static const struct seq_operations locks_seq_operations = { 2321static const struct seq_operations locks_seq_operations = {
@@ -2320,7 +2362,8 @@ int lock_may_read(struct inode *inode, loff_t start, unsigned long len)
2320{ 2362{
2321 struct file_lock *fl; 2363 struct file_lock *fl;
2322 int result = 1; 2364 int result = 1;
2323 lock_flocks(); 2365
2366 spin_lock(&inode->i_lock);
2324 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { 2367 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
2325 if (IS_POSIX(fl)) { 2368 if (IS_POSIX(fl)) {
2326 if (fl->fl_type == F_RDLCK) 2369 if (fl->fl_type == F_RDLCK)
@@ -2337,7 +2380,7 @@ int lock_may_read(struct inode *inode, loff_t start, unsigned long len)
2337 result = 0; 2380 result = 0;
2338 break; 2381 break;
2339 } 2382 }
2340 unlock_flocks(); 2383 spin_unlock(&inode->i_lock);
2341 return result; 2384 return result;
2342} 2385}
2343 2386
@@ -2360,7 +2403,8 @@ int lock_may_write(struct inode *inode, loff_t start, unsigned long len)
2360{ 2403{
2361 struct file_lock *fl; 2404 struct file_lock *fl;
2362 int result = 1; 2405 int result = 1;
2363 lock_flocks(); 2406
2407 spin_lock(&inode->i_lock);
2364 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { 2408 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
2365 if (IS_POSIX(fl)) { 2409 if (IS_POSIX(fl)) {
2366 if ((fl->fl_end < start) || (fl->fl_start > (start + len))) 2410 if ((fl->fl_end < start) || (fl->fl_start > (start + len)))
@@ -2375,7 +2419,7 @@ int lock_may_write(struct inode *inode, loff_t start, unsigned long len)
2375 result = 0; 2419 result = 0;
2376 break; 2420 break;
2377 } 2421 }
2378 unlock_flocks(); 2422 spin_unlock(&inode->i_lock);
2379 return result; 2423 return result;
2380} 2424}
2381 2425