[PATCH 2/4] staging/lustre: adapt proc_dir_entry change

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



In 3.10 merge window, proc_dir_entry is now private to proc. However,
Lustre lprocfs depends heavily on it and its now-gone read_proc_t and
write_proc_t members.

The patch largely changed the fact, and made lprocfs depend on none of
proc_dir_entry private members. All lprocfs callers are converted to
use the new seq_file scheme.

Also lprocfs_srch is removed so that we can drop lprocfs_lock. All callers
are changed to save created pde in proper place.

See https://jira.hpdd.intel.com/browse/LU-3319 for more details.

Signed-off-by: Peng Tao <tao.peng@xxxxxxx>
Signed-off-by: Andreas Dilger <andreas.dilger@xxxxxxxxx>
---
 .../lustre/include/linux/libcfs/libcfs_hash.h      |    5 +-
 .../lustre/include/linux/libcfs/params_tree.h      |   64 --
 drivers/staging/lustre/lustre/fid/fid_internal.h   |    2 -
 drivers/staging/lustre/lustre/fid/lproc_fid.c      |  214 +---
 drivers/staging/lustre/lustre/fld/lproc_fld.c      |   78 +-
 drivers/staging/lustre/lustre/include/cl_object.h  |    4 +-
 .../staging/lustre/lustre/include/lprocfs_status.h |  293 +++---
 drivers/staging/lustre/lustre/include/lu_object.h  |    2 +-
 drivers/staging/lustre/lustre/include/lustre_dlm.h |    3 +
 drivers/staging/lustre/lustre/include/obd.h        |    1 +
 drivers/staging/lustre/lustre/ldlm/ldlm_internal.h |   37 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_pool.c     |  146 ++-
 drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |  189 ++--
 drivers/staging/lustre/lustre/libcfs/hash.c        |   42 +-
 drivers/staging/lustre/lustre/llite/lproc_llite.c  |  415 ++++----
 drivers/staging/lustre/lustre/llite/vvp_dev.c      |    3 +-
 drivers/staging/lustre/lustre/lmv/lmv_obd.c        |   53 +-
 drivers/staging/lustre/lustre/lmv/lproc_lmv.c      |   64 +-
 drivers/staging/lustre/lustre/lov/lov_obd.c        |   19 +-
 drivers/staging/lustre/lustre/lov/lov_pool.c       |    5 +-
 drivers/staging/lustre/lustre/lov/lproc_lov.c      |  136 ++-
 drivers/staging/lustre/lustre/mdc/lproc_mdc.c      |   92 +-
 drivers/staging/lustre/lustre/mgc/lproc_mgc.c      |   34 +-
 drivers/staging/lustre/lustre/mgc/mgc_internal.h   |    6 +-
 drivers/staging/lustre/lustre/mgc/mgc_request.c    |   13 +-
 drivers/staging/lustre/lustre/obdclass/cl_object.c |   47 +-
 drivers/staging/lustre/lustre/obdclass/genops.c    |    8 +-
 .../lustre/lustre/obdclass/linux/linux-module.c    |   72 +-
 .../lustre/lustre/obdclass/lprocfs_jobstats.c      |   29 +-
 .../lustre/lustre/obdclass/lprocfs_status.c        | 1018 ++++----------------
 drivers/staging/lustre/lustre/obdclass/lu_object.c |    4 +-
 .../staging/lustre/lustre/obdclass/obd_config.c    |   11 +-
 drivers/staging/lustre/lustre/obdecho/lproc_echo.c |    6 +-
 drivers/staging/lustre/lustre/osc/lproc_osc.c      |  293 +++---
 .../staging/lustre/lustre/ptlrpc/gss/lproc_gss.c   |   34 +-
 .../staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c    |  220 ++---
 .../staging/lustre/lustre/ptlrpc/ptlrpc_internal.h |    3 +-
 drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c    |    5 +-
 drivers/staging/lustre/lustre/ptlrpc/sec_lproc.c   |    3 +-
 39 files changed, 1335 insertions(+), 2338 deletions(-)

diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h
index c5b3715..f6361b3 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h
@@ -792,8 +792,9 @@ static inline void __cfs_hash_set_theta(cfs_hash_t *hs, int min, int max)
 }
 
 /* Generic debug formatting routines mainly for proc handler */
-int cfs_hash_debug_header(char *str, int size);
-int cfs_hash_debug_str(cfs_hash_t *hs, char *str, int size);
+struct seq_file;
+int cfs_hash_debug_header(struct seq_file *m);
+int cfs_hash_debug_str(cfs_hash_t *hs, struct seq_file *m);
 
 /*
  * Generic djb2 hash algorithm for character arrays.
diff --git a/drivers/staging/lustre/include/linux/libcfs/params_tree.h b/drivers/staging/lustre/include/linux/libcfs/params_tree.h
index 6551f4b..3f18a44 100644
--- a/drivers/staging/lustre/include/linux/libcfs/params_tree.h
+++ b/drivers/staging/lustre/include/linux/libcfs/params_tree.h
@@ -58,7 +58,6 @@ typedef module_t			   *cfs_param_module_t;
 typedef struct proc_dir_entry		   cfs_param_dentry_t;
 typedef struct poll_table_struct		cfs_poll_table_t;
 #define CFS_PARAM_MODULE			THIS_MODULE
-#define CFS_PDE(value)			  PDE(value)
 #define cfs_file_private(file)		  (file->private_data)
 #define cfs_dentry_data(dentry)		 (dentry->data)
 #define cfs_proc_inode_pde(proc_inode)	  (proc_inode->pde)
@@ -75,52 +74,6 @@ typedef struct poll_table_struct		cfs_poll_table_t;
 							    count, ppos))
 #define cfs_seq_open(file, ops, rc)	     (rc = seq_open(file, ops))
 
-/* in lprocfs_stat.c, to protect the private data for proc entries */
-extern struct rw_semaphore		_lprocfs_lock;
-
-/* to begin from 2.6.23, Linux defines self file_operations (proc_reg_file_ops)
- * in procfs, the proc file_operation defined by Lustre (lprocfs_generic_fops)
- * will be wrapped into the new defined proc_reg_file_ops, which instroduces
- * user count in proc_dir_entrey(pde_users) to protect the proc entry from
- * being deleted. then the protection lock (_lprocfs_lock) defined by Lustre
- * isn't necessary anymore for lprocfs_generic_fops(e.g. lprocfs_fops_read).
- * see bug19706 for detailed information.
- */
-#define LPROCFS_ENTRY() do{ }while(0)
-#define LPROCFS_EXIT()  do{ }while(0)
-
-static inline
-int LPROCFS_ENTRY_AND_CHECK(struct proc_dir_entry *dp)
-{
-	int deleted = 0;
-
-	spin_lock(&(dp)->pde_unload_lock);
-	if (dp->proc_fops == NULL)
-		deleted = 1;
-	spin_unlock(&(dp)->pde_unload_lock);
-	if (deleted)
-		return -ENODEV;
-	return 0;
-}
-#define LPROCFS_SRCH_ENTRY()	    \
-do {				    \
-	down_read(&_lprocfs_lock);      \
-} while(0)
-
-#define LPROCFS_SRCH_EXIT()	     \
-do {				    \
-	up_read(&_lprocfs_lock);	\
-} while(0)
-
-#define LPROCFS_WRITE_ENTRY()		\
-do {					\
-	down_write(&_lprocfs_lock);	\
-} while(0)
-
-#define LPROCFS_WRITE_EXIT()		\
-do {					\
-	up_write(&_lprocfs_lock);	\
-} while(0)
 #else /* !LPROCFS */
 
 typedef struct cfs_params_file {
@@ -181,13 +134,7 @@ static inline cfs_proc_inode_t *FAKE_PROC_I(const cfs_inode_t *inode)
 	return container_of(inode, cfs_proc_inode_t, param_inode);
 }
 
-static inline cfs_param_dentry_t *FAKE_PDE(cfs_inode_t *inode)
-{
-	return FAKE_PROC_I(inode)->param_pde;
-}
-
 #define CFS_PARAM_MODULE			NULL
-#define CFS_PDE(value)			  FAKE_PDE(value)
 #define cfs_file_private(file)		  (file->param_private)
 #define cfs_dentry_data(dentry)		 (dentry->param_data)
 #define cfs_proc_inode(proc_inode)	      (proc_inode->param_inode)
@@ -212,17 +159,6 @@ do {						    \
 	rc = 0;					 \
 } while(0)
 
-#define LPROCFS_ENTRY()	     do {} while(0)
-#define LPROCFS_EXIT()	      do {} while(0)
-static inline
-int LPROCFS_ENTRY_AND_CHECK(cfs_param_dentry_t *dp)
-{
-	LPROCFS_ENTRY();
-	return 0;
-}
-#define LPROCFS_WRITE_ENTRY()       do {} while(0)
-#define LPROCFS_WRITE_EXIT()	do {} while(0)
-
 #endif /* LPROCFS */
 
 /* XXX: params_tree APIs */
diff --git a/drivers/staging/lustre/lustre/fid/fid_internal.h b/drivers/staging/lustre/lustre/fid/fid_internal.h
index c3a94f4..407a743 100644
--- a/drivers/staging/lustre/lustre/fid/fid_internal.h
+++ b/drivers/staging/lustre/lustre/fid/fid_internal.h
@@ -57,10 +57,8 @@ enum {
 
 extern struct lu_context_key seq_thread_key;
 
-/* Functions used internally in module. */
 int seq_client_alloc_super(struct lu_client_seq *seq,
 			   const struct lu_env *env);
-
 /* Store API functions. */
 int seq_store_init(struct lu_server_seq *seq,
 		   const struct lu_env *env,
diff --git a/drivers/staging/lustre/lustre/fid/lproc_fid.c b/drivers/staging/lustre/lustre/fid/lproc_fid.c
index 49ea357..af817a8 100644
--- a/drivers/staging/lustre/lustre/fid/lproc_fid.c
+++ b/drivers/staging/lustre/lustre/fid/lproc_fid.c
@@ -60,9 +60,8 @@
  * use.
  */
 static int
-seq_proc_write_common(struct file *file, const char *buffer,
-		      unsigned long count, void *data,
-		      struct lu_seq_range *range)
+lprocfs_fid_write_common(const char *buffer, unsigned long count,
+			 struct lu_seq_range *range)
 {
 	struct lu_seq_range tmp;
 	int rc;
@@ -79,151 +78,19 @@ seq_proc_write_common(struct file *file, const char *buffer,
 	RETURN(0);
 }
 
-static int
-seq_proc_read_common(char *page, char **start, off_t off,
-		     int count, int *eof, void *data,
-		     struct lu_seq_range *range)
-{
-	int rc;
-	ENTRY;
-
-	*eof = 1;
-	rc = snprintf(page, count, "["LPX64" - "LPX64"]:%x:%s\n",
-			PRANGE(range));
-	RETURN(rc);
-}
-
-/*
- * Server side procfs stuff.
- */
-static int
-seq_server_proc_write_space(struct file *file, const char *buffer,
-			    unsigned long count, void *data)
-{
-	struct lu_server_seq *seq = (struct lu_server_seq *)data;
-	int rc;
-	ENTRY;
-
-	LASSERT(seq != NULL);
-
-	mutex_lock(&seq->lss_mutex);
-	rc = seq_proc_write_common(file, buffer, count,
-				   data, &seq->lss_space);
-	if (rc == 0) {
-		CDEBUG(D_INFO, "%s: Space: "DRANGE"\n",
-		       seq->lss_name, PRANGE(&seq->lss_space));
-	}
-
-	mutex_unlock(&seq->lss_mutex);
-
-	RETURN(count);
-}
-
-static int
-seq_server_proc_read_space(char *page, char **start, off_t off,
-			   int count, int *eof, void *data)
-{
-	struct lu_server_seq *seq = (struct lu_server_seq *)data;
-	int rc;
-	ENTRY;
-
-	LASSERT(seq != NULL);
-
-	mutex_lock(&seq->lss_mutex);
-	rc = seq_proc_read_common(page, start, off, count, eof,
-				  data, &seq->lss_space);
-	mutex_unlock(&seq->lss_mutex);
-
-	RETURN(rc);
-}
-
-static int
-seq_server_proc_read_server(char *page, char **start, off_t off,
-			    int count, int *eof, void *data)
-{
-	struct lu_server_seq *seq = (struct lu_server_seq *)data;
-	struct client_obd *cli;
-	int rc;
-	ENTRY;
-
-	LASSERT(seq != NULL);
-
-	*eof = 1;
-	if (seq->lss_cli) {
-		if (seq->lss_cli->lcs_exp != NULL) {
-			cli = &seq->lss_cli->lcs_exp->exp_obd->u.cli;
-			rc = snprintf(page, count, "%s\n",
-				      cli->cl_target_uuid.uuid);
-		} else {
-			rc = snprintf(page, count, "%s\n",
-				      seq->lss_cli->lcs_srv->lss_name);
-		}
-	} else {
-		rc = snprintf(page, count, "<none>\n");
-	}
-
-	RETURN(rc);
-}
-
-static int
-seq_server_proc_write_width(struct file *file, const char *buffer,
-			    unsigned long count, void *data)
-{
-	struct lu_server_seq *seq = (struct lu_server_seq *)data;
-	int rc, val;
-	ENTRY;
-
-	LASSERT(seq != NULL);
-
-	mutex_lock(&seq->lss_mutex);
-
-	rc = lprocfs_write_helper(buffer, count, &val);
-	if (rc != 0) {
-		CERROR("%s: invalid width.\n", seq->lss_name);
-		GOTO(out_unlock, rc);
-	}
-
-	seq->lss_width = val;
-
-	CDEBUG(D_INFO, "%s: Width: "LPU64"\n",
-	       seq->lss_name, seq->lss_width);
-out_unlock:
-	mutex_unlock(&seq->lss_mutex);
-
-	RETURN(count);
-}
-
-static int
-seq_server_proc_read_width(char *page, char **start, off_t off,
-			   int count, int *eof, void *data)
-{
-	struct lu_server_seq *seq = (struct lu_server_seq *)data;
-	int rc;
-	ENTRY;
-
-	LASSERT(seq != NULL);
-
-	mutex_lock(&seq->lss_mutex);
-	rc = snprintf(page, count, LPU64"\n", seq->lss_width);
-	mutex_unlock(&seq->lss_mutex);
-
-	RETURN(rc);
-}
-
 /* Client side procfs stuff */
-static int
-seq_client_proc_write_space(struct file *file, const char *buffer,
-			    unsigned long count, void *data)
+static ssize_t
+lprocfs_fid_space_seq_write(struct file *file, const char *buffer,
+			    size_t count, loff_t *off)
 {
-	struct lu_client_seq *seq = (struct lu_client_seq *)data;
+	struct lu_client_seq *seq = ((struct seq_file *)file->private_data)->private;
 	int rc;
 	ENTRY;
 
 	LASSERT(seq != NULL);
 
 	mutex_lock(&seq->lcs_mutex);
-	rc = seq_proc_write_common(file, buffer, count,
-				   data, &seq->lcs_space);
+	rc = lprocfs_fid_write_common(buffer, count, &seq->lcs_space);
 
 	if (rc == 0) {
 		CDEBUG(D_INFO, "%s: Space: "DRANGE"\n",
@@ -236,42 +103,37 @@ seq_client_proc_write_space(struct file *file, const char *buffer,
 }
 
 static int
-seq_client_proc_read_space(char *page, char **start, off_t off,
-			   int count, int *eof, void *data)
+lprocfs_fid_space_seq_show(struct seq_file *m, void *unused)
 {
-	struct lu_client_seq *seq = (struct lu_client_seq *)data;
+	struct lu_client_seq *seq = (struct lu_client_seq *)m->private;
 	int rc;
 	ENTRY;
 
 	LASSERT(seq != NULL);
 
 	mutex_lock(&seq->lcs_mutex);
-	rc = seq_proc_read_common(page, start, off, count, eof,
-				  data, &seq->lcs_space);
+	rc = seq_printf(m, "["LPX64" - "LPX64"]:%x:%s\n", PRANGE(&seq->lcs_space));
 	mutex_unlock(&seq->lcs_mutex);
 
 	RETURN(rc);
 }
 
-static int
-seq_client_proc_write_width(struct file *file, const char *buffer,
-			    unsigned long count, void *data)
+static ssize_t
+lprocfs_fid_width_seq_write(struct file *file, const char *buffer,
+			    size_t count, loff_t *off)
 {
-	struct lu_client_seq *seq = (struct lu_client_seq *)data;
+	struct lu_client_seq *seq = ((struct seq_file *)file->private_data)->private;
 	__u64  max;
 	int rc, val;
 	ENTRY;
 
 	LASSERT(seq != NULL);
 
-	mutex_lock(&seq->lcs_mutex);
-
 	rc = lprocfs_write_helper(buffer, count, &val);
-	if (rc) {
-		mutex_unlock(&seq->lcs_mutex);
+	if (rc)
 		RETURN(rc);
-	}
 
+	mutex_lock(&seq->lcs_mutex);
 	if (seq->lcs_type == LUSTRE_SEQ_DATA)
 		max = LUSTRE_DATA_SEQ_MAX_WIDTH;
 	else
@@ -292,44 +154,41 @@ seq_client_proc_write_width(struct file *file, const char *buffer,
 }
 
 static int
-seq_client_proc_read_width(char *page, char **start, off_t off,
-			   int count, int *eof, void *data)
+lprocfs_fid_width_seq_show(struct seq_file *m, void *unused)
 {
-	struct lu_client_seq *seq = (struct lu_client_seq *)data;
+	struct lu_client_seq *seq = (struct lu_client_seq *)m->private;
 	int rc;
 	ENTRY;
 
 	LASSERT(seq != NULL);
 
 	mutex_lock(&seq->lcs_mutex);
-	rc = snprintf(page, count, LPU64"\n", seq->lcs_width);
+	rc = seq_printf(m, LPU64"\n", seq->lcs_width);
 	mutex_unlock(&seq->lcs_mutex);
 
 	RETURN(rc);
 }
 
 static int
-seq_client_proc_read_fid(char *page, char **start, off_t off,
-			 int count, int *eof, void *data)
+lprocfs_fid_fid_seq_show(struct seq_file *m, void *unused)
 {
-	struct lu_client_seq *seq = (struct lu_client_seq *)data;
+	struct lu_client_seq *seq = (struct lu_client_seq *)m->private;
 	int rc;
 	ENTRY;
 
 	LASSERT(seq != NULL);
 
 	mutex_lock(&seq->lcs_mutex);
-	rc = snprintf(page, count, DFID"\n", PFID(&seq->lcs_fid));
+	rc = seq_printf(m, DFID"\n", PFID(&seq->lcs_fid));
 	mutex_unlock(&seq->lcs_mutex);
 
 	RETURN(rc);
 }
 
 static int
-seq_client_proc_read_server(char *page, char **start, off_t off,
-			    int count, int *eof, void *data)
+lprocfs_fid_server_seq_show(struct seq_file *m, void *unused)
 {
-	struct lu_client_seq *seq = (struct lu_client_seq *)data;
+	struct lu_client_seq *seq = (struct lu_client_seq *)m->private;
 	struct client_obd *cli;
 	int rc;
 	ENTRY;
@@ -338,23 +197,26 @@ seq_client_proc_read_server(char *page, char **start, off_t off,
 
 	if (seq->lcs_exp != NULL) {
 		cli = &seq->lcs_exp->exp_obd->u.cli;
-		rc = snprintf(page, count, "%s\n", cli->cl_target_uuid.uuid);
+		rc = seq_printf(m, "%s\n", cli->cl_target_uuid.uuid);
 	} else {
-		rc = snprintf(page, count, "%s\n", seq->lcs_srv->lss_name);
+		rc = seq_printf(m, "%s\n", seq->lcs_srv->lss_name);
 	}
 	RETURN(rc);
 }
 
 struct lprocfs_vars seq_server_proc_list[] = {
-	{ "space",    seq_server_proc_read_space, seq_server_proc_write_space, NULL },
-	{ "width",    seq_server_proc_read_width, seq_server_proc_write_width, NULL },
-	{ "server",   seq_server_proc_read_server, NULL, NULL },
-	{ NULL }};
+};
+
+LPROC_SEQ_FOPS(lprocfs_fid_space);
+LPROC_SEQ_FOPS(lprocfs_fid_width);
+LPROC_SEQ_FOPS_RO(lprocfs_fid_server);
+LPROC_SEQ_FOPS_RO(lprocfs_fid_fid);
 
 struct lprocfs_vars seq_client_proc_list[] = {
-	{ "space",    seq_client_proc_read_space, seq_client_proc_write_space, NULL },
-	{ "width",    seq_client_proc_read_width, seq_client_proc_write_width, NULL },
-	{ "server",   seq_client_proc_read_server, NULL, NULL },
-	{ "fid",      seq_client_proc_read_fid, NULL, NULL },
-	{ NULL }};
+	{ "space", &lprocfs_fid_space_fops },
+	{ "width", &lprocfs_fid_width_fops },
+	{ "server", &lprocfs_fid_server_fops },
+	{ "fid", &lprocfs_fid_fid_fops },
+	{ NULL }
+};
 #endif
diff --git a/drivers/staging/lustre/lustre/fld/lproc_fld.c b/drivers/staging/lustre/lustre/fld/lproc_fld.c
index 00fe31e..c1bd803 100644
--- a/drivers/staging/lustre/lustre/fld/lproc_fld.c
+++ b/drivers/staging/lustre/lustre/fld/lproc_fld.c
@@ -58,12 +58,10 @@
 
 #ifdef LPROCFS
 static int
-fld_proc_read_targets(char *page, char **start, off_t off,
-		      int count, int *eof, void *data)
+fld_proc_targets_seq_show(struct seq_file *m, void *unused)
 {
-	struct lu_client_fld *fld = (struct lu_client_fld *)data;
+	struct lu_client_fld *fld = (struct lu_client_fld *)m->private;
 	struct lu_fld_target *target;
-	int total = 0, rc;
 	ENTRY;
 
 	LASSERT(fld != NULL);
@@ -71,41 +69,32 @@ fld_proc_read_targets(char *page, char **start, off_t off,
 	spin_lock(&fld->lcf_lock);
 	list_for_each_entry(target,
 				&fld->lcf_targets, ft_chain)
-	{
-		rc = snprintf(page, count, "%s\n",
-			      fld_target_name(target));
-		page += rc;
-		count -= rc;
-		total += rc;
-		if (count == 0)
-			break;
-	}
+		seq_printf(m, "%s\n", fld_target_name(target));
 	spin_unlock(&fld->lcf_lock);
-	RETURN(total);
+
+	RETURN(0);
 }
 
 static int
-fld_proc_read_hash(char *page, char **start, off_t off,
-		   int count, int *eof, void *data)
+fld_proc_hash_seq_show(struct seq_file *m, void *unused)
 {
-	struct lu_client_fld *fld = (struct lu_client_fld *)data;
-	int rc;
+	struct lu_client_fld *fld = (struct lu_client_fld *)m->private;
 	ENTRY;
 
 	LASSERT(fld != NULL);
 
 	spin_lock(&fld->lcf_lock);
-	rc = snprintf(page, count, "%s\n", fld->lcf_hash->fh_name);
+	seq_printf(m, "%s\n", fld->lcf_hash->fh_name);
 	spin_unlock(&fld->lcf_lock);
 
-	RETURN(rc);
+	RETURN(0);
 }
 
-static int
-fld_proc_write_hash(struct file *file, const char *buffer,
-		    unsigned long count, void *data)
+static ssize_t
+fld_proc_hash_seq_write(struct file *file, const char *buffer,
+			size_t count, loff_t *off)
 {
-	struct lu_client_fld *fld = (struct lu_client_fld *)data;
+	struct lu_client_fld *fld = ((struct seq_file *)file->private_data)->private;
 	struct lu_fld_hash *hash = NULL;
 	int i;
 	ENTRY;
@@ -134,11 +123,11 @@ fld_proc_write_hash(struct file *file, const char *buffer,
 	RETURN(count);
 }
 
-static int
-fld_proc_write_cache_flush(struct file *file, const char *buffer,
-			   unsigned long count, void *data)
+static ssize_t
+fld_proc_cache_flush_write(struct file *file, const char __user *buffer,
+			       size_t count, loff_t *pos)
 {
-	struct lu_client_fld *fld = (struct lu_client_fld *)data;
+	struct lu_client_fld *fld = file->private_data;
 	ENTRY;
 
 	LASSERT(fld != NULL);
@@ -150,6 +139,25 @@ fld_proc_write_cache_flush(struct file *file, const char *buffer,
 	RETURN(count);
 }
 
+static int fld_proc_cache_flush_open(struct inode *inode, struct file *file)
+{
+	file->private_data = PDE_DATA(inode);
+	return 0;
+}
+
+static int fld_proc_cache_flush_release(struct inode *inode, struct file *file)
+{
+	file->private_data = NULL;
+	return 0;
+}
+
+struct file_operations fld_proc_cache_flush_fops = {
+	.owner		= THIS_MODULE,
+	.open		= fld_proc_cache_flush_open,
+	.write		= fld_proc_cache_flush_write,
+	.release	= fld_proc_cache_flush_release,
+};
+
 struct fld_seq_param {
 	struct lu_env		fsp_env;
 	struct dt_it		*fsp_it;
@@ -265,16 +273,14 @@ struct seq_operations fldb_sops = {
 
 static int fldb_seq_open(struct inode *inode, struct file *file)
 {
-	struct proc_dir_entry	*dp = PDE(inode);
 	struct seq_file		*seq;
-	struct lu_server_fld    *fld = (struct lu_server_fld *)dp->data;
+	struct lu_server_fld    *fld = (struct lu_server_fld *)PDE_DATA(inode);
 	struct dt_object	*obj;
 	const struct dt_it_ops  *iops;
 	struct fld_seq_param    *param = NULL;
 	int			env_init = 0;
 	int			rc;
 
-	LPROCFS_ENTRY_AND_CHECK(dp);
 	rc = seq_open(file, &fldb_sops);
 	if (rc)
 		GOTO(out, rc);
@@ -311,7 +317,6 @@ out:
 			lu_env_fini(&param->fsp_env);
 		if (param != NULL)
 			OBD_FREE_PTR(param);
-		LPROCFS_EXIT();
 	}
 	return rc;
 }
@@ -349,10 +354,13 @@ static int fldb_seq_release(struct inode *inode, struct file *file)
 struct lprocfs_vars fld_server_proc_list[] = {
 	{ NULL }};
 
+LPROC_SEQ_FOPS_RO(fld_proc_targets);
+LPROC_SEQ_FOPS(fld_proc_hash);
+
 struct lprocfs_vars fld_client_proc_list[] = {
-	{ "targets",     fld_proc_read_targets, NULL, NULL },
-	{ "hash",	fld_proc_read_hash, fld_proc_write_hash, NULL },
-	{ "cache_flush", NULL, fld_proc_write_cache_flush, NULL },
+	{ "targets", &fld_proc_targets_fops },
+	{ "hash", &fld_proc_hash_fops },
+	{ "cache_flush", &fld_proc_cache_flush_fops },
 	{ NULL }};
 
 struct file_operations fld_proc_seq_fops = {
diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h
index 61c4635..4bb6880 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -2598,8 +2598,6 @@ struct cache_stats {
 
 /** These are not exported so far */
 void cache_stats_init (struct cache_stats *cs, const char *name);
-int  cache_stats_print(const struct cache_stats *cs,
-		       char *page, int count, int header);
 
 /**
  * Client-side site. This represents particular client stack. "Global"
@@ -2631,7 +2629,7 @@ void cl_stack_fini(const struct lu_env *env, struct cl_device *cl);
  * Output client site statistical counters into a buffer. Suitable for
  * ll_rd_*()-style functions.
  */
-int cl_site_stats_print(const struct cl_site *s, char *page, int count);
+int cl_site_stats_print(const struct cl_site *site, struct seq_file *m);
 
 /**
  * \name helpers
diff --git a/drivers/staging/lustre/lustre/include/lprocfs_status.h b/drivers/staging/lustre/lustre/include/lprocfs_status.h
index e4e8f72..e770d02 100644
--- a/drivers/staging/lustre/lustre/include/lprocfs_status.h
+++ b/drivers/staging/lustre/lustre/include/lprocfs_status.h
@@ -47,15 +47,13 @@
 #include <linux/libcfs/params_tree.h>
 
 struct lprocfs_vars {
-	const char	     *name;
-	read_proc_t	*read_fptr;
-	write_proc_t       *write_fptr;
-	void		   *data;
-	struct file_operations *fops;
+	const char		*name;
+	struct file_operations	*fops;
+	void			*data;
 	/**
 	 * /proc file mode.
 	 */
-	mode_t		  proc_mode;
+	mode_t			proc_mode;
 };
 
 struct lprocfs_static_vars {
@@ -570,8 +568,6 @@ extern int lprocfs_exp_setup(struct obd_export *exp,
 extern int lprocfs_exp_cleanup(struct obd_export *exp);
 extern proc_dir_entry_t *lprocfs_add_simple(struct proc_dir_entry *root,
 						char *name,
-						read_proc_t *read_proc,
-						write_proc_t *write_proc,
 						void *data,
 						struct file_operations *fops);
 extern struct proc_dir_entry *
@@ -581,8 +577,7 @@ extern void lprocfs_free_per_client_stats(struct obd_device *obd);
 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);
+extern int lprocfs_nid_stats_clear_read(struct seq_file *m, void *data);
 
 extern int lprocfs_register_stats(proc_dir_entry_t *root, const char *name,
 				  struct lprocfs_stats *stats);
@@ -600,15 +595,9 @@ extern proc_dir_entry_t *lprocfs_register(const char *name,
 extern void lprocfs_remove(proc_dir_entry_t **root);
 extern void lprocfs_remove_proc_entry(const char *name,
 				      struct proc_dir_entry *parent);
-extern void lprocfs_try_remove_proc_entry(const char *name,
-					  struct proc_dir_entry *parent);
-
-extern proc_dir_entry_t *lprocfs_srch(proc_dir_entry_t *root,
-					  const char *name);
 
 extern int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list);
 extern int lprocfs_obd_cleanup(struct obd_device *obd);
-extern struct file_operations lprocfs_evict_client_fops;
 
 extern int lprocfs_seq_create(proc_dir_entry_t *parent, const char *name,
 			      mode_t mode,
@@ -621,72 +610,52 @@ extern int lprocfs_obd_seq_create(struct obd_device *dev, const char *name,
 
 /* Generic callbacks */
 
-extern int lprocfs_rd_u64(char *page, char **start, off_t off,
-			  int count, int *eof, void *data);
-extern int lprocfs_rd_atomic(char *page, char **start, off_t off,
-			     int count, int *eof, void *data);
+extern int lprocfs_rd_u64(struct seq_file *m, void *data);
+extern int lprocfs_rd_atomic(struct seq_file *m, void *data);
 extern int lprocfs_wr_atomic(struct file *file, const char *buffer,
 			     unsigned long count, void *data);
-extern int lprocfs_rd_uint(char *page, char **start, off_t off,
-			   int count, int *eof, void *data);
+extern int lprocfs_rd_uint(struct seq_file *m, void *data);
 extern int lprocfs_wr_uint(struct file *file, const char *buffer,
 			   unsigned long count, void *data);
-extern int lprocfs_rd_uuid(char *page, char **start, off_t off,
-			   int count, int *eof, void *data);
-extern int lprocfs_rd_name(char *page, char **start, off_t off,
-			   int count, int *eof, void *data);
-extern int lprocfs_rd_server_uuid(char *page, char **start, off_t off,
-				  int count, int *eof, void *data);
-extern int lprocfs_rd_conn_uuid(char *page, char **start, off_t off,
-				int count, int *eof, void *data);
-extern int lprocfs_rd_import(char *page, char **start, off_t off, int count,
-			     int *eof, void *data);
-extern int lprocfs_rd_state(char *page, char **start, off_t off, int count,
-			    int *eof, void *data);
-extern int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
-				    int count, int *eof, void *data);
-extern int lprocfs_rd_num_exports(char *page, char **start, off_t off,
-				  int count, int *eof, void *data);
-extern int lprocfs_rd_numrefs(char *page, char **start, off_t off,
-			      int count, int *eof, void *data);
+extern int lprocfs_rd_uuid(struct seq_file *m, void *data);
+extern int lprocfs_rd_name(struct seq_file *m, void *data);
+extern int lprocfs_rd_server_uuid(struct seq_file *m, void *data);
+extern int lprocfs_rd_conn_uuid(struct seq_file *m, void *data);
+extern int lprocfs_rd_import(struct seq_file *m, void *data);
+extern int lprocfs_rd_state(struct seq_file *m, void *data);
+extern int lprocfs_rd_connect_flags(struct seq_file *m, void *data);
+extern int lprocfs_rd_num_exports(struct seq_file *m, void *data);
+extern int lprocfs_rd_numrefs(struct seq_file *m, void *data);
+
 struct adaptive_timeout;
-extern int lprocfs_at_hist_helper(char *page, int count, int rc,
+extern int lprocfs_at_hist_helper(struct seq_file *m,
 				  struct adaptive_timeout *at);
-extern int lprocfs_rd_timeouts(char *page, char **start, off_t off,
-			       int count, int *eof, void *data);
+extern int lprocfs_rd_timeouts(struct seq_file *m, void *data);
 extern int lprocfs_wr_timeouts(struct file *file, const char *buffer,
 			       unsigned long count, void *data);
 extern int lprocfs_wr_evict_client(struct file *file, const char *buffer,
-				   unsigned long count, void *data);
+			    size_t count, loff_t *off);
 extern int lprocfs_wr_ping(struct file *file, const char *buffer,
-			   unsigned long count, void *data);
+			   size_t count, loff_t *off);
 extern int lprocfs_wr_import(struct file *file, const char *buffer,
-			     unsigned long count, void *data);
-extern int lprocfs_rd_pinger_recov(char *page, char **start, off_t off,
-				   int count, int *eof, void *data);
+		      size_t count, loff_t *off);
+extern int lprocfs_rd_pinger_recov(struct seq_file *m, void *n);
 extern int lprocfs_wr_pinger_recov(struct file *file, const char *buffer,
-				   unsigned long count, void *data);
+				   size_t count, loff_t *off);
 
 /* Statfs helpers */
-extern int lprocfs_rd_blksize(char *page, char **start, off_t off,
-			      int count, int *eof, void *data);
-extern int lprocfs_rd_kbytestotal(char *page, char **start, off_t off,
-				  int count, int *eof, void *data);
-extern int lprocfs_rd_kbytesfree(char *page, char **start, off_t off,
-				 int count, int *eof, void *data);
-extern int lprocfs_rd_kbytesavail(char *page, char **start, off_t off,
-				 int count, int *eof, void *data);
-extern int lprocfs_rd_filestotal(char *page, char **start, off_t off,
-				 int count, int *eof, void *data);
-extern int lprocfs_rd_filesfree(char *page, char **start, off_t off,
-				int count, int *eof, void *data);
-extern int lprocfs_rd_filegroups(char *page, char **start, off_t off,
-				 int count, int *eof, void *data);
+extern int lprocfs_rd_blksize(struct seq_file *m, void *data);
+extern int lprocfs_rd_kbytestotal(struct seq_file *m, void *data);
+extern int lprocfs_rd_kbytesfree(struct seq_file *m, void *data);
+extern int lprocfs_rd_kbytesavail(struct seq_file *m, void *data);
+extern int lprocfs_rd_filestotal(struct seq_file *m, void *data);
+extern int lprocfs_rd_filesfree(struct seq_file *m, void *data);
 
 extern int lprocfs_write_helper(const char *buffer, unsigned long count,
 				int *val);
 extern int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
 				     int *val, int mult);
+extern int lprocfs_seq_read_frac_helper(struct seq_file *m, long val, int mult);
 extern int lprocfs_read_frac_helper(char *buffer, unsigned long count,
 				    long val, int mult);
 extern int lprocfs_write_u64_helper(const char *buffer, unsigned long count,
@@ -704,20 +673,6 @@ unsigned long lprocfs_oh_sum(struct obd_histogram *oh);
 void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
 			   struct lprocfs_counter *cnt);
 
-/* lprocfs_status.c: recovery status */
-int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
-				   int count, int *eof, void *data);
-
-/* lprocfs_statuc.c: hash statistics */
-int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
-			int count, int *eof, void *data);
-
-/* lprocfs_status.c: IR factor */
-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);
-
 extern int lprocfs_single_release(cfs_inode_t *, struct file *);
 extern int lprocfs_seq_release(cfs_inode_t *, struct file *);
 
@@ -739,18 +694,11 @@ extern int lprocfs_seq_release(cfs_inode_t *, struct file *);
   proc entries; otherwise, you will define name##_seq_write function also for
   a read-write proc entry, and then call LPROC_SEQ_SEQ instead. Finally,
   call lprocfs_obd_seq_create(obd, filename, 0444, &name#_fops, data); */
-#define __LPROC_SEQ_FOPS(name, custom_seq_write)			   \
-static int name##_single_open(cfs_inode_t *inode, struct file *file) {     \
-	struct proc_dir_entry *dp = PDE(inode);			    \
-	int rc;							    \
-	LPROCFS_ENTRY_AND_CHECK(dp);				       \
-	rc = single_open(file, name##_seq_show, dp->data);		 \
-	if (rc) {							  \
-		LPROCFS_EXIT();					    \
-		return rc;						 \
-	}								  \
-	return 0;							  \
-}									  \
+#define __LPROC_SEQ_FOPS(name, custom_seq_write)			\
+static int name##_single_open(cfs_inode_t *inode, struct file *file)	\
+{									\
+	return single_open(file, name##_seq_show, PDE_DATA(inode));	\
+}									\
 struct file_operations name##_fops = {				     \
 	.owner   = THIS_MODULE,					    \
 	.open    = name##_single_open,				     \
@@ -763,14 +711,50 @@ struct file_operations name##_fops = {				     \
 #define LPROC_SEQ_FOPS_RO(name)	 __LPROC_SEQ_FOPS(name, NULL)
 #define LPROC_SEQ_FOPS(name)	    __LPROC_SEQ_FOPS(name, name##_seq_write)
 
+#define LPROC_SEQ_FOPS_RO_TYPE(name, type)				\
+	static int name##_##type##_seq_show(struct seq_file *m, void *v)\
+	{								\
+		return lprocfs_rd_##type(m, m->private);		\
+	}								\
+	LPROC_SEQ_FOPS_RO(name##_##type)
+
+#define LPROC_SEQ_FOPS_RW_TYPE(name, type)				\
+	static int name##_##type##_seq_show(struct seq_file *m, void *v)\
+	{								\
+		return lprocfs_rd_##type(m, m->private);		\
+	}								\
+	static ssize_t name##_##type##_seq_write(struct file *file,	\
+			const char *buffer, size_t count, loff_t *off)	\
+	{								\
+		struct seq_file *seq = file->private_data;		\
+		return lprocfs_wr_##type(file, buffer,			\
+					 count, seq->private);		\
+	}								\
+	LPROC_SEQ_FOPS(name##_##type);
+
+#define LPROC_SEQ_FOPS_WR_ONLY(name, type)				\
+	static ssize_t name##_##type##_write(struct file *file,		\
+			const char *buffer, size_t count, loff_t *off)	\
+	{								\
+		return lprocfs_wr_##type(file, buffer, count, off);	\
+	}								\
+	static int name##_##type##_open(cfs_inode_t *inode, struct file *file) \
+	{								\
+		return single_open(file, NULL, PDE_DATA(inode));	\
+	}								\
+	struct file_operations name##_##type##_fops = {			\
+		.open	= name##_##type##_open,				\
+		.write	= name##_##type##_write,			\
+		.release = lprocfs_single_release,			\
+	};
+
 /* 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);
-int lprocfs_rd_job_interval(char *page, char **start, off_t off,
-			    int count, int *eof, void *data);
+int lprocfs_rd_job_interval(struct seq_file *m, void *data);
 int lprocfs_wr_job_interval(struct file *file, const char *buffer,
 			    unsigned long count, void *data);
 
@@ -779,78 +763,65 @@ 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);
-int lprocfs_obd_wr_recovery_time_soft(struct file *file,
-				      const char *buffer,
-				      unsigned long count, void *data);
-int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
-				      int count, int *eof, void *data);
-int lprocfs_obd_wr_recovery_time_hard(struct file *file,
-				      const char *buffer,
-				      unsigned long count, void *data);
-int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off,
-				     int count, int *eof, void *data);
+int lprocfs_obd_rd_max_pages_per_rpc(struct seq_file *m, void *data);
 int lprocfs_obd_wr_max_pages_per_rpc(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);
+				     size_t count, loff_t *off);
 
 /* all quota proc functions */
 extern int lprocfs_quota_rd_bunit(char *page, char **start,
-				  off_t off, int count,
+				  loff_t off, int count,
 				  int *eof, void *data);
 extern int lprocfs_quota_wr_bunit(struct file *file, const char *buffer,
 				  unsigned long count, void *data);
 extern int lprocfs_quota_rd_btune(char *page, char **start,
-				  off_t off, int count,
+				  loff_t off, int count,
 				  int *eof, void *data);
 extern int lprocfs_quota_wr_btune(struct file *file, const char *buffer,
 				  unsigned long count, void *data);
 extern int lprocfs_quota_rd_iunit(char *page, char **start,
-				  off_t off, int count,
+				  loff_t off, int count,
 				  int *eof, void *data);
 extern int lprocfs_quota_wr_iunit(struct file *file, const char *buffer,
 				  unsigned long count, void *data);
 extern int lprocfs_quota_rd_itune(char *page, char **start,
-				  off_t off, int count,
+				  loff_t off, int count,
 				  int *eof, void *data);
 extern int lprocfs_quota_wr_itune(struct file *file, const char *buffer,
 				  unsigned long count, void *data);
-extern int lprocfs_quota_rd_type(char *page, char **start, off_t off, int count,
+extern int lprocfs_quota_rd_type(char *page, char **start, loff_t off, int count,
 				 int *eof, void *data);
 extern int lprocfs_quota_wr_type(struct file *file, const char *buffer,
 				 unsigned long count, void *data);
-extern int lprocfs_quota_rd_switch_seconds(char *page, char **start, off_t off,
+extern int lprocfs_quota_rd_switch_seconds(char *page, char **start, loff_t off,
 					   int count, int *eof, void *data);
 extern int lprocfs_quota_wr_switch_seconds(struct file *file,
 					   const char *buffer,
 					   unsigned long count, void *data);
-extern int lprocfs_quota_rd_sync_blk(char *page, char **start, off_t off,
+extern int lprocfs_quota_rd_sync_blk(char *page, char **start, loff_t off,
 				     int count, int *eof, void *data);
 extern int lprocfs_quota_wr_sync_blk(struct file *file, const char *buffer,
 				     unsigned long count, void *data);
-extern int lprocfs_quota_rd_switch_qs(char *page, char **start, off_t off,
+extern int lprocfs_quota_rd_switch_qs(char *page, char **start, loff_t off,
 				      int count, int *eof, void *data);
 extern int lprocfs_quota_wr_switch_qs(struct file *file,
 				      const char *buffer,
 				      unsigned long count, void *data);
-extern int lprocfs_quota_rd_boundary_factor(char *page, char **start, off_t off,
+extern int lprocfs_quota_rd_boundary_factor(char *page, char **start, loff_t off,
 					    int count, int *eof, void *data);
 extern int lprocfs_quota_wr_boundary_factor(struct file *file,
 					    const char *buffer,
 					    unsigned long count, void *data);
-extern int lprocfs_quota_rd_least_bunit(char *page, char **start, off_t off,
+extern int lprocfs_quota_rd_least_bunit(char *page, char **start, loff_t off,
 					int count, int *eof, void *data);
 extern int lprocfs_quota_wr_least_bunit(struct file *file,
 					const char *buffer,
 					unsigned long count, void *data);
-extern int lprocfs_quota_rd_least_iunit(char *page, char **start, off_t off,
+extern int lprocfs_quota_rd_least_iunit(char *page, char **start, loff_t off,
 					int count, int *eof, void *data);
 extern int lprocfs_quota_wr_least_iunit(struct file *file,
 					const char *buffer,
 					unsigned long count, void *data);
-extern int lprocfs_quota_rd_qs_factor(char *page, char **start, off_t off,
+extern int lprocfs_quota_rd_qs_factor(char *page, char **start, loff_t off,
 				      int count, int *eof, void *data);
 extern int lprocfs_quota_wr_qs_factor(struct file *file,
 				      const char *buffer,
@@ -925,7 +896,6 @@ static inline int lprocfs_exp_cleanup(struct obd_export *exp)
 { return 0; }
 static inline proc_dir_entry_t *
 lprocfs_add_simple(struct proc_dir_entry *root, char *name,
-		   read_proc_t *read_proc, write_proc_t *write_proc,
 		   void *data, struct file_operations *fops)
 {return 0; }
 static inline struct proc_dir_entry *
@@ -939,9 +909,8 @@ 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;}
+int lprocfs_nid_stats_clear_read(struct seq_file *m, void *data)
+{ return 0; }
 
 static inline proc_dir_entry_t *
 lprocfs_register(const char *name, proc_dir_entry_t *parent,
@@ -956,103 +925,74 @@ static inline void lprocfs_remove(proc_dir_entry_t **root)
 static inline void lprocfs_remove_proc_entry(const char *name,
 					     struct proc_dir_entry *parent)
 { return; }
-static inline void lprocfs_try_remove_proc_entry(const char *name,
-						 struct proc_dir_entry *parent)
-{ return; }
-static inline proc_dir_entry_t *lprocfs_srch(proc_dir_entry_t *head,
-						 const char *name)
-{ return 0; }
 static inline int lprocfs_obd_setup(struct obd_device *dev,
 				    struct lprocfs_vars *list)
 { return 0; }
 static inline int lprocfs_obd_cleanup(struct obd_device *dev)
 { return 0; }
-static inline int lprocfs_rd_u64(char *page, char **start, off_t off,
-				 int count, int *eof, void *data)
+static inline int lprocfs_rd_u64(struct seq_file *m, void *data)
 { return 0; }
-static inline int lprocfs_rd_uuid(char *page, char **start, off_t off,
-				  int count, int *eof, void *data)
+static inline int lprocfs_rd_uuid(struct seq_file *m, void *data)
 { return 0; }
-static inline int lprocfs_rd_name(char *page, char **start, off_t off,
-				  int count, int *eof, void *data)
+static inline int lprocfs_rd_name(struct seq_file *m, void *data)
 { return 0; }
-static inline int lprocfs_rd_server_uuid(char *page, char **start, off_t off,
-					 int count, int *eof, void *data)
+static inline int lprocfs_rd_server_uuid(struct seq_file *m, void *data)
 { return 0; }
-static inline int lprocfs_rd_conn_uuid(char *page, char **start, off_t off,
-				       int count, int *eof, void *data)
+static inline int lprocfs_rd_conn_uuid(struct seq_file *m, void *data)
 { return 0; }
-static inline int lprocfs_rd_import(char *page, char **start, off_t off,
-				    int count, int *eof, void *data)
+static inline int lprocfs_rd_import(struct seq_file *m, void *data)
 { return 0; }
-static inline int lprocfs_rd_pinger_recov(char *page, char **start, off_t off,
-					  int count, int *eof, void *data)
+static inline int lprocfs_rd_pinger_recov(struct seq_file *m, void *n)
 { return 0; }
-static inline int lprocfs_rd_state(char *page, char **start, off_t off,
-				   int count, int *eof, void *data)
+static inline int lprocfs_rd_state(struct seq_file *m, void *data)
 { return 0; }
-static inline int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
-					   int count, int *eof, void *data)
+static inline int lprocfs_rd_connect_flags(struct seq_file *m, void *data)
 { return 0; }
-static inline int lprocfs_rd_num_exports(char *page, char **start, off_t off,
-					 int count, int *eof, void *data)
+static inline int lprocfs_rd_num_exports(struct seq_file *m, void *data)
 { return 0; }
-static inline int lprocfs_rd_numrefs(char *page, char **start, off_t off,
-				     int count, int *eof, void *data)
+extern inline int lprocfs_rd_numrefs(struct seq_file *m, void *data)
 { return 0; }
 struct adaptive_timeout;
-static inline int lprocfs_at_hist_helper(char *page, int count, int rc,
+static inline int lprocfs_at_hist_helper(struct seq_file *m,
 					 struct adaptive_timeout *at)
 { return 0; }
-static inline int lprocfs_rd_timeouts(char *page, char **start, off_t off,
-				      int count, int *eof, void *data)
+static inline int lprocfs_rd_timeouts(struct seq_file *m, void *data)
 { return 0; }
 static inline int lprocfs_wr_timeouts(struct file *file,
 				      const char *buffer,
 				      unsigned long count, void *data)
 { return 0; }
-static inline int lprocfs_wr_evict_client(struct file *file,
-					  const char *buffer,
-					  unsigned long count, void *data)
+static inline int lprocfs_wr_evict_client(struct file *file, const char *buffer,
+				    size_t count, loff_t *off)
 { return 0; }
 static inline int lprocfs_wr_ping(struct file *file, const char *buffer,
-				  unsigned long count, void *data)
+			   size_t count, loff_t *off)
 { return 0; }
 static inline int lprocfs_wr_import(struct file *file, const char *buffer,
-				    unsigned long count, void *data)
+			      size_t count, loff_t *off)
 { return 0; }
 static inline int lprocfs_wr_pinger_recov(struct file *file, const char *buffer,
-				    unsigned long count, void *data)
+					size_t count, loff_t *off)
 { return 0; }
 
 /* Statfs helpers */
 static inline
-int lprocfs_rd_blksize(char *page, char **start, off_t off,
-		       int count, int *eof, void *data)
-{ return 0; }
-static inline
-int lprocfs_rd_kbytestotal(char *page, char **start, off_t off,
-			   int count, int *eof, void *data)
+int lprocfs_rd_blksize(struct seq_file *m, void *data)
 { return 0; }
 static inline
-int lprocfs_rd_kbytesfree(char *page, char **start, off_t off,
-			  int count, int *eof, void *data)
+int lprocfs_rd_kbytestotal(struct seq_file *m, void *data)
 { return 0; }
 static inline
-int lprocfs_rd_kbytesavail(char *page, char **start, off_t off,
-			   int count, int *eof, void *data)
+int lprocfs_rd_kbytesfree(struct seq_file *m, void *data)
 { return 0; }
 static inline
-int lprocfs_rd_filestotal(char *page, char **start, off_t off,
-			  int count, int *eof, void *data)
+int lprocfs_rd_kbytesavail(struct seq_file *m, void *data)
 { return 0; }
 static inline
-int lprocfs_rd_filesfree(char *page, char **start, off_t off,
-			 int count, int *eof, void *data)
+int lprocfs_rd_filestotal(struct seq_file *m, void *data)
 { return 0; }
 static inline
-int lprocfs_rd_filegroups(char *page, char **start, off_t off,
-			  int count, int *eof, void *data)
+int lprocfs_rd_filesfree(struct seq_file *m, void *data)
 { return 0; }
 static inline
 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
@@ -1077,6 +1017,9 @@ __u64 lprocfs_stats_collector(struct lprocfs_stats *stats, int idx,
 
 #define LPROC_SEQ_FOPS_RO(name)
 #define LPROC_SEQ_FOPS(name)
+#define LPROC_SEQ_FOPS_RO_TYPE(name, type)
+#define LPROC_SEQ_FOPS_RW_TYPE(name, type)
+#define LPROC_SEQ_FOPS_WR_ONLY(name, type)
 
 /* lprocfs_jobstats.c */
 static inline
diff --git a/drivers/staging/lustre/lustre/include/lu_object.h b/drivers/staging/lustre/lustre/include/lu_object.h
index 4bd11bb..d40ad81 100644
--- a/drivers/staging/lustre/lustre/include/lu_object.h
+++ b/drivers/staging/lustre/lustre/include/lu_object.h
@@ -1281,7 +1281,7 @@ int  lu_env_refill_by_tags(struct lu_env *env, __u32 ctags, __u32 stags);
  * Output site statistical counters into a buffer. Suitable for
  * ll_rd_*()-style functions.
  */
-int lu_site_stats_print(const struct lu_site *s, char *page, int count);
+int lu_site_stats_print(const struct lu_site *s, struct seq_file *m);
 
 /**
  * Common name structure to be passed around for various name related methods.
diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm.h b/drivers/staging/lustre/lustre/include/lustre_dlm.h
index f6eaed8..317f928 100644
--- a/drivers/staging/lustre/lustre/include/lustre_dlm.h
+++ b/drivers/staging/lustre/lustre/include/lustre_dlm.h
@@ -545,6 +545,9 @@ struct ldlm_namespace {
 	/** Client side original connect flags supported by server. */
 	__u64			ns_orig_connect_flags;
 
+	/* namespace proc dir entry */
+	struct proc_dir_entry	*ns_proc_dir_entry;
+
 	/**
 	 * Position in global namespace list linking all namespaces on
 	 * the node.
diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h
index dade2fd..98fdb32 100644
--- a/drivers/staging/lustre/lustre/include/obd.h
+++ b/drivers/staging/lustre/lustre/include/obd.h
@@ -1060,6 +1060,7 @@ struct obd_device {
 	struct lprocfs_stats  *md_stats;
 
 	proc_dir_entry_t  *obd_proc_entry;
+	void		  *obd_proc_private; /* type private PDEs */
 	proc_dir_entry_t  *obd_proc_exports_entry;
 	proc_dir_entry_t  *obd_svc_procroot;
 	struct lprocfs_stats  *obd_svc_stats;
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h b/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h
index a08e6d9..141a957 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h
@@ -199,41 +199,40 @@ enum ldlm_policy_res {
 
 typedef enum ldlm_policy_res ldlm_policy_res_t;
 
-#define LDLM_POOL_PROC_READER(var, type)				    \
-	static int lprocfs_rd_##var(char *page, char **start, off_t off,    \
-				    int count, int *eof, void *data)	\
-	{								   \
-		struct ldlm_pool *pl = data;				\
-		type tmp;						   \
+#define LDLM_POOL_PROC_READER_SEQ_SHOW(var, type)			    \
+	static int lprocfs_##var##_seq_show(struct seq_file *m, void *v) \
+	{								    \
+		struct ldlm_pool *pl = m->private;			    \
+		type tmp;						    \
 									    \
 		spin_lock(&pl->pl_lock);				    \
 		tmp = pl->pl_##var;					    \
 		spin_unlock(&pl->pl_lock);				    \
 									    \
-		return lprocfs_rd_uint(page, start, off, count, eof, &tmp); \
-	}								   \
+		return lprocfs_rd_uint(m, &tmp);			    \
+	}								    \
 	struct __##var##__dummy_read {;} /* semicolon catcher */
 
 #define LDLM_POOL_PROC_WRITER(var, type)				    \
-	int lprocfs_wr_##var(struct file *file, const char *buffer,	 \
-			     unsigned long count, void *data)	       \
-	{								   \
-		struct ldlm_pool *pl = data;				\
-		type tmp;						   \
-		int rc;						     \
+	int lprocfs_wr_##var(struct file *file, const char *buffer,	    \
+			     unsigned long count, void *data)		    \
+	{								    \
+		struct ldlm_pool *pl = data;				    \
+		type tmp;						    \
+		int rc;							    \
 									    \
 		rc = lprocfs_wr_uint(file, buffer, count, &tmp);	    \
-		if (rc < 0) {					       \
+		if (rc < 0) {						    \
 			CERROR("Can't parse user input, rc = %d\n", rc);    \
-			return rc;					  \
-		}							   \
+			return rc;					    \
+		}							    \
 									    \
 		spin_lock(&pl->pl_lock);				    \
 		pl->pl_##var = tmp;					    \
 		spin_unlock(&pl->pl_lock);				    \
 									    \
-		return rc;						  \
-	}								   \
+		return rc;						    \
+	}								    \
 	struct __##var##__dummy_write {;} /* semicolon catcher */
 
 static inline int is_granted_or_cancelled(struct ldlm_lock *lock)
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
index 0604295..b3b6028 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
@@ -645,12 +645,11 @@ int ldlm_pool_setup(struct ldlm_pool *pl, int limit)
 }
 EXPORT_SYMBOL(ldlm_pool_setup);
 
-static int lprocfs_rd_pool_state(char *page, char **start, off_t off,
-				 int count, int *eof, void *data)
+static int lprocfs_pool_state_seq_show(struct seq_file *m, void *unused)
 {
 	int granted, grant_rate, cancel_rate, grant_step;
-	int nr = 0, grant_speed, grant_plan, lvf;
-	struct ldlm_pool *pl = data;
+	int grant_speed, grant_plan, lvf;
+	struct ldlm_pool *pl = m->private;
 	__u64 slv, clv;
 	__u32 limit;
 
@@ -667,35 +666,29 @@ static int lprocfs_rd_pool_state(char *page, char **start, off_t off,
 	grant_step = ldlm_pool_t2gsp(pl->pl_recalc_period);
 	spin_unlock(&pl->pl_lock);
 
-	nr += snprintf(page + nr, count - nr, "LDLM pool state (%s):\n",
-		       pl->pl_name);
-	nr += snprintf(page + nr, count - nr, "  SLV: "LPU64"\n", slv);
-	nr += snprintf(page + nr, count - nr, "  CLV: "LPU64"\n", clv);
-	nr += snprintf(page + nr, count - nr, "  LVF: %d\n", lvf);
+	seq_printf(m, "LDLM pool state (%s):\n"
+		      "  SLV: "LPU64"\n"
+		      "  CLV: "LPU64"\n"
+		      "  LVF: %d\n",
+		      pl->pl_name, slv, clv, lvf);
 
 	if (ns_is_server(ldlm_pl2ns(pl))) {
-		nr += snprintf(page + nr, count - nr, "  GSP: %d%%\n",
-			       grant_step);
-		nr += snprintf(page + nr, count - nr, "  GP:  %d\n",
-			       grant_plan);
+		seq_printf(m, "  GSP: %d%%\n"
+			      "  GP:  %d\n",
+			      grant_step, grant_plan);
 	}
-	nr += snprintf(page + nr, count - nr, "  GR:  %d\n",
-		       grant_rate);
-	nr += snprintf(page + nr, count - nr, "  CR:  %d\n",
-		       cancel_rate);
-	nr += snprintf(page + nr, count - nr, "  GS:  %d\n",
-		       grant_speed);
-	nr += snprintf(page + nr, count - nr, "  G:   %d\n",
-		       granted);
-	nr += snprintf(page + nr, count - nr, "  L:   %d\n",
-		       limit);
-	return nr;
+	seq_printf(m, "  GR:  %d\n" "  CR:  %d\n" "  GS:  %d\n"
+		      "  G:   %d\n" "  L:   %d\n",
+		      grant_rate, cancel_rate, grant_speed,
+		      granted, limit);
+
+	return 0;
 }
+LPROC_SEQ_FOPS_RO(lprocfs_pool_state);
 
-static int lprocfs_rd_grant_speed(char *page, char **start, off_t off,
-				  int count, int *eof, void *data)
+static int lprocfs_grant_speed_seq_show(struct seq_file *m, void *unused)
 {
-	struct ldlm_pool *pl = data;
+	struct ldlm_pool *pl = m->private;
 	int	       grant_speed;
 
 	spin_lock(&pl->pl_lock);
@@ -703,12 +696,36 @@ static int lprocfs_rd_grant_speed(char *page, char **start, off_t off,
 	grant_speed = atomic_read(&pl->pl_grant_rate) -
 			atomic_read(&pl->pl_cancel_rate);
 	spin_unlock(&pl->pl_lock);
-	return lprocfs_rd_uint(page, start, off, count, eof, &grant_speed);
+	return lprocfs_rd_uint(m, &grant_speed);
 }
 
-LDLM_POOL_PROC_READER(grant_plan, int);
-LDLM_POOL_PROC_READER(recalc_period, int);
+LDLM_POOL_PROC_READER_SEQ_SHOW(grant_plan, int);
+LPROC_SEQ_FOPS_RO(lprocfs_grant_plan);
+
+LDLM_POOL_PROC_READER_SEQ_SHOW(recalc_period, int);
 LDLM_POOL_PROC_WRITER(recalc_period, int);
+static ssize_t lprocfs_recalc_period_seq_write(struct file *file, const char *buf,
+					   size_t len, loff_t *off)
+{
+	struct seq_file *seq = file->private_data;
+
+	return lprocfs_wr_recalc_period(file, buf, len, seq->private);
+}
+LPROC_SEQ_FOPS(lprocfs_recalc_period);
+
+LPROC_SEQ_FOPS_RO_TYPE(ldlm_pool, u64);
+LPROC_SEQ_FOPS_RO_TYPE(ldlm_pool, atomic);
+LPROC_SEQ_FOPS_RW_TYPE(ldlm_pool_rw, atomic);
+
+LPROC_SEQ_FOPS_RO(lprocfs_grant_speed);
+
+#define LDLM_POOL_ADD_VAR(name, var, ops)			\
+	do {							\
+		snprintf(var_name, MAX_STRING_SIZE, #name);	\
+		pool_vars[0].data = var;			\
+		pool_vars[0].fops = ops;			\
+		lprocfs_add_vars(pl->pl_proc_dir, pool_vars, 0);\
+	} while (0)
 
 static int ldlm_pool_proc_init(struct ldlm_pool *pl)
 {
@@ -723,8 +740,7 @@ static int ldlm_pool_proc_init(struct ldlm_pool *pl)
 	if (!var_name)
 		RETURN(-ENOMEM);
 
-	parent_ns_proc = lprocfs_srch(ldlm_ns_proc_dir,
-				      ldlm_ns_name(ns));
+	parent_ns_proc = ns->ns_proc_dir_entry;
 	if (parent_ns_proc == NULL) {
 		CERROR("%s: proc entry is not initialized\n",
 		       ldlm_ns_name(ns));
@@ -742,58 +758,20 @@ static int ldlm_pool_proc_init(struct ldlm_pool *pl)
 	memset(pool_vars, 0, sizeof(pool_vars));
 	pool_vars[0].name = var_name;
 
-	snprintf(var_name, MAX_STRING_SIZE, "server_lock_volume");
-	pool_vars[0].data = &pl->pl_server_lock_volume;
-	pool_vars[0].read_fptr = lprocfs_rd_u64;
-	lprocfs_add_vars(pl->pl_proc_dir, pool_vars, 0);
-
-	snprintf(var_name, MAX_STRING_SIZE, "limit");
-	pool_vars[0].data = &pl->pl_limit;
-	pool_vars[0].read_fptr = lprocfs_rd_atomic;
-	pool_vars[0].write_fptr = lprocfs_wr_atomic;
-	lprocfs_add_vars(pl->pl_proc_dir, pool_vars, 0);
-
-	snprintf(var_name, MAX_STRING_SIZE, "granted");
-	pool_vars[0].data = &pl->pl_granted;
-	pool_vars[0].read_fptr = lprocfs_rd_atomic;
-	lprocfs_add_vars(pl->pl_proc_dir, pool_vars, 0);
-
-	snprintf(var_name, MAX_STRING_SIZE, "grant_speed");
-	pool_vars[0].data = pl;
-	pool_vars[0].read_fptr = lprocfs_rd_grant_speed;
-	lprocfs_add_vars(pl->pl_proc_dir, pool_vars, 0);
-
-	snprintf(var_name, MAX_STRING_SIZE, "cancel_rate");
-	pool_vars[0].data = &pl->pl_cancel_rate;
-	pool_vars[0].read_fptr = lprocfs_rd_atomic;
-	lprocfs_add_vars(pl->pl_proc_dir, pool_vars, 0);
-
-	snprintf(var_name, MAX_STRING_SIZE, "grant_rate");
-	pool_vars[0].data = &pl->pl_grant_rate;
-	pool_vars[0].read_fptr = lprocfs_rd_atomic;
-	lprocfs_add_vars(pl->pl_proc_dir, pool_vars, 0);
-
-	snprintf(var_name, MAX_STRING_SIZE, "grant_plan");
-	pool_vars[0].data = pl;
-	pool_vars[0].read_fptr = lprocfs_rd_grant_plan;
-	lprocfs_add_vars(pl->pl_proc_dir, pool_vars, 0);
-
-	snprintf(var_name, MAX_STRING_SIZE, "recalc_period");
-	pool_vars[0].data = pl;
-	pool_vars[0].read_fptr = lprocfs_rd_recalc_period;
-	pool_vars[0].write_fptr = lprocfs_wr_recalc_period;
-	lprocfs_add_vars(pl->pl_proc_dir, pool_vars, 0);
-
-	snprintf(var_name, MAX_STRING_SIZE, "lock_volume_factor");
-	pool_vars[0].data = &pl->pl_lock_volume_factor;
-	pool_vars[0].read_fptr = lprocfs_rd_atomic;
-	pool_vars[0].write_fptr = lprocfs_wr_atomic;
-	lprocfs_add_vars(pl->pl_proc_dir, pool_vars, 0);
-
-	snprintf(var_name, MAX_STRING_SIZE, "state");
-	pool_vars[0].data = pl;
-	pool_vars[0].read_fptr = lprocfs_rd_pool_state;
-	lprocfs_add_vars(pl->pl_proc_dir, pool_vars, 0);
+	LDLM_POOL_ADD_VAR("server_lock_volume", &pl->pl_server_lock_volume,
+			  &ldlm_pool_u64_fops);
+	LDLM_POOL_ADD_VAR("limit", &pl->pl_limit, &ldlm_pool_rw_atomic_fops);
+	LDLM_POOL_ADD_VAR("granted", &pl->pl_granted, &ldlm_pool_atomic_fops);
+	LDLM_POOL_ADD_VAR("grant_speed", pl, &lprocfs_grant_speed_fops);
+	LDLM_POOL_ADD_VAR("cancel_rate", &pl->pl_cancel_rate,
+			  &ldlm_pool_atomic_fops);
+	LDLM_POOL_ADD_VAR("grant_rate", &pl->pl_grant_rate,
+			  &ldlm_pool_atomic_fops);
+	LDLM_POOL_ADD_VAR("grant_plan", pl, &lprocfs_grant_plan_fops);
+	LDLM_POOL_ADD_VAR("recalc_period", pl, &lprocfs_recalc_period_fops);
+	LDLM_POOL_ADD_VAR("lock_volume_factor", &pl->pl_lock_volume_factor,
+			  &ldlm_pool_rw_atomic_fops);
+	LDLM_POOL_ADD_VAR("state", pl, &lprocfs_pool_state_fops);
 
 	pl->pl_stats = lprocfs_alloc_stats(LDLM_POOL_LAST_STAT -
 					   LDLM_POOL_FIRST_STAT, 0);
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
index 6bdfb42..f4d5b50 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
@@ -68,25 +68,27 @@ extern unsigned int ldlm_cancel_unused_locks_before_replay;
 unsigned int ldlm_dump_granted_max = 256;
 
 #ifdef LPROCFS
-static int ldlm_proc_dump_ns(struct file *file, const char *buffer,
-			     unsigned long count, void *data)
+static ssize_t lprocfs_wr_dump_ns(struct file *file, const char *buffer,
+				  size_t count, loff_t *off)
 {
 	ldlm_dump_all_namespaces(LDLM_NAMESPACE_SERVER, D_DLMTRACE);
 	ldlm_dump_all_namespaces(LDLM_NAMESPACE_CLIENT, D_DLMTRACE);
 	RETURN(count);
 }
+LPROC_SEQ_FOPS_WR_ONLY(ldlm, dump_ns);
+
+LPROC_SEQ_FOPS_RW_TYPE(ldlm_rw, uint);
+LPROC_SEQ_FOPS_RO_TYPE(ldlm, uint);
 
 int ldlm_proc_setup(void)
 {
 	int rc;
 	struct lprocfs_vars list[] = {
-		{ "dump_namespaces", NULL, ldlm_proc_dump_ns, NULL },
-		{ "dump_granted_max",
-		  lprocfs_rd_uint, lprocfs_wr_uint,
-		  &ldlm_dump_granted_max, NULL },
-		{ "cancel_unused_locks_before_replay",
-		  lprocfs_rd_uint, lprocfs_wr_uint,
-		  &ldlm_cancel_unused_locks_before_replay, NULL },
+		{ "dump_namespaces", &ldlm_dump_ns_fops, 0, 0222 },
+		{ "dump_granted_max", &ldlm_rw_uint_fops,
+		  &ldlm_dump_granted_max },
+		{ "cancel_unused_locks_before_replay", &ldlm_rw_uint_fops,
+		  &ldlm_cancel_unused_locks_before_replay },
 		{ NULL }};
 	ENTRY;
 	LASSERT(ldlm_ns_proc_dir == NULL);
@@ -143,10 +145,9 @@ void ldlm_proc_cleanup(void)
 		lprocfs_remove(&ldlm_type_proc_dir);
 }
 
-static int lprocfs_rd_ns_resources(char *page, char **start, off_t off,
-				   int count, int *eof, void *data)
+static int lprocfs_ns_resources_seq_show(struct seq_file *m, void *v)
 {
-	struct ldlm_namespace *ns  = data;
+	struct ldlm_namespace *ns  = m->private;
 	__u64		  res = 0;
 	cfs_hash_bd_t	  bd;
 	int		    i;
@@ -154,35 +155,35 @@ static int lprocfs_rd_ns_resources(char *page, char **start, off_t off,
 	/* result is not strictly consistant */
 	cfs_hash_for_each_bucket(ns->ns_rs_hash, &bd, i)
 		res += cfs_hash_bd_count_get(&bd);
-	return lprocfs_rd_u64(page, start, off, count, eof, &res);
+	return lprocfs_rd_u64(m, &res);
 }
+LPROC_SEQ_FOPS_RO(lprocfs_ns_resources);
 
-static int lprocfs_rd_ns_locks(char *page, char **start, off_t off,
-			       int count, int *eof, void *data)
+static int lprocfs_ns_locks_seq_show(struct seq_file *m, void *v)
 {
-	struct ldlm_namespace *ns = data;
+	struct ldlm_namespace *ns = m->private;
 	__u64		  locks;
 
 	locks = lprocfs_stats_collector(ns->ns_stats, LDLM_NSS_LOCKS,
 					LPROCFS_FIELDS_FLAGS_SUM);
-	return lprocfs_rd_u64(page, start, off, count, eof, &locks);
+	return lprocfs_rd_u64(m, &locks);
 }
+LPROC_SEQ_FOPS_RO(lprocfs_ns_locks);
 
-static int lprocfs_rd_lru_size(char *page, char **start, off_t off,
-			       int count, int *eof, void *data)
+static int lprocfs_lru_size_seq_show(struct seq_file *m, void *v)
 {
-	struct ldlm_namespace *ns = data;
+	struct ldlm_namespace *ns = m->private;
 	__u32 *nr = &ns->ns_max_unused;
 
 	if (ns_connect_lru_resize(ns))
 		nr = &ns->ns_nr_unused;
-	return lprocfs_rd_uint(page, start, off, count, eof, nr);
+	return lprocfs_rd_uint(m, nr);
 }
 
-static int lprocfs_wr_lru_size(struct file *file, const char *buffer,
-			       unsigned long count, void *data)
+static ssize_t lprocfs_lru_size_seq_write(struct file *file, const char *buffer,
+				      size_t count, loff_t *off)
 {
-	struct ldlm_namespace *ns = data;
+	struct ldlm_namespace *ns = ((struct seq_file *)file->private_data)->private;
 	char dummy[MAX_STRING_SIZE + 1], *end;
 	unsigned long tmp;
 	int lru_resize;
@@ -265,20 +266,20 @@ static int lprocfs_wr_lru_size(struct file *file, const char *buffer,
 
 	return count;
 }
+LPROC_SEQ_FOPS(lprocfs_lru_size);
 
-static int lprocfs_rd_elc(char *page, char **start, off_t off,
-			  int count, int *eof, void *data)
+static int lprocfs_elc_seq_show(struct seq_file *m, void *v)
 {
-	struct ldlm_namespace *ns = data;
+	struct ldlm_namespace *ns = m->private;
 	unsigned int supp = ns_connect_cancelset(ns);
 
-	return lprocfs_rd_uint(page, start, off, count, eof, &supp);
+	return lprocfs_rd_uint(m, &supp);
 }
 
-static int lprocfs_wr_elc(struct file *file, const char *buffer,
-			       unsigned long count, void *data)
+static ssize_t lprocfs_elc_seq_write(struct file *file, const char *buffer,
+				 size_t count, loff_t *off)
 {
-	struct ldlm_namespace *ns = data;
+	struct ldlm_namespace *ns = ((struct seq_file *)file->private_data)->private;
 	unsigned int supp = -1;
 	int rc;
 
@@ -292,31 +293,46 @@ static int lprocfs_wr_elc(struct file *file, const char *buffer,
 		ns->ns_connect_flags |= OBD_CONNECT_CANCELSET;
 	return count;
 }
+LPROC_SEQ_FOPS(lprocfs_elc);
 
 void ldlm_namespace_proc_unregister(struct ldlm_namespace *ns)
 {
-	struct proc_dir_entry *dir;
-
-	dir = lprocfs_srch(ldlm_ns_proc_dir, ldlm_ns_name(ns));
-	if (dir == NULL) {
+	if (ns->ns_proc_dir_entry == NULL)
 		CERROR("dlm namespace %s has no procfs dir?\n",
 		       ldlm_ns_name(ns));
-	} else {
-		lprocfs_remove(&dir);
-	}
+	else
+		lprocfs_remove(&ns->ns_proc_dir_entry);
 
 	if (ns->ns_stats != NULL)
 		lprocfs_free_stats(&ns->ns_stats);
 }
 
+#define LDLM_NS_ADD_VAR(name, var, ops)				\
+	do {							\
+		snprintf(lock_name, MAX_STRING_SIZE, name);	\
+		lock_vars[0].data = var;			\
+		lock_vars[0].fops = ops;			\
+		lprocfs_add_vars(ns_pde, lock_vars, 0);		\
+	} while (0)
+
 int ldlm_namespace_proc_register(struct ldlm_namespace *ns)
 {
 	struct lprocfs_vars lock_vars[2];
 	char lock_name[MAX_STRING_SIZE + 1];
+	proc_dir_entry_t *ns_pde;
 
 	LASSERT(ns != NULL);
 	LASSERT(ns->ns_rs_hash != NULL);
 
+	if (ns->ns_proc_dir_entry != NULL) {
+		ns_pde = ns->ns_proc_dir_entry;
+	} else {
+		ns_pde = proc_mkdir(ldlm_ns_name(ns), ldlm_ns_proc_dir);
+		if (ns_pde == NULL)
+			return -ENOMEM;
+		ns->ns_proc_dir_entry = ns_pde;
+	}
+
 	ns->ns_stats = lprocfs_alloc_stats(LDLM_NSS_LAST, 0);
 	if (ns->ns_stats == NULL)
 		return -ENOMEM;
@@ -329,86 +345,29 @@ int ldlm_namespace_proc_register(struct ldlm_namespace *ns)
 	memset(lock_vars, 0, sizeof(lock_vars));
 	lock_vars[0].name = lock_name;
 
-	snprintf(lock_name, MAX_STRING_SIZE, "%s/resource_count",
-		 ldlm_ns_name(ns));
-	lock_vars[0].data = ns;
-	lock_vars[0].read_fptr = lprocfs_rd_ns_resources;
-	lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0);
-
-	snprintf(lock_name, MAX_STRING_SIZE, "%s/lock_count",
-		 ldlm_ns_name(ns));
-	lock_vars[0].data = ns;
-	lock_vars[0].read_fptr = lprocfs_rd_ns_locks;
-	lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0);
+	LDLM_NS_ADD_VAR("resource_count", ns, &lprocfs_ns_resources_fops);
+	LDLM_NS_ADD_VAR("lock_count", ns, &lprocfs_ns_locks_fops);
 
 	if (ns_is_client(ns)) {
-		snprintf(lock_name, MAX_STRING_SIZE, "%s/lock_unused_count",
-			 ldlm_ns_name(ns));
-		lock_vars[0].data = &ns->ns_nr_unused;
-		lock_vars[0].read_fptr = lprocfs_rd_uint;
-		lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0);
-
-		snprintf(lock_name, MAX_STRING_SIZE, "%s/lru_size",
-			 ldlm_ns_name(ns));
-		lock_vars[0].data = ns;
-		lock_vars[0].read_fptr = lprocfs_rd_lru_size;
-		lock_vars[0].write_fptr = lprocfs_wr_lru_size;
-		lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0);
-
-		snprintf(lock_name, MAX_STRING_SIZE, "%s/lru_max_age",
-			 ldlm_ns_name(ns));
-		lock_vars[0].data = &ns->ns_max_age;
-		lock_vars[0].read_fptr = lprocfs_rd_uint;
-		lock_vars[0].write_fptr = lprocfs_wr_uint;
-		lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0);
-
-		snprintf(lock_name, MAX_STRING_SIZE, "%s/early_lock_cancel",
-			 ldlm_ns_name(ns));
-		lock_vars[0].data = ns;
-		lock_vars[0].read_fptr = lprocfs_rd_elc;
-		lock_vars[0].write_fptr = lprocfs_wr_elc;
-		lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0);
+		LDLM_NS_ADD_VAR("lock_unused_count", &ns->ns_nr_unused,
+				&ldlm_uint_fops);
+		LDLM_NS_ADD_VAR("lru_size", ns, &lprocfs_lru_size_fops);
+		LDLM_NS_ADD_VAR("lru_max_age", &ns->ns_max_age,
+				&ldlm_rw_uint_fops);
+		LDLM_NS_ADD_VAR("early_lock_cancel", ns, &lprocfs_elc_fops);
 	} else {
-		snprintf(lock_name, MAX_STRING_SIZE, "%s/ctime_age_limit",
-			 ldlm_ns_name(ns));
-		lock_vars[0].data = &ns->ns_ctime_age_limit;
-		lock_vars[0].read_fptr = lprocfs_rd_uint;
-		lock_vars[0].write_fptr = lprocfs_wr_uint;
-		lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0);
-
-		snprintf(lock_name, MAX_STRING_SIZE, "%s/lock_timeouts",
-			 ldlm_ns_name(ns));
-		lock_vars[0].data = &ns->ns_timeouts;
-		lock_vars[0].read_fptr = lprocfs_rd_uint;
-		lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0);
-
-		snprintf(lock_name, MAX_STRING_SIZE, "%s/max_nolock_bytes",
-			 ldlm_ns_name(ns));
-		lock_vars[0].data = &ns->ns_max_nolock_size;
-		lock_vars[0].read_fptr = lprocfs_rd_uint;
-		lock_vars[0].write_fptr = lprocfs_wr_uint;
-		lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0);
-
-		snprintf(lock_name, MAX_STRING_SIZE, "%s/contention_seconds",
-			 ldlm_ns_name(ns));
-		lock_vars[0].data = &ns->ns_contention_time;
-		lock_vars[0].read_fptr = lprocfs_rd_uint;
-		lock_vars[0].write_fptr = lprocfs_wr_uint;
-		lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0);
-
-		snprintf(lock_name, MAX_STRING_SIZE, "%s/contended_locks",
-			 ldlm_ns_name(ns));
-		lock_vars[0].data = &ns->ns_contended_locks;
-		lock_vars[0].read_fptr = lprocfs_rd_uint;
-		lock_vars[0].write_fptr = lprocfs_wr_uint;
-		lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0);
-
-		snprintf(lock_name, MAX_STRING_SIZE, "%s/max_parallel_ast",
-			 ldlm_ns_name(ns));
-		lock_vars[0].data = &ns->ns_max_parallel_ast;
-		lock_vars[0].read_fptr = lprocfs_rd_uint;
-		lock_vars[0].write_fptr = lprocfs_wr_uint;
-		lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0);
+		LDLM_NS_ADD_VAR("ctime_age_limit", &ns->ns_ctime_age_limit,
+				&ldlm_rw_uint_fops);
+		LDLM_NS_ADD_VAR("lock_timeouts", &ns->ns_timeouts,
+				&ldlm_uint_fops);
+		LDLM_NS_ADD_VAR("max_nolock_bytes", &ns->ns_max_nolock_size,
+				&ldlm_rw_uint_fops);
+		LDLM_NS_ADD_VAR("contention_seconds", &ns->ns_contention_time,
+				&ldlm_rw_uint_fops);
+		LDLM_NS_ADD_VAR("contended_locks", &ns->ns_contended_locks,
+				&ldlm_rw_uint_fops);
+		LDLM_NS_ADD_VAR("max_parallel_ast", &ns->ns_max_parallel_ast,
+				&ldlm_rw_uint_fops);
 	}
 	return 0;
 }
diff --git a/drivers/staging/lustre/lustre/libcfs/hash.c b/drivers/staging/lustre/lustre/libcfs/hash.c
index 231c678..98c76df 100644
--- a/drivers/staging/lustre/lustre/libcfs/hash.c
+++ b/drivers/staging/lustre/lustre/libcfs/hash.c
@@ -108,6 +108,7 @@
  */
 
 #include <linux/libcfs/libcfs.h>
+#include <linux/seq_file.h>
 
 #if CFS_HASH_DEBUG_LEVEL >= CFS_HASH_DEBUG_1
 static unsigned int warn_on_depth = 8;
@@ -2027,9 +2028,9 @@ void cfs_hash_rehash_key(cfs_hash_t *hs, const void *old_key,
 }
 EXPORT_SYMBOL(cfs_hash_rehash_key);
 
-int cfs_hash_debug_header(char *str, int size)
+int cfs_hash_debug_header(struct seq_file *m)
 {
-	return snprintf(str, size, "%-*s%6s%6s%6s%6s%6s%6s%6s%7s%8s%8s%8s%s\n",
+	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",
@@ -2061,38 +2062,28 @@ cfs_hash_full_nbkt(cfs_hash_t *hs)
 	       CFS_HASH_RH_NBKT(hs) : CFS_HASH_NBKT(hs);
 }
 
-int cfs_hash_debug_str(cfs_hash_t *hs, char *str, int size)
+int cfs_hash_debug_str(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;
 
-	if (str == NULL || size == 0)
-		return 0;
-
 	cfs_hash_lock(hs, 0);
 	theta = __cfs_hash_theta(hs);
 
-	c += snprintf(str + c, size - c, "%-*s ",
-		      CFS_HASH_BIGNAME_LEN, hs->hs_name);
-	c += snprintf(str + c, size - c, "%5d ",  1 << hs->hs_cur_bits);
-	c += snprintf(str + c, size - c, "%5d ",  1 << hs->hs_min_bits);
-	c += snprintf(str + c, size - c, "%5d ",  1 << hs->hs_max_bits);
-	c += snprintf(str + c, size - c, "%d.%03d ",
-		      __cfs_hash_theta_int(theta),
-		      __cfs_hash_theta_frac(theta));
-	c += snprintf(str + c, size - c, "%d.%03d ",
+	seq_printf(m, "%-*s %5d %5d %5d %d.%03d %d.%03d %d.%03d  0x%02x %6d ",
+		      CFS_HASH_BIGNAME_LEN, hs->hs_name,
+		      1 << hs->hs_cur_bits, 1 << hs->hs_min_bits,
+		      1 << hs->hs_max_bits,
+		      __cfs_hash_theta_int(theta), __cfs_hash_theta_frac(theta),
 		      __cfs_hash_theta_int(hs->hs_min_theta),
-		      __cfs_hash_theta_frac(hs->hs_min_theta));
-	c += snprintf(str + c, size - c, "%d.%03d ",
+		      __cfs_hash_theta_frac(hs->hs_min_theta),
 		      __cfs_hash_theta_int(hs->hs_max_theta),
-		      __cfs_hash_theta_frac(hs->hs_max_theta));
-	c += snprintf(str + c, size - c, " 0x%02x ", hs->hs_flags);
-	c += snprintf(str + c, size - c, "%6d ", hs->hs_rehash_count);
+		      __cfs_hash_theta_frac(hs->hs_max_theta),
+		      hs->hs_flags, hs->hs_rehash_count);
 
 	/*
 	 * The distribution is a summary of the chained hash depth in
@@ -2121,15 +2112,12 @@ int cfs_hash_debug_str(cfs_hash_t *hs, char *str, int size)
 		cfs_hash_bd_unlock(hs, &bd, 0);
 	}
 
-	c += snprintf(str + c, size - c, "%7d ", total);
-	c += snprintf(str + c, size - c, "%7d ", maxdep);
-	c += snprintf(str + c, size - c, "%7d ", maxdepb);
+	seq_printf(m, "%7d %7d %7d ", total, maxdep, maxdepb);
 	for (i = 0; i < 8; i++)
-		c += snprintf(str + c, size - c, "%d%c",  dist[i],
-			      (i == 7) ? '\n' : '/');
+		seq_printf(m, "%d%c",  dist[i], (i == 7) ? '\n' : '/');
 
 	cfs_hash_unlock(hs, 0);
 
-	return c;
+	return 0;
 }
 EXPORT_SYMBOL(cfs_hash_debug_str);
diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c
index 22e19a6..f71b15b 100644
--- a/drivers/staging/lustre/lustre/llite/lproc_llite.c
+++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c
@@ -52,10 +52,9 @@ struct file_operations ll_rw_extents_stats_fops;
 struct file_operations ll_rw_extents_stats_pp_fops;
 struct file_operations ll_rw_offset_stats_fops;
 
-static int ll_rd_blksize(char *page, char **start, off_t off, int count,
-			 int *eof, void *data)
+static int ll_blksize_seq_show(struct seq_file *m, void *v)
 {
-	struct super_block *sb = (struct super_block *)data;
+	struct super_block *sb = (struct super_block *)m->private;
 	struct obd_statfs osfs;
 	int rc;
 
@@ -63,18 +62,16 @@ static int ll_rd_blksize(char *page, char **start, off_t off, int count,
 	rc = ll_statfs_internal(sb, &osfs,
 				cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
 				OBD_STATFS_NODELAY);
-	if (!rc) {
-	      *eof = 1;
-	      rc = snprintf(page, count, "%u\n", osfs.os_bsize);
-	}
+	if (!rc)
+	      rc = seq_printf(m, "%u\n", osfs.os_bsize);
 
 	return rc;
 }
+LPROC_SEQ_FOPS_RO(ll_blksize);
 
-static int ll_rd_kbytestotal(char *page, char **start, off_t off, int count,
-			     int *eof, void *data)
+static int ll_kbytestotal_seq_show(struct seq_file *m, void *v)
 {
-	struct super_block *sb = (struct super_block *)data;
+	struct super_block *sb = (struct super_block *)m->private;
 	struct obd_statfs osfs;
 	int rc;
 
@@ -89,17 +86,15 @@ static int ll_rd_kbytestotal(char *page, char **start, off_t off, int count,
 		while (blk_size >>= 1)
 			result <<= 1;
 
-		*eof = 1;
-		rc = snprintf(page, count, LPU64"\n", result);
+		rc = seq_printf(m, LPU64"\n", result);
 	}
 	return rc;
-
 }
+LPROC_SEQ_FOPS_RO(ll_kbytestotal);
 
-static int ll_rd_kbytesfree(char *page, char **start, off_t off, int count,
-			    int *eof, void *data)
+static int ll_kbytesfree_seq_show(struct seq_file *m, void *v)
 {
-	struct super_block *sb = (struct super_block *)data;
+	struct super_block *sb = (struct super_block *)m->private;
 	struct obd_statfs osfs;
 	int rc;
 
@@ -114,16 +109,15 @@ static int ll_rd_kbytesfree(char *page, char **start, off_t off, int count,
 		while (blk_size >>= 1)
 			result <<= 1;
 
-		*eof = 1;
-		rc = snprintf(page, count, LPU64"\n", result);
+		rc = seq_printf(m, LPU64"\n", result);
 	}
 	return rc;
 }
+LPROC_SEQ_FOPS_RO(ll_kbytesfree);
 
-static int ll_rd_kbytesavail(char *page, char **start, off_t off, int count,
-			     int *eof, void *data)
+static int ll_kbytesavail_seq_show(struct seq_file *m, void *v)
 {
-	struct super_block *sb = (struct super_block *)data;
+	struct super_block *sb = (struct super_block *)m->private;
 	struct obd_statfs osfs;
 	int rc;
 
@@ -138,16 +132,15 @@ static int ll_rd_kbytesavail(char *page, char **start, off_t off, int count,
 		while (blk_size >>= 1)
 			result <<= 1;
 
-		*eof = 1;
-		rc = snprintf(page, count, LPU64"\n", result);
+		rc = seq_printf(m, LPU64"\n", result);
 	}
 	return rc;
 }
+LPROC_SEQ_FOPS_RO(ll_kbytesavail);
 
-static int ll_rd_filestotal(char *page, char **start, off_t off, int count,
-			    int *eof, void *data)
+static int ll_filestotal_seq_show(struct seq_file *m, void *v)
 {
-	struct super_block *sb = (struct super_block *)data;
+	struct super_block *sb = (struct super_block *)m->private;
 	struct obd_statfs osfs;
 	int rc;
 
@@ -155,17 +148,15 @@ static int ll_rd_filestotal(char *page, char **start, off_t off, int count,
 	rc = ll_statfs_internal(sb, &osfs,
 				cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
 				OBD_STATFS_NODELAY);
-	if (!rc) {
-		 *eof = 1;
-		 rc = snprintf(page, count, LPU64"\n", osfs.os_files);
-	}
+	if (!rc)
+		 rc = seq_printf(m, LPU64"\n", osfs.os_files);
 	return rc;
 }
+LPROC_SEQ_FOPS_RO(ll_filestotal);
 
-static int ll_rd_filesfree(char *page, char **start, off_t off, int count,
-			   int *eof, void *data)
+static int ll_filesfree_seq_show(struct seq_file *m, void *v)
 {
-	struct super_block *sb = (struct super_block *)data;
+	struct super_block *sb = (struct super_block *)m->private;
 	struct obd_statfs osfs;
 	int rc;
 
@@ -173,68 +164,61 @@ static int ll_rd_filesfree(char *page, char **start, off_t off, int count,
 	rc = ll_statfs_internal(sb, &osfs,
 				cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
 				OBD_STATFS_NODELAY);
-	if (!rc) {
-		 *eof = 1;
-		 rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
-	}
+	if (!rc)
+		 rc = seq_printf(m, LPU64"\n", osfs.os_ffree);
 	return rc;
-
 }
+LPROC_SEQ_FOPS_RO(ll_filesfree);
 
-static int ll_rd_client_type(char *page, char **start, off_t off, int count,
-			    int *eof, void *data)
+static int ll_client_type_seq_show(struct seq_file *m, void *v)
 {
-	struct ll_sb_info *sbi = ll_s2sbi((struct super_block *)data);
+	struct ll_sb_info *sbi = ll_s2sbi((struct super_block *)m->private);
 	int rc;
 
 	LASSERT(sbi != NULL);
 
-	*eof = 1;
 	if (sbi->ll_flags & LL_SBI_RMT_CLIENT)
-		rc = snprintf(page, count, "remote client\n");
+		rc = seq_printf(m, "remote client\n");
 	else
-		rc = snprintf(page, count, "local client\n");
+		rc = seq_printf(m, "local client\n");
 
 	return rc;
 }
+LPROC_SEQ_FOPS_RO(ll_client_type);
 
-static int ll_rd_fstype(char *page, char **start, off_t off, int count,
-			int *eof, void *data)
+static int ll_fstype_seq_show(struct seq_file *m, void *v)
 {
-	struct super_block *sb = (struct super_block*)data;
+	struct super_block *sb = (struct super_block *)m->private;
 
 	LASSERT(sb != NULL);
-	*eof = 1;
-	return snprintf(page, count, "%s\n", sb->s_type->name);
+	return seq_printf(m, "%s\n", sb->s_type->name);
 }
+LPROC_SEQ_FOPS_RO(ll_fstype);
 
-static int ll_rd_sb_uuid(char *page, char **start, off_t off, int count,
-			 int *eof, void *data)
+static int ll_sb_uuid_seq_show(struct seq_file *m, void *v)
 {
-	struct super_block *sb = (struct super_block *)data;
+	struct super_block *sb = (struct super_block *)m->private;
 
 	LASSERT(sb != NULL);
-	*eof = 1;
-	return snprintf(page, count, "%s\n", ll_s2sbi(sb)->ll_sb_uuid.uuid);
+	return seq_printf(m, "%s\n", ll_s2sbi(sb)->ll_sb_uuid.uuid);
 }
+LPROC_SEQ_FOPS_RO(ll_sb_uuid);
 
-static int ll_rd_site_stats(char *page, char **start, off_t off,
-			    int count, int *eof, void *data)
+static int ll_site_stats_seq_show(struct seq_file *m, void *v)
 {
-	struct super_block *sb = data;
+	struct super_block *sb = m->private;
 
 	/*
 	 * See description of statistical counters in struct cl_site, and
 	 * struct lu_site.
 	 */
-	return cl_site_stats_print(lu2cl_site(ll_s2sbi(sb)->ll_site),
-				   page, count);
+	return cl_site_stats_print(lu2cl_site(ll_s2sbi(sb)->ll_site), m);
 }
+LPROC_SEQ_FOPS_RO(ll_site_stats);
 
-static int ll_rd_max_readahead_mb(char *page, char **start, off_t off,
-				   int count, int *eof, void *data)
+static int ll_max_readahead_mb_seq_show(struct seq_file *m, void *v)
 {
-	struct super_block *sb = data;
+	struct super_block *sb = m->private;
 	struct ll_sb_info *sbi = ll_s2sbi(sb);
 	long pages_number;
 	int mult;
@@ -244,13 +228,13 @@ static int ll_rd_max_readahead_mb(char *page, char **start, off_t off,
 	spin_unlock(&sbi->ll_lock);
 
 	mult = 1 << (20 - PAGE_CACHE_SHIFT);
-	return lprocfs_read_frac_helper(page, count, pages_number, mult);
+	return lprocfs_seq_read_frac_helper(m, pages_number, mult);
 }
 
-static int ll_wr_max_readahead_mb(struct file *file, const char *buffer,
-				  unsigned long count, void *data)
+static ssize_t ll_max_readahead_mb_seq_write(struct file *file, const char *buffer,
+					 size_t count, loff_t *off)
 {
-	struct super_block *sb = data;
+	struct super_block *sb = ((struct seq_file *)file->private_data)->private;
 	struct ll_sb_info *sbi = ll_s2sbi(sb);
 	int mult, rc, pages_number;
 
@@ -271,11 +255,11 @@ static int ll_wr_max_readahead_mb(struct file *file, const char *buffer,
 
 	return count;
 }
+LPROC_SEQ_FOPS(ll_max_readahead_mb);
 
-static int ll_rd_max_readahead_per_file_mb(char *page, char **start, off_t off,
-					   int count, int *eof, void *data)
+static int ll_max_readahead_per_file_mb_seq_show(struct seq_file *m, void *v)
 {
-	struct super_block *sb = data;
+	struct super_block *sb = m->private;
 	struct ll_sb_info *sbi = ll_s2sbi(sb);
 	long pages_number;
 	int mult;
@@ -285,13 +269,14 @@ static int ll_rd_max_readahead_per_file_mb(char *page, char **start, off_t off,
 	spin_unlock(&sbi->ll_lock);
 
 	mult = 1 << (20 - PAGE_CACHE_SHIFT);
-	return lprocfs_read_frac_helper(page, count, pages_number, mult);
+	return lprocfs_seq_read_frac_helper(m, pages_number, mult);
 }
 
-static int ll_wr_max_readahead_per_file_mb(struct file *file, const char *buffer,
-					  unsigned long count, void *data)
+static ssize_t ll_max_readahead_per_file_mb_seq_write(struct file *file,
+						  const char *buffer,
+						  size_t count, loff_t *off)
 {
-	struct super_block *sb = data;
+	struct super_block *sb = ((struct seq_file *)file->private_data)->private;
 	struct ll_sb_info *sbi = ll_s2sbi(sb);
 	int mult, rc, pages_number;
 
@@ -314,11 +299,11 @@ static int ll_wr_max_readahead_per_file_mb(struct file *file, const char *buffer
 
 	return count;
 }
+LPROC_SEQ_FOPS(ll_max_readahead_per_file_mb);
 
-static int ll_rd_max_read_ahead_whole_mb(char *page, char **start, off_t off,
-					 int count, int *eof, void *data)
+static int ll_max_read_ahead_whole_mb_seq_show(struct seq_file *m, void *unused)
 {
-	struct super_block *sb = data;
+	struct super_block *sb = m->private;
 	struct ll_sb_info *sbi = ll_s2sbi(sb);
 	long pages_number;
 	int mult;
@@ -328,13 +313,14 @@ static int ll_rd_max_read_ahead_whole_mb(char *page, char **start, off_t off,
 	spin_unlock(&sbi->ll_lock);
 
 	mult = 1 << (20 - PAGE_CACHE_SHIFT);
-	return lprocfs_read_frac_helper(page, count, pages_number, mult);
+	return lprocfs_seq_read_frac_helper(m, pages_number, mult);
 }
 
-static int ll_wr_max_read_ahead_whole_mb(struct file *file, const char *buffer,
-					 unsigned long count, void *data)
+static ssize_t ll_max_read_ahead_whole_mb_seq_write(struct file *file,
+						const char *buffer,
+						size_t count, loff_t *off)
 {
-	struct super_block *sb = data;
+	struct super_block *sb = ((struct seq_file *)file->private_data)->private;
 	struct ll_sb_info *sbi = ll_s2sbi(sb);
 	int mult, rc, pages_number;
 
@@ -359,21 +345,20 @@ static int ll_wr_max_read_ahead_whole_mb(struct file *file, const char *buffer,
 
 	return count;
 }
+LPROC_SEQ_FOPS(ll_max_read_ahead_whole_mb);
 
-static int ll_rd_max_cached_mb(char *page, char **start, off_t off,
-			       int count, int *eof, void *data)
+static int ll_max_cached_mb_seq_show(struct seq_file *m, void *v)
 {
-	struct super_block     *sb    = data;
+	struct super_block     *sb    = m->private;
 	struct ll_sb_info      *sbi   = ll_s2sbi(sb);
 	struct cl_client_cache *cache = &sbi->ll_cache;
 	int shift = 20 - PAGE_CACHE_SHIFT;
 	int max_cached_mb;
 	int unused_mb;
 
-	*eof = 1;
 	max_cached_mb = cache->ccc_lru_max >> shift;
 	unused_mb = atomic_read(&cache->ccc_lru_left) >> shift;
-	return snprintf(page, count,
+	return seq_printf(m,
 			"users: %d\n"
 			"max_cached_mb: %d\n"
 			"used_mb: %d\n"
@@ -386,10 +371,10 @@ static int ll_rd_max_cached_mb(char *page, char **start, off_t off,
 			cache->ccc_lru_shrinkers);
 }
 
-static int ll_wr_max_cached_mb(struct file *file, const char *buffer,
-			       unsigned long count, void *data)
+static ssize_t ll_max_cached_mb_seq_write(struct file *file, const char *buffer,
+				      size_t count, loff_t *off)
 {
-	struct super_block *sb = data;
+	struct super_block *sb = ((struct seq_file *)file->private_data)->private;
 	struct ll_sb_info *sbi = ll_s2sbi(sb);
 	struct cl_client_cache *cache = &sbi->ll_cache;
 	int mult, rc, pages_number;
@@ -468,21 +453,20 @@ out:
 	}
 	return rc;
 }
+LPROC_SEQ_FOPS(ll_max_cached_mb);
 
-static int ll_rd_checksum(char *page, char **start, off_t off,
-			  int count, int *eof, void *data)
+static int ll_checksum_seq_show(struct seq_file *m, void *v)
 {
-	struct super_block *sb = data;
+	struct super_block *sb = m->private;
 	struct ll_sb_info *sbi = ll_s2sbi(sb);
 
-	return snprintf(page, count, "%u\n",
-			(sbi->ll_flags & LL_SBI_CHECKSUM) ? 1 : 0);
+	return seq_printf(m, "%u\n", (sbi->ll_flags & LL_SBI_CHECKSUM) ? 1 : 0);
 }
 
-static int ll_wr_checksum(struct file *file, const char *buffer,
-			  unsigned long count, void *data)
+static ssize_t ll_checksum_seq_write(struct file *file, const char *buffer,
+				 size_t count, loff_t *off)
 {
-	struct super_block *sb = data;
+	struct super_block *sb = ((struct seq_file *)file->private_data)->private;
 	struct ll_sb_info *sbi = ll_s2sbi(sb);
 	int val, rc;
 
@@ -505,19 +489,19 @@ static int ll_wr_checksum(struct file *file, const char *buffer,
 
 	return count;
 }
+LPROC_SEQ_FOPS(ll_checksum);
 
-static int ll_rd_max_rw_chunk(char *page, char **start, off_t off,
-			  int count, int *eof, void *data)
+static int ll_max_rw_chunk_seq_show(struct seq_file *m, void *v)
 {
-	struct super_block *sb = data;
+	struct super_block *sb = m->private;
 
-	return snprintf(page, count, "%lu\n", ll_s2sbi(sb)->ll_max_rw_chunk);
+	return seq_printf(m, "%lu\n", ll_s2sbi(sb)->ll_max_rw_chunk);
 }
 
-static int ll_wr_max_rw_chunk(struct file *file, const char *buffer,
-			  unsigned long count, void *data)
+static ssize_t ll_max_rw_chunk_seq_write(struct file *file, const char *buffer,
+				     size_t count, loff_t *off)
 {
-	struct super_block *sb = data;
+	struct super_block *sb = ((struct seq_file *)file->private_data)->private;
 	int rc, val;
 
 	rc = lprocfs_write_helper(buffer, count, &val);
@@ -526,20 +510,20 @@ static int ll_wr_max_rw_chunk(struct file *file, const char *buffer,
 	ll_s2sbi(sb)->ll_max_rw_chunk = val;
 	return count;
 }
+LPROC_SEQ_FOPS(ll_max_rw_chunk);
 
-static int ll_rd_track_id(char *page, int count, void *data,
-			  enum stats_track_type type)
+static int ll_rd_track_id(struct seq_file *m, enum stats_track_type type)
 {
-	struct super_block *sb = data;
+	struct super_block *sb = m->private;
 
 	if (ll_s2sbi(sb)->ll_stats_track_type == type) {
-		return snprintf(page, count, "%d\n",
+		return seq_printf(m, "%d\n",
 				ll_s2sbi(sb)->ll_stats_track_id);
 
 	} else if (ll_s2sbi(sb)->ll_stats_track_type == STATS_TRACK_ALL) {
-		return snprintf(page, count, "0 (all)\n");
+		return seq_printf(m, "0 (all)\n");
 	} else {
-		return snprintf(page, count, "untracked\n");
+		return seq_printf(m, "untracked\n");
 	}
 }
 
@@ -561,55 +545,57 @@ static int ll_wr_track_id(const char *buffer, unsigned long count, void *data,
 	return count;
 }
 
-static int ll_rd_track_pid(char *page, char **start, off_t off,
-			  int count, int *eof, void *data)
+static int ll_track_pid_seq_show(struct seq_file *m, void *v)
 {
-	return (ll_rd_track_id(page, count, data, STATS_TRACK_PID));
+	return ll_rd_track_id(m, STATS_TRACK_PID);
 }
 
-static int ll_wr_track_pid(struct file *file, const char *buffer,
-			  unsigned long count, void *data)
+static ssize_t ll_track_pid_seq_write(struct file *file, const char *buffer,
+				  size_t count, loff_t *off)
 {
-	return (ll_wr_track_id(buffer, count, data, STATS_TRACK_PID));
+	struct seq_file *seq = file->private_data;
+	return ll_wr_track_id(buffer, count, seq->private, STATS_TRACK_PID);
 }
+LPROC_SEQ_FOPS(ll_track_pid);
 
-static int ll_rd_track_ppid(char *page, char **start, off_t off,
-			  int count, int *eof, void *data)
+static int ll_track_ppid_seq_show(struct seq_file *m, void *v)
 {
-	return (ll_rd_track_id(page, count, data, STATS_TRACK_PPID));
+	return ll_rd_track_id(m, STATS_TRACK_PPID);
 }
 
-static int ll_wr_track_ppid(struct file *file, const char *buffer,
-			  unsigned long count, void *data)
+static ssize_t ll_track_ppid_seq_write(struct file *file, const char *buffer,
+				   size_t count, loff_t *off)
 {
-	return (ll_wr_track_id(buffer, count, data, STATS_TRACK_PPID));
+	struct seq_file *seq = file->private_data;
+	return ll_wr_track_id(buffer, count, seq->private, STATS_TRACK_PPID);
 }
+LPROC_SEQ_FOPS(ll_track_ppid);
 
-static int ll_rd_track_gid(char *page, char **start, off_t off,
-			  int count, int *eof, void *data)
+static int ll_track_gid_seq_show(struct seq_file *m, void *v)
 {
-	return (ll_rd_track_id(page, count, data, STATS_TRACK_GID));
+	return ll_rd_track_id(m, STATS_TRACK_GID);
 }
 
-static int ll_wr_track_gid(struct file *file, const char *buffer,
-			  unsigned long count, void *data)
+static ssize_t ll_track_gid_seq_write(struct file *file, const char *buffer,
+				  size_t count, loff_t *off)
 {
-	return (ll_wr_track_id(buffer, count, data, STATS_TRACK_GID));
+	struct seq_file *seq = file->private_data;
+	return ll_wr_track_id(buffer, count, seq->private, STATS_TRACK_GID);
 }
+LPROC_SEQ_FOPS(ll_track_gid);
 
-static int ll_rd_statahead_max(char *page, char **start, off_t off,
-			       int count, int *eof, void *data)
+static int ll_statahead_max_seq_show(struct seq_file *m, void *v)
 {
-	struct super_block *sb = data;
+	struct super_block *sb = m->private;
 	struct ll_sb_info *sbi = ll_s2sbi(sb);
 
-	return snprintf(page, count, "%u\n", sbi->ll_sa_max);
+	return seq_printf(m, "%u\n", sbi->ll_sa_max);
 }
 
-static int ll_wr_statahead_max(struct file *file, const char *buffer,
-			       unsigned long count, void *data)
+static ssize_t ll_statahead_max_seq_write(struct file *file, const char *buffer,
+				      size_t count, loff_t *off)
 {
-	struct super_block *sb = data;
+	struct super_block *sb = ((struct seq_file *)file->private_data)->private;
 	struct ll_sb_info *sbi = ll_s2sbi(sb);
 	int val, rc;
 
@@ -625,21 +611,21 @@ static int ll_wr_statahead_max(struct file *file, const char *buffer,
 
 	return count;
 }
+LPROC_SEQ_FOPS(ll_statahead_max);
 
-static int ll_rd_statahead_agl(char *page, char **start, off_t off,
-			       int count, int *eof, void *data)
+static int ll_statahead_agl_seq_show(struct seq_file *m, void *v)
 {
-	struct super_block *sb = data;
+	struct super_block *sb = m->private;
 	struct ll_sb_info *sbi = ll_s2sbi(sb);
 
-	return snprintf(page, count, "%u\n",
+	return seq_printf(m, "%u\n",
 			sbi->ll_flags & LL_SBI_AGL_ENABLED ? 1 : 0);
 }
 
-static int ll_wr_statahead_agl(struct file *file, const char *buffer,
-			       unsigned long count, void *data)
+static ssize_t ll_statahead_agl_seq_write(struct file *file, const char *buffer,
+				      size_t count, loff_t *off)
 {
-	struct super_block *sb = data;
+	struct super_block *sb = ((struct seq_file *)file->private_data)->private;
 	struct ll_sb_info *sbi = ll_s2sbi(sb);
 	int val, rc;
 
@@ -654,14 +640,14 @@ static int ll_wr_statahead_agl(struct file *file, const char *buffer,
 
 	return count;
 }
+LPROC_SEQ_FOPS(ll_statahead_agl);
 
-static int ll_rd_statahead_stats(char *page, char **start, off_t off,
-				 int count, int *eof, void *data)
+static int ll_statahead_stats_seq_show(struct seq_file *m, void *v)
 {
-	struct super_block *sb = data;
+	struct super_block *sb = m->private;
 	struct ll_sb_info *sbi = ll_s2sbi(sb);
 
-	return snprintf(page, count,
+	return seq_printf(m,
 			"statahead total: %u\n"
 			"statahead wrong: %u\n"
 			"agl total: %u\n",
@@ -669,21 +655,21 @@ static int ll_rd_statahead_stats(char *page, char **start, off_t off,
 			atomic_read(&sbi->ll_sa_wrong),
 			atomic_read(&sbi->ll_agl_total));
 }
+LPROC_SEQ_FOPS_RO(ll_statahead_stats);
 
-static int ll_rd_lazystatfs(char *page, char **start, off_t off,
-			    int count, int *eof, void *data)
+static int ll_lazystatfs_seq_show(struct seq_file *m, void *v)
 {
-	struct super_block *sb = data;
+	struct super_block *sb = m->private;
 	struct ll_sb_info *sbi = ll_s2sbi(sb);
 
-	return snprintf(page, count, "%u\n",
+	return seq_printf(m, "%u\n",
 			(sbi->ll_flags & LL_SBI_LAZYSTATFS) ? 1 : 0);
 }
 
-static int ll_wr_lazystatfs(struct file *file, const char *buffer,
-			    unsigned long count, void *data)
+static ssize_t ll_lazystatfs_seq_write(struct file *file, const char *buffer,
+				   size_t count, loff_t *off)
 {
-	struct super_block *sb = data;
+	struct super_block *sb = ((struct seq_file *)file->private_data)->private;
 	struct ll_sb_info *sbi = ll_s2sbi(sb);
 	int val, rc;
 
@@ -698,11 +684,11 @@ static int ll_wr_lazystatfs(struct file *file, const char *buffer,
 
 	return count;
 }
+LPROC_SEQ_FOPS(ll_lazystatfs);
 
-static int ll_rd_maxea_size(char *page, char **start, off_t off,
-			    int count, int *eof, void *data)
+static int ll_maxea_size_seq_show(struct seq_file *m, void *v)
 {
-	struct super_block *sb = data;
+	struct super_block *sb = m->private;
 	struct ll_sb_info *sbi = ll_s2sbi(sb);
 	unsigned int ealen;
 	int rc;
@@ -711,17 +697,16 @@ static int ll_rd_maxea_size(char *page, char **start, off_t off,
 	if (rc)
 		return rc;
 
-	return snprintf(page, count, "%u\n", ealen);
+	return seq_printf(m, "%u\n", ealen);
 }
+LPROC_SEQ_FOPS_RO(ll_maxea_size);
 
-static int ll_rd_sbi_flags(char *page, char **start, off_t off,
-				int count, int *eof, void *data)
+static int ll_sbi_flags_seq_show(struct seq_file *m, void *v)
 {
 	const char *str[] = LL_SBI_FLAGS;
-	struct super_block *sb = data;
+	struct super_block *sb = m->private;
 	int flags = ll_s2sbi(sb)->ll_flags;
 	int i = 0;
-	int rc = 0;
 
 	while (flags != 0) {
 		if (ARRAY_SIZE(str) <= i) {
@@ -731,19 +716,18 @@ static int ll_rd_sbi_flags(char *page, char **start, off_t off,
 		}
 
 		if (flags & 0x1)
-			rc += snprintf(page + rc, count - rc, "%s ", str[i]);
+			seq_printf(m, "%s ", str[i]);
 		flags >>= 1;
 		++i;
 	}
-	if (rc > 0)
-		rc += snprintf(page + rc, count - rc, "\b\n");
-	return rc;
+	seq_printf(m, "\b\n");
+	return 0;
 }
+LPROC_SEQ_FOPS_RO(ll_sbi_flags);
 
-static int ll_rd_unstable_stats(char *page, char **start, off_t off,
-			      int count, int *eof, void *data)
+static int ll_unstable_stats_seq_show(struct seq_file *m, void *v)
 {
-	struct super_block	*sb    = data;
+	struct super_block	*sb    = m->private;
 	struct ll_sb_info	*sbi   = ll_s2sbi(sb);
 	struct cl_client_cache	*cache = &sbi->ll_cache;
 	int pages, mb, rc;
@@ -751,44 +735,42 @@ static int ll_rd_unstable_stats(char *page, char **start, off_t off,
 	pages = atomic_read(&cache->ccc_unstable_nr);
 	mb    = (pages * PAGE_CACHE_SIZE) >> 20;
 
-	rc = snprintf(page, count, "unstable_pages: %8d\n"
-				   "unstable_mb:    %8d\n", pages, mb);
+	rc = seq_printf(m, "unstable_pages: %8d\n"
+			   "unstable_mb:    %8d\n", pages, mb);
 
 	return rc;
 }
+LPROC_SEQ_FOPS_RO(ll_unstable_stats);
 
 static struct lprocfs_vars lprocfs_llite_obd_vars[] = {
-	{ "uuid",	 ll_rd_sb_uuid,	  0, 0 },
+	{ "uuid",	  &ll_sb_uuid_fops,	  0, 0 },
 	//{ "mntpt_path",   ll_rd_path,	     0, 0 },
-	{ "fstype",       ll_rd_fstype,	   0, 0 },
-	{ "site",	 ll_rd_site_stats,       0, 0 },
-	{ "blocksize",    ll_rd_blksize,	  0, 0 },
-	{ "kbytestotal",  ll_rd_kbytestotal,      0, 0 },
-	{ "kbytesfree",   ll_rd_kbytesfree,       0, 0 },
-	{ "kbytesavail",  ll_rd_kbytesavail,      0, 0 },
-	{ "filestotal",   ll_rd_filestotal,       0, 0 },
-	{ "filesfree",    ll_rd_filesfree,	0, 0 },
-	{ "client_type",  ll_rd_client_type,      0, 0 },
+	{ "fstype",       &ll_fstype_fops,	  0, 0 },
+	{ "site",	  &ll_site_stats_fops,    0, 0 },
+	{ "blocksize",    &ll_blksize_fops,	  0, 0 },
+	{ "kbytestotal",  &ll_kbytestotal_fops,   0, 0 },
+	{ "kbytesfree",   &ll_kbytesfree_fops,    0, 0 },
+	{ "kbytesavail",  &ll_kbytesavail_fops,   0, 0 },
+	{ "filestotal",   &ll_filestotal_fops,    0, 0 },
+	{ "filesfree",    &ll_filesfree_fops,	  0, 0 },
+	{ "client_type",  &ll_client_type_fops,   0, 0 },
 	//{ "filegroups",   lprocfs_rd_filegroups,  0, 0 },
-	{ "max_read_ahead_mb", ll_rd_max_readahead_mb,
-			       ll_wr_max_readahead_mb, 0 },
-	{ "max_read_ahead_per_file_mb", ll_rd_max_readahead_per_file_mb,
-					ll_wr_max_readahead_per_file_mb, 0 },
-	{ "max_read_ahead_whole_mb", ll_rd_max_read_ahead_whole_mb,
-				     ll_wr_max_read_ahead_whole_mb, 0 },
-	{ "max_cached_mb",    ll_rd_max_cached_mb, ll_wr_max_cached_mb, 0 },
-	{ "checksum_pages",   ll_rd_checksum, ll_wr_checksum, 0 },
-	{ "max_rw_chunk",     ll_rd_max_rw_chunk, ll_wr_max_rw_chunk, 0 },
-	{ "stats_track_pid",  ll_rd_track_pid, ll_wr_track_pid, 0 },
-	{ "stats_track_ppid", ll_rd_track_ppid, ll_wr_track_ppid, 0 },
-	{ "stats_track_gid",  ll_rd_track_gid, ll_wr_track_gid, 0 },
-	{ "statahead_max",    ll_rd_statahead_max, ll_wr_statahead_max, 0 },
-	{ "statahead_agl",    ll_rd_statahead_agl, ll_wr_statahead_agl, 0 },
-	{ "statahead_stats",  ll_rd_statahead_stats, 0, 0 },
-	{ "lazystatfs",       ll_rd_lazystatfs, ll_wr_lazystatfs, 0 },
-	{ "max_easize",       ll_rd_maxea_size, 0, 0 },
-	{ "sbi_flags",	ll_rd_sbi_flags, 0, 0 },
-	{ "unstable_stats",   ll_rd_unstable_stats, 0, 0},
+	{ "max_read_ahead_mb", &ll_max_readahead_mb_fops, 0 },
+	{ "max_read_ahead_per_file_mb", &ll_max_readahead_per_file_mb_fops, 0 },
+	{ "max_read_ahead_whole_mb", &ll_max_read_ahead_whole_mb_fops, 0 },
+	{ "max_cached_mb",    &ll_max_cached_mb_fops, 0 },
+	{ "checksum_pages",   &ll_checksum_fops, 0 },
+	{ "max_rw_chunk",     &ll_max_rw_chunk_fops, 0 },
+	{ "stats_track_pid",  &ll_track_pid_fops, 0 },
+	{ "stats_track_ppid", &ll_track_ppid_fops, 0 },
+	{ "stats_track_gid",  &ll_track_gid_fops, 0 },
+	{ "statahead_max",    &ll_statahead_max_fops, 0 },
+	{ "statahead_agl",    &ll_statahead_agl_fops, 0 },
+	{ "statahead_stats",  &ll_statahead_stats_fops, 0, 0 },
+	{ "lazystatfs",       &ll_lazystatfs_fops, 0 },
+	{ "max_easize",       &ll_maxea_size_fops, 0, 0 },
+	{ "sbi_flags",	      &ll_sbi_flags_fops, 0, 0 },
+	{ "unstable_stats",   &ll_unstable_stats_fops, 0, 0},
 	{ 0 }
 };
 
@@ -878,6 +860,8 @@ static const char *ra_stat_string[] = {
 	[RA_STAT_WRONG_GRAB_PAGE] = "wrong page from grab_cache_page",
 };
 
+LPROC_SEQ_FOPS_RO_TYPE(llite, name);
+LPROC_SEQ_FOPS_RO_TYPE(llite, uuid);
 
 int lprocfs_register_mountpoint(struct proc_dir_entry *parent,
 				struct super_block *sb, char *osc, char *mdc)
@@ -886,6 +870,7 @@ int lprocfs_register_mountpoint(struct proc_dir_entry *parent,
 	struct lustre_sb_info *lsi = s2lsi(sb);
 	struct ll_sb_info *sbi = ll_s2sbi(sb);
 	struct obd_device *obd;
+	proc_dir_entry_t *dir;
 	char name[MAX_STRING_SIZE + 1], *ptr;
 	int err, id, len, rc;
 	ENTRY;
@@ -985,16 +970,19 @@ int lprocfs_register_mountpoint(struct proc_dir_entry *parent,
 	LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
 	LASSERT(obd->obd_type->typ_name != NULL);
 
-	snprintf(name, MAX_STRING_SIZE, "%s/common_name",
-		 obd->obd_type->typ_name);
-	lvars[0].read_fptr = lprocfs_rd_name;
-	err = lprocfs_add_vars(sbi->ll_proc_root, lvars, obd);
+	dir = proc_mkdir(obd->obd_type->typ_name, sbi->ll_proc_root);
+	if (dir == NULL)
+		GOTO(out, err = -ENOMEM);
+
+	snprintf(name, MAX_STRING_SIZE, "common_name");
+	lvars[0].fops = &llite_name_fops;
+	err = lprocfs_add_vars(dir, lvars, obd);
 	if (err)
 		GOTO(out, err);
 
-	snprintf(name, MAX_STRING_SIZE, "%s/uuid", obd->obd_type->typ_name);
-	lvars[0].read_fptr = lprocfs_rd_uuid;
-	err = lprocfs_add_vars(sbi->ll_proc_root, lvars, obd);
+	snprintf(name, MAX_STRING_SIZE, "uuid");
+	lvars[0].fops = &llite_uuid_fops;
+	err = lprocfs_add_vars(dir, lvars, obd);
 	if (err)
 		GOTO(out, err);
 
@@ -1005,16 +993,19 @@ int lprocfs_register_mountpoint(struct proc_dir_entry *parent,
 	LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
 	LASSERT(obd->obd_type->typ_name != NULL);
 
-	snprintf(name, MAX_STRING_SIZE, "%s/common_name",
-		 obd->obd_type->typ_name);
-	lvars[0].read_fptr = lprocfs_rd_name;
-	err = lprocfs_add_vars(sbi->ll_proc_root, lvars, obd);
+	dir = proc_mkdir(obd->obd_type->typ_name, sbi->ll_proc_root);
+	if (dir == NULL)
+		GOTO(out, err = -ENOMEM);
+
+	snprintf(name, MAX_STRING_SIZE, "common_name");
+	lvars[0].fops = &llite_name_fops;
+	err = lprocfs_add_vars(dir, lvars, obd);
 	if (err)
 		GOTO(out, err);
 
-	snprintf(name, MAX_STRING_SIZE, "%s/uuid", obd->obd_type->typ_name);
-	lvars[0].read_fptr = lprocfs_rd_uuid;
-	err = lprocfs_add_vars(sbi->ll_proc_root, lvars, obd);
+	snprintf(name, MAX_STRING_SIZE, "uuid");
+	lvars[0].fops = &llite_uuid_fops;
+	err = lprocfs_add_vars(dir, lvars, obd);
 out:
 	if (err) {
 		lprocfs_remove(&sbi->ll_proc_root);
diff --git a/drivers/staging/lustre/lustre/llite/vvp_dev.c b/drivers/staging/lustre/lustre/llite/vvp_dev.c
index 60daf75..9254b99 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_dev.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_dev.c
@@ -525,8 +525,7 @@ static struct seq_operations vvp_pgcache_ops = {
 
 static int vvp_dump_pgcache_seq_open(struct inode *inode, struct file *filp)
 {
-	struct proc_dir_entry *dp  = PDE(inode);
-	struct ll_sb_info     *sbi = dp->data;
+	struct ll_sb_info     *sbi = PDE_DATA(inode);
 	struct seq_file       *seq;
 	int		    result;
 
diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
index a13eead..1eebfbf 100644
--- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c
+++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
@@ -76,7 +76,7 @@ static void lmv_activate_target(struct lmv_obd *lmv,
 static int lmv_set_mdc_active(struct lmv_obd *lmv, struct obd_uuid *uuid,
 			      int activate)
 {
-	struct lmv_tgt_desc    *tgt;
+	struct lmv_tgt_desc    *uninitialized_var(tgt);
 	struct obd_device      *obd;
 	int		     i;
 	int		     rc = 0;
@@ -230,12 +230,17 @@ static int lmv_connect(const struct lu_env *env,
 	if (data)
 		lmv->conn_data = *data;
 
-	lmv_proc_dir = lprocfs_register("target_obds", obd->obd_proc_entry,
-					NULL, NULL);
-	if (IS_ERR(lmv_proc_dir)) {
-		CERROR("could not register /proc/fs/lustre/%s/%s/target_obds.",
-		       obd->obd_type->typ_name, obd->obd_name);
-		lmv_proc_dir = NULL;
+	if (obd->obd_proc_private != NULL) {
+		lmv_proc_dir = obd->obd_proc_private;
+	} else {
+		lmv_proc_dir = lprocfs_register("target_obds", obd->obd_proc_entry,
+						NULL, NULL);
+		if (IS_ERR(lmv_proc_dir)) {
+			CERROR("could not register /proc/fs/lustre/%s/%s/target_obds.",
+			       obd->obd_type->typ_name, obd->obd_name);
+			lmv_proc_dir = NULL;
+		}
+		obd->obd_proc_private = lmv_proc_dir;
 	}
 
 	/*
@@ -247,9 +252,9 @@ static int lmv_connect(const struct lu_env *env,
 	if (data->ocd_connect_flags & OBD_CONNECT_REAL)
 		rc = lmv_check_connect(obd);
 
-	if (rc) {
-		if (lmv_proc_dir)
-			lprocfs_remove(&lmv_proc_dir);
+	if (rc && lmv_proc_dir) {
+		lprocfs_remove(&lmv_proc_dir);
+		obd->obd_proc_private = NULL;
 	}
 
 	RETURN(rc);
@@ -408,7 +413,7 @@ int lmv_connect_mdc(struct obd_device *obd, struct lmv_tgt_desc *tgt)
 		mdc_obd->obd_name, mdc_obd->obd_uuid.uuid,
 		atomic_read(&obd->obd_refcount));
 
-	lmv_proc_dir = lprocfs_srch(obd->obd_proc_entry, "target_obds");
+	lmv_proc_dir = obd->obd_proc_private;
 	if (lmv_proc_dir) {
 		struct proc_dir_entry *mdc_symlink;
 
@@ -425,7 +430,7 @@ int lmv_connect_mdc(struct obd_device *obd, struct lmv_tgt_desc *tgt)
 			       obd->obd_type->typ_name, obd->obd_name,
 			       mdc_obd->obd_name);
 			lprocfs_remove(&lmv_proc_dir);
-			lmv_proc_dir = NULL;
+			obd->obd_proc_private = NULL;
 		}
 	}
 	RETURN(0);
@@ -626,19 +631,10 @@ static int lmv_disconnect_mdc(struct obd_device *obd, struct lmv_tgt_desc *tgt)
 		mdc_obd->obd_no_recov = obd->obd_no_recov;
 	}
 
-	lmv_proc_dir = lprocfs_srch(obd->obd_proc_entry, "target_obds");
-	if (lmv_proc_dir) {
-		struct proc_dir_entry *mdc_symlink;
+	lmv_proc_dir = obd->obd_proc_private;
+	if (lmv_proc_dir)
+		lprocfs_remove_proc_entry(mdc_obd->obd_name, lmv_proc_dir);
 
-		mdc_symlink = lprocfs_srch(lmv_proc_dir, mdc_obd->obd_name);
-		if (mdc_symlink) {
-			lprocfs_remove(&mdc_symlink);
-		} else {
-			CERROR("/proc/fs/lustre/%s/%s/target_obds/%s missing\n",
-			       obd->obd_type->typ_name, obd->obd_name,
-			       mdc_obd->obd_name);
-		}
-	}
 	rc = obd_fid_fini(tgt->ltd_exp->exp_obd);
 	if (rc)
 		CERROR("Can't finanize fids factory\n");
@@ -664,7 +660,6 @@ static int lmv_disconnect_mdc(struct obd_device *obd, struct lmv_tgt_desc *tgt)
 static int lmv_disconnect(struct obd_export *exp)
 {
 	struct obd_device     *obd = class_exp2obd(exp);
-	struct proc_dir_entry *lmv_proc_dir;
 	struct lmv_obd	*lmv = &obd->u.lmv;
 	int		    rc;
 	int		    i;
@@ -687,13 +682,11 @@ static int lmv_disconnect(struct obd_export *exp)
 		lmv_disconnect_mdc(obd, lmv->tgts[i]);
 	}
 
-	lmv_proc_dir = lprocfs_srch(obd->obd_proc_entry, "target_obds");
-	if (lmv_proc_dir) {
-		lprocfs_remove(&lmv_proc_dir);
-	} else {
+	if (obd->obd_proc_private)
+		lprocfs_remove((proc_dir_entry_t **)&obd->obd_proc_private);
+	else
 		CERROR("/proc/fs/lustre/%s/%s/target_obds missing\n",
 		       obd->obd_type->typ_name, obd->obd_name);
-	}
 
 out_local:
 	/*
diff --git a/drivers/staging/lustre/lustre/lmv/lproc_lmv.c b/drivers/staging/lustre/lustre/lmv/lproc_lmv.c
index 4bbe024..d1c45b5 100644
--- a/drivers/staging/lustre/lustre/lmv/lproc_lmv.c
+++ b/drivers/staging/lustre/lustre/lmv/lproc_lmv.c
@@ -46,18 +46,16 @@
 static struct lprocfs_vars lprocfs_module_vars[] = { {0} };
 static struct lprocfs_vars lprocfs_obd_vars[] = { {0} };
 #else
-static int lmv_rd_numobd(char *page, char **start, off_t off, int count,
-			 int *eof, void *data)
+static int lmv_numobd_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device       *dev = (struct obd_device*)data;
+	struct obd_device       *dev = (struct obd_device *)m->private;
 	struct lmv_desc	 *desc;
 
 	LASSERT(dev != NULL);
 	desc = &dev->u.lmv.desc;
-	*eof = 1;
-	return snprintf(page, count, "%u\n", desc->ld_tgt_count);
-
+	return seq_printf(m, "%u\n", desc->ld_tgt_count);
 }
+LPROC_SEQ_FOPS_RO(lmv_numobd);
 
 static const char *placement_name[] = {
 	[PLACEMENT_CHAR_POLICY] = "CHAR",
@@ -82,26 +80,22 @@ static const char *placement_policy2name(placement_policy_t placement)
 	return placement_name[placement];
 }
 
-static int lmv_rd_placement(char *page, char **start, off_t off, int count,
-			    int *eof, void *data)
+static int lmv_placement_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device       *dev = (struct obd_device*)data;
+	struct obd_device       *dev = (struct obd_device *)m->private;
 	struct lmv_obd	  *lmv;
 
 	LASSERT(dev != NULL);
 	lmv = &dev->u.lmv;
-	*eof = 1;
-	return snprintf(page, count, "%s\n",
-			placement_policy2name(lmv->lmv_placement));
-
+	return seq_printf(m, "%s\n", placement_policy2name(lmv->lmv_placement));
 }
 
 #define MAX_POLICY_STRING_SIZE 64
 
-static int lmv_wr_placement(struct file *file, const char *buffer,
-			    unsigned long count, void *data)
+static ssize_t lmv_placement_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;
 	char		     dummy[MAX_POLICY_STRING_SIZE + 1];
 	int		      len = count;
 	placement_policy_t       policy;
@@ -131,30 +125,29 @@ static int lmv_wr_placement(struct file *file, const char *buffer,
 	}
 	return count;
 }
+LPROC_SEQ_FOPS(lmv_placement);
 
-static int lmv_rd_activeobd(char *page, char **start, off_t off, int count,
-			    int *eof, void *data)
+static int lmv_activeobd_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device       *dev = (struct obd_device*)data;
+	struct obd_device       *dev = (struct obd_device *)m->private;
 	struct lmv_desc	 *desc;
 
 	LASSERT(dev != NULL);
 	desc = &dev->u.lmv.desc;
-	*eof = 1;
-	return snprintf(page, count, "%u\n", desc->ld_active_tgt_count);
+	return seq_printf(m, "%u\n", desc->ld_active_tgt_count);
 }
+LPROC_SEQ_FOPS_RO(lmv_activeobd);
 
-static int lmv_rd_desc_uuid(char *page, char **start, off_t off, int count,
-			    int *eof, void *data)
+static int lmv_desc_uuid_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device       *dev = (struct obd_device*) data;
+	struct obd_device *dev = (struct obd_device *)m->private;
 	struct lmv_obd	  *lmv;
 
 	LASSERT(dev != NULL);
 	lmv = &dev->u.lmv;
-	*eof = 1;
-	return snprintf(page, count, "%s\n", lmv->desc.ld_uuid.uuid);
+	return seq_printf(m, "%s\n", lmv->desc.ld_uuid.uuid);
 }
+LPROC_SEQ_FOPS_RO(lmv_desc_uuid);
 
 static void *lmv_tgt_seq_start(struct seq_file *p, loff_t *pos)
 {
@@ -195,7 +188,6 @@ struct seq_operations lmv_tgt_sops = {
 
 static int lmv_target_seq_open(struct inode *inode, struct file *file)
 {
-	struct proc_dir_entry   *dp = PDE(inode);
 	struct seq_file	 *seq;
 	int		     rc;
 
@@ -204,22 +196,26 @@ static int lmv_target_seq_open(struct inode *inode, struct file *file)
 		return rc;
 
 	seq = file->private_data;
-	seq->private = dp->data;
+	seq->private = PDE_DATA(inode);
 
 	return 0;
 }
 
+LPROC_SEQ_FOPS_RO_TYPE(lmv, uuid);
+
 struct lprocfs_vars lprocfs_lmv_obd_vars[] = {
-	{ "numobd",	     lmv_rd_numobd,	  0, 0 },
-	{ "placement",	  lmv_rd_placement,       lmv_wr_placement, 0 },
-	{ "activeobd",	  lmv_rd_activeobd,       0, 0 },
-	{ "uuid",	       lprocfs_rd_uuid,	0, 0 },
-	{ "desc_uuid",	  lmv_rd_desc_uuid,       0, 0 },
+	{ "numobd",	  &lmv_numobd_fops,	  0, 0 },
+	{ "placement",	  &lmv_placement_fops,    0, 0 },
+	{ "activeobd",	  &lmv_activeobd_fops,    0, 0 },
+	{ "uuid",	  &lmv_uuid_fops,	  0, 0 },
+	{ "desc_uuid",	  &lmv_desc_uuid_fops,    0, 0 },
 	{ 0 }
 };
 
+LPROC_SEQ_FOPS_RO_TYPE(lmv, numrefs);
+
 static struct lprocfs_vars lprocfs_lmv_module_vars[] = {
-	{ "num_refs",	   lprocfs_rd_numrefs,     0, 0 },
+	{ "num_refs",	   &lmv_numrefs_fops, 0, 0 },
 	{ 0 }
 };
 
diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c b/drivers/staging/lustre/lustre/lov/lov_obd.c
index 8089f03..5c7ab42 100644
--- a/drivers/staging/lustre/lustre/lov/lov_obd.c
+++ b/drivers/staging/lustre/lustre/lov/lov_obd.c
@@ -191,7 +191,7 @@ int lov_connect_obd(struct obd_device *obd, __u32 index, int activate,
 	CDEBUG(D_CONFIG, "Connected tgt idx %d %s (%s) %sactive\n", index,
 	       obd_uuid2str(tgt_uuid), tgt_obd->obd_name, activate ? "":"in");
 
-	lov_proc_dir = lprocfs_srch(obd->obd_proc_entry, "target_obds");
+	lov_proc_dir = obd->obd_proc_private;
 	if (lov_proc_dir) {
 		struct obd_device *osc_obd = lov->lov_tgts[index]->ltd_exp->exp_obd;
 		proc_dir_entry_t *osc_symlink;
@@ -211,6 +211,7 @@ int lov_connect_obd(struct obd_device *obd, __u32 index, int activate,
 				obd->obd_type->typ_name, obd->obd_name,
 				osc_obd->obd_name);
 			lprocfs_remove(&lov_proc_dir);
+			obd->obd_proc_private = NULL;
 		}
 	}
 
@@ -290,19 +291,9 @@ static int lov_disconnect_obd(struct obd_device *obd, struct lov_tgt_desc *tgt)
 		tgt->ltd_exp->exp_obd->obd_inactive = 1;
 	}
 
-	lov_proc_dir = lprocfs_srch(obd->obd_proc_entry, "target_obds");
-	if (lov_proc_dir) {
-		proc_dir_entry_t *osc_symlink;
-
-		osc_symlink = lprocfs_srch(lov_proc_dir, osc_obd->obd_name);
-		if (osc_symlink) {
-			lprocfs_remove(&osc_symlink);
-		} else {
-			CERROR("/proc/fs/lustre/%s/%s/target_obds/%s missing.",
-			       obd->obd_type->typ_name, obd->obd_name,
-			       osc_obd->obd_name);
-		}
-	}
+	lov_proc_dir = obd->obd_proc_private;
+	if (lov_proc_dir)
+		lprocfs_remove_proc_entry(osc_obd->obd_name, lov_proc_dir);
 
 	if (osc_obd) {
 		/* Pass it on to our clients.
diff --git a/drivers/staging/lustre/lustre/lov/lov_pool.c b/drivers/staging/lustre/lustre/lov/lov_pool.c
index 0f3f96d..a96f908 100644
--- a/drivers/staging/lustre/lustre/lov/lov_pool.c
+++ b/drivers/staging/lustre/lustre/lov/lov_pool.c
@@ -284,7 +284,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;
 }
@@ -468,8 +468,7 @@ int lov_pool_new(struct obd_device *obd, char *poolname)
 	/* get ref for /proc file */
 	lov_pool_getref(new_pool);
 	new_pool->pool_proc_entry = lprocfs_add_simple(lov->lov_pool_proc_entry,
-						       poolname, NULL, NULL,
-						       new_pool,
+						       poolname, new_pool,
 						       &pool_proc_operations);
 	if (IS_ERR(new_pool->pool_proc_entry)) {
 		CWARN("Cannot add proc pool entry "LOV_POOLNAMEF"\n", poolname);
diff --git a/drivers/staging/lustre/lustre/lov/lproc_lov.c b/drivers/staging/lustre/lustre/lov/lproc_lov.c
index 732d5c7..5b2c0d8 100644
--- a/drivers/staging/lustre/lustre/lov/lproc_lov.c
+++ b/drivers/staging/lustre/lustre/lov/lproc_lov.c
@@ -43,22 +43,20 @@
 #include "lov_internal.h"
 
 #ifdef LPROCFS
-static int lov_rd_stripesize(char *page, char **start, off_t off, int count,
-			     int *eof, void *data)
+static int lov_stripesize_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device *dev = (struct obd_device *)data;
+	struct obd_device *dev = (struct obd_device *)m->private;
 	struct lov_desc *desc;
 
 	LASSERT(dev != NULL);
 	desc = &dev->u.lov.desc;
-	*eof = 1;
-	return snprintf(page, count, LPU64"\n", desc->ld_default_stripe_size);
+	return seq_printf(m, LPU64"\n", desc->ld_default_stripe_size);
 }
 
-static int lov_wr_stripesize(struct file *file, const char *buffer,
-			       unsigned long count, void *data)
+static ssize_t lov_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 lov_desc *desc;
 	__u64 val;
 	int rc;
@@ -73,23 +71,22 @@ static int lov_wr_stripesize(struct file *file, const char *buffer,
 	desc->ld_default_stripe_size = val;
 	return count;
 }
+LPROC_SEQ_FOPS(lov_stripesize);
 
-static int lov_rd_stripeoffset(char *page, char **start, off_t off, int count,
-			       int *eof, void *data)
+static int lov_stripeoffset_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device *dev = (struct obd_device *)data;
+	struct obd_device *dev = (struct obd_device *)m->private;
 	struct lov_desc *desc;
 
 	LASSERT(dev != NULL);
 	desc = &dev->u.lov.desc;
-	*eof = 1;
-	return snprintf(page, count, LPU64"\n", desc->ld_default_stripe_offset);
+	return seq_printf(m, LPU64"\n", desc->ld_default_stripe_offset);
 }
 
-static int lov_wr_stripeoffset(struct file *file, const char *buffer,
-			       unsigned long count, void *data)
+static ssize_t lov_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 lov_desc *desc;
 	__u64 val;
 	int rc;
@@ -103,23 +100,22 @@ static int lov_wr_stripeoffset(struct file *file, const char *buffer,
 	desc->ld_default_stripe_offset = val;
 	return count;
 }
+LPROC_SEQ_FOPS(lov_stripeoffset);
 
-static int lov_rd_stripetype(char *page, char **start, off_t off, int count,
-			     int *eof, void *data)
+static int lov_stripetype_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device* dev = (struct obd_device*)data;
+	struct obd_device *dev = (struct obd_device *)m->private;
 	struct lov_desc *desc;
 
 	LASSERT(dev != NULL);
 	desc = &dev->u.lov.desc;
-	*eof = 1;
-	return snprintf(page, count, "%u\n", desc->ld_pattern);
+	return seq_printf(m, "%u\n", desc->ld_pattern);
 }
 
-static int lov_wr_stripetype(struct file *file, const char *buffer,
-			     unsigned long count, void *data)
+static ssize_t lov_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 lov_desc *desc;
 	int val, rc;
 
@@ -133,24 +129,23 @@ static int lov_wr_stripetype(struct file *file, const char *buffer,
 	desc->ld_pattern = val;
 	return count;
 }
+LPROC_SEQ_FOPS(lov_stripetype);
 
-static int lov_rd_stripecount(char *page, char **start, off_t off, int count,
-			      int *eof, void *data)
+static int lov_stripecount_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device *dev = (struct obd_device *)data;
+	struct obd_device *dev = (struct obd_device *)m->private;
 	struct lov_desc *desc;
 
 	LASSERT(dev != NULL);
 	desc = &dev->u.lov.desc;
-	*eof = 1;
-	return snprintf(page, count, "%d\n",
+	return seq_printf(m, "%d\n",
 			(__s16)(desc->ld_default_stripe_count + 1) - 1);
 }
 
-static int lov_wr_stripecount(struct file *file, const char *buffer,
-			      unsigned long count, void *data)
+static ssize_t lov_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 lov_desc *desc;
 	int val, rc;
 
@@ -164,43 +159,40 @@ static int lov_wr_stripecount(struct file *file, const char *buffer,
 	desc->ld_default_stripe_count = val;
 	return count;
 }
+LPROC_SEQ_FOPS(lov_stripecount);
 
-static int lov_rd_numobd(char *page, char **start, off_t off, int count,
-			 int *eof, void *data)
+static int lov_numobd_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device *dev = (struct obd_device*)data;
+	struct obd_device *dev = (struct obd_device *)m->private;
 	struct lov_desc *desc;
 
 	LASSERT(dev != NULL);
 	desc = &dev->u.lov.desc;
-	*eof = 1;
-	return snprintf(page, count, "%u\n", desc->ld_tgt_count);
-
+	return seq_printf(m, "%u\n", desc->ld_tgt_count);
 }
+LPROC_SEQ_FOPS_RO(lov_numobd);
 
-static int lov_rd_activeobd(char *page, char **start, off_t off, int count,
-			    int *eof, void *data)
+static int lov_activeobd_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device* dev = (struct obd_device*)data;
+	struct obd_device *dev = (struct obd_device *)m->private;
 	struct lov_desc *desc;
 
 	LASSERT(dev != NULL);
 	desc = &dev->u.lov.desc;
-	*eof = 1;
-	return snprintf(page, count, "%u\n", desc->ld_active_tgt_count);
+	return seq_printf(m, "%u\n", desc->ld_active_tgt_count);
 }
+LPROC_SEQ_FOPS_RO(lov_activeobd);
 
-static int lov_rd_desc_uuid(char *page, char **start, off_t off, int count,
-			    int *eof, void *data)
+static int lov_desc_uuid_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device *dev = (struct obd_device*) data;
+	struct obd_device *dev = (struct obd_device *)m->private;
 	struct lov_obd *lov;
 
 	LASSERT(dev != NULL);
 	lov = &dev->u.lov;
-	*eof = 1;
-	return snprintf(page, count, "%s\n", lov->desc.ld_uuid.uuid);
+	return seq_printf(m, "%s\n", lov->desc.ld_uuid.uuid);
 }
+LPROC_SEQ_FOPS_RO(lov_desc_uuid);
 
 static void *lov_tgt_seq_start(struct seq_file *p, loff_t *pos)
 {
@@ -248,43 +240,49 @@ struct seq_operations lov_tgt_sops = {
 
 static int lov_target_seq_open(struct inode *inode, struct file *file)
 {
-	struct proc_dir_entry *dp = PDE(inode);
 	struct seq_file *seq;
 	int rc;
 
-	LPROCFS_ENTRY_AND_CHECK(dp);
 	rc = seq_open(file, &lov_tgt_sops);
-	if (rc) {
-		LPROCFS_EXIT();
+	if (rc)
 		return rc;
-	}
 
 	seq = file->private_data;
-	seq->private = dp->data;
+	seq->private = PDE_DATA(inode);
 	return 0;
 }
 
+LPROC_SEQ_FOPS_RO_TYPE(lov, uuid);
+LPROC_SEQ_FOPS_RO_TYPE(lov, filestotal);
+LPROC_SEQ_FOPS_RO_TYPE(lov, filesfree);
+LPROC_SEQ_FOPS_RO_TYPE(lov, blksize);
+LPROC_SEQ_FOPS_RO_TYPE(lov, kbytestotal);
+LPROC_SEQ_FOPS_RO_TYPE(lov, kbytesfree);
+LPROC_SEQ_FOPS_RO_TYPE(lov, kbytesavail);
+
 struct lprocfs_vars lprocfs_lov_obd_vars[] = {
-	{ "uuid",	 lprocfs_rd_uuid,	0, 0 },
-	{ "stripesize",   lov_rd_stripesize,      lov_wr_stripesize, 0 },
-	{ "stripeoffset", lov_rd_stripeoffset,    lov_wr_stripeoffset, 0 },
-	{ "stripecount",  lov_rd_stripecount,     lov_wr_stripecount, 0 },
-	{ "stripetype",   lov_rd_stripetype,      lov_wr_stripetype, 0 },
-	{ "numobd",       lov_rd_numobd,	  0, 0 },
-	{ "activeobd",    lov_rd_activeobd,       0, 0 },
-	{ "filestotal",   lprocfs_rd_filestotal,  0, 0 },
-	{ "filesfree",    lprocfs_rd_filesfree,   0, 0 },
+	{ "uuid",	  &lov_uuid_fops,	  0, 0 },
+	{ "stripesize",   &lov_stripesize_fops,   0 },
+	{ "stripeoffset", &lov_stripeoffset_fops, 0 },
+	{ "stripecount",  &lov_stripecount_fops,  0 },
+	{ "stripetype",   &lov_stripetype_fops,   0 },
+	{ "numobd",       &lov_numobd_fops,	  0, 0 },
+	{ "activeobd",    &lov_activeobd_fops,	  0, 0 },
+	{ "filestotal",   &lov_filestotal_fops,   0, 0 },
+	{ "filesfree",    &lov_filesfree_fops,    0, 0 },
 	/*{ "filegroups", lprocfs_rd_filegroups,  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 },
-	{ "desc_uuid",    lov_rd_desc_uuid,       0, 0 },
+	{ "blocksize",    &lov_blksize_fops,      0, 0 },
+	{ "kbytestotal",  &lov_kbytestotal_fops,  0, 0 },
+	{ "kbytesfree",   &lov_kbytesfree_fops,   0, 0 },
+	{ "kbytesavail",  &lov_kbytesavail_fops,  0, 0 },
+	{ "desc_uuid",    &lov_desc_uuid_fops,    0, 0 },
 	{ 0 }
 };
 
+LPROC_SEQ_FOPS_RO_TYPE(lov, numrefs);
+
 static struct lprocfs_vars lprocfs_lov_module_vars[] = {
-	{ "num_refs",     lprocfs_rd_numrefs,     0, 0 },
+	{ "num_refs",     &lov_numrefs_fops,     0, 0 },
 	{ 0 }
 };
 
diff --git a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c
index a6a8a0d..8d5c2f4 100644
--- a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c
+++ b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c
@@ -42,23 +42,24 @@
 
 #ifdef LPROCFS
 
-static int mdc_rd_max_rpcs_in_flight(char *page, char **start, off_t off,
-				     int count, int *eof, void *data)
+static int mdc_max_rpcs_in_flight_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device *dev = data;
+	struct obd_device *dev = m->private;
 	struct client_obd *cli = &dev->u.cli;
 	int rc;
 
 	client_obd_list_lock(&cli->cl_loi_list_lock);
-	rc = snprintf(page, count, "%u\n", cli->cl_max_rpcs_in_flight);
+	rc = seq_printf(m, "%u\n", cli->cl_max_rpcs_in_flight);
 	client_obd_list_unlock(&cli->cl_loi_list_lock);
 	return rc;
 }
 
-static int mdc_wr_max_rpcs_in_flight(struct file *file, const char *buffer,
-				     unsigned long count, void *data)
+static ssize_t mdc_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 client_obd *cli = &dev->u.cli;
 	int val, rc;
 
@@ -75,12 +76,13 @@ static int mdc_wr_max_rpcs_in_flight(struct file *file, const char *buffer,
 
 	return count;
 }
+LPROC_SEQ_FOPS(mdc_max_rpcs_in_flight);
 
 /* temporary for testing */
-static int mdc_wr_kuc(struct file *file, const char *buffer,
-		      unsigned long count, void *data)
+static ssize_t mdc_wr_kuc(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 kuc_hdr		*lh;
 	struct hsm_action_list	*hal;
 	struct hsm_action_item	*hai;
@@ -137,41 +139,67 @@ static int mdc_wr_kuc(struct file *file, const char *buffer,
 		RETURN(rc);
 	RETURN(count);
 }
+struct file_operations mdc_kuc_fops = {
+	.write = mdc_wr_kuc,
+};
+
+LPROC_SEQ_FOPS_WR_ONLY(mdc, ping);
+
+LPROC_SEQ_FOPS_RO_TYPE(mdc, uuid);
+LPROC_SEQ_FOPS_RO_TYPE(mdc, connect_flags);
+LPROC_SEQ_FOPS_RO_TYPE(mdc, blksize);
+LPROC_SEQ_FOPS_RO_TYPE(mdc, kbytestotal);
+LPROC_SEQ_FOPS_RO_TYPE(mdc, kbytesfree);
+LPROC_SEQ_FOPS_RO_TYPE(mdc, kbytesavail);
+LPROC_SEQ_FOPS_RO_TYPE(mdc, filestotal);
+LPROC_SEQ_FOPS_RO_TYPE(mdc, filesfree);
+LPROC_SEQ_FOPS_RO_TYPE(mdc, server_uuid);
+LPROC_SEQ_FOPS_RO_TYPE(mdc, conn_uuid);
+LPROC_SEQ_FOPS_RO_TYPE(mdc, timeouts);
+LPROC_SEQ_FOPS_RO_TYPE(mdc, state);
+
+static int mdc_obd_max_pages_per_rpc_seq_show(struct seq_file *m, void *v)
+{
+	return lprocfs_obd_rd_max_pages_per_rpc(m, m->private);
+}
+LPROC_SEQ_FOPS_RO(mdc_obd_max_pages_per_rpc);
+
+LPROC_SEQ_FOPS_RW_TYPE(mdc, import);
+LPROC_SEQ_FOPS_RW_TYPE(mdc, pinger_recov);
 
 static struct lprocfs_vars lprocfs_mdc_obd_vars[] = {
-	{ "uuid",	    lprocfs_rd_uuid,	0, 0 },
-	{ "ping",	    0, lprocfs_wr_ping,     0, 0, 0222 },
-	{ "connect_flags",   lprocfs_rd_connect_flags, 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 },
+	{ "uuid",	    &mdc_uuid_fops,		0, 0 },
+	{ "ping",	    &mdc_ping_fops,		0, 0222 },
+	{ "connect_flags",  &mdc_connect_flags_fops,	0, 0 },
+	{ "blocksize",      &mdc_blksize_fops,		0, 0 },
+	{ "kbytestotal",    &mdc_kbytestotal_fops,	0, 0 },
+	{ "kbytesfree",     &mdc_kbytesfree_fops,	0, 0 },
+	{ "kbytesavail",    &mdc_kbytesavail_fops,	0, 0 },
+	{ "filestotal",     &mdc_filestotal_fops,	0, 0 },
+	{ "filesfree",      &mdc_filesfree_fops,	0, 0 },
 	/*{ "filegroups",      lprocfs_rd_filegroups,  0, 0 },*/
-	{ "mds_server_uuid", lprocfs_rd_server_uuid, 0, 0 },
-	{ "mds_conn_uuid",   lprocfs_rd_conn_uuid,   0, 0 },
+	{ "mds_server_uuid", &mdc_server_uuid_fops,	0, 0 },
+	{ "mds_conn_uuid",  &mdc_conn_uuid_fops,	0, 0 },
 	/*
 	 * FIXME: below proc entry is provided, but not in used, instead
 	 * sbi->sb_md_brw_size is used, the per obd variable should be used
 	 * when CMD is enabled, and dir pages are managed in MDC layer.
 	 * Remember to enable proc write function.
 	 */
-	{ "max_pages_per_rpc",  lprocfs_obd_rd_max_pages_per_rpc,
-				/* lprocfs_obd_wr_max_pages_per_rpc */0, 0 },
-	{ "max_rpcs_in_flight", mdc_rd_max_rpcs_in_flight,
-				mdc_wr_max_rpcs_in_flight, 0 },
-	{ "timeouts",	lprocfs_rd_timeouts,    0, 0 },
-	{ "import",	  lprocfs_rd_import,      lprocfs_wr_import, 0 },
-	{ "state",	   lprocfs_rd_state,       0, 0 },
-	{ "hsm_nl",	  0, mdc_wr_kuc,	  0, 0, 0200 },
-	{ "pinger_recov",    lprocfs_rd_pinger_recov,
-			     lprocfs_wr_pinger_recov, 0, 0 },
+	{ "max_pages_per_rpc",  &mdc_obd_max_pages_per_rpc_fops, 0, 0 },
+	{ "max_rpcs_in_flight", &mdc_max_rpcs_in_flight_fops, 0, 0 },
+	{ "timeouts",		&mdc_timeouts_fops,    0, 0 },
+	{ "import",		&mdc_import_fops, 0 },
+	{ "state",		&mdc_state_fops, 0, 0 },
+	{ "hsm_nl",		&mdc_kuc_fops, 0, 0200 },
+	{ "pinger_recov",	&mdc_pinger_recov_fops, 0, 0 },
 	{ 0 }
 };
 
+LPROC_SEQ_FOPS_RO_TYPE(mdc, numrefs);
+
 static struct lprocfs_vars lprocfs_mdc_module_vars[] = {
-	{ "num_refs",	lprocfs_rd_numrefs,     0, 0 },
+	{ "num_refs",	&mdc_numrefs_fops,     0, 0 },
 	{ 0 }
 };
 
diff --git a/drivers/staging/lustre/lustre/mgc/lproc_mgc.c b/drivers/staging/lustre/lustre/mgc/lproc_mgc.c
index 041f365..1105eaa 100644
--- a/drivers/staging/lustre/lustre/mgc/lproc_mgc.c
+++ b/drivers/staging/lustre/lustre/mgc/lproc_mgc.c
@@ -43,20 +43,36 @@
 
 #ifdef LPROCFS
 
+LPROC_SEQ_FOPS_RO_TYPE(mgc, uuid);
+LPROC_SEQ_FOPS_RO_TYPE(mgc, connect_flags);
+LPROC_SEQ_FOPS_RO_TYPE(mgc, server_uuid);
+LPROC_SEQ_FOPS_RO_TYPE(mgc, conn_uuid);
+LPROC_SEQ_FOPS_RO_TYPE(mgc, import);
+LPROC_SEQ_FOPS_RO_TYPE(mgc, state);
+
+LPROC_SEQ_FOPS_WR_ONLY(mgc, ping);
+
+static int mgc_ir_state_seq_show(struct seq_file *m, void *v)
+{
+	return lprocfs_mgc_rd_ir_state(m, m->private);
+}
+LPROC_SEQ_FOPS_RO(mgc_ir_state);
+
 static struct lprocfs_vars lprocfs_mgc_obd_vars[] = {
-	{ "uuid",	    lprocfs_rd_uuid,	  0, 0 },
-	{ "ping",	    0, lprocfs_wr_ping,       0, 0, 0222 },
-	{ "connect_flags",   lprocfs_rd_connect_flags, 0, 0 },
-	{ "mgs_server_uuid", lprocfs_rd_server_uuid,   0, 0 },
-	{ "mgs_conn_uuid",   lprocfs_rd_conn_uuid,     0, 0 },
-	{ "import",	  lprocfs_rd_import,	0, 0 },
-	{ "state",	   lprocfs_rd_state,	 0, 0 },
-	{ "ir_state",	lprocfs_mgc_rd_ir_state,  0, 0 },
+	{ "uuid",	     &mgc_uuid_fops,	  0, 0 },
+	{ "ping",	     &mgc_ping_fops,      0, 0222 },
+	{ "connect_flags",   &mgc_connect_flags_fops, 0, 0 },
+	{ "mgs_server_uuid", &mgc_server_uuid_fops,   0, 0 },
+	{ "mgs_conn_uuid",   &mgc_conn_uuid_fops,     0, 0 },
+	{ "import",	     &mgc_import_fops,	0, 0 },
+	{ "state",	     &mgc_state_fops,	 0, 0 },
+	{ "ir_state",	     &mgc_ir_state_fops,  0, 0 },
 	{ 0 }
 };
 
+LPROC_SEQ_FOPS_RO_TYPE(mgc, numrefs);
 static struct lprocfs_vars lprocfs_mgc_module_vars[] = {
-	{ "num_refs",	lprocfs_rd_numrefs,       0, 0 },
+	{ "num_refs",	&mgc_numrefs_fops,       0, 0 },
 	{ 0 }
 };
 
diff --git a/drivers/staging/lustre/lustre/mgc/mgc_internal.h b/drivers/staging/lustre/lustre/mgc/mgc_internal.h
index 111db90..dbd6982 100644
--- a/drivers/staging/lustre/lustre/mgc/mgc_internal.h
+++ b/drivers/staging/lustre/lustre/mgc/mgc_internal.h
@@ -46,15 +46,13 @@
 
 #ifdef LPROCFS
 void lprocfs_mgc_init_vars(struct lprocfs_static_vars *lvars);
-int lprocfs_mgc_rd_ir_state(char *page, char **start, off_t off,
-			    int count, int *eof, void *data);
+int lprocfs_mgc_rd_ir_state(struct seq_file *m, void *data);
 #else
 static void lprocfs_mgc_init_vars(struct lprocfs_static_vars *lvars)
 {
 	memset(lvars, 0, sizeof(*lvars));
 }
-static inline int lprocfs_mgc_rd_ir_state(char *page, char **start,
-	off_t off, int count, int *eof, void *data)
+static inline int lprocfs_mgc_rd_ir_state(struct seq_file *m, void *data)
 {
 	return 0;
 }
diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c
index 74232f4..c6c84d9 100644
--- a/drivers/staging/lustre/lustre/mgc/mgc_request.c
+++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c
@@ -409,32 +409,29 @@ static int config_log_end(char *logname, struct config_llog_instance *cfg)
 	RETURN(rc);
 }
 
-int lprocfs_mgc_rd_ir_state(char *page, char **start, off_t off,
-			    int count, int *eof, void *data)
+int lprocfs_mgc_rd_ir_state(struct seq_file *m, void *data)
 {
 	struct obd_device       *obd = data;
 	struct obd_import       *imp = obd->u.cli.cl_import;
 	struct obd_connect_data *ocd = &imp->imp_connect_data;
 	struct config_llog_data *cld;
-	int rc = 0;
 	ENTRY;
 
-	rc = snprintf(page, count, "imperative_recovery: %s\n",
+	seq_printf(m, "imperative_recovery: %s\n",
 		      OCD_HAS_FLAG(ocd, IMP_RECOV) ? "ENABLED" : "DISABLED");
-	rc += snprintf(page + rc, count - rc, "client_state:\n");
+	seq_printf(m, "client_state:\n");
 
 	spin_lock(&config_list_lock);
 	list_for_each_entry(cld, &config_llog_list, cld_list_chain) {
 		if (cld->cld_recover == NULL)
 			continue;
-		rc += snprintf(page + rc, count - rc,
-			       "    - { client: %s, nidtbl_version: %u }\n",
+		seq_printf(m,  "    - { client: %s, nidtbl_version: %u }\n",
 			       cld->cld_logname,
 			       cld->cld_recover->cld_cfg.cfg_last_idx);
 	}
 	spin_unlock(&config_list_lock);
 
-	RETURN(rc);
+	RETURN(0);
 }
 
 /* reenqueue any lost locks */
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
index faa9ef6..cdb5fba 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
@@ -394,10 +394,8 @@ void cache_stats_init(struct cache_stats *cs, const char *name)
 		atomic_set(&cs->cs_stats[i], 0);
 }
 
-int cache_stats_print(const struct cache_stats *cs,
-		      char *page, int count, int h)
+int cache_stats_print(const struct cache_stats *cs, struct seq_file *m, int h)
 {
-	int nob = 0;
 	int i;
 	/*
 	 *   lookup    hit    total  cached create
@@ -406,18 +404,16 @@ int cache_stats_print(const struct cache_stats *cs,
 	if (h) {
 		const char *names[CS_NR] = CS_NAMES;
 
-		nob += snprintf(page + nob, count - nob, "%6s", " ");
+		seq_printf(m, "%6s", " ");
 		for (i = 0; i < CS_NR; i++)
-			nob += snprintf(page + nob, count - nob,
-					"%8s", names[i]);
-		nob += snprintf(page + nob, count - nob, "\n");
+			seq_printf(m, "%8s", names[i]);
+		seq_printf(m, "\n");
 	}
 
-	nob += snprintf(page + nob, count - nob, "%5.5s:", cs->cs_name);
+	seq_printf(m, "%5.5s:", cs->cs_name);
 	for (i = 0; i < CS_NR; i++)
-		nob += snprintf(page + nob, count - nob, "%8u",
-				atomic_read(&cs->cs_stats[i]));
-	return nob;
+		seq_printf(m, "%8u", atomic_read(&cs->cs_stats[i]));
+	return 0;
 }
 
 /**
@@ -462,9 +458,8 @@ static struct cache_stats cl_env_stats = {
  * Outputs client site statistical counters into a buffer. Suitable for
  * ll_rd_*()-style functions.
  */
-int cl_site_stats_print(const struct cl_site *site, char *page, int count)
+int cl_site_stats_print(const struct cl_site *site, struct seq_file *m)
 {
-	int nob;
 	int i;
 	static const char *pstate[] = {
 		[CPS_CACHED]  = "c",
@@ -488,24 +483,22 @@ pages: ...... ...... ...... ...... ...... [...... ...... ...... ......]
 locks: ...... ...... ...... ...... ...... [...... ...... ...... ...... ......]
   env: ...... ...... ...... ...... ......
  */
-	nob = lu_site_stats_print(&site->cs_lu, page, count);
-	nob += cache_stats_print(&site->cs_pages, page + nob, count - nob, 1);
-	nob += snprintf(page + nob, count - nob, " [");
+	lu_site_stats_print(&site->cs_lu, m);
+	cache_stats_print(&site->cs_pages, m, 1);
+	seq_printf(m, " [");
 	for (i = 0; i < ARRAY_SIZE(site->cs_pages_state); ++i)
-		nob += snprintf(page + nob, count - nob, "%s: %u ",
-				pstate[i],
+		seq_printf(m, "%s: %u ", pstate[i],
 				atomic_read(&site->cs_pages_state[i]));
-	nob += snprintf(page + nob, count - nob, "]\n");
-	nob += cache_stats_print(&site->cs_locks, page + nob, count - nob, 0);
-	nob += snprintf(page + nob, count - nob, " [");
+	seq_printf(m, "]\n");
+	cache_stats_print(&site->cs_locks, m, 0);
+	seq_printf(m, " [");
 	for (i = 0; i < ARRAY_SIZE(site->cs_locks_state); ++i)
-		nob += snprintf(page + nob, count - nob, "%s: %u ",
-				lstate[i],
+		seq_printf(m, "%s: %u ", lstate[i],
 				atomic_read(&site->cs_locks_state[i]));
-	nob += snprintf(page + nob, count - nob, "]\n");
-	nob += cache_stats_print(&cl_env_stats, page + nob, count - nob, 0);
-	nob += snprintf(page + nob, count - nob, "\n");
-	return nob;
+	seq_printf(m, "]\n");
+	cache_stats_print(&cl_env_stats, m, 0);
+	seq_printf(m, "\n");
+	return 0;
 }
 EXPORT_SYMBOL(cl_site_stats_print);
 
diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
index 1cc9b55..d96876e 100644
--- a/drivers/staging/lustre/lustre/obdclass/genops.c
+++ b/drivers/staging/lustre/lustre/obdclass/genops.c
@@ -247,11 +247,9 @@ int class_unregister_type(const char *name)
 		RETURN(-EBUSY);
 	}
 
-	/* we do not use type->typ_procroot as for compatibility purposes
-	 * other modules can share names (i.e. lod can use lov entry). so
-	 * we can't reference pointer as it can get invalided when another
-	 * module removes the entry */
-	lprocfs_try_remove_proc_entry(type->typ_name, proc_lustre_root);
+	if (type->typ_procroot) {
+		lprocfs_remove(&type->typ_procroot);
+	}
 
 	if (type->typ_lu)
 		lu_device_type_fini(type->typ_lu);
diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
index 16208ba..d2c3072 100644
--- a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
+++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
@@ -219,47 +219,26 @@ psdev_t obd_psdev = {
 
 
 #ifdef LPROCFS
-int obd_proc_read_version(char *page, char **start, off_t off, int count,
-			  int *eof, void *data)
+int obd_proc_version_seq_show(struct seq_file *m, void *v)
 {
-	*eof = 1;
-	return snprintf(page, count, "lustre: %s\nkernel: %s\nbuild:  %s\n",
+	return seq_printf(m, "lustre: %s\nkernel: %s\nbuild:  %s\n",
 			LUSTRE_VERSION_STRING, "patchless_client",
 			BUILD_VERSION);
 }
+LPROC_SEQ_FOPS_RO(obd_proc_version);
 
-int obd_proc_read_pinger(char *page, char **start, off_t off, int count,
-			 int *eof, void *data)
+int obd_proc_pinger_seq_show(struct seq_file *m, void *v)
 {
-	*eof = 1;
-	return snprintf(page, count, "%s\n",
-			"on"
-		       );
+	return seq_printf(m, "%s\n", "on");
 }
+LPROC_SEQ_FOPS_RO(obd_proc_pinger);
 
-/**
- * Check all obd devices health
- *
- * \param page
- * \param start
- * \param off
- * \param count
- * \param eof
- * \param data
- *		  proc read function parameters, please refer to kernel
- *		  code fs/proc/generic.c proc_file_read()
- * \param data [in] unused
- *
- * \retval number of characters printed
- */
-static int obd_proc_read_health(char *page, char **start, off_t off,
-				int count, int *eof, void *data)
+static int obd_proc_health_seq_show(struct seq_file *m, void *v)
 {
 	int rc = 0, i;
-	*eof = 1;
 
 	if (libcfs_catastrophe)
-		rc += snprintf(page + rc, count - rc, "LBUG\n");
+		seq_printf(m, "LBUG\n");
 
 	read_lock(&obd_dev_lock);
 	for (i = 0; i < class_devno_max(); i++) {
@@ -277,9 +256,9 @@ static int obd_proc_read_health(char *page, char **start, off_t off,
 		read_unlock(&obd_dev_lock);
 
 		if (obd_health_check(NULL, obd)) {
-			rc += snprintf(page + rc, count - rc,
-				       "device %s reported unhealthy\n",
-				       obd->obd_name);
+			seq_printf(m, "device %s reported unhealthy\n",
+				      obd->obd_name);
+			rc++;
 		}
 		class_decref(obd, __FUNCTION__, current);
 		read_lock(&obd_dev_lock);
@@ -287,20 +266,20 @@ static int obd_proc_read_health(char *page, char **start, off_t off,
 	read_unlock(&obd_dev_lock);
 
 	if (rc == 0)
-		return snprintf(page, count, "healthy\n");
+		return seq_printf(m, "healthy\n");
 
-	rc += snprintf(page + rc, count - rc, "NOT HEALTHY\n");
-	return rc;
+	seq_printf(m, "NOT HEALTHY\n");
+	return 0;
 }
+LPROC_SEQ_FOPS_RO(obd_proc_health);
 
-static int obd_proc_rd_jobid_var(char *page, char **start, off_t off,
-				int count, int *eof, void *data)
+static int obd_proc_jobid_var_seq_show(struct seq_file *m, void *v)
 {
-	return snprintf(page, count, "%s\n", obd_jobid_var);
+	return seq_printf(m, "%s\n", obd_jobid_var);
 }
 
-static int obd_proc_wr_jobid_var(struct file *file, const char *buffer,
-				unsigned long count, void *data)
+static ssize_t obd_proc_jobid_var_seq_write(struct file *file, const char *buffer,
+					size_t count, loff_t *off)
 {
 	if (!count || count > JOBSTATS_JOBID_VAR_MAX_LEN)
 		return -EINVAL;
@@ -310,17 +289,17 @@ static int obd_proc_wr_jobid_var(struct file *file, const char *buffer,
 	memcpy(obd_jobid_var, buffer, count - (buffer[count - 1] == '\n'));
 	return count;
 }
+LPROC_SEQ_FOPS(obd_proc_jobid_var);
 
 /* Root for /proc/fs/lustre */
 struct proc_dir_entry *proc_lustre_root = NULL;
 EXPORT_SYMBOL(proc_lustre_root);
 
 struct lprocfs_vars lprocfs_base[] = {
-	{ "version", obd_proc_read_version, NULL, NULL },
-	{ "pinger", obd_proc_read_pinger, NULL, NULL },
-	{ "health_check", obd_proc_read_health, NULL, NULL },
-	{ "jobid_var", obd_proc_rd_jobid_var,
-		       obd_proc_wr_jobid_var, NULL },
+	{ "version", &obd_proc_version_fops },
+	{ "pinger", &obd_proc_pinger_fops },
+	{ "health_check", &obd_proc_health_fops },
+	{ "jobid_var", &obd_proc_jobid_var_fops },
 	{ 0 }
 };
 #else
@@ -384,7 +363,6 @@ struct seq_operations obd_device_list_sops = {
 
 static int obd_device_list_open(struct inode *inode, struct file *file)
 {
-	struct proc_dir_entry *dp = PDE(inode);
 	struct seq_file *seq;
 	int rc = seq_open(file, &obd_device_list_sops);
 
@@ -392,7 +370,7 @@ static int obd_device_list_open(struct inode *inode, struct file *file)
 		return rc;
 
 	seq = file->private_data;
-	seq->private = dp->data;
+	seq->private = PDE_DATA(inode);
 
 	return 0;
 }
diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_jobstats.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_jobstats.c
index 7afc2ad..e2d57fe 100644
--- a/drivers/staging/lustre/lustre/obdclass/lprocfs_jobstats.c
+++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_jobstats.c
@@ -418,20 +418,14 @@ 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_AND_CHECK(dp))
-		return -ENOENT;
-
 	rc = seq_open(file, &lprocfs_jobstats_seq_sops);
-	if (rc) {
-		LPROCFS_EXIT();
+	if (rc)
 		return rc;
-	}
 	seq = file->private_data;
-	seq->private = dp->data;
+	seq->private = PDE_DATA(inode);
 	return 0;
 }
 
@@ -523,30 +517,23 @@ int lprocfs_job_stats_init(struct obd_device *obd, int cntr_num,
 	stats->ojs_cleanup_interval = 600; /* 10 mins by default */
 	stats->ojs_last_cleanup = cfs_time_current_sec();
 
-	LPROCFS_WRITE_ENTRY();
-	entry = create_proc_entry("job_stats", 0644, obd->obd_proc_entry);
-	LPROCFS_WRITE_EXIT();
-	if (entry) {
-		entry->proc_fops = &lprocfs_jobstats_seq_fops;
-		entry->data = stats;
+	entry = proc_create_data("job_stats", 0644, obd->obd_proc_entry,
+				 &lprocfs_jobstats_seq_fops, stats);
+	if (entry)
 		RETURN(0);
-	} else {
-		lprocfs_job_stats_fini(obd);
+	else
 		RETURN(-ENOMEM);
-	}
 }
 EXPORT_SYMBOL(lprocfs_job_stats_init);
 
-int lprocfs_rd_job_interval(char *page, char **start, off_t off,
-			    int count, int *eof, void *data)
+int lprocfs_rd_job_interval(struct seq_file *m, void *data)
 {
 	struct obd_device *obd = (struct obd_device *)data;
 	struct obd_job_stats *stats;
 
 	LASSERT(obd != NULL);
 	stats = &obd->u.obt.obt_jobstats;
-	*eof = 1;
-	return snprintf(page, count, "%d\n", stats->ojs_cleanup_interval);
+	return seq_printf(m, "%d\n", stats->ojs_cleanup_interval);
 }
 EXPORT_SYMBOL(lprocfs_rd_job_interval);
 
diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
index 96e568f..7d92db9 100644
--- a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
+++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
@@ -44,6 +44,7 @@
 #include <obd_class.h>
 #include <lprocfs_status.h>
 #include <lustre/lustre_idl.h>
+#include <linux/seq_file.h>
 
 #if defined(LPROCFS)
 
@@ -53,109 +54,39 @@ CFS_MODULE_PARM(lprocfs_no_percpu_stats, "i", int, 0644,
 
 #define MAX_STRING_SIZE 128
 
-/* for bug 10866, global variable */
-DECLARE_RWSEM(_lprocfs_lock);
-EXPORT_SYMBOL(_lprocfs_lock);
-
 int lprocfs_single_release(struct inode *inode, struct file *file)
 {
-	LPROCFS_EXIT();
 	return single_release(inode, file);
 }
 EXPORT_SYMBOL(lprocfs_single_release);
 
 int lprocfs_seq_release(struct inode *inode, struct file *file)
 {
-	LPROCFS_EXIT();
 	return seq_release(inode, file);
 }
 EXPORT_SYMBOL(lprocfs_seq_release);
 
-static struct proc_dir_entry *__lprocfs_srch(struct proc_dir_entry *head,
-					     const char *name)
-{
-	struct proc_dir_entry *temp;
-
-	if (head == NULL)
-		return NULL;
-
-	temp = head->subdir;
-	while (temp != NULL) {
-		if (strcmp(temp->name, name) == 0) {
-			return temp;
-		}
-
-		temp = temp->next;
-	}
-	return NULL;
-}
-
-struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
-				    const char *name)
-{
-	struct proc_dir_entry *temp;
-
-	LPROCFS_SRCH_ENTRY();
-	temp = __lprocfs_srch(head, name);
-	LPROCFS_SRCH_EXIT();
-	return temp;
-}
-EXPORT_SYMBOL(lprocfs_srch);
-
 /* lprocfs API calls */
 
-/* Function that emulates snprintf but also has the side effect of advancing
-   the page pointer for the next write into the buffer, incrementing the total
-   length written to the buffer, and decrementing the size left in the
-   buffer. */
-static int lprocfs_obd_snprintf(char **page, int end, int *len,
-				const char *format, ...)
-{
-	va_list list;
-	int n;
-
-	if (*len >= end)
-		return 0;
-
-	va_start(list, format);
-	n = vsnprintf(*page, end - *len, format, list);
-	va_end(list);
-
-	*page += n; *len += n;
-	return n;
-}
-
 proc_dir_entry_t *lprocfs_add_simple(struct proc_dir_entry *root,
-					 char *name,
-					 read_proc_t *read_proc,
-					 write_proc_t *write_proc,
-					 void *data,
-					 struct file_operations *fops)
+				     char *name, void *data,
+				     struct file_operations *fops)
 {
 	proc_dir_entry_t *proc;
 	mode_t mode = 0;
 
-	if (root == NULL || name == NULL)
+	if (root == NULL || name == NULL || fops == NULL)
 		return ERR_PTR(-EINVAL);
-	if (read_proc)
+
+	if (fops->read)
 		mode = 0444;
-	if (write_proc)
+	if (fops->write)
 		mode |= 0200;
-	if (fops)
-		mode = 0644;
-	LPROCFS_WRITE_ENTRY();
-	proc = create_proc_entry(name, mode, root);
+	proc = proc_create_data(name, mode, root, fops, data);
 	if (!proc) {
 		CERROR("LprocFS: No memory to create /proc entry %s", name);
-		LPROCFS_WRITE_EXIT();
 		return ERR_PTR(-ENOMEM);
 	}
-	proc->read_proc = read_proc;
-	proc->write_proc = write_proc;
-	proc->data = data;
-	if (fops)
-		proc->proc_fops = fops;
-	LPROCFS_WRITE_EXIT();
 	return proc;
 }
 EXPORT_SYMBOL(lprocfs_add_simple);
@@ -188,108 +119,7 @@ struct proc_dir_entry *lprocfs_add_symlink(const char *name,
 }
 EXPORT_SYMBOL(lprocfs_add_symlink);
 
-static ssize_t lprocfs_fops_read(struct file *f, char __user *buf,
-				 size_t size, loff_t *ppos)
-{
-	struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
-	char *page, *start = NULL;
-	int rc = 0, eof = 1, count;
-
-	if (*ppos >= PAGE_CACHE_SIZE)
-		return 0;
-
-	page = (char *)__get_free_page(GFP_KERNEL);
-	if (page == NULL)
-		return -ENOMEM;
-
-	if (LPROCFS_ENTRY_AND_CHECK(dp)) {
-		rc = -ENOENT;
-		goto out;
-	}
-
-	OBD_FAIL_TIMEOUT(OBD_FAIL_LPROC_REMOVE, 10);
-	if (dp->read_proc)
-		rc = dp->read_proc(page, &start, *ppos, PAGE_CACHE_SIZE,
-				   &eof, dp->data);
-	LPROCFS_EXIT();
-	if (rc <= 0)
-		goto out;
-
-	/* for lustre proc read, the read count must be less than PAGE_SIZE */
-	LASSERT(eof == 1);
-
-	if (start == NULL) {
-		rc -= *ppos;
-		if (rc < 0)
-			rc = 0;
-		if (rc == 0)
-			goto out;
-		start = page + *ppos;
-	} else if (start < page) {
-		start = page;
-	}
-
-	count = (rc < size) ? rc : size;
-	if (copy_to_user(buf, start, count)) {
-		rc = -EFAULT;
-		goto out;
-	}
-	*ppos += count;
-
-out:
-	free_page((unsigned long)page);
-	return rc;
-}
-
-static ssize_t lprocfs_fops_write(struct file *f, const char __user *buf,
-				  size_t size, loff_t *ppos)
-{
-	struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
-	int rc = -EIO;
-
-	if (LPROCFS_ENTRY_AND_CHECK(dp))
-		return -ENOENT;
-	if (dp->write_proc)
-		rc = dp->write_proc(f, buf, size, dp->data);
-	LPROCFS_EXIT();
-	return rc;
-}
-
-static struct file_operations lprocfs_generic_fops = {
-	.owner = THIS_MODULE,
-	.read = lprocfs_fops_read,
-	.write = lprocfs_fops_write,
-};
-
-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;
-
-	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;
-
-	atomic_dec(&obd->obd_evict_inprogress);
-	wake_up(&obd->obd_evict_inprogress_waitq);
-
-	return 0;
-}
-
-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,
-};
-EXPORT_SYMBOL(lprocfs_evict_client_fops);
+static struct file_operations lprocfs_generic_fops = { };
 
 /**
  * Add /proc entries.
@@ -305,119 +135,36 @@ EXPORT_SYMBOL(lprocfs_evict_client_fops);
 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
 		     void *data)
 {
-	int rc = 0;
-
 	if (root == NULL || list == NULL)
 		return -EINVAL;
 
-	LPROCFS_WRITE_ENTRY();
 	while (list->name != NULL) {
-		struct proc_dir_entry *cur_root, *proc;
-		char *pathcopy, *cur, *next, pathbuf[64];
-		int pathsize = strlen(list->name) + 1;
-
-		proc = NULL;
-		cur_root = root;
-
-		/* need copy of path for strsep */
-		if (strlen(list->name) > sizeof(pathbuf) - 1) {
-			OBD_ALLOC(pathcopy, pathsize);
-			if (pathcopy == NULL)
-				GOTO(out, rc = -ENOMEM);
-		} else {
-			pathcopy = pathbuf;
-		}
-
-		next = pathcopy;
-		strcpy(pathcopy, list->name);
-
-		while (cur_root != NULL && (cur = strsep(&next, "/"))) {
-			if (*cur =='\0') /* skip double/trailing "/" */
-				continue;
-
-			proc = __lprocfs_srch(cur_root, cur);
-			CDEBUG(D_OTHER, "cur_root=%s, cur=%s, next=%s, (%s)\n",
-			       cur_root->name, cur, next,
-			       (proc ? "exists" : "new"));
-			if (next != NULL) {
-				cur_root = (proc ? proc :
-					    proc_mkdir(cur, cur_root));
-			} else if (proc == NULL) {
-				mode_t mode = 0;
-				if (list->proc_mode != 0000) {
-					mode = list->proc_mode;
-				} else {
-					if (list->read_fptr)
-						mode = 0444;
-					if (list->write_fptr)
-						mode |= 0200;
-				}
-				proc = create_proc_entry(cur, mode, cur_root);
-			}
+		struct proc_dir_entry *proc;
+		mode_t mode = 0;
+
+		if (list->proc_mode != 0000) {
+			mode = list->proc_mode;
+		} else if (list->fops) {
+			if (list->fops->read)
+				mode = 0444;
+			if (list->fops->write)
+				mode |= 0200;
 		}
-
-		if (pathcopy != pathbuf)
-			OBD_FREE(pathcopy, pathsize);
-
-		if (cur_root == NULL || proc == NULL) {
-			CERROR("LprocFS: No memory to create /proc entry %s",
-			       list->name);
-			GOTO(out, rc = -ENOMEM);
-		}
-
-		if (list->fops)
-			proc->proc_fops = list->fops;
-		else
-			proc->proc_fops = &lprocfs_generic_fops;
-		proc->read_proc = list->read_fptr;
-		proc->write_proc = list->write_fptr;
-		proc->data = (list->data ? list->data : data);
+		proc = proc_create_data(list->name, mode, root,
+					list->fops ?: &lprocfs_generic_fops,
+					list->data ?: data);
+		if (proc == NULL)
+			return -ENOMEM;
 		list++;
 	}
-out:
-	LPROCFS_WRITE_EXIT();
-	return rc;
+	return 0;
 }
 EXPORT_SYMBOL(lprocfs_add_vars);
 
-void lprocfs_remove_nolock(struct proc_dir_entry **rooth)
-{
-	struct proc_dir_entry *root = *rooth;
-	struct proc_dir_entry *temp = root;
-	struct proc_dir_entry *rm_entry;
-	struct proc_dir_entry *parent;
-
-	if (!root)
-		return;
-	*rooth = NULL;
-
-	parent = root->parent;
-	LASSERT(parent != NULL);
-
-	while (1) {
-		while (temp->subdir != NULL)
-			temp = temp->subdir;
-
-		rm_entry = temp;
-		temp = temp->parent;
-
-		/* Memory corruption once caused this to fail, and
-		   without this LASSERT we would loop here forever. */
-		LASSERTF(strlen(rm_entry->name) == rm_entry->namelen,
-			 "0x%p  %s/%s len %d\n", rm_entry, temp->name,
-			 rm_entry->name, (int)strlen(rm_entry->name));
-
-		remove_proc_entry(rm_entry->name, temp);
-		if (temp == parent)
-			break;
-	}
-}
-
 void lprocfs_remove(struct proc_dir_entry **rooth)
 {
-	LPROCFS_WRITE_ENTRY(); /* search vs remove race */
-	lprocfs_remove_nolock(rooth);
-	LPROCFS_WRITE_EXIT();
+	proc_remove(*rooth);
+	*rooth = NULL;
 }
 EXPORT_SYMBOL(lprocfs_remove);
 
@@ -428,65 +175,12 @@ void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent)
 }
 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
 
-void lprocfs_try_remove_proc_entry(const char *name,
-				   struct proc_dir_entry *parent)
-{
-	struct proc_dir_entry	 *t = NULL;
-	struct proc_dir_entry	**p;
-	int			  len, busy = 0;
-
-	LASSERT(parent != NULL);
-	len = strlen(name);
-
-	LPROCFS_WRITE_ENTRY();
-
-	/* lookup target name */
-	for (p = &parent->subdir; *p; p = &(*p)->next) {
-		if ((*p)->namelen != len)
-			continue;
-		if (memcmp(name, (*p)->name, len))
-			continue;
-		t = *p;
-		break;
-	}
-
-	if (t) {
-		/* verify it's empty: do not count "num_refs" */
-		for (p = &t->subdir; *p; p = &(*p)->next) {
-			if ((*p)->namelen != strlen("num_refs")) {
-				busy = 1;
-				break;
-			}
-			if (memcmp("num_refs", (*p)->name,
-				   strlen("num_refs"))) {
-				busy = 1;
-				break;
-			}
-		}
-	}
-
-	if (busy == 0)
-		lprocfs_remove_nolock(&t);
-
-	LPROCFS_WRITE_EXIT();
-
-	return;
-}
-EXPORT_SYMBOL(lprocfs_try_remove_proc_entry);
-
 struct proc_dir_entry *lprocfs_register(const char *name,
 					struct proc_dir_entry *parent,
 					struct lprocfs_vars *list, void *data)
 {
 	struct proc_dir_entry *newchild;
 
-	newchild = lprocfs_srch(parent, name);
-	if (newchild != NULL) {
-		CERROR(" Lproc: Attempting to register %s more than once \n",
-		       name);
-		return ERR_PTR(-EALREADY);
-	}
-
 	newchild = proc_mkdir(name, parent);
 	if (newchild != NULL && list != NULL) {
 		int rc = lprocfs_add_vars(newchild, list, data);
@@ -500,15 +194,13 @@ struct proc_dir_entry *lprocfs_register(const char *name,
 EXPORT_SYMBOL(lprocfs_register);
 
 /* Generic callbacks */
-int lprocfs_rd_uint(char *page, char **start, off_t off,
-		    int count, int *eof, void *data)
+int lprocfs_rd_uint(struct seq_file *m, void *data)
 {
-	unsigned int *temp = data;
-	return snprintf(page, count, "%u\n", *temp);
+	return seq_printf(m, "%u\n", *(unsigned int *)data);
 }
 EXPORT_SYMBOL(lprocfs_rd_uint);
 
-int lprocfs_wr_uint(struct file *file, const char *buffer,
+int lprocfs_wr_uint(struct file *file, const char __user *buffer,
 		    unsigned long count, void *data)
 {
 	unsigned *p = data;
@@ -528,26 +220,21 @@ int lprocfs_wr_uint(struct file *file, const char *buffer,
 }
 EXPORT_SYMBOL(lprocfs_wr_uint);
 
-int lprocfs_rd_u64(char *page, char **start, off_t off,
-		   int count, int *eof, void *data)
+int lprocfs_rd_u64(struct seq_file *m, void *data)
 {
-	LASSERT(data != NULL);
-	*eof = 1;
-	return snprintf(page, count, LPU64"\n", *(__u64 *)data);
+	return seq_printf(m, LPU64"\n", *(__u64 *)data);
 }
 EXPORT_SYMBOL(lprocfs_rd_u64);
 
-int lprocfs_rd_atomic(char *page, char **start, off_t off,
-		   int count, int *eof, void *data)
+int lprocfs_rd_atomic(struct seq_file *m, void *data)
 {
 	atomic_t *atom = data;
 	LASSERT(atom != NULL);
-	*eof = 1;
-	return snprintf(page, count, "%d\n", atomic_read(atom));
+	return seq_printf(m, "%d\n", atomic_read(atom));
 }
 EXPORT_SYMBOL(lprocfs_rd_atomic);
 
-int lprocfs_wr_atomic(struct file *file, const char *buffer,
+int lprocfs_wr_atomic(struct file *file, const char __user *buffer,
 		      unsigned long count, void *data)
 {
 	atomic_t *atm = data;
@@ -566,46 +253,38 @@ int lprocfs_wr_atomic(struct file *file, const char *buffer,
 }
 EXPORT_SYMBOL(lprocfs_wr_atomic);
 
-int lprocfs_rd_uuid(char *page, char **start, off_t off, int count,
-		    int *eof, void *data)
+int lprocfs_rd_uuid(struct seq_file *m, void *data)
 {
 	struct obd_device *obd = data;
 
 	LASSERT(obd != NULL);
-	*eof = 1;
-	return snprintf(page, count, "%s\n", obd->obd_uuid.uuid);
+	return seq_printf(m, "%s\n", obd->obd_uuid.uuid);
 }
 EXPORT_SYMBOL(lprocfs_rd_uuid);
 
-int lprocfs_rd_name(char *page, char **start, off_t off, int count,
-		    int *eof, void *data)
+int lprocfs_rd_name(struct seq_file *m, void *data)
 {
 	struct obd_device *dev = data;
 
 	LASSERT(dev != NULL);
-	*eof = 1;
-	return snprintf(page, count, "%s\n", dev->obd_name);
+	return seq_printf(m, "%s\n", dev->obd_name);
 }
 EXPORT_SYMBOL(lprocfs_rd_name);
 
-int lprocfs_rd_blksize(char *page, char **start, off_t off, int count,
-		       int *eof, void *data)
+int lprocfs_rd_blksize(struct seq_file *m, void *data)
 {
 	struct obd_device *obd = data;
 	struct obd_statfs  osfs;
 	int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
 			    cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
 			    OBD_STATFS_NODELAY);
-	if (!rc) {
-		*eof = 1;
-		rc = snprintf(page, count, "%u\n", osfs.os_bsize);
-	}
+	if (!rc)
+		rc = seq_printf(m, "%u\n", osfs.os_bsize);
 	return rc;
 }
 EXPORT_SYMBOL(lprocfs_rd_blksize);
 
-int lprocfs_rd_kbytestotal(char *page, char **start, off_t off, int count,
-			   int *eof, void *data)
+int lprocfs_rd_kbytestotal(struct seq_file *m, void *data)
 {
 	struct obd_device *obd = data;
 	struct obd_statfs  osfs;
@@ -619,15 +298,13 @@ int lprocfs_rd_kbytestotal(char *page, char **start, off_t off, int count,
 		while (blk_size >>= 1)
 			result <<= 1;
 
-		*eof = 1;
-		rc = snprintf(page, count, LPU64"\n", result);
+		rc = seq_printf(m, LPU64"\n", result);
 	}
 	return rc;
 }
 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
 
-int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, int count,
-			  int *eof, void *data)
+int lprocfs_rd_kbytesfree(struct seq_file *m, void *data)
 {
 	struct obd_device *obd = data;
 	struct obd_statfs  osfs;
@@ -641,15 +318,13 @@ int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, int count,
 		while (blk_size >>= 1)
 			result <<= 1;
 
-		*eof = 1;
-		rc = snprintf(page, count, LPU64"\n", result);
+		rc = seq_printf(m, LPU64"\n", result);
 	}
 	return rc;
 }
 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
 
-int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count,
-			   int *eof, void *data)
+int lprocfs_rd_kbytesavail(struct seq_file *m, void *data)
 {
 	struct obd_device *obd = data;
 	struct obd_statfs  osfs;
@@ -663,48 +338,40 @@ int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count,
 		while (blk_size >>= 1)
 			result <<= 1;
 
-		*eof = 1;
-		rc = snprintf(page, count, LPU64"\n", result);
+		rc = seq_printf(m, LPU64"\n", result);
 	}
 	return rc;
 }
 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
 
-int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count,
-			  int *eof, void *data)
+int lprocfs_rd_filestotal(struct seq_file *m, void *data)
 {
 	struct obd_device *obd = data;
 	struct obd_statfs  osfs;
 	int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
 			    cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
 			    OBD_STATFS_NODELAY);
-	if (!rc) {
-		*eof = 1;
-		rc = snprintf(page, count, LPU64"\n", osfs.os_files);
-	}
+	if (!rc)
+		rc = seq_printf(m, LPU64"\n", osfs.os_files);
 
 	return rc;
 }
 EXPORT_SYMBOL(lprocfs_rd_filestotal);
 
-int lprocfs_rd_filesfree(char *page, char **start, off_t off, int count,
-			 int *eof, void *data)
+int lprocfs_rd_filesfree(struct seq_file *m, void *data)
 {
 	struct obd_device *obd = data;
 	struct obd_statfs  osfs;
 	int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
 			    cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
 			    OBD_STATFS_NODELAY);
-	if (!rc) {
-		*eof = 1;
-		rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
-	}
+	if (!rc)
+		rc = seq_printf(m, LPU64"\n", osfs.os_ffree);
 	return rc;
 }
 EXPORT_SYMBOL(lprocfs_rd_filesfree);
 
-int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count,
-			   int *eof, void *data)
+int lprocfs_rd_server_uuid(struct seq_file *m, void *data)
 {
 	struct obd_device *obd = data;
 	struct obd_import *imp;
@@ -715,18 +382,15 @@ int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count,
 	LPROCFS_CLIMP_CHECK(obd);
 	imp = obd->u.cli.cl_import;
 	imp_state_name = ptlrpc_import_state_name(imp->imp_state);
-	*eof = 1;
-	rc = snprintf(page, count, "%s\t%s%s\n",
-		      obd2cli_tgt(obd), imp_state_name,
-		      imp->imp_deactive ? "\tDEACTIVATED" : "");
+	rc = seq_printf(m, "%s\t%s%s\n", obd2cli_tgt(obd), imp_state_name,
+			imp->imp_deactive ? "\tDEACTIVATED" : "");
 
 	LPROCFS_CLIMP_EXIT(obd);
 	return rc;
 }
 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
 
-int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
-			 int *eof,  void *data)
+int lprocfs_rd_conn_uuid(struct seq_file *m, void *data)
 {
 	struct obd_device *obd = data;
 	struct ptlrpc_connection *conn;
@@ -736,13 +400,10 @@ int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
 
 	LPROCFS_CLIMP_CHECK(obd);
 	conn = obd->u.cli.cl_import->imp_connection;
-	*eof = 1;
-	if (conn && obd->u.cli.cl_import) {
-		rc = snprintf(page, count, "%s\n",
-			      conn->c_remote_uuid.uuid);
-	} else {
-		rc = snprintf(page, count, "%s\n", "<none>");
-	}
+	if (conn && obd->u.cli.cl_import)
+		rc = seq_printf(m, "%s\n", conn->c_remote_uuid.uuid);
+	else
+		rc = seq_printf(m, "%s\n", "<none>");
 
 	LPROCFS_CLIMP_EXIT(obd);
 	return rc;
@@ -793,21 +454,26 @@ EXPORT_SYMBOL(lprocfs_stats_collect);
 /**
  * Append a space separated list of current set flags to str.
  */
-#define flag2str(flag) \
-	if (imp->imp_##flag && max - len > 0) \
-	     len += snprintf(str + len, max - len, "%s" #flag, len ? ", " : "");
-static int obd_import_flags2str(struct obd_import *imp, char *str, int max)
-{
-	int len = 0;
-
-	if (imp->imp_obd->obd_no_recov)
-		len += snprintf(str, max - len, "no_recov");
+#define flag2str(flag, first)						\
+	do {								\
+		if (imp->imp_##flag)					\
+		     seq_printf(m, "%s" #flag, first ? "" : ", ");	\
+	} while (0)
+static int obd_import_flags2str(struct obd_import *imp, struct seq_file *m)
+{
+	bool first = true;
+
+	if (imp->imp_obd->obd_no_recov) {
+		seq_printf(m, "no_recov");
+		first = false;
+	}
 
-	flag2str(invalid);
-	flag2str(deactive);
-	flag2str(replayable);
-	flag2str(pingable);
-	return len;
+	flag2str(invalid, first);
+	first = false;
+	flag2str(deactive, first);
+	flag2str(replayable, first);
+	flag2str(pingable, first);
+	return 0;
 }
 #undef flags2str
 
@@ -867,6 +533,24 @@ static const char *obd_connect_names[] = {
 	NULL
 };
 
+static void obd_connect_seq_flags2str(struct seq_file *m, __u64 flags, char *sep)
+{
+	__u64 mask = 1;
+	int i;
+	bool first = true;
+
+	for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
+		if (flags & mask) {
+			seq_printf(m, "%s%s",
+					first ? sep : "", obd_connect_names[i]);
+			first = false;
+		}
+	}
+	if (flags & ~(mask - 1))
+		seq_printf(m, "%sunknown flags "LPX64,
+				first ? sep : "", flags & ~(mask - 1));
+}
+
 int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
 {
 	__u64 mask = 1;
@@ -885,15 +569,13 @@ int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
 }
 EXPORT_SYMBOL(obd_connect_flags2str);
 
-int lprocfs_rd_import(char *page, char **start, off_t off, int count,
-		      int *eof, void *data)
+int lprocfs_rd_import(struct seq_file *m, void *data)
 {
 	struct lprocfs_counter		ret;
 	struct lprocfs_counter_header	*header;
 	struct obd_device		*obd	= (struct obd_device *)data;
 	struct obd_import		*imp;
 	struct obd_import_conn		*conn;
-	int				i;
 	int				j;
 	int				k;
 	int				rw	= 0;
@@ -901,9 +583,8 @@ int lprocfs_rd_import(char *page, char **start, off_t off, int count,
 	LASSERT(obd != NULL);
 	LPROCFS_CLIMP_CHECK(obd);
 	imp = obd->u.cli.cl_import;
-	*eof = 1;
 
-	i = snprintf(page, count,
+	seq_printf(m,
 		     "import:\n"
 		     "    name: %s\n"
 		     "    target: %s\n"
@@ -914,26 +595,24 @@ int lprocfs_rd_import(char *page, char **start, off_t off, int count,
 		     obd2cli_tgt(obd),
 		     ptlrpc_import_state_name(imp->imp_state),
 		     imp->imp_connect_data.ocd_instance);
-	i += obd_connect_flags2str(page + i, count - i,
-				   imp->imp_connect_data.ocd_connect_flags,
-				   ", ");
-	i += snprintf(page + i, count - i,
+	obd_connect_seq_flags2str(m, imp->imp_connect_data.ocd_connect_flags, ", ");
+	seq_printf(m,
 		      "]\n"
 		      "    import_flags: [");
-	i += obd_import_flags2str(imp, page + i, count - i);
+	obd_import_flags2str(imp, m);
 
-	i += snprintf(page + i, count - i,
+	seq_printf(m,
 		      "]\n"
 		      "    connection:\n"
 		      "       failover_nids: [");
 	spin_lock(&imp->imp_lock);
 	j = 0;
 	list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
-		i += snprintf(page + i, count - i, "%s%s", j ? ", " : "",
-			      libcfs_nid2str(conn->oic_conn->c_peer.nid));
+		seq_printf(m, "%s%s", j ? ", " : "",
+			   libcfs_nid2str(conn->oic_conn->c_peer.nid));
 		j++;
 	}
-	i += snprintf(page + i, count - i,
+	seq_printf(m,
 		      "]\n"
 		      "       current_connection: %s\n"
 		      "       connection_attempts: %u\n"
@@ -958,7 +637,7 @@ int lprocfs_rd_import(char *page, char **start, off_t off, int count,
 		ret.lc_sum = sum;
 	} else
 		ret.lc_sum = 0;
-	i += snprintf(page + i, count - i,
+	seq_printf(m,
 		      "    rpcs:\n"
 		      "       inflight: %u\n"
 		      "       unregistering: %u\n"
@@ -976,14 +655,14 @@ int lprocfs_rd_import(char *page, char **start, off_t off, int count,
 		k = max_t(unsigned int, k,
 			  at_get(&imp->imp_at.iat_service_estimate[j]));
 	}
-	i += snprintf(page + i, count - i,
+	seq_printf(m,
 		      "    service_estimates:\n"
 		      "       services: %u sec\n"
 		      "       network: %u sec\n",
 		      k,
 		      at_get(&imp->imp_at.iat_net_latency));
 
-	i += snprintf(page + i, count - i,
+	seq_printf(m,
 		      "    transactions:\n"
 		      "       last_replay: "LPU64"\n"
 		      "       peer_committed: "LPU64"\n"
@@ -1002,7 +681,7 @@ int lprocfs_rd_import(char *page, char **start, off_t off, int count,
 			__u64 sum = ret.lc_sum;
 			do_div(sum, ret.lc_count);
 			ret.lc_sum = sum;
-			i += snprintf(page + i, count - i,
+			seq_printf(m,
 				      "    %s_data_averages:\n"
 				      "       bytes_per_rpc: "LPU64"\n",
 				      rw ? "write" : "read",
@@ -1017,12 +696,12 @@ int lprocfs_rd_import(char *page, char **start, off_t off, int count,
 			__u64 sum = ret.lc_sum;
 			do_div(sum, ret.lc_count);
 			ret.lc_sum = sum;
-			i += snprintf(page + i, count - i,
+			seq_printf(m,
 				      "       %s_per_rpc: "LPU64"\n",
 				      header->lc_units, ret.lc_sum);
 			j = (int)ret.lc_sum;
 			if (j > 0)
-				i += snprintf(page + i, count - i,
+				seq_printf(m,
 					      "       MB_per_sec: %u.%.02u\n",
 					      k / j, (100 * k / j) % 100);
 		}
@@ -1030,86 +709,77 @@ int lprocfs_rd_import(char *page, char **start, off_t off, int count,
 
 out_climp:
 	LPROCFS_CLIMP_EXIT(obd);
-	return i;
+	return 0;
 }
 EXPORT_SYMBOL(lprocfs_rd_import);
 
-int lprocfs_rd_state(char *page, char **start, off_t off, int count,
-		      int *eof, void *data)
+int lprocfs_rd_state(struct seq_file *m, void *data)
 {
 	struct obd_device *obd = (struct obd_device *)data;
 	struct obd_import *imp;
-	int i, j, k;
+	int j, k;
 
 	LASSERT(obd != NULL);
 	LPROCFS_CLIMP_CHECK(obd);
 	imp = obd->u.cli.cl_import;
-	*eof = 1;
 
-	i = snprintf(page, count, "current_state: %s\n",
+	seq_printf(m, "current_state: %s\n",
 		     ptlrpc_import_state_name(imp->imp_state));
-	i += snprintf(page + i, count - i,
-		      "state_history:\n");
+	seq_printf(m, "state_history:\n");
 	k = imp->imp_state_hist_idx;
 	for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
 		struct import_state_hist *ish =
 			&imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
 		if (ish->ish_state == 0)
 			continue;
-		i += snprintf(page + i, count - i, " - ["CFS_TIME_T", %s]\n",
+		seq_printf(m, " - ["CFS_TIME_T", %s]\n",
 			      ish->ish_time,
 			      ptlrpc_import_state_name(ish->ish_state));
 	}
 
 	LPROCFS_CLIMP_EXIT(obd);
-	return i;
+	return 0;
 }
 EXPORT_SYMBOL(lprocfs_rd_state);
 
-int lprocfs_at_hist_helper(char *page, int count, int rc,
-			   struct adaptive_timeout *at)
+int lprocfs_at_hist_helper(struct seq_file *m, struct adaptive_timeout *at)
 {
 	int i;
 	for (i = 0; i < AT_BINS; i++)
-		rc += snprintf(page + rc, count - rc, "%3u ", at->at_hist[i]);
-	rc += snprintf(page + rc, count - rc, "\n");
-	return rc;
+		seq_printf(m, "%3u ", at->at_hist[i]);
+	seq_printf(m, "\n");
+	return 0;
 }
 EXPORT_SYMBOL(lprocfs_at_hist_helper);
 
 /* See also ptlrpc_lprocfs_rd_timeouts */
-int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
-			int *eof, void *data)
+int lprocfs_rd_timeouts(struct seq_file *m, void *data)
 {
 	struct obd_device *obd = (struct obd_device *)data;
 	struct obd_import *imp;
 	unsigned int cur, worst;
 	time_t now, worstt;
 	struct dhms ts;
-	int i, rc = 0;
+	int i;
 
 	LASSERT(obd != NULL);
 	LPROCFS_CLIMP_CHECK(obd);
 	imp = obd->u.cli.cl_import;
-	*eof = 1;
 
 	now = cfs_time_current_sec();
 
 	/* Some network health info for kicks */
 	s2dhms(&ts, now - imp->imp_last_reply_time);
-	rc += snprintf(page + rc, count - rc,
-		       "%-10s : %ld, "DHMS_FMT" ago\n",
+	seq_printf(m, "%-10s : %ld, "DHMS_FMT" ago\n",
 		       "last reply", imp->imp_last_reply_time, DHMS_VARS(&ts));
 
 	cur = at_get(&imp->imp_at.iat_net_latency);
 	worst = imp->imp_at.iat_net_latency.at_worst_ever;
 	worstt = imp->imp_at.iat_net_latency.at_worst_time;
 	s2dhms(&ts, now - worstt);
-	rc += snprintf(page + rc, count - rc,
-		       "%-10s : cur %3u  worst %3u (at %ld, "DHMS_FMT" ago) ",
+	seq_printf(m, "%-10s : cur %3u  worst %3u (at %ld, "DHMS_FMT" ago) ",
 		       "network", cur, worst, worstt, DHMS_VARS(&ts));
-	rc = lprocfs_at_hist_helper(page, count, rc,
-				    &imp->imp_at.iat_net_latency);
+	lprocfs_at_hist_helper(m, &imp->imp_at.iat_net_latency);
 
 	for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
 		if (imp->imp_at.iat_portal[i] == 0)
@@ -1118,55 +788,47 @@ int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
 		worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
 		worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
 		s2dhms(&ts, now - worstt);
-		rc += snprintf(page + rc, count - rc,
-			       "portal %-2d  : cur %3u  worst %3u (at %ld, "
+		seq_printf(m, "portal %-2d  : cur %3u  worst %3u (at %ld, "
 			       DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
 			       cur, worst, worstt, DHMS_VARS(&ts));
-		rc = lprocfs_at_hist_helper(page, count, rc,
-					  &imp->imp_at.iat_service_estimate[i]);
+		lprocfs_at_hist_helper(m, &imp->imp_at.iat_service_estimate[i]);
 	}
 
 	LPROCFS_CLIMP_EXIT(obd);
-	return rc;
+	return 0;
 }
 EXPORT_SYMBOL(lprocfs_rd_timeouts);
 
-int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
-			     int count, int *eof, void *data)
+int lprocfs_rd_connect_flags(struct seq_file *m, void *data)
 {
 	struct obd_device *obd = data;
 	__u64 flags;
-	int ret = 0;
 
 	LPROCFS_CLIMP_CHECK(obd);
 	flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
-	ret = snprintf(page, count, "flags="LPX64"\n", flags);
-	ret += obd_connect_flags2str(page + ret, count - ret, flags, "\n");
-	ret += snprintf(page + ret, count - ret, "\n");
+	seq_printf(m, "flags="LPX64"\n", flags);
+	obd_connect_seq_flags2str(m, flags, "\n");
+	seq_printf(m, "\n");
 	LPROCFS_CLIMP_EXIT(obd);
-	return ret;
+	return 0;
 }
 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
 
-int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
-			   int *eof,  void *data)
+int lprocfs_rd_num_exports(struct seq_file *m, void *data)
 {
 	struct obd_device *obd = data;
 
 	LASSERT(obd != NULL);
-	*eof = 1;
-	return snprintf(page, count, "%u\n", obd->obd_num_exports);
+	return seq_printf(m, "%u\n", obd->obd_num_exports);
 }
 EXPORT_SYMBOL(lprocfs_rd_num_exports);
 
-int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
-		       int *eof, void *data)
+int lprocfs_rd_numrefs(struct seq_file *m, void *data)
 {
 	struct obd_type *class = (struct obd_type*) data;
 
 	LASSERT(class != NULL);
-	*eof = 1;
-	return snprintf(page, count, "%d\n", class->typ_refcnt);
+	return seq_printf(m, "%d\n", class->typ_refcnt);
 }
 EXPORT_SYMBOL(lprocfs_rd_numrefs);
 
@@ -1196,7 +858,6 @@ int lprocfs_obd_cleanup(struct obd_device *obd)
 		return -EINVAL;
 	if (obd->obd_proc_exports_entry) {
 		/* Should be no exports left */
-		LASSERT(obd->obd_proc_exports_entry->subdir == NULL);
 		lprocfs_remove(&obd->obd_proc_exports_entry);
 		obd->obd_proc_exports_entry = NULL;
 	}
@@ -1364,7 +1025,8 @@ void lprocfs_clear_stats(struct lprocfs_stats *stats)
 }
 EXPORT_SYMBOL(lprocfs_clear_stats);
 
-static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
+static ssize_t lprocfs_stats_seq_write(struct file *file,
+				       const char __user *buf,
 				       size_t len, loff_t *off)
 {
 	struct seq_file *seq = file->private_data;
@@ -1457,20 +1119,14 @@ struct seq_operations lprocfs_stats_seq_sops = {
 
 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
 {
-	struct proc_dir_entry *dp = PDE(inode);
 	struct seq_file *seq;
 	int rc;
 
-	if (LPROCFS_ENTRY_AND_CHECK(dp))
-		return -ENOENT;
-
 	rc = seq_open(file, &lprocfs_stats_seq_sops);
-	if (rc) {
-		LPROCFS_EXIT();
+	if (rc)
 		return rc;
-	}
 	seq = file->private_data;
-	seq->private = dp->data;
+	seq->private = PDE_DATA(inode);
 	return 0;
 }
 
@@ -1489,15 +1145,8 @@ int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
 	struct proc_dir_entry *entry;
 	LASSERT(root != NULL);
 
-	LPROCFS_WRITE_ENTRY();
-	entry = create_proc_entry(name, 0644, root);
-	if (entry) {
-		entry->proc_fops = &lprocfs_stats_seq_fops;
-		entry->data = stats;
-	}
-
-	LPROCFS_WRITE_EXIT();
-
+	entry = proc_create_data(name, 0644, root,
+				 &lprocfs_stats_seq_fops, stats);
 	if (entry == NULL)
 		return -ENOMEM;
 
@@ -1783,103 +1432,72 @@ void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
 }
 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
 
-int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
-			 int *eof,  void *data)
-{
-	struct obd_export *exp = data;
-	LASSERT(exp != NULL);
-	*eof = 1;
-	return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
-}
-
-struct exp_uuid_cb_data {
-	char		   *page;
-	int		     count;
-	int		    *eof;
-	int		    *len;
-};
-
-static void
-lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
-			    int count, int *eof, int *len)
-{
-	cb_data->page = page;
-	cb_data->count = count;
-	cb_data->eof = eof;
-	cb_data->len = len;
-}
-
 int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
-			   struct hlist_node *hnode, void *cb_data)
+			   struct hlist_node *hnode, void *data)
 
 {
 	struct obd_export *exp = cfs_hash_object(hs, hnode);
-	struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
+	struct seq_file *m = (struct seq_file *)data;
 
 	if (exp->exp_nid_stats)
-		*data->len += snprintf((data->page + *data->len),
-				       data->count, "%s\n",
-				       obd_uuid2str(&exp->exp_client_uuid));
+		seq_printf(m, "%s\n", obd_uuid2str(&exp->exp_client_uuid));
+
 	return 0;
 }
 
-int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
-			int *eof,  void *data)
+static int
+lproc_exp_uuid_seq_show(struct seq_file *m, void *unused)
 {
-	struct nid_stat *stats = (struct nid_stat *)data;
-	struct exp_uuid_cb_data cb_data;
+	struct nid_stat *stats = (struct nid_stat *)m->private;
 	struct obd_device *obd = stats->nid_obd;
-	int len = 0;
 
-	*eof = 1;
-	page[0] = '\0';
-	lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
 	cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
-			      lprocfs_exp_print_uuid, &cb_data);
-	return (*cb_data.len);
+			      lprocfs_exp_print_uuid, m);
+	return 0;
 }
 
+LPROC_SEQ_FOPS_RO(lproc_exp_uuid);
+
+struct exp_hash_cb_data {
+	struct seq_file *m;
+	bool		first;
+};
+
 int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
 			   struct hlist_node *hnode, void *cb_data)
 
 {
-	struct exp_uuid_cb_data *data = cb_data;
+	struct exp_hash_cb_data *data = (struct exp_hash_cb_data *)cb_data;
 	struct obd_export       *exp = cfs_hash_object(hs, hnode);
 
 	if (exp->exp_lock_hash != NULL) {
-		if (!*data->len) {
-			*data->len += cfs_hash_debug_header(data->page,
-							    data->count);
+		if (data->first) {
+			cfs_hash_debug_header(data->m);
+			data->first = false;
 		}
-		*data->len += cfs_hash_debug_str(hs, data->page + *data->len,
-						 data->count);
+		cfs_hash_debug_str(hs, data->m);
 	}
 
 	return 0;
 }
 
-int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
-			int *eof,  void *data)
+static int
+lproc_exp_hash_seq_show(struct seq_file *m, void *unused)
 {
-	struct nid_stat *stats = (struct nid_stat *)data;
-	struct exp_uuid_cb_data cb_data;
+	struct nid_stat *stats = (struct nid_stat *)m->private;
 	struct obd_device *obd = stats->nid_obd;
-	int len = 0;
-
-	*eof = 1;
-	page[0] = '\0';
-	lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
+	struct exp_hash_cb_data cb_data = {m, true};
 
 	cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
 			      lprocfs_exp_print_hash, &cb_data);
-	return (*cb_data.len);
+	return 0;
 }
 
-int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
-					int count, int *eof,  void *data)
+LPROC_SEQ_FOPS_RO(lproc_exp_hash);
+
+int lprocfs_nid_stats_clear_read(struct seq_file *m, void *data)
 {
-	*eof = 1;
-	return snprintf(page, count, "%s\n",
+	return seq_printf(m, "%s\n",
 			"Write into this file to clear all nid stats and "
 			"stale nid entries");
 }
@@ -1997,7 +1615,7 @@ int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
 	}
 
 	entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
-				   lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
+				   new_stat, &lproc_exp_uuid_fops);
 	if (IS_ERR(entry)) {
 		CWARN("Error adding the NID stats file\n");
 		rc = PTR_ERR(entry);
@@ -2005,7 +1623,7 @@ int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
 	}
 
 	entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
-				   lprocfs_exp_rd_hash, NULL, new_stat, NULL);
+				   new_stat, &lproc_exp_hash_fops);
 	if (IS_ERR(entry)) {
 		CWARN("Error adding the hash file\n");
 		rc = PTR_ERR(entry);
@@ -2152,6 +1770,31 @@ int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
 }
 EXPORT_SYMBOL(lprocfs_read_frac_helper);
 
+int lprocfs_seq_read_frac_helper(struct seq_file *m, long val, int mult)
+{
+	long decimal_val, frac_val;
+
+	decimal_val = val / mult;
+	seq_printf(m, "%ld", decimal_val);
+	frac_val = val % mult;
+
+	if (frac_val > 0) {
+		frac_val *= 100;
+		frac_val /= mult;
+	}
+	if (frac_val > 0) {
+		/* Three cases: x0, xx, 0x */
+		if ((frac_val % 10) != 0)
+			seq_printf(m, ".%ld", frac_val);
+		else
+			seq_printf(m, ".%ld", frac_val / 10);
+	}
+
+	seq_printf(m, "\n");
+	return 0;
+}
+EXPORT_SYMBOL(lprocfs_seq_read_frac_helper);
+
 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
 {
 	return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
@@ -2277,14 +1920,7 @@ int lprocfs_seq_create(proc_dir_entry_t *parent,
 
 	/* Disallow secretly (un)writable entries. */
 	LASSERT((seq_fops->write == NULL) == ((mode & 0222) == 0));
-
-	LPROCFS_WRITE_ENTRY();
-	entry = create_proc_entry(name, mode, parent);
-	if (entry) {
-		entry->proc_fops = seq_fops;
-		entry->data = data;
-	}
-	LPROCFS_WRITE_EXIT();
+	entry = proc_create_data(name, mode, parent, seq_fops, data);
 
 	if (entry == NULL)
 		RETURN(-ENOMEM);
@@ -2345,255 +1981,17 @@ void lprocfs_oh_clear(struct obd_histogram *oh)
 }
 EXPORT_SYMBOL(lprocfs_oh_clear);
 
-int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
-			int count, int *eof, void *data)
-{
-	struct obd_device *obd = data;
-	int c = 0;
-
-	if (obd == NULL)
-		return 0;
-
-	c += cfs_hash_debug_header(page, count);
-	c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
-	c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
-	c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
-
-	return c;
-}
-EXPORT_SYMBOL(lprocfs_obd_rd_hash);
-
-int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
-				   int count, int *eof, void *data)
-{
-	struct obd_device *obd = data;
-	int len = 0, size;
-
-	LASSERT(obd != NULL);
-	LASSERT(count >= 0);
-
-	/* Set start of user data returned to
-	   page + off since the user may have
-	   requested to read much smaller than
-	   what we need to read */
-	*start = page + off;
-
-	/* We know we are allocated a page here.
-	   Also we know that this function will
-	   not need to write more than a page
-	   so we can truncate at PAGE_CACHE_SIZE.  */
-	size = min(count + (int)off + 1, (int)PAGE_CACHE_SIZE);
-
-	/* Initialize the page */
-	memset(page, 0, size);
-
-	if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
-		goto out;
-	if (obd->obd_max_recoverable_clients == 0) {
-		if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
-			goto out;
-
-		goto fclose;
-	}
-
-	/* sampled unlocked, but really... */
-	if (obd->obd_recovering == 0) {
-		if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
-			goto out;
-		if (lprocfs_obd_snprintf(&page, size, &len,
-					 "recovery_start: %lu\n",
-					 obd->obd_recovery_start) <= 0)
-			goto out;
-		if (lprocfs_obd_snprintf(&page, size, &len,
-					 "recovery_duration: %lu\n",
-					 obd->obd_recovery_end -
-					 obd->obd_recovery_start) <= 0)
-			goto out;
-		/* Number of clients that have completed recovery */
-		if (lprocfs_obd_snprintf(&page, size, &len,
-					 "completed_clients: %d/%d\n",
-					 obd->obd_max_recoverable_clients -
-					 obd->obd_stale_clients,
-					 obd->obd_max_recoverable_clients) <= 0)
-			goto out;
-		if (lprocfs_obd_snprintf(&page, size, &len,
-					 "replayed_requests: %d\n",
-					 obd->obd_replayed_requests) <= 0)
-			goto out;
-		if (lprocfs_obd_snprintf(&page, size, &len,
-					 "last_transno: "LPD64"\n",
-					 obd->obd_next_recovery_transno - 1)<=0)
-			goto out;
-		if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
-					 obd->obd_version_recov ?
-					 "ENABLED" : "DISABLED") <=0)
-			goto out;
-		if (lprocfs_obd_snprintf(&page, size, &len, "IR: %s\n",
-					 obd->obd_no_ir ?
-					 "DISABLED" : "ENABLED") <= 0)
-			goto out;
-		goto fclose;
-	}
-
-	if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
-		goto out;
-	if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
-				 obd->obd_recovery_start) <= 0)
-		goto out;
-	if (lprocfs_obd_snprintf(&page, size, &len, "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()) <= 0)
-		goto out;
-	if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
-				 atomic_read(&obd->obd_connected_clients),
-				 obd->obd_max_recoverable_clients) <= 0)
-		goto out;
-	/* Number of clients that have completed recovery */
-	if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
-				 atomic_read(&obd->obd_req_replay_clients))
-		<= 0)
-		goto out;
-	if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
-				 atomic_read(&obd->obd_lock_replay_clients))
-		<=0)
-		goto out;
-	if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
-				 atomic_read(&obd->obd_connected_clients) -
-				 atomic_read(&obd->obd_lock_replay_clients))
-		<=0)
-		goto out;
-	if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
-				 obd->obd_stale_clients) <= 0)
-		goto out;
-	if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
-				 obd->obd_replayed_requests) <= 0)
-		goto out;
-	if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
-				 obd->obd_requests_queued_for_recovery) <= 0)
-		goto out;
-
-	if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
-				 obd->obd_next_recovery_transno) <= 0)
-		goto out;
-
-fclose:
-	*eof = 1;
-out:
-	return min(count, len - (int)off);
-}
-EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
-
-int lprocfs_obd_rd_ir_factor(char *page, char **start, off_t off,
-			     int count, int *eof, void *data)
-{
-	struct obd_device *obd = (struct obd_device *)data;
-	LASSERT(obd != NULL);
-
-	return snprintf(page, count, "%d\n",
-			obd->obd_recovery_ir_factor);
-}
-EXPORT_SYMBOL(lprocfs_obd_rd_ir_factor);
-
-int lprocfs_obd_wr_ir_factor(struct file *file, const char *buffer,
-			     unsigned long count, void *data)
-{
-	struct obd_device *obd = (struct obd_device *)data;
-	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_obd_wr_ir_factor);
-
-int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
-				      int count, int *eof, void *data)
-{
-	struct obd_device *obd = (struct obd_device *)data;
-	LASSERT(obd != NULL);
-
-	return snprintf(page, count, "%d\n",
-			obd->obd_recovery_timeout);
-}
-EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
-
-int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
-				      unsigned long count, void *data)
-{
-	struct obd_device *obd = (struct obd_device *)data;
-	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_obd_wr_recovery_time_soft);
-
-int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
-				      int count, int *eof, void *data)
-{
-	struct obd_device *obd = data;
-	LASSERT(obd != NULL);
-
-	return snprintf(page, count, "%u\n", obd->obd_recovery_time_hard);
-}
-EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
-
-int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
-				      unsigned long count, void *data)
-{
-	struct obd_device *obd = data;
-	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_obd_wr_recovery_time_hard);
-
-int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off,
-				     int count, int *eof, void *data)
+int lprocfs_obd_rd_max_pages_per_rpc(struct seq_file *m, void *data)
 {
 	struct obd_device *dev = data;
 	struct client_obd *cli = &dev->u.cli;
 	int rc;
 
 	client_obd_list_lock(&cli->cl_loi_list_lock);
-	rc = snprintf(page, count, "%d\n", cli->cl_max_pages_per_rpc);
+	rc = seq_printf(m, "%d\n", cli->cl_max_pages_per_rpc);
 	client_obd_list_unlock(&cli->cl_loi_list_lock);
 	return rc;
 }
 EXPORT_SYMBOL(lprocfs_obd_rd_max_pages_per_rpc);
 
-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 /* LPROCFS*/
diff --git a/drivers/staging/lustre/lustre/obdclass/lu_object.c b/drivers/staging/lustre/lustre/obdclass/lu_object.c
index 6c0de3f..1cbbb6f 100644
--- a/drivers/staging/lustre/lustre/obdclass/lu_object.c
+++ b/drivers/staging/lustre/lustre/obdclass/lu_object.c
@@ -2021,14 +2021,14 @@ static __u32 ls_stats_read(struct lprocfs_stats *stats, int idx)
  * Output site statistical counters into a buffer. Suitable for
  * lprocfs_rd_*()-style functions.
  */
-int lu_site_stats_print(const struct lu_site *s, char *page, int count)
+int lu_site_stats_print(const struct lu_site *s, struct seq_file *m)
 {
 	lu_site_stats_t stats;
 
 	memset(&stats, 0, sizeof(stats));
 	lu_site_stats_get(s->ls_obj_hash, &stats, 1);
 
-	return snprintf(page, count, "%d/%d %d/%d %d %d %d %d %d %d %d\n",
+	return seq_printf(m, "%d/%d %d/%d %d %d %d %d %d %d %d\n",
 			stats.lss_busy,
 			stats.lss_total,
 			stats.lss_populated,
diff --git a/drivers/staging/lustre/lustre/obdclass/obd_config.c b/drivers/staging/lustre/lustre/obdclass/obd_config.c
index 9636aa9..bbf06d0 100644
--- a/drivers/staging/lustre/lustre/obdclass/obd_config.c
+++ b/drivers/staging/lustre/lustre/obdclass/obd_config.c
@@ -1237,6 +1237,8 @@ int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars,
 			     struct lustre_cfg *lcfg, void *data)
 {
 	struct lprocfs_vars *var;
+	struct file fakefile;
+	struct seq_file fake_seqfile;
 	char *key, *sval;
 	int i, keylen, vallen;
 	int matched = 0, j = 0;
@@ -1249,6 +1251,9 @@ int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars,
 		RETURN(-EINVAL);
 	}
 
+	/* fake a seq file so that var->fops->write can work... */
+	fakefile.private_data = &fake_seqfile;
+	fake_seqfile.private = data;
 	/* e.g. tunefs.lustre --param mdt.group_upcall=foo /r/tmp/lustre-mdt
 	   or   lctl conf_param lustre-MDT0000.mdt.group_upcall=bar
 	   or   lctl conf_param lustre-OST0000.osc.max_dirty_mb=36 */
@@ -1274,12 +1279,12 @@ int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars,
 			    keylen == strlen(var->name)) {
 				matched++;
 				rc = -EROFS;
-				if (var->write_fptr) {
+				if (var->fops && var->fops->write) {
 					mm_segment_t oldfs;
 					oldfs = get_fs();
 					set_fs(KERNEL_DS);
-					rc = (var->write_fptr)(NULL, sval,
-							       vallen, data);
+					rc = (var->fops->write)(&fakefile, sval,
+								vallen, NULL);
 					set_fs(oldfs);
 				}
 				break;
diff --git a/drivers/staging/lustre/lustre/obdecho/lproc_echo.c b/drivers/staging/lustre/lustre/obdecho/lproc_echo.c
index e23ed32..b9abac1 100644
--- a/drivers/staging/lustre/lustre/obdecho/lproc_echo.c
+++ b/drivers/staging/lustre/lustre/obdecho/lproc_echo.c
@@ -37,13 +37,15 @@
 #include <obd_class.h>
 
 #ifdef LPROCFS
+LPROC_SEQ_FOPS_RO_TYPE(echo, uuid);
 static struct lprocfs_vars lprocfs_echo_obd_vars[] = {
-	{ "uuid",	 lprocfs_rd_uuid,	0, 0 },
+	{ "uuid",	 &echo_uuid_fops,	0, 0 },
 	{ 0 }
 };
 
+LPROC_SEQ_FOPS_RO_TYPE(echo, numrefs);
 static struct lprocfs_vars lprocfs_echo_module_vars[] = {
-	{ "num_refs",     lprocfs_rd_numrefs,     0, 0 },
+	{ "num_refs",     &echo_numrefs_fops,     0, 0 },
 	{ 0 }
 };
 
diff --git a/drivers/staging/lustre/lustre/osc/lproc_osc.c b/drivers/staging/lustre/lustre/osc/lproc_osc.c
index 016ad02..198cf3b 100644
--- a/drivers/staging/lustre/lustre/osc/lproc_osc.c
+++ b/drivers/staging/lustre/lustre/osc/lproc_osc.c
@@ -44,22 +44,21 @@
 #include "osc_internal.h"
 
 #ifdef LPROCFS
-static int osc_rd_active(char *page, char **start, off_t off,
-			 int count, int *eof, void *data)
+static int osc_active_seq_show(struct seq_file *m, void *v)
 {
-	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 osc_wr_active(struct file *file, const char *buffer,
-			 unsigned long count, void *data)
+static ssize_t osc_active_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;
 	int val, rc;
 
 	rc = lprocfs_write_helper(buffer, count, &val);
@@ -76,24 +75,24 @@ static int osc_wr_active(struct file *file, const char *buffer,
 
 	return count;
 }
+LPROC_SEQ_FOPS(osc_active);
 
-static int osc_rd_max_rpcs_in_flight(char *page, char **start, off_t off,
-				     int count, int *eof, void *data)
+static int osc_max_rpcs_in_flight_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device *dev = data;
+	struct obd_device *dev = m->private;
 	struct client_obd *cli = &dev->u.cli;
 	int rc;
 
 	client_obd_list_lock(&cli->cl_loi_list_lock);
-	rc = snprintf(page, count, "%u\n", cli->cl_max_rpcs_in_flight);
+	rc = seq_printf(m, "%u\n", cli->cl_max_rpcs_in_flight);
 	client_obd_list_unlock(&cli->cl_loi_list_lock);
 	return rc;
 }
 
-static int osc_wr_max_rpcs_in_flight(struct file *file, const char *buffer,
-				     unsigned long count, void *data)
+static ssize_t osc_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 client_obd *cli = &dev->u.cli;
 	struct ptlrpc_request_pool *pool = cli->cl_import->imp_rq_pool;
 	int val, rc;
@@ -116,11 +115,11 @@ static int osc_wr_max_rpcs_in_flight(struct file *file, const char *buffer,
 	LPROCFS_CLIMP_EXIT(dev);
 	return count;
 }
+LPROC_SEQ_FOPS(osc_max_rpcs_in_flight);
 
-static int osc_rd_max_dirty_mb(char *page, char **start, off_t off, int count,
-			       int *eof, void *data)
+static int osc_max_dirty_mb_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device *dev = data;
+	struct obd_device *dev = m->private;
 	struct client_obd *cli = &dev->u.cli;
 	long val;
 	int mult;
@@ -130,13 +129,13 @@ static int osc_rd_max_dirty_mb(char *page, char **start, off_t off, int count,
 	client_obd_list_unlock(&cli->cl_loi_list_lock);
 
 	mult = 1 << 20;
-	return lprocfs_read_frac_helper(page, count, val, mult);
+	return lprocfs_seq_read_frac_helper(m, val, mult);
 }
 
-static int osc_wr_max_dirty_mb(struct file *file, const char *buffer,
-			       unsigned long count, void *data)
+static ssize_t osc_max_dirty_mb_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 client_obd *cli = &dev->u.cli;
 	int pages_number, mult, rc;
 
@@ -157,16 +156,16 @@ static int osc_wr_max_dirty_mb(struct file *file, const char *buffer,
 
 	return count;
 }
+LPROC_SEQ_FOPS(osc_max_dirty_mb);
 
-static int osc_rd_cached_mb(char *page, char **start, off_t off, int count,
-			    int *eof, void *data)
+static int osc_cached_mb_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device *dev = data;
+	struct obd_device *dev = m->private;
 	struct client_obd *cli = &dev->u.cli;
 	int shift = 20 - PAGE_CACHE_SHIFT;
 	int rc;
 
-	rc = snprintf(page, count,
+	rc = seq_printf(m,
 		      "used_mb: %d\n"
 		      "busy_cnt: %d\n",
 		      (atomic_read(&cli->cl_lru_in_list) +
@@ -177,10 +176,10 @@ static int osc_rd_cached_mb(char *page, char **start, off_t off, int count,
 }
 
 /* shrink the number of caching pages to a specific number */
-static int osc_wr_cached_mb(struct file *file, const char *buffer,
-			    unsigned long count, void *data)
+static ssize_t osc_cached_mb_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 client_obd *cli = &dev->u.cli;
 	int pages_number, mult, rc;
 
@@ -199,37 +198,37 @@ static int osc_wr_cached_mb(struct file *file, const char *buffer,
 
 	return count;
 }
+LPROC_SEQ_FOPS(osc_cached_mb);
 
-static int osc_rd_cur_dirty_bytes(char *page, char **start, off_t off,
-				  int count, int *eof, void *data)
+static int osc_cur_dirty_bytes_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device *dev = data;
+	struct obd_device *dev = m->private;
 	struct client_obd *cli = &dev->u.cli;
 	int rc;
 
 	client_obd_list_lock(&cli->cl_loi_list_lock);
-	rc = snprintf(page, count, "%lu\n", cli->cl_dirty);
+	rc = seq_printf(m, "%lu\n", cli->cl_dirty);
 	client_obd_list_unlock(&cli->cl_loi_list_lock);
 	return rc;
 }
+LPROC_SEQ_FOPS_RO(osc_cur_dirty_bytes);
 
-static int osc_rd_cur_grant_bytes(char *page, char **start, off_t off,
-				  int count, int *eof, void *data)
+static int osc_cur_grant_bytes_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device *dev = data;
+	struct obd_device *dev = m->private;
 	struct client_obd *cli = &dev->u.cli;
 	int rc;
 
 	client_obd_list_lock(&cli->cl_loi_list_lock);
-	rc = snprintf(page, count, "%lu\n", cli->cl_avail_grant);
+	rc = seq_printf(m, "%lu\n", cli->cl_avail_grant);
 	client_obd_list_unlock(&cli->cl_loi_list_lock);
 	return rc;
 }
 
-static int osc_wr_cur_grant_bytes(struct file *file, const char *buffer,
-				  unsigned long count, void *data)
+static ssize_t osc_cur_grant_bytes_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 client_obd *cli = &obd->u.cli;
 	int		rc;
 	__u64	      val;
@@ -257,35 +256,35 @@ static int osc_wr_cur_grant_bytes(struct file *file, const char *buffer,
 		return rc;
 	return count;
 }
+LPROC_SEQ_FOPS(osc_cur_grant_bytes);
 
-static int osc_rd_cur_lost_grant_bytes(char *page, char **start, off_t off,
-				       int count, int *eof, void *data)
+static int osc_cur_lost_grant_bytes_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device *dev = data;
+	struct obd_device *dev = m->private;
 	struct client_obd *cli = &dev->u.cli;
 	int rc;
 
 	client_obd_list_lock(&cli->cl_loi_list_lock);
-	rc = snprintf(page, count, "%lu\n", cli->cl_lost_grant);
+	rc = seq_printf(m, "%lu\n", cli->cl_lost_grant);
 	client_obd_list_unlock(&cli->cl_loi_list_lock);
 	return rc;
 }
+LPROC_SEQ_FOPS_RO(osc_cur_lost_grant_bytes);
 
-static int osc_rd_grant_shrink_interval(char *page, char **start, off_t off,
-					int count, int *eof, void *data)
+static int osc_grant_shrink_interval_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device *obd = data;
+	struct obd_device *obd = m->private;
 
 	if (obd == NULL)
 		return 0;
-	return snprintf(page, count, "%d\n",
+	return seq_printf(m, "%d\n",
 			obd->u.cli.cl_grant_shrink_interval);
 }
 
-static int osc_wr_grant_shrink_interval(struct file *file, const char *buffer,
-					unsigned long count, void *data)
+static ssize_t osc_grant_shrink_interval_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;
 
 	if (obd == NULL)
@@ -302,23 +301,23 @@ static int osc_wr_grant_shrink_interval(struct file *file, const char *buffer,
 
 	return count;
 }
+LPROC_SEQ_FOPS(osc_grant_shrink_interval);
 
-static int osc_rd_checksum(char *page, char **start, off_t off, int count,
-			   int *eof, void *data)
+static int osc_checksum_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device *obd = data;
+	struct obd_device *obd = m->private;
 
 	if (obd == NULL)
 		return 0;
 
-	return snprintf(page, count, "%d\n",
+	return seq_printf(m, "%d\n",
 			obd->u.cli.cl_checksum ? 1 : 0);
 }
 
-static int osc_wr_checksum(struct file *file, const char *buffer,
-			   unsigned long count, void *data)
+static ssize_t osc_checksum_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;
 
 	if (obd == NULL)
@@ -332,36 +331,33 @@ static int osc_wr_checksum(struct file *file, const char *buffer,
 
 	return count;
 }
+LPROC_SEQ_FOPS(osc_checksum);
 
-static int osc_rd_checksum_type(char *page, char **start, off_t off, int count,
-				int *eof, void *data)
+static int osc_checksum_type_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device *obd = data;
-	int i, len =0;
+	struct obd_device *obd = m->private;
+	int i;
 	DECLARE_CKSUM_NAME;
 
 	if (obd == NULL)
 		return 0;
 
-	for (i = 0; i < ARRAY_SIZE(cksum_name) && len < count; i++) {
+	for (i = 0; i < ARRAY_SIZE(cksum_name); i++) {
 		if (((1 << i) & obd->u.cli.cl_supp_cksum_types) == 0)
 			continue;
 		if (obd->u.cli.cl_cksum_type == (1 << i))
-			len += snprintf(page + len, count - len, "[%s] ",
-					cksum_name[i]);
+			seq_printf(m, "[%s] ", cksum_name[i]);
 		else
-			len += snprintf(page + len, count - len, "%s ",
-					cksum_name[i]);
+			seq_printf(m, "%s ", cksum_name[i]);
 	}
-	if (len < count)
-		len += sprintf(page + len, "\n");
-	return len;
+	seq_printf(m, "\n");
+	return 0;
 }
 
-static int osc_wd_checksum_type(struct file *file, const char *buffer,
-				unsigned long count, void *data)
+static ssize_t osc_checksum_type_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 i;
 	DECLARE_CKSUM_NAME;
 	char kernbuf[10];
@@ -388,20 +384,19 @@ static int osc_wd_checksum_type(struct file *file, const char *buffer,
 	}
 	return -EINVAL;
 }
+LPROC_SEQ_FOPS(osc_checksum_type);
 
-static int osc_rd_resend_count(char *page, char **start, off_t off, int count,
-			       int *eof, void *data)
+static int osc_resend_count_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device *obd = data;
+	struct obd_device *obd = m->private;
 
-	return snprintf(page, count, "%u\n",
-			atomic_read(&obd->u.cli.cl_resends));
+	return seq_printf(m, "%u\n", atomic_read(&obd->u.cli.cl_resends));
 }
 
-static int osc_wr_resend_count(struct file *file, const char *buffer,
-			       unsigned long count, void *data)
+static ssize_t osc_resend_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;
 	int val, rc;
 
 	rc = lprocfs_write_helper(buffer, count, &val);
@@ -415,57 +410,63 @@ static int osc_wr_resend_count(struct file *file, const char *buffer,
 
 	return count;
 }
+LPROC_SEQ_FOPS(osc_resend_count);
 
-static int osc_rd_contention_seconds(char *page, char **start, off_t off,
-				     int count, int *eof, void *data)
+static int osc_contention_seconds_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device *obd = data;
+	struct obd_device *obd = m->private;
 	struct osc_device *od  = obd2osc_dev(obd);
 
-	return snprintf(page, count, "%u\n", od->od_contention_time);
+	return seq_printf(m, "%u\n", od->od_contention_time);
 }
 
-static int osc_wr_contention_seconds(struct file *file, const char *buffer,
-				     unsigned long count, void *data)
+static ssize_t osc_contention_seconds_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 osc_device *od  = obd2osc_dev(obd);
 
 	return lprocfs_write_helper(buffer, count, &od->od_contention_time) ?:
 		count;
 }
+LPROC_SEQ_FOPS(osc_contention_seconds);
 
-static int osc_rd_lockless_truncate(char *page, char **start, off_t off,
-				    int count, int *eof, void *data)
+static int osc_lockless_truncate_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device *obd = data;
+	struct obd_device *obd = m->private;
 	struct osc_device *od  = obd2osc_dev(obd);
 
-	return snprintf(page, count, "%u\n", od->od_lockless_truncate);
+	return seq_printf(m, "%u\n", od->od_lockless_truncate);
 }
 
-static int osc_wr_lockless_truncate(struct file *file, const char *buffer,
-				    unsigned long count, void *data)
+static ssize_t osc_lockless_truncate_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 osc_device *od  = obd2osc_dev(obd);
 
 	return lprocfs_write_helper(buffer, count, &od->od_lockless_truncate) ?:
 		count;
 }
+LPROC_SEQ_FOPS(osc_lockless_truncate);
 
-static int osc_rd_destroys_in_flight(char *page, char **start, off_t off,
-				     int count, int *eof, void *data)
+static int osc_destroys_in_flight_seq_show(struct seq_file *m, void *v)
 {
-	struct obd_device *obd = data;
-	return snprintf(page, count, "%u\n",
+	struct obd_device *obd = m->private;
+	return seq_printf(m, "%u\n",
 			atomic_read(&obd->u.cli.cl_destroy_in_flight));
 }
+LPROC_SEQ_FOPS_RO(osc_destroys_in_flight);
+
+static int osc_obd_max_pages_per_rpc_seq_show(struct seq_file *m, void *v)
+{
+	return lprocfs_obd_rd_max_pages_per_rpc(m, m->private);
+}
 
-static int lprocfs_osc_wr_max_pages_per_rpc(struct file *file,
-	const char *buffer, unsigned long count, void *data)
+static ssize_t osc_obd_max_pages_per_rpc_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 client_obd *cli = &dev->u.cli;
 	struct obd_connect_data *ocd = &cli->cl_import->imp_connect_data;
 	int chunk_mask, rc;
@@ -495,52 +496,64 @@ static int lprocfs_osc_wr_max_pages_per_rpc(struct file *file,
 	LPROCFS_CLIMP_EXIT(dev);
 	return count;
 }
+LPROC_SEQ_FOPS(osc_obd_max_pages_per_rpc);
+
+LPROC_SEQ_FOPS_RO_TYPE(osc, uuid);
+LPROC_SEQ_FOPS_RO_TYPE(osc, connect_flags);
+LPROC_SEQ_FOPS_RO_TYPE(osc, blksize);
+LPROC_SEQ_FOPS_RO_TYPE(osc, kbytestotal);
+LPROC_SEQ_FOPS_RO_TYPE(osc, kbytesfree);
+LPROC_SEQ_FOPS_RO_TYPE(osc, kbytesavail);
+LPROC_SEQ_FOPS_RO_TYPE(osc, filestotal);
+LPROC_SEQ_FOPS_RO_TYPE(osc, filesfree);
+LPROC_SEQ_FOPS_RO_TYPE(osc, server_uuid);
+LPROC_SEQ_FOPS_RO_TYPE(osc, conn_uuid);
+LPROC_SEQ_FOPS_RO_TYPE(osc, timeouts);
+LPROC_SEQ_FOPS_RO_TYPE(osc, state);
+
+LPROC_SEQ_FOPS_WR_ONLY(osc, ping);
+
+LPROC_SEQ_FOPS_RW_TYPE(osc, import);
+LPROC_SEQ_FOPS_RW_TYPE(osc, pinger_recov);
 
 static struct lprocfs_vars lprocfs_osc_obd_vars[] = {
-	{ "uuid",	    lprocfs_rd_uuid,	0, 0 },
-	{ "ping",	    0, lprocfs_wr_ping,     0, 0, 0222 },
-	{ "connect_flags",   lprocfs_rd_connect_flags, 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 },
+	{ "uuid",	     &osc_uuid_fops,	0, 0 },
+	{ "ping",	     &osc_ping_fops,    0, 0222 },
+	{ "connect_flags",   &osc_connect_flags_fops, 0, 0 },
+	{ "blocksize",       &osc_blksize_fops,     0, 0 },
+	{ "kbytestotal",     &osc_kbytestotal_fops, 0, 0 },
+	{ "kbytesfree",      &osc_kbytesfree_fops,  0, 0 },
+	{ "kbytesavail",     &osc_kbytesavail_fops, 0, 0 },
+	{ "filestotal",      &osc_filestotal_fops,  0, 0 },
+	{ "filesfree",       &osc_filesfree_fops,   0, 0 },
 	//{ "filegroups",      lprocfs_rd_filegroups,  0, 0 },
-	{ "ost_server_uuid", lprocfs_rd_server_uuid, 0, 0 },
-	{ "ost_conn_uuid",   lprocfs_rd_conn_uuid, 0, 0 },
-	{ "active",	  osc_rd_active,
-			     osc_wr_active, 0 },
-	{ "max_pages_per_rpc", lprocfs_obd_rd_max_pages_per_rpc,
-			       lprocfs_osc_wr_max_pages_per_rpc, 0 },
-	{ "max_rpcs_in_flight", osc_rd_max_rpcs_in_flight,
-				osc_wr_max_rpcs_in_flight, 0 },
-	{ "destroys_in_flight", osc_rd_destroys_in_flight, 0, 0 },
-	{ "max_dirty_mb",    osc_rd_max_dirty_mb, osc_wr_max_dirty_mb, 0 },
-	{ "osc_cached_mb",   osc_rd_cached_mb,     osc_wr_cached_mb, 0 },
-	{ "cur_dirty_bytes", osc_rd_cur_dirty_bytes, 0, 0 },
-	{ "cur_grant_bytes", osc_rd_cur_grant_bytes,
-			     osc_wr_cur_grant_bytes, 0 },
-	{ "cur_lost_grant_bytes", osc_rd_cur_lost_grant_bytes, 0, 0},
-	{ "grant_shrink_interval", osc_rd_grant_shrink_interval,
-				   osc_wr_grant_shrink_interval, 0 },
-	{ "checksums",       osc_rd_checksum, osc_wr_checksum, 0 },
-	{ "checksum_type",   osc_rd_checksum_type, osc_wd_checksum_type, 0 },
-	{ "resend_count",    osc_rd_resend_count, osc_wr_resend_count, 0},
-	{ "timeouts",	lprocfs_rd_timeouts,      0, 0 },
-	{ "contention_seconds", osc_rd_contention_seconds,
-				osc_wr_contention_seconds, 0 },
-	{ "lockless_truncate",  osc_rd_lockless_truncate,
-				osc_wr_lockless_truncate, 0 },
-	{ "import",	  lprocfs_rd_import,	lprocfs_wr_import, 0 },
-	{ "state",	   lprocfs_rd_state,	 0, 0 },
-	{ "pinger_recov",    lprocfs_rd_pinger_recov,
-			     lprocfs_wr_pinger_recov,  0, 0 },
+	{ "ost_server_uuid", &osc_server_uuid_fops, 0, 0 },
+	{ "ost_conn_uuid",   &osc_conn_uuid_fops, 0, 0 },
+	{ "active",	     &osc_active_fops, 0 },
+	{ "max_pages_per_rpc", &osc_obd_max_pages_per_rpc_fops, 0 },
+	{ "max_rpcs_in_flight", &osc_max_rpcs_in_flight_fops, 0 },
+	{ "destroys_in_flight", &osc_destroys_in_flight_fops, 0, 0 },
+	{ "max_dirty_mb",    &osc_max_dirty_mb_fops, 0 },
+	{ "osc_cached_mb",   &osc_cached_mb_fops, 0 },
+	{ "cur_dirty_bytes", &osc_cur_dirty_bytes_fops, 0, 0 },
+	{ "cur_grant_bytes", &osc_cur_grant_bytes_fops, 0 },
+	{ "cur_lost_grant_bytes", &osc_cur_lost_grant_bytes_fops, 0, 0},
+	{ "grant_shrink_interval", &osc_grant_shrink_interval_fops, 0 },
+	{ "checksums",       &osc_checksum_fops, 0 },
+	{ "checksum_type",   &osc_checksum_type_fops, 0 },
+	{ "resend_count",    &osc_resend_count_fops, 0},
+	{ "timeouts",	     &osc_timeouts_fops, 0, 0 },
+	{ "contention_seconds", &osc_contention_seconds_fops, 0 },
+	{ "lockless_truncate",  &osc_lockless_truncate_fops, 0 },
+	{ "import",		&osc_import_fops, 0 },
+	{ "state",		&osc_state_fops, 0, 0 },
+	{ "pinger_recov",	&osc_pinger_recov_fops, 0 },
 	{ 0 }
 };
 
+LPROC_SEQ_FOPS_RO_TYPE(osc, numrefs);
 static struct lprocfs_vars lprocfs_osc_module_vars[] = {
-	{ "num_refs",	lprocfs_rd_numrefs,     0, 0 },
+	{ "num_refs",	&osc_numrefs_fops,     0, 0 },
 	{ 0 }
 };
 
diff --git a/drivers/staging/lustre/lustre/ptlrpc/gss/lproc_gss.c b/drivers/staging/lustre/lustre/ptlrpc/gss/lproc_gss.c
index 2522e05..3404000 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/gss/lproc_gss.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/gss/lproc_gss.c
@@ -94,12 +94,9 @@ void gss_stat_oos_record_svc(int phase, int replay)
 		atomic_inc(&gss_stat_oos.oos_svc_pass[phase]);
 }
 
-static int gss_proc_read_oos(char *page, char **start, off_t off, int count,
-			     int *eof, void *data)
+static int gss_proc_oos_seq_show(struct seq_file *m, void *v)
 {
-	int written;
-
-	written = snprintf(page, count,
+	return seq_printf(m,
 			"seqwin:		%u\n"
 			"backwin:	       %u\n"
 			"client fall behind seqwin\n"
@@ -119,12 +116,11 @@ static int gss_proc_read_oos(char *page, char **start, off_t off, int count,
 			atomic_read(&gss_stat_oos.oos_svc_replay[1]),
 			atomic_read(&gss_stat_oos.oos_svc_replay[2]),
 			atomic_read(&gss_stat_oos.oos_svc_pass[2]));
-
-	return written;
 }
+LPROC_SEQ_FOPS_RO(gss_proc_oos);
 
 static int gss_proc_write_secinit(struct file *file, const char *buffer,
-				  unsigned long count, void *data)
+				  size_t count, off_t *off)
 {
 	int rc;
 
@@ -134,12 +130,16 @@ static int gss_proc_write_secinit(struct file *file, const char *buffer,
 		return rc;
 	}
 
-	return ((int) count);
+	return count;
 }
 
+static const struct file_operations gss_proc_secinit = {
+	.write = gss_proc_write_secinit,
+};
+
 static struct lprocfs_vars gss_lprocfs_vars[] = {
-	{ "replays", gss_proc_read_oos, NULL },
-	{ "init_channel", NULL, gss_proc_write_secinit, NULL, NULL, 0222 },
+	{ "replays", &gss_proc_oos_fops },
+	{ "init_channel", &gss_proc_secinit, NULL, 0222 },
 	{ NULL }
 };
 
@@ -150,14 +150,13 @@ static struct lprocfs_vars gss_lprocfs_vars[] = {
  */
 static int gss_lk_debug_level = 1;
 
-static int gss_lk_proc_read_dl(char *page, char **start, off_t off,
-			       int count, int *eof, void *data)
+static int gss_lk_proc_dl_seq_show(struct seq_file *m, void *v)
 {
-	return snprintf(page, count, "%u\n", gss_lk_debug_level);
+	return seq_printf(m, "%u\n", gss_lk_debug_level);
 }
 
-static int gss_lk_proc_write_dl(struct file *file, const char *buffer,
-				unsigned long count, void *data)
+static int gss_lk_proc_dl_seq_write(struct file *file, const char *buffer,
+				    size_t count, off_t *off)
 {
 	int     val, rc;
 
@@ -171,9 +170,10 @@ static int gss_lk_proc_write_dl(struct file *file, const char *buffer,
 	gss_lk_debug_level = val;
 	return count;
 }
+LPROC_SEQ_FOPS(gss_lk_proc_dl);
 
 static struct lprocfs_vars gss_lk_lprocfs_vars[] = {
-	{ "debug_level", gss_lk_proc_read_dl, gss_lk_proc_write_dl, NULL },
+	{ "debug_level", &gss_lk_proc_dl_fops },
 	{ NULL }
 };
 
diff --git a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
index 031c0f9..3e73254 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
@@ -254,43 +254,39 @@ void ptlrpc_lprocfs_register(struct proc_dir_entry *root, char *dir,
 }
 
 static int
-ptlrpc_lprocfs_read_req_history_len(char *page, char **start, off_t off,
-				    int count, int *eof, void *data)
+ptlrpc_lprocfs_req_history_len_seq_show(struct seq_file *m, void *v)
 {
-	struct ptlrpc_service *svc = data;
+	struct ptlrpc_service *svc = m->private;
 	struct ptlrpc_service_part *svcpt;
 	int	total = 0;
 	int	i;
 
-	*eof = 1;
-
 	ptlrpc_service_for_each_part(svcpt, i, svc)
 		total += svcpt->scp_hist_nrqbds;
 
-	return snprintf(page, count, "%d\n", total);
+	return seq_printf(m, "%d\n", total);
 }
+LPROC_SEQ_FOPS_RO(ptlrpc_lprocfs_req_history_len);
 
 static int
-ptlrpc_lprocfs_read_req_history_max(char *page, char **start, off_t off,
-				    int count, int *eof, void *data)
+ptlrpc_lprocfs_req_history_max_seq_show(struct seq_file *m, void *n)
 {
-	struct ptlrpc_service *svc = data;
+	struct ptlrpc_service *svc = m->private;
 	struct ptlrpc_service_part *svcpt;
 	int	total = 0;
 	int	i;
 
-	*eof = 1;
 	ptlrpc_service_for_each_part(svcpt, i, svc)
 		total += svc->srv_hist_nrqbds_cpt_max;
 
-	return snprintf(page, count, "%d\n", total);
+	return seq_printf(m, "%d\n", total);
 }
 
-static int
-ptlrpc_lprocfs_write_req_history_max(struct file *file, const char *buffer,
-				     unsigned long count, void *data)
+static ssize_t
+ptlrpc_lprocfs_req_history_max_seq_write(struct file *file, const char *buffer,
+					 size_t count, loff_t *off)
 {
-	struct ptlrpc_service	   *svc = data;
+	struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private;
 	int			    bufpages;
 	int			    val;
 	int			    rc;
@@ -320,22 +316,22 @@ ptlrpc_lprocfs_write_req_history_max(struct file *file, const char *buffer,
 
 	return count;
 }
+LPROC_SEQ_FOPS(ptlrpc_lprocfs_req_history_max);
 
 static int
-ptlrpc_lprocfs_rd_threads_min(char *page, char **start, off_t off,
-			      int count, int *eof, void *data)
+ptlrpc_lprocfs_threads_min_seq_show(struct seq_file *m, void *n)
 {
-	struct ptlrpc_service *svc = data;
+	struct ptlrpc_service *svc = m->private;
 
-	return snprintf(page, count, "%d\n",
+	return seq_printf(m, "%d\n",
 			svc->srv_nthrs_cpt_init * svc->srv_ncpts);
 }
 
-static int
-ptlrpc_lprocfs_wr_threads_min(struct file *file, const char *buffer,
-			      unsigned long count, void *data)
+static ssize_t
+ptlrpc_lprocfs_threads_min_seq_write(struct file *file, const char *buffer,
+				     size_t count, loff_t *off)
 {
-	struct ptlrpc_service	   *svc = data;
+	struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private;
 	int	val;
 	int	rc = lprocfs_write_helper(buffer, count, &val);
 
@@ -357,12 +353,12 @@ ptlrpc_lprocfs_wr_threads_min(struct file *file, const char *buffer,
 
 	return count;
 }
+LPROC_SEQ_FOPS(ptlrpc_lprocfs_threads_min);
 
 static int
-ptlrpc_lprocfs_rd_threads_started(char *page, char **start, off_t off,
-				  int count, int *eof, void *data)
+ptlrpc_lprocfs_threads_started_seq_show(struct seq_file *m, void *n)
 {
-	struct ptlrpc_service *svc = data;
+	struct ptlrpc_service *svc = m->private;
 	struct ptlrpc_service_part *svcpt;
 	int	total = 0;
 	int	i;
@@ -370,24 +366,24 @@ ptlrpc_lprocfs_rd_threads_started(char *page, char **start, off_t off,
 	ptlrpc_service_for_each_part(svcpt, i, svc)
 		total += svcpt->scp_nthrs_running;
 
-	return snprintf(page, count, "%d\n", total);
+	return seq_printf(m, "%d\n", total);
 }
+LPROC_SEQ_FOPS_RO(ptlrpc_lprocfs_threads_started);
 
 static int
-ptlrpc_lprocfs_rd_threads_max(char *page, char **start, off_t off,
-			      int count, int *eof, void *data)
+ptlrpc_lprocfs_threads_max_seq_show(struct seq_file *m, void *n)
 {
-	struct ptlrpc_service *svc = data;
+	struct ptlrpc_service *svc = m->private;
 
-	return snprintf(page, count, "%d\n",
+	return seq_printf(m, "%d\n",
 			svc->srv_nthrs_cpt_limit * svc->srv_ncpts);
 }
 
-static int
-ptlrpc_lprocfs_wr_threads_max(struct file *file, const char *buffer,
-			      unsigned long count, void *data)
+static ssize_t
+ptlrpc_lprocfs_threads_max_seq_write(struct file *file, const char *buffer,
+				     size_t count, loff_t *off)
 {
-	struct ptlrpc_service *svc = data;
+	struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private;
 	int	val;
 	int	rc = lprocfs_write_helper(buffer, count, &val);
 
@@ -409,6 +405,7 @@ ptlrpc_lprocfs_wr_threads_max(struct file *file, const char *buffer,
 
 	return count;
 }
+LPROC_SEQ_FOPS(ptlrpc_lprocfs_threads_max);
 
 /**
  * \addtogoup nrs
@@ -470,10 +467,9 @@ void nrs_policy_get_info_locked(struct ptlrpc_nrs_policy *policy,
  * Reads and prints policy status information for all policies of a PTLRPC
  * service.
  */
-static int ptlrpc_lprocfs_rd_nrs(char *page, char **start, off_t off,
-				 int count, int *eof, void *data)
+static int ptlrpc_lprocfs_nrs_seq_show(struct seq_file *m, void *n)
 {
-	struct ptlrpc_service	       *svc = data;
+	struct ptlrpc_service	       *svc = m->private;
 	struct ptlrpc_service_part     *svcpt;
 	struct ptlrpc_nrs	       *nrs;
 	struct ptlrpc_nrs_policy       *policy;
@@ -484,7 +480,6 @@ static int ptlrpc_lprocfs_rd_nrs(char *page, char **start, off_t off,
 	bool				hp = false;
 	int				i;
 	int				rc = 0;
-	int				rc2 = 0;
 	ENTRY;
 
 	/**
@@ -586,21 +581,11 @@ again:
 	 *	    queued: 0
 	 *	    active: 0
 	 */
-	rc2 = snprintf(page + rc, count - rc,
-		       "%s\n", !hp ?
-		       "\nregular_requests:" :
-		       "high_priority_requests:");
-
-	if (rc2 >= count - rc) {
-		/** Output was truncated */
-		GOTO(out, rc = -EFBIG);
-	}
-
-	rc += rc2;
+	seq_printf(m, "%s\n",
+		      !hp ?  "\nregular_requests:" : "high_priority_requests:");
 
 	for (pol_idx = 0; pol_idx < num_pols; pol_idx++) {
-		rc2 = snprintf(page + rc, count - rc,
-			       "  - name: %s\n"
+		seq_printf(m,  "  - name: %s\n"
 			       "    state: %s\n"
 			       "    fallback: %s\n"
 			       "    queued: %-20d\n"
@@ -610,14 +595,6 @@ again:
 			       infos[pol_idx].pi_fallback ? "yes" : "no",
 			       (int)infos[pol_idx].pi_req_queued,
 			       (int)infos[pol_idx].pi_req_started);
-
-
-		if (rc2 >= count - rc) {
-			/** Output was truncated */
-			GOTO(out, rc = -EFBIG);
-		}
-
-		rc += rc2;
 	}
 
 	if (!hp && nrs_svc_has_hp(svc)) {
@@ -630,8 +607,6 @@ again:
 		goto again;
 	}
 
-	*eof = 1;
-
 out:
 	if (infos)
 		OBD_FREE(infos, num_pols * sizeof(*infos));
@@ -654,10 +629,10 @@ out:
  * if the optional token is omitted, the operation is performed on both the
  * regular and high-priority (if the service has one) NRS head.
  */
-static int ptlrpc_lprocfs_wr_nrs(struct file *file, const char *buffer,
-				 unsigned long count, void *data)
+static ssize_t ptlrpc_lprocfs_nrs_seq_write(struct file *file, const char *buffer,
+					size_t count, loff_t *off)
 {
-	struct ptlrpc_service	       *svc = data;
+	struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private;
 	enum ptlrpc_nrs_queue_type	queue = PTLRPC_NRS_QUEUE_BOTH;
 	char			       *cmd;
 	char			       *cmd_copy = NULL;
@@ -725,6 +700,7 @@ out:
 
 	RETURN(rc < 0 ? rc : count);
 }
+LPROC_SEQ_FOPS(ptlrpc_lprocfs_nrs);
 
 /** @} nrs */
 
@@ -984,41 +960,33 @@ ptlrpc_lprocfs_svc_req_history_open(struct inode *inode, struct file *file)
 		.next  = ptlrpc_lprocfs_svc_req_history_next,
 		.show  = ptlrpc_lprocfs_svc_req_history_show,
 	};
-	struct proc_dir_entry *dp = PDE(inode);
 	struct seq_file       *seqf;
 	int		    rc;
 
-	LPROCFS_ENTRY_AND_CHECK(dp);
 	rc = seq_open(file, &sops);
-	if (rc) {
-		LPROCFS_EXIT();
+	if (rc)
 		return rc;
-	}
 
 	seqf = file->private_data;
-	seqf->private = dp->data;
+	seqf->private = PDE_DATA(inode);
 	return 0;
 }
 
 /* See also lprocfs_rd_timeouts */
-static int ptlrpc_lprocfs_rd_timeouts(char *page, char **start, off_t off,
-				      int count, int *eof, void *data)
+static int ptlrpc_lprocfs_timeouts_seq_show(struct seq_file *m, void *n)
 {
-	struct ptlrpc_service		*svc = data;
+	struct ptlrpc_service		*svc = m->private;
 	struct ptlrpc_service_part	*svcpt;
 	struct dhms			ts;
 	time_t				worstt;
 	unsigned int			cur;
 	unsigned int			worst;
-	int				nob = 0;
-	int				rc = 0;
 	int				i;
 
 	if (AT_OFF) {
-		rc += snprintf(page + rc, count - rc,
-			       "adaptive timeouts off, using obd_timeout %u\n",
+		seq_printf(m, "adaptive timeouts off, using obd_timeout %u\n",
 			       obd_timeout);
-		return rc;
+		return 0;
 	}
 
 	ptlrpc_service_for_each_part(svcpt, i, svc) {
@@ -1027,46 +995,29 @@ static int ptlrpc_lprocfs_rd_timeouts(char *page, char **start, off_t off,
 		worstt	= svcpt->scp_at_estimate.at_worst_time;
 		s2dhms(&ts, cfs_time_current_sec() - worstt);
 
-		nob = snprintf(page, count,
-			       "%10s : cur %3u  worst %3u (at %ld, "
-			       DHMS_FMT" ago) ", "service",
-			       cur, worst, worstt, DHMS_VARS(&ts));
-
-		nob = lprocfs_at_hist_helper(page, count, nob,
-					     &svcpt->scp_at_estimate);
-		rc += nob;
-		page += nob;
-		count -= nob;
-
-		/*
-		 * NB: for lustre proc read, the read count must be less
-		 * than PAGE_SIZE, please see details in lprocfs_fops_read.
-		 * It's unlikely that we exceed PAGE_SIZE at here because
-		 * it means the service has more than 50 partitions.
-		 */
-		if (count <= 0) {
-			CWARN("Can't fit AT information of %s in one page, "
-			      "please contact with developer to fix this.\n",
-			      svc->srv_name);
-			break;
-		}
+		seq_printf(m, "%10s : cur %3u  worst %3u (at %ld, "
+			      DHMS_FMT" ago) ", "service",
+			      cur, worst, worstt, DHMS_VARS(&ts));
+
+		lprocfs_at_hist_helper(m, &svcpt->scp_at_estimate);
 	}
 
-	return rc;
+	return 0;
 }
+LPROC_SEQ_FOPS_RO(ptlrpc_lprocfs_timeouts);
 
-static int ptlrpc_lprocfs_rd_hp_ratio(char *page, char **start, off_t off,
-				      int count, int *eof, void *data)
+static int ptlrpc_lprocfs_hp_ratio_seq_show(struct seq_file *m, void *v)
 {
-	struct ptlrpc_service *svc = data;
-	int rc = snprintf(page, count, "%d", svc->srv_hpreq_ratio);
-	return rc;
+	struct ptlrpc_service *svc = m->private;
+	return seq_printf(m, "%d", svc->srv_hpreq_ratio);
 }
 
-static int ptlrpc_lprocfs_wr_hp_ratio(struct file *file, const char *buffer,
-				      unsigned long count, void *data)
+static ssize_t ptlrpc_lprocfs_hp_ratio_seq_write(struct file *file,
+					     const char *buffer,
+					     size_t count,
+					     loff_t *off)
 {
-	struct ptlrpc_service		*svc = data;
+	struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private;
 	int	rc;
 	int	val;
 
@@ -1083,39 +1034,35 @@ static int ptlrpc_lprocfs_wr_hp_ratio(struct file *file, const char *buffer,
 
 	return count;
 }
+LPROC_SEQ_FOPS(ptlrpc_lprocfs_hp_ratio);
 
 void ptlrpc_lprocfs_register_service(struct proc_dir_entry *entry,
 				     struct ptlrpc_service *svc)
 {
 	struct lprocfs_vars lproc_vars[] = {
 		{.name       = "high_priority_ratio",
-		 .read_fptr  = ptlrpc_lprocfs_rd_hp_ratio,
-		 .write_fptr = ptlrpc_lprocfs_wr_hp_ratio,
+		 .fops	     = &ptlrpc_lprocfs_hp_ratio_fops,
 		 .data       = svc},
 		{.name       = "req_buffer_history_len",
-		 .read_fptr  = ptlrpc_lprocfs_read_req_history_len,
+		 .fops	     = &ptlrpc_lprocfs_req_history_len_fops,
 		 .data       = svc},
 		{.name       = "req_buffer_history_max",
-		 .write_fptr = ptlrpc_lprocfs_write_req_history_max,
-		 .read_fptr  = ptlrpc_lprocfs_read_req_history_max,
+		 .fops	     = &ptlrpc_lprocfs_req_history_max_fops,
 		 .data       = svc},
 		{.name       = "threads_min",
-		 .read_fptr  = ptlrpc_lprocfs_rd_threads_min,
-		 .write_fptr = ptlrpc_lprocfs_wr_threads_min,
+		 .fops	     = &ptlrpc_lprocfs_threads_min_fops,
 		 .data       = svc},
 		{.name       = "threads_max",
-		 .read_fptr  = ptlrpc_lprocfs_rd_threads_max,
-		 .write_fptr = ptlrpc_lprocfs_wr_threads_max,
+		 .fops	     = &ptlrpc_lprocfs_threads_max_fops,
 		 .data       = svc},
 		{.name       = "threads_started",
-		 .read_fptr  = ptlrpc_lprocfs_rd_threads_started,
+		 .fops	     = &ptlrpc_lprocfs_threads_started_fops,
 		 .data       = svc},
 		{.name       = "timeouts",
-		 .read_fptr  = ptlrpc_lprocfs_rd_timeouts,
+		 .fops	     = &ptlrpc_lprocfs_timeouts_fops,
 		 .data       = svc},
 		{.name       = "nrs_policies",
-		 .read_fptr  = ptlrpc_lprocfs_rd_nrs,
-		 .write_fptr = ptlrpc_lprocfs_wr_nrs,
+		 .fops	     = &ptlrpc_lprocfs_nrs_fops,
 		 .data	     = svc},
 		{NULL}
 	};
@@ -1217,9 +1164,9 @@ 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)
+			    size_t count, loff_t *off)
 {
-	struct obd_device *obd = data;
+	struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
 	char	      *kbuf;
 	char	      *tmpbuf;
 
@@ -1245,7 +1192,6 @@ int lprocfs_wr_evict_client(struct file *file, const char *buffer,
 	 * the proc entries under the being destroyed export{}, so I have
 	 * to drop the lock at first here.
 	 * - jay, jxiong@xxxxxxxxxxxxx */
-	LPROCFS_EXIT();
 	class_incref(obd, __FUNCTION__, current);
 
 	if (strncmp(tmpbuf, "nid:", 4) == 0)
@@ -1256,7 +1202,6 @@ int lprocfs_wr_evict_client(struct file *file, const char *buffer,
 		obd_export_evict_by_uuid(obd, tmpbuf);
 
 	class_decref(obd, __FUNCTION__, current);
-	LPROCFS_ENTRY();
 
 out:
 	OBD_FREE(kbuf, BUFLEN);
@@ -1267,9 +1212,9 @@ EXPORT_SYMBOL(lprocfs_wr_evict_client);
 #undef BUFLEN
 
 int lprocfs_wr_ping(struct file *file, const char *buffer,
-		    unsigned long count, void *data)
+		    size_t count, loff_t *off)
 {
-	struct obd_device     *obd = data;
+	struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
 	struct ptlrpc_request *req;
 	int		    rc;
 	ENTRY;
@@ -1296,9 +1241,9 @@ EXPORT_SYMBOL(lprocfs_wr_ping);
  * "echo connection=192.168.0.1@tcp0::instance > .../import".
  */
 int lprocfs_wr_import(struct file *file, const char *buffer,
-		      unsigned long count, void *data)
+		      size_t count, loff_t *off)
 {
-	struct obd_device *obd = data;
+	struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
 	struct obd_import *imp = obd->u.cli.cl_import;
 	char *kbuf = NULL;
 	char *uuid;
@@ -1357,15 +1302,14 @@ out:
 }
 EXPORT_SYMBOL(lprocfs_wr_import);
 
-int lprocfs_rd_pinger_recov(char *page, char **start, off_t off,
-			    int count, int *eof, void *data)
+int lprocfs_rd_pinger_recov(struct seq_file *m, void *n)
 {
-	struct obd_device *obd = data;
+	struct obd_device *obd = m->private;
 	struct obd_import *imp = obd->u.cli.cl_import;
 	int rc;
 
 	LPROCFS_CLIMP_CHECK(obd);
-	rc = snprintf(page, count, "%d\n", !imp->imp_no_pinger_recover);
+	rc = seq_printf(m, "%d\n", !imp->imp_no_pinger_recover);
 	LPROCFS_CLIMP_EXIT(obd);
 
 	return rc;
@@ -1373,9 +1317,9 @@ int lprocfs_rd_pinger_recov(char *page, char **start, off_t off,
 EXPORT_SYMBOL(lprocfs_rd_pinger_recov);
 
 int lprocfs_wr_pinger_recov(struct file *file, const char *buffer,
-		      unsigned long count, void *data)
+		      size_t count, loff_t *off)
 {
-	struct obd_device *obd = data;
+	struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
 	struct client_obd *cli = &obd->u.cli;
 	struct obd_import *imp = cli->cl_import;
 	int rc, val;
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
index 9ba7600..ab36347 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
@@ -256,8 +256,7 @@ void sptlrpc_plain_fini(void);
 /* sec_bulk.c */
 int  sptlrpc_enc_pool_init(void);
 void sptlrpc_enc_pool_fini(void);
-int sptlrpc_proc_read_enc_pool(char *page, char **start, off_t off, int count,
-			       int *eof, void *data);
+int sptlrpc_proc_enc_pool_seq_show(struct seq_file *m, void *v);
 
 /* sec_lproc.c */
 int  sptlrpc_lproc_init(void);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c
index 60ab2ea..bf53f1b 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c
@@ -130,14 +130,13 @@ static struct shrinker *pools_shrinker = NULL;
 /*
  * /proc/fs/lustre/sptlrpc/encrypt_page_pools
  */
-int sptlrpc_proc_read_enc_pool(char *page, char **start, off_t off, int count,
-			       int *eof, void *data)
+int sptlrpc_proc_enc_pool_seq_show(struct seq_file *m, void *v)
 {
 	int     rc;
 
 	spin_lock(&page_pools.epp_lock);
 
-	rc = snprintf(page, count,
+	rc = seq_printf(m,
 		      "physical pages:	  %lu\n"
 		      "pages per pool:	  %lu\n"
 		      "max pages:	       %lu\n"
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_lproc.c b/drivers/staging/lustre/lustre/ptlrpc/sec_lproc.c
index 920591b..1213621 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_lproc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_lproc.c
@@ -168,8 +168,9 @@ int sptlrpc_lprocfs_cliobd_attach(struct obd_device *dev)
 }
 EXPORT_SYMBOL(sptlrpc_lprocfs_cliobd_attach);
 
+LPROC_SEQ_FOPS_RO(sptlrpc_proc_enc_pool);
 static struct lprocfs_vars sptlrpc_lprocfs_vars[] = {
-	{ "encrypt_page_pools", sptlrpc_proc_read_enc_pool, NULL, NULL },
+	{ "encrypt_page_pools", &sptlrpc_proc_enc_pool_fops },
 	{ NULL }
 };
 
-- 
1.7.9.5

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/devel




[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux