diff mbox series

[01/22] mpool: add utility routines and ioctl definitions

Message ID 20200928164534.48203-2-nmeeramohide@micron.com (mailing list archive)
State Superseded
Headers show
Series add Object Storage Media Pool (mpool) | expand

Commit Message

Nabeel Meeramohideen Mohamed (nmeeramohide) Sept. 28, 2020, 4:45 p.m. UTC
From: Nabeel M Mohamed <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 |  44 +++
 drivers/mpool/uuid.h         |  59 ++++
 5 files changed, 786 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 mbox series

Patch

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..933040ffd6d9
--- /dev/null
+++ b/drivers/mpool/mpool_printk.h
@@ -0,0 +1,44 @@ 
+/* 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>
+
+/* 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 {								\
+	static unsigned long mp_pr_rl_state;			\
+	uint dly = msecs_to_jiffies(333);			\
+								\
+	if (printk_timed_ratelimit(&mp_pr_rl_state, dly)) {	\
+		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 */