diff options
Diffstat (limited to 'fs/inode.c')
-rw-r--r-- | fs/inode.c | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/fs/inode.c b/fs/inode.c index a1f5c2fa1d4a..99d664bafe9f 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -136,7 +136,7 @@ int inode_init_always(struct super_block *sb, struct inode *inode) | |||
136 | inode->i_sb = sb; | 136 | inode->i_sb = sb; |
137 | inode->i_blkbits = sb->s_blocksize_bits; | 137 | inode->i_blkbits = sb->s_blocksize_bits; |
138 | inode->i_flags = 0; | 138 | inode->i_flags = 0; |
139 | atomic_set(&inode->i_count, 1); | 139 | inode->i_count = 1; |
140 | inode->i_op = &empty_iops; | 140 | inode->i_op = &empty_iops; |
141 | inode->i_fop = &empty_fops; | 141 | inode->i_fop = &empty_fops; |
142 | inode->i_nlink = 1; | 142 | inode->i_nlink = 1; |
@@ -290,11 +290,10 @@ static void init_once(void *foo) | |||
290 | void __iget(struct inode *inode) | 290 | void __iget(struct inode *inode) |
291 | { | 291 | { |
292 | assert_spin_locked(&inode->i_lock); | 292 | assert_spin_locked(&inode->i_lock); |
293 | if (atomic_read(&inode->i_count)) { | 293 | inode->i_count++; |
294 | atomic_inc(&inode->i_count); | 294 | if (inode->i_count > 1) |
295 | return; | 295 | return; |
296 | } | 296 | |
297 | atomic_inc(&inode->i_count); | ||
298 | if (!(inode->i_state & (I_DIRTY|I_SYNC))) | 297 | if (!(inode->i_state & (I_DIRTY|I_SYNC))) |
299 | list_move(&inode->i_list, &inode_in_use); | 298 | list_move(&inode->i_list, &inode_in_use); |
300 | inodes_stat.nr_unused--; | 299 | inodes_stat.nr_unused--; |
@@ -399,7 +398,7 @@ static int invalidate_list(struct list_head *head, struct list_head *dispose) | |||
399 | continue; | 398 | continue; |
400 | } | 399 | } |
401 | invalidate_inode_buffers(inode); | 400 | invalidate_inode_buffers(inode); |
402 | if (!atomic_read(&inode->i_count)) { | 401 | if (!inode->i_count) { |
403 | list_move(&inode->i_list, dispose); | 402 | list_move(&inode->i_list, dispose); |
404 | WARN_ON(inode->i_state & I_NEW); | 403 | WARN_ON(inode->i_state & I_NEW); |
405 | inode->i_state |= I_FREEING; | 404 | inode->i_state |= I_FREEING; |
@@ -450,7 +449,7 @@ static int can_unuse(struct inode *inode) | |||
450 | return 0; | 449 | return 0; |
451 | if (inode_has_buffers(inode)) | 450 | if (inode_has_buffers(inode)) |
452 | return 0; | 451 | return 0; |
453 | if (atomic_read(&inode->i_count)) | 452 | if (inode->i_count) |
454 | return 0; | 453 | return 0; |
455 | if (inode->i_data.nrpages) | 454 | if (inode->i_data.nrpages) |
456 | return 0; | 455 | return 0; |
@@ -488,7 +487,7 @@ static void prune_icache(int nr_to_scan) | |||
488 | inode = list_entry(inode_unused.prev, struct inode, i_list); | 487 | inode = list_entry(inode_unused.prev, struct inode, i_list); |
489 | 488 | ||
490 | spin_lock(&inode->i_lock); | 489 | spin_lock(&inode->i_lock); |
491 | if (inode->i_state || atomic_read(&inode->i_count)) { | 490 | if (inode->i_state || inode->i_count) { |
492 | list_move(&inode->i_list, &inode_unused); | 491 | list_move(&inode->i_list, &inode_unused); |
493 | spin_unlock(&inode->i_lock); | 492 | spin_unlock(&inode->i_lock); |
494 | continue; | 493 | continue; |
@@ -1277,8 +1276,6 @@ void generic_delete_inode(struct inode *inode) | |||
1277 | { | 1276 | { |
1278 | const struct super_operations *op = inode->i_sb->s_op; | 1277 | const struct super_operations *op = inode->i_sb->s_op; |
1279 | 1278 | ||
1280 | spin_lock(&sb_inode_list_lock); | ||
1281 | spin_lock(&inode->i_lock); | ||
1282 | list_del_init(&inode->i_list); | 1279 | list_del_init(&inode->i_list); |
1283 | list_del_init(&inode->i_sb_list); | 1280 | list_del_init(&inode->i_sb_list); |
1284 | spin_unlock(&sb_inode_list_lock); | 1281 | spin_unlock(&sb_inode_list_lock); |
@@ -1327,8 +1324,6 @@ int generic_detach_inode(struct inode *inode) | |||
1327 | { | 1324 | { |
1328 | struct super_block *sb = inode->i_sb; | 1325 | struct super_block *sb = inode->i_sb; |
1329 | 1326 | ||
1330 | spin_lock(&sb_inode_list_lock); | ||
1331 | spin_lock(&inode->i_lock); | ||
1332 | if (!hlist_unhashed(&inode->i_hash)) { | 1327 | if (!hlist_unhashed(&inode->i_hash)) { |
1333 | if (!(inode->i_state & (I_DIRTY|I_SYNC))) | 1328 | if (!(inode->i_state & (I_DIRTY|I_SYNC))) |
1334 | list_move(&inode->i_list, &inode_unused); | 1329 | list_move(&inode->i_list, &inode_unused); |
@@ -1427,8 +1422,24 @@ void iput(struct inode *inode) | |||
1427 | if (inode) { | 1422 | if (inode) { |
1428 | BUG_ON(inode->i_state == I_CLEAR); | 1423 | BUG_ON(inode->i_state == I_CLEAR); |
1429 | 1424 | ||
1430 | if (atomic_dec_and_lock(&inode->i_count, &inode_lock)) | 1425 | retry: |
1426 | spin_lock(&inode->i_lock); | ||
1427 | if (inode->i_count == 1) { | ||
1428 | if (!spin_trylock(&inode_lock)) { | ||
1429 | spin_unlock(&inode->i_lock); | ||
1430 | goto retry; | ||
1431 | } | ||
1432 | if (!spin_trylock(&sb_inode_list_lock)) { | ||
1433 | spin_unlock(&inode_lock); | ||
1434 | spin_unlock(&inode->i_lock); | ||
1435 | goto retry; | ||
1436 | } | ||
1437 | inode->i_count--; | ||
1431 | iput_final(inode); | 1438 | iput_final(inode); |
1439 | } else { | ||
1440 | inode->i_count--; | ||
1441 | spin_unlock(&inode->i_lock); | ||
1442 | } | ||
1432 | } | 1443 | } |
1433 | } | 1444 | } |
1434 | EXPORT_SYMBOL(iput); | 1445 | EXPORT_SYMBOL(iput); |