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

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
...@@ -785,10 +785,10 @@ static int blkio_policy_parse_and_set(char *buf, ...@@ -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,20 +826,23 @@ static int blkio_policy_parse_and_set(char *buf, ...@@ -826,20 +826,23 @@ static int blkio_policy_parse_and_set(char *buf,
dev = MKDEV(major, minor); dev = MKDEV(major, minor);
ret = blkio_check_dev_num(dev); ret = strict_strtoull(s[1], 10, &temp);
if (ret) if (ret)
return ret; return -EINVAL;
newpn->dev = dev; /* For rule removal, do not check for device presence. */
if (temp) {
ret = blkio_check_dev_num(dev);
if (ret)
return ret;
}
if (s[1] == NULL) newpn->dev = dev;
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;
newpn->plid = plid; newpn->plid = plid;
...@@ -850,26 +853,18 @@ static int blkio_policy_parse_and_set(char *buf, ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment