]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - db/convert.c
Undoes mod: xfs-cmds:slinx:120772a
[thirdparty/xfsprogs-dev.git] / db / convert.c
1 /*
2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
3 *
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.
7 *
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.
11 *
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.
18 *
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.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
32
33 #include <libxfs.h>
34 #include "command.h"
35 #include "data.h"
36 #include "convert.h"
37 #include "output.h"
38 #include "mount.h"
39
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)
57
58 typedef enum {
59 CT_NONE = -1,
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 */
71 NCTS
72 } ctype_t;
73
74 typedef struct ctydesc {
75 ctype_t ctype;
76 int allowed;
77 const char **names;
78 } ctydesc_t;
79
80 typedef union {
81 xfs_agblock_t agblock;
82 xfs_agino_t agino;
83 xfs_agnumber_t agnumber;
84 int bboff;
85 int blkoff;
86 __uint64_t byte;
87 xfs_daddr_t daddr;
88 xfs_fsblock_t fsblock;
89 xfs_ino_t ino;
90 int inoidx;
91 int inooff;
92 } cval_t;
93
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);
98
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",
104 NULL };
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 };
111
112 static const ctydesc_t ctydescs[NCTS] = {
113 { CT_AGBLOCK, M(AGNUMBER)|M(BBOFF)|M(BLKOFF)|M(INOIDX)|M(INOOFF),
114 agblock_names },
115 { CT_AGINO, M(AGNUMBER)|M(INOOFF), agino_names },
116 { CT_AGNUMBER,
117 M(AGBLOCK)|M(AGINO)|M(BBOFF)|M(BLKOFF)|M(INOIDX)|M(INOOFF),
118 agnumber_names },
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),
126 inoidx_names },
127 { CT_INOOFF,
128 M(AGBLOCK)|M(AGINO)|M(AGNUMBER)|M(FSBLOCK)|M(INO)|M(INOIDX),
129 inooff_names },
130 };
131
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 };
135
136 static __uint64_t
137 bytevalue(ctype_t ctype, cval_t *val)
138 {
139 switch (ctype) {
140 case CT_AGBLOCK:
141 return agblock_to_bytes(val->agblock);
142 case CT_AGINO:
143 return agino_to_bytes(val->agino);
144 case CT_AGNUMBER:
145 return agnumber_to_bytes(val->agnumber);
146 case CT_BBOFF:
147 return (__uint64_t)val->bboff;
148 case CT_BLKOFF:
149 return (__uint64_t)val->blkoff;
150 case CT_BYTE:
151 return val->byte;
152 case CT_DADDR:
153 return daddr_to_bytes(val->daddr);
154 case CT_FSBLOCK:
155 return fsblock_to_bytes(val->fsblock);
156 case CT_INO:
157 return ino_to_bytes(val->ino);
158 case CT_INOIDX:
159 return inoidx_to_bytes(val->inoidx);
160 case CT_INOOFF:
161 return (__uint64_t)val->inooff;
162 case CT_NONE:
163 case NCTS:
164 }
165 /* NOTREACHED */
166 return 0;
167 }
168
169 static int
170 convert_f(int argc, char **argv)
171 {
172 ctype_t c;
173 int conmask;
174 cval_t cvals[NCTS];
175 int i;
176 int mask;
177 __uint64_t v;
178 ctype_t wtype;
179
180 /* move past the "convert" command */
181 argc--;
182 argv++;
183
184 if ((argc % 2) != 1) {
185 dbprintf("bad argument count %d to convert, expected 3,5,7,9 "
186 "arguments\n", argc);
187 return 0;
188 }
189 if ((wtype = lookupcty(argv[argc - 1])) == CT_NONE) {
190 dbprintf("unknown conversion type %s\n", argv[argc - 1]);
191 return 0;
192 }
193
194 for (i = mask = conmask = 0; i < (argc - 1) / 2; i++) {
195 c = lookupcty(argv[i * 2]);
196 if (c == CT_NONE) {
197 dbprintf("unknown conversion type %s\n", argv[i * 2]);
198 return 0;
199 }
200 if (c == wtype) {
201 dbprintf("result type same as argument\n");
202 return 0;
203 }
204 if (conmask & (1 << c)) {
205 dbprintf("conflicting conversion type %s\n",
206 argv[i * 2]);
207 return 0;
208 }
209 if (!getvalue(argv[i * 2 + 1], c, &cvals[c]))
210 return 0;
211 mask |= 1 << c;
212 conmask |= ~ctydescs[c].allowed;
213 }
214 if (cur_agno != NULLAGNUMBER && (conmask & M(AGNUMBER)) == 0) {
215 cvals[CT_AGNUMBER].agnumber = cur_agno;
216 mask |= M(AGNUMBER);
217 conmask |= ~ctydescs[CT_AGNUMBER].allowed;
218 }
219 v = 0;
220 for (c = (ctype_t)0; c < NCTS; c++) {
221 if (!(mask & (1 << c)))
222 continue;
223 v += bytevalue(c, &cvals[c]);
224 }
225 switch (wtype) {
226 case CT_AGBLOCK:
227 v = XFS_DADDR_TO_AGBNO(mp, v >> BBSHIFT);
228 break;
229 case CT_AGINO:
230 v = (v >> mp->m_sb.sb_inodelog) %
231 (mp->m_sb.sb_agblocks << mp->m_sb.sb_inopblog);
232 break;
233 case CT_AGNUMBER:
234 v = XFS_DADDR_TO_AGNO(mp, v >> BBSHIFT);
235 break;
236 case CT_BBOFF:
237 v &= BBMASK;
238 break;
239 case CT_BLKOFF:
240 v &= mp->m_blockmask;
241 break;
242 case CT_BYTE:
243 break;
244 case CT_DADDR:
245 v >>= BBSHIFT;
246 break;
247 case CT_FSBLOCK:
248 v = XFS_DADDR_TO_FSB(mp, v >> BBSHIFT);
249 break;
250 case CT_INO:
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));
254 break;
255 case CT_INOIDX:
256 v = (v >> mp->m_sb.sb_inodelog) & (mp->m_sb.sb_inopblock - 1);
257 break;
258 case CT_INOOFF:
259 v &= mp->m_sb.sb_inodesize - 1;
260 break;
261 case CT_NONE:
262 case NCTS:
263 /* NOTREACHED */
264 }
265 dbprintf("0x%llx (%llu)\n", v, v);
266 return 0;
267 }
268
269 void
270 convert_init(void)
271 {
272 add_command(&convert_cmd);
273 }
274
275 static int
276 getvalue(char *s, ctype_t ctype, cval_t *val)
277 {
278 char *p;
279 __uint64_t v;
280
281 v = strtoull(s, &p, 0);
282 if (*p != '\0') {
283 dbprintf("%s is not a number\n", s);
284 return 0;
285 }
286 switch (ctype) {
287 case CT_AGBLOCK:
288 val->agblock = (xfs_agblock_t)v;
289 break;
290 case CT_AGINO:
291 val->agino = (xfs_agino_t)v;
292 break;
293 case CT_AGNUMBER:
294 val->agnumber = (xfs_agnumber_t)v;
295 break;
296 case CT_BBOFF:
297 val->bboff = (int)v;
298 break;
299 case CT_BLKOFF:
300 val->blkoff = (int)v;
301 break;
302 case CT_BYTE:
303 val->byte = (__uint64_t)v;
304 break;
305 case CT_DADDR:
306 val->daddr = (xfs_daddr_t)v;
307 break;
308 case CT_FSBLOCK:
309 val->fsblock = (xfs_fsblock_t)v;
310 break;
311 case CT_INO:
312 val->ino = (xfs_ino_t)v;
313 break;
314 case CT_INOIDX:
315 val->inoidx = (int)v;
316 break;
317 case CT_INOOFF:
318 val->inooff = (int)v;
319 break;
320 case CT_NONE:
321 case NCTS:
322 /* NOTREACHED */
323 }
324 return 1;
325 }
326
327 static ctype_t
328 lookupcty(char *ctyname)
329 {
330 ctype_t cty;
331 const char **name;
332
333 for (cty = (ctype_t)0; cty < NCTS; cty++) {
334 for (name = ctydescs[cty].names; *name; name++) {
335 if (strcmp(ctyname, *name) == 0)
336 return cty;
337 }
338 }
339 return CT_NONE;
340 }