Skip to content

Commit 9efa3ed

Browse files
committed
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()
2 parents c601747 + 1edc8eb commit 9efa3ed

File tree

6 files changed

+18
-3
lines changed

6 files changed

+18
-3
lines changed

fs/drop_caches.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused)
3535
spin_unlock(&inode->i_lock);
3636
spin_unlock(&sb->s_inode_list_lock);
3737

38-
cond_resched();
3938
invalidate_mapping_pages(inode->i_mapping, 0, -1);
4039
iput(toput_inode);
4140
toput_inode = inode;
4241

42+
cond_resched();
4343
spin_lock(&sb->s_inode_list_lock);
4444
}
4545
spin_unlock(&sb->s_inode_list_lock);

fs/inode.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,7 @@ int invalidate_inodes(struct super_block *sb, bool kill_dirty)
676676
struct inode *inode, *next;
677677
LIST_HEAD(dispose);
678678

679+
again:
679680
spin_lock(&sb->s_inode_list_lock);
680681
list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) {
681682
spin_lock(&inode->i_lock);
@@ -698,6 +699,12 @@ int invalidate_inodes(struct super_block *sb, bool kill_dirty)
698699
inode_lru_list_del(inode);
699700
spin_unlock(&inode->i_lock);
700701
list_add(&inode->i_lru, &dispose);
702+
if (need_resched()) {
703+
spin_unlock(&sb->s_inode_list_lock);
704+
cond_resched();
705+
dispose_list(&dispose);
706+
goto again;
707+
}
701708
}
702709
spin_unlock(&sb->s_inode_list_lock);
703710

fs/notify/fsnotify.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ static void fsnotify_unmount_inodes(struct super_block *sb)
5757
* doing an __iget/iput with SB_ACTIVE clear would actually
5858
* evict all inodes with zero i_count from icache which is
5959
* unnecessarily violent and may in fact be illegal to do.
60+
* However, we should have been called /after/ evict_inodes
61+
* removed all zero refcount inodes, in any case. Test to
62+
* be sure.
6063
*/
6164
if (!atomic_read(&inode->i_count)) {
6265
spin_unlock(&inode->i_lock);
@@ -77,6 +80,7 @@ static void fsnotify_unmount_inodes(struct super_block *sb)
7780

7881
iput_inode = inode;
7982

83+
cond_resched();
8084
spin_lock(&sb->s_inode_list_lock);
8185
}
8286
spin_unlock(&sb->s_inode_list_lock);

fs/quota/dquot.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,7 @@ static int add_dquot_ref(struct super_block *sb, int type)
984984
* later.
985985
*/
986986
old_inode = inode;
987+
cond_resched();
987988
spin_lock(&sb->s_inode_list_lock);
988989
}
989990
spin_unlock(&sb->s_inode_list_lock);

fs/super.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,10 +448,12 @@ void generic_shutdown_super(struct super_block *sb)
448448
sync_filesystem(sb);
449449
sb->s_flags &= ~SB_ACTIVE;
450450

451-
fsnotify_sb_delete(sb);
452451
cgroup_writeback_umount();
453452

453+
/* evict all inodes with zero refcount */
454454
evict_inodes(sb);
455+
/* only nonzero refcount inodes can have marks */
456+
fsnotify_sb_delete(sb);
455457

456458
if (sb->s_dio_done_wq) {
457459
destroy_workqueue(sb->s_dio_done_wq);

lib/iov_iter.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1222,11 +1222,12 @@ EXPORT_SYMBOL(iov_iter_discard);
12221222

12231223
unsigned long iov_iter_alignment(const struct iov_iter *i)
12241224
{
1225-
unsigned int p_mask = i->pipe->ring_size - 1;
12261225
unsigned long res = 0;
12271226
size_t size = i->count;
12281227

12291228
if (unlikely(iov_iter_is_pipe(i))) {
1229+
unsigned int p_mask = i->pipe->ring_size - 1;
1230+
12301231
if (size && i->iov_offset && allocated(&i->pipe->bufs[i->head & p_mask]))
12311232
return size | i->iov_offset;
12321233
return size;

0 commit comments

Comments
 (0)