Skip to content

Commit

Permalink
fs: assign sb->s_bdi to default_backing_dev_info if the bdi is going …
Browse files Browse the repository at this point in the history
…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: Torsten Hilbrich <torsten.hilbrich@secunet.com>
Tested-by: Torsten Hilbrich <torsten.hilbrich@secunet.com>
Cc: stable@kernel.org
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
  • Loading branch information
Jens Axboe committed Mar 17, 2011
1 parent a91a278 commit 95f2860
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 3 deletions.
2 changes: 2 additions & 0 deletions fs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ static struct super_block *alloc_super(struct file_system_type *type)
#else
INIT_LIST_HEAD(&s->s_files);
#endif
s->s_bdi = &default_backing_dev_info;
INIT_LIST_HEAD(&s->s_instances);
INIT_HLIST_BL_HEAD(&s->s_anon);
INIT_LIST_HEAD(&s->s_inodes);
Expand Down Expand Up @@ -1003,6 +1004,7 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
}
BUG_ON(!mnt->mnt_sb);
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;

error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata);
Expand Down
4 changes: 2 additions & 2 deletions fs/sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
* 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;

if (sb->s_qcop && sb->s_qcop->quota_sync)
Expand Down Expand Up @@ -79,7 +79,7 @@ EXPORT_SYMBOL_GPL(sync_filesystem);

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);
}
/*
Expand Down
2 changes: 1 addition & 1 deletion mm/backing-dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ static void bdi_prune_sb(struct backing_dev_info *bdi)
spin_lock(&sb_lock);
list_for_each_entry(sb, &super_blocks, s_list) {
if (sb->s_bdi == bdi)
sb->s_bdi = NULL;
sb->s_bdi = &default_backing_dev_info;
}
spin_unlock(&sb_lock);
}
Expand Down

0 comments on commit 95f2860

Please sign in to comment.