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