Add a new BLOCK_URING_CMD_ZONE_RESET_ALL uring cmd to reset all zones for a given block device. This can be used by storage systems or file system mkfs tools to initialize multiple devices in parallel.
Unified · Split
| @@ -14,6 +14,7 @@ · 13 unmodified lines | |||
| 14 | #include <linux/pagemap.h> | 14 | #include <linux/pagemap.h> |
| 15 | #include <linux/io_uring/cmd.h> | 15 | #include <linux/io_uring/cmd.h> |
| 16 | #include <linux/blk-integrity.h> | 16 | #include <linux/blk-integrity.h> |
| 17 | #include <trace/events/block.h> | ||
| 17 | #include <uapi/linux/blkdev.h> | 18 | #include <uapi/linux/blkdev.h> |
| 18 | #include "blk.h" | 19 | #include "blk.h" |
| 19 | #include "blk-crypto-internal.h" | 20 | #include "blk-crypto-internal.h" |
| @@ -943,6 +944,40 @@ static int blkdev_cmd_discard(struct io_uring_cmd *cmd) · 923 unmodified lines | |||
| 943 | return -EIOCBQUEUED; | 944 | return -EIOCBQUEUED; |
| 944 | } | 945 | } |
| 945 | 946 | ||
| 947 | static int blkdev_cmd_zone_reset_all(struct io_uring_cmd *cmd) | ||
| 948 | { | ||
| 949 | struct blk_iou_cmd *bic = io_uring_cmd_to_pdu(cmd, struct blk_iou_cmd); | ||
| 950 | struct block_device *bdev = I_BDEV(cmd->file->f_mapping->host); | ||
| 951 | struct bio *bio; | ||
| 952 | int err; | ||
| 953 | |||
| 954 | if (!(file_to_blk_mode(cmd->file) & BLK_OPEN_WRITE)) | ||
| 955 | return -EBADF; | ||
| 956 | if (bdev_read_only(bdev)) | ||
| 957 | return -EPERM; | ||
| 958 | if (!bdev_is_zoned(bdev)) | ||
| 959 | return -EOPNOTSUPP; | ||
| 960 | if (bic->start || bic->len) | ||
| 961 | return -EINVAL; | ||
| 962 | |||
| 963 | err = filemap_invalidate_pages(bdev->bd_mapping, 0, | ||
| 964 | bdev_nr_bytes(bdev) - 1, bic->nowait); | ||
| 965 | if (err) | ||
| 966 | return err; | ||
| 967 | |||
| 968 | bio = bio_alloc(bdev, 0, REQ_OP_ZONE_RESET_ALL, | ||
| 969 | bic->nowait ? GFP_NOWAIT : GFP_KERNEL); | ||
| 970 | if (!bio) | ||
| 971 | return -EAGAIN; | ||
| 972 | if (bic->nowait) | ||
| 973 | bio->bi_opf |= REQ_NOWAIT; | ||
| 974 | trace_blkdev_zone_mgmt(bio, 0); | ||
| 975 | bio->bi_private = cmd; | ||
| 976 | bio->bi_end_io = bio_cmd_bio_end_io; | ||
| 977 | submit_bio(bio); | ||
| 978 | return -EIOCBQUEUED; | ||
| 979 | } | ||
| 980 | |||
| 946 | int blkdev_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags) | 981 | int blkdev_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags) |
| 947 | { | 982 | { |
| 948 | struct blk_iou_cmd *bic = io_uring_cmd_to_pdu(cmd, struct blk_iou_cmd); | 983 | struct blk_iou_cmd *bic = io_uring_cmd_to_pdu(cmd, struct blk_iou_cmd); |
| @@ -966,6 +1001,8 @@ int blkdev_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags) · 17 unmodified lines | |||
| 966 | switch (cmd_op) { | 1001 | switch (cmd_op) { |
| 967 | case BLOCK_URING_CMD_DISCARD: | 1002 | case BLOCK_URING_CMD_DISCARD: |
| 968 | return blkdev_cmd_discard(cmd); | 1003 | return blkdev_cmd_discard(cmd); |
| 1004 | case BLOCK_URING_CMD_ZONE_RESET_ALL: | ||
| 1005 | return blkdev_cmd_zone_reset_all(cmd); | ||
| 969 | } | 1006 | } |
| 970 | return -EINVAL; | 1007 | return -EINVAL; |
| 971 | } | 1008 | } |
| @@ -10,5 +10,6 @@ · 9 unmodified lines | |||
| 10 | * It's a different number space from ioctl(), reuse the block's code 0x12. | 10 | * It's a different number space from ioctl(), reuse the block's code 0x12. |
| 11 | */ | 11 | */ |
| 12 | #define BLOCK_URING_CMD_DISCARD _IO(0x12, 0) | 12 | #define BLOCK_URING_CMD_DISCARD _IO(0x12, 0) |
| 13 | #define BLOCK_URING_CMD_ZONE_RESET_ALL _IO(0x12, 1) | ||
| 13 | 14 | ||
| 14 | #endif | 15 | #endif |