1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00
lvm2/lib/metadata/metadata.h
2001-09-25 12:49:28 +00:00

369 lines
11 KiB
C

/*
* 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.
*
*/
/* FIXME: LVM1-format-specific stuff should be in lvm_v1.h instead */
#ifndef _LVM_METADATA_H
#define _LVM_METADATA_H
#include "metadata/lvm_v1.h"
/***********************************************************
* In core data representation.
***********************************************************/
/*
* 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;
/*
* 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;
/*
* 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;
} lv_t;
/*
* 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;
struct proc_dir_entry *vg_dir_pde;
struct proc_dir_entry *lv_subdir_pde;
struct proc_dir_entry *pv_subdir_pde;
} vg_t;
/***********************************************************
* 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);
#endif