提交 95f28604 编写于 作者: J Jens Axboe

fs: assign sb->s_bdi to default_backing_dev_info if the bdi is going away

We don't have proper reference counting for this yet, so we run into
cases where the device is pulled and we OOPS on flushing the fs data.
This happens even though the dirty inodes have already been
migrated to the default_backing_dev_info.
Reported-by: NTorsten Hilbrich <torsten.hilbrich@secunet.com>
Tested-by: NTorsten Hilbrich <torsten.hilbrich@secunet.com>
Cc: stable@kernel.org
Signed-off-by: NJens Axboe <jaxboe@fusionio.com>
上级 a91a2785
...@@ -71,6 +71,7 @@ static struct super_block *alloc_super(struct file_system_type *type) ...@@ -71,6 +71,7 @@ static struct super_block *alloc_super(struct file_system_type *type)
#else #else
INIT_LIST_HEAD(&s->s_files); INIT_LIST_HEAD(&s->s_files);
#endif #endif
s->s_bdi = &default_backing_dev_info;
INIT_LIST_HEAD(&s->s_instances); INIT_LIST_HEAD(&s->s_instances);
INIT_HLIST_BL_HEAD(&s->s_anon); INIT_HLIST_BL_HEAD(&s->s_anon);
INIT_LIST_HEAD(&s->s_inodes); INIT_LIST_HEAD(&s->s_inodes);
...@@ -1003,6 +1004,7 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void ...@@ -1003,6 +1004,7 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
} }
BUG_ON(!mnt->mnt_sb); BUG_ON(!mnt->mnt_sb);
WARN_ON(!mnt->mnt_sb->s_bdi); WARN_ON(!mnt->mnt_sb->s_bdi);
WARN_ON(mnt->mnt_sb->s_bdi == &default_backing_dev_info);
mnt->mnt_sb->s_flags |= MS_BORN; mnt->mnt_sb->s_flags |= MS_BORN;
error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata); error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata);
......
...@@ -33,7 +33,7 @@ static int __sync_filesystem(struct super_block *sb, int wait) ...@@ -33,7 +33,7 @@ static int __sync_filesystem(struct super_block *sb, int wait)
* This should be safe, as we require bdi backing to actually * This should be safe, as we require bdi backing to actually
* write out data in the first place * write out data in the first place
*/ */
if (!sb->s_bdi || sb->s_bdi == &noop_backing_dev_info) if (sb->s_bdi == &noop_backing_dev_info)
return 0; return 0;
if (sb->s_qcop && sb->s_qcop->quota_sync) if (sb->s_qcop && sb->s_qcop->quota_sync)
...@@ -79,7 +79,7 @@ EXPORT_SYMBOL_GPL(sync_filesystem); ...@@ -79,7 +79,7 @@ EXPORT_SYMBOL_GPL(sync_filesystem);
static void sync_one_sb(struct super_block *sb, void *arg) static void sync_one_sb(struct super_block *sb, void *arg)
{ {
if (!(sb->s_flags & MS_RDONLY) && sb->s_bdi) if (!(sb->s_flags & MS_RDONLY))
__sync_filesystem(sb, *(int *)arg); __sync_filesystem(sb, *(int *)arg);
} }
/* /*
......
...@@ -598,7 +598,7 @@ static void bdi_prune_sb(struct backing_dev_info *bdi) ...@@ -598,7 +598,7 @@ static void bdi_prune_sb(struct backing_dev_info *bdi)
spin_lock(&sb_lock); spin_lock(&sb_lock);
list_for_each_entry(sb, &super_blocks, s_list) { list_for_each_entry(sb, &super_blocks, s_list) {
if (sb->s_bdi == bdi) if (sb->s_bdi == bdi)
sb->s_bdi = NULL; sb->s_bdi = &default_backing_dev_info;
} }
spin_unlock(&sb_lock); spin_unlock(&sb_lock);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册