Blame SOURCES/0197-RHBZ-1394059-max-sectors-kb.patch

4728c8
---
4728c8
 libmultipath/config.c      |    3 +
4728c8
 libmultipath/config.h      |    3 +
4728c8
 libmultipath/configure.c   |    1 
4728c8
 libmultipath/defaults.h    |    1 
4728c8
 libmultipath/devmapper.c   |    4 +-
4728c8
 libmultipath/dict.c        |   87 +++++++++++++++++++++++++++++++++++++++++++++
4728c8
 libmultipath/discovery.c   |   60 +++++++++++++++++++++++++++++++
4728c8
 libmultipath/discovery.h   |    1 
4728c8
 libmultipath/propsel.c     |   25 ++++++++++++
4728c8
 libmultipath/propsel.h     |    1 
4728c8
 libmultipath/structs.h     |    7 +++
4728c8
 multipath/multipath.conf.5 |    8 ++++
4728c8
 12 files changed, 200 insertions(+), 1 deletion(-)
4728c8
4728c8
Index: multipath-tools-130222/libmultipath/config.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/config.c
4728c8
+++ multipath-tools-130222/libmultipath/config.c
4728c8
@@ -344,6 +344,7 @@ merge_hwe (struct hwentry * dst, struct
4728c8
 	merge_num(delay_watch_checks);
4728c8
 	merge_num(delay_wait_checks);
4728c8
 	merge_num(skip_kpartx);
4728c8
+	merge_num(max_sectors_kb);
4728c8
 
4728c8
 	/*
4728c8
 	 * Make sure features is consistent with
4728c8
@@ -405,6 +406,7 @@ overwrite_hwe (struct hwentry * dst, str
4728c8
 	overwrite_num(delay_watch_checks);
4728c8
 	overwrite_num(delay_wait_checks);
4728c8
 	overwrite_num(skip_kpartx);
4728c8
+	overwrite_num(max_sectors_kb);
4728c8
 
4728c8
 	/*
4728c8
 	 * Make sure features is consistent with
4728c8
@@ -682,6 +684,7 @@ load_config (char * file, struct udev *u
4728c8
 	conf->skip_kpartx = DEFAULT_SKIP_KPARTX;
4728c8
 	conf->remove_retries = 0;
4728c8
 	conf->disable_changed_wwids = 0;
4728c8
+	conf->max_sectors_kb = DEFAULT_MAX_SECTORS_KB;
4728c8
 
4728c8
 	/*
4728c8
 	 * preload default hwtable
4728c8
Index: multipath-tools-130222/libmultipath/config.h
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/config.h
4728c8
+++ multipath-tools-130222/libmultipath/config.h
4728c8
@@ -65,6 +65,7 @@ struct hwentry {
4728c8
 	int delay_watch_checks;
4728c8
 	int delay_wait_checks;
4728c8
 	int skip_kpartx;
4728c8
+	int max_sectors_kb;
4728c8
 	char * bl_product;
4728c8
 };
4728c8
 
4728c8
@@ -92,6 +93,7 @@ struct mpentry {
4728c8
 	int delay_watch_checks;
4728c8
 	int delay_wait_checks;
4728c8
 	int skip_kpartx;
4728c8
+	int max_sectors_kb;
4728c8
 	uid_t uid;
4728c8
 	gid_t gid;
4728c8
 	mode_t mode;
4728c8
@@ -148,6 +150,7 @@ struct config {
4728c8
 	int skip_kpartx;
4728c8
 	int remove_retries;
4728c8
 	int disable_changed_wwids;
4728c8
+	int max_sectors_kb;
4728c8
 	unsigned int version[3];
4728c8
 
4728c8
 	char * dev;
4728c8
Index: multipath-tools-130222/libmultipath/configure.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/configure.c
4728c8
+++ multipath-tools-130222/libmultipath/configure.c
4728c8
@@ -295,6 +295,7 @@ setup_map (struct multipath * mpp, char
4728c8
 	select_delay_watch_checks(mpp);
4728c8
 	select_delay_wait_checks(mpp);
4728c8
 	select_skip_kpartx(mpp);
4728c8
+	select_max_sectors_kb(mpp);
4728c8
 
4728c8
 	sysfs_set_scsi_tmo(mpp);
4728c8
 	/*
4728c8
Index: multipath-tools-130222/libmultipath/defaults.h
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/defaults.h
4728c8
+++ multipath-tools-130222/libmultipath/defaults.h
4728c8
@@ -25,6 +25,7 @@
4728c8
 #define DEFAULT_RETRIGGER_TRIES 3
4728c8
 #define DEFAULT_UEV_WAIT_TIMEOUT 30
4728c8
 #define DEFAULT_SKIP_KPARTX SKIP_KPARTX_OFF
4728c8
+#define DEFAULT_MAX_SECTORS_KB	MAX_SECTORS_KB_UNDEF
4728c8
 
4728c8
 #define DEFAULT_CHECKINT	5
4728c8
 #define MAX_CHECKINT(a)		(a << 2)
4728c8
Index: multipath-tools-130222/libmultipath/dict.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/dict.c
4728c8
+++ multipath-tools-130222/libmultipath/dict.c
4728c8
@@ -976,6 +976,22 @@ def_disable_changed_wwids_handler(vector
4728c8
 	return 0;
4728c8
 }
4728c8
 
4728c8
+static int
4728c8
+def_max_sectors_kb_handler(vector strvec)
4728c8
+{
4728c8
+	char * buff;
4728c8
+
4728c8
+	buff = set_value(strvec);
4728c8
+	if (!buff)
4728c8
+		return 1;
4728c8
+
4728c8
+	if ((conf->max_sectors_kb = atoi(buff)) < MAX_SECTORS_KB_MIN)
4728c8
+		conf->max_sectors_kb = MAX_SECTORS_KB_UNDEF;
4728c8
+
4728c8
+	FREE(buff);
4728c8
+	return 0;
4728c8
+}
4728c8
+
4728c8
 /*
4728c8
  * blacklist block handlers
4728c8
  */
4728c8
@@ -1765,6 +1781,26 @@ hw_delay_wait_checks_handler(vector strv
4728c8
 	return 0;
4728c8
 }
4728c8
 
4728c8
+static int
4728c8
+hw_max_sectors_kb_handler(vector strvec)
4728c8
+{
4728c8
+	struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
4728c8
+	char * buff;
4728c8
+
4728c8
+	if (!hwe)
4728c8
+		return 1;
4728c8
+
4728c8
+	buff = set_value(strvec);
4728c8
+	if (!buff)
4728c8
+		return 1;
4728c8
+
4728c8
+	if ((hwe->max_sectors_kb = atoi(buff)) < MAX_SECTORS_KB_MIN)
4728c8
+		hwe->max_sectors_kb = MAX_SECTORS_KB_UNDEF;
4728c8
+
4728c8
+	FREE(buff);
4728c8
+	return 0;
4728c8
+}
4728c8
+
4728c8
 /*
4728c8
  * multipaths block handlers
4728c8
  */
4728c8
@@ -2316,6 +2352,26 @@ mp_delay_wait_checks_handler(vector strv
4728c8
 	return 0;
4728c8
 }
4728c8
 
4728c8
+static int
4728c8
+mp_max_sectors_kb_handler(vector strvec)
4728c8
+{
4728c8
+	struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
4728c8
+	char * buff;
4728c8
+
4728c8
+	if (!mpe)
4728c8
+		return 1;
4728c8
+
4728c8
+	buff = set_value(strvec);
4728c8
+	if (!buff)
4728c8
+		return 1;
4728c8
+
4728c8
+	if ((mpe->max_sectors_kb = atoi(buff)) < MAX_SECTORS_KB_MIN)
4728c8
+		mpe->max_sectors_kb = MAX_SECTORS_KB_UNDEF;
4728c8
+
4728c8
+	FREE(buff);
4728c8
+	return 0;
4728c8
+}
4728c8
+
4728c8
 /*
4728c8
  * config file keywords printing
4728c8
  */
4728c8
@@ -2615,6 +2671,16 @@ snprint_mp_delay_wait_checks(char * buff
4728c8
 }
4728c8
 
4728c8
 static int
4728c8
+snprint_mp_max_sectors_kb(char * buff, int len, void * data)
4728c8
+{
4728c8
+	struct mpentry * mpe = (struct mpentry *)data;
4728c8
+
4728c8
+	if (mpe->max_sectors_kb == MAX_SECTORS_KB_UNDEF)
4728c8
+		return 0;
4728c8
+	return snprintf(buff, len, "%d", mpe->max_sectors_kb);
4728c8
+}
4728c8
+
4728c8
+static int
4728c8
 snprint_hw_fast_io_fail(char * buff, int len, void * data)
4728c8
 {
4728c8
 	struct hwentry * hwe = (struct hwentry *)data;
4728c8
@@ -2993,6 +3059,16 @@ snprint_detect_prio(char * buff, int len
4728c8
 }
4728c8
 
4728c8
 static int
4728c8
+snprint_hw_max_sectors_kb(char * buff, int len, void * data)
4728c8
+{
4728c8
+	struct hwentry * hwe = (struct hwentry *)data;
4728c8
+
4728c8
+	if (hwe->max_sectors_kb == MAX_SECTORS_KB_UNDEF)
4728c8
+		return 0;
4728c8
+	return snprintf(buff, len, "%d", hwe->max_sectors_kb);
4728c8
+}
4728c8
+
4728c8
+static int
4728c8
 snprint_def_polling_interval (char * buff, int len, void * data)
4728c8
 {
4728c8
 	return snprintf(buff, len, "%i", conf->checkint);
4728c8
@@ -3461,6 +3537,14 @@ snprint_def_disable_changed_wwids(char *
4728c8
 }
4728c8
 
4728c8
 static int
4728c8
+snprint_def_max_sectors_kb(char * buff, int len, void * data)
4728c8
+{
4728c8
+	if (conf->max_sectors_kb == MAX_SECTORS_KB_UNDEF)
4728c8
+		return 0;
4728c8
+	return snprintf(buff, len, "%d", conf->max_sectors_kb);
4728c8
+}
4728c8
+
4728c8
+static int
4728c8
 snprint_ble_simple (char * buff, int len, void * data)
4728c8
 {
4728c8
 	struct blentry * ble = (struct blentry *)data;
4728c8
@@ -3541,6 +3625,7 @@ init_keywords(void)
4728c8
 	install_keyword("new_bindings_in_boot", &def_new_bindings_in_boot_handler, &snprint_def_new_bindings_in_boot);
4728c8
 	install_keyword("remove_retries", &def_remove_retries_handler, &snprint_def_remove_retries);
4728c8
 	install_keyword("disable_changed_wwids", &def_disable_changed_wwids_handler, &snprint_def_disable_changed_wwids);
4728c8
+	install_keyword("max_sectors_kb", &def_max_sectors_kb_handler, &snprint_def_max_sectors_kb);
4728c8
 	__deprecated install_keyword("default_selector", &def_selector_handler, NULL);
4728c8
 	__deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
4728c8
 	__deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL);
4728c8
@@ -3609,6 +3694,7 @@ init_keywords(void)
4728c8
 	install_keyword("delay_watch_checks", &hw_delay_watch_checks_handler, &snprint_hw_delay_watch_checks);
4728c8
 	install_keyword("delay_wait_checks", &hw_delay_wait_checks_handler, &snprint_hw_delay_wait_checks);
4728c8
 	install_keyword("skip_kpartx", &hw_skip_kpartx_handler, &snprint_hw_skip_kpartx);
4728c8
+	install_keyword("max_sectors_kb", &hw_max_sectors_kb_handler, &snprint_hw_max_sectors_kb);
4728c8
 	install_sublevel_end();
4728c8
 
4728c8
 	install_keyword_root("multipaths", &multipaths_handler);
4728c8
@@ -3637,5 +3723,6 @@ init_keywords(void)
4728c8
 	install_keyword("delay_watch_checks", &mp_delay_watch_checks_handler, &snprint_mp_delay_watch_checks);
4728c8
 	install_keyword("delay_wait_checks", &mp_delay_wait_checks_handler, &snprint_mp_delay_wait_checks);
4728c8
 	install_keyword("skip_kpartx", &mp_skip_kpartx_handler, &snprint_mp_skip_kpartx);
4728c8
+	install_keyword("max_sectors_kb", &mp_max_sectors_kb_handler, &snprint_mp_max_sectors_kb);
4728c8
 	install_sublevel_end();
4728c8
 }
4728c8
Index: multipath-tools-130222/libmultipath/discovery.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/discovery.c
4728c8
+++ multipath-tools-130222/libmultipath/discovery.c
4728c8
@@ -12,6 +12,7 @@
4728c8
 #include <errno.h>
4728c8
 #include <libgen.h>
4728c8
 #include <libudev.h>
4728c8
+#include <libdevmapper.h>
4728c8
 
4728c8
 #include "checkers.h"
4728c8
 #include "vector.h"
4728c8
@@ -27,6 +28,7 @@
4728c8
 #include "discovery.h"
4728c8
 #include "prio.h"
4728c8
 #include "defaults.h"
4728c8
+#include "devmapper.h"
4728c8
 
4728c8
 int
4728c8
 store_pathinfo (vector pathvec, vector hwtable, struct udev_device *udevice,
4728c8
@@ -166,6 +168,64 @@ declare_sysfs_get_str(rev);
4728c8
 declare_sysfs_get_str(dev);
4728c8
 
4728c8
 int
4728c8
+sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload)
4728c8
+{
4728c8
+	struct pathgroup * pgp;
4728c8
+	struct path *pp;
4728c8
+	char buff[11];
4728c8
+	struct udev_device *udevice = NULL;
4728c8
+	int i, j, len, ret;
4728c8
+	int max_sectors_kb;
4728c8
+
4728c8
+	if (mpp->max_sectors_kb == MAX_SECTORS_KB_UNDEF)
4728c8
+		return 0;
4728c8
+	max_sectors_kb = mpp->max_sectors_kb;
4728c8
+	if (is_reload) {
4728c8
+		if (!mpp->dmi && dm_get_info(mpp->alias, &mpp->dmi) != 0) {
4728c8
+			condlog(0, "failed to get dm info on %s to set max_sectors_kb", mpp->alias);
4728c8
+			return 1;
4728c8
+		}
4728c8
+		udevice = udev_device_new_from_devnum(conf->udev, 'b',
4728c8
+						      makedev(mpp->dmi->major,
4728c8
+							      mpp->dmi->minor));
4728c8
+		if (!udevice) {
4728c8
+			condlog(0, "failed to get udev device to set max_sectors_kb for %s", mpp->alias);
4728c8
+			return 1;
4728c8
+		}
4728c8
+		if (sysfs_attr_get_value(udevice, "queue/max_sectors_kb",
4728c8
+					 buff, sizeof(buff)) <= 0) {
4728c8
+			condlog(0, "failed to get current max_sectors_kb from %s", mpp->alias);
4728c8
+			goto fail_reload;
4728c8
+		}
4728c8
+		if (sscanf(buff, "%u\n", &max_sectors_kb) != 1) {
4728c8
+			condlog(0, "can't parse current max_sectors_kb from %s",
4728c8
+				mpp->alias);
4728c8
+			goto fail_reload;
4728c8
+		}
4728c8
+		udev_device_unref(udevice);
4728c8
+	}
4728c8
+	snprintf(buff, 11, "%d", max_sectors_kb);
4728c8
+	len = strlen(buff);
4728c8
+
4728c8
+	vector_foreach_slot (mpp->pg, pgp, i) {
4728c8
+		vector_foreach_slot (pgp->paths, pp, j) {
4728c8
+			ret = sysfs_attr_set_value(pp->udev,
4728c8
+						   "queue/max_sectors_kb",
4728c8
+					  	   buff, len);
4728c8
+			if (ret < 0) {
4728c8
+				condlog(0, "failed setting max_sectors_kb on %s : %s", pp->dev, strerror(-ret));
4728c8
+				return 1;
4728c8
+			}
4728c8
+		}
4728c8
+	}
4728c8
+	return 0;
4728c8
+
4728c8
+fail_reload:
4728c8
+	udev_device_unref(udevice);
4728c8
+	return 1;
4728c8
+}
4728c8
+
4728c8
+int
4728c8
 sysfs_get_timeout(struct path *pp, unsigned int *timeout)
4728c8
 {
4728c8
 	const char *attr = NULL;
4728c8
Index: multipath-tools-130222/libmultipath/discovery.h
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/discovery.h
4728c8
+++ multipath-tools-130222/libmultipath/discovery.h
4728c8
@@ -41,6 +41,7 @@ int store_pathinfo (vector pathvec, vect
4728c8
 		    struct udev_device *udevice, int flag,
4728c8
 		    struct path **pp_ptr);
4728c8
 int sysfs_set_scsi_tmo (struct multipath *mpp);
4728c8
+int sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload);
4728c8
 int sysfs_get_timeout(struct path *pp, unsigned int *timeout);
4728c8
 int sysfs_get_host_pci_name(struct path *pp, char *pci_name);
4728c8
 int sysfs_get_iscsi_ip_address(struct path *pp, char *ip_address);
4728c8
Index: multipath-tools-130222/libmultipath/propsel.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/propsel.c
4728c8
+++ multipath-tools-130222/libmultipath/propsel.c
4728c8
@@ -880,3 +880,28 @@ select_skip_kpartx (struct multipath * m
4728c8
 	condlog(3, "skip_kpartx = DISABLED (internal default)");
4728c8
 	return 0;
4728c8
 }
4728c8
+
4728c8
+extern int
4728c8
+select_max_sectors_kb (struct multipath * mp)
4728c8
+{
4728c8
+	if (mp->mpe && mp->mpe->max_sectors_kb != MAX_SECTORS_KB_UNDEF) {
4728c8
+		mp->max_sectors_kb = mp->mpe->max_sectors_kb;
4728c8
+		condlog(3, "max_sectors_kb = %i (multipath setting)",
4728c8
+				mp->max_sectors_kb);
4728c8
+		return 0;
4728c8
+	}
4728c8
+	if (mp->hwe && mp->hwe->max_sectors_kb != MAX_SECTORS_KB_UNDEF) {
4728c8
+		mp->max_sectors_kb = mp->hwe->max_sectors_kb;
4728c8
+		condlog(3, "max_sectors_kb = %i (controler setting)",
4728c8
+				mp->max_sectors_kb);
4728c8
+		return 0;
4728c8
+	}
4728c8
+	if (conf->max_sectors_kb != MAX_SECTORS_KB_UNDEF) {
4728c8
+		mp->max_sectors_kb = conf->max_sectors_kb;
4728c8
+		condlog(3, "max_sectors_kb = %i (config file default)",
4728c8
+				mp->max_sectors_kb);
4728c8
+		return 0;
4728c8
+	}
4728c8
+	mp->max_sectors_kb = MAX_SECTORS_KB_UNDEF;
4728c8
+	return 0;
4728c8
+}
4728c8
Index: multipath-tools-130222/libmultipath/propsel.h
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/propsel.h
4728c8
+++ multipath-tools-130222/libmultipath/propsel.h
4728c8
@@ -24,3 +24,4 @@ int select_deferred_remove(struct multip
4728c8
 int select_delay_watch_checks (struct multipath * mp);
4728c8
 int select_delay_wait_checks (struct multipath * mp);
4728c8
 int select_skip_kpartx (struct multipath * mp);
4728c8
+int select_max_sectors_kb (struct multipath * mp);
4728c8
Index: multipath-tools-130222/libmultipath/structs.h
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/structs.h
4728c8
+++ multipath-tools-130222/libmultipath/structs.h
4728c8
@@ -128,6 +128,12 @@ enum skip_kpartx_states {
4728c8
 	SKIP_KPARTX_ON,
4728c8
 };
4728c8
 
4728c8
+
4728c8
+enum max_sectors_kb_states {
4728c8
+	MAX_SECTORS_KB_UNDEF = 0,
4728c8
+	MAX_SECTORS_KB_MIN = 4,  /* can't be smaller than page size */
4728c8
+};
4728c8
+
4728c8
 enum scsi_protocol {
4728c8
 	SCSI_PROTOCOL_FCP = 0,	/* Fibre Channel */
4728c8
 	SCSI_PROTOCOL_SPI = 1,	/* parallel SCSI */
4728c8
@@ -245,6 +251,7 @@ struct multipath {
4728c8
 	int delay_wait_checks;
4728c8
 	int force_udev_reload;
4728c8
 	int skip_kpartx;
4728c8
+	int max_sectors_kb;
4728c8
 	unsigned int dev_loss;
4728c8
 	uid_t uid;
4728c8
 	gid_t gid;
4728c8
Index: multipath-tools-130222/multipath/multipath.conf.5
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/multipath/multipath.conf.5
4728c8
+++ multipath-tools-130222/multipath/multipath.conf.5
4728c8
@@ -567,6 +567,10 @@ disable access to the path until the wwi
4728c8
 This sets how may times multipath will retry removing a device that is in-use.
4728c8
 Between each attempt, multipath will sleep 1 second. The default is
4728c8
 .I 0
4728c8
+.TP
4728c8
+.B max_sectors_kb
4728c8
+Sets the max_sectors_kb device parameter on all path devices and the multipath
4728c8
+device to the specified value. Default is device dependent.
4728c8
 .
4728c8
 .SH "blacklist section"
4728c8
 The
4728c8
@@ -678,6 +682,8 @@ section:
4728c8
 .B delay_wait_checks
4728c8
 .TP
4728c8
 .B skip_kpartx
4728c8
+.TP
4728c8
+.B max_sectors_kb
4728c8
 .RE
4728c8
 .PD
4728c8
 .LP
4728c8
@@ -778,6 +784,8 @@ section:
4728c8
 .B delay_wait_checks
4728c8
 .TP
4728c8
 .B skip_kpartx
4728c8
+.TP
4728c8
+.B max_sectors_kb
4728c8
 .RE
4728c8
 .PD
4728c8
 .LP
4728c8
Index: multipath-tools-130222/libmultipath/devmapper.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/devmapper.c
4728c8
+++ multipath-tools-130222/libmultipath/devmapper.c
4728c8
@@ -21,7 +21,7 @@
4728c8
 #include "devmapper.h"
4728c8
 #include "config.h"
4728c8
 #include "sysfs.h"
4728c8
-
4728c8
+#include "discovery.h"
4728c8
 #include "log_pthread.h"
4728c8
 #include <sys/types.h>
4728c8
 #include <time.h>
4728c8
@@ -330,6 +330,7 @@ extern int
4728c8
 dm_addmap_create (struct multipath *mpp, char * params) {
4728c8
 	int ro;
4728c8
 
4728c8
+	sysfs_set_max_sectors_kb(mpp, 0);
4728c8
 	for (ro = 0; ro <= 1; ro++) {
4728c8
 		int err;
4728c8
 
4728c8
@@ -356,6 +357,7 @@ dm_addmap_create (struct multipath *mpp,
4728c8
 
4728c8
 extern int
4728c8
 dm_addmap_reload (struct multipath *mpp, char *params) {
4728c8
+	sysfs_set_max_sectors_kb(mpp, 1);
4728c8
 	if (dm_addmap(DM_DEVICE_RELOAD, TGT_MPATH, mpp, params, 0, ADDMAP_RW, SKIP_KPARTX_OFF))
4728c8
 		return 1;
4728c8
 	if (errno != EROFS)