~ubuntu-branches/ubuntu/utopic/xfsprogs/utopic-proposed

« back to all changes in this revision

Viewing changes to db/convert.c

  • Committer: Bazaar Package Importer
  • Author(s): Nathan Scott
  • Date: 2002-04-13 09:45:06 UTC
  • Revision ID: james.westby@ubuntu.com-20020413094506-t8dhemv41gkeg4kx
Tags: 2.0.3-1
New upstream bugfix release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}