drbd_proc.c revision b411b3637fa71fce9cf2acf0639009500f5892fe
1b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner/*
2b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   drbd_proc.c
3b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
4b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
5b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
6b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   Copyright (C) 2001-2008, LINBIT Information Technologies GmbH.
7b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>.
8b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
9b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
10b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   drbd is free software; you can redistribute it and/or modify
11b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   it under the terms of the GNU General Public License as published by
12b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   the Free Software Foundation; either version 2, or (at your option)
13b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   any later version.
14b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
15b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   drbd is distributed in the hope that it will be useful,
16b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   but WITHOUT ANY WARRANTY; without even the implied warranty of
17b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   GNU General Public License for more details.
19b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
20b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   You should have received a copy of the GNU General Public License
21b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   along with drbd; see the file COPYING.  If not, write to
22b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
24b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner */
25b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
26b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/autoconf.h>
27b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/module.h>
28b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
29b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <asm/uaccess.h>
30b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/fs.h>
31b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/file.h>
32b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/slab.h>
33b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/proc_fs.h>
34b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/seq_file.h>
35b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/drbd.h>
36b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include "drbd_int.h"
37b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
38b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_proc_open(struct inode *inode, struct file *file);
39b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
40b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
41b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstruct proc_dir_entry *drbd_proc;
42b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstruct file_operations drbd_proc_fops = {
43b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	.owner		= THIS_MODULE,
44b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	.open		= drbd_proc_open,
45b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	.read		= seq_read,
46b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	.llseek		= seq_lseek,
47b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	.release	= single_release,
48b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner};
49b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
50b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
51b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner/*lge
52b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * progress bars shamelessly adapted from driver/md/md.c
53b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * output looks like
54b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner *	[=====>..............] 33.5% (23456/123456)
55b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner *	finish: 2:20:20 speed: 6,345 (6,456) K/sec
56b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner */
57b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq)
58b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
59b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	unsigned long db, dt, dbdt, rt, rs_left;
60b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	unsigned int res;
61b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int i, x, y;
62b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
63b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	drbd_get_syncer_progress(mdev, &rs_left, &res);
64b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
65b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	x = res/50;
66b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	y = 20-x;
67b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	seq_printf(seq, "\t[");
68b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	for (i = 1; i < x; i++)
69b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		seq_printf(seq, "=");
70b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	seq_printf(seq, ">");
71b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	for (i = 0; i < y; i++)
72b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		seq_printf(seq, ".");
73b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	seq_printf(seq, "] ");
74b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
75b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	seq_printf(seq, "sync'ed:%3u.%u%% ", res / 10, res % 10);
76b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* if more than 1 GB display in MB */
77b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (mdev->rs_total > 0x100000L)
78b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		seq_printf(seq, "(%lu/%lu)M\n\t",
79b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			    (unsigned long) Bit2KB(rs_left >> 10),
80b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			    (unsigned long) Bit2KB(mdev->rs_total >> 10));
81b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	else
82b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		seq_printf(seq, "(%lu/%lu)K\n\t",
83b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			    (unsigned long) Bit2KB(rs_left),
84b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			    (unsigned long) Bit2KB(mdev->rs_total));
85b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
86b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* see drivers/md/md.c
87b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * We do not want to overflow, so the order of operands and
88b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * the * 100 / 100 trick are important. We do a +1 to be
89b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * safe against division by zero. We only estimate anyway.
90b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 *
91b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * dt: time from mark until now
92b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * db: blocks written from mark until now
93b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * rt: remaining time
94b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 */
95b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	dt = (jiffies - mdev->rs_mark_time) / HZ;
96b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
97b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (dt > 20) {
98b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		/* if we made no update to rs_mark_time for too long,
99b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		 * we are stalled. show that. */
100b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		seq_printf(seq, "stalled\n");
101b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		return;
102b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
103b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
104b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (!dt)
105b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dt++;
106b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	db = mdev->rs_mark_left - rs_left;
107b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	rt = (dt * (rs_left / (db/100+1)))/100; /* seconds */
108b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
109b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	seq_printf(seq, "finish: %lu:%02lu:%02lu",
110b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		rt / 3600, (rt % 3600) / 60, rt % 60);
111b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
112b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* current speed average over (SYNC_MARKS * SYNC_MARK_STEP) jiffies */
113b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	dbdt = Bit2KB(db/dt);
114b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (dbdt > 1000)
115b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		seq_printf(seq, " speed: %ld,%03ld",
116b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			dbdt/1000, dbdt % 1000);
117b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	else
118b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		seq_printf(seq, " speed: %ld", dbdt);
119b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
120b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/* mean speed since syncer started
121b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 * we do account for PausedSync periods */
122b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	dt = (jiffies - mdev->rs_start - mdev->rs_paused) / HZ;
123b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (dt <= 0)
124b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		dt = 1;
125b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	db = mdev->rs_total - rs_left;
126b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	dbdt = Bit2KB(db/dt);
127b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	if (dbdt > 1000)
128b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		seq_printf(seq, " (%ld,%03ld)",
129b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			dbdt/1000, dbdt % 1000);
130b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	else
131b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		seq_printf(seq, " (%ld)", dbdt);
132b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
133b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	seq_printf(seq, " K/sec\n");
134b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
135b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
136b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic void resync_dump_detail(struct seq_file *seq, struct lc_element *e)
137b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
138b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct bm_extent *bme = lc_entry(e, struct bm_extent, lce);
139b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
140b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	seq_printf(seq, "%5d %s %s\n", bme->rs_left,
141b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		   bme->flags & BME_NO_WRITES ? "NO_WRITES" : "---------",
142b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		   bme->flags & BME_LOCKED ? "LOCKED" : "------"
143b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		   );
144b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
145b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
146b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_seq_show(struct seq_file *seq, void *v)
147b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
148b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	int i, hole = 0;
149b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	const char *sn;
150b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	struct drbd_conf *mdev;
151b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
152b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	static char write_ordering_chars[] = {
153b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		[WO_none] = 'n',
154b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		[WO_drain_io] = 'd',
155b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		[WO_bdev_flush] = 'f',
156b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		[WO_bio_barrier] = 'b',
157b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	};
158b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
159b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	seq_printf(seq, "version: " REL_VERSION " (api:%d/proto:%d-%d)\n%s\n",
160b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		   API_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX, drbd_buildtag());
161b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
162b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	/*
163b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	  cs .. connection state
164b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	  ro .. node role (local/remote)
165b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	  ds .. disk state (local/remote)
166b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	     protocol
167b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	     various flags
168b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	  ns .. network send
169b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	  nr .. network receive
170b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	  dw .. disk write
171b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	  dr .. disk read
172b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	  al .. activity log write count
173b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	  bm .. bitmap update write count
174b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	  pe .. pending (waiting for ack or data reply)
175b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	  ua .. unack'd (still need to send ack or data reply)
176b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	  ap .. application requests accepted, but not yet completed
177b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	  ep .. number of epochs currently "on the fly", P_BARRIER_ACK pending
178b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	  wo .. write ordering mode currently in use
179b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	 oos .. known out-of-sync kB
180b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	*/
181b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
182b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	for (i = 0; i < minor_count; i++) {
183b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		mdev = minor_to_mdev(i);
184b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (!mdev) {
185b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			hole = 1;
186b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			continue;
187b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
188b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (hole) {
189b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			hole = 0;
190b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			seq_printf(seq, "\n");
191b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
192b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
193b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		sn = drbd_conn_str(mdev->state.conn);
194b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
195b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (mdev->state.conn == C_STANDALONE &&
196b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		    mdev->state.disk == D_DISKLESS &&
197b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		    mdev->state.role == R_SECONDARY) {
198b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			seq_printf(seq, "%2d: cs:Unconfigured\n", i);
199b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		} else {
200b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			seq_printf(seq,
201b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   "%2d: cs:%s ro:%s/%s ds:%s/%s %c %c%c%c%c%c\n"
202b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   "    ns:%u nr:%u dw:%u dr:%u al:%u bm:%u "
203b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   "lo:%d pe:%d ua:%d ap:%d ep:%d wo:%c",
204b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   i, sn,
205b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   drbd_role_str(mdev->state.role),
206b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   drbd_role_str(mdev->state.peer),
207b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   drbd_disk_str(mdev->state.disk),
208b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   drbd_disk_str(mdev->state.pdsk),
209b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   (mdev->net_conf == NULL ? ' ' :
210b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			    (mdev->net_conf->wire_protocol - DRBD_PROT_A+'A')),
211b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   mdev->state.susp ? 's' : 'r',
212b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   mdev->state.aftr_isp ? 'a' : '-',
213b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   mdev->state.peer_isp ? 'p' : '-',
214b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   mdev->state.user_isp ? 'u' : '-',
215b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   mdev->congestion_reason ?: '-',
216b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   mdev->send_cnt/2,
217b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   mdev->recv_cnt/2,
218b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   mdev->writ_cnt/2,
219b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   mdev->read_cnt/2,
220b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   mdev->al_writ_cnt,
221b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   mdev->bm_writ_cnt,
222b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   atomic_read(&mdev->local_cnt),
223b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   atomic_read(&mdev->ap_pending_cnt) +
224b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   atomic_read(&mdev->rs_pending_cnt),
225b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   atomic_read(&mdev->unacked_cnt),
226b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   atomic_read(&mdev->ap_bio_cnt),
227b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   mdev->epochs,
228b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			   write_ordering_chars[mdev->write_ordering]
229b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			);
230b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			seq_printf(seq, " oos:%lu\n",
231b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				   Bit2KB(drbd_bm_total_weight(mdev)));
232b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
233b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (mdev->state.conn == C_SYNC_SOURCE ||
234b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		    mdev->state.conn == C_SYNC_TARGET)
235b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			drbd_syncer_progress(mdev, seq);
236b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
237b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (mdev->state.conn == C_VERIFY_S || mdev->state.conn == C_VERIFY_T)
238b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			seq_printf(seq, "\t%3d%%      %lu/%lu\n",
239b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				   (int)((mdev->rs_total-mdev->ov_left) /
240b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner					 (mdev->rs_total/100+1)),
241b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				   mdev->rs_total - mdev->ov_left,
242b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				   mdev->rs_total);
243b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
244b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (proc_details >= 1 && get_ldev_if_state(mdev, D_FAILED)) {
245b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			lc_seq_printf_stats(seq, mdev->resync);
246b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			lc_seq_printf_stats(seq, mdev->act_log);
247b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			put_ldev(mdev);
248b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
249b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
250b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		if (proc_details >= 2) {
251b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			if (mdev->resync) {
252b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner				lc_seq_dump_details(seq, mdev->resync, "rs_left",
253b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner					resync_dump_detail);
254b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner			}
255b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner		}
256b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	}
257b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
258b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return 0;
259b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
260b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
261b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_proc_open(struct inode *inode, struct file *file)
262b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{
263b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner	return single_open(file, drbd_seq_show, PDE(inode)->data);
264b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}
265b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner
266b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner/* PROC FS stuff end */
267