commit:     df0695149a3fa01865c93eefcfce342bf58c5162
Author:     Justin Lecher <jlec <AT> gentoo <DOT> org>
AuthorDate: Wed Nov 12 11:36:00 2014 +0000
Commit:     Christoph Junghans <ottxor <AT> gentoo <DOT> org>
CommitDate: Wed Nov 12 11:36:00 2014 +0000
URL:        http://sources.gentoo.org/gitweb/?p=proj/sci.git;a=commit;h=df069514

Move large patch to patch dir

Signed-off-by: Justin Lecher <jlec <AT> gentoo.org>

---
 ...cfs-move-mdd-ofd-proc-handling-to-seq_fil.patch | 2082 ++++++++++++++++++++
 1 file changed, 2082 insertions(+)

diff --git 
a/patches/0002-LU-3319-procfs-move-mdd-ofd-proc-handling-to-seq_fil.patch 
b/patches/0002-LU-3319-procfs-move-mdd-ofd-proc-handling-to-seq_fil.patch
new file mode 100644
index 0000000..813446c
--- /dev/null
+++ b/patches/0002-LU-3319-procfs-move-mdd-ofd-proc-handling-to-seq_fil.patch
@@ -0,0 +1,2082 @@
+From 9071634fd9db37a6121fdfbd817162f782661202 Mon Sep 17 00:00:00 2001
+From: James Simmons <[email protected]>
+Date: Mon, 5 May 2014 10:02:21 -0400
+Subject: [PATCH 2/3] LU-3319 procfs: move mdd/ofd proc handling to seq_files
+
+With 3.10 linux kernel and above proc handling now only
+uses struct seq_files. This patch migrates the mdd/ofd
+layer proc entries over to using seq_files.
+
+Signed-off-by: James Simmons <[email protected]>
+Change-Id: I61b7df6bfd5efd0f12e3ca1a1813b7b62d493168
+---
+ lustre/include/lustre_lfsck.h  |   6 +-
+ lustre/lfsck/lfsck_internal.h  |   9 +-
+ lustre/lfsck/lfsck_layout.c    | 132 ++++-------
+ lustre/lfsck/lfsck_lib.c       |  88 +++-----
+ lustre/lfsck/lfsck_namespace.c |  75 ++-----
+ lustre/mdd/mdd_device.c        |  25 +--
+ lustre/mdd/mdd_internal.h      |   1 -
+ lustre/mdd/mdd_lproc.c         | 302 ++++++++++++-------------
+ lustre/ofd/lproc_ofd.c         | 490 +++++++++++++++++++++--------------------
+ lustre/ofd/ofd_dev.c           |  90 ++++----
+ lustre/ofd/ofd_internal.h      |   6 +-
+ 11 files changed, 543 insertions(+), 681 deletions(-)
+
+diff --git a/lustre/include/lustre_lfsck.h b/lustre/include/lustre_lfsck.h
+index 0d6f666..5adbffe 100644
+--- a/lustre/include/lustre_lfsck.h
++++ b/lustre/include/lustre_lfsck.h
+@@ -148,12 +148,12 @@ int lfsck_in_notify(const struct lu_env *env, struct 
dt_device *key,
+ int lfsck_query(const struct lu_env *env, struct dt_device *key,
+               struct lfsck_request *lr);
+ 
+-int lfsck_get_speed(struct dt_device *key, void *buf, int len);
++int lfsck_get_speed(struct seq_file *m, struct dt_device *key);
+ int lfsck_set_speed(struct dt_device *key, int val);
+-int lfsck_get_windows(struct dt_device *key, void *buf, int len);
++int lfsck_get_windows(struct seq_file *m, struct dt_device *key);
+ int lfsck_set_windows(struct dt_device *key, int val);
+ 
+-int lfsck_dump(struct dt_device *key, void *buf, int len, enum lfsck_type 
type);
++int lfsck_dump(struct seq_file *m, struct dt_device *key, enum lfsck_type 
type);
+ 
+ static inline void lfsck_pack_rfa(struct lfsck_request *lr,
+                                 const struct lu_fid *fid)
+diff --git a/lustre/lfsck/lfsck_internal.h b/lustre/lfsck/lfsck_internal.h
+index 24b84ae..203ad74 100644
+--- a/lustre/lfsck/lfsck_internal.h
++++ b/lustre/lfsck/lfsck_internal.h
+@@ -303,8 +303,7 @@ struct lfsck_operations {
+ 
+       int (*lfsck_dump)(const struct lu_env *env,
+                         struct lfsck_component *com,
+-                        char *buf,
+-                        int len);
++                        struct seq_file *m);
+ 
+       int (*lfsck_double_scan)(const struct lu_env *env,
+                                struct lfsck_component *com);
+@@ -590,10 +589,10 @@ void lfsck_component_cleanup(const struct lu_env *env,
+                            struct lfsck_component *com);
+ void lfsck_instance_cleanup(const struct lu_env *env,
+                           struct lfsck_instance *lfsck);
+-int lfsck_bits_dump(char **buf, int *len, int bits, const char *names[],
++int lfsck_bits_dump(struct seq_file *m, int bits, const char *names[],
+                   const char *prefix);
+-int lfsck_time_dump(char **buf, int *len, __u64 time, const char *prefix);
+-int lfsck_pos_dump(char **buf, int *len, struct lfsck_position *pos,
++int lfsck_time_dump(struct seq_file *m, __u64 time, const char *prefix);
++int lfsck_pos_dump(struct seq_file *m, struct lfsck_position *pos,
+                  const char *prefix);
+ void lfsck_pos_fill(const struct lu_env *env, struct lfsck_instance *lfsck,
+                   struct lfsck_position *pos, bool init);
+diff --git a/lustre/lfsck/lfsck_layout.c b/lustre/lfsck/lfsck_layout.c
+index ced2e4d..e2df62d 100644
+--- a/lustre/lfsck/lfsck_layout.c
++++ b/lustre/lfsck/lfsck_layout.c
+@@ -492,7 +492,7 @@ static struct lfsck_rbtree_node *lfsck_rbtree_new(const 
struct lu_env *env,
+               return ERR_PTR(-ENOMEM);
+       }
+ 
+-      rb_init_node(&lrn->lrn_node);
++      RB_CLEAR_NODE(&lrn->lrn_node);
+       lrn->lrn_seq = fid_seq(fid);
+       lrn->lrn_first_oid = fid_oid(fid) & ~LFSCK_RBTREE_BITMAP_MASK;
+       atomic_set(&lrn->lrn_known_count, 0);
+@@ -4873,69 +4873,53 @@ static int lfsck_layout_slave_post(const struct lu_env 
*env,
+ }
+ 
+ static int lfsck_layout_dump(const struct lu_env *env,
+-                           struct lfsck_component *com, char *buf, int len)
++                           struct lfsck_component *com, struct seq_file *m)
+ {
+       struct lfsck_instance   *lfsck = com->lc_lfsck;
+       struct lfsck_bookmark   *bk    = &lfsck->li_bookmark_ram;
+       struct lfsck_layout     *lo    = com->lc_file_ram;
+-      int                      save  = len;
+-      int                      ret   = -ENOSPC;
+       int                      rc;
+ 
+       down_read(&com->lc_sem);
+-      rc = snprintf(buf, len,
+-                    "name: lfsck_layout\n"
++      seq_printf(m, "name: lfsck_layout\n"
+                     "magic: %#x\n"
+                     "version: %d\n"
+                     "status: %s\n",
+                     lo->ll_magic,
+                     bk->lb_version,
+                     lfsck_status2names(lo->ll_status));
+-      if (rc <= 0)
+-              goto out;
+ 
+-      buf += rc;
+-      len -= rc;
+-      rc = lfsck_bits_dump(&buf, &len, lo->ll_flags, lfsck_flags_names,
+-                           "flags");
++      rc = lfsck_bits_dump(m, lo->ll_flags, lfsck_flags_names, "flags");
+       if (rc < 0)
+               goto out;
+ 
+-      rc = lfsck_bits_dump(&buf, &len, bk->lb_param, lfsck_param_names,
+-                           "param");
++      rc = lfsck_bits_dump(m, bk->lb_param, lfsck_param_names, "param");
+       if (rc < 0)
+               goto out;
+ 
+-      rc = lfsck_time_dump(&buf, &len, lo->ll_time_last_complete,
++      rc = lfsck_time_dump(m, lo->ll_time_last_complete,
+                            "time_since_last_completed");
+       if (rc < 0)
+               goto out;
+ 
+-      rc = lfsck_time_dump(&buf, &len, lo->ll_time_latest_start,
++      rc = lfsck_time_dump(m, lo->ll_time_latest_start,
+                            "time_since_latest_start");
+       if (rc < 0)
+               goto out;
+ 
+-      rc = lfsck_time_dump(&buf, &len, lo->ll_time_last_checkpoint,
++      rc = lfsck_time_dump(m, lo->ll_time_last_checkpoint,
+                            "time_since_last_checkpoint");
+       if (rc < 0)
+               goto out;
+ 
+-      rc = snprintf(buf, len,
+-                    "latest_start_position: "LPU64"\n"
++      seq_printf(m, "latest_start_position: "LPU64"\n"
+                     "last_checkpoint_position: "LPU64"\n"
+                     "first_failure_position: "LPU64"\n",
+                     lo->ll_pos_latest_start,
+                     lo->ll_pos_last_checkpoint,
+                     lo->ll_pos_first_inconsistent);
+-      if (rc <= 0)
+-              goto out;
+ 
+-      buf += rc;
+-      len -= rc;
+-
+-      rc = snprintf(buf, len,
+-                    "success_count: %u\n"
++      seq_printf(m, "success_count: %u\n"
+                     "repaired_dangling: "LPU64"\n"
+                     "repaired_unmatched_pair: "LPU64"\n"
+                     "repaired_multiple_referenced: "LPU64"\n"
+@@ -4955,11 +4939,6 @@ static int lfsck_layout_dump(const struct lu_env *env,
+                     lo->ll_objs_skipped,
+                     lo->ll_objs_failed_phase1,
+                     lo->ll_objs_failed_phase2);
+-      if (rc <= 0)
+-              goto out;
+-
+-      buf += rc;
+-      len -= rc;
+ 
+       if (lo->ll_status == LS_SCANNING_PHASE1) {
+               __u64 pos;
+@@ -4977,8 +4956,7 @@ static int lfsck_layout_dump(const struct lu_env *env,
+                       do_div(new_checked, duration);
+               if (rtime != 0)
+                       do_div(speed, rtime);
+-              rc = snprintf(buf, len,
+-                            "checked_phase1: "LPU64"\n"
++              seq_printf(m, "checked_phase1: "LPU64"\n"
+                             "checked_phase2: "LPU64"\n"
+                             "run_time_phase1: %u seconds\n"
+                             "run_time_phase2: %u seconds\n"
+@@ -4992,11 +4970,6 @@ static int lfsck_layout_dump(const struct lu_env *env,
+                             lo->ll_run_time_phase2,
+                             speed,
+                             new_checked);
+-              if (rc <= 0)
+-                      goto out;
+-
+-              buf += rc;
+-              len -= rc;
+ 
+               LASSERT(lfsck->li_di_oit != NULL);
+ 
+@@ -5009,12 +4982,8 @@ static int lfsck_layout_dump(const struct lu_env *env,
+               pos = iops->store(env, lfsck->li_di_oit);
+               if (!lfsck->li_current_oit_processed)
+                       pos--;
+-              rc = snprintf(buf, len, "current_position: "LPU64"\n", pos);
+-              if (rc <= 0)
+-                      goto out;
++              seq_printf(m, "current_position: "LPU64"\n", pos);
+ 
+-              buf += rc;
+-              len -= rc;
+       } else if (lo->ll_status == LS_SCANNING_PHASE2) {
+               cfs_duration_t duration = cfs_time_current() -
+                                         lfsck->li_time_last_checkpoint;
+@@ -5032,29 +5001,26 @@ static int lfsck_layout_dump(const struct lu_env *env,
+                       do_div(speed1, lo->ll_run_time_phase1);
+               if (rtime != 0)
+                       do_div(speed2, rtime);
+-              rc = snprintf(buf, len,
+-                            "checked_phase1: "LPU64"\n"
+-                            "checked_phase2: "LPU64"\n"
+-                            "run_time_phase1: %u seconds\n"
+-                            "run_time_phase2: %u seconds\n"
+-                            "average_speed_phase1: "LPU64" items/sec\n"
+-                            "average_speed_phase2: "LPU64" items/sec\n"
+-                            "real-time_speed_phase1: N/A\n"
+-                            "real-time_speed_phase2: "LPU64" items/sec\n"
+-                            "current_position: "DFID"\n",
+-                            lo->ll_objs_checked_phase1,
+-                            checked,
+-                            lo->ll_run_time_phase1,
+-                            rtime,
+-                            speed1,
+-                            speed2,
+-                            new_checked,
+-                            PFID(&com->lc_fid_latest_scanned_phase2));
++              rc = seq_printf(m, "checked_phase1: "LPU64"\n"
++                              "checked_phase2: "LPU64"\n"
++                              "run_time_phase1: %u seconds\n"
++                              "run_time_phase2: %u seconds\n"
++                              "average_speed_phase1: "LPU64" items/sec\n"
++                              "average_speed_phase2: "LPU64" items/sec\n"
++                              "real-time_speed_phase1: N/A\n"
++                              "real-time_speed_phase2: "LPU64" items/sec\n"
++                              "current_position: "DFID"\n",
++                              lo->ll_objs_checked_phase1,
++                              checked,
++                              lo->ll_run_time_phase1,
++                              rtime,
++                              speed1,
++                              speed2,
++                              new_checked,
++                              PFID(&com->lc_fid_latest_scanned_phase2));
+               if (rc <= 0)
+                       goto out;
+ 
+-              buf += rc;
+-              len -= rc;
+       } else {
+               __u64 speed1 = lo->ll_objs_checked_phase1;
+               __u64 speed2 = lo->ll_objs_checked_phase2;
+@@ -5063,34 +5029,26 @@ static int lfsck_layout_dump(const struct lu_env *env,
+                       do_div(speed1, lo->ll_run_time_phase1);
+               if (lo->ll_run_time_phase2 != 0)
+                       do_div(speed2, lo->ll_run_time_phase2);
+-              rc = snprintf(buf, len,
+-                            "checked_phase1: "LPU64"\n"
+-                            "checked_phase2: "LPU64"\n"
+-                            "run_time_phase1: %u seconds\n"
+-                            "run_time_phase2: %u seconds\n"
+-                            "average_speed_phase1: "LPU64" items/sec\n"
+-                            "average_speed_phase2: "LPU64" objs/sec\n"
+-                            "real-time_speed_phase1: N/A\n"
+-                            "real-time_speed_phase2: N/A\n"
+-                            "current_position: N/A\n",
+-                            lo->ll_objs_checked_phase1,
+-                            lo->ll_objs_checked_phase2,
+-                            lo->ll_run_time_phase1,
+-                            lo->ll_run_time_phase2,
+-                            speed1,
+-                            speed2);
+-              if (rc <= 0)
+-                      goto out;
+-
+-              buf += rc;
+-              len -= rc;
++              seq_printf(m, "checked_phase1: "LPU64"\n"
++                         "checked_phase2: "LPU64"\n"
++                         "run_time_phase1: %u seconds\n"
++                         "run_time_phase2: %u seconds\n"
++                         "average_speed_phase1: "LPU64" items/sec\n"
++                         "average_speed_phase2: "LPU64" objs/sec\n"
++                         "real-time_speed_phase1: N/A\n"
++                         "real-time_speed_phase2: N/A\n"
++                         "current_position: N/A\n",
++                         lo->ll_objs_checked_phase1,
++                         lo->ll_objs_checked_phase2,
++                         lo->ll_run_time_phase1,
++                         lo->ll_run_time_phase2,
++                         speed1,
++                         speed2);
+       }
+-      ret = save - len;
+-
+ out:
+       up_read(&com->lc_sem);
+ 
+-      return ret;
++      return rc;
+ }
+ 
+ static int lfsck_layout_master_double_scan(const struct lu_env *env,
+diff --git a/lustre/lfsck/lfsck_lib.c b/lustre/lfsck/lfsck_lib.c
+index db73616..f6f1cce 100644
+--- a/lustre/lfsck/lfsck_lib.c
++++ b/lustre/lfsck/lfsck_lib.c
+@@ -900,21 +900,15 @@ static inline int lfsck_instance_add(struct 
lfsck_instance *lfsck)
+       return 0;
+ }
+ 
+-int lfsck_bits_dump(char **buf, int *len, int bits, const char *names[],
++int lfsck_bits_dump(struct seq_file *m, int bits, const char *names[],
+                   const char *prefix)
+ {
+-      int save = *len;
+       int flag;
+-      int rc;
+       int i;
+       bool newline = (bits != 0 ? false : true);
+ 
+-      rc = snprintf(*buf, *len, "%s:%c", prefix, newline ? '\n' : ' ');
+-      if (rc <= 0)
+-              return -ENOSPC;
++      seq_printf(m, "%s:%c", prefix, bits != 0 ? ' ' : '\n');
+ 
+-      *buf += rc;
+-      *len -= rc;
+       for (i = 0, flag = 1; bits != 0; i++, flag = 1 << i) {
+               if (flag & bits) {
+                       bits &= ~flag;
+@@ -922,69 +916,43 @@ int lfsck_bits_dump(char **buf, int *len, int bits, 
const char *names[],
+                               if (bits == 0)
+                                       newline = true;
+ 
+-                              rc = snprintf(*buf, *len, "%s%c", names[i],
+-                                            newline ? '\n' : ',');
+-                              if (rc <= 0)
+-                                      return -ENOSPC;
+-
+-                              *buf += rc;
+-                              *len -= rc;
++                              seq_printf(m, "%s%c", names[i],
++                                         newline ? '\n' : ',');
+                       }
+               }
+       }
+ 
+-      if (!newline) {
+-              rc = snprintf(*buf, *len, "\n");
+-              if (rc <= 0)
+-                      return -ENOSPC;
+-
+-              *buf += rc;
+-              *len -= rc;
+-      }
+-
+-      return save - *len;
++      if (!newline)
++              seq_printf(m, "\n");
++      return 0;
+ }
+ 
+-int lfsck_time_dump(char **buf, int *len, __u64 time, const char *prefix)
++int lfsck_time_dump(struct seq_file *m, __u64 time, const char *prefix)
+ {
+-      int rc;
+-
+       if (time != 0)
+-              rc = snprintf(*buf, *len, "%s: "LPU64" seconds\n", prefix,
+-                            cfs_time_current_sec() - time);
++              seq_printf(m, "%s: "LPU64" seconds\n", prefix,
++                        cfs_time_current_sec() - time);
+       else
+-              rc = snprintf(*buf, *len, "%s: N/A\n", prefix);
+-      if (rc <= 0)
+-              return -ENOSPC;
+-
+-      *buf += rc;
+-      *len -= rc;
+-      return rc;
++              seq_printf(m, "%s: N/A\n", prefix);
++      return 0;
+ }
+ 
+-int lfsck_pos_dump(char **buf, int *len, struct lfsck_position *pos,
++int lfsck_pos_dump(struct seq_file *m, struct lfsck_position *pos,
+                  const char *prefix)
+ {
+-      int rc;
+-
+       if (fid_is_zero(&pos->lp_dir_parent)) {
+               if (pos->lp_oit_cookie == 0)
+-                      rc = snprintf(*buf, *len, "%s: N/A, N/A, N/A\n",
+-                                    prefix);
++                      seq_printf(m, "%s: N/A, N/A, N/A\n",
++                                 prefix);
+               else
+-                      rc = snprintf(*buf, *len, "%s: "LPU64", N/A, N/A\n",
+-                                    prefix, pos->lp_oit_cookie);
++                      seq_printf(m, "%s: "LPU64", N/A, N/A\n",
++                                 prefix, pos->lp_oit_cookie);
+       } else {
+-              rc = snprintf(*buf, *len, "%s: "LPU64", "DFID", "LPU64"\n",
+-                            prefix, pos->lp_oit_cookie,
+-                            PFID(&pos->lp_dir_parent), pos->lp_dir_cookie);
++              seq_printf(m, "%s: "LPU64", "DFID", "LPU64"\n",
++                         prefix, pos->lp_oit_cookie,
++                         PFID(&pos->lp_dir_parent), pos->lp_dir_cookie);
+       }
+-      if (rc <= 0)
+-              return -ENOSPC;
+-
+-      *buf += rc;
+-      *len -= rc;
+-      return rc;
++      return 0;
+ }
+ 
+ void lfsck_pos_fill(const struct lu_env *env, struct lfsck_instance *lfsck,
+@@ -1670,7 +1638,7 @@ int lfsck_async_request(const struct lu_env *env, struct 
obd_export *exp,
+ 
+ /* external interfaces */
+ 
+-int lfsck_get_speed(struct dt_device *key, void *buf, int len)
++int lfsck_get_speed(struct seq_file *m, struct dt_device *key)
+ {
+       struct lu_env           env;
+       struct lfsck_instance  *lfsck;
+@@ -1683,8 +1651,7 @@ int lfsck_get_speed(struct dt_device *key, void *buf, 
int len)
+ 
+       lfsck = lfsck_instance_find(key, true, false);
+       if (likely(lfsck != NULL)) {
+-              rc = snprintf(buf, len, "%u\n",
+-                            lfsck->li_bookmark_ram.lb_speed_limit);
++              seq_printf(m, "%u\n", lfsck->li_bookmark_ram.lb_speed_limit);
+               lfsck_instance_put(&env, lfsck);
+       } else {
+               rc = -ENXIO;
+@@ -1724,7 +1691,7 @@ int lfsck_set_speed(struct dt_device *key, int val)
+ }
+ EXPORT_SYMBOL(lfsck_set_speed);
+ 
+-int lfsck_get_windows(struct dt_device *key, void *buf, int len)
++int lfsck_get_windows(struct seq_file *m, struct dt_device *key)
+ {
+       struct lu_env           env;
+       struct lfsck_instance  *lfsck;
+@@ -1737,8 +1704,7 @@ int lfsck_get_windows(struct dt_device *key, void *buf, 
int len)
+ 
+       lfsck = lfsck_instance_find(key, true, false);
+       if (likely(lfsck != NULL)) {
+-              rc = snprintf(buf, len, "%u\n",
+-                            lfsck->li_bookmark_ram.lb_async_windows);
++              seq_printf(m, "%u\n", lfsck->li_bookmark_ram.lb_async_windows);
+               lfsck_instance_put(&env, lfsck);
+       } else {
+               rc = -ENXIO;
+@@ -1788,7 +1754,7 @@ int lfsck_set_windows(struct dt_device *key, int val)
+ }
+ EXPORT_SYMBOL(lfsck_set_windows);
+ 
+-int lfsck_dump(struct dt_device *key, void *buf, int len, enum lfsck_type 
type)
++int lfsck_dump(struct seq_file *m, struct dt_device *key, enum lfsck_type 
type)
+ {
+       struct lu_env           env;
+       struct lfsck_instance  *lfsck;
+@@ -1804,7 +1770,7 @@ int lfsck_dump(struct dt_device *key, void *buf, int 
len, enum lfsck_type type)
+       if (likely(lfsck != NULL)) {
+               com = lfsck_component_find(lfsck, type);
+               if (likely(com != NULL)) {
+-                      rc = com->lc_ops->lfsck_dump(&env, com, buf, len);
++                      rc = com->lc_ops->lfsck_dump(&env, com, m);
+                       lfsck_component_put(&env, com);
+               } else {
+                       rc = -ENOTSUPP;
+diff --git a/lustre/lfsck/lfsck_namespace.c b/lustre/lfsck/lfsck_namespace.c
+index 4dccb70..fc9a0dc 100644
+--- a/lustre/lfsck/lfsck_namespace.c
++++ b/lustre/lfsck/lfsck_namespace.c
+@@ -1099,65 +1099,56 @@ static int lfsck_namespace_post(const struct lu_env 
*env,
+ 
+ static int
+ lfsck_namespace_dump(const struct lu_env *env, struct lfsck_component *com,
+-                   char *buf, int len)
++                   struct seq_file *m)
+ {
+       struct lfsck_instance   *lfsck = com->lc_lfsck;
+       struct lfsck_bookmark   *bk    = &lfsck->li_bookmark_ram;
+       struct lfsck_namespace  *ns    = com->lc_file_ram;
+-      int                      save  = len;
+-      int                      ret   = -ENOSPC;
+       int                      rc;
+ 
+       down_read(&com->lc_sem);
+-      rc = snprintf(buf, len,
+-                    "name: lfsck_namespace\n"
+-                    "magic: %#x\n"
+-                    "version: %d\n"
+-                    "status: %s\n",
+-                    ns->ln_magic,
+-                    bk->lb_version,
+-                    lfsck_status2names(ns->ln_status));
+-      if (rc <= 0)
+-              goto out;
+-
+-      buf += rc;
+-      len -= rc;
+-      rc = lfsck_bits_dump(&buf, &len, ns->ln_flags, lfsck_flags_names,
+-                           "flags");
++      seq_printf(m, "name: lfsck_namespace\n"
++                 "magic: %#x\n"
++                 "version: %d\n"
++                 "status: %s\n",
++                 ns->ln_magic,
++                 bk->lb_version,
++                 lfsck_status2names(ns->ln_status));
++
++      rc = lfsck_bits_dump(m, ns->ln_flags, lfsck_flags_names, "flags");
+       if (rc < 0)
+               goto out;
+ 
+-      rc = lfsck_bits_dump(&buf, &len, bk->lb_param, lfsck_param_names,
+-                           "param");
++      rc = lfsck_bits_dump(m, bk->lb_param, lfsck_param_names, "param");
+       if (rc < 0)
+               goto out;
+ 
+-      rc = lfsck_time_dump(&buf, &len, ns->ln_time_last_complete,
++      rc = lfsck_time_dump(m, ns->ln_time_last_complete,
+                            "time_since_last_completed");
+       if (rc < 0)
+               goto out;
+ 
+-      rc = lfsck_time_dump(&buf, &len, ns->ln_time_latest_start,
++      rc = lfsck_time_dump(m, ns->ln_time_latest_start,
+                            "time_since_latest_start");
+       if (rc < 0)
+               goto out;
+ 
+-      rc = lfsck_time_dump(&buf, &len, ns->ln_time_last_checkpoint,
++      rc = lfsck_time_dump(m, ns->ln_time_last_checkpoint,
+                            "time_since_last_checkpoint");
+       if (rc < 0)
+               goto out;
+ 
+-      rc = lfsck_pos_dump(&buf, &len, &ns->ln_pos_latest_start,
++      rc = lfsck_pos_dump(m, &ns->ln_pos_latest_start,
+                           "latest_start_position");
+       if (rc < 0)
+               goto out;
+ 
+-      rc = lfsck_pos_dump(&buf, &len, &ns->ln_pos_last_checkpoint,
++      rc = lfsck_pos_dump(m, &ns->ln_pos_last_checkpoint,
+                           "last_checkpoint_position");
+       if (rc < 0)
+               goto out;
+ 
+-      rc = lfsck_pos_dump(&buf, &len, &ns->ln_pos_first_inconsistent,
++      rc = lfsck_pos_dump(m, &ns->ln_pos_first_inconsistent,
+                           "first_failure_position");
+       if (rc < 0)
+               goto out;
+@@ -1177,8 +1168,7 @@ lfsck_namespace_dump(const struct lu_env *env, struct 
lfsck_component *com,
+                       do_div(new_checked, duration);
+               if (rtime != 0)
+                       do_div(speed, rtime);
+-              rc = snprintf(buf, len,
+-                            "checked_phase1: "LPU64"\n"
++              seq_printf(m, "checked_phase1: "LPU64"\n"
+                             "checked_phase2: "LPU64"\n"
+                             "updated_phase1: "LPU64"\n"
+                             "updated_phase2: "LPU64"\n"
+@@ -1214,11 +1204,6 @@ lfsck_namespace_dump(const struct lu_env *env, struct 
lfsck_component *com,
+                             ns->ln_run_time_phase2,
+                             speed,
+                             new_checked);
+-              if (rc <= 0)
+-                      goto out;
+-
+-              buf += rc;
+-              len -= rc;
+ 
+               LASSERT(lfsck->li_di_oit != NULL);
+ 
+@@ -1247,9 +1232,7 @@ lfsck_namespace_dump(const struct lu_env *env, struct 
lfsck_component *com,
+                       pos.lp_dir_cookie = 0;
+               }
+               spin_unlock(&lfsck->li_lock);
+-              rc = lfsck_pos_dump(&buf, &len, &pos, "current_position");
+-              if (rc <= 0)
+-                      goto out;
++              lfsck_pos_dump(m, &pos, "current_position");
+       } else if (ns->ln_status == LS_SCANNING_PHASE2) {
+               cfs_duration_t duration = cfs_time_current() -
+                                         lfsck->li_time_last_checkpoint;
+@@ -1267,8 +1250,7 @@ lfsck_namespace_dump(const struct lu_env *env, struct 
lfsck_component *com,
+                       do_div(speed1, ns->ln_run_time_phase1);
+               if (rtime != 0)
+                       do_div(speed2, rtime);
+-              rc = snprintf(buf, len,
+-                            "checked_phase1: "LPU64"\n"
++              seq_printf(m, "checked_phase1: "LPU64"\n"
+                             "checked_phase2: "LPU64"\n"
+                             "updated_phase1: "LPU64"\n"
+                             "updated_phase2: "LPU64"\n"
+@@ -1307,11 +1289,6 @@ lfsck_namespace_dump(const struct lu_env *env, struct 
lfsck_component *com,
+                             speed2,
+                             new_checked,
+                             PFID(&ns->ln_fid_latest_scanned_phase2));
+-              if (rc <= 0)
+-                      goto out;
+-
+-              buf += rc;
+-              len -= rc;
+       } else {
+               __u64 speed1 = ns->ln_items_checked;
+               __u64 speed2 = ns->ln_objs_checked_phase2;
+@@ -1320,8 +1297,7 @@ lfsck_namespace_dump(const struct lu_env *env, struct 
lfsck_component *com,
+                       do_div(speed1, ns->ln_run_time_phase1);
+               if (ns->ln_run_time_phase2 != 0)
+                       do_div(speed2, ns->ln_run_time_phase2);
+-              rc = snprintf(buf, len,
+-                            "checked_phase1: "LPU64"\n"
++              seq_printf(m, "checked_phase1: "LPU64"\n"
+                             "checked_phase2: "LPU64"\n"
+                             "updated_phase1: "LPU64"\n"
+                             "updated_phase2: "LPU64"\n"
+@@ -1358,17 +1334,10 @@ lfsck_namespace_dump(const struct lu_env *env, struct 
lfsck_component *com,
+                             ns->ln_run_time_phase2,
+                             speed1,
+                             speed2);
+-              if (rc <= 0)
+-                      goto out;
+-
+-              buf += rc;
+-              len -= rc;
+       }
+-      ret = save - len;
+-
+ out:
+       up_read(&com->lc_sem);
+-      return ret;
++      return 0;
+ }
+ 
+ static int lfsck_namespace_double_scan_main(void *args)
+diff --git a/lustre/mdd/mdd_device.c b/lustre/mdd/mdd_device.c
+index 4f0baa4..f6deaca 100644
+--- a/lustre/mdd/mdd_device.c
++++ b/lustre/mdd/mdd_device.c
+@@ -889,16 +889,16 @@ static int mdd_process_config(const struct lu_env *env,
+         ENTRY;
+ 
+         switch (cfg->lcfg_command) {
+-        case LCFG_PARAM: {
+-                struct lprocfs_static_vars lvars;
+-
+-                lprocfs_mdd_init_vars(&lvars);
+-                rc = class_process_proc_param(PARAM_MDD, lvars.obd_vars, 
cfg,m);
+-                if (rc > 0 || rc == -ENOSYS)
+-                        /* we don't understand; pass it on */
+-                        rc = next->ld_ops->ldo_process_config(env, next, cfg);
+-                break;
+-        }
++      case LCFG_PARAM: {
++              struct obd_device *obd = mdd2obd_dev(m);
++
++              rc = class_process_proc_seq_param(PARAM_MDD, obd->obd_vars,
++                                                cfg, m);
++              if (rc > 0 || rc == -ENOSYS)
++                      /* we don't understand; pass it on */
++                      rc = next->ld_ops->ldo_process_config(env, next, cfg);
++              break;
++      }
+         case LCFG_SETUP:
+                 rc = next->ld_ops->ldo_process_config(env, next, cfg);
+                 if (rc)
+@@ -1566,11 +1566,8 @@ LU_CONTEXT_KEY_DEFINE(mdd, LCT_MD_THREAD);
+ 
+ static int __init mdd_mod_init(void)
+ {
+-      struct lprocfs_static_vars lvars;
+       int rc;
+ 
+-      lprocfs_mdd_init_vars(&lvars);
+-
+       rc = lu_kmem_init(mdd_caches);
+       if (rc)
+               return rc;
+@@ -1586,7 +1583,7 @@ static int __init mdd_mod_init(void)
+ 
+       rc = class_register_type(&mdd_obd_device_ops, NULL, true, NULL,
+ #ifndef HAVE_ONLY_PROCFS_SEQ
+-                               lvars.module_vars,
++                               NULL,
+ #endif
+                                LUSTRE_MDD_NAME, &mdd_device_type);
+       if (rc)
+diff --git a/lustre/mdd/mdd_internal.h b/lustre/mdd/mdd_internal.h
+index 4411892..37698f8 100644
+--- a/lustre/mdd/mdd_internal.h
++++ b/lustre/mdd/mdd_internal.h
+@@ -248,7 +248,6 @@ int orph_declare_index_delete(const struct lu_env *, 
struct mdd_object *,
+                               struct thandle *);
+ 
+ /* mdd_lproc.c */
+-void lprocfs_mdd_init_vars(struct lprocfs_static_vars *lvars);
+ int mdd_procfs_init(struct mdd_device *mdd, const char *name);
+ int mdd_procfs_fini(struct mdd_device *mdd);
+ 
+diff --git a/lustre/mdd/mdd_lproc.c b/lustre/mdd/mdd_lproc.c
+index de379b3..7ac4afa 100644
+--- a/lustre/mdd/mdd_lproc.c
++++ b/lustre/mdd/mdd_lproc.c
+@@ -49,56 +49,14 @@
+ #include <libcfs/libcfs_string.h>
+ #include "mdd_internal.h"
+ 
+-int mdd_procfs_init(struct mdd_device *mdd, const char *name)
+-{
+-        struct lprocfs_static_vars lvars;
+-        struct obd_type     *type;
+-        int                  rc;
+-        ENTRY;
+-
+-      /* at the moment there is no linkage between lu_type
+-       * and obd_type, so we lookup obd_type this way */
+-      type = class_search_type(LUSTRE_MDD_NAME);
+-
+-        LASSERT(name != NULL);
+-        LASSERT(type != NULL);
+-
+-        /* Find the type procroot and add the proc entry for this device */
+-        lprocfs_mdd_init_vars(&lvars);
+-        mdd->mdd_proc_entry = lprocfs_register(name, type->typ_procroot,
+-                                               lvars.obd_vars, mdd);
+-        if (IS_ERR(mdd->mdd_proc_entry)) {
+-                rc = PTR_ERR(mdd->mdd_proc_entry);
+-                CERROR("Error %d setting up lprocfs for %s\n",
+-                       rc, name);
+-                mdd->mdd_proc_entry = NULL;
+-                GOTO(out, rc);
+-        }
+-
+-      rc = 0;
+-
+-        EXIT;
+-out:
+-        if (rc)
+-               mdd_procfs_fini(mdd);
+-        return rc;
+-}
+-
+-int mdd_procfs_fini(struct mdd_device *mdd)
+-{
+-        if (mdd->mdd_proc_entry) {
+-                 lprocfs_remove(&mdd->mdd_proc_entry);
+-                 mdd->mdd_proc_entry = NULL;
+-        }
+-        RETURN(0);
+-}
+-
+-static int lprocfs_wr_atime_diff(struct file *file, const char *buffer,
+-                                 unsigned long count, void *data)
++static ssize_t
++mdd_atime_diff_seq_write(struct file *file, const char *buffer,
++                       size_t count, loff_t *off)
+ {
+-        struct mdd_device *mdd = data;
+-        char kernbuf[20], *end;
+-        unsigned long diff = 0;
++      struct seq_file *m = file->private_data;
++      struct mdd_device *mdd = m->private;
++      char kernbuf[20], *end;
++      unsigned long diff = 0;
+ 
+         if (count > (sizeof(kernbuf) - 1))
+                 return -EINVAL;
+@@ -116,37 +74,35 @@ static int lprocfs_wr_atime_diff(struct file *file, const 
char *buffer,
+         return count;
+ }
+ 
+-static int lprocfs_rd_atime_diff(char *page, char **start, off_t off,
+-                                 int count, int *eof, void *data)
++static int mdd_atime_diff_seq_show(struct seq_file *m, void *data)
+ {
+-        struct mdd_device *mdd = data;
++      struct mdd_device *mdd = m->private;
+ 
+-        *eof = 1;
+-        return snprintf(page, count, "%lu\n", mdd->mdd_atime_diff);
++      return seq_printf(m, "%lu\n", mdd->mdd_atime_diff);
+ }
+-
++LPROC_SEQ_FOPS(mdd_atime_diff);
+ 
+ /**** changelogs ****/
+-static int lprocfs_rd_changelog_mask(char *page, char **start, off_t off,
+-                                     int count, int *eof, void *data)
++static int mdd_changelog_mask_seq_show(struct seq_file *m, void *data)
+ {
+-        struct mdd_device *mdd = data;
+-        int i = 0, rc = 0;
+-
+-        *eof = 1;
+-        while (i < CL_LAST) {
+-                if (mdd->mdd_cl.mc_mask & (1 << i))
+-                        rc += snprintf(page + rc, count - rc, "%s ",
+-                                       changelog_type2str(i));
+-                i++;
+-        }
+-        return rc;
++      struct mdd_device *mdd = m->private;
++      int i = 0;
++
++      while (i < CL_LAST) {
++              if (mdd->mdd_cl.mc_mask & (1 << i))
++                      seq_printf(m, "%s ", changelog_type2str(i));
++              i++;
++      }
++      seq_printf(m, "\n");
++      return 0;
+ }
+ 
+-static int lprocfs_wr_changelog_mask(struct file *file, const char *buffer,
+-                                   unsigned long count, void *data)
++static ssize_t
++mdd_changelog_mask_seq_write(struct file *file, const char *buffer,
++                           size_t count, loff_t *off)
+ {
+-      struct mdd_device *mdd = data;
++      struct seq_file *m = file->private_data;
++      struct mdd_device *mdd = m->private;
+       char *kernbuf;
+       int rc;
+       ENTRY;
+@@ -168,45 +124,32 @@ out:
+       OBD_FREE(kernbuf, PAGE_CACHE_SIZE);
+       return rc;
+ }
+-
+-struct cucb_data {
+-        char *page;
+-        int count;
+-        int idx;
+-};
++LPROC_SEQ_FOPS(mdd_changelog_mask);
+ 
+ static int lprocfs_changelog_users_cb(const struct lu_env *env,
+                                     struct llog_handle *llh,
+                                     struct llog_rec_hdr *hdr, void *data)
+ {
+-        struct llog_changelog_user_rec *rec;
+-        struct cucb_data *cucb = (struct cucb_data *)data;
++      struct llog_changelog_user_rec *rec;
++      struct seq_file *m = data;
+ 
+-        LASSERT(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN);
++      LASSERT(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN);
+ 
+-        rec = (struct llog_changelog_user_rec *)hdr;
++      rec = (struct llog_changelog_user_rec *)hdr;
+ 
+-        cucb->idx += snprintf(cucb->page + cucb->idx, cucb->count - cucb->idx,
+-                              CHANGELOG_USER_PREFIX"%-3d "LPU64"\n",
+-                              rec->cur_id, rec->cur_endrec);
+-        if (cucb->idx >= cucb->count)
+-                return -ENOSPC;
+-
+-        return 0;
++      seq_printf(m, CHANGELOG_USER_PREFIX"%-3d "LPU64"\n",
++                 rec->cur_id, rec->cur_endrec);
++      return 0;
+ }
+ 
+-static int lprocfs_rd_changelog_users(char *page, char **start, off_t off,
+-                                      int count, int *eof, void *data)
++static int mdd_changelog_users_seq_show(struct seq_file *m, void *data)
+ {
+       struct lu_env            env;
+-      struct mdd_device       *mdd = data;
++      struct mdd_device       *mdd = m->private;
+       struct llog_ctxt        *ctxt;
+-      struct cucb_data         cucb;
+       __u64                    cur;
+       int                      rc;
+ 
+-        *eof = 1;
+-
+         ctxt = llog_get_context(mdd2obd_dev(mdd),
+                               LLOG_CHANGELOG_USER_ORIG_CTXT);
+         if (ctxt == NULL)
+@@ -223,37 +166,32 @@ static int lprocfs_rd_changelog_users(char *page, char 
**start, off_t off,
+       cur = mdd->mdd_cl.mc_index;
+       spin_unlock(&mdd->mdd_cl.mc_lock);
+ 
+-        cucb.count = count;
+-        cucb.page = page;
+-        cucb.idx = 0;
+-
+-        cucb.idx += snprintf(cucb.page + cucb.idx, cucb.count - cucb.idx,
+-                              "current index: "LPU64"\n", cur);
+-
+-        cucb.idx += snprintf(cucb.page + cucb.idx, cucb.count - cucb.idx,
+-                              "%-5s %s\n", "ID", "index");
++      seq_printf(m, "current index: "LPU64"\n", cur);
++      seq_printf(m, "%-5s %s\n", "ID", "index");
+ 
+       llog_cat_process(&env, ctxt->loc_handle, lprocfs_changelog_users_cb,
+-                       &cucb, 0, 0);
++                       m, 0, 0);
+ 
+       lu_env_fini(&env);
+       llog_ctxt_put(ctxt);
+-      return cucb.idx;
++      return 0;
+ }
++LPROC_SEQ_FOPS_RO(mdd_changelog_users);
+ 
+-static int lprocfs_rd_sync_perm(char *page, char **start, off_t off,
+-                                int count, int *eof, void *data)
++static int mdd_sync_perm_seq_show(struct seq_file *m, void *data)
+ {
+-        struct mdd_device *mdd = data;
++      struct mdd_device *mdd = m->private;
+ 
+-        LASSERT(mdd != NULL);
+-        return snprintf(page, count, "%d\n", mdd->mdd_sync_permission);
++      LASSERT(mdd != NULL);
++      return seq_printf(m, "%d\n", mdd->mdd_sync_permission);
+ }
+ 
+-static int lprocfs_wr_sync_perm(struct file *file, const char *buffer,
+-                                unsigned long count, void *data)
++static ssize_t
++mdd_sync_perm_seq_write(struct file *file, const char *buffer,
++                      size_t count, loff_t *off)
+ {
+-        struct mdd_device *mdd = data;
++      struct seq_file *m = file->private_data;
++      struct mdd_device *mdd = m->private;
+         int val, rc;
+ 
+         LASSERT(mdd != NULL);
+@@ -264,22 +202,22 @@ static int lprocfs_wr_sync_perm(struct file *file, const 
char *buffer,
+         mdd->mdd_sync_permission = !!val;
+         return count;
+ }
++LPROC_SEQ_FOPS(mdd_sync_perm);
+ 
+-static int lprocfs_rd_lfsck_speed_limit(char *page, char **start, off_t off,
+-                                      int count, int *eof, void *data)
++static int mdd_lfsck_speed_limit_seq_show(struct seq_file *m, void *data)
+ {
+-      struct mdd_device *mdd = data;
++      struct mdd_device *mdd = m->private;
+ 
+       LASSERT(mdd != NULL);
+-      *eof = 1;
+-
+-      return lfsck_get_speed(mdd->mdd_bottom, page, count);
++      return lfsck_get_speed(m, mdd->mdd_bottom);
+ }
+ 
+-static int lprocfs_wr_lfsck_speed_limit(struct file *file, const char *buffer,
+-                                      unsigned long count, void *data)
++static ssize_t
++mdd_lfsck_speed_limit_seq_write(struct file *file, const char *buffer,
++                              size_t count, loff_t *off)
+ {
+-      struct mdd_device *mdd = data;
++      struct seq_file *m = file->private_data;
++      struct mdd_device *mdd = m->private;
+       __u32 val;
+       int rc;
+ 
+@@ -291,25 +229,22 @@ static int lprocfs_wr_lfsck_speed_limit(struct file 
*file, const char *buffer,
+       rc = lfsck_set_speed(mdd->mdd_bottom, val);
+       return rc != 0 ? rc : count;
+ }
++LPROC_SEQ_FOPS(mdd_lfsck_speed_limit);
+ 
+-static int lprocfs_rd_lfsck_async_windows(char *page, char **start, off_t off,
+-                                        int count, int *eof, void *data)
++static int mdd_lfsck_async_windows_seq_show(struct seq_file *m, void *data)
+ {
+-      struct mdd_device *mdd = data;
+-      int                rc;
++      struct mdd_device *mdd = m->private;
+ 
+       LASSERT(mdd != NULL);
+-      *eof = 1;
+-
+-      rc = lfsck_get_windows(mdd->mdd_bottom, page, count);
+-
+-      return rc != 0 ? rc : count;
++      return lfsck_get_windows(m, mdd->mdd_bottom);
+ }
+ 
+-static int lprocfs_wr_lfsck_async_windows(struct file *file, const char 
*buffer,
+-                                        unsigned long count, void *data)
++static ssize_t
++mdd_lfsck_async_windows_seq_write(struct file *file, const char *buffer,
++                                size_t count, loff_t *off)
+ {
+-      struct mdd_device *mdd = data;
++      struct seq_file   *m = file->private_data;
++      struct mdd_device *mdd = m->private;
+       __u32              val;
+       int                rc;
+ 
+@@ -320,54 +255,87 @@ static int lprocfs_wr_lfsck_async_windows(struct file 
*file, const char *buffer,
+ 
+       return rc != 0 ? rc : count;
+ }
++LPROC_SEQ_FOPS(mdd_lfsck_async_windows);
+ 
+-static int lprocfs_rd_lfsck_namespace(char *page, char **start, off_t off,
+-                                    int count, int *eof, void *data)
++static int mdd_lfsck_namespace_seq_show(struct seq_file *m, void *data)
+ {
+-      struct mdd_device *mdd = data;
+-      int rc;
++      struct mdd_device *mdd = m->private;
+ 
+       LASSERT(mdd != NULL);
+-      *eof = 1;
+ 
+-      rc = lfsck_dump(mdd->mdd_bottom, page, count, LT_NAMESPACE);
+-      return rc;
++      return lfsck_dump(m, mdd->mdd_bottom, LT_NAMESPACE);
+ }
++LPROC_SEQ_FOPS_RO(mdd_lfsck_namespace);
+ 
+-static int lprocfs_rd_lfsck_layout(char *page, char **start, off_t off,
+-                                 int count, int *eof, void *data)
++static int mdd_lfsck_layout_seq_show(struct seq_file *m, void *data)
+ {
+-      struct mdd_device *mdd = data;
++      struct mdd_device *mdd = m->private;
+ 
+       LASSERT(mdd != NULL);
+-      *eof = 1;
+ 
+-      return lfsck_dump(mdd->mdd_bottom, page, count, LT_LAYOUT);
++      return lfsck_dump(m, mdd->mdd_bottom, LT_LAYOUT);
+ }
+-
+-static struct lprocfs_vars lprocfs_mdd_obd_vars[] = {
+-        { "atime_diff",      lprocfs_rd_atime_diff, lprocfs_wr_atime_diff, 0 
},
+-        { "changelog_mask",  lprocfs_rd_changelog_mask,
+-                             lprocfs_wr_changelog_mask, 0 },
+-        { "changelog_users", lprocfs_rd_changelog_users, 0, 0},
+-        { "sync_permission", lprocfs_rd_sync_perm, lprocfs_wr_sync_perm, 0 },
+-      { "lfsck_speed_limit", lprocfs_rd_lfsck_speed_limit,
+-                             lprocfs_wr_lfsck_speed_limit, 0 },
+-      { "lfsck_async_windows", lprocfs_rd_lfsck_async_windows,
+-                               lprocfs_wr_lfsck_async_windows, 0 },
+-      { "lfsck_namespace", lprocfs_rd_lfsck_namespace, 0, 0 },
+-      { "lfsck_layout", lprocfs_rd_lfsck_layout, 0, 0 },
++LPROC_SEQ_FOPS_RO(mdd_lfsck_layout);
++
++static struct lprocfs_seq_vars lprocfs_mdd_obd_vars[] = {
++      { .name =       "atime_diff",
++        .fops =       &mdd_atime_diff_fops            },
++      { .name =       "changelog_mask",
++        .fops =       &mdd_changelog_mask_fops        },
++      { .name =       "changelog_users",
++        .fops =       &mdd_changelog_users_fops       },
++      { .name =       "sync_permission",
++        .fops =       &mdd_sync_perm_fops             },
++      { .name =       "lfsck_speed_limit",
++        .fops =       &mdd_lfsck_speed_limit_fops     },
++      { .name =       "lfsck_async_windows",
++        .fops =       &mdd_lfsck_async_windows_fops   },
++      { .name =       "lfsck_namespace",
++        .fops =       &mdd_lfsck_namespace_fops       },
++      { .name =       "lfsck_layout",
++        .fops =       &mdd_lfsck_layout_fops          },
+       { 0 }
+ };
+ 
+-static struct lprocfs_vars lprocfs_mdd_module_vars[] = {
+-        { "num_refs",   lprocfs_rd_numrefs, 0, 0 },
+-        { 0 }
+-};
+-
+-void lprocfs_mdd_init_vars(struct lprocfs_static_vars *lvars)
++int mdd_procfs_init(struct mdd_device *mdd, const char *name)
+ {
+-        lvars->module_vars  = lprocfs_mdd_module_vars;
+-        lvars->obd_vars     = lprocfs_mdd_obd_vars;
++      struct obd_device *obd = class_name2obd(name);
++      struct obd_type   *type;
++      int                rc;
++      ENTRY;
++
++      /* at the moment there is no linkage between lu_type
++       * and obd_type, so we lookup obd_type this way */
++      type = class_search_type(LUSTRE_MDD_NAME);
++
++      LASSERT(name != NULL);
++      LASSERT(type != NULL);
++      LASSERT(obd  != NULL);
++
++      /* Find the type procroot and add the proc entry for this device */
++      obd->obd_vars = lprocfs_mdd_obd_vars;
++      mdd->mdd_proc_entry = lprocfs_seq_register(name, type->typ_procroot,
++                                                 obd->obd_vars, mdd);
++      if (IS_ERR(mdd->mdd_proc_entry)) {
++              rc = PTR_ERR(mdd->mdd_proc_entry);
++              CERROR("Error %d setting up lprocfs for %s\n",
++                     rc, name);
++              mdd->mdd_proc_entry = NULL;
++              GOTO(out, rc);
++      }
++      rc = 0;
++      EXIT;
++out:
++      if (rc)
++              mdd_procfs_fini(mdd);
++      return rc;
+ }
+ 
++int mdd_procfs_fini(struct mdd_device *mdd)
++{
++      if (mdd->mdd_proc_entry) {
++              lprocfs_remove(&mdd->mdd_proc_entry);
++              mdd->mdd_proc_entry = NULL;
++      }
++      RETURN(0);
++}
+diff --git a/lustre/ofd/lproc_ofd.c b/lustre/ofd/lproc_ofd.c
+index 359b373..fcde82a 100644
+--- a/lustre/ofd/lproc_ofd.c
++++ b/lustre/ofd/lproc_ofd.c
+@@ -47,81 +47,75 @@
+ 
+ #ifdef LPROCFS
+ 
+-static int lprocfs_ofd_rd_seqs(char *page, char **start, off_t off,
+-                              int count, int *eof, void *data)
++static int ofd_seqs_seq_show(struct seq_file *m, void *data)
+ {
+-      struct obd_device *obd = (struct obd_device *)data;
++      struct obd_device *obd = m->private;
+       struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+ 
+-      *eof = 1;
+-      return snprintf(page, count, "%u\n", ofd->ofd_seq_count);
++      return seq_printf(m, "%u\n", ofd->ofd_seq_count);
+ }
++LPROC_SEQ_FOPS_RO(ofd_seqs);
+ 
+-static int lprocfs_ofd_rd_tot_dirty(char *page, char **start, off_t off,
+-                                  int count, int *eof, void *data)
++static int ofd_tot_dirty_seq_show(struct seq_file *m, void *data)
+ {
+-      struct obd_device *obd = (struct obd_device *)data;
++      struct obd_device *obd = m->private;
+       struct ofd_device *ofd;
+ 
+       LASSERT(obd != NULL);
+       ofd = ofd_dev(obd->obd_lu_dev);
+-      *eof = 1;
+-      return snprintf(page, count, LPU64"\n", ofd->ofd_tot_dirty);
++      return seq_printf(m, LPU64"\n", ofd->ofd_tot_dirty);
+ }
++LPROC_SEQ_FOPS_RO(ofd_tot_dirty);
+ 
+-static int lprocfs_ofd_rd_tot_granted(char *page, char **start, off_t off,
+-                                    int count, int *eof, void *data)
++static int ofd_tot_granted_seq_show(struct seq_file *m, void *data)
+ {
+-      struct obd_device *obd = (struct obd_device *)data;
++      struct obd_device *obd = m->private;
+       struct ofd_device *ofd;
+ 
+       LASSERT(obd != NULL);
+       ofd = ofd_dev(obd->obd_lu_dev);
+-      *eof = 1;
+-      return snprintf(page, count, LPU64"\n", ofd->ofd_tot_granted);
++      return seq_printf(m, LPU64"\n", ofd->ofd_tot_granted);
+ }
++LPROC_SEQ_FOPS_RO(ofd_tot_granted);
+ 
+-static int lprocfs_ofd_rd_tot_pending(char *page, char **start, off_t off,
+-                                    int count, int *eof, void *data)
++static int ofd_tot_pending_seq_show(struct seq_file *m, void *data)
+ {
+-      struct obd_device *obd = (struct obd_device *)data;
++      struct obd_device *obd = m->private;
+       struct ofd_device *ofd;
+ 
+       LASSERT(obd != NULL);
+       ofd = ofd_dev(obd->obd_lu_dev);
+-      *eof = 1;
+-      return snprintf(page, count, LPU64"\n", ofd->ofd_tot_pending);
++      return seq_printf(m, LPU64"\n", ofd->ofd_tot_pending);
+ }
++LPROC_SEQ_FOPS_RO(ofd_tot_pending);
+ 
+-static int lprocfs_ofd_rd_grant_precreate(char *page, char **start, off_t off,
+-                                        int count, int *eof, void *data)
++static int ofd_grant_precreate_seq_show(struct seq_file *m, void *data)
+ {
+-      struct obd_device *obd = (struct obd_device *)data;
++      struct obd_device *obd = m->private;
+ 
+       LASSERT(obd != NULL);
+-      *eof = 1;
+-      return snprintf(page, count, "%ld\n",
+-                      obd->obd_self_export->exp_filter_data.fed_grant);
++      return seq_printf(m, "%ld\n",
++                        obd->obd_self_export->exp_filter_data.fed_grant);
+ }
++LPROC_SEQ_FOPS_RO(ofd_grant_precreate);
+ 
+-static int lprocfs_ofd_rd_grant_ratio(char *page, char **start, off_t off,
+-                                    int count, int *eof, void *data)
++static int ofd_grant_ratio_seq_show(struct seq_file *m, void *data)
+ {
+-      struct obd_device *obd = (struct obd_device *)data;
++      struct obd_device *obd = m->private;
+       struct ofd_device *ofd;
+ 
+       LASSERT(obd != NULL);
+       ofd = ofd_dev(obd->obd_lu_dev);
+-      *eof = 1;
+-      return snprintf(page, count, "%d%%\n",
+-                      (int) ofd_grant_reserved(ofd, 100));
++      return seq_printf(m, "%d%%\n",
++                        (int) ofd_grant_reserved(ofd, 100));
+ }
+ 
+-static int lprocfs_ofd_wr_grant_ratio(struct file *file,
+-                                    const char __user *buffer,
+-                                    unsigned long count, void *data)
++static ssize_t
++ofd_grant_ratio_seq_write(struct file *file, const char __user *buffer,
++                        size_t count, loff_t *off)
+ {
+-      struct obd_device       *obd = (struct obd_device *)data;
++      struct seq_file         *m = file->private_data;
++      struct obd_device       *obd = m->private;
+       struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
+       int                      val;
+       int                      rc;
+@@ -145,24 +139,24 @@ static int lprocfs_ofd_wr_grant_ratio(struct file *file,
+       spin_unlock(&ofd->ofd_grant_lock);
+       return count;
+ }
++LPROC_SEQ_FOPS(ofd_grant_ratio);
+ 
+-static int lprocfs_ofd_rd_precreate_batch(char *page, char **start, off_t off,
+-                                        int count, int *eof, void *data)
++static int ofd_precreate_batch_seq_show(struct seq_file *m, void *data)
+ {
+-      struct obd_device *obd = (struct obd_device *)data;
++      struct obd_device *obd = m->private;
+       struct ofd_device *ofd;
+ 
+       LASSERT(obd != NULL);
+       ofd = ofd_dev(obd->obd_lu_dev);
+-      *eof = 1;
+-      return snprintf(page, count, "%d\n", ofd->ofd_precreate_batch);
++      return seq_printf(m, "%d\n", ofd->ofd_precreate_batch);
+ }
+ 
+-static int lprocfs_ofd_wr_precreate_batch(struct file *file,
+-                                        const char __user *buffer,
+-                                        unsigned long count, void *data)
++static ssize_t
++ofd_precreate_batch_seq_write(struct file *file, const char __user *buffer,
++                            size_t count, loff_t *off)
+ {
+-      struct obd_device *obd = (struct obd_device *)data;
++      struct seq_file   *m = file->private_data;
++      struct obd_device *obd = m->private;
+       struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+       int val;
+       int rc;
+@@ -179,11 +173,11 @@ static int lprocfs_ofd_wr_precreate_batch(struct file 
*file,
+       spin_unlock(&ofd->ofd_batch_lock);
+       return count;
+ }
++LPROC_SEQ_FOPS(ofd_precreate_batch);
+ 
+-static int lprocfs_ofd_rd_last_id(char *page, char **start, off_t off,
+-                                int count, int *eof, void *data)
++static int ofd_last_id_seq_show(struct seq_file *m, void *data)
+ {
+-      struct obd_device       *obd = data;
++      struct obd_device       *obd = m->private;
+       struct ofd_device       *ofd;
+       struct ofd_seq          *oseq = NULL;
+       int                     retval = 0, rc;
+@@ -201,35 +195,32 @@ static int lprocfs_ofd_rd_last_id(char *page, char 
**start, off_t off,
+                     fid_idif_seq(ostid_id(&oseq->os_oi),
+                                  ofd->ofd_lut.lut_lsd.lsd_osd_index) :
+                     ostid_seq(&oseq->os_oi);
+-              rc = snprintf(page, count, DOSTID"\n", seq,
+-                            ostid_id(&oseq->os_oi));
++              rc = seq_printf(m, DOSTID"\n", seq, ostid_id(&oseq->os_oi));
+               if (rc < 0) {
+                       retval = rc;
+                       break;
+               }
+-              page += rc;
+-              count -= rc;
+               retval += rc;
+       }
+       read_unlock(&ofd->ofd_seq_list_lock);
+       return retval;
+ }
++LPROC_SEQ_FOPS_RO(ofd_last_id);
+ 
+-int lprocfs_ofd_rd_fmd_max_num(char *page, char **start, off_t off,
+-                             int count, int *eof, void *data)
++static int ofd_fmd_max_num_seq_show(struct seq_file *m, void *data)
+ {
+-      struct obd_device       *obd = data;
+-      struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
+-      int                      rc;
++      struct obd_device *obd = m->private;
++      struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+ 
+-      rc = snprintf(page, count, "%u\n", ofd->ofd_fmd_max_num);
+-      return rc;
++      return seq_printf(m, "%u\n", ofd->ofd_fmd_max_num);
+ }
+ 
+-int lprocfs_ofd_wr_fmd_max_num(struct file *file, const char __user *buffer,
+-                             unsigned long count, void *data)
++static ssize_t
++ofd_fmd_max_num_seq_write(struct file *file, const char __user *buffer,
++                        size_t count, loff_t *off)
+ {
+-      struct obd_device       *obd = data;
++      struct seq_file         *m = file->private_data;
++      struct obd_device       *obd = m->private;
+       struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
+       int                      val;
+       int                      rc;
+@@ -244,22 +235,22 @@ int lprocfs_ofd_wr_fmd_max_num(struct file *file, const 
char __user *buffer,
+       ofd->ofd_fmd_max_num = val;
+       return count;
+ }
++LPROC_SEQ_FOPS(ofd_fmd_max_num);
+ 
+-int lprocfs_ofd_rd_fmd_max_age(char *page, char **start, off_t off,
+-                             int count, int *eof, void *data)
++static int ofd_fmd_max_age_seq_show(struct seq_file *m, void *data)
+ {
+-      struct obd_device       *obd = data;
+-      struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
+-      int                      rc;
++      struct obd_device *obd = m->private;
++      struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+ 
+-      rc = snprintf(page, count, "%ld\n", ofd->ofd_fmd_max_age / HZ);
+-      return rc;
++      return seq_printf(m, "%ld\n", ofd->ofd_fmd_max_age / HZ);
+ }
+ 
+-int lprocfs_ofd_wr_fmd_max_age(struct file *file, const char __user *buffer,
+-                             unsigned long count, void *data)
++static ssize_t
++ofd_fmd_max_age_seq_write(struct file *file, const char __user *buffer,
++                        size_t count, loff_t *off)
+ {
+-      struct obd_device       *obd = data;
++      struct seq_file         *m = file->private_data;
++      struct obd_device       *obd = m->private;
+       struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
+       int                      val;
+       int                      rc;
+@@ -274,22 +265,22 @@ int lprocfs_ofd_wr_fmd_max_age(struct file *file, const 
char __user *buffer,
+       ofd->ofd_fmd_max_age = val * HZ;
+       return count;
+ }
++LPROC_SEQ_FOPS(ofd_fmd_max_age);
+ 
+-static int lprocfs_ofd_rd_capa(char *page, char **start, off_t off,
+-                             int count, int *eof, void *data)
++static int ofd_capa_seq_show(struct seq_file *m, void *data)
+ {
+-      struct obd_device       *obd = data;
+-      int                      rc;
++      struct obd_device       *obd = m->private;
+ 
+-      rc = snprintf(page, count, "capability on: %s\n",
+-                    obd->u.filter.fo_fl_oss_capa ? "oss" : "");
+-      return rc;
++      return seq_printf(m, "capability on: %s\n",
++                        obd->u.filter.fo_fl_oss_capa ? "oss" : "");
+ }
+ 
+-static int lprocfs_ofd_wr_capa(struct file *file, const char __user *buffer,
+-                             unsigned long count, void *data)
++static ssize_t
++ofd_capa_seq_write(struct file *file, const char *__user buffer, size_t count,
++                 loff_t *off)
+ {
+-      struct obd_device       *obd = data;
++      struct seq_file         *m = file->private_data;
++      struct obd_device       *obd = m->private;
+       int                      val, rc;
+ 
+       rc = lprocfs_write_helper(buffer, count, &val);
+@@ -308,28 +299,29 @@ static int lprocfs_ofd_wr_capa(struct file *file, const 
char __user *buffer,
+                     val ? "enabled" : "disabled");
+       return count;
+ }
++LPROC_SEQ_FOPS(ofd_capa);
+ 
+-static int lprocfs_ofd_rd_capa_count(char *page, char **start, off_t off,
+-                                   int count, int *eof, void *data)
++static int ofd_capa_count_seq_show(struct seq_file *m, void *data)
+ {
+-      return snprintf(page, count, "%d %d\n",
+-                      capa_count[CAPA_SITE_CLIENT],
+-                      capa_count[CAPA_SITE_SERVER]);
++      return seq_printf(m, "%d %d\n", capa_count[CAPA_SITE_CLIENT],
++                        capa_count[CAPA_SITE_SERVER]);
+ }
++LPROC_SEQ_FOPS_RO(ofd_capa_count);
+ 
+-int lprocfs_ofd_rd_degraded(char *page, char **start, off_t off,
+-                          int count, int *eof, void *data)
++static int ofd_degraded_seq_show(struct seq_file *m, void *data)
+ {
+-      struct obd_device *obd = data;
++      struct obd_device *obd = m->private;
+       struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+ 
+-      return snprintf(page, count, "%u\n", ofd->ofd_raid_degraded);
++      return seq_printf(m, "%u\n", ofd->ofd_raid_degraded);
+ }
+ 
+-int lprocfs_ofd_wr_degraded(struct file *file, const char __user *buffer,
+-                          unsigned long count, void *data)
++static ssize_t
++ofd_degraded_seq_write(struct file *file, const char __user *buffer,
++                     size_t count, loff_t *off)
+ {
+-      struct obd_device       *obd = data;
++      struct seq_file         *m = file->private_data;
++      struct obd_device       *obd = m->private;
+       struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
+       int                      val, rc;
+ 
+@@ -340,38 +332,37 @@ int lprocfs_ofd_wr_degraded(struct file *file, const 
char __user *buffer,
+       spin_lock(&ofd->ofd_flags_lock);
+       ofd->ofd_raid_degraded = !!val;
+       spin_unlock(&ofd->ofd_flags_lock);
+-
+       return count;
+ }
++LPROC_SEQ_FOPS(ofd_degraded);
+ 
+-int lprocfs_ofd_rd_fstype(char *page, char **start, off_t off, int count,
+-                        int *eof, void *data)
++static int ofd_fstype_seq_show(struct seq_file *m, void *data)
+ {
+-      struct obd_device *obd = data;
++      struct obd_device *obd = m->private;
+       struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+       struct lu_device  *d;
+ 
+       LASSERT(ofd->ofd_osd);
+       d = &ofd->ofd_osd->dd_lu_dev;
+       LASSERT(d->ld_type);
+-      return snprintf(page, count, "%s\n", d->ld_type->ldt_name);
++      return seq_printf(m, "%s\n", d->ld_type->ldt_name);
+ }
++LPROC_SEQ_FOPS_RO(ofd_fstype);
+ 
+-int lprocfs_ofd_rd_syncjournal(char *page, char **start, off_t off,
+-                             int count, int *eof, void *data)
++static int ofd_syncjournal_seq_show(struct seq_file *m, void *data)
+ {
+-      struct obd_device       *obd = data;
++      struct obd_device       *obd = m->private;
+       struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
+-      int                      rc;
+ 
+-      rc = snprintf(page, count, "%u\n", ofd->ofd_syncjournal);
+-      return rc;
++      return seq_printf(m, "%u\n", ofd->ofd_syncjournal);
+ }
+ 
+-int lprocfs_ofd_wr_syncjournal(struct file *file, const char __user *buffer,
+-                             unsigned long count, void *data)
++static ssize_t
++ofd_syncjournal_seq_write(struct file *file, const char __user *buffer,
++                        size_t count, loff_t *off)
+ {
+-      struct obd_device       *obd = data;
++      struct seq_file         *m = file->private_data;
++      struct obd_device       *obd = m->private;
+       struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
+       int                      val;
+       int                      rc;
+@@ -390,6 +381,7 @@ int lprocfs_ofd_wr_syncjournal(struct file *file, const 
char __user *buffer,
+ 
+       return count;
+ }
++LPROC_SEQ_FOPS(ofd_syncjournal);
+ 
+ /* This must be longer than the longest string below */
+ #define SYNC_STATES_MAXLEN 16
+@@ -397,23 +389,21 @@ static char *sync_on_cancel_states[] = {"never",
+                                       "blocking",
+                                       "always" };
+ 
+-int lprocfs_ofd_rd_sync_lock_cancel(char *page, char **start, off_t off,
+-                                  int count, int *eof, void *data)
++static int ofd_sync_lock_cancel_seq_show(struct seq_file *m, void *data)
+ {
+-      struct obd_device       *obd = data;
++      struct obd_device       *obd = m->private;
+       struct lu_target        *tgt = obd->u.obt.obt_lut;
+-      int                      rc;
+ 
+-      rc = snprintf(page, count, "%s\n",
+-                    sync_on_cancel_states[tgt->lut_sync_lock_cancel]);
+-      return rc;
++      return seq_printf(m, "%s\n",
++                        sync_on_cancel_states[tgt->lut_sync_lock_cancel]);
+ }
+ 
+-int lprocfs_ofd_wr_sync_lock_cancel(struct file *file,
+-                                  const char __user *buffer,
+-                                  unsigned long count, void *data)
++static ssize_t
++ofd_sync_lock_cancel_seq_write(struct file *file, const char __user *buffer,
++                             size_t count, loff_t *off)
+ {
+-      struct obd_device       *obd = data;
++      struct seq_file         *m = file->private_data;
++      struct obd_device       *obd = m->private;
+       struct lu_target        *tgt = obd->u.obt.obt_lut;
+       char                     kernbuf[SYNC_STATES_MAXLEN];
+       int                      val = -1;
+@@ -455,23 +445,23 @@ int lprocfs_ofd_wr_sync_lock_cancel(struct file *file,
+       spin_unlock(&tgt->lut_flags_lock);
+       return count;
+ }
++LPROC_SEQ_FOPS(ofd_sync_lock_cancel);
+ 
+-int lprocfs_ofd_rd_grant_compat_disable(char *page, char **start, off_t off,
+-                                      int count, int *eof, void *data)
++static int ofd_grant_compat_disable_seq_show(struct seq_file *m, void *data)
+ {
+-      struct obd_device       *obd = data;
+-      struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
+-      int                      rc;
++      struct obd_device *obd = m->private;
++      struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+ 
+-      rc = snprintf(page, count, "%u\n", ofd->ofd_grant_compat_disable);
+-      return rc;
++      return seq_printf(m, "%u\n", ofd->ofd_grant_compat_disable);
+ }
+ 
+-int lprocfs_ofd_wr_grant_compat_disable(struct file *file,
+-                                      const char __user *buffer,
+-                                      unsigned long count, void *data)
++static ssize_t
++ofd_grant_compat_disable_seq_write(struct file *file,
++                                 const char __user *buffer,
++                                 size_t count, loff_t *off)
+ {
+-      struct obd_device       *obd = data;
++      struct seq_file         *m = file->private_data;
++      struct obd_device       *obd = m->private;
+       struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
+       int                      val;
+       int                      rc;
+@@ -489,42 +479,43 @@ int lprocfs_ofd_wr_grant_compat_disable(struct file 
*file,
+ 
+       return count;
+ }
++LPROC_SEQ_FOPS(ofd_grant_compat_disable);
+ 
+-int lprocfs_ofd_rd_soft_sync_limit(char *page, char **start, off_t off,
+-                                 int count, int *eof, void *data)
++static int ofd_soft_sync_limit_seq_show(struct seq_file *m, void *data)
+ {
+-      struct obd_device       *obd = data;
++      struct obd_device       *obd = m->private;
+       struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
+ 
+-      return lprocfs_rd_uint(page, start, off, count, eof,
+-                             &ofd->ofd_soft_sync_limit);
++      return lprocfs_uint_seq_show(m, &ofd->ofd_soft_sync_limit);
+ }
+ 
+-int lprocfs_ofd_wr_soft_sync_limit(struct file *file, const char __user 
*buffer,
+-                                 unsigned long count, void *data)
++static ssize_t
++ofd_soft_sync_limit_seq_write(struct file *file, const char __user *buffer,
++                            size_t count, loff_t *off)
+ {
+-      struct obd_device       *obd = data;
+-      struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
++      struct seq_file   *m = file->private_data;
++      struct obd_device *obd = m->private;
++      struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+ 
+-      return lprocfs_wr_uint(file, buffer, count, &ofd->ofd_soft_sync_limit);
++      return lprocfs_uint_seq_write(file, buffer, count,
++                                    (loff_t *) &ofd->ofd_soft_sync_limit);
+ }
++LPROC_SEQ_FOPS(ofd_soft_sync_limit);
+ 
+-static int lprocfs_rd_lfsck_speed_limit(char *page, char **start, off_t off,
+-                                      int count, int *eof, void *data)
++static int ofd_lfsck_speed_limit_seq_show(struct seq_file *m, void *data)
+ {
+-      struct obd_device       *obd = data;
++      struct obd_device       *obd = m->private;
+       struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
+ 
+-      *eof = 1;
+-
+-      return lfsck_get_speed(ofd->ofd_osd, page, count);
++      return lfsck_get_speed(m, ofd->ofd_osd);
+ }
+ 
+-static int lprocfs_wr_lfsck_speed_limit(struct file *file,
+-                                      const char __user *buffer,
+-                                      unsigned long count, void *data)
++static ssize_t
++ofd_lfsck_speed_limit_seq_write(struct file *file, const char __user *buffer,
++                              size_t count, loff_t *off)
+ {
+-      struct obd_device       *obd = data;
++      struct seq_file         *m = file->private_data;
++      struct obd_device       *obd = m->private;
+       struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
+       __u32                    val;
+       int                      rc;
+@@ -537,38 +528,35 @@ static int lprocfs_wr_lfsck_speed_limit(struct file 
*file,
+ 
+       return rc != 0 ? rc : count;
+ }
++LPROC_SEQ_FOPS(ofd_lfsck_speed_limit);
+ 
+-static int lprocfs_rd_lfsck_layout(char *page, char **start, off_t off,
+-                                 int count, int *eof, void *data)
++static int ofd_lfsck_layout_seq_show(struct seq_file *m, void *data)
+ {
+-      struct obd_device       *obd = data;
+-      struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
+-
+-      *eof = 1;
++      struct obd_device *obd = m->private;
++      struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+ 
+-      return lfsck_dump(ofd->ofd_osd, page, count, LT_LAYOUT);
++      return lfsck_dump(m, ofd->ofd_osd, LT_LAYOUT);
+ }
++LPROC_SEQ_FOPS_RO(ofd_lfsck_layout);
+ 
+-static int lprocfs_rd_lfsck_verify_pfid(char *page, char **start, off_t off,
+-                                      int count, int *eof, void *data)
++static int ofd_lfsck_verify_pfid_seq_show(struct seq_file *m, void *data)
+ {
+-      struct obd_device       *obd = data;
+-      struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
+-
+-      *eof = 1;
++      struct obd_device *obd = m->private;
++      struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+ 
+-      return snprintf(page, count,
+-                      "switch: %s\ndetected: "LPU64"\nrepaired: "LPU64"\n",
+-                      ofd->ofd_lfsck_verify_pfid ? "on" : "off",
+-                      ofd->ofd_inconsistency_self_detected,
+-                      ofd->ofd_inconsistency_self_repaired);
++      return seq_printf(m,
++                        "switch: %s\ndetected: "LPU64"\nrepaired: "LPU64"\n",
++                        ofd->ofd_lfsck_verify_pfid ? "on" : "off",
++                        ofd->ofd_inconsistency_self_detected,
++                        ofd->ofd_inconsistency_self_repaired);
+ }
+ 
+-static int lprocfs_wr_lfsck_verify_pfid(struct file *file,
+-                                      const char __user *buffer,
+-                                      unsigned long count, void *data)
++static ssize_t
++ofd_lfsck_verify_pfid_seq_write(struct file *file, const char __user *buffer,
++                              size_t count, loff_t *off)
+ {
+-      struct obd_device       *obd = data;
++      struct seq_file         *m = file->private_data;
++      struct obd_device       *obd = m->private;
+       struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
+       __u32                    val;
+       int                      rc;
+@@ -581,75 +569,101 @@ static int lprocfs_wr_lfsck_verify_pfid(struct file 
*file,
+ 
+       return count;
+ }
+-
+-static struct lprocfs_vars lprocfs_ofd_obd_vars[] = {
+-      { "uuid",                lprocfs_rd_uuid, 0, 0 },
+-      { "blocksize",           lprocfs_rd_blksize, 0, 0 },
+-      { "kbytestotal",         lprocfs_rd_kbytestotal, 0, 0 },
+-      { "kbytesfree",          lprocfs_rd_kbytesfree, 0, 0 },
+-      { "kbytesavail",         lprocfs_rd_kbytesavail, 0, 0 },
+-      { "filestotal",          lprocfs_rd_filestotal, 0, 0 },
+-      { "filesfree",           lprocfs_rd_filesfree, 0, 0 },
+-      { "seqs_allocated",      lprocfs_ofd_rd_seqs, 0, 0 },
+-      { "fstype",              lprocfs_ofd_rd_fstype, 0, 0 },
+-      { "last_id",             lprocfs_ofd_rd_last_id, 0, 0 },
+-      { "tot_dirty",           lprocfs_ofd_rd_tot_dirty,   0, 0 },
+-      { "tot_pending",         lprocfs_ofd_rd_tot_pending, 0, 0 },
+-      { "tot_granted",         lprocfs_ofd_rd_tot_granted, 0, 0 },
+-      { "grant_precreate",     lprocfs_ofd_rd_grant_precreate, 0, 0 },
+-      { "grant_ratio",         lprocfs_ofd_rd_grant_ratio,
+-                               lprocfs_ofd_wr_grant_ratio, 0, 0 },
+-      { "precreate_batch",     lprocfs_ofd_rd_precreate_batch,
+-                               lprocfs_ofd_wr_precreate_batch, 0 },
+-      { "recovery_status",     lprocfs_obd_rd_recovery_status, 0, 0 },
+-      { "recovery_time_soft",  lprocfs_obd_rd_recovery_time_soft,
+-                               lprocfs_obd_wr_recovery_time_soft, 0},
+-      { "recovery_time_hard",  lprocfs_obd_rd_recovery_time_hard,
+-                               lprocfs_obd_wr_recovery_time_hard, 0},
+-      { "evict_client",        0, lprocfs_wr_evict_client, 0,
+-                               &lprocfs_evict_client_fops},
+-      { "num_exports",         lprocfs_rd_num_exports,   0, 0 },
+-      { "degraded",            lprocfs_ofd_rd_degraded,
+-                               lprocfs_ofd_wr_degraded, 0},
+-      { "sync_journal",        lprocfs_ofd_rd_syncjournal,
+-                               lprocfs_ofd_wr_syncjournal, 0 },
+-      { "sync_on_lock_cancel", lprocfs_ofd_rd_sync_lock_cancel,
+-                               lprocfs_ofd_wr_sync_lock_cancel, 0 },
+-      { "instance",            lprocfs_target_rd_instance, 0 },
+-      { "ir_factor",           lprocfs_obd_rd_ir_factor,
+-                               lprocfs_obd_wr_ir_factor, 0},
+-      { "grant_compat_disable", lprocfs_ofd_rd_grant_compat_disable,
+-                                lprocfs_ofd_wr_grant_compat_disable, 0 },
+-      { "client_cache_count",  lprocfs_ofd_rd_fmd_max_num,
+-                               lprocfs_ofd_wr_fmd_max_num, 0 },
+-      { "client_cache_seconds", lprocfs_ofd_rd_fmd_max_age,
+-                                lprocfs_ofd_wr_fmd_max_age, 0 },
+-      { "capa",                lprocfs_ofd_rd_capa,
+-                               lprocfs_ofd_wr_capa, 0 },
+-      { "capa_count",          lprocfs_ofd_rd_capa_count, 0, 0 },
+-      { "job_cleanup_interval", lprocfs_rd_job_interval,
+-                                lprocfs_wr_job_interval, 0},
+-      { "soft_sync_limit",     lprocfs_ofd_rd_soft_sync_limit,
+-                               lprocfs_ofd_wr_soft_sync_limit, 0},
+-      { "lfsck_speed_limit",  lprocfs_rd_lfsck_speed_limit,
+-                              lprocfs_wr_lfsck_speed_limit, 0 },
+-      { "lfsck_layout",       lprocfs_rd_lfsck_layout, 0, 0 },
+-      { "lfsck_verify_pfid",  lprocfs_rd_lfsck_verify_pfid,
+-                              lprocfs_wr_lfsck_verify_pfid, 0 },
+-      { 0 }
+-};
+-
+-static struct lprocfs_vars lprocfs_ofd_module_vars[] = {
+-      { "num_refs",     lprocfs_rd_numrefs,   0, 0 },
++LPROC_SEQ_FOPS(ofd_lfsck_verify_pfid);
++
++LPROC_SEQ_FOPS_RO_TYPE(ofd, uuid);
++LPROC_SEQ_FOPS_RO_TYPE(ofd, blksize);
++LPROC_SEQ_FOPS_RO_TYPE(ofd, kbytestotal);
++LPROC_SEQ_FOPS_RO_TYPE(ofd, kbytesfree);
++LPROC_SEQ_FOPS_RO_TYPE(ofd, kbytesavail);
++LPROC_SEQ_FOPS_RO_TYPE(ofd, filestotal);
++LPROC_SEQ_FOPS_RO_TYPE(ofd, filesfree);
++
++LPROC_SEQ_FOPS_RO_TYPE(ofd, recovery_status);
++LPROC_SEQ_FOPS_RW_TYPE(ofd, recovery_time_soft);
++LPROC_SEQ_FOPS_RW_TYPE(ofd, recovery_time_hard);
++LPROC_SEQ_FOPS_WO_TYPE(ofd, evict_client);
++LPROC_SEQ_FOPS_RO_TYPE(ofd, num_exports);
++LPROC_SEQ_FOPS_RO_TYPE(ofd, target_instance);
++LPROC_SEQ_FOPS_RW_TYPE(ofd, ir_factor);
++LPROC_SEQ_FOPS_RW_TYPE(ofd, job_interval);
++
++struct lprocfs_seq_vars lprocfs_ofd_obd_vars[] = {
++      { .name =       "uuid",
++        .fops =       &ofd_uuid_fops                  },
++      { .name =       "blocksize",
++        .fops =       &ofd_blksize_fops               },
++      { .name =       "kbytestotal",
++        .fops =       &ofd_kbytestotal_fops           },
++      { .name =       "kbytesfree",
++        .fops =       &ofd_kbytesfree_fops            },
++      { .name =       "kbytesavail",
++        .fops =       &ofd_kbytesavail_fops           },
++      { .name =       "filestotal",
++        .fops =       &ofd_filestotal_fops            },
++      { .name =       "filesfree",
++        .fops =       &ofd_filesfree_fops             },
++      { .name =       "seqs_allocated",
++        .fops =       &ofd_seqs_fops                  },
++      { .name =       "fstype",
++        .fops =       &ofd_fstype_fops                },
++      { .name =       "last_id",
++        .fops =       &ofd_last_id_fops               },
++      { .name =       "tot_dirty",
++        .fops =       &ofd_tot_dirty_fops             },
++      { .name =       "tot_pending",
++        .fops =       &ofd_tot_pending_fops           },
++      { .name =       "tot_granted",
++        .fops =       &ofd_tot_granted_fops           },
++      { .name =       "grant_precreate",
++        .fops =       &ofd_grant_precreate_fops       },
++      { .name =       "grant_ratio",
++        .fops =       &ofd_grant_ratio_fops           },
++      { .name =       "precreate_batch",
++        .fops =       &ofd_precreate_batch_fops       },
++      { .name =       "recovery_status",
++        .fops =       &ofd_recovery_status_fops       },
++      { .name =       "recovery_time_soft",
++        .fops =       &ofd_recovery_time_soft_fops    },
++      { .name =       "recovery_time_hard",
++        .fops =       &ofd_recovery_time_hard_fops    },
++      { .name =       "evict_client",
++        .fops =       &ofd_evict_client_fops          },
++      { .name =       "num_exports",
++        .fops =       &ofd_num_exports_fops           },
++      { .name =       "degraded",
++        .fops =       &ofd_degraded_fops              },
++      { .name =       "sync_journal",
++        .fops =       &ofd_syncjournal_fops           },
++      { .name =       "sync_on_lock_cancel",
++        .fops =       &ofd_sync_lock_cancel_fops      },
++      { .name =       "instance",
++        .fops =       &ofd_target_instance_fops       },
++      { .name =       "ir_factor",
++        .fops =       &ofd_ir_factor_fops             },
++      { .name =       "grant_compat_disable",
++        .fops =       &ofd_grant_compat_disable_fops  },
++      { .name =       "client_cache_count",
++        .fops =       &ofd_fmd_max_num_fops           },
++      { .name =       "client_cache_seconds",
++        .fops =       &ofd_fmd_max_age_fops           },
++      { .name =       "capa",
++        .fops =       &ofd_capa_fops                  },
++      { .name =       "capa_count",
++        .fops =       &ofd_capa_count_fops            },
++      { .name =       "job_cleanup_interval",
++        .fops =       &ofd_job_interval_fops          },
++      { .name =       "soft_sync_limit",
++        .fops =       &ofd_soft_sync_limit_fops       },
++      { .name =       "lfsck_speed_limit",
++        .fops =       &ofd_lfsck_speed_limit_fops     },
++      { .name =       "lfsck_layout",
++        .fops =       &ofd_lfsck_layout_fops          },
++      { .name =       "lfsck_verify_pfid",
++        .fops =       &ofd_lfsck_verify_pfid_fops     },
+       { 0 }
+ };
+ 
+-void lprocfs_ofd_init_vars(struct lprocfs_static_vars *lvars)
+-{
+-      lvars->module_vars  = lprocfs_ofd_module_vars;
+-      lvars->obd_vars     = lprocfs_ofd_obd_vars;
+-}
+-
+ void ofd_stats_counter_init(struct lprocfs_stats *stats)
+ {
+       LASSERT(stats && stats->ls_num >= LPROC_OFD_STATS_LAST);
+diff --git a/lustre/ofd/ofd_dev.c b/lustre/ofd/ofd_dev.c
+index 0f0d51a..6172913 100644
+--- a/lustre/ofd/ofd_dev.c
++++ b/lustre/ofd/ofd_dev.c
+@@ -239,8 +239,7 @@ static int ofd_process_config(const struct lu_env *env, 
struct lu_device *d,
+ 
+       switch (cfg->lcfg_command) {
+       case LCFG_PARAM: {
+-              struct lprocfs_static_vars lvars;
+-
++              struct obd_device       *obd = ofd_obd(m);
+               /* For interoperability */
+               struct cfg_interop_param   *ptr = NULL;
+               struct lustre_cfg          *old_cfg = NULL;
+@@ -278,8 +277,7 @@ static int ofd_process_config(const struct lu_env *env, 
struct lu_device *d,
+                       break;
+               }
+ 
+-              lprocfs_ofd_init_vars(&lvars);
+-              rc = class_process_proc_param(PARAM_OST, lvars.obd_vars, cfg,
++              rc = class_process_proc_seq_param(PARAM_OST, obd->obd_vars, cfg,
+                                             d->ld_obd);
+               if (rc > 0 || rc == -ENOSYS) {
+                       CDEBUG(D_CONFIG, "pass param %s down the stack.\n",
+@@ -485,9 +483,10 @@ static struct lu_device_operations ofd_lu_ops = {
+       .ldo_prepare            = ofd_prepare,
+ };
+ 
++LPROC_SEQ_FOPS(lprocfs_nid_stats_clear);
++
+ static int ofd_procfs_init(struct ofd_device *ofd)
+ {
+-      struct lprocfs_static_vars       lvars;
+       struct obd_device               *obd = ofd_obd(ofd);
+       cfs_proc_dir_entry_t            *entry;
+       int                              rc = 0;
+@@ -496,8 +495,8 @@ static int ofd_procfs_init(struct ofd_device *ofd)
+ 
+       /* lprocfs must be setup before the ofd so state can be safely added
+        * to /proc incrementally as the ofd is setup */
+-      lprocfs_ofd_init_vars(&lvars);
+-      rc = lprocfs_obd_setup(obd, lvars.obd_vars);
++      obd->obd_vars = lprocfs_ofd_obd_vars;
++      rc = lprocfs_seq_obd_setup(obd);
+       if (rc) {
+               CERROR("%s: lprocfs_obd_setup failed: %d.\n",
+                      obd->obd_name, rc);
+@@ -513,7 +512,8 @@ static int ofd_procfs_init(struct ofd_device *ofd)
+ 
+       obd->obd_uses_nid_stats = 1;
+ 
+-      entry = lprocfs_register("exports", obd->obd_proc_entry, NULL, NULL);
++      entry = lprocfs_seq_register("exports", obd->obd_proc_entry, NULL,
++                                   NULL);
+       if (IS_ERR(entry)) {
+               rc = PTR_ERR(entry);
+               CERROR("%s: error %d setting up lprocfs for %s\n",
+@@ -523,8 +523,10 @@ static int ofd_procfs_init(struct ofd_device *ofd)
+       obd->obd_proc_exports_entry = entry;
+ 
+       entry = lprocfs_add_simple(obd->obd_proc_exports_entry, "clear",
+-                                 lprocfs_nid_stats_clear_read,
+-                                 lprocfs_nid_stats_clear_write, obd, NULL);
++#ifndef HAVE_ONLY_PROCFS_SEQ
++                                 NULL, NULL,
++#endif
++                                 obd, &lprocfs_nid_stats_clear_fops);
+       if (IS_ERR(entry)) {
+               rc = PTR_ERR(entry);
+               CERROR("%s: add proc entry 'clear' failed: %d.\n",
+@@ -540,7 +542,7 @@ static int ofd_procfs_init(struct ofd_device *ofd)
+               GOTO(remove_entry_clear, rc);
+       RETURN(0);
+ remove_entry_clear:
+-      lprocfs_remove_proc_entry("clear", obd->obd_proc_exports_entry);
++      lprocfs_remove(&obd->obd_proc_exports_entry);
+ obd_cleanup:
+       lprocfs_obd_cleanup(obd);
+       lprocfs_free_obd_stats(obd);
+@@ -548,51 +550,48 @@ obd_cleanup:
+       return rc;
+ }
+ 
++/**
++ * ofd_procfs_add_brw_stats_symlink - expose osd stats to ofd layer
++ *
++ * The osd interfaces to the backend file system exposes useful data
++ * such as brw_stats and read or write cache states. This same data
++ * needs to be exposed into the obdfilter (ofd) layer to maintain
++ * backwards compatibility. This function creates the symlinks in the
++ * proc layer to enable this.
++ */
+ static void ofd_procfs_add_brw_stats_symlink(struct ofd_device *ofd)
+ {
+       struct obd_device       *obd = ofd_obd(ofd);
+       struct obd_device       *osd_obd = ofd->ofd_osd_exp->exp_obd;
+-      cfs_proc_dir_entry_t    *osd_root = osd_obd->obd_type->typ_procroot;
+-      cfs_proc_dir_entry_t    *osd_dir;
+ 
+-      osd_dir = lprocfs_srch(osd_root, obd->obd_name);
+-      if (osd_dir == NULL)
++      if (obd->obd_proc_entry == NULL)
+               return;
+ 
+-      if (lprocfs_srch(osd_dir, "brw_stats") != NULL)
+-              lprocfs_add_symlink("brw_stats", obd->obd_proc_entry,
+-                                  "../../%s/%s/brw_stats",
+-                                  osd_root->name, osd_dir->name);
+-
+-      if (lprocfs_srch(osd_dir, "read_cache_enable") != NULL)
+-              lprocfs_add_symlink("read_cache_enable", obd->obd_proc_entry,
+-                                  "../../%s/%s/read_cache_enable",
+-                                  osd_root->name, osd_dir->name);
+-
+-      if (lprocfs_srch(osd_dir, "readcache_max_filesize") != NULL)
+-              lprocfs_add_symlink("readcache_max_filesize",
+-                                  obd->obd_proc_entry,
+-                                  "../../%s/%s/readcache_max_filesize",
+-                                  osd_root->name, osd_dir->name);
+-
+-      if (lprocfs_srch(osd_dir, "writethrough_cache_enable") != NULL)
+-              lprocfs_add_symlink("writethrough_cache_enable",
+-                                  obd->obd_proc_entry,
+-                                  "../../%s/%s/writethrough_cache_enable",
+-                                  osd_root->name, osd_dir->name);
++      lprocfs_add_symlink("brw_stats", obd->obd_proc_entry,
++                          "../../%s/%s/brw_stats",
++                          osd_obd->obd_type->typ_name, obd->obd_name);
++
++      lprocfs_add_symlink("read_cache_enable", obd->obd_proc_entry,
++                          "../../%s/%s/read_cache_enable",
++                          osd_obd->obd_type->typ_name, obd->obd_name);
++
++      lprocfs_add_symlink("readcache_max_filesize",
++                          obd->obd_proc_entry,
++                          "../../%s/%s/readcache_max_filesize",
++                          osd_obd->obd_type->typ_name, obd->obd_name);
++
++      lprocfs_add_symlink("writethrough_cache_enable",
++                          obd->obd_proc_entry,
++                          "../../%s/%s/writethrough_cache_enable",
++                          osd_obd->obd_type->typ_name, obd->obd_name);
+ }
+ 
+ static void ofd_procfs_fini(struct ofd_device *ofd)
+ {
+       struct obd_device *obd = ofd_obd(ofd);
+ 
+-      lprocfs_remove_proc_entry("writethrough_cache_enable",
+-                                obd->obd_proc_entry);
+-      lprocfs_remove_proc_entry("readcache_max_filesize",
+-                                obd->obd_proc_entry);
+-      lprocfs_remove_proc_entry("read_cache_enable", obd->obd_proc_entry);
+-      lprocfs_remove_proc_entry("brw_stats", obd->obd_proc_entry);
+-      lprocfs_remove_proc_entry("clear", obd->obd_proc_exports_entry);
++      lprocfs_remove(&obd->obd_proc_exports_entry);
++      lprocfs_remove(&obd->obd_proc_entry);
+       lprocfs_free_per_client_stats(obd);
+       lprocfs_obd_cleanup(obd);
+       lprocfs_free_obd_stats(obd);
+@@ -2377,7 +2376,6 @@ static struct lu_device_type ofd_device_type = {
+ 
+ int __init ofd_init(void)
+ {
+-      struct lprocfs_static_vars      lvars;
+       int                             rc;
+ 
+       rc = lu_kmem_init(ofd_caches);
+@@ -2390,11 +2388,9 @@ int __init ofd_init(void)
+               return(rc);
+       }
+ 
+-      lprocfs_ofd_init_vars(&lvars);
+-
+       rc = class_register_type(&ofd_obd_ops, NULL, true, NULL,
+ #ifndef HAVE_ONLY_PROCFS_SEQ
+-                               lvars.module_vars,
++                               NULL,
+ #endif
+                                LUSTRE_OST_NAME, &ofd_device_type);
+       return rc;
+diff --git a/lustre/ofd/ofd_internal.h b/lustre/ofd/ofd_internal.h
+index 4f12506..2e75de5 100644
+--- a/lustre/ofd/ofd_internal.h
++++ b/lustre/ofd/ofd_internal.h
+@@ -403,13 +403,9 @@ int ofd_txn_stop_cb(const struct lu_env *env, struct 
thandle *txn,
+ 
+ /* lproc_ofd.c */
+ #ifdef LPROCFS
+-void lprocfs_ofd_init_vars(struct lprocfs_static_vars *lvars);
++extern struct lprocfs_seq_vars lprocfs_ofd_obd_vars[];
+ void ofd_stats_counter_init(struct lprocfs_stats *stats);
+ #else
+-static void lprocfs_ofd_init_vars(struct lprocfs_static_vars *lvars)
+-{
+-      memset(lvars, 0, sizeof(*lvars));
+-}
+ static inline void ofd_stats_counter_init(struct lprocfs_stats *stats) {}
+ #endif
+ 
+-- 
+1.9.3
+

Reply via email to