]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - db/block.c
xfs: cache last bitmap block in realtime allocator
[thirdparty/xfsprogs-dev.git] / db / block.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
5 */
6
7 #include "libxfs.h"
8 #include "block.h"
9 #include "bmap.h"
10 #include "command.h"
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"
18 #include "init.h"
19
20 static int ablock_f(int argc, char **argv);
21 static void ablock_help(void);
22 static int daddr_f(int argc, char **argv);
23 static void daddr_help(void);
24 static int dblock_f(int argc, char **argv);
25 static void dblock_help(void);
26 static int fsblock_f(int argc, char **argv);
27 static void fsblock_help(void);
28 static void print_rawdata(void *data, int len);
29
30 static const cmdinfo_t ablock_cmd =
31 { "ablock", NULL, ablock_f, 1, 1, 1, N_("filoff"),
32 N_("set address to file offset (attr fork)"), ablock_help };
33 static const cmdinfo_t daddr_cmd =
34 { "daddr", NULL, daddr_f, 0, 1, 1, N_("[d]"),
35 N_("set address to daddr value"), daddr_help };
36 static const cmdinfo_t dblock_cmd =
37 { "dblock", NULL, dblock_f, 1, 1, 1, N_("filoff"),
38 N_("set address to file offset (data fork)"), dblock_help };
39 static const cmdinfo_t fsblock_cmd =
40 { "fsblock", "fsb", fsblock_f, 0, 1, 1, N_("[fsb]"),
41 N_("set address to fsblock value"), fsblock_help };
42
43 static void
44 ablock_help(void)
45 {
46 dbprintf(_(
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"
52 ));
53 }
54
55 /*ARGSUSED*/
56 static int
57 ablock_f(
58 int argc,
59 char **argv)
60 {
61 bmap_ext_t bm;
62 xfs_fileoff_t bno;
63 xfs_fsblock_t dfsbno;
64 int haveattr;
65 xfs_extnum_t nex;
66 char *p;
67 struct xfs_dinode *dip = iocur_top->data;
68
69 bno = (xfs_fileoff_t)strtoull(argv[1], &p, 0);
70 if (*p != '\0') {
71 dbprintf(_("bad block number %s\n"), argv[1]);
72 return 0;
73 }
74 push_cur();
75 set_cur_inode(iocur_top->ino);
76 if (!dip) {
77 pop_cur();
78 dbprintf(_("no current inode\n"));
79 return 0;
80 }
81 haveattr = dip->di_forkoff;
82 pop_cur();
83 if (!haveattr) {
84 dbprintf(_("no attribute data for file\n"));
85 return 0;
86 }
87 nex = 1;
88 bmap(bno, 1, XFS_ATTR_FORK, &nex, &bm);
89 if (nex == 0) {
90 dbprintf(_("file attr block is unmapped\n"));
91 return 0;
92 }
93 dfsbno = bm.startblock + (bno - bm.startoff);
94 ASSERT(typtab[TYP_ATTR].typnm == TYP_ATTR);
95 set_cur(&typtab[TYP_ATTR], (int64_t)XFS_FSB_TO_DADDR(mp, dfsbno),
96 blkbb, DB_RING_ADD, NULL);
97 return 0;
98 }
99
100 void
101 block_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
109 static void
110 daddr_help(void)
111 {
112 dbprintf(_(
113 "\n Example:\n"
114 "\n"
115 " 'daddr 102' - sets position to the 102nd absolute disk block\n"
116 " (512 byte block).\n"
117 ));
118 }
119
120 static int
121 daddr_f(
122 int argc,
123 char **argv)
124 {
125 int64_t d;
126 char *p;
127
128 if (argc == 1) {
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
138 return 0;
139 }
140 d = (int64_t)strtoull(argv[1], &p, 0);
141 if (*p != '\0' ||
142 d >= mp->m_sb.sb_dblocks << (mp->m_sb.sb_blocklog - BBSHIFT)) {
143 dbprintf(_("bad daddr %s\n"), argv[1]);
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
151 static void
152 dblock_help(void)
153 {
154 dbprintf(_(
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"
160 ));
161 }
162
163 static int
164 dblock_f(
165 int argc,
166 char **argv)
167 {
168 bbmap_t bbmap;
169 bmap_ext_t *bmp;
170 xfs_fileoff_t bno;
171 xfs_fsblock_t dfsbno;
172 int nb;
173 xfs_extnum_t nex;
174 char *p;
175 typnm_t type;
176
177 bno = (xfs_fileoff_t)strtoull(argv[1], &p, 0);
178 if (*p != '\0') {
179 dbprintf(_("bad block number %s\n"), argv[1]);
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) {
187 dbprintf(_("no type for file data\n"));
188 return 0;
189 }
190 nex = nb = type == TYP_DIR2 ? mp->m_dir_geo->fsbcount : 1;
191 bmp = malloc(nb * sizeof(*bmp));
192 bmap(bno, nb, XFS_DATA_FORK, &nex, bmp);
193 if (nex == 0) {
194 dbprintf(_("file data block is unmapped\n"));
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);
202 set_cur(&typtab[type], (int64_t)XFS_FSB_TO_DADDR(mp, dfsbno),
203 nb * blkbb, DB_RING_ADD, nex > 1 ? &bbmap : NULL);
204 free(bmp);
205 return 0;
206 }
207
208 static void
209 fsblock_help(void)
210 {
211 dbprintf(_(
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"
217 ));
218 }
219
220 static int
221 fsblock_f(
222 int argc,
223 char **argv)
224 {
225 xfs_agblock_t agbno;
226 xfs_agnumber_t agno;
227 xfs_fsblock_t d;
228 char *p;
229
230 if (argc == 1) {
231 if (!iocur_is_ddev(iocur_top)) {
232 dbprintf(_("cursor does not point to data device\n"));
233 return 0;
234 }
235 dbprintf(_("current fsblock is %lld\n"),
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') {
241 dbprintf(_("bad fsblock %s\n"), argv[1]);
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) {
247 dbprintf(_("bad fsblock %s\n"), argv[1]);
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
256 void
257 print_block(
258 const field_t *fields,
259 int argc,
260 char **argv)
261 {
262 print_rawdata(iocur_top->data, iocur_top->len);
263 }
264
265 static void
266 print_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 }