]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - db/bmap.c
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
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
7 * published by the Free Software Foundation.
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.
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
19 #include <xfs/libxfs.h>
31 static int bmap_f(int argc
, char **argv
);
32 static int bmap_one_extent(xfs_bmbt_rec_64_t
*ep
,
33 xfs_dfiloff_t
*offp
, xfs_dfiloff_t eoff
,
34 int *idxp
, bmap_ext_t
*bep
);
35 static xfs_fsblock_t
select_child(xfs_dfiloff_t off
, xfs_bmbt_key_t
*kp
,
36 xfs_bmbt_ptr_t
*pp
, int nrecs
);
38 static const cmdinfo_t bmap_cmd
=
39 { "bmap", NULL
, bmap_f
, 0, 3, 0, "[-ad] [block [len]]",
40 "show block map for current file", NULL
};
50 struct xfs_btree_block
*block
;
52 xfs_dfiloff_t curoffset
;
54 xfs_dfiloff_t eoffset
;
55 xfs_bmbt_rec_64_t
*ep
;
61 xfs_fsblock_t nextbno
;
64 xfs_bmdr_block_t
*rblock
;
66 xfs_bmbt_rec_64_t
*xp
;
69 set_cur_inode(iocur_top
->ino
);
73 dip
= iocur_top
->data
;
75 eoffset
= offset
+ len
- 1;
77 fmt
= (xfs_dinode_fmt_t
)XFS_DFORK_FORMAT(dip
, whichfork
);
78 typ
= whichfork
== XFS_DATA_FORK
? TYP_BMAPBTD
: TYP_BMAPBTA
;
79 ASSERT(typtab
[typ
].typnm
== typ
);
80 ASSERT(fmt
== XFS_DINODE_FMT_LOCAL
|| fmt
== XFS_DINODE_FMT_EXTENTS
||
81 fmt
== XFS_DINODE_FMT_BTREE
);
82 if (fmt
== XFS_DINODE_FMT_EXTENTS
) {
83 nextents
= XFS_DFORK_NEXTENTS(dip
, whichfork
);
84 xp
= (xfs_bmbt_rec_64_t
*)XFS_DFORK_PTR(dip
, whichfork
);
85 for (ep
= xp
; ep
< &xp
[nextents
] && n
< nex
; ep
++) {
86 if (!bmap_one_extent(ep
, &curoffset
, eoffset
, &n
, bep
))
89 } else if (fmt
== XFS_DINODE_FMT_BTREE
) {
92 rblock
= (xfs_bmdr_block_t
*)XFS_DFORK_PTR(dip
, whichfork
);
93 fsize
= XFS_DFORK_SIZE(dip
, mp
, whichfork
);
94 pp
= XFS_BMDR_PTR_ADDR(rblock
, 1, xfs_bmdr_maxrecs(mp
, fsize
, 0));
95 kp
= XFS_BMDR_KEY_ADDR(rblock
, 1);
96 bno
= select_child(curoffset
, kp
, pp
,
97 be16_to_cpu(rblock
->bb_numrecs
));
99 set_cur(&typtab
[typ
], XFS_FSB_TO_DADDR(mp
, bno
),
100 blkbb
, DB_RING_IGN
, NULL
);
101 block
= (struct xfs_btree_block
*)iocur_top
->data
;
102 if (be16_to_cpu(block
->bb_level
) == 0)
104 pp
= XFS_BMDR_PTR_ADDR(block
, 1,
105 xfs_bmbt_maxrecs(mp
, mp
->m_sb
.sb_blocksize
, 0));
106 kp
= XFS_BMDR_KEY_ADDR(block
, 1);
107 bno
= select_child(curoffset
, kp
, pp
,
108 be16_to_cpu(block
->bb_numrecs
));
111 nextbno
= be64_to_cpu(block
->bb_u
.l
.bb_rightsib
);
112 nextents
= be16_to_cpu(block
->bb_numrecs
);
113 xp
= (xfs_bmbt_rec_64_t
*)
114 XFS_BMBT_REC_ADDR(mp
, block
, 1);
115 for (ep
= xp
; ep
< &xp
[nextents
] && n
< nex
; ep
++) {
116 if (!bmap_one_extent(ep
, &curoffset
, eoffset
,
118 nextbno
= NULLFSBLOCK
;
123 if (bno
== NULLFSBLOCK
)
125 set_cur(&typtab
[typ
], XFS_FSB_TO_DADDR(mp
, bno
),
126 blkbb
, DB_RING_IGN
, NULL
);
127 block
= (struct xfs_btree_block
*)iocur_top
->data
;
143 xfs_dfiloff_t co
, cosave
;
152 if (iocur_top
->ino
== NULLFSINO
) {
153 dbprintf("no current inode\n");
157 if (argc
) while ((c
= getopt(argc
, argv
, "ad")) != EOF
) {
166 dbprintf("bad option for bmap command\n");
170 if (afork
+ dfork
== 0) {
172 set_cur_inode(iocur_top
->ino
);
173 dip
= iocur_top
->data
;
174 if (be32_to_cpu(dip
->di_core
.di_nextents
))
176 if (be16_to_cpu(dip
->di_core
.di_anextents
))
181 co
= (xfs_dfiloff_t
)strtoull(argv
[optind
], &p
, 0);
183 dbprintf("bad block number for bmap %s\n",
189 len
= (xfs_dfilblks_t
)strtoull(argv
[optind
], &p
, 0);
191 dbprintf("bad len for bmap %s\n", argv
[optind
]);
202 for (whichfork
= XFS_DATA_FORK
;
203 whichfork
<= XFS_ATTR_FORK
;
205 if (whichfork
== XFS_DATA_FORK
&& !dfork
)
207 if (whichfork
== XFS_ATTR_FORK
&& !afork
)
211 bmap(co
, eo
- co
+ 1, whichfork
, &nex
, &be
);
214 dbprintf("%s offset %lld startblock %llu (%u/%u) count "
216 whichfork
== XFS_DATA_FORK
? "data" : "attr",
217 be
.startoff
, be
.startblock
,
218 XFS_FSB_TO_AGNO(mp
, be
.startblock
),
219 XFS_FSB_TO_AGBNO(mp
, be
.startblock
),
220 be
.blockcount
, be
.flag
);
221 co
= be
.startoff
+ be
.blockcount
;
231 add_command(&bmap_cmd
);
236 xfs_bmbt_rec_64_t
*ep
,
243 xfs_dfiloff_t curoffset
;
249 convert_extent(ep
, &o
, &s
, &c
, &f
);
252 if (o
+ c
<= curoffset
)
261 if (o
+ c
- 1 > eoff
)
262 c
-= (o
+ c
- 1) - eoff
;
263 bep
[idx
].startoff
= o
;
264 bep
[idx
].startblock
= s
;
265 bep
[idx
].blockcount
= c
;
274 xfs_bmbt_rec_64_t
*rp
,
280 xfs_bmbt_irec_t irec
, *s
= &irec
;
281 xfs_bmbt_rec_t rpcopy
, *p
= &rpcopy
;
283 memmove(&rpcopy
, rp
, sizeof(rpcopy
));
284 libxfs_bmbt_disk_get_all(p
, s
);
286 if (s
->br_state
== XFS_EXT_UNWRITTEN
) {
292 *op
= s
->br_startoff
;
293 *sp
= s
->br_startblock
;
294 *cp
= s
->br_blockcount
;
309 for (i
= 0, d
= 0; i
< nex
; i
++) {
310 dfsbno
= bmp
[i
].startblock
;
311 for (j
= 0; j
< bmp
[i
].blockcount
; j
++, dfsbno
++) {
312 for (k
= 0; k
< blkbb
; k
++)
314 XFS_FSB_TO_DADDR(mp
, dfsbno
) + k
;
328 for (i
= 0; i
< nrecs
; i
++) {
329 if (be64_to_cpu(kp
[i
].br_startoff
) == off
)
330 return be64_to_cpu(pp
[i
]);
331 if (be64_to_cpu(kp
[i
].br_startoff
) > off
) {
333 return be64_to_cpu(pp
[i
]);
335 return be64_to_cpu(pp
[i
- 1]);
338 return be64_to_cpu(pp
[nrecs
- 1]);