diff options
Diffstat (limited to 'fs/9p/fcprint.c')
-rw-r--r-- | fs/9p/fcprint.c | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/fs/9p/fcprint.c b/fs/9p/fcprint.c new file mode 100644 index 000000000000..fc8a98437b73 --- /dev/null +++ b/fs/9p/fcprint.c | |||
@@ -0,0 +1,347 @@ | |||
1 | /* | ||
2 | * linux/fs/9p/fcprint.c | ||
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 | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to: | ||
20 | * Free Software Foundation | ||
21 | * 51 Franklin Street, Fifth Floor | ||
22 | * Boston, MA 02111-1301 USA | ||
23 | * | ||
24 | */ | ||
25 | #include <linux/config.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/errno.h> | ||
28 | #include <linux/fs.h> | ||
29 | #include <linux/idr.h> | ||
30 | |||
31 | #include "debug.h" | ||
32 | #include "v9fs.h" | ||
33 | #include "9p.h" | ||
34 | #include "mux.h" | ||
35 | |||
36 | static int | ||
37 | v9fs_printqid(char *buf, int buflen, struct v9fs_qid *q) | ||
38 | { | ||
39 | int n; | ||
40 | char b[10]; | ||
41 | |||
42 | n = 0; | ||
43 | if (q->type & V9FS_QTDIR) | ||
44 | b[n++] = 'd'; | ||
45 | if (q->type & V9FS_QTAPPEND) | ||
46 | b[n++] = 'a'; | ||
47 | if (q->type & V9FS_QTAUTH) | ||
48 | b[n++] = 'A'; | ||
49 | if (q->type & V9FS_QTEXCL) | ||
50 | b[n++] = 'l'; | ||
51 | if (q->type & V9FS_QTTMP) | ||
52 | b[n++] = 't'; | ||
53 | if (q->type & V9FS_QTSYMLINK) | ||
54 | b[n++] = 'L'; | ||
55 | b[n] = '\0'; | ||
56 | |||
57 | return scnprintf(buf, buflen, "(%.16llx %x %s)", (long long int) q->path, | ||
58 | q->version, b); | ||
59 | } | ||
60 | |||
61 | static int | ||
62 | v9fs_printperm(char *buf, int buflen, int perm) | ||
63 | { | ||
64 | int n; | ||
65 | char b[15]; | ||
66 | |||
67 | n = 0; | ||
68 | if (perm & V9FS_DMDIR) | ||
69 | b[n++] = 'd'; | ||
70 | if (perm & V9FS_DMAPPEND) | ||
71 | b[n++] = 'a'; | ||
72 | if (perm & V9FS_DMAUTH) | ||
73 | b[n++] = 'A'; | ||
74 | if (perm & V9FS_DMEXCL) | ||
75 | b[n++] = 'l'; | ||
76 | if (perm & V9FS_DMTMP) | ||
77 | b[n++] = 't'; | ||
78 | if (perm & V9FS_DMDEVICE) | ||
79 | b[n++] = 'D'; | ||
80 | if (perm & V9FS_DMSOCKET) | ||
81 | b[n++] = 'S'; | ||
82 | if (perm & V9FS_DMNAMEDPIPE) | ||
83 | b[n++] = 'P'; | ||
84 | if (perm & V9FS_DMSYMLINK) | ||
85 | b[n++] = 'L'; | ||
86 | b[n] = '\0'; | ||
87 | |||
88 | return scnprintf(buf, buflen, "%s%03o", b, perm&077); | ||
89 | } | ||
90 | |||
91 | static int | ||
92 | v9fs_printstat(char *buf, int buflen, struct v9fs_stat *st, int extended) | ||
93 | { | ||
94 | int n; | ||
95 | |||
96 | n = scnprintf(buf, buflen, "'%.*s' '%.*s'", st->name.len, | ||
97 | st->name.str, st->uid.len, st->uid.str); | ||
98 | if (extended) | ||
99 | n += scnprintf(buf+n, buflen-n, "(%d)", st->n_uid); | ||
100 | |||
101 | n += scnprintf(buf+n, buflen-n, " '%.*s'", st->gid.len, st->gid.str); | ||
102 | if (extended) | ||
103 | n += scnprintf(buf+n, buflen-n, "(%d)", st->n_gid); | ||
104 | |||
105 | n += scnprintf(buf+n, buflen-n, " '%.*s'", st->muid.len, st->muid.str); | ||
106 | if (extended) | ||
107 | n += scnprintf(buf+n, buflen-n, "(%d)", st->n_muid); | ||
108 | |||
109 | n += scnprintf(buf+n, buflen-n, " q "); | ||
110 | n += v9fs_printqid(buf+n, buflen-n, &st->qid); | ||
111 | n += scnprintf(buf+n, buflen-n, " m "); | ||
112 | n += v9fs_printperm(buf+n, buflen-n, st->mode); | ||
113 | n += scnprintf(buf+n, buflen-n, " at %d mt %d l %lld", | ||
114 | st->atime, st->mtime, (long long int) st->length); | ||
115 | |||
116 | if (extended) | ||
117 | n += scnprintf(buf+n, buflen-n, " ext '%.*s'", | ||
118 | st->extension.len, st->extension.str); | ||
119 | |||
120 | return n; | ||
121 | } | ||
122 | |||
123 | static int | ||
124 | v9fs_dumpdata(char *buf, int buflen, u8 *data, int datalen) | ||
125 | { | ||
126 | int i, n; | ||
127 | |||
128 | i = n = 0; | ||
129 | while (i < datalen) { | ||
130 | n += scnprintf(buf + n, buflen - n, "%02x", data[i]); | ||
131 | if (i%4 == 3) | ||
132 | n += scnprintf(buf + n, buflen - n, " "); | ||
133 | if (i%32 == 31) | ||
134 | n += scnprintf(buf + n, buflen - n, "\n"); | ||
135 | |||
136 | i++; | ||
137 | } | ||
138 | n += scnprintf(buf + n, buflen - n, "\n"); | ||
139 | |||
140 | return n; | ||
141 | } | ||
142 | |||
143 | static int | ||
144 | v9fs_printdata(char *buf, int buflen, u8 *data, int datalen) | ||
145 | { | ||
146 | return v9fs_dumpdata(buf, buflen, data, datalen<16?datalen:16); | ||
147 | } | ||
148 | |||
149 | int | ||
150 | v9fs_printfcall(char *buf, int buflen, struct v9fs_fcall *fc, int extended) | ||
151 | { | ||
152 | int i, ret, type, tag; | ||
153 | |||
154 | if (!fc) | ||
155 | return scnprintf(buf, buflen, "<NULL>"); | ||
156 | |||
157 | type = fc->id; | ||
158 | tag = fc->tag; | ||
159 | |||
160 | ret = 0; | ||
161 | switch (type) { | ||
162 | case TVERSION: | ||
163 | ret += scnprintf(buf+ret, buflen-ret, | ||
164 | "Tversion tag %u msize %u version '%.*s'", tag, | ||
165 | fc->params.tversion.msize, fc->params.tversion.version.len, | ||
166 | fc->params.tversion.version.str); | ||
167 | break; | ||
168 | |||
169 | case RVERSION: | ||
170 | ret += scnprintf(buf+ret, buflen-ret, | ||
171 | "Rversion tag %u msize %u version '%.*s'", tag, | ||
172 | fc->params.rversion.msize, fc->params.rversion.version.len, | ||
173 | fc->params.rversion.version.str); | ||
174 | break; | ||
175 | |||
176 | case TAUTH: | ||
177 | ret += scnprintf(buf+ret, buflen-ret, | ||
178 | "Tauth tag %u afid %d uname '%.*s' aname '%.*s'", tag, | ||
179 | fc->params.tauth.afid, fc->params.tauth.uname.len, | ||
180 | fc->params.tauth.uname.str, fc->params.tauth.aname.len, | ||
181 | fc->params.tauth.aname.str); | ||
182 | break; | ||
183 | |||
184 | case RAUTH: | ||
185 | ret += scnprintf(buf+ret, buflen-ret, "Rauth tag %u qid ", tag); | ||
186 | v9fs_printqid(buf+ret, buflen-ret, &fc->params.rauth.qid); | ||
187 | break; | ||
188 | |||
189 | case TATTACH: | ||
190 | ret += scnprintf(buf+ret, buflen-ret, | ||
191 | "Tattach tag %u fid %d afid %d uname '%.*s' aname '%.*s'", | ||
192 | tag, fc->params.tattach.fid, fc->params.tattach.afid, | ||
193 | fc->params.tattach.uname.len, fc->params.tattach.uname.str, | ||
194 | fc->params.tattach.aname.len, fc->params.tattach.aname.str); | ||
195 | break; | ||
196 | |||
197 | case RATTACH: | ||
198 | ret += scnprintf(buf+ret, buflen-ret, "Rattach tag %u qid ", tag); | ||
199 | v9fs_printqid(buf+ret, buflen-ret, &fc->params.rattach.qid); | ||
200 | break; | ||
201 | |||
202 | case RERROR: | ||
203 | ret += scnprintf(buf+ret, buflen-ret, "Rerror tag %u ename '%.*s'", | ||
204 | tag, fc->params.rerror.error.len, | ||
205 | fc->params.rerror.error.str); | ||
206 | if (extended) | ||
207 | ret += scnprintf(buf+ret, buflen-ret, " ecode %d\n", | ||
208 | fc->params.rerror.errno); | ||
209 | break; | ||
210 | |||
211 | case TFLUSH: | ||
212 | ret += scnprintf(buf+ret, buflen-ret, "Tflush tag %u oldtag %u", | ||
213 | tag, fc->params.tflush.oldtag); | ||
214 | break; | ||
215 | |||
216 | case RFLUSH: | ||
217 | ret += scnprintf(buf+ret, buflen-ret, "Rflush tag %u", tag); | ||
218 | break; | ||
219 | |||
220 | case TWALK: | ||
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); | ||
225 | for(i = 0; i < fc->params.twalk.nwname; i++) | ||
226 | ret += scnprintf(buf+ret, buflen-ret," '%.*s'", | ||
227 | fc->params.twalk.wnames[i].len, | ||
228 | fc->params.twalk.wnames[i].str); | ||
229 | break; | ||
230 | |||
231 | case RWALK: | ||
232 | ret += scnprintf(buf+ret, buflen-ret, "Rwalk tag %u nwqid %d", | ||
233 | tag, fc->params.rwalk.nwqid); | ||
234 | for(i = 0; i < fc->params.rwalk.nwqid; i++) | ||
235 | ret += v9fs_printqid(buf+ret, buflen-ret, | ||
236 | &fc->params.rwalk.wqids[i]); | ||
237 | break; | ||
238 | |||
239 | case TOPEN: | ||
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 | |||
245 | case ROPEN: | ||
246 | ret += scnprintf(buf+ret, buflen-ret, "Ropen tag %u", tag); | ||
247 | ret += v9fs_printqid(buf+ret, buflen-ret, &fc->params.ropen.qid); | ||
248 | ret += scnprintf(buf+ret, buflen-ret," iounit %d", | ||
249 | fc->params.ropen.iounit); | ||
250 | break; | ||
251 | |||
252 | case TCREATE: | ||
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 | |||
258 | ret += v9fs_printperm(buf+ret, buflen-ret, fc->params.tcreate.perm); | ||
259 | ret += scnprintf(buf+ret, buflen-ret, " mode %d", | ||
260 | fc->params.tcreate.mode); | ||
261 | break; | ||
262 | |||
263 | case RCREATE: | ||
264 | ret += scnprintf(buf+ret, buflen-ret, "Rcreate tag %u", tag); | ||
265 | ret += v9fs_printqid(buf+ret, buflen-ret, &fc->params.rcreate.qid); | ||
266 | ret += scnprintf(buf+ret, buflen-ret, " iounit %d", | ||
267 | fc->params.rcreate.iounit); | ||
268 | break; | ||
269 | |||
270 | case TREAD: | ||
271 | ret += scnprintf(buf+ret, buflen-ret, | ||
272 | "Tread tag %u fid %d offset %lld count %u", tag, | ||
273 | fc->params.tread.fid, | ||
274 | (long long int) fc->params.tread.offset, | ||
275 | fc->params.tread.count); | ||
276 | break; | ||
277 | |||
278 | case RREAD: | ||
279 | ret += scnprintf(buf+ret, buflen-ret, | ||
280 | "Rread tag %u count %u data ", tag, | ||
281 | fc->params.rread.count); | ||
282 | ret += v9fs_printdata(buf+ret, buflen-ret, fc->params.rread.data, | ||
283 | fc->params.rread.count); | ||
284 | break; | ||
285 | |||
286 | case TWRITE: | ||
287 | ret += scnprintf(buf+ret, buflen-ret, | ||
288 | "Twrite tag %u fid %d offset %lld count %u data ", | ||
289 | tag, fc->params.twrite.fid, | ||
290 | (long long int) fc->params.twrite.offset, | ||
291 | fc->params.twrite.count); | ||
292 | ret += v9fs_printdata(buf+ret, buflen-ret, fc->params.twrite.data, | ||
293 | fc->params.twrite.count); | ||
294 | break; | ||
295 | |||
296 | case RWRITE: | ||
297 | ret += scnprintf(buf+ret, buflen-ret, "Rwrite tag %u count %u", | ||
298 | tag, fc->params.rwrite.count); | ||
299 | break; | ||
300 | |||
301 | case TCLUNK: | ||
302 | ret += scnprintf(buf+ret, buflen-ret, "Tclunk tag %u fid %d", | ||
303 | tag, fc->params.tclunk.fid); | ||
304 | break; | ||
305 | |||
306 | case RCLUNK: | ||
307 | ret += scnprintf(buf+ret, buflen-ret, "Rclunk tag %u", tag); | ||
308 | break; | ||
309 | |||
310 | case TREMOVE: | ||
311 | ret += scnprintf(buf+ret, buflen-ret, "Tremove tag %u fid %d", | ||
312 | tag, fc->params.tremove.fid); | ||
313 | break; | ||
314 | |||
315 | case RREMOVE: | ||
316 | ret += scnprintf(buf+ret, buflen-ret, "Rremove tag %u", tag); | ||
317 | break; | ||
318 | |||
319 | case TSTAT: | ||
320 | ret += scnprintf(buf+ret, buflen-ret, "Tstat tag %u fid %d", | ||
321 | tag, fc->params.tstat.fid); | ||
322 | break; | ||
323 | |||
324 | case RSTAT: | ||
325 | ret += scnprintf(buf+ret, buflen-ret, "Rstat tag %u ", tag); | ||
326 | ret += v9fs_printstat(buf+ret, buflen-ret, &fc->params.rstat.stat, | ||
327 | extended); | ||
328 | break; | ||
329 | |||
330 | case TWSTAT: | ||
331 | ret += scnprintf(buf+ret, buflen-ret, "Twstat tag %u fid %d ", | ||
332 | tag, fc->params.twstat.fid); | ||
333 | ret += v9fs_printstat(buf+ret, buflen-ret, &fc->params.twstat.stat, | ||
334 | extended); | ||
335 | break; | ||
336 | |||
337 | case RWSTAT: | ||
338 | ret += scnprintf(buf+ret, buflen-ret, "Rwstat tag %u", tag); | ||
339 | break; | ||
340 | |||
341 | default: | ||
342 | ret += scnprintf(buf+ret, buflen-ret, "unknown type %d", type); | ||
343 | break; | ||
344 | } | ||
345 | |||
346 | return ret; | ||
347 | } | ||