Re: [PATCH 2/4] Add bio/request flags for using ZBC/ZAC commands

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

 



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-block" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux