Re: [PATCH v4 5/6] btrfs: implement shutdown ioctl

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Jul 04, 2025 at 10:12:33AM +0930, Qu Wenruo wrote:
> The shutdown ioctl should follow the XFS one, which use magic number 'X',
> and ioctl number 125, with a u32 as flags.
> 
> For now btrfs don't distinguish DEFAULT and LOGFLUSH flags (just like
> f2fs), both will freeze the fs first (implies committing the current
> transaction), setting the SHUTDOWN flag and finally thaw the fs.
> 
> For NOLOGFLUSH flag, the freeze/thaw part is skipped thus the current
> transaction is aborted.
> 
> The new shutdown ioctl is hidden behind experimental features for more
> testing.
> 
> Signed-off-by: Qu Wenruo <wqu@xxxxxxxx>
> ---
>  fs/btrfs/ioctl.c           | 40 ++++++++++++++++++++++++++++++++++++++
>  include/uapi/linux/btrfs.h |  9 +++++++++
>  2 files changed, 49 insertions(+)
> 
> diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
> index 2f3b7be13bea..94eb7a8499db 100644
> --- a/fs/btrfs/ioctl.c
> +++ b/fs/btrfs/ioctl.c
> @@ -5194,6 +5194,36 @@ static int btrfs_ioctl_subvol_sync(struct btrfs_fs_info *fs_info, void __user *a
>  	return 0;
>  }
>  
> +#ifdef CONFIG_BTRFS_EXPERIMENTAL
> +static int btrfs_emergency_shutdown(struct btrfs_fs_info *fs_info, u32 flags)
> +{
> +	int ret = 0;
> +
> +	if (flags >= BTRFS_SHUTDOWN_FLAGS_LAST)
> +		return -EINVAL;
> +
> +	if (btrfs_is_shutdown(fs_info))
> +		return 0;
> +
> +	switch (flags) {
> +	case BTRFS_SHUTDOWN_FLAGS_LOGFLUSH:
> +	case BTRFS_SHUTDOWN_FLAGS_DEFAULT:
> +		ret = freeze_super(fs_info->sb, FREEZE_HOLDER_KERNEL, NULL);

Recently I've looked at scrub blocking filesystem freezing and it does
not work because it blocks on the semaphore taken in mnt_want_write,
also taken in freeze_super().

I have an idea for fix, basically pause scrub, undo mnt_want_write
and then call freeze_super. So we'll need that too for shutdown. Once
implemented the fixup would be to use btrfs_freeze_super callback here.

> +		if (ret)
> +			return ret;
> +		btrfs_force_shutdown(fs_info);
> +		ret = thaw_super(fs_info->sb, FREEZE_HOLDER_KERNEL, NULL);
> +		if (ret)
> +			return ret;
> +		break;
> +	case BTRFS_SHUTDOWN_FLAGS_NOLOGFLUSH:
> +		btrfs_force_shutdown(fs_info);
> +		break;
> +	}
> +	return ret;
> +}
> +#endif
> +
>  long btrfs_ioctl(struct file *file, unsigned int
>  		cmd, unsigned long arg)
>  {

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

In XFS it's

#define XFS_IOC_GOINGDOWN            _IOR ('X', 125, uint32_t)

It's right to use the same definition and ioctl value as this will
be a generic ioctl eventually, with 3 users at least. I like the name
SHUTDOWN better, ext4 also uses that.




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux