1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-10-27 01:55:10 +03:00

label: Wrap _find_labeller params into a struct.

Move the actual buffer reading up to _label_read() so _find_labeller()
just examines the buffer supplied.
This commit is contained in:
Alasdair G Kergon 2018-01-02 16:01:10 +00:00
parent 9b830791ea
commit 3db51e3f0e

View File

@ -119,42 +119,48 @@ static void _update_lvmcache_orphan(struct lvmcache_info *info)
stack; stack;
} }
static void _set_label_read_result(int failed, struct device *dev, uint64_t sector, struct label **result) struct find_labeller_params {
struct device *dev;
uint64_t scan_sector; /* Sector to be scanned */
uint64_t label_sector; /* Sector where label found */
struct label **result;
};
static void _set_label_read_result(int failed, struct find_labeller_params *flp)
{ {
struct label **result = flp->result;
if (failed) if (failed)
goto_out; goto_out;
if (result && *result) { if (result && *result) {
(*result)->dev = dev; (*result)->dev = flp->dev;
(*result)->sector = sector; (*result)->sector = flp->label_sector;
} }
out: out:
if (!dev_close(dev)) if (!dev_close(flp->dev))
stack; stack;
} }
static int _find_labeller(struct device *dev, uint64_t scan_sector, struct label **result) static int _find_labeller(struct find_labeller_params *flp, char *readbuf)
{ {
struct device *dev = flp->dev;
uint64_t scan_sector = flp->scan_sector;
struct label **result = flp->result;
char labelbuf[LABEL_SIZE] __attribute__((aligned(8))); char labelbuf[LABEL_SIZE] __attribute__((aligned(8)));
uint64_t label_sector;
struct labeller_i *li; struct labeller_i *li;
struct labeller *l = NULL; /* Set when a labeller claims the label */ struct labeller *l = NULL; /* Set when a labeller claims the label */
struct label_header *lh; struct label_header *lh;
struct lvmcache_info *info; struct lvmcache_info *info;
uint64_t sector; uint64_t sector;
char *buf = NULL;
int r = 0; int r = 0;
if (!(buf = dev_read(dev, scan_sector << SECTOR_SHIFT, LABEL_SCAN_SIZE, DEV_IO_LABEL))) {
log_debug_devs("%s: Failed to read label area", dev_name(dev));
goto out;
}
/* Scan a few sectors for a valid label */ /* Scan a few sectors for a valid label */
for (sector = 0; sector < LABEL_SCAN_SECTORS; for (sector = 0; sector < LABEL_SCAN_SECTORS;
sector += LABEL_SIZE >> SECTOR_SHIFT) { sector += LABEL_SIZE >> SECTOR_SHIFT) {
lh = (struct label_header *) (buf + (sector << SECTOR_SHIFT)); lh = (struct label_header *) (readbuf + (sector << SECTOR_SHIFT));
if (!strncmp((char *)lh->id, LABEL_ID, sizeof(lh->id))) { if (!strncmp((char *)lh->id, LABEL_ID, sizeof(lh->id))) {
if (l) { if (l) {
@ -196,15 +202,14 @@ static int _find_labeller(struct device *dev, uint64_t scan_sector, struct label
continue; continue;
} }
memcpy(labelbuf, lh, LABEL_SIZE); memcpy(labelbuf, lh, LABEL_SIZE);
label_sector = sector + scan_sector; flp->label_sector = sector + scan_sector;
l = li->l; l = li->l;
break; break;
} }
} }
} }
out: dm_free(readbuf);
dm_free(buf);
if (!l) { if (!l) {
if ((info = lvmcache_info_from_pvid(dev->pvid, dev, 0))) if ((info = lvmcache_info_from_pvid(dev->pvid, dev, 0)))
@ -213,7 +218,7 @@ static int _find_labeller(struct device *dev, uint64_t scan_sector, struct label
} else } else
r = (l->ops->read)(l, dev, labelbuf, result); r = (l->ops->read)(l, dev, labelbuf, result);
_set_label_read_result(!r, dev, label_sector, result); _set_label_read_result(!r, flp);
return r; return r;
} }
@ -296,6 +301,8 @@ int label_remove(struct device *dev)
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)
{ {
struct lvmcache_info *info; struct lvmcache_info *info;
struct find_labeller_params *flp;
char *readbuf = NULL;
if ((info = lvmcache_info_from_pvid(dev->pvid, dev, 1))) { if ((info = lvmcache_info_from_pvid(dev->pvid, dev, 1))) {
log_debug_devs("Reading label from lvmcache for %s", dev_name(dev)); log_debug_devs("Reading label from lvmcache for %s", dev_name(dev));
@ -303,6 +310,19 @@ static int _label_read(struct device *dev, uint64_t scan_sector, struct label **
return 1; return 1;
} }
if (!(flp = dm_pool_zalloc(_labeller_mem, sizeof *flp))) {
log_error("find_labeller_params allocation failed.");
return 0;
}
flp->dev = dev;
flp->scan_sector = scan_sector;
flp->result = result;
/* Ensure result is always wiped as a precaution */
if (result)
*result = NULL;
log_debug_devs("Reading label from device %s", dev_name(dev)); log_debug_devs("Reading label from device %s", dev_name(dev));
if (!dev_open_readonly(dev)) { if (!dev_open_readonly(dev)) {
@ -314,7 +334,13 @@ static int _label_read(struct device *dev, uint64_t scan_sector, struct label **
return 0; return 0;
} }
return _find_labeller(dev, scan_sector, result); if (!(readbuf = dev_read(dev, scan_sector << SECTOR_SHIFT, LABEL_SCAN_SIZE, DEV_IO_LABEL))) {
log_debug_devs("%s: Failed to read label area", dev_name(dev));
_set_label_read_result(1, flp);
return 0;
}
return _find_labeller(flp, readbuf);
} }
int label_read(struct device *dev, struct label **result, uint64_t scan_sector) int label_read(struct device *dev, struct label **result, uint64_t scan_sector)