diff options
-rw-r--r-- | fs/inode.c | 16 | ||||
-rw-r--r-- | include/linux/fs.h | 1 |
2 files changed, 11 insertions, 6 deletions
diff --git a/fs/inode.c b/fs/inode.c index 801fe7f36280..1f9a3a2b89bc 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -500,7 +500,7 @@ repeat: | |||
500 | continue; | 500 | continue; |
501 | if (!test(inode, data)) | 501 | if (!test(inode, data)) |
502 | continue; | 502 | continue; |
503 | if (inode->i_state & (I_FREEING|I_CLEAR)) { | 503 | if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) { |
504 | __wait_on_freeing_inode(inode); | 504 | __wait_on_freeing_inode(inode); |
505 | goto repeat; | 505 | goto repeat; |
506 | } | 506 | } |
@@ -525,7 +525,7 @@ repeat: | |||
525 | continue; | 525 | continue; |
526 | if (inode->i_sb != sb) | 526 | if (inode->i_sb != sb) |
527 | continue; | 527 | continue; |
528 | if (inode->i_state & (I_FREEING|I_CLEAR)) { | 528 | if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) { |
529 | __wait_on_freeing_inode(inode); | 529 | __wait_on_freeing_inode(inode); |
530 | goto repeat; | 530 | goto repeat; |
531 | } | 531 | } |
@@ -727,7 +727,7 @@ EXPORT_SYMBOL(iunique); | |||
727 | struct inode *igrab(struct inode *inode) | 727 | struct inode *igrab(struct inode *inode) |
728 | { | 728 | { |
729 | spin_lock(&inode_lock); | 729 | spin_lock(&inode_lock); |
730 | if (!(inode->i_state & I_FREEING)) | 730 | if (!(inode->i_state & (I_FREEING|I_WILL_FREE))) |
731 | __iget(inode); | 731 | __iget(inode); |
732 | else | 732 | else |
733 | /* | 733 | /* |
@@ -1024,17 +1024,21 @@ static void generic_forget_inode(struct inode *inode) | |||
1024 | if (!(inode->i_state & (I_DIRTY|I_LOCK))) | 1024 | if (!(inode->i_state & (I_DIRTY|I_LOCK))) |
1025 | list_move(&inode->i_list, &inode_unused); | 1025 | list_move(&inode->i_list, &inode_unused); |
1026 | inodes_stat.nr_unused++; | 1026 | inodes_stat.nr_unused++; |
1027 | spin_unlock(&inode_lock); | 1027 | if (!sb || (sb->s_flags & MS_ACTIVE)) { |
1028 | if (!sb || (sb->s_flags & MS_ACTIVE)) | 1028 | spin_unlock(&inode_lock); |
1029 | return; | 1029 | return; |
1030 | } | ||
1031 | inode->i_state |= I_WILL_FREE; | ||
1032 | spin_unlock(&inode_lock); | ||
1030 | write_inode_now(inode, 1); | 1033 | write_inode_now(inode, 1); |
1031 | spin_lock(&inode_lock); | 1034 | spin_lock(&inode_lock); |
1035 | inode->i_state &= ~I_WILL_FREE; | ||
1032 | inodes_stat.nr_unused--; | 1036 | inodes_stat.nr_unused--; |
1033 | hlist_del_init(&inode->i_hash); | 1037 | hlist_del_init(&inode->i_hash); |
1034 | } | 1038 | } |
1035 | list_del_init(&inode->i_list); | 1039 | list_del_init(&inode->i_list); |
1036 | list_del_init(&inode->i_sb_list); | 1040 | list_del_init(&inode->i_sb_list); |
1037 | inode->i_state|=I_FREEING; | 1041 | inode->i_state |= I_FREEING; |
1038 | inodes_stat.nr_inodes--; | 1042 | inodes_stat.nr_inodes--; |
1039 | spin_unlock(&inode_lock); | 1043 | spin_unlock(&inode_lock); |
1040 | if (inode->i_data.nrpages) | 1044 | if (inode->i_data.nrpages) |
diff --git a/include/linux/fs.h b/include/linux/fs.h index e5a8db00df29..3622e952e98c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1025,6 +1025,7 @@ struct super_operations { | |||
1025 | #define I_FREEING 16 | 1025 | #define I_FREEING 16 |
1026 | #define I_CLEAR 32 | 1026 | #define I_CLEAR 32 |
1027 | #define I_NEW 64 | 1027 | #define I_NEW 64 |
1028 | #define I_WILL_FREE 128 | ||
1028 | 1029 | ||
1029 | #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES) | 1030 | #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES) |
1030 | 1031 | ||