]>
Commit | Line | Data |
---|---|---|
2bd0ea18 | 1 | /* |
da23017d NS |
2 | * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | |
dfc130f3 | 4 | * |
da23017d NS |
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 | |
2bd0ea18 | 7 | * published by the Free Software Foundation. |
dfc130f3 | 8 | * |
da23017d NS |
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. | |
dfc130f3 | 13 | * |
da23017d NS |
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 | |
2bd0ea18 NS |
17 | */ |
18 | ||
6b803e5a | 19 | #include "libxfs.h" |
2bd0ea18 NS |
20 | #include "block.h" |
21 | #include "bmap.h" | |
22 | #include "command.h" | |
2bd0ea18 NS |
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" | |
4ca431fc | 30 | #include "init.h" |
2bd0ea18 NS |
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 = | |
9ee7055c AM |
43 | { "ablock", NULL, ablock_f, 1, 1, 1, N_("filoff"), |
44 | N_("set address to file offset (attr fork)"), ablock_help }; | |
2bd0ea18 | 45 | static const cmdinfo_t daddr_cmd = |
9ee7055c AM |
46 | { "daddr", NULL, daddr_f, 0, 1, 1, N_("[d]"), |
47 | N_("set address to daddr value"), daddr_help }; | |
2bd0ea18 | 48 | static const cmdinfo_t dblock_cmd = |
9ee7055c AM |
49 | { "dblock", NULL, dblock_f, 1, 1, 1, N_("filoff"), |
50 | N_("set address to file offset (data fork)"), dblock_help }; | |
2bd0ea18 | 51 | static const cmdinfo_t fsblock_cmd = |
9ee7055c AM |
52 | { "fsblock", "fsb", fsblock_f, 0, 1, 1, N_("[fsb]"), |
53 | N_("set address to fsblock value"), fsblock_help }; | |
2bd0ea18 | 54 | |
dfc130f3 | 55 | static void |
2bd0ea18 NS |
56 | ablock_help(void) |
57 | { | |
9ee7055c | 58 | dbprintf(_( |
2bd0ea18 NS |
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" | |
9ee7055c | 64 | )); |
2bd0ea18 NS |
65 | } |
66 | ||
67 | /*ARGSUSED*/ | |
68 | static int | |
69 | ablock_f( | |
70 | int argc, | |
71 | char **argv) | |
72 | { | |
73 | bmap_ext_t bm; | |
5a35bf2c DC |
74 | xfs_fileoff_t bno; |
75 | xfs_fsblock_t dfsbno; | |
2bd0ea18 NS |
76 | int haveattr; |
77 | int nex; | |
78 | char *p; | |
79 | ||
5a35bf2c | 80 | bno = (xfs_fileoff_t)strtoull(argv[1], &p, 0); |
2bd0ea18 | 81 | if (*p != '\0') { |
9ee7055c | 82 | dbprintf(_("bad block number %s\n"), argv[1]); |
2bd0ea18 NS |
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) { | |
9ee7055c | 90 | dbprintf(_("no attribute data for file\n")); |
2bd0ea18 NS |
91 | return 0; |
92 | } | |
93 | nex = 1; | |
94 | bmap(bno, 1, XFS_ATTR_FORK, &nex, &bm); | |
95 | if (nex == 0) { | |
9ee7055c | 96 | dbprintf(_("file attr block is unmapped\n")); |
2bd0ea18 NS |
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 | ||
dfc130f3 | 115 | static void |
2bd0ea18 NS |
116 | daddr_help(void) |
117 | { | |
9ee7055c | 118 | dbprintf(_( |
2bd0ea18 NS |
119 | "\n Example:\n" |
120 | "\n" | |
121 | " 'daddr 102' - sets position to the 102nd absolute disk block\n" | |
122 | " (512 byte block).\n" | |
9ee7055c | 123 | )); |
2bd0ea18 NS |
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) { | |
9ee7055c | 135 | dbprintf(_("current daddr is %lld\n"), iocur_top->off >> BBSHIFT); |
2bd0ea18 NS |
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)) { | |
9ee7055c | 141 | dbprintf(_("bad daddr %s\n"), argv[1]); |
2bd0ea18 NS |
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 | ||
dfc130f3 | 149 | static void |
2bd0ea18 NS |
150 | dblock_help(void) |
151 | { | |
9ee7055c | 152 | dbprintf(_( |
2bd0ea18 NS |
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" | |
9ee7055c | 158 | )); |
2bd0ea18 NS |
159 | } |
160 | ||
161 | static int | |
162 | dblock_f( | |
163 | int argc, | |
164 | char **argv) | |
165 | { | |
166 | bbmap_t bbmap; | |
167 | bmap_ext_t *bmp; | |
5a35bf2c DC |
168 | xfs_fileoff_t bno; |
169 | xfs_fsblock_t dfsbno; | |
2bd0ea18 NS |
170 | int nb; |
171 | int nex; | |
172 | char *p; | |
173 | typnm_t type; | |
174 | ||
5a35bf2c | 175 | bno = (xfs_fileoff_t)strtoull(argv[1], &p, 0); |
2bd0ea18 | 176 | if (*p != '\0') { |
9ee7055c | 177 | dbprintf(_("bad block number %s\n"), argv[1]); |
2bd0ea18 NS |
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) { | |
9ee7055c | 185 | dbprintf(_("no type for file data\n")); |
2bd0ea18 NS |
186 | return 0; |
187 | } | |
ff105f75 | 188 | nex = nb = type == TYP_DIR2 ? mp->m_dir_geo->fsbcount : 1; |
2bd0ea18 NS |
189 | bmp = malloc(nb * sizeof(*bmp)); |
190 | bmap(bno, nb, XFS_DATA_FORK, &nex, bmp); | |
191 | if (nex == 0) { | |
9ee7055c | 192 | dbprintf(_("file data block is unmapped\n")); |
2bd0ea18 NS |
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 | ||
dfc130f3 | 206 | static void |
2bd0ea18 NS |
207 | fsblock_help(void) |
208 | { | |
9ee7055c | 209 | dbprintf(_( |
2bd0ea18 NS |
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" | |
9ee7055c | 215 | )); |
2bd0ea18 NS |
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; | |
5a35bf2c | 225 | xfs_fsblock_t d; |
2bd0ea18 NS |
226 | char *p; |
227 | ||
228 | if (argc == 1) { | |
9ee7055c | 229 | dbprintf(_("current fsblock is %lld\n"), |
2bd0ea18 NS |
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') { | |
9ee7055c | 235 | dbprintf(_("bad fsblock %s\n"), argv[1]); |
2bd0ea18 NS |
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) { | |
9ee7055c | 241 | dbprintf(_("bad fsblock %s\n"), argv[1]); |
2bd0ea18 NS |
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 | } |