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