mirror of https://gitee.com/openkylin/linux.git
Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs fixes from Al Viro: "Eric's s_inodes softlockup fixes + Jan's fix for recent regression from pipe rework" * 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: fs: call fsnotify_sb_delete after evict_inodes fs: avoid softlockups in s_inodes iterators pipe: Fix bogus dereference in iov_iter_alignment()
This commit is contained in:
commit
9efa3ed504
|
@ -35,11 +35,11 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused)
|
|||
spin_unlock(&inode->i_lock);
|
||||
spin_unlock(&sb->s_inode_list_lock);
|
||||
|
||||
cond_resched();
|
||||
invalidate_mapping_pages(inode->i_mapping, 0, -1);
|
||||
iput(toput_inode);
|
||||
toput_inode = inode;
|
||||
|
||||
cond_resched();
|
||||
spin_lock(&sb->s_inode_list_lock);
|
||||
}
|
||||
spin_unlock(&sb->s_inode_list_lock);
|
||||
|
|
|
@ -676,6 +676,7 @@ int invalidate_inodes(struct super_block *sb, bool kill_dirty)
|
|||
struct inode *inode, *next;
|
||||
LIST_HEAD(dispose);
|
||||
|
||||
again:
|
||||
spin_lock(&sb->s_inode_list_lock);
|
||||
list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) {
|
||||
spin_lock(&inode->i_lock);
|
||||
|
@ -698,6 +699,12 @@ int invalidate_inodes(struct super_block *sb, bool kill_dirty)
|
|||
inode_lru_list_del(inode);
|
||||
spin_unlock(&inode->i_lock);
|
||||
list_add(&inode->i_lru, &dispose);
|
||||
if (need_resched()) {
|
||||
spin_unlock(&sb->s_inode_list_lock);
|
||||
cond_resched();
|
||||
dispose_list(&dispose);
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
spin_unlock(&sb->s_inode_list_lock);
|
||||
|
||||
|
|
|
@ -57,6 +57,9 @@ static void fsnotify_unmount_inodes(struct super_block *sb)
|
|||
* doing an __iget/iput with SB_ACTIVE clear would actually
|
||||
* evict all inodes with zero i_count from icache which is
|
||||
* unnecessarily violent and may in fact be illegal to do.
|
||||
* However, we should have been called /after/ evict_inodes
|
||||
* removed all zero refcount inodes, in any case. Test to
|
||||
* be sure.
|
||||
*/
|
||||
if (!atomic_read(&inode->i_count)) {
|
||||
spin_unlock(&inode->i_lock);
|
||||
|
@ -77,6 +80,7 @@ static void fsnotify_unmount_inodes(struct super_block *sb)
|
|||
|
||||
iput_inode = inode;
|
||||
|
||||
cond_resched();
|
||||
spin_lock(&sb->s_inode_list_lock);
|
||||
}
|
||||
spin_unlock(&sb->s_inode_list_lock);
|
||||
|
|
|
@ -984,6 +984,7 @@ static int add_dquot_ref(struct super_block *sb, int type)
|
|||
* later.
|
||||
*/
|
||||
old_inode = inode;
|
||||
cond_resched();
|
||||
spin_lock(&sb->s_inode_list_lock);
|
||||
}
|
||||
spin_unlock(&sb->s_inode_list_lock);
|
||||
|
|
|
@ -448,10 +448,12 @@ void generic_shutdown_super(struct super_block *sb)
|
|||
sync_filesystem(sb);
|
||||
sb->s_flags &= ~SB_ACTIVE;
|
||||
|
||||
fsnotify_sb_delete(sb);
|
||||
cgroup_writeback_umount();
|
||||
|
||||
/* evict all inodes with zero refcount */
|
||||
evict_inodes(sb);
|
||||
/* only nonzero refcount inodes can have marks */
|
||||
fsnotify_sb_delete(sb);
|
||||
|
||||
if (sb->s_dio_done_wq) {
|
||||
destroy_workqueue(sb->s_dio_done_wq);
|
||||
|
|
|
@ -1222,11 +1222,12 @@ EXPORT_SYMBOL(iov_iter_discard);
|
|||
|
||||
unsigned long iov_iter_alignment(const struct iov_iter *i)
|
||||
{
|
||||
unsigned int p_mask = i->pipe->ring_size - 1;
|
||||
unsigned long res = 0;
|
||||
size_t size = i->count;
|
||||
|
||||
if (unlikely(iov_iter_is_pipe(i))) {
|
||||
unsigned int p_mask = i->pipe->ring_size - 1;
|
||||
|
||||
if (size && i->iov_offset && allocated(&i->pipe->bufs[i->head & p_mask]))
|
||||
return size | i->iov_offset;
|
||||
return size;
|
||||
|
|
Loading…
Reference in New Issue