2018-05-08 11:30:29 +00:00
|
|
|
/*-
|
|
|
|
* BSD LICENSE
|
|
|
|
*
|
|
|
|
* Copyright (c) Intel Corporation.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
*
|
|
|
|
* * Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in
|
|
|
|
* the documentation and/or other materials provided with the
|
|
|
|
* distribution.
|
|
|
|
* * Neither the name of Intel Corporation nor the names of its
|
|
|
|
* contributors may be used to endorse or promote products derived
|
|
|
|
* from this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef SPDK_BDEV_RAID_INTERNAL_H
|
|
|
|
#define SPDK_BDEV_RAID_INTERNAL_H
|
|
|
|
|
|
|
|
#include "spdk/bdev_module.h"
|
|
|
|
|
2019-10-09 11:46:46 +00:00
|
|
|
enum raid_level {
|
|
|
|
INVALID_RAID_LEVEL = -1,
|
|
|
|
RAID0 = 0,
|
|
|
|
};
|
2019-09-27 14:35:37 +00:00
|
|
|
|
2018-05-08 11:30:29 +00:00
|
|
|
/*
|
|
|
|
* Raid state describes the state of the raid. This raid bdev can be either in
|
|
|
|
* configured list or configuring list
|
|
|
|
*/
|
|
|
|
enum raid_bdev_state {
|
|
|
|
/* raid bdev is ready and is seen by upper layers */
|
|
|
|
RAID_BDEV_STATE_ONLINE,
|
|
|
|
|
2018-10-08 04:04:34 +00:00
|
|
|
/*
|
|
|
|
* raid bdev is configuring, not all underlying bdevs are present.
|
|
|
|
* And can't be seen by upper layers.
|
|
|
|
*/
|
2018-05-08 11:30:29 +00:00
|
|
|
RAID_BDEV_STATE_CONFIGURING,
|
|
|
|
|
|
|
|
/*
|
|
|
|
* In offline state, raid bdev layer will complete all incoming commands without
|
|
|
|
* submitting to underlying base nvme bdevs
|
|
|
|
*/
|
|
|
|
RAID_BDEV_STATE_OFFLINE,
|
|
|
|
|
|
|
|
/* raid bdev max, new states should be added before this */
|
|
|
|
RAID_BDEV_MAX
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* raid_base_bdev_info contains information for the base bdevs which are part of some
|
|
|
|
* raid. This structure contains the per base bdev information. Whatever is
|
|
|
|
* required per base device for raid bdev will be kept here
|
|
|
|
*/
|
|
|
|
struct raid_base_bdev_info {
|
|
|
|
/* pointer to base spdk bdev */
|
2018-08-20 23:01:56 +00:00
|
|
|
struct spdk_bdev *bdev;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
/* pointer to base bdev descriptor opened by raid bdev */
|
2018-08-20 23:01:56 +00:00
|
|
|
struct spdk_bdev_desc *desc;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* When underlying base device calls the hot plug function on drive removal,
|
|
|
|
* this flag will be set and later after doing some processing, base device
|
|
|
|
* descriptor will be closed
|
|
|
|
*/
|
2018-08-20 23:01:56 +00:00
|
|
|
bool remove_scheduled;
|
2018-05-08 11:30:29 +00:00
|
|
|
};
|
|
|
|
|
2019-09-05 22:39:10 +00:00
|
|
|
/*
|
|
|
|
* raid_bdev_io is the context part of bdev_io. It contains the information
|
|
|
|
* related to bdev_io for a raid bdev
|
|
|
|
*/
|
|
|
|
struct raid_bdev_io {
|
2019-10-10 10:07:02 +00:00
|
|
|
/* The raid bdev associated with this IO */
|
|
|
|
struct raid_bdev *raid_bdev;
|
|
|
|
|
2019-09-05 22:39:10 +00:00
|
|
|
/* WaitQ entry, used only in waitq logic */
|
|
|
|
struct spdk_bdev_io_wait_entry waitq_entry;
|
|
|
|
|
2019-10-10 09:23:01 +00:00
|
|
|
/* Context of the original channel for this IO */
|
|
|
|
struct raid_bdev_io_channel *raid_ch;
|
2019-09-05 22:39:10 +00:00
|
|
|
|
|
|
|
/* Used for tracking progress on io requests sent to member disks. */
|
|
|
|
uint8_t base_bdev_io_submitted;
|
|
|
|
uint8_t base_bdev_io_completed;
|
|
|
|
uint8_t base_bdev_io_expected;
|
|
|
|
uint8_t base_bdev_io_status;
|
|
|
|
};
|
|
|
|
|
2018-05-08 11:30:29 +00:00
|
|
|
/*
|
2018-07-31 00:14:18 +00:00
|
|
|
* raid_bdev is the single entity structure which contains SPDK block device
|
|
|
|
* and the information related to any raid bdev either configured or
|
|
|
|
* in configuring list. io device is created on this.
|
2018-05-08 11:30:29 +00:00
|
|
|
*/
|
|
|
|
struct raid_bdev {
|
2018-07-31 00:14:18 +00:00
|
|
|
/* raid bdev device, this will get registered in bdev layer */
|
2019-08-07 01:53:53 +00:00
|
|
|
struct spdk_bdev bdev;
|
2018-07-31 00:14:18 +00:00
|
|
|
|
2018-05-08 11:30:29 +00:00
|
|
|
/* link of raid bdev to link it to configured, configuring or offline list */
|
2019-08-07 01:53:53 +00:00
|
|
|
TAILQ_ENTRY(raid_bdev) state_link;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
/* link of raid bdev to link it to global raid bdev list */
|
2019-08-07 01:53:53 +00:00
|
|
|
TAILQ_ENTRY(raid_bdev) global_link;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
/* pointer to config file entry */
|
2019-08-07 01:53:53 +00:00
|
|
|
struct raid_bdev_config *config;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
/* array of base bdev info */
|
2019-08-07 01:53:53 +00:00
|
|
|
struct raid_base_bdev_info *base_bdev_info;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
/* strip size of raid bdev in blocks */
|
2019-08-07 01:53:53 +00:00
|
|
|
uint32_t strip_size;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
2018-12-19 18:04:18 +00:00
|
|
|
/* strip size of raid bdev in KB */
|
2019-08-07 01:53:53 +00:00
|
|
|
uint32_t strip_size_kb;
|
2018-12-19 18:04:18 +00:00
|
|
|
|
2018-05-08 11:30:29 +00:00
|
|
|
/* strip size bit shift for optimized calculation */
|
2019-08-07 01:53:53 +00:00
|
|
|
uint32_t strip_size_shift;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
/* block length bit shift for optimized calculation */
|
2019-08-07 01:53:53 +00:00
|
|
|
uint32_t blocklen_shift;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
/* state of raid bdev */
|
2019-08-07 01:53:53 +00:00
|
|
|
enum raid_bdev_state state;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
/* number of base bdevs comprising raid bdev */
|
2019-08-07 01:53:53 +00:00
|
|
|
uint8_t num_base_bdevs;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
/* number of base bdevs discovered */
|
2019-08-07 01:53:53 +00:00
|
|
|
uint8_t num_base_bdevs_discovered;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
/* Raid Level of this raid bdev */
|
2019-10-09 11:46:46 +00:00
|
|
|
enum raid_level level;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
/* Set to true if destruct is called for this raid bdev */
|
2019-08-07 01:53:53 +00:00
|
|
|
bool destruct_called;
|
2019-04-11 02:56:30 +00:00
|
|
|
|
|
|
|
/* Set to true if destroy of this raid bdev is started. */
|
2019-08-07 01:53:53 +00:00
|
|
|
bool destroy_started;
|
2019-10-09 09:22:41 +00:00
|
|
|
|
|
|
|
/* Module for RAID-level specific operations */
|
|
|
|
struct raid_bdev_module *module;
|
2018-05-08 11:30:29 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* raid_base_bdev_config is the per base bdev data structure which contains
|
|
|
|
* information w.r.t to per base bdev during parsing config
|
|
|
|
*/
|
|
|
|
struct raid_base_bdev_config {
|
|
|
|
/* base bdev name from config file */
|
2018-08-27 04:43:27 +00:00
|
|
|
char *name;
|
2018-05-08 11:30:29 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* raid_bdev_config contains the raid bdev config related information after
|
|
|
|
* parsing the config file
|
|
|
|
*/
|
|
|
|
struct raid_bdev_config {
|
|
|
|
/* base bdev config per underlying bdev */
|
2019-09-09 21:35:12 +00:00
|
|
|
struct raid_base_bdev_config *base_bdev;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
/* Points to already created raid bdev */
|
2019-09-09 21:35:12 +00:00
|
|
|
struct raid_bdev *raid_bdev;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
2019-09-09 21:35:12 +00:00
|
|
|
char *name;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
/* strip size of this raid bdev in kilo bytes */
|
2019-09-09 21:35:12 +00:00
|
|
|
uint32_t strip_size;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
/* number of base bdevs */
|
2019-09-09 21:35:12 +00:00
|
|
|
uint8_t num_base_bdevs;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
/* raid level */
|
2019-10-09 11:46:46 +00:00
|
|
|
enum raid_level level;
|
2018-07-23 07:54:33 +00:00
|
|
|
|
2019-09-09 21:35:12 +00:00
|
|
|
TAILQ_ENTRY(raid_bdev_config) link;
|
2018-05-08 11:30:29 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* raid_config is the top level structure representing the raid bdev config as read
|
|
|
|
* from config file for all raids
|
|
|
|
*/
|
|
|
|
struct raid_config {
|
|
|
|
/* raid bdev context from config file */
|
2018-07-23 07:54:33 +00:00
|
|
|
TAILQ_HEAD(, raid_bdev_config) raid_bdev_config_head;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
|
|
|
/* total raid bdev from config file */
|
|
|
|
uint8_t total_raid_bdev;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* raid_bdev_io_channel is the context of spdk_io_channel for raid bdev device. It
|
|
|
|
* contains the relationship of raid bdev io channel with base bdev io channels.
|
|
|
|
*/
|
|
|
|
struct raid_bdev_io_channel {
|
|
|
|
/* Array of IO channels of base bdevs */
|
2019-08-06 23:53:26 +00:00
|
|
|
struct spdk_io_channel **base_channel;
|
|
|
|
|
|
|
|
/* Number of IO channels */
|
|
|
|
uint8_t num_channels;
|
2018-05-08 11:30:29 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* TAIL heads for various raid bdev lists */
|
2019-04-08 06:57:04 +00:00
|
|
|
TAILQ_HEAD(raid_configured_tailq, raid_bdev);
|
|
|
|
TAILQ_HEAD(raid_configuring_tailq, raid_bdev);
|
|
|
|
TAILQ_HEAD(raid_all_tailq, raid_bdev);
|
|
|
|
TAILQ_HEAD(raid_offline_tailq, raid_bdev);
|
|
|
|
|
|
|
|
extern struct raid_configured_tailq g_raid_bdev_configured_list;
|
|
|
|
extern struct raid_configuring_tailq g_raid_bdev_configuring_list;
|
|
|
|
extern struct raid_all_tailq g_raid_bdev_list;
|
|
|
|
extern struct raid_offline_tailq g_raid_bdev_offline_list;
|
|
|
|
extern struct raid_config g_raid_config;
|
2018-05-08 11:30:29 +00:00
|
|
|
|
2019-04-09 00:40:54 +00:00
|
|
|
typedef void (*raid_bdev_destruct_cb)(void *cb_ctx, int rc);
|
|
|
|
|
2018-08-31 00:25:37 +00:00
|
|
|
int raid_bdev_create(struct raid_bdev_config *raid_cfg);
|
2018-08-31 06:27:29 +00:00
|
|
|
int raid_bdev_add_base_devices(struct raid_bdev_config *raid_cfg);
|
2019-04-09 00:40:54 +00:00
|
|
|
void raid_bdev_remove_base_devices(struct raid_bdev_config *raid_cfg,
|
|
|
|
raid_bdev_destruct_cb cb_fn, void *cb_ctx);
|
2019-08-07 06:06:28 +00:00
|
|
|
int raid_bdev_config_add(const char *raid_name, uint32_t strip_size, uint8_t num_base_bdevs,
|
2019-10-09 11:46:46 +00:00
|
|
|
enum raid_level level, struct raid_bdev_config **_raid_cfg);
|
2018-07-25 02:12:39 +00:00
|
|
|
int raid_bdev_config_add_base_bdev(struct raid_bdev_config *raid_cfg,
|
2019-08-07 01:53:53 +00:00
|
|
|
const char *base_bdev_name, uint8_t slot);
|
2018-07-25 00:03:45 +00:00
|
|
|
void raid_bdev_config_cleanup(struct raid_bdev_config *raid_cfg);
|
2018-08-31 02:09:06 +00:00
|
|
|
struct raid_bdev_config *raid_bdev_config_find_by_name(const char *raid_name);
|
2019-10-09 11:46:46 +00:00
|
|
|
enum raid_level raid_bdev_parse_raid_level(const char *str);
|
|
|
|
const char *raid_bdev_level_to_str(enum raid_level level);
|
2018-05-08 11:30:29 +00:00
|
|
|
|
2019-10-09 09:22:41 +00:00
|
|
|
/*
|
|
|
|
* RAID module descriptor
|
|
|
|
*/
|
|
|
|
struct raid_bdev_module {
|
|
|
|
/* RAID level implemented by this module */
|
|
|
|
enum raid_level level;
|
|
|
|
|
2019-10-29 13:31:51 +00:00
|
|
|
/*
|
|
|
|
* Called when the raid is starting, right before changing the state to
|
|
|
|
* online and registering the bdev. Parameters of the bdev like blockcnt
|
|
|
|
* should be set here.
|
|
|
|
*
|
|
|
|
* Non-zero return value will abort the startup process.
|
|
|
|
*/
|
|
|
|
int (*start)(struct raid_bdev *raid_bdev);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Called when the raid is stopping, right before changing the state to
|
|
|
|
* offline and unregistering the bdev. Optional.
|
|
|
|
*/
|
|
|
|
void (*stop)(struct raid_bdev *raid_bdev);
|
|
|
|
|
2019-10-10 12:24:07 +00:00
|
|
|
/* Handler for R/W requests */
|
|
|
|
void (*submit_rw_request)(struct raid_bdev_io *raid_io);
|
|
|
|
|
|
|
|
/* Handler for requests without payload (flush, unmap) */
|
|
|
|
void (*submit_null_payload_request)(struct raid_bdev_io *raid_io);
|
|
|
|
|
2019-10-09 09:22:41 +00:00
|
|
|
TAILQ_ENTRY(raid_bdev_module) link;
|
|
|
|
};
|
|
|
|
|
|
|
|
void raid_bdev_module_list_add(struct raid_bdev_module *raid_module);
|
|
|
|
|
|
|
|
#define __RAID_MODULE_REGISTER(line) __RAID_MODULE_REGISTER_(line)
|
|
|
|
#define __RAID_MODULE_REGISTER_(line) raid_module_register_##line
|
|
|
|
|
|
|
|
#define RAID_MODULE_REGISTER(_module) \
|
|
|
|
__attribute__((constructor)) static void \
|
|
|
|
__RAID_MODULE_REGISTER(__LINE__)(void) \
|
|
|
|
{ \
|
|
|
|
raid_bdev_module_list_add(_module); \
|
|
|
|
}
|
|
|
|
|
2019-10-08 10:33:15 +00:00
|
|
|
void
|
|
|
|
raid_bdev_base_io_completion(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg);
|
|
|
|
void
|
2019-10-10 10:39:08 +00:00
|
|
|
raid_bdev_queue_io_wait(struct raid_bdev_io *raid_io, struct spdk_bdev *bdev,
|
|
|
|
struct spdk_io_channel *ch, spdk_bdev_io_wait_cb cb_fn);
|
2019-10-10 10:48:13 +00:00
|
|
|
void
|
|
|
|
raid_bdev_io_complete(struct raid_bdev_io *raid_io, enum spdk_bdev_io_status status);
|
2019-10-08 10:33:15 +00:00
|
|
|
|
2018-10-29 02:45:42 +00:00
|
|
|
#endif /* SPDK_BDEV_RAID_INTERNAL_H */
|