]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - db/convert.c
2 * Copyright (c) 2000-2001 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/
39 #define M(A) (1 << CT_ ## A)
40 #define agblock_to_bytes(x) \
41 ((__uint64_t)(x) << mp->m_sb.sb_blocklog)
42 #define agino_to_bytes(x) \
43 ((__uint64_t)(x) << mp->m_sb.sb_inodelog)
44 #define agnumber_to_bytes(x) \
45 agblock_to_bytes((__uint64_t)(x) * mp->m_sb.sb_agblocks)
46 #define daddr_to_bytes(x) \
47 ((__uint64_t)(x) << BBSHIFT)
48 #define fsblock_to_bytes(x) \
49 (agnumber_to_bytes(XFS_FSB_TO_AGNO(mp, (x))) + \
50 agblock_to_bytes(XFS_FSB_TO_AGBNO(mp, (x))))
51 #define ino_to_bytes(x) \
52 (agnumber_to_bytes(XFS_INO_TO_AGNO(mp, (x))) + \
53 agino_to_bytes(XFS_INO_TO_AGINO(mp, (x))))
54 #define inoidx_to_bytes(x) \
55 ((__uint64_t)(x) << mp->m_sb.sb_inodelog)
59 CT_AGBLOCK
, /* xfs_agblock_t */
60 CT_AGINO
, /* xfs_agino_t */
61 CT_AGNUMBER
, /* xfs_agno_t */
62 CT_BBOFF
, /* byte offset in daddr */
63 CT_BLKOFF
, /* byte offset in fsb/agb */
64 CT_BYTE
, /* byte in filesystem */
65 CT_DADDR
, /* daddr_t */
66 CT_FSBLOCK
, /* xfs_fsblock_t */
67 CT_INO
, /* xfs_ino_t */
68 CT_INOIDX
, /* index of inode in fsblock */
69 CT_INOOFF
, /* byte offset in inode */
73 typedef struct ctydesc
{
80 xfs_agblock_t agblock
;
82 xfs_agnumber_t agnumber
;
87 xfs_fsblock_t fsblock
;
93 static __uint64_t
bytevalue(ctype_t ctype
, cval_t
*val
);
94 static int convert_f(int argc
, char **argv
);
95 static int getvalue(char *s
, ctype_t ctype
, cval_t
*val
);
96 static ctype_t
lookupcty(char *ctyname
);
98 static const char *agblock_names
[] = { "agblock", "agbno", NULL
};
99 static const char *agino_names
[] = { "agino", "aginode", NULL
};
100 static const char *agnumber_names
[] = { "agnumber", "agno", NULL
};
101 static const char *bboff_names
[] = { "bboff", "daddroff", NULL
};
102 static const char *blkoff_names
[] = { "blkoff", "fsboff", "agboff",
104 static const char *byte_names
[] = { "byte", "fsbyte", NULL
};
105 static const char *daddr_names
[] = { "daddr", "bb", NULL
};
106 static const char *fsblock_names
[] = { "fsblock", "fsb", "fsbno", NULL
};
107 static const char *ino_names
[] = { "ino", "inode", NULL
};
108 static const char *inoidx_names
[] = { "inoidx", "offset", NULL
};
109 static const char *inooff_names
[] = { "inooff", "inodeoff", NULL
};
111 static const ctydesc_t ctydescs
[NCTS
] = {
112 { CT_AGBLOCK
, M(AGNUMBER
)|M(BBOFF
)|M(BLKOFF
)|M(INOIDX
)|M(INOOFF
),
114 { CT_AGINO
, M(AGNUMBER
)|M(INOOFF
), agino_names
},
116 M(AGBLOCK
)|M(AGINO
)|M(BBOFF
)|M(BLKOFF
)|M(INOIDX
)|M(INOOFF
),
118 { CT_BBOFF
, M(AGBLOCK
)|M(AGNUMBER
)|M(DADDR
)|M(FSBLOCK
), bboff_names
},
119 { CT_BLKOFF
, M(AGBLOCK
)|M(AGNUMBER
)|M(FSBLOCK
), blkoff_names
},
120 { CT_BYTE
, 0, byte_names
},
121 { CT_DADDR
, M(BBOFF
), daddr_names
},
122 { CT_FSBLOCK
, M(BBOFF
)|M(BLKOFF
)|M(INOIDX
), fsblock_names
},
123 { CT_INO
, M(INOOFF
), ino_names
},
124 { CT_INOIDX
, M(AGBLOCK
)|M(AGNUMBER
)|M(FSBLOCK
)|M(INOOFF
),
127 M(AGBLOCK
)|M(AGINO
)|M(AGNUMBER
)|M(FSBLOCK
)|M(INO
)|M(INOIDX
),
131 static const cmdinfo_t convert_cmd
=
132 { "convert", NULL
, convert_f
, 3, 9, 0, "type num [type num]... type",
133 "convert from one address form to another", NULL
};
136 bytevalue(ctype_t ctype
, cval_t
*val
)
140 return agblock_to_bytes(val
->agblock
);
142 return agino_to_bytes(val
->agino
);
144 return agnumber_to_bytes(val
->agnumber
);
146 return (__uint64_t
)val
->bboff
;
148 return (__uint64_t
)val
->blkoff
;
152 return daddr_to_bytes(val
->daddr
);
154 return fsblock_to_bytes(val
->fsblock
);
156 return ino_to_bytes(val
->ino
);
158 return inoidx_to_bytes(val
->inoidx
);
160 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;
266 dbprintf("0x%llx (%llu)\n", v
, v
);
273 add_command(&convert_cmd
);
277 getvalue(char *s
, ctype_t ctype
, cval_t
*val
)
282 v
= strtoull(s
, &p
, 0);
284 dbprintf("%s is not a number\n", s
);
289 val
->agblock
= (xfs_agblock_t
)v
;
292 val
->agino
= (xfs_agino_t
)v
;
295 val
->agnumber
= (xfs_agnumber_t
)v
;
301 val
->blkoff
= (int)v
;
304 val
->byte
= (__uint64_t
)v
;
307 val
->daddr
= (xfs_daddr_t
)v
;
310 val
->fsblock
= (xfs_fsblock_t
)v
;
313 val
->ino
= (xfs_ino_t
)v
;
316 val
->inoidx
= (int)v
;
319 val
->inooff
= (int)v
;
330 lookupcty(char *ctyname
)
335 for (cty
= (ctype_t
)0; cty
< NCTS
; cty
++) {
336 for (name
= ctydescs
[cty
].names
; *name
; name
++) {
337 if (strcmp(ctyname
, *name
) == 0)