+static int osc_destroys_in_flight_seq_show(struct seq_file *m, void *v)
+{
+ 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_max_pages_per_rpc_seq_show(m, m->private);
+}
+
+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 = ((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;
+ __u64 val;
+
+ rc = lprocfs_write_u64_helper(buffer, count, &val);
+ if (rc)
+ return rc;
+
+ /* if the max_pages is specified in bytes, convert to pages */
+ if (val >= ONE_MB_BRW_SIZE)
+ val >>= PAGE_CACHE_SHIFT;
+
+ LPROCFS_CLIMP_CHECK(dev);
+
+ chunk_mask = ~((1 << (cli->cl_chunkbits - PAGE_CACHE_SHIFT)) - 1);
+ /* max_pages_per_rpc must be chunk aligned */
+ val = (val + ~chunk_mask) & chunk_mask;
+ if (val == 0 || val > ocd->ocd_brw_size >> PAGE_CACHE_SHIFT) {
+ LPROCFS_CLIMP_EXIT(dev);
+ return -ERANGE;
+ }
+ client_obd_list_lock(&cli->cl_loi_list_lock);
+ cli->cl_max_pages_per_rpc = val;
+ client_obd_list_unlock(&cli->cl_loi_list_lock);
+
+ LPROCFS_CLIMP_EXIT(dev);
+ return count;
+}
+LPROC_SEQ_FOPS(osc_obd_max_pages_per_rpc);
+
+static int osc_unstable_stats_seq_show(struct seq_file *m, void *v)
+{
+ struct obd_device *dev = m->private;
+ struct client_obd *cli = &dev->u.cli;
+ int pages, mb;
+
+ pages = atomic_read(&cli->cl_unstable_count);
+ mb = (pages * PAGE_CACHE_SIZE) >> 20;
+
+ return seq_printf(m, "unstable_pages: %8d\n"
+ "unstable_mb: %8d\n",
+ pages, mb);
+}
+LPROC_SEQ_FOPS_RO(osc_unstable_stats);
+
+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_WO_TYPE(osc, ping);
+
+LPROC_SEQ_FOPS_RW_TYPE(osc, import);
+LPROC_SEQ_FOPS_RW_TYPE(osc, pinger_recov);
+
+struct lprocfs_seq_vars lprocfs_osc_obd_vars[] = {
+ { .name = "uuid",
+ .fops = &osc_uuid_fops },
+ { .name = "ping",
+ .fops = &osc_ping_fops,
+ .proc_mode = 0222 },
+ { .name = "connect_flags",
+ .fops = &osc_connect_flags_fops },
+ { .name = "blocksize",
+ .fops = &osc_blksize_fops },
+ { .name = "kbytestotal",
+ .fops = &osc_kbytestotal_fops },
+ { .name = "kbytesfree",
+ .fops = &osc_kbytesfree_fops },
+ { .name = "kbytesavail",
+ .fops = &osc_kbytesavail_fops },
+ { .name = "filestotal",
+ .fops = &osc_filestotal_fops },
+ { .name = "filesfree",
+ .fops = &osc_filesfree_fops },
+ { .name = "ost_server_uuid",
+ .fops = &osc_server_uuid_fops },
+ { .name = "ost_conn_uuid",
+ .fops = &osc_conn_uuid_fops },
+ { .name = "active",
+ .fops = &osc_active_fops },
+ { .name = "max_pages_per_rpc",
+ .fops = &osc_obd_max_pages_per_rpc_fops },
+ { .name = "max_rpcs_in_flight",
+ .fops = &osc_max_rpcs_in_flight_fops },
+ { .name = "destroys_in_flight",
+ .fops = &osc_destroys_in_flight_fops },
+ { .name = "max_dirty_mb",
+ .fops = &osc_max_dirty_mb_fops },
+ { .name = "osc_cached_mb",
+ .fops = &osc_cached_mb_fops },
+ { .name = "cur_dirty_bytes",
+ .fops = &osc_cur_dirty_bytes_fops },
+ { .name = "cur_grant_bytes",
+ .fops = &osc_cur_grant_bytes_fops },
+ { .name = "cur_lost_grant_bytes",
+ .fops = &osc_cur_lost_grant_bytes_fops },
+ { .name = "grant_shrink_interval",
+ .fops = &osc_grant_shrink_interval_fops },
+ { .name = "checksums",
+ .fops = &osc_checksum_fops },
+ { .name = "checksum_type",
+ .fops = &osc_checksum_type_fops },
+ { .name = "resend_count",
+ .fops = &osc_resend_count_fops },
+ { .name = "timeouts",
+ .fops = &osc_timeouts_fops },
+ { .name = "contention_seconds",
+ .fops = &osc_contention_seconds_fops },
+ { .name = "lockless_truncate",
+ .fops = &osc_lockless_truncate_fops },
+ { .name = "import",
+ .fops = &osc_import_fops },
+ { .name = "state",
+ .fops = &osc_state_fops },
+ { .name = "pinger_recov",
+ .fops = &osc_pinger_recov_fops },
+ { .name = "unstable_stats",
+ .fops = &osc_unstable_stats_fops },
+ { 0 }
+};
+
+#define pct(a,b) (b ? a * 100 / b : 0)
+
+static int osc_rpc_stats_seq_show(struct seq_file *seq, void *v)
+{
+ struct timeval now;
+ struct obd_device *dev = seq->private;
+ struct client_obd *cli = &dev->u.cli;
+ unsigned long read_tot = 0, write_tot = 0, read_cum, write_cum;
+ int i;
+
+ do_gettimeofday(&now);
+
+ client_obd_list_lock(&cli->cl_loi_list_lock);
+
+ seq_printf(seq, "snapshot_time: %lu.%lu (secs.usecs)\n",
+ now.tv_sec, now.tv_usec);
+ seq_printf(seq, "read RPCs in flight: %d\n",
+ cli->cl_r_in_flight);
+ seq_printf(seq, "write RPCs in flight: %d\n",
+ cli->cl_w_in_flight);
+ seq_printf(seq, "pending write pages: %d\n",
+ atomic_read(&cli->cl_pending_w_pages));
+ seq_printf(seq, "pending read pages: %d\n",
+ atomic_read(&cli->cl_pending_r_pages));
+
+ seq_printf(seq, "\n\t\t\tread\t\t\twrite\n");
+ seq_printf(seq, "pages per rpc rpcs %% cum %% |");
+ seq_printf(seq, " rpcs %% cum %%\n");
+
+ read_tot = lprocfs_oh_sum(&cli->cl_read_page_hist);
+ write_tot = lprocfs_oh_sum(&cli->cl_write_page_hist);
+
+ read_cum = 0;
+ write_cum = 0;
+ for (i = 0; i < OBD_HIST_MAX; i++) {
+ unsigned long r = cli->cl_read_page_hist.oh_buckets[i];
+ unsigned long w = cli->cl_write_page_hist.oh_buckets[i];
+
+ read_cum += r;
+ write_cum += w;
+ seq_printf(seq, "%d:\t\t%10lu %3lu %3lu | %10lu %3lu %3lu\n",
+ 1 << i, r, pct(r, read_tot),
+ pct(read_cum, read_tot), w,
+ pct(w, write_tot),
+ pct(write_cum, write_tot));
+ if (read_cum == read_tot && write_cum == write_tot)
+ break;
+ }
+
+ seq_printf(seq, "\n\t\t\tread\t\t\twrite\n");
+ seq_printf(seq, "rpcs in flight rpcs %% cum %% |");
+ seq_printf(seq, " rpcs %% cum %%\n");
+
+ read_tot = lprocfs_oh_sum(&cli->cl_read_rpc_hist);
+ write_tot = lprocfs_oh_sum(&cli->cl_write_rpc_hist);