2
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms of version 2 of the GNU General Public License as
6
* published by the Free Software Foundation.
8
* This program is distributed in the hope that it would be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
* Further, this software is distributed without any warranty that it is
13
* free of the rightful claim of any third person regarding infringement
14
* or the like. Any license provided herein, whether implied or
15
* otherwise, applies only to this software file. Patent licenses, if
16
* any, provided herein do not apply to combinations of this program with
17
* other software, or any other product whatsoever.
19
* You should have received a copy of the GNU General Public License along
20
* with this program; if not, write the Free Software Foundation, Inc., 59
21
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
23
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24
* Mountain View, CA 94043, or:
28
* For further information regarding this notice, see:
30
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
40
#define M(A) (1 << CT_ ## A)
41
#define agblock_to_bytes(x) \
42
((__uint64_t)(x) << mp->m_sb.sb_blocklog)
43
#define agino_to_bytes(x) \
44
((__uint64_t)(x) << mp->m_sb.sb_inodelog)
45
#define agnumber_to_bytes(x) \
46
agblock_to_bytes((__uint64_t)(x) * mp->m_sb.sb_agblocks)
47
#define daddr_to_bytes(x) \
48
((__uint64_t)(x) << BBSHIFT)
49
#define fsblock_to_bytes(x) \
50
(agnumber_to_bytes(XFS_FSB_TO_AGNO(mp, (x))) + \
51
agblock_to_bytes(XFS_FSB_TO_AGBNO(mp, (x))))
52
#define ino_to_bytes(x) \
53
(agnumber_to_bytes(XFS_INO_TO_AGNO(mp, (x))) + \
54
agino_to_bytes(XFS_INO_TO_AGINO(mp, (x))))
55
#define inoidx_to_bytes(x) \
56
((__uint64_t)(x) << mp->m_sb.sb_inodelog)
60
CT_AGBLOCK, /* xfs_agblock_t */
61
CT_AGINO, /* xfs_agino_t */
62
CT_AGNUMBER, /* xfs_agno_t */
63
CT_BBOFF, /* byte offset in daddr */
64
CT_BLKOFF, /* byte offset in fsb/agb */
65
CT_BYTE, /* byte in filesystem */
66
CT_DADDR, /* daddr_t */
67
CT_FSBLOCK, /* xfs_fsblock_t */
68
CT_INO, /* xfs_ino_t */
69
CT_INOIDX, /* index of inode in fsblock */
70
CT_INOOFF, /* byte offset in inode */
74
typedef struct ctydesc {
81
xfs_agblock_t agblock;
83
xfs_agnumber_t agnumber;
88
xfs_fsblock_t fsblock;
94
static __uint64_t bytevalue(ctype_t ctype, cval_t *val);
95
static int convert_f(int argc, char **argv);
96
static int getvalue(char *s, ctype_t ctype, cval_t *val);
97
static ctype_t lookupcty(char *ctyname);
99
static const char *agblock_names[] = { "agblock", "agbno", NULL };
100
static const char *agino_names[] = { "agino", "aginode", NULL };
101
static const char *agnumber_names[] = { "agnumber", "agno", NULL };
102
static const char *bboff_names[] = { "bboff", "daddroff", NULL };
103
static const char *blkoff_names[] = { "blkoff", "fsboff", "agboff",
105
static const char *byte_names[] = { "byte", "fsbyte", NULL };
106
static const char *daddr_names[] = { "daddr", "bb", NULL };
107
static const char *fsblock_names[] = { "fsblock", "fsb", "fsbno", NULL };
108
static const char *ino_names[] = { "ino", "inode", NULL };
109
static const char *inoidx_names[] = { "inoidx", "offset", NULL };
110
static const char *inooff_names[] = { "inooff", "inodeoff", NULL };
112
static const ctydesc_t ctydescs[NCTS] = {
113
{ CT_AGBLOCK, M(AGNUMBER)|M(BBOFF)|M(BLKOFF)|M(INOIDX)|M(INOOFF),
115
{ CT_AGINO, M(AGNUMBER)|M(INOOFF), agino_names },
117
M(AGBLOCK)|M(AGINO)|M(BBOFF)|M(BLKOFF)|M(INOIDX)|M(INOOFF),
119
{ CT_BBOFF, M(AGBLOCK)|M(AGNUMBER)|M(DADDR)|M(FSBLOCK), bboff_names },
120
{ CT_BLKOFF, M(AGBLOCK)|M(AGNUMBER)|M(FSBLOCK), blkoff_names },
121
{ CT_BYTE, 0, byte_names },
122
{ CT_DADDR, M(BBOFF), daddr_names },
123
{ CT_FSBLOCK, M(BBOFF)|M(BLKOFF)|M(INOIDX), fsblock_names },
124
{ CT_INO, M(INOOFF), ino_names },
125
{ CT_INOIDX, M(AGBLOCK)|M(AGNUMBER)|M(FSBLOCK)|M(INOOFF),
128
M(AGBLOCK)|M(AGINO)|M(AGNUMBER)|M(FSBLOCK)|M(INO)|M(INOIDX),
132
static const cmdinfo_t convert_cmd =
133
{ "convert", NULL, convert_f, 3, 9, 0, "type num [type num]... type",
134
"convert from one address form to another", NULL };
137
bytevalue(ctype_t ctype, cval_t *val)
141
return agblock_to_bytes(val->agblock);
143
return agino_to_bytes(val->agino);
145
return agnumber_to_bytes(val->agnumber);
147
return (__uint64_t)val->bboff;
149
return (__uint64_t)val->blkoff;
153
return daddr_to_bytes(val->daddr);
155
return fsblock_to_bytes(val->fsblock);
157
return ino_to_bytes(val->ino);
159
return inoidx_to_bytes(val->inoidx);
161
return (__uint64_t)val->inooff;
170
convert_f(int argc, char **argv)
180
/* move past the "convert" command */
184
if ((argc % 2) != 1) {
185
dbprintf("bad argument count %d to convert, expected 3,5,7,9 "
186
"arguments\n", argc);
189
if ((wtype = lookupcty(argv[argc - 1])) == CT_NONE) {
190
dbprintf("unknown conversion type %s\n", argv[argc - 1]);
194
for (i = mask = conmask = 0; i < (argc - 1) / 2; i++) {
195
c = lookupcty(argv[i * 2]);
197
dbprintf("unknown conversion type %s\n", argv[i * 2]);
201
dbprintf("result type same as argument\n");
204
if (conmask & (1 << c)) {
205
dbprintf("conflicting conversion type %s\n",
209
if (!getvalue(argv[i * 2 + 1], c, &cvals[c]))
212
conmask |= ~ctydescs[c].allowed;
214
if (cur_agno != NULLAGNUMBER && (conmask & M(AGNUMBER)) == 0) {
215
cvals[CT_AGNUMBER].agnumber = cur_agno;
217
conmask |= ~ctydescs[CT_AGNUMBER].allowed;
220
for (c = (ctype_t)0; c < NCTS; c++) {
221
if (!(mask & (1 << c)))
223
v += bytevalue(c, &cvals[c]);
227
v = XFS_DADDR_TO_AGBNO(mp, v >> BBSHIFT);
230
v = (v >> mp->m_sb.sb_inodelog) %
231
(mp->m_sb.sb_agblocks << mp->m_sb.sb_inopblog);
234
v = XFS_DADDR_TO_AGNO(mp, v >> BBSHIFT);
240
v &= mp->m_blockmask;
248
v = XFS_DADDR_TO_FSB(mp, v >> BBSHIFT);
251
v = XFS_AGINO_TO_INO(mp, XFS_DADDR_TO_AGNO(mp, v >> BBSHIFT),
252
(v >> mp->m_sb.sb_inodelog) %
253
(mp->m_sb.sb_agblocks << mp->m_sb.sb_inopblog));
256
v = (v >> mp->m_sb.sb_inodelog) & (mp->m_sb.sb_inopblock - 1);
259
v &= mp->m_sb.sb_inodesize - 1;
265
dbprintf("0x%llx (%llu)\n", v, v);
272
add_command(&convert_cmd);
276
getvalue(char *s, ctype_t ctype, cval_t *val)
281
v = strtoull(s, &p, 0);
283
dbprintf("%s is not a number\n", s);
288
val->agblock = (xfs_agblock_t)v;
291
val->agino = (xfs_agino_t)v;
294
val->agnumber = (xfs_agnumber_t)v;
300
val->blkoff = (int)v;
303
val->byte = (__uint64_t)v;
306
val->daddr = (xfs_daddr_t)v;
309
val->fsblock = (xfs_fsblock_t)v;
312
val->ino = (xfs_ino_t)v;
315
val->inoidx = (int)v;
318
val->inooff = (int)v;
328
lookupcty(char *ctyname)
333
for (cty = (ctype_t)0; cty < NCTS; cty++) {
334
for (name = ctydescs[cty].names; *name; name++) {
335
if (strcmp(ctyname, *name) == 0)