Commit b2b2af8e614b4dcd8aca1369d82ce5ad0461a7b1
Committed by
Al Viro
1 parent
250df6ed27
Exists in
master
and in
4 other branches
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>
Showing 1 changed file with 41 additions and 63 deletions Side-by-side Diff
fs/inode.c
... | ... | @@ -423,17 +423,6 @@ |
423 | 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 | 426 | * remove_inode_hash - remove an inode from the hash |
438 | 427 | * @inode: inode to unhash |
439 | 428 | * |
440 | 429 | |
... | ... | @@ -462,10 +451,31 @@ |
462 | 451 | } |
463 | 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 | 467 | static void evict(struct inode *inode) |
466 | 468 | { |
467 | 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 | 479 | if (op->evict_inode) { |
470 | 480 | op->evict_inode(inode); |
471 | 481 | } else { |
... | ... | @@ -477,6 +487,15 @@ |
477 | 487 | bd_forget(inode); |
478 | 488 | if (S_ISCHR(inode->i_mode) && inode->i_cdev) |
479 | 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 @@ |
495 | 514 | list_del_init(&inode->i_lru); |
496 | 515 | |
497 | 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 | |
511 | 520 | |
... | ... | @@ -537,13 +546,7 @@ |
537 | 546 | if (!(inode->i_state & (I_DIRTY | I_SYNC))) |
538 | 547 | inodes_stat.nr_unused--; |
539 | 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 | 549 | list_move(&inode->i_lru, &dispose); |
546 | - list_del_init(&inode->i_wb_list); | |
547 | 550 | } |
548 | 551 | spin_unlock(&inode_lock); |
549 | 552 | |
550 | 553 | |
... | ... | @@ -596,13 +599,7 @@ |
596 | 599 | if (!(inode->i_state & (I_DIRTY | I_SYNC))) |
597 | 600 | inodes_stat.nr_unused--; |
598 | 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 | 602 | list_move(&inode->i_lru, &dispose); |
605 | - list_del_init(&inode->i_wb_list); | |
606 | 603 | } |
607 | 604 | spin_unlock(&inode_lock); |
608 | 605 | |
609 | 606 | |
... | ... | @@ -699,12 +696,7 @@ |
699 | 696 | inode->i_state |= I_FREEING; |
700 | 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 | 699 | list_move(&inode->i_lru, &freeable); |
707 | - list_del_init(&inode->i_wb_list); | |
708 | 700 | inodes_stat.nr_unused--; |
709 | 701 | } |
710 | 702 | if (current_is_kswapd()) |
711 | 703 | |
... | ... | @@ -1434,16 +1426,16 @@ |
1434 | 1426 | else |
1435 | 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 | 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 | 1439 | inode->i_state |= I_WILL_FREE; |
1448 | 1440 | spin_unlock(&inode->i_lock); |
1449 | 1441 | spin_unlock(&inode_lock); |
1450 | 1442 | |
1451 | 1443 | |
1452 | 1444 | |
1453 | 1445 | |
... | ... | @@ -1452,28 +1444,14 @@ |
1452 | 1444 | spin_lock(&inode->i_lock); |
1453 | 1445 | WARN_ON(inode->i_state & I_NEW); |
1454 | 1446 | inode->i_state &= ~I_WILL_FREE; |
1455 | - __remove_inode_hash(inode); | |
1456 | 1447 | } |
1457 | 1448 | |
1458 | 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 | 1450 | inode_lru_list_del(inode); |
1466 | - list_del_init(&inode->i_wb_list); | |
1467 | - | |
1468 | - __inode_sb_list_del(inode); | |
1451 | + spin_unlock(&inode->i_lock); | |
1469 | 1452 | spin_unlock(&inode_lock); |
1453 | + | |
1470 | 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 | /** |