]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - db/block.c
Merge whitespace changes over
[thirdparty/xfsprogs-dev.git] / db / block.c
1 /*
2 * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
32
33 #include <libxfs.h>
34 #include "block.h"
35 #include "bmap.h"
36 #include "command.h"
37 #include "type.h"
38 #include "faddr.h"
39 #include "fprint.h"
40 #include "field.h"
41 #include "inode.h"
42 #include "io.h"
43 #include "output.h"
44 #include "init.h"
45
46 static int ablock_f(int argc, char **argv);
47 static void ablock_help(void);
48 static int daddr_f(int argc, char **argv);
49 static void daddr_help(void);
50 static int dblock_f(int argc, char **argv);
51 static void dblock_help(void);
52 static int fsblock_f(int argc, char **argv);
53 static void fsblock_help(void);
54 static void print_rawdata(void *data, int len);
55
56 static const cmdinfo_t ablock_cmd =
57 { "ablock", NULL, ablock_f, 1, 1, 1, "filoff",
58 "set address to file offset (attr fork)", ablock_help };
59 static const cmdinfo_t daddr_cmd =
60 { "daddr", NULL, daddr_f, 0, 1, 1, "[d]",
61 "set address to daddr value", daddr_help };
62 static const cmdinfo_t dblock_cmd =
63 { "dblock", NULL, dblock_f, 1, 1, 1, "filoff",
64 "set address to file offset (data fork)", dblock_help };
65 static const cmdinfo_t fsblock_cmd =
66 { "fsblock", "fsb", fsblock_f, 0, 1, 1, "[fsb]",
67 "set address to fsblock value", fsblock_help };
68
69 static void
70 ablock_help(void)
71 {
72 dbprintf(
73 "\n Example:\n"
74 "\n"
75 " 'ablock 23' - sets the file position to the 23rd filesystem block in\n"
76 " the inode's attribute fork. The filesystem block size is specified in\n"
77 " the superblock.\n\n"
78 );
79 }
80
81 /*ARGSUSED*/
82 static int
83 ablock_f(
84 int argc,
85 char **argv)
86 {
87 bmap_ext_t bm;
88 xfs_dfiloff_t bno;
89 xfs_dfsbno_t dfsbno;
90 int haveattr;
91 int nex;
92 char *p;
93
94 bno = (xfs_dfiloff_t)strtoull(argv[1], &p, 0);
95 if (*p != '\0') {
96 dbprintf("bad block number %s\n", argv[1]);
97 return 0;
98 }
99 push_cur();
100 set_cur_inode(iocur_top->ino);
101 haveattr = XFS_DFORK_Q((xfs_dinode_t *)iocur_top->data);
102 pop_cur();
103 if (!haveattr) {
104 dbprintf("no attribute data for file\n");
105 return 0;
106 }
107 nex = 1;
108 bmap(bno, 1, XFS_ATTR_FORK, &nex, &bm);
109 if (nex == 0) {
110 dbprintf("file attr block is unmapped\n");
111 return 0;
112 }
113 dfsbno = bm.startblock + (bno - bm.startoff);
114 ASSERT(typtab[TYP_ATTR].typnm == TYP_ATTR);
115 set_cur(&typtab[TYP_ATTR], (__int64_t)XFS_FSB_TO_DADDR(mp, dfsbno),
116 blkbb, DB_RING_ADD, NULL);
117 return 0;
118 }
119
120 void
121 block_init(void)
122 {
123 add_command(&ablock_cmd);
124 add_command(&daddr_cmd);
125 add_command(&dblock_cmd);
126 add_command(&fsblock_cmd);
127 }
128
129 static void
130 daddr_help(void)
131 {
132 dbprintf(
133 "\n Example:\n"
134 "\n"
135 " 'daddr 102' - sets position to the 102nd absolute disk block\n"
136 " (512 byte block).\n"
137 );
138 }
139
140 static int
141 daddr_f(
142 int argc,
143 char **argv)
144 {
145 __int64_t d;
146 char *p;
147
148 if (argc == 1) {
149 dbprintf("current daddr is %lld\n", iocur_top->off >> BBSHIFT);
150 return 0;
151 }
152 d = (__int64_t)strtoull(argv[1], &p, 0);
153 if (*p != '\0' ||
154 d >= mp->m_sb.sb_dblocks << (mp->m_sb.sb_blocklog - BBSHIFT)) {
155 dbprintf("bad daddr %s\n", argv[1]);
156 return 0;
157 }
158 ASSERT(typtab[TYP_DATA].typnm == TYP_DATA);
159 set_cur(&typtab[TYP_DATA], d, 1, DB_RING_ADD, NULL);
160 return 0;
161 }
162
163 static void
164 dblock_help(void)
165 {
166 dbprintf(
167 "\n Example:\n"
168 "\n"
169 " 'dblock 23' - sets the file position to the 23rd filesystem block in\n"
170 " the inode's data fork. The filesystem block size is specified in the\n"
171 " superblock.\n\n"
172 );
173 }
174
175 static int
176 dblock_f(
177 int argc,
178 char **argv)
179 {
180 bbmap_t bbmap;
181 bmap_ext_t *bmp;
182 xfs_dfiloff_t bno;
183 xfs_dfsbno_t dfsbno;
184 int nb;
185 int nex;
186 char *p;
187 typnm_t type;
188
189 bno = (xfs_dfiloff_t)strtoull(argv[1], &p, 0);
190 if (*p != '\0') {
191 dbprintf("bad block number %s\n", argv[1]);
192 return 0;
193 }
194 push_cur();
195 set_cur_inode(iocur_top->ino);
196 type = inode_next_type();
197 pop_cur();
198 if (type == TYP_NONE) {
199 dbprintf("no type for file data\n");
200 return 0;
201 }
202 nex = nb = type == TYP_DIR2 ? mp->m_dirblkfsbs : 1;
203 bmp = malloc(nb * sizeof(*bmp));
204 bmap(bno, nb, XFS_DATA_FORK, &nex, bmp);
205 if (nex == 0) {
206 dbprintf("file data block is unmapped\n");
207 free(bmp);
208 return 0;
209 }
210 dfsbno = bmp->startblock + (bno - bmp->startoff);
211 ASSERT(typtab[type].typnm == type);
212 if (nex > 1)
213 make_bbmap(&bbmap, nex, bmp);
214 set_cur(&typtab[type], (__int64_t)XFS_FSB_TO_DADDR(mp, dfsbno),
215 nb * blkbb, DB_RING_ADD, nex > 1 ? &bbmap : NULL);
216 free(bmp);
217 return 0;
218 }
219
220 static void
221 fsblock_help(void)
222 {
223 dbprintf(
224 "\n Example:\n"
225 "\n"
226 " 'fsblock 1023' - sets the file position to the 1023rd filesystem block.\n"
227 " The filesystem block size is specified in the superblock and set during\n"
228 " mkfs time. Offset is absolute (not AG relative).\n\n"
229 );
230 }
231
232 static int
233 fsblock_f(
234 int argc,
235 char **argv)
236 {
237 xfs_agblock_t agbno;
238 xfs_agnumber_t agno;
239 xfs_dfsbno_t d;
240 char *p;
241
242 if (argc == 1) {
243 dbprintf("current fsblock is %lld\n",
244 XFS_DADDR_TO_FSB(mp, iocur_top->off >> BBSHIFT));
245 return 0;
246 }
247 d = strtoull(argv[1], &p, 0);
248 if (*p != '\0') {
249 dbprintf("bad fsblock %s\n", argv[1]);
250 return 0;
251 }
252 agno = XFS_FSB_TO_AGNO(mp, d);
253 agbno = XFS_FSB_TO_AGBNO(mp, d);
254 if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks) {
255 dbprintf("bad fsblock %s\n", argv[1]);
256 return 0;
257 }
258 ASSERT(typtab[TYP_DATA].typnm == TYP_DATA);
259 set_cur(&typtab[TYP_DATA], XFS_AGB_TO_DADDR(mp, agno, agbno),
260 blkbb, DB_RING_ADD, NULL);
261 return 0;
262 }
263
264 void
265 print_block(
266 const field_t *fields,
267 int argc,
268 char **argv)
269 {
270 print_rawdata(iocur_top->data, iocur_top->len);
271 }
272
273 static void
274 print_rawdata(
275 void *data,
276 int len)
277 {
278 int i;
279 int j;
280 int lastaddr;
281 int offchars;
282 unsigned char *p;
283
284 lastaddr = (len - 1) & ~(32 - 1);
285 if (lastaddr < 0x10)
286 offchars = 1;
287 else if (lastaddr < 0x100)
288 offchars = 2;
289 else if (lastaddr < 0x1000)
290 offchars = 3;
291 else
292 offchars = 4;
293 for (i = 0, p = data; i < len; i += 32) {
294 dbprintf("%-0*.*x:", offchars, offchars, i);
295 for (j = 0; j < 32 && i + j < len; j++, p++) {
296 if ((j & 3) == 0)
297 dbprintf(" ");
298 dbprintf("%02x", *p);
299 }
300 dbprintf("\n");
301 }
302 }