pandora: reserve CMA area for c64_tools
[pandora-kernel.git] / block / blk-cgroup.c
index b596e54..8f630ce 100644 (file)
@@ -768,25 +768,14 @@ static uint64_t blkio_get_stat(struct blkio_group *blkg,
        return disk_total;
 }
 
-static int blkio_check_dev_num(dev_t dev)
-{
-       int part = 0;
-       struct gendisk *disk;
-
-       disk = get_gendisk(dev, &part);
-       if (!disk || part)
-               return -ENODEV;
-
-       return 0;
-}
-
 static int blkio_policy_parse_and_set(char *buf,
        struct blkio_policy_node *newpn, enum blkio_policy_id plid, int fileid)
 {
+       struct gendisk *disk = NULL;
        char *s[4], *p, *major_s = NULL, *minor_s = NULL;
-       int ret;
        unsigned long major, minor;
-       int i = 0;
+       int i = 0, ret = -EINVAL;
+       int part;
        dev_t dev;
        u64 temp;
 
@@ -804,37 +793,36 @@ static int blkio_policy_parse_and_set(char *buf,
        }
 
        if (i != 2)
-               return -EINVAL;
+               goto out;
 
        p = strsep(&s[0], ":");
        if (p != NULL)
                major_s = p;
        else
-               return -EINVAL;
+               goto out;
 
        minor_s = s[0];
        if (!minor_s)
-               return -EINVAL;
+               goto out;
 
-       ret = strict_strtoul(major_s, 10, &major);
-       if (ret)
-               return -EINVAL;
+       if (strict_strtoul(major_s, 10, &major))
+               goto out;
 
-       ret = strict_strtoul(minor_s, 10, &minor);
-       if (ret)
-               return -EINVAL;
+       if (strict_strtoul(minor_s, 10, &minor))
+               goto out;
 
        dev = MKDEV(major, minor);
 
-       ret = strict_strtoull(s[1], 10, &temp);
-       if (ret)
-               return -EINVAL;
+       if (strict_strtoull(s[1], 10, &temp))
+               goto out;
 
        /* For rule removal, do not check for device presence. */
        if (temp) {
-               ret = blkio_check_dev_num(dev);
-               if (ret)
-                       return ret;
+               disk = get_gendisk(dev, &part);
+               if (!disk || part) {
+                       ret = -ENODEV;
+                       goto out;
+               }
        }
 
        newpn->dev = dev;
@@ -843,7 +831,7 @@ static int blkio_policy_parse_and_set(char *buf,
        case BLKIO_POLICY_PROP:
                if ((temp < BLKIO_WEIGHT_MIN && temp > 0) ||
                     temp > BLKIO_WEIGHT_MAX)
-                       return -EINVAL;
+                       goto out;
 
                newpn->plid = plid;
                newpn->fileid = fileid;
@@ -860,7 +848,7 @@ static int blkio_policy_parse_and_set(char *buf,
                case BLKIO_THROTL_read_iops_device:
                case BLKIO_THROTL_write_iops_device:
                        if (temp > THROTL_IOPS_MAX)
-                               return -EINVAL;
+                               goto out;
 
                        newpn->plid = plid;
                        newpn->fileid = fileid;
@@ -871,68 +859,96 @@ static int blkio_policy_parse_and_set(char *buf,
        default:
                BUG();
        }
-
-       return 0;
+       ret = 0;
+out:
+       put_disk(disk);
+       return ret;
 }
 
 unsigned int blkcg_get_weight(struct blkio_cgroup *blkcg,
                              dev_t dev)
 {
        struct blkio_policy_node *pn;
+       unsigned long flags;
+       unsigned int weight;
+
+       spin_lock_irqsave(&blkcg->lock, flags);
 
        pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_PROP,
                                BLKIO_PROP_weight_device);
        if (pn)
-               return pn->val.weight;
+               weight = pn->val.weight;
        else
-               return blkcg->weight;
+               weight = blkcg->weight;
+
+       spin_unlock_irqrestore(&blkcg->lock, flags);
+
+       return weight;
 }
 EXPORT_SYMBOL_GPL(blkcg_get_weight);
 
 uint64_t blkcg_get_read_bps(struct blkio_cgroup *blkcg, dev_t dev)
 {
        struct blkio_policy_node *pn;
+       unsigned long flags;
+       uint64_t bps = -1;
 
+       spin_lock_irqsave(&blkcg->lock, flags);
        pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL,
                                BLKIO_THROTL_read_bps_device);
        if (pn)
-               return pn->val.bps;
-       else
-               return -1;
+               bps = pn->val.bps;
+       spin_unlock_irqrestore(&blkcg->lock, flags);
+
+       return bps;
 }
 
 uint64_t blkcg_get_write_bps(struct blkio_cgroup *blkcg, dev_t dev)
 {
        struct blkio_policy_node *pn;
+       unsigned long flags;
+       uint64_t bps = -1;
+
+       spin_lock_irqsave(&blkcg->lock, flags);
        pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL,
                                BLKIO_THROTL_write_bps_device);
        if (pn)
-               return pn->val.bps;
-       else
-               return -1;
+               bps = pn->val.bps;
+       spin_unlock_irqrestore(&blkcg->lock, flags);
+
+       return bps;
 }
 
 unsigned int blkcg_get_read_iops(struct blkio_cgroup *blkcg, dev_t dev)
 {
        struct blkio_policy_node *pn;
+       unsigned long flags;
+       unsigned int iops = -1;
 
+       spin_lock_irqsave(&blkcg->lock, flags);
        pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL,
                                BLKIO_THROTL_read_iops_device);
        if (pn)
-               return pn->val.iops;
-       else
-               return -1;
+               iops = pn->val.iops;
+       spin_unlock_irqrestore(&blkcg->lock, flags);
+
+       return iops;
 }
 
 unsigned int blkcg_get_write_iops(struct blkio_cgroup *blkcg, dev_t dev)
 {
        struct blkio_policy_node *pn;
+       unsigned long flags;
+       unsigned int iops = -1;
+
+       spin_lock_irqsave(&blkcg->lock, flags);
        pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL,
                                BLKIO_THROTL_write_iops_device);
        if (pn)
-               return pn->val.iops;
-       else
-               return -1;
+               iops = pn->val.iops;
+       spin_unlock_irqrestore(&blkcg->lock, flags);
+
+       return iops;
 }
 
 /* Checks whether user asked for deleting a policy rule */
@@ -1085,6 +1101,7 @@ static int blkiocg_file_write(struct cgroup *cgrp, struct cftype *cft,
 
        if (blkio_delete_rule_command(newpn)) {
                blkio_policy_delete_node(pn);
+               kfree(pn);
                spin_unlock_irq(&blkcg->lock);
                goto update_io_group;
        }