diff options
Diffstat (limited to 'fs/inode.c')
-rw-r--r-- | fs/inode.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/fs/inode.c b/fs/inode.c index da93f7d160d4..6bc8761cc333 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -486,7 +486,7 @@ void __remove_inode_hash(struct inode *inode) | |||
486 | } | 486 | } |
487 | EXPORT_SYMBOL(__remove_inode_hash); | 487 | EXPORT_SYMBOL(__remove_inode_hash); |
488 | 488 | ||
489 | void end_writeback(struct inode *inode) | 489 | void clear_inode(struct inode *inode) |
490 | { | 490 | { |
491 | might_sleep(); | 491 | might_sleep(); |
492 | /* | 492 | /* |
@@ -500,11 +500,10 @@ void end_writeback(struct inode *inode) | |||
500 | BUG_ON(!list_empty(&inode->i_data.private_list)); | 500 | BUG_ON(!list_empty(&inode->i_data.private_list)); |
501 | BUG_ON(!(inode->i_state & I_FREEING)); | 501 | BUG_ON(!(inode->i_state & I_FREEING)); |
502 | BUG_ON(inode->i_state & I_CLEAR); | 502 | BUG_ON(inode->i_state & I_CLEAR); |
503 | inode_sync_wait(inode); | ||
504 | /* don't need i_lock here, no concurrent mods to i_state */ | 503 | /* don't need i_lock here, no concurrent mods to i_state */ |
505 | inode->i_state = I_FREEING | I_CLEAR; | 504 | inode->i_state = I_FREEING | I_CLEAR; |
506 | } | 505 | } |
507 | EXPORT_SYMBOL(end_writeback); | 506 | EXPORT_SYMBOL(clear_inode); |
508 | 507 | ||
509 | /* | 508 | /* |
510 | * Free the inode passed in, removing it from the lists it is still connected | 509 | * Free the inode passed in, removing it from the lists it is still connected |
@@ -531,12 +530,20 @@ static void evict(struct inode *inode) | |||
531 | 530 | ||
532 | inode_sb_list_del(inode); | 531 | inode_sb_list_del(inode); |
533 | 532 | ||
533 | /* | ||
534 | * Wait for flusher thread to be done with the inode so that filesystem | ||
535 | * does not start destroying it while writeback is still running. Since | ||
536 | * the inode has I_FREEING set, flusher thread won't start new work on | ||
537 | * the inode. We just have to wait for running writeback to finish. | ||
538 | */ | ||
539 | inode_wait_for_writeback(inode); | ||
540 | |||
534 | if (op->evict_inode) { | 541 | if (op->evict_inode) { |
535 | op->evict_inode(inode); | 542 | op->evict_inode(inode); |
536 | } else { | 543 | } else { |
537 | if (inode->i_data.nrpages) | 544 | if (inode->i_data.nrpages) |
538 | truncate_inode_pages(&inode->i_data, 0); | 545 | truncate_inode_pages(&inode->i_data, 0); |
539 | end_writeback(inode); | 546 | clear_inode(inode); |
540 | } | 547 | } |
541 | if (S_ISBLK(inode->i_mode) && inode->i_bdev) | 548 | if (S_ISBLK(inode->i_mode) && inode->i_bdev) |
542 | bd_forget(inode); | 549 | bd_forget(inode); |