⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rrc_common.h

📁 create raid tool at linux
💻 H
字号:
/* * Common interface for the level drivers * * (C) 2000 by Jakob Oestergaard * * This source is covered by the GNU GPL, the same as all Linux kernel * sources. */#ifndef __RRC_COMMON_H#define __RRC_COMMON_H#include "raidreconf.h"#include <limits.h>typedef struct wish_t {	int source_disk_id;	unsigned long source_rblock;	int sink_disk_id;	unsigned long sink_rblock;	struct wish_t *next;} wish_t;typedef struct fulfilled_t {	int sink_disk_id;	unsigned long sink_rblock;	char *data;	struct fulfilled_t *next;} fulfilled_t;/* * About free blocks:   A block is considered free, if it has been * read from the source disk.  Free means ``sink is free to write stuff * here''. * Thus, we only account free blocks on the source disks, sink-only disks * are per definition always entirely free.  nr_free_blocks() return only * number of free blocks on source disks. * * When the sink wishes for a block, this means it wants the data in * that global block read from somewhere on the old array.  It also * means, that it wants the sink-disk,sink-disk-block freed so that it * can safely write to it.  Freeing the block will mean reading it to * memory.  So in real-life (TM), wishing for one block can often mean * freeing two blocks, where only one can actually be written to * somewhere.  The freed blocks will end up in the list of fulfilled * requests, so the list of fulfilled requests _will_ actually hold * (lots of) blocks that hasn't directly been asked for by the sink * driver. * If the sink-disk,sink-disk-block locations of the un-wished-for * blocks are free themselves, we can easily flush these blocks.  If * they are not, we should probably look for a way to free them. * This, in turn, may leed to freeing even more un-wished-for blocks. * The sink will never get more than two blocks from each wish it * files, but this is still bad if we recurse for long (quadratic * memory requirements). * There is no simple way (that I thought of at least) to ensure that * we follow a request/read/write pattern so that this program can work * correctly at all times within some limited memory space (memory much * less than size of array).  Therefore we always run an algorithm check * before we actually perform the reconfiguration.  The algorithm check * is a full run of the reconfiguration, only with physical disk access * turned off. If such a run can succeed, so can one with physical disk * access. * * If algorithm check fails, we probably could try a multiple-pass * strategy. For example, converting chunk sizes first, then levels, * or going thru intermediate levels...  Eventually we could use a * scratch disk,  or use the parity blocks on raid-[145] as temporary * buffers. * * Driver vs. common-layer operation:    * * request: *  The sink driver will request that a number of blocks are read from *  the old array, so that it can write them to their proper location *  on the new array.  Wishes are inserted with global block *  addresses.  Global block N on the sink drive is usually not the *  same as global block N on the source drive, so before the wish is *  hooked into the wish-list, the common layer will have the source *  driver map the global block number into a *  source-disk,source-disk-block address. * * read: *  The source driver will use the common layer to fulfill requests *  that look good, that is, request sequences that are large and *  sequential.  As blocks are read, the common layer will mark them *  as free. * * write: *  The common layer will flush the fulfilled requests to the sink *  disks.  As the source driver will usually ask for sink-disk *  sequential regions, the writer can assume that just flushing the *  sorted sequences of fulfilled requests will perform reasonably *  well. * */const char *setup_free_blocks (unsigned ndisks, rrc_disk_t * diskcfg);const char *initialize_unique_disks (void);/*  * Drivers should not touch these directly */extern unsigned max_wishes;extern unsigned long reconf_block_size;extern char **source_disk_free_map;extern unsigned long *source_disk_free_size;extern unsigned long source_blocks, sink_blocks;/* * Drivers should use these routines instead... *//* * These are for the sink requester  */int can_wish_again (void);int is_gblock_in_source (unsigned long gblock);void insert_wish (unsigned long gblock);/* * These are generic */unsigned long nr_free_blocks (void);int is_diskid_in_source (int diskid);int is_disk_block_free (int diskid, unsigned long block);wish_t *wish_list_source_diskid (int source_disk_id);fulfilled_t *gift_list_diskid (int disk_id);const char *generic_write_blocks (int partial);void debug_print_nonfree_blocks (void);void debug_print_wish_list (void);void print_common_stats (void);/* * These are for the common reader stuff */void fulfill_wishes (int partial);int must_fulfill_more (int partial);unsigned nr_wishes_left (void);unsigned nr_gifts_left (void);void fulfill_wish (int diskid, unsigned long begin, unsigned long end);	/* do the reading *//* * This one's for the initial block freeing when we shrink arrays  */void mark_disk_block_free (int diskid, unsigned long block);/* to be used in free_block_above_gblock() only! */void unchecked_mark_disk_block_free (int diskid, unsigned long block);void mark_disk_block_unfree (int diskid, unsigned long block);#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -