From 954a9731e0e6c4f007e2fa59a3752d5d2bf5a430 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Fri, 28 Sep 2001 13:15:30 +0000 Subject: [PATCH] o logical data structures --- lib/metadata/metadata.h | 458 ++++++++++------------------------------ 1 file changed, 112 insertions(+), 346 deletions(-) diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h index 6c7068f69..f54d7ae41 100644 --- a/lib/metadata/metadata.h +++ b/lib/metadata/metadata.h @@ -1,368 +1,134 @@ /* * Copyright (C) 2001 Sistina Software * - * lvm is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * lvm is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU CC; see the file COPYING. If not, write to - * the Free Software Foundation, 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * This file is released under the GPL. * + * This is the in core representation of a volume group and it's + * associated physical and logical volumes. */ -/* FIXME: LVM1-format-specific stuff should be in lvm_v1.h instead */ +#ifndef METADATA_H +#define METADATA_H -#ifndef _LVM_METADATA_H -#define _LVM_METADATA_H +#define ID_LEN 32 -#include "metadata/lvm_v1.h" +struct id { + uint8_t chars[ID_LEN]; +}; -/*********************************************************** - * In core data representation. - ***********************************************************/ +struct logical_volume; -/* - * physical volume - core - */ -typedef struct pv { - 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; - uint pe_size; - uint pe_total; - uint pe_allocated; - uint pe_stale; /* for future use */ - pe_disk_t *pe; /* HM */ - struct block_device *bd; - char pv_uuid[UUID_LEN+1]; -#ifdef __KERNEL__ -#else - uint32_t pe_start; - char dummy[39]; -#endif -} pv_t; +struct physical_volume { + struct id *id; + struct device *dev; + char *vg_name; + + uint32_t status; + uint64_t size; + + /* physical extents */ + uint64_t pe_size; + uint64_t pe_start; + uint32_t pe_count; + uint32_t pe_allocated; +}; + +struct pe_specifier { + struct physical_volume *pv; + uint32_t pe; +}; + +struct logical_volume { + /* disk */ + struct id *id; + char *name; + + uint32_t access; + uint32_t status; + uint32_t open; + + uint64_t size; + uint32_t le_count; + + /* le -> pe mapping array */ + struct pe_specifier *map; +}; + +struct volume_group { + struct id *id; + char *name; + + uint64_t extent_size; + uint32_t extent_count; + uint32_t free_count; + + /* physical volumes */ + uint32_t pv_count; + struct physical_volume **pv; + + /* logical volumes */ + uint32_t lv_count; + struct logical_volume **lv; +}; + +/* ownership of returned objects passes */ +struct io_space { + struct str_list *(*get_vgs)(struct io_space *is); + struct dev_list *(*get_pvs)(struct io_space *is); + + struct physical_volume *read_pv(struct io_space *is, + struct device *dev); + int write_pv(struct io_space *is, struct physical_volume *pv); + + struct volume_group *(*read_vg)(struct io_space *is, + const char *vg_name); + int (*write_vg)(struct io_space *is, struct volume_group *vg); + void (*destructor)(struct io_space *is); + + struct device_manager *mgr; + void *private; +}; + +struct io_space *create_text_format(struct device_manager *mgr, + const char *text_file); +struct io_space *create_lvm1_format(struct device_manager *mgr); + +inline struct volume_group *read_vg(struct io_space *f) +{ + struct dev_list *pvs = f->get_pvs(); + return f->read_vg(pvs); +} + +inline int write_vg(struct io_object *f, struct volume_group *vg) +{ + return f->write_vg(vg); +} -/* - * extent descriptor - core - */ -typedef struct { - kdev_t dev; - uint32_t pe; /* to be changed if > 2TB */ - uint32_t reads; - uint32_t writes; -} pe_t; -/* - * block exception descriptor for snapshots - core - */ -typedef struct lv_block_exception_v1 { - struct list_head hash; - uint32_t rsector_org; - kdev_t rdev_org; - uint32_t rsector_new; - kdev_t rdev_new; -} lv_block_exception_t; +inline int write_backup(struct io_format *orig, struct io_format *text) +{ + +} -/* - * logical volume - core - */ -typedef struct lv { - char lv_name[NAME_LEN]; - char vg_name[NAME_LEN]; - uint lv_access; - uint lv_status; - uint lv_open; - kdev_t lv_dev; - uint lv_number; - uint lv_mirror_copies; /* for future use */ - uint lv_recovery; /* " */ - uint lv_schedule; /* " */ - uint lv_size; - pe_t *lv_current_pe; - uint lv_current_le; /* for future use */ - uint lv_allocated_le; - uint lv_stripes; - uint lv_stripesize; - uint lv_badblock; /* for future use */ - uint lv_allocation; - uint lv_io_timeout; /* for future use */ - uint lv_read_ahead; - /* delta to version 1 starts here */ - struct lv *lv_snapshot_org; - struct lv *lv_snapshot_prev; - struct lv *lv_snapshot_next; - lv_block_exception_t *lv_block_exception; - uint lv_remap_ptr; - uint lv_remap_end; - uint lv_chunk_size; - uint lv_snapshot_minor; - uint32_t chunk_shift; - uint32_t chunk_mask; +int id_eq(struct id *op1, struct id *op2); -} lv_t; +struct volume_group *create_vg(); +int destroy_vg(struct volume_group *vg); -/* - * volume group - core - */ -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; /* maximum logical volumes */ - uint lv_cur; /* current logical volumes */ - uint lv_open; /* open logical volumes */ - uint pv_max; /* maximum physical volumes */ - uint pv_cur; /* current physical volumes FU */ - uint pv_act; /* active physical volumes */ - uint dummy; /* was obsolete max_pe_per_pv */ - uint vgda; /* volume group descriptor arrays FU */ - uint pe_size; /* physical extent size in sectors */ - uint pe_total; /* total of physical extents */ - uint pe_allocated; /* allocated physical extents */ - uint pvg_total; /* physical volume groups FU */ - struct proc_dir_entry *proc; - pv_t *pv[MAX_PV]; /* physical volume struct pointers */ - lv_t *lv[MAX_LV]; /* logical volume struct pointers */ - char vg_uuid[UUID_LEN+1]; /* volume group UUID */ - uint32_t pe_shift; - uint32_t pe_mask; +int add_pv(struct volume_group *vg, struct physical_volume *pv); +struct physical_volume *find_pv(struct volume_group *vg, + struct physical_volume *pv); - struct proc_dir_entry *vg_dir_pde; - struct proc_dir_entry *lv_subdir_pde; - struct proc_dir_entry *pv_subdir_pde; -} vg_t; +int add_lv(struct volume_group *vg, struct logical_volume *lv); +struct logical_volume *find_lv(struct volume_group *vg, + struct logical_volume *lv); - -/*********************************************************** - * Status flags - **********************************************************/ - -/* volume group */ -#define VG_ACTIVE 0x01 /* vg_status */ -#define VG_EXPORTED 0x02 /* " */ -#define VG_EXTENDABLE 0x04 /* " */ - -#define VG_READ 0x01 /* vg_access */ -#define VG_WRITE 0x02 /* " */ -#define VG_CLUSTERED 0x04 /* " */ -#define VG_SHARED 0x08 /* " */ - -/* logical volume */ -#define LV_ACTIVE 0x01 /* lv_status */ -#define LV_SPINDOWN 0x02 /* " */ - -#define LV_READ 0x01 /* lv_access */ -#define LV_WRITE 0x02 /* " */ -#define LV_SNAPSHOT 0x04 /* " */ -#define LV_SNAPSHOT_ORG 0x08 /* " */ - -#define LV_BADBLOCK_ON 0x01 /* lv_badblock */ - -#define LV_STRICT 0x01 /* lv_allocation */ -#define LV_CONTIGUOUS 0x02 /* " */ - -/* physical volume */ -#define PV_ACTIVE 0x01 /* pv_status */ -#define PV_ALLOCATABLE 0x02 /* pv_allocatable */ - - -/* misc */ -#define LVM_SNAPSHOT_DROPPED_SECTOR 1 - - -/*********************************************************** - * Constants and limits - **********************************************************/ - -/* - * LVM_PE_T_MAX corresponds to: - * 8KB PE size can map a ~512 MB logical volume at the cost of 1MB memory, - * 128MB PE size can map a 8TB logical volume at the same cost of memory. - * - * Default PE size of 4 MB gives a maximum logical volume size of 256 GB. - * Maximum PE size of 16GB gives a maximum logical volume size of 1024 TB. - * - * AFAIK, the actual kernels limit this to 1 TB. - * - * Should be a sufficient spectrum - */ - -/* This is the usable size of pe_disk_t.le_num */ -#define LVM_PE_T_MAX ((1 << (sizeof(uint16_t) * 8)) - 2) - -/* FIXME: these numbers look like they could get too big */ -#define LVM_LV_SIZE_MAX(a) \ -((long long) LVM_PE_T_MAX * (a)->pe_size > \ - (long long) 1024 * 1024 / SECTOR_SIZE * 1024 * 1024 ? \ - (long long) 1024 * 1024 / SECTOR_SIZE * 1024 * 1024 : \ - (long long) LVM_PE_T_MAX * (a)->pe_size) - -#define LVM_MIN_PE_SIZE (8192L / SECTOR_SIZE) /* 8 KB in sectors */ - -/* 16GB in sectors */ -#define LVM_MAX_PE_SIZE ((16L * 1024L * 1024L / SECTOR_SIZE) * 1024) - -/* 4 MB in sectors */ -#define LVM_DEFAULT_PE_SIZE (4096L * 1024 / SECTOR_SIZE) - -#define LVM_DEFAULT_STRIPE_SIZE 16L /* 16 KB */ - -/* PAGESIZE in sectors */ -#define LVM_MIN_STRIPE_SIZE (PAGE_SIZE / SECTOR_SIZE) - -/* 512 KB in sectors */ -#define LVM_MAX_STRIPE_SIZE (512L * 1024 / SECTOR_SIZE) - -#define LVM_MAX_STRIPES 128 /* max # of stripes */ - -/* 1TB[sectors] */ -#define LVM_MAX_SIZE (1024LU * 1024 / SECTOR_SIZE * 1024 * 1024) - -#define LVM_MAX_MIRRORS 2 /* future use */ -#define LVM_MIN_READ_AHEAD 2 /* minimum read ahead sectors */ -#define LVM_MAX_READ_AHEAD 120 /* maximum read ahead sectors */ -#define LVM_MAX_LV_IO_TIMEOUT 60 /* seconds I/O timeout (future use) */ -#define LVM_PARTITION 0xfe /* LVM partition id */ -#define LVM_NEW_PARTITION 0x8e /* new LVM partition id (10/09/1999) */ -#define LVM_PE_SIZE_PV_SIZE_REL 5 /* max relation PV size and PE size */ - -#define LVM_SNAPSHOT_MAX_CHUNK 1024 /* 1024 KB */ -#define LVM_SNAPSHOT_DEF_CHUNK 64 /* 64 KB */ -#define LVM_SNAPSHOT_MIN_CHUNK (PAGE_SIZE / 1024) /* 4 or 8 KB */ - -#define lvm_version "device-mapper-1" - -#ifdef _G_LSEEK64 -int lseek64 ( unsigned int, unsigned long long, unsigned int); -#define llseek lseek64 -#else -int llseek ( unsigned int, unsigned long long, unsigned int); -#endif - -#define LVM_ID "HM" /* Identifier PV (id in pv_t) */ -#define EXPORTED "PV_EXP" /* Identifier exported PV (system_id in pv_t) */ -#define IMPORTED "PV_IMP" /* Identifier imported PV ( " ) */ -#define DISK_NAME_LEN 8 -#define LV_MIN_NAME_LEN 5 -#define LV_MAX_NAME_LEN 7 -#define MIN_PART 1 -#define MAX_PART 15 - -/* some metadata on the disk need to be aligned */ -#define LVM_VGDA_ALIGN 4096UL - -/* base of PV structure in disk partition */ -#define LVM_PV_DISK_BASE 0L - -/* size reserved for PV structure on disk */ -#define LVM_PV_DISK_SIZE 1024L - -/* base of VG structure in disk partition */ -#define LVM_VG_DISK_BASE round_up(LVM_PV_DISK_BASE + LVM_PV_DISK_SIZE, \ - LVM_VGDA_ALIGN) - -/* size reserved for VG structure */ -#define LVM_VG_DISK_SIZE (8 * 512L) - -/* name list of physical volumes on disk */ -#define LVM_PV_UUIDLIST_DISK_BASE round_up(LVM_VG_DISK_BASE + \ - LVM_VG_DISK_SIZE, LVM_VGDA_ALIGN) - -/* now for the dynamically calculated parts of the VGDA */ -#define LVM_LV_DISK_OFFSET(a, b) ((a)->lv_on_disk.base + sizeof(lv_disk_t) * b) - -#define LVM_VGDA_SIZE(pv) ((pv)->pe_on_disk.base + (pv)->pe_on_disk.size) - -#define LVM_PE_ALIGN (65536UL / SECTOR_SIZE) - -/* core <-> disk conversion macros */ -#if __BYTE_ORDER == __BIG_ENDIAN -#define LVM_TO_CORE16(x) ( \ - ((uint16_t)((((uint16_t)(x) & 0x00FFU) << 8) | \ - (((uint16_t)(x) & 0xFF00U) >> 8)))) - -#define LVM_TO_DISK16(x) LVM_TO_CORE16(x) - -#define LVM_TO_CORE32(x) ( \ - ((uint32_t)((((uint32_t)(x) & 0x000000FFU) << 24) | \ - (((uint32_t)(x) & 0x0000FF00U) << 8) | \ - (((uint32_t)(x) & 0x00FF0000U) >> 8) | \ - (((uint32_t)(x) & 0xFF000000U) >> 24)))) - -#define LVM_TO_DISK32(x) LVM_TO_CORE32(x) - -#define LVM_TO_CORE64(x) \ - ((uint64_t)((((uint64_t)(x) & 0x00000000000000FFULL) << 56) | \ - (((uint64_t)(x) & 0x000000000000FF00ULL) << 40) | \ - (((uint64_t)(x) & 0x0000000000FF0000ULL) << 24) | \ - (((uint64_t)(x) & 0x00000000FF000000ULL) << 8) | \ - (((uint64_t)(x) & 0x000000FF00000000ULL) >> 8) | \ - (((uint64_t)(x) & 0x0000FF0000000000ULL) >> 24) | \ - (((uint64_t)(x) & 0x00FF000000000000ULL) >> 40) | \ - (((uint64_t)(x) & 0xFF00000000000000ULL) >> 56))) - -#define LVM_TO_DISK64(x) LVM_TO_CORE64(x) -#elif __BYTE_ORDER == __LITTLE_ENDIAN -#define LVM_TO_CORE16(x) x -#define LVM_TO_DISK16(x) x -#define LVM_TO_CORE32(x) x -#define LVM_TO_DISK32(x) x -#define LVM_TO_CORE64(x) x -#define LVM_TO_DISK64(x) x -#else -#error "__BYTE_ORDER must be defined as __LITTLE_ENDIAN or __BIG_ENDIAN" -#endif /* #if __BYTE_ORDER == __BIG_ENDIAN */ - -/* return codes */ -#define LVM_VG_CFGBACKUP_NO_DIFF 100 - -#define BLOCK_SIZE 1024 -#define SECTOR_SIZE 512 - -#define UNDEF -1 - -#ifndef min -#define min(a,b) (((a)<(b))?(a):(b)) -#endif -#ifndef max -#define max(a,b) (((a)>(b))?(a):(b)) -#endif - - -/* FIXME */ -#include "dev-mgr/dev-manager.h" -pv_t *pv_read_lvm_v1(struct dev_mgr *dm, const char *pv_name); -pv_t *pv_read(struct dev_mgr *dm, const char *pv_name); -pe_disk_t *pv_read_pe(const char *pv_name, const pv_t *pv); - -pe_disk_t *pv_read_pe_lvm_v1(const char *pv_name, const pv_t * pv); -lv_disk_t *pv_read_lvs(const pv_t *pv); -lv_disk_t *pv_read_lvs_lvm_v1(const pv_t *pv); +struct io_handler { + struct volume_group *read_vg(); + int write_vg(struct volume_group *vg); +}; #endif -