Merge tag 'for-f2fs-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk...
[deliverable/linux.git] / drivers / block / drbd / drbd_proc.c
CommitLineData
b411b363
PR
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
b411b363
PR
26#include <linux/module.h>
27
28#include <asm/uaccess.h>
29#include <linux/fs.h>
30#include <linux/file.h>
b411b363
PR
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);
3da127fa 37static int drbd_proc_release(struct inode *inode, struct file *file);
b411b363
PR
38
39
40struct proc_dir_entry *drbd_proc;
7d4e9d09 41const struct file_operations drbd_proc_fops = {
b411b363
PR
42 .owner = THIS_MODULE,
43 .open = drbd_proc_open,
44 .read = seq_read,
45 .llseek = seq_lseek,
3da127fa 46 .release = drbd_proc_release,
b411b363
PR
47};
48
fbe0d91c 49static void seq_printf_with_thousands_grouping(struct seq_file *seq, long v)
439d5953
LE
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);
fc251d5c 55 v %= 1000000;
439d5953
LE
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}
b411b363 62
a5655dac
LE
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
b411b363
PR
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 */
a5655dac
LE
113static void drbd_syncer_progress(struct drbd_device *device, struct seq_file *seq,
114 union drbd_dev_state state)
b411b363 115{
a5655dac 116 unsigned long db, dt, dbdt, rt, rs_total, rs_left;
b411b363
PR
117 unsigned int res;
118 int i, x, y;
1d7734a0 119 int stalled = 0;
b411b363 120
a5655dac 121 drbd_get_syncer_progress(device, state, &rs_total, &rs_left, &res);
b411b363
PR
122
123 x = res/50;
124 y = 20-x;
125 seq_printf(seq, "\t[");
126 for (i = 1; i < x; i++)
127 seq_printf(seq, "=");
128 seq_printf(seq, ">");
129 for (i = 0; i < y; i++)
130 seq_printf(seq, ".");
131 seq_printf(seq, "] ");
132
a5655dac 133 if (state.conn == C_VERIFY_S || state.conn == C_VERIFY_T)
5f9915bb
LE
134 seq_printf(seq, "verified:");
135 else
136 seq_printf(seq, "sync'ed:");
137 seq_printf(seq, "%3u.%u%% ", res / 10, res % 10);
138
4b0715f0 139 /* if more than a few GB, display in MB */
a5655dac 140 if (rs_total > (4UL << (30 - BM_BLOCK_SHIFT)))
4b0715f0 141 seq_printf(seq, "(%lu/%lu)M",
b411b363 142 (unsigned long) Bit2KB(rs_left >> 10),
a5655dac 143 (unsigned long) Bit2KB(rs_total >> 10));
b411b363 144 else
590001c2 145 seq_printf(seq, "(%lu/%lu)K",
b411b363 146 (unsigned long) Bit2KB(rs_left),
a5655dac 147 (unsigned long) Bit2KB(rs_total));
b411b363 148
590001c2
PR
149 seq_printf(seq, "\n\t");
150
b411b363
PR
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 */
1d7734a0
LE
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. */
439d5953 163 /* ------------------------ ~18s average ------------------------ */
b30ab791
AG
164 i = (device->rs_last_mark + 2) % DRBD_SYNC_MARKS;
165 dt = (jiffies - device->rs_mark_time[i]) / HZ;
9ae47260 166 if (dt > 180)
1d7734a0 167 stalled = 1;
b411b363
PR
168
169 if (!dt)
170 dt++;
b30ab791 171 db = device->rs_mark_left[i] - rs_left;
b411b363
PR
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
b411b363 177 dbdt = Bit2KB(db/dt);
439d5953
LE
178 seq_printf(seq, " speed: ");
179 seq_printf_with_thousands_grouping(seq, dbdt);
180 seq_printf(seq, " (");
181 /* ------------------------- ~3s average ------------------------ */
182 if (proc_details >= 1) {
183 /* this is what drbd_rs_should_slow_down() uses */
b30ab791
AG
184 i = (device->rs_last_mark + DRBD_SYNC_MARKS-1) % DRBD_SYNC_MARKS;
185 dt = (jiffies - device->rs_mark_time[i]) / HZ;
439d5953
LE
186 if (!dt)
187 dt++;
b30ab791 188 db = device->rs_mark_left[i] - rs_left;
439d5953
LE
189 dbdt = Bit2KB(db/dt);
190 seq_printf_with_thousands_grouping(seq, dbdt);
191 seq_printf(seq, " -- ");
192 }
b411b363 193
439d5953 194 /* --------------------- long term average ---------------------- */
b411b363
PR
195 /* mean speed since syncer started
196 * we do account for PausedSync periods */
b30ab791 197 dt = (jiffies - device->rs_start - device->rs_paused) / HZ;
22657695 198 if (dt == 0)
b411b363 199 dt = 1;
a5655dac 200 db = rs_total - rs_left;
b411b363 201 dbdt = Bit2KB(db/dt);
439d5953
LE
202 seq_printf_with_thousands_grouping(seq, dbdt);
203 seq_printf(seq, ")");
b411b363 204
a5655dac
LE
205 if (state.conn == C_SYNC_TARGET ||
206 state.conn == C_VERIFY_S) {
5f9915bb 207 seq_printf(seq, " want: ");
b30ab791 208 seq_printf_with_thousands_grouping(seq, device->c_sync_rate);
1d7734a0
LE
209 }
210 seq_printf(seq, " K/sec%s\n", stalled ? " (stalled)" : "");
5f9915bb
LE
211
212 if (proc_details >= 1) {
213 /* 64 bit:
214 * we convert to sectors in the display below. */
b30ab791 215 unsigned long bm_bits = drbd_bm_bits(device);
4896e8c1 216 unsigned long bit_pos;
58ffa580 217 unsigned long long stop_sector = 0;
a5655dac
LE
218 if (state.conn == C_VERIFY_S ||
219 state.conn == C_VERIFY_T) {
b30ab791
AG
220 bit_pos = bm_bits - device->ov_left;
221 if (verify_can_do_stop_sector(device))
222 stop_sector = device->ov_stop_sector;
58ffa580 223 } else
b30ab791 224 bit_pos = device->bm_resync_fo;
5f9915bb
LE
225 /* Total sectors may be slightly off for oddly
226 * sized devices. So what. */
227 seq_printf(seq,
58ffa580 228 "\t%3d%% sector pos: %llu/%llu",
5f9915bb 229 (int)(bit_pos / (bm_bits/100+1)),
4896e8c1
LE
230 (unsigned long long)bit_pos * BM_SECT_PER_BIT,
231 (unsigned long long)bm_bits * BM_SECT_PER_BIT);
58ffa580
LE
232 if (stop_sector != 0 && stop_sector != ULLONG_MAX)
233 seq_printf(seq, " stop sector: %llu", stop_sector);
234 seq_printf(seq, "\n");
5f9915bb 235 }
b411b363
PR
236}
237
b411b363
PR
238static int drbd_seq_show(struct seq_file *seq, void *v)
239{
81a5d60e 240 int i, prev_i = -1;
b411b363 241 const char *sn;
b30ab791 242 struct drbd_device *device;
44ed167d 243 struct net_conf *nc;
a5655dac 244 union drbd_dev_state state;
44ed167d 245 char wp;
b411b363
PR
246
247 static char write_ordering_chars[] = {
f6ba8636
AG
248 [WO_NONE] = 'n',
249 [WO_DRAIN_IO] = 'd',
250 [WO_BDEV_FLUSH] = 'f',
b411b363
PR
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
c141ebda 276 rcu_read_lock();
05a10ec7 277 idr_for_each_entry(&drbd_devices, device, i) {
81a5d60e 278 if (prev_i != i - 1)
b411b363 279 seq_printf(seq, "\n");
81a5d60e 280 prev_i = i;
b411b363 281
a5655dac
LE
282 state = device->state;
283 sn = drbd_conn_str(state.conn);
b411b363 284
a5655dac
LE
285 if (state.conn == C_STANDALONE &&
286 state.disk == D_DISKLESS &&
287 state.role == R_SECONDARY) {
b411b363
PR
288 seq_printf(seq, "%2d: cs:Unconfigured\n", i);
289 } else {
b30ab791
AG
290 /* reset device->congestion_reason */
291 bdi_rw_congested(&device->rq_queue->backing_dev_info);
8a943170 292
a6b32bc3 293 nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
44ed167d 294 wp = nc ? nc->wire_protocol - DRBD_PROT_A + 'A' : ' ';
b411b363 295 seq_printf(seq,
0778286a 296 "%2d: cs:%s ro:%s/%s ds:%s/%s %c %c%c%c%c%c%c\n"
b411b363
PR
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,
a5655dac
LE
300 drbd_role_str(state.role),
301 drbd_role_str(state.peer),
302 drbd_disk_str(state.disk),
303 drbd_disk_str(state.pdsk),
44ed167d 304 wp,
b30ab791 305 drbd_suspended(device) ? 's' : 'r',
a5655dac
LE
306 state.aftr_isp ? 'a' : '-',
307 state.peer_isp ? 'p' : '-',
308 state.user_isp ? 'u' : '-',
b30ab791
AG
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),
a6b32bc3 322 first_peer_device(device)->connection->epochs,
e9526580 323 write_ordering_chars[device->resource->write_ordering]
b411b363 324 );
18edc0b9
LE
325 seq_printf(seq, " oos:%llu\n",
326 Bit2KB((unsigned long long)
b30ab791 327 drbd_bm_total_weight(device)));
b411b363 328 }
a5655dac
LE
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);
b30ab791
AG
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);
b411b363 339 }
ad3fee79
LE
340
341 if (proc_details >= 2)
342 seq_printf(seq, "\tblocked on activity log: %d\n", atomic_read(&device->ap_actlog_cnt));
b411b363 343 }
c141ebda 344 rcu_read_unlock();
b411b363
PR
345
346 return 0;
347}
348
349static int drbd_proc_open(struct inode *inode, struct file *file)
350{
193d0153
AK
351 int err;
352
353 if (try_module_get(THIS_MODULE)) {
caa3db0e 354 err = single_open(file, drbd_seq_show, NULL);
193d0153
AK
355 if (err)
356 module_put(THIS_MODULE);
357 return err;
358 }
3da127fa
LE
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);
b411b363
PR
366}
367
368/* PROC FS stuff end */
This page took 0.295953 seconds and 5 git commands to generate.