From d949e34f7e3b9b89287d83492cba8b44901a5809 Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Tue, 9 Jun 2009 00:04:55 -0400 Subject: [PATCH 3/3] Add devices/data_alignment_offset_detection to lvm.conf. If the pvcreate --dataalignmentoffset option is not specified the offset of the start of a PV's aligned data area will be padded with the associated 'alignment_offset' exposed in sysfs (unless devices/data_alignment_offset_detection is disabled in lvm.conf). Signed-off-by: Mike Snitzer --- WHATS_NEW | 1 doc/example.conf | 5 +++ lib/config/defaults.h | 1 lib/device/device.c | 60 ++++++++++++++++++++++++++++++++++++++++++ lib/device/device.h | 3 ++ lib/format_text/format-text.c | 9 ++++++ man/lvm.conf.5.in | 8 ++++- 7 files changed, 86 insertions(+), 1 deletion(-) Index: LVM2/WHATS_NEW =================================================================== --- LVM2.orig/WHATS_NEW +++ LVM2/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.48 - =============================== + Add devices/data_alignment_offset_detection to lvm.conf. Implement pvcreate --dataalignmentoffset to pad offset of pe_start. Update the man pages to uniformly document size units. Allow specifying commandline sizes in terms of bytes and sectors. Index: LVM2/doc/example.conf =================================================================== --- LVM2.orig/doc/example.conf +++ LVM2/doc/example.conf @@ -104,6 +104,11 @@ devices { # Set to 0 for the default alignment of 64KB or page size, if larger. data_alignment = 0 + # By default, the offset of the start of a PV's aligned data area + # will be padded with the 'alignment_offset' exposed in sysfs. + # 1 enables; 0 disables. + data_alignment_offset_detection = 1 + # If, while scanning the system for PVs, LVM2 encounters a device-mapper # device that has its I/O suspended, it waits for it to become accessible. # Set this to 1 to skip such devices. This should only be needed Index: LVM2/lib/config/defaults.h =================================================================== --- LVM2.orig/lib/config/defaults.h +++ LVM2/lib/config/defaults.h @@ -34,6 +34,7 @@ #define DEFAULT_MD_COMPONENT_DETECTION 1 #define DEFAULT_MD_CHUNK_ALIGNMENT 1 #define DEFAULT_IGNORE_SUSPENDED_DEVICES 1 +#define DEFAULT_DATA_ALIGNMENT_OFFSET_DETECTION 1 #define DEFAULT_LOCK_DIR "/var/lock/lvm" #define DEFAULT_LOCKING_LIB "liblvm2clusterlock.so" Index: LVM2/lib/device/device.c =================================================================== --- LVM2.orig/lib/device/device.c +++ LVM2/lib/device/device.c @@ -278,3 +278,63 @@ int _get_partition_type(struct dev_mgr * return 0; } #endif + +#ifdef linux + +unsigned long dev_data_alignment_offset(const char *sysfs_dir, + struct device *dev) +{ + char path[PATH_MAX+1], buffer[64]; + FILE *fp; + struct stat info; + unsigned long data_alignment_offset = 0UL; + + if (!sysfs_dir || !*sysfs_dir) + return_0; + + if (dm_snprintf(path, PATH_MAX, "%s/dev/block/%d:%d/alignment_offset", + sysfs_dir, MAJOR(dev->dev), MINOR(dev->dev)) < 0) { + log_error("dm_snprintf alignment_offset failed"); + return 0; + } + + /* old sysfs structure not applicable (topology support is newer) */ + + if (stat(path, &info) < 0) + return 0; + + if (!(fp = fopen(path, "r"))) { + log_sys_error("fopen", path); + return 0; + } + + if (!fgets(buffer, sizeof(buffer), fp)) { + log_sys_error("fgets", path); + goto out; + } + + if (sscanf(buffer, "%lu", &data_alignment_offset) != 1) { + log_error("sysfs file %s not in expected format: %s", path, + buffer); + goto out; + } + + log_very_verbose("Device %s data_alignment is %lu bytes.", + dev_name(dev), data_alignment_offset); + +out: + if (fclose(fp)) + log_sys_error("fclose", path); + + return data_alignment_offset >> SECTOR_SHIFT; +} + +#else + +unsigned long dev_data_alignment_offset(const char *sysfs_dir, + struct device *dev) +{ + return 0UL; +} + +#endif Index: LVM2/lib/device/device.h =================================================================== --- LVM2.orig/lib/device/device.h +++ LVM2/lib/device/device.h @@ -100,4 +100,7 @@ unsigned long dev_md_chunk_size(const ch int is_partitioned_dev(struct device *dev); +unsigned long dev_data_alignment_offset(const char *sysfs_dir, + struct device *dev); + #endif Index: LVM2/lib/format_text/format-text.c =================================================================== --- LVM2.orig/lib/format_text/format-text.c +++ LVM2/lib/format_text/format-text.c @@ -29,6 +29,7 @@ #include "label.h" #include "memlock.h" #include "lvmcache.h" +#include "defaults.h" #include #include @@ -1720,6 +1721,14 @@ static int _text_pv_setup(const struct f "%lu sectors (requested %lu sectors)", pv_dev_name(pv), pv->pe_align, data_alignment); + if (!pe_start && !data_alignment_offset && + find_config_tree_bool(pv->fmt->cmd, + "devices/data_alignment_offset_detection", + DEFAULT_DATA_ALIGNMENT_OFFSET_DETECTION)) { + data_alignment_offset = + dev_data_alignment_offset(pv->fmt->cmd->sysfs_dir, pv->dev); + } + if (pv->pe_start < pv->pe_align) pv->pe_start = pv->pe_align; Index: LVM2/man/lvm.conf.5.in =================================================================== --- LVM2.orig/man/lvm.conf.5.in +++ LVM2/man/lvm.conf.5.in @@ -142,10 +142,16 @@ when creating a new Physical Volume usin If a Physical Volume is placed directly upon an md device and \fBmd_chunk_alignment\fP is enabled this parameter is ignored. Set to 0 to use the default alignment of 64KB or the page size, if larger. +.IP +\fBdata_alignment_offset_detection\fP \(em If set to 1, the offset to +the start of a PV's aligned data area will be set to the +alignment_offset exposed in sysfs. .sp To see the location of the first Physical Extent of an existing Physical Volume use \fBpvs -o +pe_start\fP . It will be a multiple of the requested -\fBdata_alignment\fP. +\fBdata_alignment\fP plus the alignment_offset from +\fBdata_alignment_offset_detection\fP (if enabled) or the pvcreate +commandline. .TP \fBlog\fP \(em Default log settings .IP