diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-08-13 14:17:40 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-08-13 14:17:40 -0400 |
commit | bc7af9ba154f648598bf92b391e446e31b09330a (patch) | |
tree | 01f1e0c9f7410c059e91ba9f7a5727fbeb25dd8b /fs/ocfs2/dcache.c | |
parent | d58d2d1adec90e7bc0c56e09b3ac0e9a5a471e68 (diff) | |
parent | b409d7a0ab46fe530efe52734984b4ed5d46c3eb (diff) |
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2: (22 commits)
ocfs2: Fix possible deadlock when extending quota file
ocfs2: keep index within status_map[]
ocfs2: Initialize the cluster we're writing to in a non-sparse extend
ocfs2: Remove redundant BUG_ON in __dlm_queue_ast()
ocfs2/quota: Release lock for error in ocfs2_quota_write.
ocfs2: Define credit counts for quota operations
ocfs2: Remove syncjiff field from quota info
ocfs2: Fix initialization of blockcheck stats
ocfs2: Zero out padding of on disk dquot structure
ocfs2: Initialize blocks allocated to local quota file
ocfs2: Mark buffer uptodate before calling ocfs2_journal_access_dq()
ocfs2: Make global quota files blocksize aligned
ocfs2: Use ocfs2_rec_clusters in ocfs2_adjust_adjacent_records.
ocfs2: Fix deadlock on umount
ocfs2: Add extra credits and access the modified bh in update_edge_lengths.
ocfs2: Fail ocfs2_get_block() immediately when a block needs allocation
ocfs2: Fix error return in ocfs2_write_cluster()
ocfs2: Fix compilation warning for fs/ocfs2/xattr.c
ocfs2: Initialize count in aio_write before generic_write_checks
ocfs2: log the actual return value of ocfs2_file_aio_write()
...
Diffstat (limited to 'fs/ocfs2/dcache.c')
-rw-r--r-- | fs/ocfs2/dcache.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c index b574431a031d..2f28b7de2c8d 100644 --- a/fs/ocfs2/dcache.c +++ b/fs/ocfs2/dcache.c | |||
@@ -310,22 +310,19 @@ out_attach: | |||
310 | return ret; | 310 | return ret; |
311 | } | 311 | } |
312 | 312 | ||
313 | static DEFINE_SPINLOCK(dentry_list_lock); | 313 | DEFINE_SPINLOCK(dentry_list_lock); |
314 | 314 | ||
315 | /* We limit the number of dentry locks to drop in one go. We have | 315 | /* We limit the number of dentry locks to drop in one go. We have |
316 | * this limit so that we don't starve other users of ocfs2_wq. */ | 316 | * this limit so that we don't starve other users of ocfs2_wq. */ |
317 | #define DL_INODE_DROP_COUNT 64 | 317 | #define DL_INODE_DROP_COUNT 64 |
318 | 318 | ||
319 | /* Drop inode references from dentry locks */ | 319 | /* Drop inode references from dentry locks */ |
320 | void ocfs2_drop_dl_inodes(struct work_struct *work) | 320 | static void __ocfs2_drop_dl_inodes(struct ocfs2_super *osb, int drop_count) |
321 | { | 321 | { |
322 | struct ocfs2_super *osb = container_of(work, struct ocfs2_super, | ||
323 | dentry_lock_work); | ||
324 | struct ocfs2_dentry_lock *dl; | 322 | struct ocfs2_dentry_lock *dl; |
325 | int drop_count = DL_INODE_DROP_COUNT; | ||
326 | 323 | ||
327 | spin_lock(&dentry_list_lock); | 324 | spin_lock(&dentry_list_lock); |
328 | while (osb->dentry_lock_list && drop_count--) { | 325 | while (osb->dentry_lock_list && (drop_count < 0 || drop_count--)) { |
329 | dl = osb->dentry_lock_list; | 326 | dl = osb->dentry_lock_list; |
330 | osb->dentry_lock_list = dl->dl_next; | 327 | osb->dentry_lock_list = dl->dl_next; |
331 | spin_unlock(&dentry_list_lock); | 328 | spin_unlock(&dentry_list_lock); |
@@ -333,11 +330,32 @@ void ocfs2_drop_dl_inodes(struct work_struct *work) | |||
333 | kfree(dl); | 330 | kfree(dl); |
334 | spin_lock(&dentry_list_lock); | 331 | spin_lock(&dentry_list_lock); |
335 | } | 332 | } |
336 | if (osb->dentry_lock_list) | 333 | spin_unlock(&dentry_list_lock); |
334 | } | ||
335 | |||
336 | void ocfs2_drop_dl_inodes(struct work_struct *work) | ||
337 | { | ||
338 | struct ocfs2_super *osb = container_of(work, struct ocfs2_super, | ||
339 | dentry_lock_work); | ||
340 | |||
341 | __ocfs2_drop_dl_inodes(osb, DL_INODE_DROP_COUNT); | ||
342 | /* | ||
343 | * Don't queue dropping if umount is in progress. We flush the | ||
344 | * list in ocfs2_dismount_volume | ||
345 | */ | ||
346 | spin_lock(&dentry_list_lock); | ||
347 | if (osb->dentry_lock_list && | ||
348 | !ocfs2_test_osb_flag(osb, OCFS2_OSB_DROP_DENTRY_LOCK_IMMED)) | ||
337 | queue_work(ocfs2_wq, &osb->dentry_lock_work); | 349 | queue_work(ocfs2_wq, &osb->dentry_lock_work); |
338 | spin_unlock(&dentry_list_lock); | 350 | spin_unlock(&dentry_list_lock); |
339 | } | 351 | } |
340 | 352 | ||
353 | /* Flush the whole work queue */ | ||
354 | void ocfs2_drop_all_dl_inodes(struct ocfs2_super *osb) | ||
355 | { | ||
356 | __ocfs2_drop_dl_inodes(osb, -1); | ||
357 | } | ||
358 | |||
341 | /* | 359 | /* |
342 | * ocfs2_dentry_iput() and friends. | 360 | * ocfs2_dentry_iput() and friends. |
343 | * | 361 | * |
@@ -368,7 +386,8 @@ static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb, | |||
368 | /* We leave dropping of inode reference to ocfs2_wq as that can | 386 | /* We leave dropping of inode reference to ocfs2_wq as that can |
369 | * possibly lead to inode deletion which gets tricky */ | 387 | * possibly lead to inode deletion which gets tricky */ |
370 | spin_lock(&dentry_list_lock); | 388 | spin_lock(&dentry_list_lock); |
371 | if (!osb->dentry_lock_list) | 389 | if (!osb->dentry_lock_list && |
390 | !ocfs2_test_osb_flag(osb, OCFS2_OSB_DROP_DENTRY_LOCK_IMMED)) | ||
372 | queue_work(ocfs2_wq, &osb->dentry_lock_work); | 391 | queue_work(ocfs2_wq, &osb->dentry_lock_work); |
373 | dl->dl_next = osb->dentry_lock_list; | 392 | dl->dl_next = osb->dentry_lock_list; |
374 | osb->dentry_lock_list = dl; | 393 | osb->dentry_lock_list = dl; |