Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit cf056a4

Browse files
Christoph Hellwigaxboe
authored andcommitted
init: improve the name_to_dev_t interface
name_to_dev_t has a very misleading name, that doesn't make clear it should only be used by the early init code, and also has a bad calling convention that doesn't allow returning different kinds of errors. Rename it to early_lookup_bdev to make the use case clear, and return an errno, where -EINVAL means the string could not be parsed, and -ENODEV means it the string was valid, but there was no device found for it. Also stub out the whole call for !CONFIG_BLOCK as all the non-block root cases are always covered in the caller. Signed-off-by: Christoph Hellwig <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent c0c1a7d commit cf056a4

File tree

9 files changed

+74
-75
lines changed

9 files changed

+74
-75
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5453,8 +5453,8 @@
54535453

54545454
root= [KNL] Root filesystem
54555455
Usually this a a block device specifier of some kind,
5456-
see the name_to_dev_t comment in init/do_mounts.c for
5457-
details.
5456+
see the early_lookup_bdev comment in init/do_mounts.c
5457+
for details.
54585458
Alternatively this can be "ram" for the legacy initial
54595459
ramdisk, "nfs" and "cifs" for root on a network file
54605460
system, or "mtd" and "ubi" for mounting from raw flash.

drivers/md/dm-table.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,8 +330,9 @@ dev_t dm_get_dev_t(const char *path)
330330
{
331331
dev_t dev;
332332

333-
if (lookup_bdev(path, &dev))
334-
dev = name_to_dev_t(path);
333+
if (lookup_bdev(path, &dev) &&
334+
early_lookup_bdev(path, &dev))
335+
return 0;
335336
return dev;
336337
}
337338
EXPORT_SYMBOL_GPL(dm_get_dev_t);

drivers/md/md-autodetect.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,8 @@ static void __init md_setup_drive(struct md_setup_args *args)
147147
if (p)
148148
*p++ = 0;
149149

150-
dev = name_to_dev_t(devname);
150+
if (early_lookup_bdev(devname, &dev))
151+
dev = 0;
151152
if (strncmp(devname, "/dev/", 5) == 0)
152153
devname += 5;
153154
snprintf(comp_name, 63, "/dev/%s", devname);

drivers/mtd/devices/block2mtd.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size,
254254
msleep(1000);
255255
wait_for_device_probe();
256256

257-
devt = name_to_dev_t(devname);
258-
if (!devt)
257+
if (early_lookup_bdev(devname, &devt))
259258
continue;
260259
bdev = blkdev_get_by_dev(devt, mode, dev, NULL);
261260
}

fs/pstore/blk.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,9 +263,9 @@ static __init const char *early_boot_devpath(const char *initial_devname)
263263
* same scheme to find the device that we use for mounting
264264
* the root file system.
265265
*/
266-
dev_t dev = name_to_dev_t(initial_devname);
266+
dev_t dev;
267267

268-
if (!dev) {
268+
if (early_lookup_bdev(initial_devname, &dev)) {
269269
pr_err("failed to resolve '%s'!\n", initial_devname);
270270
return initial_devname;
271271
}

include/linux/blkdev.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,6 +1501,7 @@ int sync_blockdev_nowait(struct block_device *bdev);
15011501
void sync_bdevs(bool wait);
15021502
void bdev_statx_dioalign(struct inode *inode, struct kstat *stat);
15031503
void printk_all_partitions(void);
1504+
int early_lookup_bdev(const char *pathname, dev_t *dev);
15041505
#else
15051506
static inline void invalidate_bdev(struct block_device *bdev)
15061507
{
@@ -1522,6 +1523,10 @@ static inline void bdev_statx_dioalign(struct inode *inode, struct kstat *stat)
15221523
static inline void printk_all_partitions(void)
15231524
{
15241525
}
1526+
static inline int early_lookup_bdev(const char *pathname, dev_t *dev)
1527+
{
1528+
return -EINVAL;
1529+
}
15251530
#endif /* CONFIG_BLOCK */
15261531

15271532
int fsync_bdev(struct block_device *bdev);

include/linux/mount.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@ extern struct vfsmount *vfs_submount(const struct dentry *mountpoint,
107107
extern void mnt_set_expiry(struct vfsmount *mnt, struct list_head *expiry_list);
108108
extern void mark_mounts_for_expiry(struct list_head *mounts);
109109

110-
extern dev_t name_to_dev_t(const char *name);
111110
extern bool path_is_mountpoint(const struct path *path);
112111

113112
extern bool our_mnt(struct vfsmount *mnt);

init/do_mounts.c

Lines changed: 49 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,10 @@ static int match_dev_by_uuid(struct device *dev, const void *data)
9696
*
9797
* Returns the matching dev_t on success or 0 on failure.
9898
*/
99-
static dev_t devt_from_partuuid(const char *uuid_str)
99+
static int devt_from_partuuid(const char *uuid_str, dev_t *devt)
100100
{
101101
struct uuidcmp cmp;
102102
struct device *dev = NULL;
103-
dev_t devt = 0;
104103
int offset = 0;
105104
char *slash;
106105

@@ -124,29 +123,29 @@ static dev_t devt_from_partuuid(const char *uuid_str)
124123

125124
dev = class_find_device(&block_class, NULL, &cmp, &match_dev_by_uuid);
126125
if (!dev)
127-
return 0;
126+
return -ENODEV;
128127

129128
if (offset) {
130129
/*
131130
* Attempt to find the requested partition by adding an offset
132131
* to the partition number found by UUID.
133132
*/
134-
devt = part_devt(dev_to_disk(dev),
135-
dev_to_bdev(dev)->bd_partno + offset);
133+
*devt = part_devt(dev_to_disk(dev),
134+
dev_to_bdev(dev)->bd_partno + offset);
136135
} else {
137-
devt = dev->devt;
136+
*devt = dev->devt;
138137
}
139138

140139
put_device(dev);
141-
return devt;
140+
return 0;
142141

143142
clear_root_wait:
144143
pr_err("VFS: PARTUUID= is invalid.\n"
145144
"Expected PARTUUID=<valid-uuid-id>[/PARTNROFF=%%d]\n");
146145
if (root_wait)
147146
pr_err("Disabling rootwait; root= is invalid.\n");
148147
root_wait = 0;
149-
return 0;
148+
return -EINVAL;
150149
}
151150

152151
/**
@@ -166,38 +165,35 @@ static int match_dev_by_label(struct device *dev, const void *data)
166165
return 1;
167166
}
168167

169-
static dev_t devt_from_partlabel(const char *label)
168+
static int devt_from_partlabel(const char *label, dev_t *devt)
170169
{
171170
struct device *dev;
172-
dev_t devt = 0;
173171

174172
dev = class_find_device(&block_class, NULL, label, &match_dev_by_label);
175-
if (dev) {
176-
devt = dev->devt;
177-
put_device(dev);
178-
}
179-
180-
return devt;
173+
if (!dev)
174+
return -ENODEV;
175+
*devt = dev->devt;
176+
put_device(dev);
177+
return 0;
181178
}
182179

183-
static dev_t devt_from_devname(const char *name)
180+
static int devt_from_devname(const char *name, dev_t *devt)
184181
{
185-
dev_t devt = 0;
186182
int part;
187183
char s[32];
188184
char *p;
189185

190186
if (strlen(name) > 31)
191-
return 0;
187+
return -EINVAL;
192188
strcpy(s, name);
193189
for (p = s; *p; p++) {
194190
if (*p == '/')
195191
*p = '!';
196192
}
197193

198-
devt = blk_lookup_devt(s, 0);
199-
if (devt)
200-
return devt;
194+
*devt = blk_lookup_devt(s, 0);
195+
if (*devt)
196+
return 0;
201197

202198
/*
203199
* Try non-existent, but valid partition, which may only exist after
@@ -206,41 +202,42 @@ static dev_t devt_from_devname(const char *name)
206202
while (p > s && isdigit(p[-1]))
207203
p--;
208204
if (p == s || !*p || *p == '0')
209-
return 0;
205+
return -EINVAL;
210206

211207
/* try disk name without <part number> */
212208
part = simple_strtoul(p, NULL, 10);
213209
*p = '\0';
214-
devt = blk_lookup_devt(s, part);
215-
if (devt)
216-
return devt;
210+
*devt = blk_lookup_devt(s, part);
211+
if (*devt)
212+
return 0;
217213

218214
/* try disk name without p<part number> */
219215
if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p')
220-
return 0;
216+
return -EINVAL;
221217
p[-1] = '\0';
222-
return blk_lookup_devt(s, part);
218+
*devt = blk_lookup_devt(s, part);
219+
if (*devt)
220+
return 0;
221+
return -EINVAL;
223222
}
224-
#endif /* CONFIG_BLOCK */
225223

226-
static dev_t devt_from_devnum(const char *name)
224+
static int devt_from_devnum(const char *name, dev_t *devt)
227225
{
228226
unsigned maj, min, offset;
229-
dev_t devt = 0;
230227
char *p, dummy;
231228

232229
if (sscanf(name, "%u:%u%c", &maj, &min, &dummy) == 2 ||
233230
sscanf(name, "%u:%u:%u:%c", &maj, &min, &offset, &dummy) == 3) {
234-
devt = MKDEV(maj, min);
235-
if (maj != MAJOR(devt) || min != MINOR(devt))
236-
return 0;
231+
*devt = MKDEV(maj, min);
232+
if (maj != MAJOR(*devt) || min != MINOR(*devt))
233+
return -EINVAL;
237234
} else {
238-
devt = new_decode_dev(simple_strtoul(name, &p, 16));
235+
*devt = new_decode_dev(simple_strtoul(name, &p, 16));
239236
if (*p)
240-
return 0;
237+
return -EINVAL;
241238
}
242239

243-
return devt;
240+
return 0;
244241
}
245242

246243
/*
@@ -271,19 +268,18 @@ static dev_t devt_from_devnum(const char *name)
271268
* name contains slashes, the device name has them replaced with
272269
* bangs.
273270
*/
274-
dev_t name_to_dev_t(const char *name)
271+
int early_lookup_bdev(const char *name, dev_t *devt)
275272
{
276-
#ifdef CONFIG_BLOCK
277273
if (strncmp(name, "PARTUUID=", 9) == 0)
278-
return devt_from_partuuid(name + 9);
274+
return devt_from_partuuid(name + 9, devt);
279275
if (strncmp(name, "PARTLABEL=", 10) == 0)
280-
return devt_from_partlabel(name + 10);
276+
return devt_from_partlabel(name + 10, devt);
281277
if (strncmp(name, "/dev/", 5) == 0)
282-
return devt_from_devname(name + 5);
283-
#endif
284-
return devt_from_devnum(name);
278+
return devt_from_devname(name + 5, devt);
279+
return devt_from_devnum(name, devt);
285280
}
286-
EXPORT_SYMBOL_GPL(name_to_dev_t);
281+
EXPORT_SYMBOL_GPL(early_lookup_bdev);
282+
#endif
287283

288284
static int __init root_dev_setup(char *line)
289285
{
@@ -606,20 +602,17 @@ static void __init wait_for_root(char *root_device_name)
606602

607603
pr_info("Waiting for root device %s...\n", root_device_name);
608604

609-
for (;;) {
610-
if (driver_probe_done()) {
611-
ROOT_DEV = name_to_dev_t(root_device_name);
612-
if (ROOT_DEV)
613-
break;
614-
}
605+
while (!driver_probe_done() ||
606+
early_lookup_bdev(root_device_name, &ROOT_DEV) < 0)
615607
msleep(5);
616-
}
617608
async_synchronize_full();
618609

619610
}
620611

621612
static dev_t __init parse_root_device(char *root_device_name)
622613
{
614+
dev_t dev;
615+
623616
if (!strncmp(root_device_name, "mtd", 3) ||
624617
!strncmp(root_device_name, "ubi", 3))
625618
return Root_Generic;
@@ -629,7 +622,10 @@ static dev_t __init parse_root_device(char *root_device_name)
629622
return Root_CIFS;
630623
if (strcmp(root_device_name, "/dev/ram") == 0)
631624
return Root_RAM0;
632-
return name_to_dev_t(root_device_name);
625+
626+
if (early_lookup_bdev(root_device_name, &dev))
627+
return 0;
628+
return dev;
633629
}
634630

635631
/*

kernel/power/hibernate.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#define pr_fmt(fmt) "PM: hibernation: " fmt
1313

14+
#include <linux/blkdev.h>
1415
#include <linux/export.h>
1516
#include <linux/suspend.h>
1617
#include <linux/reboot.h>
@@ -921,8 +922,7 @@ static int __init find_resume_device(void)
921922
}
922923

923924
/* Check if the device is there */
924-
swsusp_resume_device = name_to_dev_t(resume_file);
925-
if (swsusp_resume_device)
925+
if (!early_lookup_bdev(resume_file, &swsusp_resume_device))
926926
return 0;
927927

928928
/*
@@ -931,15 +931,12 @@ static int __init find_resume_device(void)
931931
*/
932932
wait_for_device_probe();
933933
if (resume_wait) {
934-
while (!(swsusp_resume_device = name_to_dev_t(resume_file)))
934+
while (early_lookup_bdev(resume_file, &swsusp_resume_device))
935935
msleep(10);
936936
async_synchronize_full();
937937
}
938938

939-
swsusp_resume_device = name_to_dev_t(resume_file);
940-
if (!swsusp_resume_device)
941-
return -ENODEV;
942-
return 0;
939+
return early_lookup_bdev(resume_file, &swsusp_resume_device);
943940
}
944941

945942
static int software_resume(void)
@@ -1169,7 +1166,8 @@ static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr,
11691166
unsigned int sleep_flags;
11701167
int len = n;
11711168
char *name;
1172-
dev_t res;
1169+
dev_t dev;
1170+
int error;
11731171

11741172
if (!hibernation_available())
11751173
return 0;
@@ -1180,13 +1178,13 @@ static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr,
11801178
if (!name)
11811179
return -ENOMEM;
11821180

1183-
res = name_to_dev_t(name);
1181+
error = early_lookup_bdev(name, &dev);
11841182
kfree(name);
1185-
if (!res)
1186-
return -EINVAL;
1183+
if (error)
1184+
return error;
11871185

11881186
sleep_flags = lock_system_sleep();
1189-
swsusp_resume_device = res;
1187+
swsusp_resume_device = dev;
11901188
unlock_system_sleep(sleep_flags);
11911189

11921190
pm_pr_dbg("Configured hibernation resume from disk to %u\n",

0 commit comments

Comments
 (0)