On 18.11.2017 15:50, Anand Jain wrote: > > > On 11/16/2017 10:11 PM, Nikolay Borisov wrote: >> >> >> On 13.11.2017 07:44, Anand Jain wrote: >>> Support for a new command is being added here: >>> btrfs dev ignore <dev> >>> Which shall undo the effects of the command >>> btrfs dev scan <dev> >>> >>> This cli/ioctl is needed as there is no way to continue to mount in >>> degraded mode if the device is already scanned, which is required to >>> recover from the split brain raid conditions. >>> >>> This patch proposes to use ioctl #5 as it was empty. >>> IOW(BTRFS_IOCTL_MAGIC, 5, ..) >>> If #5 is reserved for some other purpose, I think I should change this. >>> >>> Signed-off-by: Anand Jain <anand.j...@oracle.com> >>> --- >>> fs/btrfs/super.c | 4 +++ >>> fs/btrfs/volumes.c | 70 >>> ++++++++++++++++++++++++++++++++++++++++++++++ >>> fs/btrfs/volumes.h | 2 ++ >>> include/uapi/linux/btrfs.h | 2 ++ >>> 4 files changed, 78 insertions(+) >>> >>> diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c >>> index fa7bad8b22da..64f4beb1526d 100644 >>> --- a/fs/btrfs/super.c >>> +++ b/fs/btrfs/super.c >>> @@ -2183,6 +2183,10 @@ static long btrfs_control_ioctl(struct file >>> *file, unsigned int cmd, >>> ret = btrfs_scan_one_device(vol->name, FMODE_READ, >>> &btrfs_fs_type, &fs_devices); >>> break; >>> + case BTRFS_IOC_IGNORE_DEV: >>> + ret = btrfs_ignore_one_device(vol->name, FMODE_READ, >>> + &btrfs_fs_type, &fs_devices); >>> + break; >>> case BTRFS_IOC_DEVICES_READY: >>> ret = btrfs_scan_one_device(vol->name, FMODE_READ, >>> &btrfs_fs_type, &fs_devices); >>> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c >>> index 8ead85dba6f5..1a06a17e111e 100644 >>> --- a/fs/btrfs/volumes.c >>> +++ b/fs/btrfs/volumes.c >>> @@ -1181,6 +1181,76 @@ int btrfs_read_disk_super(struct block_device >>> *bdev, u64 bytenr, >>> return 0; >>> } >>> +static int device_list_remove(struct btrfs_super_block >>> *disk_super, u64 devid) >>> +{ >>> + int ret = 0; >>> + struct btrfs_fs_devices *fs_devices; >>> + struct btrfs_device *device; >>> + >>> + fs_devices = find_fsid(disk_super->fsid); >>> + if (!fs_devices) >>> + return -ENOENT; >>> + >>> + if (fs_devices->opened) >>> + return -EPERM; >>> + >>> + mutex_lock(&uuid_mutex); >>> + mutex_lock(&fs_devices->device_list_mutex); >>> + device = find_device(fs_devices, devid, disk_super->dev_item.uuid); >>> + if (!device) { >>> + ret = -ENOENT; >>> + goto error; >>> + } >>> + >>> + delete_device_from_list(device); >>> + >>> +error: >>> + mutex_unlock(&fs_devices->device_list_mutex); >>> + mutex_unlock(&uuid_mutex); >>> + >>> + return ret; >>> +} >>> + >>> +int btrfs_ignore_one_device(const char *path, fmode_t flags, void >>> *holder, >>> + struct btrfs_fs_devices **fs_devices_ret) >>> +{ >>> + struct btrfs_super_block *disk_super; >>> + struct block_device *bdev; >>> + struct page *page; >>> + int ret = -EINVAL; >>> + u64 devid; >>> + u64 bytenr; >>> + >>> + bytenr = btrfs_sb_offset(0); >>> + flags |= FMODE_EXCL; >>> + >>> + bdev = blkdev_get_by_path(path, flags, holder); >>> + if (IS_ERR(bdev)) { >>> + ret = PTR_ERR(bdev); >>> + goto error; >>> + } >>> + >>> + if (btrfs_read_disk_super(bdev, bytenr, &page, &disk_super)) >>> + goto error_bdev_put; >>> + >>> + devid = btrfs_stack_device_id(&disk_super->dev_item); >>> + >>> + ret = device_list_remove(disk_super, devid); >>> + if (ret) >>> + pr_err("BTRFS: %pU: device %s uuid %pU devid %llu failed to >>> unscan: %d", >>> + disk_super->fsid, path, disk_super->dev_item.uuid, devid, ret); >>> + else >>> + pr_info("BTRFS: %pU: device %s uuid %pU devid %llu ran undo scan", >>> + disk_super->fsid, path, disk_super->dev_item.uuid, devid); >> >> There is already btrfs_err and btrfs_info, use those. This will allow to >> uniquely identify the failing btrfs file system > > We don't have fs_info in this context, btrfs_err/info can't be used.
Yes, but we have struct file in btrfs_control_ioctl then can't we do : struct btrfs_fs_info = btrfs_sb(file_inode(file)->i_sb) > >> also the pr_* statements >> need to be indented after the if/else. > > Will do. > > Thanks, Anand > >>> + >>> + btrfs_release_disk_super(page); >>> + >>> +error_bdev_put: >>> + blkdev_put(bdev, flags); >>> +error: >>> + return ret; >>> +} >>> + >>> /* >>> * Look for a btrfs signature on a device. This may be called out >>> of the mount path >>> * and we are not allowed to call set_blocksize during the scan. >>> The superblock >>> diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h >>> index 6108fdfec67f..340e40acdab5 100644 >>> --- a/fs/btrfs/volumes.h >>> +++ b/fs/btrfs/volumes.h >>> @@ -421,6 +421,8 @@ int btrfs_open_devices(struct btrfs_fs_devices >>> *fs_devices, >>> fmode_t flags, void *holder); >>> int btrfs_scan_one_device(const char *path, fmode_t flags, void >>> *holder, >>> struct btrfs_fs_devices **fs_devices_ret); >>> +int btrfs_ignore_one_device(const char *path, fmode_t flags, void >>> *holder, >>> + struct btrfs_fs_devices **fs_devices_ret); >>> int btrfs_close_devices(struct btrfs_fs_devices *fs_devices); >>> void btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices, >>> int step); >>> void btrfs_assign_next_active_device(struct btrfs_fs_info *fs_info, >>> diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h >>> index 378230c163d5..928485c31aa4 100644 >>> --- a/include/uapi/linux/btrfs.h >>> +++ b/include/uapi/linux/btrfs.h >>> @@ -739,6 +739,8 @@ enum btrfs_err_code { >>> struct btrfs_ioctl_vol_args) >>> #define BTRFS_IOC_SCAN_DEV _IOW(BTRFS_IOCTL_MAGIC, 4, \ >>> struct btrfs_ioctl_vol_args) >>> +#define BTRFS_IOC_IGNORE_DEV _IOW(BTRFS_IOCTL_MAGIC, 5, \ >>> + struct btrfs_ioctl_vol_args) >>> /* trans start and trans end are dangerous, and only for >>> * use by applications that know how to avoid the >>> * resulting deadlocks >>> >> -- >> 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 >> > -- 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