]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - db/block.c
libxfs/linux.c: Replace use of ustat by stat
[thirdparty/xfsprogs-dev.git] / db / block.c
CommitLineData
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
32static int ablock_f(int argc, char **argv);
33static void ablock_help(void);
34static int daddr_f(int argc, char **argv);
35static void daddr_help(void);
36static int dblock_f(int argc, char **argv);
37static void dblock_help(void);
38static int fsblock_f(int argc, char **argv);
39static void fsblock_help(void);
40static void print_rawdata(void *data, int len);
41
42static 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 45static 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 48static 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 51static 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 55static void
2bd0ea18
NS
56ablock_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*/
68static int
69ablock_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
106void
107block_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 115static void
2bd0ea18
NS
116daddr_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
126static int
127daddr_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 149static void
2bd0ea18
NS
150dblock_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
161static int
162dblock_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 206static void
2bd0ea18
NS
207fsblock_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
218static int
219fsblock_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
250void
251print_block(
252 const field_t *fields,
253 int argc,
254 char **argv)
255{
256 print_rawdata(iocur_top->data, iocur_top->len);
257}
258
259static void
260print_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}