GNU Linux-libre 4.14.251-gnu1
[releases.git] / drivers / staging / lustre / 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 <linux/libcfs/libcfs.h>
42 #include <linux/module.h>
43
44 #include <obd.h>
45 #include <obd_class.h>
46 #include <obd_support.h>
47 #include <lustre_req_layout.h>
48 #include <lustre_fid.h>
49 #include "fid_internal.h"
50
51 /* Format: [0x64BIT_INT - 0x64BIT_INT] + 32 bytes just in case */
52 #define MAX_FID_RANGE_STRLEN (32 + 2 * 2 * sizeof(__u64))
53 /*
54  * Note: this function is only used for testing, it is no safe for production
55  * use.
56  */
57 static int
58 ldebugfs_fid_write_common(const char __user *buffer, size_t count,
59                           struct lu_seq_range *range)
60 {
61         struct lu_seq_range tmp;
62         int rc;
63         char kernbuf[MAX_FID_RANGE_STRLEN];
64
65         LASSERT(range);
66
67         if (count >= sizeof(kernbuf))
68                 return -EINVAL;
69
70         if (copy_from_user(kernbuf, buffer, count))
71                 return -EFAULT;
72
73         kernbuf[count] = 0;
74
75         if (count == 5 && strcmp(kernbuf, "clear") == 0) {
76                 memset(range, 0, sizeof(*range));
77                 return count;
78         }
79
80         /* of the form "[0x0000000240000400 - 0x000000028000400]" */
81         rc = sscanf(kernbuf, "[%llx - %llx]\n",
82                     (unsigned long long *)&tmp.lsr_start,
83                     (unsigned long long *)&tmp.lsr_end);
84         if (rc != 2)
85                 return -EINVAL;
86         if (!lu_seq_range_is_sane(&tmp) || lu_seq_range_is_zero(&tmp) ||
87             tmp.lsr_start < range->lsr_start || tmp.lsr_end > range->lsr_end)
88                 return -EINVAL;
89         *range = tmp;
90         return count;
91 }
92
93 /* Client side debugfs stuff */
94 static ssize_t
95 ldebugfs_fid_space_seq_write(struct file *file,
96                              const char __user *buffer,
97                              size_t count, loff_t *off)
98 {
99         struct lu_client_seq *seq;
100         int rc;
101
102         seq = ((struct seq_file *)file->private_data)->private;
103
104         mutex_lock(&seq->lcs_mutex);
105         rc = ldebugfs_fid_write_common(buffer, count, &seq->lcs_space);
106
107         if (rc == 0) {
108                 CDEBUG(D_INFO, "%s: Space: " DRANGE "\n",
109                        seq->lcs_name, PRANGE(&seq->lcs_space));
110         }
111
112         mutex_unlock(&seq->lcs_mutex);
113
114         return count;
115 }
116
117 static int
118 ldebugfs_fid_space_seq_show(struct seq_file *m, void *unused)
119 {
120         struct lu_client_seq *seq = (struct lu_client_seq *)m->private;
121
122         mutex_lock(&seq->lcs_mutex);
123         seq_printf(m, "[%#llx - %#llx]:%x:%s\n", PRANGE(&seq->lcs_space));
124         mutex_unlock(&seq->lcs_mutex);
125
126         return 0;
127 }
128
129 static ssize_t
130 ldebugfs_fid_width_seq_write(struct file *file,
131                              const char __user *buffer,
132                              size_t count, loff_t *off)
133 {
134         struct lu_client_seq *seq;
135         __u64  max;
136         int rc, val;
137
138         seq = ((struct seq_file *)file->private_data)->private;
139
140         rc = lprocfs_write_helper(buffer, count, &val);
141         if (rc)
142                 return rc;
143
144         mutex_lock(&seq->lcs_mutex);
145         if (seq->lcs_type == LUSTRE_SEQ_DATA)
146                 max = LUSTRE_DATA_SEQ_MAX_WIDTH;
147         else
148                 max = LUSTRE_METADATA_SEQ_MAX_WIDTH;
149
150         if (val <= max && val > 0) {
151                 seq->lcs_width = val;
152
153                 CDEBUG(D_INFO, "%s: Sequence size: %llu\n", seq->lcs_name,
154                        seq->lcs_width);
155         }
156
157         mutex_unlock(&seq->lcs_mutex);
158
159         return count;
160 }
161
162 static int
163 ldebugfs_fid_width_seq_show(struct seq_file *m, void *unused)
164 {
165         struct lu_client_seq *seq = (struct lu_client_seq *)m->private;
166
167         mutex_lock(&seq->lcs_mutex);
168         seq_printf(m, "%llu\n", seq->lcs_width);
169         mutex_unlock(&seq->lcs_mutex);
170
171         return 0;
172 }
173
174 static int
175 ldebugfs_fid_fid_seq_show(struct seq_file *m, void *unused)
176 {
177         struct lu_client_seq *seq = (struct lu_client_seq *)m->private;
178
179         mutex_lock(&seq->lcs_mutex);
180         seq_printf(m, DFID "\n", PFID(&seq->lcs_fid));
181         mutex_unlock(&seq->lcs_mutex);
182
183         return 0;
184 }
185
186 static int
187 ldebugfs_fid_server_seq_show(struct seq_file *m, void *unused)
188 {
189         struct lu_client_seq *seq = (struct lu_client_seq *)m->private;
190         struct client_obd *cli;
191
192         if (seq->lcs_exp) {
193                 cli = &seq->lcs_exp->exp_obd->u.cli;
194                 seq_printf(m, "%s\n", cli->cl_target_uuid.uuid);
195         }
196
197         return 0;
198 }
199
200 LPROC_SEQ_FOPS(ldebugfs_fid_space);
201 LPROC_SEQ_FOPS(ldebugfs_fid_width);
202 LPROC_SEQ_FOPS_RO(ldebugfs_fid_server);
203 LPROC_SEQ_FOPS_RO(ldebugfs_fid_fid);
204
205 struct lprocfs_vars seq_client_debugfs_list[] = {
206         { .name =       "space",
207           .fops =       &ldebugfs_fid_space_fops },
208         { .name =       "width",
209           .fops =       &ldebugfs_fid_width_fops },
210         { .name =       "server",
211           .fops =       &ldebugfs_fid_server_fops },
212         { .name =       "fid",
213           .fops =       &ldebugfs_fid_fid_fops },
214         { NULL }
215 };