diff options
Diffstat (limited to 'init')
| -rw-r--r-- | init/Kconfig | 9 | ||||
| -rw-r--r-- | init/do_mounts.c | 70 | 
2 files changed, 76 insertions, 3 deletions
diff --git a/init/Kconfig b/init/Kconfig index be85a0ab1b82..bd125a795374 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -661,11 +661,14 @@ config BLK_CGROUP  	Currently, CFQ IO scheduler uses it to recognize task groups and  	control disk bandwidth allocation (proportional time slice allocation) -	to such task groups. +	to such task groups. It is also used by bio throttling logic in +	block layer to implement upper limit in IO rates on a device.  	This option only enables generic Block IO controller infrastructure. -	One needs to also enable actual IO controlling logic in CFQ for it -	to take effect. (CONFIG_CFQ_GROUP_IOSCHED=y). +	One needs to also enable actual IO controlling logic/policy. For +	enabling proportional weight division of disk bandwidth in CFQ seti +	CONFIG_CFQ_GROUP_IOSCHED=y and for enabling throttling policy set +	CONFIG_BLK_THROTTLE=y.  	See Documentation/cgroups/blkio-controller.txt for more information. diff --git a/init/do_mounts.c b/init/do_mounts.c index 02e3ca4fc527..42db0551c3aa 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -58,6 +58,62 @@ static int __init readwrite(char *str)  __setup("ro", readonly);  __setup("rw", readwrite); +#ifdef CONFIG_BLOCK +/** + * match_dev_by_uuid - callback for finding a partition using its uuid + * @dev:	device passed in by the caller + * @data:	opaque pointer to a 36 byte char array with a UUID + * + * Returns 1 if the device matches, and 0 otherwise. + */ +static int match_dev_by_uuid(struct device *dev, void *data) +{ +	u8 *uuid = data; +	struct hd_struct *part = dev_to_part(dev); + +	if (!part->info) +		goto no_match; + +	if (memcmp(uuid, part->info->uuid, sizeof(part->info->uuid))) +			goto no_match; + +	return 1; +no_match: +	return 0; +} + + +/** + * devt_from_partuuid - looks up the dev_t of a partition by its UUID + * @uuid:	36 byte char array containing a hex ascii UUID + * + * The function will return the first partition which contains a matching + * UUID value in its partition_meta_info struct.  This does not search + * by filesystem UUIDs. + * + * Returns the matching dev_t on success or 0 on failure. + */ +static dev_t __init devt_from_partuuid(char *uuid_str) +{ +	dev_t res = 0; +	struct device *dev = NULL; +	u8 uuid[16]; + +	/* Pack the requested UUID in the expected format. */ +	part_pack_uuid(uuid_str, uuid); + +	dev = class_find_device(&block_class, NULL, uuid, &match_dev_by_uuid); +	if (!dev) +		goto done; + +	res = dev->devt; +	put_device(dev); + +done: +	return res; +} +#endif +  /*   *	Convert a name into device number.  We accept the following variants:   * @@ -68,6 +124,8 @@ __setup("rw", readwrite);   *         of partition - device number of disk plus the partition number   *	5) /dev/<disk_name>p<decimal> - same as the above, that form is   *	   used when disk name of partitioned disk ends on a digit. + *	6) PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF representing the + *	   unique id of a partition if the partition table provides it.   *   *	If name doesn't have fall into the categories above, we return (0,0).   *	block_class is used to check if something is a disk name. If the disk @@ -82,6 +140,18 @@ dev_t name_to_dev_t(char *name)  	dev_t res = 0;  	int part; +#ifdef CONFIG_BLOCK +	if (strncmp(name, "PARTUUID=", 9) == 0) { +		name += 9; +		if (strlen(name) != 36) +			goto fail; +		res = devt_from_partuuid(name); +		if (!res) +			goto fail; +		goto done; +	} +#endif +  	if (strncmp(name, "/dev/", 5) != 0) {  		unsigned maj, min;  |