]> granicus.if.org Git - strace/blob - quota.c
Fix preadv/pwritev offset decoding on bigendian architectures
[strace] / quota.c
1 /*
2  * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3  * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5  * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6  * Copyright (c) 2005, 2006 Dmitry V. Levin <ldv@altlinux.org>
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. The name of the author may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #include "defs.h"
33
34 #define SUBCMDMASK  0x00ff
35 #define SUBCMDSHIFT 8
36 #define QCMD_CMD(cmd)   ((u_int32_t)(cmd) >> SUBCMDSHIFT)
37 #define QCMD_TYPE(cmd)  ((u_int32_t)(cmd) & SUBCMDMASK)
38
39 #define OLD_CMD(cmd)    ((u_int32_t)(cmd) << 8)
40 #define NEW_CMD(cmd)    ((u_int32_t)(cmd) | 0x800000)
41 #define XQM_CMD(cmd)    ((u_int32_t)(cmd) | ('X'<<8))
42
43 #define Q_V1_QUOTAON    OLD_CMD(0x1)
44 #define Q_V1_QUOTAOFF   OLD_CMD(0x2)
45 #define Q_V1_GETQUOTA   OLD_CMD(0x3)
46 #define Q_V1_SETQUOTA   OLD_CMD(0x4)
47 #define Q_V1_SETUSE     OLD_CMD(0x5)
48 #define Q_V1_SYNC       OLD_CMD(0x6)
49 #define Q_SETQLIM       OLD_CMD(0x7)
50 #define Q_V1_GETSTATS   OLD_CMD(0x8)
51 #define Q_V1_RSQUASH    OLD_CMD(0x10)
52
53 #define Q_V2_GETQUOTA   OLD_CMD(0xD)
54 #define Q_V2_SETQUOTA   OLD_CMD(0xE)
55 #define Q_V2_SETUSE     OLD_CMD(0xF)
56 #define Q_V2_GETINFO    OLD_CMD(0x9)
57 #define Q_V2_SETINFO    OLD_CMD(0xA)
58 #define Q_V2_SETGRACE   OLD_CMD(0xB)
59 #define Q_V2_SETFLAGS   OLD_CMD(0xC)
60 #define Q_V2_GETSTATS   OLD_CMD(0x11)
61
62 #define Q_SYNC          NEW_CMD(0x1)
63 #define Q_QUOTAON       NEW_CMD(0x2)
64 #define Q_QUOTAOFF      NEW_CMD(0x3)
65 #define Q_GETFMT        NEW_CMD(0x4)
66 #define Q_GETINFO       NEW_CMD(0x5)
67 #define Q_SETINFO       NEW_CMD(0x6)
68 #define Q_GETQUOTA      NEW_CMD(0x7)
69 #define Q_SETQUOTA      NEW_CMD(0x8)
70
71 #define Q_XQUOTAON      XQM_CMD(0x1)
72 #define Q_XQUOTAOFF     XQM_CMD(0x2)
73 #define Q_XGETQUOTA     XQM_CMD(0x3)
74 #define Q_XSETQLIM      XQM_CMD(0x4)
75 #define Q_XGETQSTAT     XQM_CMD(0x5)
76 #define Q_XQUOTARM      XQM_CMD(0x6)
77 #define Q_XQUOTASYNC    XQM_CMD(0x7)
78
79 #include "xlat/quotacmds.h"
80
81 #define USRQUOTA 0
82 #define GRPQUOTA 1
83
84 #include "xlat/quotatypes.h"
85
86 /* Quota format identifiers */
87 #define QFMT_VFS_OLD 1
88 #define QFMT_VFS_V0  2
89
90 #include "xlat/quota_formats.h"
91
92 #define XFS_QUOTA_UDQ_ACCT      (1<<0)  /* user quota accounting */
93 #define XFS_QUOTA_UDQ_ENFD      (1<<1)  /* user quota limits enforcement */
94 #define XFS_QUOTA_GDQ_ACCT      (1<<2)  /* group quota accounting */
95 #define XFS_QUOTA_GDQ_ENFD      (1<<3)  /* group quota limits enforcement */
96
97 #define XFS_USER_QUOTA          (1<<0)  /* user quota type */
98 #define XFS_PROJ_QUOTA          (1<<1)  /* (IRIX) project quota type */
99 #define XFS_GROUP_QUOTA         (1<<2)  /* group quota type */
100
101 #include "xlat/xfs_quota_flags.h"
102 #include "xlat/xfs_dqblk_flags.h"
103
104 /*
105  * Following flags are used to specify which fields are valid
106  */
107 #define QIF_BLIMITS     1
108 #define QIF_SPACE       2
109 #define QIF_ILIMITS     4
110 #define QIF_INODES      8
111 #define QIF_BTIME       16
112 #define QIF_ITIME       32
113
114 #include "xlat/if_dqblk_valid.h"
115
116 struct if_dqblk
117 {
118         u_int64_t dqb_bhardlimit;
119         u_int64_t dqb_bsoftlimit;
120         u_int64_t dqb_curspace;
121         u_int64_t dqb_ihardlimit;
122         u_int64_t dqb_isoftlimit;
123         u_int64_t dqb_curinodes;
124         u_int64_t dqb_btime;
125         u_int64_t dqb_itime;
126         u_int32_t dqb_valid;
127 };
128
129 struct v1_dqblk
130 {
131         u_int32_t dqb_bhardlimit;       /* absolute limit on disk blks alloc */
132         u_int32_t dqb_bsoftlimit;       /* preferred limit on disk blks */
133         u_int32_t dqb_curblocks;        /* current block count */
134         u_int32_t dqb_ihardlimit;       /* maximum # allocated inodes */
135         u_int32_t dqb_isoftlimit;       /* preferred inode limit */
136         u_int32_t dqb_curinodes;        /* current # allocated inodes */
137         time_t  dqb_btime;      /* time limit for excessive disk use */
138         time_t  dqb_itime;      /* time limit for excessive files */
139 };
140
141 struct v2_dqblk
142 {
143         unsigned int dqb_ihardlimit;
144         unsigned int dqb_isoftlimit;
145         unsigned int dqb_curinodes;
146         unsigned int dqb_bhardlimit;
147         unsigned int dqb_bsoftlimit;
148         u_int64_t dqb_curspace;
149         time_t  dqb_btime;
150         time_t  dqb_itime;
151 };
152
153 struct xfs_dqblk
154 {
155         int8_t  d_version;      /* version of this structure */
156         int8_t  d_flags;        /* XFS_{USER,PROJ,GROUP}_QUOTA */
157         u_int16_t d_fieldmask;  /* field specifier */
158         u_int32_t d_id;         /* user, project, or group ID */
159         u_int64_t d_blk_hardlimit;      /* absolute limit on disk blks */
160         u_int64_t d_blk_softlimit;      /* preferred limit on disk blks */
161         u_int64_t d_ino_hardlimit;      /* maximum # allocated inodes */
162         u_int64_t d_ino_softlimit;      /* preferred inode limit */
163         u_int64_t d_bcount;     /* # disk blocks owned by the user */
164         u_int64_t d_icount;     /* # inodes owned by the user */
165         int32_t d_itimer;       /* zero if within inode limits */
166         int32_t d_btimer;       /* similar to above; for disk blocks */
167         u_int16_t d_iwarns;     /* # warnings issued wrt num inodes */
168         u_int16_t d_bwarns;     /* # warnings issued wrt disk blocks */
169         int32_t d_padding2;     /* padding2 - for future use */
170         u_int64_t d_rtb_hardlimit;      /* absolute limit on realtime blks */
171         u_int64_t d_rtb_softlimit;      /* preferred limit on RT disk blks */
172         u_int64_t d_rtbcount;   /* # realtime blocks owned */
173         int32_t d_rtbtimer;     /* similar to above; for RT disk blks */
174         u_int16_t d_rtbwarns;   /* # warnings issued wrt RT disk blks */
175         int16_t d_padding3;     /* padding3 - for future use */
176         char    d_padding4[8];  /* yet more padding */
177 };
178
179 /*
180  * Following flags are used to specify which fields are valid
181  */
182 #define IIF_BGRACE      1
183 #define IIF_IGRACE      2
184 #define IIF_FLAGS       4
185
186 #include "xlat/if_dqinfo_valid.h"
187
188 struct if_dqinfo
189 {
190         u_int64_t dqi_bgrace;
191         u_int64_t dqi_igrace;
192         u_int32_t dqi_flags;
193         u_int32_t dqi_valid;
194 };
195
196 struct v2_dqinfo
197 {
198         unsigned int dqi_bgrace;
199         unsigned int dqi_igrace;
200         unsigned int dqi_flags;
201         unsigned int dqi_blocks;
202         unsigned int dqi_free_blk;
203         unsigned int dqi_free_entry;
204 };
205
206 struct v1_dqstats
207 {
208         u_int32_t lookups;
209         u_int32_t drops;
210         u_int32_t reads;
211         u_int32_t writes;
212         u_int32_t cache_hits;
213         u_int32_t allocated_dquots;
214         u_int32_t free_dquots;
215         u_int32_t syncs;
216 };
217
218 struct v2_dqstats
219 {
220         u_int32_t lookups;
221         u_int32_t drops;
222         u_int32_t reads;
223         u_int32_t writes;
224         u_int32_t cache_hits;
225         u_int32_t allocated_dquots;
226         u_int32_t free_dquots;
227         u_int32_t syncs;
228         u_int32_t version;
229 };
230
231 typedef struct fs_qfilestat
232 {
233         u_int64_t qfs_ino;      /* inode number */
234         u_int64_t qfs_nblks;    /* number of BBs 512-byte-blks */
235         u_int32_t qfs_nextents; /* number of extents */
236 } fs_qfilestat_t;
237
238 struct xfs_dqstats
239 {
240         int8_t  qs_version;     /* version number for future changes */
241         u_int16_t qs_flags;     /* XFS_QUOTA_{U,P,G}DQ_{ACCT,ENFD} */
242         int8_t  qs_pad;         /* unused */
243         fs_qfilestat_t qs_uquota;       /* user quota storage information */
244         fs_qfilestat_t qs_gquota;       /* group quota storage information */
245         u_int32_t qs_incoredqs; /* number of dquots incore */
246         int32_t qs_btimelimit;  /* limit for blks timer */
247         int32_t qs_itimelimit;  /* limit for inodes timer */
248         int32_t qs_rtbtimelimit;        /* limit for rt blks timer */
249         u_int16_t qs_bwarnlimit;        /* limit for num warnings */
250         u_int16_t qs_iwarnlimit;        /* limit for num warnings */
251 };
252
253 static void
254 decode_cmd_data(struct tcb *tcp, u_int32_t cmd, unsigned long data)
255 {
256         switch (cmd) {
257                 case Q_GETQUOTA:
258                 case Q_SETQUOTA:
259                 {
260                         struct if_dqblk dq;
261
262                         if (cmd == Q_GETQUOTA && syserror(tcp)) {
263                                 tprintf("%#lx", data);
264                                 break;
265                         }
266                         if (umove(tcp, data, &dq) < 0) {
267                                 tprintf("{???} %#lx", data);
268                                 break;
269                         }
270                         tprintf("{bhardlimit=%" PRIu64 ", ", dq.dqb_bhardlimit);
271                         tprintf("bsoftlimit=%" PRIu64 ", ", dq.dqb_bsoftlimit);
272                         tprintf("curspace=%" PRIu64 ", ", dq.dqb_curspace);
273                         tprintf("ihardlimit=%" PRIu64 ", ", dq.dqb_ihardlimit);
274                         tprintf("isoftlimit=%" PRIu64 ", ", dq.dqb_isoftlimit);
275                         tprintf("curinodes=%" PRIu64 ", ", dq.dqb_curinodes);
276                         if (!abbrev(tcp)) {
277                                 tprintf("btime=%" PRIu64 ", ", dq.dqb_btime);
278                                 tprintf("itime=%" PRIu64 ", ", dq.dqb_itime);
279                                 tprints("valid=");
280                                 printflags(if_dqblk_valid,
281                                            dq.dqb_valid, "QIF_???");
282                                 tprints("}");
283                         } else
284                                 tprints("...}");
285                         break;
286                 }
287                 case Q_V1_GETQUOTA:
288                 case Q_V1_SETQUOTA:
289                 {
290                         struct v1_dqblk dq;
291
292                         if (cmd == Q_V1_GETQUOTA && syserror(tcp)) {
293                                 tprintf("%#lx", data);
294                                 break;
295                         }
296                         if (umove(tcp, data, &dq) < 0) {
297                                 tprintf("{???} %#lx", data);
298                                 break;
299                         }
300                         tprintf("{bhardlimit=%u, ", dq.dqb_bhardlimit);
301                         tprintf("bsoftlimit=%u, ", dq.dqb_bsoftlimit);
302                         tprintf("curblocks=%u, ", dq.dqb_curblocks);
303                         tprintf("ihardlimit=%u, ", dq.dqb_ihardlimit);
304                         tprintf("isoftlimit=%u, ", dq.dqb_isoftlimit);
305                         tprintf("curinodes=%u, ", dq.dqb_curinodes);
306                         tprintf("btime=%lu, ", (long) dq.dqb_btime);
307                         tprintf("itime=%lu}", (long) dq.dqb_itime);
308                         break;
309                 }
310                 case Q_V2_GETQUOTA:
311                 case Q_V2_SETQUOTA:
312                 {
313                         struct v2_dqblk dq;
314
315                         if (cmd == Q_V2_GETQUOTA && syserror(tcp)) {
316                                 tprintf("%#lx", data);
317                                 break;
318                         }
319                         if (umove(tcp, data, &dq) < 0) {
320                                 tprintf("{???} %#lx", data);
321                                 break;
322                         }
323                         tprintf("{ihardlimit=%u, ", dq.dqb_ihardlimit);
324                         tprintf("isoftlimit=%u, ", dq.dqb_isoftlimit);
325                         tprintf("curinodes=%u, ", dq.dqb_curinodes);
326                         tprintf("bhardlimit=%u, ", dq.dqb_bhardlimit);
327                         tprintf("bsoftlimit=%u, ", dq.dqb_bsoftlimit);
328                         tprintf("curspace=%" PRIu64 ", ", dq.dqb_curspace);
329                         tprintf("btime=%lu, ", (long) dq.dqb_btime);
330                         tprintf("itime=%lu}", (long) dq.dqb_itime);
331                         break;
332                 }
333                 case Q_XGETQUOTA:
334                 case Q_XSETQLIM:
335                 {
336                         struct xfs_dqblk dq;
337
338                         if (cmd == Q_XGETQUOTA && syserror(tcp)) {
339                                 tprintf("%#lx", data);
340                                 break;
341                         }
342                         if (umove(tcp, data, &dq) < 0) {
343                                 tprintf("{???} %#lx", data);
344                                 break;
345                         }
346                         tprintf("{version=%d, ", dq.d_version);
347                         tprints("flags=");
348                         printflags(xfs_dqblk_flags,
349                                    dq.d_flags, "XFS_???_QUOTA");
350                         tprintf(", fieldmask=%#x, ", dq.d_fieldmask);
351                         tprintf("id=%u, ", dq.d_id);
352                         tprintf("blk_hardlimit=%" PRIu64 ", ", dq.d_blk_hardlimit);
353                         tprintf("blk_softlimit=%" PRIu64 ", ", dq.d_blk_softlimit);
354                         tprintf("ino_hardlimit=%" PRIu64 ", ", dq.d_ino_hardlimit);
355                         tprintf("ino_softlimit=%" PRIu64 ", ", dq.d_ino_softlimit);
356                         tprintf("bcount=%" PRIu64 ", ", dq.d_bcount);
357                         tprintf("icount=%" PRIu64 ", ", dq.d_icount);
358                         if (!abbrev(tcp)) {
359                                 tprintf("itimer=%d, ", dq.d_itimer);
360                                 tprintf("btimer=%d, ", dq.d_btimer);
361                                 tprintf("iwarns=%u, ", dq.d_iwarns);
362                                 tprintf("bwarns=%u, ", dq.d_bwarns);
363                                 tprintf("rtbcount=%" PRIu64 ", ", dq.d_rtbcount);
364                                 tprintf("rtbtimer=%d, ", dq.d_rtbtimer);
365                                 tprintf("rtbwarns=%u}", dq.d_rtbwarns);
366                         } else
367                                 tprints("...}");
368                         break;
369                 }
370                 case Q_GETFMT:
371                 {
372                         u_int32_t fmt;
373
374                         if (syserror(tcp)) {
375                                 tprintf("%#lx", data);
376                                 break;
377                         }
378                         if (umove(tcp, data, &fmt) < 0) {
379                                 tprintf("{???} %#lx", data);
380                                 break;
381                         }
382                         tprints("{");
383                         printxval(quota_formats, fmt, "QFMT_VFS_???");
384                         tprints("}");
385                         break;
386                 }
387                 case Q_GETINFO:
388                 case Q_SETINFO:
389                 {
390                         struct if_dqinfo dq;
391
392                         if (cmd == Q_GETINFO && syserror(tcp)) {
393                                 tprintf("%#lx", data);
394                                 break;
395                         }
396                         if (umove(tcp, data, &dq) < 0) {
397                                 tprintf("{???} %#lx", data);
398                                 break;
399                         }
400                         tprintf("{bgrace=%" PRIu64 ", ", dq.dqi_bgrace);
401                         tprintf("igrace=%" PRIu64 ", ", dq.dqi_igrace);
402                         tprintf("flags=%#x, ", dq.dqi_flags);
403                         tprints("valid=");
404                         printflags(if_dqinfo_valid, dq.dqi_valid, "IIF_???");
405                         tprints("}");
406                         break;
407                 }
408                 case Q_V2_GETINFO:
409                 case Q_V2_SETINFO:
410                 {
411                         struct v2_dqinfo dq;
412
413                         if (cmd == Q_V2_GETINFO && syserror(tcp)) {
414                                 tprintf("%#lx", data);
415                                 break;
416                         }
417                         if (umove(tcp, data, &dq) < 0) {
418                                 tprintf("{???} %#lx", data);
419                                 break;
420                         }
421                         tprintf("{bgrace=%u, ", dq.dqi_bgrace);
422                         tprintf("igrace=%u, ", dq.dqi_igrace);
423                         tprintf("flags=%#x, ", dq.dqi_flags);
424                         tprintf("blocks=%u, ", dq.dqi_blocks);
425                         tprintf("free_blk=%u, ", dq.dqi_free_blk);
426                         tprintf("free_entry=%u}", dq.dqi_free_entry);
427                         break;
428                 }
429                 case Q_V1_GETSTATS:
430                 {
431                         struct v1_dqstats dq;
432
433                         if (syserror(tcp)) {
434                                 tprintf("%#lx", data);
435                                 break;
436                         }
437                         if (umove(tcp, data, &dq) < 0) {
438                                 tprintf("{???} %#lx", data);
439                                 break;
440                         }
441                         tprintf("{lookups=%u, ", dq.lookups);
442                         tprintf("drops=%u, ", dq.drops);
443                         tprintf("reads=%u, ", dq.reads);
444                         tprintf("writes=%u, ", dq.writes);
445                         tprintf("cache_hits=%u, ", dq.cache_hits);
446                         tprintf("allocated_dquots=%u, ", dq.allocated_dquots);
447                         tprintf("free_dquots=%u, ", dq.free_dquots);
448                         tprintf("syncs=%u}", dq.syncs);
449                         break;
450                 }
451                 case Q_V2_GETSTATS:
452                 {
453                         struct v2_dqstats dq;
454
455                         if (syserror(tcp)) {
456                                 tprintf("%#lx", data);
457                                 break;
458                         }
459                         if (umove(tcp, data, &dq) < 0) {
460                                 tprintf("{???} %#lx", data);
461                                 break;
462                         }
463                         tprintf("{lookups=%u, ", dq.lookups);
464                         tprintf("drops=%u, ", dq.drops);
465                         tprintf("reads=%u, ", dq.reads);
466                         tprintf("writes=%u, ", dq.writes);
467                         tprintf("cache_hits=%u, ", dq.cache_hits);
468                         tprintf("allocated_dquots=%u, ", dq.allocated_dquots);
469                         tprintf("free_dquots=%u, ", dq.free_dquots);
470                         tprintf("syncs=%u, ", dq.syncs);
471                         tprintf("version=%u}", dq.version);
472                         break;
473                 }
474                 case Q_XGETQSTAT:
475                 {
476                         struct xfs_dqstats dq;
477
478                         if (syserror(tcp)) {
479                                 tprintf("%#lx", data);
480                                 break;
481                         }
482                         if (umove(tcp, data, &dq) < 0) {
483                                 tprintf("{???} %#lx", data);
484                                 break;
485                         }
486                         tprintf("{version=%d, ", dq.qs_version);
487                         if (abbrev(tcp)) {
488                                 tprints("...}");
489                                 break;
490                         }
491                         tprints("flags=");
492                         printflags(xfs_quota_flags,
493                                    dq.qs_flags, "XFS_QUOTA_???");
494                         tprintf(", incoredqs=%u, ", dq.qs_incoredqs);
495                         tprintf("u_ino=%" PRIu64 ", ", dq.qs_uquota.qfs_ino);
496                         tprintf("u_nblks=%" PRIu64 ", ", dq.qs_uquota.qfs_nblks);
497                         tprintf("u_nextents=%u, ", dq.qs_uquota.qfs_nextents);
498                         tprintf("g_ino=%" PRIu64 ", ", dq.qs_gquota.qfs_ino);
499                         tprintf("g_nblks=%" PRIu64 ", ", dq.qs_gquota.qfs_nblks);
500                         tprintf("g_nextents=%u, ", dq.qs_gquota.qfs_nextents);
501                         tprintf("btimelimit=%d, ", dq.qs_btimelimit);
502                         tprintf("itimelimit=%d, ", dq.qs_itimelimit);
503                         tprintf("rtbtimelimit=%d, ", dq.qs_rtbtimelimit);
504                         tprintf("bwarnlimit=%u, ", dq.qs_bwarnlimit);
505                         tprintf("iwarnlimit=%u}", dq.qs_iwarnlimit);
506                         break;
507                 }
508                 case Q_XQUOTAON:
509                 {
510                         u_int32_t flag;
511
512                         if (umove(tcp, data, &flag) < 0) {
513                                 tprintf("{???} %#lx", data);
514                                 break;
515                         }
516                         tprints("{");
517                         printflags(xfs_quota_flags, flag, "XFS_QUOTA_???");
518                         tprints("}");
519                         break;
520                 }
521                 default:
522                         tprintf("%#lx", data);
523                         break;
524         }
525 }
526
527 int
528 sys_quotactl(struct tcb *tcp)
529 {
530         /*
531          * The Linux kernel only looks at the low 32 bits of command and id
532          * arguments, but on some 64-bit architectures (s390x) this word
533          * will have been sign-extended when we see it.  The high 1 bits
534          * don't mean anything, so don't confuse the output with them.
535          */
536         u_int32_t qcmd = tcp->u_arg[0];
537         u_int32_t cmd = QCMD_CMD(qcmd);
538         u_int32_t type = QCMD_TYPE(qcmd);
539         u_int32_t id = tcp->u_arg[2];
540
541         if (!verbose(tcp))
542                 return printargs(tcp);
543
544         if (entering(tcp)) {
545                 printxval(quotacmds, cmd, "Q_???");
546                 tprints("|");
547                 printxval(quotatypes, type, "???QUOTA");
548                 tprints(", ");
549                 printpath(tcp, tcp->u_arg[1]);
550                 tprints(", ");
551                 switch (cmd) {
552                         case Q_V1_QUOTAON:
553                         case Q_QUOTAON:
554                                 printxval(quota_formats, id, "QFMT_VFS_???");
555                                 break;
556                         case Q_V1_GETQUOTA:
557                         case Q_V2_GETQUOTA:
558                         case Q_GETQUOTA:
559                         case Q_V1_SETQUOTA:
560                         case Q_V2_SETQUOTA:
561                         case Q_V1_SETUSE:
562                         case Q_V2_SETUSE:
563                         case Q_SETQLIM:
564                         case Q_SETQUOTA:
565                         case Q_XGETQUOTA:
566                         case Q_XSETQLIM:
567                                 tprintf("%u", id);
568                                 break;
569                         default:
570                                 tprintf("%#lx", tcp->u_arg[2]);
571                                 break;
572                 }
573                 tprints(", ");
574         } else {
575                 if (!tcp->u_arg[3])
576                         tprints("NULL");
577                 else
578                         decode_cmd_data(tcp, cmd, tcp->u_arg[3]);
579         }
580         return 0;
581 }