Whamcloud - gitweb
LU-12455 osd: Correct readcache_max_filesize proc 66/35266/5
authorPatrick Farrell <pfarrell@whamcloud.com>
Fri, 21 Jun 2019 16:44:14 +0000 (12:44 -0400)
committerOleg Drokin <green@whamcloud.com>
Tue, 27 Aug 2019 02:21:34 +0000 (02:21 +0000)
Readcache max file size is displayed as unsigned, but
parsed as signed.  This causes confusion when users try to
set it back to the default, which is 2^64-1 (or -1), and
they can't use 2^64-1.

Easy enough to add an unsigned parser and use it instead.

Signed-off-by: Patrick Farrell <pfarrell@whamcloud.com>
Change-Id: I15f5677c61f4f12a8448a665c5d52a8c94d062f3
Reviewed-on: https://review.whamcloud.com/35266
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Ann Koehler <amk@cray.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/lprocfs_status.h
lustre/obdclass/lprocfs_status.c
lustre/osd-ldiskfs/osd_lproc.c
lustre/osd-zfs/osd_lproc.c

index f878c00..98a2b1a 100644 (file)
@@ -618,6 +618,10 @@ extern int lprocfs_str_with_units_to_s64(const char __user *buffer,
                                         unsigned long count, __s64 *val,
                                         char defunit);
 
+extern int lprocfs_str_with_units_to_u64(const char __user *buffer,
+                                        unsigned long count, __u64 *val,
+                                        char defunit);
+
 char *lprocfs_strnstr(const char *s1, const char *s2, size_t len);
 char *lprocfs_find_named_value(const char *buffer, const char *name,
                                size_t *count);
index 2035fb7..12ade8a 100644 (file)
@@ -2024,6 +2024,29 @@ static int str_to_s64_internal(const char __user *buffer, unsigned long count,
        return 0;
 }
 
+/* identical to s64 version, but does not handle overflow */
+static int str_to_u64_internal(const char __user *buffer, unsigned long count,
+                              __u64 *val, __u64 def_mult, bool allow_units)
+{
+       char kernbuf[22];
+       unsigned int offset = 0;
+       int rc = 0;
+
+       if (count > (sizeof(kernbuf) - 1))
+               return -EINVAL;
+
+       if (copy_from_user(kernbuf, buffer, count))
+               return -EFAULT;
+
+       kernbuf[count] = '\0';
+
+       rc = str_to_u64_parse(kernbuf + offset, count - offset,
+                             val, def_mult, allow_units);
+       if (rc)
+               return rc;
+
+       return 0;
+}
 /**
  * Convert a user string into a signed 64 bit number. This function produces
  * an error when the value parsed from the string times multiplier underflows or
@@ -2057,6 +2080,23 @@ int lprocfs_str_with_units_to_s64(const char __user *buffer,
 }
 EXPORT_SYMBOL(lprocfs_str_with_units_to_s64);
 
+/* identical to s64 version above, but does not handle overflow */
+int lprocfs_str_with_units_to_u64(const char __user *buffer,
+                                 unsigned long count, __u64 *val, char defunit)
+{
+       __u64 mult = 1;
+       int rc;
+
+       if (defunit != '1') {
+               rc = get_mult(defunit, &mult);
+               if (rc)
+                       return rc;
+       }
+
+       return str_to_u64_internal(buffer, count, val, mult, true);
+}
+EXPORT_SYMBOL(lprocfs_str_with_units_to_u64);
+
 char *lprocfs_strnstr(const char *s1, const char *s2, size_t len)
 {
        size_t l2;
index 02cf972..cba3a82 100644 (file)
@@ -561,18 +561,16 @@ ldiskfs_osd_readcache_seq_write(struct file *file, const char __user *buffer,
        struct seq_file *m = file->private_data;
        struct dt_device *dt = m->private;
        struct osd_device *osd = osd_dt_dev(dt);
-       s64 val;
+       u64 val;
        int rc;
 
        LASSERT(osd != NULL);
        if (unlikely(osd->od_mnt == NULL))
                return -EINPROGRESS;
 
-       rc = lprocfs_str_with_units_to_s64(buffer, count, &val, '1');
+       rc = lprocfs_str_with_units_to_u64(buffer, count, &val, '1');
        if (rc)
                return rc;
-       if (val < 0)
-               return -ERANGE;
 
        osd->od_readcache_max_filesize = val > OSD_MAX_CACHE_SIZE ?
                                         OSD_MAX_CACHE_SIZE : val;
index e84ed46..a1becc1 100644 (file)
@@ -387,18 +387,16 @@ zfs_osd_readcache_seq_write(struct file *file, const char __user *buffer,
        struct seq_file *m = file->private_data;
        struct dt_device *dt = m->private;
        struct osd_device *osd = osd_dt_dev(dt);
-       s64 val;
+       u64 val;
        int rc;
 
        LASSERT(osd != NULL);
        if (unlikely(osd->od_os == NULL))
                return -EINPROGRESS;
 
-       rc = lprocfs_str_with_units_to_s64(buffer, count, &val, '1');
+       rc = lprocfs_str_with_units_to_u64(buffer, count, &val, '1');
        if (rc)
                return rc;
-       if (val < 0)
-               return -ERANGE;
 
        osd->od_readcache_max_filesize = val > OSD_MAX_CACHE_SIZE ?
                                         OSD_MAX_CACHE_SIZE : val;