Commit a4ffdde6 authored by Al Viro's avatar Al Viro

simplify checks for I_CLEAR/I_FREEING

add I_CLEAR instead of replacing I_FREEING with it.  I_CLEAR is
equivalent to I_FREEING for almost all code looking at either;
it's there to keep track of having called clear_inode() exactly
once per inode lifetime, at some point after having set I_FREEING.
I_CLEAR and I_FREEING never get set at the same time with the
current code, so we can switch to setting i_flags to I_FREEING | I_CLEAR
instead of I_CLEAR without loss of information.  As the result of
such change, checks become simpler and the amount of code that needs
to know about I_CLEAR shrinks a lot.
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent b5fc510c
...@@ -3860,7 +3860,7 @@ static void inode_tree_add(struct inode *inode) ...@@ -3860,7 +3860,7 @@ static void inode_tree_add(struct inode *inode)
p = &parent->rb_right; p = &parent->rb_right;
else { else {
WARN_ON(!(entry->vfs_inode.i_state & WARN_ON(!(entry->vfs_inode.i_state &
(I_WILL_FREE | I_FREEING | I_CLEAR))); (I_WILL_FREE | I_FREEING)));
rb_erase(parent, &root->inode_tree); rb_erase(parent, &root->inode_tree);
RB_CLEAR_NODE(parent); RB_CLEAR_NODE(parent);
spin_unlock(&root->inode_lock); spin_unlock(&root->inode_lock);
......
...@@ -18,7 +18,7 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused) ...@@ -18,7 +18,7 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused)
spin_lock(&inode_lock); spin_lock(&inode_lock);
list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE|I_NEW)) if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW))
continue; continue;
if (inode->i_mapping->nrpages == 0) if (inode->i_mapping->nrpages == 0)
continue; continue;
......
...@@ -352,7 +352,7 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc) ...@@ -352,7 +352,7 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
spin_lock(&inode_lock); spin_lock(&inode_lock);
inode->i_state &= ~I_SYNC; inode->i_state &= ~I_SYNC;
if (!(inode->i_state & (I_FREEING | I_CLEAR))) { if (!(inode->i_state & I_FREEING)) {
if ((inode->i_state & I_DIRTY_PAGES) && wbc->for_kupdate) { if ((inode->i_state & I_DIRTY_PAGES) && wbc->for_kupdate) {
/* /*
* More pages get dirtied by a fast dirtier. * More pages get dirtied by a fast dirtier.
...@@ -499,7 +499,7 @@ static int writeback_sb_inodes(struct super_block *sb, struct bdi_writeback *wb, ...@@ -499,7 +499,7 @@ static int writeback_sb_inodes(struct super_block *sb, struct bdi_writeback *wb,
if (inode_dirtied_after(inode, wbc->wb_start)) if (inode_dirtied_after(inode, wbc->wb_start))
return 1; return 1;
BUG_ON(inode->i_state & (I_FREEING | I_CLEAR)); BUG_ON(inode->i_state & I_FREEING);
__iget(inode); __iget(inode);
pages_skipped = wbc->pages_skipped; pages_skipped = wbc->pages_skipped;
writeback_single_inode(inode, wbc); writeback_single_inode(inode, wbc);
...@@ -935,7 +935,7 @@ void __mark_inode_dirty(struct inode *inode, int flags) ...@@ -935,7 +935,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
if (hlist_unhashed(&inode->i_hash)) if (hlist_unhashed(&inode->i_hash))
goto out; goto out;
} }
if (inode->i_state & (I_FREEING|I_CLEAR)) if (inode->i_state & I_FREEING)
goto out; goto out;
/* /*
...@@ -1001,7 +1001,7 @@ static void wait_sb_inodes(struct super_block *sb) ...@@ -1001,7 +1001,7 @@ static void wait_sb_inodes(struct super_block *sb)
list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
struct address_space *mapping; struct address_space *mapping;
if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE|I_NEW)) if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW))
continue; continue;
mapping = inode->i_mapping; mapping = inode->i_mapping;
if (mapping->nrpages == 0) if (mapping->nrpages == 0)
......
...@@ -84,7 +84,7 @@ static int iget_skip_test(struct inode *inode, void *opaque) ...@@ -84,7 +84,7 @@ static int iget_skip_test(struct inode *inode, void *opaque)
struct gfs2_skip_data *data = opaque; struct gfs2_skip_data *data = opaque;
if (ip->i_no_addr == data->no_addr) { if (ip->i_no_addr == data->no_addr) {
if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)){ if (inode->i_state & (I_FREEING|I_WILL_FREE)){
data->skipped = 1; data->skipped = 1;
return 0; return 0;
} }
......
...@@ -317,7 +317,7 @@ void clear_inode(struct inode *inode) ...@@ -317,7 +317,7 @@ void clear_inode(struct inode *inode)
bd_forget(inode); bd_forget(inode);
if (S_ISCHR(inode->i_mode) && inode->i_cdev) if (S_ISCHR(inode->i_mode) && inode->i_cdev)
cd_forget(inode); cd_forget(inode);
inode->i_state = I_CLEAR; inode->i_state = I_FREEING | I_CLEAR;
} }
EXPORT_SYMBOL(clear_inode); EXPORT_SYMBOL(clear_inode);
...@@ -553,7 +553,7 @@ static struct inode *find_inode(struct super_block *sb, ...@@ -553,7 +553,7 @@ static struct inode *find_inode(struct super_block *sb,
continue; continue;
if (!test(inode, data)) if (!test(inode, data))
continue; continue;
if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) { if (inode->i_state & (I_FREEING|I_WILL_FREE)) {
__wait_on_freeing_inode(inode); __wait_on_freeing_inode(inode);
goto repeat; goto repeat;
} }
...@@ -578,7 +578,7 @@ static struct inode *find_inode_fast(struct super_block *sb, ...@@ -578,7 +578,7 @@ static struct inode *find_inode_fast(struct super_block *sb,
continue; continue;
if (inode->i_sb != sb) if (inode->i_sb != sb)
continue; continue;
if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) { if (inode->i_state & (I_FREEING|I_WILL_FREE)) {
__wait_on_freeing_inode(inode); __wait_on_freeing_inode(inode);
goto repeat; goto repeat;
} }
...@@ -840,7 +840,7 @@ EXPORT_SYMBOL(iunique); ...@@ -840,7 +840,7 @@ EXPORT_SYMBOL(iunique);
struct inode *igrab(struct inode *inode) struct inode *igrab(struct inode *inode)
{ {
spin_lock(&inode_lock); spin_lock(&inode_lock);
if (!(inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE))) if (!(inode->i_state & (I_FREEING|I_WILL_FREE)))
__iget(inode); __iget(inode);
else else
/* /*
...@@ -1089,7 +1089,7 @@ int insert_inode_locked(struct inode *inode) ...@@ -1089,7 +1089,7 @@ int insert_inode_locked(struct inode *inode)
continue; continue;
if (old->i_sb != sb) if (old->i_sb != sb)
continue; continue;
if (old->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) if (old->i_state & (I_FREEING|I_WILL_FREE))
continue; continue;
break; break;
} }
...@@ -1128,7 +1128,7 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval, ...@@ -1128,7 +1128,7 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval,
continue; continue;
if (!test(old, data)) if (!test(old, data))
continue; continue;
if (old->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) if (old->i_state & (I_FREEING|I_WILL_FREE))
continue; continue;
break; break;
} }
...@@ -1218,7 +1218,7 @@ void generic_delete_inode(struct inode *inode) ...@@ -1218,7 +1218,7 @@ void generic_delete_inode(struct inode *inode)
hlist_del_init(&inode->i_hash); hlist_del_init(&inode->i_hash);
spin_unlock(&inode_lock); spin_unlock(&inode_lock);
wake_up_inode(inode); wake_up_inode(inode);
BUG_ON(inode->i_state != I_CLEAR); BUG_ON(inode->i_state != (I_FREEING | I_CLEAR));
destroy_inode(inode); destroy_inode(inode);
} }
EXPORT_SYMBOL(generic_delete_inode); EXPORT_SYMBOL(generic_delete_inode);
...@@ -1322,7 +1322,7 @@ static inline void iput_final(struct inode *inode) ...@@ -1322,7 +1322,7 @@ static inline void iput_final(struct inode *inode)
void iput(struct inode *inode) void iput(struct inode *inode)
{ {
if (inode) { if (inode) {
BUG_ON(inode->i_state == I_CLEAR); BUG_ON(inode->i_state & I_CLEAR);
if (atomic_dec_and_lock(&inode->i_count, &inode_lock)) if (atomic_dec_and_lock(&inode->i_count, &inode_lock))
iput_final(inode); iput_final(inode);
......
...@@ -78,7 +78,7 @@ void nilfs_clear_gcdat_inode(struct the_nilfs *nilfs) ...@@ -78,7 +78,7 @@ void nilfs_clear_gcdat_inode(struct the_nilfs *nilfs)
struct inode *gcdat = nilfs->ns_gc_dat; struct inode *gcdat = nilfs->ns_gc_dat;
struct nilfs_inode_info *gii = NILFS_I(gcdat); struct nilfs_inode_info *gii = NILFS_I(gcdat);
gcdat->i_state = I_CLEAR; gcdat->i_state = I_FREEING | I_CLEAR;
gii->i_flags = 0; gii->i_flags = 0;
nilfs_palloc_clear_cache(gcdat); nilfs_palloc_clear_cache(gcdat);
......
...@@ -369,11 +369,11 @@ void fsnotify_unmount_inodes(struct list_head *list) ...@@ -369,11 +369,11 @@ void fsnotify_unmount_inodes(struct list_head *list)
struct inode *need_iput_tmp; struct inode *need_iput_tmp;
/* /*
* We cannot __iget() an inode in state I_CLEAR, I_FREEING, * We cannot __iget() an inode in state I_FREEING,
* I_WILL_FREE, or I_NEW which is fine because by that point * I_WILL_FREE, or I_NEW which is fine because by that point
* the inode cannot have any associated watches. * the inode cannot have any associated watches.
*/ */
if (inode->i_state & (I_CLEAR|I_FREEING|I_WILL_FREE|I_NEW)) if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW))
continue; continue;
/* /*
...@@ -397,7 +397,7 @@ void fsnotify_unmount_inodes(struct list_head *list) ...@@ -397,7 +397,7 @@ void fsnotify_unmount_inodes(struct list_head *list)
/* In case the dropping of a reference would nuke next_i. */ /* In case the dropping of a reference would nuke next_i. */
if ((&next_i->i_sb_list != list) && if ((&next_i->i_sb_list != list) &&
atomic_read(&next_i->i_count) && atomic_read(&next_i->i_count) &&
!(next_i->i_state & (I_CLEAR | I_FREEING | I_WILL_FREE))) { !(next_i->i_state & (I_FREEING | I_WILL_FREE))) {
__iget(next_i); __iget(next_i);
need_iput = next_i; need_iput = next_i;
} }
......
...@@ -377,11 +377,11 @@ void inotify_unmount_inodes(struct list_head *list) ...@@ -377,11 +377,11 @@ void inotify_unmount_inodes(struct list_head *list)
struct list_head *watches; struct list_head *watches;
/* /*
* We cannot __iget() an inode in state I_CLEAR, I_FREEING, * We cannot __iget() an inode in state I_FREEING,
* I_WILL_FREE, or I_NEW which is fine because by that point * I_WILL_FREE, or I_NEW which is fine because by that point
* the inode cannot have any associated watches. * the inode cannot have any associated watches.
*/ */
if (inode->i_state & (I_CLEAR|I_FREEING|I_WILL_FREE|I_NEW)) if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW))
continue; continue;
/* /*
...@@ -403,8 +403,7 @@ void inotify_unmount_inodes(struct list_head *list) ...@@ -403,8 +403,7 @@ void inotify_unmount_inodes(struct list_head *list)
/* In case the dropping of a reference would nuke next_i. */ /* In case the dropping of a reference would nuke next_i. */
if ((&next_i->i_sb_list != list) && if ((&next_i->i_sb_list != list) &&
atomic_read(&next_i->i_count) && atomic_read(&next_i->i_count) &&
!(next_i->i_state & (I_CLEAR | I_FREEING | !(next_i->i_state & (I_FREEING|I_WILL_FREE))) {
I_WILL_FREE))) {
__iget(next_i); __iget(next_i);
need_iput = next_i; need_iput = next_i;
} }
......
...@@ -885,7 +885,7 @@ static void add_dquot_ref(struct super_block *sb, int type) ...@@ -885,7 +885,7 @@ static void add_dquot_ref(struct super_block *sb, int type)
spin_lock(&inode_lock); spin_lock(&inode_lock);
list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE|I_NEW)) if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW))
continue; continue;
#ifdef CONFIG_QUOTA_DEBUG #ifdef CONFIG_QUOTA_DEBUG
if (unlikely(inode_get_rsv_space(inode) > 0)) if (unlikely(inode_get_rsv_space(inode) > 0))
......
...@@ -80,7 +80,7 @@ xfs_mark_inode_dirty_sync( ...@@ -80,7 +80,7 @@ xfs_mark_inode_dirty_sync(
{ {
struct inode *inode = VFS_I(ip); struct inode *inode = VFS_I(ip);
if (!(inode->i_state & (I_WILL_FREE|I_FREEING|I_CLEAR))) if (!(inode->i_state & (I_WILL_FREE|I_FREEING)))
mark_inode_dirty_sync(inode); mark_inode_dirty_sync(inode);
} }
...@@ -90,7 +90,7 @@ xfs_mark_inode_dirty( ...@@ -90,7 +90,7 @@ xfs_mark_inode_dirty(
{ {
struct inode *inode = VFS_I(ip); struct inode *inode = VFS_I(ip);
if (!(inode->i_state & (I_WILL_FREE|I_FREEING|I_CLEAR))) if (!(inode->i_state & (I_WILL_FREE|I_FREEING)))
mark_inode_dirty(inode); mark_inode_dirty(inode);
} }
......
...@@ -1616,8 +1616,8 @@ struct super_operations { ...@@ -1616,8 +1616,8 @@ struct super_operations {
* I_FREEING Set when inode is about to be freed but still has dirty * I_FREEING Set when inode is about to be freed but still has dirty
* pages or buffers attached or the inode itself is still * pages or buffers attached or the inode itself is still
* dirty. * dirty.
* I_CLEAR Set by clear_inode(). In this state the inode is clean * I_CLEAR Added by clear_inode(). In this state the inode is clean
* and can be destroyed. * and can be destroyed. Inode keeps I_FREEING.
* *
* Inodes that are I_WILL_FREE, I_FREEING or I_CLEAR are * Inodes that are I_WILL_FREE, I_FREEING or I_CLEAR are
* prohibited for many purposes. iget() must wait for * prohibited for many purposes. iget() must wait for
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment