size_t size, loff_t *loff)
{
struct xt_quota_counter *e = PDE_DATA(file_inode(file));
- char buf[sizeof("18446744073709551616")];
+ char buf[sizeof("+-18446744073709551616")];
if (size > sizeof(buf))
size = sizeof(buf);
if (size < sizeof(buf))
buf[size] = '\0';
- spin_lock_bh(&e->lock);
- e->quota = simple_strtoull(buf, NULL, 0);
- spin_unlock_bh(&e->lock);
+ if (*buf == '+') {
+ int64_t temp = simple_strtoll(buf + 1, NULL, 0);
+ spin_lock_bh(&e->lock);
+ /* Do not let quota become negative if @tmp is very negative */
+ if (temp > 0 || -temp < e->quota)
+ e->quota += temp;
+ else
+ e->quota = 0;
+ spin_unlock_bh(&e->lock);
+ } else if (*buf == '-') {
+ int64_t temp = simple_strtoll(buf + 1, NULL, 0);
+ spin_lock_bh(&e->lock);
+ /* Do not let quota become negative if @tmp is very big */
+ if (temp < 0 || temp < e->quota)
+ e->quota -= temp;
+ else
+ e->quota = 0;
+ spin_unlock_bh(&e->lock);
+ } else {
+ spin_lock_bh(&e->lock);
+ e->quota = simple_strtoull(buf, NULL, 0);
+ spin_unlock_bh(&e->lock);
+ }
return size;
}