2
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
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.
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.
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.
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.
23
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24
* Mountain View, CA 94043, or:
28
* For further information regarding this notice, see:
30
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
46
static int pop_f(int argc, char **argv);
47
static void pop_help(void);
48
static int push_f(int argc, char **argv);
49
static void push_help(void);
50
static int stack_f(int argc, char **argv);
51
static void stack_help(void);
52
static int forward_f(int argc, char **argv);
53
static void forward_help(void);
54
static int back_f(int argc, char **argv);
55
static void back_help(void);
56
static int ring_f(int argc, char **argv);
57
static void ring_help(void);
59
static const cmdinfo_t pop_cmd =
60
{ "pop", NULL, pop_f, 0, 0, 0, NULL,
61
"pop location from the stack", pop_help };
62
static const cmdinfo_t push_cmd =
63
{ "push", NULL, push_f, 0, 2, 0, "[command]",
64
"push location to the stack", push_help };
65
static const cmdinfo_t stack_cmd =
66
{ "stack", NULL, stack_f, 0, 0, 0, NULL,
67
"view the location stack", stack_help };
68
static const cmdinfo_t forward_cmd =
69
{ "forward", "f", forward_f, 0, 0, 0, NULL,
70
"move forward to next entry in the position ring", forward_help };
71
static const cmdinfo_t back_cmd =
72
{ "back", "b", back_f, 0, 0, 0, NULL,
73
"move to the previous location in the position ring", back_help };
74
static const cmdinfo_t ring_cmd =
75
{ "ring", NULL, ring_f, 0, 1, 0, NULL,
76
"show position ring or move to a specific entry", ring_help };
83
#define RING_ENTRIES 20
84
static iocur_t iocur_ring[RING_ENTRIES];
85
static int ring_head = -1;
86
static int ring_tail = -1;
87
static int ring_current = -1;
92
add_command(&pop_cmd);
93
add_command(&push_cmd);
94
add_command(&stack_cmd);
95
add_command(&forward_cmd);
96
add_command(&back_cmd);
97
add_command(&ring_cmd);
105
if (iocur_top == NULL || off + len > BBTOB(iocur_top->blen))
106
dbprintf("can't set block offset to %d\n", off);
108
iocur_top->boff = off;
109
iocur_top->off = ((xfs_off_t)iocur_top->bb << BBSHIFT) + off;
110
iocur_top->len = len;
111
iocur_top->data = (void *)((char *)iocur_top->buf + off);
119
dbprintf("can't pop anything from I/O stack\n");
123
xfree(iocur_top->buf);
124
if (--iocur_sp >= 0) {
125
iocur_top = iocur_base + iocur_sp;
126
cur_typ = iocur_top->typ;
128
iocur_top = iocur_base;
148
" Changes the address and data type to the first entry on the stack.\n"
160
dbprintf("%s\n", tag);
161
dbprintf("\tbyte offset %lld, length %d\n", ioc->off, ioc->len);
162
dbprintf("\tbuffer block %lld (fsbno %lld), %d bb%s\n", ioc->bb,
163
(xfs_dfsbno_t)XFS_DADDR_TO_FSB(mp, ioc->bb), ioc->blen,
164
ioc->blen == 1 ? "" : "s");
165
if (ioc->use_bbmap) {
166
dbprintf("\tblock map");
167
for (i = 0; i < ioc->blen; i++)
168
dbprintf(" %d:%lld", i, ioc->bbmap.b[i]);
171
dbprintf("\tinode %lld, dir inode %lld, type %s\n", ioc->ino,
172
ioc->dirino, ioc->typ == NULL ? "none" : ioc->typ->name);
181
if (ring_current == -1) {
182
dbprintf("no entries in location ring.\n");
186
dbprintf(" type bblock bblen fsbno inode\n");
190
ioc = &iocur_ring[i];
191
if (i == ring_current)
196
dbprintf("%-7.7s %8lld %5d %8lld %9lld\n",
197
ioc->typ == NULL ? "none" : ioc->typ->name,
200
(xfs_dfsbno_t)XFS_DADDR_TO_FSB(mp, ioc->bb),
207
i = (i+(RING_ENTRIES-1))%RING_ENTRIES;
215
if (iocur_sp + 1 >= iocur_len) {
216
iocur_base = xrealloc(iocur_base,
217
sizeof(*iocur_base) * (iocur_len + 1));
221
iocur_top = iocur_base + iocur_sp;
222
memset(iocur_top, 0, sizeof(*iocur_base));
223
iocur_top->ino = iocur_sp > 0 ? iocur_top[-1].ino : NULLFSINO;
224
iocur_top->dirino = iocur_sp > 0 ? iocur_top[-1].dirino : NULLFSINO;
225
iocur_top->mode = iocur_sp > 0 ? iocur_top[-1].mode : 0;
237
/* check we can execute command */
238
ct = find_command(argv[1]);
240
dbprintf("no such command %s\n", argv[1]);
244
dbprintf("no push form allowed for %s\n", argv[1]);
249
/* save current state */
251
if (iocur_top[-1].typ && iocur_top[-1].typ->typnm == TYP_INODE)
252
set_cur_inode(iocur_top[-1].ino);
254
set_cur(iocur_top[-1].typ, iocur_top[-1].bb,
255
iocur_top[-1].blen, DB_RING_IGN,
256
iocur_top[-1].use_bbmap ? &iocur_top[-1].bbmap : NULL);
258
/* run requested command */
260
(void)command(argc-1, argv+1);
269
" Allows you to push the current address and data type on the stack for\n"
270
" later return. 'push' also accepts an additional command to execute after\n"
271
" storing the current address (ex: 'push a rootino' from the superblock).\n"
276
/* move forward through the ring */
283
if (ring_current == -1) {
284
dbprintf("ring is empty\n");
287
if (ring_current == ring_head) {
288
dbprintf("no further entries\n");
292
ring_current = (ring_current+1)%RING_ENTRIES;
294
set_cur(iocur_ring[ring_current].typ,
295
iocur_ring[ring_current].bb,
296
iocur_ring[ring_current].blen,
298
iocur_ring[ring_current].use_bbmap ?
299
&iocur_ring[ring_current].bbmap : NULL);
309
" The 'forward' ('f') command moves to the next location in the position\n"
310
" ring, updating the current position and data type. If the current location\n"
311
" is the top entry in the ring, then the 'forward' command will have\n"
317
/* move backwards through the ring */
324
if (ring_current == -1) {
325
dbprintf("ring is empty\n");
328
if (ring_current == ring_tail) {
329
dbprintf("no previous entries\n");
333
ring_current = (ring_current+(RING_ENTRIES-1))%RING_ENTRIES;
335
set_cur(iocur_ring[ring_current].typ,
336
iocur_ring[ring_current].bb,
337
iocur_ring[ring_current].blen,
339
iocur_ring[ring_current].use_bbmap ?
340
&iocur_ring[ring_current].bbmap : NULL);
350
" The 'back' ('b') command moves to the previous location in the position\n"
351
" ring, updating the current position and data type. If the current location\n"
352
" is the last entry in the ring, then the 'back' command will have no effect.\n"
357
/* show or go to specific point in ring */
370
index = (int)strtoul(argv[0], NULL, 0);
371
if (index < 0 || index >= RING_ENTRIES)
372
dbprintf("invalid entry: %d\n", index);
374
ring_current = index;
376
set_cur(iocur_ring[index].typ,
377
iocur_ring[index].bb,
378
iocur_ring[index].blen,
380
iocur_ring[index].use_bbmap ? &iocur_ring[index].bbmap : NULL);
390
" The position ring automatically keeps track of each disk location and\n"
391
" structure type for each change of position you make during your xfs_db\n"
392
" session. The last %d most recent entries are kept in the ring.\n"
394
" To display the current list of ring entries type 'ring' by itself on\n"
395
" the command line. The entry highlighted by an asterisk ('*') is the\n"
398
" To move to another entry in the ring type 'ring <num>' where <num> is\n"
399
" your desired entry from the ring position list.\n"
401
" You may also use the 'forward' ('f') or 'back' ('b') commands to move\n"
402
" to the previous or next entry in the ring, respectively.\n"
404
" Note: Unlike the 'stack', 'push' and 'pop' commands, the ring tracks your\n"
405
" location implicitly. Use the 'push' and 'pop' commands if you wish to\n"
406
" store a specific location explicitly for later return.\n"
415
if (ring_head == -1) {
416
/* only get here right after startup */
420
iocur_ring[0] = *iocur_top;
422
if (ring_current == ring_head) {
423
ring_head = (ring_head+1)%RING_ENTRIES;
424
iocur_ring[ring_head] = *iocur_top;
425
if (ring_head == ring_tail)
426
ring_tail = (ring_tail+1)%RING_ENTRIES;
427
ring_current = ring_head;
429
ring_current = (ring_current+1)%RING_ENTRIES;
430
iocur_ring[ring_current] = *iocur_top;
446
int rval = EINVAL; /* initialize for zero `count' case */
448
for (j = 0; j < count; j += bbmap ? 1 : count) {
451
if (lseek64(xfsargs.dfd, bbno << BBSHIFT, SEEK_SET) < 0) {
453
dbprintf("can't seek in filesystem at bb %lld\n", bbno);
456
c = BBTOB(bbmap ? 1 : count);
457
i = (int)write(xfsargs.dfd, (char *)bufp + BBTOB(j), c);
491
for (j = 0; j < count; j += bbmap ? 1 : count) {
494
if (lseek64(xfsargs.dfd, bbno << BBSHIFT, SEEK_SET) < 0) {
496
dbprintf("can't seek in filesystem at bb %lld\n", bbno);
501
c = BBTOB(bbmap ? 1 : count);
502
i = (int)read(xfsargs.dfd, (char *)buf + BBTOB(j), c);
530
dbprintf("nothing to write\n");
533
ret = write_bbs(iocur_top->bb, iocur_top->blen, iocur_top->buf,
534
iocur_top->use_bbmap ? &iocur_top->bbmap : NULL);
536
dbprintf("incomplete write, block: %lld\n",
537
(iocur_base + iocur_sp)->bb);
539
dbprintf("write error: %s\n", strerror(ret));
540
/* re-read buffer from disk */
541
ret = read_bbs(iocur_top->bb, iocur_top->blen, &iocur_top->buf,
542
iocur_top->use_bbmap ? &iocur_top->bbmap : NULL);
544
dbprintf("incomplete read, block: %lld\n",
545
(iocur_base + iocur_sp)->bb);
547
dbprintf("read error: %s\n", strerror(ret));
563
dbprintf("set_cur no stack element to set\n");
569
printf("xfs_db got a bbmap for %lld\n", (long long)d);
571
ino = iocur_top->ino;
572
dirino = iocur_top->dirino;
573
mode = iocur_top->mode;
576
if (read_bbs(d, c, &iocur_top->buf, bbmap))
581
iocur_top->data = iocur_top->buf;
582
iocur_top->len = BBTOB(c);
583
iocur_top->off = d << BBSHIFT;
584
iocur_top->typ = cur_typ = t;
585
iocur_top->ino = ino;
586
iocur_top->dirino = dirino;
587
iocur_top->mode = mode;
588
if ((iocur_top->use_bbmap = (bbmap != NULL)))
589
iocur_top->bbmap = *bbmap;
591
/* store location in ring */
601
" The stack is used to explicitly store your location and data type\n"
602
" for later return. The 'push' operation stores the current address\n"
603
" and type on the stack, the 'pop' operation returns you to the\n"
604
" position and datatype of the top entry on the stack.\n"
606
" The 'stack' allows explicit location saves, see 'ring' for implicit\n"
607
" position tracking.\n"
621
for (i = iocur_sp; i > 0; i--) {
622
snprintf(tagbuf, sizeof(tagbuf), "%d: ", i);
623
print_iocur(tagbuf, &iocur_base[i]);