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 | ||
ee443996 EVH |
145 | /** |
146 | * p9_printfcall - decode and print a protocol structure into a buffer | |
147 | * @buf: buffer to deposit decoded structure into | |
148 | * @buflen: available space in buffer | |
149 | * @fc: protocol rpc structure of type &p9_fcall | |
150 | * @extended: whether or not session is operating with extended protocol | |
151 | */ | |
152 | ||
5174fdab | 153 | int |
bd238fb4 | 154 | p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int extended) |
5174fdab LI |
155 | { |
156 | int i, ret, type, tag; | |
157 | ||
158 | if (!fc) | |
159 | return scnprintf(buf, buflen, "<NULL>"); | |
160 | ||
161 | type = fc->id; | |
162 | tag = fc->tag; | |
163 | ||
164 | ret = 0; | |
165 | switch (type) { | |
bd238fb4 | 166 | case P9_TVERSION: |
5174fdab | 167 | ret += scnprintf(buf+ret, buflen-ret, |
bd238fb4 LI |
168 | "Tversion tag %u msize %u version '%.*s'", tag, |
169 | fc->params.tversion.msize, | |
170 | fc->params.tversion.version.len, | |
171 | fc->params.tversion.version.str); | |
5174fdab LI |
172 | break; |
173 | ||
bd238fb4 | 174 | case P9_RVERSION: |
5174fdab | 175 | ret += scnprintf(buf+ret, buflen-ret, |
bd238fb4 LI |
176 | "Rversion tag %u msize %u version '%.*s'", tag, |
177 | fc->params.rversion.msize, | |
178 | fc->params.rversion.version.len, | |
179 | fc->params.rversion.version.str); | |
5174fdab LI |
180 | break; |
181 | ||
bd238fb4 | 182 | case P9_TAUTH: |
5174fdab LI |
183 | ret += scnprintf(buf+ret, buflen-ret, |
184 | "Tauth tag %u afid %d uname '%.*s' aname '%.*s'", tag, | |
185 | fc->params.tauth.afid, fc->params.tauth.uname.len, | |
186 | fc->params.tauth.uname.str, fc->params.tauth.aname.len, | |
187 | fc->params.tauth.aname.str); | |
188 | break; | |
189 | ||
bd238fb4 | 190 | case P9_RAUTH: |
5174fdab | 191 | ret += scnprintf(buf+ret, buflen-ret, "Rauth tag %u qid ", tag); |
bd238fb4 | 192 | p9_printqid(buf+ret, buflen-ret, &fc->params.rauth.qid); |
5174fdab LI |
193 | break; |
194 | ||
bd238fb4 | 195 | case P9_TATTACH: |
5174fdab | 196 | ret += scnprintf(buf+ret, buflen-ret, |
bd238fb4 LI |
197 | "Tattach tag %u fid %d afid %d uname '%.*s' aname '%.*s'", tag, |
198 | fc->params.tattach.fid, fc->params.tattach.afid, | |
199 | fc->params.tattach.uname.len, fc->params.tattach.uname.str, | |
200 | fc->params.tattach.aname.len, fc->params.tattach.aname.str); | |
5174fdab LI |
201 | break; |
202 | ||
bd238fb4 LI |
203 | case P9_RATTACH: |
204 | ret += scnprintf(buf+ret, buflen-ret, "Rattach tag %u qid ", | |
205 | tag); | |
206 | p9_printqid(buf+ret, buflen-ret, &fc->params.rattach.qid); | |
5174fdab LI |
207 | break; |
208 | ||
bd238fb4 LI |
209 | case P9_RERROR: |
210 | ret += scnprintf(buf+ret, buflen-ret, | |
211 | "Rerror tag %u ename '%.*s'", tag, | |
212 | fc->params.rerror.error.len, | |
213 | fc->params.rerror.error.str); | |
5174fdab LI |
214 | if (extended) |
215 | ret += scnprintf(buf+ret, buflen-ret, " ecode %d\n", | |
216 | fc->params.rerror.errno); | |
217 | break; | |
218 | ||
bd238fb4 | 219 | case P9_TFLUSH: |
5174fdab LI |
220 | ret += scnprintf(buf+ret, buflen-ret, "Tflush tag %u oldtag %u", |
221 | tag, fc->params.tflush.oldtag); | |
222 | break; | |
223 | ||
bd238fb4 | 224 | case P9_RFLUSH: |
5174fdab LI |
225 | ret += scnprintf(buf+ret, buflen-ret, "Rflush tag %u", tag); |
226 | break; | |
227 | ||
bd238fb4 | 228 | case P9_TWALK: |
5174fdab LI |
229 | ret += scnprintf(buf+ret, buflen-ret, |
230 | "Twalk tag %u fid %d newfid %d nwname %d", tag, | |
231 | fc->params.twalk.fid, fc->params.twalk.newfid, | |
232 | fc->params.twalk.nwname); | |
bd238fb4 LI |
233 | for (i = 0; i < fc->params.twalk.nwname; i++) |
234 | ret += scnprintf(buf+ret, buflen-ret, " '%.*s'", | |
5174fdab LI |
235 | fc->params.twalk.wnames[i].len, |
236 | fc->params.twalk.wnames[i].str); | |
237 | break; | |
238 | ||
bd238fb4 | 239 | case P9_RWALK: |
5174fdab LI |
240 | ret += scnprintf(buf+ret, buflen-ret, "Rwalk tag %u nwqid %d", |
241 | tag, fc->params.rwalk.nwqid); | |
bd238fb4 LI |
242 | for (i = 0; i < fc->params.rwalk.nwqid; i++) |
243 | ret += p9_printqid(buf+ret, buflen-ret, | |
5174fdab LI |
244 | &fc->params.rwalk.wqids[i]); |
245 | break; | |
246 | ||
bd238fb4 | 247 | case P9_TOPEN: |
5174fdab LI |
248 | ret += scnprintf(buf+ret, buflen-ret, |
249 | "Topen tag %u fid %d mode %d", tag, | |
250 | fc->params.topen.fid, fc->params.topen.mode); | |
251 | break; | |
252 | ||
bd238fb4 | 253 | case P9_ROPEN: |
5174fdab | 254 | ret += scnprintf(buf+ret, buflen-ret, "Ropen tag %u", tag); |
bd238fb4 LI |
255 | ret += p9_printqid(buf+ret, buflen-ret, &fc->params.ropen.qid); |
256 | ret += scnprintf(buf+ret, buflen-ret, " iounit %d", | |
5174fdab LI |
257 | fc->params.ropen.iounit); |
258 | break; | |
259 | ||
bd238fb4 | 260 | case P9_TCREATE: |
5174fdab LI |
261 | ret += scnprintf(buf+ret, buflen-ret, |
262 | "Tcreate tag %u fid %d name '%.*s' perm ", tag, | |
263 | fc->params.tcreate.fid, fc->params.tcreate.name.len, | |
264 | fc->params.tcreate.name.str); | |
265 | ||
bd238fb4 LI |
266 | ret += p9_printperm(buf+ret, buflen-ret, |
267 | fc->params.tcreate.perm); | |
5174fdab LI |
268 | ret += scnprintf(buf+ret, buflen-ret, " mode %d", |
269 | fc->params.tcreate.mode); | |
270 | break; | |
271 | ||
bd238fb4 | 272 | case P9_RCREATE: |
5174fdab | 273 | ret += scnprintf(buf+ret, buflen-ret, "Rcreate tag %u", tag); |
bd238fb4 LI |
274 | ret += p9_printqid(buf+ret, buflen-ret, |
275 | &fc->params.rcreate.qid); | |
5174fdab LI |
276 | ret += scnprintf(buf+ret, buflen-ret, " iounit %d", |
277 | fc->params.rcreate.iounit); | |
278 | break; | |
279 | ||
bd238fb4 | 280 | case P9_TREAD: |
5174fdab LI |
281 | ret += scnprintf(buf+ret, buflen-ret, |
282 | "Tread tag %u fid %d offset %lld count %u", tag, | |
283 | fc->params.tread.fid, | |
284 | (long long int) fc->params.tread.offset, | |
285 | fc->params.tread.count); | |
286 | break; | |
287 | ||
bd238fb4 | 288 | case P9_RREAD: |
5174fdab LI |
289 | ret += scnprintf(buf+ret, buflen-ret, |
290 | "Rread tag %u count %u data ", tag, | |
291 | fc->params.rread.count); | |
bd238fb4 | 292 | ret += p9_printdata(buf+ret, buflen-ret, fc->params.rread.data, |
5174fdab LI |
293 | fc->params.rread.count); |
294 | break; | |
295 | ||
bd238fb4 | 296 | case P9_TWRITE: |
5174fdab LI |
297 | ret += scnprintf(buf+ret, buflen-ret, |
298 | "Twrite tag %u fid %d offset %lld count %u data ", | |
299 | tag, fc->params.twrite.fid, | |
300 | (long long int) fc->params.twrite.offset, | |
301 | fc->params.twrite.count); | |
bd238fb4 | 302 | ret += p9_printdata(buf+ret, buflen-ret, fc->params.twrite.data, |
5174fdab LI |
303 | fc->params.twrite.count); |
304 | break; | |
305 | ||
bd238fb4 | 306 | case P9_RWRITE: |
5174fdab LI |
307 | ret += scnprintf(buf+ret, buflen-ret, "Rwrite tag %u count %u", |
308 | tag, fc->params.rwrite.count); | |
309 | break; | |
310 | ||
bd238fb4 | 311 | case P9_TCLUNK: |
5174fdab LI |
312 | ret += scnprintf(buf+ret, buflen-ret, "Tclunk tag %u fid %d", |
313 | tag, fc->params.tclunk.fid); | |
314 | break; | |
315 | ||
bd238fb4 | 316 | case P9_RCLUNK: |
5174fdab LI |
317 | ret += scnprintf(buf+ret, buflen-ret, "Rclunk tag %u", tag); |
318 | break; | |
319 | ||
bd238fb4 | 320 | case P9_TREMOVE: |
5174fdab LI |
321 | ret += scnprintf(buf+ret, buflen-ret, "Tremove tag %u fid %d", |
322 | tag, fc->params.tremove.fid); | |
323 | break; | |
324 | ||
bd238fb4 | 325 | case P9_RREMOVE: |
5174fdab LI |
326 | ret += scnprintf(buf+ret, buflen-ret, "Rremove tag %u", tag); |
327 | break; | |
328 | ||
bd238fb4 | 329 | case P9_TSTAT: |
5174fdab LI |
330 | ret += scnprintf(buf+ret, buflen-ret, "Tstat tag %u fid %d", |
331 | tag, fc->params.tstat.fid); | |
332 | break; | |
333 | ||
bd238fb4 | 334 | case P9_RSTAT: |
5174fdab | 335 | ret += scnprintf(buf+ret, buflen-ret, "Rstat tag %u ", tag); |
bd238fb4 | 336 | ret += p9_printstat(buf+ret, buflen-ret, &fc->params.rstat.stat, |
5174fdab LI |
337 | extended); |
338 | break; | |
339 | ||
bd238fb4 | 340 | case P9_TWSTAT: |
5174fdab LI |
341 | ret += scnprintf(buf+ret, buflen-ret, "Twstat tag %u fid %d ", |
342 | tag, fc->params.twstat.fid); | |
bd238fb4 LI |
343 | ret += p9_printstat(buf+ret, buflen-ret, |
344 | &fc->params.twstat.stat, extended); | |
5174fdab LI |
345 | break; |
346 | ||
bd238fb4 | 347 | case P9_RWSTAT: |
5174fdab LI |
348 | ret += scnprintf(buf+ret, buflen-ret, "Rwstat tag %u", tag); |
349 | break; | |
350 | ||
351 | default: | |
352 | ret += scnprintf(buf+ret, buflen-ret, "unknown type %d", type); | |
353 | break; | |
354 | } | |
355 | ||
356 | return ret; | |
357 | } | |
bd238fb4 LI |
358 | #else |
359 | int | |
360 | p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int extended) | |
361 | { | |
362 | return 0; | |
363 | } | |
bd238fb4 | 364 | #endif /* CONFIG_NET_9P_DEBUG */ |
72767443 AM |
365 | EXPORT_SYMBOL(p9_printfcall); |
366 |