summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys
diff options
context:
space:
mode:
authorJason King <jason.king@joyent.com>2019-12-03 23:13:23 +0000
committerJason King <jason.king@joyent.com>2020-07-09 17:01:46 -0500
commit1a5ae140ba142cafb59ab08b3212c4ebbce84f32 (patch)
tree392db089970c3c0a81a85ab86094d0af5196f57c /usr/src/uts/common/sys
parent2fc9ab6e6080d66d8dc6b967cea7ba24bee8c7e5 (diff)
downloadillumos-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.h41
-rw-r--r--usr/src/uts/common/sys/dkioc_free_util.h43
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
}