From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2261 invoked by alias); 1 Aug 2009 17:08:46 -0000 Received: (qmail 2247 invoked by uid 9805); 1 Aug 2009 17:08:45 -0000 Date: Sat, 01 Aug 2009 17:08:00 -0000 Message-ID: <20090801170845.2245.qmail@sourceware.org> From: snitzer@sourceware.org To: lvm-devel@redhat.com, lvm2-cvs@sourceware.org Subject: LVM2 ./WHATS_NEW doc/example.conf lib/config/d ... Mailing-List: contact lvm2-cvs-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: lvm2-cvs-owner@sourceware.org X-SW-Source: 2009-08/txt/msg00001.txt.bz2 CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: snitzer@sourceware.org 2009-08-01 17:08:44 Modified files: . : WHATS_NEW doc : example.conf lib/config : defaults.h lib/device : device.c device.h lib/metadata : metadata.c man : lvm.conf.5.in Log message: Add devices/data_alignment_detection to lvm.conf. Adds 'data_alignment_detection' config option to the devices section of lvm.conf. If your kernel provides topology information in sysfs (linux >= 2.6.31) for the Physical Volume, the start of data area will be aligned on a multiple of the ’minimum_io_size’ or ’optimal_io_size’ exposed in sysfs. minimum_io_size is used if optimal_io_size is undefined (0). If both md_chunk_alignment and data_alignment_detection are enabled the result of data_alignment_detection is used. Signed-off-by: Mike Snitzer Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1224&r2=1.1225 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/doc/example.conf.diff?cvsroot=lvm2&r1=1.43&r2=1.44 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/config/defaults.h.diff?cvsroot=lvm2&r1=1.48&r2=1.49 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/device/device.c.diff?cvsroot=lvm2&r1=1.28&r2=1.29 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/device/device.h.diff?cvsroot=lvm2&r1=1.41&r2=1.42 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata.c.diff?cvsroot=lvm2&r1=1.276&r2=1.277 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/man/lvm.conf.5.in.diff?cvsroot=lvm2&r1=1.5&r2=1.6 --- LVM2/WHATS_NEW 2009/08/01 17:07:36 1.1224 +++ LVM2/WHATS_NEW 2009/08/01 17:08:43 1.1225 @@ -4,6 +4,7 @@ Added configure --enable-udev_rules --enable-udev_sync. Added configure --with-udev-prefix --with-udevdir. Added udev dir to hold udev rules. + Add devices/data_alignment_detection to lvm.conf. Add devices/data_alignment_offset_detection to lvm.conf. Add --dataalignmentoffset to pvcreate to shift start of aligned data area. Fix _mda_setup() to not check first mda's size before pe_align rounding. --- LVM2/doc/example.conf 2009/08/01 17:07:36 1.43 +++ LVM2/doc/example.conf 2009/08/01 17:08:44 1.44 @@ -98,9 +98,21 @@ # 1 enables; 0 disables. md_chunk_alignment = 1 + # By default, the start of a PV's data area will be a multiple of + # the 'minimum_io_size' or 'optimal_io_size' exposed in sysfs. + # - minimum_io_size - the smallest request the device can perform + # w/o incurring a read-modify-write penalty (e.g. MD's chunk size) + # - optimal_io_size - the device's preferred unit of receiving I/O + # (e.g. MD's stripe width) + # minimum_io_size is used if optimal_io_size is undefined (0). + # If md_chunk_alignment is enabled, that detects the optimal_io_size. + # This setting takes precedence over md_chunk_alignment. + # 1 enables; 0 disables. + data_alignment_detection = 1 + # Alignment (in KB) of start of data area when creating a new PV. - # If a PV is placed directly upon an md device and md_chunk_alignment is - # enabled this parameter is ignored. + # If a PV is placed directly upon an md device and md_chunk_alignment or + # data_alignment_detection is enabled this parameter is ignored. # Set to 0 for the default alignment of 64KB or page size, if larger. data_alignment = 0 --- LVM2/lib/config/defaults.h 2009/08/01 17:07:37 1.48 +++ LVM2/lib/config/defaults.h 2009/08/01 17:08:44 1.49 @@ -35,6 +35,7 @@ #define DEFAULT_MD_CHUNK_ALIGNMENT 1 #define DEFAULT_IGNORE_SUSPENDED_DEVICES 1 #define DEFAULT_DATA_ALIGNMENT_OFFSET_DETECTION 1 +#define DEFAULT_DATA_ALIGNMENT_DETECTION 1 #define DEFAULT_LOCK_DIR "/var/lock/lvm" #define DEFAULT_LOCKING_LIB "liblvm2clusterlock.so" --- LVM2/lib/device/device.c 2009/08/01 17:07:37 1.28 +++ LVM2/lib/device/device.c 2009/08/01 17:08:44 1.29 @@ -285,13 +285,36 @@ #ifdef linux +static int _primary_dev(const char *sysfs_dir, + struct device *dev, dev_t *result) +{ + char path[PATH_MAX+1]; + struct stat info; + + /* check if dev is a partition */ + if (dm_snprintf(path, PATH_MAX, "%s/dev/block/%d:%d/partition", + sysfs_dir, (int)MAJOR(dev->dev), (int)MINOR(dev->dev)) < 0) { + log_error("dm_snprintf partition failed"); + return 0; + } + + if (stat(path, &info) < 0) + return 0; + + *result = dev->dev - + (MINOR(dev->dev) % max_partitions(MAJOR(dev->dev))); + return 1; +} + static unsigned long _dev_topology_attribute(const char *attribute, const char *sysfs_dir, struct device *dev) { + const char *sysfs_fmt_str = "%s/dev/block/%d:%d/%s"; char path[PATH_MAX+1], buffer[64]; FILE *fp; struct stat info; + dev_t uninitialized_var(primary); unsigned long result = 0UL; if (!attribute || !*attribute) @@ -300,16 +323,32 @@ if (!sysfs_dir || !*sysfs_dir) return_0; - if (dm_snprintf(path, PATH_MAX, "%s/dev/block/%d:%d/%s", - sysfs_dir, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), + if (dm_snprintf(path, PATH_MAX, sysfs_fmt_str, sysfs_dir, + (int)MAJOR(dev->dev), (int)MINOR(dev->dev), attribute) < 0) { log_error("dm_snprintf %s failed", attribute); return 0; } - /* check if the desired sysfs attribute exists */ - if (stat(path, &info) < 0) - return 0; + /* + * check if the desired sysfs attribute exists + * - if not: either the kernel doesn't have topology support + * or the device could be a partition + */ + if (stat(path, &info) < 0) { + if (!_primary_dev(sysfs_dir, dev, &primary)) + return 0; + + /* get attribute from partition's primary device */ + if (dm_snprintf(path, PATH_MAX, sysfs_fmt_str, sysfs_dir, + (int)MAJOR(primary), (int)MINOR(primary), + attribute) < 0) { + log_error("primary dm_snprintf %s failed", attribute); + return 0; + } + if (stat(path, &info) < 0) + return 0; + } if (!(fp = fopen(path, "r"))) { log_sys_error("fopen", path); @@ -344,6 +383,20 @@ sysfs_dir, dev); } +unsigned long dev_minimum_io_size(const char *sysfs_dir, + struct device *dev) +{ + return _dev_topology_attribute("queue/minimum_io_size", + sysfs_dir, dev); +} + +unsigned long dev_optimal_io_size(const char *sysfs_dir, + struct device *dev) +{ + return _dev_topology_attribute("queue/optimal_io_size", + sysfs_dir, dev); +} + #else unsigned long dev_alignment_offset(const char *sysfs_dir, @@ -352,4 +405,16 @@ return 0UL; } +unsigned long dev_minimum_io_size(const char *sysfs_dir, + struct device *dev) +{ + return 0UL; +} + +unsigned long dev_optimal_io_size(const char *sysfs_dir, + struct device *dev) +{ + return 0UL; +} + #endif --- LVM2/lib/device/device.h 2009/08/01 17:07:37 1.41 +++ LVM2/lib/device/device.h 2009/08/01 17:08:44 1.42 @@ -103,4 +103,10 @@ unsigned long dev_alignment_offset(const char *sysfs_dir, struct device *dev); +unsigned long dev_minimum_io_size(const char *sysfs_dir, + struct device *dev); + +unsigned long dev_optimal_io_size(const char *sysfs_dir, + struct device *dev); + #endif --- LVM2/lib/metadata/metadata.c 2009/08/01 17:07:37 1.276 +++ LVM2/lib/metadata/metadata.c 2009/08/01 17:08:44 1.277 @@ -86,6 +86,25 @@ dev_md_stripe_width(pv->fmt->cmd->sysfs_dir, pv->dev)); + /* + * Align to topology's minimum_io_size or optimal_io_size if present + * - minimum_io_size - the smallest request the device can perform + * w/o incurring a read-modify-write penalty (e.g. MD's chunk size) + * - optimal_io_size - the device's preferred unit of receiving I/O + * (e.g. MD's stripe width) + */ + if (find_config_tree_bool(pv->fmt->cmd, + "devices/data_alignment_detection", + DEFAULT_DATA_ALIGNMENT_DETECTION)) { + pv->pe_align = MAX(pv->pe_align, + dev_minimum_io_size(pv->fmt->cmd->sysfs_dir, + pv->dev)); + + pv->pe_align = MAX(pv->pe_align, + dev_optimal_io_size(pv->fmt->cmd->sysfs_dir, + pv->dev)); + } + log_very_verbose("%s: Setting PE alignment to %lu sectors.", dev_name(pv->dev), pv->pe_align); --- LVM2/man/lvm.conf.5.in 2009/08/01 17:07:37 1.5 +++ LVM2/man/lvm.conf.5.in 2009/08/01 17:08:44 1.6 @@ -137,11 +137,23 @@ directly upon an md device, LVM2 will align its data blocks with the md device's stripe-width. .IP +\fBdata_alignment_detection\fP \(em If set to 1, and your kernel provides +topology information in sysfs for the Physical Volume, the start of data +area will be aligned on a multiple of the ’minimum_io_size’ or +’optimal_io_size’ exposed in sysfs. minimum_io_size is the smallest +request the device can perform without incurring a read-modify-write +penalty (e.g. MD's chunk size). optimal_io_size is the device's +preferred unit of receiving I/O (e.g. MD's stripe width). minimum_io_size +is used if optimal_io_size is undefined (0). If both \fBmd_chunk_alignment\fP +and \fBdata_alignment_detection\fP are enabled the result of +\fBdata_alignment_detection\fP is used. +.IP \fBdata_alignment\fP \(em Default alignment (in KB) of start of data area when creating a new Physical Volume using the \fBlvm2\fP format. 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. +\fBmd_chunk_alignment\fP or \fBdata_alignment_detection\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, and your kernel provides topology information in sysfs for the Physical Volume, the