aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Shvetsov <alexxy@gentoo.org>2013-12-19 17:44:55 +0400
committerAlexey Shvetsov <alexxy@gentoo.org>2013-12-19 17:44:55 +0400
commited3fe3aa23eae829c2bbaeb29115cba0889f1a68 (patch)
tree1e18a9029a11d337db25aa7cd5ea36cfc26f0e02 /sys-cluster/lustre
parentGive me more patches =D (diff)
downloadsci-ed3fe3aa23eae829c2bbaeb29115cba0889f1a68.tar.gz
sci-ed3fe3aa23eae829c2bbaeb29115cba0889f1a68.tar.bz2
sci-ed3fe3aa23eae829c2bbaeb29115cba0889f1a68.zip
More...
Package-Manager: portage-2.2.7 RepoMan-Options: --force
Diffstat (limited to 'sys-cluster/lustre')
-rw-r--r--sys-cluster/lustre/ChangeLog22
-rw-r--r--sys-cluster/lustre/files/0001-LU-2982-build-make-AC-check-for-linux-arch-sandbox-f.patch2
-rw-r--r--sys-cluster/lustre/files/0002-LU-3373-ldiskfs-ldiskfs-patches-for-3.11.1-fc19.patch2
-rw-r--r--sys-cluster/lustre/files/0003-LU-3974-llite-dentry-d_compare-changes-in-3.11.patch2
-rw-r--r--sys-cluster/lustre/files/0004-LU-3974-llite-use-new-struct-dir_context.patch2
-rw-r--r--sys-cluster/lustre/files/0005-LU-3974-llite-invalidatepage-api-changed.patch2
-rw-r--r--sys-cluster/lustre/files/0006-LU-3319-procfs-move-llite-proc-handling-over-to-seq_.patch2
-rw-r--r--sys-cluster/lustre/files/0007-LU-3319-procfs-move-lmv-proc-handling-over-to-seq_fi.patch2
-rw-r--r--sys-cluster/lustre/files/0008-LU-3319-procfs-move-ldlm-proc-handling-over-to-seq_f.patch2
-rw-r--r--sys-cluster/lustre/files/0009-LU-3319-procfs-move-ost-proc-handling-over-to-seq_fi.patch2
-rw-r--r--sys-cluster/lustre/files/0010-LU-3319-procfs-update-shared-server-side-core-proc-h.patch1260
-rw-r--r--sys-cluster/lustre/files/0011-LU-3319-procfs-update-zfs-proc-handling-to-seq_files.patch171
-rw-r--r--sys-cluster/lustre/files/0012-LU-3319-procfs-move-mgs-proc-handling-to-seq_files.patch351
-rw-r--r--sys-cluster/lustre/files/0013-LU-3319-procfs-move-ofd-proc-handling-to-seq_files.patch759
-rw-r--r--sys-cluster/lustre/files/0014-LU-3319-procfs-move-lod-proc-handling-to-seq_files.patch589
-rw-r--r--sys-cluster/lustre/files/0015-LU-3319-procfs-move-osp-proc-handling-to-seq_files.patch779
-rw-r--r--sys-cluster/lustre/files/0016-LU-3319-procfs-move-mdt-mds-proc-handling-to-seq_fil.patch1484
-rw-r--r--sys-cluster/lustre/files/0017-LU-3319-procfs-move-mdd-proc-handling-to-seq_files.patch788
-rw-r--r--sys-cluster/lustre/files/0018-LU-3319-procfs-update-ldiskfs-proc-handling-to-seq_f.patch748
-rw-r--r--sys-cluster/lustre/lustre-9999.ebuild9
20 files changed, 6969 insertions, 9 deletions
diff --git a/sys-cluster/lustre/ChangeLog b/sys-cluster/lustre/ChangeLog
index 33ff78cda..1a47118ac 100644
--- a/sys-cluster/lustre/ChangeLog
+++ b/sys-cluster/lustre/ChangeLog
@@ -3,6 +3,28 @@
# $Header: $
19 Dec 2013; Alexey Shvetsov <alexxy@gentoo.org>
+ +files/0010-LU-3319-procfs-update-shared-server-side-core-proc-h.patch,
+ +files/0011-LU-3319-procfs-update-zfs-proc-handling-to-seq_files.patch,
+ +files/0012-LU-3319-procfs-move-mgs-proc-handling-to-seq_files.patch,
+ +files/0013-LU-3319-procfs-move-ofd-proc-handling-to-seq_files.patch,
+ +files/0014-LU-3319-procfs-move-lod-proc-handling-to-seq_files.patch,
+ +files/0015-LU-3319-procfs-move-osp-proc-handling-to-seq_files.patch,
+ +files/0016-LU-3319-procfs-move-mdt-mds-proc-handling-to-seq_fil.patch,
+ +files/0017-LU-3319-procfs-move-mdd-proc-handling-to-seq_files.patch,
+ +files/0018-LU-3319-procfs-update-ldiskfs-proc-handling-to-seq_f.patch,
+ files/0001-LU-2982-build-make-AC-check-for-linux-arch-sandbox-f.patch,
+ files/0002-LU-3373-ldiskfs-ldiskfs-patches-for-3.11.1-fc19.patch,
+ files/0003-LU-3974-llite-dentry-d_compare-changes-in-3.11.patch,
+ files/0004-LU-3974-llite-use-new-struct-dir_context.patch,
+ files/0005-LU-3974-llite-invalidatepage-api-changed.patch,
+ files/0006-LU-3319-procfs-move-llite-proc-handling-over-to-seq_.patch,
+ files/0007-LU-3319-procfs-move-lmv-proc-handling-over-to-seq_fi.patch,
+ files/0008-LU-3319-procfs-move-ldlm-proc-handling-over-to-seq_f.patch,
+ files/0009-LU-3319-procfs-move-ost-proc-handling-over-to-seq_fi.patch,
+ lustre-9999.ebuild:
+ More...
+
+ 19 Dec 2013; Alexey Shvetsov <alexxy@gentoo.org>
+files/0007-LU-3319-procfs-move-lmv-proc-handling-over-to-seq_fi.patch,
+files/0008-LU-3319-procfs-move-ldlm-proc-handling-over-to-seq_f.patch,
+files/0009-LU-3319-procfs-move-ost-proc-handling-over-to-seq_fi.patch,
diff --git a/sys-cluster/lustre/files/0001-LU-2982-build-make-AC-check-for-linux-arch-sandbox-f.patch b/sys-cluster/lustre/files/0001-LU-2982-build-make-AC-check-for-linux-arch-sandbox-f.patch
index b1123cc94..e4897334b 100644
--- a/sys-cluster/lustre/files/0001-LU-2982-build-make-AC-check-for-linux-arch-sandbox-f.patch
+++ b/sys-cluster/lustre/files/0001-LU-2982-build-make-AC-check-for-linux-arch-sandbox-f.patch
@@ -1,7 +1,7 @@
From a607b37a64f797b766825ccb6f41176685cd843f Mon Sep 17 00:00:00 2001
From: Alexey Shvetsov <alexxy@gentoo.org>
Date: Mon, 18 Mar 2013 16:22:27 +0400
-Subject: [PATCH 01/10] LU-2982 build: make AC check for linux arch sandbox
+Subject: [PATCH 01/18] LU-2982 build: make AC check for linux arch sandbox
friendly
this commit makes AC check for linux kernel arch sandbox friendly
diff --git a/sys-cluster/lustre/files/0002-LU-3373-ldiskfs-ldiskfs-patches-for-3.11.1-fc19.patch b/sys-cluster/lustre/files/0002-LU-3373-ldiskfs-ldiskfs-patches-for-3.11.1-fc19.patch
index d231dd4cf..8f3258a86 100644
--- a/sys-cluster/lustre/files/0002-LU-3373-ldiskfs-ldiskfs-patches-for-3.11.1-fc19.patch
+++ b/sys-cluster/lustre/files/0002-LU-3373-ldiskfs-ldiskfs-patches-for-3.11.1-fc19.patch
@@ -1,7 +1,7 @@
From e53207df22261a635315a62f1405eb8c7b700963 Mon Sep 17 00:00:00 2001
From: James Simmons <uja.ornl@gmail.com>
Date: Thu, 5 Dec 2013 09:05:22 -0500
-Subject: [PATCH 02/10] LU-3373 ldiskfs: ldiskfs patches for 3.11.1 fc19
+Subject: [PATCH 02/18] LU-3373 ldiskfs: ldiskfs patches for 3.11.1 fc19
ldiskfs patches
diff --git a/sys-cluster/lustre/files/0003-LU-3974-llite-dentry-d_compare-changes-in-3.11.patch b/sys-cluster/lustre/files/0003-LU-3974-llite-dentry-d_compare-changes-in-3.11.patch
index 09fcceef6..6873a226a 100644
--- a/sys-cluster/lustre/files/0003-LU-3974-llite-dentry-d_compare-changes-in-3.11.patch
+++ b/sys-cluster/lustre/files/0003-LU-3974-llite-dentry-d_compare-changes-in-3.11.patch
@@ -1,7 +1,7 @@
From 18cfd561fae3b2eac663b51f8e5147b59c711af7 Mon Sep 17 00:00:00 2001
From: James Simmons <uja.ornl@gmail.com>
Date: Wed, 11 Dec 2013 10:29:41 -0500
-Subject: [PATCH 03/10] LU-3974 llite: dentry d_compare changes in 3.11
+Subject: [PATCH 03/18] LU-3974 llite: dentry d_compare changes in 3.11
In the linux 3.11 kernel the d_compare function has
removed passing in any struct inode arguments. This
diff --git a/sys-cluster/lustre/files/0004-LU-3974-llite-use-new-struct-dir_context.patch b/sys-cluster/lustre/files/0004-LU-3974-llite-use-new-struct-dir_context.patch
index d60c144a0..f79a30e16 100644
--- a/sys-cluster/lustre/files/0004-LU-3974-llite-use-new-struct-dir_context.patch
+++ b/sys-cluster/lustre/files/0004-LU-3974-llite-use-new-struct-dir_context.patch
@@ -1,7 +1,7 @@
From 82f692de87cb6c7db8f050b3201d23f4852a404c Mon Sep 17 00:00:00 2001
From: James Simmons <uja.ornl@gmail.com>
Date: Mon, 2 Dec 2013 12:05:14 -0500
-Subject: [PATCH 04/10] LU-3974 llite: use new struct dir_context
+Subject: [PATCH 04/18] LU-3974 llite: use new struct dir_context
The readdir and nfs code over time has added more
parameters to be passed to be processed. For the 3.11
diff --git a/sys-cluster/lustre/files/0005-LU-3974-llite-invalidatepage-api-changed.patch b/sys-cluster/lustre/files/0005-LU-3974-llite-invalidatepage-api-changed.patch
index ea5eea58f..63efe17eb 100644
--- a/sys-cluster/lustre/files/0005-LU-3974-llite-invalidatepage-api-changed.patch
+++ b/sys-cluster/lustre/files/0005-LU-3974-llite-invalidatepage-api-changed.patch
@@ -1,7 +1,7 @@
From 2725bc0f3bc5fa7706b9a475ccb0c191f21ca884 Mon Sep 17 00:00:00 2001
From: James Simmons <uja.ornl@gmail.com>
Date: Tue, 24 Sep 2013 12:29:47 -0400
-Subject: [PATCH 05/10] LU-3974 llite: invalidatepage api changed
+Subject: [PATCH 05/18] LU-3974 llite: invalidatepage api changed
Until recently invalidating pages from the buffer cache
was dependent only on the page passed in and the start
diff --git a/sys-cluster/lustre/files/0006-LU-3319-procfs-move-llite-proc-handling-over-to-seq_.patch b/sys-cluster/lustre/files/0006-LU-3319-procfs-move-llite-proc-handling-over-to-seq_.patch
index 1df737393..e56376aab 100644
--- a/sys-cluster/lustre/files/0006-LU-3319-procfs-move-llite-proc-handling-over-to-seq_.patch
+++ b/sys-cluster/lustre/files/0006-LU-3319-procfs-move-llite-proc-handling-over-to-seq_.patch
@@ -1,7 +1,7 @@
From 01ce737ef8bba37c904d79f3aabe88a4ead20b74 Mon Sep 17 00:00:00 2001
From: James Simmons <uja.ornl@gmail.com>
Date: Thu, 5 Dec 2013 13:53:37 -0500
-Subject: [PATCH 06/10] LU-3319 procfs: move llite proc handling over to
+Subject: [PATCH 06/18] LU-3319 procfs: move llite proc handling over to
seq_file
For lustre clients a special abstract layer so a lustre
diff --git a/sys-cluster/lustre/files/0007-LU-3319-procfs-move-lmv-proc-handling-over-to-seq_fi.patch b/sys-cluster/lustre/files/0007-LU-3319-procfs-move-lmv-proc-handling-over-to-seq_fi.patch
index c710c5cda..0fee4ee7b 100644
--- a/sys-cluster/lustre/files/0007-LU-3319-procfs-move-lmv-proc-handling-over-to-seq_fi.patch
+++ b/sys-cluster/lustre/files/0007-LU-3319-procfs-move-lmv-proc-handling-over-to-seq_fi.patch
@@ -1,7 +1,7 @@
From 4169735b41f2452d884e24c92581af0c4fbf6121 Mon Sep 17 00:00:00 2001
From: James Simmons <uja.ornl@gmail.com>
Date: Thu, 14 Nov 2013 09:32:29 -0500
-Subject: [PATCH 07/10] LU-3319 procfs: move lmv proc handling over to seq_file
+Subject: [PATCH 07/18] LU-3319 procfs: move lmv proc handling over to seq_file
In order to support 3.10+ kernels for clients we adapt
the lmv proc handling to using seq_files.
diff --git a/sys-cluster/lustre/files/0008-LU-3319-procfs-move-ldlm-proc-handling-over-to-seq_f.patch b/sys-cluster/lustre/files/0008-LU-3319-procfs-move-ldlm-proc-handling-over-to-seq_f.patch
index 5d2cd20bd..d3768d583 100644
--- a/sys-cluster/lustre/files/0008-LU-3319-procfs-move-ldlm-proc-handling-over-to-seq_f.patch
+++ b/sys-cluster/lustre/files/0008-LU-3319-procfs-move-ldlm-proc-handling-over-to-seq_f.patch
@@ -1,7 +1,7 @@
From a464fd862a7876e1c4f679b32956904eee88d45e Mon Sep 17 00:00:00 2001
From: James Simmons <uja.ornl@gmail.com>
Date: Tue, 17 Dec 2013 19:11:15 -0500
-Subject: [PATCH 08/10] LU-3319 procfs: move ldlm proc handling over to
+Subject: [PATCH 08/18] LU-3319 procfs: move ldlm proc handling over to
seq_file
In order to support 3.10+ kernels for clients we adapt
diff --git a/sys-cluster/lustre/files/0009-LU-3319-procfs-move-ost-proc-handling-over-to-seq_fi.patch b/sys-cluster/lustre/files/0009-LU-3319-procfs-move-ost-proc-handling-over-to-seq_fi.patch
index 0f01c97a7..59eeb06e6 100644
--- a/sys-cluster/lustre/files/0009-LU-3319-procfs-move-ost-proc-handling-over-to-seq_fi.patch
+++ b/sys-cluster/lustre/files/0009-LU-3319-procfs-move-ost-proc-handling-over-to-seq_fi.patch
@@ -1,7 +1,7 @@
From 917c26236db7d3684733f693ccc579c3dd41f26c Mon Sep 17 00:00:00 2001
From: James Simmons <uja.ornl@gmail.com>
Date: Thu, 14 Nov 2013 09:48:08 -0500
-Subject: [PATCH 09/10] LU-3319 procfs: move ost proc handling over to seq_file
+Subject: [PATCH 09/18] LU-3319 procfs: move ost proc handling over to seq_file
Most of the current proc handling of the OST is already
based on seq_file handling except for the reporting of
diff --git a/sys-cluster/lustre/files/0010-LU-3319-procfs-update-shared-server-side-core-proc-h.patch b/sys-cluster/lustre/files/0010-LU-3319-procfs-update-shared-server-side-core-proc-h.patch
new file mode 100644
index 000000000..01afb45f4
--- /dev/null
+++ b/sys-cluster/lustre/files/0010-LU-3319-procfs-update-shared-server-side-core-proc-h.patch
@@ -0,0 +1,1260 @@
+From 7ae65a1edcb16232d34ead46860f6390ce93f583 Mon Sep 17 00:00:00 2001
+From: James Simmons <uja.ornl@gmail.com>
+Date: Tue, 3 Dec 2013 16:30:21 -0500
+Subject: [PATCH 10/18] LU-3319 procfs: update shared server side core proc
+ handling to seq_files
+
+Several of the server side abstact layers such as mdt,mgs
+etc share several common proc handling routines. This patch
+adds the seq_file version so that the stack can gradually
+be ported over to these new methods.
+
+Signed-off-by: James Simmons <uja.ornl@gmail.com>
+Change-Id: I2dd64046fdd4d2bb6f7550bb49cf1c9ef703c157
+---
+ libcfs/include/libcfs/libcfs_hash.h | 5 +
+ libcfs/libcfs/hash.c | 80 ++++++
+ lustre/include/dt_object.h | 8 +
+ lustre/include/lprocfs_status.h | 101 ++++++--
+ lustre/obdclass/dt_object.c | 96 +++++++-
+ lustre/obdclass/lprocfs_jobstats.c | 47 +++-
+ lustre/obdclass/lprocfs_status.c | 467 ++++++++++++++++++++++++++++++++----
+ lustre/ptlrpc/lproc_ptlrpc.c | 43 ----
+ 8 files changed, 724 insertions(+), 123 deletions(-)
+
+diff --git a/libcfs/include/libcfs/libcfs_hash.h b/libcfs/include/libcfs/libcfs_hash.h
+index e7d2dc8..07a12f6 100644
+--- a/libcfs/include/libcfs/libcfs_hash.h
++++ b/libcfs/include/libcfs/libcfs_hash.h
+@@ -840,8 +840,13 @@ static inline void __cfs_hash_set_theta(cfs_hash_t *hs, int min, int max)
+ }
+
+ /* Generic debug formatting routines mainly for proc handler */
++#ifndef HAVE_ONLY_PROCFS_SEQ
+ int cfs_hash_debug_header(char *str, int size);
+ int cfs_hash_debug_str(cfs_hash_t *hs, char *str, int size);
++#endif
++struct seq_file;
++int cfs_hash_debug_header_seq(struct seq_file *m);
++int cfs_hash_debug_str_seq(cfs_hash_t *hs, struct seq_file *m);
+
+ /*
+ * Generic djb2 hash algorithm for character arrays.
+diff --git a/libcfs/libcfs/hash.c b/libcfs/libcfs/hash.c
+index 35c64a0..0c4faf8 100644
+--- a/libcfs/libcfs/hash.c
++++ b/libcfs/libcfs/hash.c
+@@ -2026,6 +2026,7 @@ void cfs_hash_rehash_key(cfs_hash_t *hs, const void *old_key,
+ }
+ EXPORT_SYMBOL(cfs_hash_rehash_key);
+
++#ifndef HAVE_ONLY_PROCFS_SEQ
+ int cfs_hash_debug_header(char *str, int size)
+ {
+ return snprintf(str, size, "%-*s%6s%6s%6s%6s%6s%6s%6s%7s%8s%8s%8s%s\n",
+@@ -2035,6 +2036,17 @@ int cfs_hash_debug_header(char *str, int size)
+ " distribution");
+ }
+ EXPORT_SYMBOL(cfs_hash_debug_header);
++#endif
++
++int cfs_hash_debug_header_seq(struct seq_file *m)
++{
++ return seq_printf(m, "%-*s%6s%6s%6s%6s%6s%6s%6s%7s%8s%8s%8s%s\n",
++ CFS_HASH_BIGNAME_LEN,
++ "name", "cur", "min", "max", "theta", "t-min", "t-max",
++ "flags", "rehash", "count", "maxdep", "maxdepb",
++ " distribution");
++}
++EXPORT_SYMBOL(cfs_hash_debug_header_seq);
+
+ static cfs_hash_bucket_t **
+ cfs_hash_full_bkts(cfs_hash_t *hs)
+@@ -2060,6 +2072,7 @@ cfs_hash_full_nbkt(cfs_hash_t *hs)
+ CFS_HASH_RH_NBKT(hs) : CFS_HASH_NBKT(hs);
+ }
+
++#ifndef HAVE_ONLY_PROCFS_SEQ
+ int cfs_hash_debug_str(cfs_hash_t *hs, char *str, int size)
+ {
+ int dist[8] = { 0, };
+@@ -2134,3 +2147,70 @@ int cfs_hash_debug_str(cfs_hash_t *hs, char *str, int size)
+ return c;
+ }
+ EXPORT_SYMBOL(cfs_hash_debug_str);
++#endif
++
++int cfs_hash_debug_str_seq(cfs_hash_t *hs, struct seq_file *m)
++{
++ int dist[8] = { 0, };
++ int maxdep = -1;
++ int maxdepb = -1;
++ int total = 0;
++ int c = 0;
++ int theta;
++ int i;
++
++ cfs_hash_lock(hs, 0);
++ theta = __cfs_hash_theta(hs);
++
++ c += seq_printf(m, "%-*s ", CFS_HASH_BIGNAME_LEN, hs->hs_name);
++ c += seq_printf(m, "%5d ", 1 << hs->hs_cur_bits);
++ c += seq_printf(m, "%5d ", 1 << hs->hs_min_bits);
++ c += seq_printf(m, "%5d ", 1 << hs->hs_max_bits);
++ c += seq_printf(m, "%d.%03d ", __cfs_hash_theta_int(theta),
++ __cfs_hash_theta_frac(theta));
++ c += seq_printf(m, "%d.%03d ", __cfs_hash_theta_int(hs->hs_min_theta),
++ __cfs_hash_theta_frac(hs->hs_min_theta));
++ c += seq_printf(m, "%d.%03d ", __cfs_hash_theta_int(hs->hs_max_theta),
++ __cfs_hash_theta_frac(hs->hs_max_theta));
++ c += seq_printf(m, " 0x%02x ", hs->hs_flags);
++ c += seq_printf(m, "%6d ", hs->hs_rehash_count);
++
++ /*
++ * The distribution is a summary of the chained hash depth in
++ * each of the libcfs hash buckets. Each buckets hsb_count is
++ * divided by the hash theta value and used to generate a
++ * histogram of the hash distribution. A uniform hash will
++ * result in all hash buckets being close to the average thus
++ * only the first few entries in the histogram will be non-zero.
++ * If you hash function results in a non-uniform hash the will
++ * be observable by outlier bucks in the distribution histogram.
++ *
++ * Uniform hash distribution: 128/128/0/0/0/0/0/0
++ * Non-Uniform hash distribution: 128/125/0/0/0/0/2/1
++ */
++ for (i = 0; i < cfs_hash_full_nbkt(hs); i++) {
++ cfs_hash_bd_t bd;
++
++ bd.bd_bucket = cfs_hash_full_bkts(hs)[i];
++ cfs_hash_bd_lock(hs, &bd, 0);
++ if (maxdep < bd.bd_bucket->hsb_depmax) {
++ maxdep = bd.bd_bucket->hsb_depmax;
++#ifdef __KERNEL__
++ maxdepb = ffz(~maxdep);
++#endif
++ }
++ total += bd.bd_bucket->hsb_count;
++ dist[min(fls(bd.bd_bucket->hsb_count/max(theta,1)),7)]++;
++ cfs_hash_bd_unlock(hs, &bd, 0);
++ }
++
++ c += seq_printf(m, "%7d ", total);
++ c += seq_printf(m, "%7d ", maxdep);
++ c += seq_printf(m, "%7d ", maxdepb);
++ for (i = 0; i < 8; i++)
++ c += seq_printf(m, "%d%c", dist[i], (i == 7) ? '\n' : '/');
++
++ cfs_hash_unlock(hs, 0);
++ return c;
++}
++EXPORT_SYMBOL(cfs_hash_debug_str_seq);
+diff --git a/lustre/include/dt_object.h b/lustre/include/dt_object.h
+index bdf559d..ba88a80 100644
+--- a/lustre/include/dt_object.h
++++ b/lustre/include/dt_object.h
+@@ -1489,6 +1489,7 @@ int dt_global_init(void);
+ void dt_global_fini(void);
+
+ # ifdef LPROCFS
++#ifndef HAVE_ONLY_PROCFS_SEQ
+ int lprocfs_dt_rd_blksize(char *page, char **start, off_t off,
+ int count, int *eof, void *data);
+ int lprocfs_dt_rd_kbytestotal(char *page, char **start, off_t off,
+@@ -1501,6 +1502,13 @@ int lprocfs_dt_rd_filestotal(char *page, char **start, off_t off,
+ int count, int *eof, void *data);
+ int lprocfs_dt_rd_filesfree(char *page, char **start, off_t off,
+ int count, int *eof, void *data);
++#endif
++int lprocfs_dt_blksize_seq_show(struct seq_file *m, void *v);
++int lprocfs_dt_kbytestotal_seq_show(struct seq_file *m, void *v);
++int lprocfs_dt_kbytesfree_seq_show(struct seq_file *m, void *v);
++int lprocfs_dt_kbytesavail_seq_show(struct seq_file *m, void *v);
++int lprocfs_dt_filestotal_seq_show(struct seq_file *m, void *v);
++int lprocfs_dt_filesfree_seq_show(struct seq_file *m, void *v);
+ # endif /* LPROCFS */
+
+ #endif /* __LUSTRE_DT_OBJECT_H */
+diff --git a/lustre/include/lprocfs_status.h b/lustre/include/lprocfs_status.h
+index 2080592..70f10a9 100644
+--- a/lustre/include/lprocfs_status.h
++++ b/lustre/include/lprocfs_status.h
+@@ -603,12 +603,19 @@ extern struct proc_dir_entry *
+ lprocfs_add_symlink(const char *name, struct proc_dir_entry *parent,
+ const char *format, ...);
+ extern void lprocfs_free_per_client_stats(struct obd_device *obd);
++#ifdef HAVE_SERVER_SUPPORT
++#ifndef HAVE_ONLY_PROCFS_SEQ
+ extern int
+ lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
+ unsigned long count, void *data);
+ extern int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
+ int count, int *eof, void *data);
+-
++#endif
++extern ssize_t
++lprocfs_nid_stats_clear_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off);
++extern int lprocfs_nid_stats_clear_seq_show(struct seq_file *file, void *data);
++#endif
+ extern int lprocfs_register_stats(cfs_proc_dir_entry_t *root, const char *name,
+ struct lprocfs_stats *stats);
+
+@@ -700,6 +707,9 @@ extern int lprocfs_conn_uuid_seq_show(struct seq_file *m, void *data);
+ extern int lprocfs_import_seq_show(struct seq_file *m, void *data);
+ extern int lprocfs_state_seq_show(struct seq_file *m, void *data);
+ extern int lprocfs_connect_flags_seq_show(struct seq_file *m, void *data);
++#ifdef HAVE_SERVER_SUPPORT
++extern int lprocfs_num_exports_seq_show(struct seq_file *m, void *data);
++#endif
+ struct adaptive_timeout;
+ #ifndef HAVE_ONLY_PROCFS_SEQ
+ extern int lprocfs_at_hist_helper(char *page, int count, int rc,
+@@ -715,9 +725,11 @@ extern int lprocfs_timeouts_seq_show(struct seq_file *m, void *data);
+ extern ssize_t
+ lprocfs_timeouts_seq_write(struct file *file, const char *buffer,
+ size_t count, loff_t *off);
++#ifndef HAVE_ONLY_PROCFS_SEQ
++#ifdef HAVE_SERVER_SUPPORT
+ extern int lprocfs_wr_evict_client(struct file *file, const char *buffer,
+ unsigned long count, void *data);
+-#ifndef HAVE_ONLY_PROCFS_SEQ
++#endif
+ extern int lprocfs_wr_ping(struct file *file, const char *buffer,
+ unsigned long count, void *data);
+ extern int lprocfs_wr_import(struct file *file, const char *buffer,
+@@ -727,6 +739,11 @@ extern int lprocfs_rd_pinger_recov(char *page, char **start, off_t off,
+ extern int lprocfs_wr_pinger_recov(struct file *file, const char *buffer,
+ unsigned long count, void *data);
+ #endif
++#ifdef HAVE_SERVER_SUPPORT
++extern ssize_t
++lprocfs_evict_client_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off);
++#endif
+ extern ssize_t
+ lprocfs_ping_seq_write(struct file *file, const char *buffer,
+ size_t count, loff_t *off);
+@@ -785,10 +802,10 @@ void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
+ struct lprocfs_counter *cnt);
+
+ #ifdef HAVE_SERVER_SUPPORT
++#ifndef HAVE_ONLY_PROCFS_SEQ
+ /* lprocfs_status.c: recovery status */
+ int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
+ int count, int *eof, void *data);
+-#endif
+ /* lprocfs_statuc.c: hash statistics */
+ int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
+ int count, int *eof, void *data);
+@@ -798,7 +815,19 @@ int lprocfs_obd_rd_ir_factor(char *page, char **start, off_t off,
+ int count, int *eof, void *data);
+ int lprocfs_obd_wr_ir_factor(struct file *file, const char *buffer,
+ unsigned long count, void *data);
++#endif
++/* lprocfs_status.c: recovery status */
++int lprocfs_recovery_status_seq_show(struct seq_file *m, void *data);
+
++/* lprocfs_status.c: hash statistics */
++int lprocfs_hash_seq_show(struct seq_file *m, void *data);
++
++/* lprocfs_status.c: IR factor */
++int lprocfs_ir_factor_seq_show(struct seq_file *m, void *data);
++ssize_t
++lprocfs_ir_factor_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off);
++#endif
+ extern int lprocfs_single_release(cfs_inode_t *, struct file *);
+ extern int lprocfs_seq_release(cfs_inode_t *, struct file *);
+
+@@ -874,21 +903,23 @@ struct file_operations name##_fops = { \
+ .release = lprocfs_single_release, \
+ };
+
++/* lproc_ptlrpc.c */
++struct ptlrpc_request;
++extern void target_print_req(void *seq_file, struct ptlrpc_request *req);
++
++#ifdef HAVE_SERVER_SUPPORT
+ /* lprocfs_jobstats.c */
+ int lprocfs_job_stats_log(struct obd_device *obd, char *jobid,
+ int event, long amount);
+ void lprocfs_job_stats_fini(struct obd_device *obd);
+ int lprocfs_job_stats_init(struct obd_device *obd, int cntr_num,
+ cntr_init_callback fn);
++#ifndef HAVE_ONLY_PROCFS_SEQ
+ int lprocfs_rd_job_interval(char *page, char **start, off_t off,
+ int count, int *eof, void *data);
+ int lprocfs_wr_job_interval(struct file *file, const char *buffer,
+ unsigned long count, void *data);
+
+-/* lproc_ptlrpc.c */
+-struct ptlrpc_request;
+-extern void target_print_req(void *seq_file, struct ptlrpc_request *req);
+-
+ /* lproc_status.c */
+ int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
+ int count, int *eof, void *data);
+@@ -900,6 +931,24 @@ int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
+ int lprocfs_obd_wr_recovery_time_hard(struct file *file,
+ const char *buffer,
+ unsigned long count, void *data);
++int lprocfs_target_rd_instance(char *page, char **start, off_t off,
++ int count, int *eof, void *data);
++#endif
++int lprocfs_job_interval_seq_show(struct seq_file *m, void *data);
++ssize_t
++lprocfs_job_interval_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off);
++/* lproc_status.c */
++int lprocfs_recovery_time_soft_seq_show(struct seq_file *m, void *data);
++ssize_t lprocfs_recovery_time_soft_seq_write(struct file *file,
++ const char *buffer,
++ size_t count, loff_t *off);
++int lprocfs_recovery_time_hard_seq_show(struct seq_file *m, void *data);
++ssize_t
++lprocfs_recovery_time_hard_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off);
++int lprocfs_target_instance_seq_show(struct seq_file *m, void *data);
++#endif
+ #ifndef HAVE_ONLY_PROCFS_SEQ
+ int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off,
+ int count, int *eof, void *data);
+@@ -910,8 +959,6 @@ int lprocfs_obd_max_pages_per_rpc_seq_show(struct seq_file *m, void *data);
+ ssize_t
+ lprocfs_obd_max_pages_per_rpc_seq_write(struct file *file, const char *buffer,
+ size_t count, loff_t *off);
+-int lprocfs_target_rd_instance(char *page, char **start, off_t off,
+- int count, int *eof, void *data);
+
+ /* all quota proc functions */
+ extern int lprocfs_quota_rd_bunit(char *page, char **start,
+@@ -1032,7 +1079,26 @@ static inline void lprocfs_free_md_stats(struct obd_device *obddev)
+ struct obd_export;
+ static inline int lprocfs_add_clear_entry(struct obd_export *exp)
+ { return 0; }
++static inline void lprocfs_free_per_client_stats(struct obd_device *obd)
++{ return; }
+ #ifdef HAVE_SERVER_SUPPORT
++#ifndef HAVE_ONLY_PROCFS_SEQ
++static inline
++int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
++ unsigned long count, void *data)
++{return count;}
++static inline
++int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
++ int count, int *eof, void *data)
++{return count;}
++#endif
++static inline
++ssize_t lprocfs_nid_stats_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
++{return 0;}
++static inline
++int lprocfs_nid_stats_clear_seq_show(struct seq_file *m, void *data)
++{return 0;}
+ static inline int lprocfs_exp_setup(struct obd_export *exp,lnet_nid_t *peer_nid,
+ int *newnid)
+ { return 0; }
+@@ -1050,17 +1116,6 @@ static inline struct proc_dir_entry *
+ lprocfs_add_symlink(const char *name, struct proc_dir_entry *parent,
+ const char *format, ...)
+ {return NULL; }
+-static inline void lprocfs_free_per_client_stats(struct obd_device *obd)
+-{ return; }
+-static inline
+-int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
+- unsigned long count, void *data)
+-{return count;}
+-static inline
+-int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
+-{return count;}
+-
+ #ifndef HAVE_ONLY_PROCFS_SEQ
+ static inline cfs_proc_dir_entry_t *
+ lprocfs_register(const char *name, cfs_proc_dir_entry_t *parent,
+@@ -1145,10 +1200,12 @@ static inline int lprocfs_wr_timeouts(struct file *file,
+ const char *buffer,
+ unsigned long count, void *data)
+ { return 0; }
++#ifdef HAVE_SERVER_SUPPORT
+ static inline int lprocfs_wr_evict_client(struct file *file,
+ const char *buffer,
+ unsigned long count, void *data)
+ { return 0; }
++#endif
+ static inline int lprocfs_wr_ping(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+ { return 0; }
+@@ -1173,8 +1230,10 @@ static inline int lprocfs_state_seq_show(struct seq_file *m, void *data)
+ { return 0; }
+ static inline int lprocfs_connect_flags_seq_show(struct seq_file *m, void *data)
+ { return 0; }
++#ifdef HAVE_SERVER_SUPPORT
+ static inline int lprocfs_num_exports_seq_show(struct seq_file *m, void *data)
+ { return 0; }
++#endif
+ struct adaptive_timeout;
+ static inline int lprocfs_seq_at_hist_helper(struct seq_file *m,
+ struct adaptive_timeout *at)
+@@ -1185,10 +1244,12 @@ static inline ssize_t
+ lprocfs_timeouts_seq_write(struct file *file, const char *buffer,
+ size_t count, loff_t *off)
+ { return 0; }
++#ifdef HAVE_SERVER_SUPPORT
+ static inline ssize_t
+ lprocfs_evict_client_seq_write(struct file *file, const char *buffer,
+ size_t count, loff_t *off)
+ { return 0; }
++#endif
+ static inline ssize_t
+ lprocfs_ping_seq_write(struct file *file, const char *buffer,
+ size_t count, loff_t *off)
+diff --git a/lustre/obdclass/dt_object.c b/lustre/obdclass/dt_object.c
+index deb5863..242a45d 100644
+--- a/lustre/obdclass/dt_object.c
++++ b/lustre/obdclass/dt_object.c
+@@ -936,7 +936,7 @@ out:
+ EXPORT_SYMBOL(dt_index_read);
+
+ #ifdef LPROCFS
+-
++#ifndef HAVE_ONLY_PROCFS_SEQ
+ int lprocfs_dt_rd_blksize(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+ {
+@@ -1051,5 +1051,99 @@ int lprocfs_dt_rd_filesfree(char *page, char **start, off_t off,
+ return rc;
+ }
+ EXPORT_SYMBOL(lprocfs_dt_rd_filesfree);
++#endif
++
++int lprocfs_dt_blksize_seq_show(struct seq_file *m, void *v)
++{
++ struct dt_device *dt = m->private;
++ struct obd_statfs osfs;
++
++ int rc = dt_statfs(NULL, dt, &osfs);
++ if (rc == 0)
++ seq_printf(m, "%u\n", (unsigned) osfs.os_bsize);
++ return rc;
++}
++EXPORT_SYMBOL(lprocfs_dt_blksize_seq_show);
++
++int lprocfs_dt_kbytestotal_seq_show(struct seq_file *m, void *v)
++{
++ struct dt_device *dt = m->private;
++ struct obd_statfs osfs;
++
++ int rc = dt_statfs(NULL, dt, &osfs);
++ if (rc == 0) {
++ __u32 blk_size = osfs.os_bsize >> 10;
++ __u64 result = osfs.os_blocks;
++
++ while (blk_size >>= 1)
++ result <<= 1;
++
++ seq_printf(m, LPU64"\n", result);
++ }
++ return rc;
++}
++EXPORT_SYMBOL(lprocfs_dt_kbytestotal_seq_show);
++
++int lprocfs_dt_kbytesfree_seq_show(struct seq_file *m, void *v)
++{
++ struct dt_device *dt = m->private;
++ struct obd_statfs osfs;
++
++ int rc = dt_statfs(NULL, dt, &osfs);
++ if (rc == 0) {
++ __u32 blk_size = osfs.os_bsize >> 10;
++ __u64 result = osfs.os_bfree;
++
++ while (blk_size >>= 1)
++ result <<= 1;
++
++ seq_printf(m, LPU64"\n", result);
++ }
++ return rc;
++}
++EXPORT_SYMBOL(lprocfs_dt_kbytesfree_seq_show);
++
++int lprocfs_dt_kbytesavail_seq_show(struct seq_file *m, void *v)
++{
++ struct dt_device *dt = m->private;
++ struct obd_statfs osfs;
++
++ int rc = dt_statfs(NULL, dt, &osfs);
++ if (rc == 0) {
++ __u32 blk_size = osfs.os_bsize >> 10;
++ __u64 result = osfs.os_bavail;
++
++ while (blk_size >>= 1)
++ result <<= 1;
++
++ seq_printf(m, LPU64"\n", result);
++ }
++ return rc;
++}
++EXPORT_SYMBOL(lprocfs_dt_kbytesavail_seq_show);
++
++int lprocfs_dt_filestotal_seq_show(struct seq_file *m, void *v)
++{
++ struct dt_device *dt = m->private;
++ struct obd_statfs osfs;
++
++ int rc = dt_statfs(NULL, dt, &osfs);
++ if (rc == 0)
++ seq_printf(m, LPU64"\n", osfs.os_files);
++ return rc;
++}
++EXPORT_SYMBOL(lprocfs_dt_filestotal_seq_show);
++
++int lprocfs_dt_filesfree_seq_show(struct seq_file *m, void *v)
++{
++ struct dt_device *dt = m->private;
++ struct obd_statfs osfs;
++
++ int rc = dt_statfs(NULL, dt, &osfs);
++ if (rc == 0)
++ seq_printf(m, LPU64"\n", osfs.os_ffree);
++ return rc;
++}
++EXPORT_SYMBOL(lprocfs_dt_filesfree_seq_show);
+
+ #endif /* LPROCFS */
+diff --git a/lustre/obdclass/lprocfs_jobstats.c b/lustre/obdclass/lprocfs_jobstats.c
+index f67e426..4e16a17 100644
+--- a/lustre/obdclass/lprocfs_jobstats.c
++++ b/lustre/obdclass/lprocfs_jobstats.c
+@@ -416,18 +416,17 @@ struct seq_operations lprocfs_jobstats_seq_sops = {
+
+ static int lprocfs_jobstats_seq_open(struct inode *inode, struct file *file)
+ {
+- struct proc_dir_entry *dp = PDE(inode);
+ struct seq_file *seq;
+ int rc;
+
+- if (LPROCFS_ENTRY_CHECK(dp))
++ if (LPROCFS_ENTRY_CHECK(PDE(inode)))
+ return -ENOENT;
+
+ rc = seq_open(file, &lprocfs_jobstats_seq_sops);
+ if (rc)
+ return rc;
+ seq = file->private_data;
+- seq->private = dp->data;
++ seq->private = PDE_DATA(inode);
+ return 0;
+ }
+
+@@ -520,19 +519,18 @@ int lprocfs_job_stats_init(struct obd_device *obd, int cntr_num,
+ stats->ojs_last_cleanup = cfs_time_current_sec();
+
+ LPROCFS_WRITE_ENTRY();
+- entry = create_proc_entry("job_stats", 0644, obd->obd_proc_entry);
++ entry = proc_create_data("job_stats", 0644, obd->obd_proc_entry,
++ &lprocfs_jobstats_seq_fops, stats);
+ LPROCFS_WRITE_EXIT();
+- if (entry) {
+- entry->proc_fops = &lprocfs_jobstats_seq_fops;
+- entry->data = stats;
+- RETURN(0);
+- } else {
++ if (entry == NULL) {
+ lprocfs_job_stats_fini(obd);
+ RETURN(-ENOMEM);
+ }
++ RETURN(0);
+ }
+ EXPORT_SYMBOL(lprocfs_job_stats_init);
+
++#ifndef HAVE_ONLY_PROCFS_SEQ
+ int lprocfs_rd_job_interval(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+ {
+@@ -567,5 +565,36 @@ int lprocfs_wr_job_interval(struct file *file, const char *buffer,
+
+ }
+ EXPORT_SYMBOL(lprocfs_wr_job_interval);
++#endif
++int lprocfs_job_interval_seq_show(struct seq_file *m, void *data)
++{
++ struct obd_device *obd = m->private;
++ struct obd_job_stats *stats;
++
++ LASSERT(obd != NULL);
++ stats = &obd->u.obt.obt_jobstats;
++ return seq_printf(m, "%d\n", stats->ojs_cleanup_interval);
++}
++EXPORT_SYMBOL(lprocfs_job_interval_seq_show);
++
++ssize_t
++lprocfs_job_interval_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
++{
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
++ struct obd_job_stats *stats;
++ int val, rc;
++
++ LASSERT(obd != NULL);
++ stats = &obd->u.obt.obt_jobstats;
++
++ rc = lprocfs_write_helper(buffer, count, &val);
++ if (rc)
++ return rc;
+
++ stats->ojs_cleanup_interval = val;
++ lprocfs_job_cleanup(stats, true);
++ return count;
++}
++EXPORT_SYMBOL(lprocfs_job_interval_seq_write);
+ #endif /* LPROCFS*/
+diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c
+index 0c805be..a33cbf2 100644
+--- a/lustre/obdclass/lprocfs_status.c
++++ b/lustre/obdclass/lprocfs_status.c
+@@ -288,25 +288,104 @@ static struct file_operations lprocfs_generic_fops = { };
+ #ifdef HAVE_SERVER_SUPPORT
+ int lprocfs_evict_client_open(struct inode *inode, struct file *f)
+ {
+- struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
+- struct obd_device *obd = dp->data;
+-
+- cfs_atomic_inc(&obd->obd_evict_inprogress);
++ struct obd_device *obd = PDE_DATA(f->f_dentry->d_inode);
+
+- return 0;
++ cfs_atomic_inc(&obd->obd_evict_inprogress);
++ return 0;
+ }
+
+ int lprocfs_evict_client_release(struct inode *inode, struct file *f)
+ {
+- struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
+- struct obd_device *obd = dp->data;
++ struct obd_device *obd = PDE_DATA(f->f_dentry->d_inode);
+
+ cfs_atomic_dec(&obd->obd_evict_inprogress);
+ wake_up(&obd->obd_evict_inprogress_waitq);
+-
+ return 0;
+ }
+
++#define BUFLEN (UUID_MAX + 5)
++
++#ifndef HAVE_ONLY_PROCFS_SEQ
++int lprocfs_wr_evict_client(struct file *file, const char *buffer,
++ unsigned long count, void *data)
++{
++ struct obd_device *obd = data;
++ char *kbuf;
++ char *tmpbuf;
++
++ OBD_ALLOC(kbuf, BUFLEN);
++ if (kbuf == NULL)
++ return -ENOMEM;
++
++ /*
++ * OBD_ALLOC() will zero kbuf, but we only copy BUFLEN - 1
++ * bytes into kbuf, to ensure that the string is NUL-terminated.
++ * UUID_MAX should include a trailing NUL already.
++ */
++ if (copy_from_user(kbuf, buffer,
++ min_t(unsigned long, BUFLEN - 1, count))) {
++ count = -EFAULT;
++ goto out;
++ }
++ tmpbuf = cfs_firststr(kbuf, min_t(unsigned long, BUFLEN - 1, count));
++ class_incref(obd, __FUNCTION__, current);
++
++ if (strncmp(tmpbuf, "nid:", 4) == 0)
++ obd_export_evict_by_nid(obd, tmpbuf + 4);
++ else if (strncmp(tmpbuf, "uuid:", 5) == 0)
++ obd_export_evict_by_uuid(obd, tmpbuf + 5);
++ else
++ obd_export_evict_by_uuid(obd, tmpbuf);
++
++ class_decref(obd, __FUNCTION__, current);
++out:
++ OBD_FREE(kbuf, BUFLEN);
++ return count;
++}
++EXPORT_SYMBOL(lprocfs_wr_evict_client);
++#endif
++
++ssize_t
++lprocfs_evict_client_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
++{
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
++ char *tmpbuf, *kbuf;
++
++ OBD_ALLOC(kbuf, BUFLEN);
++ if (kbuf == NULL)
++ return -ENOMEM;
++
++ /*
++ * OBD_ALLOC() will zero kbuf, but we only copy BUFLEN - 1
++ * bytes into kbuf, to ensure that the string is NUL-terminated.
++ * UUID_MAX should include a trailing NUL already.
++ */
++ if (copy_from_user(kbuf, buffer,
++ min_t(unsigned long, BUFLEN - 1, count))) {
++ count = -EFAULT;
++ goto out;
++ }
++ tmpbuf = cfs_firststr(kbuf, min_t(unsigned long, BUFLEN - 1, count));
++ class_incref(obd, __FUNCTION__, current);
++
++ if (strncmp(tmpbuf, "nid:", 4) == 0)
++ obd_export_evict_by_nid(obd, tmpbuf + 4);
++ else if (strncmp(tmpbuf, "uuid:", 5) == 0)
++ obd_export_evict_by_uuid(obd, tmpbuf + 5);
++ else
++ obd_export_evict_by_uuid(obd, tmpbuf);
++
++ class_decref(obd, __FUNCTION__, current);
++
++out:
++ OBD_FREE(kbuf, BUFLEN);
++ return count;
++}
++EXPORT_SYMBOL(lprocfs_evict_client_seq_write);
++
++#undef BUFLEN
++
+ struct file_operations lprocfs_evict_client_fops = {
+ .owner = THIS_MODULE,
+ .read = lprocfs_fops_read,
+@@ -1228,6 +1307,17 @@ int lprocfs_connect_flags_seq_show(struct seq_file *m, void *data)
+ }
+ EXPORT_SYMBOL(lprocfs_connect_flags_seq_show);
+
++#ifdef HAVE_SERVER_SUPPORT
++int lprocfs_num_exports_seq_show(struct seq_file *m, void *data)
++{
++ struct obd_device *obd = data;
++
++ LASSERT(obd != NULL);
++ return seq_printf(m, "%u\n", obd->obd_num_exports);
++}
++EXPORT_SYMBOL(lprocfs_num_exports_seq_show);
++#endif
++
+ #ifndef HAVE_ONLY_PROCFS_SEQ
+
+ int lprocfs_rd_uint(char *page, char **start, off_t off,
+@@ -1743,6 +1833,7 @@ int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
+ }
+ EXPORT_SYMBOL(lprocfs_rd_connect_flags);
+
++#ifdef HAVE_SERVER_SUPPORT
+ int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
+ int *eof, void *data)
+ {
+@@ -1753,6 +1844,7 @@ int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
+ return snprintf(page, count, "%u\n", obd->obd_num_exports);
+ }
+ EXPORT_SYMBOL(lprocfs_rd_num_exports);
++#endif
+
+ int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
+ int *eof, void *data)
+@@ -2436,6 +2528,112 @@ void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
+ }
+ EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
+
++#ifdef HAVE_SERVER_SUPPORT
++/* No one appears to be using this ?? */
++int lprocfs_exp_nid_seq_show(struct seq_file *m, void *data)
++{
++ struct obd_export *exp = m->private;
++ LASSERT(exp != NULL);
++ return seq_printf(m, "%s\n", obd_export_nid2str(exp));
++}
++
++int lprocfs_exp_print_uuid_seq(cfs_hash_t *hs, cfs_hash_bd_t *bd,
++ cfs_hlist_node_t *hnode, void *cb_data)
++
++{
++ struct obd_export *exp = cfs_hash_object(hs, hnode);
++ struct seq_file *m = cb_data;
++
++ if (exp->exp_nid_stats)
++ seq_printf(m, "%s\n", obd_uuid2str(&exp->exp_client_uuid));
++ return 0;
++}
++
++int lprocfs_exp_uuid_seq_show(struct seq_file *m, void *data)
++{
++ struct nid_stat *stats = m->private;
++ struct obd_device *obd = stats->nid_obd;
++
++ cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
++ lprocfs_exp_print_uuid_seq, m);
++ return 0;
++}
++LPROC_SEQ_FOPS_RO(lprocfs_exp_uuid);
++
++int lprocfs_exp_print_hash_seq(cfs_hash_t *hs, cfs_hash_bd_t *bd,
++ cfs_hlist_node_t *hnode, void *cb_data)
++
++{
++ struct seq_file *m = cb_data;
++ struct obd_export *exp = cfs_hash_object(hs, hnode);
++
++ if (exp->exp_lock_hash != NULL) {
++ cfs_hash_debug_header_seq(m);
++ cfs_hash_debug_str_seq(hs, m);
++ }
++ return 0;
++}
++
++int lprocfs_exp_hash_seq_show(struct seq_file *m, void *data)
++{
++ struct nid_stat *stats = m->private;
++ struct obd_device *obd = stats->nid_obd;
++
++ cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
++ lprocfs_exp_print_hash_seq, m);
++ return 0;
++}
++LPROC_SEQ_FOPS_RO(lprocfs_exp_hash);
++
++int lprocfs_nid_stats_clear_seq_show(struct seq_file *m, void *data)
++{
++ return seq_printf(m, "%s\n", "Write into this file to clear all nid "
++ "stats and stale nid entries");
++}
++EXPORT_SYMBOL(lprocfs_nid_stats_clear_seq_show);
++
++static int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
++{
++ struct nid_stat *stat = obj;
++ ENTRY;
++
++ CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
++ if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) {
++ /* object has only hash references. */
++ spin_lock(&stat->nid_obd->obd_nid_lock);
++ cfs_list_move(&stat->nid_list, data);
++ spin_unlock(&stat->nid_obd->obd_nid_lock);
++ RETURN(1);
++ }
++ /* we has reference to object - only clear data*/
++ if (stat->nid_stats)
++ lprocfs_clear_stats(stat->nid_stats);
++
++ RETURN(0);
++}
++
++ssize_t
++lprocfs_nid_stats_clear_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
++{
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
++ struct nid_stat *client_stat;
++ CFS_LIST_HEAD(free_list);
++
++ cfs_hash_cond_del(obd->obd_nid_stats_hash,
++ lprocfs_nid_stats_clear_write_cb, &free_list);
++
++ while (!cfs_list_empty(&free_list)) {
++ client_stat = cfs_list_entry(free_list.next, struct nid_stat,
++ nid_list);
++ cfs_list_del_init(&client_stat->nid_list);
++ lprocfs_free_client_stats(client_stat);
++ }
++ return count;
++}
++EXPORT_SYMBOL(lprocfs_nid_stats_clear_seq_write);
++
++#ifndef HAVE_ONLY_PROCFS_SEQ
+ int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
+ int *eof, void *data)
+ {
+@@ -2538,26 +2736,6 @@ int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
+ }
+ EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
+
+-static int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
+-{
+- struct nid_stat *stat = obj;
+- ENTRY;
+-
+- CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
+- if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) {
+- /* object has only hash references. */
+- spin_lock(&stat->nid_obd->obd_nid_lock);
+- cfs_list_move(&stat->nid_list, data);
+- spin_unlock(&stat->nid_obd->obd_nid_lock);
+- RETURN(1);
+- }
+- /* we has reference to object - only clear data*/
+- if (stat->nid_stats)
+- lprocfs_clear_stats(stat->nid_stats);
+-
+- RETURN(0);
+-}
+-
+ int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+ {
+@@ -2578,8 +2756,8 @@ int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
+ return count;
+ }
+ EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
++#endif
+
+-#ifdef HAVE_SERVER_SUPPORT
+ int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
+ {
+ struct nid_stat *new_stat, *old_stat;
+@@ -2638,11 +2816,17 @@ int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
+ if (buffer == NULL)
+ GOTO(destroy_new, rc = -ENOMEM);
+
+- memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
++ memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
++#ifndef HAVE_ONLY_PROCFS_SEQ
+ new_stat->nid_proc = lprocfs_register(buffer,
+- obd->obd_proc_exports_entry,
+- NULL, NULL);
+- OBD_FREE(buffer, LNET_NIDSTR_SIZE);
++ obd->obd_proc_exports_entry,
++ NULL, NULL);
++#else
++ new_stat->nid_proc = lprocfs_seq_register(buffer,
++ obd->obd_proc_exports_entry,
++ NULL, NULL);
++#endif
++ OBD_FREE(buffer, LNET_NIDSTR_SIZE);
+
+ if (IS_ERR(new_stat->nid_proc)) {
+ rc = PTR_ERR(new_stat->nid_proc);
+@@ -2652,16 +2836,26 @@ int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
+ GOTO(destroy_new_ns, rc);
+ }
+
++#ifndef HAVE_ONLY_PROCFS_SEQ
+ entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
+ lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
++#else
++ entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
++ new_stat, &lprocfs_exp_uuid_fops);
++#endif
+ if (IS_ERR(entry)) {
+ CWARN("Error adding the NID stats file\n");
+ rc = PTR_ERR(entry);
+ GOTO(destroy_new_ns, rc);
+ }
+
++#ifndef HAVE_ONLY_PROCFS_SEQ
+ entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
+ lprocfs_exp_rd_hash, NULL, new_stat, NULL);
++#else
++ entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
++ new_stat, &lprocfs_exp_hash_fops);
++#endif
+ if (IS_ERR(entry)) {
+ CWARN("Error adding the hash file\n");
+ rc = PTR_ERR(entry);
+@@ -3066,6 +3260,181 @@ void lprocfs_oh_clear(struct obd_histogram *oh)
+ }
+ EXPORT_SYMBOL(lprocfs_oh_clear);
+
++#ifdef HAVE_SERVER_SUPPORT
++int lprocfs_hash_seq_show(struct seq_file *m, void *data)
++{
++ struct obd_device *obd = m->private;
++ int c = 0;
++
++ if (obd == NULL)
++ return 0;
++
++ c += cfs_hash_debug_header_seq(m);
++ c += cfs_hash_debug_str_seq(obd->obd_uuid_hash, m);
++ c += cfs_hash_debug_str_seq(obd->obd_nid_hash, m);
++ c += cfs_hash_debug_str_seq(obd->obd_nid_stats_hash, m);
++ return c;
++}
++EXPORT_SYMBOL(lprocfs_hash_seq_show);
++
++int lprocfs_recovery_status_seq_show(struct seq_file *m, void *data)
++{
++ struct obd_device *obd = m->private;
++
++ LASSERT(obd != NULL);
++
++ seq_printf(m, "status: \n");
++ if (obd->obd_max_recoverable_clients == 0) {
++ seq_printf(m, "INACTIVE\n");
++ goto out;
++ }
++
++ /* sampled unlocked, but really... */
++ if (obd->obd_recovering == 0) {
++ seq_printf(m, "COMPLETE\n");
++ seq_printf(m, "recovery_start: %lu\n", obd->obd_recovery_start);
++ seq_printf(m, "recovery_duration: %lu\n",
++ obd->obd_recovery_end - obd->obd_recovery_start);
++ /* Number of clients that have completed recovery */
++ seq_printf(m, "completed_clients: %d/%d\n",
++ obd->obd_max_recoverable_clients -
++ obd->obd_stale_clients,
++ obd->obd_max_recoverable_clients);
++ seq_printf(m, "replayed_requests: %d\n",
++ obd->obd_replayed_requests);
++ seq_printf(m, "last_transno: "LPD64"\n",
++ obd->obd_next_recovery_transno - 1);
++ seq_printf(m, "VBR: %s\n", obd->obd_version_recov ?
++ "ENABLED" : "DISABLED");
++ seq_printf(m, "IR: %s\n", obd->obd_no_ir ?
++ "DISABLED" : "ENABLED");
++ goto out;
++ }
++
++ seq_printf(m, "RECOVERING\n");
++ seq_printf(m, "recovery_start: %lu\n", obd->obd_recovery_start);
++ seq_printf(m, "time_remaining: %lu\n",
++ cfs_time_current_sec() >=
++ obd->obd_recovery_start +
++ obd->obd_recovery_timeout ? 0 :
++ obd->obd_recovery_start +
++ obd->obd_recovery_timeout -
++ cfs_time_current_sec());
++ seq_printf(m, "connected_clients: %d/%d\n",
++ cfs_atomic_read(&obd->obd_connected_clients),
++ obd->obd_max_recoverable_clients);
++ /* Number of clients that have completed recovery */
++ seq_printf(m, "req_replay_clients: %d\n",
++ cfs_atomic_read(&obd->obd_req_replay_clients));
++ seq_printf(m, "lock_repay_clients: %d\n",
++ cfs_atomic_read(&obd->obd_lock_replay_clients));
++ seq_printf(m, "completed_clients: %d\n",
++ cfs_atomic_read(&obd->obd_connected_clients) -
++ cfs_atomic_read(&obd->obd_lock_replay_clients));
++ seq_printf(m, "evicted_clients: %d\n", obd->obd_stale_clients);
++ seq_printf(m, "replayed_requests: %d\n", obd->obd_replayed_requests);
++ seq_printf(m, "queued_requests: %d\n",
++ obd->obd_requests_queued_for_recovery);
++ seq_printf(m, "next_transno: "LPD64"\n",
++ obd->obd_next_recovery_transno);
++out:
++ return 0;
++}
++EXPORT_SYMBOL(lprocfs_recovery_status_seq_show);
++
++int lprocfs_ir_factor_seq_show(struct seq_file *m, void *data)
++{
++ struct obd_device *obd = m->private;
++
++ LASSERT(obd != NULL);
++ return seq_printf(m, "%d\n", obd->obd_recovery_ir_factor);
++}
++EXPORT_SYMBOL(lprocfs_ir_factor_seq_show);
++
++ssize_t
++lprocfs_ir_factor_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
++{
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
++ int val, rc;
++
++ LASSERT(obd != NULL);
++ rc = lprocfs_write_helper(buffer, count, &val);
++ if (rc)
++ return rc;
++
++ if (val < OBD_IR_FACTOR_MIN || val > OBD_IR_FACTOR_MAX)
++ return -EINVAL;
++
++ obd->obd_recovery_ir_factor = val;
++ return count;
++}
++EXPORT_SYMBOL(lprocfs_ir_factor_seq_write);
++
++int lprocfs_recovery_time_soft_seq_show(struct seq_file *m, void *data)
++{
++ struct obd_device *obd = m->private;
++
++ LASSERT(obd != NULL);
++ return seq_printf(m, "%d\n", obd->obd_recovery_timeout);
++}
++EXPORT_SYMBOL(lprocfs_recovery_time_soft_seq_show);
++
++ssize_t
++lprocfs_recovery_time_soft_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
++{
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
++ int val, rc;
++
++ LASSERT(obd != NULL);
++ rc = lprocfs_write_helper(buffer, count, &val);
++ if (rc)
++ return rc;
++
++ obd->obd_recovery_timeout = val;
++ return count;
++}
++EXPORT_SYMBOL(lprocfs_recovery_time_soft_seq_write);
++
++int lprocfs_recovery_time_hard_seq_show(struct seq_file *m, void *data)
++{
++ struct obd_device *obd = m->private;
++
++ LASSERT(obd != NULL);
++ return seq_printf(m, "%u\n", obd->obd_recovery_time_hard);
++}
++EXPORT_SYMBOL(lprocfs_recovery_time_hard_seq_show);
++
++ssize_t
++lprocfs_recovery_time_hard_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
++{
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
++ int val, rc;
++
++ LASSERT(obd != NULL);
++ rc = lprocfs_write_helper(buffer, count, &val);
++ if (rc)
++ return rc;
++
++ obd->obd_recovery_time_hard = val;
++ return count;
++}
++EXPORT_SYMBOL(lprocfs_recovery_time_hard_seq_write);
++
++int lprocfs_target_instance_seq_show(struct seq_file *m, void *data)
++{
++ struct obd_device *obd = m->private;
++ struct obd_device_target *target = &obd->u.obt;
++
++ LASSERT(obd != NULL);
++ LASSERT(target->obt_magic == OBT_MAGIC);
++ return seq_printf(m, "%u\n", obd->u.obt.obt_instance);
++}
++EXPORT_SYMBOL(lprocfs_target_instance_seq_show);
++
++#ifndef HAVE_ONLY_PROCFS_SEQ
+ int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+ {
+@@ -3084,7 +3453,6 @@ int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
+ }
+ EXPORT_SYMBOL(lprocfs_obd_rd_hash);
+
+-#ifdef HAVE_SERVER_SUPPORT
+ int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+ {
+@@ -3210,7 +3578,6 @@ out:
+ return min(count, len - (int)off);
+ }
+ EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
+-#endif
+
+ int lprocfs_obd_rd_ir_factor(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+@@ -3295,6 +3662,21 @@ int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
+ }
+ EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
+
++int lprocfs_target_rd_instance(char *page, char **start, off_t off,
++ int count, int *eof, void *data)
++{
++ struct obd_device *obd = (struct obd_device *)data;
++ struct obd_device_target *target = &obd->u.obt;
++
++ LASSERT(obd != NULL);
++ LASSERT(target->obt_magic == OBT_MAGIC);
++ *eof = 1;
++ return snprintf(page, count, "%u\n", obd->u.obt.obt_instance);
++}
++EXPORT_SYMBOL(lprocfs_target_rd_instance);
++#endif /* HAVE_ONLY_PROCFS_SEQ */
++#endif /* HAVE_SERVER_SUPPORT */
++
+ int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+ {
+@@ -3321,19 +3703,4 @@ int lprocfs_obd_max_pages_per_rpc_seq_show(struct seq_file *m, void *data)
+ return rc;
+ }
+ EXPORT_SYMBOL(lprocfs_obd_max_pages_per_rpc_seq_show);
+-
+-#ifdef HAVE_SERVER_SUPPORT
+-int lprocfs_target_rd_instance(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
+-{
+- struct obd_device *obd = (struct obd_device *)data;
+- struct obd_device_target *target = &obd->u.obt;
+-
+- LASSERT(obd != NULL);
+- LASSERT(target->obt_magic == OBT_MAGIC);
+- *eof = 1;
+- return snprintf(page, count, "%u\n", obd->u.obt.obt_instance);
+-}
+-EXPORT_SYMBOL(lprocfs_target_rd_instance);
+-#endif
+ #endif /* LPROCFS*/
+diff --git a/lustre/ptlrpc/lproc_ptlrpc.c b/lustre/ptlrpc/lproc_ptlrpc.c
+index 024169e..076b5e2 100644
+--- a/lustre/ptlrpc/lproc_ptlrpc.c
++++ b/lustre/ptlrpc/lproc_ptlrpc.c
+@@ -1170,49 +1170,6 @@ void ptlrpc_lprocfs_unregister_obd(struct obd_device *obd)
+ }
+ EXPORT_SYMBOL(ptlrpc_lprocfs_unregister_obd);
+
+-#define BUFLEN (UUID_MAX + 5)
+-
+-int lprocfs_wr_evict_client(struct file *file, const char *buffer,
+- unsigned long count, void *data)
+-{
+- struct obd_device *obd = data;
+- char *kbuf;
+- char *tmpbuf;
+-
+- OBD_ALLOC(kbuf, BUFLEN);
+- if (kbuf == NULL)
+- return -ENOMEM;
+-
+- /*
+- * OBD_ALLOC() will zero kbuf, but we only copy BUFLEN - 1
+- * bytes into kbuf, to ensure that the string is NUL-terminated.
+- * UUID_MAX should include a trailing NUL already.
+- */
+- if (copy_from_user(kbuf, buffer,
+- min_t(unsigned long, BUFLEN - 1, count))) {
+- count = -EFAULT;
+- goto out;
+- }
+- tmpbuf = cfs_firststr(kbuf, min_t(unsigned long, BUFLEN - 1, count));
+- class_incref(obd, __FUNCTION__, current);
+-
+- if (strncmp(tmpbuf, "nid:", 4) == 0)
+- obd_export_evict_by_nid(obd, tmpbuf + 4);
+- else if (strncmp(tmpbuf, "uuid:", 5) == 0)
+- obd_export_evict_by_uuid(obd, tmpbuf + 5);
+- else
+- obd_export_evict_by_uuid(obd, tmpbuf);
+-
+- class_decref(obd, __FUNCTION__, current);
+-
+-out:
+- OBD_FREE(kbuf, BUFLEN);
+- return count;
+-}
+-EXPORT_SYMBOL(lprocfs_wr_evict_client);
+-
+-#undef BUFLEN
+-
+ #ifndef HAVE_ONLY_PROCFS_SEQ
+ int lprocfs_wr_ping(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+--
+1.8.5.1
+
diff --git a/sys-cluster/lustre/files/0011-LU-3319-procfs-update-zfs-proc-handling-to-seq_files.patch b/sys-cluster/lustre/files/0011-LU-3319-procfs-update-zfs-proc-handling-to-seq_files.patch
new file mode 100644
index 000000000..b3964cc06
--- /dev/null
+++ b/sys-cluster/lustre/files/0011-LU-3319-procfs-update-zfs-proc-handling-to-seq_files.patch
@@ -0,0 +1,171 @@
+From 45e9fffb84c0c272992232ed229586003ab99e5e Mon Sep 17 00:00:00 2001
+From: James Simmons <uja.ornl@gmail.com>
+Date: Thu, 14 Nov 2013 19:11:20 -0500
+Subject: [PATCH 11/18] LU-3319 procfs: update zfs proc handling to seq_files
+
+Migrate all zfs proc handling to using strictly seq_files.
+
+Signed-off-by: James Simmons <uja.ornl@gmail.com>
+Change-Id: I6dc7e65c3e74e7934a17939815ec3c334fac58c7
+---
+ lustre/osd-zfs/osd_handler.c | 2 +-
+ lustre/osd-zfs/osd_internal.h | 3 --
+ lustre/osd-zfs/osd_lproc.c | 78 ++++++++++++++++++++++---------------------
+ 3 files changed, 41 insertions(+), 42 deletions(-)
+
+diff --git a/lustre/osd-zfs/osd_handler.c b/lustre/osd-zfs/osd_handler.c
+index 77f4799..b40d03d 100644
+--- a/lustre/osd-zfs/osd_handler.c
++++ b/lustre/osd-zfs/osd_handler.c
+@@ -900,7 +900,7 @@ int __init osd_init(void)
+
+ rc = class_register_type(&osd_obd_device_ops, NULL, NULL,
+ #ifndef HAVE_ONLY_PROCFS_SEQ
+- lprocfs_osd_module_vars,
++ NULL,
+ #endif
+ LUSTRE_OSD_ZFS_NAME, &osd_device_type);
+ if (rc)
+diff --git a/lustre/osd-zfs/osd_internal.h b/lustre/osd-zfs/osd_internal.h
+index 0e202d2..fbad073 100644
+--- a/lustre/osd-zfs/osd_internal.h
++++ b/lustre/osd-zfs/osd_internal.h
+@@ -402,9 +402,6 @@ enum {
+ };
+
+ /* osd_lproc.c */
+-extern struct lprocfs_vars lprocfs_osd_obd_vars[];
+-extern struct lprocfs_vars lprocfs_osd_module_vars[];
+-
+ int osd_procfs_init(struct osd_device *osd, const char *name);
+ int osd_procfs_fini(struct osd_device *osd);
+
+diff --git a/lustre/osd-zfs/osd_lproc.c b/lustre/osd-zfs/osd_lproc.c
+index 0854ce6..5a2bbac 100644
+--- a/lustre/osd-zfs/osd_lproc.c
++++ b/lustre/osd-zfs/osd_lproc.c
+@@ -107,27 +107,26 @@ out:
+ RETURN(result);
+ }
+
+-static int lprocfs_osd_rd_fstype(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int zfs_osd_fstype_seq_show(struct seq_file *m, void *data)
+ {
+- return snprintf(page, count, "zfs\n");
++ return seq_printf(m, "zfs\n");
+ }
++LPROC_SEQ_FOPS_RO(zfs_osd_fstype);
+
+-static int lprocfs_osd_rd_mntdev(char *page, char **start, off_t off, int count,
+- int *eof, void *data)
++static int zfs_osd_mntdev_seq_show(struct seq_file *m, void *data)
+ {
+- struct osd_device *osd = osd_dt_dev((struct dt_device *)data);
++ struct osd_device *osd = osd_dt_dev((struct dt_device *)m->private);
+
+ LASSERT(osd != NULL);
+- *eof = 1;
+-
+- return snprintf(page, count, "%s\n", osd->od_mntdev);
++ return seq_printf(m, "%s\n", osd->od_mntdev);
+ }
++LPROC_SEQ_FOPS_RO(zfs_osd_mntdev);
+
+-static int lprocfs_osd_wr_force_sync(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++lprocfs_osd_force_sync_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct dt_device *dt = data;
++ struct dt_device *dt = ((struct seq_file *)file->private_data)->private;
+ struct lu_env env;
+ int rc;
+
+@@ -139,20 +138,21 @@ static int lprocfs_osd_wr_force_sync(struct file *file, const char *buffer,
+
+ return rc == 0 ? count : rc;
+ }
++LPROC_SEQ_FOPS_WO_TYPE(zfs, osd_force_sync);
+
+-static int lprocfs_osd_rd_iused_est(char *page, char **start, off_t off, int count,
+- int *eof, void *data)
++static int zfs_osd_iused_est_seq_show(struct seq_file *m, void *data)
+ {
+- struct osd_device *osd = osd_dt_dev((struct dt_device *)data);
++ struct osd_device *osd = osd_dt_dev((struct dt_device *)m->private);
+ LASSERT(osd != NULL);
+
+- return snprintf(page, count, "%d\n", osd->od_quota_iused_est);
++ return seq_printf(m, "%d\n", osd->od_quota_iused_est);
+ }
+
+-static int lprocfs_osd_wr_iused_est(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t zfs_osd_iused_est_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct osd_device *osd = osd_dt_dev((struct dt_device *)data);
++ struct dt_device *dt = ((struct seq_file *)file->private_data)->private;
++ struct osd_device *osd = osd_dt_dev(dt);
+ int rc, val;
+
+ LASSERT(osd != NULL);
+@@ -165,24 +165,26 @@ static int lprocfs_osd_wr_iused_est(struct file *file, const char *buffer,
+
+ return count;
+ }
+-
+-struct lprocfs_vars lprocfs_osd_obd_vars[] = {
+- { "blocksize", lprocfs_dt_rd_blksize, 0, 0 },
+- { "kbytestotal", lprocfs_dt_rd_kbytestotal, 0, 0 },
+- { "kbytesfree", lprocfs_dt_rd_kbytesfree, 0, 0 },
+- { "kbytesavail", lprocfs_dt_rd_kbytesavail, 0, 0 },
+- { "filestotal", lprocfs_dt_rd_filestotal, 0, 0 },
+- { "filesfree", lprocfs_dt_rd_filesfree, 0, 0 },
+- { "fstype", lprocfs_osd_rd_fstype, 0, 0 },
+- { "mntdev", lprocfs_osd_rd_mntdev, 0, 0 },
+- { "force_sync", 0, lprocfs_osd_wr_force_sync },
+- { "quota_iused_estimate", lprocfs_osd_rd_iused_est,
+- lprocfs_osd_wr_iused_est, 0, 0 },
+- { 0 }
+-};
+-
+-struct lprocfs_vars lprocfs_osd_module_vars[] = {
+- { "num_refs", lprocfs_rd_numrefs, 0, 0 },
++LPROC_SEQ_FOPS(zfs_osd_iused_est);
++
++LPROC_SEQ_FOPS_RO_TYPE(zfs, dt_blksize);
++LPROC_SEQ_FOPS_RO_TYPE(zfs, dt_kbytestotal);
++LPROC_SEQ_FOPS_RO_TYPE(zfs, dt_kbytesfree);
++LPROC_SEQ_FOPS_RO_TYPE(zfs, dt_kbytesavail);
++LPROC_SEQ_FOPS_RO_TYPE(zfs, dt_filestotal);
++LPROC_SEQ_FOPS_RO_TYPE(zfs, dt_filesfree);
++
++struct lprocfs_seq_vars lprocfs_osd_obd_vars[] = {
++ { "blocksize", &zfs_dt_blksize_fops },
++ { "kbytestotal", &zfs_dt_kbytestotal_fops },
++ { "kbytesfree", &zfs_dt_kbytesfree_fops },
++ { "kbytesavail", &zfs_dt_kbytesavail_fops },
++ { "filestotal", &zfs_dt_filestotal_fops },
++ { "filesfree", &zfs_dt_filesfree_fops },
++ { "fstype", &zfs_osd_fstype_fops },
++ { "mntdev", &zfs_osd_mntdev_fops },
++ { "force_sync", &zfs_osd_force_sync_fops },
++ { "quota_iused_estimate",&zfs_osd_iused_est_fops },
+ { 0 }
+ };
+
+@@ -202,7 +204,7 @@ int osd_procfs_init(struct osd_device *osd, const char *name)
+ LASSERT(name != NULL);
+ LASSERT(type != NULL);
+
+- osd->od_proc_entry = lprocfs_register(name, type->typ_procroot,
++ osd->od_proc_entry = lprocfs_seq_register(name, type->typ_procroot,
+ lprocfs_osd_obd_vars, &osd->od_dt_dev);
+ if (IS_ERR(osd->od_proc_entry)) {
+ rc = PTR_ERR(osd->od_proc_entry);
+--
+1.8.5.1
+
diff --git a/sys-cluster/lustre/files/0012-LU-3319-procfs-move-mgs-proc-handling-to-seq_files.patch b/sys-cluster/lustre/files/0012-LU-3319-procfs-move-mgs-proc-handling-to-seq_files.patch
new file mode 100644
index 000000000..bc0b2238f
--- /dev/null
+++ b/sys-cluster/lustre/files/0012-LU-3319-procfs-move-mgs-proc-handling-to-seq_files.patch
@@ -0,0 +1,351 @@
+From fa5fde4522b64dfc2e5695d88dca0ae99910cb1f Mon Sep 17 00:00:00 2001
+From: James Simmons <uja.ornl@gmail.com>
+Date: Tue, 17 Dec 2013 12:24:40 -0500
+Subject: [PATCH 12/18] LU-3319 procfs: move mgs proc handling to seq_files
+
+With 3.10 linux kernel and above proc handling now only
+uses struct seq_files. This patch migrates the mgs
+layer proc entries over to using seq_files.
+
+Signed-off-by: James Simmons <uja.ornl@gmail.com>
+Change-Id: I1a12dd9b1fc8f139116a8f3a684956a5ba88f055
+---
+ lustre/mgs/lproc_mgs.c | 197 ++++++++++++++++++++++------------------------
+ lustre/mgs/mgs_handler.c | 5 +-
+ lustre/mgs/mgs_internal.h | 13 +--
+ lustre/mgs/mgs_nids.c | 11 ++-
+ 4 files changed, 105 insertions(+), 121 deletions(-)
+
+diff --git a/lustre/mgs/lproc_mgs.c b/lustre/mgs/lproc_mgs.c
+index ffa2d0d..746d1c1 100644
+--- a/lustre/mgs/lproc_mgs.c
++++ b/lustre/mgs/lproc_mgs.c
+@@ -126,19 +126,105 @@ static int mgsself_srpc_seq_show(struct seq_file *seq, void *v)
+
+ return 0;
+ }
+-
+ LPROC_SEQ_FOPS_RO(mgsself_srpc);
+
++static int mgs_live_seq_show(struct seq_file *seq, void *v)
++{
++ struct fs_db *fsdb = seq->private;
++ struct mgs_tgt_srpc_conf *srpc_tgt;
++ int i;
++
++ mutex_lock(&fsdb->fsdb_mutex);
++
++ seq_printf(seq, "fsname: %s\n", fsdb->fsdb_name);
++ seq_printf(seq, "flags: %#lx gen: %d\n",
++ fsdb->fsdb_flags, fsdb->fsdb_gen);
++ for (i = 0; i < INDEX_MAP_SIZE * 8; i++)
++ if (test_bit(i, fsdb->fsdb_mdt_index_map))
++ seq_printf(seq, "%s-MDT%04x\n", fsdb->fsdb_name, i);
++ for (i = 0; i < INDEX_MAP_SIZE * 8; i++)
++ if (test_bit(i, fsdb->fsdb_ost_index_map))
++ seq_printf(seq, "%s-OST%04x\n", fsdb->fsdb_name, i);
++
++ seq_printf(seq, "\nSecure RPC Config Rules:\n");
++#if 0
++ seq_printf(seq, "%s.%s=%s\n", fsdb->fsdb_name,
++ PARAM_SRPC_UDESC, fsdb->fsdb_srpc_fl_udesc ? "yes" : "no");
++#endif
++ for (srpc_tgt = fsdb->fsdb_srpc_tgt; srpc_tgt;
++ srpc_tgt = srpc_tgt->mtsc_next) {
++ seq_show_srpc_rules(seq, srpc_tgt->mtsc_tgt,
++ &srpc_tgt->mtsc_rset);
++ }
++ seq_show_srpc_rules(seq, fsdb->fsdb_name, &fsdb->fsdb_srpc_gen);
++
++ lprocfs_rd_ir_state(seq, fsdb);
++
++ mutex_unlock(&fsdb->fsdb_mutex);
++ return 0;
++}
++
++static ssize_t mgs_live_seq_write(struct file *file, const char *buf,
++ size_t len, loff_t *off)
++{
++ struct seq_file *seq = file->private_data;
++ struct fs_db *fsdb = seq->private;
++ ssize_t rc;
++
++ rc = lprocfs_wr_ir_state(file, buf, len, fsdb);
++ if (rc >= 0)
++ rc = len;
++ return rc;
++}
++LPROC_SEQ_FOPS(mgs_live);
++
++int lproc_mgs_add_live(struct mgs_device *mgs, struct fs_db *fsdb)
++{
++ int rc;
++
++ if (!mgs->mgs_proc_live)
++ return 0;
++ rc = lprocfs_seq_create(mgs->mgs_proc_live, fsdb->fsdb_name, 0644,
++ &mgs_live_fops, fsdb);
++
++ return 0;
++}
++
++int lproc_mgs_del_live(struct mgs_device *mgs, struct fs_db *fsdb)
++{
++ if (!mgs->mgs_proc_live)
++ return 0;
++
++ /* didn't create the proc file for MGSSELF_NAME */
++ if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags))
++ lprocfs_remove_proc_entry(fsdb->fsdb_name, mgs->mgs_proc_live);
++ return 0;
++}
++
++LPROC_SEQ_FOPS_RO_TYPE(mgs, uuid);
++LPROC_SEQ_FOPS_RO_TYPE(mgs, num_exports);
++LPROC_SEQ_FOPS_RO_TYPE(mgs, hash);
++LPROC_SEQ_FOPS_WO_TYPE(mgs, evict_client);
++LPROC_SEQ_FOPS_RW_TYPE(mgs, ir_timeout);
++
++struct lprocfs_seq_vars lprocfs_mgs_obd_vars[] = {
++ { "uuid", &mgs_uuid_fops },
++ { "num_exports", &mgs_num_exports_fops },
++ { "hash_stats", &mgs_hash_fops },
++ { "evict_client", &mgs_evict_client_fops },
++ { "ir_timeout", &mgs_ir_timeout_fops },
++ { 0 }
++};
++
+ int lproc_mgs_setup(struct mgs_device *mgs, const char *osd_name)
+ {
+ struct obd_device *obd = mgs->mgs_obd;
+ struct obd_device *osd_obd = mgs->mgs_bottom->dd_lu_dev.ld_obd;
+ int osd_len = strlen(osd_name) - strlen("-osd");
+ int rc;
+- struct lprocfs_static_vars lvars;
+
+- lprocfs_mgs_init_vars(&lvars);
+- rc = lprocfs_obd_setup(obd, lvars.obd_vars);
++ obd->obd_vars = lprocfs_mgs_obd_vars;
++ rc = lprocfs_seq_obd_setup(obd);
+ if (rc != 0)
+ GOTO(out, rc);
+
+@@ -152,17 +238,17 @@ int lproc_mgs_setup(struct mgs_device *mgs, const char *osd_name)
+ if (rc != 0)
+ GOTO(out, rc);
+
+- mgs->mgs_proc_live = lprocfs_register("live", obd->obd_proc_entry,
+- NULL, NULL);
++ mgs->mgs_proc_live = lprocfs_seq_register("live", obd->obd_proc_entry,
++ NULL, NULL);
+ if (IS_ERR(mgs->mgs_proc_live)) {
+ rc = PTR_ERR(mgs->mgs_proc_live);
+ mgs->mgs_proc_live = NULL;
+ GOTO(out, rc);
+ }
+
+- obd->obd_proc_exports_entry = lprocfs_register("exports",
+- obd->obd_proc_entry,
+- NULL, NULL);
++ obd->obd_proc_exports_entry = lprocfs_seq_register("exports",
++ obd->obd_proc_entry,
++ NULL, NULL);
+ if (IS_ERR(obd->obd_proc_exports_entry)) {
+ rc = PTR_ERR(obd->obd_proc_exports_entry);
+ obd->obd_proc_exports_entry = NULL;
+@@ -215,7 +301,6 @@ void lproc_mgs_cleanup(struct mgs_device *mgs)
+
+ if (mgs->mgs_proc_live != NULL) {
+ /* Should be no live entries */
+- LASSERT(mgs->mgs_proc_live->subdir == NULL);
+ lprocfs_remove(&mgs->mgs_proc_live);
+ mgs->mgs_proc_live = NULL;
+ }
+@@ -226,92 +311,6 @@ void lproc_mgs_cleanup(struct mgs_device *mgs)
+ lprocfs_free_md_stats(obd);
+ }
+
+-static int mgs_live_seq_show(struct seq_file *seq, void *v)
+-{
+- struct fs_db *fsdb = seq->private;
+- struct mgs_tgt_srpc_conf *srpc_tgt;
+- int i;
+-
+- mutex_lock(&fsdb->fsdb_mutex);
+-
+- seq_printf(seq, "fsname: %s\n", fsdb->fsdb_name);
+- seq_printf(seq, "flags: %#lx gen: %d\n",
+- fsdb->fsdb_flags, fsdb->fsdb_gen);
+- for (i = 0; i < INDEX_MAP_SIZE * 8; i++)
+- if (test_bit(i, fsdb->fsdb_mdt_index_map))
+- seq_printf(seq, "%s-MDT%04x\n", fsdb->fsdb_name, i);
+- for (i = 0; i < INDEX_MAP_SIZE * 8; i++)
+- if (test_bit(i, fsdb->fsdb_ost_index_map))
+- seq_printf(seq, "%s-OST%04x\n", fsdb->fsdb_name, i);
+-
+- seq_printf(seq, "\nSecure RPC Config Rules:\n");
+-#if 0
+- seq_printf(seq, "%s.%s=%s\n", fsdb->fsdb_name,
+- PARAM_SRPC_UDESC, fsdb->fsdb_srpc_fl_udesc ? "yes" : "no");
+-#endif
+- for (srpc_tgt = fsdb->fsdb_srpc_tgt; srpc_tgt;
+- srpc_tgt = srpc_tgt->mtsc_next) {
+- seq_show_srpc_rules(seq, srpc_tgt->mtsc_tgt,
+- &srpc_tgt->mtsc_rset);
+- }
+- seq_show_srpc_rules(seq, fsdb->fsdb_name, &fsdb->fsdb_srpc_gen);
+-
+- lprocfs_rd_ir_state(seq, fsdb);
+-
+- mutex_unlock(&fsdb->fsdb_mutex);
+- return 0;
+-}
+-
+-static ssize_t mgs_live_seq_write(struct file *file, const char *buf,
+- size_t len, loff_t *off)
+-{
+- struct seq_file *seq = file->private_data;
+- struct fs_db *fsdb = seq->private;
+- ssize_t rc;
+-
+- rc = lprocfs_wr_ir_state(file, buf, len, fsdb);
+- if (rc >= 0)
+- rc = len;
+- return rc;
+-}
+-LPROC_SEQ_FOPS(mgs_live);
+-
+-int lproc_mgs_add_live(struct mgs_device *mgs, struct fs_db *fsdb)
+-{
+- int rc;
+-
+- if (!mgs->mgs_proc_live)
+- return 0;
+- rc = lprocfs_seq_create(mgs->mgs_proc_live, fsdb->fsdb_name, 0644,
+- &mgs_live_fops, fsdb);
+-
+- return 0;
+-}
+-
+-int lproc_mgs_del_live(struct mgs_device *mgs, struct fs_db *fsdb)
+-{
+- if (!mgs->mgs_proc_live)
+- return 0;
+-
+- /* didn't create the proc file for MGSSELF_NAME */
+- if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags))
+- lprocfs_remove_proc_entry(fsdb->fsdb_name, mgs->mgs_proc_live);
+- return 0;
+-}
+-
+-struct lprocfs_vars lprocfs_mgs_obd_vars[] = {
+- { "uuid", lprocfs_rd_uuid, 0, 0 },
+- { "num_exports", lprocfs_rd_num_exports, 0, 0 },
+- { "hash_stats", lprocfs_obd_rd_hash, 0, 0 },
+- { "evict_client", 0, lprocfs_wr_evict_client, 0 },
+- { "ir_timeout", lprocfs_rd_ir_timeout, lprocfs_wr_ir_timeout, 0 },
+- { 0 }
+-};
+-
+-struct lprocfs_vars lprocfs_mgs_module_vars[] = {
+- { 0 }
+-};
+-
+ void mgs_counter_incr(struct obd_export *exp, int opcode)
+ {
+ lprocfs_counter_incr(exp->exp_obd->obd_stats, opcode);
+@@ -329,10 +328,4 @@ void mgs_stats_counter_init(struct lprocfs_stats *stats)
+ lprocfs_counter_init(stats, LPROC_MGS_TARGET_REG, 0, "tgtreg", "reqs");
+ lprocfs_counter_init(stats, LPROC_MGS_TARGET_DEL, 0, "tgtdel", "reqs");
+ }
+-
+-void lprocfs_mgs_init_vars(struct lprocfs_static_vars *lvars)
+-{
+- lvars->module_vars = lprocfs_mgs_module_vars;
+- lvars->obd_vars = lprocfs_mgs_obd_vars;
+-}
+ #endif
+diff --git a/lustre/mgs/mgs_handler.c b/lustre/mgs/mgs_handler.c
+index 560dd19..a294237 100644
+--- a/lustre/mgs/mgs_handler.c
++++ b/lustre/mgs/mgs_handler.c
+@@ -1376,12 +1376,9 @@ static struct obd_ops mgs_obd_device_ops = {
+
+ static int __init mgs_init(void)
+ {
+- struct lprocfs_static_vars lvars;
+-
+- lprocfs_mgs_init_vars(&lvars);
+ return class_register_type(&mgs_obd_device_ops, NULL, NULL,
+ #ifndef HAVE_ONLY_PROCFS_SEQ
+- lvars.module_vars,
++ NULL,
+ #endif
+ LUSTRE_MGS_NAME, &mgs_device_type);
+ }
+diff --git a/lustre/mgs/mgs_internal.h b/lustre/mgs/mgs_internal.h
+index 514dc23..497ad9d 100644
+--- a/lustre/mgs/mgs_internal.h
++++ b/lustre/mgs/mgs_internal.h
+@@ -225,10 +225,10 @@ int mgs_get_ir_logs(struct ptlrpc_request *req);
+ int lprocfs_wr_ir_state(struct file *file, const char *buffer,
+ unsigned long count, void *data);
+ int lprocfs_rd_ir_state(struct seq_file *seq, void *data);
+-int lprocfs_wr_ir_timeout(struct file *file, const char *buffer,
+- unsigned long count, void *data);
+-int lprocfs_rd_ir_timeout(char *page, char **start, off_t off, int count,
+- int *eof, void *data);
++ssize_t
++lprocfs_ir_timeout_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off);
++int lprocfs_ir_timeout_seq_show(struct seq_file *seq, void *data);
+ void mgs_fsc_cleanup(struct obd_export *exp);
+ void mgs_fsc_cleanup_by_fsdb(struct fs_db *fsdb);
+ int mgs_fsc_attach(const struct lu_env *env, struct obd_export *exp,
+@@ -246,7 +246,6 @@ int lproc_mgs_setup(struct mgs_device *mgs, const char *osd_name);
+ void lproc_mgs_cleanup(struct mgs_device *mgs);
+ int lproc_mgs_add_live(struct mgs_device *mgs, struct fs_db *fsdb);
+ int lproc_mgs_del_live(struct mgs_device *mgs, struct fs_db *fsdb);
+-void lprocfs_mgs_init_vars(struct lprocfs_static_vars *lvars);
+ #else
+ static inline int lproc_mgs_setup(struct mgs_device *mgs, const char *osd_name)
+ {return 0;}
+@@ -256,10 +255,6 @@ static inline int lproc_mgs_add_live(struct mgs_device *mgs, struct fs_db *fsdb)
+ {return 0;}
+ static inline int lproc_mgs_del_live(struct mgs_device *mgs, struct fs_db *fsdb)
+ {return 0;}
+-static void lprocfs_mgs_init_vars(struct lprocfs_static_vars *lvars)
+-{
+- memset(lvars, 0, sizeof(*lvars));
+-}
+ #endif
+
+ /* mgs/lproc_mgs.c */
+diff --git a/lustre/mgs/mgs_nids.c b/lustre/mgs/mgs_nids.c
+index 4d53969..73a4576 100644
+--- a/lustre/mgs/mgs_nids.c
++++ b/lustre/mgs/mgs_nids.c
+@@ -838,15 +838,14 @@ int lprocfs_rd_ir_state(struct seq_file *seq, void *data)
+ return 0;
+ }
+
+-int lprocfs_rd_ir_timeout(char *page, char **start, off_t off, int count,
+- int *eof, void *data)
++int lprocfs_ir_timeout_seq_show(struct seq_file *m, void *data)
+ {
+- *eof = 1;
+- return snprintf(page, count, "%d\n", ir_timeout);
++ return lprocfs_uint_seq_show(m, &ir_timeout);
+ }
+
+-int lprocfs_wr_ir_timeout(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++ssize_t
++lprocfs_ir_timeout_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+ return lprocfs_wr_uint(file, buffer, count, &ir_timeout);
+ }
+--
+1.8.5.1
+
diff --git a/sys-cluster/lustre/files/0013-LU-3319-procfs-move-ofd-proc-handling-to-seq_files.patch b/sys-cluster/lustre/files/0013-LU-3319-procfs-move-ofd-proc-handling-to-seq_files.patch
new file mode 100644
index 000000000..cb8fd79c6
--- /dev/null
+++ b/sys-cluster/lustre/files/0013-LU-3319-procfs-move-ofd-proc-handling-to-seq_files.patch
@@ -0,0 +1,759 @@
+From 8fa5fb0ecac2a7b0279e0010bfe74acb107c37d8 Mon Sep 17 00:00:00 2001
+From: James Simmons <uja.ornl@gmail.com>
+Date: Thu, 14 Nov 2013 19:47:36 -0500
+Subject: [PATCH 13/18] LU-3319 procfs: move 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 ofd
+layer proc entries over to using seq_files.
+
+Signed-off-by: James Simmons <uja.ornl@gmail.com>
+Change-Id: Id8f77d72fd35755f1b7b1c17fcf27e0731bd5ac1
+---
+ lustre/obdclass/lprocfs_status.c | 9 +-
+ lustre/ofd/lproc_ofd.c | 352 +++++++++++++++++----------------------
+ lustre/ofd/ofd_dev.c | 41 ++---
+ lustre/ofd/ofd_internal.h | 7 +-
+ 4 files changed, 180 insertions(+), 229 deletions(-)
+
+diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c
+index a33cbf2..bd6741e 100644
+--- a/lustre/obdclass/lprocfs_status.c
++++ b/lustre/obdclass/lprocfs_status.c
+@@ -387,11 +387,10 @@ EXPORT_SYMBOL(lprocfs_evict_client_seq_write);
+ #undef BUFLEN
+
+ struct file_operations lprocfs_evict_client_fops = {
+- .owner = THIS_MODULE,
+- .read = lprocfs_fops_read,
+- .write = lprocfs_fops_write,
+- .open = lprocfs_evict_client_open,
+- .release = lprocfs_evict_client_release,
++ .owner = THIS_MODULE,
++ .open = lprocfs_evict_client_open,
++ .release = lprocfs_evict_client_release,
++ .write = lprocfs_evict_client_seq_write,
+ };
+ EXPORT_SYMBOL(lprocfs_evict_client_fops);
+ #endif
+diff --git a/lustre/ofd/lproc_ofd.c b/lustre/ofd/lproc_ofd.c
+index 4354497..f462d63 100644
+--- a/lustre/ofd/lproc_ofd.c
++++ b/lustre/ofd/lproc_ofd.c
+@@ -46,80 +46,74 @@
+
+ #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",
++ 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",
++ return seq_printf(m, "%d%%\n",
+ (int) ofd_grant_reserved(ofd, 100));
+ }
+
+-static int lprocfs_ofd_wr_grant_ratio(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++ofd_grant_ratio_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *obd = (struct obd_device *)data;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
+ struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+ int val;
+ int rc;
+@@ -143,23 +137,23 @@ static int lprocfs_ofd_wr_grant_ratio(struct file *file, const char *buffer,
+ 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 *buffer,
+- unsigned long count, void *data)
++static ssize_t
++ofd_precreate_batch_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *obd = (struct obd_device *)data;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
+ struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+ int val;
+ int rc;
+@@ -176,11 +170,11 @@ static int lprocfs_ofd_wr_precreate_batch(struct file *file, const char *buffer,
+ 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;
+@@ -198,35 +192,31 @@ 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)
++int ofd_fmd_max_num_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_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 *buffer,
+- unsigned long count, void *data)
++ssize_t
++ofd_fmd_max_num_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
+ struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+ int val;
+ int rc;
+@@ -241,22 +231,21 @@ int lprocfs_ofd_wr_fmd_max_num(struct file *file, const char *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)
++int ofd_fmd_max_age_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, "%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 *buffer,
+- unsigned long count, void *data)
++ssize_t
++ofd_fmd_max_age_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
+ struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+ int val;
+ int rc;
+@@ -271,22 +260,21 @@ int lprocfs_ofd_wr_fmd_max_age(struct file *file, const char *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 *buffer,
+- unsigned long count, void *data)
++static ssize_t
++ofd_capa_seq_write(struct file *file, const char *buffer, size_t count,
++ loff_t *off)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
+ int val, rc;
+
+ rc = lprocfs_write_helper(buffer, count, &val);
+@@ -305,28 +293,29 @@ static int lprocfs_ofd_wr_capa(struct file *file, const char *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",
++ 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)
++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 *buffer,
+- unsigned long count, void *data)
++ssize_t
++ofd_degraded_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
+ struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+ int val, rc;
+
+@@ -337,38 +326,35 @@ int lprocfs_ofd_wr_degraded(struct file *file, const char *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)
++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)
++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 *buffer,
+- unsigned long count, void *data)
++ssize_t ofd_syncjournal_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
+ struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+ int val;
+ int rc;
+@@ -387,27 +373,26 @@ int lprocfs_ofd_wr_syncjournal(struct file *file, const char *buffer,
+
+ return count;
+ }
++LPROC_SEQ_FOPS(ofd_syncjournal);
+
+ 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)
++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 *buffer,
+- unsigned long count, void *data)
++ssize_t
++ofd_sync_lock_cancel_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
+ struct lu_target *tgt = obd->u.obt.obt_lut;
+ int val = -1;
+ int i;
+@@ -435,22 +420,21 @@ int lprocfs_ofd_wr_sync_lock_cancel(struct file *file, const char *buffer,
+ 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)
++int ofd_grant_compat_disable_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_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 *buffer,
+- unsigned long count, void *data)
++ssize_t
++ofd_grant_compat_disable_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
+ struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+ int val;
+ int rc;
+@@ -469,86 +453,64 @@ int lprocfs_ofd_wr_grant_compat_disable(struct file *file, const char *buffer,
+ return count;
+ }
+
+-int lprocfs_ofd_rd_soft_sync_limit(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
+-{
+- struct obd_device *obd = data;
+- struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+-
+- return lprocfs_rd_uint(page, start, off, count, eof,
+- &ofd->ofd_soft_sync_limit);
+-}
+-
+-int lprocfs_ofd_wr_soft_sync_limit(struct file *file, const char *buffer,
+- unsigned long count, void *data)
+-{
+- struct obd_device *obd = data;
+- struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+-
+- return lprocfs_wr_uint(file, buffer, count, &ofd->ofd_soft_sync_limit);
+-}
+-
+-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},
+- { 0 }
+-};
+-
+-static struct lprocfs_vars lprocfs_ofd_module_vars[] = {
+- { "num_refs", lprocfs_rd_numrefs, 0, 0 },
++LPROC_SEQ_FOPS(ofd_grant_compat_disable);
++
++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);
++
++static struct lprocfs_seq_vars lprocfs_ofd_obd_vars[] = {
++ { "uuid", &ofd_uuid_fops },
++ { "blocksize", &ofd_blksize_fops },
++ { "kbytestotal", &ofd_kbytestotal_fops },
++ { "kbytesfree", &ofd_kbytesfree_fops },
++ { "kbytesavail", &ofd_kbytesavail_fops },
++ { "filestotal", &ofd_filestotal_fops },
++ { "filesfree", &ofd_filesfree_fops },
++ { "seqs_allocated", &ofd_seqs_fops },
++ { "fstype", &ofd_fstype_fops },
++ { "last_id", &ofd_last_id_fops },
++ { "tot_dirty", &ofd_tot_dirty_fops },
++ { "tot_pending", &ofd_tot_pending_fops },
++ { "tot_granted", &ofd_tot_granted_fops },
++ { "grant_precreate", &ofd_grant_precreate_fops },
++ { "grant_ratio", &ofd_grant_ratio_fops },
++ { "precreate_batch", &ofd_precreate_batch_fops },
++ { "recovery_status", &ofd_recovery_status_fops },
++ { "recovery_time_soft", &ofd_recovery_time_soft_fops },
++ { "recovery_time_hard", &ofd_recovery_time_hard_fops },
++ { "evict_client", &ofd_evict_client_fops },
++ { "num_exports", &ofd_num_exports_fops },
++ { "degraded", &ofd_degraded_fops },
++ { "sync_journal", &ofd_syncjournal_fops },
++ { "sync_on_lock_cancel", &ofd_sync_lock_cancel_fops },
++ { "instance", &ofd_target_instance_fops },
++ { "ir_factor", &ofd_ir_factor_fops },
++ { "grant_compat_disable", &ofd_grant_compat_disable_fops },
++ { "client_cache_count", &ofd_fmd_max_num_fops },
++ { "client_cache_seconds", &ofd_fmd_max_age_fops },
++ { "capa", &ofd_capa_fops },
++ { "capa_count", &ofd_capa_count_fops },
++ { "job_cleanup_interval", &ofd_job_interval_fops },
+ { 0 }
+ };
+
+-void lprocfs_ofd_init_vars(struct lprocfs_static_vars *lvars)
++void lprocfs_ofd_init_vars(struct obd_device *obd)
+ {
+- lvars->module_vars = lprocfs_ofd_module_vars;
+- lvars->obd_vars = lprocfs_ofd_obd_vars;
++ obd->obd_vars = lprocfs_ofd_obd_vars;
+ }
+
+ void ofd_stats_counter_init(struct lprocfs_stats *stats)
+diff --git a/lustre/ofd/ofd_dev.c b/lustre/ofd/ofd_dev.c
+index 2bdbde6..e3b8358 100644
+--- a/lustre/ofd/ofd_dev.c
++++ b/lustre/ofd/ofd_dev.c
+@@ -206,8 +206,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;
+@@ -240,8 +239,7 @@ static int ofd_process_config(const struct lu_env *env, struct lu_device *d,
+ }
+ }
+
+- 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)
+ /* we don't understand; pass it on */
+@@ -422,9 +420,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;
+@@ -433,8 +432,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);
++ lprocfs_ofd_init_vars(obd);
++ rc = lprocfs_seq_obd_setup(obd);
+ if (rc) {
+ CERROR("%s: lprocfs_obd_setup failed: %d.\n",
+ obd->obd_name, rc);
+@@ -450,7 +449,7 @@ 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",
+@@ -460,8 +459,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",
+@@ -477,7 +478,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);
+@@ -487,7 +488,7 @@ obd_cleanup:
+
+ static void ofd_procfs_add_brw_stats_symlink(struct ofd_device *ofd)
+ {
+- struct obd_device *obd = ofd_obd(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;
+@@ -516,20 +517,15 @@ static void ofd_procfs_add_brw_stats_symlink(struct ofd_device *ofd)
+ lprocfs_add_symlink("writethrough_cache_enable",
+ obd->obd_proc_entry,
+ "../../%s/%s/writethrough_cache_enable",
+- osd_root->name, osd_dir->name);
++ osd_root->name, osd_dir->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);
+@@ -1889,7 +1885,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);
+@@ -1902,11 +1897,9 @@ int __init ofd_init(void)
+ return(rc);
+ }
+
+- lprocfs_ofd_init_vars(&lvars);
+-
+ rc = class_register_type(&ofd_obd_ops, NULL, 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 9285a1f..6acae49 100644
+--- a/lustre/ofd/ofd_internal.h
++++ b/lustre/ofd/ofd_internal.h
+@@ -383,13 +383,10 @@ 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);
++void lprocfs_ofd_init_vars(struct obd_device *obd);
+ 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 void lprocfs_ofd_init_vars(struct obd_device *obd) {}
+ static inline void ofd_stats_counter_init(struct lprocfs_stats *stats) {}
+ #endif
+
+--
+1.8.5.1
+
diff --git a/sys-cluster/lustre/files/0014-LU-3319-procfs-move-lod-proc-handling-to-seq_files.patch b/sys-cluster/lustre/files/0014-LU-3319-procfs-move-lod-proc-handling-to-seq_files.patch
new file mode 100644
index 000000000..4bbea0353
--- /dev/null
+++ b/sys-cluster/lustre/files/0014-LU-3319-procfs-move-lod-proc-handling-to-seq_files.patch
@@ -0,0 +1,589 @@
+From eb1406399522d52e51c3dd7e8a73813c0179d12a Mon Sep 17 00:00:00 2001
+From: James Simmons <uja.ornl@gmail.com>
+Date: Thu, 14 Nov 2013 19:20:50 -0500
+Subject: [PATCH 14/18] LU-3319 procfs: move lod proc handling to seq_files
+
+With 3.10 linux kernel and above proc handling now only
+uses struct seq_files. This patch migrates the lod
+layer proc entries over to using seq_files.
+
+Signed-off-by: James Simmons <uja.ornl@gmail.com>
+Change-Id: Iaa0f617fcd430e91f12afbc0faf6906fd275a7a5
+---
+ lustre/lod/lod_dev.c | 28 +----
+ lustre/lod/lod_internal.h | 1 -
+ lustre/lod/lod_pool.c | 7 +-
+ lustre/lod/lproc_lod.c | 255 ++++++++++++++++++++++++----------------------
+ 4 files changed, 143 insertions(+), 148 deletions(-)
+
+diff --git a/lustre/lod/lod_dev.c b/lustre/lod/lod_dev.c
+index e36aee1..8a0be26 100644
+--- a/lustre/lod/lod_dev.c
++++ b/lustre/lod/lod_dev.c
+@@ -297,12 +297,10 @@ static int lod_process_config(const struct lu_env *env,
+ }
+
+ case LCFG_PARAM: {
+- struct lprocfs_static_vars v = { 0 };
+- struct obd_device *obd = lod2obd(lod);
++ struct obd_device *obd = lod2obd(lod);
+
+- lprocfs_lod_init_vars(&v);
+-
+- rc = class_process_proc_param(PARAM_LOV, v.obd_vars, lcfg, obd);
++ rc = class_process_proc_seq_param(PARAM_LOV, obd->obd_vars,
++ lcfg, obd);
+ if (rc > 0)
+ rc = 0;
+ GOTO(out, rc);
+@@ -916,44 +914,26 @@ static struct obd_ops lod_obd_device_ops = {
+
+ static int __init lod_mod_init(void)
+ {
+- struct lprocfs_static_vars lvars = { 0 };
+- cfs_proc_dir_entry_t *lov_proc_dir;
+ int rc;
+
+ rc = lu_kmem_init(lod_caches);
+ if (rc)
+ return rc;
+
+- lprocfs_lod_init_vars(&lvars);
+-
+ rc = class_register_type(&lod_obd_device_ops, NULL, NULL,
+ #ifndef HAVE_ONLY_PROCFS_SEQ
+- lvars.module_vars,
++ NULL,
+ #endif
+ LUSTRE_LOD_NAME, &lod_device_type);
+ if (rc) {
+ lu_kmem_fini(lod_caches);
+ return rc;
+ }
+-
+- /* create "lov" entry in procfs for compatibility purposes */
+- lov_proc_dir = lprocfs_srch(proc_lustre_root, "lov");
+- if (lov_proc_dir == NULL) {
+- lov_proc_dir = lprocfs_register("lov", proc_lustre_root,
+- NULL, NULL);
+- if (IS_ERR(lov_proc_dir))
+- CERROR("lod: can't create compat entry \"lov\": %d\n",
+- (int)PTR_ERR(lov_proc_dir));
+- }
+-
+ return rc;
+ }
+
+ static void __exit lod_mod_exit(void)
+ {
+-
+- lprocfs_try_remove_proc_entry("lov", proc_lustre_root);
+-
+ class_unregister_type(LUSTRE_LOD_NAME);
+ lu_kmem_fini(lod_caches);
+ }
+diff --git a/lustre/lod/lod_internal.h b/lustre/lod/lod_internal.h
+index 0dd077b..bb6fbfb 100644
+--- a/lustre/lod/lod_internal.h
++++ b/lustre/lod/lod_internal.h
+@@ -317,7 +317,6 @@ int qos_add_tgt(struct lod_device*, struct lod_tgt_desc *);
+ int qos_del_tgt(struct lod_device *, struct lod_tgt_desc *);
+
+ /* lproc_lod.c */
+-void lprocfs_lod_init_vars(struct lprocfs_static_vars *lvars);
+ int lod_procfs_init(struct lod_device *lod);
+ void lod_procfs_fini(struct lod_device *lod);
+
+diff --git a/lustre/lod/lod_pool.c b/lustre/lod/lod_pool.c
+index e33ae4d..77d04a7 100644
+--- a/lustre/lod/lod_pool.c
++++ b/lustre/lod/lod_pool.c
+@@ -283,7 +283,7 @@ static int pool_proc_open(struct inode *inode, struct file *file)
+ rc = seq_open(file, &pool_proc_ops);
+ if (!rc) {
+ struct seq_file *s = file->private_data;
+- s->private = PROC_I(inode)->pde->data;
++ s->private = PDE_DATA(inode);
+ }
+ return rc;
+ }
+@@ -462,7 +462,10 @@ int lod_pool_new(struct obd_device *obd, char *poolname)
+ #ifdef LPROCFS
+ lod_pool_getref(new_pool);
+ new_pool->pool_proc_entry = lprocfs_add_simple(lod->lod_pool_proc_entry,
+- poolname, NULL, NULL,
++ poolname,
++#ifndef HAVE_ONLY_PROCFS_SEQ
++ NULL, NULL,
++#endif
+ new_pool,
+ &pool_proc_operations);
+ if (IS_ERR(new_pool->pool_proc_entry)) {
+diff --git a/lustre/lod/lproc_lod.c b/lustre/lod/lproc_lod.c
+index e976063..b0d4e17 100644
+--- a/lustre/lod/lproc_lod.c
++++ b/lustre/lod/lproc_lod.c
+@@ -42,23 +42,22 @@
+ #include <lustre_param.h>
+
+ #ifdef LPROCFS
+-static int lod_rd_stripesize(char *page, char **start, off_t off, int count,
+- int *eof, void *data)
++static int lod_stripesize_seq_show(struct seq_file *m, void *v)
+ {
+- struct obd_device *dev = (struct obd_device *)data;
++ struct obd_device *dev = m->private;
+ struct lod_device *lod;
+
+ LASSERT(dev != NULL);
+ lod = lu2lod_dev(dev->obd_lu_dev);
+- *eof = 1;
+- return snprintf(page, count, LPU64"\n",
++ return seq_printf(m, LPU64"\n",
+ lod->lod_desc.ld_default_stripe_size);
+ }
+
+-static int lod_wr_stripesize(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++lod_stripesize_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *dev = (struct obd_device *)data;
++ struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
+ struct lod_device *lod;
+ __u64 val;
+ int rc;
+@@ -73,24 +72,24 @@ static int lod_wr_stripesize(struct file *file, const char *buffer,
+ lod->lod_desc.ld_default_stripe_size = val;
+ return count;
+ }
++LPROC_SEQ_FOPS(lod_stripesize);
+
+-static int lod_rd_stripeoffset(char *page, char **start, off_t off, int count,
+- int *eof, void *data)
++static int lod_stripeoffset_seq_show(struct seq_file *m, void *v)
+ {
+- struct obd_device *dev = (struct obd_device *)data;
++ struct obd_device *dev = m->private;
+ struct lod_device *lod;
+
+ LASSERT(dev != NULL);
+ lod = lu2lod_dev(dev->obd_lu_dev);
+- *eof = 1;
+- return snprintf(page, count, LPU64"\n",
++ return seq_printf(m, LPU64"\n",
+ lod->lod_desc.ld_default_stripe_offset);
+ }
+
+-static int lod_wr_stripeoffset(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++lod_stripeoffset_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *dev = (struct obd_device *)data;
++ struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
+ struct lod_device *lod;
+ __u64 val;
+ int rc;
+@@ -104,23 +103,23 @@ static int lod_wr_stripeoffset(struct file *file, const char *buffer,
+ lod->lod_desc.ld_default_stripe_offset = val;
+ return count;
+ }
++LPROC_SEQ_FOPS(lod_stripeoffset);
+
+-static int lod_rd_stripetype(char *page, char **start, off_t off, int count,
+- int *eof, void *data)
++static int lod_stripetype_seq_show(struct seq_file *m, void *v)
+ {
+- struct obd_device *dev = (struct obd_device *)data;
++ struct obd_device *dev = m->private;
+ struct lod_device *lod;
+
+ LASSERT(dev != NULL);
+ lod = lu2lod_dev(dev->obd_lu_dev);
+- *eof = 1;
+- return snprintf(page, count, "%u\n", lod->lod_desc.ld_pattern);
++ return seq_printf(m, "%u\n", lod->lod_desc.ld_pattern);
+ }
+
+-static int lod_wr_stripetype(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++lod_stripetype_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *dev = (struct obd_device *)data;
++ struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
+ struct lod_device *lod;
+ int val, rc;
+
+@@ -134,24 +133,24 @@ static int lod_wr_stripetype(struct file *file, const char *buffer,
+ lod->lod_desc.ld_pattern = val;
+ return count;
+ }
++LPROC_SEQ_FOPS(lod_stripetype);
+
+-static int lod_rd_stripecount(char *page, char **start, off_t off, int count,
+- int *eof, void *data)
++static int lod_stripecount_seq_show(struct seq_file *m, void *v)
+ {
+- struct obd_device *dev = (struct obd_device *)data;
++ struct obd_device *dev = m->private;
+ struct lod_device *lod;
+
+ LASSERT(dev != NULL);
+ lod = lu2lod_dev(dev->obd_lu_dev);
+- *eof = 1;
+- return snprintf(page, count, "%d\n",
++ return seq_printf(m, "%d\n",
+ (__s16)(lod->lod_desc.ld_default_stripe_count + 1) - 1);
+ }
+
+-static int lod_wr_stripecount(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++lod_stripecount_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *dev = (struct obd_device *)data;
++ struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
+ struct lod_device *lod;
+ int val, rc;
+
+@@ -165,62 +164,57 @@ static int lod_wr_stripecount(struct file *file, const char *buffer,
+ lod->lod_desc.ld_default_stripe_count = val;
+ return count;
+ }
++LPROC_SEQ_FOPS(lod_stripecount);
+
+-static int lod_rd_numobd(char *page, char **start, off_t off, int count,
+- int *eof, void *data)
++static int lod_numobd_seq_show(struct seq_file *m, void *v)
+ {
+- struct obd_device *dev = (struct obd_device*)data;
++ struct obd_device *dev = m->private;
+ struct lod_device *lod;
+
+ LASSERT(dev != NULL);
+ lod = lu2lod_dev(dev->obd_lu_dev);
+- *eof = 1;
+- return snprintf(page, count, "%u\n", lod->lod_desc.ld_tgt_count);
+-
++ return seq_printf(m, "%u\n", lod->lod_desc.ld_tgt_count);
+ }
++LPROC_SEQ_FOPS_RO(lod_numobd);
+
+-static int lod_rd_activeobd(char *page, char **start, off_t off, int count,
+- int *eof, void *data)
++static int lod_activeobd_seq_show(struct seq_file *m, void *v)
+ {
+- struct obd_device* dev = (struct obd_device*)data;
++ struct obd_device* dev = m->private;
+ struct lod_device *lod;
+
+ LASSERT(dev != NULL);
+ lod = lu2lod_dev(dev->obd_lu_dev);
+- *eof = 1;
+- return snprintf(page, count, "%u\n",
+- lod->lod_desc.ld_active_tgt_count);
++ return seq_printf(m, "%u\n", lod->lod_desc.ld_active_tgt_count);
+ }
++LPROC_SEQ_FOPS_RO(lod_activeobd);
+
+-static int lod_rd_desc_uuid(char *page, char **start, off_t off, int count,
+- int *eof, void *data)
++static int lod_desc_uuid_seq_show(struct seq_file *m, void *v)
+ {
+- struct obd_device *dev = (struct obd_device*) data;
++ struct obd_device *dev = m->private;
+ struct lod_device *lod;
+
+ LASSERT(dev != NULL);
+ lod = lu2lod_dev(dev->obd_lu_dev);
+- *eof = 1;
+- return snprintf(page, count, "%s\n", lod->lod_desc.ld_uuid.uuid);
++ return seq_printf(m, "%s\n", lod->lod_desc.ld_uuid.uuid);
+ }
++LPROC_SEQ_FOPS_RO(lod_desc_uuid);
+
+ /* free priority (0-255): how badly user wants to choose empty osts */
+-static int lod_rd_qos_priofree(char *page, char **start, off_t off, int count,
+- int *eof, void *data)
++static int lod_qos_priofree_seq_show(struct seq_file *m, void *v)
+ {
+- struct obd_device *dev = (struct obd_device*) data;
++ struct obd_device *dev = m->private;
+ struct lod_device *lod = lu2lod_dev(dev->obd_lu_dev);
+
+ LASSERT(lod != NULL);
+- *eof = 1;
+- return snprintf(page, count, "%d%%\n",
++ return seq_printf(m, "%d%%\n",
+ (lod->lod_qos.lq_prio_free * 100 + 255) >> 8);
+ }
+
+-static int lod_wr_qos_priofree(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++lod_qos_priofree_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *dev = (struct obd_device *)data;
++ struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
+ struct lod_device *lod;
+ int val, rc;
+
+@@ -238,24 +232,24 @@ static int lod_wr_qos_priofree(struct file *file, const char *buffer,
+ lod->lod_qos.lq_reset = 1;
+ return count;
+ }
++LPROC_SEQ_FOPS(lod_qos_priofree);
+
+-static int lod_rd_qos_thresholdrr(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int lod_qos_thresholdrr_seq_show(struct seq_file *m, void *v)
+ {
+- struct obd_device *dev = (struct obd_device*) data;
++ struct obd_device *dev = m->private;
+ struct lod_device *lod;
+
+ LASSERT(dev != NULL);
+ lod = lu2lod_dev(dev->obd_lu_dev);
+- *eof = 1;
+- return snprintf(page, count, "%d%%\n",
++ return seq_printf(m, "%d%%\n",
+ (lod->lod_qos.lq_threshold_rr * 100 + 255) >> 8);
+ }
+
+-static int lod_wr_qos_thresholdrr(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++lod_qos_thresholdrr_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *dev = (struct obd_device *)data;
++ struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
+ struct lod_device *lod;
+ int val, rc;
+
+@@ -273,23 +267,23 @@ static int lod_wr_qos_thresholdrr(struct file *file, const char *buffer,
+ lod->lod_qos.lq_dirty = 1;
+ return count;
+ }
++LPROC_SEQ_FOPS(lod_qos_thresholdrr);
+
+-static int lod_rd_qos_maxage(char *page, char **start, off_t off, int count,
+- int *eof, void *data)
++static int lod_qos_maxage_seq_show(struct seq_file *m, void *v)
+ {
+- struct obd_device *dev = (struct obd_device*) data;
++ struct obd_device *dev = m->private;
+ struct lod_device *lod;
+
+ LASSERT(dev != NULL);
+ lod = lu2lod_dev(dev->obd_lu_dev);
+- *eof = 1;
+- return snprintf(page, count, "%u Sec\n", lod->lod_desc.ld_qos_maxage);
++ return seq_printf(m, "%u Sec\n", lod->lod_desc.ld_qos_maxage);
+ }
+
+-static int lod_wr_qos_maxage(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++lod_qos_maxage_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *dev = (struct obd_device *)data;
++ struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
+ struct lustre_cfg_bufs bufs;
+ struct lod_device *lod;
+ struct lu_device *next;
+@@ -327,6 +321,7 @@ static int lod_wr_qos_maxage(struct file *file, const char *buffer,
+
+ return count;
+ }
++LPROC_SEQ_FOPS(lod_qos_maxage);
+
+ static void *lod_osts_seq_start(struct seq_file *p, loff_t *pos)
+ {
+@@ -414,56 +409,52 @@ static const struct seq_operations lod_osts_sops = {
+
+ static int lod_osts_seq_open(struct inode *inode, struct file *file)
+ {
+- struct proc_dir_entry *dp = PDE(inode);
+ struct seq_file *seq;
+ int rc;
+
+- LPROCFS_ENTRY_CHECK(dp);
+ rc = seq_open(file, &lod_osts_sops);
+ if (rc)
+ return rc;
+
+ seq = file->private_data;
+- seq->private = dp->data;
++ seq->private = PDE_DATA(inode);
+ return 0;
+ }
+
+-static struct lprocfs_vars lprocfs_lod_obd_vars[] = {
+- { "uuid", lprocfs_rd_uuid, 0, 0 },
+- { "stripesize", lod_rd_stripesize, lod_wr_stripesize, 0 },
+- { "stripeoffset", lod_rd_stripeoffset, lod_wr_stripeoffset, 0 },
+- { "stripecount", lod_rd_stripecount, lod_wr_stripecount, 0 },
+- { "stripetype", lod_rd_stripetype, lod_wr_stripetype, 0 },
+- { "numobd", lod_rd_numobd, 0, 0 },
+- { "activeobd", lod_rd_activeobd, 0, 0 },
+- { "desc_uuid", lod_rd_desc_uuid, 0, 0 },
+- { "qos_prio_free",lod_rd_qos_priofree, lod_wr_qos_priofree, 0 },
+- { "qos_threshold_rr", lod_rd_qos_thresholdrr, lod_wr_qos_thresholdrr, 0 },
+- { "qos_maxage", lod_rd_qos_maxage, lod_wr_qos_maxage, 0 },
+- { 0 }
+-};
+-
+-static struct lprocfs_vars lprocfs_lod_osd_vars[] = {
+- { "blocksize", lprocfs_dt_rd_blksize, 0, 0 },
+- { "kbytestotal", lprocfs_dt_rd_kbytestotal, 0, 0 },
+- { "kbytesfree", lprocfs_dt_rd_kbytesfree, 0, 0 },
+- { "kbytesavail", lprocfs_dt_rd_kbytesavail, 0, 0 },
+- { "filestotal", lprocfs_dt_rd_filestotal, 0, 0 },
+- { "filesfree", lprocfs_dt_rd_filesfree, 0, 0 },
++LPROC_SEQ_FOPS_RO_TYPE(lod, uuid);
++
++LPROC_SEQ_FOPS_RO_TYPE(lod, dt_blksize);
++LPROC_SEQ_FOPS_RO_TYPE(lod, dt_kbytestotal);
++LPROC_SEQ_FOPS_RO_TYPE(lod, dt_kbytesfree);
++LPROC_SEQ_FOPS_RO_TYPE(lod, dt_kbytesavail);
++LPROC_SEQ_FOPS_RO_TYPE(lod, dt_filestotal);
++LPROC_SEQ_FOPS_RO_TYPE(lod, dt_filesfree);
++
++static struct lprocfs_seq_vars lprocfs_lod_obd_vars[] = {
++ { "uuid", &lod_uuid_fops },
++ { "stripesize", &lod_stripesize_fops },
++ { "stripeoffset", &lod_stripeoffset_fops },
++ { "stripecount", &lod_stripecount_fops },
++ { "stripetype", &lod_stripetype_fops },
++ { "numobd", &lod_numobd_fops },
++ { "activeobd", &lod_activeobd_fops },
++ { "desc_uuid", &lod_desc_uuid_fops },
++ { "qos_prio_free", &lod_qos_priofree_fops },
++ { "qos_threshold_rr", &lod_qos_thresholdrr_fops },
++ { "qos_maxage", &lod_qos_maxage_fops },
+ { 0 }
+ };
+
+-static struct lprocfs_vars lprocfs_lod_module_vars[] = {
+- { "num_refs", lprocfs_rd_numrefs, 0, 0 },
++static struct lprocfs_seq_vars lprocfs_lod_osd_vars[] = {
++ { "blocksize", &lod_dt_blksize_fops },
++ { "kbytestotal", &lod_dt_kbytestotal_fops },
++ { "kbytesfree", &lod_dt_kbytesfree_fops },
++ { "kbytesavail", &lod_dt_kbytesavail_fops },
++ { "filestotal", &lod_dt_filestotal_fops },
++ { "filesfree", &lod_dt_filesfree_fops },
+ { 0 }
+ };
+
+-void lprocfs_lod_init_vars(struct lprocfs_static_vars *lvars)
+-{
+- lvars->module_vars = lprocfs_lod_module_vars;
+- lvars->obd_vars = lprocfs_lod_obd_vars;
+-}
+-
+ static const struct file_operations lod_proc_target_fops = {
+ .owner = THIS_MODULE,
+ .open = lod_osts_seq_open,
+@@ -475,20 +466,19 @@ static const struct file_operations lod_proc_target_fops = {
+ int lod_procfs_init(struct lod_device *lod)
+ {
+ struct obd_device *obd = lod2obd(lod);
+- struct lprocfs_static_vars lvars;
+ cfs_proc_dir_entry_t *lov_proc_dir;
+ int rc;
+
+- lprocfs_lod_init_vars(&lvars);
+- rc = lprocfs_obd_setup(obd, lvars.obd_vars);
++ obd->obd_vars = lprocfs_lod_obd_vars;
++ rc = lprocfs_seq_obd_setup(obd);
+ if (rc) {
+ CERROR("%s: cannot setup procfs entry: %d\n",
+ obd->obd_name, rc);
+ RETURN(rc);
+ }
+
+- rc = lprocfs_add_vars(obd->obd_proc_entry, lprocfs_lod_osd_vars,
+- &lod->lod_dt_dev);
++ rc = lprocfs_seq_add_vars(obd->obd_proc_entry, lprocfs_lod_osd_vars,
++ &lod->lod_dt_dev);
+ if (rc) {
+ CERROR("%s: cannot setup procfs entry: %d\n",
+ obd->obd_name, rc);
+@@ -503,9 +493,9 @@ int lod_procfs_init(struct lod_device *lod)
+ GOTO(out, rc);
+ }
+
+- lod->lod_pool_proc_entry = lprocfs_register("pools",
+- obd->obd_proc_entry,
+- NULL, NULL);
++ lod->lod_pool_proc_entry = lprocfs_seq_register("pools",
++ obd->obd_proc_entry,
++ NULL, NULL);
+ if (IS_ERR(lod->lod_pool_proc_entry)) {
+ rc = PTR_ERR(lod->lod_pool_proc_entry);
+ lod->lod_pool_proc_entry = NULL;
+@@ -514,14 +504,34 @@ int lod_procfs_init(struct lod_device *lod)
+ GOTO(out, rc);
+ }
+
+- /* for compatibility we link old procfs's OSC entries to osp ones */
+- lov_proc_dir = lprocfs_srch(proc_lustre_root, "lov");
+- if (lov_proc_dir != NULL && strstr(obd->obd_name, "lov") != NULL)
+- lod->lod_symlink = lprocfs_add_symlink(obd->obd_name,
+- lov_proc_dir,
+- "../lod/%s",
+- obd->obd_name);
++ /* for compatibility we link old procfs's LOV entries to lod ones */
++ lov_proc_dir = obd->obd_proc_private;
++ if (lov_proc_dir == NULL) {
++ struct obd_type *type = class_search_type(LUSTRE_LOV_NAME);
++
++ /* create "lov" entry in procfs for compatibility purposes */
++ if (type == NULL) {
++ lov_proc_dir = lprocfs_seq_register("lov",
++ proc_lustre_root,
++ NULL, NULL);
++ if (IS_ERR(lov_proc_dir))
++ CERROR("lod: can't create compat entry \"lov\""
++ ": %d\n",(int)PTR_ERR(lov_proc_dir));
++ } else {
++ lov_proc_dir = type->typ_procroot;
++ }
+
++ lod->lod_symlink = lprocfs_add_symlink(obd->obd_name,
++ lov_proc_dir,
++ "../lod/%s",
++ obd->obd_name);
++ if (lod->lod_symlink == NULL) {
++ CERROR("could not register LOV symlink for "
++ "/proc/fs/lustre/lod/%s.", obd->obd_name);
++ lprocfs_remove(&lov_proc_dir);
++ } else
++ obd->obd_proc_private = lov_proc_dir;
++ }
+ RETURN(0);
+
+ out:
+@@ -542,6 +552,9 @@ void lod_procfs_fini(struct lod_device *lod)
+ lod->lod_pool_proc_entry = NULL;
+ }
+
++ if (obd->obd_proc_private != NULL)
++ lprocfs_remove((struct proc_dir_entry **)&obd->obd_proc_private);
++
+ lprocfs_obd_cleanup(obd);
+ }
+
+--
+1.8.5.1
+
diff --git a/sys-cluster/lustre/files/0015-LU-3319-procfs-move-osp-proc-handling-to-seq_files.patch b/sys-cluster/lustre/files/0015-LU-3319-procfs-move-osp-proc-handling-to-seq_files.patch
new file mode 100644
index 000000000..8d2547696
--- /dev/null
+++ b/sys-cluster/lustre/files/0015-LU-3319-procfs-move-osp-proc-handling-to-seq_files.patch
@@ -0,0 +1,779 @@
+From 1537f22b9b2bc9250006805774fc300e5240c2bc Mon Sep 17 00:00:00 2001
+From: James Simmons <uja.ornl@gmail.com>
+Date: Thu, 14 Nov 2013 19:23:09 -0500
+Subject: [PATCH 15/18] LU-3319 procfs: move osp proc handling to seq_files
+
+With 3.10 linux kernel and above proc handling now only
+uses struct seq_files. This patch migrates the osp
+layer proc entries over to using seq_files.
+
+Signed-off-by: James Simmons <uja.ornl@gmail.com>
+Change-Id: If58826e11524a5fffd2e491c1386e3795015bc7e
+---
+ lustre/osp/lproc_osp.c | 363 ++++++++++++++++++++++++----------------------
+ lustre/osp/lwp_dev.c | 18 +--
+ lustre/osp/osp_dev.c | 38 ++---
+ lustre/osp/osp_internal.h | 2 -
+ 4 files changed, 203 insertions(+), 218 deletions(-)
+
+diff --git a/lustre/osp/lproc_osp.c b/lustre/osp/lproc_osp.c
+index 22e3372..24f2f4c 100644
+--- a/lustre/osp/lproc_osp.c
++++ b/lustre/osp/lproc_osp.c
+@@ -45,24 +45,23 @@
+ #include "osp_internal.h"
+
+ #ifdef LPROCFS
+-static int osp_rd_active(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int osp_active_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *dev = data;
++ struct obd_device *dev = m->private;
+ int rc;
+
+ LPROCFS_CLIMP_CHECK(dev);
+- rc = snprintf(page, count, "%d\n",
+- !dev->u.cli.cl_import->imp_deactive);
++ rc = seq_printf(m, "%d\n", !dev->u.cli.cl_import->imp_deactive);
+ LPROCFS_CLIMP_EXIT(dev);
+ return rc;
+ }
+
+-static int osp_wr_active(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++osp_active_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *dev = data;
+- int val, rc;
++ struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
++ int val, rc;
+
+ rc = lprocfs_write_helper(buffer, count, &val);
+ if (rc)
+@@ -81,67 +80,60 @@ static int osp_wr_active(struct file *file, const char *buffer,
+ LPROCFS_CLIMP_EXIT(dev);
+ return count;
+ }
++LPROC_SEQ_FOPS(osp_active);
+
+-static int osp_rd_syn_in_flight(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int osp_syn_in_flight_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *dev = data;
++ struct obd_device *dev = m->private;
+ struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
+- int rc;
+
+ if (osp == NULL)
+ return -EINVAL;
+
+- rc = snprintf(page, count, "%u\n", osp->opd_syn_rpc_in_flight);
+- return rc;
++ return seq_printf(m, "%u\n", osp->opd_syn_rpc_in_flight);
+ }
++LPROC_SEQ_FOPS_RO(osp_syn_in_flight);
+
+-static int osp_rd_syn_in_prog(char *page, char **start, off_t off, int count,
+- int *eof, void *data)
++static int osp_syn_in_prog_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *dev = data;
++ struct obd_device *dev = m->private;
+ struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
+- int rc;
+
+ if (osp == NULL)
+ return -EINVAL;
+
+- rc = snprintf(page, count, "%u\n", osp->opd_syn_rpc_in_progress);
+- return rc;
++ return seq_printf(m, "%u\n", osp->opd_syn_rpc_in_progress);
+ }
++LPROC_SEQ_FOPS_RO(osp_syn_in_prog);
+
+-static int osp_rd_syn_changes(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int osp_syn_changes_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *dev = data;
++ struct obd_device *dev = m->private;
+ struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
+- int rc;
+
+ if (osp == NULL)
+ return -EINVAL;
+
+- rc = snprintf(page, count, "%lu\n", osp->opd_syn_changes);
+- return rc;
++ return seq_printf(m, "%lu\n", osp->opd_syn_changes);
+ }
++LPROC_SEQ_FOPS_RO(osp_syn_changes);
+
+-static int osp_rd_max_rpcs_in_flight(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int osp_max_rpcs_in_flight_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *dev = data;
++ struct obd_device *dev = m->private;
+ struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
+- int rc;
+
+ if (osp == NULL)
+ return -EINVAL;
+
+- rc = snprintf(page, count, "%u\n", osp->opd_syn_max_rpc_in_flight);
+- return rc;
++ return seq_printf(m, "%u\n", osp->opd_syn_max_rpc_in_flight);
+ }
+
+-static int osp_wr_max_rpcs_in_flight(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++osp_max_rpcs_in_flight_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *dev = data;
++ struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
+ struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
+ int val, rc;
+
+@@ -158,25 +150,24 @@ static int osp_wr_max_rpcs_in_flight(struct file *file, const char *buffer,
+ osp->opd_syn_max_rpc_in_flight = val;
+ return count;
+ }
++LPROC_SEQ_FOPS(osp_max_rpcs_in_flight);
+
+-static int osp_rd_max_rpcs_in_prog(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int osp_max_rpcs_in_prog_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *dev = data;
++ struct obd_device *dev = m->private;
+ struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
+- int rc;
+
+ if (osp == NULL)
+ return -EINVAL;
+
+- rc = snprintf(page, count, "%u\n", osp->opd_syn_max_rpc_in_progress);
+- return rc;
++ return seq_printf(m, "%u\n", osp->opd_syn_max_rpc_in_progress);
+ }
+
+-static int osp_wr_max_rpcs_in_prog(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++osp_max_rpcs_in_prog_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *dev = data;
++ struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
+ struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
+ int val, rc;
+
+@@ -194,23 +185,24 @@ static int osp_wr_max_rpcs_in_prog(struct file *file, const char *buffer,
+
+ return count;
+ }
++LPROC_SEQ_FOPS(osp_max_rpcs_in_prog);
+
+-static int osp_rd_create_count(char *page, char **start, off_t off, int count,
+- int *eof, void *data)
++static int osp_create_count_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = m->private;
+ struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
+
+ if (osp == NULL)
+ return 0;
+
+- return snprintf(page, count, "%d\n", osp->opd_pre_grow_count);
++ return seq_printf(m, "%d\n", osp->opd_pre_grow_count);
+ }
+
+-static int osp_wr_create_count(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++osp_create_count_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
+ struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
+ int val, rc, i;
+
+@@ -242,23 +234,24 @@ static int osp_wr_create_count(struct file *file, const char *buffer,
+
+ return count;
+ }
++LPROC_SEQ_FOPS(osp_create_count);
+
+-static int osp_rd_max_create_count(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int osp_max_create_count_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = m->private;
+ struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
+
+ if (osp == NULL)
+ return 0;
+
+- return snprintf(page, count, "%d\n", osp->opd_pre_max_grow_count);
++ return seq_printf(m, "%d\n", osp->opd_pre_max_grow_count);
+ }
+
+-static int osp_wr_max_create_count(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++osp_max_create_count_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
+ struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
+ int val, rc;
+
+@@ -281,89 +274,85 @@ static int osp_wr_max_create_count(struct file *file, const char *buffer,
+
+ return count;
+ }
++LPROC_SEQ_FOPS(osp_max_create_count);
+
+-static int osp_rd_prealloc_next_id(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int osp_prealloc_next_id_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = m->private;
+ struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
+
+ if (osp == NULL)
+ return 0;
+
+- return snprintf(page, count, "%u\n",
+- fid_oid(&osp->opd_pre_used_fid) + 1);
++ return seq_printf(m, "%u\n", fid_oid(&osp->opd_pre_used_fid) + 1);
+ }
++LPROC_SEQ_FOPS_RO(osp_prealloc_next_id);
+
+-static int osp_rd_prealloc_last_id(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int osp_prealloc_last_id_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = m->private;
+ struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
+
+ if (osp == NULL)
+ return 0;
+
+- return snprintf(page, count, "%u\n",
+- fid_oid(&osp->opd_pre_last_created_fid));
++ return seq_printf(m, "%u\n", fid_oid(&osp->opd_pre_last_created_fid));
+ }
++LPROC_SEQ_FOPS_RO(osp_prealloc_last_id);
+
+-static int osp_rd_prealloc_next_seq(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int osp_prealloc_next_seq_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = m->private;
+ struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
+
+ if (osp == NULL)
+ return 0;
+
+- return snprintf(page, count, LPX64"\n",
+- fid_seq(&osp->opd_pre_used_fid));
++ return seq_printf(m, LPX64"\n", fid_seq(&osp->opd_pre_used_fid));
+ }
++LPROC_SEQ_FOPS_RO(osp_prealloc_next_seq);
+
+-static int osp_rd_prealloc_last_seq(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int osp_prealloc_last_seq_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = m->private;
+ struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
+
+ if (osp == NULL)
+ return 0;
+
+- return snprintf(page, count, LPX64"\n",
++ return seq_printf(m, LPX64"\n",
+ fid_seq(&osp->opd_pre_last_created_fid));
+ }
++LPROC_SEQ_FOPS_RO(osp_prealloc_last_seq);
+
+-static int osp_rd_prealloc_reserved(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int osp_prealloc_reserved_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = m->private;
+ struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
+
+ if (osp == NULL)
+ return 0;
+
+- return snprintf(page, count, LPU64"\n", osp->opd_pre_reserved);
++ return seq_printf(m, LPU64"\n", osp->opd_pre_reserved);
+ }
++LPROC_SEQ_FOPS_RO(osp_prealloc_reserved);
+
+-static int osp_rd_maxage(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int osp_maxage_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *dev = data;
++ struct obd_device *dev = m->private;
+ struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
+- int rc;
+
+ if (osp == NULL)
+ return -EINVAL;
+
+- rc = snprintf(page, count, "%u\n", osp->opd_statfs_maxage);
+- return rc;
++ return seq_printf(m, "%u\n", osp->opd_statfs_maxage);
+ }
+
+-static int osp_wr_maxage(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++osp_maxage_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *dev = data;
++ struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
+ struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
+ int val, rc;
+
+@@ -381,25 +370,23 @@ static int osp_wr_maxage(struct file *file, const char *buffer,
+
+ return count;
+ }
++LPROC_SEQ_FOPS(osp_maxage);
+
+-static int osp_rd_pre_status(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int osp_pre_status_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *dev = data;
++ struct obd_device *dev = m->private;
+ struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
+- int rc;
+
+ if (osp == NULL)
+ return -EINVAL;
+
+- rc = snprintf(page, count, "%d\n", osp->opd_pre_status);
+- return rc;
++ return seq_printf(m, "%d\n", osp->opd_pre_status);
+ }
++LPROC_SEQ_FOPS_RO(osp_pre_status);
+
+-static int osp_rd_destroys_in_flight(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int osp_destroys_in_flight_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *dev = data;
++ struct obd_device *dev = m->private;
+ struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
+
+ if (osp == NULL)
+@@ -411,87 +398,94 @@ static int osp_rd_destroys_in_flight(char *page, char **start, off_t off,
+ * - sync changes are zero - no llog records
+ * - sync in progress are zero - no RPCs in flight
+ */
+- return snprintf(page, count, "%lu\n",
++ return seq_printf(m, "%lu\n",
+ osp->opd_syn_rpc_in_progress + osp->opd_syn_changes);
+ }
++LPROC_SEQ_FOPS_RO(osp_destroys_in_flight);
+
+-static int osp_rd_old_sync_processed(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int osp_old_sync_processed_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *dev = data;
++ struct obd_device *dev = m->private;
+ struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
+- int rc;
+
+ if (osp == NULL)
+ return -EINVAL;
+
+- rc = snprintf(page, count, "%d\n", osp->opd_syn_prev_done);
+- return rc;
++ return seq_printf(m, "%d\n", osp->opd_syn_prev_done);
+ }
++LPROC_SEQ_FOPS_RO(osp_old_sync_processed);
+
+-static struct lprocfs_vars lprocfs_osp_obd_vars[] = {
+- { "uuid", lprocfs_rd_uuid, 0, 0 },
+- { "ping", 0, lprocfs_wr_ping, 0, 0, 0222 },
+- { "connect_flags", lprocfs_rd_connect_flags, 0, 0 },
+- { "ost_server_uuid", lprocfs_rd_server_uuid, 0, 0 },
+- { "ost_conn_uuid", lprocfs_rd_conn_uuid, 0, 0 },
+- { "active", osp_rd_active, osp_wr_active, 0 },
+- { "max_rpcs_in_flight", osp_rd_max_rpcs_in_flight,
+- osp_wr_max_rpcs_in_flight, 0 },
+- { "max_rpcs_in_progress", osp_rd_max_rpcs_in_prog,
+- osp_wr_max_rpcs_in_prog, 0 },
+- { "create_count", osp_rd_create_count,
+- osp_wr_create_count, 0 },
+- { "max_create_count", osp_rd_max_create_count,
+- osp_wr_max_create_count, 0 },
+- { "prealloc_next_id", osp_rd_prealloc_next_id, 0, 0 },
+- { "prealloc_next_seq", osp_rd_prealloc_next_seq, 0, 0 },
+- { "prealloc_last_id", osp_rd_prealloc_last_id, 0, 0 },
+- { "prealloc_last_seq", osp_rd_prealloc_last_seq, 0, 0 },
+- { "prealloc_reserved", osp_rd_prealloc_reserved, 0, 0 },
+- { "timeouts", lprocfs_rd_timeouts, 0, 0 },
+- { "import", lprocfs_rd_import, lprocfs_wr_import, 0 },
+- { "state", lprocfs_rd_state, 0, 0 },
+- { "maxage", osp_rd_maxage, osp_wr_maxage, 0 },
+- { "prealloc_status", osp_rd_pre_status, 0, 0 },
+- { "sync_changes", osp_rd_syn_changes, 0, 0 },
+- { "sync_in_flight", osp_rd_syn_in_flight, 0, 0 },
+- { "sync_in_progress", osp_rd_syn_in_prog, 0, 0 },
+- { "old_sync_processed", osp_rd_old_sync_processed, 0, 0 },
++LPROC_SEQ_FOPS_WO_TYPE(osp, ping);
++LPROC_SEQ_FOPS_RO_TYPE(osp, uuid);
++LPROC_SEQ_FOPS_RO_TYPE(osp, connect_flags);
++LPROC_SEQ_FOPS_RO_TYPE(osp, server_uuid);
++LPROC_SEQ_FOPS_RO_TYPE(osp, conn_uuid);
+
+- /* for compatibility reasons */
+- { "destroys_in_flight", osp_rd_destroys_in_flight, 0, 0 },
+- { 0 }
+-};
++static int osp_max_pages_per_rpc_seq_show(struct seq_file *m, void *v)
++{
++ return lprocfs_obd_max_pages_per_rpc_seq_show(m, m->private);
++}
++LPROC_SEQ_FOPS_RO(osp_max_pages_per_rpc);
++LPROC_SEQ_FOPS_RO_TYPE(osp, timeouts);
++
++LPROC_SEQ_FOPS_RW_TYPE(osp, import);
++LPROC_SEQ_FOPS_RO_TYPE(osp, state);
++
++static struct lprocfs_seq_vars lprocfs_osp_obd_vars[] = {
++ { "uuid", &osp_uuid_fops },
++ { "ping", &osp_ping_fops, 0, 0222 },
++ { "connect_flags", &osp_connect_flags_fops },
++ { "ost_server_uuid", &osp_server_uuid_fops },
++ { "ost_conn_uuid", &osp_conn_uuid_fops },
++ { "active", &osp_active_fops },
++ { "max_rpcs_in_flight", &osp_max_rpcs_in_flight_fops },
++ { "max_rpcs_in_progress", &osp_max_rpcs_in_prog_fops },
++ { "create_count", &osp_create_count_fops },
++ { "max_create_count", &osp_max_create_count_fops },
++ { "prealloc_next_id", &osp_prealloc_next_id_fops },
++ { "prealloc_next_seq", &osp_prealloc_next_seq_fops },
++ { "prealloc_last_id", &osp_prealloc_last_id_fops },
++ { "prealloc_last_seq", &osp_prealloc_last_seq_fops },
++ { "prealloc_reserved", &osp_prealloc_reserved_fops },
++ { "timeouts", &osp_timeouts_fops },
++ { "import", &osp_import_fops },
++ { "state", &osp_state_fops },
++ { "maxage", &osp_maxage_fops },
++ { "prealloc_status", &osp_pre_status_fops },
++ { "sync_changes", &osp_syn_changes_fops },
++ { "sync_in_flight", &osp_syn_in_flight_fops },
++ { "sync_in_progress", &osp_syn_in_prog_fops },
++ { "old_sync_processed", &osp_old_sync_processed_fops },
+
+-static struct lprocfs_vars lprocfs_osp_osd_vars[] = {
+- { "blocksize", lprocfs_dt_rd_blksize, 0, 0 },
+- { "kbytestotal", lprocfs_dt_rd_kbytestotal, 0, 0 },
+- { "kbytesfree", lprocfs_dt_rd_kbytesfree, 0, 0 },
+- { "kbytesavail", lprocfs_dt_rd_kbytesavail, 0, 0 },
+- { "filestotal", lprocfs_dt_rd_filestotal, 0, 0 },
+- { "filesfree", lprocfs_dt_rd_filesfree, 0, 0 },
++ /* for compatibility reasons */
++ { "destroys_in_flight", &osp_destroys_in_flight_fops },
+ { 0 }
+ };
+
+-static struct lprocfs_vars lprocfs_osp_module_vars[] = {
+- { "num_refs", lprocfs_rd_numrefs, 0, 0 },
++LPROC_SEQ_FOPS_RO_TYPE(osp, dt_blksize);
++LPROC_SEQ_FOPS_RO_TYPE(osp, dt_kbytestotal);
++LPROC_SEQ_FOPS_RO_TYPE(osp, dt_kbytesfree);
++LPROC_SEQ_FOPS_RO_TYPE(osp, dt_kbytesavail);
++LPROC_SEQ_FOPS_RO_TYPE(osp, dt_filestotal);
++LPROC_SEQ_FOPS_RO_TYPE(osp, dt_filesfree);
++
++static struct lprocfs_seq_vars lprocfs_osp_osd_vars[] = {
++ { "blocksize", &osp_dt_blksize_fops },
++ { "kbytestotal", &osp_dt_kbytestotal_fops },
++ { "kbytesfree", &osp_dt_kbytesfree_fops },
++ { "kbytesavail", &osp_dt_kbytesavail_fops },
++ { "filestotal", &osp_dt_filestotal_fops },
++ { "filesfree", &osp_dt_filesfree_fops },
+ { 0 }
+ };
+
+-void lprocfs_osp_init_vars(struct lprocfs_static_vars *lvars)
+-{
+- lvars->module_vars = lprocfs_osp_module_vars;
+- lvars->obd_vars = lprocfs_osp_obd_vars;
+-}
+-
+ void osp_lprocfs_init(struct osp_device *osp)
+ {
+ struct obd_device *obd = osp->opd_obd;
+ struct proc_dir_entry *osc_proc_dir;
+ int rc;
+
+- obd->obd_proc_entry = lprocfs_register(obd->obd_name,
++ obd->obd_proc_entry = lprocfs_seq_register(obd->obd_name,
+ obd->obd_type->typ_procroot,
+ lprocfs_osp_osd_vars,
+ &osp->opd_dt_dev);
+@@ -502,7 +496,7 @@ void osp_lprocfs_init(struct osp_device *osp)
+ return;
+ }
+
+- rc = lprocfs_add_vars(obd->obd_proc_entry, lprocfs_osp_obd_vars, obd);
++ rc = lprocfs_seq_add_vars(obd->obd_proc_entry, lprocfs_osp_obd_vars, obd);
+ if (rc) {
+ CERROR("%s: can't register in lprocfs: %ld\n",
+ obd->obd_name, PTR_ERR(obd->obd_proc_entry));
+@@ -511,24 +505,47 @@ void osp_lprocfs_init(struct osp_device *osp)
+
+ ptlrpc_lprocfs_register_obd(obd);
+
++ if (osp->opd_connect_mdt)
++ return;
++
+ /* for compatibility we link old procfs's OSC entries to osp ones */
+- if (!osp->opd_connect_mdt) {
+- osc_proc_dir = lprocfs_srch(proc_lustre_root, "osc");
+- if (osc_proc_dir) {
+- cfs_proc_dir_entry_t *symlink = NULL;
+- char *name;
+-
+- OBD_ALLOC(name, strlen(obd->obd_name) + 1);
+- if (name == NULL)
+- return;
+-
+- strcpy(name, obd->obd_name);
+- if (strstr(name, "osc"))
+- symlink = lprocfs_add_symlink(name,
+- osc_proc_dir, "../osp/%s",
+- obd->obd_name);
++ osc_proc_dir = obd->obd_proc_private;
++ if (osc_proc_dir == NULL) {
++ cfs_proc_dir_entry_t *symlink = NULL;
++ struct obd_type *type;
++ char *name;
++
++ type = class_search_type(LUSTRE_OSC_NAME);
++ if (type == NULL) {
++ osc_proc_dir = lprocfs_seq_register("osc",
++ proc_lustre_root,
++ NULL, NULL);
++ if (IS_ERR(osc_proc_dir))
++ CERROR("osp: can't create compat entry \"osc\": %d\n",
++ (int) PTR_ERR(osc_proc_dir));
++ } else {
++ osc_proc_dir = type->typ_procroot;
++ }
++
++ OBD_ALLOC(name, strlen(obd->obd_name) + 1);
++ if (name == NULL)
++ return;
++
++ strcpy(name, obd->obd_name);
++ if (strstr(name, "osc")) {
++ symlink = lprocfs_add_symlink(name, osc_proc_dir,
++ "../osp/%s",
++ obd->obd_name);
+ OBD_FREE(name, strlen(obd->obd_name) + 1);
+- osp->opd_symlink = symlink;
++ if (symlink == NULL) {
++ CERROR("could not register OSC symlink for "
++ "/proc/fs/lustre/osp/%s.",
++ obd->obd_name);
++ lprocfs_remove(&osc_proc_dir);
++ } else {
++ osp->opd_symlink = symlink;
++ obd->obd_proc_private = osc_proc_dir;
++ }
+ }
+ }
+ }
+diff --git a/lustre/osp/lwp_dev.c b/lustre/osp/lwp_dev.c
+index fce82a2..755c096 100644
+--- a/lustre/osp/lwp_dev.c
++++ b/lustre/osp/lwp_dev.c
+@@ -210,25 +210,13 @@ const struct lu_device_operations lwp_lu_ops = {
+ .ldo_process_config = lwp_process_config,
+ };
+
+-static struct lprocfs_vars lprocfs_lwp_module_vars[] = {
+- { "num_refs", lprocfs_rd_numrefs, 0, 0 },
++static struct lprocfs_seq_vars lprocfs_lwp_obd_vars[] = {
+ { 0 }
+ };
+
+-static struct lprocfs_vars lprocfs_lwp_obd_vars[] = {
+- { 0 }
+-};
+-
+-void lprocfs_lwp_init_vars(struct lprocfs_static_vars *lvars)
+-{
+- lvars->module_vars = lprocfs_lwp_module_vars;
+- lvars->obd_vars = lprocfs_lwp_obd_vars;
+-}
+-
+ int lwp_init0(const struct lu_env *env, struct lwp_device *lwp,
+ struct lu_device_type *ldt, struct lustre_cfg *cfg)
+ {
+- struct lprocfs_static_vars lvars = { 0 };
+ int rc;
+ ENTRY;
+
+@@ -257,8 +245,8 @@ int lwp_init0(const struct lu_env *env, struct lwp_device *lwp,
+ RETURN(rc);
+ }
+
+- lprocfs_lwp_init_vars(&lvars);
+- if (lprocfs_obd_setup(lwp->lpd_obd, lvars.obd_vars) == 0)
++ lwp->lpd_obd->obd_vars = lprocfs_lwp_obd_vars;
++ if (lprocfs_seq_obd_setup(lwp->lpd_obd) == 0)
+ ptlrpc_lprocfs_register_obd(lwp->lpd_obd);
+
+ RETURN(0);
+diff --git a/lustre/osp/osp_dev.c b/lustre/osp/osp_dev.c
+index 096de6a..780276d 100644
+--- a/lustre/osp/osp_dev.c
++++ b/lustre/osp/osp_dev.c
+@@ -371,7 +371,7 @@ static int osp_process_config(const struct lu_env *env,
+ struct lu_device *dev, struct lustre_cfg *lcfg)
+ {
+ struct osp_device *d = lu2osp_dev(dev);
+- struct lprocfs_static_vars lvars = { 0 };
++ struct obd_device *obd = d->opd_obd;
+ int rc;
+
+ ENTRY;
+@@ -385,11 +385,9 @@ static int osp_process_config(const struct lu_env *env,
+ rc = osp_shutdown(env, d);
+ break;
+ case LCFG_PARAM:
+- lprocfs_osp_init_vars(&lvars);
+-
+- LASSERT(d->opd_obd);
+- rc = class_process_proc_param(PARAM_OSC, lvars.obd_vars,
+- lcfg, d->opd_obd);
++ LASSERT(obd);
++ rc = class_process_proc_seq_param(PARAM_OSC, obd->obd_vars,
++ lcfg, obd);
+ if (rc > 0)
+ rc = 0;
+ if (rc == -ENOSYS) {
+@@ -837,6 +835,9 @@ static struct lu_device *osp_device_fini(const struct lu_env *env,
+ OBD_FREE_PTR(cli->cl_rpc_lock);
+ cli->cl_rpc_lock = NULL;
+ }
++ } else {
++ if (m->opd_obd->obd_proc_private != NULL)
++ lprocfs_remove((struct proc_dir_entry **)&m->opd_obd->obd_proc_private);
+ }
+
+ rc = client_obd_cleanup(m->opd_obd);
+@@ -1188,33 +1189,25 @@ struct llog_operations osp_mds_ost_orig_logops;
+
+ static int __init osp_mod_init(void)
+ {
+- struct lprocfs_static_vars lvars;
+- cfs_proc_dir_entry_t *osc_proc_dir;
+- int rc;
++ int rc;
+
+ rc = lu_kmem_init(osp_caches);
+ if (rc)
+ return rc;
+
+- lprocfs_osp_init_vars(&lvars);
+-
+ rc = class_register_type(&osp_obd_device_ops, NULL, NULL,
+ #ifndef HAVE_ONLY_PROCFS_SEQ
+- lvars.module_vars,
++ NULL,
+ #endif
+ LUSTRE_OSP_NAME, &osp_device_type);
+-
+- /* create "osc" entry in procfs for compatibility purposes */
+ if (rc != 0) {
+ lu_kmem_fini(osp_caches);
+ return rc;
+ }
+
+- lprocfs_lwp_init_vars(&lvars);
+-
+ rc = class_register_type(&lwp_obd_device_ops, NULL, NULL,
+ #ifndef HAVE_ONLY_PROCFS_SEQ
+- lvars.module_vars,
++ NULL,
+ #endif
+ LUSTRE_LWP_NAME, &lwp_device_type);
+ if (rc != 0) {
+@@ -1227,22 +1220,11 @@ static int __init osp_mod_init(void)
+ osp_mds_ost_orig_logops = llog_osd_ops;
+ osp_mds_ost_orig_logops.lop_add = llog_cat_add_rec;
+ osp_mds_ost_orig_logops.lop_declare_add = llog_cat_declare_add_rec;
+-
+- osc_proc_dir = lprocfs_srch(proc_lustre_root, "osc");
+- if (osc_proc_dir == NULL) {
+- osc_proc_dir = lprocfs_register("osc", proc_lustre_root, NULL,
+- NULL);
+- if (IS_ERR(osc_proc_dir))
+- CERROR("osp: can't create compat entry \"osc\": %d\n",
+- (int) PTR_ERR(osc_proc_dir));
+- }
+ return rc;
+ }
+
+ static void __exit osp_mod_exit(void)
+ {
+- lprocfs_try_remove_proc_entry("osc", proc_lustre_root);
+-
+ class_unregister_type(LUSTRE_LWP_NAME);
+ class_unregister_type(LUSTRE_OSP_NAME);
+ lu_kmem_fini(osp_caches);
+diff --git a/lustre/osp/osp_internal.h b/lustre/osp/osp_internal.h
+index 92c7b72..fe8b57e 100644
+--- a/lustre/osp/osp_internal.h
++++ b/lustre/osp/osp_internal.h
+@@ -415,7 +415,6 @@ int osp_write_last_oid_seq_files(struct lu_env *env, struct osp_device *osp,
+ struct lu_fid *fid, int sync);
+
+ /* lproc_osp.c */
+-void lprocfs_osp_init_vars(struct lprocfs_static_vars *lvars);
+ void osp_lprocfs_init(struct osp_device *osp);
+
+ /* osp_sync.c */
+@@ -429,7 +428,6 @@ int osp_sync_fini(struct osp_device *d);
+ void __osp_sync_check_for_work(struct osp_device *d);
+
+ /* lwp_dev.c */
+-void lprocfs_lwp_init_vars(struct lprocfs_static_vars *lvars);
+ extern struct obd_ops lwp_obd_device_ops;
+ extern struct lu_device_type lwp_device_type;
+
+--
+1.8.5.1
+
diff --git a/sys-cluster/lustre/files/0016-LU-3319-procfs-move-mdt-mds-proc-handling-to-seq_fil.patch b/sys-cluster/lustre/files/0016-LU-3319-procfs-move-mdt-mds-proc-handling-to-seq_fil.patch
new file mode 100644
index 000000000..d1ebc8cc6
--- /dev/null
+++ b/sys-cluster/lustre/files/0016-LU-3319-procfs-move-mdt-mds-proc-handling-to-seq_fil.patch
@@ -0,0 +1,1484 @@
+From 6bc2e0318f464ba5b946c97031e63dc354bfc87e Mon Sep 17 00:00:00 2001
+From: James Simmons <uja.ornl@gmail.com>
+Date: Mon, 2 Dec 2013 12:36:06 -0500
+Subject: [PATCH 16/18] LU-3319 procfs: move mdt/mds proc handling to seq_files
+
+With 3.10 linux kernel and above proc handling now only
+uses struct seq_files. This patch migrates the mdt/mds
+layer proc entries over to using seq_files.
+
+Signed-off-by: James Simmons <uja.ornl@gmail.com>
+Change-Id: Icbafdcd2c2fe3959a51dda3f9c715b0ff8d95742
+---
+ lustre/mdt/mdt_coordinator.c | 246 +++++++---------
+ lustre/mdt/mdt_handler.c | 16 +-
+ lustre/mdt/mdt_hsm_cdt_actions.c | 7 +-
+ lustre/mdt/mdt_hsm_cdt_agent.c | 5 +-
+ lustre/mdt/mdt_hsm_cdt_requests.c | 5 +-
+ lustre/mdt/mdt_internal.h | 14 +-
+ lustre/mdt/mdt_lproc.c | 603 ++++++++++++++++++--------------------
+ lustre/mdt/mdt_mds.c | 12 +-
+ 8 files changed, 402 insertions(+), 506 deletions(-)
+
+diff --git a/lustre/mdt/mdt_coordinator.c b/lustre/mdt/mdt_coordinator.c
+index 3915e21..eb05bdf 100644
+--- a/lustre/mdt/mdt_coordinator.c
++++ b/lustre/mdt/mdt_coordinator.c
+@@ -46,7 +46,7 @@
+ #include <lustre_log.h>
+ #include "mdt_internal.h"
+
+-static struct lprocfs_vars lprocfs_mdt_hsm_vars[];
++static struct lprocfs_seq_vars lprocfs_mdt_hsm_vars[];
+
+ /**
+ * get obj and HSM attributes on a fid
+@@ -393,7 +393,7 @@ int hsm_cdt_procfs_init(struct mdt_device *mdt)
+ ENTRY;
+
+ /* init /proc entries, failure is not critical */
+- cdt->cdt_proc_dir = lprocfs_register("hsm",
++ cdt->cdt_proc_dir = lprocfs_seq_register("hsm",
+ mdt2obd_dev(mdt)->obd_proc_entry,
+ lprocfs_mdt_hsm_vars, mdt);
+ if (IS_ERR(cdt->cdt_proc_dir)) {
+@@ -425,7 +425,7 @@ void hsm_cdt_procfs_fini(struct mdt_device *mdt)
+ * \param none
+ * \retval var vector
+ */
+-struct lprocfs_vars *hsm_cdt_get_proc_vars(void)
++struct lprocfs_seq_vars *hsm_cdt_get_proc_vars(void)
+ {
+ return lprocfs_mdt_hsm_vars;
+ }
+@@ -1769,22 +1769,17 @@ static __u64 hsm_policy_str2bit(const char *name)
+ * \param hexa [IN] print mask before bit names
+ * \param buffer [OUT] string
+ * \param count [IN] size of buffer
+- * \retval size filled in buffer
+ */
+-static int hsm_policy_bit2str(const __u64 mask, const bool hexa, char *buffer,
+- int count)
++static void hsm_policy_bit2str(struct seq_file *m, const __u64 mask,
++ const bool hexa)
+ {
+- int i, j, sz;
+- char *ptr;
++ int i, j;
+ __u64 bit;
+ ENTRY;
+
+- ptr = buffer;
+- if (hexa) {
+- sz = snprintf(buffer, count, "("LPX64") ", mask);
+- ptr += sz;
+- count -= sz;
+- }
++ if (hexa)
++ seq_printf(m, "("LPX64") ", mask);
++
+ for (i = 0; i < CDT_POLICY_SHIFT_COUNT; i++) {
+ bit = (1ULL << i);
+
+@@ -1793,48 +1788,34 @@ static int hsm_policy_bit2str(const __u64 mask, const bool hexa, char *buffer,
+ break;
+ }
+ if (bit & mask)
+- sz = snprintf(ptr, count, "[%s] ",
+- hsm_policy_names[j].name);
++ seq_printf(m, "[%s] ", hsm_policy_names[j].name);
+ else
+- sz = snprintf(ptr, count, "%s ",
+- hsm_policy_names[j].name);
+-
+- ptr += sz;
+- count -= sz;
++ seq_printf(m, "%s ", hsm_policy_names[j].name);
+ }
+- /* remove last ' ' */
+- *ptr = '\0';
+- ptr--;
+- RETURN(ptr - buffer);
+ }
+
+ /* methods to read/write HSM policy flags */
+-static int lprocfs_rd_hsm_policy(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int mdt_hsm_policy_seq_show(struct seq_file *m, void *data)
+ {
+- struct mdt_device *mdt = data;
++ struct mdt_device *mdt = m->private;
+ struct coordinator *cdt = &mdt->mdt_coordinator;
+- int sz;
+ ENTRY;
+
+- sz = hsm_policy_bit2str(cdt->cdt_policy, false, page, count);
+- page[sz] = '\n';
+- sz++;
+- page[sz] = '\0';
+- *eof = 1;
+- RETURN(sz);
++ hsm_policy_bit2str(m, cdt->cdt_policy, false);
++ RETURN(0);
+ }
+
+-static int lprocfs_wr_hsm_policy(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++mdt_hsm_policy_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct mdt_device *mdt = data;
++ struct seq_file *m = file->private_data;
++ struct mdt_device *mdt = m->private;
+ struct coordinator *cdt = &mdt->mdt_coordinator;
+ char *start, *token, sign;
+ char *buf;
+ __u64 policy;
+ __u64 add_mask, remove_mask, set_mask;
+- int sz;
+ int rc;
+ ENTRY;
+
+@@ -1867,18 +1848,10 @@ static int lprocfs_wr_hsm_policy(struct file *file, const char *buffer,
+
+ policy = hsm_policy_str2bit(token);
+ if (policy == 0) {
+- char *msg;
+-
+- sz = PAGE_SIZE;
+- OBD_ALLOC(msg, sz);
+- if (!msg)
+- GOTO(out, rc = -ENOMEM);
+-
+- hsm_policy_bit2str(0, false, msg, sz);
+ CWARN("%s: '%s' is unknown, "
+- "supported policies are: %s\n", mdt_obd_name(mdt),
+- token, msg);
+- OBD_FREE(msg, sz);
++ "supported policies are: \n", mdt_obd_name(mdt),
++ token);
++ hsm_policy_bit2str(m, 0, false);
+ GOTO(out, rc = -EINVAL);
+ }
+ switch (sign) {
+@@ -1917,25 +1890,24 @@ out:
+ OBD_FREE(buf, count + 1);
+ RETURN(rc);
+ }
++LPROC_SEQ_FOPS(mdt_hsm_policy);
+
+ #define GENERATE_PROC_METHOD(VAR) \
+-static int lprocfs_rd_hsm_##VAR(char *page, char **start, off_t off, \
+- int count, int *eof, void *data) \
++static int mdt_hsm_##VAR##_seq_show(struct seq_file *m, void *data) \
+ { \
+- struct mdt_device *mdt = data; \
++ struct mdt_device *mdt = m->private; \
+ struct coordinator *cdt = &mdt->mdt_coordinator; \
+- int sz; \
+ ENTRY; \
+ \
+- sz = snprintf(page, count, LPU64"\n", (__u64)cdt->VAR); \
+- *eof = 1; \
+- RETURN(sz); \
++ seq_printf(m, LPU64"\n", (__u64)cdt->VAR); \
++ RETURN(0); \
+ } \
+-static int lprocfs_wr_hsm_##VAR(struct file *file, const char *buffer, \
+- unsigned long count, void *data) \
++static ssize_t \
++mdt_hsm_##VAR##_seq_write(struct file *file, const char *buffer, \
++ size_t count, loff_t *off) \
+ \
+ { \
+- struct mdt_device *mdt = data; \
++ struct mdt_device *mdt = ((struct seq_file *)file->private_data)->private;\
+ struct coordinator *cdt = &mdt->mdt_coordinator; \
+ int val; \
+ int rc; \
+@@ -1949,7 +1921,7 @@ static int lprocfs_wr_hsm_##VAR(struct file *file, const char *buffer, \
+ RETURN(count); \
+ } \
+ RETURN(-EINVAL); \
+-}
++} \
+
+ GENERATE_PROC_METHOD(cdt_loop_period)
+ GENERATE_PROC_METHOD(cdt_grace_delay)
+@@ -1967,10 +1939,11 @@ GENERATE_PROC_METHOD(cdt_default_archive_id)
+ #define CDT_PURGE_CMD "purge"
+ #define CDT_HELP_CMD "help"
+
+-int lprocfs_wr_hsm_cdt_control(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++ssize_t
++mdt_hsm_cdt_control_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
+ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+ struct coordinator *cdt = &(mdt->mdt_coordinator);
+ int rc, usage = 0;
+@@ -2024,83 +1997,71 @@ int lprocfs_wr_hsm_cdt_control(struct file *file, const char *buffer,
+ RETURN(count);
+ }
+
+-int lprocfs_rd_hsm_cdt_control(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++int mdt_hsm_cdt_control_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = m->private;
+ struct coordinator *cdt;
+- int sz;
+ ENTRY;
+
+ cdt = &(mdt_dev(obd->obd_lu_dev)->mdt_coordinator);
+- *eof = 1;
+
+ if (cdt->cdt_state == CDT_INIT)
+- sz = snprintf(page, count, "init\n");
++ seq_printf(m, "init\n");
+ else if (cdt->cdt_state == CDT_RUNNING)
+- sz = snprintf(page, count, "enabled\n");
++ seq_printf(m, "enabled\n");
+ else if (cdt->cdt_state == CDT_STOPPING)
+- sz = snprintf(page, count, "stopping\n");
++ seq_printf(m, "stopping\n");
+ else if (cdt->cdt_state == CDT_STOPPED)
+- sz = snprintf(page, count, "stopped\n");
++ seq_printf(m, "stopped\n");
+ else if (cdt->cdt_state == CDT_DISABLE)
+- sz = snprintf(page, count, "disabled\n");
++ seq_printf(m, "disabled\n");
+ else
+- sz = snprintf(page, count, "unknown\n");
++ seq_printf(m, "unknown\n");
+
+- RETURN(sz);
++ RETURN(0);
+ }
+
+ static int
+-lprocfs_rd_hsm_request_mask(char *page, char **start, off_t off,
+- int count, int *eof, __u64 mask)
++mdt_hsm_request_mask_show(struct seq_file *m, __u64 mask)
+ {
+ int i, rc = 0;
+ ENTRY;
+
+ for (i = 0; i < 8 * sizeof(mask); i++) {
+ if (mask & (1UL << i))
+- rc += snprintf(page + rc, count - rc, "%s%s",
+- rc == 0 ? "" : " ",
+- hsm_copytool_action2name(i));
++ rc += seq_printf(m, "%s%s", rc == 0 ? "" : " ",
++ hsm_copytool_action2name(i));
+ }
+-
+- rc += snprintf(page + rc, count - rc, "\n");
++ rc += seq_printf(m, "\n");
+
+ RETURN(rc);
+ }
+
+ static int
+-lprocfs_rd_hsm_user_request_mask(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++mdt_hsm_user_request_mask_seq_show(struct seq_file *m, void *data)
+ {
+- struct mdt_device *mdt = data;
++ struct mdt_device *mdt = m->private;
+ struct coordinator *cdt = &mdt->mdt_coordinator;
+
+- return lprocfs_rd_hsm_request_mask(page, start, off, count, eof,
+- cdt->cdt_user_request_mask);
++ return mdt_hsm_request_mask_show(m, cdt->cdt_user_request_mask);
+ }
+
+ static int
+-lprocfs_rd_hsm_group_request_mask(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++mdt_hsm_group_request_mask_seq_show(struct seq_file *m, void *data)
+ {
+- struct mdt_device *mdt = data;
++ struct mdt_device *mdt = m->private;
+ struct coordinator *cdt = &mdt->mdt_coordinator;
+
+- return lprocfs_rd_hsm_request_mask(page, start, off, count, eof,
+- cdt->cdt_group_request_mask);
++ return mdt_hsm_request_mask_show(m, cdt->cdt_group_request_mask);
+ }
+
+ static int
+-lprocfs_rd_hsm_other_request_mask(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++mdt_hsm_other_request_mask_seq_show(struct seq_file *m, void *data)
+ {
+- struct mdt_device *mdt = data;
++ struct mdt_device *mdt = m->private;
+ struct coordinator *cdt = &mdt->mdt_coordinator;
+
+- return lprocfs_rd_hsm_request_mask(page, start, off, count, eof,
+- cdt->cdt_other_request_mask);
++ return mdt_hsm_request_mask_show(m, cdt->cdt_other_request_mask);
+ }
+
+ static inline enum hsm_copytool_action
+@@ -2120,9 +2081,9 @@ hsm_copytool_name2action(const char *name)
+ return -1;
+ }
+
+-static int
+-lprocfs_wr_hsm_request_mask(struct file *file, const char __user *user_buf,
+- unsigned long user_count, __u64 *mask)
++static ssize_t
++mdt_write_hsm_request_mask(struct file *file, const char __user *user_buf,
++ size_t user_count, __u64 *mask)
+ {
+ char *buf, *pos, *name;
+ size_t buf_size;
+@@ -2166,69 +2127,60 @@ out:
+ RETURN(rc);
+ }
+
+-static int
+-lprocfs_wr_hsm_user_request_mask(struct file *file, const char __user *buf,
+- unsigned long count, void *data)
++static ssize_t
++mdt_hsm_user_request_mask_seq_write(struct file *file, const char __user *buf,
++ size_t count, loff_t *off)
+ {
+- struct mdt_device *mdt = data;
++ struct mdt_device *mdt = ((struct seq_file *)file->private_data)->private;
+ struct coordinator *cdt = &mdt->mdt_coordinator;
+
+- return lprocfs_wr_hsm_request_mask(file, buf, count,
++ return mdt_write_hsm_request_mask(file, buf, count,
+ &cdt->cdt_user_request_mask);
+ }
+
+-static int
+-lprocfs_wr_hsm_group_request_mask(struct file *file, const char __user *buf,
+- unsigned long count, void *data)
++static ssize_t
++mdt_hsm_group_request_mask_seq_write(struct file *file, const char __user *buf,
++ size_t count, loff_t *off)
+ {
+- struct mdt_device *mdt = data;
++ struct mdt_device *mdt = ((struct seq_file *)file->private_data)->private;
+ struct coordinator *cdt = &mdt->mdt_coordinator;
+
+- return lprocfs_wr_hsm_request_mask(file, buf, count,
++ return mdt_write_hsm_request_mask(file, buf, count,
+ &cdt->cdt_group_request_mask);
+ }
+
+-static int
+-lprocfs_wr_hsm_other_request_mask(struct file *file, const char __user *buf,
+- unsigned long count, void *data)
++static ssize_t
++mdt_hsm_other_request_mask_seq_write(struct file *file, const char __user *buf,
++ size_t count, loff_t *off)
+ {
+- struct mdt_device *mdt = data;
++ struct mdt_device *mdt = ((struct seq_file *)file->private_data)->private;
+ struct coordinator *cdt = &mdt->mdt_coordinator;
+
+- return lprocfs_wr_hsm_request_mask(file, buf, count,
++ return mdt_write_hsm_request_mask(file, buf, count,
+ &cdt->cdt_other_request_mask);
+ }
+
+-static struct lprocfs_vars lprocfs_mdt_hsm_vars[] = {
+- { "agents", NULL, NULL, NULL, &mdt_hsm_agent_fops,
+- 0 },
+- { "actions", NULL, NULL, NULL, &mdt_hsm_actions_fops,
+- 0444 },
+- { "default_archive_id", lprocfs_rd_hsm_cdt_default_archive_id,
+- lprocfs_wr_hsm_cdt_default_archive_id,
+- NULL, NULL, 0 },
+- { "grace_delay", lprocfs_rd_hsm_cdt_grace_delay,
+- lprocfs_wr_hsm_cdt_grace_delay,
+- NULL, NULL, 0 },
+- { "loop_period", lprocfs_rd_hsm_cdt_loop_period,
+- lprocfs_wr_hsm_cdt_loop_period,
+- NULL, NULL, 0 },
+- { "max_requests", lprocfs_rd_hsm_cdt_max_requests,
+- lprocfs_wr_hsm_cdt_max_requests,
+- NULL, NULL, 0 },
+- { "policy", lprocfs_rd_hsm_policy,
+- lprocfs_wr_hsm_policy,
+- NULL, NULL, 0 },
+- { "active_request_timeout", lprocfs_rd_hsm_cdt_active_req_timeout,
+- lprocfs_wr_hsm_cdt_active_req_timeout,
+- NULL, NULL, 0 },
+- { "active_requests", NULL, NULL, NULL,
+- &mdt_hsm_active_requests_fops, 0 },
+- { "user_request_mask", lprocfs_rd_hsm_user_request_mask,
+- lprocfs_wr_hsm_user_request_mask, },
+- { "group_request_mask", lprocfs_rd_hsm_group_request_mask,
+- lprocfs_wr_hsm_group_request_mask, },
+- { "other_request_mask", lprocfs_rd_hsm_other_request_mask,
+- lprocfs_wr_hsm_other_request_mask, },
++LPROC_SEQ_FOPS(mdt_hsm_cdt_loop_period);
++LPROC_SEQ_FOPS(mdt_hsm_cdt_grace_delay);
++LPROC_SEQ_FOPS(mdt_hsm_cdt_active_req_timeout);
++LPROC_SEQ_FOPS(mdt_hsm_cdt_max_requests);
++LPROC_SEQ_FOPS(mdt_hsm_cdt_default_archive_id);
++LPROC_SEQ_FOPS(mdt_hsm_user_request_mask);
++LPROC_SEQ_FOPS(mdt_hsm_group_request_mask);
++LPROC_SEQ_FOPS(mdt_hsm_other_request_mask);
++
++static struct lprocfs_seq_vars lprocfs_mdt_hsm_vars[] = {
++ { "agents", &mdt_hsm_agent_fops },
++ { "actions", &mdt_hsm_actions_fops, NULL, 0444 },
++ { "default_archive_id", &mdt_hsm_cdt_default_archive_id_fops },
++ { "grace_delay", &mdt_hsm_cdt_grace_delay_fops },
++ { "loop_period", &mdt_hsm_cdt_loop_period_fops },
++ { "max_requests", &mdt_hsm_cdt_max_requests_fops },
++ { "policy", &mdt_hsm_policy_fops },
++ { "active_request_timeout",&mdt_hsm_cdt_active_req_timeout_fops },
++ { "active_requests", &mdt_hsm_active_requests_fops },
++ { "user_request_mask", &mdt_hsm_user_request_mask_fops, },
++ { "group_request_mask", &mdt_hsm_group_request_mask_fops, },
++ { "other_request_mask", &mdt_hsm_other_request_mask_fops, },
+ { 0 }
+ };
+diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c
+index 8daf7e1..9f7d4ba 100644
+--- a/lustre/mdt/mdt_handler.c
++++ b/lustre/mdt/mdt_handler.c
+@@ -4508,7 +4508,6 @@ static int mdt_process_config(const struct lu_env *env,
+
+ switch (cfg->lcfg_command) {
+ case LCFG_PARAM: {
+- struct lprocfs_static_vars lvars;
+ struct obd_device *obd = d->ld_obd;
+
+ /* For interoperability */
+@@ -4543,14 +4542,13 @@ static int mdt_process_config(const struct lu_env *env,
+ }
+ }
+
+- lprocfs_mdt_init_vars(&lvars);
+- rc = class_process_proc_param(PARAM_MDT, lvars.obd_vars,
+- cfg, obd);
++ rc = class_process_proc_seq_param(PARAM_MDT, obd->obd_vars,
++ cfg, obd);
+ if (rc > 0 || rc == -ENOSYS) {
+ /* is it an HSM var ? */
+- rc = class_process_proc_param(PARAM_HSM,
+- hsm_cdt_get_proc_vars(),
+- cfg, obd);
++ rc = class_process_proc_seq_param(PARAM_HSM,
++ hsm_cdt_get_proc_vars(),
++ cfg, obd);
+ if (rc > 0 || rc == -ENOSYS)
+ /* we don't understand; pass it on */
+ rc = next->ld_ops->ldo_process_config(env, next,
+@@ -5725,7 +5723,6 @@ static struct lu_device_type mdt_device_type = {
+
+ static int __init mdt_mod_init(void)
+ {
+- struct lprocfs_static_vars lvars;
+ int rc;
+
+ CLASSERT(sizeof("0x0123456789ABCDEF:0x01234567:0x01234567") ==
+@@ -5740,10 +5737,9 @@ static int __init mdt_mod_init(void)
+ if (rc)
+ GOTO(lu_fini, rc);
+
+- lprocfs_mdt_init_vars(&lvars);
+ rc = class_register_type(&mdt_obd_device_ops, NULL, NULL,
+ #ifndef HAVE_ONLY_PROCFS_SEQ
+- lvars.module_vars,
++ NULL,
+ #endif
+ LUSTRE_MDT_NAME, &mdt_device_type);
+ if (rc)
+diff --git a/lustre/mdt/mdt_hsm_cdt_actions.c b/lustre/mdt/mdt_hsm_cdt_actions.c
+index da7f5a9..c4c5bbf 100644
+--- a/lustre/mdt/mdt_hsm_cdt_actions.c
++++ b/lustre/mdt/mdt_hsm_cdt_actions.c
+@@ -513,9 +513,6 @@ static int lprocfs_open_hsm_actions(struct inode *inode, struct file *file)
+ struct mdt_device *mdt;
+ ENTRY;
+
+- if (LPROCFS_ENTRY_CHECK(PDE(inode)))
+- RETURN(-ENOENT);
+-
+ rc = seq_open(file, &mdt_hsm_actions_proc_ops);
+ if (rc)
+ RETURN(rc);
+@@ -532,8 +529,8 @@ static int lprocfs_open_hsm_actions(struct inode *inode, struct file *file)
+ /* mdt is saved in proc_dir_entry->data by
+ * mdt_coordinator_procfs_init() calling lprocfs_register()
+ */
+- mdt = (struct mdt_device *)PDE(inode)->data;
+- aai->aai_mdt = mdt;
++ mdt = (struct mdt_device *)PDE_DATA(inode);
++ aai->aai_obd = mdt2obd_dev(mdt);
+ s = file->private_data;
+ s->private = aai;
+
+diff --git a/lustre/mdt/mdt_hsm_cdt_agent.c b/lustre/mdt/mdt_hsm_cdt_agent.c
+index 9a9ce6d..158cced 100644
+--- a/lustre/mdt/mdt_hsm_cdt_agent.c
++++ b/lustre/mdt/mdt_hsm_cdt_agent.c
+@@ -621,15 +621,12 @@ static int lprocfs_open_hsm_agent(struct inode *inode, struct file *file)
+ int rc;
+ ENTRY;
+
+- if (LPROCFS_ENTRY_CHECK(PDE(inode)))
+- RETURN(-ENOENT);
+-
+ rc = seq_open(file, &mdt_hsm_agent_proc_ops);
+ if (rc)
+ RETURN(rc);
+
+ s = file->private_data;
+- s->private = PDE(inode)->data;
++ s->private = PDE_DATA(inode);
+
+ RETURN(rc);
+ }
+diff --git a/lustre/mdt/mdt_hsm_cdt_requests.c b/lustre/mdt/mdt_hsm_cdt_requests.c
+index 796cbea..7bbc771 100644
+--- a/lustre/mdt/mdt_hsm_cdt_requests.c
++++ b/lustre/mdt/mdt_hsm_cdt_requests.c
+@@ -569,15 +569,12 @@ static int lprocfs_open_hsm_active_requests(struct inode *inode,
+ int rc;
+ ENTRY;
+
+- if (LPROCFS_ENTRY_CHECK(PDE(inode)))
+- RETURN(-ENOENT);
+-
+ rc = seq_open(file, &mdt_hsm_active_requests_proc_ops);
+ if (rc) {
+ RETURN(rc);
+ }
+ s = file->private_data;
+- s->private = PDE(inode)->data;
++ s->private = PDE_DATA(inode);
+
+ RETURN(rc);
+ }
+diff --git a/lustre/mdt/mdt_internal.h b/lustre/mdt/mdt_internal.h
+index dd36201..43cf9eb 100644
+--- a/lustre/mdt/mdt_internal.h
++++ b/lustre/mdt/mdt_internal.h
+@@ -778,9 +778,6 @@ void mdt_thread_info_init(struct ptlrpc_request *req,
+ void mdt_thread_info_fini(struct mdt_thread_info *mti);
+ struct mdt_thread_info *tsi2mdt_info(struct tgt_session_info *tsi);
+
+-extern struct lprocfs_vars lprocfs_mds_module_vars[];
+-extern struct lprocfs_vars lprocfs_mds_obd_vars[];
+-
+ int mdt_hsm_attr_set(struct mdt_thread_info *info, struct mdt_object *obj,
+ const struct md_hsm *mh);
+
+@@ -913,13 +910,12 @@ int mdt_hsm_cdt_fini(struct mdt_device *mdt);
+ int mdt_hsm_cdt_wakeup(struct mdt_device *mdt);
+
+ /* coordinator control /proc interface */
+-int lprocfs_wr_hsm_cdt_control(struct file *file, const char *buffer,
+- unsigned long count, void *data);
+-int lprocfs_rd_hsm_cdt_control(char *page, char **start, off_t off,
+- int count, int *eof, void *data);
++ssize_t mdt_hsm_cdt_control_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off);
++int mdt_hsm_cdt_control_seq_show(struct seq_file *m, void *data);
+ int hsm_cdt_procfs_init(struct mdt_device *mdt);
+ void hsm_cdt_procfs_fini(struct mdt_device *mdt);
+-struct lprocfs_vars *hsm_cdt_get_proc_vars(void);
++struct lprocfs_seq_vars *hsm_cdt_get_proc_vars(void);
+ /* md_hsm helpers */
+ struct mdt_object *mdt_hsm_get_md_hsm(struct mdt_thread_info *mti,
+ const struct lu_fid *fid,
+@@ -1087,8 +1083,6 @@ enum {
+ };
+ void mdt_counter_incr(struct ptlrpc_request *req, int opcode);
+ void mdt_stats_counter_init(struct lprocfs_stats *stats);
+-void lprocfs_mdt_init_vars(struct lprocfs_static_vars *lvars);
+-void lprocfs_mds_init_vars(struct lprocfs_static_vars *lvars);
+ int mdt_procfs_init(struct mdt_device *mdt, const char *name);
+ void mdt_procfs_fini(struct mdt_device *mdt);
+ void mdt_rename_counter_tally(struct mdt_thread_info *info,
+diff --git a/lustre/mdt/mdt_lproc.c b/lustre/mdt/mdt_lproc.c
+index 4abb532..236b6c2 100644
+--- a/lustre/mdt/mdt_lproc.c
++++ b/lustre/mdt/mdt_lproc.c
+@@ -156,7 +156,6 @@ static ssize_t mdt_rename_stats_seq_write(struct file *file, const char *buf,
+
+ return len;
+ }
+-
+ LPROC_SEQ_FOPS(mdt_rename_stats);
+
+ static int lproc_mdt_attach_rename_seqstat(struct mdt_device *mdt)
+@@ -213,143 +212,73 @@ void mdt_rename_counter_tally(struct mdt_thread_info *info,
+ (unsigned int)ma->ma_attr.la_size);
+ }
+
+-int mdt_procfs_init(struct mdt_device *mdt, const char *name)
+-{
+- struct obd_device *obd = mdt2obd_dev(mdt);
+- struct lprocfs_static_vars lvars;
+- int rc;
+- ENTRY;
+-
+- LASSERT(name != NULL);
+-
+- lprocfs_mdt_init_vars(&lvars);
+- rc = lprocfs_obd_setup(obd, lvars.obd_vars);
+- if (rc) {
+- CERROR("%s: cannot create proc entries: rc = %d\n",
+- mdt_obd_name(mdt), rc);
+- return rc;
+- }
+-
+- rc = hsm_cdt_procfs_init(mdt);
+- if (rc) {
+- CERROR("%s: cannot create hsm proc entries: rc = %d\n",
+- mdt_obd_name(mdt), rc);
+- return rc;
+- }
+-
+- obd->obd_proc_exports_entry = proc_mkdir("exports",
+- obd->obd_proc_entry);
+- if (obd->obd_proc_exports_entry)
+- lprocfs_add_simple(obd->obd_proc_exports_entry,
+- "clear", lprocfs_nid_stats_clear_read,
+- lprocfs_nid_stats_clear_write, obd, NULL);
+- rc = lprocfs_alloc_md_stats(obd, LPROC_MDT_LAST);
+- if (rc)
+- return rc;
+- mdt_stats_counter_init(obd->obd_md_stats);
+-
+- rc = lprocfs_job_stats_init(obd, LPROC_MDT_LAST,
+- mdt_stats_counter_init);
+-
+- rc = lproc_mdt_attach_rename_seqstat(mdt);
+- if (rc)
+- CERROR("%s: MDT can not create rename stats rc = %d\n",
+- mdt_obd_name(mdt), rc);
+-
+- RETURN(rc);
+-}
+-
+-void mdt_procfs_fini(struct mdt_device *mdt)
+-{
+- struct obd_device *obd = mdt2obd_dev(mdt);
+-
+- if (obd->obd_proc_exports_entry != NULL) {
+- lprocfs_remove_proc_entry("clear", obd->obd_proc_exports_entry);
+- obd->obd_proc_exports_entry = NULL;
+- }
+-
+- lprocfs_free_per_client_stats(obd);
+- hsm_cdt_procfs_fini(mdt);
+- lprocfs_obd_cleanup(obd);
+- lprocfs_free_md_stats(obd);
+- lprocfs_free_obd_stats(obd);
+- lprocfs_job_stats_fini(obd);
+-}
+-
+-static int lprocfs_rd_identity_expire(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int mdt_identity_expire_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *obd = data;
+- struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
++ struct obd_device *obd = m->private;
++ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+
+- *eof = 1;
+- return snprintf(page, count, "%u\n",
+- mdt->mdt_identity_cache->uc_entry_expire);
++ return seq_printf(m, "%u\n", mdt->mdt_identity_cache->uc_entry_expire);
+ }
+
+-static int lprocfs_wr_identity_expire(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++mdt_identity_expire_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *obd = data;
+- struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+- int rc, val;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
++ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
++ int rc, val;
+
+- rc = lprocfs_write_helper(buffer, count, &val);
+- if (rc)
+- return rc;
++ rc = lprocfs_write_helper(buffer, count, &val);
++ if (rc)
++ return rc;
+
+- mdt->mdt_identity_cache->uc_entry_expire = val;
+- return count;
++ mdt->mdt_identity_cache->uc_entry_expire = val;
++ return count;
+ }
++LPROC_SEQ_FOPS(mdt_identity_expire);
+
+-static int lprocfs_rd_identity_acquire_expire(char *page, char **start,
+- off_t off, int count, int *eof,
+- void *data)
++static int mdt_identity_acquire_expire_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *obd = data;
+- struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
++ struct obd_device *obd = m->private;
++ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+
+- *eof = 1;
+- return snprintf(page, count, "%u\n",
+- mdt->mdt_identity_cache->uc_acquire_expire);
++ return seq_printf(m,"%u\n", mdt->mdt_identity_cache->uc_acquire_expire);
+ }
+
+-static int lprocfs_wr_identity_acquire_expire(struct file *file,
+- const char *buffer,
+- unsigned long count,
+- void *data)
++static ssize_t
++mdt_identity_acquire_expire_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *obd = data;
+- struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+- int rc, val;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
++ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
++ int rc, val;
+
+- rc = lprocfs_write_helper(buffer, count, &val);
+- if (rc)
+- return rc;
++ rc = lprocfs_write_helper(buffer, count, &val);
++ if (rc)
++ return rc;
+
+- mdt->mdt_identity_cache->uc_acquire_expire = val;
+- return count;
++ mdt->mdt_identity_cache->uc_acquire_expire = val;
++ return count;
+ }
++LPROC_SEQ_FOPS(mdt_identity_acquire_expire);
+
+-static int lprocfs_rd_identity_upcall(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int mdt_identity_upcall_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *obd = data;
+- struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+- struct upcall_cache *hash = mdt->mdt_identity_cache;
+- int len;
++ struct obd_device *obd = m->private;
++ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
++ struct upcall_cache *hash = mdt->mdt_identity_cache;
+
+- *eof = 1;
+ read_lock(&hash->uc_upcall_rwlock);
+- len = snprintf(page, count, "%s\n", hash->uc_upcall);
++ seq_printf(m, "%s\n", hash->uc_upcall);
+ read_unlock(&hash->uc_upcall_rwlock);
+- return len;
++ return 0;
+ }
+
+-static int lprocfs_wr_identity_upcall(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++mdt_identity_upcall_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
+ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+ struct upcall_cache *hash = mdt->mdt_identity_cache;
+ int rc;
+@@ -388,11 +317,13 @@ static int lprocfs_wr_identity_upcall(struct file *file, const char *buffer,
+ OBD_FREE(kernbuf, count + 1);
+ RETURN(rc);
+ }
++LPROC_SEQ_FOPS(mdt_identity_upcall);
+
+-static int lprocfs_wr_identity_flush(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++lprocfs_identity_flush_seq_write(struct file *file, const char *buffer,
++ size_t count, void *data)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
+ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+ int rc, uid;
+
+@@ -403,11 +334,13 @@ static int lprocfs_wr_identity_flush(struct file *file, const char *buffer,
+ mdt_flush_identity(mdt->mdt_identity_cache, uid);
+ return count;
+ }
++LPROC_SEQ_FOPS_WO_TYPE(mdt, identity_flush);
+
+-static int lprocfs_wr_identity_info(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++lprocfs_identity_info_seq_write(struct file *file, const char *buffer,
++ size_t count, void *data)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
+ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+ struct identity_downcall_data *param;
+ int size = sizeof(*param), rc, checked = 0;
+@@ -468,23 +401,24 @@ out:
+
+ return rc ? rc : count;
+ }
++LPROC_SEQ_FOPS_WO_TYPE(mdt, identity_info);
+
+ /* for debug only */
+-static int lprocfs_rd_capa(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int mdt_capa_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = m->private;
+ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+
+- return snprintf(page, count, "capability on: %s %s\n",
++ return seq_printf(m, "capability on: %s %s\n",
+ mdt->mdt_lut.lut_oss_capa ? "oss" : "",
+ mdt->mdt_lut.lut_mds_capa ? "mds" : "");
+ }
+
+-static int lprocfs_wr_capa(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++mdt_capa_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
+ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+ int val, rc;
+
+@@ -521,64 +455,65 @@ static int lprocfs_wr_capa(struct file *file, const char *buffer,
+ mdt->mdt_lut.lut_oss_capa ? "enabled" : "disabled");
+ return count;
+ }
++LPROC_SEQ_FOPS(mdt_capa);
+
+-static int lprocfs_rd_capa_count(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int mdt_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(mdt_capa_count);
+
+-static int lprocfs_rd_site_stats(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int mdt_site_stats_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *obd = data;
+- struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
++ struct obd_device *obd = m->private;
++ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+
+- return lu_site_stats_print(mdt_lu_site(mdt), page, count);
++ return lu_site_stats_seq_print(mdt_lu_site(mdt), m);
+ }
++LPROC_SEQ_FOPS_RO(mdt_site_stats);
+
+-static int lprocfs_rd_capa_timeout(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int mdt_capa_timeout_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *obd = data;
+- struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
++ struct obd_device *obd = m->private;
++ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+
+- return snprintf(page, count, "%lu\n", mdt->mdt_capa_timeout);
++ return seq_printf(m, "%lu\n", mdt->mdt_capa_timeout);
+ }
+
+-static int lprocfs_wr_capa_timeout(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++mdt_capa_timeout_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *obd = data;
+- struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+- int val, rc;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
++ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
++ int val, rc;
+
+- rc = lprocfs_write_helper(buffer, count, &val);
+- if (rc)
+- return rc;
++ rc = lprocfs_write_helper(buffer, count, &val);
++ if (rc)
++ return rc;
+
+- mdt->mdt_capa_timeout = (unsigned long)val;
+- mdt->mdt_capa_conf = 1;
+- return count;
++ mdt->mdt_capa_timeout = (unsigned long)val;
++ mdt->mdt_capa_conf = 1;
++ return count;
+ }
++LPROC_SEQ_FOPS(mdt_capa_timeout);
+
+-static int lprocfs_rd_ck_timeout(char *page, char **start, off_t off, int count,
+- int *eof, void *data)
++static int mdt_ck_timeout_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *obd = data;
+- struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
++ struct obd_device *obd = m->private;
++ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+
+- return snprintf(page, count, "%lu\n", mdt->mdt_ck_timeout);
++ return seq_printf(m, "%lu\n", mdt->mdt_ck_timeout);
+ }
+
+-static int lprocfs_wr_ck_timeout(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++mdt_ck_timeout_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *obd = data;
+- struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+- int val, rc;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
++ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
++ int val, rc;
+
+ rc = lprocfs_write_helper(buffer, count, &val);
+ if (rc)
+@@ -588,11 +523,13 @@ static int lprocfs_wr_ck_timeout(struct file *file, const char *buffer,
+ mdt->mdt_capa_conf = 1;
+ return count;
+ }
++LPROC_SEQ_FOPS(mdt_ck_timeout);
+
+ #define BUFLEN (UUID_MAX + 4)
+
+-static int lprocfs_mdt_wr_evict_client(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++lprocfs_mds_evict_client_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+ char *kbuf;
+ char *tmpbuf;
+@@ -614,7 +551,7 @@ static int lprocfs_mdt_wr_evict_client(struct file *file, const char *buffer,
+ tmpbuf = cfs_firststr(kbuf, min_t(unsigned long, BUFLEN - 1, count));
+
+ if (strncmp(tmpbuf, "nid:", 4) != 0) {
+- count = lprocfs_wr_evict_client(file, buffer, count, data);
++ count = lprocfs_evict_client_seq_write(file, buffer, count, off);
+ goto out;
+ }
+
+@@ -627,21 +564,21 @@ out:
+
+ #undef BUFLEN
+
+-static int lprocfs_rd_sec_level(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int mdt_sec_level_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *obd = data;
+- struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
++ struct obd_device *obd = m->private;
++ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+
+- return snprintf(page, count, "%d\n", mdt->mdt_lut.lut_sec_level);
++ return seq_printf(m, "%d\n", mdt->mdt_lut.lut_sec_level);
+ }
+
+-static int lprocfs_wr_sec_level(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++mdt_sec_level_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *obd = data;
+- struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+- int val, rc;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
++ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
++ int val, rc;
+
+ rc = lprocfs_write_helper(buffer, count, &val);
+ if (rc)
+@@ -659,22 +596,23 @@ static int lprocfs_wr_sec_level(struct file *file, const char *buffer,
+ mdt->mdt_lut.lut_sec_level = val;
+ return count;
+ }
++LPROC_SEQ_FOPS(mdt_sec_level);
+
+-static int lprocfs_rd_cos(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int mdt_cos_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *obd = data;
+- struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
++ struct obd_device *obd = m->private;
++ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+
+- return snprintf(page, count, "%u\n", mdt_cos_is_enabled(mdt));
++ return seq_printf(m, "%u\n", mdt_cos_is_enabled(mdt));
+ }
+
+-static int lprocfs_wr_cos(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++mdt_cos_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *obd = data;
+- struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+- int val, rc;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
++ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
++ int val, rc;
+
+ rc = lprocfs_write_helper(buffer, count, &val);
+ if (rc)
+@@ -682,15 +620,15 @@ static int lprocfs_wr_cos(struct file *file, const char *buffer,
+ mdt_enable_cos(mdt, val);
+ return count;
+ }
++LPROC_SEQ_FOPS(mdt_cos);
+
+-static int lprocfs_rd_root_squash(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int mdt_root_squash_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *obd = data;
+- struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
++ struct obd_device *obd = m->private;
++ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+
+- return snprintf(page, count, "%u:%u\n", mdt->mdt_squash_uid,
+- mdt->mdt_squash_gid);
++ return seq_printf(m, "%u:%u\n", mdt->mdt_squash_uid,
++ mdt->mdt_squash_gid);
+ }
+
+ static int safe_strtoul(const char *str, char **endp, unsigned long *res)
+@@ -708,10 +646,11 @@ static int safe_strtoul(const char *str, char **endp, unsigned long *res)
+ return 0;
+ }
+
+-static int lprocfs_wr_root_squash(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++mdt_root_squash_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
+ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+ int rc;
+ char kernbuf[50], *tmp, *end, *errmsg;
+@@ -765,22 +704,23 @@ failed:
+ mdt_obd_name(mdt), buffer, errmsg, rc);
+ RETURN(rc);
+ }
++LPROC_SEQ_FOPS(mdt_root_squash);
+
+-static int lprocfs_rd_nosquash_nids(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int mdt_nosquash_nids_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *obd = data;
+- struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
++ struct obd_device *obd = m->private;
++ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+
+- if (mdt->mdt_nosquash_str)
+- return snprintf(page, count, "%s\n", mdt->mdt_nosquash_str);
+- return snprintf(page, count, "NONE\n");
++ if (mdt->mdt_nosquash_str)
++ return seq_printf(m, "%s\n", mdt->mdt_nosquash_str);
++ return seq_printf(m, "NONE\n");
+ }
+
+-static int lprocfs_wr_nosquash_nids(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++mdt_nosquash_nids_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
+ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+ int rc;
+ char *kernbuf, *errmsg;
+@@ -842,25 +782,26 @@ failed:
+ OBD_FREE(kernbuf, count + 1);
+ RETURN(rc);
+ }
++LPROC_SEQ_FOPS(mdt_nosquash_nids);
+
+-static int lprocfs_rd_mdt_som(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int mdt_som_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *obd = data;
+- struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
++ struct obd_device *obd = m->private;
++ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+
+- return snprintf(page, count, "%sabled\n",
+- mdt->mdt_som_conf ? "en" : "dis");
++ return seq_printf(m, "%sabled\n",
++ mdt->mdt_som_conf ? "en" : "dis");
+ }
+
+-static int lprocfs_wr_mdt_som(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++mdt_som_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_export *exp;
+- struct obd_device *obd = data;
+- struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+- char kernbuf[16];
+- unsigned long val = 0;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
++ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
++ struct obd_export *exp;
++ char kernbuf[16];
++ unsigned long val = 0;
+
+ if (count > (sizeof(kernbuf) - 1))
+ return -EINVAL;
+@@ -902,20 +843,21 @@ static int lprocfs_wr_mdt_som(struct file *file, const char *buffer,
+
+ return count;
+ }
++LPROC_SEQ_FOPS(mdt_som);
+
+-static int lprocfs_rd_enable_remote_dir(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int mdt_enable_remote_dir_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = m->private;
+ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+
+- return snprintf(page, count, "%u\n", mdt->mdt_enable_remote_dir);
++ return seq_printf(m, "%u\n", mdt->mdt_enable_remote_dir);
+ }
+
+-static int lprocfs_wr_enable_remote_dir(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++mdt_enable_remote_dir_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
+ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+ __u32 val;
+ int rc;
+@@ -930,22 +872,22 @@ static int lprocfs_wr_enable_remote_dir(struct file *file, const char *buffer,
+ mdt->mdt_enable_remote_dir = val;
+ return count;
+ }
++LPROC_SEQ_FOPS(mdt_enable_remote_dir);
+
+-static int lprocfs_rd_enable_remote_dir_gid(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int mdt_enable_remote_dir_gid_seq_show(struct seq_file *m, void *data)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = m->private;
+ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+
+- return snprintf(page, count, "%d\n",
+- (int)mdt->mdt_enable_remote_dir_gid);
++ return seq_printf(m, "%d\n",
++ (int)mdt->mdt_enable_remote_dir_gid);
+ }
+
+-static int lprocfs_wr_enable_remote_dir_gid(struct file *file,
+- const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++mdt_enable_remote_dir_gid_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct obd_device *obd = data;
++ struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
+ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+ __u32 val;
+ int rc;
+@@ -957,97 +899,46 @@ static int lprocfs_wr_enable_remote_dir_gid(struct file *file,
+ mdt->mdt_enable_remote_dir_gid = val;
+ return count;
+ }
+-
+-static struct lprocfs_vars lprocfs_mdt_obd_vars[] = {
+- { "uuid", lprocfs_rd_uuid, NULL,
+- NULL, NULL, 0 },
+- { "recovery_status", lprocfs_obd_rd_recovery_status, NULL,
+- NULL, NULL, 0 },
+- { "num_exports", lprocfs_rd_num_exports, NULL,
+- NULL, NULL, 0 },
+- { "identity_expire", lprocfs_rd_identity_expire,
+- lprocfs_wr_identity_expire,
+- NULL, NULL, 0 },
+- { "identity_acquire_expire", lprocfs_rd_identity_acquire_expire,
+- lprocfs_wr_identity_acquire_expire,
+- NULL, NULL, 0 },
+- { "identity_upcall", lprocfs_rd_identity_upcall,
+- lprocfs_wr_identity_upcall,
+- NULL, NULL, 0 },
+- { "identity_flush", NULL, lprocfs_wr_identity_flush,
+- NULL, NULL, 0 },
+- { "identity_info", NULL, lprocfs_wr_identity_info,
+- NULL, NULL, 0 },
+- { "capa", lprocfs_rd_capa,
+- lprocfs_wr_capa,
+- NULL, NULL, 0 },
+- { "capa_timeout", lprocfs_rd_capa_timeout,
+- lprocfs_wr_capa_timeout,
+- NULL, NULL, 0 },
+- { "capa_key_timeout", lprocfs_rd_ck_timeout,
+- lprocfs_wr_ck_timeout,
+- NULL, NULL, 0 },
+- { "capa_count", lprocfs_rd_capa_count, NULL,
+- NULL, NULL, 0 },
+- { "site_stats", lprocfs_rd_site_stats, NULL,
+- NULL, NULL, 0 },
+- { "evict_client", NULL, lprocfs_mdt_wr_evict_client,
+- NULL, NULL, 0 },
+- { "hash_stats", lprocfs_obd_rd_hash, NULL,
+- NULL, NULL, 0 },
+- { "sec_level", lprocfs_rd_sec_level,
+- lprocfs_wr_sec_level,
+- NULL, NULL, 0 },
+- { "commit_on_sharing", lprocfs_rd_cos, lprocfs_wr_cos,
+- NULL, NULL, 0 },
+- { "root_squash", lprocfs_rd_root_squash,
+- lprocfs_wr_root_squash,
+- NULL, NULL, 0 },
+- { "nosquash_nids", lprocfs_rd_nosquash_nids,
+- lprocfs_wr_nosquash_nids,
+- NULL, NULL, 0 },
+- { "som", lprocfs_rd_mdt_som,
+- lprocfs_wr_mdt_som,
+- NULL, NULL, 0 },
+- { "instance", lprocfs_target_rd_instance, NULL,
+- NULL, NULL, 0},
+- { "ir_factor", lprocfs_obd_rd_ir_factor,
+- lprocfs_obd_wr_ir_factor,
+- NULL, NULL, 0 },
+- { "job_cleanup_interval", lprocfs_rd_job_interval,
+- lprocfs_wr_job_interval,
+- NULL, NULL, 0 },
+- { "enable_remote_dir", lprocfs_rd_enable_remote_dir,
+- lprocfs_wr_enable_remote_dir,
+- NULL, NULL, 0},
+- { "enable_remote_dir_gid", lprocfs_rd_enable_remote_dir_gid,
+- lprocfs_wr_enable_remote_dir_gid,
+- NULL, NULL, 0},
+- { "hsm_control", lprocfs_rd_hsm_cdt_control,
+- lprocfs_wr_hsm_cdt_control,
+- NULL, NULL, 0 },
+- { 0 }
+-};
+-
+-static struct lprocfs_vars lprocfs_mdt_module_vars[] = {
+- { "num_refs", lprocfs_rd_numrefs, NULL,
+- NULL, NULL, 0 },
+- { 0 }
+-};
+-
+-void lprocfs_mdt_init_vars(struct lprocfs_static_vars *lvars)
+-{
+- lvars->module_vars = lprocfs_mdt_module_vars;
+- lvars->obd_vars = lprocfs_mdt_obd_vars;
+-}
+-
+-struct lprocfs_vars lprocfs_mds_obd_vars[] = {
+- { "uuid", lprocfs_rd_uuid, NULL, NULL, NULL, 0 },
+- { 0 }
+-};
+-
+-struct lprocfs_vars lprocfs_mds_module_vars[] = {
+- { "num_refs", lprocfs_rd_numrefs, NULL, NULL, NULL, 0 },
++LPROC_SEQ_FOPS(mdt_enable_remote_dir_gid);
++
++LPROC_SEQ_FOPS_RO_TYPE(mdt, uuid);
++LPROC_SEQ_FOPS_RO_TYPE(mdt, recovery_status);
++LPROC_SEQ_FOPS_RO_TYPE(mdt, num_exports);
++LPROC_SEQ_FOPS_RO_TYPE(mdt, target_instance);
++LPROC_SEQ_FOPS_RO_TYPE(mdt, hash);
++LPROC_SEQ_FOPS_WO_TYPE(mdt, mds_evict_client);
++LPROC_SEQ_FOPS_RW_TYPE(mdt, job_interval);
++LPROC_SEQ_FOPS_RW_TYPE(mdt, ir_factor);
++LPROC_SEQ_FOPS_RW_TYPE(mdt, nid_stats_clear);
++LPROC_SEQ_FOPS(mdt_hsm_cdt_control);
++
++static struct lprocfs_seq_vars lprocfs_mdt_obd_vars[] = {
++ { "uuid", &mdt_uuid_fops },
++ { "recovery_status", &mdt_recovery_status_fops },
++ { "num_exports", &mdt_num_exports_fops },
++ { "identity_expire", &mdt_identity_expire_fops },
++ { "identity_acquire_expire", &mdt_identity_acquire_expire_fops },
++ { "identity_upcall", &mdt_identity_upcall_fops },
++ { "identity_flush", &mdt_identity_flush_fops },
++ { "identity_info", &mdt_identity_info_fops },
++ { "capa", &mdt_capa_fops },
++ { "capa_timeout", &mdt_capa_timeout_fops },
++ { "capa_key_timeout", &mdt_ck_timeout_fops },
++ { "capa_count", &mdt_capa_count_fops },
++ { "site_stats", &mdt_site_stats_fops },
++ { "evict_client", &mdt_mds_evict_client_fops },
++ { "hash_stats", &mdt_hash_fops },
++ { "sec_level", &mdt_sec_level_fops },
++ { "commit_on_sharing", &mdt_cos_fops },
++ { "root_squash", &mdt_root_squash_fops },
++ { "nosquash_nids", &mdt_nosquash_nids_fops },
++ { "som", &mdt_som_fops },
++ { "instance", &mdt_target_instance_fops },
++ { "ir_factor", &mdt_ir_factor_fops },
++ { "job_cleanup_interval", &mdt_job_interval_fops },
++ { "enable_remote_dir", &mdt_enable_remote_dir_fops },
++ { "enable_remote_dir_gid", &mdt_enable_remote_dir_gid_fops },
++ { "hsm_control", &mdt_hsm_cdt_control_fops },
+ { 0 }
+ };
+
+@@ -1087,3 +978,67 @@ void mdt_stats_counter_init(struct lprocfs_stats *stats)
+ lprocfs_counter_init(stats, LPROC_MDT_CROSSDIR_RENAME, 0,
+ "crossdir_rename", "reqs");
+ }
++
++int mdt_procfs_init(struct mdt_device *mdt, const char *name)
++{
++ struct obd_device *obd = mdt2obd_dev(mdt);
++ int rc;
++ ENTRY;
++
++ LASSERT(name != NULL);
++
++ obd->obd_vars = lprocfs_mdt_obd_vars;
++ rc = lprocfs_seq_obd_setup(obd);
++ if (rc) {
++ CERROR("%s: cannot create proc entries: rc = %d\n",
++ mdt_obd_name(mdt), rc);
++ return rc;
++ }
++
++ rc = hsm_cdt_procfs_init(mdt);
++ if (rc) {
++ CERROR("%s: cannot create hsm proc entries: rc = %d\n",
++ mdt_obd_name(mdt), rc);
++ return rc;
++ }
++
++ obd->obd_proc_exports_entry = proc_mkdir("exports",
++ obd->obd_proc_entry);
++ if (obd->obd_proc_exports_entry)
++ lprocfs_add_simple(obd->obd_proc_exports_entry, "clear",
++#ifndef HAVE_ONLY_PROCFS_SEQ
++ NULL, NULL,
++#endif
++ obd, &mdt_nid_stats_clear_fops);
++ rc = lprocfs_alloc_md_stats(obd, LPROC_MDT_LAST);
++ if (rc)
++ return rc;
++ mdt_stats_counter_init(obd->obd_md_stats);
++
++ rc = lprocfs_job_stats_init(obd, LPROC_MDT_LAST,
++ mdt_stats_counter_init);
++
++ rc = lproc_mdt_attach_rename_seqstat(mdt);
++ if (rc)
++ CERROR("%s: MDT can not create rename stats rc = %d\n",
++ mdt_obd_name(mdt), rc);
++
++ RETURN(rc);
++}
++
++void mdt_procfs_fini(struct mdt_device *mdt)
++{
++ struct obd_device *obd = mdt2obd_dev(mdt);
++
++ if (obd->obd_proc_exports_entry != NULL) {
++ lprocfs_remove_proc_entry("clear", obd->obd_proc_exports_entry);
++ obd->obd_proc_exports_entry = NULL;
++ }
++
++ lprocfs_free_per_client_stats(obd);
++ hsm_cdt_procfs_fini(mdt);
++ lprocfs_obd_cleanup(obd);
++ lprocfs_free_md_stats(obd);
++ lprocfs_free_obd_stats(obd);
++ lprocfs_job_stats_fini(obd);
++}
+diff --git a/lustre/mdt/mdt_mds.c b/lustre/mdt/mdt_mds.c
+index 367f659..4fa66c3 100644
+--- a/lustre/mdt/mdt_mds.c
++++ b/lustre/mdt/mdt_mds.c
+@@ -464,6 +464,13 @@ static struct lu_device *mds_device_free(const struct lu_env *env,
+ RETURN(NULL);
+ }
+
++LPROC_SEQ_FOPS_RO_TYPE(mds, uuid);
++
++static struct lprocfs_seq_vars lprocfs_mds_obd_vars[] = {
++ { "uuid", &mds_uuid_fops },
++ { 0 }
++};
++
+ static struct lu_device *mds_device_alloc(const struct lu_env *env,
+ struct lu_device_type *t,
+ struct lustre_cfg *cfg)
+@@ -487,7 +494,8 @@ static struct lu_device *mds_device_alloc(const struct lu_env *env,
+ /* set this lu_device to obd, because error handling need it */
+ obd->obd_lu_dev = l;
+
+- rc = lprocfs_obd_setup(obd, lprocfs_mds_obd_vars);
++ obd->obd_vars = lprocfs_mds_obd_vars;
++ rc = lprocfs_seq_obd_setup(obd);
+ if (rc != 0) {
+ mds_device_free(env, l);
+ l = ERR_PTR(rc);
+@@ -541,7 +549,7 @@ int mds_mod_init(void)
+
+ return class_register_type(&mds_obd_device_ops, NULL, NULL,
+ #ifndef HAVE_ONLY_PROCFS_SEQ
+- lprocfs_mds_module_vars,
++ NULL,
+ #endif
+ LUSTRE_MDS_NAME, &mds_device_type);
+ }
+--
+1.8.5.1
+
diff --git a/sys-cluster/lustre/files/0017-LU-3319-procfs-move-mdd-proc-handling-to-seq_files.patch b/sys-cluster/lustre/files/0017-LU-3319-procfs-move-mdd-proc-handling-to-seq_files.patch
new file mode 100644
index 000000000..0d1004751
--- /dev/null
+++ b/sys-cluster/lustre/files/0017-LU-3319-procfs-move-mdd-proc-handling-to-seq_files.patch
@@ -0,0 +1,788 @@
+From df4a9172881e4eac4f7ef511079c2f306d515bf7 Mon Sep 17 00:00:00 2001
+From: James Simmons <uja.ornl@gmail.com>
+Date: Mon, 2 Dec 2013 12:40:35 -0500
+Subject: [PATCH 17/18] LU-3319 procfs: move mdd 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
+layer proc entries over to using seq_files.
+
+Signed-off-by: James Simmons <uja.ornl@gmail.com>
+Change-Id: I61b7df6bfd5efd0f12e3ca1a1813b7b62d493168
+---
+ lustre/include/lustre_lfsck.h | 4 +-
+ lustre/lfsck/lfsck_internal.h | 9 +-
+ lustre/lfsck/lfsck_lib.c | 68 ++++-------
+ lustre/lfsck/lfsck_namespace.c | 61 +++-------
+ lustre/mdd/mdd_device.c | 25 ++--
+ lustre/mdd/mdd_internal.h | 1 -
+ lustre/mdd/mdd_lproc.c | 259 +++++++++++++++++------------------------
+ 7 files changed, 162 insertions(+), 265 deletions(-)
+
+diff --git a/lustre/include/lustre_lfsck.h b/lustre/include/lustre_lfsck.h
+index f75d507..e491933 100644
+--- a/lustre/include/lustre_lfsck.h
++++ b/lustre/include/lustre_lfsck.h
+@@ -52,9 +52,9 @@ int lfsck_start(const struct lu_env *env, struct dt_device *key,
+ int lfsck_stop(const struct lu_env *env, struct dt_device *key,
+ bool pause);
+
+-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_dump(struct dt_device *key, void *buf, int len, __u16 type);
++int lfsck_dump(struct seq_file *m, struct dt_device *key, __u16 type);
+
+ #endif /* _LUSTRE_LFSCK_H */
+diff --git a/lustre/lfsck/lfsck_internal.h b/lustre/lfsck/lfsck_internal.h
+index 56cdff0..50eb341 100644
+--- a/lustre/lfsck/lfsck_internal.h
++++ b/lustre/lfsck/lfsck_internal.h
+@@ -229,8 +229,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);
+@@ -361,10 +360,10 @@ struct lfsck_thread_info {
+ /* lfsck_lib.c */
+ void lfsck_component_cleanup(const struct lu_env *env,
+ struct lfsck_component *com);
+-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_lib.c b/lustre/lfsck/lfsck_lib.c
+index 0da2614..da68358 100644
+--- a/lustre/lfsck/lfsck_lib.c
++++ b/lustre/lfsck/lfsck_lib.c
+@@ -258,75 +258,49 @@ 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;
+
+- rc = snprintf(*buf, *len, "%s:%c", prefix, bits != 0 ? ' ' : '\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;
+- rc = snprintf(*buf, *len, "%s%c", names[i],
++ seq_printf(m, "%s%c", names[i],
+ bits != 0 ? ',' : '\n');
+- if (rc <= 0)
+- return -ENOSPC;
+-
+- *buf += rc;
+- *len -= rc;
+ }
+ }
+- return save - *len;
++ 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,
+@@ -765,7 +739,7 @@ int lfsck_double_scan(const struct lu_env *env, struct lfsck_instance *lfsck)
+
+ /* 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;
+@@ -780,7 +754,7 @@ int lfsck_get_speed(struct dt_device *key, void *buf, int len)
+ if (rc != 0)
+ GOTO(out, rc);
+
+- 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);
+ lu_env_fini(&env);
+
+ GOTO(out, rc);
+@@ -820,7 +794,7 @@ out:
+ }
+ EXPORT_SYMBOL(lfsck_set_speed);
+
+-int lfsck_dump(struct dt_device *key, void *buf, int len, __u16 type)
++int lfsck_dump(struct seq_file *m, struct dt_device *key, __u16 type)
+ {
+ struct lu_env env;
+ struct lfsck_instance *lfsck;
+@@ -840,7 +814,7 @@ int lfsck_dump(struct dt_device *key, void *buf, int len, __u16 type)
+ if (rc != 0)
+ GOTO(out, rc);
+
+- rc = com->lc_ops->lfsck_dump(&env, com, buf, len);
++ rc = com->lc_ops->lfsck_dump(&env, com, m);
+ lu_env_fini(&env);
+
+ GOTO(out, rc);
+diff --git a/lustre/lfsck/lfsck_namespace.c b/lustre/lfsck/lfsck_namespace.c
+index 3cc043d..225351f 100644
+--- a/lustre/lfsck/lfsck_namespace.c
++++ b/lustre/lfsck/lfsck_namespace.c
+@@ -1092,66 +1092,57 @@ 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 =
+ (struct lfsck_namespace *)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"
++ seq_printf(m, "name: lfsck_namespace\n"
+ "magic: 0x%x\n"
+ "version: %d\n"
+ "status: %s\n",
+ ns->ln_magic,
+ bk->lb_version,
+ lfsck_status_names[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");
++ 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;
+@@ -1171,8 +1162,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"
+@@ -1204,11 +1194,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);
+
+@@ -1237,9 +1222,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;
+@@ -1257,8 +1240,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"
+@@ -1293,11 +1275,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;
+@@ -1306,8 +1283,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"
+@@ -1340,17 +1316,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(const struct lu_env *env,
+diff --git a/lustre/mdd/mdd_device.c b/lustre/mdd/mdd_device.c
+index 750281a..ee82f71 100644
+--- a/lustre/mdd/mdd_device.c
++++ b/lustre/mdd/mdd_device.c
+@@ -812,16 +812,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)
+@@ -1492,11 +1492,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;
+@@ -1512,7 +1509,7 @@ static int __init mdd_mod_init(void)
+
+ rc = class_register_type(&mdd_obd_device_ops, NULL, 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 daa1dcb..5332b2c 100644
+--- a/lustre/mdd/mdd_internal.h
++++ b/lustre/mdd/mdd_internal.h
+@@ -340,7 +340,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 bd23302..6ddacf7 100644
+--- a/lustre/mdd/mdd_lproc.c
++++ b/lustre/mdd/mdd_lproc.c
+@@ -49,56 +49,13 @@
+ #include <libcfs/libcfs_string.h>
+ #include "mdd_internal.h"
+
+-int mdd_procfs_init(struct mdd_device *mdd, const char *name)
++static ssize_t
++mdd_atime_diff_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- 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)
+-{
+- struct mdd_device *mdd = data;
+- char kernbuf[20], *end;
+- unsigned long diff = 0;
++ struct mdd_device *mdd = ((struct seq_file *)file->private_data)->private;
++ char kernbuf[20], *end;
++ unsigned long diff = 0;
+
+ if (count > (sizeof(kernbuf) - 1))
+ return -EINVAL;
+@@ -116,37 +73,34 @@ 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 mdd_device *mdd = ((struct seq_file *)file->private_data)->private;
+ char *kernbuf;
+ int rc;
+ ENTRY;
+@@ -168,45 +122,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;
+-
+- LASSERT(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN);
++ struct llog_changelog_user_rec *rec;
++ struct seq_file *m = data;
+
+- rec = (struct llog_changelog_user_rec *)hdr;
++ LASSERT(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN);
+
+- 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;
++ rec = (struct llog_changelog_user_rec *)hdr;
+
+- 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 +164,31 @@ 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 mdd_device *mdd = ((struct seq_file *)file->private_data)->private;
+ int val, rc;
+
+ LASSERT(mdd != NULL);
+@@ -264,24 +199,21 @@ 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;
+- int rc;
++ struct mdd_device *mdd = m->private;
+
+ LASSERT(mdd != NULL);
+- *eof = 1;
+-
+- rc = lfsck_get_speed(mdd->mdd_bottom, page, count);
+- return rc != 0 ? rc : 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 mdd_device *mdd = ((struct seq_file *)file->private_data)->private;
+ __u32 val;
+ int rc;
+
+@@ -293,40 +225,67 @@ 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_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);
+ }
+-
+-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_namespace", lprocfs_rd_lfsck_namespace, 0, 0 },
++LPROC_SEQ_FOPS_RO(mdd_lfsck_namespace);
++
++static struct lprocfs_seq_vars lprocfs_mdd_obd_vars[] = {
++ { "atime_diff", &mdd_atime_diff_fops },
++ { "changelog_mask", &mdd_changelog_mask_fops },
++ { "changelog_users", &mdd_changelog_users_fops },
++ { "sync_permission", &mdd_sync_perm_fops },
++ { "lfsck_speed_limit", &mdd_lfsck_speed_limit_fops },
++ { "lfsck_namespace", &mdd_lfsck_namespace_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);
++}
+--
+1.8.5.1
+
diff --git a/sys-cluster/lustre/files/0018-LU-3319-procfs-update-ldiskfs-proc-handling-to-seq_f.patch b/sys-cluster/lustre/files/0018-LU-3319-procfs-update-ldiskfs-proc-handling-to-seq_f.patch
new file mode 100644
index 000000000..9d9976a97
--- /dev/null
+++ b/sys-cluster/lustre/files/0018-LU-3319-procfs-update-ldiskfs-proc-handling-to-seq_f.patch
@@ -0,0 +1,748 @@
+From 92589047bca132101a9106f018b2ed9ad1efdfd0 Mon Sep 17 00:00:00 2001
+From: James Simmons <uja.ornl@gmail.com>
+Date: Thu, 14 Nov 2013 19:41:12 -0500
+Subject: [PATCH 18/18] LU-3319 procfs: update ldiskfs proc handling to
+ seq_files
+
+Migrate all ldiskfs proc handling to using strictly
+seq_files.
+
+Signed-off-by: James Simmons <uja.ornl@gmail.com>
+Change-Id: Ia296a4682e2feda02bcfbe0100de8a89404cd731
+---
+ lustre/osd-ldiskfs/osd_handler.c | 7 +-
+ lustre/osd-ldiskfs/osd_internal.h | 6 +-
+ lustre/osd-ldiskfs/osd_lproc.c | 321 +++++++++++++++++++-------------------
+ lustre/osd-ldiskfs/osd_scrub.c | 73 +++------
+ 4 files changed, 192 insertions(+), 215 deletions(-)
+
+diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c
+index c13c682..7f8748d 100644
+--- a/lustre/osd-ldiskfs/osd_handler.c
++++ b/lustre/osd-ldiskfs/osd_handler.c
+@@ -5820,19 +5820,18 @@ static struct obd_ops osd_obd_device_ops = {
+
+ static int __init osd_mod_init(void)
+ {
+- struct lprocfs_static_vars lvars;
+ int rc;
+
+ osd_oi_mod_init();
+- lprocfs_osd_init_vars(&lvars);
+
+ rc = lu_kmem_init(ldiskfs_caches);
+ if (rc)
+ return rc;
+
+- rc = class_register_type(&osd_obd_device_ops, NULL, NULL,
++ rc = class_register_type(&osd_obd_device_ops, NULL,
++ lprocfs_osd_module_vars,
+ #ifndef HAVE_ONLY_PROCFS_SEQ
+- lvars.module_vars,
++ NULL,
+ #endif
+ LUSTRE_OSD_LDISKFS_NAME, &osd_device_type);
+ if (rc)
+diff --git a/lustre/osd-ldiskfs/osd_internal.h b/lustre/osd-ldiskfs/osd_internal.h
+index 8d5ca40..35d1b10 100644
+--- a/lustre/osd-ldiskfs/osd_internal.h
++++ b/lustre/osd-ldiskfs/osd_internal.h
+@@ -623,11 +623,11 @@ static inline int __osd_xattr_set(struct osd_thread_info *info,
+
+ #ifdef LPROCFS
+ /* osd_lproc.c */
+-void lprocfs_osd_init_vars(struct lprocfs_static_vars *lvars);
++extern struct lprocfs_seq_vars lprocfs_osd_module_vars[];
++
+ int osd_procfs_init(struct osd_device *osd, const char *name);
+ int osd_procfs_fini(struct osd_device *osd);
+ void osd_brw_stats_update(struct osd_device *osd, struct osd_iobuf *iobuf);
+-
+ #endif
+ int osd_statfs(const struct lu_env *env, struct dt_device *dev,
+ struct obd_statfs *sfs);
+@@ -678,7 +678,7 @@ int osd_oii_insert(struct osd_device *dev, struct osd_idmap_cache *oic,
+ int insert);
+ int osd_oii_lookup(struct osd_device *dev, const struct lu_fid *fid,
+ struct osd_inode_id *id);
+-int osd_scrub_dump(struct osd_device *dev, char *buf, int len);
++int osd_scrub_dump(struct seq_file *m, struct osd_device *dev);
+
+ int osd_fld_lookup(const struct lu_env *env, struct osd_device *osd,
+ obd_seq seq, struct lu_seq_range *range);
+diff --git a/lustre/osd-ldiskfs/osd_lproc.c b/lustre/osd-ldiskfs/osd_lproc.c
+index 83bb586..528f60e 100644
+--- a/lustre/osd-ldiskfs/osd_lproc.c
++++ b/lustre/osd-ldiskfs/osd_lproc.c
+@@ -237,93 +237,45 @@ out:
+ RETURN(result);
+ }
+
+-int osd_procfs_init(struct osd_device *osd, 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_OSD_LDISKFS_NAME);
+-
+- LASSERT(name != NULL);
+- LASSERT(type != NULL);
+-
+- /* Find the type procroot and add the proc entry for this device */
+- lprocfs_osd_init_vars(&lvars);
+- osd->od_proc_entry = lprocfs_register(name, type->typ_procroot,
+- lvars.obd_vars, &osd->od_dt_dev);
+- if (IS_ERR(osd->od_proc_entry)) {
+- rc = PTR_ERR(osd->od_proc_entry);
+- CERROR("Error %d setting up lprocfs for %s\n",
+- rc, name);
+- osd->od_proc_entry = NULL;
+- GOTO(out, rc);
+- }
+-
+- rc = osd_stats_init(osd);
+-
+- EXIT;
+-out:
+- if (rc)
+- osd_procfs_fini(osd);
+- return rc;
+-}
+-
+-int osd_procfs_fini(struct osd_device *osd)
+-{
+- if (osd->od_stats)
+- lprocfs_free_stats(&osd->od_stats);
+-
+- if (osd->od_proc_entry) {
+- lprocfs_remove(&osd->od_proc_entry);
+- osd->od_proc_entry = NULL;
+- }
+- RETURN(0);
+-}
+-
+-static int lprocfs_osd_rd_fstype(char *page, char **start, off_t off, int count,
+- int *eof, void *data)
++static int ldiskfs_osd_fstype_seq_show(struct seq_file *m, void *data)
+ {
+- struct osd_device *osd = osd_dt_dev(data);
++ struct osd_device *osd = osd_dt_dev((struct dt_device *)m->private);
+
+- LASSERT(osd != NULL);
+- return snprintf(page, count, "ldiskfs\n");
++ LASSERT(osd != NULL);
++ return seq_printf(m, "ldiskfs\n");
+ }
++LPROC_SEQ_FOPS_RO(ldiskfs_osd_fstype);
+
+-static int lprocfs_osd_rd_mntdev(char *page, char **start, off_t off, int count,
+- int *eof, void *data)
++static int ldiskfs_osd_mntdev_seq_show(struct seq_file *m, void *data)
+ {
+- struct osd_device *osd = osd_dt_dev(data);
++ struct osd_device *osd = osd_dt_dev((struct dt_device *)m->private);
+
+- LASSERT(osd != NULL);
++ LASSERT(osd != NULL);
+ if (unlikely(osd->od_mnt == NULL))
+- return -EINPROGRESS;
+-
+- *eof = 1;
++ return -EINPROGRESS;
+
+- return snprintf(page, count, "%s\n", osd->od_mntdev);
++ return seq_printf(m, "%s\n", osd->od_mntdev);
+ }
++LPROC_SEQ_FOPS_RO(ldiskfs_osd_mntdev);
+
+-static int lprocfs_osd_rd_cache(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int ldiskfs_osd_cache_seq_show(struct seq_file *m, void *data)
+ {
+- struct osd_device *osd = osd_dt_dev(data);
++ struct osd_device *osd = osd_dt_dev((struct dt_device *)m->private);
+
+ LASSERT(osd != NULL);
+ if (unlikely(osd->od_mnt == NULL))
+ return -EINPROGRESS;
+
+- return snprintf(page, count, "%u\n", osd->od_read_cache);
++ return seq_printf(m, "%u\n", osd->od_read_cache);
+ }
+
+-static int lprocfs_osd_wr_cache(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++ldiskfs_osd_cache_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct osd_device *osd = osd_dt_dev(data);
+- int val, rc;
++ struct dt_device *dt = ((struct seq_file *)file->private_data)->private;
++ struct osd_device *osd = osd_dt_dev(dt);
++ int val, rc;
+
+ LASSERT(osd != NULL);
+ if (unlikely(osd->od_mnt == NULL))
+@@ -336,24 +288,26 @@ static int lprocfs_osd_wr_cache(struct file *file, const char *buffer,
+ osd->od_read_cache = !!val;
+ return count;
+ }
++LPROC_SEQ_FOPS(ldiskfs_osd_cache);
+
+-static int lprocfs_osd_rd_wcache(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int ldiskfs_osd_wcache_seq_show(struct seq_file *m, void *data)
+ {
+- struct osd_device *osd = osd_dt_dev(data);
++ struct osd_device *osd = osd_dt_dev((struct dt_device *)m->private);
+
+ LASSERT(osd != NULL);
+ if (unlikely(osd->od_mnt == NULL))
+ return -EINPROGRESS;
+
+- return snprintf(page, count, "%u\n", osd->od_writethrough_cache);
++ return seq_printf(m, "%u\n", osd->od_writethrough_cache);
+ }
+
+-static int lprocfs_osd_wr_wcache(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++ldiskfs_osd_wcache_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct osd_device *osd = osd_dt_dev(data);
+- int val, rc;
++ struct dt_device *dt = ((struct seq_file *)file->private_data)->private;
++ struct osd_device *osd = osd_dt_dev(dt);
++ int val, rc;
+
+ LASSERT(osd != NULL);
+ if (unlikely(osd->od_mnt == NULL))
+@@ -366,14 +320,16 @@ static int lprocfs_osd_wr_wcache(struct file *file, const char *buffer,
+ osd->od_writethrough_cache = !!val;
+ return count;
+ }
++LPROC_SEQ_FOPS(ldiskfs_osd_wcache);
+
+-static int lprocfs_osd_wr_force_sync(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++lprocfs_osd_force_sync_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct osd_device *osd = osd_dt_dev(data);
+- struct dt_device *dt = data;
+- struct lu_env env;
+- int rc;
++ struct dt_device *dt = ((struct seq_file *)file->private_data)->private;
++ struct osd_device *osd = osd_dt_dev(dt);
++ struct lu_env env;
++ int rc;
+
+ LASSERT(osd != NULL);
+ if (unlikely(osd->od_mnt == NULL))
+@@ -387,20 +343,18 @@ static int lprocfs_osd_wr_force_sync(struct file *file, const char *buffer,
+
+ return rc == 0 ? count : rc;
+ }
++LPROC_SEQ_FOPS_WO_TYPE(ldiskfs, osd_force_sync);
+
+-static int lprocfs_osd_rd_pdo(char *page, char **start, off_t off, int count,
+- int *eof, void *data)
++static int ldiskfs_osd_pdo_seq_show(struct seq_file *m, void *data)
+ {
+- *eof = 1;
+-
+- return snprintf(page, count, "%s\n", ldiskfs_pdo ? "ON" : "OFF");
++ return seq_printf(m, "%s\n", ldiskfs_pdo ? "ON" : "OFF");
+ }
+
+-static int lprocfs_osd_wr_pdo(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++ldiskfs_osd_pdo_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- int pdo;
+- int rc;
++ int pdo, rc;
+
+ rc = lprocfs_write_helper(buffer, count, &pdo);
+ if (rc != 0)
+@@ -410,24 +364,25 @@ static int lprocfs_osd_wr_pdo(struct file *file, const char *buffer,
+
+ return count;
+ }
++LPROC_SEQ_FOPS(ldiskfs_osd_pdo);
+
+-static int lprocfs_osd_rd_auto_scrub(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int ldiskfs_osd_auto_scrub_seq_show(struct seq_file *m, void *data)
+ {
+- struct osd_device *dev = osd_dt_dev(data);
++ struct osd_device *dev = osd_dt_dev((struct dt_device *)m->private);
+
+ LASSERT(dev != NULL);
+ if (unlikely(dev->od_mnt == NULL))
+ return -EINPROGRESS;
+
+- *eof = 1;
+- return snprintf(page, count, "%d\n", !dev->od_noscrub);
++ return seq_printf(m, "%d\n", !dev->od_noscrub);
+ }
+
+-static int lprocfs_osd_wr_auto_scrub(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++ldiskfs_osd_auto_scrub_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct osd_device *dev = osd_dt_dev(data);
++ struct dt_device *dt = ((struct seq_file *)file->private_data)->private;
++ struct osd_device *dev = osd_dt_dev(dt);
+ int val, rc;
+
+ LASSERT(dev != NULL);
+@@ -441,19 +396,18 @@ static int lprocfs_osd_wr_auto_scrub(struct file *file, const char *buffer,
+ dev->od_noscrub = !val;
+ return count;
+ }
++LPROC_SEQ_FOPS(ldiskfs_osd_auto_scrub);
+
+-static int lprocfs_osd_rd_track_declares_assert(char *page, char **start,
+- off_t off, int count,
+- int *eof, void *data)
++static int
++ldiskfs_osd_track_declares_assert_seq_show(struct seq_file *m, void *data)
+ {
+- *eof = 1;
+-
+- return snprintf(page, count, "%d\n", ldiskfs_track_declares_assert);
++ return seq_printf(m, "%d\n", ldiskfs_track_declares_assert);
+ }
+
+-static int lprocfs_osd_wr_track_declares_assert(struct file *file,
++static ssize_t
++ldiskfs_osd_track_declares_assert_seq_write(struct file *file,
+ const char *buffer,
+- unsigned long count, void *data)
++ size_t count, loff_t *off)
+ {
+ int track_declares_assert;
+ int rc;
+@@ -466,38 +420,39 @@ static int lprocfs_osd_wr_track_declares_assert(struct file *file,
+
+ return count;
+ }
++LPROC_SEQ_FOPS(ldiskfs_osd_track_declares_assert);
++
++extern int osd_scrub_dump(struct seq_file *m, struct osd_device *dev);
+
+-static int lprocfs_osd_rd_oi_scrub(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int ldiskfs_osd_oi_scrub_seq_show(struct seq_file *m, void *data)
+ {
+- struct osd_device *dev = osd_dt_dev(data);
++ struct osd_device *dev = osd_dt_dev((struct dt_device *)m->private);
+
+ LASSERT(dev != NULL);
+ if (unlikely(dev->od_mnt == NULL))
+ return -EINPROGRESS;
+
+- *eof = 1;
+- return osd_scrub_dump(dev, page, count);
++ return osd_scrub_dump(m, dev);
+ }
++LPROC_SEQ_FOPS_RO(ldiskfs_osd_oi_scrub);
+
+-int lprocfs_osd_rd_readcache(char *page, char **start, off_t off, int count,
+- int *eof, void *data)
++int ldiskfs_osd_readcache_seq_show(struct seq_file *m, void *data)
+ {
+- struct osd_device *osd = osd_dt_dev(data);
+- int rc;
++ struct osd_device *osd = osd_dt_dev((struct dt_device *)m->private);
+
+ LASSERT(osd != NULL);
+ if (unlikely(osd->od_mnt == NULL))
+ return -EINPROGRESS;
+
+- rc = snprintf(page, count, LPU64"\n", osd->od_readcache_max_filesize);
+- return rc;
++ return seq_printf(m, LPU64"\n", osd->od_readcache_max_filesize);
+ }
+
+-int lprocfs_osd_wr_readcache(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++ssize_t
++ldiskfs_osd_readcache_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct osd_device *osd = osd_dt_dev(data);
++ struct dt_device *dt = ((struct seq_file *)file->private_data)->private;
++ struct osd_device *osd = osd_dt_dev(dt);
+ __u64 val;
+ int rc;
+
+@@ -513,24 +468,25 @@ int lprocfs_osd_wr_readcache(struct file *file, const char *buffer,
+ OSD_MAX_CACHE_SIZE : val;
+ return count;
+ }
++LPROC_SEQ_FOPS(ldiskfs_osd_readcache);
+
+-static int lprocfs_osd_rd_lma_self_repair(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int ldiskfs_osd_lma_self_repair_seq_show(struct seq_file *m, void *data)
+ {
+- struct osd_device *dev = osd_dt_dev(data);
++ struct osd_device *dev = osd_dt_dev((struct dt_device *)m->private);
+
+ LASSERT(dev != NULL);
+ if (unlikely(dev->od_mnt == NULL))
+ return -EINPROGRESS;
+
+- *eof = 1;
+- return snprintf(page, count, "%d\n", !!dev->od_lma_self_repair);
++ return seq_printf(m, "%d\n", !!dev->od_lma_self_repair);
+ }
+
+-static int lprocfs_osd_wr_lma_self_repair(struct file *file, const char *buffer,
+- unsigned long count, void *data)
++static ssize_t
++ldiskfs_osd_lma_self_repair_seq_write(struct file *file, const char *buffer,
++ size_t count, loff_t *off)
+ {
+- struct osd_device *dev = osd_dt_dev(data);
++ struct dt_device *dt = ((struct seq_file *)file->private_data)->private;
++ struct osd_device *dev = osd_dt_dev(dt);
+ int val;
+ int rc;
+
+@@ -545,43 +501,86 @@ static int lprocfs_osd_wr_lma_self_repair(struct file *file, const char *buffer,
+ dev->od_lma_self_repair = !!val;
+ return count;
+ }
+-
+-struct lprocfs_vars lprocfs_osd_obd_vars[] = {
+- { "blocksize", lprocfs_dt_rd_blksize, 0, 0 },
+- { "kbytestotal", lprocfs_dt_rd_kbytestotal, 0, 0 },
+- { "kbytesfree", lprocfs_dt_rd_kbytesfree, 0, 0 },
+- { "kbytesavail", lprocfs_dt_rd_kbytesavail, 0, 0 },
+- { "filestotal", lprocfs_dt_rd_filestotal, 0, 0 },
+- { "filesfree", lprocfs_dt_rd_filesfree, 0, 0 },
+- { "fstype", lprocfs_osd_rd_fstype, 0, 0 },
+- { "mntdev", lprocfs_osd_rd_mntdev, 0, 0 },
+- { "force_sync", 0, lprocfs_osd_wr_force_sync },
+- { "pdo", lprocfs_osd_rd_pdo, lprocfs_osd_wr_pdo, 0 },
+- { "auto_scrub", lprocfs_osd_rd_auto_scrub,
+- lprocfs_osd_wr_auto_scrub, 0 },
+- { "oi_scrub", lprocfs_osd_rd_oi_scrub, 0, 0 },
+- { "force_sync", 0, lprocfs_osd_wr_force_sync },
+- { "read_cache_enable", lprocfs_osd_rd_cache, lprocfs_osd_wr_cache, 0 },
+- { "writethrough_cache_enable", lprocfs_osd_rd_wcache,
+- lprocfs_osd_wr_wcache, 0 },
+- { "readcache_max_filesize", lprocfs_osd_rd_readcache,
+- lprocfs_osd_wr_readcache, 0 },
+- { "lma_self_repair", lprocfs_osd_rd_lma_self_repair,
+- lprocfs_osd_wr_lma_self_repair, 0, 0 },
++LPROC_SEQ_FOPS(ldiskfs_osd_lma_self_repair);
++
++LPROC_SEQ_FOPS_RO_TYPE(ldiskfs, dt_blksize);
++LPROC_SEQ_FOPS_RO_TYPE(ldiskfs, dt_kbytestotal);
++LPROC_SEQ_FOPS_RO_TYPE(ldiskfs, dt_kbytesfree);
++LPROC_SEQ_FOPS_RO_TYPE(ldiskfs, dt_kbytesavail);
++LPROC_SEQ_FOPS_RO_TYPE(ldiskfs, dt_filestotal);
++LPROC_SEQ_FOPS_RO_TYPE(ldiskfs, dt_filesfree);
++
++static struct lprocfs_seq_vars lprocfs_osd_obd_vars[] = {
++ { "blocksize", &ldiskfs_dt_blksize_fops },
++ { "kbytestotal", &ldiskfs_dt_kbytestotal_fops },
++ { "kbytesfree", &ldiskfs_dt_kbytesfree_fops },
++ { "kbytesavail", &ldiskfs_dt_kbytesavail_fops },
++ { "filestotal", &ldiskfs_dt_filestotal_fops },
++ { "filesfree", &ldiskfs_dt_filesfree_fops },
++ { "fstype", &ldiskfs_osd_fstype_fops },
++ { "mntdev", &ldiskfs_osd_mntdev_fops },
++ { "force_sync", &ldiskfs_osd_force_sync_fops },
++ { "pdo", &ldiskfs_osd_pdo_fops },
++ { "auto_scrub", &ldiskfs_osd_auto_scrub_fops },
++ { "oi_scrub", &ldiskfs_osd_oi_scrub_fops },
++ { "read_cache_enable", &ldiskfs_osd_cache_fops },
++ { "writethrough_cache_enable", &ldiskfs_osd_wcache_fops },
++ { "readcache_max_filesize", &ldiskfs_osd_readcache_fops },
++ { "lma_self_repair", &ldiskfs_osd_lma_self_repair_fops },
+ { 0 }
+ };
+
+-struct lprocfs_vars lprocfs_osd_module_vars[] = {
+- { "num_refs", lprocfs_rd_numrefs, 0, 0 },
+- { "track_declares_assert", lprocfs_osd_rd_track_declares_assert,
+- lprocfs_osd_wr_track_declares_assert,
+- 0 },
+- { 0 }
++struct lprocfs_seq_vars lprocfs_osd_module_vars[] = {
++ { "track_declares_assert", &ldiskfs_osd_track_declares_assert_fops },
++ { 0 }
+ };
+
+-void lprocfs_osd_init_vars(struct lprocfs_static_vars *lvars)
++int osd_procfs_init(struct osd_device *osd, const char *name)
++{
++ struct obd_type *type;
++ int rc;
++ ENTRY;
++
++ if (osd->od_proc_entry)
++ RETURN(0);
++
++ /* 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_OSD_LDISKFS_NAME);
++
++ LASSERT(name != NULL);
++ LASSERT(type != NULL);
++
++ /* Find the type procroot and add the proc entry for this device */
++ osd->od_proc_entry = lprocfs_seq_register(name, type->typ_procroot,
++ lprocfs_osd_obd_vars,
++ &osd->od_dt_dev);
++ if (IS_ERR(osd->od_proc_entry)) {
++ rc = PTR_ERR(osd->od_proc_entry);
++ CERROR("Error %d setting up lprocfs for %s\n",
++ rc, name);
++ osd->od_proc_entry = NULL;
++ GOTO(out, rc);
++ }
++
++ rc = osd_stats_init(osd);
++
++ EXIT;
++out:
++ if (rc)
++ osd_procfs_fini(osd);
++ return rc;
++}
++
++int osd_procfs_fini(struct osd_device *osd)
+ {
+- lvars->module_vars = lprocfs_osd_module_vars;
+- lvars->obd_vars = lprocfs_osd_obd_vars;
++ if (osd->od_stats)
++ lprocfs_free_stats(&osd->od_stats);
++
++ if (osd->od_proc_entry) {
++ lprocfs_remove(&osd->od_proc_entry);
++ osd->od_proc_entry = NULL;
++ }
++ RETURN(0);
+ }
+ #endif
+diff --git a/lustre/osd-ldiskfs/osd_scrub.c b/lustre/osd-ldiskfs/osd_scrub.c
+index 18a0a2a..38f5d29 100644
+--- a/lustre/osd-ldiskfs/osd_scrub.c
++++ b/lustre/osd-ldiskfs/osd_scrub.c
+@@ -2508,80 +2508,69 @@ static const char *scrub_param_names[] = {
+ NULL
+ };
+
+-static int scrub_bits_dump(char **buf, int *len, int bits, const char *names[],
++static int scrub_bits_dump(struct seq_file *m, int bits, const char *names[],
+ const char *prefix)
+ {
+- int save = *len;
+ int flag;
+ int rc;
+ int i;
+
+- rc = snprintf(*buf, *len, "%s:%c", prefix, bits != 0 ? ' ' : '\n');
++ rc = seq_printf(m, "%s:%c", prefix, bits != 0 ? ' ' : '\n');
+ if (rc <= 0)
+ return -ENOSPC;
+
+- *buf += rc;
+- *len -= rc;
+ for (i = 0, flag = 1; bits != 0; i++, flag = 1 << i) {
+ if (flag & bits) {
+ bits &= ~flag;
+- rc = snprintf(*buf, *len, "%s%c", names[i],
+- bits != 0 ? ',' : '\n');
++ rc = seq_printf(m, "%s%c", names[i],
++ bits != 0 ? ',' : '\n');
+ if (rc <= 0)
+ return -ENOSPC;
+-
+- *buf += rc;
+- *len -= rc;
+ }
+ }
+- return save - *len;
++ return 0;
+ }
+
+-static int scrub_time_dump(char **buf, int *len, __u64 time, const char *prefix)
++static int scrub_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,
++ rc = seq_printf(m, "%s: "LPU64" seconds\n", prefix,
+ cfs_time_current_sec() - time);
+ else
+- rc = snprintf(*buf, *len, "%s: N/A\n", prefix);
++ rc = seq_printf(m, "%s: N/A\n", prefix);
+ if (rc <= 0)
+ return -ENOSPC;
+
+- *buf += rc;
+- *len -= rc;
+- return rc;
++ return 0;
+ }
+
+-static int scrub_pos_dump(char **buf, int *len, __u64 pos, const char *prefix)
++static int scrub_pos_dump(struct seq_file *m, __u64 pos, const char *prefix)
+ {
+ int rc;
+
+ if (pos != 0)
+- rc = snprintf(*buf, *len, "%s: "LPU64"\n", prefix, pos);
++ rc = seq_printf(m, "%s: "LPU64"\n", prefix, pos);
+ else
+- rc = snprintf(*buf, *len, "%s: N/A\n", prefix);
++ rc = seq_printf(m, "%s: N/A\n", prefix);
+ if (rc <= 0)
+ return -ENOSPC;
+
+- *buf += rc;
+- *len -= rc;
+ return rc;
+ }
+
+-int osd_scrub_dump(struct osd_device *dev, char *buf, int len)
++int osd_scrub_dump(struct seq_file *m,struct osd_device *dev)
+ {
+ struct osd_scrub *scrub = &dev->od_scrub;
+ struct scrub_file *sf = &scrub->os_file;
+ __u64 checked;
+ __u64 speed;
+- int save = len;
+ int ret = -ENOSPC;
+ int rc;
+
+ down_read(&scrub->os_rwsem);
+- rc = snprintf(buf, len,
++ rc = seq_printf(m,
+ "name: OI_scrub\n"
+ "magic: 0x%x\n"
+ "oi_files: %d\n"
+@@ -2591,51 +2580,48 @@ int osd_scrub_dump(struct osd_device *dev, char *buf, int len)
+ if (rc <= 0)
+ goto out;
+
+- buf += rc;
+- len -= rc;
+- rc = scrub_bits_dump(&buf, &len, sf->sf_flags, scrub_flags_names,
++ rc = scrub_bits_dump(m, sf->sf_flags, scrub_flags_names,
+ "flags");
+ if (rc < 0)
+ goto out;
+
+- rc = scrub_bits_dump(&buf, &len, sf->sf_param, scrub_param_names,
++ rc = scrub_bits_dump(m, sf->sf_param, scrub_param_names,
+ "param");
+ if (rc < 0)
+ goto out;
+
+- rc = scrub_time_dump(&buf, &len, sf->sf_time_last_complete,
++ rc = scrub_time_dump(m, sf->sf_time_last_complete,
+ "time_since_last_completed");
+ if (rc < 0)
+ goto out;
+
+- rc = scrub_time_dump(&buf, &len, sf->sf_time_latest_start,
++ rc = scrub_time_dump(m, sf->sf_time_latest_start,
+ "time_since_latest_start");
+ if (rc < 0)
+ goto out;
+
+- rc = scrub_time_dump(&buf, &len, sf->sf_time_last_checkpoint,
++ rc = scrub_time_dump(m, sf->sf_time_last_checkpoint,
+ "time_since_last_checkpoint");
+ if (rc < 0)
+ goto out;
+
+- rc = scrub_pos_dump(&buf, &len, sf->sf_pos_latest_start,
++ rc = scrub_pos_dump(m, sf->sf_pos_latest_start,
+ "latest_start_position");
+ if (rc < 0)
+ goto out;
+
+- rc = scrub_pos_dump(&buf, &len, sf->sf_pos_last_checkpoint,
++ rc = scrub_pos_dump(m, sf->sf_pos_last_checkpoint,
+ "last_checkpoint_position");
+ if (rc < 0)
+ goto out;
+
+- rc = scrub_pos_dump(&buf, &len, sf->sf_pos_first_inconsistent,
++ rc = scrub_pos_dump(m, sf->sf_pos_first_inconsistent,
+ "first_failure_position");
+ if (rc < 0)
+ goto out;
+
+ checked = sf->sf_items_checked + scrub->os_new_checked;
+- rc = snprintf(buf, len,
+- "checked: "LPU64"\n"
++ rc = seq_printf(m, "checked: "LPU64"\n"
+ "updated: "LPU64"\n"
+ "failed: "LPU64"\n"
+ "prior_updated: "LPU64"\n"
+@@ -2648,8 +2634,6 @@ int osd_scrub_dump(struct osd_device *dev, char *buf, int len)
+ if (rc <= 0)
+ goto out;
+
+- buf += rc;
+- len -= rc;
+ speed = checked;
+ if (thread_is_running(&scrub->os_thread)) {
+ cfs_duration_t duration = cfs_time_current() -
+@@ -2662,8 +2646,7 @@ int osd_scrub_dump(struct osd_device *dev, char *buf, int len)
+ do_div(new_checked, duration);
+ if (rtime != 0)
+ do_div(speed, rtime);
+- rc = snprintf(buf, len,
+- "run_time: %u seconds\n"
++ rc = seq_printf(m, "run_time: %u seconds\n"
+ "average_speed: "LPU64" objects/sec\n"
+ "real-time_speed: "LPU64" objects/sec\n"
+ "current_position: %u\n"
+@@ -2676,8 +2659,7 @@ int osd_scrub_dump(struct osd_device *dev, char *buf, int len)
+ } else {
+ if (sf->sf_run_time != 0)
+ do_div(speed, sf->sf_run_time);
+- rc = snprintf(buf, len,
+- "run_time: %u seconds\n"
++ rc = seq_printf(m, "run_time: %u seconds\n"
+ "average_speed: "LPU64" objects/sec\n"
+ "real-time_speed: N/A\n"
+ "current_position: N/A\n"
+@@ -2689,10 +2671,7 @@ int osd_scrub_dump(struct osd_device *dev, char *buf, int len)
+ }
+ if (rc <= 0)
+ goto out;
+-
+- buf += rc;
+- len -= rc;
+- ret = save - len;
++ ret = 0;
+
+ out:
+ up_read(&scrub->os_rwsem);
+--
+1.8.5.1
+
diff --git a/sys-cluster/lustre/lustre-9999.ebuild b/sys-cluster/lustre/lustre-9999.ebuild
index 610c7555d..123c81cef 100644
--- a/sys-cluster/lustre/lustre-9999.ebuild
+++ b/sys-cluster/lustre/lustre-9999.ebuild
@@ -42,6 +42,15 @@ PATCHES=(
"${FILESDIR}/0007-LU-3319-procfs-move-lmv-proc-handling-over-to-seq_fi.patch"
"${FILESDIR}/0008-LU-3319-procfs-move-ldlm-proc-handling-over-to-seq_f.patch"
"${FILESDIR}/0009-LU-3319-procfs-move-ost-proc-handling-over-to-seq_fi.patch"
+ "${FILESDIR}/0010-LU-3319-procfs-update-shared-server-side-core-proc-h.patch"
+ "${FILESDIR}/0011-LU-3319-procfs-update-zfs-proc-handling-to-seq_files.patch"
+ "${FILESDIR}/0012-LU-3319-procfs-move-mgs-proc-handling-to-seq_files.patch"
+ "${FILESDIR}/0013-LU-3319-procfs-move-ofd-proc-handling-to-seq_files.patch"
+ "${FILESDIR}/0014-LU-3319-procfs-move-lod-proc-handling-to-seq_files.patch"
+ "${FILESDIR}/0015-LU-3319-procfs-move-osp-proc-handling-to-seq_files.patch"
+ "${FILESDIR}/0016-LU-3319-procfs-move-mdt-mds-proc-handling-to-seq_fil.patch"
+ "${FILESDIR}/0017-LU-3319-procfs-move-mdd-proc-handling-to-seq_files.patch"
+ "${FILESDIR}/0018-LU-3319-procfs-update-ldiskfs-proc-handling-to-seq_f.patch"
)
pkg_setup() {