diff options
Diffstat (limited to 'block/blk-cgroup.c')
-rw-r--r-- | block/blk-cgroup.c | 111 |
1 files changed, 64 insertions, 47 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index b596e54ddd71..8f630cec906e 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c | |||
@@ -768,25 +768,14 @@ static uint64_t blkio_get_stat(struct blkio_group *blkg, | |||
768 | return disk_total; | 768 | return disk_total; |
769 | } | 769 | } |
770 | 770 | ||
771 | static int blkio_check_dev_num(dev_t dev) | ||
772 | { | ||
773 | int part = 0; | ||
774 | struct gendisk *disk; | ||
775 | |||
776 | disk = get_gendisk(dev, &part); | ||
777 | if (!disk || part) | ||
778 | return -ENODEV; | ||
779 | |||
780 | return 0; | ||
781 | } | ||
782 | |||
783 | static int blkio_policy_parse_and_set(char *buf, | 771 | static int blkio_policy_parse_and_set(char *buf, |
784 | struct blkio_policy_node *newpn, enum blkio_policy_id plid, int fileid) | 772 | struct blkio_policy_node *newpn, enum blkio_policy_id plid, int fileid) |
785 | { | 773 | { |
774 | struct gendisk *disk = NULL; | ||
786 | char *s[4], *p, *major_s = NULL, *minor_s = NULL; | 775 | char *s[4], *p, *major_s = NULL, *minor_s = NULL; |
787 | int ret; | ||
788 | unsigned long major, minor; | 776 | unsigned long major, minor; |
789 | int i = 0; | 777 | int i = 0, ret = -EINVAL; |
778 | int part; | ||
790 | dev_t dev; | 779 | dev_t dev; |
791 | u64 temp; | 780 | u64 temp; |
792 | 781 | ||
@@ -804,37 +793,36 @@ static int blkio_policy_parse_and_set(char *buf, | |||
804 | } | 793 | } |
805 | 794 | ||
806 | if (i != 2) | 795 | if (i != 2) |
807 | return -EINVAL; | 796 | goto out; |
808 | 797 | ||
809 | p = strsep(&s[0], ":"); | 798 | p = strsep(&s[0], ":"); |
810 | if (p != NULL) | 799 | if (p != NULL) |
811 | major_s = p; | 800 | major_s = p; |
812 | else | 801 | else |
813 | return -EINVAL; | 802 | goto out; |
814 | 803 | ||
815 | minor_s = s[0]; | 804 | minor_s = s[0]; |
816 | if (!minor_s) | 805 | if (!minor_s) |
817 | return -EINVAL; | 806 | goto out; |
818 | 807 | ||
819 | ret = strict_strtoul(major_s, 10, &major); | 808 | if (strict_strtoul(major_s, 10, &major)) |
820 | if (ret) | 809 | goto out; |
821 | return -EINVAL; | ||
822 | 810 | ||
823 | ret = strict_strtoul(minor_s, 10, &minor); | 811 | if (strict_strtoul(minor_s, 10, &minor)) |
824 | if (ret) | 812 | goto out; |
825 | return -EINVAL; | ||
826 | 813 | ||
827 | dev = MKDEV(major, minor); | 814 | dev = MKDEV(major, minor); |
828 | 815 | ||
829 | ret = strict_strtoull(s[1], 10, &temp); | 816 | if (strict_strtoull(s[1], 10, &temp)) |
830 | if (ret) | 817 | goto out; |
831 | return -EINVAL; | ||
832 | 818 | ||
833 | /* For rule removal, do not check for device presence. */ | 819 | /* For rule removal, do not check for device presence. */ |
834 | if (temp) { | 820 | if (temp) { |
835 | ret = blkio_check_dev_num(dev); | 821 | disk = get_gendisk(dev, &part); |
836 | if (ret) | 822 | if (!disk || part) { |
837 | return ret; | 823 | ret = -ENODEV; |
824 | goto out; | ||
825 | } | ||
838 | } | 826 | } |
839 | 827 | ||
840 | newpn->dev = dev; | 828 | newpn->dev = dev; |
@@ -843,7 +831,7 @@ static int blkio_policy_parse_and_set(char *buf, | |||
843 | case BLKIO_POLICY_PROP: | 831 | case BLKIO_POLICY_PROP: |
844 | if ((temp < BLKIO_WEIGHT_MIN && temp > 0) || | 832 | if ((temp < BLKIO_WEIGHT_MIN && temp > 0) || |
845 | temp > BLKIO_WEIGHT_MAX) | 833 | temp > BLKIO_WEIGHT_MAX) |
846 | return -EINVAL; | 834 | goto out; |
847 | 835 | ||
848 | newpn->plid = plid; | 836 | newpn->plid = plid; |
849 | newpn->fileid = fileid; | 837 | newpn->fileid = fileid; |
@@ -860,7 +848,7 @@ static int blkio_policy_parse_and_set(char *buf, | |||
860 | case BLKIO_THROTL_read_iops_device: | 848 | case BLKIO_THROTL_read_iops_device: |
861 | case BLKIO_THROTL_write_iops_device: | 849 | case BLKIO_THROTL_write_iops_device: |
862 | if (temp > THROTL_IOPS_MAX) | 850 | if (temp > THROTL_IOPS_MAX) |
863 | return -EINVAL; | 851 | goto out; |
864 | 852 | ||
865 | newpn->plid = plid; | 853 | newpn->plid = plid; |
866 | newpn->fileid = fileid; | 854 | newpn->fileid = fileid; |
@@ -871,68 +859,96 @@ static int blkio_policy_parse_and_set(char *buf, | |||
871 | default: | 859 | default: |
872 | BUG(); | 860 | BUG(); |
873 | } | 861 | } |
874 | 862 | ret = 0; | |
875 | return 0; | 863 | out: |
864 | put_disk(disk); | ||
865 | return ret; | ||
876 | } | 866 | } |
877 | 867 | ||
878 | unsigned int blkcg_get_weight(struct blkio_cgroup *blkcg, | 868 | unsigned int blkcg_get_weight(struct blkio_cgroup *blkcg, |
879 | dev_t dev) | 869 | dev_t dev) |
880 | { | 870 | { |
881 | struct blkio_policy_node *pn; | 871 | struct blkio_policy_node *pn; |
872 | unsigned long flags; | ||
873 | unsigned int weight; | ||
874 | |||
875 | spin_lock_irqsave(&blkcg->lock, flags); | ||
882 | 876 | ||
883 | pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_PROP, | 877 | pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_PROP, |
884 | BLKIO_PROP_weight_device); | 878 | BLKIO_PROP_weight_device); |
885 | if (pn) | 879 | if (pn) |
886 | return pn->val.weight; | 880 | weight = pn->val.weight; |
887 | else | 881 | else |
888 | return blkcg->weight; | 882 | weight = blkcg->weight; |
883 | |||
884 | spin_unlock_irqrestore(&blkcg->lock, flags); | ||
885 | |||
886 | return weight; | ||
889 | } | 887 | } |
890 | EXPORT_SYMBOL_GPL(blkcg_get_weight); | 888 | EXPORT_SYMBOL_GPL(blkcg_get_weight); |
891 | 889 | ||
892 | uint64_t blkcg_get_read_bps(struct blkio_cgroup *blkcg, dev_t dev) | 890 | uint64_t blkcg_get_read_bps(struct blkio_cgroup *blkcg, dev_t dev) |
893 | { | 891 | { |
894 | struct blkio_policy_node *pn; | 892 | struct blkio_policy_node *pn; |
893 | unsigned long flags; | ||
894 | uint64_t bps = -1; | ||
895 | 895 | ||
896 | spin_lock_irqsave(&blkcg->lock, flags); | ||
896 | pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL, | 897 | pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL, |
897 | BLKIO_THROTL_read_bps_device); | 898 | BLKIO_THROTL_read_bps_device); |
898 | if (pn) | 899 | if (pn) |
899 | return pn->val.bps; | 900 | bps = pn->val.bps; |
900 | else | 901 | spin_unlock_irqrestore(&blkcg->lock, flags); |
901 | return -1; | 902 | |
903 | return bps; | ||
902 | } | 904 | } |
903 | 905 | ||
904 | uint64_t blkcg_get_write_bps(struct blkio_cgroup *blkcg, dev_t dev) | 906 | uint64_t blkcg_get_write_bps(struct blkio_cgroup *blkcg, dev_t dev) |
905 | { | 907 | { |
906 | struct blkio_policy_node *pn; | 908 | struct blkio_policy_node *pn; |
909 | unsigned long flags; | ||
910 | uint64_t bps = -1; | ||
911 | |||
912 | spin_lock_irqsave(&blkcg->lock, flags); | ||
907 | pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL, | 913 | pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL, |
908 | BLKIO_THROTL_write_bps_device); | 914 | BLKIO_THROTL_write_bps_device); |
909 | if (pn) | 915 | if (pn) |
910 | return pn->val.bps; | 916 | bps = pn->val.bps; |
911 | else | 917 | spin_unlock_irqrestore(&blkcg->lock, flags); |
912 | return -1; | 918 | |
919 | return bps; | ||
913 | } | 920 | } |
914 | 921 | ||
915 | unsigned int blkcg_get_read_iops(struct blkio_cgroup *blkcg, dev_t dev) | 922 | unsigned int blkcg_get_read_iops(struct blkio_cgroup *blkcg, dev_t dev) |
916 | { | 923 | { |
917 | struct blkio_policy_node *pn; | 924 | struct blkio_policy_node *pn; |
925 | unsigned long flags; | ||
926 | unsigned int iops = -1; | ||
918 | 927 | ||
928 | spin_lock_irqsave(&blkcg->lock, flags); | ||
919 | pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL, | 929 | pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL, |
920 | BLKIO_THROTL_read_iops_device); | 930 | BLKIO_THROTL_read_iops_device); |
921 | if (pn) | 931 | if (pn) |
922 | return pn->val.iops; | 932 | iops = pn->val.iops; |
923 | else | 933 | spin_unlock_irqrestore(&blkcg->lock, flags); |
924 | return -1; | 934 | |
935 | return iops; | ||
925 | } | 936 | } |
926 | 937 | ||
927 | unsigned int blkcg_get_write_iops(struct blkio_cgroup *blkcg, dev_t dev) | 938 | unsigned int blkcg_get_write_iops(struct blkio_cgroup *blkcg, dev_t dev) |
928 | { | 939 | { |
929 | struct blkio_policy_node *pn; | 940 | struct blkio_policy_node *pn; |
941 | unsigned long flags; | ||
942 | unsigned int iops = -1; | ||
943 | |||
944 | spin_lock_irqsave(&blkcg->lock, flags); | ||
930 | pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL, | 945 | pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL, |
931 | BLKIO_THROTL_write_iops_device); | 946 | BLKIO_THROTL_write_iops_device); |
932 | if (pn) | 947 | if (pn) |
933 | return pn->val.iops; | 948 | iops = pn->val.iops; |
934 | else | 949 | spin_unlock_irqrestore(&blkcg->lock, flags); |
935 | return -1; | 950 | |
951 | return iops; | ||
936 | } | 952 | } |
937 | 953 | ||
938 | /* Checks whether user asked for deleting a policy rule */ | 954 | /* Checks whether user asked for deleting a policy rule */ |
@@ -1085,6 +1101,7 @@ static int blkiocg_file_write(struct cgroup *cgrp, struct cftype *cft, | |||
1085 | 1101 | ||
1086 | if (blkio_delete_rule_command(newpn)) { | 1102 | if (blkio_delete_rule_command(newpn)) { |
1087 | blkio_policy_delete_node(pn); | 1103 | blkio_policy_delete_node(pn); |
1104 | kfree(pn); | ||
1088 | spin_unlock_irq(&blkcg->lock); | 1105 | spin_unlock_irq(&blkcg->lock); |
1089 | goto update_io_group; | 1106 | goto update_io_group; |
1090 | } | 1107 | } |