[lvm-devel] master - label: Add label_read callback.

Alasdair Kergon agk at sourceware.org
Tue Jan 9 00:58:28 UTC 2018


Gitweb:        https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=4b02d4e22eeb0dbf61e2c93f3803fbbaeffb0291
Commit:        4b02d4e22eeb0dbf61e2c93f3803fbbaeffb0291
Parent:        6d322e68f302e5406e93ec7649f537776f78f641
Author:        Alasdair G Kergon <agk at redhat.com>
AuthorDate:    Mon Jan 8 23:08:22 2018 +0000
Committer:     Alasdair G Kergon <agk at redhat.com>
CommitterDate: Mon Jan 8 23:30:50 2018 +0000

label: Add label_read callback.

---
 lib/cache/lvmcache.c |   15 +++++++++++++--
 lib/label/label.c    |   44 +++++++++++++++++++++++++++++++++++++-------
 lib/label/label.h    |    2 ++
 3 files changed, 52 insertions(+), 9 deletions(-)

diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 25bf7ee..53f1c95 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -1095,6 +1095,14 @@ next:
 	goto next;
 }
 
+/* Track the number of outstanding label reads */
+static void _process_label_data(int failed, void *context, void *data)
+{
+	int *nr_labels_outstanding = context;
+
+	(*nr_labels_outstanding)--;
+}
+
 int lvmcache_label_scan(struct cmd_context *cmd)
 {
 	struct dm_list del_cache_devs;
@@ -1106,6 +1114,7 @@ int lvmcache_label_scan(struct cmd_context *cmd)
 	struct device *dev;
 	struct format_type *fmt;
 	int dev_count = 0;
+	int nr_labels_outstanding = 0;
 
 	int r = 0;
 
@@ -1144,13 +1153,15 @@ int lvmcache_label_scan(struct cmd_context *cmd)
 	_destroy_duplicate_device_list(&_found_duplicate_devs);
 
 	while ((dev = dev_iter_get(iter))) {
-		(void) label_read(dev, &label, UINT64_C(0));
+		nr_labels_outstanding++;
+		if (!label_read_callback(cmd->mem, dev, UINT64_C(0), _process_label_data, &nr_labels_outstanding))
+			nr_labels_outstanding--;
 		dev_count++;
 	}
 
 	dev_iter_destroy(iter);
 
-	log_very_verbose("Scanned %d device labels", dev_count);
+	log_very_verbose("Scanned %d device labels (%d outstanding)", dev_count, nr_labels_outstanding);
 
 	/*
 	 * _choose_preferred_devs() returns:
diff --git a/lib/label/label.c b/lib/label/label.c
index 0ed5c6a..b116ea6 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -122,8 +122,10 @@ static void _update_lvmcache_orphan(struct lvmcache_info *info)
 struct find_labeller_params {
 	struct device *dev;
 	uint64_t scan_sector;	/* Sector to be scanned */
-
 	uint64_t label_sector;	/* Sector where label found */
+	lvm_callback_fn_t process_label_data_fn;
+	void *process_label_data_context;
+
 	struct label **result;
 
 	int ret;
@@ -134,8 +136,10 @@ static void _set_label_read_result(int failed, void *context, void *data)
 	struct find_labeller_params *flp = context;
 	struct label **result = flp->result;
 
-	if (failed)
+	if (failed) {
+		flp->ret = 0;
 		goto_out;
+	}
 
 	if (result && *result) {
 		(*result)->dev = flp->dev;
@@ -145,6 +149,9 @@ static void _set_label_read_result(int failed, void *context, void *data)
 out:
 	if (!dev_close(flp->dev))
 		stack;
+
+	if (flp->ret && flp->process_label_data_fn)
+		flp->process_label_data_fn(0, flp->process_label_data_context, NULL);
 }
 
 static void _find_labeller(int failed, void *context, void *data)
@@ -161,6 +168,12 @@ static void _find_labeller(int failed, void *context, void *data)
 	struct lvmcache_info *info;
 	uint64_t sector;
 
+	if (failed) {
+		log_debug_devs("%s: Failed to read label area", dev_name(dev));
+		_set_label_read_result(1, flp, NULL);
+		return;
+	}
+
 	/* Scan a few sectors for a valid label */
 	for (sector = 0; sector < LABEL_SCAN_SECTORS;
 	     sector += LABEL_SIZE >> SECTOR_SHIFT) {
@@ -222,7 +235,7 @@ static void _find_labeller(int failed, void *context, void *data)
 		flp->ret = 0;
 		_set_label_read_result(1, flp, NULL);
 	} else
-		flp->ret = (l->ops->read)(l, dev, labelbuf, result, &_set_label_read_result, flp);
+		(void) (l->ops->read)(l, dev, labelbuf, result, &_set_label_read_result, flp);
 }
 
 /* FIXME Also wipe associated metadata area headers? */
@@ -300,7 +313,8 @@ int label_remove(struct device *dev)
 	return r;
 }
 
-static int _label_read(struct device *dev, uint64_t scan_sector, struct label **result)
+static int _label_read(struct device *dev, uint64_t scan_sector, struct label **result,
+		       lvm_callback_fn_t process_label_data_fn, void *process_label_data_context)
 {
 	struct lvmcache_info *info;
 	struct find_labeller_params *flp;
@@ -309,6 +323,8 @@ static int _label_read(struct device *dev, uint64_t scan_sector, struct label **
 	if ((info = lvmcache_info_from_pvid(dev->pvid, dev, 1))) {
 		log_debug_devs("Reading label from lvmcache for %s", dev_name(dev));
 		*result = lvmcache_get_label(info);
+		if (process_label_data_fn)
+			process_label_data_fn(0, process_label_data_context, NULL);
 		return 1;
 	}
 
@@ -320,6 +336,8 @@ static int _label_read(struct device *dev, uint64_t scan_sector, struct label **
 	flp->dev = dev;
 	flp->scan_sector = scan_sector;
 	flp->result = result;
+	flp->process_label_data_fn = process_label_data_fn;
+	flp->process_label_data_context = process_label_data_context;
 	flp->ret = 1;
 
 	/* Ensure result is always wiped as a precaution */
@@ -337,19 +355,31 @@ static int _label_read(struct device *dev, uint64_t scan_sector, struct label **
 		return 0;
 	}
 
-	if (!(readbuf = dev_read(dev, scan_sector << SECTOR_SHIFT, LABEL_SCAN_SIZE, DEV_IO_LABEL))) {
+	if (!(dev_read_callback(dev, scan_sector << SECTOR_SHIFT, LABEL_SCAN_SIZE, DEV_IO_LABEL, _find_labeller, flp))) {
 		log_debug_devs("%s: Failed to read label area", dev_name(dev));
 		_set_label_read_result(1, flp, NULL);
 		return 0;
 	}
 
-	_find_labeller(0, flp, readbuf);
 	return flp->ret;
 }
 
 int label_read(struct device *dev, struct label **result, uint64_t scan_sector)
 {
-	return _label_read(dev, scan_sector, result);
+	return _label_read(dev, scan_sector, result, NULL, NULL);
+}
+
+int label_read_callback(struct dm_pool *mem, struct device *dev, uint64_t scan_sector,
+		       lvm_callback_fn_t process_label_data_fn, void *process_label_data_context)
+{
+	struct label **result;	/* FIXME Eliminate this */
+
+	if (!(result = dm_zalloc(sizeof(*result)))) {
+		log_error("Couldn't allocate memory for internal result pointer.");
+		return 0;
+	}
+
+	return _label_read(dev, scan_sector, result, process_label_data_fn, process_label_data_context);
 }
 
 /* Caller may need to use label_get_handler to create label struct! */
diff --git a/lib/label/label.h b/lib/label/label.h
index 984acce..1f12294 100644
--- a/lib/label/label.h
+++ b/lib/label/label.h
@@ -96,6 +96,8 @@ struct labeller *label_get_handler(const char *name);
 int label_remove(struct device *dev);
 int label_read(struct device *dev, struct label **result,
 		uint64_t scan_sector);
+int label_read_callback(struct dm_pool *mem, struct device *dev, uint64_t scan_sector,
+	lvm_callback_fn_t process_label_data_fn, void *process_label_data_context);
 int label_write(struct device *dev, struct label *label);
 struct label *label_create(struct labeller *labeller);
 void label_destroy(struct label *label);




More information about the lvm-devel mailing list