📄 rrc_single.c
字号:
/* * Single-disk driver code for the raidreconf utility * (C) 1999,2000 by Jakob Oestergaard * * This source is covered by the GNU GPL, the same as all Linux kernel * sources. */#include "raidreconf.h"#include "rrc_common.h"#define GOOD_READ_LENGTH 128static const char *single_initialize (void *, md_cfg_entry_t *, rrc_disk_t *, unsigned long *);static driver_status_t single_request_blocks (void *);static const char *single_update_super (void *);static const char *single_map_global_to_local (void *, unsigned long, int *, unsigned long *);static unsigned long single_map_local_to_global (void *, int, unsigned long);static void single_free_blocks_above_gblock (void *, unsigned long);static void single_unfree_all_blocks (void *);typedef struct single_driver_priv { int diskid; rrc_disk_t *disks; unsigned long blocks_per_chunk; unsigned long total_blocks; unsigned long blocks_done;} single_driver_priv;level_driver_t *new_single_driver (void){ level_driver_t *drv = (level_driver_t *) malloc (sizeof (level_driver_t)); single_driver_priv *priv = (single_driver_priv *) malloc (sizeof (single_driver_priv)); if (!drv || !priv) return 0; drv->initialize = single_initialize; drv->request_blocks = single_request_blocks; drv->update_super = single_update_super; drv->map_global_to_local = single_map_global_to_local; drv->map_local_to_global = single_map_local_to_global; drv->free_blocks_above_gblock = single_free_blocks_above_gblock; drv->unfree_all_blocks = single_unfree_all_blocks; drv->priv = priv; priv->diskid = -1; priv->disks = 0; priv->blocks_per_chunk = 0; priv->total_blocks = 0; priv->blocks_done = 0; return drv;}static const char *single_initialize (void *thisp, md_cfg_entry_t * cfg, rrc_disk_t * cfgdisks, unsigned long *blocks){ single_driver_priv *this = (single_driver_priv *) thisp; assert (cfgdisks); assert (cfg); this->disks = cfgdisks; this->diskid = cfgdisks[0].disk_id; this->blocks_per_chunk = (cfg->array.param.chunk_size / MD_BLK_SIZ) / reconf_block_size; this->total_blocks = this->disks->chunks * this->blocks_per_chunk; *blocks = this->total_blocks; fprintf (stderr, "Single disk size: %lu blocks\n", this->total_blocks); return 0;}static driver_status_tsingle_request_blocks (void *thisp){ single_driver_priv *this = (single_driver_priv *) thisp; /* * This is simple: read from where we got to, wish for * blocks while we can still wish... */ while (can_wish_again () && this->blocks_done < this->total_blocks) { if (is_gblock_in_source (this->blocks_done)) { insert_wish (this->blocks_done); } this->blocks_done++; } if (can_wish_again ()) return LDR_DONE; return LDR_INCOMPLETE;}static const char *single_update_super (void *thisp){ fprintf (stderr, "There's no superblock on a plain disk. So we're done :)\n"); return 0;}static const char *single_map_global_to_local (void *thisp, unsigned long gblock, int *diskid, unsigned long *lblock){ single_driver_priv *this = (single_driver_priv *) thisp; if (gblock >= this->total_blocks) return "Cannot map out-of-range gblocks to single device"; /* This one's simple :) */ *diskid = this->diskid; *lblock = gblock; return 0;}static unsigned longsingle_map_local_to_global (void *thisp, int diskid, unsigned long block){ single_driver_priv *this = (single_driver_priv *) thisp; if (diskid != this->diskid) { fprintf (stderr, "Diskid %i is not the single disk id %i -> cannot map to global\n", diskid, this->diskid); abort (); } return block;}static voidsingle_free_blocks_above_gblock (void *thisp, unsigned long gblock){ single_driver_priv *this = (single_driver_priv *) thisp; unsigned long block; for (block = gblock; block < this->total_blocks; block++) unchecked_mark_disk_block_free (this->diskid, block);}static voidsingle_unfree_all_blocks (void *thisp){ single_driver_priv *this = (single_driver_priv *) thisp; unsigned long block; for (block = 0; block != this->total_blocks; block++) mark_disk_block_unfree (this->diskid, block);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -