diff mbox series

[5/5] btrfs: add more zeroout modes to CLEAR_FREE ioctl

Message ID 207cb619230063cd62a5857dc1b98139e1f3a4d6.1740753608.git.dsterba@suse.com (mailing list archive)
State New
Headers show
Series Ioctl to clear unused space in various ways | expand

Commit Message

David Sterba Feb. 28, 2025, 2:49 p.m. UTC
The zeroing mode BTRFS_CLEAR_OP_ZERO is safe for use regardless of the
underlying device capabilities, either zeros are written or the device
will unmap the blocks. This a safe behaviour.

In case it's desired to do one or the another add modes that can enforce
that or fail when unsupported;

- CLEAR_OP_ZERO - overwrite by zero blocks, forbid unmapping blocks by
                  the device

- CLEAR_OP_ZERO_NOFALLBACK - unmap the blocks by device and do not fall
                             back to overwriting by zeros

Implemented by __blkdev_issue_zeroout() and also documented there.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 fs/btrfs/extent-tree.c     | 11 +++++++++--
 include/uapi/linux/btrfs.h |  5 +++++
 2 files changed, 14 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index e38760fbf324..779216aa8ce0 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -1259,10 +1259,17 @@  static int btrfs_issue_clear_op(struct block_device *bdev, u64 start, u64 size,
 	case BTRFS_CLEAR_OP_DISCARD:
 		return blkdev_issue_discard(bdev, start >> SECTOR_SHIFT,
 					    size >> SECTOR_SHIFT, GFP_NOFS);
+	case BTRFS_CLEAR_OP_ZERO_NOUNMAP:
+		flags |= BLKDEV_ZERO_NOUNMAP;
+		return blkdev_issue_zeroout(bdev, start >> SECTOR_SHIFT,
+					    size >> SECTOR_SHIFT, GFP_NOFS, flags);
+	case BTRFS_CLEAR_OP_ZERO_NOFALLBACK:
+		flags |= BLKDEV_ZERO_NOFALLBACK;
+		return blkdev_issue_zeroout(bdev, start >> SECTOR_SHIFT,
+					    size >> SECTOR_SHIFT, GFP_NOFS, flags);
 	case BTRFS_CLEAR_OP_ZERO:
 		return blkdev_issue_zeroout(bdev, start >> SECTOR_SHIFT,
-					    size >> SECTOR_SHIFT, GFP_NOFS,
-					    flags);
+					    size >> SECTOR_SHIFT, GFP_NOFS, flags);
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h
index 018f0f1bbd5f..12e54f3b0a13 100644
--- a/include/uapi/linux/btrfs.h
+++ b/include/uapi/linux/btrfs.h
@@ -1104,6 +1104,11 @@  enum btrfs_clear_op_type {
 	 * garbage collection must also be erased.
 	 */
 	BTRFS_CLEAR_OP_SECURE_ERASE,
+
+	/* Overwrite by zeros, do not try to unmap blocks. */
+	BTRFS_CLEAR_OP_ZERO_NOUNMAP,
+	/* Request unmapping the blocks and don't fall back to writing zeros. */
+	BTRFS_CLEAR_OP_ZERO_NOFALLBACK,
 	BTRFS_NR_CLEAR_OP_TYPES,
 };