diff options
Diffstat (limited to 'kernel/res_counter.c')
-rw-r--r-- | kernel/res_counter.c | 48 |
1 files changed, 21 insertions, 27 deletions
diff --git a/kernel/res_counter.c b/kernel/res_counter.c index d3c61b4ebef2..f275c8eca772 100644 --- a/kernel/res_counter.c +++ b/kernel/res_counter.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/res_counter.h> | 14 | #include <linux/res_counter.h> |
15 | #include <linux/uaccess.h> | 15 | #include <linux/uaccess.h> |
16 | #include <linux/mm.h> | ||
16 | 17 | ||
17 | void res_counter_init(struct res_counter *counter) | 18 | void res_counter_init(struct res_counter *counter) |
18 | { | 19 | { |
@@ -102,44 +103,37 @@ u64 res_counter_read_u64(struct res_counter *counter, int member) | |||
102 | return *res_counter_member(counter, member); | 103 | return *res_counter_member(counter, member); |
103 | } | 104 | } |
104 | 105 | ||
105 | ssize_t res_counter_write(struct res_counter *counter, int member, | 106 | int res_counter_memparse_write_strategy(const char *buf, |
106 | const char __user *userbuf, size_t nbytes, loff_t *pos, | 107 | unsigned long long *res) |
107 | int (*write_strategy)(char *st_buf, unsigned long long *val)) | ||
108 | { | 108 | { |
109 | int ret; | 109 | char *end; |
110 | char *buf, *end; | 110 | /* FIXME - make memparse() take const char* args */ |
111 | unsigned long flags; | 111 | *res = memparse((char *)buf, &end); |
112 | unsigned long long tmp, *val; | 112 | if (*end != '\0') |
113 | 113 | return -EINVAL; | |
114 | buf = kmalloc(nbytes + 1, GFP_KERNEL); | ||
115 | ret = -ENOMEM; | ||
116 | if (buf == NULL) | ||
117 | goto out; | ||
118 | 114 | ||
119 | buf[nbytes] = '\0'; | 115 | *res = PAGE_ALIGN(*res); |
120 | ret = -EFAULT; | 116 | return 0; |
121 | if (copy_from_user(buf, userbuf, nbytes)) | 117 | } |
122 | goto out_free; | ||
123 | 118 | ||
124 | ret = -EINVAL; | 119 | int res_counter_write(struct res_counter *counter, int member, |
120 | const char *buf, write_strategy_fn write_strategy) | ||
121 | { | ||
122 | char *end; | ||
123 | unsigned long flags; | ||
124 | unsigned long long tmp, *val; | ||
125 | 125 | ||
126 | strstrip(buf); | ||
127 | if (write_strategy) { | 126 | if (write_strategy) { |
128 | if (write_strategy(buf, &tmp)) { | 127 | if (write_strategy(buf, &tmp)) |
129 | goto out_free; | 128 | return -EINVAL; |
130 | } | ||
131 | } else { | 129 | } else { |
132 | tmp = simple_strtoull(buf, &end, 10); | 130 | tmp = simple_strtoull(buf, &end, 10); |
133 | if (*end != '\0') | 131 | if (*end != '\0') |
134 | goto out_free; | 132 | return -EINVAL; |
135 | } | 133 | } |
136 | spin_lock_irqsave(&counter->lock, flags); | 134 | spin_lock_irqsave(&counter->lock, flags); |
137 | val = res_counter_member(counter, member); | 135 | val = res_counter_member(counter, member); |
138 | *val = tmp; | 136 | *val = tmp; |
139 | spin_unlock_irqrestore(&counter->lock, flags); | 137 | spin_unlock_irqrestore(&counter->lock, flags); |
140 | ret = nbytes; | 138 | return 0; |
141 | out_free: | ||
142 | kfree(buf); | ||
143 | out: | ||
144 | return ret; | ||
145 | } | 139 | } |