diff options
author | Dave Chinner <dchinner@redhat.com> | 2011-03-22 07:23:37 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-03-24 21:16:31 -0400 |
commit | b2b2af8e614b4dcd8aca1369d82ce5ad0461a7b1 (patch) | |
tree | 08b810e4df93a0705cc3c430a327344ae46ebfc8 /fs/inode.c | |
parent | 250df6ed274d767da844a5d9f05720b804240197 (diff) |
fs: factor inode disposal
We have a couple of places that dispose of inodes. factor the
disposal into evict() to isolate this code and make it simpler to
peel away the inode_lock from the code.
While doing this, change the logic flow in iput_final() to separate
the different cases that need to be handled to make the transitions
the inode goes through more obvious.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/inode.c')
-rw-r--r-- | fs/inode.c | 104 |
1 files changed, 41 insertions, 63 deletions
diff --git a/fs/inode.c b/fs/inode.c index 14b12c4ee026..f752a959254b 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -423,17 +423,6 @@ void __insert_inode_hash(struct inode *inode, unsigned long hashval) | |||
423 | EXPORT_SYMBOL(__insert_inode_hash); | 423 | EXPORT_SYMBOL(__insert_inode_hash); |
424 | 424 | ||
425 | /** | 425 | /** |
426 | * __remove_inode_hash - remove an inode from the hash | ||
427 | * @inode: inode to unhash | ||
428 | * | ||
429 | * Remove an inode from the superblock. | ||
430 | */ | ||
431 | static void __remove_inode_hash(struct inode *inode) | ||
432 | { | ||
433 | hlist_del_init(&inode->i_hash); | ||
434 | } | ||
435 | |||
436 | /** | ||
437 | * remove_inode_hash - remove an inode from the hash | 426 | * remove_inode_hash - remove an inode from the hash |
438 | * @inode: inode to unhash | 427 | * @inode: inode to unhash |
439 | * | 428 | * |
@@ -462,10 +451,31 @@ void end_writeback(struct inode *inode) | |||
462 | } | 451 | } |
463 | EXPORT_SYMBOL(end_writeback); | 452 | EXPORT_SYMBOL(end_writeback); |
464 | 453 | ||
454 | /* | ||
455 | * Free the inode passed in, removing it from the lists it is still connected | ||
456 | * to. We remove any pages still attached to the inode and wait for any IO that | ||
457 | * is still in progress before finally destroying the inode. | ||
458 | * | ||
459 | * An inode must already be marked I_FREEING so that we avoid the inode being | ||
460 | * moved back onto lists if we race with other code that manipulates the lists | ||
461 | * (e.g. writeback_single_inode). The caller is responsible for setting this. | ||
462 | * | ||
463 | * An inode must already be removed from the LRU list before being evicted from | ||
464 | * the cache. This should occur atomically with setting the I_FREEING state | ||
465 | * flag, so no inodes here should ever be on the LRU when being evicted. | ||
466 | */ | ||
465 | static void evict(struct inode *inode) | 467 | static void evict(struct inode *inode) |
466 | { | 468 | { |
467 | const struct super_operations *op = inode->i_sb->s_op; | 469 | const struct super_operations *op = inode->i_sb->s_op; |
468 | 470 | ||
471 | BUG_ON(!(inode->i_state & I_FREEING)); | ||
472 | BUG_ON(!list_empty(&inode->i_lru)); | ||
473 | |||
474 | spin_lock(&inode_lock); | ||
475 | list_del_init(&inode->i_wb_list); | ||
476 | __inode_sb_list_del(inode); | ||
477 | spin_unlock(&inode_lock); | ||
478 | |||
469 | if (op->evict_inode) { | 479 | if (op->evict_inode) { |
470 | op->evict_inode(inode); | 480 | op->evict_inode(inode); |
471 | } else { | 481 | } else { |
@@ -477,6 +487,15 @@ static void evict(struct inode *inode) | |||
477 | bd_forget(inode); | 487 | bd_forget(inode); |
478 | if (S_ISCHR(inode->i_mode) && inode->i_cdev) | 488 | if (S_ISCHR(inode->i_mode) && inode->i_cdev) |
479 | cd_forget(inode); | 489 | cd_forget(inode); |
490 | |||
491 | remove_inode_hash(inode); | ||
492 | |||
493 | spin_lock(&inode->i_lock); | ||
494 | wake_up_bit(&inode->i_state, __I_NEW); | ||
495 | BUG_ON(inode->i_state != (I_FREEING | I_CLEAR)); | ||
496 | spin_unlock(&inode->i_lock); | ||
497 | |||
498 | destroy_inode(inode); | ||
480 | } | 499 | } |
481 | 500 | ||
482 | /* | 501 | /* |
@@ -495,16 +514,6 @@ static void dispose_list(struct list_head *head) | |||
495 | list_del_init(&inode->i_lru); | 514 | list_del_init(&inode->i_lru); |
496 | 515 | ||
497 | evict(inode); | 516 | evict(inode); |
498 | |||
499 | spin_lock(&inode_lock); | ||
500 | __remove_inode_hash(inode); | ||
501 | __inode_sb_list_del(inode); | ||
502 | spin_unlock(&inode_lock); | ||
503 | |||
504 | spin_lock(&inode->i_lock); | ||
505 | wake_up_bit(&inode->i_state, __I_NEW); | ||
506 | spin_unlock(&inode->i_lock); | ||
507 | destroy_inode(inode); | ||
508 | } | 517 | } |
509 | } | 518 | } |
510 | 519 | ||
@@ -537,13 +546,7 @@ void evict_inodes(struct super_block *sb) | |||
537 | if (!(inode->i_state & (I_DIRTY | I_SYNC))) | 546 | if (!(inode->i_state & (I_DIRTY | I_SYNC))) |
538 | inodes_stat.nr_unused--; | 547 | inodes_stat.nr_unused--; |
539 | spin_unlock(&inode->i_lock); | 548 | spin_unlock(&inode->i_lock); |
540 | |||
541 | /* | ||
542 | * Move the inode off the IO lists and LRU once I_FREEING is | ||
543 | * set so that it won't get moved back on there if it is dirty. | ||
544 | */ | ||
545 | list_move(&inode->i_lru, &dispose); | 549 | list_move(&inode->i_lru, &dispose); |
546 | list_del_init(&inode->i_wb_list); | ||
547 | } | 550 | } |
548 | spin_unlock(&inode_lock); | 551 | spin_unlock(&inode_lock); |
549 | 552 | ||
@@ -596,13 +599,7 @@ int invalidate_inodes(struct super_block *sb, bool kill_dirty) | |||
596 | if (!(inode->i_state & (I_DIRTY | I_SYNC))) | 599 | if (!(inode->i_state & (I_DIRTY | I_SYNC))) |
597 | inodes_stat.nr_unused--; | 600 | inodes_stat.nr_unused--; |
598 | spin_unlock(&inode->i_lock); | 601 | spin_unlock(&inode->i_lock); |
599 | |||
600 | /* | ||
601 | * Move the inode off the IO lists and LRU once I_FREEING is | ||
602 | * set so that it won't get moved back on there if it is dirty. | ||
603 | */ | ||
604 | list_move(&inode->i_lru, &dispose); | 602 | list_move(&inode->i_lru, &dispose); |
605 | list_del_init(&inode->i_wb_list); | ||
606 | } | 603 | } |
607 | spin_unlock(&inode_lock); | 604 | spin_unlock(&inode_lock); |
608 | 605 | ||
@@ -699,12 +696,7 @@ static void prune_icache(int nr_to_scan) | |||
699 | inode->i_state |= I_FREEING; | 696 | inode->i_state |= I_FREEING; |
700 | spin_unlock(&inode->i_lock); | 697 | spin_unlock(&inode->i_lock); |
701 | 698 | ||
702 | /* | ||
703 | * Move the inode off the IO lists and LRU once I_FREEING is | ||
704 | * set so that it won't get moved back on there if it is dirty. | ||
705 | */ | ||
706 | list_move(&inode->i_lru, &freeable); | 699 | list_move(&inode->i_lru, &freeable); |
707 | list_del_init(&inode->i_wb_list); | ||
708 | inodes_stat.nr_unused--; | 700 | inodes_stat.nr_unused--; |
709 | } | 701 | } |
710 | if (current_is_kswapd()) | 702 | if (current_is_kswapd()) |
@@ -1434,16 +1426,16 @@ static void iput_final(struct inode *inode) | |||
1434 | else | 1426 | else |
1435 | drop = generic_drop_inode(inode); | 1427 | drop = generic_drop_inode(inode); |
1436 | 1428 | ||
1429 | if (!drop && (sb->s_flags & MS_ACTIVE)) { | ||
1430 | inode->i_state |= I_REFERENCED; | ||
1431 | if (!(inode->i_state & (I_DIRTY|I_SYNC))) | ||
1432 | inode_lru_list_add(inode); | ||
1433 | spin_unlock(&inode->i_lock); | ||
1434 | spin_unlock(&inode_lock); | ||
1435 | return; | ||
1436 | } | ||
1437 | |||
1437 | if (!drop) { | 1438 | if (!drop) { |
1438 | if (sb->s_flags & MS_ACTIVE) { | ||
1439 | inode->i_state |= I_REFERENCED; | ||
1440 | if (!(inode->i_state & (I_DIRTY|I_SYNC))) { | ||
1441 | inode_lru_list_add(inode); | ||
1442 | } | ||
1443 | spin_unlock(&inode->i_lock); | ||
1444 | spin_unlock(&inode_lock); | ||
1445 | return; | ||
1446 | } | ||
1447 | inode->i_state |= I_WILL_FREE; | 1439 | inode->i_state |= I_WILL_FREE; |
1448 | spin_unlock(&inode->i_lock); | 1440 | spin_unlock(&inode->i_lock); |
1449 | spin_unlock(&inode_lock); | 1441 | spin_unlock(&inode_lock); |
@@ -1452,28 +1444,14 @@ static void iput_final(struct inode *inode) | |||
1452 | spin_lock(&inode->i_lock); | 1444 | spin_lock(&inode->i_lock); |
1453 | WARN_ON(inode->i_state & I_NEW); | 1445 | WARN_ON(inode->i_state & I_NEW); |
1454 | inode->i_state &= ~I_WILL_FREE; | 1446 | inode->i_state &= ~I_WILL_FREE; |
1455 | __remove_inode_hash(inode); | ||
1456 | } | 1447 | } |
1457 | 1448 | ||
1458 | inode->i_state |= I_FREEING; | 1449 | inode->i_state |= I_FREEING; |
1459 | spin_unlock(&inode->i_lock); | ||
1460 | |||
1461 | /* | ||
1462 | * Move the inode off the IO lists and LRU once I_FREEING is | ||
1463 | * set so that it won't get moved back on there if it is dirty. | ||
1464 | */ | ||
1465 | inode_lru_list_del(inode); | 1450 | inode_lru_list_del(inode); |
1466 | list_del_init(&inode->i_wb_list); | 1451 | spin_unlock(&inode->i_lock); |
1467 | |||
1468 | __inode_sb_list_del(inode); | ||
1469 | spin_unlock(&inode_lock); | 1452 | spin_unlock(&inode_lock); |
1453 | |||
1470 | evict(inode); | 1454 | evict(inode); |
1471 | remove_inode_hash(inode); | ||
1472 | spin_lock(&inode->i_lock); | ||
1473 | wake_up_bit(&inode->i_state, __I_NEW); | ||
1474 | BUG_ON(inode->i_state != (I_FREEING | I_CLEAR)); | ||
1475 | spin_unlock(&inode->i_lock); | ||
1476 | destroy_inode(inode); | ||
1477 | } | 1455 | } |
1478 | 1456 | ||
1479 | /** | 1457 | /** |