diff options
Diffstat (limited to 'fs/ocfs2/dcache.c')
| -rw-r--r-- | fs/ocfs2/dcache.c | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c index b574431a031d..b4957c7d9fe2 100644 --- a/fs/ocfs2/dcache.c +++ b/fs/ocfs2/dcache.c | |||
| @@ -85,6 +85,17 @@ static int ocfs2_dentry_revalidate(struct dentry *dentry, | |||
| 85 | goto bail; | 85 | goto bail; |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | /* | ||
| 89 | * If the last lookup failed to create dentry lock, let us | ||
| 90 | * redo it. | ||
| 91 | */ | ||
| 92 | if (!dentry->d_fsdata) { | ||
| 93 | mlog(0, "Inode %llu doesn't have dentry lock, " | ||
| 94 | "returning false\n", | ||
| 95 | (unsigned long long)OCFS2_I(inode)->ip_blkno); | ||
| 96 | goto bail; | ||
| 97 | } | ||
| 98 | |||
| 88 | ret = 1; | 99 | ret = 1; |
| 89 | 100 | ||
| 90 | bail: | 101 | bail: |
| @@ -310,22 +321,19 @@ out_attach: | |||
| 310 | return ret; | 321 | return ret; |
| 311 | } | 322 | } |
| 312 | 323 | ||
| 313 | static DEFINE_SPINLOCK(dentry_list_lock); | 324 | DEFINE_SPINLOCK(dentry_list_lock); |
| 314 | 325 | ||
| 315 | /* We limit the number of dentry locks to drop in one go. We have | 326 | /* 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. */ | 327 | * this limit so that we don't starve other users of ocfs2_wq. */ |
| 317 | #define DL_INODE_DROP_COUNT 64 | 328 | #define DL_INODE_DROP_COUNT 64 |
| 318 | 329 | ||
| 319 | /* Drop inode references from dentry locks */ | 330 | /* Drop inode references from dentry locks */ |
| 320 | void ocfs2_drop_dl_inodes(struct work_struct *work) | 331 | static void __ocfs2_drop_dl_inodes(struct ocfs2_super *osb, int drop_count) |
| 321 | { | 332 | { |
| 322 | struct ocfs2_super *osb = container_of(work, struct ocfs2_super, | ||
| 323 | dentry_lock_work); | ||
| 324 | struct ocfs2_dentry_lock *dl; | 333 | struct ocfs2_dentry_lock *dl; |
| 325 | int drop_count = DL_INODE_DROP_COUNT; | ||
| 326 | 334 | ||
| 327 | spin_lock(&dentry_list_lock); | 335 | spin_lock(&dentry_list_lock); |
| 328 | while (osb->dentry_lock_list && drop_count--) { | 336 | while (osb->dentry_lock_list && (drop_count < 0 || drop_count--)) { |
| 329 | dl = osb->dentry_lock_list; | 337 | dl = osb->dentry_lock_list; |
| 330 | osb->dentry_lock_list = dl->dl_next; | 338 | osb->dentry_lock_list = dl->dl_next; |
| 331 | spin_unlock(&dentry_list_lock); | 339 | spin_unlock(&dentry_list_lock); |
| @@ -333,11 +341,32 @@ void ocfs2_drop_dl_inodes(struct work_struct *work) | |||
| 333 | kfree(dl); | 341 | kfree(dl); |
| 334 | spin_lock(&dentry_list_lock); | 342 | spin_lock(&dentry_list_lock); |
| 335 | } | 343 | } |
| 336 | if (osb->dentry_lock_list) | 344 | spin_unlock(&dentry_list_lock); |
| 345 | } | ||
| 346 | |||
| 347 | void ocfs2_drop_dl_inodes(struct work_struct *work) | ||
| 348 | { | ||
| 349 | struct ocfs2_super *osb = container_of(work, struct ocfs2_super, | ||
| 350 | dentry_lock_work); | ||
| 351 | |||
| 352 | __ocfs2_drop_dl_inodes(osb, DL_INODE_DROP_COUNT); | ||
| 353 | /* | ||
| 354 | * Don't queue dropping if umount is in progress. We flush the | ||
| 355 | * list in ocfs2_dismount_volume | ||
| 356 | */ | ||
| 357 | spin_lock(&dentry_list_lock); | ||
| 358 | if (osb->dentry_lock_list && | ||
| 359 | !ocfs2_test_osb_flag(osb, OCFS2_OSB_DROP_DENTRY_LOCK_IMMED)) | ||
| 337 | queue_work(ocfs2_wq, &osb->dentry_lock_work); | 360 | queue_work(ocfs2_wq, &osb->dentry_lock_work); |
| 338 | spin_unlock(&dentry_list_lock); | 361 | spin_unlock(&dentry_list_lock); |
| 339 | } | 362 | } |
| 340 | 363 | ||
| 364 | /* Flush the whole work queue */ | ||
| 365 | void ocfs2_drop_all_dl_inodes(struct ocfs2_super *osb) | ||
| 366 | { | ||
| 367 | __ocfs2_drop_dl_inodes(osb, -1); | ||
| 368 | } | ||
| 369 | |||
| 341 | /* | 370 | /* |
| 342 | * ocfs2_dentry_iput() and friends. | 371 | * ocfs2_dentry_iput() and friends. |
| 343 | * | 372 | * |
| @@ -368,7 +397,8 @@ static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb, | |||
| 368 | /* We leave dropping of inode reference to ocfs2_wq as that can | 397 | /* We leave dropping of inode reference to ocfs2_wq as that can |
| 369 | * possibly lead to inode deletion which gets tricky */ | 398 | * possibly lead to inode deletion which gets tricky */ |
| 370 | spin_lock(&dentry_list_lock); | 399 | spin_lock(&dentry_list_lock); |
| 371 | if (!osb->dentry_lock_list) | 400 | if (!osb->dentry_lock_list && |
| 401 | !ocfs2_test_osb_flag(osb, OCFS2_OSB_DROP_DENTRY_LOCK_IMMED)) | ||
| 372 | queue_work(ocfs2_wq, &osb->dentry_lock_work); | 402 | queue_work(ocfs2_wq, &osb->dentry_lock_work); |
| 373 | dl->dl_next = osb->dentry_lock_list; | 403 | dl->dl_next = osb->dentry_lock_list; |
| 374 | osb->dentry_lock_list = dl; | 404 | osb->dentry_lock_list = dl; |
