From 04e7562f872092c7a94e6d77fb5d2a7f97594bcf Mon Sep 17 00:00:00 2001 From: James Simmons Date: Thu, 2 Jan 2014 09:03:26 -0500 Subject: [PATCH] LU-3319 procfs: update shared server side core proc handling to seq_files Several of the server side abstact layers such as mdt,mgs etc share several common proc handling routines. This patch adds the seq_file version so that the stack can gradually be ported over to these new methods. Signed-off-by: James Simmons Change-Id: I2dd64046fdd4d2bb6f7550bb49cf1c9ef703c157 Reviewed-on: http://review.whamcloud.com/7933 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Bob Glossman Reviewed-by: Oleg Drokin --- libcfs/include/libcfs/libcfs_hash.h | 5 + libcfs/libcfs/hash.c | 80 +++++++ lustre/include/dt_object.h | 8 + lustre/include/lprocfs_status.h | 101 ++++++-- lustre/obdclass/dt_object.c | 96 +++++++- lustre/obdclass/lprocfs_jobstats.c | 47 +++- lustre/obdclass/lprocfs_status.c | 464 ++++++++++++++++++++++++++++++++---- lustre/ptlrpc/lproc_ptlrpc.c | 43 ---- 8 files changed, 723 insertions(+), 121 deletions(-) diff --git a/libcfs/include/libcfs/libcfs_hash.h b/libcfs/include/libcfs/libcfs_hash.h index e7d2dc8..07a12f6 100644 --- a/libcfs/include/libcfs/libcfs_hash.h +++ b/libcfs/include/libcfs/libcfs_hash.h @@ -840,8 +840,13 @@ static inline void __cfs_hash_set_theta(cfs_hash_t *hs, int min, int max) } /* Generic debug formatting routines mainly for proc handler */ +#ifndef HAVE_ONLY_PROCFS_SEQ int cfs_hash_debug_header(char *str, int size); int cfs_hash_debug_str(cfs_hash_t *hs, char *str, int size); +#endif +struct seq_file; +int cfs_hash_debug_header_seq(struct seq_file *m); +int cfs_hash_debug_str_seq(cfs_hash_t *hs, struct seq_file *m); /* * Generic djb2 hash algorithm for character arrays. diff --git a/libcfs/libcfs/hash.c b/libcfs/libcfs/hash.c index 35c64a0..0c4faf8 100644 --- a/libcfs/libcfs/hash.c +++ b/libcfs/libcfs/hash.c @@ -2026,6 +2026,7 @@ void cfs_hash_rehash_key(cfs_hash_t *hs, const void *old_key, } EXPORT_SYMBOL(cfs_hash_rehash_key); +#ifndef HAVE_ONLY_PROCFS_SEQ int cfs_hash_debug_header(char *str, int size) { return snprintf(str, size, "%-*s%6s%6s%6s%6s%6s%6s%6s%7s%8s%8s%8s%s\n", @@ -2035,6 +2036,17 @@ int cfs_hash_debug_header(char *str, int size) " distribution"); } EXPORT_SYMBOL(cfs_hash_debug_header); +#endif + +int cfs_hash_debug_header_seq(struct seq_file *m) +{ + return seq_printf(m, "%-*s%6s%6s%6s%6s%6s%6s%6s%7s%8s%8s%8s%s\n", + CFS_HASH_BIGNAME_LEN, + "name", "cur", "min", "max", "theta", "t-min", "t-max", + "flags", "rehash", "count", "maxdep", "maxdepb", + " distribution"); +} +EXPORT_SYMBOL(cfs_hash_debug_header_seq); static cfs_hash_bucket_t ** cfs_hash_full_bkts(cfs_hash_t *hs) @@ -2060,6 +2072,7 @@ cfs_hash_full_nbkt(cfs_hash_t *hs) CFS_HASH_RH_NBKT(hs) : CFS_HASH_NBKT(hs); } +#ifndef HAVE_ONLY_PROCFS_SEQ int cfs_hash_debug_str(cfs_hash_t *hs, char *str, int size) { int dist[8] = { 0, }; @@ -2134,3 +2147,70 @@ int cfs_hash_debug_str(cfs_hash_t *hs, char *str, int size) return c; } EXPORT_SYMBOL(cfs_hash_debug_str); +#endif + +int cfs_hash_debug_str_seq(cfs_hash_t *hs, struct seq_file *m) +{ + int dist[8] = { 0, }; + int maxdep = -1; + int maxdepb = -1; + int total = 0; + int c = 0; + int theta; + int i; + + cfs_hash_lock(hs, 0); + theta = __cfs_hash_theta(hs); + + c += seq_printf(m, "%-*s ", CFS_HASH_BIGNAME_LEN, hs->hs_name); + c += seq_printf(m, "%5d ", 1 << hs->hs_cur_bits); + c += seq_printf(m, "%5d ", 1 << hs->hs_min_bits); + c += seq_printf(m, "%5d ", 1 << hs->hs_max_bits); + c += seq_printf(m, "%d.%03d ", __cfs_hash_theta_int(theta), + __cfs_hash_theta_frac(theta)); + c += seq_printf(m, "%d.%03d ", __cfs_hash_theta_int(hs->hs_min_theta), + __cfs_hash_theta_frac(hs->hs_min_theta)); + c += seq_printf(m, "%d.%03d ", __cfs_hash_theta_int(hs->hs_max_theta), + __cfs_hash_theta_frac(hs->hs_max_theta)); + c += seq_printf(m, " 0x%02x ", hs->hs_flags); + c += seq_printf(m, "%6d ", hs->hs_rehash_count); + + /* + * The distribution is a summary of the chained hash depth in + * each of the libcfs hash buckets. Each buckets hsb_count is + * divided by the hash theta value and used to generate a + * histogram of the hash distribution. A uniform hash will + * result in all hash buckets being close to the average thus + * only the first few entries in the histogram will be non-zero. + * If you hash function results in a non-uniform hash the will + * be observable by outlier bucks in the distribution histogram. + * + * Uniform hash distribution: 128/128/0/0/0/0/0/0 + * Non-Uniform hash distribution: 128/125/0/0/0/0/2/1 + */ + for (i = 0; i < cfs_hash_full_nbkt(hs); i++) { + cfs_hash_bd_t bd; + + bd.bd_bucket = cfs_hash_full_bkts(hs)[i]; + cfs_hash_bd_lock(hs, &bd, 0); + if (maxdep < bd.bd_bucket->hsb_depmax) { + maxdep = bd.bd_bucket->hsb_depmax; +#ifdef __KERNEL__ + maxdepb = ffz(~maxdep); +#endif + } + total += bd.bd_bucket->hsb_count; + dist[min(fls(bd.bd_bucket->hsb_count/max(theta,1)),7)]++; + cfs_hash_bd_unlock(hs, &bd, 0); + } + + c += seq_printf(m, "%7d ", total); + c += seq_printf(m, "%7d ", maxdep); + c += seq_printf(m, "%7d ", maxdepb); + for (i = 0; i < 8; i++) + c += seq_printf(m, "%d%c", dist[i], (i == 7) ? '\n' : '/'); + + cfs_hash_unlock(hs, 0); + return c; +} +EXPORT_SYMBOL(cfs_hash_debug_str_seq); diff --git a/lustre/include/dt_object.h b/lustre/include/dt_object.h index 43f6a43..e93ae43 100644 --- a/lustre/include/dt_object.h +++ b/lustre/include/dt_object.h @@ -1492,6 +1492,7 @@ int dt_global_init(void); void dt_global_fini(void); # ifdef LPROCFS +#ifndef HAVE_ONLY_PROCFS_SEQ int lprocfs_dt_rd_blksize(char *page, char **start, off_t off, int count, int *eof, void *data); int lprocfs_dt_rd_kbytestotal(char *page, char **start, off_t off, @@ -1504,6 +1505,13 @@ int lprocfs_dt_rd_filestotal(char *page, char **start, off_t off, int count, int *eof, void *data); int lprocfs_dt_rd_filesfree(char *page, char **start, off_t off, int count, int *eof, void *data); +#endif +int lprocfs_dt_blksize_seq_show(struct seq_file *m, void *v); +int lprocfs_dt_kbytestotal_seq_show(struct seq_file *m, void *v); +int lprocfs_dt_kbytesfree_seq_show(struct seq_file *m, void *v); +int lprocfs_dt_kbytesavail_seq_show(struct seq_file *m, void *v); +int lprocfs_dt_filestotal_seq_show(struct seq_file *m, void *v); +int lprocfs_dt_filesfree_seq_show(struct seq_file *m, void *v); # endif /* LPROCFS */ #endif /* __LUSTRE_DT_OBJECT_H */ diff --git a/lustre/include/lprocfs_status.h b/lustre/include/lprocfs_status.h index 2080592..70f10a9 100644 --- a/lustre/include/lprocfs_status.h +++ b/lustre/include/lprocfs_status.h @@ -603,12 +603,19 @@ extern struct proc_dir_entry * lprocfs_add_symlink(const char *name, struct proc_dir_entry *parent, const char *format, ...); extern void lprocfs_free_per_client_stats(struct obd_device *obd); +#ifdef HAVE_SERVER_SUPPORT +#ifndef HAVE_ONLY_PROCFS_SEQ extern int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer, unsigned long count, void *data); extern int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off, int count, int *eof, void *data); - +#endif +extern ssize_t +lprocfs_nid_stats_clear_seq_write(struct file *file, const char *buffer, + size_t count, loff_t *off); +extern int lprocfs_nid_stats_clear_seq_show(struct seq_file *file, void *data); +#endif extern int lprocfs_register_stats(cfs_proc_dir_entry_t *root, const char *name, struct lprocfs_stats *stats); @@ -700,6 +707,9 @@ extern int lprocfs_conn_uuid_seq_show(struct seq_file *m, void *data); extern int lprocfs_import_seq_show(struct seq_file *m, void *data); extern int lprocfs_state_seq_show(struct seq_file *m, void *data); extern int lprocfs_connect_flags_seq_show(struct seq_file *m, void *data); +#ifdef HAVE_SERVER_SUPPORT +extern int lprocfs_num_exports_seq_show(struct seq_file *m, void *data); +#endif struct adaptive_timeout; #ifndef HAVE_ONLY_PROCFS_SEQ extern int lprocfs_at_hist_helper(char *page, int count, int rc, @@ -715,9 +725,11 @@ extern int lprocfs_timeouts_seq_show(struct seq_file *m, void *data); extern ssize_t lprocfs_timeouts_seq_write(struct file *file, const char *buffer, size_t count, loff_t *off); +#ifndef HAVE_ONLY_PROCFS_SEQ +#ifdef HAVE_SERVER_SUPPORT extern int lprocfs_wr_evict_client(struct file *file, const char *buffer, unsigned long count, void *data); -#ifndef HAVE_ONLY_PROCFS_SEQ +#endif extern int lprocfs_wr_ping(struct file *file, const char *buffer, unsigned long count, void *data); extern int lprocfs_wr_import(struct file *file, const char *buffer, @@ -727,6 +739,11 @@ extern int lprocfs_rd_pinger_recov(char *page, char **start, off_t off, extern int lprocfs_wr_pinger_recov(struct file *file, const char *buffer, unsigned long count, void *data); #endif +#ifdef HAVE_SERVER_SUPPORT +extern ssize_t +lprocfs_evict_client_seq_write(struct file *file, const char *buffer, + size_t count, loff_t *off); +#endif extern ssize_t lprocfs_ping_seq_write(struct file *file, const char *buffer, size_t count, loff_t *off); @@ -785,10 +802,10 @@ void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx, struct lprocfs_counter *cnt); #ifdef HAVE_SERVER_SUPPORT +#ifndef HAVE_ONLY_PROCFS_SEQ /* lprocfs_status.c: recovery status */ int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off, int count, int *eof, void *data); -#endif /* lprocfs_statuc.c: hash statistics */ int lprocfs_obd_rd_hash(char *page, char **start, off_t off, int count, int *eof, void *data); @@ -798,7 +815,19 @@ int lprocfs_obd_rd_ir_factor(char *page, char **start, off_t off, int count, int *eof, void *data); int lprocfs_obd_wr_ir_factor(struct file *file, const char *buffer, unsigned long count, void *data); +#endif +/* lprocfs_status.c: recovery status */ +int lprocfs_recovery_status_seq_show(struct seq_file *m, void *data); +/* lprocfs_status.c: hash statistics */ +int lprocfs_hash_seq_show(struct seq_file *m, void *data); + +/* lprocfs_status.c: IR factor */ +int lprocfs_ir_factor_seq_show(struct seq_file *m, void *data); +ssize_t +lprocfs_ir_factor_seq_write(struct file *file, const char *buffer, + size_t count, loff_t *off); +#endif extern int lprocfs_single_release(cfs_inode_t *, struct file *); extern int lprocfs_seq_release(cfs_inode_t *, struct file *); @@ -874,21 +903,23 @@ struct file_operations name##_fops = { \ .release = lprocfs_single_release, \ }; +/* lproc_ptlrpc.c */ +struct ptlrpc_request; +extern void target_print_req(void *seq_file, struct ptlrpc_request *req); + +#ifdef HAVE_SERVER_SUPPORT /* lprocfs_jobstats.c */ int lprocfs_job_stats_log(struct obd_device *obd, char *jobid, int event, long amount); void lprocfs_job_stats_fini(struct obd_device *obd); int lprocfs_job_stats_init(struct obd_device *obd, int cntr_num, cntr_init_callback fn); +#ifndef HAVE_ONLY_PROCFS_SEQ int lprocfs_rd_job_interval(char *page, char **start, off_t off, int count, int *eof, void *data); int lprocfs_wr_job_interval(struct file *file, const char *buffer, unsigned long count, void *data); -/* lproc_ptlrpc.c */ -struct ptlrpc_request; -extern void target_print_req(void *seq_file, struct ptlrpc_request *req); - /* lproc_status.c */ int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off, int count, int *eof, void *data); @@ -900,6 +931,24 @@ int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off, int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer, unsigned long count, void *data); +int lprocfs_target_rd_instance(char *page, char **start, off_t off, + int count, int *eof, void *data); +#endif +int lprocfs_job_interval_seq_show(struct seq_file *m, void *data); +ssize_t +lprocfs_job_interval_seq_write(struct file *file, const char *buffer, + size_t count, loff_t *off); +/* lproc_status.c */ +int lprocfs_recovery_time_soft_seq_show(struct seq_file *m, void *data); +ssize_t lprocfs_recovery_time_soft_seq_write(struct file *file, + const char *buffer, + size_t count, loff_t *off); +int lprocfs_recovery_time_hard_seq_show(struct seq_file *m, void *data); +ssize_t +lprocfs_recovery_time_hard_seq_write(struct file *file, const char *buffer, + size_t count, loff_t *off); +int lprocfs_target_instance_seq_show(struct seq_file *m, void *data); +#endif #ifndef HAVE_ONLY_PROCFS_SEQ int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off, int count, int *eof, void *data); @@ -910,8 +959,6 @@ int lprocfs_obd_max_pages_per_rpc_seq_show(struct seq_file *m, void *data); ssize_t lprocfs_obd_max_pages_per_rpc_seq_write(struct file *file, const char *buffer, size_t count, loff_t *off); -int lprocfs_target_rd_instance(char *page, char **start, off_t off, - int count, int *eof, void *data); /* all quota proc functions */ extern int lprocfs_quota_rd_bunit(char *page, char **start, @@ -1032,7 +1079,26 @@ static inline void lprocfs_free_md_stats(struct obd_device *obddev) struct obd_export; static inline int lprocfs_add_clear_entry(struct obd_export *exp) { return 0; } +static inline void lprocfs_free_per_client_stats(struct obd_device *obd) +{ return; } #ifdef HAVE_SERVER_SUPPORT +#ifndef HAVE_ONLY_PROCFS_SEQ +static inline +int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer, + unsigned long count, void *data) +{return count;} +static inline +int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off, + int count, int *eof, void *data) +{return count;} +#endif +static inline +ssize_t lprocfs_nid_stats_seq_write(struct file *file, const char *buffer, + size_t count, loff_t *off) +{return 0;} +static inline +int lprocfs_nid_stats_clear_seq_show(struct seq_file *m, void *data) +{return 0;} static inline int lprocfs_exp_setup(struct obd_export *exp,lnet_nid_t *peer_nid, int *newnid) { return 0; } @@ -1050,17 +1116,6 @@ static inline struct proc_dir_entry * lprocfs_add_symlink(const char *name, struct proc_dir_entry *parent, const char *format, ...) {return NULL; } -static inline void lprocfs_free_per_client_stats(struct obd_device *obd) -{ return; } -static inline -int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer, - unsigned long count, void *data) -{return count;} -static inline -int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{return count;} - #ifndef HAVE_ONLY_PROCFS_SEQ static inline cfs_proc_dir_entry_t * lprocfs_register(const char *name, cfs_proc_dir_entry_t *parent, @@ -1145,10 +1200,12 @@ static inline int lprocfs_wr_timeouts(struct file *file, const char *buffer, unsigned long count, void *data) { return 0; } +#ifdef HAVE_SERVER_SUPPORT static inline int lprocfs_wr_evict_client(struct file *file, const char *buffer, unsigned long count, void *data) { return 0; } +#endif static inline int lprocfs_wr_ping(struct file *file, const char *buffer, unsigned long count, void *data) { return 0; } @@ -1173,8 +1230,10 @@ static inline int lprocfs_state_seq_show(struct seq_file *m, void *data) { return 0; } static inline int lprocfs_connect_flags_seq_show(struct seq_file *m, void *data) { return 0; } +#ifdef HAVE_SERVER_SUPPORT static inline int lprocfs_num_exports_seq_show(struct seq_file *m, void *data) { return 0; } +#endif struct adaptive_timeout; static inline int lprocfs_seq_at_hist_helper(struct seq_file *m, struct adaptive_timeout *at) @@ -1185,10 +1244,12 @@ static inline ssize_t lprocfs_timeouts_seq_write(struct file *file, const char *buffer, size_t count, loff_t *off) { return 0; } +#ifdef HAVE_SERVER_SUPPORT static inline ssize_t lprocfs_evict_client_seq_write(struct file *file, const char *buffer, size_t count, loff_t *off) { return 0; } +#endif static inline ssize_t lprocfs_ping_seq_write(struct file *file, const char *buffer, size_t count, loff_t *off) diff --git a/lustre/obdclass/dt_object.c b/lustre/obdclass/dt_object.c index afe90d3..5f31e12 100644 --- a/lustre/obdclass/dt_object.c +++ b/lustre/obdclass/dt_object.c @@ -939,7 +939,7 @@ out: EXPORT_SYMBOL(dt_index_read); #ifdef LPROCFS - +#ifndef HAVE_ONLY_PROCFS_SEQ int lprocfs_dt_rd_blksize(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -1054,5 +1054,99 @@ int lprocfs_dt_rd_filesfree(char *page, char **start, off_t off, return rc; } EXPORT_SYMBOL(lprocfs_dt_rd_filesfree); +#endif + +int lprocfs_dt_blksize_seq_show(struct seq_file *m, void *v) +{ + struct dt_device *dt = m->private; + struct obd_statfs osfs; + + int rc = dt_statfs(NULL, dt, &osfs); + if (rc == 0) + seq_printf(m, "%u\n", (unsigned) osfs.os_bsize); + return rc; +} +EXPORT_SYMBOL(lprocfs_dt_blksize_seq_show); + +int lprocfs_dt_kbytestotal_seq_show(struct seq_file *m, void *v) +{ + struct dt_device *dt = m->private; + struct obd_statfs osfs; + + int rc = dt_statfs(NULL, dt, &osfs); + if (rc == 0) { + __u32 blk_size = osfs.os_bsize >> 10; + __u64 result = osfs.os_blocks; + + while (blk_size >>= 1) + result <<= 1; + + seq_printf(m, LPU64"\n", result); + } + return rc; +} +EXPORT_SYMBOL(lprocfs_dt_kbytestotal_seq_show); + +int lprocfs_dt_kbytesfree_seq_show(struct seq_file *m, void *v) +{ + struct dt_device *dt = m->private; + struct obd_statfs osfs; + + int rc = dt_statfs(NULL, dt, &osfs); + if (rc == 0) { + __u32 blk_size = osfs.os_bsize >> 10; + __u64 result = osfs.os_bfree; + + while (blk_size >>= 1) + result <<= 1; + + seq_printf(m, LPU64"\n", result); + } + return rc; +} +EXPORT_SYMBOL(lprocfs_dt_kbytesfree_seq_show); + +int lprocfs_dt_kbytesavail_seq_show(struct seq_file *m, void *v) +{ + struct dt_device *dt = m->private; + struct obd_statfs osfs; + + int rc = dt_statfs(NULL, dt, &osfs); + if (rc == 0) { + __u32 blk_size = osfs.os_bsize >> 10; + __u64 result = osfs.os_bavail; + + while (blk_size >>= 1) + result <<= 1; + + seq_printf(m, LPU64"\n", result); + } + return rc; +} +EXPORT_SYMBOL(lprocfs_dt_kbytesavail_seq_show); + +int lprocfs_dt_filestotal_seq_show(struct seq_file *m, void *v) +{ + struct dt_device *dt = m->private; + struct obd_statfs osfs; + + int rc = dt_statfs(NULL, dt, &osfs); + if (rc == 0) + seq_printf(m, LPU64"\n", osfs.os_files); + return rc; +} +EXPORT_SYMBOL(lprocfs_dt_filestotal_seq_show); + +int lprocfs_dt_filesfree_seq_show(struct seq_file *m, void *v) +{ + struct dt_device *dt = m->private; + struct obd_statfs osfs; + + int rc = dt_statfs(NULL, dt, &osfs); + if (rc == 0) + seq_printf(m, LPU64"\n", osfs.os_ffree); + return rc; +} +EXPORT_SYMBOL(lprocfs_dt_filesfree_seq_show); #endif /* LPROCFS */ diff --git a/lustre/obdclass/lprocfs_jobstats.c b/lustre/obdclass/lprocfs_jobstats.c index 36c6e1e..d443841 100644 --- a/lustre/obdclass/lprocfs_jobstats.c +++ b/lustre/obdclass/lprocfs_jobstats.c @@ -416,18 +416,17 @@ struct seq_operations lprocfs_jobstats_seq_sops = { static int lprocfs_jobstats_seq_open(struct inode *inode, struct file *file) { - struct proc_dir_entry *dp = PDE(inode); struct seq_file *seq; int rc; - if (LPROCFS_ENTRY_CHECK(dp)) + if (LPROCFS_ENTRY_CHECK(PDE(inode))) return -ENOENT; rc = seq_open(file, &lprocfs_jobstats_seq_sops); if (rc) return rc; seq = file->private_data; - seq->private = dp->data; + seq->private = PDE_DATA(inode); return 0; } @@ -520,19 +519,18 @@ int lprocfs_job_stats_init(struct obd_device *obd, int cntr_num, stats->ojs_last_cleanup = cfs_time_current_sec(); LPROCFS_WRITE_ENTRY(); - entry = create_proc_entry("job_stats", 0644, obd->obd_proc_entry); + entry = proc_create_data("job_stats", 0644, obd->obd_proc_entry, + &lprocfs_jobstats_seq_fops, stats); LPROCFS_WRITE_EXIT(); - if (entry) { - entry->proc_fops = &lprocfs_jobstats_seq_fops; - entry->data = stats; - RETURN(0); - } else { + if (entry == NULL) { lprocfs_job_stats_fini(obd); RETURN(-ENOMEM); } + RETURN(0); } EXPORT_SYMBOL(lprocfs_job_stats_init); +#ifndef HAVE_ONLY_PROCFS_SEQ int lprocfs_rd_job_interval(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -567,5 +565,36 @@ int lprocfs_wr_job_interval(struct file *file, const char *buffer, } EXPORT_SYMBOL(lprocfs_wr_job_interval); +#endif +int lprocfs_job_interval_seq_show(struct seq_file *m, void *data) +{ + struct obd_device *obd = m->private; + struct obd_job_stats *stats; + + LASSERT(obd != NULL); + stats = &obd->u.obt.obt_jobstats; + return seq_printf(m, "%d\n", stats->ojs_cleanup_interval); +} +EXPORT_SYMBOL(lprocfs_job_interval_seq_show); + +ssize_t +lprocfs_job_interval_seq_write(struct file *file, const char *buffer, + size_t count, loff_t *off) +{ + struct obd_device *obd = ((struct seq_file *)file->private_data)->private; + struct obd_job_stats *stats; + int val, rc; + + LASSERT(obd != NULL); + stats = &obd->u.obt.obt_jobstats; + + rc = lprocfs_write_helper(buffer, count, &val); + if (rc) + return rc; + stats->ojs_cleanup_interval = val; + lprocfs_job_cleanup(stats, true); + return count; +} +EXPORT_SYMBOL(lprocfs_job_interval_seq_write); #endif /* LPROCFS*/ diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c index 1012ab9..7cd7870 100644 --- a/lustre/obdclass/lprocfs_status.c +++ b/lustre/obdclass/lprocfs_status.c @@ -288,18 +288,15 @@ static struct file_operations lprocfs_generic_fops = { }; #ifdef HAVE_SERVER_SUPPORT int lprocfs_evict_client_open(struct inode *inode, struct file *f) { - struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode); - struct obd_device *obd = dp->data; + struct obd_device *obd = PDE_DATA(f->f_dentry->d_inode); atomic_inc(&obd->obd_evict_inprogress); - - return 0; + return 0; } int lprocfs_evict_client_release(struct inode *inode, struct file *f) { - struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode); - struct obd_device *obd = dp->data; + struct obd_device *obd = PDE_DATA(f->f_dentry->d_inode); atomic_dec(&obd->obd_evict_inprogress); wake_up(&obd->obd_evict_inprogress_waitq); @@ -307,6 +304,89 @@ int lprocfs_evict_client_release(struct inode *inode, struct file *f) return 0; } +#define BUFLEN (UUID_MAX + 5) + +#ifndef HAVE_ONLY_PROCFS_SEQ +int lprocfs_wr_evict_client(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + struct obd_device *obd = data; + char *kbuf; + char *tmpbuf; + + OBD_ALLOC(kbuf, BUFLEN); + if (kbuf == NULL) + return -ENOMEM; + + /* + * OBD_ALLOC() will zero kbuf, but we only copy BUFLEN - 1 + * bytes into kbuf, to ensure that the string is NUL-terminated. + * UUID_MAX should include a trailing NUL already. + */ + if (copy_from_user(kbuf, buffer, + min_t(unsigned long, BUFLEN - 1, count))) { + count = -EFAULT; + goto out; + } + tmpbuf = cfs_firststr(kbuf, min_t(unsigned long, BUFLEN - 1, count)); + class_incref(obd, __FUNCTION__, current); + + if (strncmp(tmpbuf, "nid:", 4) == 0) + obd_export_evict_by_nid(obd, tmpbuf + 4); + else if (strncmp(tmpbuf, "uuid:", 5) == 0) + obd_export_evict_by_uuid(obd, tmpbuf + 5); + else + obd_export_evict_by_uuid(obd, tmpbuf); + + class_decref(obd, __FUNCTION__, current); +out: + OBD_FREE(kbuf, BUFLEN); + return count; +} +EXPORT_SYMBOL(lprocfs_wr_evict_client); +#endif + +ssize_t +lprocfs_evict_client_seq_write(struct file *file, const char *buffer, + size_t count, loff_t *off) +{ + struct obd_device *obd = ((struct seq_file *)file->private_data)->private; + char *tmpbuf, *kbuf; + + OBD_ALLOC(kbuf, BUFLEN); + if (kbuf == NULL) + return -ENOMEM; + + /* + * OBD_ALLOC() will zero kbuf, but we only copy BUFLEN - 1 + * bytes into kbuf, to ensure that the string is NUL-terminated. + * UUID_MAX should include a trailing NUL already. + */ + if (copy_from_user(kbuf, buffer, + min_t(unsigned long, BUFLEN - 1, count))) { + count = -EFAULT; + goto out; + } + tmpbuf = cfs_firststr(kbuf, min_t(unsigned long, BUFLEN - 1, count)); + class_incref(obd, __FUNCTION__, current); + + if (strncmp(tmpbuf, "nid:", 4) == 0) + obd_export_evict_by_nid(obd, tmpbuf + 4); + else if (strncmp(tmpbuf, "uuid:", 5) == 0) + obd_export_evict_by_uuid(obd, tmpbuf + 5); + else + obd_export_evict_by_uuid(obd, tmpbuf); + + class_decref(obd, __FUNCTION__, current); + +out: + OBD_FREE(kbuf, BUFLEN); + return count; +} +EXPORT_SYMBOL(lprocfs_evict_client_seq_write); + +#undef BUFLEN + struct file_operations lprocfs_evict_client_fops = { .owner = THIS_MODULE, .read = lprocfs_fops_read, @@ -1279,6 +1359,17 @@ int lprocfs_connect_flags_seq_show(struct seq_file *m, void *data) } EXPORT_SYMBOL(lprocfs_connect_flags_seq_show); +#ifdef HAVE_SERVER_SUPPORT +int lprocfs_num_exports_seq_show(struct seq_file *m, void *data) +{ + struct obd_device *obd = data; + + LASSERT(obd != NULL); + return seq_printf(m, "%u\n", obd->obd_num_exports); +} +EXPORT_SYMBOL(lprocfs_num_exports_seq_show); +#endif + #ifndef HAVE_ONLY_PROCFS_SEQ int lprocfs_rd_uint(char *page, char **start, off_t off, @@ -1794,6 +1885,7 @@ int lprocfs_rd_connect_flags(char *page, char **start, off_t off, } EXPORT_SYMBOL(lprocfs_rd_connect_flags); +#ifdef HAVE_SERVER_SUPPORT int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -1804,6 +1896,7 @@ int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count, return snprintf(page, count, "%u\n", obd->obd_num_exports); } EXPORT_SYMBOL(lprocfs_rd_num_exports); +#endif int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count, int *eof, void *data) @@ -2488,6 +2581,112 @@ void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats) } EXPORT_SYMBOL(lprocfs_init_ldlm_stats); +#ifdef HAVE_SERVER_SUPPORT +/* No one appears to be using this ?? */ +int lprocfs_exp_nid_seq_show(struct seq_file *m, void *data) +{ + struct obd_export *exp = m->private; + LASSERT(exp != NULL); + return seq_printf(m, "%s\n", obd_export_nid2str(exp)); +} + +int lprocfs_exp_print_uuid_seq(cfs_hash_t *hs, cfs_hash_bd_t *bd, + cfs_hlist_node_t *hnode, void *cb_data) + +{ + struct obd_export *exp = cfs_hash_object(hs, hnode); + struct seq_file *m = cb_data; + + if (exp->exp_nid_stats) + seq_printf(m, "%s\n", obd_uuid2str(&exp->exp_client_uuid)); + return 0; +} + +int lprocfs_exp_uuid_seq_show(struct seq_file *m, void *data) +{ + struct nid_stat *stats = m->private; + struct obd_device *obd = stats->nid_obd; + + cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid, + lprocfs_exp_print_uuid_seq, m); + return 0; +} +LPROC_SEQ_FOPS_RO(lprocfs_exp_uuid); + +int lprocfs_exp_print_hash_seq(cfs_hash_t *hs, cfs_hash_bd_t *bd, + cfs_hlist_node_t *hnode, void *cb_data) + +{ + struct seq_file *m = cb_data; + struct obd_export *exp = cfs_hash_object(hs, hnode); + + if (exp->exp_lock_hash != NULL) { + cfs_hash_debug_header_seq(m); + cfs_hash_debug_str_seq(hs, m); + } + return 0; +} + +int lprocfs_exp_hash_seq_show(struct seq_file *m, void *data) +{ + struct nid_stat *stats = m->private; + struct obd_device *obd = stats->nid_obd; + + cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid, + lprocfs_exp_print_hash_seq, m); + return 0; +} +LPROC_SEQ_FOPS_RO(lprocfs_exp_hash); + +int lprocfs_nid_stats_clear_seq_show(struct seq_file *m, void *data) +{ + return seq_printf(m, "%s\n", "Write into this file to clear all nid " + "stats and stale nid entries"); +} +EXPORT_SYMBOL(lprocfs_nid_stats_clear_seq_show); + +static int lprocfs_nid_stats_clear_write_cb(void *obj, void *data) +{ + struct nid_stat *stat = obj; + ENTRY; + + CDEBUG(D_INFO,"refcnt %d\n", atomic_read(&stat->nid_exp_ref_count)); + if (atomic_read(&stat->nid_exp_ref_count) == 1) { + /* object has only hash references. */ + spin_lock(&stat->nid_obd->obd_nid_lock); + cfs_list_move(&stat->nid_list, data); + spin_unlock(&stat->nid_obd->obd_nid_lock); + RETURN(1); + } + /* we has reference to object - only clear data*/ + if (stat->nid_stats) + lprocfs_clear_stats(stat->nid_stats); + + RETURN(0); +} + +ssize_t +lprocfs_nid_stats_clear_seq_write(struct file *file, const char *buffer, + size_t count, loff_t *off) +{ + struct obd_device *obd = ((struct seq_file *)file->private_data)->private; + struct nid_stat *client_stat; + CFS_LIST_HEAD(free_list); + + cfs_hash_cond_del(obd->obd_nid_stats_hash, + lprocfs_nid_stats_clear_write_cb, &free_list); + + while (!cfs_list_empty(&free_list)) { + client_stat = cfs_list_entry(free_list.next, struct nid_stat, + nid_list); + cfs_list_del_init(&client_stat->nid_list); + lprocfs_free_client_stats(client_stat); + } + return count; +} +EXPORT_SYMBOL(lprocfs_nid_stats_clear_seq_write); + +#ifndef HAVE_ONLY_PROCFS_SEQ int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -2590,26 +2789,6 @@ int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off, } EXPORT_SYMBOL(lprocfs_nid_stats_clear_read); -static int lprocfs_nid_stats_clear_write_cb(void *obj, void *data) -{ - struct nid_stat *stat = obj; - ENTRY; - - CDEBUG(D_INFO,"refcnt %d\n", atomic_read(&stat->nid_exp_ref_count)); - if (atomic_read(&stat->nid_exp_ref_count) == 1) { - /* object has only hash references. */ - spin_lock(&stat->nid_obd->obd_nid_lock); - cfs_list_move(&stat->nid_list, data); - spin_unlock(&stat->nid_obd->obd_nid_lock); - RETURN(1); - } - /* we has reference to object - only clear data*/ - if (stat->nid_stats) - lprocfs_clear_stats(stat->nid_stats); - - RETURN(0); -} - int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer, unsigned long count, void *data) { @@ -2630,8 +2809,8 @@ int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer, return count; } EXPORT_SYMBOL(lprocfs_nid_stats_clear_write); +#endif -#ifdef HAVE_SERVER_SUPPORT int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid) { struct nid_stat *new_stat, *old_stat; @@ -2690,11 +2869,17 @@ int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid) if (buffer == NULL) GOTO(destroy_new, rc = -ENOMEM); - memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE); + memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE); +#ifndef HAVE_ONLY_PROCFS_SEQ new_stat->nid_proc = lprocfs_register(buffer, - obd->obd_proc_exports_entry, - NULL, NULL); - OBD_FREE(buffer, LNET_NIDSTR_SIZE); + obd->obd_proc_exports_entry, + NULL, NULL); +#else + new_stat->nid_proc = lprocfs_seq_register(buffer, + obd->obd_proc_exports_entry, + NULL, NULL); +#endif + OBD_FREE(buffer, LNET_NIDSTR_SIZE); if (IS_ERR(new_stat->nid_proc)) { rc = PTR_ERR(new_stat->nid_proc); @@ -2704,16 +2889,26 @@ int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid) GOTO(destroy_new_ns, rc); } +#ifndef HAVE_ONLY_PROCFS_SEQ entry = lprocfs_add_simple(new_stat->nid_proc, "uuid", lprocfs_exp_rd_uuid, NULL, new_stat, NULL); +#else + entry = lprocfs_add_simple(new_stat->nid_proc, "uuid", + new_stat, &lprocfs_exp_uuid_fops); +#endif if (IS_ERR(entry)) { CWARN("Error adding the NID stats file\n"); rc = PTR_ERR(entry); GOTO(destroy_new_ns, rc); } +#ifndef HAVE_ONLY_PROCFS_SEQ entry = lprocfs_add_simple(new_stat->nid_proc, "hash", lprocfs_exp_rd_hash, NULL, new_stat, NULL); +#else + entry = lprocfs_add_simple(new_stat->nid_proc, "hash", + new_stat, &lprocfs_exp_hash_fops); +#endif if (IS_ERR(entry)) { CWARN("Error adding the hash file\n"); rc = PTR_ERR(entry); @@ -3118,6 +3313,181 @@ void lprocfs_oh_clear(struct obd_histogram *oh) } EXPORT_SYMBOL(lprocfs_oh_clear); +#ifdef HAVE_SERVER_SUPPORT +int lprocfs_hash_seq_show(struct seq_file *m, void *data) +{ + struct obd_device *obd = m->private; + int c = 0; + + if (obd == NULL) + return 0; + + c += cfs_hash_debug_header_seq(m); + c += cfs_hash_debug_str_seq(obd->obd_uuid_hash, m); + c += cfs_hash_debug_str_seq(obd->obd_nid_hash, m); + c += cfs_hash_debug_str_seq(obd->obd_nid_stats_hash, m); + return c; +} +EXPORT_SYMBOL(lprocfs_hash_seq_show); + +int lprocfs_recovery_status_seq_show(struct seq_file *m, void *data) +{ + struct obd_device *obd = m->private; + + LASSERT(obd != NULL); + + seq_printf(m, "status: \n"); + if (obd->obd_max_recoverable_clients == 0) { + seq_printf(m, "INACTIVE\n"); + goto out; + } + + /* sampled unlocked, but really... */ + if (obd->obd_recovering == 0) { + seq_printf(m, "COMPLETE\n"); + seq_printf(m, "recovery_start: %lu\n", obd->obd_recovery_start); + seq_printf(m, "recovery_duration: %lu\n", + obd->obd_recovery_end - obd->obd_recovery_start); + /* Number of clients that have completed recovery */ + seq_printf(m, "completed_clients: %d/%d\n", + obd->obd_max_recoverable_clients - + obd->obd_stale_clients, + obd->obd_max_recoverable_clients); + seq_printf(m, "replayed_requests: %d\n", + obd->obd_replayed_requests); + seq_printf(m, "last_transno: "LPD64"\n", + obd->obd_next_recovery_transno - 1); + seq_printf(m, "VBR: %s\n", obd->obd_version_recov ? + "ENABLED" : "DISABLED"); + seq_printf(m, "IR: %s\n", obd->obd_no_ir ? + "DISABLED" : "ENABLED"); + goto out; + } + + seq_printf(m, "RECOVERING\n"); + seq_printf(m, "recovery_start: %lu\n", obd->obd_recovery_start); + seq_printf(m, "time_remaining: %lu\n", + cfs_time_current_sec() >= + obd->obd_recovery_start + + obd->obd_recovery_timeout ? 0 : + obd->obd_recovery_start + + obd->obd_recovery_timeout - + cfs_time_current_sec()); + seq_printf(m, "connected_clients: %d/%d\n", + atomic_read(&obd->obd_connected_clients), + obd->obd_max_recoverable_clients); + /* Number of clients that have completed recovery */ + seq_printf(m, "req_replay_clients: %d\n", + atomic_read(&obd->obd_req_replay_clients)); + seq_printf(m, "lock_repay_clients: %d\n", + atomic_read(&obd->obd_lock_replay_clients)); + seq_printf(m, "completed_clients: %d\n", + atomic_read(&obd->obd_connected_clients) - + atomic_read(&obd->obd_lock_replay_clients)); + seq_printf(m, "evicted_clients: %d\n", obd->obd_stale_clients); + seq_printf(m, "replayed_requests: %d\n", obd->obd_replayed_requests); + seq_printf(m, "queued_requests: %d\n", + obd->obd_requests_queued_for_recovery); + seq_printf(m, "next_transno: "LPD64"\n", + obd->obd_next_recovery_transno); +out: + return 0; +} +EXPORT_SYMBOL(lprocfs_recovery_status_seq_show); + +int lprocfs_ir_factor_seq_show(struct seq_file *m, void *data) +{ + struct obd_device *obd = m->private; + + LASSERT(obd != NULL); + return seq_printf(m, "%d\n", obd->obd_recovery_ir_factor); +} +EXPORT_SYMBOL(lprocfs_ir_factor_seq_show); + +ssize_t +lprocfs_ir_factor_seq_write(struct file *file, const char *buffer, + size_t count, loff_t *off) +{ + struct obd_device *obd = ((struct seq_file *)file->private_data)->private; + int val, rc; + + LASSERT(obd != NULL); + rc = lprocfs_write_helper(buffer, count, &val); + if (rc) + return rc; + + if (val < OBD_IR_FACTOR_MIN || val > OBD_IR_FACTOR_MAX) + return -EINVAL; + + obd->obd_recovery_ir_factor = val; + return count; +} +EXPORT_SYMBOL(lprocfs_ir_factor_seq_write); + +int lprocfs_recovery_time_soft_seq_show(struct seq_file *m, void *data) +{ + struct obd_device *obd = m->private; + + LASSERT(obd != NULL); + return seq_printf(m, "%d\n", obd->obd_recovery_timeout); +} +EXPORT_SYMBOL(lprocfs_recovery_time_soft_seq_show); + +ssize_t +lprocfs_recovery_time_soft_seq_write(struct file *file, const char *buffer, + size_t count, loff_t *off) +{ + struct obd_device *obd = ((struct seq_file *)file->private_data)->private; + int val, rc; + + LASSERT(obd != NULL); + rc = lprocfs_write_helper(buffer, count, &val); + if (rc) + return rc; + + obd->obd_recovery_timeout = val; + return count; +} +EXPORT_SYMBOL(lprocfs_recovery_time_soft_seq_write); + +int lprocfs_recovery_time_hard_seq_show(struct seq_file *m, void *data) +{ + struct obd_device *obd = m->private; + + LASSERT(obd != NULL); + return seq_printf(m, "%u\n", obd->obd_recovery_time_hard); +} +EXPORT_SYMBOL(lprocfs_recovery_time_hard_seq_show); + +ssize_t +lprocfs_recovery_time_hard_seq_write(struct file *file, const char *buffer, + size_t count, loff_t *off) +{ + struct obd_device *obd = ((struct seq_file *)file->private_data)->private; + int val, rc; + + LASSERT(obd != NULL); + rc = lprocfs_write_helper(buffer, count, &val); + if (rc) + return rc; + + obd->obd_recovery_time_hard = val; + return count; +} +EXPORT_SYMBOL(lprocfs_recovery_time_hard_seq_write); + +int lprocfs_target_instance_seq_show(struct seq_file *m, void *data) +{ + struct obd_device *obd = m->private; + struct obd_device_target *target = &obd->u.obt; + + LASSERT(obd != NULL); + LASSERT(target->obt_magic == OBT_MAGIC); + return seq_printf(m, "%u\n", obd->u.obt.obt_instance); +} +EXPORT_SYMBOL(lprocfs_target_instance_seq_show); + +#ifndef HAVE_ONLY_PROCFS_SEQ int lprocfs_obd_rd_hash(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -3136,7 +3506,6 @@ int lprocfs_obd_rd_hash(char *page, char **start, off_t off, } EXPORT_SYMBOL(lprocfs_obd_rd_hash); -#ifdef HAVE_SERVER_SUPPORT int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -3262,7 +3631,6 @@ out: return min(count, len - (int)off); } EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status); -#endif int lprocfs_obd_rd_ir_factor(char *page, char **start, off_t off, int count, int *eof, void *data) @@ -3347,6 +3715,21 @@ int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer, } EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard); +int lprocfs_target_rd_instance(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + struct obd_device *obd = (struct obd_device *)data; + struct obd_device_target *target = &obd->u.obt; + + LASSERT(obd != NULL); + LASSERT(target->obt_magic == OBT_MAGIC); + *eof = 1; + return snprintf(page, count, "%u\n", obd->u.obt.obt_instance); +} +EXPORT_SYMBOL(lprocfs_target_rd_instance); +#endif /* HAVE_ONLY_PROCFS_SEQ */ +#endif /* HAVE_SERVER_SUPPORT */ + int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -3373,19 +3756,4 @@ int lprocfs_obd_max_pages_per_rpc_seq_show(struct seq_file *m, void *data) return rc; } EXPORT_SYMBOL(lprocfs_obd_max_pages_per_rpc_seq_show); - -#ifdef HAVE_SERVER_SUPPORT -int lprocfs_target_rd_instance(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - struct obd_device_target *target = &obd->u.obt; - - LASSERT(obd != NULL); - LASSERT(target->obt_magic == OBT_MAGIC); - *eof = 1; - return snprintf(page, count, "%u\n", obd->u.obt.obt_instance); -} -EXPORT_SYMBOL(lprocfs_target_rd_instance); -#endif #endif /* LPROCFS*/ diff --git a/lustre/ptlrpc/lproc_ptlrpc.c b/lustre/ptlrpc/lproc_ptlrpc.c index fe6491a1..720d580 100644 --- a/lustre/ptlrpc/lproc_ptlrpc.c +++ b/lustre/ptlrpc/lproc_ptlrpc.c @@ -1180,49 +1180,6 @@ void ptlrpc_lprocfs_unregister_obd(struct obd_device *obd) } EXPORT_SYMBOL(ptlrpc_lprocfs_unregister_obd); -#define BUFLEN (UUID_MAX + 5) - -int lprocfs_wr_evict_client(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - struct obd_device *obd = data; - char *kbuf; - char *tmpbuf; - - OBD_ALLOC(kbuf, BUFLEN); - if (kbuf == NULL) - return -ENOMEM; - - /* - * OBD_ALLOC() will zero kbuf, but we only copy BUFLEN - 1 - * bytes into kbuf, to ensure that the string is NUL-terminated. - * UUID_MAX should include a trailing NUL already. - */ - if (copy_from_user(kbuf, buffer, - min_t(unsigned long, BUFLEN - 1, count))) { - count = -EFAULT; - goto out; - } - tmpbuf = cfs_firststr(kbuf, min_t(unsigned long, BUFLEN - 1, count)); - class_incref(obd, __FUNCTION__, current); - - if (strncmp(tmpbuf, "nid:", 4) == 0) - obd_export_evict_by_nid(obd, tmpbuf + 4); - else if (strncmp(tmpbuf, "uuid:", 5) == 0) - obd_export_evict_by_uuid(obd, tmpbuf + 5); - else - obd_export_evict_by_uuid(obd, tmpbuf); - - class_decref(obd, __FUNCTION__, current); - -out: - OBD_FREE(kbuf, BUFLEN); - return count; -} -EXPORT_SYMBOL(lprocfs_wr_evict_client); - -#undef BUFLEN - #ifndef HAVE_ONLY_PROCFS_SEQ int lprocfs_wr_ping(struct file *file, const char *buffer, unsigned long count, void *data) -- 1.8.3.1