Whamcloud - gitweb
LU-6421 osc: fix bug when setting max_pages_per_rpc
[fs/lustre-release.git] / lustre / osc / lproc_osc.c
index 1dae975..73ec748 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2013, Intel Corporation.
+ * Copyright (c) 2011, 2014, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -43,7 +43,7 @@
 #include <linux/seq_file.h>
 #include "osc_internal.h"
 
-#ifdef LPROCFS
+#ifdef CONFIG_PROC_FS
 static int osc_active_seq_show(struct seq_file *m, void *v)
 {
        struct obd_device *dev = m->private;
@@ -55,7 +55,8 @@ static int osc_active_seq_show(struct seq_file *m, void *v)
        return rc;
 }
 
-static ssize_t osc_active_seq_write(struct file *file, const char *buffer,
+static ssize_t osc_active_seq_write(struct file *file,
+                                   const char __user *buffer,
                                    size_t count, loff_t *off)
 {
        struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
@@ -83,14 +84,14 @@ static int osc_max_rpcs_in_flight_seq_show(struct seq_file *m, void *v)
        struct client_obd *cli = &dev->u.cli;
        int rc;
 
-       client_obd_list_lock(&cli->cl_loi_list_lock);
+       spin_lock(&cli->cl_loi_list_lock);
        rc = seq_printf(m, "%u\n", cli->cl_max_rpcs_in_flight);
-       client_obd_list_unlock(&cli->cl_loi_list_lock);
+       spin_unlock(&cli->cl_loi_list_lock);
        return rc;
 }
 
 static ssize_t osc_max_rpcs_in_flight_seq_write(struct file *file,
-                                               const char *buffer,
+                                               const char __user *buffer,
                                                size_t count, loff_t *off)
 {
        struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
@@ -109,13 +110,13 @@ static ssize_t osc_max_rpcs_in_flight_seq_write(struct file *file,
         if (pool && val > cli->cl_max_rpcs_in_flight)
                 pool->prp_populate(pool, val-cli->cl_max_rpcs_in_flight);
 
-        client_obd_list_lock(&cli->cl_loi_list_lock);
-        cli->cl_max_rpcs_in_flight = val;
+       spin_lock(&cli->cl_loi_list_lock);
+       cli->cl_max_rpcs_in_flight = val;
        client_adjust_max_dirty(cli);
-        client_obd_list_unlock(&cli->cl_loi_list_lock);
+       spin_unlock(&cli->cl_loi_list_lock);
 
-        LPROCFS_CLIMP_EXIT(dev);
-        return count;
+       LPROCFS_CLIMP_EXIT(dev);
+       return count;
 }
 LPROC_SEQ_FOPS(osc_max_rpcs_in_flight);
 
@@ -126,15 +127,16 @@ static int osc_max_dirty_mb_seq_show(struct seq_file *m, void *v)
         long val;
         int mult;
 
-        client_obd_list_lock(&cli->cl_loi_list_lock);
-        val = cli->cl_dirty_max;
-        client_obd_list_unlock(&cli->cl_loi_list_lock);
+       spin_lock(&cli->cl_loi_list_lock);
+       val = cli->cl_dirty_max_pages;
+       spin_unlock(&cli->cl_loi_list_lock);
 
-       mult = 1 << 20;
+       mult = 1 << (20 - PAGE_CACHE_SHIFT);
        return lprocfs_seq_read_frac_helper(m, val, mult);
 }
 
-static ssize_t osc_max_dirty_mb_seq_write(struct file *file, const char *buffer,
+static ssize_t osc_max_dirty_mb_seq_write(struct file *file,
+                                         const char __user *buffer,
                                          size_t count, loff_t *off)
 {
        struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
@@ -151,10 +153,10 @@ static ssize_t osc_max_dirty_mb_seq_write(struct file *file, const char *buffer,
            pages_number > totalram_pages / 4) /* 1/4 of RAM */
                return -ERANGE;
 
-       client_obd_list_lock(&cli->cl_loi_list_lock);
-       cli->cl_dirty_max = (obd_count)(pages_number << PAGE_CACHE_SHIFT);
+       spin_lock(&cli->cl_loi_list_lock);
+       cli->cl_dirty_max_pages = pages_number;
        osc_wake_cache_waiters(cli);
-       client_obd_list_unlock(&cli->cl_loi_list_lock);
+       spin_unlock(&cli->cl_loi_list_lock);
 
        return count;
 }
@@ -168,11 +170,11 @@ static int osc_cached_mb_seq_show(struct seq_file *m, void *v)
        int rc;
 
        rc = seq_printf(m,
-                     "used_mb: %d\n"
-                     "busy_cnt: %d\n",
-                     (atomic_read(&cli->cl_lru_in_list) +
-                       atomic_read(&cli->cl_lru_busy)) >> shift,
-                     atomic_read(&cli->cl_lru_busy));
+                     "used_mb: %ld\n"
+                     "busy_cnt: %ld\n",
+                     (atomic_long_read(&cli->cl_lru_in_list) +
+                       atomic_long_read(&cli->cl_lru_busy)) >> shift,
+                     atomic_long_read(&cli->cl_lru_busy));
 
        return rc;
 }
@@ -184,7 +186,10 @@ osc_cached_mb_seq_write(struct file *file, const char __user *buffer,
 {
        struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
        struct client_obd *cli = &dev->u.cli;
-       int pages_number, mult, rc;
+       __u64 val;
+       long pages_number;
+       long rc;
+       int mult;
        char kernbuf[128];
 
        if (count >= sizeof(kernbuf))
@@ -197,14 +202,19 @@ osc_cached_mb_seq_write(struct file *file, const char __user *buffer,
        mult = 1 << (20 - PAGE_CACHE_SHIFT);
        buffer += lprocfs_find_named_value(kernbuf, "used_mb:", &count) -
                  kernbuf;
-       rc = lprocfs_write_frac_helper(buffer, count, &pages_number, mult);
+       rc = lprocfs_write_frac_u64_helper(buffer, count, &val, mult);
+
        if (rc)
                return rc;
 
+       if (val > LONG_MAX)
+               return -ERANGE;
+       pages_number = (long)val;
+
        if (pages_number < 0)
                return -ERANGE;
 
-       rc = atomic_read(&cli->cl_lru_in_list) - pages_number;
+       rc = atomic_long_read(&cli->cl_lru_in_list) - pages_number;
        if (rc > 0) {
                struct lu_env *env;
                int refcheck;
@@ -226,9 +236,9 @@ static int osc_cur_dirty_bytes_seq_show(struct seq_file *m, void *v)
        struct client_obd *cli = &dev->u.cli;
        int rc;
 
-       client_obd_list_lock(&cli->cl_loi_list_lock);
-       rc = seq_printf(m, "%lu\n", cli->cl_dirty);
-       client_obd_list_unlock(&cli->cl_loi_list_lock);
+       spin_lock(&cli->cl_loi_list_lock);
+       rc = seq_printf(m, "%lu\n", cli->cl_dirty_pages << PAGE_CACHE_SHIFT);
+       spin_unlock(&cli->cl_loi_list_lock);
        return rc;
 }
 LPROC_SEQ_FOPS_RO(osc_cur_dirty_bytes);
@@ -239,13 +249,14 @@ static int osc_cur_grant_bytes_seq_show(struct seq_file *m, void *v)
        struct client_obd *cli = &dev->u.cli;
        int rc;
 
-       client_obd_list_lock(&cli->cl_loi_list_lock);
+       spin_lock(&cli->cl_loi_list_lock);
        rc = seq_printf(m, "%lu\n", cli->cl_avail_grant);
-       client_obd_list_unlock(&cli->cl_loi_list_lock);
+       spin_unlock(&cli->cl_loi_list_lock);
        return rc;
 }
 
-static ssize_t osc_cur_grant_bytes_seq_write(struct file *file, const char *buffer,
+static ssize_t osc_cur_grant_bytes_seq_write(struct file *file,
+                                            const char __user *buffer,
                                             size_t count, loff_t *off)
 {
        struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
@@ -261,12 +272,13 @@ static ssize_t osc_cur_grant_bytes_seq_write(struct file *file, const char *buff
                 return rc;
 
         /* this is only for shrinking grant */
-        client_obd_list_lock(&cli->cl_loi_list_lock);
-        if (val >= cli->cl_avail_grant) {
-                client_obd_list_unlock(&cli->cl_loi_list_lock);
-                return 0;
-        }
-        client_obd_list_unlock(&cli->cl_loi_list_lock);
+       spin_lock(&cli->cl_loi_list_lock);
+       if (val >= cli->cl_avail_grant) {
+               spin_unlock(&cli->cl_loi_list_lock);
+               return 0;
+       }
+
+       spin_unlock(&cli->cl_loi_list_lock);
 
         LPROCFS_CLIMP_CHECK(obd);
         if (cli->cl_import->imp_state == LUSTRE_IMP_FULL)
@@ -284,9 +296,9 @@ static int osc_cur_lost_grant_bytes_seq_show(struct seq_file *m, void *v)
        struct client_obd *cli = &dev->u.cli;
        int rc;
 
-       client_obd_list_lock(&cli->cl_loi_list_lock);
+       spin_lock(&cli->cl_loi_list_lock);
        rc = seq_printf(m, "%lu\n", cli->cl_lost_grant);
-       client_obd_list_unlock(&cli->cl_loi_list_lock);
+       spin_unlock(&cli->cl_loi_list_lock);
        return rc;
 }
 LPROC_SEQ_FOPS_RO(osc_cur_lost_grant_bytes);
@@ -302,7 +314,7 @@ static int osc_grant_shrink_interval_seq_show(struct seq_file *m, void *v)
 }
 
 static ssize_t osc_grant_shrink_interval_seq_write(struct file *file,
-                                                  const char *buffer,
+                                                  const char __user *buffer,
                                                   size_t count, loff_t *off)
 {
        struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
@@ -335,7 +347,8 @@ static int osc_checksum_seq_show(struct seq_file *m, void *v)
                          obd->u.cli.cl_checksum ? 1 : 0);
 }
 
-static ssize_t osc_checksum_seq_write(struct file *file, const char *buffer,
+static ssize_t osc_checksum_seq_write(struct file *file,
+                                     const char __user *buffer,
                                      size_t count, loff_t *off)
 {
        struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
@@ -375,7 +388,8 @@ static int osc_checksum_type_seq_show(struct seq_file *m, void *v)
        return 0;
 }
 
-static ssize_t osc_checksum_type_seq_write(struct file *file, const char *buffer,
+static ssize_t osc_checksum_type_seq_write(struct file *file,
+                                          const char __user *buffer,
                                           size_t count, loff_t *off)
 {
        struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
@@ -414,7 +428,8 @@ static int osc_resend_count_seq_show(struct seq_file *m, void *v)
        return seq_printf(m, "%u\n", atomic_read(&obd->u.cli.cl_resends));
 }
 
-static ssize_t osc_resend_count_seq_write(struct file *file, const char *buffer,
+static ssize_t osc_resend_count_seq_write(struct file *file,
+                                         const char __user *buffer,
                                          size_t count, loff_t *off)
 {
        struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
@@ -441,7 +456,8 @@ static int osc_contention_seconds_seq_show(struct seq_file *m, void *v)
        return seq_printf(m, "%u\n", od->od_contention_time);
 }
 
-static ssize_t osc_contention_seconds_seq_write(struct file *file, const char *buffer,
+static ssize_t osc_contention_seconds_seq_write(struct file *file,
+                                               const char __user *buffer,
                                                size_t count, loff_t *off)
 {
        struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
@@ -459,7 +475,8 @@ static int osc_lockless_truncate_seq_show(struct seq_file *m, void *v)
        return seq_printf(m, "%u\n", od->od_lockless_truncate);
 }
 
-static ssize_t osc_lockless_truncate_seq_write(struct file *file, const char *buffer,
+static ssize_t osc_lockless_truncate_seq_write(struct file *file,
+                                              const char __user *buffer,
                                    size_t count, loff_t *off)
 {
        struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
@@ -484,7 +501,7 @@ static int osc_obd_max_pages_per_rpc_seq_show(struct seq_file *m, void *v)
 }
 
 static ssize_t osc_obd_max_pages_per_rpc_seq_write(struct file *file,
-                                                  const char *buffer,
+                                                  const char __user *buffer,
                                                   size_t count, loff_t *off)
 {
        struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
@@ -506,14 +523,15 @@ static ssize_t osc_obd_max_pages_per_rpc_seq_write(struct file *file,
        chunk_mask = ~((1 << (cli->cl_chunkbits - PAGE_CACHE_SHIFT)) - 1);
        /* max_pages_per_rpc must be chunk aligned */
        val = (val + ~chunk_mask) & chunk_mask;
-       if (val == 0 || val > ocd->ocd_brw_size >> PAGE_CACHE_SHIFT) {
+       if (val == 0 || (ocd->ocd_brw_size != 0 &&
+                        val > ocd->ocd_brw_size >> PAGE_CACHE_SHIFT)) {
                LPROCFS_CLIMP_EXIT(dev);
                return -ERANGE;
        }
-       client_obd_list_lock(&cli->cl_loi_list_lock);
+       spin_lock(&cli->cl_loi_list_lock);
        cli->cl_max_pages_per_rpc = val;
        client_adjust_max_dirty(cli);
-       client_obd_list_unlock(&cli->cl_loi_list_lock);
+       spin_unlock(&cli->cl_loi_list_lock);
 
        LPROCFS_CLIMP_EXIT(dev);
        return count;
@@ -524,13 +542,14 @@ static int osc_unstable_stats_seq_show(struct seq_file *m, void *v)
 {
        struct obd_device *dev = m->private;
        struct client_obd *cli = &dev->u.cli;
-       int pages, mb;
+       long pages;
+       int mb;
 
-       pages = atomic_read(&cli->cl_unstable_count);
+       pages = atomic_long_read(&cli->cl_unstable_count);
        mb    = (pages * PAGE_CACHE_SIZE) >> 20;
 
-       return seq_printf(m, "unstable_pages: %8d\n"
-                       "unstable_mb:    %8d\n",
+       return seq_printf(m, "unstable_pages: %20ld\n"
+                         "unstable_mb:              %10d\n",
                        pages, mb);
 }
 LPROC_SEQ_FOPS_RO(osc_unstable_stats);
@@ -553,7 +572,7 @@ LPROC_SEQ_FOPS_WO_TYPE(osc, ping);
 LPROC_SEQ_FOPS_RW_TYPE(osc, import);
 LPROC_SEQ_FOPS_RW_TYPE(osc, pinger_recov);
 
-struct lprocfs_seq_vars lprocfs_osc_obd_vars[] = {
+struct lprocfs_vars lprocfs_osc_obd_vars[] = {
        { .name =       "uuid",
          .fops =       &osc_uuid_fops                  },
        { .name =       "ping",
@@ -617,7 +636,7 @@ struct lprocfs_seq_vars lprocfs_osc_obd_vars[] = {
          .fops =       &osc_pinger_recov_fops          },
        { .name =       "unstable_stats",
          .fops =       &osc_unstable_stats_fops        },
-       { 0 }
+       { NULL }
 };
 
 #define pct(a,b) (b ? a * 100 / b : 0)
@@ -632,7 +651,7 @@ static int osc_rpc_stats_seq_show(struct seq_file *seq, void *v)
 
        do_gettimeofday(&now);
 
-       client_obd_list_lock(&cli->cl_loi_list_lock);
+       spin_lock(&cli->cl_loi_list_lock);
 
        seq_printf(seq, "snapshot_time:         %lu.%lu (secs.usecs)\n",
                   now.tv_sec, now.tv_usec);
@@ -714,13 +733,14 @@ static int osc_rpc_stats_seq_show(struct seq_file *seq, void *v)
                         break;
         }
 
-        client_obd_list_unlock(&cli->cl_loi_list_lock);
+       spin_unlock(&cli->cl_loi_list_lock);
 
         return 0;
 }
 #undef pct
 
-static ssize_t osc_rpc_stats_seq_write(struct file *file, const char *buf,
+static ssize_t osc_rpc_stats_seq_write(struct file *file,
+                                      const char __user *buf,
                                        size_t len, loff_t *off)
 {
         struct seq_file *seq = file->private_data;
@@ -757,7 +777,8 @@ static int osc_stats_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static ssize_t osc_stats_seq_write(struct file *file, const char *buf,
+static ssize_t osc_stats_seq_write(struct file *file,
+                                  const char __user *buf,
                                    size_t len, loff_t *off)
 {
         struct seq_file *seq = file->private_data;
@@ -782,4 +803,4 @@ int lproc_osc_attach_seqstat(struct obd_device *dev)
 
        return rc;
 }
-#endif /* LPROCFS */
+#endif /* CONFIG_PROC_FS */