aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2011-03-22 07:23:39 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2011-03-24 21:16:32 -0400
commitf283c86afe6aa70b733d1ecebad5d9464943b774 (patch)
treebeaeca959996f2d8a00a997c56932dc5916bfec8 /fs
parent02afc410f363f98ac4f186341e38dcec13fc0e60 (diff)
fs: remove inode_lock from iput_final and prune_icache
Now that inode state changes are protected by the inode->i_lock and the inode LRU manipulations by the inode_lru_lock, we can remove the inode_lock from prune_icache and the initial part of iput_final(). instead of using the inode_lock to protect the inode during iput_final, use the inode->i_lock instead. This protects the inode against new references being taken while we change the inode state to I_FREEING, as well as preventing prune_icache from grabbing the inode while we are manipulating it. Hence we no longer need the inode_lock in iput_final prior to setting I_FREEING on the inode. For prune_icache, we no longer need the inode_lock to protect the LRU list, and the inodes themselves are protected against freeing races by the inode->i_lock. Hence we can lift the inode_lock from prune_icache as well. Signed-off-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/inode.c17
-rw-r--r--fs/logfs/inode.c2
2 files changed, 4 insertions, 15 deletions
diff --git a/fs/inode.c b/fs/inode.c
index b19cb6ee6ca3..389f5a247599 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -650,7 +650,6 @@ static void prune_icache(int nr_to_scan)
650 unsigned long reap = 0; 650 unsigned long reap = 0;
651 651
652 down_read(&iprune_sem); 652 down_read(&iprune_sem);
653 spin_lock(&inode_lock);
654 spin_lock(&inode_lru_lock); 653 spin_lock(&inode_lru_lock);
655 for (nr_scanned = 0; nr_scanned < nr_to_scan; nr_scanned++) { 654 for (nr_scanned = 0; nr_scanned < nr_to_scan; nr_scanned++) {
656 struct inode *inode; 655 struct inode *inode;
@@ -676,8 +675,8 @@ static void prune_icache(int nr_to_scan)
676 */ 675 */
677 if (atomic_read(&inode->i_count) || 676 if (atomic_read(&inode->i_count) ||
678 (inode->i_state & ~I_REFERENCED)) { 677 (inode->i_state & ~I_REFERENCED)) {
679 spin_unlock(&inode->i_lock);
680 list_del_init(&inode->i_lru); 678 list_del_init(&inode->i_lru);
679 spin_unlock(&inode->i_lock);
681 inodes_stat.nr_unused--; 680 inodes_stat.nr_unused--;
682 continue; 681 continue;
683 } 682 }
@@ -685,20 +684,18 @@ static void prune_icache(int nr_to_scan)
685 /* recently referenced inodes get one more pass */ 684 /* recently referenced inodes get one more pass */
686 if (inode->i_state & I_REFERENCED) { 685 if (inode->i_state & I_REFERENCED) {
687 inode->i_state &= ~I_REFERENCED; 686 inode->i_state &= ~I_REFERENCED;
688 spin_unlock(&inode->i_lock);
689 list_move(&inode->i_lru, &inode_lru); 687 list_move(&inode->i_lru, &inode_lru);
688 spin_unlock(&inode->i_lock);
690 continue; 689 continue;
691 } 690 }
692 if (inode_has_buffers(inode) || inode->i_data.nrpages) { 691 if (inode_has_buffers(inode) || inode->i_data.nrpages) {
693 __iget(inode); 692 __iget(inode);
694 spin_unlock(&inode->i_lock); 693 spin_unlock(&inode->i_lock);
695 spin_unlock(&inode_lru_lock); 694 spin_unlock(&inode_lru_lock);
696 spin_unlock(&inode_lock);
697 if (remove_inode_buffers(inode)) 695 if (remove_inode_buffers(inode))
698 reap += invalidate_mapping_pages(&inode->i_data, 696 reap += invalidate_mapping_pages(&inode->i_data,
699 0, -1); 697 0, -1);
700 iput(inode); 698 iput(inode);
701 spin_lock(&inode_lock);
702 spin_lock(&inode_lru_lock); 699 spin_lock(&inode_lru_lock);
703 700
704 if (inode != list_entry(inode_lru.next, 701 if (inode != list_entry(inode_lru.next,
@@ -724,7 +721,6 @@ static void prune_icache(int nr_to_scan)
724 else 721 else
725 __count_vm_events(PGINODESTEAL, reap); 722 __count_vm_events(PGINODESTEAL, reap);
726 spin_unlock(&inode_lru_lock); 723 spin_unlock(&inode_lru_lock);
727 spin_unlock(&inode_lock);
728 724
729 dispose_list(&freeable); 725 dispose_list(&freeable);
730 up_read(&iprune_sem); 726 up_read(&iprune_sem);
@@ -1082,7 +1078,6 @@ EXPORT_SYMBOL(iunique);
1082 1078
1083struct inode *igrab(struct inode *inode) 1079struct inode *igrab(struct inode *inode)
1084{ 1080{
1085 spin_lock(&inode_lock);
1086 spin_lock(&inode->i_lock); 1081 spin_lock(&inode->i_lock);
1087 if (!(inode->i_state & (I_FREEING|I_WILL_FREE))) { 1082 if (!(inode->i_state & (I_FREEING|I_WILL_FREE))) {
1088 __iget(inode); 1083 __iget(inode);
@@ -1096,7 +1091,6 @@ struct inode *igrab(struct inode *inode)
1096 */ 1091 */
1097 inode = NULL; 1092 inode = NULL;
1098 } 1093 }
1099 spin_unlock(&inode_lock);
1100 return inode; 1094 return inode;
1101} 1095}
1102EXPORT_SYMBOL(igrab); 1096EXPORT_SYMBOL(igrab);
@@ -1439,7 +1433,6 @@ static void iput_final(struct inode *inode)
1439 const struct super_operations *op = inode->i_sb->s_op; 1433 const struct super_operations *op = inode->i_sb->s_op;
1440 int drop; 1434 int drop;
1441 1435
1442 spin_lock(&inode->i_lock);
1443 WARN_ON(inode->i_state & I_NEW); 1436 WARN_ON(inode->i_state & I_NEW);
1444 1437
1445 if (op && op->drop_inode) 1438 if (op && op->drop_inode)
@@ -1452,16 +1445,13 @@ static void iput_final(struct inode *inode)
1452 if (!(inode->i_state & (I_DIRTY|I_SYNC))) 1445 if (!(inode->i_state & (I_DIRTY|I_SYNC)))
1453 inode_lru_list_add(inode); 1446 inode_lru_list_add(inode);
1454 spin_unlock(&inode->i_lock); 1447 spin_unlock(&inode->i_lock);
1455 spin_unlock(&inode_lock);
1456 return; 1448 return;
1457 } 1449 }
1458 1450
1459 if (!drop) { 1451 if (!drop) {
1460 inode->i_state |= I_WILL_FREE; 1452 inode->i_state |= I_WILL_FREE;
1461 spin_unlock(&inode->i_lock); 1453 spin_unlock(&inode->i_lock);
1462 spin_unlock(&inode_lock);
1463 write_inode_now(inode, 1); 1454 write_inode_now(inode, 1);
1464 spin_lock(&inode_lock);
1465 spin_lock(&inode->i_lock); 1455 spin_lock(&inode->i_lock);
1466 WARN_ON(inode->i_state & I_NEW); 1456 WARN_ON(inode->i_state & I_NEW);
1467 inode->i_state &= ~I_WILL_FREE; 1457 inode->i_state &= ~I_WILL_FREE;
@@ -1470,7 +1460,6 @@ static void iput_final(struct inode *inode)
1470 inode->i_state |= I_FREEING; 1460 inode->i_state |= I_FREEING;
1471 inode_lru_list_del(inode); 1461 inode_lru_list_del(inode);
1472 spin_unlock(&inode->i_lock); 1462 spin_unlock(&inode->i_lock);
1473 spin_unlock(&inode_lock);
1474 1463
1475 evict(inode); 1464 evict(inode);
1476} 1465}
@@ -1489,7 +1478,7 @@ void iput(struct inode *inode)
1489 if (inode) { 1478 if (inode) {
1490 BUG_ON(inode->i_state & I_CLEAR); 1479 BUG_ON(inode->i_state & I_CLEAR);
1491 1480
1492 if (atomic_dec_and_lock(&inode->i_count, &inode_lock)) 1481 if (atomic_dec_and_lock(&inode->i_count, &inode->i_lock))
1493 iput_final(inode); 1482 iput_final(inode);
1494 } 1483 }
1495} 1484}
diff --git a/fs/logfs/inode.c b/fs/logfs/inode.c
index 03b8c240aeda..edfea7a3a747 100644
--- a/fs/logfs/inode.c
+++ b/fs/logfs/inode.c
@@ -293,7 +293,7 @@ static int logfs_write_inode(struct inode *inode, struct writeback_control *wbc)
293 return ret; 293 return ret;
294} 294}
295 295
296/* called with inode_lock held */ 296/* called with inode->i_lock held */
297static int logfs_drop_inode(struct inode *inode) 297static int logfs_drop_inode(struct inode *inode)
298{ 298{
299 struct logfs_super *super = logfs_super(inode->i_sb); 299 struct logfs_super *super = logfs_super(inode->i_sb);