Whamcloud - gitweb
LU-1866 lfsck: enhance otable-based iteration
[fs/lustre-release.git] / lustre / osp / lproc_osp.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  *
30  * Copyright (c) 2012, Intel Corporation.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * lustre/osp/lproc_osp.c
37  *
38  * Lustre OST Proxy Device, procfs functions
39  *
40  * Author: Alex Zhuravlev <alexey.zhuravlev@intel.com>
41  */
42
43 #define DEBUG_SUBSYSTEM S_CLASS
44
45 #include "osp_internal.h"
46
47 #ifdef LPROCFS
48 static int osp_rd_active(char *page, char **start, off_t off,
49                          int count, int *eof, void *data)
50 {
51         struct obd_device       *dev = data;
52         int                      rc;
53
54         LPROCFS_CLIMP_CHECK(dev);
55         rc = snprintf(page, count, "%d\n",
56                       !dev->u.cli.cl_import->imp_deactive);
57         LPROCFS_CLIMP_EXIT(dev);
58         return rc;
59 }
60
61 static int osp_wr_active(struct file *file, const char *buffer,
62                          unsigned long count, void *data)
63 {
64         struct obd_device       *dev = data;
65         int                      val, rc;
66
67         rc = lprocfs_write_helper(buffer, count, &val);
68         if (rc)
69                 return rc;
70         if (val < 0 || val > 1)
71                 return -ERANGE;
72
73         LPROCFS_CLIMP_CHECK(dev);
74         /* opposite senses */
75         if (dev->u.cli.cl_import->imp_deactive == val)
76                 rc = ptlrpc_set_import_active(dev->u.cli.cl_import, val);
77         else
78                 CDEBUG(D_CONFIG, "activate %d: ignoring repeat request\n",
79                        val);
80
81         LPROCFS_CLIMP_EXIT(dev);
82         return count;
83 }
84
85 static int osp_rd_syn_in_flight(char *page, char **start, off_t off,
86                                 int count, int *eof, void *data)
87 {
88         struct obd_device       *dev = data;
89         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
90         int                      rc;
91
92         if (osp == NULL)
93                 return -EINVAL;
94
95         rc = snprintf(page, count, "%u\n", osp->opd_syn_rpc_in_flight);
96         return rc;
97 }
98
99 static int osp_rd_syn_in_prog(char *page, char **start, off_t off, int count,
100                               int *eof, void *data)
101 {
102         struct obd_device       *dev = data;
103         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
104         int                      rc;
105
106         if (osp == NULL)
107                 return -EINVAL;
108
109         rc = snprintf(page, count, "%u\n", osp->opd_syn_rpc_in_progress);
110         return rc;
111 }
112
113 static int osp_rd_syn_changes(char *page, char **start, off_t off,
114                               int count, int *eof, void *data)
115 {
116         struct obd_device       *dev = data;
117         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
118         int                      rc;
119
120         if (osp == NULL)
121                 return -EINVAL;
122
123         rc = snprintf(page, count, "%lu\n", osp->opd_syn_changes);
124         return rc;
125 }
126
127 static int osp_rd_max_rpcs_in_flight(char *page, char **start, off_t off,
128                                      int count, int *eof, void *data)
129 {
130         struct obd_device       *dev = data;
131         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
132         int                      rc;
133
134         if (osp == NULL)
135                 return -EINVAL;
136
137         rc = snprintf(page, count, "%u\n", osp->opd_syn_max_rpc_in_flight);
138         return rc;
139 }
140
141 static int osp_wr_max_rpcs_in_flight(struct file *file, const char *buffer,
142                                      unsigned long count, void *data)
143 {
144         struct obd_device       *dev = data;
145         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
146         int                      val, rc;
147
148         if (osp == NULL)
149                 return -EINVAL;
150
151         rc = lprocfs_write_helper(buffer, count, &val);
152         if (rc)
153                 return rc;
154
155         if (val < 1)
156                 return -ERANGE;
157
158         osp->opd_syn_max_rpc_in_flight = val;
159         return count;
160 }
161
162 static int osp_rd_max_rpcs_in_prog(char *page, char **start, off_t off,
163                                    int count, int *eof, void *data)
164 {
165         struct obd_device       *dev = data;
166         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
167         int                      rc;
168
169         if (osp == NULL)
170                 return -EINVAL;
171
172         rc = snprintf(page, count, "%u\n", osp->opd_syn_max_rpc_in_progress);
173         return rc;
174 }
175
176 static int osp_wr_max_rpcs_in_prog(struct file *file, const char *buffer,
177                                    unsigned long count, void *data)
178 {
179         struct obd_device       *dev = data;
180         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
181         int                      val, rc;
182
183         if (osp == NULL)
184                 return -EINVAL;
185
186         rc = lprocfs_write_helper(buffer, count, &val);
187         if (rc)
188                 return rc;
189
190         if (val < 1)
191                 return -ERANGE;
192
193         osp->opd_syn_max_rpc_in_progress = val;
194
195         return count;
196 }
197
198 static int osp_rd_create_count(char *page, char **start, off_t off, int count,
199                                int *eof, void *data)
200 {
201         struct obd_device *obd = data;
202         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
203
204         if (osp == NULL)
205                 return 0;
206
207         return snprintf(page, count, "%d\n", osp->opd_pre_grow_count);
208 }
209
210 static int osp_wr_create_count(struct file *file, const char *buffer,
211                                unsigned long count, void *data)
212 {
213         struct obd_device       *obd = data;
214         struct osp_device       *osp = lu2osp_dev(obd->obd_lu_dev);
215         int                      val, rc, i;
216
217         if (osp == NULL)
218                 return 0;
219
220         rc = lprocfs_write_helper(buffer, count, &val);
221         if (rc)
222                 return rc;
223
224         /* The MDT ALWAYS needs to limit the precreate count to
225          * OST_MAX_PRECREATE, and the constant cannot be changed
226          * because it is a value shared between the OSP and OST
227          * that is the maximum possible number of objects that will
228          * ever be handled by MDT->OST recovery processing.
229          *
230          * If the OST ever gets a request to delete more orphans,
231          * this implies that something has gone badly on the MDT
232          * and the OST will refuse to delete so much data from the
233          * filesystem as a safety measure. */
234         if (val < OST_MIN_PRECREATE || val > OST_MAX_PRECREATE)
235                 return -ERANGE;
236         if (val > osp->opd_pre_max_grow_count)
237                 return -ERANGE;
238
239         for (i = 1; (i << 1) <= val; i <<= 1)
240                 ;
241         osp->opd_pre_grow_count = i;
242
243         return count;
244 }
245
246 static int osp_rd_max_create_count(char *page, char **start, off_t off,
247                                    int count, int *eof, void *data)
248 {
249         struct obd_device *obd = data;
250         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
251
252         if (osp == NULL)
253                 return 0;
254
255         return snprintf(page, count, "%d\n", osp->opd_pre_max_grow_count);
256 }
257
258 static int osp_wr_max_create_count(struct file *file, const char *buffer,
259                                    unsigned long count, void *data)
260 {
261         struct obd_device       *obd = data;
262         struct osp_device       *osp = lu2osp_dev(obd->obd_lu_dev);
263         int                      val, rc;
264
265         if (osp == NULL)
266                 return 0;
267
268         rc = lprocfs_write_helper(buffer, count, &val);
269         if (rc)
270                 return rc;
271
272         if (val < 0)
273                 return -ERANGE;
274         if (val > OST_MAX_PRECREATE)
275                 return -ERANGE;
276
277         if (osp->opd_pre_grow_count > val)
278                 osp->opd_pre_grow_count = val;
279
280         osp->opd_pre_max_grow_count = val;
281
282         return count;
283 }
284
285 static int osp_rd_prealloc_next_id(char *page, char **start, off_t off,
286                                    int count, int *eof, void *data)
287 {
288         struct obd_device *obd = data;
289         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
290
291         if (osp == NULL)
292                 return 0;
293
294         return snprintf(page, count, "%u\n",
295                         fid_oid(&osp->opd_pre_used_fid) + 1);
296 }
297
298 static int osp_rd_prealloc_last_id(char *page, char **start, off_t off,
299                                    int count, int *eof, void *data)
300 {
301         struct obd_device *obd = data;
302         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
303
304         if (osp == NULL)
305                 return 0;
306
307         return snprintf(page, count, "%u\n",
308                         fid_oid(&osp->opd_pre_last_created_fid));
309 }
310
311 static int osp_rd_prealloc_next_seq(char *page, char **start, off_t off,
312                                     int count, int *eof, void *data)
313 {
314         struct obd_device *obd = data;
315         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
316
317         if (osp == NULL)
318                 return 0;
319
320         return snprintf(page, count, LPX64"\n",
321                         fid_seq(&osp->opd_pre_used_fid));
322 }
323
324 static int osp_rd_prealloc_last_seq(char *page, char **start, off_t off,
325                                     int count, int *eof, void *data)
326 {
327         struct obd_device *obd = data;
328         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
329
330         if (osp == NULL)
331                 return 0;
332
333         return snprintf(page, count, LPX64"\n",
334                         fid_seq(&osp->opd_pre_last_created_fid));
335 }
336
337 static int osp_rd_prealloc_reserved(char *page, char **start, off_t off,
338                                     int count, int *eof, void *data)
339 {
340         struct obd_device *obd = data;
341         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
342
343         if (osp == NULL)
344                 return 0;
345
346         return snprintf(page, count, LPU64"\n", osp->opd_pre_reserved);
347 }
348
349 static int osp_rd_maxage(char *page, char **start, off_t off,
350                          int count, int *eof, void *data)
351 {
352         struct obd_device       *dev = data;
353         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
354         int                      rc;
355
356         if (osp == NULL)
357                 return -EINVAL;
358
359         rc = snprintf(page, count, "%u\n", osp->opd_statfs_maxage);
360         return rc;
361 }
362
363 static int osp_wr_maxage(struct file *file, const char *buffer,
364                          unsigned long count, void *data)
365 {
366         struct obd_device       *dev = data;
367         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
368         int                      val, rc;
369
370         if (osp == NULL)
371                 return -EINVAL;
372
373         rc = lprocfs_write_helper(buffer, count, &val);
374         if (rc)
375                 return rc;
376
377         if (val < 1)
378                 return -ERANGE;
379
380         osp->opd_statfs_maxage = val;
381
382         return count;
383 }
384
385 static int osp_rd_pre_status(char *page, char **start, off_t off,
386                              int count, int *eof, void *data)
387 {
388         struct obd_device       *dev = data;
389         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
390         int                      rc;
391
392         if (osp == NULL)
393                 return -EINVAL;
394
395         rc = snprintf(page, count, "%d\n", osp->opd_pre_status);
396         return rc;
397 }
398
399 static int osp_rd_destroys_in_flight(char *page, char **start, off_t off,
400                                      int count, int *eof, void *data)
401 {
402         struct obd_device *dev = data;
403         struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
404
405         /*
406          * This counter used to determine if OST has space returned.
407          * Now we need to wait for the following:
408          * - sync changes are zero - no llog records
409          * - sync in progress are zero - no RPCs in flight
410          */
411         return snprintf(page, count, "%lu\n",
412                         osp->opd_syn_rpc_in_progress + osp->opd_syn_changes);
413 }
414
415 static int osp_rd_old_sync_processed(char *page, char **start, off_t off,
416                                      int count, int *eof, void *data)
417 {
418         struct obd_device       *dev = data;
419         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
420         int                      rc;
421
422         if (osp == NULL)
423                 return -EINVAL;
424
425         rc = snprintf(page, count, "%d\n", osp->opd_syn_prev_done);
426         return rc;
427 }
428
429 static struct lprocfs_vars lprocfs_osp_obd_vars[] = {
430         { "uuid",               lprocfs_rd_uuid, 0, 0 },
431         { "ping",               0, lprocfs_wr_ping, 0, 0, 0222 },
432         { "connect_flags",      lprocfs_rd_connect_flags, 0, 0 },
433         { "ost_server_uuid",    lprocfs_rd_server_uuid, 0, 0 },
434         { "ost_conn_uuid",      lprocfs_rd_conn_uuid, 0, 0 },
435         { "active",             osp_rd_active, osp_wr_active, 0 },
436         { "max_rpcs_in_flight", osp_rd_max_rpcs_in_flight,
437                                 osp_wr_max_rpcs_in_flight, 0 },
438         { "max_rpcs_in_progress", osp_rd_max_rpcs_in_prog,
439                                   osp_wr_max_rpcs_in_prog, 0 },
440         { "create_count",       osp_rd_create_count,
441                                 osp_wr_create_count, 0 },
442         { "max_create_count",   osp_rd_max_create_count,
443                                 osp_wr_max_create_count, 0 },
444         { "prealloc_next_id",   osp_rd_prealloc_next_id, 0, 0 },
445         { "prealloc_next_seq",  osp_rd_prealloc_next_seq, 0, 0 },
446         { "prealloc_last_id",   osp_rd_prealloc_last_id,  0, 0 },
447         { "prealloc_last_seq",  osp_rd_prealloc_last_seq, 0, 0 },
448         { "prealloc_reserved",  osp_rd_prealloc_reserved, 0, 0 },
449         { "timeouts",           lprocfs_rd_timeouts, 0, 0 },
450         { "import",             lprocfs_rd_import, lprocfs_wr_import, 0 },
451         { "state",              lprocfs_rd_state, 0, 0 },
452         { "maxage",             osp_rd_maxage, osp_wr_maxage, 0 },
453         { "prealloc_status",    osp_rd_pre_status, 0, 0 },
454         { "sync_changes",       osp_rd_syn_changes, 0, 0 },
455         { "sync_in_flight",     osp_rd_syn_in_flight, 0, 0 },
456         { "sync_in_progress",   osp_rd_syn_in_prog, 0, 0 },
457         { "old_sync_processed", osp_rd_old_sync_processed, 0, 0 },
458
459         /* for compatibility reasons */
460         { "destroys_in_flight", osp_rd_destroys_in_flight, 0, 0 },
461         { 0 }
462 };
463
464 static struct lprocfs_vars lprocfs_osp_osd_vars[] = {
465         { "blocksize",          lprocfs_osd_rd_blksize, 0, 0 },
466         { "kbytestotal",        lprocfs_osd_rd_kbytestotal, 0, 0 },
467         { "kbytesfree",         lprocfs_osd_rd_kbytesfree, 0, 0 },
468         { "kbytesavail",        lprocfs_osd_rd_kbytesavail, 0, 0 },
469         { "filestotal",         lprocfs_osd_rd_filestotal, 0, 0 },
470         { "filesfree",          lprocfs_osd_rd_filesfree, 0, 0 },
471         { 0 }
472 };
473
474 static struct lprocfs_vars lprocfs_osp_module_vars[] = {
475         { "num_refs",           lprocfs_rd_numrefs, 0, 0 },
476         { 0 }
477 };
478
479 void lprocfs_osp_init_vars(struct lprocfs_static_vars *lvars)
480 {
481         lvars->module_vars = lprocfs_osp_module_vars;
482         lvars->obd_vars = lprocfs_osp_obd_vars;
483 }
484
485 void osp_lprocfs_init(struct osp_device *osp)
486 {
487         struct obd_device       *obd = osp->opd_obd;
488         struct proc_dir_entry   *osc_proc_dir;
489         int                      rc;
490
491         obd->obd_proc_entry = lprocfs_register(obd->obd_name,
492                                                obd->obd_type->typ_procroot,
493                                                lprocfs_osp_osd_vars,
494                                                &osp->opd_dt_dev);
495         if (IS_ERR(obd->obd_proc_entry)) {
496                 CERROR("%s: can't register in lprocfs: %ld\n",
497                        obd->obd_name, PTR_ERR(obd->obd_proc_entry));
498                 obd->obd_proc_entry = NULL;
499                 return;
500         }
501
502         rc = lprocfs_add_vars(obd->obd_proc_entry, lprocfs_osp_obd_vars, obd);
503         if (rc) {
504                 CERROR("%s: can't register in lprocfs: %ld\n",
505                        obd->obd_name, PTR_ERR(obd->obd_proc_entry));
506                 return;
507         }
508
509         ptlrpc_lprocfs_register_obd(obd);
510
511         /* for compatibility we link old procfs's OSC entries to osp ones */
512         if (!osp->opd_connect_mdt) {
513                 osc_proc_dir = lprocfs_srch(proc_lustre_root, "osc");
514                 if (osc_proc_dir) {
515                         cfs_proc_dir_entry_t    *symlink = NULL;
516                         char                    *name;
517
518                         OBD_ALLOC(name, strlen(obd->obd_name) + 1);
519                         if (name == NULL)
520                                 return;
521
522                         strcpy(name, obd->obd_name);
523                         if (strstr(name, "osc"))
524                                 symlink = lprocfs_add_symlink(name,
525                                                 osc_proc_dir, "../osp/%s",
526                                                 obd->obd_name);
527                         OBD_FREE(name, strlen(obd->obd_name) + 1);
528                         osp->opd_symlink = symlink;
529                 }
530         }
531 }
532
533 #endif /* LPROCFS */
534