Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d11bb446 authored by Wanlong Gao's avatar Wanlong Gao Committed by Jens Axboe
Browse files

blk-cgroup: be able to remove the record of unplugged device



The bug is we're not able to remove the device from blkio cgroup's
per-device control files if it gets unplugged.

To reproduce the bug:

  # mount -t cgroup -o blkio xxx /cgroup
  # cd /cgroup
  # echo "8:0 1000" > blkio.throttle.read_bps_device
  # unplug the device
  # cat blkio.throttle.read_bps_device
  8:0	1000
  # echo "8:0 0" > blkio.throttle.read_bps_device
  -bash: echo: write error: No such device

After patching, the device removal will succeed.

Thanks for the comments of Paul, Zefan, and Vivek.

Signed-off-by: default avatarWanlong Gao <gaowanlong@cn.fujitsu.com>
Cc: Li Zefan <lizf@cn.fujitsu.com>
Cc: Paul Menage <paul@paulmenage.org>
Acked-by: default avatarVivek Goyal <vgoyal@redhat.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: <stable@kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 8ad6a56f
Loading
Loading
Loading
Loading
+16 −21
Original line number Original line Diff line number Diff line
@@ -785,10 +785,10 @@ static int blkio_policy_parse_and_set(char *buf,
{
{
	char *s[4], *p, *major_s = NULL, *minor_s = NULL;
	char *s[4], *p, *major_s = NULL, *minor_s = NULL;
	int ret;
	int ret;
	unsigned long major, minor, temp;
	unsigned long major, minor;
	int i = 0;
	int i = 0;
	dev_t dev;
	dev_t dev;
	u64 bps, iops;
	u64 temp;


	memset(s, 0, sizeof(s));
	memset(s, 0, sizeof(s));


@@ -826,19 +826,22 @@ static int blkio_policy_parse_and_set(char *buf,


	dev = MKDEV(major, minor);
	dev = MKDEV(major, minor);


	ret = strict_strtoull(s[1], 10, &temp);
	if (ret)
		return -EINVAL;

	/* For rule removal, do not check for device presence. */
	if (temp) {
		ret = blkio_check_dev_num(dev);
		ret = blkio_check_dev_num(dev);
		if (ret)
		if (ret)
			return ret;
			return ret;
	}


	newpn->dev = dev;
	newpn->dev = dev;


	if (s[1] == NULL)
		return -EINVAL;

	switch (plid) {
	switch (plid) {
	case BLKIO_POLICY_PROP:
	case BLKIO_POLICY_PROP:
		ret = strict_strtoul(s[1], 10, &temp);
		if ((temp < BLKIO_WEIGHT_MIN && temp > 0) ||
		if (ret || (temp < BLKIO_WEIGHT_MIN && temp > 0) ||
		     temp > BLKIO_WEIGHT_MAX)
		     temp > BLKIO_WEIGHT_MAX)
			return -EINVAL;
			return -EINVAL;


@@ -850,26 +853,18 @@ static int blkio_policy_parse_and_set(char *buf,
		switch(fileid) {
		switch(fileid) {
		case BLKIO_THROTL_read_bps_device:
		case BLKIO_THROTL_read_bps_device:
		case BLKIO_THROTL_write_bps_device:
		case BLKIO_THROTL_write_bps_device:
			ret = strict_strtoull(s[1], 10, &bps);
			if (ret)
				return -EINVAL;

			newpn->plid = plid;
			newpn->plid = plid;
			newpn->fileid = fileid;
			newpn->fileid = fileid;
			newpn->val.bps = bps;
			newpn->val.bps = temp;
			break;
			break;
		case BLKIO_THROTL_read_iops_device:
		case BLKIO_THROTL_read_iops_device:
		case BLKIO_THROTL_write_iops_device:
		case BLKIO_THROTL_write_iops_device:
			ret = strict_strtoull(s[1], 10, &iops);
			if (temp > THROTL_IOPS_MAX)
			if (ret)
				return -EINVAL;

			if (iops > THROTL_IOPS_MAX)
				return -EINVAL;
				return -EINVAL;


			newpn->plid = plid;
			newpn->plid = plid;
			newpn->fileid = fileid;
			newpn->fileid = fileid;
			newpn->val.iops = (unsigned int)iops;
			newpn->val.iops = (unsigned int)temp;
			break;
			break;
		}
		}
		break;
		break;