The shutdown interface should all follow the XFS one, which use magic 'X', and ioctl number 125, with a u32 as flags. For now btrfs doesn't follow the flags, as there is no traditional journal in btrfs (the log tree is to mostly speed up fsync). Signed-off-by: Qu Wenruo <wqu@xxxxxxxx> --- fs/btrfs/ioctl.c | 18 ++++++++++++++++++ include/uapi/linux/btrfs.h | 9 +++++++++ 2 files changed, 27 insertions(+) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 84a516053a8e..1fd7486af851 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -5213,6 +5213,16 @@ static int btrfs_ioctl_subvol_sync(struct btrfs_fs_info *fs_info, void __user *a return 0; } +static int btrfs_emergency_shutdown(struct btrfs_fs_info *fs_info, u32 flags) +{ + if (flags >= BTRFS_SHUTDOWN_FLAGS_LAST) + return -EINVAL; + + /* For now, btrfs do not distinguish the different flags. */ + btrfs_shutdown(fs_info); + return 0; +} + long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -5368,6 +5378,14 @@ long btrfs_ioctl(struct file *file, unsigned int #endif case BTRFS_IOC_SUBVOL_SYNC_WAIT: return btrfs_ioctl_subvol_sync(fs_info, argp); + case BTRFS_IOC_SHUTDOWN: + u32 flags; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + if (get_user(flags, (__u32 __user *)arg)) + return -EFAULT; + return btrfs_emergency_shutdown(fs_info, flags); } return -ENOTTY; diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h index dd02160015b2..8f6324cf15d9 100644 --- a/include/uapi/linux/btrfs.h +++ b/include/uapi/linux/btrfs.h @@ -1096,6 +1096,12 @@ enum btrfs_err_code { BTRFS_ERROR_DEV_RAID1C4_MIN_NOT_MET, }; +/* Flags for IOC_SHUTDOWN, should match XFS' flags. */ +#define BTRFS_SHUTDOWN_FLAGS_DEFAULT 0x0 +#define BTRFS_SHUTDOWN_FLAGS_LOGFLUSH 0x1 +#define BTRFS_SHUTDOWN_FLAGS_NOLOGFLUSH 0x2 +#define BTRFS_SHUTDOWN_FLAGS_LAST 0x3 + #define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \ struct btrfs_ioctl_vol_args) #define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \ @@ -1217,6 +1223,9 @@ enum btrfs_err_code { #define BTRFS_IOC_SUBVOL_SYNC_WAIT _IOW(BTRFS_IOCTL_MAGIC, 65, \ struct btrfs_ioctl_subvol_wait) +/* Shutdown ioctl should follow XFS's interfaces, thus not using btrfs magic. */ +#define BTRFS_IOC_SHUTDOWN _IOR('X', 125, __u32) + #ifdef __cplusplus } #endif -- 2.49.0