All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nabeel M Mohamed <nmeeramohide@micron.com>
To: <linux-kernel@vger.kernel.org>, <linux-block@vger.kernel.org>,
	<linux-nvme@lists.infradead.org>, <linux-mm@kvack.org>,
	<linux-nvdimm@lists.01.org>
Cc: smoyer@micron.com, gbecker@micron.com, plabat@micron.com,
	jgroves@micron.com, Nabeel M Mohamed <nmeeramohide@micron.com>
Subject: [PATCH v2 01/22] mpool: add utility routines and ioctl definitions
Date: Mon, 12 Oct 2020 11:27:15 -0500	[thread overview]
Message-ID: <20201012162736.65241-2-nmeeramohide@micron.com> (raw)
In-Reply-To: <20201012162736.65241-1-nmeeramohide@micron.com>

This adds structures used by mpool ioctls and utility routines
for logging, UUID management etc.

The mpool ioctls can be categorized as follows:

1. IOCTLs issued to the mpool control device (/dev/mpoolctl)
   - Mpool life cycle management (MPIOC_MP_*)

2. IOCTLs issued to the mpool device (/dev/mpool/<mpool-name>)
   - Mpool parameters (MPIOC_PARAMS_*)
   - Mpool properties (MPIOC_PROP_*)
   - Mpool media class management (MPIOC_MP_MCLASS_*)
   - Device management (MPIOC_DRV_*)
   - Mblock object life cycle management and IO (MPIOC_MB_*)
   - Mlog object life cycle management and IO (MPIOC_MLOG_*)
   - Mblock cache management (MPIOC_VMA_*)

Co-developed-by: Greg Becker <gbecker@micron.com>
Signed-off-by: Greg Becker <gbecker@micron.com>
Co-developed-by: Pierre Labat <plabat@micron.com>
Signed-off-by: Pierre Labat <plabat@micron.com>
Co-developed-by: John Groves <jgroves@micron.com>
Signed-off-by: John Groves <jgroves@micron.com>
Signed-off-by: Nabeel M Mohamed <nmeeramohide@micron.com>
---
 drivers/mpool/assert.h       |  25 ++
 drivers/mpool/init.c         |  22 ++
 drivers/mpool/mpool_ioctl.h  | 636 +++++++++++++++++++++++++++++++++++
 drivers/mpool/mpool_printk.h |  43 +++
 drivers/mpool/uuid.h         |  59 ++++
 5 files changed, 785 insertions(+)
 create mode 100644 drivers/mpool/assert.h
 create mode 100644 drivers/mpool/init.c
 create mode 100644 drivers/mpool/mpool_ioctl.h
 create mode 100644 drivers/mpool/mpool_printk.h
 create mode 100644 drivers/mpool/uuid.h

diff --git a/drivers/mpool/assert.h b/drivers/mpool/assert.h
new file mode 100644
index 000000000000..a2081e71ec93
--- /dev/null
+++ b/drivers/mpool/assert.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2015-2020 Micron Technology, Inc.  All rights reserved.
+ */
+
+#ifndef MPOOL_ASSERT_H
+#define MPOOL_ASSERT_H
+
+#include <linux/bug.h>
+
+#ifdef CONFIG_MPOOL_ASSERT
+__cold __noreturn
+static inline void assertfail(const char *expr, const char *file, int line)
+{
+	pr_err("mpool assertion failed: %s in %s:%d\n", expr, file, line);
+	BUG();
+}
+
+#define ASSERT(_expr)   (likely(_expr) ? (void)0 : assertfail(#_expr, __FILE__, __LINE__))
+
+#else
+#define ASSERT(_expr)   (void)(_expr)
+#endif
+
+#endif /* MPOOL_ASSERT_H */
diff --git a/drivers/mpool/init.c b/drivers/mpool/init.c
new file mode 100644
index 000000000000..0493fb5b1157
--- /dev/null
+++ b/drivers/mpool/init.c
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2015-2020 Micron Technology, Inc.  All rights reserved.
+ */
+
+#include <linux/module.h>
+
+static __init int mpool_init(void)
+{
+	return 0;
+}
+
+static __exit void mpool_exit(void)
+{
+}
+
+module_init(mpool_init);
+module_exit(mpool_exit);
+
+MODULE_DESCRIPTION("Object Storage Media Pool (mpool)");
+MODULE_AUTHOR("Micron Technology, Inc.");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mpool/mpool_ioctl.h b/drivers/mpool/mpool_ioctl.h
new file mode 100644
index 000000000000..599da0618a09
--- /dev/null
+++ b/drivers/mpool/mpool_ioctl.h
@@ -0,0 +1,636 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (C) 2015-2020 Micron Technology, Inc.  All rights reserved.
+ */
+
+#ifndef MPOOL_IOCTL_H
+#define MPOOL_IOCTL_H
+
+#include <linux/uuid.h>
+#include <linux/uio.h>
+
+#ifndef __user
+#define __user
+#endif
+
+/*
+ * Maximum name lengths including NUL terminator.  Note that the maximum
+ * mpool name length is baked into libblkid and may not be changed here.
+ */
+#define MPOOL_NAMESZ_MAX            32
+#define MPOOL_LABELSZ_MAX           64
+#define PD_NAMESZ_MAX               32
+
+#define MPC_DEV_SUBDIR              "mpool"
+#define MPC_DEV_CTLNAME             MPC_DEV_SUBDIR "ctl"
+#define MPC_DEV_CTLPATH             "/dev/" MPC_DEV_CTLNAME
+
+#define MPOOL_LABEL_INVALID         ""
+#define MPOOL_LABEL_DEFAULT         "raw"
+
+#define MPOOL_RA_PAGES_INVALID      U32_MAX
+#define MPOOL_RA_PAGES_MAX          ((128 * 1024) / PAGE_SIZE)
+
+#define MPOOL_MCLASS_INVALID        MP_MED_INVALID
+#define MPOOL_MCLASS_DEFAULT        MP_MED_CAPACITY
+
+#define MPOOL_SPARES_INVALID        U8_MAX
+#define MPOOL_SPARES_DEFAULT        5
+
+#define MPOOL_ROOT_LOG_CAP          (8 * 1024 * 1024)
+
+#define MPOOL_MBSIZE_MB_DEFAULT     32
+
+#define MPOOL_MDCNUM_DEFAULT        16
+
+
+/**
+ * mp_mgmt_flags - Mpool Management Flags
+ * @MP_FLAGS_FORCE:
+ * @MP_PERMIT_META_CONV: permit mpool metadata conversion. That is, allow the
+ *	mpool activate to write back the mpool metadata to the latest version
+ *	used by the binary activating the mpool.
+ * @MP_FLAGS_RESIZE: Resize mpool
+ */
+enum mp_mgmt_flags {
+	MP_FLAGS_FORCE,
+	MP_FLAGS_PERMIT_META_CONV,
+	MP_FLAGS_RESIZE,
+};
+
+/**
+ * mp_media_classp = Media classes
+ *
+ * @MP_MED_STAGING:  Initial data ingest, hot data storage, or similar.
+ * @MP_MED_CAPACITY: Primary data storage, cold data, or similar.
+ */
+enum mp_media_classp {
+	MP_MED_STAGING   = 0,
+	MP_MED_CAPACITY  = 1,
+};
+
+#define MP_MED_BASE        MP_MED_STAGING
+#define MP_MED_NUMBER      (MP_MED_CAPACITY + 1)
+#define MP_MED_INVALID     U8_MAX
+
+/**
+ * struct mpool_devprops -
+ * @pdp_devid:   UUID for drive
+ * @pdp_mclassp: enum mp_media_classp
+ * @pdp_status:  enum pd_status
+ * @pdp_total:   raw capacity of drive
+ * @pdp_avail:   available capacity (total - bad zones) of drive
+ * @pdp_spare:   spare capacity of drive
+ * @pdp_fspare:  free spare capacity of drive
+ * @pdp_usable:  usable capacity of drive
+ * @pdp_fusable: free usable capacity of drive
+ * @pdp_used:    used capacity of drive:
+ */
+struct mpool_devprops {
+	uuid_le    pdp_devid;
+	uint8_t    pdp_mclassp;
+	uint8_t    pdp_status;
+	uint8_t    pdp_rsvd1[6];
+	uint64_t   pdp_total;
+	uint64_t   pdp_avail;
+	uint64_t   pdp_spare;
+	uint64_t   pdp_fspare;
+	uint64_t   pdp_usable;
+	uint64_t   pdp_fusable;
+	uint64_t   pdp_used;
+	uint64_t   pdp_rsvd2;
+};
+
+/**
+ * struct mpool_params -
+ * @mp_poolid:          UUID of mpool
+ * @mp_type:            user-specified identifier
+ * @mp_uid:
+ * @mp_gid:
+ * @mp_mode:
+ * @mp_stat:            overall mpool status (enum mpool_status)
+ * @mp_mdc_captgt:      user MDC capacity
+ * @mp_oidv:            user MDC OIDs
+ * @mp_ra_pages_max:    max VMA map readahead pages
+ * @mp_vma_size_max:    max VMA map size (log2)
+ * @mp_mblocksz:        mblock size by media class (MiB)
+ * @mp_utype:           user-defined type
+ * @mp_label:           user specified label
+ * @mp_name:            mpool name (2x for planned expansion)
+ */
+struct mpool_params {
+	uuid_le     mp_poolid;
+	uid_t       mp_uid;
+	gid_t       mp_gid;
+	mode_t      mp_mode;
+	uint8_t     mp_stat;
+	uint8_t     mp_spare_cap;
+	uint8_t     mp_spare_stg;
+	uint8_t     mp_rsvd0;
+	uint64_t    mp_mdc_captgt;
+	uint64_t    mp_oidv[2];
+	uint32_t    mp_ra_pages_max;
+	uint32_t    mp_vma_size_max;
+	uint32_t    mp_mblocksz[MP_MED_NUMBER];
+	uint16_t    mp_mdc0cap;
+	uint16_t    mp_mdcncap;
+	uint16_t    mp_mdcnum;
+	uint16_t    mp_rsvd1;
+	uint32_t    mp_rsvd2;
+	uint64_t    mp_rsvd3;
+	uint64_t    mp_rsvd4;
+	uuid_le     mp_utype;
+	char        mp_label[MPOOL_LABELSZ_MAX];
+	char        mp_name[MPOOL_NAMESZ_MAX * 2];
+};
+
+/**
+ * struct mpool_usage - in bytes
+ * @mpu_total:   raw capacity for all drives
+ * @mpu_usable:  usable capacity for all drives
+ * @mpu_fusable: free usable capacity for all drives
+ * @mpu_used:    used capacity for all drives; possible for
+ *               used > usable when fusable=0; see smap
+ *               module for details
+ * @mpu_spare:   total spare space
+ * @mpu_fspare:  free spare space
+ *
+ * @mpu_mblock_alen: mblock allocated length
+ * @mpu_mblock_wlen: mblock written length
+ * @mpu_mlog_alen:   mlog allocated length
+ * @mpu_mblock_cnt:  number of active mblocks
+ * @mpu_mlog_cnt:    number of active mlogs
+ */
+struct mpool_usage {
+	uint64_t   mpu_total;
+	uint64_t   mpu_usable;
+	uint64_t   mpu_fusable;
+	uint64_t   mpu_used;
+	uint64_t   mpu_spare;
+	uint64_t   mpu_fspare;
+
+	uint64_t   mpu_alen;
+	uint64_t   mpu_wlen;
+	uint64_t   mpu_mblock_alen;
+	uint64_t   mpu_mblock_wlen;
+	uint64_t   mpu_mlog_alen;
+	uint32_t   mpu_mblock_cnt;
+	uint32_t   mpu_mlog_cnt;
+};
+
+/**
+ * mpool_mclass_xprops -
+ * @mc_devtype: type of devices in the media class
+ *                  (enum pd_devtype)
+ * @mc_mclass: media class (enum mp_media_classp)
+ * @mc_sectorsz: media class (enum mp_media_classp)
+ * @mc_spare: percent spare zones for drives
+ * @mc_uacnt: UNAVAIL status drive count
+ * @mc_zonepg: pages per zone
+ * @mc_features: feature bitmask
+ * @mc_usage: feature bitmask
+ */
+struct mpool_mclass_xprops {
+	uint8_t                    mc_devtype;
+	uint8_t                    mc_mclass;
+	uint8_t                    mc_sectorsz;
+	uint8_t                    mc_rsvd1;
+	uint32_t                   mc_spare;
+	uint16_t                   mc_uacnt;
+	uint16_t                   mc_rsvd2;
+	uint32_t                   mc_zonepg;
+	uint64_t                   mc_features;
+	uint64_t                   mc_rsvd3;
+	struct mpool_usage         mc_usage;
+};
+
+/**
+ * mpool_mclass_props -
+ *
+ * @mc_mblocksz:   mblock size in MiB
+ * @mc_rsvd:       reserved struct field (for future use)
+ * @mc_total:      total space in the media class (mc_usable + mc_spare)
+ * @mc_usable:     usable space in bytes
+ * @mc_used:       bytes allocated from usable space
+ * @mc_spare:      spare space in bytes
+ * @mc_spare_used: bytes allocated from spare space
+ */
+struct mpool_mclass_props {
+	uint32_t   mc_mblocksz;
+	uint32_t   mc_rsvd;
+	uint64_t   mc_total;
+	uint64_t   mc_usable;
+	uint64_t   mc_used;
+	uint64_t   mc_spare;
+	uint64_t   mc_spare_used;
+};
+
+/**
+ * struct mpool_xprops - Extended mpool properties
+ * @ppx_params: mpool configuration parameters
+ * @ppx_drive_spares: percent spare zones for drives in each media class
+ * @ppx_uacnt:  UNAVAIL status drive count in each media class
+ */
+struct mpool_xprops {
+	struct mpool_params     ppx_params;
+	uint8_t                 ppx_rsvd[MP_MED_NUMBER];
+	uint8_t                 ppx_drive_spares[MP_MED_NUMBER];
+	uint16_t                ppx_uacnt[MP_MED_NUMBER];
+	uint32_t                ppx_pd_mclassv[MP_MED_NUMBER];
+	char                    ppx_pd_namev[MP_MED_NUMBER][PD_NAMESZ_MAX];
+};
+
+
+/*
+ * struct mblock_props -
+ *
+ * @mpr_objid:        mblock identifier
+ * @mpr_alloc_cap:    allocated capacity in bytes
+ * @mpr_write_len:    written user-data in bytes
+ * @mpr_optimal_wrsz: optimal write size(in bytes) for all but the last incremental mblock write
+ * @mpr_mclassp:      media class
+ * @mpr_iscommitted:  Is this mblock committed?
+ */
+struct mblock_props {
+	uint64_t                mpr_objid;
+	uint32_t                mpr_alloc_cap;
+	uint32_t                mpr_write_len;
+	uint32_t                mpr_optimal_wrsz;
+	uint32_t                mpr_mclassp; /* enum mp_media_classp */
+	uint8_t                 mpr_iscommitted;
+	uint8_t                 mpr_rsvd1[7];
+	uint64_t                mpr_rsvd2;
+};
+
+struct mblock_props_ex {
+	struct mblock_props     mbx_props;
+	uint8_t                 mbx_zonecnt;      /* zone count per strip */
+	uint8_t                 mbx_rsvd1[7];
+	uint64_t                mbx_rsvd2;
+};
+
+
+/*
+ * enum mlog_open_flags -
+ * @MLOG_OF_COMPACT_SEM: Enforce compaction semantics
+ * @MLOG_OF_SKIP_SER:    Appends and reads are guaranteed to be serialized
+ *                       outside of the mlog API
+ */
+enum mlog_open_flags {
+	MLOG_OF_COMPACT_SEM = 0x1,
+	MLOG_OF_SKIP_SER    = 0x2,
+};
+
+/*
+ * NOTE:
+ * + a value of 0 for targets (*tgt) means no specific target and the
+ *   allocator is free to choose based on media class configuration
+ */
+struct mlog_capacity {
+	uint64_t    lcp_captgt;       /* capacity target for mlog in bytes */
+	uint8_t     lcp_spare;        /* true if alloc mlog from spare space */
+	uint8_t     lcp_rsvd1[7];
+};
+
+/*
+ * struct mlog_props -
+ *
+ * @lpr_uuid:        UUID or mlog magic
+ * @lpr_objid:       mlog identifier
+ * @lpr_alloc_cap:   maximum capacity in bytes
+ * @lpr_gen:         generation no. (user mlogs)
+ * @lpr_mclassp:     media class
+ * @lpr_iscommitted: Is this mlog committed?
+ */
+struct mlog_props {
+	uuid_le     lpr_uuid;
+	uint64_t    lpr_objid;
+	uint64_t    lpr_alloc_cap;
+	uint64_t    lpr_gen;
+	uint8_t     lpr_mclassp;
+	uint8_t     lpr_iscommitted;
+	uint8_t     lpr_rsvd1[6];
+	uint64_t    lpr_rsvd2;
+};
+
+/*
+ * struct mlog_props_ex -
+ *
+ * @lpx_props:
+ * @lpx_totsec:   total number of sectors
+ * @lpx_zonecnt:   zone count per strip
+ * @lpx_state:    mlog layout state
+ * @lpx_secshift: sector shift
+ */
+struct mlog_props_ex {
+	struct mlog_props   lpx_props;
+	uint32_t            lpx_totsec;
+	uint32_t            lpx_zonecnt;
+	uint8_t             lpx_state;
+	uint8_t             lpx_secshift;
+	uint8_t             lpx_rsvd1[6];
+	uint64_t            lpx_rsvd2;
+};
+
+
+/**
+ * enum mdc_open_flags -
+ * @MDC_OF_SKIP_SER: appends and reads are guaranteed to be serialized
+ *                   outside of the MDC API
+ */
+enum mdc_open_flags {
+	MDC_OF_SKIP_SER  = 0x1,
+};
+
+/**
+ * struct mdc_capacity -
+ * @mdt_captgt: capacity target for mlog in bytes
+ * @mpt_spare:  true if alloc MDC from spare space
+ */
+struct mdc_capacity {
+	uint64_t   mdt_captgt;
+	bool       mdt_spare;
+};
+
+/**
+ * struct mdc_props -
+ * @mdc_objid1:
+ * @mdc_objid2:
+ * @mdc_alloc_cap:
+ * @mdc_mclassp:
+ */
+struct mdc_props {
+	uint64_t               mdc_objid1;
+	uint64_t               mdc_objid2;
+	uint64_t               mdc_alloc_cap;
+	enum mp_media_classp   mdc_mclassp;
+};
+
+
+/**
+ * enum mpc_vma_advice -
+ * @MPC_VMA_COLD:
+ * @MPC_VMA_WARM:
+ * @MPC_VMA_HOT:
+ * @MPC_VMA_PINNED:
+ */
+enum mpc_vma_advice {
+	MPC_VMA_COLD = 0,
+	MPC_VMA_WARM,
+	MPC_VMA_HOT,
+	MPC_VMA_PINNED
+};
+
+
+/**
+ * struct pd_znparam - zone parameter arg used in compute/set API functions
+ * @dvb_zonepg:     zone size in PAGE_SIZE units.
+ * @dvb_zonetot:    total number of zones
+ */
+struct pd_znparam {
+	uint32_t   dvb_zonepg;
+	uint32_t   dvb_zonetot;
+	uint64_t   dvb_rsvd1;
+};
+
+#define PD_DEV_ID_LEN              64
+
+/**
+ * struct pd_prop - PD properties
+ * @pdp_didstr:         drive id string (model)
+ * @pdp_devtype:	device type (enum pd_devtype)
+ * @pdp_phys_if:	physical interface of the drive
+ *			Determined by the device discovery.
+ *			(device_phys_if)
+ * @pdp_mclassp:        performance characteristic of the media class
+ *			Determined by the user, not by the device discovery.
+ *			(enum mp_media_classp)
+ * @pdp_cmdopt:         enum pd_cmd_opt. Features of the PD.
+ * @pdp_zparam:	zone parameters
+ * @pdp_discard_granularity: specified by
+ *	/sys/block/<disk>/queue/discard_granularity
+ * @pdp_sectorsz:	Sector size, exponent base 2
+ * @pdp_optiosz:        Optimal IO size
+ * @pdp_devsz:		device size in bytes
+ *
+ * Note: in order to avoid passing enums across user-kernel boundary
+ * declare the following as uint8_t
+ * pdp_devtype: enum pd_devtype
+ * pdp_devstate: enum pd_state
+ * pdp_phys_if: enum device_phys_if
+ * pdp_mclassp: enum mp_media_classp
+ */
+struct pd_prop {
+	char		        pdp_didstr[PD_DEV_ID_LEN];
+	uint8_t                 pdp_devtype;
+	uint8_t                 pdp_devstate;
+	uint8_t                 pdp_phys_if;
+	uint8_t                 pdp_mclassp;
+	bool                    pdp_fua;
+	uint64_t                pdp_cmdopt;
+
+	struct pd_znparam       pdp_zparam;
+	uint32_t                pdp_discard_granularity;
+	uint32_t                pdp_sectorsz;
+	uint32_t                pdp_optiosz;
+	uint32_t                pdp_rsvd2;
+	uint64_t	        pdp_devsz;
+	uint64_t	        pdp_rsvd3;
+};
+
+
+struct mpioc_mpool {
+	struct mpool_params     mp_params;
+	uint32_t                mp_flags;       /* mp_mgmt_flags */
+	uint32_t                mp_dpathc;      /* Count of device paths */
+	uint32_t                mp_dpathssz;    /* Length of mp_dpaths */
+	uint32_t                mp_rsvd1;
+	uint64_t                mp_rsvd2;
+	char __user            *mp_dpaths;      /* Newline separated paths */
+	struct pd_prop __user  *mp_pd_prop;     /* mp_dpathc elements */
+};
+
+/**
+ * struct mpioc_params -
+ * @mps_params;
+ */
+struct mpioc_params {
+	struct mpool_params     mps_params;
+};
+
+struct mpioc_mclass {
+	struct mpool_mclass_xprops __user  *mcl_xprops;
+	uint32_t                            mcl_cnt;
+	uint32_t                            mcl_rsvd1;
+};
+
+struct mpioc_drive {
+	uint32_t	        drv_flags;   /* mp_mgmt_flags */
+	uint32_t	        drv_rsvd1;
+	uint32_t                drv_dpathc;  /* Count of device paths */
+	uint32_t                drv_dpathssz;/* Length of mp_dpaths */
+	struct pd_prop __user  *drv_pd_prop; /* mp_dpathc elements */
+	char __user            *drv_dpaths;  /* Newline separated device paths*/
+};
+
+enum mpioc_list_cmd {
+	MPIOC_LIST_CMD_INVALID     = 0,
+	MPIOC_LIST_CMD_PROP_GET    = 1,       /* Used by mpool get command */
+	MPIOC_LIST_CMD_PROP_LIST   = 2,       /* Used by mpool list command */
+	MPIOC_LIST_CMD_LAST = MPIOC_LIST_CMD_PROP_LIST,
+};
+
+struct mpioc_list {
+	uint32_t        ls_cmd;     /* enum mpioc_list_cmd */
+	uint32_t        ls_listc;
+	void __user    *ls_listv;
+};
+
+struct mpioc_prop {
+	struct mpool_xprops         pr_xprops;
+	struct mpool_usage          pr_usage;
+	struct mpool_mclass_xprops  pr_mcxv[MP_MED_NUMBER];
+	uint32_t                    pr_mcxc;
+	uint32_t                    pr_rsvd1;
+	uint64_t                    pr_rsvd2;
+};
+
+struct mpioc_devprops {
+	char                    dpr_pdname[PD_NAMESZ_MAX];
+	struct mpool_devprops   dpr_devprops;
+};
+
+/**
+ * struct mpioc_mblock:
+ * @mb_objid:   mblock unique ID (permanent)
+ * @mb_offset:  mblock read offset (ephemeral)
+ * @mb_props:
+ * @mb_layout
+ * @mb_spare:
+ * @mb_mclassp: enum mp_media_classp, declared as uint8_t
+ */
+struct mpioc_mblock {
+	uint64_t                mb_objid;
+	int64_t                 mb_offset;
+	struct mblock_props_ex  mb_props;
+	uint8_t                 mb_spare;
+	uint8_t                 mb_mclassp;
+	uint16_t                mb_rsvd1;
+	uint32_t                mb_rsvd2;
+	uint64_t                mb_rsvd3;
+};
+
+struct mpioc_mblock_id {
+	uint64_t    mi_objid;
+};
+
+#define MPIOC_KIOV_MAX          (1024)
+
+struct mpioc_mblock_rw {
+	uint64_t                    mb_objid;
+	int64_t                     mb_offset;
+	uint32_t                    mb_rsvd2;
+	uint16_t                    mb_rsvd3;
+	uint16_t                    mb_iov_cnt;
+	const struct iovec __user  *mb_iov;
+};
+
+struct mpioc_mlog {
+	uint64_t                ml_objid;
+	uint64_t                ml_rsvd;
+	struct mlog_props_ex    ml_props;
+	struct mlog_capacity    ml_cap;
+	uint8_t                 ml_mclassp; /* enum mp_media_classp */
+	uint8_t                 ml_rsvd1[7];
+	uint64_t                ml_rsvd2;
+};
+
+struct mpioc_mlog_id {
+	uint64_t    mi_objid;
+	uint64_t    mi_gen;
+	uint8_t     mi_state;
+	uint8_t     mi_rsvd1[7];
+};
+
+struct mpioc_mlog_io {
+	uint64_t                mi_objid;
+	int64_t                 mi_off;
+	uint8_t                 mi_op;
+	uint8_t                 mi_rsvd1[5];
+	uint16_t                mi_iovc;
+	struct iovec __user    *mi_iov;
+	uint64_t                mi_rsvd2;
+};
+
+struct mpioc_vma {
+	uint32_t            im_advice;
+	uint32_t            im_mbidc;
+	uint64_t __user    *im_mbidv;
+	uint64_t            im_bktsz;
+	int64_t             im_offset;
+	uint64_t            im_len;
+	uint64_t            im_vssp;
+	uint64_t            im_rssp;
+	uint64_t            im_rsvd;
+};
+
+union mpioc_union {
+	struct mpioc_mpool      mpu_mpool;
+	struct mpioc_drive      mpu_drive;
+	struct mpioc_params     mpu_params;
+	struct mpioc_mclass     mpu_mclass;
+	struct mpioc_list       mpu_list;
+	struct mpioc_prop       mpu_prop;
+	struct mpioc_devprops   mpu_devprops;
+	struct mpioc_mlog       mpu_mlog;
+	struct mpioc_mlog_id    mpu_mlog_id;
+	struct mpioc_mlog_io    mpu_mlog_io;
+	struct mpioc_mblock     mpu_mblock;
+	struct mpioc_mblock_id  mpu_mblock_id;
+	struct mpioc_mblock_rw  mpu_mblock_rw;
+	struct mpioc_vma        mpu_vma;
+};
+
+#define MPIOC_MAGIC             ('2')
+
+#define MPIOC_MP_CREATE         _IOWR(MPIOC_MAGIC, 1, struct mpioc_mpool)
+#define MPIOC_MP_DESTROY        _IOW(MPIOC_MAGIC, 2, struct mpioc_mpool)
+#define MPIOC_MP_ACTIVATE       _IOWR(MPIOC_MAGIC, 5, struct mpioc_mpool)
+#define MPIOC_MP_DEACTIVATE     _IOW(MPIOC_MAGIC, 6, struct mpioc_mpool)
+#define MPIOC_MP_RENAME         _IOWR(MPIOC_MAGIC, 7, struct mpioc_mpool)
+
+#define MPIOC_PARAMS_GET        _IOWR(MPIOC_MAGIC, 10, struct mpioc_params)
+#define MPIOC_PARAMS_SET        _IOWR(MPIOC_MAGIC, 11, struct mpioc_params)
+#define MPIOC_MP_MCLASS_GET     _IOWR(MPIOC_MAGIC, 12, struct mpioc_mclass)
+
+#define MPIOC_DRV_ADD           _IOWR(MPIOC_MAGIC, 15, struct mpioc_drive)
+#define MPIOC_DRV_SPARES        _IOWR(MPIOC_MAGIC, 16, struct mpioc_drive)
+
+#define MPIOC_PROP_GET          _IOWR(MPIOC_MAGIC, 20, struct mpioc_list)
+#define MPIOC_PROP_SET          _IOWR(MPIOC_MAGIC, 21, struct mpioc_list)
+#define MPIOC_DEVPROPS_GET      _IOWR(MPIOC_MAGIC, 22, struct mpioc_devprops)
+
+#define MPIOC_MLOG_ALLOC        _IOWR(MPIOC_MAGIC, 30, struct mpioc_mlog)
+#define MPIOC_MLOG_COMMIT       _IOWR(MPIOC_MAGIC, 32, struct mpioc_mlog_id)
+#define MPIOC_MLOG_ABORT        _IOW(MPIOC_MAGIC, 33, struct mpioc_mlog_id)
+#define MPIOC_MLOG_DELETE       _IOW(MPIOC_MAGIC, 34, struct mpioc_mlog_id)
+#define MPIOC_MLOG_FIND         _IOWR(MPIOC_MAGIC, 37, struct mpioc_mlog)
+#define MPIOC_MLOG_READ         _IOW(MPIOC_MAGIC, 40, struct mpioc_mlog_io)
+#define MPIOC_MLOG_WRITE        _IOW(MPIOC_MAGIC, 41, struct mpioc_mlog_io)
+#define MPIOC_MLOG_PROPS        _IOWR(MPIOC_MAGIC, 42, struct mpioc_mlog)
+#define MPIOC_MLOG_ERASE        _IOWR(MPIOC_MAGIC, 43, struct mpioc_mlog_id)
+
+#define MPIOC_MB_ALLOC          _IOWR(MPIOC_MAGIC, 50, struct mpioc_mblock)
+#define MPIOC_MB_ABORT          _IOW(MPIOC_MAGIC, 52, struct mpioc_mblock_id)
+#define MPIOC_MB_COMMIT         _IOW(MPIOC_MAGIC, 53, struct mpioc_mblock_id)
+#define MPIOC_MB_DELETE         _IOW(MPIOC_MAGIC, 54, struct mpioc_mblock_id)
+#define MPIOC_MB_FIND           _IOWR(MPIOC_MAGIC, 56, struct mpioc_mblock)
+#define MPIOC_MB_READ           _IOW(MPIOC_MAGIC, 60, struct mpioc_mblock_rw)
+#define MPIOC_MB_WRITE          _IOW(MPIOC_MAGIC, 61, struct mpioc_mblock_rw)
+
+#define MPIOC_VMA_CREATE        _IOWR(MPIOC_MAGIC, 70, struct mpioc_vma)
+#define MPIOC_VMA_DESTROY       _IOW(MPIOC_MAGIC, 71, struct mpioc_vma)
+#define MPIOC_VMA_PURGE         _IOW(MPIOC_MAGIC, 72, struct mpioc_vma)
+#define MPIOC_VMA_VRSS          _IOWR(MPIOC_MAGIC, 73, struct mpioc_vma)
+
+#endif
diff --git a/drivers/mpool/mpool_printk.h b/drivers/mpool/mpool_printk.h
new file mode 100644
index 000000000000..280a8e064115
--- /dev/null
+++ b/drivers/mpool/mpool_printk.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2015-2020 Micron Technology, Inc.  All rights reserved.
+ */
+
+#ifndef MPOOL_PRINTK_H
+#define MPOOL_PRINTK_H
+
+#include <linux/printk.h>
+
+static unsigned long mp_pr_rl_state __maybe_unused;
+
+/* TODO: Use dev_crit(), dev_err(), ... */
+
+#define mp_pr_crit(_fmt, _err, ...)				\
+	pr_crit("%s: " _fmt ": errno %d", __func__, ## __VA_ARGS__, (_err))
+
+#define mp_pr_err(_fmt, _err, ...)				\
+	pr_err("%s: " _fmt ": errno %d", __func__, ## __VA_ARGS__, (_err))
+
+#define mp_pr_warn(_fmt, ...)					\
+	pr_warn("%s: " _fmt, __func__, ## __VA_ARGS__)
+
+#define mp_pr_notice(_fmt, ...)					\
+	pr_notice("%s: " _fmt, __func__, ## __VA_ARGS__)
+
+#define mp_pr_info(_fmt, ...)					\
+	pr_info("%s: " _fmt, __func__, ## __VA_ARGS__)
+
+#define mp_pr_debug(_fmt, _err, ...)				\
+	pr_debug("%s: " _fmt ": errno %d", __func__, ## __VA_ARGS__,  (_err))
+
+
+/* Rate limited version of mp_pr_err(). */
+#define mp_pr_rl(_fmt, _err, ...)				\
+do {								\
+	if (printk_timed_ratelimit(&mp_pr_rl_state, 333)) {	\
+		pr_err("%s: " _fmt ": errno %d",		\
+		       __func__, ## __VA_ARGS__, (_err));	\
+	}							\
+} while (0)
+
+#endif /* MPOOL_PRINTK_H */
diff --git a/drivers/mpool/uuid.h b/drivers/mpool/uuid.h
new file mode 100644
index 000000000000..28e53be68662
--- /dev/null
+++ b/drivers/mpool/uuid.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2015-2020 Micron Technology, Inc.  All rights reserved.
+ */
+
+#ifndef MPOOL_UUID_H
+#define MPOOL_UUID_H
+
+#define MPOOL_UUID_SIZE        16
+#define MPOOL_UUID_STRING_LEN  36
+
+#include <linux/kernel.h>
+#include <linux/uuid.h>
+
+struct mpool_uuid {
+	unsigned char uuid[MPOOL_UUID_SIZE];
+};
+
+/* mpool_uuid uses the LE version in the kernel */
+static inline void mpool_generate_uuid(struct mpool_uuid *uuid)
+{
+	generate_random_guid(uuid->uuid);
+}
+
+static inline void mpool_uuid_copy(struct mpool_uuid *u_dst, const struct mpool_uuid *u_src)
+{
+	memcpy(u_dst->uuid, u_src->uuid, MPOOL_UUID_SIZE);
+}
+
+static inline int mpool_uuid_compare(const struct mpool_uuid *uuid1, const struct mpool_uuid *uuid2)
+{
+	return memcmp(uuid1, uuid2, MPOOL_UUID_SIZE);
+}
+
+static inline void mpool_uuid_clear(struct mpool_uuid *uuid)
+{
+	memset(uuid->uuid, 0, MPOOL_UUID_SIZE);
+}
+
+static inline int mpool_uuid_is_null(const struct mpool_uuid *uuid)
+{
+	const struct mpool_uuid zero = { };
+
+	return !memcmp(&zero, uuid, sizeof(zero));
+}
+
+static inline void mpool_unparse_uuid(const struct mpool_uuid *uuid, char *dst)
+{
+	const unsigned char *u = uuid->uuid;
+
+	snprintf(dst, MPOOL_UUID_STRING_LEN + 1,
+		 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+		 u[0], u[1], u[2], u[3],
+		 u[4], u[5], u[6], u[7],
+		 u[8], u[9], u[10], u[11],
+		 u[12], u[13], u[14], u[15]);
+}
+
+#endif /* MPOOL_UUID_H */
-- 
2.17.2
_______________________________________________
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-leave@lists.01.org

WARNING: multiple messages have this Message-ID (diff)
From: Nabeel M Mohamed <nmeeramohide@micron.com>
To: <linux-kernel@vger.kernel.org>, <linux-block@vger.kernel.org>,
	<linux-nvme@lists.infradead.org>, <linux-mm@kvack.org>,
	<linux-nvdimm@lists.01.org>
Cc: <smoyer@micron.com>, <gbecker@micron.com>, <plabat@micron.com>,
	<jgroves@micron.com>, Nabeel M Mohamed <nmeeramohide@micron.com>
Subject: [PATCH v2 01/22] mpool: add utility routines and ioctl definitions
Date: Mon, 12 Oct 2020 11:27:15 -0500	[thread overview]
Message-ID: <20201012162736.65241-2-nmeeramohide@micron.com> (raw)
In-Reply-To: <20201012162736.65241-1-nmeeramohide@micron.com>

This adds structures used by mpool ioctls and utility routines
for logging, UUID management etc.

The mpool ioctls can be categorized as follows:

1. IOCTLs issued to the mpool control device (/dev/mpoolctl)
   - Mpool life cycle management (MPIOC_MP_*)

2. IOCTLs issued to the mpool device (/dev/mpool/<mpool-name>)
   - Mpool parameters (MPIOC_PARAMS_*)
   - Mpool properties (MPIOC_PROP_*)
   - Mpool media class management (MPIOC_MP_MCLASS_*)
   - Device management (MPIOC_DRV_*)
   - Mblock object life cycle management and IO (MPIOC_MB_*)
   - Mlog object life cycle management and IO (MPIOC_MLOG_*)
   - Mblock cache management (MPIOC_VMA_*)

Co-developed-by: Greg Becker <gbecker@micron.com>
Signed-off-by: Greg Becker <gbecker@micron.com>
Co-developed-by: Pierre Labat <plabat@micron.com>
Signed-off-by: Pierre Labat <plabat@micron.com>
Co-developed-by: John Groves <jgroves@micron.com>
Signed-off-by: John Groves <jgroves@micron.com>
Signed-off-by: Nabeel M Mohamed <nmeeramohide@micron.com>
---
 drivers/mpool/assert.h       |  25 ++
 drivers/mpool/init.c         |  22 ++
 drivers/mpool/mpool_ioctl.h  | 636 +++++++++++++++++++++++++++++++++++
 drivers/mpool/mpool_printk.h |  43 +++
 drivers/mpool/uuid.h         |  59 ++++
 5 files changed, 785 insertions(+)
 create mode 100644 drivers/mpool/assert.h
 create mode 100644 drivers/mpool/init.c
 create mode 100644 drivers/mpool/mpool_ioctl.h
 create mode 100644 drivers/mpool/mpool_printk.h
 create mode 100644 drivers/mpool/uuid.h

diff --git a/drivers/mpool/assert.h b/drivers/mpool/assert.h
new file mode 100644
index 000000000000..a2081e71ec93
--- /dev/null
+++ b/drivers/mpool/assert.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2015-2020 Micron Technology, Inc.  All rights reserved.
+ */
+
+#ifndef MPOOL_ASSERT_H
+#define MPOOL_ASSERT_H
+
+#include <linux/bug.h>
+
+#ifdef CONFIG_MPOOL_ASSERT
+__cold __noreturn
+static inline void assertfail(const char *expr, const char *file, int line)
+{
+	pr_err("mpool assertion failed: %s in %s:%d\n", expr, file, line);
+	BUG();
+}
+
+#define ASSERT(_expr)   (likely(_expr) ? (void)0 : assertfail(#_expr, __FILE__, __LINE__))
+
+#else
+#define ASSERT(_expr)   (void)(_expr)
+#endif
+
+#endif /* MPOOL_ASSERT_H */
diff --git a/drivers/mpool/init.c b/drivers/mpool/init.c
new file mode 100644
index 000000000000..0493fb5b1157
--- /dev/null
+++ b/drivers/mpool/init.c
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2015-2020 Micron Technology, Inc.  All rights reserved.
+ */
+
+#include <linux/module.h>
+
+static __init int mpool_init(void)
+{
+	return 0;
+}
+
+static __exit void mpool_exit(void)
+{
+}
+
+module_init(mpool_init);
+module_exit(mpool_exit);
+
+MODULE_DESCRIPTION("Object Storage Media Pool (mpool)");
+MODULE_AUTHOR("Micron Technology, Inc.");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mpool/mpool_ioctl.h b/drivers/mpool/mpool_ioctl.h
new file mode 100644
index 000000000000..599da0618a09
--- /dev/null
+++ b/drivers/mpool/mpool_ioctl.h
@@ -0,0 +1,636 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (C) 2015-2020 Micron Technology, Inc.  All rights reserved.
+ */
+
+#ifndef MPOOL_IOCTL_H
+#define MPOOL_IOCTL_H
+
+#include <linux/uuid.h>
+#include <linux/uio.h>
+
+#ifndef __user
+#define __user
+#endif
+
+/*
+ * Maximum name lengths including NUL terminator.  Note that the maximum
+ * mpool name length is baked into libblkid and may not be changed here.
+ */
+#define MPOOL_NAMESZ_MAX            32
+#define MPOOL_LABELSZ_MAX           64
+#define PD_NAMESZ_MAX               32
+
+#define MPC_DEV_SUBDIR              "mpool"
+#define MPC_DEV_CTLNAME             MPC_DEV_SUBDIR "ctl"
+#define MPC_DEV_CTLPATH             "/dev/" MPC_DEV_CTLNAME
+
+#define MPOOL_LABEL_INVALID         ""
+#define MPOOL_LABEL_DEFAULT         "raw"
+
+#define MPOOL_RA_PAGES_INVALID      U32_MAX
+#define MPOOL_RA_PAGES_MAX          ((128 * 1024) / PAGE_SIZE)
+
+#define MPOOL_MCLASS_INVALID        MP_MED_INVALID
+#define MPOOL_MCLASS_DEFAULT        MP_MED_CAPACITY
+
+#define MPOOL_SPARES_INVALID        U8_MAX
+#define MPOOL_SPARES_DEFAULT        5
+
+#define MPOOL_ROOT_LOG_CAP          (8 * 1024 * 1024)
+
+#define MPOOL_MBSIZE_MB_DEFAULT     32
+
+#define MPOOL_MDCNUM_DEFAULT        16
+
+
+/**
+ * mp_mgmt_flags - Mpool Management Flags
+ * @MP_FLAGS_FORCE:
+ * @MP_PERMIT_META_CONV: permit mpool metadata conversion. That is, allow the
+ *	mpool activate to write back the mpool metadata to the latest version
+ *	used by the binary activating the mpool.
+ * @MP_FLAGS_RESIZE: Resize mpool
+ */
+enum mp_mgmt_flags {
+	MP_FLAGS_FORCE,
+	MP_FLAGS_PERMIT_META_CONV,
+	MP_FLAGS_RESIZE,
+};
+
+/**
+ * mp_media_classp = Media classes
+ *
+ * @MP_MED_STAGING:  Initial data ingest, hot data storage, or similar.
+ * @MP_MED_CAPACITY: Primary data storage, cold data, or similar.
+ */
+enum mp_media_classp {
+	MP_MED_STAGING   = 0,
+	MP_MED_CAPACITY  = 1,
+};
+
+#define MP_MED_BASE        MP_MED_STAGING
+#define MP_MED_NUMBER      (MP_MED_CAPACITY + 1)
+#define MP_MED_INVALID     U8_MAX
+
+/**
+ * struct mpool_devprops -
+ * @pdp_devid:   UUID for drive
+ * @pdp_mclassp: enum mp_media_classp
+ * @pdp_status:  enum pd_status
+ * @pdp_total:   raw capacity of drive
+ * @pdp_avail:   available capacity (total - bad zones) of drive
+ * @pdp_spare:   spare capacity of drive
+ * @pdp_fspare:  free spare capacity of drive
+ * @pdp_usable:  usable capacity of drive
+ * @pdp_fusable: free usable capacity of drive
+ * @pdp_used:    used capacity of drive:
+ */
+struct mpool_devprops {
+	uuid_le    pdp_devid;
+	uint8_t    pdp_mclassp;
+	uint8_t    pdp_status;
+	uint8_t    pdp_rsvd1[6];
+	uint64_t   pdp_total;
+	uint64_t   pdp_avail;
+	uint64_t   pdp_spare;
+	uint64_t   pdp_fspare;
+	uint64_t   pdp_usable;
+	uint64_t   pdp_fusable;
+	uint64_t   pdp_used;
+	uint64_t   pdp_rsvd2;
+};
+
+/**
+ * struct mpool_params -
+ * @mp_poolid:          UUID of mpool
+ * @mp_type:            user-specified identifier
+ * @mp_uid:
+ * @mp_gid:
+ * @mp_mode:
+ * @mp_stat:            overall mpool status (enum mpool_status)
+ * @mp_mdc_captgt:      user MDC capacity
+ * @mp_oidv:            user MDC OIDs
+ * @mp_ra_pages_max:    max VMA map readahead pages
+ * @mp_vma_size_max:    max VMA map size (log2)
+ * @mp_mblocksz:        mblock size by media class (MiB)
+ * @mp_utype:           user-defined type
+ * @mp_label:           user specified label
+ * @mp_name:            mpool name (2x for planned expansion)
+ */
+struct mpool_params {
+	uuid_le     mp_poolid;
+	uid_t       mp_uid;
+	gid_t       mp_gid;
+	mode_t      mp_mode;
+	uint8_t     mp_stat;
+	uint8_t     mp_spare_cap;
+	uint8_t     mp_spare_stg;
+	uint8_t     mp_rsvd0;
+	uint64_t    mp_mdc_captgt;
+	uint64_t    mp_oidv[2];
+	uint32_t    mp_ra_pages_max;
+	uint32_t    mp_vma_size_max;
+	uint32_t    mp_mblocksz[MP_MED_NUMBER];
+	uint16_t    mp_mdc0cap;
+	uint16_t    mp_mdcncap;
+	uint16_t    mp_mdcnum;
+	uint16_t    mp_rsvd1;
+	uint32_t    mp_rsvd2;
+	uint64_t    mp_rsvd3;
+	uint64_t    mp_rsvd4;
+	uuid_le     mp_utype;
+	char        mp_label[MPOOL_LABELSZ_MAX];
+	char        mp_name[MPOOL_NAMESZ_MAX * 2];
+};
+
+/**
+ * struct mpool_usage - in bytes
+ * @mpu_total:   raw capacity for all drives
+ * @mpu_usable:  usable capacity for all drives
+ * @mpu_fusable: free usable capacity for all drives
+ * @mpu_used:    used capacity for all drives; possible for
+ *               used > usable when fusable=0; see smap
+ *               module for details
+ * @mpu_spare:   total spare space
+ * @mpu_fspare:  free spare space
+ *
+ * @mpu_mblock_alen: mblock allocated length
+ * @mpu_mblock_wlen: mblock written length
+ * @mpu_mlog_alen:   mlog allocated length
+ * @mpu_mblock_cnt:  number of active mblocks
+ * @mpu_mlog_cnt:    number of active mlogs
+ */
+struct mpool_usage {
+	uint64_t   mpu_total;
+	uint64_t   mpu_usable;
+	uint64_t   mpu_fusable;
+	uint64_t   mpu_used;
+	uint64_t   mpu_spare;
+	uint64_t   mpu_fspare;
+
+	uint64_t   mpu_alen;
+	uint64_t   mpu_wlen;
+	uint64_t   mpu_mblock_alen;
+	uint64_t   mpu_mblock_wlen;
+	uint64_t   mpu_mlog_alen;
+	uint32_t   mpu_mblock_cnt;
+	uint32_t   mpu_mlog_cnt;
+};
+
+/**
+ * mpool_mclass_xprops -
+ * @mc_devtype: type of devices in the media class
+ *                  (enum pd_devtype)
+ * @mc_mclass: media class (enum mp_media_classp)
+ * @mc_sectorsz: media class (enum mp_media_classp)
+ * @mc_spare: percent spare zones for drives
+ * @mc_uacnt: UNAVAIL status drive count
+ * @mc_zonepg: pages per zone
+ * @mc_features: feature bitmask
+ * @mc_usage: feature bitmask
+ */
+struct mpool_mclass_xprops {
+	uint8_t                    mc_devtype;
+	uint8_t                    mc_mclass;
+	uint8_t                    mc_sectorsz;
+	uint8_t                    mc_rsvd1;
+	uint32_t                   mc_spare;
+	uint16_t                   mc_uacnt;
+	uint16_t                   mc_rsvd2;
+	uint32_t                   mc_zonepg;
+	uint64_t                   mc_features;
+	uint64_t                   mc_rsvd3;
+	struct mpool_usage         mc_usage;
+};
+
+/**
+ * mpool_mclass_props -
+ *
+ * @mc_mblocksz:   mblock size in MiB
+ * @mc_rsvd:       reserved struct field (for future use)
+ * @mc_total:      total space in the media class (mc_usable + mc_spare)
+ * @mc_usable:     usable space in bytes
+ * @mc_used:       bytes allocated from usable space
+ * @mc_spare:      spare space in bytes
+ * @mc_spare_used: bytes allocated from spare space
+ */
+struct mpool_mclass_props {
+	uint32_t   mc_mblocksz;
+	uint32_t   mc_rsvd;
+	uint64_t   mc_total;
+	uint64_t   mc_usable;
+	uint64_t   mc_used;
+	uint64_t   mc_spare;
+	uint64_t   mc_spare_used;
+};
+
+/**
+ * struct mpool_xprops - Extended mpool properties
+ * @ppx_params: mpool configuration parameters
+ * @ppx_drive_spares: percent spare zones for drives in each media class
+ * @ppx_uacnt:  UNAVAIL status drive count in each media class
+ */
+struct mpool_xprops {
+	struct mpool_params     ppx_params;
+	uint8_t                 ppx_rsvd[MP_MED_NUMBER];
+	uint8_t                 ppx_drive_spares[MP_MED_NUMBER];
+	uint16_t                ppx_uacnt[MP_MED_NUMBER];
+	uint32_t                ppx_pd_mclassv[MP_MED_NUMBER];
+	char                    ppx_pd_namev[MP_MED_NUMBER][PD_NAMESZ_MAX];
+};
+
+
+/*
+ * struct mblock_props -
+ *
+ * @mpr_objid:        mblock identifier
+ * @mpr_alloc_cap:    allocated capacity in bytes
+ * @mpr_write_len:    written user-data in bytes
+ * @mpr_optimal_wrsz: optimal write size(in bytes) for all but the last incremental mblock write
+ * @mpr_mclassp:      media class
+ * @mpr_iscommitted:  Is this mblock committed?
+ */
+struct mblock_props {
+	uint64_t                mpr_objid;
+	uint32_t                mpr_alloc_cap;
+	uint32_t                mpr_write_len;
+	uint32_t                mpr_optimal_wrsz;
+	uint32_t                mpr_mclassp; /* enum mp_media_classp */
+	uint8_t                 mpr_iscommitted;
+	uint8_t                 mpr_rsvd1[7];
+	uint64_t                mpr_rsvd2;
+};
+
+struct mblock_props_ex {
+	struct mblock_props     mbx_props;
+	uint8_t                 mbx_zonecnt;      /* zone count per strip */
+	uint8_t                 mbx_rsvd1[7];
+	uint64_t                mbx_rsvd2;
+};
+
+
+/*
+ * enum mlog_open_flags -
+ * @MLOG_OF_COMPACT_SEM: Enforce compaction semantics
+ * @MLOG_OF_SKIP_SER:    Appends and reads are guaranteed to be serialized
+ *                       outside of the mlog API
+ */
+enum mlog_open_flags {
+	MLOG_OF_COMPACT_SEM = 0x1,
+	MLOG_OF_SKIP_SER    = 0x2,
+};
+
+/*
+ * NOTE:
+ * + a value of 0 for targets (*tgt) means no specific target and the
+ *   allocator is free to choose based on media class configuration
+ */
+struct mlog_capacity {
+	uint64_t    lcp_captgt;       /* capacity target for mlog in bytes */
+	uint8_t     lcp_spare;        /* true if alloc mlog from spare space */
+	uint8_t     lcp_rsvd1[7];
+};
+
+/*
+ * struct mlog_props -
+ *
+ * @lpr_uuid:        UUID or mlog magic
+ * @lpr_objid:       mlog identifier
+ * @lpr_alloc_cap:   maximum capacity in bytes
+ * @lpr_gen:         generation no. (user mlogs)
+ * @lpr_mclassp:     media class
+ * @lpr_iscommitted: Is this mlog committed?
+ */
+struct mlog_props {
+	uuid_le     lpr_uuid;
+	uint64_t    lpr_objid;
+	uint64_t    lpr_alloc_cap;
+	uint64_t    lpr_gen;
+	uint8_t     lpr_mclassp;
+	uint8_t     lpr_iscommitted;
+	uint8_t     lpr_rsvd1[6];
+	uint64_t    lpr_rsvd2;
+};
+
+/*
+ * struct mlog_props_ex -
+ *
+ * @lpx_props:
+ * @lpx_totsec:   total number of sectors
+ * @lpx_zonecnt:   zone count per strip
+ * @lpx_state:    mlog layout state
+ * @lpx_secshift: sector shift
+ */
+struct mlog_props_ex {
+	struct mlog_props   lpx_props;
+	uint32_t            lpx_totsec;
+	uint32_t            lpx_zonecnt;
+	uint8_t             lpx_state;
+	uint8_t             lpx_secshift;
+	uint8_t             lpx_rsvd1[6];
+	uint64_t            lpx_rsvd2;
+};
+
+
+/**
+ * enum mdc_open_flags -
+ * @MDC_OF_SKIP_SER: appends and reads are guaranteed to be serialized
+ *                   outside of the MDC API
+ */
+enum mdc_open_flags {
+	MDC_OF_SKIP_SER  = 0x1,
+};
+
+/**
+ * struct mdc_capacity -
+ * @mdt_captgt: capacity target for mlog in bytes
+ * @mpt_spare:  true if alloc MDC from spare space
+ */
+struct mdc_capacity {
+	uint64_t   mdt_captgt;
+	bool       mdt_spare;
+};
+
+/**
+ * struct mdc_props -
+ * @mdc_objid1:
+ * @mdc_objid2:
+ * @mdc_alloc_cap:
+ * @mdc_mclassp:
+ */
+struct mdc_props {
+	uint64_t               mdc_objid1;
+	uint64_t               mdc_objid2;
+	uint64_t               mdc_alloc_cap;
+	enum mp_media_classp   mdc_mclassp;
+};
+
+
+/**
+ * enum mpc_vma_advice -
+ * @MPC_VMA_COLD:
+ * @MPC_VMA_WARM:
+ * @MPC_VMA_HOT:
+ * @MPC_VMA_PINNED:
+ */
+enum mpc_vma_advice {
+	MPC_VMA_COLD = 0,
+	MPC_VMA_WARM,
+	MPC_VMA_HOT,
+	MPC_VMA_PINNED
+};
+
+
+/**
+ * struct pd_znparam - zone parameter arg used in compute/set API functions
+ * @dvb_zonepg:     zone size in PAGE_SIZE units.
+ * @dvb_zonetot:    total number of zones
+ */
+struct pd_znparam {
+	uint32_t   dvb_zonepg;
+	uint32_t   dvb_zonetot;
+	uint64_t   dvb_rsvd1;
+};
+
+#define PD_DEV_ID_LEN              64
+
+/**
+ * struct pd_prop - PD properties
+ * @pdp_didstr:         drive id string (model)
+ * @pdp_devtype:	device type (enum pd_devtype)
+ * @pdp_phys_if:	physical interface of the drive
+ *			Determined by the device discovery.
+ *			(device_phys_if)
+ * @pdp_mclassp:        performance characteristic of the media class
+ *			Determined by the user, not by the device discovery.
+ *			(enum mp_media_classp)
+ * @pdp_cmdopt:         enum pd_cmd_opt. Features of the PD.
+ * @pdp_zparam:	zone parameters
+ * @pdp_discard_granularity: specified by
+ *	/sys/block/<disk>/queue/discard_granularity
+ * @pdp_sectorsz:	Sector size, exponent base 2
+ * @pdp_optiosz:        Optimal IO size
+ * @pdp_devsz:		device size in bytes
+ *
+ * Note: in order to avoid passing enums across user-kernel boundary
+ * declare the following as uint8_t
+ * pdp_devtype: enum pd_devtype
+ * pdp_devstate: enum pd_state
+ * pdp_phys_if: enum device_phys_if
+ * pdp_mclassp: enum mp_media_classp
+ */
+struct pd_prop {
+	char		        pdp_didstr[PD_DEV_ID_LEN];
+	uint8_t                 pdp_devtype;
+	uint8_t                 pdp_devstate;
+	uint8_t                 pdp_phys_if;
+	uint8_t                 pdp_mclassp;
+	bool                    pdp_fua;
+	uint64_t                pdp_cmdopt;
+
+	struct pd_znparam       pdp_zparam;
+	uint32_t                pdp_discard_granularity;
+	uint32_t                pdp_sectorsz;
+	uint32_t                pdp_optiosz;
+	uint32_t                pdp_rsvd2;
+	uint64_t	        pdp_devsz;
+	uint64_t	        pdp_rsvd3;
+};
+
+
+struct mpioc_mpool {
+	struct mpool_params     mp_params;
+	uint32_t                mp_flags;       /* mp_mgmt_flags */
+	uint32_t                mp_dpathc;      /* Count of device paths */
+	uint32_t                mp_dpathssz;    /* Length of mp_dpaths */
+	uint32_t                mp_rsvd1;
+	uint64_t                mp_rsvd2;
+	char __user            *mp_dpaths;      /* Newline separated paths */
+	struct pd_prop __user  *mp_pd_prop;     /* mp_dpathc elements */
+};
+
+/**
+ * struct mpioc_params -
+ * @mps_params;
+ */
+struct mpioc_params {
+	struct mpool_params     mps_params;
+};
+
+struct mpioc_mclass {
+	struct mpool_mclass_xprops __user  *mcl_xprops;
+	uint32_t                            mcl_cnt;
+	uint32_t                            mcl_rsvd1;
+};
+
+struct mpioc_drive {
+	uint32_t	        drv_flags;   /* mp_mgmt_flags */
+	uint32_t	        drv_rsvd1;
+	uint32_t                drv_dpathc;  /* Count of device paths */
+	uint32_t                drv_dpathssz;/* Length of mp_dpaths */
+	struct pd_prop __user  *drv_pd_prop; /* mp_dpathc elements */
+	char __user            *drv_dpaths;  /* Newline separated device paths*/
+};
+
+enum mpioc_list_cmd {
+	MPIOC_LIST_CMD_INVALID     = 0,
+	MPIOC_LIST_CMD_PROP_GET    = 1,       /* Used by mpool get command */
+	MPIOC_LIST_CMD_PROP_LIST   = 2,       /* Used by mpool list command */
+	MPIOC_LIST_CMD_LAST = MPIOC_LIST_CMD_PROP_LIST,
+};
+
+struct mpioc_list {
+	uint32_t        ls_cmd;     /* enum mpioc_list_cmd */
+	uint32_t        ls_listc;
+	void __user    *ls_listv;
+};
+
+struct mpioc_prop {
+	struct mpool_xprops         pr_xprops;
+	struct mpool_usage          pr_usage;
+	struct mpool_mclass_xprops  pr_mcxv[MP_MED_NUMBER];
+	uint32_t                    pr_mcxc;
+	uint32_t                    pr_rsvd1;
+	uint64_t                    pr_rsvd2;
+};
+
+struct mpioc_devprops {
+	char                    dpr_pdname[PD_NAMESZ_MAX];
+	struct mpool_devprops   dpr_devprops;
+};
+
+/**
+ * struct mpioc_mblock:
+ * @mb_objid:   mblock unique ID (permanent)
+ * @mb_offset:  mblock read offset (ephemeral)
+ * @mb_props:
+ * @mb_layout
+ * @mb_spare:
+ * @mb_mclassp: enum mp_media_classp, declared as uint8_t
+ */
+struct mpioc_mblock {
+	uint64_t                mb_objid;
+	int64_t                 mb_offset;
+	struct mblock_props_ex  mb_props;
+	uint8_t                 mb_spare;
+	uint8_t                 mb_mclassp;
+	uint16_t                mb_rsvd1;
+	uint32_t                mb_rsvd2;
+	uint64_t                mb_rsvd3;
+};
+
+struct mpioc_mblock_id {
+	uint64_t    mi_objid;
+};
+
+#define MPIOC_KIOV_MAX          (1024)
+
+struct mpioc_mblock_rw {
+	uint64_t                    mb_objid;
+	int64_t                     mb_offset;
+	uint32_t                    mb_rsvd2;
+	uint16_t                    mb_rsvd3;
+	uint16_t                    mb_iov_cnt;
+	const struct iovec __user  *mb_iov;
+};
+
+struct mpioc_mlog {
+	uint64_t                ml_objid;
+	uint64_t                ml_rsvd;
+	struct mlog_props_ex    ml_props;
+	struct mlog_capacity    ml_cap;
+	uint8_t                 ml_mclassp; /* enum mp_media_classp */
+	uint8_t                 ml_rsvd1[7];
+	uint64_t                ml_rsvd2;
+};
+
+struct mpioc_mlog_id {
+	uint64_t    mi_objid;
+	uint64_t    mi_gen;
+	uint8_t     mi_state;
+	uint8_t     mi_rsvd1[7];
+};
+
+struct mpioc_mlog_io {
+	uint64_t                mi_objid;
+	int64_t                 mi_off;
+	uint8_t                 mi_op;
+	uint8_t                 mi_rsvd1[5];
+	uint16_t                mi_iovc;
+	struct iovec __user    *mi_iov;
+	uint64_t                mi_rsvd2;
+};
+
+struct mpioc_vma {
+	uint32_t            im_advice;
+	uint32_t            im_mbidc;
+	uint64_t __user    *im_mbidv;
+	uint64_t            im_bktsz;
+	int64_t             im_offset;
+	uint64_t            im_len;
+	uint64_t            im_vssp;
+	uint64_t            im_rssp;
+	uint64_t            im_rsvd;
+};
+
+union mpioc_union {
+	struct mpioc_mpool      mpu_mpool;
+	struct mpioc_drive      mpu_drive;
+	struct mpioc_params     mpu_params;
+	struct mpioc_mclass     mpu_mclass;
+	struct mpioc_list       mpu_list;
+	struct mpioc_prop       mpu_prop;
+	struct mpioc_devprops   mpu_devprops;
+	struct mpioc_mlog       mpu_mlog;
+	struct mpioc_mlog_id    mpu_mlog_id;
+	struct mpioc_mlog_io    mpu_mlog_io;
+	struct mpioc_mblock     mpu_mblock;
+	struct mpioc_mblock_id  mpu_mblock_id;
+	struct mpioc_mblock_rw  mpu_mblock_rw;
+	struct mpioc_vma        mpu_vma;
+};
+
+#define MPIOC_MAGIC             ('2')
+
+#define MPIOC_MP_CREATE         _IOWR(MPIOC_MAGIC, 1, struct mpioc_mpool)
+#define MPIOC_MP_DESTROY        _IOW(MPIOC_MAGIC, 2, struct mpioc_mpool)
+#define MPIOC_MP_ACTIVATE       _IOWR(MPIOC_MAGIC, 5, struct mpioc_mpool)
+#define MPIOC_MP_DEACTIVATE     _IOW(MPIOC_MAGIC, 6, struct mpioc_mpool)
+#define MPIOC_MP_RENAME         _IOWR(MPIOC_MAGIC, 7, struct mpioc_mpool)
+
+#define MPIOC_PARAMS_GET        _IOWR(MPIOC_MAGIC, 10, struct mpioc_params)
+#define MPIOC_PARAMS_SET        _IOWR(MPIOC_MAGIC, 11, struct mpioc_params)
+#define MPIOC_MP_MCLASS_GET     _IOWR(MPIOC_MAGIC, 12, struct mpioc_mclass)
+
+#define MPIOC_DRV_ADD           _IOWR(MPIOC_MAGIC, 15, struct mpioc_drive)
+#define MPIOC_DRV_SPARES        _IOWR(MPIOC_MAGIC, 16, struct mpioc_drive)
+
+#define MPIOC_PROP_GET          _IOWR(MPIOC_MAGIC, 20, struct mpioc_list)
+#define MPIOC_PROP_SET          _IOWR(MPIOC_MAGIC, 21, struct mpioc_list)
+#define MPIOC_DEVPROPS_GET      _IOWR(MPIOC_MAGIC, 22, struct mpioc_devprops)
+
+#define MPIOC_MLOG_ALLOC        _IOWR(MPIOC_MAGIC, 30, struct mpioc_mlog)
+#define MPIOC_MLOG_COMMIT       _IOWR(MPIOC_MAGIC, 32, struct mpioc_mlog_id)
+#define MPIOC_MLOG_ABORT        _IOW(MPIOC_MAGIC, 33, struct mpioc_mlog_id)
+#define MPIOC_MLOG_DELETE       _IOW(MPIOC_MAGIC, 34, struct mpioc_mlog_id)
+#define MPIOC_MLOG_FIND         _IOWR(MPIOC_MAGIC, 37, struct mpioc_mlog)
+#define MPIOC_MLOG_READ         _IOW(MPIOC_MAGIC, 40, struct mpioc_mlog_io)
+#define MPIOC_MLOG_WRITE        _IOW(MPIOC_MAGIC, 41, struct mpioc_mlog_io)
+#define MPIOC_MLOG_PROPS        _IOWR(MPIOC_MAGIC, 42, struct mpioc_mlog)
+#define MPIOC_MLOG_ERASE        _IOWR(MPIOC_MAGIC, 43, struct mpioc_mlog_id)
+
+#define MPIOC_MB_ALLOC          _IOWR(MPIOC_MAGIC, 50, struct mpioc_mblock)
+#define MPIOC_MB_ABORT          _IOW(MPIOC_MAGIC, 52, struct mpioc_mblock_id)
+#define MPIOC_MB_COMMIT         _IOW(MPIOC_MAGIC, 53, struct mpioc_mblock_id)
+#define MPIOC_MB_DELETE         _IOW(MPIOC_MAGIC, 54, struct mpioc_mblock_id)
+#define MPIOC_MB_FIND           _IOWR(MPIOC_MAGIC, 56, struct mpioc_mblock)
+#define MPIOC_MB_READ           _IOW(MPIOC_MAGIC, 60, struct mpioc_mblock_rw)
+#define MPIOC_MB_WRITE          _IOW(MPIOC_MAGIC, 61, struct mpioc_mblock_rw)
+
+#define MPIOC_VMA_CREATE        _IOWR(MPIOC_MAGIC, 70, struct mpioc_vma)
+#define MPIOC_VMA_DESTROY       _IOW(MPIOC_MAGIC, 71, struct mpioc_vma)
+#define MPIOC_VMA_PURGE         _IOW(MPIOC_MAGIC, 72, struct mpioc_vma)
+#define MPIOC_VMA_VRSS          _IOWR(MPIOC_MAGIC, 73, struct mpioc_vma)
+
+#endif
diff --git a/drivers/mpool/mpool_printk.h b/drivers/mpool/mpool_printk.h
new file mode 100644
index 000000000000..280a8e064115
--- /dev/null
+++ b/drivers/mpool/mpool_printk.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2015-2020 Micron Technology, Inc.  All rights reserved.
+ */
+
+#ifndef MPOOL_PRINTK_H
+#define MPOOL_PRINTK_H
+
+#include <linux/printk.h>
+
+static unsigned long mp_pr_rl_state __maybe_unused;
+
+/* TODO: Use dev_crit(), dev_err(), ... */
+
+#define mp_pr_crit(_fmt, _err, ...)				\
+	pr_crit("%s: " _fmt ": errno %d", __func__, ## __VA_ARGS__, (_err))
+
+#define mp_pr_err(_fmt, _err, ...)				\
+	pr_err("%s: " _fmt ": errno %d", __func__, ## __VA_ARGS__, (_err))
+
+#define mp_pr_warn(_fmt, ...)					\
+	pr_warn("%s: " _fmt, __func__, ## __VA_ARGS__)
+
+#define mp_pr_notice(_fmt, ...)					\
+	pr_notice("%s: " _fmt, __func__, ## __VA_ARGS__)
+
+#define mp_pr_info(_fmt, ...)					\
+	pr_info("%s: " _fmt, __func__, ## __VA_ARGS__)
+
+#define mp_pr_debug(_fmt, _err, ...)				\
+	pr_debug("%s: " _fmt ": errno %d", __func__, ## __VA_ARGS__,  (_err))
+
+
+/* Rate limited version of mp_pr_err(). */
+#define mp_pr_rl(_fmt, _err, ...)				\
+do {								\
+	if (printk_timed_ratelimit(&mp_pr_rl_state, 333)) {	\
+		pr_err("%s: " _fmt ": errno %d",		\
+		       __func__, ## __VA_ARGS__, (_err));	\
+	}							\
+} while (0)
+
+#endif /* MPOOL_PRINTK_H */
diff --git a/drivers/mpool/uuid.h b/drivers/mpool/uuid.h
new file mode 100644
index 000000000000..28e53be68662
--- /dev/null
+++ b/drivers/mpool/uuid.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2015-2020 Micron Technology, Inc.  All rights reserved.
+ */
+
+#ifndef MPOOL_UUID_H
+#define MPOOL_UUID_H
+
+#define MPOOL_UUID_SIZE        16
+#define MPOOL_UUID_STRING_LEN  36
+
+#include <linux/kernel.h>
+#include <linux/uuid.h>
+
+struct mpool_uuid {
+	unsigned char uuid[MPOOL_UUID_SIZE];
+};
+
+/* mpool_uuid uses the LE version in the kernel */
+static inline void mpool_generate_uuid(struct mpool_uuid *uuid)
+{
+	generate_random_guid(uuid->uuid);
+}
+
+static inline void mpool_uuid_copy(struct mpool_uuid *u_dst, const struct mpool_uuid *u_src)
+{
+	memcpy(u_dst->uuid, u_src->uuid, MPOOL_UUID_SIZE);
+}
+
+static inline int mpool_uuid_compare(const struct mpool_uuid *uuid1, const struct mpool_uuid *uuid2)
+{
+	return memcmp(uuid1, uuid2, MPOOL_UUID_SIZE);
+}
+
+static inline void mpool_uuid_clear(struct mpool_uuid *uuid)
+{
+	memset(uuid->uuid, 0, MPOOL_UUID_SIZE);
+}
+
+static inline int mpool_uuid_is_null(const struct mpool_uuid *uuid)
+{
+	const struct mpool_uuid zero = { };
+
+	return !memcmp(&zero, uuid, sizeof(zero));
+}
+
+static inline void mpool_unparse_uuid(const struct mpool_uuid *uuid, char *dst)
+{
+	const unsigned char *u = uuid->uuid;
+
+	snprintf(dst, MPOOL_UUID_STRING_LEN + 1,
+		 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+		 u[0], u[1], u[2], u[3],
+		 u[4], u[5], u[6], u[7],
+		 u[8], u[9], u[10], u[11],
+		 u[12], u[13], u[14], u[15]);
+}
+
+#endif /* MPOOL_UUID_H */
-- 
2.17.2


WARNING: multiple messages have this Message-ID (diff)
From: Nabeel M Mohamed <nmeeramohide@micron.com>
To: <linux-kernel@vger.kernel.org>, <linux-block@vger.kernel.org>,
	<linux-nvme@lists.infradead.org>, <linux-mm@kvack.org>,
	<linux-nvdimm@lists.01.org>
Cc: plabat@micron.com, smoyer@micron.com, jgroves@micron.com,
	gbecker@micron.com, Nabeel M Mohamed <nmeeramohide@micron.com>
Subject: [PATCH v2 01/22] mpool: add utility routines and ioctl definitions
Date: Mon, 12 Oct 2020 11:27:15 -0500	[thread overview]
Message-ID: <20201012162736.65241-2-nmeeramohide@micron.com> (raw)
In-Reply-To: <20201012162736.65241-1-nmeeramohide@micron.com>

This adds structures used by mpool ioctls and utility routines
for logging, UUID management etc.

The mpool ioctls can be categorized as follows:

1. IOCTLs issued to the mpool control device (/dev/mpoolctl)
   - Mpool life cycle management (MPIOC_MP_*)

2. IOCTLs issued to the mpool device (/dev/mpool/<mpool-name>)
   - Mpool parameters (MPIOC_PARAMS_*)
   - Mpool properties (MPIOC_PROP_*)
   - Mpool media class management (MPIOC_MP_MCLASS_*)
   - Device management (MPIOC_DRV_*)
   - Mblock object life cycle management and IO (MPIOC_MB_*)
   - Mlog object life cycle management and IO (MPIOC_MLOG_*)
   - Mblock cache management (MPIOC_VMA_*)

Co-developed-by: Greg Becker <gbecker@micron.com>
Signed-off-by: Greg Becker <gbecker@micron.com>
Co-developed-by: Pierre Labat <plabat@micron.com>
Signed-off-by: Pierre Labat <plabat@micron.com>
Co-developed-by: John Groves <jgroves@micron.com>
Signed-off-by: John Groves <jgroves@micron.com>
Signed-off-by: Nabeel M Mohamed <nmeeramohide@micron.com>
---
 drivers/mpool/assert.h       |  25 ++
 drivers/mpool/init.c         |  22 ++
 drivers/mpool/mpool_ioctl.h  | 636 +++++++++++++++++++++++++++++++++++
 drivers/mpool/mpool_printk.h |  43 +++
 drivers/mpool/uuid.h         |  59 ++++
 5 files changed, 785 insertions(+)
 create mode 100644 drivers/mpool/assert.h
 create mode 100644 drivers/mpool/init.c
 create mode 100644 drivers/mpool/mpool_ioctl.h
 create mode 100644 drivers/mpool/mpool_printk.h
 create mode 100644 drivers/mpool/uuid.h

diff --git a/drivers/mpool/assert.h b/drivers/mpool/assert.h
new file mode 100644
index 000000000000..a2081e71ec93
--- /dev/null
+++ b/drivers/mpool/assert.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2015-2020 Micron Technology, Inc.  All rights reserved.
+ */
+
+#ifndef MPOOL_ASSERT_H
+#define MPOOL_ASSERT_H
+
+#include <linux/bug.h>
+
+#ifdef CONFIG_MPOOL_ASSERT
+__cold __noreturn
+static inline void assertfail(const char *expr, const char *file, int line)
+{
+	pr_err("mpool assertion failed: %s in %s:%d\n", expr, file, line);
+	BUG();
+}
+
+#define ASSERT(_expr)   (likely(_expr) ? (void)0 : assertfail(#_expr, __FILE__, __LINE__))
+
+#else
+#define ASSERT(_expr)   (void)(_expr)
+#endif
+
+#endif /* MPOOL_ASSERT_H */
diff --git a/drivers/mpool/init.c b/drivers/mpool/init.c
new file mode 100644
index 000000000000..0493fb5b1157
--- /dev/null
+++ b/drivers/mpool/init.c
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2015-2020 Micron Technology, Inc.  All rights reserved.
+ */
+
+#include <linux/module.h>
+
+static __init int mpool_init(void)
+{
+	return 0;
+}
+
+static __exit void mpool_exit(void)
+{
+}
+
+module_init(mpool_init);
+module_exit(mpool_exit);
+
+MODULE_DESCRIPTION("Object Storage Media Pool (mpool)");
+MODULE_AUTHOR("Micron Technology, Inc.");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mpool/mpool_ioctl.h b/drivers/mpool/mpool_ioctl.h
new file mode 100644
index 000000000000..599da0618a09
--- /dev/null
+++ b/drivers/mpool/mpool_ioctl.h
@@ -0,0 +1,636 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (C) 2015-2020 Micron Technology, Inc.  All rights reserved.
+ */
+
+#ifndef MPOOL_IOCTL_H
+#define MPOOL_IOCTL_H
+
+#include <linux/uuid.h>
+#include <linux/uio.h>
+
+#ifndef __user
+#define __user
+#endif
+
+/*
+ * Maximum name lengths including NUL terminator.  Note that the maximum
+ * mpool name length is baked into libblkid and may not be changed here.
+ */
+#define MPOOL_NAMESZ_MAX            32
+#define MPOOL_LABELSZ_MAX           64
+#define PD_NAMESZ_MAX               32
+
+#define MPC_DEV_SUBDIR              "mpool"
+#define MPC_DEV_CTLNAME             MPC_DEV_SUBDIR "ctl"
+#define MPC_DEV_CTLPATH             "/dev/" MPC_DEV_CTLNAME
+
+#define MPOOL_LABEL_INVALID         ""
+#define MPOOL_LABEL_DEFAULT         "raw"
+
+#define MPOOL_RA_PAGES_INVALID      U32_MAX
+#define MPOOL_RA_PAGES_MAX          ((128 * 1024) / PAGE_SIZE)
+
+#define MPOOL_MCLASS_INVALID        MP_MED_INVALID
+#define MPOOL_MCLASS_DEFAULT        MP_MED_CAPACITY
+
+#define MPOOL_SPARES_INVALID        U8_MAX
+#define MPOOL_SPARES_DEFAULT        5
+
+#define MPOOL_ROOT_LOG_CAP          (8 * 1024 * 1024)
+
+#define MPOOL_MBSIZE_MB_DEFAULT     32
+
+#define MPOOL_MDCNUM_DEFAULT        16
+
+
+/**
+ * mp_mgmt_flags - Mpool Management Flags
+ * @MP_FLAGS_FORCE:
+ * @MP_PERMIT_META_CONV: permit mpool metadata conversion. That is, allow the
+ *	mpool activate to write back the mpool metadata to the latest version
+ *	used by the binary activating the mpool.
+ * @MP_FLAGS_RESIZE: Resize mpool
+ */
+enum mp_mgmt_flags {
+	MP_FLAGS_FORCE,
+	MP_FLAGS_PERMIT_META_CONV,
+	MP_FLAGS_RESIZE,
+};
+
+/**
+ * mp_media_classp = Media classes
+ *
+ * @MP_MED_STAGING:  Initial data ingest, hot data storage, or similar.
+ * @MP_MED_CAPACITY: Primary data storage, cold data, or similar.
+ */
+enum mp_media_classp {
+	MP_MED_STAGING   = 0,
+	MP_MED_CAPACITY  = 1,
+};
+
+#define MP_MED_BASE        MP_MED_STAGING
+#define MP_MED_NUMBER      (MP_MED_CAPACITY + 1)
+#define MP_MED_INVALID     U8_MAX
+
+/**
+ * struct mpool_devprops -
+ * @pdp_devid:   UUID for drive
+ * @pdp_mclassp: enum mp_media_classp
+ * @pdp_status:  enum pd_status
+ * @pdp_total:   raw capacity of drive
+ * @pdp_avail:   available capacity (total - bad zones) of drive
+ * @pdp_spare:   spare capacity of drive
+ * @pdp_fspare:  free spare capacity of drive
+ * @pdp_usable:  usable capacity of drive
+ * @pdp_fusable: free usable capacity of drive
+ * @pdp_used:    used capacity of drive:
+ */
+struct mpool_devprops {
+	uuid_le    pdp_devid;
+	uint8_t    pdp_mclassp;
+	uint8_t    pdp_status;
+	uint8_t    pdp_rsvd1[6];
+	uint64_t   pdp_total;
+	uint64_t   pdp_avail;
+	uint64_t   pdp_spare;
+	uint64_t   pdp_fspare;
+	uint64_t   pdp_usable;
+	uint64_t   pdp_fusable;
+	uint64_t   pdp_used;
+	uint64_t   pdp_rsvd2;
+};
+
+/**
+ * struct mpool_params -
+ * @mp_poolid:          UUID of mpool
+ * @mp_type:            user-specified identifier
+ * @mp_uid:
+ * @mp_gid:
+ * @mp_mode:
+ * @mp_stat:            overall mpool status (enum mpool_status)
+ * @mp_mdc_captgt:      user MDC capacity
+ * @mp_oidv:            user MDC OIDs
+ * @mp_ra_pages_max:    max VMA map readahead pages
+ * @mp_vma_size_max:    max VMA map size (log2)
+ * @mp_mblocksz:        mblock size by media class (MiB)
+ * @mp_utype:           user-defined type
+ * @mp_label:           user specified label
+ * @mp_name:            mpool name (2x for planned expansion)
+ */
+struct mpool_params {
+	uuid_le     mp_poolid;
+	uid_t       mp_uid;
+	gid_t       mp_gid;
+	mode_t      mp_mode;
+	uint8_t     mp_stat;
+	uint8_t     mp_spare_cap;
+	uint8_t     mp_spare_stg;
+	uint8_t     mp_rsvd0;
+	uint64_t    mp_mdc_captgt;
+	uint64_t    mp_oidv[2];
+	uint32_t    mp_ra_pages_max;
+	uint32_t    mp_vma_size_max;
+	uint32_t    mp_mblocksz[MP_MED_NUMBER];
+	uint16_t    mp_mdc0cap;
+	uint16_t    mp_mdcncap;
+	uint16_t    mp_mdcnum;
+	uint16_t    mp_rsvd1;
+	uint32_t    mp_rsvd2;
+	uint64_t    mp_rsvd3;
+	uint64_t    mp_rsvd4;
+	uuid_le     mp_utype;
+	char        mp_label[MPOOL_LABELSZ_MAX];
+	char        mp_name[MPOOL_NAMESZ_MAX * 2];
+};
+
+/**
+ * struct mpool_usage - in bytes
+ * @mpu_total:   raw capacity for all drives
+ * @mpu_usable:  usable capacity for all drives
+ * @mpu_fusable: free usable capacity for all drives
+ * @mpu_used:    used capacity for all drives; possible for
+ *               used > usable when fusable=0; see smap
+ *               module for details
+ * @mpu_spare:   total spare space
+ * @mpu_fspare:  free spare space
+ *
+ * @mpu_mblock_alen: mblock allocated length
+ * @mpu_mblock_wlen: mblock written length
+ * @mpu_mlog_alen:   mlog allocated length
+ * @mpu_mblock_cnt:  number of active mblocks
+ * @mpu_mlog_cnt:    number of active mlogs
+ */
+struct mpool_usage {
+	uint64_t   mpu_total;
+	uint64_t   mpu_usable;
+	uint64_t   mpu_fusable;
+	uint64_t   mpu_used;
+	uint64_t   mpu_spare;
+	uint64_t   mpu_fspare;
+
+	uint64_t   mpu_alen;
+	uint64_t   mpu_wlen;
+	uint64_t   mpu_mblock_alen;
+	uint64_t   mpu_mblock_wlen;
+	uint64_t   mpu_mlog_alen;
+	uint32_t   mpu_mblock_cnt;
+	uint32_t   mpu_mlog_cnt;
+};
+
+/**
+ * mpool_mclass_xprops -
+ * @mc_devtype: type of devices in the media class
+ *                  (enum pd_devtype)
+ * @mc_mclass: media class (enum mp_media_classp)
+ * @mc_sectorsz: media class (enum mp_media_classp)
+ * @mc_spare: percent spare zones for drives
+ * @mc_uacnt: UNAVAIL status drive count
+ * @mc_zonepg: pages per zone
+ * @mc_features: feature bitmask
+ * @mc_usage: feature bitmask
+ */
+struct mpool_mclass_xprops {
+	uint8_t                    mc_devtype;
+	uint8_t                    mc_mclass;
+	uint8_t                    mc_sectorsz;
+	uint8_t                    mc_rsvd1;
+	uint32_t                   mc_spare;
+	uint16_t                   mc_uacnt;
+	uint16_t                   mc_rsvd2;
+	uint32_t                   mc_zonepg;
+	uint64_t                   mc_features;
+	uint64_t                   mc_rsvd3;
+	struct mpool_usage         mc_usage;
+};
+
+/**
+ * mpool_mclass_props -
+ *
+ * @mc_mblocksz:   mblock size in MiB
+ * @mc_rsvd:       reserved struct field (for future use)
+ * @mc_total:      total space in the media class (mc_usable + mc_spare)
+ * @mc_usable:     usable space in bytes
+ * @mc_used:       bytes allocated from usable space
+ * @mc_spare:      spare space in bytes
+ * @mc_spare_used: bytes allocated from spare space
+ */
+struct mpool_mclass_props {
+	uint32_t   mc_mblocksz;
+	uint32_t   mc_rsvd;
+	uint64_t   mc_total;
+	uint64_t   mc_usable;
+	uint64_t   mc_used;
+	uint64_t   mc_spare;
+	uint64_t   mc_spare_used;
+};
+
+/**
+ * struct mpool_xprops - Extended mpool properties
+ * @ppx_params: mpool configuration parameters
+ * @ppx_drive_spares: percent spare zones for drives in each media class
+ * @ppx_uacnt:  UNAVAIL status drive count in each media class
+ */
+struct mpool_xprops {
+	struct mpool_params     ppx_params;
+	uint8_t                 ppx_rsvd[MP_MED_NUMBER];
+	uint8_t                 ppx_drive_spares[MP_MED_NUMBER];
+	uint16_t                ppx_uacnt[MP_MED_NUMBER];
+	uint32_t                ppx_pd_mclassv[MP_MED_NUMBER];
+	char                    ppx_pd_namev[MP_MED_NUMBER][PD_NAMESZ_MAX];
+};
+
+
+/*
+ * struct mblock_props -
+ *
+ * @mpr_objid:        mblock identifier
+ * @mpr_alloc_cap:    allocated capacity in bytes
+ * @mpr_write_len:    written user-data in bytes
+ * @mpr_optimal_wrsz: optimal write size(in bytes) for all but the last incremental mblock write
+ * @mpr_mclassp:      media class
+ * @mpr_iscommitted:  Is this mblock committed?
+ */
+struct mblock_props {
+	uint64_t                mpr_objid;
+	uint32_t                mpr_alloc_cap;
+	uint32_t                mpr_write_len;
+	uint32_t                mpr_optimal_wrsz;
+	uint32_t                mpr_mclassp; /* enum mp_media_classp */
+	uint8_t                 mpr_iscommitted;
+	uint8_t                 mpr_rsvd1[7];
+	uint64_t                mpr_rsvd2;
+};
+
+struct mblock_props_ex {
+	struct mblock_props     mbx_props;
+	uint8_t                 mbx_zonecnt;      /* zone count per strip */
+	uint8_t                 mbx_rsvd1[7];
+	uint64_t                mbx_rsvd2;
+};
+
+
+/*
+ * enum mlog_open_flags -
+ * @MLOG_OF_COMPACT_SEM: Enforce compaction semantics
+ * @MLOG_OF_SKIP_SER:    Appends and reads are guaranteed to be serialized
+ *                       outside of the mlog API
+ */
+enum mlog_open_flags {
+	MLOG_OF_COMPACT_SEM = 0x1,
+	MLOG_OF_SKIP_SER    = 0x2,
+};
+
+/*
+ * NOTE:
+ * + a value of 0 for targets (*tgt) means no specific target and the
+ *   allocator is free to choose based on media class configuration
+ */
+struct mlog_capacity {
+	uint64_t    lcp_captgt;       /* capacity target for mlog in bytes */
+	uint8_t     lcp_spare;        /* true if alloc mlog from spare space */
+	uint8_t     lcp_rsvd1[7];
+};
+
+/*
+ * struct mlog_props -
+ *
+ * @lpr_uuid:        UUID or mlog magic
+ * @lpr_objid:       mlog identifier
+ * @lpr_alloc_cap:   maximum capacity in bytes
+ * @lpr_gen:         generation no. (user mlogs)
+ * @lpr_mclassp:     media class
+ * @lpr_iscommitted: Is this mlog committed?
+ */
+struct mlog_props {
+	uuid_le     lpr_uuid;
+	uint64_t    lpr_objid;
+	uint64_t    lpr_alloc_cap;
+	uint64_t    lpr_gen;
+	uint8_t     lpr_mclassp;
+	uint8_t     lpr_iscommitted;
+	uint8_t     lpr_rsvd1[6];
+	uint64_t    lpr_rsvd2;
+};
+
+/*
+ * struct mlog_props_ex -
+ *
+ * @lpx_props:
+ * @lpx_totsec:   total number of sectors
+ * @lpx_zonecnt:   zone count per strip
+ * @lpx_state:    mlog layout state
+ * @lpx_secshift: sector shift
+ */
+struct mlog_props_ex {
+	struct mlog_props   lpx_props;
+	uint32_t            lpx_totsec;
+	uint32_t            lpx_zonecnt;
+	uint8_t             lpx_state;
+	uint8_t             lpx_secshift;
+	uint8_t             lpx_rsvd1[6];
+	uint64_t            lpx_rsvd2;
+};
+
+
+/**
+ * enum mdc_open_flags -
+ * @MDC_OF_SKIP_SER: appends and reads are guaranteed to be serialized
+ *                   outside of the MDC API
+ */
+enum mdc_open_flags {
+	MDC_OF_SKIP_SER  = 0x1,
+};
+
+/**
+ * struct mdc_capacity -
+ * @mdt_captgt: capacity target for mlog in bytes
+ * @mpt_spare:  true if alloc MDC from spare space
+ */
+struct mdc_capacity {
+	uint64_t   mdt_captgt;
+	bool       mdt_spare;
+};
+
+/**
+ * struct mdc_props -
+ * @mdc_objid1:
+ * @mdc_objid2:
+ * @mdc_alloc_cap:
+ * @mdc_mclassp:
+ */
+struct mdc_props {
+	uint64_t               mdc_objid1;
+	uint64_t               mdc_objid2;
+	uint64_t               mdc_alloc_cap;
+	enum mp_media_classp   mdc_mclassp;
+};
+
+
+/**
+ * enum mpc_vma_advice -
+ * @MPC_VMA_COLD:
+ * @MPC_VMA_WARM:
+ * @MPC_VMA_HOT:
+ * @MPC_VMA_PINNED:
+ */
+enum mpc_vma_advice {
+	MPC_VMA_COLD = 0,
+	MPC_VMA_WARM,
+	MPC_VMA_HOT,
+	MPC_VMA_PINNED
+};
+
+
+/**
+ * struct pd_znparam - zone parameter arg used in compute/set API functions
+ * @dvb_zonepg:     zone size in PAGE_SIZE units.
+ * @dvb_zonetot:    total number of zones
+ */
+struct pd_znparam {
+	uint32_t   dvb_zonepg;
+	uint32_t   dvb_zonetot;
+	uint64_t   dvb_rsvd1;
+};
+
+#define PD_DEV_ID_LEN              64
+
+/**
+ * struct pd_prop - PD properties
+ * @pdp_didstr:         drive id string (model)
+ * @pdp_devtype:	device type (enum pd_devtype)
+ * @pdp_phys_if:	physical interface of the drive
+ *			Determined by the device discovery.
+ *			(device_phys_if)
+ * @pdp_mclassp:        performance characteristic of the media class
+ *			Determined by the user, not by the device discovery.
+ *			(enum mp_media_classp)
+ * @pdp_cmdopt:         enum pd_cmd_opt. Features of the PD.
+ * @pdp_zparam:	zone parameters
+ * @pdp_discard_granularity: specified by
+ *	/sys/block/<disk>/queue/discard_granularity
+ * @pdp_sectorsz:	Sector size, exponent base 2
+ * @pdp_optiosz:        Optimal IO size
+ * @pdp_devsz:		device size in bytes
+ *
+ * Note: in order to avoid passing enums across user-kernel boundary
+ * declare the following as uint8_t
+ * pdp_devtype: enum pd_devtype
+ * pdp_devstate: enum pd_state
+ * pdp_phys_if: enum device_phys_if
+ * pdp_mclassp: enum mp_media_classp
+ */
+struct pd_prop {
+	char		        pdp_didstr[PD_DEV_ID_LEN];
+	uint8_t                 pdp_devtype;
+	uint8_t                 pdp_devstate;
+	uint8_t                 pdp_phys_if;
+	uint8_t                 pdp_mclassp;
+	bool                    pdp_fua;
+	uint64_t                pdp_cmdopt;
+
+	struct pd_znparam       pdp_zparam;
+	uint32_t                pdp_discard_granularity;
+	uint32_t                pdp_sectorsz;
+	uint32_t                pdp_optiosz;
+	uint32_t                pdp_rsvd2;
+	uint64_t	        pdp_devsz;
+	uint64_t	        pdp_rsvd3;
+};
+
+
+struct mpioc_mpool {
+	struct mpool_params     mp_params;
+	uint32_t                mp_flags;       /* mp_mgmt_flags */
+	uint32_t                mp_dpathc;      /* Count of device paths */
+	uint32_t                mp_dpathssz;    /* Length of mp_dpaths */
+	uint32_t                mp_rsvd1;
+	uint64_t                mp_rsvd2;
+	char __user            *mp_dpaths;      /* Newline separated paths */
+	struct pd_prop __user  *mp_pd_prop;     /* mp_dpathc elements */
+};
+
+/**
+ * struct mpioc_params -
+ * @mps_params;
+ */
+struct mpioc_params {
+	struct mpool_params     mps_params;
+};
+
+struct mpioc_mclass {
+	struct mpool_mclass_xprops __user  *mcl_xprops;
+	uint32_t                            mcl_cnt;
+	uint32_t                            mcl_rsvd1;
+};
+
+struct mpioc_drive {
+	uint32_t	        drv_flags;   /* mp_mgmt_flags */
+	uint32_t	        drv_rsvd1;
+	uint32_t                drv_dpathc;  /* Count of device paths */
+	uint32_t                drv_dpathssz;/* Length of mp_dpaths */
+	struct pd_prop __user  *drv_pd_prop; /* mp_dpathc elements */
+	char __user            *drv_dpaths;  /* Newline separated device paths*/
+};
+
+enum mpioc_list_cmd {
+	MPIOC_LIST_CMD_INVALID     = 0,
+	MPIOC_LIST_CMD_PROP_GET    = 1,       /* Used by mpool get command */
+	MPIOC_LIST_CMD_PROP_LIST   = 2,       /* Used by mpool list command */
+	MPIOC_LIST_CMD_LAST = MPIOC_LIST_CMD_PROP_LIST,
+};
+
+struct mpioc_list {
+	uint32_t        ls_cmd;     /* enum mpioc_list_cmd */
+	uint32_t        ls_listc;
+	void __user    *ls_listv;
+};
+
+struct mpioc_prop {
+	struct mpool_xprops         pr_xprops;
+	struct mpool_usage          pr_usage;
+	struct mpool_mclass_xprops  pr_mcxv[MP_MED_NUMBER];
+	uint32_t                    pr_mcxc;
+	uint32_t                    pr_rsvd1;
+	uint64_t                    pr_rsvd2;
+};
+
+struct mpioc_devprops {
+	char                    dpr_pdname[PD_NAMESZ_MAX];
+	struct mpool_devprops   dpr_devprops;
+};
+
+/**
+ * struct mpioc_mblock:
+ * @mb_objid:   mblock unique ID (permanent)
+ * @mb_offset:  mblock read offset (ephemeral)
+ * @mb_props:
+ * @mb_layout
+ * @mb_spare:
+ * @mb_mclassp: enum mp_media_classp, declared as uint8_t
+ */
+struct mpioc_mblock {
+	uint64_t                mb_objid;
+	int64_t                 mb_offset;
+	struct mblock_props_ex  mb_props;
+	uint8_t                 mb_spare;
+	uint8_t                 mb_mclassp;
+	uint16_t                mb_rsvd1;
+	uint32_t                mb_rsvd2;
+	uint64_t                mb_rsvd3;
+};
+
+struct mpioc_mblock_id {
+	uint64_t    mi_objid;
+};
+
+#define MPIOC_KIOV_MAX          (1024)
+
+struct mpioc_mblock_rw {
+	uint64_t                    mb_objid;
+	int64_t                     mb_offset;
+	uint32_t                    mb_rsvd2;
+	uint16_t                    mb_rsvd3;
+	uint16_t                    mb_iov_cnt;
+	const struct iovec __user  *mb_iov;
+};
+
+struct mpioc_mlog {
+	uint64_t                ml_objid;
+	uint64_t                ml_rsvd;
+	struct mlog_props_ex    ml_props;
+	struct mlog_capacity    ml_cap;
+	uint8_t                 ml_mclassp; /* enum mp_media_classp */
+	uint8_t                 ml_rsvd1[7];
+	uint64_t                ml_rsvd2;
+};
+
+struct mpioc_mlog_id {
+	uint64_t    mi_objid;
+	uint64_t    mi_gen;
+	uint8_t     mi_state;
+	uint8_t     mi_rsvd1[7];
+};
+
+struct mpioc_mlog_io {
+	uint64_t                mi_objid;
+	int64_t                 mi_off;
+	uint8_t                 mi_op;
+	uint8_t                 mi_rsvd1[5];
+	uint16_t                mi_iovc;
+	struct iovec __user    *mi_iov;
+	uint64_t                mi_rsvd2;
+};
+
+struct mpioc_vma {
+	uint32_t            im_advice;
+	uint32_t            im_mbidc;
+	uint64_t __user    *im_mbidv;
+	uint64_t            im_bktsz;
+	int64_t             im_offset;
+	uint64_t            im_len;
+	uint64_t            im_vssp;
+	uint64_t            im_rssp;
+	uint64_t            im_rsvd;
+};
+
+union mpioc_union {
+	struct mpioc_mpool      mpu_mpool;
+	struct mpioc_drive      mpu_drive;
+	struct mpioc_params     mpu_params;
+	struct mpioc_mclass     mpu_mclass;
+	struct mpioc_list       mpu_list;
+	struct mpioc_prop       mpu_prop;
+	struct mpioc_devprops   mpu_devprops;
+	struct mpioc_mlog       mpu_mlog;
+	struct mpioc_mlog_id    mpu_mlog_id;
+	struct mpioc_mlog_io    mpu_mlog_io;
+	struct mpioc_mblock     mpu_mblock;
+	struct mpioc_mblock_id  mpu_mblock_id;
+	struct mpioc_mblock_rw  mpu_mblock_rw;
+	struct mpioc_vma        mpu_vma;
+};
+
+#define MPIOC_MAGIC             ('2')
+
+#define MPIOC_MP_CREATE         _IOWR(MPIOC_MAGIC, 1, struct mpioc_mpool)
+#define MPIOC_MP_DESTROY        _IOW(MPIOC_MAGIC, 2, struct mpioc_mpool)
+#define MPIOC_MP_ACTIVATE       _IOWR(MPIOC_MAGIC, 5, struct mpioc_mpool)
+#define MPIOC_MP_DEACTIVATE     _IOW(MPIOC_MAGIC, 6, struct mpioc_mpool)
+#define MPIOC_MP_RENAME         _IOWR(MPIOC_MAGIC, 7, struct mpioc_mpool)
+
+#define MPIOC_PARAMS_GET        _IOWR(MPIOC_MAGIC, 10, struct mpioc_params)
+#define MPIOC_PARAMS_SET        _IOWR(MPIOC_MAGIC, 11, struct mpioc_params)
+#define MPIOC_MP_MCLASS_GET     _IOWR(MPIOC_MAGIC, 12, struct mpioc_mclass)
+
+#define MPIOC_DRV_ADD           _IOWR(MPIOC_MAGIC, 15, struct mpioc_drive)
+#define MPIOC_DRV_SPARES        _IOWR(MPIOC_MAGIC, 16, struct mpioc_drive)
+
+#define MPIOC_PROP_GET          _IOWR(MPIOC_MAGIC, 20, struct mpioc_list)
+#define MPIOC_PROP_SET          _IOWR(MPIOC_MAGIC, 21, struct mpioc_list)
+#define MPIOC_DEVPROPS_GET      _IOWR(MPIOC_MAGIC, 22, struct mpioc_devprops)
+
+#define MPIOC_MLOG_ALLOC        _IOWR(MPIOC_MAGIC, 30, struct mpioc_mlog)
+#define MPIOC_MLOG_COMMIT       _IOWR(MPIOC_MAGIC, 32, struct mpioc_mlog_id)
+#define MPIOC_MLOG_ABORT        _IOW(MPIOC_MAGIC, 33, struct mpioc_mlog_id)
+#define MPIOC_MLOG_DELETE       _IOW(MPIOC_MAGIC, 34, struct mpioc_mlog_id)
+#define MPIOC_MLOG_FIND         _IOWR(MPIOC_MAGIC, 37, struct mpioc_mlog)
+#define MPIOC_MLOG_READ         _IOW(MPIOC_MAGIC, 40, struct mpioc_mlog_io)
+#define MPIOC_MLOG_WRITE        _IOW(MPIOC_MAGIC, 41, struct mpioc_mlog_io)
+#define MPIOC_MLOG_PROPS        _IOWR(MPIOC_MAGIC, 42, struct mpioc_mlog)
+#define MPIOC_MLOG_ERASE        _IOWR(MPIOC_MAGIC, 43, struct mpioc_mlog_id)
+
+#define MPIOC_MB_ALLOC          _IOWR(MPIOC_MAGIC, 50, struct mpioc_mblock)
+#define MPIOC_MB_ABORT          _IOW(MPIOC_MAGIC, 52, struct mpioc_mblock_id)
+#define MPIOC_MB_COMMIT         _IOW(MPIOC_MAGIC, 53, struct mpioc_mblock_id)
+#define MPIOC_MB_DELETE         _IOW(MPIOC_MAGIC, 54, struct mpioc_mblock_id)
+#define MPIOC_MB_FIND           _IOWR(MPIOC_MAGIC, 56, struct mpioc_mblock)
+#define MPIOC_MB_READ           _IOW(MPIOC_MAGIC, 60, struct mpioc_mblock_rw)
+#define MPIOC_MB_WRITE          _IOW(MPIOC_MAGIC, 61, struct mpioc_mblock_rw)
+
+#define MPIOC_VMA_CREATE        _IOWR(MPIOC_MAGIC, 70, struct mpioc_vma)
+#define MPIOC_VMA_DESTROY       _IOW(MPIOC_MAGIC, 71, struct mpioc_vma)
+#define MPIOC_VMA_PURGE         _IOW(MPIOC_MAGIC, 72, struct mpioc_vma)
+#define MPIOC_VMA_VRSS          _IOWR(MPIOC_MAGIC, 73, struct mpioc_vma)
+
+#endif
diff --git a/drivers/mpool/mpool_printk.h b/drivers/mpool/mpool_printk.h
new file mode 100644
index 000000000000..280a8e064115
--- /dev/null
+++ b/drivers/mpool/mpool_printk.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2015-2020 Micron Technology, Inc.  All rights reserved.
+ */
+
+#ifndef MPOOL_PRINTK_H
+#define MPOOL_PRINTK_H
+
+#include <linux/printk.h>
+
+static unsigned long mp_pr_rl_state __maybe_unused;
+
+/* TODO: Use dev_crit(), dev_err(), ... */
+
+#define mp_pr_crit(_fmt, _err, ...)				\
+	pr_crit("%s: " _fmt ": errno %d", __func__, ## __VA_ARGS__, (_err))
+
+#define mp_pr_err(_fmt, _err, ...)				\
+	pr_err("%s: " _fmt ": errno %d", __func__, ## __VA_ARGS__, (_err))
+
+#define mp_pr_warn(_fmt, ...)					\
+	pr_warn("%s: " _fmt, __func__, ## __VA_ARGS__)
+
+#define mp_pr_notice(_fmt, ...)					\
+	pr_notice("%s: " _fmt, __func__, ## __VA_ARGS__)
+
+#define mp_pr_info(_fmt, ...)					\
+	pr_info("%s: " _fmt, __func__, ## __VA_ARGS__)
+
+#define mp_pr_debug(_fmt, _err, ...)				\
+	pr_debug("%s: " _fmt ": errno %d", __func__, ## __VA_ARGS__,  (_err))
+
+
+/* Rate limited version of mp_pr_err(). */
+#define mp_pr_rl(_fmt, _err, ...)				\
+do {								\
+	if (printk_timed_ratelimit(&mp_pr_rl_state, 333)) {	\
+		pr_err("%s: " _fmt ": errno %d",		\
+		       __func__, ## __VA_ARGS__, (_err));	\
+	}							\
+} while (0)
+
+#endif /* MPOOL_PRINTK_H */
diff --git a/drivers/mpool/uuid.h b/drivers/mpool/uuid.h
new file mode 100644
index 000000000000..28e53be68662
--- /dev/null
+++ b/drivers/mpool/uuid.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2015-2020 Micron Technology, Inc.  All rights reserved.
+ */
+
+#ifndef MPOOL_UUID_H
+#define MPOOL_UUID_H
+
+#define MPOOL_UUID_SIZE        16
+#define MPOOL_UUID_STRING_LEN  36
+
+#include <linux/kernel.h>
+#include <linux/uuid.h>
+
+struct mpool_uuid {
+	unsigned char uuid[MPOOL_UUID_SIZE];
+};
+
+/* mpool_uuid uses the LE version in the kernel */
+static inline void mpool_generate_uuid(struct mpool_uuid *uuid)
+{
+	generate_random_guid(uuid->uuid);
+}
+
+static inline void mpool_uuid_copy(struct mpool_uuid *u_dst, const struct mpool_uuid *u_src)
+{
+	memcpy(u_dst->uuid, u_src->uuid, MPOOL_UUID_SIZE);
+}
+
+static inline int mpool_uuid_compare(const struct mpool_uuid *uuid1, const struct mpool_uuid *uuid2)
+{
+	return memcmp(uuid1, uuid2, MPOOL_UUID_SIZE);
+}
+
+static inline void mpool_uuid_clear(struct mpool_uuid *uuid)
+{
+	memset(uuid->uuid, 0, MPOOL_UUID_SIZE);
+}
+
+static inline int mpool_uuid_is_null(const struct mpool_uuid *uuid)
+{
+	const struct mpool_uuid zero = { };
+
+	return !memcmp(&zero, uuid, sizeof(zero));
+}
+
+static inline void mpool_unparse_uuid(const struct mpool_uuid *uuid, char *dst)
+{
+	const unsigned char *u = uuid->uuid;
+
+	snprintf(dst, MPOOL_UUID_STRING_LEN + 1,
+		 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+		 u[0], u[1], u[2], u[3],
+		 u[4], u[5], u[6], u[7],
+		 u[8], u[9], u[10], u[11],
+		 u[12], u[13], u[14], u[15]);
+}
+
+#endif /* MPOOL_UUID_H */
-- 
2.17.2


_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

  reply	other threads:[~2020-10-12 16:28 UTC|newest]

Thread overview: 114+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-12 16:27 [PATCH v2 00/22] add Object Storage Media Pool (mpool) Nabeel M Mohamed
2020-10-12 16:27 ` Nabeel M Mohamed
2020-10-12 16:27 ` Nabeel M Mohamed
2020-10-12 16:27 ` Nabeel M Mohamed [this message]
2020-10-12 16:27   ` [PATCH v2 01/22] mpool: add utility routines and ioctl definitions Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:45   ` Randy Dunlap
2020-10-12 16:45     ` Randy Dunlap
2020-10-12 16:45     ` Randy Dunlap
2020-10-12 16:48     ` Randy Dunlap
2020-10-12 16:48       ` Randy Dunlap
2020-10-12 16:48       ` Randy Dunlap
2020-10-12 16:27 ` [PATCH v2 02/22] mpool: add in-memory struct definitions Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27 ` [PATCH v2 03/22] mpool: add on-media " Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27 ` [PATCH v2 04/22] mpool: add pool drive component which handles mpool IO using the block layer API Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27 ` [PATCH v2 05/22] mpool: add space map component which manages free space on mpool devices Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27 ` [PATCH v2 06/22] mpool: add on-media pack, unpack and upgrade routines Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27 ` [PATCH v2 07/22] mpool: add superblock management routines Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27 ` [PATCH v2 08/22] mpool: add pool metadata routines to manage object lifecycle and IO Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27 ` [PATCH v2 09/22] mpool: add mblock lifecycle management and IO routines Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27 ` [PATCH v2 10/22] mpool: add mlog IO utility routines Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27 ` [PATCH v2 11/22] mpool: add mlog lifecycle management and IO routines Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27 ` [PATCH v2 12/22] mpool: add metadata container or mlog-pair framework Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27 ` [PATCH v2 13/22] mpool: add utility routines for mpool lifecycle management Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27 ` [PATCH v2 14/22] mpool: add pool metadata routines to create persistent mpools Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27 ` [PATCH v2 15/22] mpool: add mpool lifecycle management routines Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27 ` [PATCH v2 16/22] mpool: add mpool control plane utility routines Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27 ` [PATCH v2 17/22] mpool: add mpool lifecycle management ioctls Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27 ` [PATCH v2 18/22] mpool: add object " Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27 ` [PATCH v2 19/22] mpool: add support to mmap arbitrary collection of mblocks Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27 ` [PATCH v2 20/22] mpool: add support to proactively evict cached mblock data from the page-cache Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27 ` [PATCH v2 21/22] mpool: add documentation Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:53   ` Randy Dunlap
2020-10-12 16:53     ` Randy Dunlap
2020-10-12 16:53     ` Randy Dunlap
2020-10-12 16:27 ` [PATCH v2 22/22] mpool: add Kconfig and Makefile Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-12 16:27   ` Nabeel M Mohamed
2020-10-15  8:02 ` [PATCH v2 00/22] add Object Storage Media Pool (mpool) Christoph Hellwig
2020-10-15  8:02   ` Christoph Hellwig
2020-10-15  8:02   ` Christoph Hellwig
2020-10-16 21:58   ` [EXT] " Nabeel Meeramohideen Mohamed (nmeeramohide)
2020-10-16 21:58     ` Nabeel Meeramohideen Mohamed (nmeeramohide)
2020-10-16 21:58     ` Nabeel Meeramohideen Mohamed (nmeeramohide)
2020-10-16 21:58     ` Nabeel Meeramohideen Mohamed (nmeeramohide)
2020-10-16 22:11     ` Dan Williams
2020-10-16 22:11       ` Dan Williams
2020-10-16 22:11       ` Dan Williams
2020-10-19 22:30       ` Nabeel Meeramohideen Mohamed (nmeeramohide)
2020-10-19 22:30         ` Nabeel Meeramohideen Mohamed (nmeeramohide)
2020-10-19 22:30         ` Nabeel Meeramohideen Mohamed (nmeeramohide)
2020-10-19 22:30         ` Nabeel Meeramohideen Mohamed (nmeeramohide)
2020-10-20 21:35         ` Dan Williams
2020-10-20 21:35           ` Dan Williams
2020-10-20 21:35           ` Dan Williams
2020-10-20 21:35           ` Dan Williams
2020-10-21 17:10           ` Nabeel Meeramohideen Mohamed (nmeeramohide)
2020-10-21 17:10             ` Nabeel Meeramohideen Mohamed (nmeeramohide)
2020-10-21 17:10             ` Nabeel Meeramohideen Mohamed (nmeeramohide)
2020-10-21 17:10             ` Nabeel Meeramohideen Mohamed (nmeeramohide)
2020-10-21 17:48             ` Dan Williams
2020-10-21 17:48               ` Dan Williams
2020-10-21 17:48               ` Dan Williams
2020-10-21 17:48               ` Dan Williams
2020-10-21 14:24       ` Mike Snitzer
2020-10-21 14:24         ` [dm-devel] " Mike Snitzer
2020-10-21 14:24         ` Mike Snitzer
2020-10-21 14:24         ` Mike Snitzer
2020-10-21 14:24         ` Mike Snitzer
2020-10-21 16:24         ` Dan Williams
2020-10-21 16:24           ` [dm-devel] " Dan Williams
2020-10-21 16:24           ` Dan Williams
2020-10-21 16:24           ` Dan Williams
2020-10-21 16:24           ` Dan Williams

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201012162736.65241-2-nmeeramohide@micron.com \
    --to=nmeeramohide@micron.com \
    --cc=gbecker@micron.com \
    --cc=jgroves@micron.com \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linux-nvdimm@lists.01.org \
    --cc=linux-nvme@lists.infradead.org \
    --cc=plabat@micron.com \
    --cc=smoyer@micron.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.