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: 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>

+5 -3
+2
fs/super.c
··· 71 #else 72 INIT_LIST_HEAD(&s->s_files); 73 #endif 74 INIT_LIST_HEAD(&s->s_instances); 75 INIT_HLIST_BL_HEAD(&s->s_anon); 76 INIT_LIST_HEAD(&s->s_inodes); ··· 1004 } 1005 BUG_ON(!mnt->mnt_sb); 1006 WARN_ON(!mnt->mnt_sb->s_bdi); 1007 mnt->mnt_sb->s_flags |= MS_BORN; 1008 1009 error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata);
··· 71 #else 72 INIT_LIST_HEAD(&s->s_files); 73 #endif 74 + s->s_bdi = &default_backing_dev_info; 75 INIT_LIST_HEAD(&s->s_instances); 76 INIT_HLIST_BL_HEAD(&s->s_anon); 77 INIT_LIST_HEAD(&s->s_inodes); ··· 1003 } 1004 BUG_ON(!mnt->mnt_sb); 1005 WARN_ON(!mnt->mnt_sb->s_bdi); 1006 + WARN_ON(mnt->mnt_sb->s_bdi == &default_backing_dev_info); 1007 mnt->mnt_sb->s_flags |= MS_BORN; 1008 1009 error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata);
+2 -2
fs/sync.c
··· 33 * This should be safe, as we require bdi backing to actually 34 * write out data in the first place 35 */ 36 - if (!sb->s_bdi || sb->s_bdi == &noop_backing_dev_info) 37 return 0; 38 39 if (sb->s_qcop && sb->s_qcop->quota_sync) ··· 79 80 static void sync_one_sb(struct super_block *sb, void *arg) 81 { 82 - if (!(sb->s_flags & MS_RDONLY) && sb->s_bdi) 83 __sync_filesystem(sb, *(int *)arg); 84 } 85 /*
··· 33 * This should be safe, as we require bdi backing to actually 34 * write out data in the first place 35 */ 36 + if (sb->s_bdi == &noop_backing_dev_info) 37 return 0; 38 39 if (sb->s_qcop && sb->s_qcop->quota_sync) ··· 79 80 static void sync_one_sb(struct super_block *sb, void *arg) 81 { 82 + if (!(sb->s_flags & MS_RDONLY)) 83 __sync_filesystem(sb, *(int *)arg); 84 } 85 /*
+1 -1
mm/backing-dev.c
··· 598 spin_lock(&sb_lock); 599 list_for_each_entry(sb, &super_blocks, s_list) { 600 if (sb->s_bdi == bdi) 601 - sb->s_bdi = NULL; 602 } 603 spin_unlock(&sb_lock); 604 }
··· 598 spin_lock(&sb_lock); 599 list_for_each_entry(sb, &super_blocks, s_list) { 600 if (sb->s_bdi == bdi) 601 + sb->s_bdi = &default_backing_dev_info; 602 } 603 spin_unlock(&sb_lock); 604 }