Whamcloud - gitweb
LU-8378 all: remove set but unused variables
[fs/lustre-release.git] / lustre / fid / lproc_fid.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.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2011, 2015, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  * Lustre is a trademark of Sun Microsystems, Inc.
31  *
32  * lustre/fid/lproc_fid.c
33  *
34  * Lustre Sequence Manager
35  *
36  * Author: Yury Umanets <umka@clusterfs.com>
37  */
38
39 #define DEBUG_SUBSYSTEM S_FID
40
41 #include <libcfs/libcfs.h>
42 #include <linux/module.h>
43 #include <obd.h>
44 #include <obd_class.h>
45 #include <obd_support.h>
46 #include <lustre_fid.h>
47 #include <lprocfs_status.h>
48 #include "fid_internal.h"
49
50 #ifdef CONFIG_PROC_FS
51
52 /* Format: [0x64BIT_INT - 0x64BIT_INT] + 32 bytes just in case */
53 #define MAX_FID_RANGE_STRLEN (32 + 2 * 2 * sizeof(__u64))
54 /**
55  * Reduce the SEQ range allocated to a node to a strict subset of the range
56  * currently-allocated SEQ range.  If the specified range is "clear", then
57  * drop all allocated sequences and request a new one from the master.
58  *
59  * Note: this function should only be used for testing, it is not necessarily
60  * safe for production use.
61  */
62 static int
63 lprocfs_fid_write_common(const char __user *buffer, size_t count,
64                                 struct lu_seq_range *range)
65 {
66         struct lu_seq_range tmp = { 0, };
67         char kernbuf[MAX_FID_RANGE_STRLEN];
68         ENTRY;
69
70         LASSERT(range != NULL);
71
72         if (count >= sizeof(kernbuf))
73                 RETURN(-EINVAL);
74
75         if (copy_from_user(kernbuf, buffer, count))
76                 RETURN(-EFAULT);
77
78         kernbuf[count] = 0;
79
80         if (count == 5 && strcmp(kernbuf, "clear") == 0) {
81                 memset(range, 0, sizeof(*range));
82                 RETURN(0);
83         }
84
85         /* of the form "[0x0000000240000400 - 0x000000028000400]" */
86         sscanf(kernbuf, "[%llx - %llx]\n",
87                (long long unsigned *)&tmp.lsr_start,
88                (long long unsigned *)&tmp.lsr_end);
89         if (!lu_seq_range_is_sane(&tmp) || lu_seq_range_is_zero(&tmp) ||
90             tmp.lsr_start < range->lsr_start || tmp.lsr_end > range->lsr_end)
91                 RETURN(-EINVAL);
92         *range = tmp;
93         RETURN(0);
94 }
95
96 #ifdef HAVE_SERVER_SUPPORT
97 /*
98  * Server side procfs stuff.
99  */
100 static ssize_t
101 lprocfs_server_fid_space_seq_write(struct file *file, const char __user *buffer,
102                                         size_t count, loff_t *off)
103 {
104         struct lu_server_seq *seq = ((struct seq_file *)file->private_data)->private;
105         int rc;
106         ENTRY;
107
108         LASSERT(seq != NULL);
109
110         mutex_lock(&seq->lss_mutex);
111         rc = lprocfs_fid_write_common(buffer, count, &seq->lss_space);
112         if (rc == 0) {
113                 CDEBUG(D_INFO, "%s: Space: "DRANGE"\n",
114                         seq->lss_name, PRANGE(&seq->lss_space));
115         }
116         mutex_unlock(&seq->lss_mutex);
117
118         RETURN(count);
119 }
120
121 static int
122 lprocfs_server_fid_space_seq_show(struct seq_file *m, void *unused)
123 {
124         struct lu_server_seq *seq = (struct lu_server_seq *)m->private;
125         ENTRY;
126
127         LASSERT(seq != NULL);
128
129         mutex_lock(&seq->lss_mutex);
130         seq_printf(m, "[%#llx - %#llx]:%x:%s\n", PRANGE(&seq->lss_space));
131         mutex_unlock(&seq->lss_mutex);
132
133         RETURN(0);
134 }
135
136 static int
137 lprocfs_server_fid_server_seq_show(struct seq_file *m, void *unused)
138 {
139         struct lu_server_seq *seq = (struct lu_server_seq *)m->private;
140         struct client_obd *cli;
141         ENTRY;
142
143         LASSERT(seq != NULL);
144
145         if (seq->lss_cli) {
146                 if (seq->lss_cli->lcs_exp != NULL) {
147                         cli = &seq->lss_cli->lcs_exp->exp_obd->u.cli;
148                         seq_printf(m, "%s\n", cli->cl_target_uuid.uuid);
149                 } else {
150                         seq_printf(m, "%s\n", seq->lss_cli->lcs_srv->lss_name);
151                 }
152         } else {
153                 seq_puts(m, "<none>\n");
154         }
155
156         RETURN(0);
157 }
158
159 static ssize_t
160 lprocfs_server_fid_width_seq_write(struct file *file, const char __user *buffer,
161                                         size_t count, loff_t *off)
162 {
163         struct lu_server_seq *seq = ((struct seq_file *)file->private_data)->private;
164         int rc;
165         __s64 val;
166         ENTRY;
167
168         LASSERT(seq != NULL);
169
170         mutex_lock(&seq->lss_mutex);
171
172         rc = lprocfs_str_to_s64(buffer, count, &val);
173         if (rc) {
174                 CERROR("%s: invalid FID sequence width: rc = %d\n",
175                        seq->lss_name, rc);
176                 GOTO(out_unlock, count = rc);
177         }
178
179         if (val < 0) {
180                 CERROR("%s: invalid FID sequence width: rc = %d\n",
181                        seq->lss_name, -ERANGE);
182                 GOTO(out_unlock, count = -ERANGE);
183         }
184
185         seq->lss_width = val;
186
187         CDEBUG(D_INFO, "%s: Width: %llu\n",
188                seq->lss_name, seq->lss_width);
189 out_unlock:
190         mutex_unlock(&seq->lss_mutex);
191
192         RETURN(count);
193 }
194
195 static int
196 lprocfs_server_fid_width_seq_show(struct seq_file *m, void *unused)
197 {
198         struct lu_server_seq *seq = (struct lu_server_seq *)m->private;
199         ENTRY;
200
201         LASSERT(seq != NULL);
202
203         mutex_lock(&seq->lss_mutex);
204         seq_printf(m, "%llu\n", seq->lss_width);
205         mutex_unlock(&seq->lss_mutex);
206
207         RETURN(0);
208 }
209
210 LPROC_SEQ_FOPS(lprocfs_server_fid_space);
211 LPROC_SEQ_FOPS(lprocfs_server_fid_width);
212 LPROC_SEQ_FOPS_RO(lprocfs_server_fid_server);
213
214 struct lprocfs_vars seq_server_proc_list[] = {
215         { .name =       "space",
216           .fops =       &lprocfs_server_fid_space_fops  },
217         { .name =       "width",
218           .fops =       &lprocfs_server_fid_width_fops  },
219         { .name =       "server",
220           .fops =       &lprocfs_server_fid_server_fops },
221         { NULL }
222 };
223
224 struct fld_seq_param {
225         struct lu_env           fsp_env;
226         struct dt_it            *fsp_it;
227         struct lu_server_fld    *fsp_fld;
228         struct lu_server_seq    *fsp_seq;
229         unsigned int            fsp_stop:1;
230 };
231
232 /*
233  * XXX: below is a copy of the functions in lustre/fld/lproc_fld.c.
234  * we want to avoid this duplication either by exporting the
235  * functions or merging fid and fld into a single module.
236  */
237 static void *fldb_seq_start(struct seq_file *p, loff_t *pos)
238 {
239         struct fld_seq_param    *param = p->private;
240         struct lu_server_fld    *fld;
241         struct dt_object        *obj;
242         const struct dt_it_ops  *iops;
243         struct dt_key           *key;
244         int                     rc;
245
246         if (param == NULL || param->fsp_stop)
247                 return NULL;
248
249         fld = param->fsp_fld;
250         obj = fld->lsf_obj;
251         LASSERT(obj != NULL);
252         iops = &obj->do_index_ops->dio_it;
253
254         rc = iops->load(&param->fsp_env, param->fsp_it, *pos);
255         if (rc <= 0)
256                 return NULL;
257
258         key = iops->key(&param->fsp_env, param->fsp_it);
259         if (IS_ERR(key))
260                 return NULL;
261
262         *pos = be64_to_cpu(*(__u64 *)key);
263
264         return param;
265 }
266
267 static void fldb_seq_stop(struct seq_file *p, void *v)
268 {
269         struct fld_seq_param    *param = p->private;
270         const struct dt_it_ops  *iops;
271         struct lu_server_fld    *fld;
272         struct dt_object        *obj;
273
274         if (param == NULL)
275                 return;
276
277         fld = param->fsp_fld;
278         obj = fld->lsf_obj;
279         LASSERT(obj != NULL);
280         iops = &obj->do_index_ops->dio_it;
281
282         iops->put(&param->fsp_env, param->fsp_it);
283 }
284
285 static void *fldb_seq_next(struct seq_file *p, void *v, loff_t *pos)
286 {
287         struct fld_seq_param    *param = p->private;
288         struct lu_server_fld    *fld;
289         struct dt_object        *obj;
290         const struct dt_it_ops  *iops;
291         int                     rc;
292
293         if (param == NULL || param->fsp_stop)
294                 return NULL;
295
296         fld = param->fsp_fld;
297         obj = fld->lsf_obj;
298         LASSERT(obj != NULL);
299         iops = &obj->do_index_ops->dio_it;
300
301         rc = iops->next(&param->fsp_env, param->fsp_it);
302         if (rc > 0) {
303                 param->fsp_stop = 1;
304                 return NULL;
305         }
306
307         *pos = be64_to_cpu(*(__u64 *)iops->key(&param->fsp_env, param->fsp_it));
308         return param;
309 }
310
311 static int fldb_seq_show(struct seq_file *p, void *v)
312 {
313         struct fld_seq_param    *param = p->private;
314         struct lu_server_fld    *fld;
315         struct dt_object        *obj;
316         const struct dt_it_ops  *iops;
317         struct lu_seq_range      fld_rec;
318         int                     rc;
319
320         if (param == NULL || param->fsp_stop)
321                 return 0;
322
323         fld = param->fsp_fld;
324         obj = fld->lsf_obj;
325         LASSERT(obj != NULL);
326         iops = &obj->do_index_ops->dio_it;
327
328         rc = iops->rec(&param->fsp_env, param->fsp_it,
329                        (struct dt_rec *)&fld_rec, 0);
330         if (rc != 0) {
331                 CERROR("%s: read record error: rc = %d\n",
332                        fld->lsf_name, rc);
333         } else if (fld_rec.lsr_start != 0) {
334                 range_be_to_cpu(&fld_rec, &fld_rec);
335                 seq_printf(p, DRANGE"\n", PRANGE(&fld_rec));
336         }
337
338         return rc;
339 }
340
341 struct seq_operations fldb_sops = {
342         .start = fldb_seq_start,
343         .stop = fldb_seq_stop,
344         .next = fldb_seq_next,
345         .show = fldb_seq_show,
346 };
347
348 static int fldb_seq_open(struct inode *inode, struct file *file)
349 {
350         struct seq_file         *seq;
351         struct lu_server_seq    *ss = (struct lu_server_seq *) PDE_DATA(inode);
352         struct lu_server_fld    *fld;
353         struct dt_object        *obj;
354         const struct dt_it_ops  *iops;
355         struct fld_seq_param    *param = NULL;
356         int                     env_init = 0;
357         int                     rc;
358
359         fld = ss->lss_site->ss_server_fld;
360         LASSERT(fld != NULL);
361
362         rc = LPROCFS_ENTRY_CHECK(inode);
363         if (rc < 0)
364                 return rc;
365
366         rc = seq_open(file, &fldb_sops);
367         if (rc)
368                 return rc;
369
370         obj = fld->lsf_obj;
371         if (obj == NULL) {
372                 seq = file->private_data;
373                 seq->private = NULL;
374                 return 0;
375         }
376
377         OBD_ALLOC_PTR(param);
378         if (param == NULL)
379                 GOTO(out, rc = -ENOMEM);
380
381         rc = lu_env_init(&param->fsp_env, LCT_MD_THREAD);
382         if (rc != 0)
383                 GOTO(out, rc);
384
385         env_init = 1;
386         iops = &obj->do_index_ops->dio_it;
387         param->fsp_it = iops->init(&param->fsp_env, obj, 0);
388         if (IS_ERR(param->fsp_it))
389                 GOTO(out, rc = PTR_ERR(param->fsp_it));
390
391         param->fsp_fld = fld;
392         param->fsp_seq = ss;
393         param->fsp_stop = 0;
394
395         seq = file->private_data;
396         seq->private = param;
397 out:
398         if (rc != 0) {
399                 if (env_init == 1)
400                         lu_env_fini(&param->fsp_env);
401                 if (param != NULL)
402                         OBD_FREE_PTR(param);
403         }
404         return rc;
405 }
406
407 static int fldb_seq_release(struct inode *inode, struct file *file)
408 {
409         struct seq_file         *seq = file->private_data;
410         struct fld_seq_param    *param;
411         struct lu_server_fld    *fld;
412         struct dt_object        *obj;
413         const struct dt_it_ops  *iops;
414
415         param = seq->private;
416         if (param == NULL) {
417                 lprocfs_seq_release(inode, file);
418                 return 0;
419         }
420
421         fld = param->fsp_fld;
422         obj = fld->lsf_obj;
423         LASSERT(obj != NULL);
424         iops = &obj->do_index_ops->dio_it;
425
426         LASSERT(iops != NULL);
427         LASSERT(param->fsp_it != NULL);
428         iops->fini(&param->fsp_env, param->fsp_it);
429         lu_env_fini(&param->fsp_env);
430         OBD_FREE_PTR(param);
431         lprocfs_seq_release(inode, file);
432
433         return 0;
434 }
435
436 static ssize_t fldb_seq_write(struct file *file, const char __user *buf,
437                               size_t len, loff_t *off)
438 {
439         struct seq_file         *seq = file->private_data;
440         struct fld_seq_param    *param;
441         struct lu_seq_range      range;
442         int                      rc = 0;
443         char                     _buffer[MAX_FID_RANGE_STRLEN];
444         char                    *buffer = _buffer;
445         ENTRY;
446
447         param = seq->private;
448         if (param == NULL)
449                 RETURN(-EINVAL);
450
451         if (len >= sizeof(_buffer))
452                 RETURN(-EINVAL);
453
454         if (copy_from_user(buffer, buf, len))
455                 GOTO(out, rc = -EFAULT);
456         buffer[len] = 0;
457
458         /*
459          * format - [0x0000000200000007-0x0000000200000008):0:mdt
460          */
461         if (*buffer != '[')
462                 GOTO(out, rc = -EINVAL);
463         buffer++;
464
465         range.lsr_start = simple_strtoull(buffer, &buffer, 0);
466         if (*buffer != '-')
467                 GOTO(out, rc = -EINVAL);
468         buffer++;
469
470         range.lsr_end = simple_strtoull(buffer, &buffer, 0);
471         if (*buffer != ')')
472                 GOTO(out, rc = -EINVAL);
473         buffer++;
474         if (*buffer != ':')
475                 GOTO(out, rc = -EINVAL);
476         buffer++;
477
478         range.lsr_index = simple_strtoul(buffer, &buffer, 0);
479         if (*buffer != ':')
480                 GOTO(out, rc = -EINVAL);
481         buffer++;
482
483         if (strncmp(buffer, "mdt", 3) == 0)
484                 range.lsr_flags = LU_SEQ_RANGE_MDT;
485         else if (strncmp(buffer, "ost", 3) == 0)
486                 range.lsr_flags = LU_SEQ_RANGE_OST;
487         else
488                 GOTO(out, rc = -EINVAL);
489
490         rc = seq_server_alloc_spec(param->fsp_seq->lss_site->ss_control_seq,
491                                    &range, &param->fsp_env);
492
493 out:
494         RETURN(rc < 0 ? rc : len);
495 }
496
497 const struct file_operations seq_fld_proc_seq_fops = {
498         .owner   = THIS_MODULE,
499         .open    = fldb_seq_open,
500         .read    = seq_read,
501         .write   = fldb_seq_write,
502         .release = fldb_seq_release,
503 };
504
505 #endif /* HAVE_SERVER_SUPPORT */
506
507 /* Client side procfs stuff */
508 static ssize_t
509 lprocfs_client_fid_space_seq_write(struct file *file, const char __user *buffer,
510                                    size_t count, loff_t *off)
511 {
512         struct lu_client_seq *seq = ((struct seq_file *)file->private_data)->private;
513         int rc;
514         ENTRY;
515
516         LASSERT(seq != NULL);
517
518         mutex_lock(&seq->lcs_mutex);
519         rc = lprocfs_fid_write_common(buffer, count, &seq->lcs_space);
520         if (rc == 0) {
521                 CDEBUG(D_INFO, "%s: Space: "DRANGE"\n",
522                        seq->lcs_name, PRANGE(&seq->lcs_space));
523         }
524
525         mutex_unlock(&seq->lcs_mutex);
526
527         RETURN(count);
528 }
529
530 static int
531 lprocfs_client_fid_space_seq_show(struct seq_file *m, void *unused)
532 {
533         struct lu_client_seq *seq = (struct lu_client_seq *)m->private;
534         ENTRY;
535
536         LASSERT(seq != NULL);
537
538         mutex_lock(&seq->lcs_mutex);
539         seq_printf(m, "[%#llx - %#llx]:%x:%s\n",
540                    PRANGE(&seq->lcs_space));
541         mutex_unlock(&seq->lcs_mutex);
542
543         RETURN(0);
544 }
545
546 static ssize_t
547 lprocfs_client_fid_width_seq_write(struct file *file, const char __user *buffer,
548                                    size_t count, loff_t *off)
549 {
550         struct lu_client_seq *seq = ((struct seq_file *)file->private_data)->private;
551         __u64 max;
552         int rc;
553         __s64 val;
554         ENTRY;
555
556         LASSERT(seq != NULL);
557
558         mutex_lock(&seq->lcs_mutex);
559
560         rc = lprocfs_str_to_s64(buffer, count, &val);
561         if (rc) {
562                 GOTO(out_unlock, count = rc);
563         }
564
565         if (seq->lcs_type == LUSTRE_SEQ_DATA)
566                 max = LUSTRE_DATA_SEQ_MAX_WIDTH;
567         else
568                 max = LUSTRE_METADATA_SEQ_MAX_WIDTH;
569
570         if (val <= max && val > 0) {
571                 seq->lcs_width = val;
572
573                 CDEBUG(D_INFO, "%s: Sequence size: %llu\n",
574                        seq->lcs_name, seq->lcs_width);
575         } else {
576                 GOTO(out_unlock, count = -ERANGE);
577         }
578
579 out_unlock:
580         mutex_unlock(&seq->lcs_mutex);
581         RETURN(count);
582 }
583
584 static int
585 lprocfs_client_fid_width_seq_show(struct seq_file *m, void *unused)
586 {
587         struct lu_client_seq *seq = (struct lu_client_seq *)m->private;
588         ENTRY;
589
590         LASSERT(seq != NULL);
591
592         mutex_lock(&seq->lcs_mutex);
593         seq_printf(m, "%llu\n", seq->lcs_width);
594         mutex_unlock(&seq->lcs_mutex);
595
596         RETURN(0);
597 }
598
599 static int
600 lprocfs_client_fid_fid_seq_show(struct seq_file *m, void *unused)
601 {
602         struct lu_client_seq *seq = (struct lu_client_seq *)m->private;
603         ENTRY;
604
605         LASSERT(seq != NULL);
606
607         mutex_lock(&seq->lcs_mutex);
608         seq_printf(m, DFID"\n", PFID(&seq->lcs_fid));
609         mutex_unlock(&seq->lcs_mutex);
610
611         RETURN(0);
612 }
613
614 static int
615 lprocfs_client_fid_server_seq_show(struct seq_file *m, void *unused)
616 {
617         struct lu_client_seq *seq = (struct lu_client_seq *)m->private;
618         struct client_obd *cli;
619         ENTRY;
620
621         LASSERT(seq != NULL);
622
623         if (seq->lcs_exp != NULL) {
624                 cli = &seq->lcs_exp->exp_obd->u.cli;
625                 seq_printf(m, "%s\n", cli->cl_target_uuid.uuid);
626         } else {
627                 seq_printf(m, "%s\n", seq->lcs_srv->lss_name);
628         }
629         RETURN(0);
630 }
631
632 LPROC_SEQ_FOPS(lprocfs_client_fid_space);
633 LPROC_SEQ_FOPS(lprocfs_client_fid_width);
634 LPROC_SEQ_FOPS_RO(lprocfs_client_fid_server);
635 LPROC_SEQ_FOPS_RO(lprocfs_client_fid_fid);
636
637 struct lprocfs_vars seq_client_proc_list[] = {
638         { .name =       "space",
639           .fops =       &lprocfs_client_fid_space_fops  },
640         { .name =       "width",
641           .fops =       &lprocfs_client_fid_width_fops  },
642         { .name =       "server",
643           .fops =       &lprocfs_client_fid_server_fops },
644         { .name =       "fid",
645           .fops =       &lprocfs_client_fid_fid_fops    },
646         { NULL }
647 };
648
649 #endif /* CONFIG_PROC_FS */