Blame view
fs/afs/proc.c
14.2 KB
ec26815ad [AFS]: Clean up t... |
1 |
/* /proc interface for AFS |
1da177e4c Linux-2.6.12-rc2 |
2 3 4 5 6 7 8 9 10 |
* * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ |
1da177e4c Linux-2.6.12-rc2 |
11 12 13 14 |
#include <linux/slab.h> #include <linux/module.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> |
e8edc6e03 Detach sched.h fr... |
15 |
#include <linux/sched.h> |
7c0f6ba68 Replace <asm/uacc... |
16 |
#include <linux/uaccess.h> |
1da177e4c Linux-2.6.12-rc2 |
17 |
#include "internal.h" |
5b86d4ff5 afs: Implement ne... |
18 |
static inline struct afs_net *afs_seq2net(struct seq_file *m) |
f044c8847 afs: Lay the grou... |
19 |
{ |
5b86d4ff5 afs: Implement ne... |
20 |
return afs_net(seq_file_net(m)); |
f044c8847 afs: Lay the grou... |
21 |
} |
1da177e4c Linux-2.6.12-rc2 |
22 |
|
5b86d4ff5 afs: Implement ne... |
23 |
static inline struct afs_net *afs_seq2net_single(struct seq_file *m) |
f044c8847 afs: Lay the grou... |
24 |
{ |
5b86d4ff5 afs: Implement ne... |
25 |
return afs_net(seq_file_single_net(m)); |
f044c8847 afs: Lay the grou... |
26 |
} |
1da177e4c Linux-2.6.12-rc2 |
27 |
|
1da177e4c Linux-2.6.12-rc2 |
28 |
/* |
5d9de25d9 afs: Rearrange fs... |
29 |
* Display the list of cells known to the namespace. |
f06916895 afs: Rearrange fs... |
30 31 32 33 |
*/ static int afs_proc_cells_show(struct seq_file *m, void *v) { struct afs_cell *cell = list_entry(v, struct afs_cell, proc_link); |
f06916895 afs: Rearrange fs... |
34 |
|
6b3944e42 afs: Fix cell pro... |
35 |
if (v == SEQ_START_TOKEN) { |
f06916895 afs: Rearrange fs... |
36 37 38 39 40 41 42 43 44 45 46 |
/* display header on line 1 */ seq_puts(m, "USE NAME "); return 0; } /* display one cell per line on subsequent lines */ seq_printf(m, "%3u %s ", atomic_read(&cell->usage), cell->name); return 0; } |
1da177e4c Linux-2.6.12-rc2 |
47 |
static void *afs_proc_cells_start(struct seq_file *m, loff_t *_pos) |
fe342cf77 afs: Fix checker ... |
48 |
__acquires(rcu) |
1da177e4c Linux-2.6.12-rc2 |
49 |
{ |
989782dcd afs: Overhaul cel... |
50 |
rcu_read_lock(); |
6b3944e42 afs: Fix cell pro... |
51 |
return seq_hlist_start_head_rcu(&afs_seq2net(m)->proc_cells, *_pos); |
ec26815ad [AFS]: Clean up t... |
52 |
} |
1da177e4c Linux-2.6.12-rc2 |
53 |
|
f044c8847 afs: Lay the grou... |
54 |
static void *afs_proc_cells_next(struct seq_file *m, void *v, loff_t *pos) |
1da177e4c Linux-2.6.12-rc2 |
55 |
{ |
6b3944e42 afs: Fix cell pro... |
56 |
return seq_hlist_next_rcu(v, &afs_seq2net(m)->proc_cells, pos); |
ec26815ad [AFS]: Clean up t... |
57 |
} |
1da177e4c Linux-2.6.12-rc2 |
58 |
|
f044c8847 afs: Lay the grou... |
59 |
static void afs_proc_cells_stop(struct seq_file *m, void *v) |
fe342cf77 afs: Fix checker ... |
60 |
__releases(rcu) |
1da177e4c Linux-2.6.12-rc2 |
61 |
{ |
989782dcd afs: Overhaul cel... |
62 |
rcu_read_unlock(); |
ec26815ad [AFS]: Clean up t... |
63 |
} |
1da177e4c Linux-2.6.12-rc2 |
64 |
|
5d9de25d9 afs: Rearrange fs... |
65 66 67 68 69 70 |
static const struct seq_operations afs_proc_cells_ops = { .start = afs_proc_cells_start, .next = afs_proc_cells_next, .stop = afs_proc_cells_stop, .show = afs_proc_cells_show, }; |
1da177e4c Linux-2.6.12-rc2 |
71 |
/* |
1da177e4c Linux-2.6.12-rc2 |
72 73 74 |
* handle writes to /proc/fs/afs/cells * - to add cells: echo "add <cellname> <IP>[:<IP>][:<IP>]" */ |
5b86d4ff5 afs: Implement ne... |
75 |
static int afs_proc_cells_write(struct file *file, char *buf, size_t size) |
1da177e4c Linux-2.6.12-rc2 |
76 |
{ |
5b86d4ff5 afs: Implement ne... |
77 78 79 |
struct seq_file *m = file->private_data; struct afs_net *net = afs_seq2net(m); char *name, *args; |
1da177e4c Linux-2.6.12-rc2 |
80 |
int ret; |
1da177e4c Linux-2.6.12-rc2 |
81 |
/* trim to first NL */ |
5b86d4ff5 afs: Implement ne... |
82 83 |
name = memchr(buf, ' ', size); |
1da177e4c Linux-2.6.12-rc2 |
84 85 86 87 |
if (name) *name = 0; /* split into command, name and argslist */ |
5b86d4ff5 afs: Implement ne... |
88 |
name = strchr(buf, ' '); |
1da177e4c Linux-2.6.12-rc2 |
89 90 91 92 93 94 95 96 97 |
if (!name) goto inval; do { *name++ = 0; } while(*name == ' '); if (!*name) goto inval; args = strchr(name, ' '); |
ecfe951f0 afs: Fix cell spe... |
98 99 100 101 102 103 104 |
if (args) { do { *args++ = 0; } while(*args == ' '); if (!*args) goto inval; } |
1da177e4c Linux-2.6.12-rc2 |
105 106 |
/* determine command to perform */ |
5b86d4ff5 afs: Implement ne... |
107 |
_debug("cmd=%s name=%s args=%s", buf, name, args); |
1da177e4c Linux-2.6.12-rc2 |
108 |
|
5b86d4ff5 afs: Implement ne... |
109 |
if (strcmp(buf, "add") == 0) { |
1da177e4c Linux-2.6.12-rc2 |
110 |
struct afs_cell *cell; |
08e0e7c82 [AF_RXRPC]: Make ... |
111 |
|
989782dcd afs: Overhaul cel... |
112 |
cell = afs_lookup_cell(net, name, strlen(name), args, true); |
08e0e7c82 [AF_RXRPC]: Make ... |
113 114 |
if (IS_ERR(cell)) { ret = PTR_ERR(cell); |
1da177e4c Linux-2.6.12-rc2 |
115 |
goto done; |
08e0e7c82 [AF_RXRPC]: Make ... |
116 |
} |
1da177e4c Linux-2.6.12-rc2 |
117 |
|
17814aef5 afs: Don't over-i... |
118 119 |
if (test_and_set_bit(AFS_CELL_FL_NO_GC, &cell->flags)) afs_put_cell(net, cell); |
ec26815ad [AFS]: Clean up t... |
120 |
} else { |
1da177e4c Linux-2.6.12-rc2 |
121 122 |
goto inval; } |
5b86d4ff5 afs: Implement ne... |
123 |
ret = 0; |
1da177e4c Linux-2.6.12-rc2 |
124 |
|
ec26815ad [AFS]: Clean up t... |
125 |
done: |
1da177e4c Linux-2.6.12-rc2 |
126 127 |
_leave(" = %d", ret); return ret; |
ec26815ad [AFS]: Clean up t... |
128 |
inval: |
1da177e4c Linux-2.6.12-rc2 |
129 130 131 132 |
ret = -EINVAL; printk("kAFS: Invalid Command on /proc/fs/afs/cells file "); goto done; |
ec26815ad [AFS]: Clean up t... |
133 |
} |
1da177e4c Linux-2.6.12-rc2 |
134 |
|
5d9de25d9 afs: Rearrange fs... |
135 |
/* |
5b86d4ff5 afs: Implement ne... |
136 |
* Display the name of the current workstation cell. |
5d9de25d9 afs: Rearrange fs... |
137 |
*/ |
5b86d4ff5 afs: Implement ne... |
138 |
static int afs_proc_rootcell_show(struct seq_file *m, void *v) |
1da177e4c Linux-2.6.12-rc2 |
139 |
{ |
37ab63688 afs: Implement @c... |
140 |
struct afs_cell *cell; |
5b86d4ff5 afs: Implement ne... |
141 142 143 144 145 146 147 148 149 150 151 152 |
struct afs_net *net; net = afs_seq2net_single(m); if (rcu_access_pointer(net->ws_cell)) { rcu_read_lock(); cell = rcu_dereference(net->ws_cell); if (cell) seq_printf(m, "%s ", cell->name); rcu_read_unlock(); } return 0; |
1da177e4c Linux-2.6.12-rc2 |
153 |
} |
1da177e4c Linux-2.6.12-rc2 |
154 |
/* |
5d9de25d9 afs: Rearrange fs... |
155 156 157 158 |
* Set the current workstation cell and optionally supply its list of volume * location servers. * * echo "cell.name:192.168.231.14" >/proc/fs/afs/rootcell |
1da177e4c Linux-2.6.12-rc2 |
159 |
*/ |
5b86d4ff5 afs: Implement ne... |
160 |
static int afs_proc_rootcell_write(struct file *file, char *buf, size_t size) |
1da177e4c Linux-2.6.12-rc2 |
161 |
{ |
5b86d4ff5 afs: Implement ne... |
162 163 164 |
struct seq_file *m = file->private_data; struct afs_net *net = afs_seq2net_single(m); char *s; |
1da177e4c Linux-2.6.12-rc2 |
165 |
int ret; |
6f8880d8e afs: Implement @s... |
166 |
ret = -EINVAL; |
5b86d4ff5 afs: Implement ne... |
167 |
if (buf[0] == '.') |
6f8880d8e afs: Implement @s... |
168 |
goto out; |
5b86d4ff5 afs: Implement ne... |
169 |
if (memchr(buf, '/', size)) |
6f8880d8e afs: Implement @s... |
170 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
171 |
/* trim to first NL */ |
5b86d4ff5 afs: Implement ne... |
172 173 |
s = memchr(buf, ' ', size); |
1da177e4c Linux-2.6.12-rc2 |
174 175 176 177 |
if (s) *s = 0; /* determine command to perform */ |
5b86d4ff5 afs: Implement ne... |
178 |
_debug("rootcell=%s", buf); |
1da177e4c Linux-2.6.12-rc2 |
179 |
|
5b86d4ff5 afs: Implement ne... |
180 |
ret = afs_cell_init(net, buf); |
1da177e4c Linux-2.6.12-rc2 |
181 |
|
6f8880d8e afs: Implement @s... |
182 |
out: |
1da177e4c Linux-2.6.12-rc2 |
183 184 |
_leave(" = %d", ret); return ret; |
ec26815ad [AFS]: Clean up t... |
185 |
} |
1da177e4c Linux-2.6.12-rc2 |
186 |
|
f06916895 afs: Rearrange fs... |
187 188 189 190 191 192 193 |
static const char afs_vol_types[3][3] = { [AFSVL_RWVOL] = "RW", [AFSVL_ROVOL] = "RO", [AFSVL_BACKVOL] = "BK", }; /* |
5d9de25d9 afs: Rearrange fs... |
194 |
* Display the list of volumes known to a cell. |
f06916895 afs: Rearrange fs... |
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
*/ static int afs_proc_cell_volumes_show(struct seq_file *m, void *v) { struct afs_cell *cell = PDE_DATA(file_inode(m->file)); struct afs_volume *vol = list_entry(v, struct afs_volume, proc_link); /* Display header on line 1 */ if (v == &cell->proc_volumes) { seq_puts(m, "USE VID TY "); return 0; } seq_printf(m, "%3d %08x %s ", atomic_read(&vol->usage), vol->vid, afs_vol_types[vol->type]); return 0; } |
1da177e4c Linux-2.6.12-rc2 |
215 |
static void *afs_proc_cell_volumes_start(struct seq_file *m, loff_t *_pos) |
fe342cf77 afs: Fix checker ... |
216 |
__acquires(cell->proc_lock) |
1da177e4c Linux-2.6.12-rc2 |
217 |
{ |
353861cf0 afs: simplify pro... |
218 |
struct afs_cell *cell = PDE_DATA(file_inode(m->file)); |
1da177e4c Linux-2.6.12-rc2 |
219 |
|
d2ddc776a afs: Overhaul vol... |
220 221 |
read_lock(&cell->proc_lock); return seq_list_start_head(&cell->proc_volumes, *_pos); |
ec26815ad [AFS]: Clean up t... |
222 |
} |
1da177e4c Linux-2.6.12-rc2 |
223 |
|
5b86d4ff5 afs: Implement ne... |
224 |
static void *afs_proc_cell_volumes_next(struct seq_file *m, void *v, |
1da177e4c Linux-2.6.12-rc2 |
225 226 |
loff_t *_pos) { |
5b86d4ff5 afs: Implement ne... |
227 |
struct afs_cell *cell = PDE_DATA(file_inode(m->file)); |
1da177e4c Linux-2.6.12-rc2 |
228 |
|
d2ddc776a afs: Overhaul vol... |
229 |
return seq_list_next(v, &cell->proc_volumes, _pos); |
ec26815ad [AFS]: Clean up t... |
230 |
} |
1da177e4c Linux-2.6.12-rc2 |
231 |
|
5b86d4ff5 afs: Implement ne... |
232 |
static void afs_proc_cell_volumes_stop(struct seq_file *m, void *v) |
fe342cf77 afs: Fix checker ... |
233 |
__releases(cell->proc_lock) |
1da177e4c Linux-2.6.12-rc2 |
234 |
{ |
5b86d4ff5 afs: Implement ne... |
235 |
struct afs_cell *cell = PDE_DATA(file_inode(m->file)); |
1da177e4c Linux-2.6.12-rc2 |
236 |
|
d2ddc776a afs: Overhaul vol... |
237 |
read_unlock(&cell->proc_lock); |
ec26815ad [AFS]: Clean up t... |
238 |
} |
1da177e4c Linux-2.6.12-rc2 |
239 |
|
5d9de25d9 afs: Rearrange fs... |
240 241 242 243 244 245 |
static const struct seq_operations afs_proc_cell_volumes_ops = { .start = afs_proc_cell_volumes_start, .next = afs_proc_cell_volumes_next, .stop = afs_proc_cell_volumes_stop, .show = afs_proc_cell_volumes_show, }; |
1da177e4c Linux-2.6.12-rc2 |
246 |
/* |
5d9de25d9 afs: Rearrange fs... |
247 |
* Display the list of Volume Location servers we're using for a cell. |
1da177e4c Linux-2.6.12-rc2 |
248 |
*/ |
f06916895 afs: Rearrange fs... |
249 |
static int afs_proc_cell_vlservers_show(struct seq_file *m, void *v) |
1da177e4c Linux-2.6.12-rc2 |
250 |
{ |
f06916895 afs: Rearrange fs... |
251 |
struct sockaddr_rxrpc *addr = v; |
1da177e4c Linux-2.6.12-rc2 |
252 |
|
f06916895 afs: Rearrange fs... |
253 254 255 256 |
/* display header on line 1 */ if (v == (void *)1) { seq_puts(m, "ADDRESS "); |
1da177e4c Linux-2.6.12-rc2 |
257 258 |
return 0; } |
f06916895 afs: Rearrange fs... |
259 260 261 |
/* display one cell per line on subsequent lines */ seq_printf(m, "%pISp ", &addr->transport); |
1da177e4c Linux-2.6.12-rc2 |
262 |
return 0; |
ec26815ad [AFS]: Clean up t... |
263 |
} |
1da177e4c Linux-2.6.12-rc2 |
264 |
|
1da177e4c Linux-2.6.12-rc2 |
265 |
static void *afs_proc_cell_vlservers_start(struct seq_file *m, loff_t *_pos) |
fe342cf77 afs: Fix checker ... |
266 |
__acquires(rcu) |
1da177e4c Linux-2.6.12-rc2 |
267 |
{ |
8b2a464ce afs: Add an addre... |
268 |
struct afs_addr_list *alist; |
353861cf0 afs: simplify pro... |
269 |
struct afs_cell *cell = PDE_DATA(file_inode(m->file)); |
1da177e4c Linux-2.6.12-rc2 |
270 |
loff_t pos = *_pos; |
8b2a464ce afs: Add an addre... |
271 |
rcu_read_lock(); |
1da177e4c Linux-2.6.12-rc2 |
272 |
|
8b2a464ce afs: Add an addre... |
273 |
alist = rcu_dereference(cell->vl_addrs); |
1da177e4c Linux-2.6.12-rc2 |
274 275 276 277 278 |
/* allow for the header line */ if (!pos) return (void *) 1; pos--; |
8b2a464ce afs: Add an addre... |
279 |
if (!alist || pos >= alist->nr_addrs) |
1da177e4c Linux-2.6.12-rc2 |
280 |
return NULL; |
8b2a464ce afs: Add an addre... |
281 |
return alist->addrs + pos; |
ec26815ad [AFS]: Clean up t... |
282 |
} |
1da177e4c Linux-2.6.12-rc2 |
283 |
|
5b86d4ff5 afs: Implement ne... |
284 |
static void *afs_proc_cell_vlservers_next(struct seq_file *m, void *v, |
1da177e4c Linux-2.6.12-rc2 |
285 286 |
loff_t *_pos) { |
8b2a464ce afs: Add an addre... |
287 |
struct afs_addr_list *alist; |
5b86d4ff5 afs: Implement ne... |
288 |
struct afs_cell *cell = PDE_DATA(file_inode(m->file)); |
1da177e4c Linux-2.6.12-rc2 |
289 |
loff_t pos; |
8b2a464ce afs: Add an addre... |
290 |
alist = rcu_dereference(cell->vl_addrs); |
1da177e4c Linux-2.6.12-rc2 |
291 292 293 |
pos = *_pos; (*_pos)++; |
8b2a464ce afs: Add an addre... |
294 |
if (!alist || pos >= alist->nr_addrs) |
1da177e4c Linux-2.6.12-rc2 |
295 |
return NULL; |
8b2a464ce afs: Add an addre... |
296 |
return alist->addrs + pos; |
ec26815ad [AFS]: Clean up t... |
297 |
} |
1da177e4c Linux-2.6.12-rc2 |
298 |
|
5b86d4ff5 afs: Implement ne... |
299 |
static void afs_proc_cell_vlservers_stop(struct seq_file *m, void *v) |
fe342cf77 afs: Fix checker ... |
300 |
__releases(rcu) |
1da177e4c Linux-2.6.12-rc2 |
301 |
{ |
8b2a464ce afs: Add an addre... |
302 |
rcu_read_unlock(); |
ec26815ad [AFS]: Clean up t... |
303 |
} |
1da177e4c Linux-2.6.12-rc2 |
304 |
|
5d9de25d9 afs: Rearrange fs... |
305 306 307 308 309 310 |
static const struct seq_operations afs_proc_cell_vlservers_ops = { .start = afs_proc_cell_vlservers_start, .next = afs_proc_cell_vlservers_next, .stop = afs_proc_cell_vlservers_stop, .show = afs_proc_cell_vlservers_show, }; |
1da177e4c Linux-2.6.12-rc2 |
311 |
/* |
5d9de25d9 afs: Rearrange fs... |
312 |
* Display the list of fileservers we're using within a namespace. |
1da177e4c Linux-2.6.12-rc2 |
313 |
*/ |
f06916895 afs: Rearrange fs... |
314 |
static int afs_proc_servers_show(struct seq_file *m, void *v) |
1da177e4c Linux-2.6.12-rc2 |
315 |
{ |
f06916895 afs: Rearrange fs... |
316 317 |
struct afs_server *server; struct afs_addr_list *alist; |
0aac4bce4 afs: Show all of ... |
318 |
int i; |
1da177e4c Linux-2.6.12-rc2 |
319 |
|
f06916895 afs: Rearrange fs... |
320 321 322 |
if (v == SEQ_START_TOKEN) { seq_puts(m, "UUID USE ADDR "); |
1da177e4c Linux-2.6.12-rc2 |
323 324 |
return 0; } |
f06916895 afs: Rearrange fs... |
325 326 |
server = list_entry(v, struct afs_server, proc_link); alist = rcu_dereference(server->addresses); |
0aac4bce4 afs: Show all of ... |
327 328 |
seq_printf(m, "%pU %3d %pISpc%s ", |
f06916895 afs: Rearrange fs... |
329 330 |
&server->uuid, atomic_read(&server->usage), |
0aac4bce4 afs: Show all of ... |
331 332 333 334 335 336 337 |
&alist->addrs[0].transport, alist->index == 0 ? "*" : ""); for (i = 1; i < alist->nr_addrs; i++) seq_printf(m, " %pISpc%s ", &alist->addrs[i].transport, alist->index == i ? "*" : ""); |
1da177e4c Linux-2.6.12-rc2 |
338 |
return 0; |
ec26815ad [AFS]: Clean up t... |
339 |
} |
1da177e4c Linux-2.6.12-rc2 |
340 |
|
d2ddc776a afs: Overhaul vol... |
341 |
static void *afs_proc_servers_start(struct seq_file *m, loff_t *_pos) |
fe342cf77 afs: Fix checker ... |
342 |
__acquires(rcu) |
1da177e4c Linux-2.6.12-rc2 |
343 |
{ |
d2ddc776a afs: Overhaul vol... |
344 |
rcu_read_lock(); |
5d9de25d9 afs: Rearrange fs... |
345 |
return seq_hlist_start_head_rcu(&afs_seq2net(m)->fs_proc, *_pos); |
ec26815ad [AFS]: Clean up t... |
346 |
} |
1da177e4c Linux-2.6.12-rc2 |
347 |
|
d2ddc776a afs: Overhaul vol... |
348 |
static void *afs_proc_servers_next(struct seq_file *m, void *v, loff_t *_pos) |
1da177e4c Linux-2.6.12-rc2 |
349 |
{ |
5d9de25d9 afs: Rearrange fs... |
350 |
return seq_hlist_next_rcu(v, &afs_seq2net(m)->fs_proc, _pos); |
ec26815ad [AFS]: Clean up t... |
351 |
} |
1da177e4c Linux-2.6.12-rc2 |
352 |
|
5b86d4ff5 afs: Implement ne... |
353 |
static void afs_proc_servers_stop(struct seq_file *m, void *v) |
fe342cf77 afs: Fix checker ... |
354 |
__releases(rcu) |
1da177e4c Linux-2.6.12-rc2 |
355 |
{ |
d2ddc776a afs: Overhaul vol... |
356 |
rcu_read_unlock(); |
ec26815ad [AFS]: Clean up t... |
357 |
} |
1da177e4c Linux-2.6.12-rc2 |
358 |
|
5d9de25d9 afs: Rearrange fs... |
359 360 361 362 363 364 |
static const struct seq_operations afs_proc_servers_ops = { .start = afs_proc_servers_start, .next = afs_proc_servers_next, .stop = afs_proc_servers_stop, .show = afs_proc_servers_show, }; |
6f8880d8e afs: Implement @s... |
365 |
|
6f8880d8e afs: Implement @s... |
366 |
/* |
5d9de25d9 afs: Rearrange fs... |
367 368 |
* Display the list of strings that may be substituted for the @sys pathname * macro. |
6f8880d8e afs: Implement @s... |
369 |
*/ |
5d9de25d9 afs: Rearrange fs... |
370 |
static int afs_proc_sysname_show(struct seq_file *m, void *v) |
6f8880d8e afs: Implement @s... |
371 |
{ |
5d9de25d9 afs: Rearrange fs... |
372 373 374 |
struct afs_net *net = afs_seq2net(m); struct afs_sysnames *sysnames = net->sysnames; unsigned int i = (unsigned long)v - 1; |
6f8880d8e afs: Implement @s... |
375 |
|
5d9de25d9 afs: Rearrange fs... |
376 377 378 379 380 |
if (i < sysnames->nr) seq_printf(m, "%s ", sysnames->subs[i]); return 0; } |
6f8880d8e afs: Implement @s... |
381 |
|
5d9de25d9 afs: Rearrange fs... |
382 383 384 385 |
static void *afs_proc_sysname_start(struct seq_file *m, loff_t *pos) __acquires(&net->sysnames_lock) { struct afs_net *net = afs_seq2net(m); |
5b86d4ff5 afs: Implement ne... |
386 |
struct afs_sysnames *names; |
6f8880d8e afs: Implement @s... |
387 |
|
5d9de25d9 afs: Rearrange fs... |
388 |
read_lock(&net->sysnames_lock); |
6f8880d8e afs: Implement @s... |
389 |
|
5b86d4ff5 afs: Implement ne... |
390 |
names = net->sysnames; |
5d9de25d9 afs: Rearrange fs... |
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 |
if (*pos >= names->nr) return NULL; return (void *)(unsigned long)(*pos + 1); } static void *afs_proc_sysname_next(struct seq_file *m, void *v, loff_t *pos) { struct afs_net *net = afs_seq2net(m); struct afs_sysnames *names = net->sysnames; *pos += 1; if (*pos >= names->nr) return NULL; return (void *)(unsigned long)(*pos + 1); } static void afs_proc_sysname_stop(struct seq_file *m, void *v) __releases(&net->sysnames_lock) { struct afs_net *net = afs_seq2net(m); read_unlock(&net->sysnames_lock); |
6f8880d8e afs: Implement @s... |
413 |
} |
5d9de25d9 afs: Rearrange fs... |
414 415 416 417 418 419 |
static const struct seq_operations afs_proc_sysname_ops = { .start = afs_proc_sysname_start, .next = afs_proc_sysname_next, .stop = afs_proc_sysname_stop, .show = afs_proc_sysname_show, }; |
6f8880d8e afs: Implement @s... |
420 |
/* |
5d9de25d9 afs: Rearrange fs... |
421 |
* Allow the @sys substitution to be configured. |
6f8880d8e afs: Implement @s... |
422 |
*/ |
5b86d4ff5 afs: Implement ne... |
423 |
static int afs_proc_sysname_write(struct file *file, char *buf, size_t size) |
6f8880d8e afs: Implement @s... |
424 |
{ |
5b86d4ff5 afs: Implement ne... |
425 |
struct afs_sysnames *sysnames, *kill; |
6f8880d8e afs: Implement @s... |
426 |
struct seq_file *m = file->private_data; |
5b86d4ff5 afs: Implement ne... |
427 428 |
struct afs_net *net = afs_seq2net(m); char *s, *p, *sub; |
6f8880d8e afs: Implement @s... |
429 |
int ret, len; |
5b86d4ff5 afs: Implement ne... |
430 |
sysnames = kzalloc(sizeof(*sysnames), GFP_KERNEL); |
6f8880d8e afs: Implement @s... |
431 |
if (!sysnames) |
5b86d4ff5 afs: Implement ne... |
432 433 434 |
return -ENOMEM; refcount_set(&sysnames->usage, 1); kill = sysnames; |
6f8880d8e afs: Implement @s... |
435 |
|
5b86d4ff5 afs: Implement ne... |
436 |
p = buf; |
6f8880d8e afs: Implement @s... |
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 |
while ((s = strsep(&p, " \t "))) { len = strlen(s); if (len == 0) continue; ret = -ENAMETOOLONG; if (len >= AFSNAMEMAX) goto error; if (len >= 4 && s[len - 4] == '@' && s[len - 3] == 's' && s[len - 2] == 'y' && s[len - 1] == 's') /* Protect against recursion */ goto invalid; if (s[0] == '.' && (len < 2 || (len == 2 && s[1] == '.'))) goto invalid; if (memchr(s, '/', len)) goto invalid; ret = -EFBIG; if (sysnames->nr >= AFS_NR_SYSNAME) goto out; if (strcmp(s, afs_init_sysname) == 0) { sub = (char *)afs_init_sysname; } else { ret = -ENOMEM; sub = kmemdup(s, len + 1, GFP_KERNEL); if (!sub) goto out; } sysnames->subs[sysnames->nr] = sub; sysnames->nr++; } |
5b86d4ff5 afs: Implement ne... |
477 478 479 480 481 482 483 484 485 486 |
if (sysnames->nr == 0) { sysnames->subs[0] = sysnames->blank; sysnames->nr++; } write_lock(&net->sysnames_lock); kill = net->sysnames; net->sysnames = sysnames; write_unlock(&net->sysnames_lock); ret = 0; |
6f8880d8e afs: Implement @s... |
487 |
out: |
5b86d4ff5 afs: Implement ne... |
488 |
afs_put_sysnames(kill); |
6f8880d8e afs: Implement @s... |
489 490 491 492 493 |
return ret; invalid: ret = -EINVAL; error: |
6f8880d8e afs: Implement @s... |
494 495 |
goto out; } |
5d9de25d9 afs: Rearrange fs... |
496 497 498 499 500 501 502 503 504 505 506 |
void afs_put_sysnames(struct afs_sysnames *sysnames) { int i; if (sysnames && refcount_dec_and_test(&sysnames->usage)) { for (i = 0; i < sysnames->nr; i++) if (sysnames->subs[i] != afs_init_sysname && sysnames->subs[i] != sysnames->blank) kfree(sysnames->subs[i]); } } |
d55b4da43 afs: Introduce a ... |
507 508 509 510 511 |
/* * Display general per-net namespace statistics */ static int afs_proc_stats_show(struct seq_file *m, void *v) { |
5b86d4ff5 afs: Implement ne... |
512 |
struct afs_net *net = afs_seq2net_single(m); |
d55b4da43 afs: Introduce a ... |
513 514 515 |
seq_puts(m, "kAFS statistics "); |
f3ddee8dc afs: Fix director... |
516 517 |
seq_printf(m, "dir-mgmt: look=%u reval=%u inval=%u relpg=%u ", |
d55b4da43 afs: Introduce a ... |
518 519 |
atomic_read(&net->n_lookup), atomic_read(&net->n_reval), |
f3ddee8dc afs: Fix director... |
520 521 |
atomic_read(&net->n_inval), atomic_read(&net->n_relpg)); |
d55b4da43 afs: Introduce a ... |
522 523 524 525 |
seq_printf(m, "dir-data: rdpg=%u ", atomic_read(&net->n_read_dir)); |
63a4681ff afs: Locally edit... |
526 527 528 529 530 |
seq_printf(m, "dir-edit: cr=%u rm=%u ", atomic_read(&net->n_dir_cr), atomic_read(&net->n_dir_rm)); |
76a5cb6fc afs: Add stats fo... |
531 532 533 534 535 536 537 538 539 |
seq_printf(m, "file-rd : n=%u nb=%lu ", atomic_read(&net->n_fetches), atomic_long_read(&net->n_fetch_bytes)); seq_printf(m, "file-wr : n=%u nb=%lu ", atomic_read(&net->n_stores), atomic_long_read(&net->n_store_bytes)); |
d55b4da43 afs: Introduce a ... |
540 541 |
return 0; } |
10495a007 afs: Move /proc m... |
542 543 544 545 |
/* * initialise /proc/fs/afs/<cell>/ */ |
5b86d4ff5 afs: Implement ne... |
546 |
int afs_proc_cell_setup(struct afs_cell *cell) |
10495a007 afs: Move /proc m... |
547 548 |
{ struct proc_dir_entry *dir; |
5b86d4ff5 afs: Implement ne... |
549 |
struct afs_net *net = cell->net; |
10495a007 afs: Move /proc m... |
550 551 |
_enter("%p{%s},%p", cell, cell->name, net->proc_afs); |
5b86d4ff5 afs: Implement ne... |
552 |
dir = proc_net_mkdir(net->net, cell->name, net->proc_afs); |
10495a007 afs: Move /proc m... |
553 554 |
if (!dir) goto error_dir; |
5b86d4ff5 afs: Implement ne... |
555 556 557 558 559 560 561 562 |
if (!proc_create_net_data("vlservers", 0444, dir, &afs_proc_cell_vlservers_ops, sizeof(struct seq_net_private), cell) || !proc_create_net_data("volumes", 0444, dir, &afs_proc_cell_volumes_ops, sizeof(struct seq_net_private), cell)) |
10495a007 afs: Move /proc m... |
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 |
goto error_tree; _leave(" = 0"); return 0; error_tree: remove_proc_subtree(cell->name, net->proc_afs); error_dir: _leave(" = -ENOMEM"); return -ENOMEM; } /* * remove /proc/fs/afs/<cell>/ */ |
5b86d4ff5 afs: Implement ne... |
578 |
void afs_proc_cell_remove(struct afs_cell *cell) |
10495a007 afs: Move /proc m... |
579 |
{ |
5b86d4ff5 afs: Implement ne... |
580 |
struct afs_net *net = cell->net; |
10495a007 afs: Move /proc m... |
581 |
|
5b86d4ff5 afs: Implement ne... |
582 |
_enter(""); |
10495a007 afs: Move /proc m... |
583 |
remove_proc_subtree(cell->name, net->proc_afs); |
10495a007 afs: Move /proc m... |
584 585 586 587 588 589 590 591 |
_leave(""); } /* * initialise the /proc/fs/afs/ directory */ int afs_proc_init(struct afs_net *net) { |
5b86d4ff5 afs: Implement ne... |
592 |
struct proc_dir_entry *p; |
10495a007 afs: Move /proc m... |
593 |
_enter(""); |
5b86d4ff5 afs: Implement ne... |
594 595 |
p = proc_net_mkdir(net->net, "afs", net->net->proc_net); if (!p) |
10495a007 afs: Move /proc m... |
596 |
goto error_dir; |
5b86d4ff5 afs: Implement ne... |
597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 |
if (!proc_create_net_data_write("cells", 0644, p, &afs_proc_cells_ops, afs_proc_cells_write, sizeof(struct seq_net_private), NULL) || !proc_create_net_single_write("rootcell", 0644, p, afs_proc_rootcell_show, afs_proc_rootcell_write, NULL) || !proc_create_net("servers", 0444, p, &afs_proc_servers_ops, sizeof(struct seq_net_private)) || !proc_create_net_single("stats", 0444, p, afs_proc_stats_show, NULL) || !proc_create_net_data_write("sysname", 0644, p, &afs_proc_sysname_ops, afs_proc_sysname_write, sizeof(struct seq_net_private), NULL)) |
10495a007 afs: Move /proc m... |
614 |
goto error_tree; |
5b86d4ff5 afs: Implement ne... |
615 |
net->proc_afs = p; |
10495a007 afs: Move /proc m... |
616 617 618 619 |
_leave(" = 0"); return 0; error_tree: |
5b86d4ff5 afs: Implement ne... |
620 |
proc_remove(p); |
10495a007 afs: Move /proc m... |
621 622 623 624 625 626 627 628 629 630 631 632 633 |
error_dir: _leave(" = -ENOMEM"); return -ENOMEM; } /* * clean up the /proc/fs/afs/ directory */ void afs_proc_cleanup(struct afs_net *net) { proc_remove(net->proc_afs); net->proc_afs = NULL; } |