diff options
-rw-r--r-- | Documentation/filesystems/Locking | 21 | ||||
-rw-r--r-- | fs/afs/flock.c | 7 | ||||
-rw-r--r-- | fs/ceph/locks.c | 2 | ||||
-rw-r--r-- | fs/ceph/mds_client.c | 8 | ||||
-rw-r--r-- | fs/cifs/cifsfs.c | 2 | ||||
-rw-r--r-- | fs/cifs/file.c | 13 | ||||
-rw-r--r-- | fs/gfs2/file.c | 2 | ||||
-rw-r--r-- | fs/lockd/svcsubs.c | 12 | ||||
-rw-r--r-- | fs/locks.c | 164 | ||||
-rw-r--r-- | fs/nfs/delegation.c | 10 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 8 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 8 | ||||
-rw-r--r-- | include/linux/fs.h | 11 |
13 files changed, 155 insertions, 113 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index f94a362f408e..c2963a74fbc3 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking | |||
@@ -342,7 +342,7 @@ prototypes: | |||
342 | 342 | ||
343 | 343 | ||
344 | locking rules: | 344 | locking rules: |
345 | file_lock_lock may block | 345 | inode->i_lock may block |
346 | fl_copy_lock: yes no | 346 | fl_copy_lock: yes no |
347 | fl_release_private: maybe no | 347 | fl_release_private: maybe no |
348 | 348 | ||
@@ -355,12 +355,19 @@ prototypes: | |||
355 | int (*lm_change)(struct file_lock **, int); | 355 | int (*lm_change)(struct file_lock **, int); |
356 | 356 | ||
357 | locking rules: | 357 | locking rules: |
358 | file_lock_lock may block | 358 | |
359 | lm_compare_owner: yes no | 359 | inode->i_lock file_lock_lock may block |
360 | lm_notify: yes no | 360 | lm_compare_owner: yes[1] maybe no |
361 | lm_grant: no no | 361 | lm_notify: yes yes no |
362 | lm_break: yes no | 362 | lm_grant: no no no |
363 | lm_change yes no | 363 | lm_break: yes no no |
364 | lm_change yes no no | ||
365 | |||
366 | [1]: ->lm_compare_owner is generally called with *an* inode->i_lock held. It | ||
367 | may not be the i_lock of the inode for either file_lock being compared! This is | ||
368 | the case with deadlock detection, since the code has to chase down the owners | ||
369 | of locks that may be entirely unrelated to the one on which the lock is being | ||
370 | acquired. When doing a search for deadlocks, the file_lock_lock is also held. | ||
364 | 371 | ||
365 | --------------------------- buffer_head ----------------------------------- | 372 | --------------------------- buffer_head ----------------------------------- |
366 | prototypes: | 373 | prototypes: |
diff --git a/fs/afs/flock.c b/fs/afs/flock.c index 2497bf306c70..a8cf2cff836c 100644 --- a/fs/afs/flock.c +++ b/fs/afs/flock.c | |||
@@ -252,7 +252,8 @@ static void afs_defer_unlock(struct afs_vnode *vnode, struct key *key) | |||
252 | */ | 252 | */ |
253 | static int afs_do_setlk(struct file *file, struct file_lock *fl) | 253 | static int afs_do_setlk(struct file *file, struct file_lock *fl) |
254 | { | 254 | { |
255 | struct afs_vnode *vnode = AFS_FS_I(file->f_mapping->host); | 255 | struct inode *inode = file_inode(file); |
256 | struct afs_vnode *vnode = AFS_FS_I(inode); | ||
256 | afs_lock_type_t type; | 257 | afs_lock_type_t type; |
257 | struct key *key = file->private_data; | 258 | struct key *key = file->private_data; |
258 | int ret; | 259 | int ret; |
@@ -273,7 +274,7 @@ static int afs_do_setlk(struct file *file, struct file_lock *fl) | |||
273 | 274 | ||
274 | type = (fl->fl_type == F_RDLCK) ? AFS_LOCK_READ : AFS_LOCK_WRITE; | 275 | type = (fl->fl_type == F_RDLCK) ? AFS_LOCK_READ : AFS_LOCK_WRITE; |
275 | 276 | ||
276 | lock_flocks(); | 277 | spin_lock(&inode->i_lock); |
277 | 278 | ||
278 | /* make sure we've got a callback on this file and that our view of the | 279 | /* make sure we've got a callback on this file and that our view of the |
279 | * data version is up to date */ | 280 | * data version is up to date */ |
@@ -420,7 +421,7 @@ given_lock: | |||
420 | afs_vnode_fetch_status(vnode, NULL, key); | 421 | afs_vnode_fetch_status(vnode, NULL, key); |
421 | 422 | ||
422 | error: | 423 | error: |
423 | unlock_flocks(); | 424 | spin_unlock(&inode->i_lock); |
424 | _leave(" = %d", ret); | 425 | _leave(" = %d", ret); |
425 | return ret; | 426 | return ret; |
426 | 427 | ||
diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c index ebbf680378e2..690f73f42425 100644 --- a/fs/ceph/locks.c +++ b/fs/ceph/locks.c | |||
@@ -192,7 +192,7 @@ void ceph_count_locks(struct inode *inode, int *fcntl_count, int *flock_count) | |||
192 | 192 | ||
193 | /** | 193 | /** |
194 | * Encode the flock and fcntl locks for the given inode into the ceph_filelock | 194 | * Encode the flock and fcntl locks for the given inode into the ceph_filelock |
195 | * array. Must be called with lock_flocks() already held. | 195 | * array. Must be called with inode->i_lock already held. |
196 | * If we encounter more of a specific lock type than expected, return -ENOSPC. | 196 | * If we encounter more of a specific lock type than expected, return -ENOSPC. |
197 | */ | 197 | */ |
198 | int ceph_encode_locks_to_buffer(struct inode *inode, | 198 | int ceph_encode_locks_to_buffer(struct inode *inode, |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 4d2920304be8..74fd2898b2ab 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -2481,20 +2481,20 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, | |||
2481 | struct ceph_filelock *flocks; | 2481 | struct ceph_filelock *flocks; |
2482 | 2482 | ||
2483 | encode_again: | 2483 | encode_again: |
2484 | lock_flocks(); | 2484 | spin_lock(&inode->i_lock); |
2485 | ceph_count_locks(inode, &num_fcntl_locks, &num_flock_locks); | 2485 | ceph_count_locks(inode, &num_fcntl_locks, &num_flock_locks); |
2486 | unlock_flocks(); | 2486 | spin_unlock(&inode->i_lock); |
2487 | flocks = kmalloc((num_fcntl_locks+num_flock_locks) * | 2487 | flocks = kmalloc((num_fcntl_locks+num_flock_locks) * |
2488 | sizeof(struct ceph_filelock), GFP_NOFS); | 2488 | sizeof(struct ceph_filelock), GFP_NOFS); |
2489 | if (!flocks) { | 2489 | if (!flocks) { |
2490 | err = -ENOMEM; | 2490 | err = -ENOMEM; |
2491 | goto out_free; | 2491 | goto out_free; |
2492 | } | 2492 | } |
2493 | lock_flocks(); | 2493 | spin_lock(&inode->i_lock); |
2494 | err = ceph_encode_locks_to_buffer(inode, flocks, | 2494 | err = ceph_encode_locks_to_buffer(inode, flocks, |
2495 | num_fcntl_locks, | 2495 | num_fcntl_locks, |
2496 | num_flock_locks); | 2496 | num_flock_locks); |
2497 | unlock_flocks(); | 2497 | spin_unlock(&inode->i_lock); |
2498 | if (err) { | 2498 | if (err) { |
2499 | kfree(flocks); | 2499 | kfree(flocks); |
2500 | if (err == -ENOSPC) | 2500 | if (err == -ENOSPC) |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 540c1ccfcdb2..a445e71746fa 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -765,7 +765,7 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int whence) | |||
765 | 765 | ||
766 | static int cifs_setlease(struct file *file, long arg, struct file_lock **lease) | 766 | static int cifs_setlease(struct file *file, long arg, struct file_lock **lease) |
767 | { | 767 | { |
768 | /* note that this is called by vfs setlease with lock_flocks held | 768 | /* note that this is called by vfs setlease with i_lock held |
769 | to protect *lease from going away */ | 769 | to protect *lease from going away */ |
770 | struct inode *inode = file_inode(file); | 770 | struct inode *inode = file_inode(file); |
771 | struct cifsFileInfo *cfile = file->private_data; | 771 | struct cifsFileInfo *cfile = file->private_data; |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 1686e4085646..0630710a9c3f 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -1092,6 +1092,7 @@ struct lock_to_push { | |||
1092 | static int | 1092 | static int |
1093 | cifs_push_posix_locks(struct cifsFileInfo *cfile) | 1093 | cifs_push_posix_locks(struct cifsFileInfo *cfile) |
1094 | { | 1094 | { |
1095 | struct inode *inode = cfile->dentry->d_inode; | ||
1095 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | 1096 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
1096 | struct file_lock *flock, **before; | 1097 | struct file_lock *flock, **before; |
1097 | unsigned int count = 0, i = 0; | 1098 | unsigned int count = 0, i = 0; |
@@ -1102,12 +1103,12 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile) | |||
1102 | 1103 | ||
1103 | xid = get_xid(); | 1104 | xid = get_xid(); |
1104 | 1105 | ||
1105 | lock_flocks(); | 1106 | spin_lock(&inode->i_lock); |
1106 | cifs_for_each_lock(cfile->dentry->d_inode, before) { | 1107 | cifs_for_each_lock(inode, before) { |
1107 | if ((*before)->fl_flags & FL_POSIX) | 1108 | if ((*before)->fl_flags & FL_POSIX) |
1108 | count++; | 1109 | count++; |
1109 | } | 1110 | } |
1110 | unlock_flocks(); | 1111 | spin_unlock(&inode->i_lock); |
1111 | 1112 | ||
1112 | INIT_LIST_HEAD(&locks_to_send); | 1113 | INIT_LIST_HEAD(&locks_to_send); |
1113 | 1114 | ||
@@ -1126,8 +1127,8 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile) | |||
1126 | } | 1127 | } |
1127 | 1128 | ||
1128 | el = locks_to_send.next; | 1129 | el = locks_to_send.next; |
1129 | lock_flocks(); | 1130 | spin_lock(&inode->i_lock); |
1130 | cifs_for_each_lock(cfile->dentry->d_inode, before) { | 1131 | cifs_for_each_lock(inode, before) { |
1131 | flock = *before; | 1132 | flock = *before; |
1132 | if ((flock->fl_flags & FL_POSIX) == 0) | 1133 | if ((flock->fl_flags & FL_POSIX) == 0) |
1133 | continue; | 1134 | continue; |
@@ -1152,7 +1153,7 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile) | |||
1152 | lck->offset = flock->fl_start; | 1153 | lck->offset = flock->fl_start; |
1153 | el = el->next; | 1154 | el = el->next; |
1154 | } | 1155 | } |
1155 | unlock_flocks(); | 1156 | spin_unlock(&inode->i_lock); |
1156 | 1157 | ||
1157 | list_for_each_entry_safe(lck, tmp, &locks_to_send, llist) { | 1158 | list_for_each_entry_safe(lck, tmp, &locks_to_send, llist) { |
1158 | int stored_rc; | 1159 | int stored_rc; |
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index b3333371aebb..cebfd404c1d9 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c | |||
@@ -889,7 +889,7 @@ out_uninit: | |||
889 | * cluster; until we do, disable leases (by just returning -EINVAL), | 889 | * cluster; until we do, disable leases (by just returning -EINVAL), |
890 | * unless the administrator has requested purely local locking. | 890 | * unless the administrator has requested purely local locking. |
891 | * | 891 | * |
892 | * Locking: called under lock_flocks | 892 | * Locking: called under i_lock |
893 | * | 893 | * |
894 | * Returns: errno | 894 | * Returns: errno |
895 | */ | 895 | */ |
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c index 97e87415b145..dc5c75930f0f 100644 --- a/fs/lockd/svcsubs.c +++ b/fs/lockd/svcsubs.c | |||
@@ -169,7 +169,7 @@ nlm_traverse_locks(struct nlm_host *host, struct nlm_file *file, | |||
169 | 169 | ||
170 | again: | 170 | again: |
171 | file->f_locks = 0; | 171 | file->f_locks = 0; |
172 | lock_flocks(); /* protects i_flock list */ | 172 | spin_lock(&inode->i_lock); |
173 | for (fl = inode->i_flock; fl; fl = fl->fl_next) { | 173 | for (fl = inode->i_flock; fl; fl = fl->fl_next) { |
174 | if (fl->fl_lmops != &nlmsvc_lock_operations) | 174 | if (fl->fl_lmops != &nlmsvc_lock_operations) |
175 | continue; | 175 | continue; |
@@ -181,7 +181,7 @@ again: | |||
181 | if (match(lockhost, host)) { | 181 | if (match(lockhost, host)) { |
182 | struct file_lock lock = *fl; | 182 | struct file_lock lock = *fl; |
183 | 183 | ||
184 | unlock_flocks(); | 184 | spin_unlock(&inode->i_lock); |
185 | lock.fl_type = F_UNLCK; | 185 | lock.fl_type = F_UNLCK; |
186 | lock.fl_start = 0; | 186 | lock.fl_start = 0; |
187 | lock.fl_end = OFFSET_MAX; | 187 | lock.fl_end = OFFSET_MAX; |
@@ -193,7 +193,7 @@ again: | |||
193 | goto again; | 193 | goto again; |
194 | } | 194 | } |
195 | } | 195 | } |
196 | unlock_flocks(); | 196 | spin_unlock(&inode->i_lock); |
197 | 197 | ||
198 | return 0; | 198 | return 0; |
199 | } | 199 | } |
@@ -228,14 +228,14 @@ nlm_file_inuse(struct nlm_file *file) | |||
228 | if (file->f_count || !list_empty(&file->f_blocks) || file->f_shares) | 228 | if (file->f_count || !list_empty(&file->f_blocks) || file->f_shares) |
229 | return 1; | 229 | return 1; |
230 | 230 | ||
231 | lock_flocks(); | 231 | spin_lock(&inode->i_lock); |
232 | for (fl = inode->i_flock; fl; fl = fl->fl_next) { | 232 | for (fl = inode->i_flock; fl; fl = fl->fl_next) { |
233 | if (fl->fl_lmops == &nlmsvc_lock_operations) { | 233 | if (fl->fl_lmops == &nlmsvc_lock_operations) { |
234 | unlock_flocks(); | 234 | spin_unlock(&inode->i_lock); |
235 | return 1; | 235 | return 1; |
236 | } | 236 | } |
237 | } | 237 | } |
238 | unlock_flocks(); | 238 | spin_unlock(&inode->i_lock); |
239 | file->f_locks = 0; | 239 | file->f_locks = 0; |
240 | return 0; | 240 | return 0; |
241 | } | 241 | } |
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 | */ | ||
157 | static LIST_HEAD(file_lock_list); | 160 | static 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 | */ | ||
160 | static LIST_HEAD(blocked_list); | 166 | static 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 | */ | ||
163 | static DEFINE_SPINLOCK(file_lock_lock); | 185 | static DEFINE_SPINLOCK(file_lock_lock); |
164 | 186 | ||
165 | void lock_flocks(void) | ||
166 | { | ||
167 | spin_lock(&file_lock_lock); | ||
168 | } | ||
169 | EXPORT_SYMBOL_GPL(lock_flocks); | ||
170 | |||
171 | void unlock_flocks(void) | ||
172 | { | ||
173 | spin_unlock(&file_lock_lock); | ||
174 | } | ||
175 | EXPORT_SYMBOL_GPL(unlock_flocks); | ||
176 | |||
177 | static struct kmem_cache *filelock_cache __read_mostly; | 187 | static struct kmem_cache *filelock_cache __read_mostly; |
178 | 188 | ||
179 | static void locks_init_lock_heads(struct file_lock *fl) | 189 | static 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) | |||
489 | static inline void | 499 | static inline void |
490 | locks_insert_global_locks(struct file_lock *fl) | 500 | locks_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 | ||
495 | static inline void | 507 | static inline void |
496 | locks_delete_global_locks(struct file_lock *fl) | 508 | locks_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 | ||
501 | static inline void | 515 | static 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 | */ |
516 | static void __locks_delete_block(struct file_lock *waiter) | 532 | static 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 | */ | ||
525 | static void locks_delete_block(struct file_lock *waiter) | 539 | static 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 | */ |
537 | static void locks_insert_block(struct file_lock *blocker, | 553 | static 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. */ | ||
564 | static 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 | */ |
552 | static void locks_wake_up_blocks(struct file_lock *blocker) | 577 | static 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 | */ |
570 | static void locks_insert_lock(struct file_lock **pos, struct file_lock *fl) | 599 | static 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 | */ |
587 | static void locks_delete_lock(struct file_lock **thisfl_p) | 618 | static void locks_delete_lock(struct file_lock **thisfl_p) |
588 | { | 619 | { |
@@ -652,8 +683,9 @@ void | |||
652 | posix_test_lock(struct file *filp, struct file_lock *fl) | 683 | posix_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 | } |
672 | EXPORT_SYMBOL(posix_test_lock); | 704 | EXPORT_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! */ | ||
713 | static int posix_locks_deadlock(struct file_lock *caller_fl, | 746 | static 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 | ||
783 | find_conflict: | 816 | find_conflict: |
@@ -804,7 +837,7 @@ find_conflict: | |||
804 | error = 0; | 837 | error = 0; |
805 | 838 | ||
806 | out: | 839 | out: |
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 | ||
1304 | out: | 1343 | out: |
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); | |||
1355 | int fcntl_getlease(struct file *filp) | 1394 | int 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 | */ |
1465 | int generic_setlease(struct file *filp, long arg, struct file_lock **flp) | 1505 | int 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 | ||
1530 | int vfs_setlease(struct file *filp, long arg, struct file_lock **lease) | 1570 | int 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) | |||
1551 | static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) | 1592 | static 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 | ||
1589 | out_free_fasync: | 1631 | out_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 | } |
2151 | EXPORT_SYMBOL(posix_unblock_lock); | 2193 | EXPORT_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 | ||
2274 | static void locks_stop(struct seq_file *f, void *v) | 2316 | static void locks_stop(struct seq_file *f, void *v) |
2275 | { | 2317 | { |
2276 | unlock_flocks(); | 2318 | spin_unlock(&file_lock_lock); |
2277 | } | 2319 | } |
2278 | 2320 | ||
2279 | static const struct seq_operations locks_seq_operations = { | 2321 | static 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 | ||
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 57db3244f4d9..7ec4814e298d 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
@@ -73,20 +73,20 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_ | |||
73 | if (inode->i_flock == NULL) | 73 | if (inode->i_flock == NULL) |
74 | goto out; | 74 | goto out; |
75 | 75 | ||
76 | /* Protect inode->i_flock using the file locks lock */ | 76 | /* Protect inode->i_flock using the i_lock */ |
77 | lock_flocks(); | 77 | spin_lock(&inode->i_lock); |
78 | for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { | 78 | for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { |
79 | if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) | 79 | if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) |
80 | continue; | 80 | continue; |
81 | if (nfs_file_open_context(fl->fl_file) != ctx) | 81 | if (nfs_file_open_context(fl->fl_file) != ctx) |
82 | continue; | 82 | continue; |
83 | unlock_flocks(); | 83 | spin_unlock(&inode->i_lock); |
84 | status = nfs4_lock_delegation_recall(fl, state, stateid); | 84 | status = nfs4_lock_delegation_recall(fl, state, stateid); |
85 | if (status < 0) | 85 | if (status < 0) |
86 | goto out; | 86 | goto out; |
87 | lock_flocks(); | 87 | spin_lock(&inode->i_lock); |
88 | } | 88 | } |
89 | unlock_flocks(); | 89 | spin_unlock(&inode->i_lock); |
90 | out: | 90 | out: |
91 | return status; | 91 | return status; |
92 | } | 92 | } |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 1fab140764c4..ff10b4aa534c 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -1373,13 +1373,13 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_ | |||
1373 | /* Guard against delegation returns and new lock/unlock calls */ | 1373 | /* Guard against delegation returns and new lock/unlock calls */ |
1374 | down_write(&nfsi->rwsem); | 1374 | down_write(&nfsi->rwsem); |
1375 | /* Protect inode->i_flock using the BKL */ | 1375 | /* Protect inode->i_flock using the BKL */ |
1376 | lock_flocks(); | 1376 | spin_lock(&inode->i_lock); |
1377 | for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { | 1377 | for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { |
1378 | if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) | 1378 | if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) |
1379 | continue; | 1379 | continue; |
1380 | if (nfs_file_open_context(fl->fl_file)->state != state) | 1380 | if (nfs_file_open_context(fl->fl_file)->state != state) |
1381 | continue; | 1381 | continue; |
1382 | unlock_flocks(); | 1382 | spin_unlock(&inode->i_lock); |
1383 | status = ops->recover_lock(state, fl); | 1383 | status = ops->recover_lock(state, fl); |
1384 | switch (status) { | 1384 | switch (status) { |
1385 | case 0: | 1385 | case 0: |
@@ -1406,9 +1406,9 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_ | |||
1406 | /* kill_proc(fl->fl_pid, SIGLOST, 1); */ | 1406 | /* kill_proc(fl->fl_pid, SIGLOST, 1); */ |
1407 | status = 0; | 1407 | status = 0; |
1408 | } | 1408 | } |
1409 | lock_flocks(); | 1409 | spin_lock(&inode->i_lock); |
1410 | } | 1410 | } |
1411 | unlock_flocks(); | 1411 | spin_unlock(&inode->i_lock); |
1412 | out: | 1412 | out: |
1413 | up_write(&nfsi->rwsem); | 1413 | up_write(&nfsi->rwsem); |
1414 | return status; | 1414 | return status; |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 316ec843dec2..f17051838b41 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -2645,13 +2645,13 @@ static void nfsd_break_one_deleg(struct nfs4_delegation *dp) | |||
2645 | 2645 | ||
2646 | list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru); | 2646 | list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru); |
2647 | 2647 | ||
2648 | /* only place dl_time is set. protected by lock_flocks*/ | 2648 | /* Only place dl_time is set; protected by i_lock: */ |
2649 | dp->dl_time = get_seconds(); | 2649 | dp->dl_time = get_seconds(); |
2650 | 2650 | ||
2651 | nfsd4_cb_recall(dp); | 2651 | nfsd4_cb_recall(dp); |
2652 | } | 2652 | } |
2653 | 2653 | ||
2654 | /* Called from break_lease() with lock_flocks() held. */ | 2654 | /* Called from break_lease() with i_lock held. */ |
2655 | static void nfsd_break_deleg_cb(struct file_lock *fl) | 2655 | static void nfsd_break_deleg_cb(struct file_lock *fl) |
2656 | { | 2656 | { |
2657 | struct nfs4_file *fp = (struct nfs4_file *)fl->fl_owner; | 2657 | struct nfs4_file *fp = (struct nfs4_file *)fl->fl_owner; |
@@ -4520,7 +4520,7 @@ check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner) | |||
4520 | struct inode *inode = filp->fi_inode; | 4520 | struct inode *inode = filp->fi_inode; |
4521 | int status = 0; | 4521 | int status = 0; |
4522 | 4522 | ||
4523 | lock_flocks(); | 4523 | spin_lock(&inode->i_lock); |
4524 | for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) { | 4524 | for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) { |
4525 | if ((*flpp)->fl_owner == (fl_owner_t)lowner) { | 4525 | if ((*flpp)->fl_owner == (fl_owner_t)lowner) { |
4526 | status = 1; | 4526 | status = 1; |
@@ -4528,7 +4528,7 @@ check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner) | |||
4528 | } | 4528 | } |
4529 | } | 4529 | } |
4530 | out: | 4530 | out: |
4531 | unlock_flocks(); | 4531 | spin_unlock(&inode->i_lock); |
4532 | return status; | 4532 | return status; |
4533 | } | 4533 | } |
4534 | 4534 | ||
diff --git a/include/linux/fs.h b/include/linux/fs.h index ed9fdaaf3223..24fe998795e1 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1024,8 +1024,6 @@ extern int vfs_setlease(struct file *, long, struct file_lock **); | |||
1024 | extern int lease_modify(struct file_lock **, int); | 1024 | extern int lease_modify(struct file_lock **, int); |
1025 | extern int lock_may_read(struct inode *, loff_t start, unsigned long count); | 1025 | extern int lock_may_read(struct inode *, loff_t start, unsigned long count); |
1026 | extern int lock_may_write(struct inode *, loff_t start, unsigned long count); | 1026 | extern int lock_may_write(struct inode *, loff_t start, unsigned long count); |
1027 | extern void lock_flocks(void); | ||
1028 | extern void unlock_flocks(void); | ||
1029 | #else /* !CONFIG_FILE_LOCKING */ | 1027 | #else /* !CONFIG_FILE_LOCKING */ |
1030 | static inline int fcntl_getlk(struct file *file, struct flock __user *user) | 1028 | static inline int fcntl_getlk(struct file *file, struct flock __user *user) |
1031 | { | 1029 | { |
@@ -1166,15 +1164,6 @@ static inline int lock_may_write(struct inode *inode, loff_t start, | |||
1166 | { | 1164 | { |
1167 | return 1; | 1165 | return 1; |
1168 | } | 1166 | } |
1169 | |||
1170 | static inline void lock_flocks(void) | ||
1171 | { | ||
1172 | } | ||
1173 | |||
1174 | static inline void unlock_flocks(void) | ||
1175 | { | ||
1176 | } | ||
1177 | |||
1178 | #endif /* !CONFIG_FILE_LOCKING */ | 1167 | #endif /* !CONFIG_FILE_LOCKING */ |
1179 | 1168 | ||
1180 | 1169 | ||