]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - db/faddr.c
xfs_db: don't crash in ablock if there's no inode
[thirdparty/xfsprogs-dev.git] / db / faddr.c
CommitLineData
2bd0ea18 1/*
da23017d
NS
2 * Copyright (c) 2000-2001,2004-2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
dfc130f3 4 *
da23017d
NS
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
2bd0ea18 7 * published by the Free Software Foundation.
dfc130f3 8 *
da23017d
NS
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
dfc130f3 13 *
da23017d
NS
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2bd0ea18
NS
17 */
18
6b803e5a 19#include "libxfs.h"
2bd0ea18 20#include "type.h"
128efca1 21#include "fprint.h"
2bd0ea18 22#include "faddr.h"
128efca1 23#include "field.h"
2bd0ea18
NS
24#include "inode.h"
25#include "io.h"
26#include "bit.h"
27#include "bmap.h"
28#include "output.h"
4ca431fc 29#include "init.h"
2bd0ea18
NS
30
31void
32fa_agblock(
33 void *obj,
34 int bit,
35 typnm_t next)
36{
37 xfs_agblock_t bno;
38
39 if (cur_agno == NULLAGNUMBER) {
9ee7055c 40 dbprintf(_("no current allocation group, cannot set new addr\n"));
2bd0ea18
NS
41 return;
42 }
43 bno = (xfs_agblock_t)getbitval(obj, bit, bitsz(bno), BVUNSIGNED);
44 if (bno == NULLAGBLOCK) {
9ee7055c 45 dbprintf(_("null block number, cannot set new addr\n"));
2bd0ea18
NS
46 return;
47 }
48 ASSERT(typtab[next].typnm == next);
49 set_cur(&typtab[next], XFS_AGB_TO_DADDR(mp, cur_agno, bno), blkbb,
50 DB_RING_ADD, NULL);
51}
52
53/*ARGSUSED*/
54void
55fa_agino(
56 void *obj,
57 int bit,
58 typnm_t next)
59{
60 xfs_agino_t agino;
61
62 if (cur_agno == NULLAGNUMBER) {
9ee7055c 63 dbprintf(_("no current allocation group, cannot set new addr\n"));
2bd0ea18
NS
64 return;
65 }
66 agino = (xfs_agino_t)getbitval(obj, bit, bitsz(agino), BVUNSIGNED);
67 if (agino == NULLAGINO) {
9ee7055c 68 dbprintf(_("null inode number, cannot set new addr\n"));
2bd0ea18
NS
69 return;
70 }
71 set_cur_inode(XFS_AGINO_TO_INO(mp, cur_agno, agino));
72}
73
74/*ARGSUSED*/
75void
76fa_attrblock(
77 void *obj,
78 int bit,
79 typnm_t next)
80{
81 bmap_ext_t bm;
14f8b681 82 uint32_t bno;
5a35bf2c 83 xfs_fsblock_t dfsbno;
2bd0ea18
NS
84 int nex;
85
14f8b681 86 bno = (uint32_t)getbitval(obj, bit, bitsz(bno), BVUNSIGNED);
2bd0ea18 87 if (bno == 0) {
9ee7055c 88 dbprintf(_("null attribute block number, cannot set new addr\n"));
2bd0ea18
NS
89 return;
90 }
91 nex = 1;
92 bmap(bno, 1, XFS_ATTR_FORK, &nex, &bm);
93 if (nex == 0) {
9ee7055c 94 dbprintf(_("attribute block is unmapped\n"));
2bd0ea18
NS
95 return;
96 }
97 dfsbno = bm.startblock + (bno - bm.startoff);
98 ASSERT(typtab[next].typnm == next);
14f8b681 99 set_cur(&typtab[next], (int64_t)XFS_FSB_TO_DADDR(mp, dfsbno), blkbb,
2bd0ea18
NS
100 DB_RING_ADD, NULL);
101}
102
103void
104fa_cfileoffa(
105 void *obj,
106 int bit,
107 typnm_t next)
108{
109 bmap_ext_t bm;
5a35bf2c
DC
110 xfs_fileoff_t bno;
111 xfs_fsblock_t dfsbno;
2bd0ea18
NS
112 int nex;
113
5a35bf2c 114 bno = (xfs_fileoff_t)getbitval(obj, bit, BMBT_STARTOFF_BITLEN,
2bd0ea18 115 BVUNSIGNED);
5a35bf2c 116 if (bno == NULLFILEOFF) {
9ee7055c 117 dbprintf(_("null block number, cannot set new addr\n"));
2bd0ea18
NS
118 return;
119 }
120 nex = 1;
121 bmap(bno, 1, XFS_ATTR_FORK, &nex, &bm);
122 if (nex == 0) {
9ee7055c 123 dbprintf(_("file block is unmapped\n"));
2bd0ea18
NS
124 return;
125 }
126 dfsbno = bm.startblock + (bno - bm.startoff);
127 ASSERT(typtab[next].typnm == next);
128 set_cur(&typtab[next], XFS_FSB_TO_DADDR(mp, dfsbno), blkbb, DB_RING_ADD,
129 NULL);
130}
131
132void
133fa_cfileoffd(
134 void *obj,
135 int bit,
136 typnm_t next)
137{
138 bbmap_t bbmap;
139 bmap_ext_t *bmp;
5a35bf2c
DC
140 xfs_fileoff_t bno;
141 xfs_fsblock_t dfsbno;
2bd0ea18
NS
142 int nb;
143 int nex;
144
5a35bf2c 145 bno = (xfs_fileoff_t)getbitval(obj, bit, BMBT_STARTOFF_BITLEN,
2bd0ea18 146 BVUNSIGNED);
5a35bf2c 147 if (bno == NULLFILEOFF) {
9ee7055c 148 dbprintf(_("null block number, cannot set new addr\n"));
2bd0ea18
NS
149 return;
150 }
ff105f75 151 nex = nb = next == TYP_DIR2 ? mp->m_dir_geo->fsbcount : 1;
2bd0ea18
NS
152 bmp = malloc(nb * sizeof(*bmp));
153 bmap(bno, nb, XFS_DATA_FORK, &nex, bmp);
154 if (nex == 0) {
9ee7055c 155 dbprintf(_("file block is unmapped\n"));
2bd0ea18
NS
156 free(bmp);
157 return;
158 }
159 dfsbno = bmp->startblock + (bno - bmp->startoff);
160 ASSERT(typtab[next].typnm == next);
161 if (nex > 1)
162 make_bbmap(&bbmap, nex, bmp);
163 set_cur(&typtab[next], XFS_FSB_TO_DADDR(mp, dfsbno), nb * blkbb,
164 DB_RING_ADD, nex > 1 ? &bbmap: NULL);
165 free(bmp);
166}
167
168void
169fa_cfsblock(
170 void *obj,
171 int bit,
172 typnm_t next)
173{
5a35bf2c 174 xfs_fsblock_t bno;
cbead9df 175 int nb;
2bd0ea18 176
5a35bf2c 177 bno = (xfs_fsblock_t)getbitval(obj, bit, BMBT_STARTBLOCK_BITLEN,
2bd0ea18 178 BVUNSIGNED);
5a35bf2c 179 if (bno == NULLFSBLOCK) {
9ee7055c 180 dbprintf(_("null block number, cannot set new addr\n"));
2bd0ea18
NS
181 return;
182 }
ff105f75 183 nb = next == TYP_DIR2 ? mp->m_dir_geo->fsbcount : 1;
2bd0ea18 184 ASSERT(typtab[next].typnm == next);
cbead9df
NS
185 set_cur(&typtab[next], XFS_FSB_TO_DADDR(mp, bno), nb * blkbb,
186 DB_RING_ADD, NULL);
2bd0ea18
NS
187}
188
189void
190fa_dfiloffa(
191 void *obj,
192 int bit,
193 typnm_t next)
194{
195 bmap_ext_t bm;
5a35bf2c
DC
196 xfs_fileoff_t bno;
197 xfs_fsblock_t dfsbno;
2bd0ea18
NS
198 int nex;
199
5a35bf2c
DC
200 bno = (xfs_fileoff_t)getbitval(obj, bit, bitsz(bno), BVUNSIGNED);
201 if (bno == NULLFILEOFF) {
9ee7055c 202 dbprintf(_("null block number, cannot set new addr\n"));
2bd0ea18
NS
203 return;
204 }
205 nex = 1;
206 bmap(bno, 1, XFS_ATTR_FORK, &nex, &bm);
207 if (nex == 0) {
9ee7055c 208 dbprintf(_("file block is unmapped\n"));
2bd0ea18
NS
209 return;
210 }
211 dfsbno = bm.startblock + (bno - bm.startoff);
212 ASSERT(typtab[next].typnm == next);
213 set_cur(&typtab[next], XFS_FSB_TO_DADDR(mp, dfsbno), blkbb, DB_RING_ADD,
214 NULL);
215}
216
217void
218fa_dfiloffd(
219 void *obj,
220 int bit,
221 typnm_t next)
222{
223 bbmap_t bbmap;
224 bmap_ext_t *bmp;
5a35bf2c
DC
225 xfs_fileoff_t bno;
226 xfs_fsblock_t dfsbno;
2bd0ea18
NS
227 int nb;
228 int nex;
229
5a35bf2c
DC
230 bno = (xfs_fileoff_t)getbitval(obj, bit, bitsz(bno), BVUNSIGNED);
231 if (bno == NULLFILEOFF) {
9ee7055c 232 dbprintf(_("null block number, cannot set new addr\n"));
2bd0ea18
NS
233 return;
234 }
ff105f75 235 nex = nb = next == TYP_DIR2 ? mp->m_dir_geo->fsbcount : 1;
2bd0ea18
NS
236 bmp = malloc(nb * sizeof(*bmp));
237 bmap(bno, nb, XFS_DATA_FORK, &nex, bmp);
238 if (nex == 0) {
9ee7055c 239 dbprintf(_("file block is unmapped\n"));
2bd0ea18
NS
240 free(bmp);
241 return;
242 }
243 dfsbno = bmp->startblock + (bno - bmp->startoff);
244 ASSERT(typtab[next].typnm == next);
245 if (nex > 1)
246 make_bbmap(&bbmap, nex, bmp);
247 set_cur(&typtab[next], XFS_FSB_TO_DADDR(mp, dfsbno), nb * blkbb,
248 DB_RING_ADD, nex > 1 ? &bbmap : NULL);
249 free(bmp);
250}
251
252void
253fa_dfsbno(
254 void *obj,
255 int bit,
256 typnm_t next)
257{
5a35bf2c 258 xfs_fsblock_t bno;
2bd0ea18 259
5a35bf2c
DC
260 bno = (xfs_fsblock_t)getbitval(obj, bit, bitsz(bno), BVUNSIGNED);
261 if (bno == NULLFSBLOCK) {
9ee7055c 262 dbprintf(_("null block number, cannot set new addr\n"));
2bd0ea18
NS
263 return;
264 }
265 ASSERT(typtab[next].typnm == next);
266 set_cur(&typtab[next], XFS_FSB_TO_DADDR(mp, bno), blkbb, DB_RING_ADD,
267 NULL);
268}
269
270/*ARGSUSED*/
271void
272fa_dirblock(
273 void *obj,
274 int bit,
275 typnm_t next)
276{
277 bbmap_t bbmap;
278 bmap_ext_t *bmp;
14f8b681 279 uint32_t bno;
5a35bf2c 280 xfs_fsblock_t dfsbno;
2bd0ea18
NS
281 int nex;
282
14f8b681 283 bno = (uint32_t)getbitval(obj, bit, bitsz(bno), BVUNSIGNED);
2bd0ea18 284 if (bno == 0) {
9ee7055c 285 dbprintf(_("null directory block number, cannot set new addr\n"));
2bd0ea18
NS
286 return;
287 }
ff105f75 288 nex = mp->m_dir_geo->fsbcount;
2bd0ea18 289 bmp = malloc(nex * sizeof(*bmp));
ff105f75 290 bmap(bno, mp->m_dir_geo->fsbcount, XFS_DATA_FORK, &nex, bmp);
2bd0ea18 291 if (nex == 0) {
9ee7055c 292 dbprintf(_("directory block is unmapped\n"));
2bd0ea18
NS
293 free(bmp);
294 return;
295 }
296 dfsbno = bmp->startblock + (bno - bmp->startoff);
297 ASSERT(typtab[next].typnm == next);
298 if (nex > 1)
299 make_bbmap(&bbmap, nex, bmp);
14f8b681 300 set_cur(&typtab[next], (int64_t)XFS_FSB_TO_DADDR(mp, dfsbno),
ff105f75 301 XFS_FSB_TO_BB(mp, mp->m_dir_geo->fsbcount), DB_RING_ADD,
2bd0ea18
NS
302 nex > 1 ? &bbmap : NULL);
303 free(bmp);
304}
305
306void
307fa_drfsbno(
308 void *obj,
309 int bit,
310 typnm_t next)
311{
5a35bf2c 312 xfs_rfsblock_t bno;
2bd0ea18 313
5a35bf2c
DC
314 bno = (xfs_rfsblock_t)getbitval(obj, bit, bitsz(bno), BVUNSIGNED);
315 if (bno == NULLRFSBLOCK) {
9ee7055c 316 dbprintf(_("null block number, cannot set new addr\n"));
2bd0ea18
NS
317 return;
318 }
319 ASSERT(typtab[next].typnm == next);
14f8b681 320 set_cur(&typtab[next], (int64_t)XFS_FSB_TO_BB(mp, bno), blkbb,
2bd0ea18
NS
321 DB_RING_ADD, NULL);
322}
323
324/*ARGSUSED*/
325void
326fa_drtbno(
327 void *obj,
328 int bit,
329 typnm_t next)
330{
5a35bf2c 331 xfs_rtblock_t bno;
2bd0ea18 332
5a35bf2c
DC
333 bno = (xfs_rtblock_t)getbitval(obj, bit, bitsz(bno), BVUNSIGNED);
334 if (bno == NULLRTBLOCK) {
9ee7055c 335 dbprintf(_("null block number, cannot set new addr\n"));
2bd0ea18
NS
336 return;
337 }
338 /* need set_cur to understand rt subvolume */
339}
340
341/*ARGSUSED*/
342void
343fa_ino(
344 void *obj,
345 int bit,
346 typnm_t next)
347{
348 xfs_ino_t ino;
349
350 ASSERT(next == TYP_INODE);
351 ino = (xfs_ino_t)getbitval(obj, bit, bitsz(ino), BVUNSIGNED);
352 if (ino == NULLFSINO) {
9ee7055c 353 dbprintf(_("null inode number, cannot set new addr\n"));
2bd0ea18
NS
354 return;
355 }
356 set_cur_inode(ino);
357}
358
359void
360fa_ino4(
361 void *obj,
362 int bit,
363 typnm_t next)
364{
365 xfs_ino_t ino;
2bd0ea18
NS
366
367 ASSERT(next == TYP_INODE);
d8bf9c63 368 ino = (xfs_ino_t)getbitval(obj, bit, bitsz(XFS_INO32_SIZE), BVUNSIGNED);
2bd0ea18 369 if (ino == NULLFSINO) {
9ee7055c 370 dbprintf(_("null inode number, cannot set new addr\n"));
2bd0ea18
NS
371 return;
372 }
373 set_cur_inode(ino);
374}
375
376void
377fa_ino8(
378 void *obj,
379 int bit,
380 typnm_t next)
381{
382 xfs_ino_t ino;
2bd0ea18
NS
383
384 ASSERT(next == TYP_INODE);
d8bf9c63 385 ino = (xfs_ino_t)getbitval(obj, bit, bitsz(XFS_INO64_SIZE), BVUNSIGNED);
2bd0ea18 386 if (ino == NULLFSINO) {
9ee7055c 387 dbprintf(_("null inode number, cannot set new addr\n"));
2bd0ea18
NS
388 return;
389 }
390 set_cur_inode(ino);
391}