📄 lvm.h.txt
字号:
any questions,send email to netxiong@eyou.com
相关文件
/drivers/md/lvm.c
*******************block设备号映射为lv和vg设备号******************
#define VG_BLK(a) ( vg_lv_map[a].vg_number)
#define LV_BLK(a) ( vg_lv_map[a].lv_number)
******************************************************************
*********************VG的基本数据结构*********************************
(1)
/*
* vg_t的定义,这个定义是内存中数据结构的定义
*/
typedef struct {
char vg_name[NAME_LEN]; /* volume group name */
uint vg_number; /* volume group number */
uint vg_access; /* read/write */
uint vg_status; /* active or not */
uint lv_max; //最大的lv的数目
uint lv_cur; // 当前VG组中的LV的数目
uint lv_open; /* open logical volumes */
uint pv_max; //最大的pv的数目
uint pv_cur; // 当前的VG组中的PV数目
uint pv_act; // 当前的VG组中的活动PV数目
uint dummy; /* was obsolete max_pe_per_pv */
uint vgda; /* volume group descriptor arrays FU */
uint pe_size; //以扇区为单位计数的pe的大小。例如pe_size=4,表明大小为4*512字节
uint pe_total; //pe的数量
uint pe_allocated; //已经分配的pe的数量
uint pvg_total; /* physical volume groups FU */
struct proc_dir_entry *proc;
pv_t *pv[ABS_MAX_PV + 1]; /* 指向这个VG组中的PV */
lv_t *lv[ABS_MAX_LV + 1]; /* 指向这个VG组中的LV */
char vg_uuid[UUID_LEN+1]; /* volume group UUID */
#ifdef __KERNEL__
struct proc_dir_entry *vg_dir_pde;
struct proc_dir_entry *lv_subdir_pde;
struct proc_dir_entry *pv_subdir_pde;
#else
char dummy1[200];
#endif
} vg_v3_t;
(2)
/*
* 这个是磁盘中的VG的组织形式。
*/
typedef struct vg_disk_v2 {
uint8_t vg_uuid[UUID_LEN]; /* volume group UUID */
uint8_t vg_name_dummy[NAME_LEN-UUID_LEN]; /* rest of v1 VG name */
uint32_t vg_number; /* volume group number */
uint32_t vg_access; /* read/write */
uint32_t vg_status; /* active or not */
uint32_t lv_max; /* maximum logical volumes */
uint32_t lv_cur; /* current logical volumes */
uint32_t lv_open; /* open logical volumes */
uint32_t pv_max; /* maximum physical volumes */
uint32_t pv_cur; /* current physical volumes FU */
uint32_t pv_act; /* active physical volumes */
uint32_t dummy;
uint32_t vgda; /* volume group descriptor arrays FU */
uint32_t pe_size; /* physical extent size in sectors */
uint32_t pe_total; /* total of physical extents */
uint32_t pe_allocated; /* allocated physical extents */
uint32_t pvg_total; /* physical volume groups FU */
} vg_disk_t;
************************************************************
******************************LV的数据结构**************************
(2)
lv_t的定义
typedef struct lv_v4 {
char lv_name[NAME_LEN];
char vg_name[NAME_LEN];
uint lv_access; //标志是什么lv,snapshot还是源lv
uint lv_status;
uint lv_open;/* HM */
kdev_t lv_dev;/* HM */
uint lv_number; //这个编号就是vg中lv中数组的下标,vg->lv[lv_number] = lv
uint lv_mirror_copies; //未来使用
uint lv_recovery;
uint lv_schedule;
uint lv_size; //lv的大小,是以扇区为计数单位的。是pe,le的单位的整数倍
pe_t *lv_current_pe; //指向一个指针数组,所有这个lv中的pe都有一个这样的结构对应
uint lv_current_le; //当前这个lv中le的数量
uint lv_allocated_le; //分配的le的数量,一般来说和lv_current_le相同
//可以用它来标志lv_current_pe的大小
uint lv_stripes;
uint lv_stripesize;
uint lv_badblock; //未来使用
uint lv_allocation;
uint lv_io_timeout; //未来使用
uint lv_read_ahead;
struct lv_v4 *lv_snapshot_org;
struct lv_v4 *lv_snapshot_prev;
struct lv_v4 *lv_snapshot_next;
//用来保存源数据盘到snap_shot盘的映射
lv_block_exception_t *lv_block_exception;
uint lv_remap_ptr; //用来标记当前使用的exception的位置
uint lv_remap_end; //指示exception的数量
uint lv_chunk_size; //这个lv的块大小,以扇区为计算单位,只对snapshot有用,源盘为0
uint lv_snapshot_minor; //如果这个个lv是snapshot,那么这里就存储源盘的minor号,反之为0
#ifdef __KERNEL__
struct kiobuf *lv_iobuf;
struct semaphore lv_snapshot_sem;
/*
* 以下的这几个数据结构,都只对snap_shot盘有用。
*/
struct list_head *lv_snapshot_hash_table; //exception的哈希表。存储exception
ulong lv_snapshot_hash_table_size; //哈希表的长度
ulong lv_snapshot_hash_mask; //哈希表的mask值
struct page *lv_COW_table_page;
wait_queue_head_t lv_snapshot_wait;
int lv_snapshot_use_rate;
void *vg;
uint lv_allocated_snapshot_le;
#else
char dummy[200];
#endif
} lv_v4_t;
(3)
//pe的核心数据结构,描述了pe的各种属性
typedef struct {
kdev_t dev;
ulong pe; //pe的开始扇区地址,以扇区为计量单位
ulong reads;
ulong writes;
} pe_t;
******************************************************************
************************PV的内存数据结构和磁盘数据结构***************
(3)
/*
* 这个结构指示包含这个结构的相应的VG,LV,PV在磁盘上的大小和起始位置。
* 这样才能定位这些物理结构。以便在系统启动的时候将数据读出来
*/
typedef struct {
uint32_t base; //结构从什么地方开始,也就是在磁盘上的偏移量
uint32_t size; //结构的大小
} lvm_disk_data_t;
(1)
/*
* 这是PV在磁盘上的数据组织结构。
*/
typedef struct pv_disk_v2 {
uint8_t id[2];
uint16_t version;
lvm_disk_data_t pv_on_disk;
lvm_disk_data_t vg_on_disk;
lvm_disk_data_t pv_uuidlist_on_disk;
lvm_disk_data_t lv_on_disk;
lvm_disk_data_t pe_on_disk;
uint8_t pv_uuid[NAME_LEN];
uint8_t vg_name[NAME_LEN];
uint8_t system_id[NAME_LEN];
uint32_t pv_major;
uint32_t pv_number;
uint32_t pv_status;
uint32_t pv_allocatable;
uint32_t pv_size; //表明这个pv设备的大小,一般就是原始设备的大小
uint32_t lv_cur;
uint32_t pe_size; //每一个pe的大小
uint32_t pe_total; //一共有多少pe。
uint32_t pe_allocated;
uint32_t pe_start; //这个pv的pe开始扇区
} pv_disk_t;
(2)
/*
* 这个是内存中的PV组织结构。它是从磁盘上读出来在内存中建立的
*/
typedef struct pv_v2 {
char id[2]; /* Identifier */
unsigned short version; /* HM lvm version */
lvm_disk_data_t pv_on_disk;
lvm_disk_data_t vg_on_disk;
lvm_disk_data_t pv_uuidlist_on_disk;
lvm_disk_data_t lv_on_disk;
lvm_disk_data_t pe_on_disk;
char pv_name[NAME_LEN];
char vg_name[NAME_LEN];
char system_id[NAME_LEN]; /* for vgexport/vgimport */
kdev_t pv_dev;
uint pv_number;
uint pv_status;
uint pv_allocatable;
uint pv_size; /* HM */
uint lv_cur; //表明这个pv中有多少个lv和它相关联
uint pe_size;
uint pe_total;
uint pe_allocated;
uint pe_stale; /* for future use */
pe_disk_t *pe; //这个pv中有多少个pe就都在这里存储。
struct block_device *bd;
char pv_uuid[UUID_LEN+1];
#ifndef __KERNEL__
uint32_t pe_start; //这个pv的pe开始扇区
#endif
} pv_t;
(3)
typedef struct {
uint16_t lv_num; //所属的lv的号码,其实就是vg中的lv数组的下标号码,用来找到lv
uint16_t le_num; //在所属的lv中的号码。从0开始编号
} pe_disk_t;
*********************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -