scsi: megaraid_sas: Print FW fault information
[linux-2.6-microblaze.git] / kernel / sysctl.c
index ba158f6..943c891 100644 (file)
@@ -2886,8 +2886,10 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int
                        if (neg)
                                continue;
                        val = convmul * val / convdiv;
-                       if ((min && val < *min) || (max && val > *max))
-                               continue;
+                       if ((min && val < *min) || (max && val > *max)) {
+                               err = -EINVAL;
+                               break;
+                       }
                        *i = val;
                } else {
                        val = convdiv * (*i) / convmul;
@@ -3170,17 +3172,19 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
 
        if (write) {
                char *kbuf, *p;
+               size_t skipped = 0;
 
-               if (left > PAGE_SIZE - 1)
+               if (left > PAGE_SIZE - 1) {
                        left = PAGE_SIZE - 1;
+                       /* How much of the buffer we'll skip this pass */
+                       skipped = *lenp - left;
+               }
 
                p = kbuf = memdup_user_nul(buffer, left);
                if (IS_ERR(kbuf))
                        return PTR_ERR(kbuf);
 
-               tmp_bitmap = kcalloc(BITS_TO_LONGS(bitmap_len),
-                                    sizeof(unsigned long),
-                                    GFP_KERNEL);
+               tmp_bitmap = bitmap_zalloc(bitmap_len, GFP_KERNEL);
                if (!tmp_bitmap) {
                        kfree(kbuf);
                        return -ENOMEM;
@@ -3189,9 +3193,22 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
                while (!err && left) {
                        unsigned long val_a, val_b;
                        bool neg;
+                       size_t saved_left;
 
+                       /* In case we stop parsing mid-number, we can reset */
+                       saved_left = left;
                        err = proc_get_long(&p, &left, &val_a, &neg, tr_a,
                                             sizeof(tr_a), &c);
+                       /*
+                        * If we consumed the entirety of a truncated buffer or
+                        * only one char is left (may be a "-"), then stop here,
+                        * reset, & come back for more.
+                        */
+                       if ((left <= 1) && skipped) {
+                               left = saved_left;
+                               break;
+                       }
+
                        if (err)
                                break;
                        if (val_a >= bitmap_len || neg) {
@@ -3209,6 +3226,15 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
                                err = proc_get_long(&p, &left, &val_b,
                                                     &neg, tr_b, sizeof(tr_b),
                                                     &c);
+                               /*
+                                * If we consumed all of a truncated buffer or
+                                * then stop here, reset, & come back for more.
+                                */
+                               if (!left && skipped) {
+                                       left = saved_left;
+                                       break;
+                               }
+
                                if (err)
                                        break;
                                if (val_b >= bitmap_len || neg ||
@@ -3227,6 +3253,7 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
                        proc_skip_char(&p, &left, '\n');
                }
                kfree(kbuf);
+               left += skipped;
        } else {
                unsigned long bit_a, bit_b = 0;
 
@@ -3271,7 +3298,7 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
                *ppos += *lenp;
        }
 
-       kfree(tmp_bitmap);
+       bitmap_free(tmp_bitmap);
        return err;
 }