Skip to content

Commit

Permalink
init: refactor name_to_dev_t
Browse files Browse the repository at this point in the history
Split each case into a self-contained helper, and move the block
dependent code entirely under the pre-existing #ifdef CONFIG_BLOCK.
This allows to remove the blk_lookup_devt stub in genhd.h.

Signed-off-by: Christoph Hellwig <[email protected]>
Reviewed-by: Greg Kroah-Hartman <[email protected]>
Reviewed-by: Jan Kara <[email protected]>
Reviewed-by: Hannes Reinecke <[email protected]>
Reviewed-by: Johannes Thumshirn <[email protected]>
Acked-by: Tejun Heo <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
Christoph Hellwig authored and axboe committed Dec 1, 2020
1 parent 3a4174e commit c2637e8
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 99 deletions.
7 changes: 1 addition & 6 deletions include/linux/genhd.h
Original file line number Diff line number Diff line change
Expand Up @@ -388,18 +388,13 @@ static inline void bd_unlink_disk_holder(struct block_device *bdev,
}
#endif /* CONFIG_SYSFS */

dev_t blk_lookup_devt(const char *name, int partno);
#ifdef CONFIG_BLOCK
void printk_all_partitions(void);
dev_t blk_lookup_devt(const char *name, int partno);
#else /* CONFIG_BLOCK */
static inline void printk_all_partitions(void)
{
}
static inline dev_t blk_lookup_devt(const char *name, int partno)
{
dev_t devt = MKDEV(0, 0);
return devt;
}
#endif /* CONFIG_BLOCK */

#endif /* _LINUX_GENHD_H */
183 changes: 90 additions & 93 deletions init/do_mounts.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ static int match_dev_by_uuid(struct device *dev, const void *data)
return 0;
}


/**
* devt_from_partuuid - looks up the dev_t of a partition by its UUID
* @uuid_str: char array containing ascii UUID
Expand Down Expand Up @@ -186,7 +185,83 @@ static int match_dev_by_label(struct device *dev, const void *data)

return 0;
}
#endif

static dev_t devt_from_partlabel(const char *label)
{
struct device *dev;
dev_t devt = 0;

dev = class_find_device(&block_class, NULL, label, &match_dev_by_label);
if (dev) {
devt = dev->devt;
put_device(dev);
}

return devt;
}

static dev_t devt_from_devname(const char *name)
{
dev_t devt = 0;
int part;
char s[32];
char *p;

if (strlen(name) > 31)
return 0;
strcpy(s, name);
for (p = s; *p; p++) {
if (*p == '/')
*p = '!';
}

devt = blk_lookup_devt(s, 0);
if (devt)
return devt;

/*
* Try non-existent, but valid partition, which may only exist after
* opening the device, like partitioned md devices.
*/
while (p > s && isdigit(p[-1]))
p--;
if (p == s || !*p || *p == '0')
return 0;

/* try disk name without <part number> */
part = simple_strtoul(p, NULL, 10);
*p = '\0';
devt = blk_lookup_devt(s, part);
if (devt)
return devt;

/* try disk name without p<part number> */
if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p')
return 0;
p[-1] = '\0';
return blk_lookup_devt(s, part);
}
#endif /* CONFIG_BLOCK */

static dev_t devt_from_devnum(const char *name)
{
unsigned maj, min, offset;
dev_t devt = 0;
char *p, dummy;

if (sscanf(name, "%u:%u%c", &maj, &min, &dummy) == 2 ||
sscanf(name, "%u:%u:%u:%c", &maj, &min, &offset, &dummy) == 3) {
devt = MKDEV(maj, min);
if (maj != MAJOR(devt) || min != MINOR(devt))
return 0;
} else {
devt = new_decode_dev(simple_strtoul(name, &p, 16));
if (*p)
return 0;
}

return devt;
}

/*
* Convert a name into device number. We accept the following variants:
Expand Down Expand Up @@ -218,101 +293,23 @@ static int match_dev_by_label(struct device *dev, const void *data)
* name contains slashes, the device name has them replaced with
* bangs.
*/

dev_t name_to_dev_t(const char *name)
{
char s[32];
char *p;
dev_t res = 0;
int part;

if (strcmp(name, "/dev/nfs") == 0)
return Root_NFS;
if (strcmp(name, "/dev/cifs") == 0)
return Root_CIFS;
if (strcmp(name, "/dev/ram") == 0)
return Root_RAM0;
#ifdef CONFIG_BLOCK
if (strncmp(name, "PARTUUID=", 9) == 0) {
name += 9;
res = devt_from_partuuid(name);
if (!res)
goto fail;
goto done;
} else if (strncmp(name, "PARTLABEL=", 10) == 0) {
struct device *dev;

dev = class_find_device(&block_class, NULL, name + 10,
&match_dev_by_label);
if (!dev)
goto fail;

res = dev->devt;
put_device(dev);
goto done;
}
if (strncmp(name, "PARTUUID=", 9) == 0)
return devt_from_partuuid(name + 9);
if (strncmp(name, "PARTLABEL=", 10) == 0)
return devt_from_partlabel(name + 10);
if (strncmp(name, "/dev/", 5) == 0)
return devt_from_devname(name + 5);
#endif

if (strncmp(name, "/dev/", 5) != 0) {
unsigned maj, min, offset;
char dummy;

if ((sscanf(name, "%u:%u%c", &maj, &min, &dummy) == 2) ||
(sscanf(name, "%u:%u:%u:%c", &maj, &min, &offset, &dummy) == 3)) {
res = MKDEV(maj, min);
if (maj != MAJOR(res) || min != MINOR(res))
goto fail;
} else {
res = new_decode_dev(simple_strtoul(name, &p, 16));
if (*p)
goto fail;
}
goto done;
}

name += 5;
res = Root_NFS;
if (strcmp(name, "nfs") == 0)
goto done;
res = Root_CIFS;
if (strcmp(name, "cifs") == 0)
goto done;
res = Root_RAM0;
if (strcmp(name, "ram") == 0)
goto done;

if (strlen(name) > 31)
goto fail;
strcpy(s, name);
for (p = s; *p; p++)
if (*p == '/')
*p = '!';
res = blk_lookup_devt(s, 0);
if (res)
goto done;

/*
* try non-existent, but valid partition, which may only exist
* after revalidating the disk, like partitioned md devices
*/
while (p > s && isdigit(p[-1]))
p--;
if (p == s || !*p || *p == '0')
goto fail;

/* try disk name without <part number> */
part = simple_strtoul(p, NULL, 10);
*p = '\0';
res = blk_lookup_devt(s, part);
if (res)
goto done;

/* try disk name without p<part number> */
if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p')
goto fail;
p[-1] = '\0';
res = blk_lookup_devt(s, part);
if (res)
goto done;

fail:
return 0;
done:
return res;
return devt_from_devnum(name);
}
EXPORT_SYMBOL_GPL(name_to_dev_t);

Expand Down

0 comments on commit c2637e8

Please sign in to comment.