]>
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
31 static int bmap_f(int argc
, char **argv
);
32 static int bmap_one_extent(xfs_bmbt_rec_t
*ep
,
33 xfs_fileoff_t
*offp
, xfs_fileoff_t eoff
,
34 int *idxp
, bmap_ext_t
*bep
);
35 static xfs_fsblock_t
select_child(xfs_fileoff_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, N_("[-ad] [block [len]]"),
40 N_("show block map for current file"), NULL
};
50 struct xfs_btree_block
*block
;
52 xfs_fileoff_t curoffset
;
54 xfs_fileoff_t eoffset
;
61 xfs_fsblock_t nextbno
;
64 xfs_bmdr_block_t
*rblock
;
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_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
) {
91 rblock
= (xfs_bmdr_block_t
*)XFS_DFORK_PTR(dip
, whichfork
);
92 fsize
= XFS_DFORK_SIZE(dip
, mp
, whichfork
);
93 pp
= XFS_BMDR_PTR_ADDR(rblock
, 1, libxfs_bmdr_maxrecs(fsize
, 0));
94 kp
= XFS_BMDR_KEY_ADDR(rblock
, 1);
95 bno
= select_child(curoffset
, kp
, pp
,
96 be16_to_cpu(rblock
->bb_numrecs
));
98 set_cur(&typtab
[typ
], XFS_FSB_TO_DADDR(mp
, bno
),
99 blkbb
, DB_RING_IGN
, NULL
);
100 block
= (struct xfs_btree_block
*)iocur_top
->data
;
101 if (be16_to_cpu(block
->bb_level
) == 0)
103 pp
= XFS_BMBT_PTR_ADDR(mp
, block
, 1,
104 libxfs_bmbt_maxrecs(mp
, mp
->m_sb
.sb_blocksize
, 0));
105 kp
= XFS_BMBT_KEY_ADDR(mp
, block
, 1);
106 bno
= select_child(curoffset
, kp
, pp
,
107 be16_to_cpu(block
->bb_numrecs
));
110 nextbno
= be64_to_cpu(block
->bb_u
.l
.bb_rightsib
);
111 nextents
= be16_to_cpu(block
->bb_numrecs
);
112 xp
= (xfs_bmbt_rec_t
*)
113 XFS_BMBT_REC_ADDR(mp
, block
, 1);
114 for (ep
= xp
; ep
< &xp
[nextents
] && n
< nex
; ep
++) {
115 if (!bmap_one_extent(ep
, &curoffset
, eoffset
,
117 nextbno
= NULLFSBLOCK
;
122 if (bno
== NULLFSBLOCK
)
124 set_cur(&typtab
[typ
], XFS_FSB_TO_DADDR(mp
, bno
),
125 blkbb
, DB_RING_IGN
, NULL
);
126 block
= (struct xfs_btree_block
*)iocur_top
->data
;
142 xfs_fileoff_t co
, cosave
;
151 if (iocur_top
->ino
== NULLFSINO
) {
152 dbprintf(_("no current inode\n"));
156 if (argc
) while ((c
= getopt(argc
, argv
, "ad")) != EOF
) {
165 dbprintf(_("bad option for bmap command\n"));
169 if (afork
+ dfork
== 0) {
171 set_cur_inode(iocur_top
->ino
);
172 dip
= iocur_top
->data
;
173 if (be32_to_cpu(dip
->di_nextents
))
175 if (be16_to_cpu(dip
->di_anextents
))
180 co
= (xfs_fileoff_t
)strtoull(argv
[optind
], &p
, 0);
182 dbprintf(_("bad block number for bmap %s\n"),
188 len
= (xfs_filblks_t
)strtoull(argv
[optind
], &p
, 0);
190 dbprintf(_("bad len for bmap %s\n"), argv
[optind
]);
201 for (whichfork
= XFS_DATA_FORK
;
202 whichfork
<= XFS_ATTR_FORK
;
204 if (whichfork
== XFS_DATA_FORK
&& !dfork
)
206 if (whichfork
== XFS_ATTR_FORK
&& !afork
)
210 bmap(co
, eo
- co
+ 1, whichfork
, &nex
, &be
);
213 dbprintf(_("%s offset %lld startblock %llu (%u/%u) count "
215 whichfork
== XFS_DATA_FORK
? _("data") : _("attr"),
216 be
.startoff
, be
.startblock
,
217 XFS_FSB_TO_AGNO(mp
, be
.startblock
),
218 XFS_FSB_TO_AGBNO(mp
, be
.startblock
),
219 be
.blockcount
, be
.flag
);
220 co
= be
.startoff
+ be
.blockcount
;
230 add_command(&bmap_cmd
);
242 xfs_fileoff_t curoffset
;
248 convert_extent(ep
, &o
, &s
, &c
, &f
);
251 if (o
+ c
<= curoffset
)
260 if (o
+ c
- 1 > eoff
)
261 c
-= (o
+ c
- 1) - eoff
;
262 bep
[idx
].startoff
= o
;
263 bep
[idx
].startblock
= s
;
264 bep
[idx
].blockcount
= c
;
279 struct xfs_bmbt_irec irec
;
281 libxfs_bmbt_disk_get_all(rp
, &irec
);
282 *fp
= irec
.br_state
== XFS_EXT_UNWRITTEN
;
283 *op
= irec
.br_startoff
;
284 *sp
= irec
.br_startblock
;
285 *cp
= irec
.br_blockcount
;
296 for (i
= 0; i
< nex
; i
++) {
297 bbmap
->b
[i
].bm_bn
= XFS_FSB_TO_DADDR(mp
, bmp
[i
].startblock
);
298 bbmap
->b
[i
].bm_len
= XFS_FSB_TO_BB(mp
, bmp
[i
].blockcount
);
312 for (i
= 0; i
< nrecs
; i
++) {
313 if (be64_to_cpu(kp
[i
].br_startoff
) == off
)
314 return be64_to_cpu(pp
[i
]);
315 if (be64_to_cpu(kp
[i
].br_startoff
) > off
) {
317 return be64_to_cpu(pp
[i
]);
319 return be64_to_cpu(pp
[i
- 1]);
322 return be64_to_cpu(pp
[nrecs
- 1]);