Whamcloud - gitweb
LU-6174 obd: perform proper division
[fs/lustre-release.git] / lustre / obdclass / lprocfs_status.c
index 11fdc78..9d6c8c2 100644 (file)
@@ -988,12 +988,9 @@ int lprocfs_import_seq_show(struct seq_file *m, void *data)
 
        header = &obd->obd_svc_stats->ls_cnt_header[PTLRPC_REQWAIT_CNTR];
        lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret);
-       if (ret.lc_count != 0) {
-               /* first argument to do_div MUST be __u64 */
-               __u64 sum = ret.lc_sum;
-               do_div(sum, ret.lc_count);
-               ret.lc_sum = sum;
-       } else
+       if (ret.lc_count != 0)
+               ret.lc_sum = div64_s64(ret.lc_sum, ret.lc_count);
+       else
                ret.lc_sum = 0;
        seq_printf(m, "    rpcs:\n"
                   "       inflight: %u\n"
@@ -1032,10 +1029,7 @@ int lprocfs_import_seq_show(struct seq_file *m, void *data)
                                      PTLRPC_LAST_CNTR + BRW_READ_BYTES + rw,
                                      &ret);
                if (ret.lc_sum > 0 && ret.lc_count > 0) {
-                       /* first argument to do_div MUST be __u64 */
-                       __u64 sum = ret.lc_sum;
-                       do_div(sum, ret.lc_count);
-                       ret.lc_sum = sum;
+                       ret.lc_sum = div64_s64(ret.lc_sum, ret.lc_count);
                        seq_printf(m, "    %s_data_averages:\n"
                                   "       bytes_per_rpc: %llu\n",
                                   rw ? "write" : "read",
@@ -1046,10 +1040,7 @@ int lprocfs_import_seq_show(struct seq_file *m, void *data)
                header = &obd->obd_svc_stats->ls_cnt_header[j];
                lprocfs_stats_collect(obd->obd_svc_stats, j, &ret);
                if (ret.lc_sum > 0 && ret.lc_count != 0) {
-                       /* first argument to do_div MUST be __u64 */
-                       __u64 sum = ret.lc_sum;
-                       do_div(sum, ret.lc_count);
-                       ret.lc_sum = sum;
+                       ret.lc_sum = div64_s64(ret.lc_sum, ret.lc_count);
                        seq_printf(m, "       %s_per_rpc: %llu\n",
                                   header->lc_units, ret.lc_sum);
                        j = (int)ret.lc_sum;
@@ -1989,34 +1980,31 @@ static int str_to_u64_parse(char *buffer, unsigned long count,
  * have a unit as the last character. The function handles overflow/underflow
  * of the signed integer.
  */
-static int str_to_s64_internal(const char __user *buffer, unsigned long count,
-                              __s64 *val, __u64 def_mult, bool allow_units)
+int lu_str_to_s64(char *buffer, unsigned long count, __s64 *val, char defunit)
 {
-       char kernbuf[22];
+       __u64 mult = 1;
        __u64 tmp;
        unsigned int offset = 0;
        int signed sign = 1;
        __u64 max = LLONG_MAX;
        int rc = 0;
 
-       if (count > (sizeof(kernbuf) - 1))
-               return -EINVAL;
-
-       if (copy_from_user(kernbuf, buffer, count))
-               return -EFAULT;
-
-       kernbuf[count] = '\0';
+       if (defunit != '1') {
+               rc = get_mult(defunit, &mult);
+               if (rc)
+                       return rc;
+       }
 
        /* keep track of our sign */
-       if (*kernbuf == '-') {
+       if (*buffer == '-') {
                sign = -1;
                offset++;
                /* equivalent to max = -LLONG_MIN, avoids overflow */
                max++;
        }
 
-       rc = str_to_u64_parse(kernbuf + offset, count - offset,
-                             &tmp, def_mult, allow_units);
+       rc = str_to_u64_parse(buffer + offset, count - offset,
+                             &tmp, mult, true);
        if (rc)
                return rc;
 
@@ -2028,6 +2016,7 @@ static int str_to_s64_internal(const char __user *buffer, unsigned long count,
 
        return 0;
 }
+EXPORT_SYMBOL(lu_str_to_s64);
 
 /* identical to s64 version, but does not handle overflow */
 static int str_to_u64_internal(const char __user *buffer, unsigned long count,
@@ -2072,16 +2061,17 @@ static int str_to_u64_internal(const char __user *buffer, unsigned long count,
 int lprocfs_str_with_units_to_s64(const char __user *buffer,
                                  unsigned long count, __s64 *val, char defunit)
 {
-       __u64 mult = 1;
-       int rc;
+       char kernbuf[22];
 
-       if (defunit != '1') {
-               rc = get_mult(defunit, &mult);
-               if (rc)
-                       return rc;
-       }
+       if (count > (sizeof(kernbuf) - 1))
+               return -EINVAL;
+
+       if (copy_from_user(kernbuf, buffer, count))
+               return -EFAULT;
+
+       kernbuf[count] = '\0';
 
-       return str_to_s64_internal(buffer, count, val, mult, true);
+       return lu_str_to_s64(kernbuf, count, val, defunit);
 }
 EXPORT_SYMBOL(lprocfs_str_with_units_to_s64);
 
@@ -2339,25 +2329,31 @@ ssize_t short_io_bytes_store(struct kobject *kobj, struct attribute *attr,
        struct obd_device *dev = container_of(kobj, struct obd_device,
                                              obd_kset.kobj);
        struct client_obd *cli = &dev->u.cli;
-       u32 val;
+       char kernbuf[32];
+       s64 val;
        int rc;
 
+       if (count >= sizeof(kernbuf))
+               return -EINVAL;
+
        LPROCFS_CLIMP_CHECK(dev);
 
-       rc = kstrtouint(buffer, 0, &val);
+       memcpy(kernbuf, buffer, count);
+       kernbuf[count] = '\0';
+       rc = lu_str_to_s64(kernbuf, count, &val, '1');
        if (rc)
                GOTO(out, rc);
 
-       if (val && (val < MIN_SHORT_IO_BYTES || val > OBD_MAX_SHORT_IO_BYTES))
+       if (val == -1)
+               val = OBD_DEF_SHORT_IO_BYTES;
+
+       if (val && (val < MIN_SHORT_IO_BYTES || val > LNET_MTU))
                GOTO(out, rc = -ERANGE);
 
        rc = count;
 
        spin_lock(&cli->cl_loi_list_lock);
-       if (val > (cli->cl_max_pages_per_rpc << PAGE_SHIFT))
-               rc = -ERANGE;
-       else
-               cli->cl_max_short_io_bytes = val;
+       cli->cl_max_short_io_bytes = min_t(u64, val, OST_MAX_SHORT_IO_BYTES);
        spin_unlock(&cli->cl_loi_list_lock);
 
 out: