On Mon, Jun 6, 2016 at 10:39 AM, Shaun Tancheff <shaun@xxxxxxxxxxxx> wrote: > > T10 ZBC and T13 ZAC specify operations for Zoned devices. > > To be able to access the zone information and open and close zones > adding flags for the report zones command (REQ_REPORT_ZONES) and for > Open and Close zone (REQ_OPEN_ZONE and REQ_CLOSE_ZONE) can be added > for use by struct bio's bi_rw and by struct request's cmd_flags. > > To reduce the number of additional flags needed REQ_RESET_ZONE shares > the same flag as REQ_REPORT_ZONES and is differentiated by direction. > Report zones is a device read that requires a buffer. Reset is a device > command (WRITE) that has no associated data transfer. > > The Finish zone command is intentionally not implimented as there is no > current use case for that operation. > > Report zones currently defaults to reporting on all zones. It expected > that support for the zone option flag will piggy back on streamid > support. The report option is useful as it can reduce the number of > zones in each report, but not critical. > > Signed-off-by: Shaun Tancheff <shaun.tancheff@xxxxxxxxxxx> > --- > MAINTAINERS | 9 ++ > block/blk-lib.c | 96 +++++++++++++++++ > drivers/scsi/sd.c | 99 +++++++++++++++++- > drivers/scsi/sd.h | 1 + > include/linux/blk_types.h | 19 +++- > include/linux/blkzoned_api.h | 25 +++++ > include/uapi/linux/Kbuild | 1 + > include/uapi/linux/blkzoned_api.h | 215 ++++++++++++++++++++++++++++++++++++++ > include/uapi/linux/fs.h | 1 + > 9 files changed, 461 insertions(+), 5 deletions(-) > create mode 100644 include/linux/blkzoned_api.h > create mode 100644 include/uapi/linux/blkzoned_api.h > > diff --git a/MAINTAINERS b/MAINTAINERS > index 7304d2e..0b71a3c 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -12660,6 +12660,15 @@ F: Documentation/networking/z8530drv.txt > F: drivers/net/hamradio/*scc.c > F: drivers/net/hamradio/z8530.h > > +ZBC AND ZBC BLOCK DEVICES > +M: Shaun Tancheff <shaun.tancheff@xxxxxxxxxxx> > +W: http://seagate.com > +W: https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_Seagate_ZDM-2DDevice-2DMapper&d=CwIBAg&c=IGDlg0lD0b-nebmJJ0Kp8A&r=Wg5NqlNlVTT7Ugl8V50qIHLe856QW0qfG3WVYGOrWzA&m=NgIOfWitaBWSqZoCVyVSkoMDm3cP1ofhQL7wPM1Z-xA&s=gEau_a22IpcIHd6A3J6ovk5P_nay7XAov8OoSfJdTXs&e= > +L: linux-block@xxxxxxxxxxxxxxx > +S: Maintained > +F: include/linux/blkzoned_api.h > +F: include/uapi/linux/blkzoned_api.h > + > ZBUD COMPRESSED PAGE ALLOCATOR > M: Seth Jennings <sjenning@xxxxxxxxxx> > L: linux-mm@xxxxxxxxx > diff --git a/block/blk-lib.c b/block/blk-lib.c > index 23d7f30..a7f047c 100644 > --- a/block/blk-lib.c > +++ b/block/blk-lib.c > @@ -6,6 +6,7 @@ > #include <linux/bio.h> > #include <linux/blkdev.h> > #include <linux/scatterlist.h> > +#include <linux/blkzoned_api.h> > > #include "blk.h" > > @@ -249,3 +250,98 @@ int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector, > return __blkdev_issue_zeroout(bdev, sector, nr_sects, gfp_mask); > } > EXPORT_SYMBOL(blkdev_issue_zeroout); > + > +/** > + * blkdev_issue_zone_report - queue a report zones operation > + * @bdev: target blockdev > + * @bi_rw: extra bio rw flags. If unsure, use 0. > + * @sector: starting sector (report will include this sector). Missing: * @opt: See: zone_report_option, default is 0 (all zones) > + * @page: one or more contiguous pages. > + * @pgsz: up to size of page in bytes, size of report. > + * @gfp_mask: memory allocation flags (for bio_alloc) > + * > + * Description: > + * Issue a zone report request for the sectors in question. > + */ > +int blkdev_issue_zone_report(struct block_device *bdev, unsigned int bi_rw, > + sector_t sector, u8 opt, struct page *page, > + size_t pgsz, gfp_t gfp_mask) > +{ > + struct bdev_zone_report *conv = page_address(page); > + struct bio *bio; > + unsigned int nr_iovecs = 1; > + int ret = 0; > + > + if (pgsz < (sizeof(struct bdev_zone_report) + > + sizeof(struct bdev_zone_descriptor))) > + return -EINVAL; > + > + bio = bio_alloc(gfp_mask, nr_iovecs); > + if (!bio) > + return -ENOMEM; > + > + conv->descriptor_count = 0; > + bio->bi_iter.bi_sector = sector; > + bio->bi_bdev = bdev; > + bio->bi_vcnt = 0; > + bio->bi_iter.bi_size = 0; > + > + bi_rw |= REQ_REPORT_ZONES; > + > + /* FUTURE ... when streamid is available: */ > + /* bio_set_streamid(bio, opt); */ > + > + bio_add_page(bio, page, pgsz, 0); > + ret = submit_bio_wait(READ | bi_rw, bio); > + > + /* > + * When our request it nak'd the underlying device maybe conventional > + * so ... report a single conventional zone the size of the device. > + */ > + if (ret == -EIO && conv->descriptor_count) { > + /* Adjust the conventional to the size of the partition ... */ > + __be64 blksz = cpu_to_be64(bdev->bd_part->nr_sects); > + > + conv->maximum_lba = blksz; > + conv->descriptors[0].type = ZTYP_CONVENTIONAL; > + conv->descriptors[0].flags = ZCOND_CONVENTIONAL << 4; > + conv->descriptors[0].length = blksz; > + conv->descriptors[0].lba_start = 0; > + conv->descriptors[0].lba_wptr = blksz; > + return 0; Memory leak here ... return should be to fall through and put bio. ret = 0; > > + } > + bio_put(bio); > + return ret; > +} > +EXPORT_SYMBOL(blkdev_issue_zone_report); > + > +/** > + * blkdev_issue_zone_action - queue a report zones operation > + * @bdev: target blockdev > + * @bi_rw: REQ_OPEN_ZONE, REQ_CLOSE_ZONE, or REQ_RESET_ZONE. > + * @sector: starting lba of sector > + * @gfp_mask: memory allocation flags (for bio_alloc) > + * > + * Description: > + * Issue a zone report request for the sectors in question. > + */ > +int blkdev_issue_zone_action(struct block_device *bdev, unsigned int bi_rw, > + sector_t sector, gfp_t gfp_mask) > +{ > + int ret; > + struct bio *bio; > + > + bio = bio_alloc(gfp_mask, 1); > + if (!bio) > + return -ENOMEM; > + > + bio->bi_iter.bi_sector = sector; > + bio->bi_bdev = bdev; > + bio->bi_vcnt = 0; > + bio->bi_iter.bi_size = 0; > + > + ret = submit_bio_wait(WRITE | bi_rw, bio); > + bio_put(bio); > + return ret; > +} > +EXPORT_SYMBOL(blkdev_issue_zone_action); > diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c > index 428c03e..372b5e2 100644 > --- a/drivers/scsi/sd.c > +++ b/drivers/scsi/sd.c > @@ -52,6 +52,7 @@ > #include <linux/slab.h> > #include <linux/pm_runtime.h> > #include <linux/pr.h> > +#include <linux/blkzoned_api.h> > #include <asm/uaccess.h> > #include <asm/unaligned.h> > > @@ -1133,11 +1134,105 @@ static int sd_setup_read_write_cmnd(struct scsi_cmnd *SCpnt) > return ret; > } > > +static int sd_setup_zoned_cmnd(struct scsi_cmnd *cmd) > +{ > + struct request *rq = cmd->request; > + struct scsi_device *sdp = cmd->device; > + struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); > + struct bio *bio = rq->bio; > + sector_t sector = blk_rq_pos(rq); > + struct gendisk *disk = rq->rq_disk; > + unsigned int nr_bytes = blk_rq_bytes(rq); > + int ret = BLKPREP_KILL; > + u8 allbit = 0; > + > + if (rq->cmd_flags & REQ_REPORT_ZONES && rq_data_dir(rq) == READ) { > + WARN_ON(nr_bytes == 0); > + > + /* > + * For conventional drives generate a report that shows a > + * large single convetional zone the size of the block device > + */ > + if (sdkp->zoned != 1 && sdkp->device->type != TYPE_ZBC) { > + void *src; > + struct bdev_zone_report *conv; > + > + if (nr_bytes < sizeof(struct bdev_zone_report)) > + goto out; > + > + src = kmap_atomic(bio->bi_io_vec->bv_page); > + conv = src + bio->bi_io_vec->bv_offset; > + conv->descriptor_count = cpu_to_be32(1); > + conv->same_field = ZS_ALL_SAME; > + conv->maximum_lba = cpu_to_be64(disk->part0.nr_sects); > + kunmap_atomic(src); > + goto out; > + } > + > + ret = scsi_init_io(cmd); > + if (ret != BLKPREP_OK) > + goto out; > + > + cmd = rq->special; > + if (sdp->changed) { > + pr_err("SCSI disk has been changed or is not present."); > + ret = BLKPREP_KILL; > + goto out; > + } > + > + cmd->cmd_len = 16; > + memset(cmd->cmnd, 0, cmd->cmd_len); > + cmd->cmnd[0] = ZBC_IN; > + cmd->cmnd[1] = ZI_REPORT_ZONES; > + put_unaligned_be64(sector, &cmd->cmnd[2]); > + put_unaligned_be32(nr_bytes, &cmd->cmnd[10]); > + /* FUTURE ... when streamid is available */ > + /* cmd->cmnd[14] = bio_get_streamid(bio); */ > + cmd->sc_data_direction = DMA_FROM_DEVICE; > + cmd->sdb.length = nr_bytes; > + cmd->transfersize = sdp->sector_size; > + cmd->underflow = 0; > + cmd->allowed = SD_MAX_RETRIES; > + ret = BLKPREP_OK; > + goto out; > + } > + > + if (sdkp->zoned != 1 && sdkp->device->type != TYPE_ZBC) > + goto out; > + > + if (sector == ~0ul) { > + allbit = 1; > + sector = 0; > + } > + > + cmd->cmd_len = 16; > + memset(cmd->cmnd, 0, cmd->cmd_len); > + memset(&cmd->sdb, 0, sizeof(cmd->sdb)); > + cmd->cmnd[0] = ZBC_OUT; > + cmd->cmnd[1] = ZO_OPEN_ZONE; > + if (rq->cmd_flags & REQ_CLOSE_ZONE) > + cmd->cmnd[1] = ZO_CLOSE_ZONE; > + if (rq->cmd_flags & REQ_RESET_ZONE) > + cmd->cmnd[1] = ZO_RESET_WRITE_POINTER; > + cmd->cmnd[14] = allbit; > + put_unaligned_be64(sector, &cmd->cmnd[2]); > + cmd->transfersize = 0; > + cmd->underflow = 0; > + cmd->allowed = SD_MAX_RETRIES; > + cmd->sc_data_direction = DMA_NONE; > + > + ret = BLKPREP_OK; > +out: > + return ret; > +} > + > static int sd_init_command(struct scsi_cmnd *cmd) > { > struct request *rq = cmd->request; > > - if (rq->cmd_flags & REQ_DISCARD) > + if (rq->cmd_flags & REQ_ZONED_CMDS) > + return sd_setup_zoned_cmnd(cmd); > + else if (rq->cmd_flags & REQ_DISCARD) > return sd_setup_discard_cmnd(cmd); > else if (rq->cmd_flags & REQ_WRITE_SAME) > return sd_setup_write_same_cmnd(cmd); > @@ -2727,6 +2822,8 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp) > queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, sdkp->disk->queue); > } > > + sdkp->zoned = (buffer[8] >> 4) & 3; > + > out: > kfree(buffer); > } > diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h > index 654630b..e012175 100644 > --- a/drivers/scsi/sd.h > +++ b/drivers/scsi/sd.h > @@ -94,6 +94,7 @@ struct scsi_disk { > unsigned lbpvpd : 1; > unsigned ws10 : 1; > unsigned ws16 : 1; > + unsigned zoned: 2; > }; > #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev) > > diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h > index 77e5d81..d2943e4 100644 > --- a/include/linux/blk_types.h > +++ b/include/linux/blk_types.h > @@ -162,6 +162,10 @@ enum rq_flag_bits { > __REQ_FUA, /* forced unit access */ > __REQ_FLUSH, /* request for cache flush */ > > + __REQ_REPORT_ZONES, /* Zoned device: Report Zones */ > + __REQ_OPEN_ZONE, /* Zoned device: Open Zone */ > + __REQ_CLOSE_ZONE, /* Zoned device: Close Zone */ > + > /* bio only flags */ > __REQ_RAHEAD, /* read ahead, can fail anytime */ > __REQ_THROTTLED, /* This bio has already been subjected to > @@ -202,20 +206,27 @@ enum rq_flag_bits { > #define REQ_WRITE_SAME (1ULL << __REQ_WRITE_SAME) > #define REQ_NOIDLE (1ULL << __REQ_NOIDLE) > #define REQ_INTEGRITY (1ULL << __REQ_INTEGRITY) > +#define REQ_REPORT_ZONES (1ULL << __REQ_REPORT_ZONES) > +#define REQ_OPEN_ZONE (1ULL << __REQ_OPEN_ZONE) > +#define REQ_CLOSE_ZONE (1ULL << __REQ_CLOSE_ZONE) > +#define REQ_RESET_ZONE (REQ_REPORT_ZONES) > +#define REQ_ZONED_CMDS \ > + (REQ_OPEN_ZONE | REQ_CLOSE_ZONE | REQ_RESET_ZONE | REQ_REPORT_ZONES) > > #define REQ_FAILFAST_MASK \ > (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER) > #define REQ_COMMON_MASK \ > (REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | \ > REQ_DISCARD | REQ_WRITE_SAME | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | \ > - REQ_SECURE | REQ_INTEGRITY | REQ_NOMERGE) > + REQ_SECURE | REQ_INTEGRITY | REQ_NOMERGE | REQ_ZONED_CMDS) > #define REQ_CLONE_MASK REQ_COMMON_MASK > - > -#define BIO_NO_ADVANCE_ITER_MASK (REQ_DISCARD|REQ_WRITE_SAME) > +#define BIO_NO_ADVANCE_ITER_MASK \ > + (REQ_DISCARD | REQ_WRITE_SAME | REQ_ZONED_CMDS) > > /* This mask is used for both bio and request merge checking */ > #define REQ_NOMERGE_FLAGS \ > - (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA | REQ_FLUSH_SEQ) > + (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | \ > + REQ_FLUSH | REQ_FUA | REQ_FLUSH_SEQ | REQ_ZONED_CMDS) > > #define REQ_RAHEAD (1ULL << __REQ_RAHEAD) > #define REQ_THROTTLED (1ULL << __REQ_THROTTLED) > diff --git a/include/linux/blkzoned_api.h b/include/linux/blkzoned_api.h > new file mode 100644 > index 0000000..6061983 > --- /dev/null > +++ b/include/linux/blkzoned_api.h > @@ -0,0 +1,25 @@ > +/* > + * Functions for zone based SMR devices. > + * > + * Copyright (C) 2015 Seagate Technology PLC > + * > + * Written by: > + * Shaun Tancheff <shaun.tancheff@xxxxxxxxxxx> > + * > + * This file is licensed under the terms of the GNU General Public > + * License version 2. This program is licensed "as is" without any > + * warranty of any kind, whether express or implied. > + */ > + > +#ifndef _BLKZONED_API_H > +#define _BLKZONED_API_H > + > +#include <uapi/linux/blkzoned_api.h> > + > +extern int blkdev_issue_zone_action(struct block_device *, unsigned int bi_rw, > + sector_t, gfp_t); > +extern int blkdev_issue_zone_report(struct block_device *, unsigned int bi_rw, > + sector_t, u8 opt, struct page *, size_t, > + gfp_t); > + > +#endif /* _BLKZONED_API_H */ > diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild > index 8bdae34..5152fa4 100644 > --- a/include/uapi/linux/Kbuild > +++ b/include/uapi/linux/Kbuild > @@ -70,6 +70,7 @@ header-y += bfs_fs.h > header-y += binfmts.h > header-y += blkpg.h > header-y += blktrace_api.h > +header-y += blkzoned_api.h > header-y += bpf_common.h > header-y += bpf.h > header-y += bpqether.h > diff --git a/include/uapi/linux/blkzoned_api.h b/include/uapi/linux/blkzoned_api.h > new file mode 100644 > index 0000000..189e925 > --- /dev/null > +++ b/include/uapi/linux/blkzoned_api.h > @@ -0,0 +1,215 @@ > +/* > + * Functions for zone based SMR devices. > + * > + * Copyright (C) 2015 Seagate Technology PLC > + * > + * Written by: > + * Shaun Tancheff <shaun.tancheff@xxxxxxxxxxx> > + * > + * This file is licensed under the terms of the GNU General Public > + * License version 2. This program is licensed "as is" without any > + * warranty of any kind, whether express or implied. > + */ > + > +#ifndef _UAPI_BLKZONED_API_H > +#define _UAPI_BLKZONED_API_H > + > +#include <linux/types.h> > + > +/** > + * enum zone_report_option - Report Zones types to be included. > + * > + * @ZOPT_NON_SEQ_AND_RESET: Default (all zones). > + * @ZOPT_ZC1_EMPTY: Zones which are empty. > + * @ZOPT_ZC2_OPEN_IMPLICIT: Zones open but not explicitly opened > + * @ZOPT_ZC3_OPEN_EXPLICIT: Zones opened explicitly > + * @ZOPT_ZC4_CLOSED: Zones closed for writing. > + * @ZOPT_ZC5_FULL: Zones that are full. > + * @ZOPT_ZC6_READ_ONLY: Zones that are read-only > + * @ZOPT_ZC7_OFFLINE: Zones that are offline > + * @ZOPT_RESET: Zones that are empty > + * @ZOPT_NON_SEQ: Zones that have HA media-cache writes pending > + * @ZOPT_NON_WP_ZONES: Zones that do not have Write Pointers (conventional) > + * > + * @ZOPT_USE_ATA_PASS: Flag used in kernel to service command I/O > + * > + * Used by Report Zones in bdev_zone_get_report: report_option > + */ > +enum zone_report_option { > + ZOPT_NON_SEQ_AND_RESET = 0x00, > + ZOPT_ZC1_EMPTY, > + ZOPT_ZC2_OPEN_IMPLICIT, > + ZOPT_ZC3_OPEN_EXPLICIT, > + ZOPT_ZC4_CLOSED, > + ZOPT_ZC5_FULL, > + ZOPT_ZC6_READ_ONLY, > + ZOPT_ZC7_OFFLINE, > + ZOPT_RESET = 0x10, > + ZOPT_NON_SEQ = 0x11, > + ZOPT_NON_WP_ZONES = 0x3f, > + ZOPT_USE_ATA_PASS = 0x80, > +}; > + > +/** > + * enum bdev_zone_type - Type of zone in descriptor > + * > + * @ZTYP_RESERVED: Reserved > + * @ZTYP_CONVENTIONAL: Conventional random write zone (No Write Pointer) > + * @ZTYP_SEQ_WRITE_REQUIRED: Non-sequential writes are rejected. > + * @ZTYP_SEQ_WRITE_PREFERRED: Non-sequential writes allowed but discouraged. > + * > + * Returned from Report Zones. See bdev_zone_descriptor* type. > + */ > +enum bdev_zone_type { > + ZTYP_RESERVED = 0, > + ZTYP_CONVENTIONAL = 1, > + ZTYP_SEQ_WRITE_REQUIRED = 2, > + ZTYP_SEQ_WRITE_PREFERRED = 3, > +}; > + > + > +/** > + * enum bdev_zone_condition - Condition of zone in descriptor > + * > + * @ZCOND_CONVENTIONAL: N/A > + * @ZCOND_ZC1_EMPTY: Empty > + * @ZCOND_ZC2_OPEN_IMPLICIT: Opened via write to zone. > + * @ZCOND_ZC3_OPEN_EXPLICIT: Opened via open zone command. > + * @ZCOND_ZC4_CLOSED: Closed > + * @ZCOND_ZC6_READ_ONLY: > + * @ZCOND_ZC5_FULL: No remaining space in zone. > + * @ZCOND_ZC7_OFFLINE: Offline > + * > + * Returned from Report Zones. See bdev_zone_descriptor* flags. > + */ > +enum bdev_zone_condition { > + ZCOND_CONVENTIONAL = 0, > + ZCOND_ZC1_EMPTY = 1, > + ZCOND_ZC2_OPEN_IMPLICIT = 2, > + ZCOND_ZC3_OPEN_EXPLICIT = 3, > + ZCOND_ZC4_CLOSED = 4, > + /* 0x5 to 0xC are reserved */ > + ZCOND_ZC6_READ_ONLY = 0xd, > + ZCOND_ZC5_FULL = 0xe, > + ZCOND_ZC7_OFFLINE = 0xf, > +}; > + > + > +/** > + * enum bdev_zone_same - Report Zones same code. > + * > + * @ZS_ALL_DIFFERENT: All zones differ in type and size. > + * @ZS_ALL_SAME: All zones are the same size and type. > + * @ZS_LAST_DIFFERS: All zones are the same size and type except the last zone. > + * @ZS_SAME_LEN_DIFF_TYPES: All zones are the same length but types differ. > + * > + * Returned from Report Zones. See bdev_zone_report* same_field. > + */ > +enum bdev_zone_same { > + ZS_ALL_DIFFERENT = 0, > + ZS_ALL_SAME = 1, > + ZS_LAST_DIFFERS = 2, > + ZS_SAME_LEN_DIFF_TYPES = 3, > +}; > + > + > +/** > + * struct bdev_zone_get_report - ioctl: Report Zones request > + * > + * @zone_locator_lba: starting lba for first [reported] zone > + * @return_page_count: number of *bytes* allocated for result > + * @report_option: see: zone_report_option enum > + * > + * Used to issue report zones command to connected device > + */ > +struct bdev_zone_get_report { > + __u64 zone_locator_lba; > + __u32 return_page_count; > + __u8 report_option; > +} __packed; > + > +/** > + * struct bdev_zone_descriptor_le - See: bdev_zone_descriptor > + */ > +struct bdev_zone_descriptor_le { > + __u8 type; > + __u8 flags; > + __u8 reserved1[6]; > + __le64 length; > + __le64 lba_start; > + __le64 lba_wptr; > + __u8 reserved[32]; > +} __packed; > + > + > +/** > + * struct bdev_zone_report_le - See: bdev_zone_report > + */ > +struct bdev_zone_report_le { > + __le32 descriptor_count; > + __u8 same_field; > + __u8 reserved1[3]; > + __le64 maximum_lba; > + __u8 reserved2[48]; > + struct bdev_zone_descriptor_le descriptors[0]; > +} __packed; > + > + > +/** > + * struct bdev_zone_descriptor - A Zone descriptor entry from report zones > + * > + * @type: see zone_type enum > + * @flags: Bits 0:reset, 1:non-seq, 2-3: resv, 4-7: see zone_condition enum > + * @reserved1: padding > + * @length: length of zone in sectors > + * @lba_start: lba where the zone starts. > + * @lba_wptr: lba of the current write pointer. > + * @reserved: padding > + * > + */ > +struct bdev_zone_descriptor { > + __u8 type; > + __u8 flags; > + __u8 reserved1[6]; > + __be64 length; > + __be64 lba_start; > + __be64 lba_wptr; > + __u8 reserved[32]; > +} __packed; > + > + > +/** > + * struct bdev_zone_report - Report Zones result > + * > + * @descriptor_count: Number of descriptor entries that follow > + * @same_field: bits 0-3: enum zone_same (MASK: 0x0F) > + * @reserved1: padding > + * @maximum_lba: LBA of the last logical sector on the device, inclusive > + * of all logical sectors in all zones. > + * @reserved2: padding > + * @descriptors: array of descriptors follows. > + */ > +struct bdev_zone_report { > + __be32 descriptor_count; > + __u8 same_field; > + __u8 reserved1[3]; > + __be64 maximum_lba; > + __u8 reserved2[48]; > + struct bdev_zone_descriptor descriptors[0]; > +} __packed; > + > + > +/** > + * struct bdev_zone_report_io - Report Zones ioctl argument. > + * > + * @in: Report Zones inputs > + * @out: Report Zones output > + */ > +struct bdev_zone_report_io { > + union { > + struct bdev_zone_get_report in; > + struct bdev_zone_report out; > + } data; > +} __packed; > + > +#endif /* _UAPI_BLKZONED_API_H */ > diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h > index 3b00f7c..c0b565b 100644 > --- a/include/uapi/linux/fs.h > +++ b/include/uapi/linux/fs.h > @@ -222,6 +222,7 @@ struct fsxattr { > #define BLKSECDISCARD _IO(0x12,125) > #define BLKROTATIONAL _IO(0x12,126) > #define BLKZEROOUT _IO(0x12,127) > +/* A jump here: See blkzoned_api.h, Reserving 130 to 133. */ > > #define BMAP_IOCTL 1 /* obsolete - kept for compatibility */ > #define FIBMAP _IO(0x00,1) /* bmap access */ > -- > 2.8.1 > -- Shaun Tancheff -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html