]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - db/convert.c
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
12 #define M(A) (1 << CT_ ## A)
13 #define agblock_to_bytes(x) \
14 ((uint64_t)(x) << mp->m_sb.sb_blocklog)
15 #define agino_to_bytes(x) \
16 ((uint64_t)(x) << mp->m_sb.sb_inodelog)
17 #define agnumber_to_bytes(x) \
18 agblock_to_bytes((uint64_t)(x) * mp->m_sb.sb_agblocks)
19 #define daddr_to_bytes(x) \
20 ((uint64_t)(x) << BBSHIFT)
21 #define fsblock_to_bytes(x) \
22 (agnumber_to_bytes(XFS_FSB_TO_AGNO(mp, (x))) + \
23 agblock_to_bytes(XFS_FSB_TO_AGBNO(mp, (x))))
24 #define ino_to_bytes(x) \
25 (agnumber_to_bytes(XFS_INO_TO_AGNO(mp, (x))) + \
26 agino_to_bytes(XFS_INO_TO_AGINO(mp, (x))))
27 #define inoidx_to_bytes(x) \
28 ((uint64_t)(x) << mp->m_sb.sb_inodelog)
32 CT_AGBLOCK
, /* xfs_agblock_t */
33 CT_AGINO
, /* xfs_agino_t */
34 CT_AGNUMBER
, /* xfs_agno_t */
35 CT_BBOFF
, /* byte offset in daddr */
36 CT_BLKOFF
, /* byte offset in fsb/agb */
37 CT_BYTE
, /* byte in filesystem */
38 CT_DADDR
, /* daddr_t */
39 CT_FSBLOCK
, /* xfs_fsblock_t */
40 CT_INO
, /* xfs_ino_t */
41 CT_INOIDX
, /* index of inode in fsblock */
42 CT_INOOFF
, /* byte offset in inode */
46 typedef struct ctydesc
{
53 xfs_agblock_t agblock
;
55 xfs_agnumber_t agnumber
;
60 xfs_fsblock_t fsblock
;
66 static uint64_t bytevalue(ctype_t ctype
, cval_t
*val
);
67 static int convert_f(int argc
, char **argv
);
68 static int getvalue(char *s
, ctype_t ctype
, cval_t
*val
);
69 static ctype_t
lookupcty(char *ctyname
);
71 static const char *agblock_names
[] = { "agblock", "agbno", NULL
};
72 static const char *agino_names
[] = { "agino", "aginode", NULL
};
73 static const char *agnumber_names
[] = { "agnumber", "agno", NULL
};
74 static const char *bboff_names
[] = { "bboff", "daddroff", NULL
};
75 static const char *blkoff_names
[] = { "blkoff", "fsboff", "agboff",
77 static const char *byte_names
[] = { "byte", "fsbyte", NULL
};
78 static const char *daddr_names
[] = { "daddr", "bb", NULL
};
79 static const char *fsblock_names
[] = { "fsblock", "fsb", "fsbno", NULL
};
80 static const char *ino_names
[] = { "ino", "inode", NULL
};
81 static const char *inoidx_names
[] = { "inoidx", "offset", NULL
};
82 static const char *inooff_names
[] = { "inooff", "inodeoff", NULL
};
84 static const ctydesc_t ctydescs
[NCTS
] = {
85 { CT_AGBLOCK
, M(AGNUMBER
)|M(BBOFF
)|M(BLKOFF
)|M(INOIDX
)|M(INOOFF
),
87 { CT_AGINO
, M(AGNUMBER
)|M(INOOFF
), agino_names
},
89 M(AGBLOCK
)|M(AGINO
)|M(BBOFF
)|M(BLKOFF
)|M(INOIDX
)|M(INOOFF
),
91 { CT_BBOFF
, M(AGBLOCK
)|M(AGNUMBER
)|M(DADDR
)|M(FSBLOCK
), bboff_names
},
92 { CT_BLKOFF
, M(AGBLOCK
)|M(AGNUMBER
)|M(FSBLOCK
), blkoff_names
},
93 { CT_BYTE
, 0, byte_names
},
94 { CT_DADDR
, M(BBOFF
), daddr_names
},
95 { CT_FSBLOCK
, M(BBOFF
)|M(BLKOFF
)|M(INOIDX
), fsblock_names
},
96 { CT_INO
, M(INOOFF
), ino_names
},
97 { CT_INOIDX
, M(AGBLOCK
)|M(AGNUMBER
)|M(FSBLOCK
)|M(INOOFF
),
100 M(AGBLOCK
)|M(AGINO
)|M(AGNUMBER
)|M(FSBLOCK
)|M(INO
)|M(INOIDX
),
104 static const cmdinfo_t convert_cmd
=
105 { "convert", NULL
, convert_f
, 3, 9, 0, "type num [type num]... type",
106 "convert from one address form to another", NULL
};
109 bytevalue(ctype_t ctype
, cval_t
*val
)
113 return agblock_to_bytes(val
->agblock
);
115 return agino_to_bytes(val
->agino
);
117 return agnumber_to_bytes(val
->agnumber
);
119 return (uint64_t)val
->bboff
;
121 return (uint64_t)val
->blkoff
;
125 return daddr_to_bytes(val
->daddr
);
127 return fsblock_to_bytes(val
->fsblock
);
129 return ino_to_bytes(val
->ino
);
131 return inoidx_to_bytes(val
->inoidx
);
133 return (uint64_t)val
->inooff
;
143 convert_f(int argc
, char **argv
)
147 cval_t cvals
[NCTS
] = {};
153 /* move past the "convert" command */
157 if ((argc
% 2) != 1) {
158 dbprintf(_("bad argument count %d to convert, expected 3,5,7,9 "
159 "arguments\n"), argc
);
162 if ((wtype
= lookupcty(argv
[argc
- 1])) == CT_NONE
) {
163 dbprintf(_("unknown conversion type %s\n"), argv
[argc
- 1]);
167 for (i
= mask
= conmask
= 0; i
< (argc
- 1) / 2; i
++) {
168 c
= lookupcty(argv
[i
* 2]);
170 dbprintf(_("unknown conversion type %s\n"), argv
[i
* 2]);
174 dbprintf(_("result type same as argument\n"));
177 if (conmask
& (1 << c
)) {
178 dbprintf(_("conflicting conversion type %s\n"),
182 if (!getvalue(argv
[i
* 2 + 1], c
, &cvals
[c
]))
185 conmask
|= ~ctydescs
[c
].allowed
;
187 if (cur_agno
!= NULLAGNUMBER
&& (conmask
& M(AGNUMBER
)) == 0) {
188 cvals
[CT_AGNUMBER
].agnumber
= cur_agno
;
192 for (c
= (ctype_t
)0; c
< NCTS
; c
++) {
193 if (!(mask
& (1 << c
)))
195 v
+= bytevalue(c
, &cvals
[c
]);
199 v
= xfs_daddr_to_agbno(mp
, v
>> BBSHIFT
);
202 v
= (v
>> mp
->m_sb
.sb_inodelog
) %
203 XFS_AGB_TO_AGINO(mp
, mp
->m_sb
.sb_agblocks
);
206 v
= xfs_daddr_to_agno(mp
, v
>> BBSHIFT
);
212 v
&= mp
->m_blockmask
;
220 v
= XFS_DADDR_TO_FSB(mp
, v
>> BBSHIFT
);
223 v
= XFS_AGINO_TO_INO(mp
, xfs_daddr_to_agno(mp
, v
>> BBSHIFT
),
224 (v
>> mp
->m_sb
.sb_inodelog
) %
225 XFS_AGB_TO_AGINO(mp
, mp
->m_sb
.sb_agblocks
));
228 v
= (v
>> mp
->m_sb
.sb_inodelog
) & (mp
->m_sb
.sb_inopblock
- 1);
231 v
&= mp
->m_sb
.sb_inodesize
- 1;
238 dbprintf("0x%llx (%llu)\n", v
, v
);
245 add_command(&convert_cmd
);
249 getvalue(char *s
, ctype_t ctype
, cval_t
*val
)
254 v
= strtoull(s
, &p
, 0);
256 dbprintf(_("%s is not a number\n"), s
);
261 val
->agblock
= (xfs_agblock_t
)v
;
264 val
->agino
= (xfs_agino_t
)v
;
267 val
->agnumber
= (xfs_agnumber_t
)v
;
273 val
->blkoff
= (int)v
;
276 val
->byte
= (uint64_t)v
;
279 val
->daddr
= (xfs_daddr_t
)v
;
282 val
->fsblock
= (xfs_fsblock_t
)v
;
285 val
->ino
= (xfs_ino_t
)v
;
288 val
->inoidx
= (int)v
;
291 val
->inooff
= (int)v
;
302 lookupcty(char *ctyname
)
307 for (cty
= (ctype_t
)0; cty
< NCTS
; cty
++) {
308 for (name
= ctydescs
[cty
].names
; *name
; name
++) {
309 if (strcmp(ctyname
, *name
) == 0)