Whamcloud - gitweb
LU-1644 mgc: remove obsolete IR swabbing workaround
[fs/lustre-release.git] / lustre / obdclass / lprocfs_status.c
index 0f15606..0c434f2 100644 (file)
@@ -59,6 +59,29 @@ int lprocfs_seq_release(struct inode *inode, struct file *file)
 }
 EXPORT_SYMBOL(lprocfs_seq_release);
 
+struct dentry *ldebugfs_add_simple(struct dentry *root,
+                                  char *name, void *data,
+                                  const struct file_operations *fops)
+{
+       struct dentry *entry;
+       umode_t mode = 0;
+
+       if (!root || !name || !fops)
+               return ERR_PTR(-EINVAL);
+
+       if (fops->read)
+               mode = 0444;
+       if (fops->write)
+               mode |= 0200;
+       entry = debugfs_create_file(name, mode, root, data, fops);
+       if (IS_ERR_OR_NULL(entry)) {
+               CERROR("LprocFS: No memory to create <debugfs> entry %s", name);
+               return entry ?: ERR_PTR(-ENOMEM);
+       }
+       return entry;
+}
+EXPORT_SYMBOL(ldebugfs_add_simple);
+
 struct proc_dir_entry *
 lprocfs_add_simple(struct proc_dir_entry *root, char *name,
                   void *data, const struct file_operations *fops)
@@ -346,93 +369,6 @@ lprocfs_register(const char *name, struct proc_dir_entry *parent,
 EXPORT_SYMBOL(lprocfs_register);
 
 /* Generic callbacks */
-int lprocfs_uint_seq_show(struct seq_file *m, void *data)
-{
-       seq_printf(m, "%u\n", *(unsigned int *)data);
-       return 0;
-}
-EXPORT_SYMBOL(lprocfs_uint_seq_show);
-
-int lprocfs_wr_uint(struct file *file, const char __user *buffer,
-                    unsigned long count, void *data)
-{
-       unsigned        *p = data;
-       char             dummy[MAX_STRING_SIZE + 1];
-       char            *end;
-       unsigned long    tmp;
-
-       if (count >= sizeof(dummy))
-               return -EINVAL;
-
-       if (count == 0)
-               return 0;
-
-       if (copy_from_user(dummy, buffer, count))
-               return -EFAULT;
-
-       dummy[count] = 0;
-
-       tmp = simple_strtoul(dummy, &end, 0);
-       if (dummy == end)
-               return -EINVAL;
-
-       *p = (unsigned int)tmp;
-       return count;
-}
-EXPORT_SYMBOL(lprocfs_wr_uint);
-
-ssize_t lprocfs_uint_seq_write(struct file *file, const char __user *buffer,
-                              size_t count, loff_t *off)
-{
-       int *data = ((struct seq_file *)file->private_data)->private;
-       int rc;
-       __s64 val = 0;
-
-       rc = lprocfs_str_to_s64(buffer, count, &val);
-       if (rc < 0)
-               return rc;
-
-       return lprocfs_wr_uint(file, buffer, count, data);
-}
-EXPORT_SYMBOL(lprocfs_uint_seq_write);
-
-int lprocfs_u64_seq_show(struct seq_file *m, void *data)
-{
-       LASSERT(data != NULL);
-       seq_printf(m, "%llu\n", *(__u64 *)data);
-       return 0;
-}
-EXPORT_SYMBOL(lprocfs_u64_seq_show);
-
-int lprocfs_atomic_seq_show(struct seq_file *m, void *data)
-{
-       atomic_t *atom = data;
-       LASSERT(atom != NULL);
-       seq_printf(m, "%d\n", atomic_read(atom));
-       return 0;
-}
-EXPORT_SYMBOL(lprocfs_atomic_seq_show);
-
-ssize_t
-lprocfs_atomic_seq_write(struct file *file, const char __user *buffer,
-                       size_t count, loff_t *off)
-{
-       atomic_t *atm = ((struct seq_file *)file->private_data)->private;
-       __s64 val = 0;
-       int rc;
-
-       rc = lprocfs_str_to_s64(buffer, count, &val);
-       if (rc < 0)
-               return rc;
-
-       if (val <= 0 || val > INT_MAX)
-               return -ERANGE;
-
-       atomic_set(atm, val);
-       return count;
-}
-EXPORT_SYMBOL(lprocfs_atomic_seq_write);
-
 int lprocfs_uuid_seq_show(struct seq_file *m, void *data)
 {
        struct obd_device *obd = data;
@@ -469,9 +405,11 @@ static ssize_t blocksize_show(struct kobject *kobj, struct attribute *attr,
        struct obd_device *obd = container_of(kobj, struct obd_device,
                                              obd_kset.kobj);
        struct obd_statfs osfs;
-       int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
-                           cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
-                           OBD_STATFS_NODELAY);
+       int rc;
+
+       rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
+                       ktime_get_seconds() - OBD_STATFS_CACHE_SECONDS,
+                       OBD_STATFS_NODELAY);
        if (!rc)
                return sprintf(buf, "%u\n", osfs.os_bsize);
 
@@ -485,9 +423,11 @@ static ssize_t kbytestotal_show(struct kobject *kobj, struct attribute *attr,
        struct obd_device *obd = container_of(kobj, struct obd_device,
                                              obd_kset.kobj);
        struct obd_statfs osfs;
-       int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
-                           cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
-                           OBD_STATFS_NODELAY);
+       int rc;
+
+       rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
+                       ktime_get_seconds() - OBD_STATFS_CACHE_SECONDS,
+                       OBD_STATFS_NODELAY);
        if (!rc) {
                u32 blk_size = osfs.os_bsize >> 10;
                u64 result = osfs.os_blocks;
@@ -508,9 +448,11 @@ static ssize_t kbytesfree_show(struct kobject *kobj, struct attribute *attr,
        struct obd_device *obd = container_of(kobj, struct obd_device,
                                              obd_kset.kobj);
        struct obd_statfs osfs;
-       int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
-                           cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
-                           OBD_STATFS_NODELAY);
+       int rc;
+
+       rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
+                       ktime_get_seconds() - OBD_STATFS_CACHE_SECONDS,
+                       OBD_STATFS_NODELAY);
        if (!rc) {
                u32 blk_size = osfs.os_bsize >> 10;
                u64 result = osfs.os_bfree;
@@ -531,9 +473,11 @@ static ssize_t kbytesavail_show(struct kobject *kobj, struct attribute *attr,
        struct obd_device *obd = container_of(kobj, struct obd_device,
                                              obd_kset.kobj);
        struct obd_statfs osfs;
-       int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
-                           cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
-                           OBD_STATFS_NODELAY);
+       int rc;
+
+       rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
+                       ktime_get_seconds() - OBD_STATFS_CACHE_SECONDS,
+                       OBD_STATFS_NODELAY);
        if (!rc) {
                u32 blk_size = osfs.os_bsize >> 10;
                u64 result = osfs.os_bavail;
@@ -554,9 +498,11 @@ static ssize_t filestotal_show(struct kobject *kobj, struct attribute *attr,
        struct obd_device *obd = container_of(kobj, struct obd_device,
                                              obd_kset.kobj);
        struct obd_statfs osfs;
-       int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
-                           cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
-                           OBD_STATFS_NODELAY);
+       int rc;
+
+       rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
+                       ktime_get_seconds() - OBD_STATFS_CACHE_SECONDS,
+                       OBD_STATFS_NODELAY);
        if (!rc)
                return sprintf(buf, "%llu\n", osfs.os_files);
 
@@ -570,9 +516,11 @@ static ssize_t filesfree_show(struct kobject *kobj, struct attribute *attr,
        struct obd_device *obd = container_of(kobj, struct obd_device,
                                              obd_kset.kobj);
        struct obd_statfs osfs;
-       int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
-                           cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
-                           OBD_STATFS_NODELAY);
+       int rc;
+
+       rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
+                       ktime_get_seconds() - OBD_STATFS_CACHE_SECONDS,
+                       OBD_STATFS_NODELAY);
        if (!rc)
                return sprintf(buf, "%llu\n", osfs.os_ffree);
 
@@ -580,6 +528,25 @@ static ssize_t filesfree_show(struct kobject *kobj, struct attribute *attr,
 }
 LUSTRE_RO_ATTR(filesfree);
 
+ssize_t conn_uuid_show(struct kobject *kobj, struct attribute *attr, char *buf)
+{
+       struct obd_device *obd = container_of(kobj, struct obd_device,
+                                             obd_kset.kobj);
+       struct ptlrpc_connection *conn;
+       ssize_t count;
+
+       LPROCFS_CLIMP_CHECK(obd);
+       conn = obd->u.cli.cl_import->imp_connection;
+       if (conn && obd->u.cli.cl_import)
+               count = sprintf(buf, "%s\n", conn->c_remote_uuid.uuid);
+       else
+               count = sprintf(buf, "%s\n", "<none>");
+
+       LPROCFS_CLIMP_EXIT(obd);
+       return count;
+}
+EXPORT_SYMBOL(conn_uuid_show);
+
 int lprocfs_server_uuid_seq_show(struct seq_file *m, void *data)
 {
        struct obd_device *obd = data;
@@ -746,16 +713,6 @@ void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
        lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
 }
 
-/**
- * Append a space separated list of current set flags to str.
- */
-#define flag2str(flag)                                         \
-       do {                                                            \
-               if (imp->imp_##flag) {                                  \
-                       seq_printf(m, "%s" #flag, first ? "" : ", ");   \
-                       first = false;                                  \
-               }                                                       \
-       } while (0)
 static void obd_import_flags2str(struct obd_import *imp, struct seq_file *m)
 {
        bool first = true;
@@ -765,18 +722,16 @@ static void obd_import_flags2str(struct obd_import *imp, struct seq_file *m)
                first = false;
        }
 
-       flag2str(invalid);
-       flag2str(deactive);
-       flag2str(replayable);
-       flag2str(delayed_recovery);
-       flag2str(vbr_failed);
-       flag2str(pingable);
-       flag2str(resend_replay);
-       flag2str(no_pinger_recover);
-       flag2str(need_mne_swab);
-       flag2str(connect_tried);
+       flag2str(imp, invalid);
+       flag2str(imp, deactive);
+       flag2str(imp, replayable);
+       flag2str(imp, delayed_recovery);
+       flag2str(imp, vbr_failed);
+       flag2str(imp, pingable);
+       flag2str(imp, resend_replay);
+       flag2str(imp, no_pinger_recover);
+       flag2str(imp, connect_tried);
 }
-#undef flag2str
 
 static const char *obd_connect_names[] = {
        /* flags names  */
@@ -850,8 +805,8 @@ static const char *obd_connect_names[] = {
        NULL
 };
 
-static void obd_connect_seq_flags2str(struct seq_file *m, __u64 flags,
-                                     __u64 flags2, const char *sep)
+void obd_connect_seq_flags2str(struct seq_file *m, __u64 flags, __u64 flags2,
+                              const char *sep)
 {
        bool first = true;
        __u64 mask;
@@ -888,6 +843,7 @@ static void obd_connect_seq_flags2str(struct seq_file *m, __u64 flags,
                first = false;
        }
 }
+EXPORT_SYMBOL(obd_connect_seq_flags2str);
 
 int obd_connect_flags2str(char *page, int count, __u64 flags, __u64 flags2,
                          const char *sep)
@@ -924,8 +880,8 @@ int obd_connect_flags2str(char *page, int count, __u64 flags, __u64 flags2,
 }
 EXPORT_SYMBOL(obd_connect_flags2str);
 
-static void obd_connect_data_seqprint(struct seq_file *m,
-                                     struct obd_connect_data *ocd)
+void
+obd_connect_data_seqprint(struct seq_file *m, struct obd_connect_data *ocd)
 {
        __u64 flags;
 
@@ -1248,6 +1204,7 @@ static void obd_sysfs_release(struct kobject *kobj)
 
 int lprocfs_obd_setup(struct obd_device *obd, bool uuid_only)
 {
+       struct lprocfs_vars *debugfs_vars = NULL;
        int rc;
 
        if (!obd || obd->obd_magic != OBD_DEVICE_MAGIC)
@@ -1262,7 +1219,7 @@ int lprocfs_obd_setup(struct obd_device *obd, bool uuid_only)
        if (obd->obd_attrs)
                obd->obd_ktype.default_attrs = obd->obd_attrs;
 
-       obd->obd_kset.kobj.parent = &obd->obd_type->typ_kobj;
+       obd->obd_kset.kobj.parent = obd->obd_type->typ_kobj;
        obd->obd_kset.kobj.ktype = &obd->obd_ktype;
        init_completion(&obd->obd_kobj_unregister);
        rc = kset_register(&obd->obd_kset);
@@ -1280,10 +1237,23 @@ int lprocfs_obd_setup(struct obd_device *obd, bool uuid_only)
                return rc;
        }
 
-       if (obd->obd_proc_entry)
-               GOTO(already_registered, rc);
+       if (!obd->obd_type->typ_procroot)
+               debugfs_vars = obd->obd_vars;
+       obd->obd_debugfs_entry = ldebugfs_register(obd->obd_name,
+                                                  obd->obd_type->typ_debugfs_entry,
+                                                  debugfs_vars, obd);
+       if (IS_ERR_OR_NULL(obd->obd_debugfs_entry)) {
+               rc = obd->obd_debugfs_entry ? PTR_ERR(obd->obd_debugfs_entry)
+                                           : -ENOMEM;
+               CERROR("error %d setting up debugfs for %s\n",
+                      rc, obd->obd_name);
+               obd->obd_debugfs_entry = NULL;
+               lprocfs_obd_cleanup(obd);
+               return rc;
+       }
 
-       LASSERT(obd->obd_type->typ_procroot != NULL);
+       if (obd->obd_proc_entry || !obd->obd_type->typ_procroot)
+               GOTO(already_registered, rc);
 
        obd->obd_proc_entry = lprocfs_register(obd->obd_name,
                                               obd->obd_type->typ_procroot,
@@ -1315,6 +1285,9 @@ int lprocfs_obd_cleanup(struct obd_device *obd)
                obd->obd_proc_entry = NULL;
        }
 
+       if (!IS_ERR_OR_NULL(obd->obd_debugfs_entry))
+               ldebugfs_remove(&obd->obd_debugfs_entry);
+
        sysfs_remove_group(&obd->obd_kset.kobj, &obd->obd_attrs_group);
        kset_unregister(&obd->obd_kset);
        wait_for_completion(&obd->obd_kobj_unregister);
@@ -1583,7 +1556,7 @@ static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
        if (rc)
                return rc;
        seq = file->private_data;
-       seq->private = inode->i_private ? : PDE_DATA(inode);
+       seq->private = inode->i_private ? inode->i_private : PDE_DATA(inode);
        return 0;
 }
 
@@ -2168,26 +2141,6 @@ static int str_to_s64_internal(const char __user *buffer, unsigned long count,
 
 /**
  * Convert a user string into a signed 64 bit number. This function produces
- * an error when the value parsed from the string underflows or
- * overflows. This function accepts strings which contain digits and
- * optionally a decimal or hex strings which are prefixed with "0x".
- *
- * \param[in] buffer   string consisting of numbers and optionally a decimal
- * \param[in] count    buffer length
- * \param[in] val      if successful, the value represented by the string
- *
- * \retval             0 on success
- * \retval             negative number on error
- */
-int lprocfs_str_to_s64(const char __user *buffer, unsigned long count,
-                      __s64 *val)
-{
-       return str_to_s64_internal(buffer, count, val, 1, false);
-}
-EXPORT_SYMBOL(lprocfs_str_to_s64);
-
-/**
- * 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
  * overflows. This function only accepts strings that contains digits, an
  * optional decimal, and a char representing a unit at the end. If a unit is
@@ -2219,7 +2172,7 @@ int lprocfs_str_with_units_to_s64(const char __user *buffer,
 }
 EXPORT_SYMBOL(lprocfs_str_with_units_to_s64);
 
-static char *lprocfs_strnstr(const char *s1, const char *s2, size_t len)
+char *lprocfs_strnstr(const char *s1, const char *s2, size_t len)
 {
        size_t l2;
 
@@ -2234,6 +2187,7 @@ static char *lprocfs_strnstr(const char *s1, const char *s2, size_t len)
        }
        return NULL;
 }
+EXPORT_SYMBOL(lprocfs_strnstr);
 
 /**
  * Find the string \a name in the input \a buffer, and return a pointer to the
@@ -2399,7 +2353,7 @@ ssize_t lprocfs_obd_max_pages_per_rpc_seq_write(struct file *file,
        struct client_obd *cli = &dev->u.cli;
        struct obd_connect_data *ocd = &cli->cl_import->imp_connect_data;
        int chunk_mask, rc;
-       __s64 val;
+       s64 val;
 
        rc = lprocfs_str_with_units_to_s64(buffer, count, &val, '1');
        if (rc)
@@ -2431,39 +2385,40 @@ ssize_t lprocfs_obd_max_pages_per_rpc_seq_write(struct file *file,
 }
 EXPORT_SYMBOL(lprocfs_obd_max_pages_per_rpc_seq_write);
 
-int lprocfs_obd_short_io_bytes_seq_show(struct seq_file *m, void *data)
+ssize_t short_io_bytes_show(struct kobject *kobj, struct attribute *attr,
+                           char *buf)
 {
-       struct obd_device *dev = data;
+       struct obd_device *dev = container_of(kobj, struct obd_device,
+                                             obd_kset.kobj);
        struct client_obd *cli = &dev->u.cli;
+       int rc;
 
        spin_lock(&cli->cl_loi_list_lock);
-       seq_printf(m, "%d\n", cli->cl_short_io_bytes);
+       rc = sprintf(buf, "%d\n", cli->cl_short_io_bytes);
        spin_unlock(&cli->cl_loi_list_lock);
-       return 0;
+       return rc;
 }
-EXPORT_SYMBOL(lprocfs_obd_short_io_bytes_seq_show);
-
+EXPORT_SYMBOL(short_io_bytes_show);
 
 /* Used to catch people who think they're specifying pages. */
 #define MIN_SHORT_IO_BYTES 64
 
-ssize_t lprocfs_obd_short_io_bytes_seq_write(struct file *file,
-                                            const char __user *buffer,
-                                            size_t count, loff_t *off)
+ssize_t short_io_bytes_store(struct kobject *kobj, struct attribute *attr,
+                            const char *buffer, size_t count)
 {
-       struct obd_device *dev = ((struct seq_file *)
-                                               file->private_data)->private;
+       struct obd_device *dev = container_of(kobj, struct obd_device,
+                                             obd_kset.kobj);
        struct client_obd *cli = &dev->u.cli;
+       u32 val;
        int rc;
-       __u64 val;
 
        LPROCFS_CLIMP_CHECK(dev);
 
-       rc = lprocfs_str_to_s64(buffer, count, &val);
+       rc = kstrtouint(buffer, 0, &val);
        if (rc)
                GOTO(out, rc);
 
-       if (val > OBD_MAX_SHORT_IO_BYTES || val < MIN_SHORT_IO_BYTES)
+       if (val < MIN_SHORT_IO_BYTES || val > OBD_MAX_SHORT_IO_BYTES)
                GOTO(out, rc = -ERANGE);
 
        rc = count;
@@ -2479,7 +2434,7 @@ out:
        LPROCFS_CLIMP_EXIT(dev);
        return rc;
 }
-EXPORT_SYMBOL(lprocfs_obd_short_io_bytes_seq_write);
+EXPORT_SYMBOL(short_io_bytes_store);
 
 int lprocfs_wr_root_squash(const char __user *buffer, unsigned long count,
                           struct root_squash_info *squash, char *name)