Commit | Line | Data |
---|---|---|
5174fdab | 1 | /* |
bd238fb4 | 2 | * net/9p/fcprint.c |
5174fdab LI |
3 | * |
4 | * Print 9P call. | |
5 | * | |
6 | * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net> | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify | |
42e8c509 EVH |
9 | * it under the terms of the GNU General Public License version 2 |
10 | * as published by the Free Software Foundation. | |
5174fdab LI |
11 | * |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with this program; if not, write to: | |
19 | * Free Software Foundation | |
20 | * 51 Franklin Street, Fifth Floor | |
21 | * Boston, MA 02111-1301 USA | |
22 | * | |
23 | */ | |
5174fdab LI |
24 | #include <linux/module.h> |
25 | #include <linux/errno.h> | |
26 | #include <linux/fs.h> | |
27 | #include <linux/idr.h> | |
bd238fb4 | 28 | #include <net/9p/9p.h> |
5174fdab | 29 | |
bd238fb4 | 30 | #ifdef CONFIG_NET_9P_DEBUG |
5174fdab LI |
31 | |
32 | static int | |
bd238fb4 | 33 | p9_printqid(char *buf, int buflen, struct p9_qid *q) |
5174fdab LI |
34 | { |
35 | int n; | |
36 | char b[10]; | |
37 | ||
38 | n = 0; | |
bd238fb4 | 39 | if (q->type & P9_QTDIR) |
5174fdab | 40 | b[n++] = 'd'; |
bd238fb4 | 41 | if (q->type & P9_QTAPPEND) |
5174fdab | 42 | b[n++] = 'a'; |
bd238fb4 | 43 | if (q->type & P9_QTAUTH) |
5174fdab | 44 | b[n++] = 'A'; |
bd238fb4 | 45 | if (q->type & P9_QTEXCL) |
5174fdab | 46 | b[n++] = 'l'; |
bd238fb4 | 47 | if (q->type & P9_QTTMP) |
5174fdab | 48 | b[n++] = 't'; |
bd238fb4 | 49 | if (q->type & P9_QTSYMLINK) |
5174fdab LI |
50 | b[n++] = 'L'; |
51 | b[n] = '\0'; | |
52 | ||
bd238fb4 LI |
53 | return scnprintf(buf, buflen, "(%.16llx %x %s)", |
54 | (long long int) q->path, q->version, b); | |
5174fdab LI |
55 | } |
56 | ||
57 | static int | |
bd238fb4 | 58 | p9_printperm(char *buf, int buflen, int perm) |
5174fdab LI |
59 | { |
60 | int n; | |
61 | char b[15]; | |
62 | ||
63 | n = 0; | |
bd238fb4 | 64 | if (perm & P9_DMDIR) |
5174fdab | 65 | b[n++] = 'd'; |
bd238fb4 | 66 | if (perm & P9_DMAPPEND) |
5174fdab | 67 | b[n++] = 'a'; |
bd238fb4 | 68 | if (perm & P9_DMAUTH) |
5174fdab | 69 | b[n++] = 'A'; |
bd238fb4 | 70 | if (perm & P9_DMEXCL) |
5174fdab | 71 | b[n++] = 'l'; |
bd238fb4 | 72 | if (perm & P9_DMTMP) |
5174fdab | 73 | b[n++] = 't'; |
bd238fb4 | 74 | if (perm & P9_DMDEVICE) |
5174fdab | 75 | b[n++] = 'D'; |
bd238fb4 | 76 | if (perm & P9_DMSOCKET) |
5174fdab | 77 | b[n++] = 'S'; |
bd238fb4 | 78 | if (perm & P9_DMNAMEDPIPE) |
5174fdab | 79 | b[n++] = 'P'; |
bd238fb4 | 80 | if (perm & P9_DMSYMLINK) |
5174fdab LI |
81 | b[n++] = 'L'; |
82 | b[n] = '\0'; | |
83 | ||
84 | return scnprintf(buf, buflen, "%s%03o", b, perm&077); | |
85 | } | |
86 | ||
87 | static int | |
bd238fb4 | 88 | p9_printstat(char *buf, int buflen, struct p9_stat *st, int extended) |
5174fdab LI |
89 | { |
90 | int n; | |
91 | ||
92 | n = scnprintf(buf, buflen, "'%.*s' '%.*s'", st->name.len, | |
93 | st->name.str, st->uid.len, st->uid.str); | |
94 | if (extended) | |
95 | n += scnprintf(buf+n, buflen-n, "(%d)", st->n_uid); | |
96 | ||
97 | n += scnprintf(buf+n, buflen-n, " '%.*s'", st->gid.len, st->gid.str); | |
98 | if (extended) | |
99 | n += scnprintf(buf+n, buflen-n, "(%d)", st->n_gid); | |
100 | ||
101 | n += scnprintf(buf+n, buflen-n, " '%.*s'", st->muid.len, st->muid.str); | |
102 | if (extended) | |
103 | n += scnprintf(buf+n, buflen-n, "(%d)", st->n_muid); | |
104 | ||
105 | n += scnprintf(buf+n, buflen-n, " q "); | |
bd238fb4 | 106 | n += p9_printqid(buf+n, buflen-n, &st->qid); |
5174fdab | 107 | n += scnprintf(buf+n, buflen-n, " m "); |
bd238fb4 | 108 | n += p9_printperm(buf+n, buflen-n, st->mode); |
5174fdab LI |
109 | n += scnprintf(buf+n, buflen-n, " at %d mt %d l %lld", |
110 | st->atime, st->mtime, (long long int) st->length); | |
111 | ||
112 | if (extended) | |
113 | n += scnprintf(buf+n, buflen-n, " ext '%.*s'", | |
114 | st->extension.len, st->extension.str); | |
115 | ||
116 | return n; | |
117 | } | |
118 | ||
119 | static int | |
bd238fb4 | 120 | p9_dumpdata(char *buf, int buflen, u8 *data, int datalen) |
5174fdab LI |
121 | { |
122 | int i, n; | |
123 | ||
124 | i = n = 0; | |
125 | while (i < datalen) { | |
126 | n += scnprintf(buf + n, buflen - n, "%02x", data[i]); | |
127 | if (i%4 == 3) | |
128 | n += scnprintf(buf + n, buflen - n, " "); | |
129 | if (i%32 == 31) | |
130 | n += scnprintf(buf + n, buflen - n, "\n"); | |
131 | ||
132 | i++; | |
133 | } | |
134 | n += scnprintf(buf + n, buflen - n, "\n"); | |
135 | ||
136 | return n; | |
137 | } | |
138 | ||
139 | static int | |
bd238fb4 | 140 | p9_printdata(char *buf, int buflen, u8 *data, int datalen) |
5174fdab | 141 | { |
bd238fb4 | 142 | return p9_dumpdata(buf, buflen, data, datalen < 16?datalen:16); |
5174fdab LI |
143 | } |
144 | ||
145 | int | |
bd238fb4 | 146 | p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int extended) |
5174fdab LI |
147 | { |
148 | int i, ret, type, tag; | |
149 | ||
150 | if (!fc) | |
151 | return scnprintf(buf, buflen, "<NULL>"); | |
152 | ||
153 | type = fc->id; | |
154 | tag = fc->tag; | |
155 | ||
156 | ret = 0; | |
157 | switch (type) { | |
bd238fb4 | 158 | case P9_TVERSION: |
5174fdab | 159 | ret += scnprintf(buf+ret, buflen-ret, |
bd238fb4 LI |
160 | "Tversion tag %u msize %u version '%.*s'", tag, |
161 | fc->params.tversion.msize, | |
162 | fc->params.tversion.version.len, | |
163 | fc->params.tversion.version.str); | |
5174fdab LI |
164 | break; |
165 | ||
bd238fb4 | 166 | case P9_RVERSION: |
5174fdab | 167 | ret += scnprintf(buf+ret, buflen-ret, |
bd238fb4 LI |
168 | "Rversion tag %u msize %u version '%.*s'", tag, |
169 | fc->params.rversion.msize, | |
170 | fc->params.rversion.version.len, | |
171 | fc->params.rversion.version.str); | |
5174fdab LI |
172 | break; |
173 | ||
bd238fb4 | 174 | case P9_TAUTH: |
5174fdab LI |
175 | ret += scnprintf(buf+ret, buflen-ret, |
176 | "Tauth tag %u afid %d uname '%.*s' aname '%.*s'", tag, | |
177 | fc->params.tauth.afid, fc->params.tauth.uname.len, | |
178 | fc->params.tauth.uname.str, fc->params.tauth.aname.len, | |
179 | fc->params.tauth.aname.str); | |
180 | break; | |
181 | ||
bd238fb4 | 182 | case P9_RAUTH: |
5174fdab | 183 | ret += scnprintf(buf+ret, buflen-ret, "Rauth tag %u qid ", tag); |
bd238fb4 | 184 | p9_printqid(buf+ret, buflen-ret, &fc->params.rauth.qid); |
5174fdab LI |
185 | break; |
186 | ||
bd238fb4 | 187 | case P9_TATTACH: |
5174fdab | 188 | ret += scnprintf(buf+ret, buflen-ret, |
bd238fb4 LI |
189 | "Tattach tag %u fid %d afid %d uname '%.*s' aname '%.*s'", tag, |
190 | fc->params.tattach.fid, fc->params.tattach.afid, | |
191 | fc->params.tattach.uname.len, fc->params.tattach.uname.str, | |
192 | fc->params.tattach.aname.len, fc->params.tattach.aname.str); | |
5174fdab LI |
193 | break; |
194 | ||
bd238fb4 LI |
195 | case P9_RATTACH: |
196 | ret += scnprintf(buf+ret, buflen-ret, "Rattach tag %u qid ", | |
197 | tag); | |
198 | p9_printqid(buf+ret, buflen-ret, &fc->params.rattach.qid); | |
5174fdab LI |
199 | break; |
200 | ||
bd238fb4 LI |
201 | case P9_RERROR: |
202 | ret += scnprintf(buf+ret, buflen-ret, | |
203 | "Rerror tag %u ename '%.*s'", tag, | |
204 | fc->params.rerror.error.len, | |
205 | fc->params.rerror.error.str); | |
5174fdab LI |
206 | if (extended) |
207 | ret += scnprintf(buf+ret, buflen-ret, " ecode %d\n", | |
208 | fc->params.rerror.errno); | |
209 | break; | |
210 | ||
bd238fb4 | 211 | case P9_TFLUSH: |
5174fdab LI |
212 | ret += scnprintf(buf+ret, buflen-ret, "Tflush tag %u oldtag %u", |
213 | tag, fc->params.tflush.oldtag); | |
214 | break; | |
215 | ||
bd238fb4 | 216 | case P9_RFLUSH: |
5174fdab LI |
217 | ret += scnprintf(buf+ret, buflen-ret, "Rflush tag %u", tag); |
218 | break; | |
219 | ||
bd238fb4 | 220 | case P9_TWALK: |
5174fdab LI |
221 | ret += scnprintf(buf+ret, buflen-ret, |
222 | "Twalk tag %u fid %d newfid %d nwname %d", tag, | |
223 | fc->params.twalk.fid, fc->params.twalk.newfid, | |
224 | fc->params.twalk.nwname); | |
bd238fb4 LI |
225 | for (i = 0; i < fc->params.twalk.nwname; i++) |
226 | ret += scnprintf(buf+ret, buflen-ret, " '%.*s'", | |
5174fdab LI |
227 | fc->params.twalk.wnames[i].len, |
228 | fc->params.twalk.wnames[i].str); | |
229 | break; | |
230 | ||
bd238fb4 | 231 | case P9_RWALK: |
5174fdab LI |
232 | ret += scnprintf(buf+ret, buflen-ret, "Rwalk tag %u nwqid %d", |
233 | tag, fc->params.rwalk.nwqid); | |
bd238fb4 LI |
234 | for (i = 0; i < fc->params.rwalk.nwqid; i++) |
235 | ret += p9_printqid(buf+ret, buflen-ret, | |
5174fdab LI |
236 | &fc->params.rwalk.wqids[i]); |
237 | break; | |
238 | ||
bd238fb4 | 239 | case P9_TOPEN: |
5174fdab LI |
240 | ret += scnprintf(buf+ret, buflen-ret, |
241 | "Topen tag %u fid %d mode %d", tag, | |
242 | fc->params.topen.fid, fc->params.topen.mode); | |
243 | break; | |
244 | ||
bd238fb4 | 245 | case P9_ROPEN: |
5174fdab | 246 | ret += scnprintf(buf+ret, buflen-ret, "Ropen tag %u", tag); |
bd238fb4 LI |
247 | ret += p9_printqid(buf+ret, buflen-ret, &fc->params.ropen.qid); |
248 | ret += scnprintf(buf+ret, buflen-ret, " iounit %d", | |
5174fdab LI |
249 | fc->params.ropen.iounit); |
250 | break; | |
251 | ||
bd238fb4 | 252 | case P9_TCREATE: |
5174fdab LI |
253 | ret += scnprintf(buf+ret, buflen-ret, |
254 | "Tcreate tag %u fid %d name '%.*s' perm ", tag, | |
255 | fc->params.tcreate.fid, fc->params.tcreate.name.len, | |
256 | fc->params.tcreate.name.str); | |
257 | ||
bd238fb4 LI |
258 | ret += p9_printperm(buf+ret, buflen-ret, |
259 | fc->params.tcreate.perm); | |
5174fdab LI |
260 | ret += scnprintf(buf+ret, buflen-ret, " mode %d", |
261 | fc->params.tcreate.mode); | |
262 | break; | |
263 | ||
bd238fb4 | 264 | case P9_RCREATE: |
5174fdab | 265 | ret += scnprintf(buf+ret, buflen-ret, "Rcreate tag %u", tag); |
bd238fb4 LI |
266 | ret += p9_printqid(buf+ret, buflen-ret, |
267 | &fc->params.rcreate.qid); | |
5174fdab LI |
268 | ret += scnprintf(buf+ret, buflen-ret, " iounit %d", |
269 | fc->params.rcreate.iounit); | |
270 | break; | |
271 | ||
bd238fb4 | 272 | case P9_TREAD: |
5174fdab LI |
273 | ret += scnprintf(buf+ret, buflen-ret, |
274 | "Tread tag %u fid %d offset %lld count %u", tag, | |
275 | fc->params.tread.fid, | |
276 | (long long int) fc->params.tread.offset, | |
277 | fc->params.tread.count); | |
278 | break; | |
279 | ||
bd238fb4 | 280 | case P9_RREAD: |
5174fdab LI |
281 | ret += scnprintf(buf+ret, buflen-ret, |
282 | "Rread tag %u count %u data ", tag, | |
283 | fc->params.rread.count); | |
bd238fb4 | 284 | ret += p9_printdata(buf+ret, buflen-ret, fc->params.rread.data, |
5174fdab LI |
285 | fc->params.rread.count); |
286 | break; | |
287 | ||
bd238fb4 | 288 | case P9_TWRITE: |
5174fdab LI |
289 | ret += scnprintf(buf+ret, buflen-ret, |
290 | "Twrite tag %u fid %d offset %lld count %u data ", | |
291 | tag, fc->params.twrite.fid, | |
292 | (long long int) fc->params.twrite.offset, | |
293 | fc->params.twrite.count); | |
bd238fb4 | 294 | ret += p9_printdata(buf+ret, buflen-ret, fc->params.twrite.data, |
5174fdab LI |
295 | fc->params.twrite.count); |
296 | break; | |
297 | ||
bd238fb4 | 298 | case P9_RWRITE: |
5174fdab LI |
299 | ret += scnprintf(buf+ret, buflen-ret, "Rwrite tag %u count %u", |
300 | tag, fc->params.rwrite.count); | |
301 | break; | |
302 | ||
bd238fb4 | 303 | case P9_TCLUNK: |
5174fdab LI |
304 | ret += scnprintf(buf+ret, buflen-ret, "Tclunk tag %u fid %d", |
305 | tag, fc->params.tclunk.fid); | |
306 | break; | |
307 | ||
bd238fb4 | 308 | case P9_RCLUNK: |
5174fdab LI |
309 | ret += scnprintf(buf+ret, buflen-ret, "Rclunk tag %u", tag); |
310 | break; | |
311 | ||
bd238fb4 | 312 | case P9_TREMOVE: |
5174fdab LI |
313 | ret += scnprintf(buf+ret, buflen-ret, "Tremove tag %u fid %d", |
314 | tag, fc->params.tremove.fid); | |
315 | break; | |
316 | ||
bd238fb4 | 317 | case P9_RREMOVE: |
5174fdab LI |
318 | ret += scnprintf(buf+ret, buflen-ret, "Rremove tag %u", tag); |
319 | break; | |
320 | ||
bd238fb4 | 321 | case P9_TSTAT: |
5174fdab LI |
322 | ret += scnprintf(buf+ret, buflen-ret, "Tstat tag %u fid %d", |
323 | tag, fc->params.tstat.fid); | |
324 | break; | |
325 | ||
bd238fb4 | 326 | case P9_RSTAT: |
5174fdab | 327 | ret += scnprintf(buf+ret, buflen-ret, "Rstat tag %u ", tag); |
bd238fb4 | 328 | ret += p9_printstat(buf+ret, buflen-ret, &fc->params.rstat.stat, |
5174fdab LI |
329 | extended); |
330 | break; | |
331 | ||
bd238fb4 | 332 | case P9_TWSTAT: |
5174fdab LI |
333 | ret += scnprintf(buf+ret, buflen-ret, "Twstat tag %u fid %d ", |
334 | tag, fc->params.twstat.fid); | |
bd238fb4 LI |
335 | ret += p9_printstat(buf+ret, buflen-ret, |
336 | &fc->params.twstat.stat, extended); | |
5174fdab LI |
337 | break; |
338 | ||
bd238fb4 | 339 | case P9_RWSTAT: |
5174fdab LI |
340 | ret += scnprintf(buf+ret, buflen-ret, "Rwstat tag %u", tag); |
341 | break; | |
342 | ||
343 | default: | |
344 | ret += scnprintf(buf+ret, buflen-ret, "unknown type %d", type); | |
345 | break; | |
346 | } | |
347 | ||
348 | return ret; | |
349 | } | |
bd238fb4 LI |
350 | |
351 | #else | |
352 | int | |
353 | p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int extended) | |
354 | { | |
355 | return 0; | |
356 | } | |
357 | EXPORT_SYMBOL(p9_printfcall); | |
358 | #endif /* CONFIG_NET_9P_DEBUG */ |