Changeset 6f13257 in mainline
- Timestamp:
- 2025-05-20T11:01:31Z (12 days ago)
- Children:
- c5b60e25
- Parents:
- a2281efc
- git-author:
- Miroslav Cimerman <mc@…> (2025-05-20 10:55:15)
- git-committer:
- Miroslav Cimerman <mc@…> (2025-05-20 11:01:31)
- Location:
- uspace
- Files:
-
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/hrctl/hrctl.c
ra2281efc r6f13257 48 48 #define NAME "hrctl" 49 49 50 static void 51 static errno_t 50 static void usage(void); 51 static errno_t fill_config_devs(int, char **, hr_config_t *); 52 52 static errno_t get_vol_configs_from_sif(const char *, hr_config_t **, size_t *); 53 53 -
uspace/lib/device/include/hr.h
ra2281efc r6f13257 48 48 49 49 typedef enum hr_level { 50 HR_LVL_0 51 HR_LVL_1 52 HR_LVL_4 53 HR_LVL_5 54 HR_LVL_UNKNOWN 50 HR_LVL_0 = 0x00, /* striping, no redundancy */ 51 HR_LVL_1 = 0x01, /* n-way mirroring */ 52 HR_LVL_4 = 0x04, /* dedicated parity */ 53 HR_LVL_5 = 0x05, /* distributed parity */ 54 HR_LVL_UNKNOWN = 0xFF 55 55 } hr_level_t; 56 56 57 57 typedef enum hr_layout { 58 HR_RLQ_NONE 59 HR_RLQ_RAID4_0, 60 HR_RLQ_RAID4_N, 61 HR_RLQ_RAID5_0R, 62 HR_RLQ_RAID5_NR, 63 HR_RLQ_RAID5_NC 58 HR_RLQ_NONE = 0, 59 HR_RLQ_RAID4_0, /* RAID-4 Non-Rotating Parity 0 */ 60 HR_RLQ_RAID4_N, /* RAID-4 Non-Rotating Parity N */ 61 HR_RLQ_RAID5_0R, /* RAID-5 Rotating Parity 0 with Data Restart */ 62 HR_RLQ_RAID5_NR, /* RAID-5 Rotating Parity N with Data Restart */ 63 HR_RLQ_RAID5_NC /* RAID-5 Rotating Parity N with Data Continuation */ 64 64 } hr_layout_t; 65 65 66 66 typedef enum hr_vol_state { 67 HR_VOL_NONE = 0, 68 HR_VOL_ONLINE, 69 HR_VOL_FAULTY, 70 HR_VOL_DEGRADED, 71 HR_VOL_REBUILD 67 HR_VOL_NONE = 0, /* Unknown/None */ 68 HR_VOL_ONLINE, /* optimal */ 69 HR_VOL_FAULTY, /* unusable */ 70 HR_VOL_DEGRADED, /* not optimal */ 71 HR_VOL_REBUILD /* rebuild in progress */ 72 72 } hr_vol_state_t; 73 73 74 74 typedef enum hr_ext_state { 75 HR_EXT_NONE = 0, 76 HR_EXT_INVALID, 77 HR_EXT_ONLINE, 78 HR_EXT_MISSING, 75 HR_EXT_NONE = 0, /* unknown/none state */ 76 HR_EXT_INVALID, /* working but not consistent */ 77 HR_EXT_ONLINE, /* ok */ 78 HR_EXT_MISSING, /* offline */ 79 79 HR_EXT_FAILED, 80 80 HR_EXT_REBUILD, … … 87 87 88 88 typedef struct hr_config { 89 char 90 service_id_t 91 size_t 92 hr_level_t 89 char devname[HR_DEVNAME_LEN]; 90 service_id_t devs[HR_MAX_EXTENTS]; 91 size_t dev_no; 92 hr_level_t level; 93 93 } hr_config_t; 94 94 95 95 typedef struct hr_extent { 96 service_id_t 97 hr_ext_state_t 96 service_id_t svc_id; 97 hr_ext_state_t state; 98 98 } hr_extent_t; 99 99 100 100 typedef struct hr_vol_info { 101 hr_extent_t 102 hr_extent_t 103 size_t 104 size_t 105 service_id_t 106 hr_level_t 107 uint64_t 108 uint32_t 109 size_t 110 hr_vol_state_t 111 uint8_t 101 hr_extent_t extents[HR_MAX_EXTENTS]; 102 hr_extent_t hotspares[HR_MAX_HOTSPARES]; 103 size_t extent_no; 104 size_t hotspare_no; 105 service_id_t svc_id; 106 hr_level_t level; 107 uint64_t nblocks; 108 uint32_t strip_size; 109 size_t bsize; 110 hr_vol_state_t state; 111 uint8_t layout; 112 112 } hr_vol_info_t; 113 113 114 114 typedef enum { 115 HR_METADATA_NATIVE 115 HR_METADATA_NATIVE = 0, 116 116 HR_METADATA_GEOM_MIRROR, 117 117 HR_METADATA_GEOM_STRIPE, … … 120 120 } hr_metadata_type_t; 121 121 122 extern errno_t 123 extern void 124 extern errno_t 125 extern errno_t 126 extern errno_t 127 extern errno_t 128 extern errno_t 129 extern errno_t 130 extern errno_t 131 extern errno_t 132 extern const char 133 extern const char 134 extern const char 135 extern const char 122 extern errno_t hr_sess_init(hr_t **); 123 extern void hr_sess_destroy(hr_t *); 124 extern errno_t hr_create(hr_t *, hr_config_t *); 125 extern errno_t hr_assemble(hr_t *, hr_config_t *, size_t *); 126 extern errno_t hr_auto_assemble(hr_t *, size_t *); 127 extern errno_t hr_stop(hr_t *, const char *); 128 extern errno_t hr_stop_all(hr_t *); 129 extern errno_t hr_fail_extent(hr_t *, const char *, unsigned long); 130 extern errno_t hr_add_hotspare(hr_t *, const char *, const char *); 131 extern errno_t hr_print_state(hr_t *); 132 extern const char *hr_get_vol_state_str(hr_vol_state_t); 133 extern const char *hr_get_ext_state_str(hr_ext_state_t); 134 extern const char *hr_get_layout_str(hr_layout_t); 135 extern const char *hr_get_metadata_type_str(hr_metadata_type_t); 136 136 137 137 #endif -
uspace/srv/bd/hr/fge.c
ra2281efc r6f13257 59 59 typedef struct wu_queue wu_queue_t; 60 60 61 static void 62 static void 63 static errno_t 64 static errno_t 65 static void 66 static void 67 static ssize_t 61 static void *hr_fpool_make_storage(hr_fpool_t *, ssize_t *); 62 static void hr_fpool_group_epilogue(hr_fpool_t *); 63 static errno_t fge_fibril(void *); 64 static errno_t wu_queue_init(wu_queue_t *, size_t); 65 static void wu_queue_push(wu_queue_t *, fge_fibril_data_t *); 66 static void wu_queue_pop(wu_queue_t *, fge_fibril_data_t *); 67 static ssize_t hr_fpool_get_free_slot(hr_fpool_t *); 68 68 69 69 struct fge_fibril_data { 70 hr_wu_t wu;/* work unit function pointer */71 void *arg;/* work unit function argument */72 hr_fgroup_t *group;/* back-pointer to group */73 ssize_t memslot;/* index to pool bitmap slot */70 hr_wu_t wu; /* work unit function pointer */ 71 void *arg; /* work unit function argument */ 72 hr_fgroup_t *group; /* back-pointer to group */ 73 ssize_t memslot; /* index to pool bitmap slot */ 74 74 }; 75 75 76 76 struct wu_queue { 77 fibril_mutex_t 78 fibril_condvar_t 79 fibril_condvar_t 80 fge_fibril_data_t *fexecs;/* circ-buf memory */77 fibril_mutex_t lock; 78 fibril_condvar_t not_empty; 79 fibril_condvar_t not_full; 80 fge_fibril_data_t *fexecs; /* circ-buf memory */ 81 81 circ_buf_t cbuf; 82 82 }; 83 83 84 84 struct hr_fpool { 85 fibril_mutex_t 86 bitmap_t bitmap;/* memory slot bitmap */87 wu_queue_t 88 fid_t 89 uint8_t *wu_storage;/* pre-allocated pool storage */90 size_t 91 size_t 92 size_t 93 bool 94 size_t 95 size_t 85 fibril_mutex_t lock; 86 bitmap_t bitmap; /* memory slot bitmap */ 87 wu_queue_t queue; 88 fid_t *fibrils; 89 uint8_t *wu_storage; /* pre-allocated pool storage */ 90 size_t fibril_cnt; 91 size_t max_wus; 92 size_t active_groups; 93 bool stop; 94 size_t wu_size; 95 size_t wu_storage_free_count; 96 96 fibril_condvar_t all_wus_done; 97 97 }; 98 98 99 99 struct hr_fgroup { 100 hr_fpool_t *pool;/* back-pointer to pool */101 size_t wu_cnt;/* upper bound of work units */102 size_t submitted;/* number of submitted jobs */103 size_t reserved_cnt;/* no. of reserved wu storage slots */104 size_t 105 size_t *memslots;/* indices to pool bitmap */106 void *own_mem;/* own allocated memory */107 size_t own_used;/* own memory slots used counter */108 errno_t final_errno;/* agreggated errno */109 size_t finished_okay;/* no. of wus that ended with EOK */110 size_t finished_fail;/* no. of wus that ended with != EOK */111 fibril_mutex_t 100 hr_fpool_t *pool;/* back-pointer to pool */ 101 size_t wu_cnt;/* upper bound of work units */ 102 size_t submitted; /* number of submitted jobs */ 103 size_t reserved_cnt; /* no. of reserved wu storage slots */ 104 size_t reserved_avail; 105 size_t *memslots; /* indices to pool bitmap */ 106 void *own_mem; /* own allocated memory */ 107 size_t own_used; /* own memory slots used counter */ 108 errno_t final_errno; /* agreggated errno */ 109 size_t finished_okay; /* no. of wus that ended with EOK */ 110 size_t finished_fail; /* no. of wus that ended with != EOK */ 111 fibril_mutex_t lock; 112 112 fibril_condvar_t all_done; 113 113 }; -
uspace/srv/bd/hr/fge.h
ra2281efc r6f13257 48 48 typedef errno_t (*hr_wu_t)(void *); 49 49 50 extern hr_fpool_t 51 extern void 52 extern hr_fgroup_t 53 extern void 54 extern void 55 extern errno_t 50 extern hr_fpool_t *hr_fpool_create(size_t, size_t, size_t); 51 extern void hr_fpool_destroy(hr_fpool_t *); 52 extern hr_fgroup_t *hr_fgroup_create(hr_fpool_t *, size_t); 53 extern void *hr_fgroup_alloc(hr_fgroup_t *); 54 extern void hr_fgroup_submit(hr_fgroup_t *, hr_wu_t, void *); 55 extern errno_t hr_fgroup_wait(hr_fgroup_t *, size_t *, size_t *); 56 56 57 57 #endif -
uspace/srv/bd/hr/io.h
ra2281efc r6f13257 40 40 41 41 typedef struct hr_io { 42 hr_bd_op_type_t 43 uint64_t 44 uint64_t 45 size_t 46 void 47 const void 48 hr_volume_t 42 hr_bd_op_type_t type; 43 uint64_t ba; 44 uint64_t cnt; 45 size_t extent; 46 void *data_read; 47 const void *data_write; 48 hr_volume_t *vol; 49 49 } hr_io_t; 50 50 -
uspace/srv/bd/hr/metadata/foreign/geom/hr_g_mirror.c
ra2281efc r6f13257 53 53 #include "g_mirror.h" 54 54 55 static void *meta_gmirror_alloc_struct(void); 56 static errno_t meta_gmirror_init_vol2meta(const hr_volume_t *, void *); 57 static errno_t meta_gmirror_init_meta2vol(const list_t *, 58 hr_volume_t *); 59 static void meta_gmirror_encode(void *, void *); 60 static errno_t meta_gmirror_decode(const void *, void *); 61 static errno_t meta_gmirror_get_block(service_id_t, void **); 62 static errno_t meta_gmirror_write_block(service_id_t, const void *); 63 static bool meta_gmirror_has_valid_magic(const void *); 64 static bool meta_gmirror_compare_uuids(const void *, const void *); 65 static void meta_gmirror_inc_counter(void *); 66 static errno_t meta_gmirror_save(hr_volume_t *, bool); 67 static const char *meta_gmirror_get_devname(const void *); 68 static hr_level_t meta_gmirror_get_level(const void *); 69 static uint64_t meta_gmirror_get_data_offset(void); 70 static size_t meta_gmirror_get_size(void); 71 static uint8_t meta_gmirror_get_flags(void); 55 static void *meta_gmirror_alloc_struct(void); 56 static errno_t meta_gmirror_init_vol2meta(const hr_volume_t *, void *); 57 static errno_t meta_gmirror_init_meta2vol(const list_t *, hr_volume_t *); 58 static void meta_gmirror_encode(void *, void *); 59 static errno_t meta_gmirror_decode(const void *, void *); 60 static errno_t meta_gmirror_get_block(service_id_t, void **); 61 static errno_t meta_gmirror_write_block(service_id_t, const void *); 62 static bool meta_gmirror_has_valid_magic(const void *); 63 static bool meta_gmirror_compare_uuids(const void *, const void *); 64 static void meta_gmirror_inc_counter(void *); 65 static errno_t meta_gmirror_save(hr_volume_t *, bool); 66 static const char *meta_gmirror_get_devname(const void *); 67 static hr_level_t meta_gmirror_get_level(const void *); 68 static uint64_t meta_gmirror_get_data_offset(void); 69 static size_t meta_gmirror_get_size(void); 70 static uint8_t meta_gmirror_get_flags(void); 72 71 static hr_metadata_type_t meta_gmirror_get_type(void); 73 static void 72 static void meta_gmirror_dump(const void *); 74 73 75 74 hr_superblock_ops_t metadata_gmirror_ops = { 76 .alloc_struct 77 .init_vol2meta 78 .init_meta2vol 79 .encode 80 .decode 81 .get_block 82 .write_block 83 .has_valid_magic 84 .compare_uuids 85 .inc_counter 86 .save 87 .get_devname 88 .get_level 89 .get_data_offset 90 .get_size 91 .get_flags 92 .get_type 93 .dump 75 .alloc_struct = meta_gmirror_alloc_struct, 76 .init_vol2meta = meta_gmirror_init_vol2meta, 77 .init_meta2vol = meta_gmirror_init_meta2vol, 78 .encode = meta_gmirror_encode, 79 .decode = meta_gmirror_decode, 80 .get_block = meta_gmirror_get_block, 81 .write_block = meta_gmirror_write_block, 82 .has_valid_magic = meta_gmirror_has_valid_magic, 83 .compare_uuids = meta_gmirror_compare_uuids, 84 .inc_counter = meta_gmirror_inc_counter, 85 .save = meta_gmirror_save, 86 .get_devname = meta_gmirror_get_devname, 87 .get_level = meta_gmirror_get_level, 88 .get_data_offset = meta_gmirror_get_data_offset, 89 .get_size = meta_gmirror_get_size, 90 .get_flags = meta_gmirror_get_flags, 91 .get_type = meta_gmirror_get_type, 92 .dump = meta_gmirror_dump 94 93 }; 95 94 -
uspace/srv/bd/hr/metadata/foreign/geom/hr_g_stripe.c
ra2281efc r6f13257 53 53 #include "g_stripe.h" 54 54 55 static void *meta_gstripe_alloc_struct(void); 56 static errno_t meta_gstripe_init_vol2meta(const hr_volume_t *, void *); 57 static errno_t meta_gstripe_init_meta2vol(const list_t *, 58 hr_volume_t *); 59 static void meta_gstripe_encode(void *, void *); 60 static errno_t meta_gstripe_decode(const void *, void *); 61 static errno_t meta_gstripe_get_block(service_id_t, void **); 62 static errno_t meta_gstripe_write_block(service_id_t, const void *); 63 static bool meta_gstripe_has_valid_magic(const void *); 64 static bool meta_gstripe_compare_uuids(const void *, const void *); 65 static void meta_gstripe_inc_counter(void *); 66 static errno_t meta_gstripe_save(hr_volume_t *, bool); 67 static const char *meta_gstripe_get_devname(const void *); 68 static hr_level_t meta_gstripe_get_level(const void *); 69 static uint64_t meta_gstripe_get_data_offset(void); 70 static size_t meta_gstripe_get_size(void); 71 static uint8_t meta_gstripe_get_flags(void); 72 static hr_metadata_type_t meta_gstripe_get_type(void); 73 static void meta_gstripe_dump(const void *); 55 static void *meta_gstripe_alloc_struct(void); 56 static errno_t meta_gstripe_init_vol2meta(const hr_volume_t *, void *); 57 static errno_t meta_gstripe_init_meta2vol(const list_t *, hr_volume_t *); 58 static void meta_gstripe_encode(void *, void *); 59 static errno_t meta_gstripe_decode(const void *, void *); 60 static errno_t meta_gstripe_get_block(service_id_t, void **); 61 static errno_t meta_gstripe_write_block(service_id_t, const void *); 62 static bool meta_gstripe_has_valid_magic(const void *); 63 static bool meta_gstripe_compare_uuids(const void *, const void *); 64 static void meta_gstripe_inc_counter(void *); 65 static errno_t meta_gstripe_save(hr_volume_t *, bool); 66 static const char *meta_gstripe_get_devname(const void *); 67 static hr_level_t meta_gstripe_get_level(const void *); 68 static uint64_t meta_gstripe_get_data_offset(void); 69 static size_t meta_gstripe_get_size(void); 70 static uint8_t meta_gstripe_get_flags(void); 71 static hr_metadata_type_t meta_gstripe_get_type(void); 72 static void meta_gstripe_dump(const void *); 74 73 75 74 hr_superblock_ops_t metadata_gstripe_ops = { 76 .alloc_struct 77 .init_vol2meta 78 .init_meta2vol 79 .encode 80 .decode 81 .get_block 82 .write_block 83 .has_valid_magic 84 .compare_uuids 85 .inc_counter 86 .save 87 .get_devname 88 .get_level 89 .get_data_offset 90 .get_size 91 .get_flags 92 .get_type 93 .dump 75 .alloc_struct = meta_gstripe_alloc_struct, 76 .init_vol2meta = meta_gstripe_init_vol2meta, 77 .init_meta2vol = meta_gstripe_init_meta2vol, 78 .encode = meta_gstripe_encode, 79 .decode = meta_gstripe_decode, 80 .get_block = meta_gstripe_get_block, 81 .write_block = meta_gstripe_write_block, 82 .has_valid_magic = meta_gstripe_has_valid_magic, 83 .compare_uuids = meta_gstripe_compare_uuids, 84 .inc_counter = meta_gstripe_inc_counter, 85 .save = meta_gstripe_save, 86 .get_devname = meta_gstripe_get_devname, 87 .get_level = meta_gstripe_get_level, 88 .get_data_offset = meta_gstripe_get_data_offset, 89 .get_size = meta_gstripe_get_size, 90 .get_flags = meta_gstripe_get_flags, 91 .get_type = meta_gstripe_get_type, 92 .dump = meta_gstripe_dump 94 93 }; 95 94 -
uspace/srv/bd/hr/metadata/foreign/softraid/hr_softraid.c
ra2281efc r6f13257 53 53 #include "softraidvar.h" 54 54 55 static void *meta_softraid_alloc_struct(void); 56 static errno_t meta_softraid_init_vol2meta(const hr_volume_t *, 57 void *); 58 static errno_t meta_softraid_init_meta2vol(const list_t *, 59 hr_volume_t *); 60 static void meta_softraid_encode(void *, void *); 61 static errno_t meta_softraid_decode(const void *, void *); 62 static errno_t meta_softraid_get_block(service_id_t, void **); 63 static errno_t meta_softraid_write_block(service_id_t, const void *); 64 static bool meta_softraid_has_valid_magic(const void *); 65 static bool meta_softraid_compare_uuids(const void *, 66 const void *); 67 static void meta_softraid_inc_counter(void *); 68 static errno_t meta_softraid_save(hr_volume_t *, bool); 69 static const char *meta_softraid_get_devname(const void *); 70 static hr_level_t meta_softraid_get_level(const void *); 71 static uint64_t meta_softraid_get_data_offset(void); 72 static size_t meta_softraid_get_size(void); 73 static uint8_t meta_softraid_get_flags(void); 55 static void *meta_softraid_alloc_struct(void); 56 static errno_t meta_softraid_init_vol2meta(const hr_volume_t *, void *); 57 static errno_t meta_softraid_init_meta2vol(const list_t *, hr_volume_t *); 58 static void meta_softraid_encode(void *, void *); 59 static errno_t meta_softraid_decode(const void *, void *); 60 static errno_t meta_softraid_get_block(service_id_t, void **); 61 static errno_t meta_softraid_write_block(service_id_t, const void *); 62 static bool meta_softraid_has_valid_magic(const void *); 63 static bool meta_softraid_compare_uuids(const void *, const void *); 64 static void meta_softraid_inc_counter(void *); 65 static errno_t meta_softraid_save(hr_volume_t *, bool); 66 static const char *meta_softraid_get_devname(const void *); 67 static hr_level_t meta_softraid_get_level(const void *); 68 static uint64_t meta_softraid_get_data_offset(void); 69 static size_t meta_softraid_get_size(void); 70 static uint8_t meta_softraid_get_flags(void); 74 71 static hr_metadata_type_t meta_softraid_get_type(void); 75 static void 72 static void meta_softraid_dump(const void *); 76 73 77 74 hr_superblock_ops_t metadata_softraid_ops = { 78 .alloc_struct 79 .init_vol2meta 80 .init_meta2vol 81 .encode 82 .decode 83 .get_block 84 .write_block 85 .has_valid_magic 86 .compare_uuids 87 .inc_counter 88 .save 89 .get_devname 90 .get_level 91 .get_data_offset 92 .get_size 93 .get_flags 94 .get_type 95 .dump 75 .alloc_struct = meta_softraid_alloc_struct, 76 .init_vol2meta = meta_softraid_init_vol2meta, 77 .init_meta2vol = meta_softraid_init_meta2vol, 78 .encode = meta_softraid_encode, 79 .decode = meta_softraid_decode, 80 .get_block = meta_softraid_get_block, 81 .write_block = meta_softraid_write_block, 82 .has_valid_magic = meta_softraid_has_valid_magic, 83 .compare_uuids = meta_softraid_compare_uuids, 84 .inc_counter = meta_softraid_inc_counter, 85 .save = meta_softraid_save, 86 .get_devname = meta_softraid_get_devname, 87 .get_level = meta_softraid_get_level, 88 .get_data_offset = meta_softraid_get_data_offset, 89 .get_size = meta_softraid_get_size, 90 .get_flags = meta_softraid_get_flags, 91 .get_type = meta_softraid_get_type, 92 .dump = meta_softraid_dump 96 93 }; 97 94 -
uspace/srv/bd/hr/metadata/native.c
ra2281efc r6f13257 53 53 #include "native.h" 54 54 55 static void *meta_native_alloc_struct(void); 56 static errno_t meta_native_init_vol2meta(const hr_volume_t *, void *); 57 static errno_t meta_native_init_meta2vol(const list_t *, 58 hr_volume_t *); 59 static void meta_native_encode(void *, void *); 60 static errno_t meta_native_decode(const void *, void *); 61 static errno_t meta_native_get_block(service_id_t, void **); 62 static errno_t meta_native_write_block(service_id_t, const void *); 63 static bool meta_native_has_valid_magic(const void *); 64 static bool meta_native_compare_uuids(const void *, const void *); 65 static void meta_native_inc_counter(void *); 66 static errno_t meta_native_save(hr_volume_t *, bool); 67 static const char *meta_native_get_devname(const void *); 68 static hr_level_t meta_native_get_level(const void *); 69 static uint64_t meta_native_get_data_offset(void); 70 static size_t meta_native_get_size(void); 71 static uint8_t meta_native_get_flags(void); 55 static void *meta_native_alloc_struct(void); 56 static errno_t meta_native_init_vol2meta(const hr_volume_t *, void *); 57 static errno_t meta_native_init_meta2vol(const list_t *, hr_volume_t *); 58 static void meta_native_encode(void *, void *); 59 static errno_t meta_native_decode(const void *, void *); 60 static errno_t meta_native_get_block(service_id_t, void **); 61 static errno_t meta_native_write_block(service_id_t, const void *); 62 static bool meta_native_has_valid_magic(const void *); 63 static bool meta_native_compare_uuids(const void *, const void *); 64 static void meta_native_inc_counter(void *); 65 static errno_t meta_native_save(hr_volume_t *, bool); 66 static const char *meta_native_get_devname(const void *); 67 static hr_level_t meta_native_get_level(const void *); 68 static uint64_t meta_native_get_data_offset(void); 69 static size_t meta_native_get_size(void); 70 static uint8_t meta_native_get_flags(void); 72 71 static hr_metadata_type_t meta_native_get_type(void); 73 static void 72 static void meta_native_dump(const void *); 74 73 75 74 hr_superblock_ops_t metadata_native_ops = { 76 .alloc_struct 77 .init_vol2meta 78 .init_meta2vol 79 .encode 80 .decode 81 .get_block 82 .write_block 83 .has_valid_magic 84 .compare_uuids 85 .inc_counter 86 .save 87 .get_devname 88 .get_level 89 .get_data_offset 90 .get_size 91 .get_flags 92 .get_type 93 .dump 75 .alloc_struct = meta_native_alloc_struct, 76 .init_vol2meta = meta_native_init_vol2meta, 77 .init_meta2vol = meta_native_init_meta2vol, 78 .encode = meta_native_encode, 79 .decode = meta_native_decode, 80 .get_block = meta_native_get_block, 81 .write_block = meta_native_write_block, 82 .has_valid_magic = meta_native_has_valid_magic, 83 .compare_uuids = meta_native_compare_uuids, 84 .inc_counter = meta_native_inc_counter, 85 .save = meta_native_save, 86 .get_devname = meta_native_get_devname, 87 .get_level = meta_native_get_level, 88 .get_data_offset = meta_native_get_data_offset, 89 .get_size = meta_native_get_size, 90 .get_flags = meta_native_get_flags, 91 .get_type = meta_native_get_type, 92 .dump = meta_native_dump 94 93 }; 95 94 -
uspace/srv/bd/hr/metadata/native.h
ra2281efc r6f13257 42 42 * Metadata is stored on the last block of an extent. 43 43 */ 44 #define HR_NATIVE_META_SIZE 1/* in blocks */45 #define HR_NATIVE_DATA_OFF 44 #define HR_NATIVE_META_SIZE 1 /* in blocks */ 45 #define HR_NATIVE_DATA_OFF 0 46 46 47 #define HR_NATIVE_MAGIC_STR 48 #define HR_NATIVE_MAGIC_SIZE 49 #define HR_NATIVE_UUID_LEN 50 #define HR_NATIVE_METADATA_VERSION 47 #define HR_NATIVE_MAGIC_STR "HelenRAID" 48 #define HR_NATIVE_MAGIC_SIZE 16 49 #define HR_NATIVE_UUID_LEN 16 50 #define HR_NATIVE_METADATA_VERSION 1 51 51 52 52 struct hr_metadata { 53 char 53 char magic[HR_NATIVE_MAGIC_SIZE]; 54 54 55 uint8_t 55 uint8_t uuid[HR_NATIVE_UUID_LEN]; 56 56 57 uint64_t data_blkno;/* usable blocks */58 uint64_t truncated_blkno;/* size of smallest extent */57 uint64_t data_blkno; /* usable blocks */ 58 uint64_t truncated_blkno; /* size of smallest extent */ 59 59 60 uint64_t 61 uint64_t 60 uint64_t data_offset; 61 uint64_t counter; 62 62 63 uint32_t version;/* XXX: yet unused */64 uint32_t 65 uint32_t index;/* index of extent in volume */66 uint32_t 63 uint32_t version; /* XXX: yet unused */ 64 uint32_t extent_no; 65 uint32_t index; /* index of extent in volume */ 66 uint32_t level; 67 67 68 uint32_t 69 uint32_t 68 uint32_t layout; 69 uint32_t strip_size; 70 70 71 uint32_t 71 uint32_t bsize; 72 72 73 char 73 char devname[HR_DEVNAME_LEN]; 74 74 } __attribute__((packed)); 75 75 -
uspace/srv/bd/hr/raid0.c
ra2281efc r6f13257 53 53 #include "var.h" 54 54 55 static void 56 static void 57 static errno_t 55 static void hr_raid0_update_vol_state(hr_volume_t *); 56 static void hr_raid0_state_callback(hr_volume_t *, size_t, errno_t); 57 static errno_t hr_raid0_bd_op(hr_bd_op_type_t, bd_srv_t *, aoff64_t, size_t, 58 58 void *, const void *, size_t); 59 59 60 60 /* bdops */ 61 static errno_t 62 static errno_t 63 static errno_t 61 static errno_t hr_raid0_bd_open(bd_srvs_t *, bd_srv_t *); 62 static errno_t hr_raid0_bd_close(bd_srv_t *); 63 static errno_t hr_raid0_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, 64 64 size_t); 65 static errno_t 66 static errno_t 65 static errno_t hr_raid0_bd_sync_cache(bd_srv_t *, aoff64_t, size_t); 66 static errno_t hr_raid0_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, 67 67 const void *, size_t); 68 static errno_t 69 static errno_t 68 static errno_t hr_raid0_bd_get_block_size(bd_srv_t *, size_t *); 69 static errno_t hr_raid0_bd_get_num_blocks(bd_srv_t *, aoff64_t *); 70 70 71 71 static bd_ops_t hr_raid0_bd_ops = { 72 .open 73 .close 74 .sync_cache 75 .read_blocks 76 .write_blocks 77 .get_block_size 78 .get_num_blocks 72 .open = hr_raid0_bd_open, 73 .close = hr_raid0_bd_close, 74 .sync_cache = hr_raid0_bd_sync_cache, 75 .read_blocks = hr_raid0_bd_read_blocks, 76 .write_blocks = hr_raid0_bd_write_blocks, 77 .get_block_size = hr_raid0_bd_get_block_size, 78 .get_num_blocks = hr_raid0_bd_get_num_blocks 79 79 }; 80 80 -
uspace/srv/bd/hr/raid1.c
ra2281efc r6f13257 56 56 #include "var.h" 57 57 58 static void 59 static void 60 static size_t 58 static void hr_raid1_update_vol_state(hr_volume_t *); 59 static void hr_raid1_ext_state_callback(hr_volume_t *, size_t, errno_t); 60 static size_t hr_raid1_count_good_extents(hr_volume_t *, uint64_t, size_t, 61 61 uint64_t); 62 static errno_t 62 static errno_t hr_raid1_bd_op(hr_bd_op_type_t, bd_srv_t *, aoff64_t, size_t, 63 63 void *, const void *, size_t); 64 static errno_t 65 static errno_t 66 static errno_t 67 static errno_t 64 static errno_t hr_raid1_rebuild(void *); 65 static errno_t init_rebuild(hr_volume_t *, size_t *); 66 static errno_t swap_hs(hr_volume_t *, size_t, size_t); 67 static errno_t hr_raid1_restore_blocks(hr_volume_t *, size_t, uint64_t, size_t, 68 68 void *); 69 69 70 70 /* bdops */ 71 static errno_t 72 static errno_t 73 static errno_t 71 static errno_t hr_raid1_bd_open(bd_srvs_t *, bd_srv_t *); 72 static errno_t hr_raid1_bd_close(bd_srv_t *); 73 static errno_t hr_raid1_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, 74 74 size_t); 75 static errno_t 76 static errno_t 75 static errno_t hr_raid1_bd_sync_cache(bd_srv_t *, aoff64_t, size_t); 76 static errno_t hr_raid1_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, 77 77 const void *, size_t); 78 static errno_t 79 static errno_t 78 static errno_t hr_raid1_bd_get_block_size(bd_srv_t *, size_t *); 79 static errno_t hr_raid1_bd_get_num_blocks(bd_srv_t *, aoff64_t *); 80 80 81 81 static bd_ops_t hr_raid1_bd_ops = { 82 .open 83 .close 84 .sync_cache 85 .read_blocks 86 .write_blocks 87 .get_block_size 88 .get_num_blocks 82 .open = hr_raid1_bd_open, 83 .close = hr_raid1_bd_close, 84 .sync_cache = hr_raid1_bd_sync_cache, 85 .read_blocks = hr_raid1_bd_read_blocks, 86 .write_blocks = hr_raid1_bd_write_blocks, 87 .get_block_size = hr_raid1_bd_get_block_size, 88 .get_num_blocks = hr_raid1_bd_get_num_blocks 89 89 }; 90 90 -
uspace/srv/bd/hr/raid5.c
ra2281efc r6f13257 54 54 #include "var.h" 55 55 56 static errno_t hr_raid5_vol_usable(hr_volume_t *); 57 static ssize_t hr_raid5_get_bad_ext(hr_volume_t *); 58 static errno_t hr_raid5_update_vol_state(hr_volume_t *); 59 static void hr_raid5_handle_extent_error(hr_volume_t *, size_t, errno_t); 60 static void xor(void *, const void *, size_t); 61 static errno_t hr_raid5_read_degraded(hr_volume_t *, uint64_t, uint64_t, 56 static errno_t hr_raid5_vol_usable(hr_volume_t *); 57 static ssize_t hr_raid5_get_bad_ext(hr_volume_t *); 58 static errno_t hr_raid5_update_vol_state(hr_volume_t *); 59 static void hr_raid5_handle_extent_error(hr_volume_t *, size_t, errno_t); 60 static void xor(void *, const void *, size_t); 61 62 static errno_t hr_raid5_read_degraded(hr_volume_t *, uint64_t, uint64_t, 62 63 void *, size_t); 63 static errno_t 64 static errno_t hr_raid5_write(hr_volume_t *, uint64_t, uint64_t, aoff64_t, 64 65 const void *, size_t); 65 static errno_t 66 static errno_t hr_raid5_write_parity(hr_volume_t *, uint64_t, uint64_t, 66 67 uint64_t, const void *, size_t); 67 static errno_t 68 static errno_t hr_raid5_bd_op(hr_bd_op_type_t, bd_srv_t *, aoff64_t, size_t, 68 69 void *, const void *, size_t); 69 static errno_t 70 static errno_t hr_raid5_rebuild(void *); 70 71 71 72 /* bdops */ 72 static errno_t 73 static errno_t 74 static errno_t 73 static errno_t hr_raid5_bd_open(bd_srvs_t *, bd_srv_t *); 74 static errno_t hr_raid5_bd_close(bd_srv_t *); 75 static errno_t hr_raid5_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, 75 76 size_t); 76 static errno_t 77 static errno_t 77 static errno_t hr_raid5_bd_sync_cache(bd_srv_t *, aoff64_t, size_t); 78 static errno_t hr_raid5_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, 78 79 const void *, size_t); 79 static errno_t 80 static errno_t 80 static errno_t hr_raid5_bd_get_block_size(bd_srv_t *, size_t *); 81 static errno_t hr_raid5_bd_get_num_blocks(bd_srv_t *, aoff64_t *); 81 82 82 83 static bd_ops_t hr_raid5_bd_ops = { 83 .open 84 .close 85 .sync_cache 86 .read_blocks 87 .write_blocks 88 .get_block_size 89 .get_num_blocks 84 .open = hr_raid5_bd_open, 85 .close = hr_raid5_bd_close, 86 .sync_cache = hr_raid5_bd_sync_cache, 87 .read_blocks = hr_raid5_bd_read_blocks, 88 .write_blocks = hr_raid5_bd_write_blocks, 89 .get_block_size = hr_raid5_bd_get_block_size, 90 .get_num_blocks = hr_raid5_bd_get_num_blocks 90 91 }; 91 92 -
uspace/srv/bd/hr/superblock.h
ra2281efc r6f13257 44 44 45 45 typedef struct hr_superblock_ops { 46 void 47 errno_t 48 errno_t 49 void 50 errno_t 51 errno_t 52 errno_t 53 bool 54 bool 55 void 56 errno_t 57 const char 58 hr_level_t 59 uint64_t 60 size_t 61 uint8_t 62 void 46 void *(*alloc_struct)(void); 47 errno_t (*init_vol2meta)(const hr_volume_t *, void *); 48 errno_t (*init_meta2vol)(const list_t *, hr_volume_t *); 49 void (*encode)(void *, void *); 50 errno_t (*decode)(const void *, void *); 51 errno_t (*get_block)(service_id_t, void **); 52 errno_t (*write_block)(service_id_t, const void *); 53 bool (*has_valid_magic)(const void *); 54 bool (*compare_uuids)(const void *, const void *); 55 void (*inc_counter)(void *); 56 errno_t (*save)(hr_volume_t *, bool); 57 const char *(*get_devname)(const void *); 58 hr_level_t (*get_level)(const void *); 59 uint64_t (*get_data_offset)(void); 60 size_t (*get_size)(void); 61 uint8_t (*get_flags)(void); 62 void (*dump)(const void *); 63 63 hr_metadata_type_t (*get_type)(void); 64 64 } hr_superblock_ops_t; 65 65 66 66 extern hr_superblock_ops_t *get_type_ops(hr_metadata_type_t); 67 extern errno_t 67 extern errno_t find_metadata(service_id_t, void **, hr_metadata_type_t *); 68 68 69 69 #endif -
uspace/srv/bd/hr/util.c
ra2281efc r6f13257 55 55 #include "var.h" 56 56 57 static bool hr_range_lock_overlap(hr_range_lock_t *, hr_range_lock_t *); 58 static errno_t hr_add_svc_linked_to_list(list_t *, service_id_t, bool, 59 void *); 60 static void free_dev_list_member(struct dev_list_member *); 61 static void free_svc_id_list(list_t *); 62 static errno_t hr_fill_disk_part_svcs_list(list_t *); 63 static errno_t block_init_dev_list(list_t *); 64 static void block_fini_dev_list(list_t *); 65 static errno_t hr_util_get_matching_md_svcs_list(list_t *, list_t *, 57 static bool hr_range_lock_overlap(hr_range_lock_t *, hr_range_lock_t *); 58 static errno_t hr_add_svc_linked_to_list(list_t *, service_id_t, bool, void *); 59 static void free_dev_list_member(struct dev_list_member *); 60 static void free_svc_id_list(list_t *); 61 static errno_t hr_fill_disk_part_svcs_list(list_t *); 62 static errno_t block_init_dev_list(list_t *); 63 static void block_fini_dev_list(list_t *); 64 static errno_t hr_util_get_matching_md_svcs_list(list_t *, list_t *, 66 65 service_id_t, hr_metadata_type_t, void *); 67 static errno_t hr_util_assemble_from_matching_list(list_t *, hr_metadata_type_t); 68 static errno_t hr_fill_svcs_list_from_cfg(hr_config_t *, list_t *); 66 static errno_t hr_util_assemble_from_matching_list(list_t *, 67 hr_metadata_type_t); 68 static errno_t hr_fill_svcs_list_from_cfg(hr_config_t *, list_t *); 69 69 70 70 #define HR_RL_LIST_LOCK(vol) (fibril_mutex_lock(&(vol)->range_lock_list_lock)) -
uspace/srv/bd/hr/util.h
ra2281efc r6f13257 46 46 47 47 struct dev_list_member { 48 link_t 49 service_id_t 50 void 51 bool 52 bool 53 bool 48 link_t link; 49 service_id_t svc_id; 50 void *md; 51 bool inited; 52 bool md_present; 53 bool fini; 54 54 }; 55 55 … … 66 66 log_msg(LOG_DEFAULT, LVL_ERROR, format, ##__VA_ARGS__) 67 67 68 69 extern errno_t hr_create_vol_struct(hr_volume_t **, hr_level_t, 70 const char *, hr_metadata_type_t); 71 extern void hr_destroy_vol_struct(hr_volume_t *); 72 extern errno_t hr_get_volume_svcs(size_t *, service_id_t **); 73 extern hr_volume_t *hr_get_volume(service_id_t); 74 extern errno_t hr_remove_volume(service_id_t); 75 extern errno_t hr_init_extents_from_cfg(hr_volume_t *, hr_config_t *); 76 extern void hr_fini_devs(hr_volume_t *); 77 extern errno_t hr_register_volume(hr_volume_t *); 78 extern errno_t hr_check_ba_range(hr_volume_t *, size_t, uint64_t); 79 extern void hr_add_ba_offset(hr_volume_t *, uint64_t *); 80 extern void hr_update_ext_state(hr_volume_t *, size_t, 81 hr_ext_state_t); 82 extern void hr_update_hotspare_state(hr_volume_t *, size_t, 83 hr_ext_state_t); 84 extern void hr_update_vol_state(hr_volume_t *, hr_vol_state_t); 85 extern void hr_update_ext_svc_id(hr_volume_t *, size_t, 86 service_id_t); 87 extern void hr_update_hotspare_svc_id(hr_volume_t *, size_t, 88 service_id_t); 89 extern void hr_sync_all_extents(hr_volume_t *); 90 extern size_t hr_count_extents(hr_volume_t *, hr_ext_state_t); 91 extern void hr_mark_vol_state_dirty(hr_volume_t *); 92 extern void hr_range_lock_release(hr_range_lock_t *); 93 extern hr_range_lock_t *hr_range_lock_acquire(hr_volume_t *, uint64_t, 68 extern errno_t hr_create_vol_struct(hr_volume_t **, hr_level_t, const char *, 69 hr_metadata_type_t); 70 extern void hr_destroy_vol_struct(hr_volume_t *); 71 extern errno_t hr_get_volume_svcs(size_t *, service_id_t **); 72 extern hr_volume_t *hr_get_volume(service_id_t); 73 extern errno_t hr_remove_volume(service_id_t); 74 extern errno_t hr_init_extents_from_cfg(hr_volume_t *, hr_config_t *); 75 extern void hr_fini_devs(hr_volume_t *); 76 extern errno_t hr_register_volume(hr_volume_t *); 77 extern errno_t hr_check_ba_range(hr_volume_t *, size_t, uint64_t); 78 extern void hr_add_ba_offset(hr_volume_t *, uint64_t *); 79 extern void hr_update_ext_state(hr_volume_t *, size_t, hr_ext_state_t); 80 extern void hr_update_hotspare_state(hr_volume_t *, size_t, hr_ext_state_t); 81 extern void hr_update_vol_state(hr_volume_t *, hr_vol_state_t); 82 extern void hr_update_ext_svc_id(hr_volume_t *, size_t, service_id_t); 83 extern void hr_update_hotspare_svc_id(hr_volume_t *, size_t, service_id_t); 84 extern void hr_sync_all_extents(hr_volume_t *); 85 extern size_t hr_count_extents(hr_volume_t *, hr_ext_state_t); 86 extern void hr_mark_vol_state_dirty(hr_volume_t *); 87 extern void hr_range_lock_release(hr_range_lock_t *); 88 extern hr_range_lock_t *hr_range_lock_acquire(hr_volume_t *, uint64_t, 94 89 uint64_t); 95 extern errno_t 96 extern errno_t 90 extern errno_t hr_util_try_assemble(hr_config_t *, size_t *); 91 extern errno_t hr_util_add_hotspare(hr_volume_t *, service_id_t); 97 92 98 93 #endif -
uspace/srv/bd/hr/var.h
ra2281efc r6f13257 47 47 #include "superblock.h" 48 48 49 #define NAME 50 #define HR_STRIP_SIZE 49 #define NAME "hr" 50 #define HR_STRIP_SIZE DATA_XFER_LIMIT 51 51 52 52 struct hr_volume; … … 56 56 57 57 typedef struct hr_ops { 58 errno_t 59 errno_t 60 void 61 errno_t 58 errno_t (*create)(hr_volume_t *); 59 errno_t (*init)(hr_volume_t *); 60 void (*state_event)(hr_volume_t *); 61 errno_t (*add_hotspare)(hr_volume_t *, service_id_t); 62 62 } hr_ops_t; 63 63 64 64 typedef struct hr_volume { 65 link_t lvolumes;/* link to all volumes list */66 hr_ops_t hr_ops;/* level init and create fcns */67 bd_srvs_t hr_bds;/* block interface to the vol */68 service_id_t svc_id;/* service id */65 link_t lvolumes; /* link to all volumes list */ 66 hr_ops_t hr_ops; /* level init and create fcns */ 67 bd_srvs_t hr_bds; /* block interface to the vol */ 68 service_id_t svc_id; /* service id */ 69 69 70 fibril_mutex_t lock;/* XXX: gone after para */71 list_t range_lock_list;/* list of range locks */72 fibril_mutex_t range_lock_list_lock;/* range locks list lock */73 hr_fpool_t *fge;/* fibril pool */70 fibril_mutex_t lock; /* XXX: gone after para */ 71 list_t range_lock_list; /* list of range locks */ 72 fibril_mutex_t range_lock_list_lock; /* range locks list lock */ 73 hr_fpool_t *fge; /* fibril pool */ 74 74 75 void 76 fibril_mutex_t md_lock;/* lock protecting in_mem_md */75 void *in_mem_md; 76 fibril_mutex_t md_lock; /* lock protecting in_mem_md */ 77 77 78 78 hr_superblock_ops_t *meta_ops; 79 79 80 80 /* invariants */ 81 size_t extent_no;/* number of extents */82 size_t bsize;/* block size */83 uint64_t truncated_blkno;/* blkno per extent */84 uint64_t data_blkno;/* no. of user usable blocks */85 uint64_t data_offset;/* user data offset in blocks */86 uint32_t strip_size;/* strip size */87 hr_level_t level;/* volume level */88 hr_layout_t layout;/* RAID Level Qualifier */89 char 81 size_t extent_no; /* number of extents */ 82 size_t bsize; /* block size */ 83 uint64_t truncated_blkno; /* blkno per extent */ 84 uint64_t data_blkno; /* no. of user usable blocks */ 85 uint64_t data_offset; /* user data offset in blocks */ 86 uint32_t strip_size; /* strip size */ 87 hr_level_t level; /* volume level */ 88 hr_layout_t layout; /* RAID Level Qualifier */ 89 char devname[HR_DEVNAME_LEN]; 90 90 91 hr_extent_t 92 fibril_rwlock_t extents_lock;/* extent service id lock */91 hr_extent_t extents[HR_MAX_EXTENTS]; 92 fibril_rwlock_t extents_lock; /* extent service id lock */ 93 93 94 size_t hotspare_no;/* no. of available hotspares */95 hr_extent_t 96 fibril_mutex_t hotspare_lock;/* lock protecting hotspares */94 size_t hotspare_no; /* no. of available hotspares */ 95 hr_extent_t hotspares[HR_MAX_HOTSPARES]; 96 fibril_mutex_t hotspare_lock; /* lock protecting hotspares */ 97 97 98 fibril_rwlock_t states_lock;/* states lock */98 fibril_rwlock_t states_lock; /* states lock */ 99 99 100 _Atomic bool state_dirty;/* dirty state */100 _Atomic bool state_dirty; /* dirty state */ 101 101 102 102 /* XXX: atomic_uint_least64_t? */ 103 _Atomic uint64_t rebuild_blk; 104 _Atomic int open_cnt;/* open/close() counter */105 hr_vol_state_t state;/* volume state */106 void 103 _Atomic uint64_t rebuild_blk; /* rebuild position */ 104 _Atomic int open_cnt; /* open/close() counter */ 105 hr_vol_state_t state; /* volume state */ 106 void (*state_callback)(hr_volume_t *, size_t, errno_t); 107 107 } hr_volume_t; 108 108 … … 118 118 119 119 typedef struct hr_range_lock { 120 link_t 121 fibril_mutex_t 122 hr_volume_t *vol;/* back-pointer to volume */123 uint64_t off;/* start of the range */124 uint64_t len;/* length of the range */120 link_t link; 121 fibril_mutex_t lock; 122 hr_volume_t *vol; /* back-pointer to volume */ 123 uint64_t off; /* start of the range */ 124 uint64_t len; /* length of the range */ 125 125 126 size_t pending;/* prot. by vol->range_lock_list_lock */127 bool ignore;/* prot. by vol->range_lock_list_lock */126 size_t pending; /* prot. by vol->range_lock_list_lock */ 127 bool ignore; /* prot. by vol->range_lock_list_lock */ 128 128 } hr_range_lock_t; 129 129 130 extern errno_t 131 extern errno_t 132 extern errno_t 130 extern errno_t hr_raid0_create(hr_volume_t *); 131 extern errno_t hr_raid1_create(hr_volume_t *); 132 extern errno_t hr_raid5_create(hr_volume_t *); 133 133 134 extern errno_t 135 extern errno_t 136 extern errno_t 134 extern errno_t hr_raid0_init(hr_volume_t *); 135 extern errno_t hr_raid1_init(hr_volume_t *); 136 extern errno_t hr_raid5_init(hr_volume_t *); 137 137 138 extern void 139 extern void 140 extern void 138 extern void hr_raid0_state_event(hr_volume_t *); 139 extern void hr_raid1_state_event(hr_volume_t *); 140 extern void hr_raid5_state_event(hr_volume_t *); 141 141 142 extern errno_t 143 extern errno_t 142 extern errno_t hr_raid1_add_hotspare(hr_volume_t *, service_id_t); 143 extern errno_t hr_raid5_add_hotspare(hr_volume_t *, service_id_t); 144 144 145 145 #endif
Note:
See TracChangeset
for help on using the changeset viewer.