2002-11-18 17:04:08 +03:00
/*
2004-03-30 23:35:44 +04:00
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
2007-08-21 00:55:30 +04:00
* Copyright ( C ) 2004 - 2006 Red Hat , Inc . All rights reserved .
2002-11-18 17:04:08 +03:00
*
2004-03-30 23:35:44 +04:00
* 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
2007-08-21 00:55:30 +04:00
* of the GNU Lesser General Public License v .2 .1 .
2004-03-30 23:35:44 +04:00
*
2007-08-21 00:55:30 +04:00
* You should have received a copy of the GNU Lesser General Public License
2004-03-30 23:35:44 +04:00
* along with this program ; if not , write to the Free Software Foundation ,
2016-01-21 13:49:46 +03:00
* Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
2002-11-18 17:04:08 +03:00
*/
# ifndef _LVM_TEXT_LAYOUT_H
# define _LVM_TEXT_LAYOUT_H
# include "config.h"
# include "metadata.h"
2015-03-19 02:43:02 +03:00
# include "lvmcache.h"
2002-11-18 17:04:08 +03:00
# include "uuid.h"
2012-02-10 05:28:27 +04:00
/* disk_locn and data_area_list are defined in format-text.h */
2002-11-18 17:04:08 +03:00
2016-02-12 15:20:34 +03:00
/*
* PV header extension versions :
* - version 1 : bootloader area support
* - version 2 : PV_EXT_USED flag support
*/
# define PV_HEADER_EXTENSION_VSN 2
2013-02-14 18:35:57 +04:00
struct pv_header_extension {
uint32_t version ;
uint32_t flags ;
2013-05-28 14:37:22 +04:00
/* NULL-terminated list of bootloader areas */
2020-08-28 20:15:01 +03:00
struct disk_locn bootloader_areas_xl [ ] ;
2013-02-14 18:35:57 +04:00
} __attribute__ ( ( packed ) ) ;
2002-11-18 17:04:08 +03:00
/* Fields with the suffix _xl should be xlate'd wherever they appear */
/* On disk */
struct pv_header {
2006-05-10 01:23:51 +04:00
int8_t pv_uuid [ ID_LEN ] ;
2005-10-31 05:37:29 +03:00
/* This size can be overridden if PV belongs to a VG */
2002-11-18 17:04:08 +03:00
uint64_t device_size_xl ; /* Bytes */
/* NULL-terminated list of data areas followed by */
/* NULL-terminated list of metadata area headers */
2020-08-28 20:15:01 +03:00
struct disk_locn disk_areas_xl [ ] ; /* Two lists */
2002-11-18 17:04:08 +03:00
} __attribute__ ( ( packed ) ) ;
2010-06-29 00:29:57 +04:00
/*
* Ignore this raw location . This allows us to
* ignored metadata areas easily , and thus balance
* metadata across VGs with many PVs .
*/
# define RAW_LOCN_IGNORED 0x00000001
2002-11-18 17:04:08 +03:00
/* On disk */
struct raw_locn {
uint64_t offset ; /* Offset in bytes to start sector */
uint64_t size ; /* Bytes */
uint32_t checksum ;
2010-06-29 00:29:42 +04:00
uint32_t flags ;
2002-11-18 17:04:08 +03:00
} __attribute__ ( ( packed ) ) ;
2010-06-29 00:29:57 +04:00
int rlocn_is_ignored ( const struct raw_locn * rlocn ) ;
2010-06-30 21:13:05 +04:00
void rlocn_set_ignored ( struct raw_locn * rlocn , unsigned mda_ignored ) ;
2010-06-29 00:29:57 +04:00
2002-11-18 17:04:08 +03:00
/* On disk */
/* Structure size limited to one sector */
struct mda_header {
uint32_t checksum_xl ; /* Checksum of rest of mda_header */
2006-05-10 01:23:51 +04:00
int8_t magic [ 16 ] ; /* To aid scans for metadata */
2002-11-18 17:04:08 +03:00
uint32_t version ;
uint64_t start ; /* Absolute start byte of mda_header */
uint64_t size ; /* Size of metadata area */
2020-08-28 20:15:01 +03:00
struct raw_locn raw_locns [ ] ; /* NULL-terminated list */
2002-11-18 17:04:08 +03:00
} __attribute__ ( ( packed ) ) ;
2018-04-20 18:43:50 +03:00
struct mda_header * raw_read_mda_header ( const struct format_type * fmt ,
struct device_area * dev_area , int primary_mda ) ;
Allow raw_read_mda_header to be called from text_label.c.
We'd like to pass in mda_header to vgname_from_mda(). In order to
do this, we need to call raw_read_mda_header() from text_label.c,
_text_read(), which gets called from the label_read() path, and
peers into the metadata and update vginfo cache. We should check
the disable bit here, and if set, not peer into the vg metadata,
thus reducing the I/O to disk.
In the process, move vgname_from_mda() to layout.h, since the fn
only gets called from format_text code, and we need the mda_header
definition from the private layout.h.
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-29 00:31:01 +04:00
2002-11-18 17:04:08 +03:00
struct mda_lists {
2008-11-04 01:14:30 +03:00
struct dm_list dirs ;
struct dm_list raws ;
2002-11-18 17:04:08 +03:00
struct metadata_area_ops * file_ops ;
struct metadata_area_ops * raw_ops ;
} ;
struct mda_context {
struct device_area area ;
2007-11-05 20:17:55 +03:00
uint64_t free_sectors ;
2002-11-18 17:04:08 +03:00
struct raw_locn rlocn ; /* Store inbetween write and commit */
} ;
/* FIXME Convert this at runtime */
# define FMTT_MAGIC "\040\114\126\115\062\040\170\133\065\101\045\162\060\116\052\076"
# define FMTT_VERSION 1
# define MDA_HEADER_SIZE 512
# define LVM2_LABEL "LVM2 001"
2006-08-17 22:23:44 +04:00
# define MDA_SIZE_MIN (8 * (unsigned) lvm_getpagesize())
2017-12-08 04:11:34 +03:00
# define MDA_ORIGINAL_ALIGNMENT 512 /* Original alignment used for start of VG metadata content */
2002-11-18 17:04:08 +03:00
scanning: optimize by checking text offset and checksum
stable backport of 0c1316cda876849d5d1375d40e8cdc08db37c2b5
which includes a number of extra supporting functions.
In stable, the optimization is only applied to reporting
and display commands, so this change applies only to those
cases.
After the VG lock is taken for vg_read, reread the mda_header
from disk and compare the metadata text offset and checksum
to what was seen during label scan. If it is unchanged, then
the metadata has not changed since the label scan, and the
metadata does not need to be reread under the lock for command
processing. If it is changed, then reread the metadata from disk.
This fixes a problem with the original optimization where lvm
reuses cached data from the label_scan phase for vg_read. This
works if the mda_header and metadata text are both read from
cache, or both read from disk, but in some cases the mda_header
could have been dropped from the cache and read from disk, while
the metadata blocks remained in the cache and were not read from
disk. If in addition to this, another concurrent command happened
to update the metadata between the label_scan and vg_read, then
the new mda_header from disk would refer to cached blocks that did
not contain the new metadata text. This would cause the lvm command
report an error about invalid metadata.
2020-06-02 00:22:09 +03:00
int read_metadata_location_summary ( const struct format_type * fmt , struct metadata_area * mda , struct mda_header * mdah , int primary_mda ,
2015-03-19 02:43:02 +03:00
struct device_area * dev_area , struct lvmcache_vgsummary * vgsummary ,
2018-04-20 18:43:50 +03:00
uint64_t * mda_free_sectors ) ;
Allow raw_read_mda_header to be called from text_label.c.
We'd like to pass in mda_header to vgname_from_mda(). In order to
do this, we need to call raw_read_mda_header() from text_label.c,
_text_read(), which gets called from the label_read() path, and
peers into the metadata and update vginfo cache. We should check
the disable bit here, and if set, not peer into the vg metadata,
thus reducing the I/O to disk.
In the process, move vgname_from_mda() to layout.h, since the fn
only gets called from format_text code, and we need the mda_header
definition from the private layout.h.
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-29 00:31:01 +04:00
2002-11-18 17:04:08 +03:00
# endif