[Devel] [PATCH rh7] ploop: Introduce PLOOP_IOC_FITRIM

Kirill Tkhai ktkhai at virtuozzo.com
Fri Feb 21 17:39:09 MSK 2020


Konstantin, could you please review?

On 21.02.2020 17:38, Kirill Tkhai wrote:
> Similar to PLOOP_IOC_FREEZE, which freezes bdev and underlining fs,
> this introduces ioctl() discarding unused blocks.
> 
> Usually, we need mount point to send FITRIM request, but in case of
> secondary ploop we do not know mnt ns, where corresponding mount
> is connected. Thus, we introduce such the ioctl.
> 
> Note, we introduce ext4_fitrim() and fake inode to avoid dependency
> from ext4 module.
> 
> https://jira.sw.ru/browse/PSBM-101699
> 
> Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
> ---
>  drivers/block/ploop/dev.c      |   63 ++++++++++++++++++++++++++++++++++++++++
>  include/linux/ploop/ploop_if.h |    3 ++
>  2 files changed, 66 insertions(+)
> 
> diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c
> index 3f70f674e112..3ac783161558 100644
> --- a/drivers/block/ploop/dev.c
> +++ b/drivers/block/ploop/dev.c
> @@ -5211,6 +5211,66 @@ static int ploop_freeze(struct ploop_device *plo, struct block_device *bdev)
>  	return 0;
>  }
>  
> +/*
> + * This function could be implemented in fs/ext4/ioctl.c:
> + * simply extract code undex FITRIM case into a helper
> + * and use the helper here. But that would introduced a dependency
> + * between ploop module and ext4, that is not desired result.
> + * So, we introduce a crutch here...
> + */
> +static int ext4_fitrim(struct super_block *sb, unsigned long arg)
> +{
> +	struct inode *inode = sb->s_root->d_inode;
> +	struct file *file;
> +	int ret;
> +
> +	file = kzalloc(sizeof(*file), GFP_KERNEL);
> +	if (!file)
> +		return -ENOMEM;
> +
> +	file->f_inode = inode;
> +	ret = inode->i_fop->unlocked_ioctl(file, FITRIM, arg);
> +
> +	kfree(file);
> +	return ret;
> +}
> +
> +static int ploop_fitrim(struct ploop_device *plo, struct block_device *bdev,
> +			unsigned long arg)
> +{
> +	struct super_block *sb;
> +	int ret = 0;
> +
> +	if (!test_bit(PLOOP_S_RUNNING, &plo->state))
> +		return -EINVAL;
> +
> +	if (plo->freeze_state != PLOOP_F_NORMAL)
> +		return -EBUSY;
> +
> +	if (plo->dm_crypt_bdev)
> +		bdev = plo->dm_crypt_bdev;
> +
> +	bdgrab(bdev);
> +	/* Note, that in case of success sb->s_root is not NULL */
> +	sb = get_super(bdev);
> +	if (!sb) {
> +		ret = -ENODEV;
> +		goto bdput;
> +	}
> +
> +	if (sb->s_magic != EXT4_SUPER_MAGIC) {
> +		ret = -EPROTO;
> +		goto put_super;
> +	}
> +
> +	ret = ext4_fitrim(sb, arg);
> +put_super:
> +	drop_super(sb);
> +bdput:
> +	bdput(bdev);
> +	return ret;
> +}
> +
>  static int ploop_thaw(struct ploop_device *plo)
>  {
>  	struct block_device *bdev = plo->frozen_bdev;
> @@ -5360,6 +5420,9 @@ static int ploop_ioctl(struct block_device *bdev, fmode_t fmode, unsigned int cm
>  	case PLOOP_IOC_FREEZE:
>  		err = ploop_freeze(plo, bdev);
>  		break;
> +	case PLOOP_IOC_FITRIM:
> +		err = ploop_fitrim(plo, bdev, arg);
> +		break;
>  	case PLOOP_IOC_THAW:
>  		err = ploop_thaw(plo);
>  		break;
> diff --git a/include/linux/ploop/ploop_if.h b/include/linux/ploop/ploop_if.h
> index 852e04d50eb9..42fe28bba685 100644
> --- a/include/linux/ploop/ploop_if.h
> +++ b/include/linux/ploop/ploop_if.h
> @@ -367,6 +367,9 @@ struct ploop_track_extent
>  /* Unfreeze FS mounted over ploop */
>  #define PLOOP_IOC_THAW		_IO(PLOOPCTLTYPE, 33)
>  
> +/* Trim EXT4 FS mounted over ploop */
> +#define PLOOP_IOC_FITRIM	_IO(PLOOPCTLTYPE, 34)
> +
>  /* Events exposed via /sys/block/ploopN/pstate/event */
>  #define PLOOP_EVENT_ABORTED	1
>  #define PLOOP_EVENT_STOPPED	2
> 
> 



More information about the Devel mailing list