]>
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/
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)