Linux Audio

Check our new training course

Embedded Linux training

Mar 31-Apr 8, 2025
Register
Loading...
v3.1
  1/*
  2   drbd_proc.c
  3
  4   This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
  5
  6   Copyright (C) 2001-2008, LINBIT Information Technologies GmbH.
  7   Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>.
  8   Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
  9
 10   drbd is free software; you can redistribute it and/or modify
 11   it under the terms of the GNU General Public License as published by
 12   the Free Software Foundation; either version 2, or (at your option)
 13   any later version.
 14
 15   drbd is distributed in the hope that it will be useful,
 16   but WITHOUT ANY WARRANTY; without even the implied warranty of
 17   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 18   GNU General Public License for more details.
 19
 20   You should have received a copy of the GNU General Public License
 21   along with drbd; see the file COPYING.  If not, write to
 22   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 23
 24 */
 25
 26#include <linux/module.h>
 27
 28#include <asm/uaccess.h>
 29#include <linux/fs.h>
 30#include <linux/file.h>
 31#include <linux/proc_fs.h>
 32#include <linux/seq_file.h>
 33#include <linux/drbd.h>
 34#include "drbd_int.h"
 35
 36static int drbd_proc_open(struct inode *inode, struct file *file);
 37static int drbd_proc_release(struct inode *inode, struct file *file);
 38
 39
 40struct proc_dir_entry *drbd_proc;
 41const struct file_operations drbd_proc_fops = {
 42	.owner		= THIS_MODULE,
 43	.open		= drbd_proc_open,
 44	.read		= seq_read,
 45	.llseek		= seq_lseek,
 46	.release	= drbd_proc_release,
 47};
 48
 49void seq_printf_with_thousands_grouping(struct seq_file *seq, long v)
 50{
 51	/* v is in kB/sec. We don't expect TiByte/sec yet. */
 52	if (unlikely(v >= 1000000)) {
 53		/* cool: > GiByte/s */
 54		seq_printf(seq, "%ld,", v / 1000000);
 55		v /= 1000000;
 56		seq_printf(seq, "%03ld,%03ld", v/1000, v % 1000);
 57	} else if (likely(v >= 1000))
 58		seq_printf(seq, "%ld,%03ld", v/1000, v % 1000);
 59	else
 60		seq_printf(seq, "%ld", v);
 61}
 62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 63/*lge
 64 * progress bars shamelessly adapted from driver/md/md.c
 65 * output looks like
 66 *	[=====>..............] 33.5% (23456/123456)
 67 *	finish: 2:20:20 speed: 6,345 (6,456) K/sec
 68 */
 69static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq)
 
 70{
 71	unsigned long db, dt, dbdt, rt, rs_left;
 72	unsigned int res;
 73	int i, x, y;
 74	int stalled = 0;
 75
 76	drbd_get_syncer_progress(mdev, &rs_left, &res);
 77
 78	x = res/50;
 79	y = 20-x;
 80	seq_printf(seq, "\t[");
 81	for (i = 1; i < x; i++)
 82		seq_printf(seq, "=");
 83	seq_printf(seq, ">");
 84	for (i = 0; i < y; i++)
 85		seq_printf(seq, ".");
 86	seq_printf(seq, "] ");
 87
 88	if (mdev->state.conn == C_VERIFY_S || mdev->state.conn == C_VERIFY_T)
 89		seq_printf(seq, "verified:");
 90	else
 91		seq_printf(seq, "sync'ed:");
 92	seq_printf(seq, "%3u.%u%% ", res / 10, res % 10);
 93
 94	/* if more than a few GB, display in MB */
 95	if (mdev->rs_total > (4UL << (30 - BM_BLOCK_SHIFT)))
 96		seq_printf(seq, "(%lu/%lu)M",
 97			    (unsigned long) Bit2KB(rs_left >> 10),
 98			    (unsigned long) Bit2KB(mdev->rs_total >> 10));
 99	else
100		seq_printf(seq, "(%lu/%lu)K\n\t",
101			    (unsigned long) Bit2KB(rs_left),
102			    (unsigned long) Bit2KB(mdev->rs_total));
 
 
103
104	/* see drivers/md/md.c
105	 * We do not want to overflow, so the order of operands and
106	 * the * 100 / 100 trick are important. We do a +1 to be
107	 * safe against division by zero. We only estimate anyway.
108	 *
109	 * dt: time from mark until now
110	 * db: blocks written from mark until now
111	 * rt: remaining time
112	 */
113	/* Rolling marks. last_mark+1 may just now be modified.  last_mark+2 is
114	 * at least (DRBD_SYNC_MARKS-2)*DRBD_SYNC_MARK_STEP old, and has at
115	 * least DRBD_SYNC_MARK_STEP time before it will be modified. */
116	/* ------------------------ ~18s average ------------------------ */
117	i = (mdev->rs_last_mark + 2) % DRBD_SYNC_MARKS;
118	dt = (jiffies - mdev->rs_mark_time[i]) / HZ;
119	if (dt > (DRBD_SYNC_MARK_STEP * DRBD_SYNC_MARKS))
120		stalled = 1;
121
122	if (!dt)
123		dt++;
124	db = mdev->rs_mark_left[i] - rs_left;
125	rt = (dt * (rs_left / (db/100+1)))/100; /* seconds */
126
127	seq_printf(seq, "finish: %lu:%02lu:%02lu",
128		rt / 3600, (rt % 3600) / 60, rt % 60);
129
130	dbdt = Bit2KB(db/dt);
131	seq_printf(seq, " speed: ");
132	seq_printf_with_thousands_grouping(seq, dbdt);
133	seq_printf(seq, " (");
134	/* ------------------------- ~3s average ------------------------ */
135	if (proc_details >= 1) {
136		/* this is what drbd_rs_should_slow_down() uses */
137		i = (mdev->rs_last_mark + DRBD_SYNC_MARKS-1) % DRBD_SYNC_MARKS;
138		dt = (jiffies - mdev->rs_mark_time[i]) / HZ;
139		if (!dt)
140			dt++;
141		db = mdev->rs_mark_left[i] - rs_left;
142		dbdt = Bit2KB(db/dt);
143		seq_printf_with_thousands_grouping(seq, dbdt);
144		seq_printf(seq, " -- ");
145	}
146
147	/* --------------------- long term average ---------------------- */
148	/* mean speed since syncer started
149	 * we do account for PausedSync periods */
150	dt = (jiffies - mdev->rs_start - mdev->rs_paused) / HZ;
151	if (dt == 0)
152		dt = 1;
153	db = mdev->rs_total - rs_left;
154	dbdt = Bit2KB(db/dt);
155	seq_printf_with_thousands_grouping(seq, dbdt);
156	seq_printf(seq, ")");
157
158	if (mdev->state.conn == C_SYNC_TARGET ||
159	    mdev->state.conn == C_VERIFY_S) {
160		seq_printf(seq, " want: ");
161		seq_printf_with_thousands_grouping(seq, mdev->c_sync_rate);
162	}
163	seq_printf(seq, " K/sec%s\n", stalled ? " (stalled)" : "");
164
165	if (proc_details >= 1) {
166		/* 64 bit:
167		 * we convert to sectors in the display below. */
168		unsigned long bm_bits = drbd_bm_bits(mdev);
169		unsigned long bit_pos;
170		if (mdev->state.conn == C_VERIFY_S ||
171		    mdev->state.conn == C_VERIFY_T)
172			bit_pos = bm_bits - mdev->ov_left;
173		else
174			bit_pos = mdev->bm_resync_fo;
 
 
 
175		/* Total sectors may be slightly off for oddly
176		 * sized devices. So what. */
177		seq_printf(seq,
178			"\t%3d%% sector pos: %llu/%llu\n",
179			(int)(bit_pos / (bm_bits/100+1)),
180			(unsigned long long)bit_pos * BM_SECT_PER_BIT,
181			(unsigned long long)bm_bits * BM_SECT_PER_BIT);
 
 
 
182	}
183}
184
185static void resync_dump_detail(struct seq_file *seq, struct lc_element *e)
186{
187	struct bm_extent *bme = lc_entry(e, struct bm_extent, lce);
188
189	seq_printf(seq, "%5d %s %s\n", bme->rs_left,
190		   bme->flags & BME_NO_WRITES ? "NO_WRITES" : "---------",
191		   bme->flags & BME_LOCKED ? "LOCKED" : "------"
192		   );
193}
194
195static int drbd_seq_show(struct seq_file *seq, void *v)
196{
197	int i, hole = 0;
198	const char *sn;
199	struct drbd_conf *mdev;
 
 
 
200
201	static char write_ordering_chars[] = {
202		[WO_none] = 'n',
203		[WO_drain_io] = 'd',
204		[WO_bdev_flush] = 'f',
205	};
206
207	seq_printf(seq, "version: " REL_VERSION " (api:%d/proto:%d-%d)\n%s\n",
208		   API_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX, drbd_buildtag());
209
210	/*
211	  cs .. connection state
212	  ro .. node role (local/remote)
213	  ds .. disk state (local/remote)
214	     protocol
215	     various flags
216	  ns .. network send
217	  nr .. network receive
218	  dw .. disk write
219	  dr .. disk read
220	  al .. activity log write count
221	  bm .. bitmap update write count
222	  pe .. pending (waiting for ack or data reply)
223	  ua .. unack'd (still need to send ack or data reply)
224	  ap .. application requests accepted, but not yet completed
225	  ep .. number of epochs currently "on the fly", P_BARRIER_ACK pending
226	  wo .. write ordering mode currently in use
227	 oos .. known out-of-sync kB
228	*/
229
230	for (i = 0; i < minor_count; i++) {
231		mdev = minor_to_mdev(i);
232		if (!mdev) {
233			hole = 1;
234			continue;
235		}
236		if (hole) {
237			hole = 0;
238			seq_printf(seq, "\n");
239		}
240
241		sn = drbd_conn_str(mdev->state.conn);
242
243		if (mdev->state.conn == C_STANDALONE &&
244		    mdev->state.disk == D_DISKLESS &&
245		    mdev->state.role == R_SECONDARY) {
246			seq_printf(seq, "%2d: cs:Unconfigured\n", i);
247		} else {
 
 
 
 
 
248			seq_printf(seq,
249			   "%2d: cs:%s ro:%s/%s ds:%s/%s %c %c%c%c%c%c%c\n"
250			   "    ns:%u nr:%u dw:%u dr:%u al:%u bm:%u "
251			   "lo:%d pe:%d ua:%d ap:%d ep:%d wo:%c",
252			   i, sn,
253			   drbd_role_str(mdev->state.role),
254			   drbd_role_str(mdev->state.peer),
255			   drbd_disk_str(mdev->state.disk),
256			   drbd_disk_str(mdev->state.pdsk),
257			   (mdev->net_conf == NULL ? ' ' :
258			    (mdev->net_conf->wire_protocol - DRBD_PROT_A+'A')),
259			   is_susp(mdev->state) ? 's' : 'r',
260			   mdev->state.aftr_isp ? 'a' : '-',
261			   mdev->state.peer_isp ? 'p' : '-',
262			   mdev->state.user_isp ? 'u' : '-',
263			   mdev->congestion_reason ?: '-',
264			   test_bit(AL_SUSPENDED, &mdev->flags) ? 's' : '-',
265			   mdev->send_cnt/2,
266			   mdev->recv_cnt/2,
267			   mdev->writ_cnt/2,
268			   mdev->read_cnt/2,
269			   mdev->al_writ_cnt,
270			   mdev->bm_writ_cnt,
271			   atomic_read(&mdev->local_cnt),
272			   atomic_read(&mdev->ap_pending_cnt) +
273			   atomic_read(&mdev->rs_pending_cnt),
274			   atomic_read(&mdev->unacked_cnt),
275			   atomic_read(&mdev->ap_bio_cnt),
276			   mdev->epochs,
277			   write_ordering_chars[mdev->write_ordering]
278			);
279			seq_printf(seq, " oos:%llu\n",
280				   Bit2KB((unsigned long long)
281					   drbd_bm_total_weight(mdev)));
282		}
283		if (mdev->state.conn == C_SYNC_SOURCE ||
284		    mdev->state.conn == C_SYNC_TARGET ||
285		    mdev->state.conn == C_VERIFY_S ||
286		    mdev->state.conn == C_VERIFY_T)
287			drbd_syncer_progress(mdev, seq);
288
289		if (proc_details >= 1 && get_ldev_if_state(mdev, D_FAILED)) {
290			lc_seq_printf_stats(seq, mdev->resync);
291			lc_seq_printf_stats(seq, mdev->act_log);
292			put_ldev(mdev);
293		}
294
295		if (proc_details >= 2) {
296			if (mdev->resync) {
297				lc_seq_dump_details(seq, mdev->resync, "rs_left",
298					resync_dump_detail);
299			}
300		}
301	}
 
302
303	return 0;
304}
305
306static int drbd_proc_open(struct inode *inode, struct file *file)
307{
308	if (try_module_get(THIS_MODULE))
309		return single_open(file, drbd_seq_show, PDE(inode)->data);
 
 
 
 
 
 
310	return -ENODEV;
311}
312
313static int drbd_proc_release(struct inode *inode, struct file *file)
314{
315	module_put(THIS_MODULE);
316	return single_release(inode, file);
317}
318
319/* PROC FS stuff end */
v4.10.11
  1/*
  2   drbd_proc.c
  3
  4   This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
  5
  6   Copyright (C) 2001-2008, LINBIT Information Technologies GmbH.
  7   Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>.
  8   Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
  9
 10   drbd is free software; you can redistribute it and/or modify
 11   it under the terms of the GNU General Public License as published by
 12   the Free Software Foundation; either version 2, or (at your option)
 13   any later version.
 14
 15   drbd is distributed in the hope that it will be useful,
 16   but WITHOUT ANY WARRANTY; without even the implied warranty of
 17   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 18   GNU General Public License for more details.
 19
 20   You should have received a copy of the GNU General Public License
 21   along with drbd; see the file COPYING.  If not, write to
 22   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 23
 24 */
 25
 26#include <linux/module.h>
 27
 28#include <linux/uaccess.h>
 29#include <linux/fs.h>
 30#include <linux/file.h>
 31#include <linux/proc_fs.h>
 32#include <linux/seq_file.h>
 33#include <linux/drbd.h>
 34#include "drbd_int.h"
 35
 36static int drbd_proc_open(struct inode *inode, struct file *file);
 37static int drbd_proc_release(struct inode *inode, struct file *file);
 38
 39
 40struct proc_dir_entry *drbd_proc;
 41const struct file_operations drbd_proc_fops = {
 42	.owner		= THIS_MODULE,
 43	.open		= drbd_proc_open,
 44	.read		= seq_read,
 45	.llseek		= seq_lseek,
 46	.release	= drbd_proc_release,
 47};
 48
 49static void seq_printf_with_thousands_grouping(struct seq_file *seq, long v)
 50{
 51	/* v is in kB/sec. We don't expect TiByte/sec yet. */
 52	if (unlikely(v >= 1000000)) {
 53		/* cool: > GiByte/s */
 54		seq_printf(seq, "%ld,", v / 1000000);
 55		v %= 1000000;
 56		seq_printf(seq, "%03ld,%03ld", v/1000, v % 1000);
 57	} else if (likely(v >= 1000))
 58		seq_printf(seq, "%ld,%03ld", v/1000, v % 1000);
 59	else
 60		seq_printf(seq, "%ld", v);
 61}
 62
 63static void drbd_get_syncer_progress(struct drbd_device *device,
 64		union drbd_dev_state state, unsigned long *rs_total,
 65		unsigned long *bits_left, unsigned int *per_mil_done)
 66{
 67	/* this is to break it at compile time when we change that, in case we
 68	 * want to support more than (1<<32) bits on a 32bit arch. */
 69	typecheck(unsigned long, device->rs_total);
 70	*rs_total = device->rs_total;
 71
 72	/* note: both rs_total and rs_left are in bits, i.e. in
 73	 * units of BM_BLOCK_SIZE.
 74	 * for the percentage, we don't care. */
 75
 76	if (state.conn == C_VERIFY_S || state.conn == C_VERIFY_T)
 77		*bits_left = device->ov_left;
 78	else
 79		*bits_left = drbd_bm_total_weight(device) - device->rs_failed;
 80	/* >> 10 to prevent overflow,
 81	 * +1 to prevent division by zero */
 82	if (*bits_left > *rs_total) {
 83		/* D'oh. Maybe a logic bug somewhere.  More likely just a race
 84		 * between state change and reset of rs_total.
 85		 */
 86		*bits_left = *rs_total;
 87		*per_mil_done = *rs_total ? 0 : 1000;
 88	} else {
 89		/* Make sure the division happens in long context.
 90		 * We allow up to one petabyte storage right now,
 91		 * at a granularity of 4k per bit that is 2**38 bits.
 92		 * After shift right and multiplication by 1000,
 93		 * this should still fit easily into a 32bit long,
 94		 * so we don't need a 64bit division on 32bit arch.
 95		 * Note: currently we don't support such large bitmaps on 32bit
 96		 * arch anyways, but no harm done to be prepared for it here.
 97		 */
 98		unsigned int shift = *rs_total > UINT_MAX ? 16 : 10;
 99		unsigned long left = *bits_left >> shift;
100		unsigned long total = 1UL + (*rs_total >> shift);
101		unsigned long tmp = 1000UL - left * 1000UL/total;
102		*per_mil_done = tmp;
103	}
104}
105
106
107/*lge
108 * progress bars shamelessly adapted from driver/md/md.c
109 * output looks like
110 *	[=====>..............] 33.5% (23456/123456)
111 *	finish: 2:20:20 speed: 6,345 (6,456) K/sec
112 */
113static void drbd_syncer_progress(struct drbd_device *device, struct seq_file *seq,
114		union drbd_dev_state state)
115{
116	unsigned long db, dt, dbdt, rt, rs_total, rs_left;
117	unsigned int res;
118	int i, x, y;
119	int stalled = 0;
120
121	drbd_get_syncer_progress(device, state, &rs_total, &rs_left, &res);
122
123	x = res/50;
124	y = 20-x;
125	seq_puts(seq, "\t[");
126	for (i = 1; i < x; i++)
127		seq_putc(seq, '=');
128	seq_putc(seq, '>');
129	for (i = 0; i < y; i++)
130		seq_printf(seq, ".");
131	seq_puts(seq, "] ");
132
133	if (state.conn == C_VERIFY_S || state.conn == C_VERIFY_T)
134		seq_puts(seq, "verified:");
135	else
136		seq_puts(seq, "sync'ed:");
137	seq_printf(seq, "%3u.%u%% ", res / 10, res % 10);
138
139	/* if more than a few GB, display in MB */
140	if (rs_total > (4UL << (30 - BM_BLOCK_SHIFT)))
141		seq_printf(seq, "(%lu/%lu)M",
142			    (unsigned long) Bit2KB(rs_left >> 10),
143			    (unsigned long) Bit2KB(rs_total >> 10));
144	else
145		seq_printf(seq, "(%lu/%lu)K",
146			    (unsigned long) Bit2KB(rs_left),
147			    (unsigned long) Bit2KB(rs_total));
148
149	seq_puts(seq, "\n\t");
150
151	/* see drivers/md/md.c
152	 * We do not want to overflow, so the order of operands and
153	 * the * 100 / 100 trick are important. We do a +1 to be
154	 * safe against division by zero. We only estimate anyway.
155	 *
156	 * dt: time from mark until now
157	 * db: blocks written from mark until now
158	 * rt: remaining time
159	 */
160	/* Rolling marks. last_mark+1 may just now be modified.  last_mark+2 is
161	 * at least (DRBD_SYNC_MARKS-2)*DRBD_SYNC_MARK_STEP old, and has at
162	 * least DRBD_SYNC_MARK_STEP time before it will be modified. */
163	/* ------------------------ ~18s average ------------------------ */
164	i = (device->rs_last_mark + 2) % DRBD_SYNC_MARKS;
165	dt = (jiffies - device->rs_mark_time[i]) / HZ;
166	if (dt > 180)
167		stalled = 1;
168
169	if (!dt)
170		dt++;
171	db = device->rs_mark_left[i] - rs_left;
172	rt = (dt * (rs_left / (db/100+1)))/100; /* seconds */
173
174	seq_printf(seq, "finish: %lu:%02lu:%02lu",
175		rt / 3600, (rt % 3600) / 60, rt % 60);
176
177	dbdt = Bit2KB(db/dt);
178	seq_puts(seq, " speed: ");
179	seq_printf_with_thousands_grouping(seq, dbdt);
180	seq_puts(seq, " (");
181	/* ------------------------- ~3s average ------------------------ */
182	if (proc_details >= 1) {
183		/* this is what drbd_rs_should_slow_down() uses */
184		i = (device->rs_last_mark + DRBD_SYNC_MARKS-1) % DRBD_SYNC_MARKS;
185		dt = (jiffies - device->rs_mark_time[i]) / HZ;
186		if (!dt)
187			dt++;
188		db = device->rs_mark_left[i] - rs_left;
189		dbdt = Bit2KB(db/dt);
190		seq_printf_with_thousands_grouping(seq, dbdt);
191		seq_puts(seq, " -- ");
192	}
193
194	/* --------------------- long term average ---------------------- */
195	/* mean speed since syncer started
196	 * we do account for PausedSync periods */
197	dt = (jiffies - device->rs_start - device->rs_paused) / HZ;
198	if (dt == 0)
199		dt = 1;
200	db = rs_total - rs_left;
201	dbdt = Bit2KB(db/dt);
202	seq_printf_with_thousands_grouping(seq, dbdt);
203	seq_putc(seq, ')');
204
205	if (state.conn == C_SYNC_TARGET ||
206	    state.conn == C_VERIFY_S) {
207		seq_puts(seq, " want: ");
208		seq_printf_with_thousands_grouping(seq, device->c_sync_rate);
209	}
210	seq_printf(seq, " K/sec%s\n", stalled ? " (stalled)" : "");
211
212	if (proc_details >= 1) {
213		/* 64 bit:
214		 * we convert to sectors in the display below. */
215		unsigned long bm_bits = drbd_bm_bits(device);
216		unsigned long bit_pos;
217		unsigned long long stop_sector = 0;
218		if (state.conn == C_VERIFY_S ||
219		    state.conn == C_VERIFY_T) {
220			bit_pos = bm_bits - device->ov_left;
221			if (verify_can_do_stop_sector(device))
222				stop_sector = device->ov_stop_sector;
223		} else
224			bit_pos = device->bm_resync_fo;
225		/* Total sectors may be slightly off for oddly
226		 * sized devices. So what. */
227		seq_printf(seq,
228			"\t%3d%% sector pos: %llu/%llu",
229			(int)(bit_pos / (bm_bits/100+1)),
230			(unsigned long long)bit_pos * BM_SECT_PER_BIT,
231			(unsigned long long)bm_bits * BM_SECT_PER_BIT);
232		if (stop_sector != 0 && stop_sector != ULLONG_MAX)
233			seq_printf(seq, " stop sector: %llu", stop_sector);
234		seq_putc(seq, '\n');
235	}
236}
237
 
 
 
 
 
 
 
 
 
 
238static int drbd_seq_show(struct seq_file *seq, void *v)
239{
240	int i, prev_i = -1;
241	const char *sn;
242	struct drbd_device *device;
243	struct net_conf *nc;
244	union drbd_dev_state state;
245	char wp;
246
247	static char write_ordering_chars[] = {
248		[WO_NONE] = 'n',
249		[WO_DRAIN_IO] = 'd',
250		[WO_BDEV_FLUSH] = 'f',
251	};
252
253	seq_printf(seq, "version: " REL_VERSION " (api:%d/proto:%d-%d)\n%s\n",
254		   API_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX, drbd_buildtag());
255
256	/*
257	  cs .. connection state
258	  ro .. node role (local/remote)
259	  ds .. disk state (local/remote)
260	     protocol
261	     various flags
262	  ns .. network send
263	  nr .. network receive
264	  dw .. disk write
265	  dr .. disk read
266	  al .. activity log write count
267	  bm .. bitmap update write count
268	  pe .. pending (waiting for ack or data reply)
269	  ua .. unack'd (still need to send ack or data reply)
270	  ap .. application requests accepted, but not yet completed
271	  ep .. number of epochs currently "on the fly", P_BARRIER_ACK pending
272	  wo .. write ordering mode currently in use
273	 oos .. known out-of-sync kB
274	*/
275
276	rcu_read_lock();
277	idr_for_each_entry(&drbd_devices, device, i) {
278		if (prev_i != i - 1)
279			seq_putc(seq, '\n');
280		prev_i = i;
281
282		state = device->state;
283		sn = drbd_conn_str(state.conn);
284
285		if (state.conn == C_STANDALONE &&
286		    state.disk == D_DISKLESS &&
287		    state.role == R_SECONDARY) {
 
 
 
 
288			seq_printf(seq, "%2d: cs:Unconfigured\n", i);
289		} else {
290			/* reset device->congestion_reason */
291			bdi_rw_congested(&device->rq_queue->backing_dev_info);
292
293			nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
294			wp = nc ? nc->wire_protocol - DRBD_PROT_A + 'A' : ' ';
295			seq_printf(seq,
296			   "%2d: cs:%s ro:%s/%s ds:%s/%s %c %c%c%c%c%c%c\n"
297			   "    ns:%u nr:%u dw:%u dr:%u al:%u bm:%u "
298			   "lo:%d pe:%d ua:%d ap:%d ep:%d wo:%c",
299			   i, sn,
300			   drbd_role_str(state.role),
301			   drbd_role_str(state.peer),
302			   drbd_disk_str(state.disk),
303			   drbd_disk_str(state.pdsk),
304			   wp,
305			   drbd_suspended(device) ? 's' : 'r',
306			   state.aftr_isp ? 'a' : '-',
307			   state.peer_isp ? 'p' : '-',
308			   state.user_isp ? 'u' : '-',
309			   device->congestion_reason ?: '-',
310			   test_bit(AL_SUSPENDED, &device->flags) ? 's' : '-',
311			   device->send_cnt/2,
312			   device->recv_cnt/2,
313			   device->writ_cnt/2,
314			   device->read_cnt/2,
315			   device->al_writ_cnt,
316			   device->bm_writ_cnt,
317			   atomic_read(&device->local_cnt),
318			   atomic_read(&device->ap_pending_cnt) +
319			   atomic_read(&device->rs_pending_cnt),
320			   atomic_read(&device->unacked_cnt),
321			   atomic_read(&device->ap_bio_cnt),
322			   first_peer_device(device)->connection->epochs,
323			   write_ordering_chars[device->resource->write_ordering]
 
324			);
325			seq_printf(seq, " oos:%llu\n",
326				   Bit2KB((unsigned long long)
327					   drbd_bm_total_weight(device)));
328		}
329		if (state.conn == C_SYNC_SOURCE ||
330		    state.conn == C_SYNC_TARGET ||
331		    state.conn == C_VERIFY_S ||
332		    state.conn == C_VERIFY_T)
333			drbd_syncer_progress(device, seq, state);
334
335		if (proc_details >= 1 && get_ldev_if_state(device, D_FAILED)) {
336			lc_seq_printf_stats(seq, device->resync);
337			lc_seq_printf_stats(seq, device->act_log);
338			put_ldev(device);
339		}
340
341		if (proc_details >= 2)
342			seq_printf(seq, "\tblocked on activity log: %d\n", atomic_read(&device->ap_actlog_cnt));
 
 
 
 
343	}
344	rcu_read_unlock();
345
346	return 0;
347}
348
349static int drbd_proc_open(struct inode *inode, struct file *file)
350{
351	int err;
352
353	if (try_module_get(THIS_MODULE)) {
354		err = single_open(file, drbd_seq_show, NULL);
355		if (err)
356			module_put(THIS_MODULE);
357		return err;
358	}
359	return -ENODEV;
360}
361
362static int drbd_proc_release(struct inode *inode, struct file *file)
363{
364	module_put(THIS_MODULE);
365	return single_release(inode, file);
366}
367
368/* PROC FS stuff end */