On Thu, Apr 14, 2016 at 02:59:23PM +0800, Anand Jain wrote: > > > Hi Yauhen > > On 04/14/2016 09:15 AM, Yauhen Kharuzhy wrote: > >fs_info->sb->s_bdev field isn't set to any value at mount time > > There were patch to do set it at the vfs layer, or something like that. > > >but is set > >after device replacing or at device closing. > > Actually we are updating s_bdev/latest_bdev wrongly at most of > the device related operations, and not just here. I had plans > of wrapping all those into a common helper function and separate > from this patch set, when time permits, I am ok if you are fixing > all those. > > Thanks, Anand
Yes, I can but I need to know expected behaviour. Should we set a s_bdev field (as proposed in my patch) or we can keep it NULL because btrfs has its own sync implementation and non-NULL value has no sense with multi-device FS? Actually s_bdev is changed in two locations only: after device replace and at device closing. At device replace we always (I hope...) may suppose that target device's bdev is valid, so we need to change behaviour of device_force_close() only. But I still didn't check latest_bdev exactly meaning. In any case, I will try to help to make global spare code stable first. > > > >Existing code of > >device_force_close() checks if current s_bdev is not equal to closing > >bdev and, if equal, replace it by bdev field of first btrfs_device from > >device list. This device may be the same as closed, and s_bdev field will > >be invalid. > > > >If s_bdev is not NULL but references an freed block device, kernel > >oopses at filesystem sync time on unmount. > > > >For multi-device FS setting of this field may be senseless, but using of > >it should be consistent over the all btrfs code. So, set it on mount > >time and select valid device at device closing time. > > > >Alternative solution may be to not set s_bdev entirely. > > > >Signed-off-by: Yauhen Kharuzhy <yauhen.kharu...@zavadatar.com> > >--- > > fs/btrfs/super.c | 1 + > > fs/btrfs/volumes.c | 16 ++++++++++++---- > > 2 files changed, 13 insertions(+), 4 deletions(-) > > > >diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c > >index 3dd154e..1a2c58f 100644 > >--- a/fs/btrfs/super.c > >+++ b/fs/btrfs/super.c > >@@ -1522,6 +1522,7 @@ static struct dentry *btrfs_mount(struct > >file_system_type *fs_type, int flags, > > char b[BDEVNAME_SIZE]; > > > > strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); > >+ s->s_bdev = bdev; > > btrfs_sb(s)->bdev_holder = fs_type; > > error = btrfs_fill_super(s, fs_devices, data, > > flags & MS_SILENT ? 1 : 0); > >diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c > >index 08ab116..f14f3f2 100644 > >--- a/fs/btrfs/volumes.c > >+++ b/fs/btrfs/volumes.c > >@@ -7132,6 +7132,7 @@ void device_force_close(struct btrfs_device *device) > > { > > struct btrfs_device *next_device; > > struct btrfs_fs_devices *fs_devices; > >+ int found = 0; > > > > fs_devices = device->fs_devices; > > > >@@ -7139,13 +7140,20 @@ void device_force_close(struct btrfs_device *device) > > mutex_lock(&fs_devices->fs_info->chunk_mutex); > > spin_lock(&fs_devices->fs_info->free_chunk_lock); > > > >- next_device = list_entry(fs_devices->devices.next, > >- struct btrfs_device, dev_list); > >+ list_for_each_entry(next_device, &fs_devices->devices, dev_list) { > >+ if (next_device->bdev && next_device->bdev != device->bdev) { > >+ found = 1; > >+ break; > >+ } > >+ } > >+ > > if (device->bdev == fs_devices->fs_info->sb->s_bdev) > >- fs_devices->fs_info->sb->s_bdev = next_device->bdev; > >+ fs_devices->fs_info->sb->s_bdev = > >+ found ? next_device->bdev : NULL; > > > > if (device->bdev == fs_devices->latest_bdev) > >- fs_devices->latest_bdev = next_device->bdev; > >+ fs_devices->latest_bdev = > >+ found ? next_device->bdev : NULL; > > > > if (device->bdev) > > fs_devices->open_devices--; > > > -- > To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Yauhen Kharuzhy -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html