1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-10-27 18:55:19 +03:00
lvm2/lib/format1/disk-rep.h
Peter Rajnoha 32ae07cef1 pv_write: clean up non-orphan format1 PV write
...to not pollute the common and format-independent code in the
abstraction layer above.

The format1 pv_write has common code for writing metadata and
PV header by calling the "write_disks" fn and when rewriting
the header itself only (e.g. just for the purpose of changing
the PV UUID) during the pvchange operation, we had to tweak
this functionality for the format1 case and we had to assign
the PV the orphan state temporarily.

This patch removes the need for this format1 tweak and it calls
the write_disks with appropriate flag indicating whether this is
a PV write call or a VG write call, allowing for metatada update
for the latter one.

Also, a side effect of the former tweak was that it effectively
invalidated the cache (even for the non-format1 PVs) as we
assigned it the orphan state temporarily just for the format1
PV write to pass.

Also, that tweak made it difficult to directly detect whether
a PV was part of a VG or not because the state was incorrect.

Also, it's not necessary to backup and restore some PV fields
when doing a PV write:

  orig_pe_size = pv_pe_size(pv);
  orig_pe_start = pv_pe_start(pv);
  orig_pe_count = pv_pe_count(pv);
  ...
  pv_write(pv)
  ...
  pv->pe_size = orig_pe_size;
  pv->pe_start = orig_pe_start;
  pv->pe_count = orig_pe_count;

...this is already done by the layer below itself (the _format1_pv_write fn).

So let's have this cleaned up so we don't need to be bothered
about any 'format1 special case for pv_write' anymore.
2013-03-25 15:08:26 +01:00

252 lines
7.8 KiB
C

/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef DISK_REP_FORMAT1_H
#define DISK_REP_FORMAT1_H
#include "lvm-types.h"
#include "metadata.h"
#include "toolcontext.h"
#define MAX_PV 256
#define MAX_LV 256
#define MAX_VG 99
#define LVM_BLK_MAJOR 58
#define MAX_PV_SIZE ((uint32_t) -1) /* 2TB in sectors - 1 */
#define MIN_PE_SIZE (8192L >> SECTOR_SHIFT) /* 8 KB in sectors */
#define MAX_PE_SIZE (16L * 1024L * (1024L >> SECTOR_SHIFT) * 1024L)
#define PE_SIZE_PV_SIZE_REL 5 /* PV size must be at least 5 times PE size */
#define MAX_LE_TOTAL 65534 /* 2^16 - 2 */
#define MAX_PE_TOTAL ((uint32_t) -2)
#define UNMAPPED_EXTENT 0
/* 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_PERSISTENT_MINOR 0x04 /* " */
#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 */
#define EXPORTED_TAG "PV_EXP" /* Identifier for exported PV */
#define IMPORTED_TAG "PV_IMP" /* Identifier for imported PV */
struct data_area {
uint32_t base;
uint32_t size;
} __attribute__ ((packed));
struct pv_disk {
int8_t id[2];
uint16_t version; /* lvm version */
struct data_area pv_on_disk;
struct data_area vg_on_disk;
struct data_area pv_uuidlist_on_disk;
struct data_area lv_on_disk;
struct data_area pe_on_disk;
int8_t pv_uuid[NAME_LEN];
int8_t vg_name[NAME_LEN];
int8_t system_id[NAME_LEN]; /* for vgexport/vgimport */
uint32_t pv_major;
uint32_t pv_number;
uint32_t pv_status;
uint32_t pv_allocatable;
uint32_t pv_size;
uint32_t lv_cur;
uint32_t pe_size;
uint32_t pe_total;
uint32_t pe_allocated;
/* only present on version == 2 pv's */
uint32_t pe_start;
} __attribute__ ((packed));
struct lv_disk {
int8_t lv_name[NAME_LEN];
int8_t vg_name[NAME_LEN];
uint32_t lv_access;
uint32_t lv_status;
uint32_t lv_open;
uint32_t lv_dev;
uint32_t lv_number;
uint32_t lv_mirror_copies; /* for future use */
uint32_t lv_recovery; /* " */
uint32_t lv_schedule; /* " */
uint32_t lv_size;
uint32_t lv_snapshot_minor; /* minor number of original */
uint16_t lv_chunk_size; /* chunk size of snapshot */
uint16_t dummy;
uint32_t lv_allocated_le;
uint32_t lv_stripes;
uint32_t lv_stripesize;
uint32_t lv_badblock; /* for future use */
uint32_t lv_allocation;
uint32_t lv_io_timeout; /* for future use */
uint32_t lv_read_ahead;
} __attribute__ ((packed));
struct vg_disk {
int8_t vg_uuid[ID_LEN]; /* volume group UUID */
int8_t vg_name_dummy[NAME_LEN - ID_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 */
} __attribute__ ((packed));
struct pe_disk {
uint16_t lv_num;
uint16_t le_num;
} __attribute__ ((packed));
struct uuid_list {
struct dm_list list;
char uuid[NAME_LEN] __attribute__((aligned(8)));
};
struct lvd_list {
struct dm_list list;
struct lv_disk lvd;
};
struct disk_list {
struct dm_list list;
struct dm_pool *mem;
struct device *dev;
struct pv_disk pvd __attribute__((aligned(8)));
struct vg_disk vgd __attribute__((aligned(8)));
struct dm_list uuids __attribute__((aligned(8)));
struct dm_list lvds __attribute__((aligned(8)));
struct pe_disk *extents __attribute__((aligned(8)));
};
/*
* Layout constants.
*/
#define METADATA_ALIGN 4096UL
#define LVM1_PE_ALIGN (65536UL >> SECTOR_SHIFT) /* PE alignment */
#define METADATA_BASE 0UL
#define PV_SIZE 1024UL
#define VG_SIZE 4096UL
/*
* Functions to calculate layout info.
*/
int calculate_layout(struct disk_list *dl);
int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size,
uint32_t max_extent_count, uint64_t pe_start);
/*
* Low level io routines which read/write
* disk_lists.
*/
struct disk_list *read_disk(const struct format_type *fmt, struct device *dev,
struct dm_pool *mem, const char *vg_name);
int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name,
struct dev_filter *filter,
struct dm_pool *mem, struct dm_list *results);
int write_disks(const struct format_type *fmt, struct dm_list *pvds,
int write_vg_metadata);
/*
* Functions to translate to between disk and in
* core structures.
*/
int import_pv(const struct format_type *fmt, struct dm_pool *mem,
struct device *dev, struct volume_group *vg,
struct physical_volume *pv, struct pv_disk *pvd,
struct vg_disk *vgd);
int export_pv(struct cmd_context *cmd, struct dm_pool *mem,
struct volume_group *vg,
struct pv_disk *pvd, struct physical_volume *pv);
int import_vg(struct dm_pool *mem,
struct volume_group *vg, struct disk_list *dl);
int export_vg(struct vg_disk *vgd, struct volume_group *vg);
int import_lv(struct cmd_context *cmd, struct dm_pool *mem,
struct logical_volume *lv, struct lv_disk *lvd);
int import_extents(struct cmd_context *cmd, struct volume_group *vg,
struct dm_list *pvds);
int export_extents(struct disk_list *dl, uint32_t lv_num,
struct logical_volume *lv, struct physical_volume *pv);
int import_pvs(const struct format_type *fmt, struct dm_pool *mem,
struct volume_group *vg, struct dm_list *pvds);
int import_lvs(struct dm_pool *mem, struct volume_group *vg, struct dm_list *pvds);
int export_lvs(struct disk_list *dl, struct volume_group *vg,
struct physical_volume *pv, const char *dev_dir);
int import_snapshots(struct dm_pool *mem, struct volume_group *vg,
struct dm_list *pvds);
int export_uuids(struct disk_list *dl, struct volume_group *vg);
void export_numbers(struct dm_list *pvds, struct volume_group *vg);
void export_pv_act(struct dm_list *pvds);
int munge_pvd(struct device *dev, struct pv_disk *pvd);
int read_vgd(struct device *dev, struct vg_disk *vgd, struct pv_disk *pvd);
/* blech */
int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter,
const char *candidate_vg, int *result);
int export_vg_number(struct format_instance *fid, struct dm_list *pvds,
const char *vg_name, struct dev_filter *filter);
#endif