]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - db/block.c
xfs: cache last bitmap block in realtime allocator
[thirdparty/xfsprogs-dev.git] / db / block.c
CommitLineData
959ef981 1// SPDX-License-Identifier: GPL-2.0
2bd0ea18 2/*
da23017d
NS
3 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
2bd0ea18
NS
5 */
6
6b803e5a 7#include "libxfs.h"
2bd0ea18
NS
8#include "block.h"
9#include "bmap.h"
10#include "command.h"
2bd0ea18
NS
11#include "type.h"
12#include "faddr.h"
13#include "fprint.h"
14#include "field.h"
15#include "inode.h"
16#include "io.h"
17#include "output.h"
4ca431fc 18#include "init.h"
2bd0ea18
NS
19
20static int ablock_f(int argc, char **argv);
21static void ablock_help(void);
22static int daddr_f(int argc, char **argv);
23static void daddr_help(void);
24static int dblock_f(int argc, char **argv);
25static void dblock_help(void);
26static int fsblock_f(int argc, char **argv);
27static void fsblock_help(void);
28static void print_rawdata(void *data, int len);
29
30static const cmdinfo_t ablock_cmd =
9ee7055c
AM
31 { "ablock", NULL, ablock_f, 1, 1, 1, N_("filoff"),
32 N_("set address to file offset (attr fork)"), ablock_help };
2bd0ea18 33static const cmdinfo_t daddr_cmd =
9ee7055c
AM
34 { "daddr", NULL, daddr_f, 0, 1, 1, N_("[d]"),
35 N_("set address to daddr value"), daddr_help };
2bd0ea18 36static const cmdinfo_t dblock_cmd =
9ee7055c
AM
37 { "dblock", NULL, dblock_f, 1, 1, 1, N_("filoff"),
38 N_("set address to file offset (data fork)"), dblock_help };
2bd0ea18 39static const cmdinfo_t fsblock_cmd =
9ee7055c
AM
40 { "fsblock", "fsb", fsblock_f, 0, 1, 1, N_("[fsb]"),
41 N_("set address to fsblock value"), fsblock_help };
2bd0ea18 42
dfc130f3 43static void
2bd0ea18
NS
44ablock_help(void)
45{
9ee7055c 46 dbprintf(_(
2bd0ea18
NS
47"\n Example:\n"
48"\n"
49" 'ablock 23' - sets the file position to the 23rd filesystem block in\n"
50" the inode's attribute fork. The filesystem block size is specified in\n"
51" the superblock.\n\n"
9ee7055c 52));
2bd0ea18
NS
53}
54
55/*ARGSUSED*/
56static int
57ablock_f(
8c6cccd7
CH
58 int argc,
59 char **argv)
2bd0ea18 60{
8c6cccd7
CH
61 bmap_ext_t bm;
62 xfs_fileoff_t bno;
63 xfs_fsblock_t dfsbno;
64 int haveattr;
3a2414fa 65 xfs_extnum_t nex;
8c6cccd7
CH
66 char *p;
67 struct xfs_dinode *dip = iocur_top->data;
2bd0ea18 68
5a35bf2c 69 bno = (xfs_fileoff_t)strtoull(argv[1], &p, 0);
2bd0ea18 70 if (*p != '\0') {
9ee7055c 71 dbprintf(_("bad block number %s\n"), argv[1]);
2bd0ea18
NS
72 return 0;
73 }
74 push_cur();
75 set_cur_inode(iocur_top->ino);
8c6cccd7 76 if (!dip) {
de24d640
DW
77 pop_cur();
78 dbprintf(_("no current inode\n"));
79 return 0;
80 }
8c6cccd7 81 haveattr = dip->di_forkoff;
2bd0ea18
NS
82 pop_cur();
83 if (!haveattr) {
9ee7055c 84 dbprintf(_("no attribute data for file\n"));
2bd0ea18
NS
85 return 0;
86 }
87 nex = 1;
88 bmap(bno, 1, XFS_ATTR_FORK, &nex, &bm);
89 if (nex == 0) {
9ee7055c 90 dbprintf(_("file attr block is unmapped\n"));
2bd0ea18
NS
91 return 0;
92 }
93 dfsbno = bm.startblock + (bno - bm.startoff);
94 ASSERT(typtab[TYP_ATTR].typnm == TYP_ATTR);
14f8b681 95 set_cur(&typtab[TYP_ATTR], (int64_t)XFS_FSB_TO_DADDR(mp, dfsbno),
2bd0ea18
NS
96 blkbb, DB_RING_ADD, NULL);
97 return 0;
98}
99
100void
101block_init(void)
102{
103 add_command(&ablock_cmd);
104 add_command(&daddr_cmd);
105 add_command(&dblock_cmd);
106 add_command(&fsblock_cmd);
107}
108
dfc130f3 109static void
2bd0ea18
NS
110daddr_help(void)
111{
9ee7055c 112 dbprintf(_(
2bd0ea18
NS
113"\n Example:\n"
114"\n"
115" 'daddr 102' - sets position to the 102nd absolute disk block\n"
116" (512 byte block).\n"
9ee7055c 117));
2bd0ea18
NS
118}
119
120static int
121daddr_f(
122 int argc,
123 char **argv)
124{
14f8b681 125 int64_t d;
2bd0ea18
NS
126 char *p;
127
128 if (argc == 1) {
1665923a
DW
129 xfs_daddr_t daddr = iocur_top->off >> BBSHIFT;
130
131 if (iocur_is_ddev(iocur_top))
132 dbprintf(_("datadev daddr is %lld\n"), daddr);
133 else if (iocur_is_extlogdev(iocur_top))
134 dbprintf(_("logdev daddr is %lld\n"), daddr);
135 else
136 dbprintf(_("current daddr is %lld\n"), daddr);
137
2bd0ea18
NS
138 return 0;
139 }
14f8b681 140 d = (int64_t)strtoull(argv[1], &p, 0);
2bd0ea18
NS
141 if (*p != '\0' ||
142 d >= mp->m_sb.sb_dblocks << (mp->m_sb.sb_blocklog - BBSHIFT)) {
9ee7055c 143 dbprintf(_("bad daddr %s\n"), argv[1]);
2bd0ea18
NS
144 return 0;
145 }
146 ASSERT(typtab[TYP_DATA].typnm == TYP_DATA);
147 set_cur(&typtab[TYP_DATA], d, 1, DB_RING_ADD, NULL);
148 return 0;
149}
150
dfc130f3 151static void
2bd0ea18
NS
152dblock_help(void)
153{
9ee7055c 154 dbprintf(_(
2bd0ea18
NS
155"\n Example:\n"
156"\n"
157" 'dblock 23' - sets the file position to the 23rd filesystem block in\n"
158" the inode's data fork. The filesystem block size is specified in the\n"
159" superblock.\n\n"
9ee7055c 160));
2bd0ea18
NS
161}
162
163static int
164dblock_f(
165 int argc,
166 char **argv)
167{
168 bbmap_t bbmap;
169 bmap_ext_t *bmp;
5a35bf2c
DC
170 xfs_fileoff_t bno;
171 xfs_fsblock_t dfsbno;
2bd0ea18 172 int nb;
3a2414fa 173 xfs_extnum_t nex;
2bd0ea18
NS
174 char *p;
175 typnm_t type;
176
5a35bf2c 177 bno = (xfs_fileoff_t)strtoull(argv[1], &p, 0);
2bd0ea18 178 if (*p != '\0') {
9ee7055c 179 dbprintf(_("bad block number %s\n"), argv[1]);
2bd0ea18
NS
180 return 0;
181 }
182 push_cur();
183 set_cur_inode(iocur_top->ino);
184 type = inode_next_type();
185 pop_cur();
186 if (type == TYP_NONE) {
9ee7055c 187 dbprintf(_("no type for file data\n"));
2bd0ea18
NS
188 return 0;
189 }
ff105f75 190 nex = nb = type == TYP_DIR2 ? mp->m_dir_geo->fsbcount : 1;
2bd0ea18
NS
191 bmp = malloc(nb * sizeof(*bmp));
192 bmap(bno, nb, XFS_DATA_FORK, &nex, bmp);
193 if (nex == 0) {
9ee7055c 194 dbprintf(_("file data block is unmapped\n"));
2bd0ea18
NS
195 free(bmp);
196 return 0;
197 }
198 dfsbno = bmp->startblock + (bno - bmp->startoff);
199 ASSERT(typtab[type].typnm == type);
200 if (nex > 1)
201 make_bbmap(&bbmap, nex, bmp);
14f8b681 202 set_cur(&typtab[type], (int64_t)XFS_FSB_TO_DADDR(mp, dfsbno),
2bd0ea18
NS
203 nb * blkbb, DB_RING_ADD, nex > 1 ? &bbmap : NULL);
204 free(bmp);
205 return 0;
206}
207
dfc130f3 208static void
2bd0ea18
NS
209fsblock_help(void)
210{
9ee7055c 211 dbprintf(_(
2bd0ea18
NS
212"\n Example:\n"
213"\n"
214" 'fsblock 1023' - sets the file position to the 1023rd filesystem block.\n"
215" The filesystem block size is specified in the superblock and set during\n"
216" mkfs time. Offset is absolute (not AG relative).\n\n"
9ee7055c 217));
2bd0ea18
NS
218}
219
220static int
221fsblock_f(
222 int argc,
223 char **argv)
224{
225 xfs_agblock_t agbno;
226 xfs_agnumber_t agno;
5a35bf2c 227 xfs_fsblock_t d;
2bd0ea18
NS
228 char *p;
229
230 if (argc == 1) {
1665923a
DW
231 if (!iocur_is_ddev(iocur_top)) {
232 dbprintf(_("cursor does not point to data device\n"));
233 return 0;
234 }
9ee7055c 235 dbprintf(_("current fsblock is %lld\n"),
2bd0ea18
NS
236 XFS_DADDR_TO_FSB(mp, iocur_top->off >> BBSHIFT));
237 return 0;
238 }
239 d = strtoull(argv[1], &p, 0);
240 if (*p != '\0') {
9ee7055c 241 dbprintf(_("bad fsblock %s\n"), argv[1]);
2bd0ea18
NS
242 return 0;
243 }
244 agno = XFS_FSB_TO_AGNO(mp, d);
245 agbno = XFS_FSB_TO_AGBNO(mp, d);
246 if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks) {
9ee7055c 247 dbprintf(_("bad fsblock %s\n"), argv[1]);
2bd0ea18
NS
248 return 0;
249 }
250 ASSERT(typtab[TYP_DATA].typnm == TYP_DATA);
251 set_cur(&typtab[TYP_DATA], XFS_AGB_TO_DADDR(mp, agno, agbno),
252 blkbb, DB_RING_ADD, NULL);
253 return 0;
254}
255
256void
257print_block(
258 const field_t *fields,
259 int argc,
260 char **argv)
261{
262 print_rawdata(iocur_top->data, iocur_top->len);
263}
264
265static void
266print_rawdata(
267 void *data,
268 int len)
269{
270 int i;
271 int j;
272 int lastaddr;
273 int offchars;
274 unsigned char *p;
275
276 lastaddr = (len - 1) & ~(32 - 1);
277 if (lastaddr < 0x10)
278 offchars = 1;
279 else if (lastaddr < 0x100)
280 offchars = 2;
281 else if (lastaddr < 0x1000)
282 offchars = 3;
283 else
284 offchars = 4;
285 for (i = 0, p = data; i < len; i += 32) {
286 dbprintf("%-0*.*x:", offchars, offchars, i);
287 for (j = 0; j < 32 && i + j < len; j++, p++) {
288 if ((j & 3) == 0)
289 dbprintf(" ");
290 dbprintf("%02x", *p);
291 }
292 dbprintf("\n");
293 }
294}