mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-11-01 02:21:16 +00:00
fs: fix buffer invalidation in invalidate_list
We must not call invalidate_inode_buffers in invalidate_list unless the inode can be reclaimed. If we remove the buffer association of a busy inode fsync won't find the buffers anymore. As invalidate_inode_buffers is called from various others sources than umount this actually does matter in practice. While at it change the loop to a more natural form and remove the WARN_ON for I_NEW, wich we already tested a few lines above. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
4d4eb36679
commit
99a3891924
1 changed files with 7 additions and 9 deletions
16
fs/inode.c
16
fs/inode.c
|
@ -28,7 +28,6 @@
|
||||||
/*
|
/*
|
||||||
* This is needed for the following functions:
|
* This is needed for the following functions:
|
||||||
* - inode_has_buffers
|
* - inode_has_buffers
|
||||||
* - invalidate_inode_buffers
|
|
||||||
* - invalidate_bdev
|
* - invalidate_bdev
|
||||||
*
|
*
|
||||||
* FIXME: remove all knowledge of the buffer layer from this file
|
* FIXME: remove all knowledge of the buffer layer from this file
|
||||||
|
@ -503,16 +502,15 @@ static int invalidate_list(struct list_head *head, struct list_head *dispose)
|
||||||
inode = list_entry(tmp, struct inode, i_sb_list);
|
inode = list_entry(tmp, struct inode, i_sb_list);
|
||||||
if (inode->i_state & I_NEW)
|
if (inode->i_state & I_NEW)
|
||||||
continue;
|
continue;
|
||||||
invalidate_inode_buffers(inode);
|
if (atomic_read(&inode->i_count)) {
|
||||||
if (!atomic_read(&inode->i_count)) {
|
busy = 1;
|
||||||
list_move(&inode->i_list, dispose);
|
|
||||||
WARN_ON(inode->i_state & I_NEW);
|
|
||||||
inode->i_state |= I_FREEING;
|
|
||||||
if (!(inode->i_state & (I_DIRTY | I_SYNC)))
|
|
||||||
percpu_counter_dec(&nr_inodes_unused);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
busy = 1;
|
|
||||||
|
list_move(&inode->i_list, dispose);
|
||||||
|
inode->i_state |= I_FREEING;
|
||||||
|
if (!(inode->i_state & (I_DIRTY | I_SYNC)))
|
||||||
|
percpu_counter_dec(&nr_inodes_unused);
|
||||||
}
|
}
|
||||||
return busy;
|
return busy;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue