[lvm-devel] [RFC PATCH] pvcreate --dataalignmentoffset
Mike Snitzer
snitzer at redhat.com
Mon Jun 8 03:40:12 UTC 2009
Alasdair,
The following patch has been tested to work but I just wanted to verify
that I've headed in the right direction before building on it (getting
alignment_offset from sysfs, lvm.conf option, pvcreate man page, etc).
The key to this working is to adjust pv->pe_start after the first mda's
start and size is known (in _mda_setup).
tested with:
pvcreate --dataalignmentoffset 3.75K /dev/loop0
thanks,
Mike
Index: lib/format1/format1.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/format1/format1.c,v
retrieving revision 1.112
diff -u -p -r1.112 format1.c
--- lib/format1/format1.c 10 Apr 2009 09:59:18 -0000 1.112
+++ lib/format1/format1.c 8 Jun 2009 03:19:03 -0000
@@ -296,6 +296,7 @@ static int _format1_pv_setup(const struc
uint64_t pe_start, uint32_t extent_count,
uint32_t extent_size,
unsigned long data_alignment __attribute((unused)),
+ unsigned long data_alignment_offset __attribute((unused)),
int pvmetadatacopies __attribute((unused)),
uint64_t pvmetadatasize __attribute((unused)), struct dm_list *mdas __attribute((unused)),
struct physical_volume *pv, struct volume_group *vg __attribute((unused)))
Index: lib/format_pool/format_pool.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/format_pool/format_pool.c,v
retrieving revision 1.23
diff -u -p -r1.23 format_pool.c
--- lib/format_pool/format_pool.c 13 May 2009 21:22:57 -0000 1.23
+++ lib/format_pool/format_pool.c 8 Jun 2009 03:19:04 -0000
@@ -192,6 +192,7 @@ static int _pool_pv_setup(const struct f
uint32_t extent_count __attribute((unused)),
uint32_t extent_size __attribute((unused)),
unsigned long data_alignment __attribute((unused)),
+ unsigned long data_alignment_offset __attribute((unused)),
int pvmetadatacopies __attribute((unused)),
uint64_t pvmetadatasize __attribute((unused)),
struct dm_list *mdas __attribute((unused)),
Index: lib/format_text/archiver.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/format_text/archiver.c,v
retrieving revision 1.25
diff -u -p -r1.25 archiver.c
--- lib/format_text/archiver.c 19 May 2009 09:45:33 -0000 1.25
+++ lib/format_text/archiver.c 8 Jun 2009 03:19:04 -0000
@@ -316,7 +316,7 @@ int backup_restore_vg(struct cmd_context
return 0;
}
if (!vg->fid->fmt->ops->
- pv_setup(vg->fid->fmt, UINT64_C(0), 0, 0, 0, 0UL,
+ pv_setup(vg->fid->fmt, UINT64_C(0), 0, 0, 0, 0, 0UL,
UINT64_C(0), &vg->fid->metadata_areas, pv, vg)) {
log_error("Format-specific setup for %s failed",
pv_dev_name(pv));
Index: lib/format_text/format-text.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/format_text/format-text.c,v
retrieving revision 1.105
diff -u -p -r1.105 format-text.c
--- lib/format_text/format-text.c 7 May 2009 12:11:51 -0000 1.105
+++ lib/format_text/format-text.c 8 Jun 2009 03:19:04 -0000
@@ -1175,12 +1175,13 @@ static int _text_scan(const struct forma
Always have an mda between end-of-label and pe_align() boundary */
static int _mda_setup(const struct format_type *fmt,
uint64_t pe_start, uint64_t pe_end,
+ unsigned long data_alignment_offset,
int pvmetadatacopies,
uint64_t pvmetadatasize, struct dm_list *mdas,
struct physical_volume *pv,
struct volume_group *vg __attribute((unused)))
{
- uint64_t mda_adjustment, disk_size, alignment;
+ uint64_t mda_adjustment, adjustment, disk_size, alignment;
uint64_t start1, mda_size1; /* First area - start of disk */
uint64_t start2, mda_size2; /* Second area - end of disk */
uint64_t wipe_size = 8 << SECTOR_SHIFT;
@@ -1251,6 +1252,22 @@ static int _mda_setup(const struct forma
return 0;
}
+ if (!pe_start && !pe_end) {
+ /*
+ * proactively adjust pv->pe_start to allow for
+ * proper padding with data_alignment_offset
+ * - _text_pv_write is too late given the lack of info
+ */
+ pv->pe_start = (start1 + mda_size1) >> SECTOR_SHIFT;
+ /* round up to pe_align boundry */
+ adjustment = pv->pe_start % pv->pe_align;
+ if (adjustment)
+ pv->pe_start += (pv->pe_align - adjustment);
+
+ if (data_alignment_offset)
+ pv->pe_start += data_alignment_offset;
+ }
+
if (pvmetadatacopies == 1)
return 1;
} else
@@ -1598,6 +1615,7 @@ static struct metadata_area_ops _metadat
static int _text_pv_setup(const struct format_type *fmt,
uint64_t pe_start, uint32_t extent_count,
uint32_t extent_size, unsigned long data_alignment,
+ unsigned long data_alignment_offset,
int pvmetadatacopies,
uint64_t pvmetadatasize, struct dm_list *mdas,
struct physical_volume *pv, struct volume_group *vg)
@@ -1707,8 +1725,8 @@ static int _text_pv_setup(const struct f
if (extent_count)
pe_end = pe_start + extent_count * extent_size - 1;
- if (!_mda_setup(fmt, pe_start, pe_end, pvmetadatacopies,
- pvmetadatasize, mdas, pv, vg))
+ if (!_mda_setup(fmt, pe_start, pe_end, data_alignment_offset,
+ pvmetadatacopies, pvmetadatasize, mdas, pv, vg))
return_0;
}
Index: lib/metadata/metadata-exported.h
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/metadata/metadata-exported.h,v
retrieving revision 1.76
diff -u -p -r1.76 metadata-exported.h
--- lib/metadata/metadata-exported.h 5 Jun 2009 20:00:52 -0000 1.76
+++ lib/metadata/metadata-exported.h 8 Jun 2009 03:19:05 -0000
@@ -423,6 +423,7 @@ pv_t *pv_create(const struct cmd_context
struct id *id,
uint64_t size,
unsigned long data_alignment,
+ unsigned long data_alignment_offset,
uint64_t pe_start,
uint32_t existing_extent_count,
uint32_t existing_extent_size,
Index: lib/metadata/metadata.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/metadata/metadata.c,v
retrieving revision 1.224
diff -u -p -r1.224 metadata.c
--- lib/metadata/metadata.c 1 Jun 2009 12:43:32 -0000 1.224
+++ lib/metadata/metadata.c 8 Jun 2009 03:19:05 -0000
@@ -48,6 +48,7 @@ static struct physical_volume *_pv_creat
struct device *dev,
struct id *id, uint64_t size,
unsigned long data_alignment,
+ unsigned long data_alignment_offset,
uint64_t pe_start,
uint32_t existing_extent_count,
uint32_t existing_extent_size,
@@ -157,7 +158,7 @@ int add_pv_to_vg(struct volume_group *vg
pv->pe_alloc_count = 0;
if (!fid->fmt->ops->pv_setup(fid->fmt, UINT64_C(0), 0,
- vg->extent_size, 0, 0UL, UINT64_C(0),
+ vg->extent_size, 0, 0, 0UL, UINT64_C(0),
&fid->metadata_areas, pv, vg)) {
log_error("Format-specific setup of physical volume '%s' "
"failed.", pv_name);
@@ -787,6 +788,7 @@ int vg_split_mdas(struct cmd_context *cm
* @id: PV UUID to use for initialization
* @size: size of the PV in sectors
* @data_alignment: requested alignment of data
+ * @data_alignment_offset: requested offset to aligned data
* @pe_start: physical extent start
* @existing_extent_count
* @existing_extent_size
@@ -805,13 +807,15 @@ pv_t *pv_create(const struct cmd_context
struct device *dev,
struct id *id, uint64_t size,
unsigned long data_alignment,
+ unsigned long data_alignment_offset,
uint64_t pe_start,
uint32_t existing_extent_count,
uint32_t existing_extent_size,
int pvmetadatacopies,
uint64_t pvmetadatasize, struct dm_list *mdas)
{
- return _pv_create(cmd->fmt, dev, id, size, data_alignment, pe_start,
+ return _pv_create(cmd->fmt, dev, id, size,
+ data_alignment, data_alignment_offset, pe_start,
existing_extent_count,
existing_extent_size,
pvmetadatacopies,
@@ -856,6 +860,7 @@ static struct physical_volume *_pv_creat
struct device *dev,
struct id *id, uint64_t size,
unsigned long data_alignment,
+ unsigned long data_alignment_offset,
uint64_t pe_start,
uint32_t existing_extent_count,
uint32_t existing_extent_size,
@@ -907,6 +912,7 @@ static struct physical_volume *_pv_creat
if (!fmt->ops->pv_setup(fmt, pe_start, existing_extent_count,
existing_extent_size, data_alignment,
+ data_alignment_offset,
pvmetadatacopies, pvmetadatasize, mdas,
pv, NULL)) {
log_error("%s: Format-specific setup of physical volume "
Index: lib/metadata/metadata.h
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/metadata/metadata.h,v
retrieving revision 1.196
diff -u -p -r1.196 metadata.h
--- lib/metadata/metadata.h 1 Jun 2009 12:43:32 -0000 1.196
+++ lib/metadata/metadata.h 8 Jun 2009 03:19:06 -0000
@@ -213,6 +213,7 @@ struct format_handler {
int (*pv_setup) (const struct format_type * fmt,
uint64_t pe_start, uint32_t extent_count,
uint32_t extent_size, unsigned long data_alignment,
+ unsigned long data_alignment_offset,
int pvmetadatacopies,
uint64_t pvmetadatasize, struct dm_list * mdas,
struct physical_volume * pv, struct volume_group * vg);
Index: tools/args.h
===================================================================
RCS file: /cvs/lvm2/LVM2/tools/args.h,v
retrieving revision 1.65
diff -u -p -r1.65 args.h
--- tools/args.h 4 Jun 2009 12:01:16 -0000 1.65
+++ tools/args.h 8 Jun 2009 03:19:06 -0000
@@ -59,6 +59,7 @@ arg(nameprefixes_ARG, '\0', "nameprefixe
arg(unquoted_ARG, '\0', "unquoted", NULL, 0)
arg(rows_ARG, '\0', "rows", NULL, 0)
arg(dataalignment_ARG, '\0', "dataalignment", size_kb_arg, 0)
+arg(dataalignmentoffset_ARG, '\0', "dataalignmentoffset", size_kb_arg, 0)
arg(virtualoriginsize_ARG, '\0', "virtualoriginsize", size_mb_arg, 0)
arg(virtualsize_ARG, '\0', "virtualsize", size_mb_arg, 0)
Index: tools/commands.h
===================================================================
RCS file: /cvs/lvm2/LVM2/tools/commands.h,v
retrieving revision 1.127
diff -u -p -r1.127 commands.h
--- tools/commands.h 4 Jun 2009 12:01:16 -0000 1.127
+++ tools/commands.h 8 Jun 2009 03:19:06 -0000
@@ -468,6 +468,7 @@ xx(pvcreate,
"\t[--metadatacopies #copies]" "\n"
"\t[--metadatasize MetadataSize[kKmMgGtTpPeE]]" "\n"
"\t[--dataalignment Alignment[kKmMgGtTpPeE]]" "\n"
+ "\t[--dataalignmentoffset AlignmentOffset[kKmMgGtTpPeE]]" "\n"
"\t[--setphysicalvolumesize PhysicalVolumeSize[kKmMgGtTpPeE]" "\n"
"\t[-t|--test] " "\n"
"\t[-u|--uuid uuid] " "\n"
@@ -477,9 +478,9 @@ xx(pvcreate,
"\t[--version] " "\n"
"\tPhysicalVolume [PhysicalVolume...]\n",
- dataalignment_ARG, force_ARG, test_ARG, labelsector_ARG, metadatatype_ARG,
- metadatacopies_ARG, metadatasize_ARG, physicalvolumesize_ARG,
- restorefile_ARG, uuidstr_ARG, yes_ARG, zero_ARG)
+ dataalignment_ARG, dataalignmentoffset_ARG, force_ARG, test_ARG,
+ labelsector_ARG, metadatatype_ARG, metadatacopies_ARG, metadatasize_ARG,
+ physicalvolumesize_ARG, restorefile_ARG, uuidstr_ARG, yes_ARG, zero_ARG)
xx(pvdata,
"Display the on-disk metadata for physical volume(s)",
Index: tools/pvcreate.c
===================================================================
RCS file: /cvs/lvm2/LVM2/tools/pvcreate.c,v
retrieving revision 1.81
diff -u -p -r1.81 pvcreate.c
--- tools/pvcreate.c 10 Apr 2009 10:01:38 -0000 1.81
+++ tools/pvcreate.c 8 Jun 2009 03:19:06 -0000
@@ -20,6 +20,7 @@ struct pvcreate_params {
int zero;
uint64_t size;
uint64_t data_alignment;
+ uint64_t data_alignment_offset;
int pvmetadatacopies;
uint64_t pvmetadatasize;
int64_t labelsector;
@@ -203,8 +204,8 @@ static int pvcreate_single(struct cmd_co
dm_list_init(&mdas);
if (!(pv = pv_create(cmd, dev, pp->idp, pp->size,
- pp->data_alignment, pp->pe_start,
- pp->extent_count, pp->extent_size,
+ pp->data_alignment, pp->data_alignment_offset,
+ pp->pe_start, pp->extent_count, pp->extent_size,
pp->pvmetadatacopies,
pp->pvmetadatasize,&mdas))) {
log_error("Failed to setup physical volume \"%s\"", pv_name);
@@ -377,6 +378,24 @@ static int pvcreate_validate_params(stru
pp->data_alignment = 0;
}
+ if (arg_sign_value(cmd, dataalignmentoffset_ARG, 0) == SIGN_MINUS) {
+ log_error("Physical volume data alignment offset may not be negative");
+ return 0;
+ }
+ pp->data_alignment_offset = arg_uint64_value(cmd, dataalignmentoffset_ARG, UINT64_C(0));
+
+ if (pp->data_alignment_offset > ULONG_MAX) {
+ log_error("Physical volume data alignment offset is too big.");
+ return 0;
+ }
+
+ if (pp->data_alignment_offset && pp->pe_start) {
+ log_warn("WARNING: Ignoring data alignment offset %" PRIu64
+ " incompatible with --restorefile value (%"
+ PRIu64").", pp->data_alignment_offset, pp->pe_start);
+ pp->data_alignment_offset = 0;
+ }
+
if (arg_sign_value(cmd, metadatasize_ARG, 0) == SIGN_MINUS) {
log_error("Metadata size may not be negative");
return 0;
Index: tools/vgconvert.c
===================================================================
RCS file: /cvs/lvm2/LVM2/tools/vgconvert.c,v
retrieving revision 1.35
diff -u -p -r1.35 vgconvert.c
--- tools/vgconvert.c 5 Jun 2009 20:00:52 -0000 1.35
+++ tools/vgconvert.c 8 Jun 2009 03:19:06 -0000
@@ -120,7 +120,7 @@ static int vgconvert_single(struct cmd_c
dm_list_init(&mdas);
if (!(pv = pv_create(cmd, pv_dev(existing_pv),
- &existing_pv->id, size, 0,
+ &existing_pv->id, size, 0, 0,
pe_start, pv_pe_count(existing_pv),
pv_pe_size(existing_pv), pvmetadatacopies,
pvmetadatasize, &mdas))) {
More information about the lvm-devel
mailing list