diff options
author | Jason King <jason.king@joyent.com> | 2019-12-03 23:13:23 +0000 |
---|---|---|
committer | Jason King <jason.king@joyent.com> | 2020-07-09 17:01:46 -0500 |
commit | 1a5ae140ba142cafb59ab08b3212c4ebbce84f32 (patch) | |
tree | 392db089970c3c0a81a85ab86094d0af5196f57c /usr/src/uts/common/sys | |
parent | 2fc9ab6e6080d66d8dc6b967cea7ba24bee8c7e5 (diff) | |
download | illumos-joyent-1a5ae140ba142cafb59ab08b3212c4ebbce84f32.tar.gz |
12506 Add support to vioblk for DISCARD operation
Reviewed by: Robert Mustacchi <rm@fingolfin.org>
Reviewed by: Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
Approved by: Dan McDonald <danmcd@joyent.com>
Diffstat (limited to 'usr/src/uts/common/sys')
-rw-r--r-- | usr/src/uts/common/sys/blkdev.h | 41 | ||||
-rw-r--r-- | usr/src/uts/common/sys/dkioc_free_util.h | 43 |
2 files changed, 80 insertions, 4 deletions
diff --git a/usr/src/uts/common/sys/blkdev.h b/usr/src/uts/common/sys/blkdev.h index 7802f06dbc..6407f7b960 100644 --- a/usr/src/uts/common/sys/blkdev.h +++ b/usr/src/uts/common/sys/blkdev.h @@ -23,6 +23,7 @@ * Copyright 2016 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2019 Western Digital Corporation. + * Copyright 2020 Joyent, Inc. */ #ifndef _SYS_BLKDEV_H @@ -79,8 +80,10 @@ typedef struct bd_handle *bd_handle_t; typedef struct bd_xfer bd_xfer_t; typedef struct bd_drive bd_drive_t; typedef struct bd_media bd_media_t; +typedef struct bd_free_info bd_free_info_t; typedef struct bd_ops bd_ops_t; +struct dkioc_free_list_s; struct bd_xfer { /* @@ -95,6 +98,7 @@ struct bd_xfer { caddr_t x_kaddr; unsigned x_flags; unsigned x_qnum; + const struct dkioc_free_list_s *x_dfl; }; #define BD_XFER_POLL (1U << 0) /* no interrupts (dump) */ @@ -119,6 +123,33 @@ struct bd_drive { uint8_t d_eui64[8]; /* Added at the end to maintain binary compatibility */ uint32_t d_qcount; + + /* + * Required starting alignment for free_space requests (in logical + * blocks). Must be >= 1. + */ + uint64_t d_free_align; + + /* + * Maximum number of segments supported in a free space request. + * 0 implies no limit. + */ + uint64_t d_max_free_seg; + + /* + * Maximum number of logical blocks allowed in a free space request. + * 0 implies no limit. + */ + uint64_t d_max_free_blks; + + /* + * Maximum number of logical blocks to free in a single segment. + * 0 implies no limit. If no limit, d_max_free_blks must also be 0. + * If > 0, d_max_free_seg_blks must be <= d_max_free_blks (basically + * you can't set a bigger value of d_max_free_seg_blks than + * d_max_free_blks). + */ + uint64_t d_max_free_seg_blks; }; struct bd_media { @@ -147,14 +178,15 @@ struct bd_media { #define BD_INFO_FLAG_READ_ONLY (1U << 2) /* - * If the API changes and we want to bump the version, add another - * enum value, Eg BD_OPS_VERSION_1. BD_OPS_CURRENT_VERSION should always - * be last. + * When adding a new version of the bd_ops_t struct, be sure to update + * BD_OPS_CURRENT_VERSION */ typedef enum { BD_OPS_VERSION_0 = 0, - BD_OPS_CURRENT_VERSION + BD_OPS_VERSION_1 = 1, + BD_OPS_VERSION_2 = 2, } bd_version_t; +#define BD_OPS_CURRENT_VERSION BD_OPS_VERSION_2 struct bd_ops { bd_version_t o_version; @@ -164,6 +196,7 @@ struct bd_ops { int (*o_sync_cache)(void *, bd_xfer_t *); int (*o_read)(void *, bd_xfer_t *); int (*o_write)(void *, bd_xfer_t *); + int (*o_free_space)(void *, bd_xfer_t *); }; struct bd_errstats { diff --git a/usr/src/uts/common/sys/dkioc_free_util.h b/usr/src/uts/common/sys/dkioc_free_util.h index 9e83ab3bff..f61630395c 100644 --- a/usr/src/uts/common/sys/dkioc_free_util.h +++ b/usr/src/uts/common/sys/dkioc_free_util.h @@ -11,6 +11,7 @@ /* * Copyright 2017 Nexenta Inc. All rights reserved. + * Copyright 2020 Joyent, Inc. */ #ifndef _SYS_DKIOC_FREE_UTIL_H @@ -24,8 +25,50 @@ extern "C" { #define DFL_COPYIN_MAX_EXTS (1024 * 1024) +#define DFL_ISSYNC(dfl) (((dfl)->dfl_flags & DF_WAIT_SYNC) ? B_TRUE : B_FALSE) + +/* + * Since dkioc_free_list_t and in general DKIOCFREE use bytes to express + * values instead of blocks, dkioc_free_info_t uses bytes as well for + * consistency. + */ +typedef struct dkioc_free_info { + /* log2(block size) */ + uint64_t dfi_bshift; + + /* Maximum number of extents in a single request. 0 == no limit */ + uint64_t dfi_max_ext; + + /* + * Maximum total number of bytes in a single request. 0 == no limit. + * Must by a multiple of 1U << dfi_bshift (e.g. dfi_bshift == 9, + * dfk_max_bytes must be a multiple of 512). + */ + uint64_t dfi_max_bytes; + + /* + * Maximum length of an extent. 0 == same as dfi_max_bytes. If > 0, + * must be a multiple of 1U << dfi_shift (the block size) and + * <= dfi_max_bytes. + */ + uint64_t dfi_max_ext_bytes; + + /* + * Minimum alignment for starting extent offsets in bytes + * Must be > 0, and a multiple of 1U << dfi_shift. + * + * A possible future extention might be to also express a preferred + * alignment when splitting extents. + */ + uint64_t dfi_align; +} dkioc_free_info_t; + +typedef int (*dfl_iter_fn_t)(dkioc_free_list_t *dfl, void *arg, int kmflag); + int dfl_copyin(void *arg, dkioc_free_list_t **out, int ddi_flags, int kmflags); void dfl_free(dkioc_free_list_t *dfl); +int dfl_iter(dkioc_free_list_t *dfl, const dkioc_free_info_t *dfi, uint64_t len, + dfl_iter_fn_t fn, void *arg, int kmflag); #ifdef __cplusplus } |