~ubuntu-branches/debian/stretch/jfsutils/stretch

« back to all changes in this revision

Viewing changes to xpeek/iag.c

  • Committer: Bazaar Package Importer
  • Author(s): Christopher L Cheney
  • Date: 2002-02-10 01:00:00 UTC
  • Revision ID: james.westby@ubuntu.com-20020210010000-v63g4150dcpnehzq
Tags: upstream-1.0.14
ImportĀ upstreamĀ versionĀ 1.0.14

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *
 
3
 *   Copyright (c) International Business Machines  Corp., 2000
 
4
 *
 
5
 *   This program is free software;  you can redistribute it and/or modify
 
6
 *   it under the terms of the GNU General Public License as published by
 
7
 *   the Free Software Foundation; either version 2 of the License, or
 
8
 *   (at your option) any later version.
 
9
 *
 
10
 *   This program is distributed in the hope that it will be useful,
 
11
 *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
 
12
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
 
13
 *   the GNU General Public License for more details.
 
14
 *
 
15
 *   You should have received a copy of the GNU General Public License
 
16
 *   along with this program;  if not, write to the Free Software
 
17
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
18
 *   MODULE_NAME:       iag.c
 
19
 *
 
20
 *   FUNCTION:          display/modify iag
 
21
 *
 
22
 */
 
23
 
 
24
#include "xpeek.h"
 
25
#include <ctype.h>
 
26
 
 
27
/* JFS includes */
 
28
#include "jfs_byteorder.h"
 
29
#include <jfs_xtree.h>
 
30
#include <jfs_filsys.h>
 
31
 
 
32
extern int64_t  AIT_2nd_offset; /* Defined and assigned in xpeek.c      */
 
33
 
 
34
/* endian routines */
 
35
extern uint32_t type_jfs;
 
36
extern void ujfs_swap_xtpage_t( xtpage_t * );
 
37
extern void ujfs_swap_iag_t( iag_t * );
 
38
 
 
39
int32_t change_iag(iag_t *);
 
40
int32_t display_ext(pxd_t *, char *);
 
41
int32_t display_map(uint32_t *, int32_t);
 
42
 
 
43
void iag()
 
44
{
 
45
  int64_t   address;
 
46
  int64_t   block_num;
 
47
  char      cmd_line[80];
 
48
  iag_t     iag;
 
49
  int32_t   iagnum;
 
50
  int32_t   rc;
 
51
  char      *token;
 
52
  uint32_t  which_table = FILESYSTEM_I;
 
53
 
 
54
  token = strtok(0, "   \n");
 
55
  if (token == 0) {
 
56
    fputs("iag: Please enter: iagnum [ a | 0 ]\niag> ",stdout);
 
57
    fgets(cmd_line, 80, stdin);
 
58
    token=strtok(cmd_line, "    \n");
 
59
    if (token == 0)
 
60
      return;
 
61
  }
 
62
  errno = 0;
 
63
  iagnum = strtoul(token, 0, 0);
 
64
  token = strtok(0, "   \n");
 
65
  if (token) {
 
66
    if (token[0] == 'a')
 
67
      which_table = AGGREGATE_I;
 
68
    else if (token[0] == 's')
 
69
      which_table = AGGREGATE_2ND_I;
 
70
    else if (token[0] != '0') {
 
71
      fputs("iag: invalide fileset\n\n", stderr);
 
72
      return;
 
73
    }
 
74
  }
 
75
  if (strtok(0, "       \n"))  {
 
76
    fputs("iag: Too many arguments\n\n", stderr);
 
77
    return;
 
78
  }
 
79
 
 
80
  if (find_iag(iagnum, which_table, &address) ||
 
81
      xRead(address, sizeof(iag_t), (char *)&iag)) {
 
82
    fputs("iag: error reading iag\n\n", stderr);
 
83
    return;
 
84
  }
 
85
 
 
86
  /* swap if on big endian machine */
 
87
  if (type_jfs & JFS_SWAP_BYTES) {
 
88
    ujfs_swap_iag_t( &iag ); 
 
89
  }
 
90
  block_num = address >> l2bsize;
 
91
 
 
92
changed:
 
93
  printf("IAG %d at block %lld\n\n", iagnum, (long long)block_num);
 
94
  display_iag(&iag);
 
95
  if ((rc = change_iag(&iag)) == XPEEK_ERROR)
 
96
    return;
 
97
  if (rc & XPEEK_CHANGED) {
 
98
    /* swap if on big endian machine */
 
99
    if (type_jfs & JFS_SWAP_BYTES) {
 
100
      ujfs_swap_iag_t( &iag ); 
 
101
    }
 
102
 
 
103
    if (xWrite(address, sizeof(iag_t), (char *)&iag)) {
 
104
      fputs("iag: error writing iag\n\n", stderr);
 
105
      /* swap back if on big endian machine */
 
106
      if (type_jfs & JFS_SWAP_BYTES) ujfs_swap_iag_t( &iag ); 
 
107
      return;
 
108
    }
 
109
 
 
110
    /* swap back if on big endian machine */
 
111
    if (type_jfs & JFS_SWAP_BYTES) {
 
112
      ujfs_swap_iag_t( &iag ); 
 
113
    }
 
114
  }
 
115
  if (rc & XPEEK_REDISPLAY)
 
116
    goto changed;
 
117
  return;
 
118
}
 
119
 
 
120
/****************************************************************************
 
121
 ************************  Sample output of display_iag()
 
122
 
 
123
IAG 0 at block 440
 
124
 
 
125
[1] agstart:            25                  [12] extsmap[0]:    ffffffff
 
126
[2] iagnum:                  0          [13] extsmap[1]:        ffffffff
 
127
[3] inofreefwd:         -1                  [14] extsmap[2]:    ffffe000
 
128
[4] inofreeback:        -1              [15] extsmap[3]:        00000000
 
129
[5] extfreefwd:         -1                  [16] nfreeinos:             284
 
130
[6] extfreeback:        -1                  [17] nfreeexts:             45
 
131
[7] iagfree:            -1                  [18] pad:               Not Displayed
 
132
[8] inosmap[0]:         ffffffff        [19] wmap:                  Type 'w'
 
133
[9] inosmap[1]:         ffffffff        [20] pmap:                  Type 'p'
 
134
[10] inosmap[2]:        ff801fff        [21] inoext:            Type 'i'
 
135
[11] inosmap[3]:        ffffffff
 
136
 
 
137
 ****************************************************************************/
 
138
 
 
139
void display_iag(iag_t  *iag)
 
140
{
 
141
  printf("[1] agstart:\t\t%lld\t\t", (long long)iag->agstart);
 
142
  printf("[12] extsmap[0]:\t%08x\n", iag->extsmap[0]);
 
143
  printf("[2] iagnum:\t\t%d\t\t", iag->iagnum);
 
144
  printf("[13] extsmap[1]:\t%08x\n", iag->extsmap[1]);
 
145
  printf("[3] inofreefwd:\t\t%d\t\t", iag->inofreefwd);
 
146
  printf("[14] extsmap[2]:\t%08x\n", iag->extsmap[2]);
 
147
  printf("[4] inofreeback:\t%d\t\t", iag->inofreeback);
 
148
  printf("[15] extsmap[3]:\t%08x\n", iag->extsmap[3]);
 
149
  printf("[5] extfreefwd:\t\t%d\t\t", iag->extfreefwd);
 
150
  printf("[16] nfreeinos:\t\t%d\n", iag->nfreeinos);
 
151
  printf("[6] extfreeback:\t%d\t\t", iag->extfreeback);
 
152
  printf("[17] nfreeexts:\t\t%d\n", iag->nfreeexts);
 
153
  printf("[7] iagfree:\t\t%d\t\t", iag->iagfree);
 
154
  printf("[18] pad:\t\tNot Displayed\n");
 
155
  printf("[8] inosmap[0]:\t\t%08x\t", iag->inosmap[0]);
 
156
  printf("[19] wmap:\t\tType 'w'\n");
 
157
  printf("[9] inosmap[1]:\t\t%08x\t", iag->inosmap[1]);
 
158
  printf("[20] pmap:\t\tType 'p'\n");
 
159
  printf("[10] inosmap[2]:\t%08x\t", iag->inosmap[2]);
 
160
  printf("[21] inoext:\t\tType 'i'\n");
 
161
  printf("[11] inosmap[3]:\t%08x\n", iag->inosmap[3]);
 
162
}
 
163
 
 
164
int32_t change_iag(iag_t  *iag)
 
165
{
 
166
  char     cmdline[80];
 
167
  int32_t  field;
 
168
  char     *token;
 
169
 
 
170
retry:
 
171
  fputs("change_iag: [m]odify, [w]map, [p]map, [i]noext or e[x]it > ", stdout);
 
172
  fgets(cmdline, 80, stdin);
 
173
  token = strtok(cmdline, "     \n");
 
174
  if (token == 0 || token[0] == 'x')
 
175
    return XPEEK_OK;
 
176
  if (token[0] == 'w')
 
177
    return display_map(iag->wmap, EXTSPERIAG);
 
178
  if (token[0] == 'p')
 
179
    return display_map(iag->pmap, EXTSPERIAG);
 
180
  if (token[0] == 'i') {
 
181
    return display_ext(iag->inoext, cmdline);
 
182
  }
 
183
  field = m_parse(cmdline, 17, &token);
 
184
  if (field == 0)
 
185
    goto retry;
 
186
 
 
187
  switch (field) {
 
188
    case 1:
 
189
      iag->agstart = strtoll(token, 0, 0);
 
190
      break;
 
191
    case 2:
 
192
      iag->iagnum = strtol(token, 0, 0);
 
193
      break;
 
194
    case 3:
 
195
      iag->inofreefwd = strtol(token, 0, 0);
 
196
      break;
 
197
    case 4:
 
198
      iag->inofreeback = strtol(token, 0, 0);
 
199
      break;
 
200
    case 5:
 
201
      iag->extfreefwd = strtol(token, 0, 0);
 
202
      break;
 
203
    case 6:
 
204
      iag->extfreeback = strtol(token, 0, 0);
 
205
      break;
 
206
    case 7:
 
207
      iag->iagfree = strtol(token, 0, 0);
 
208
      break;
 
209
    case 8:
 
210
      iag->inosmap[0] = strtoul(token, 0, 16);
 
211
      break;
 
212
    case 9:
 
213
      iag->inosmap[1] = strtoul(token, 0, 16);
 
214
      break;
 
215
    case 10:
 
216
      iag->inosmap[2] = strtoul(token, 0, 16);
 
217
      break;
 
218
    case 11:
 
219
      iag->inosmap[3] = strtoul(token, 0, 16);
 
220
      break;
 
221
    case 12:
 
222
      iag->extsmap[0] = strtoul(token, 0, 16);
 
223
      break;
 
224
    case 13:
 
225
      iag->extsmap[1] = strtoul(token, 0, 16);
 
226
      break;
 
227
    case 14:
 
228
      iag->extsmap[2] = strtoul(token, 0, 16);
 
229
      break;
 
230
    case 15:
 
231
      iag->extsmap[3] = strtoul(token, 0, 16);
 
232
      break;
 
233
    case 16:
 
234
      iag->nfreeinos = strtol(token, 0, 0);
 
235
      break;
 
236
    case 17:
 
237
      iag->nfreeexts = strtol(token, 0, 0);
 
238
      break;
 
239
  }
 
240
  return XPEEK_CHANGED | XPEEK_REDISPLAY;
 
241
}
 
242
 
 
243
#define XT_CMP(CMP, K, X) \
 
244
{ \
 
245
        int64_t offset64 = offsetXAD(X); \
 
246
        (CMP) = ((K) >= offset64 + lengthXAD(X)) ? 1 : \
 
247
                ((K) < offset64) ? -1 : 0 ; \
 
248
}
 
249
 
 
250
int32_t find_iag( uint32_t  iagnum,
 
251
                  uint32_t  which_table,
 
252
                  int64_t   *address )
 
253
{
 
254
  int32_t   base;
 
255
  char      buffer[PSIZE];
 
256
  int32_t   cmp;
 
257
  dinode_t  fileset_inode;
 
258
  int64_t   fileset_inode_address;
 
259
  int64_t   iagblock;
 
260
  int32_t   index;
 
261
  int32_t   lim;
 
262
  xtpage_t  *page;
 
263
  int32_t   rc;
 
264
 
 
265
  if (which_table != FILESYSTEM_I &&
 
266
      which_table != AGGREGATE_I &&
 
267
      which_table != AGGREGATE_2ND_I) {
 
268
    fprintf(stderr, "find_iag: Invalid fileset, %d\n", which_table);
 
269
    return 1;
 
270
  }
 
271
  iagblock = IAGTOLBLK(iagnum, L2PSIZE-l2bsize);
 
272
 
 
273
  if ( which_table == AGGREGATE_2ND_I ) {
 
274
    fileset_inode_address = AIT_2nd_offset + sizeof(dinode_t);
 
275
  } else {
 
276
    fileset_inode_address = AGGR_INODE_TABLE_START +
 
277
                            (which_table * sizeof(dinode_t));
 
278
  }
 
279
  rc = xRead(fileset_inode_address, sizeof(dinode_t),
 
280
             (char *)&fileset_inode);
 
281
  if (rc) {
 
282
    fputs("find_inode: Error reading fileset inode\n", stderr);
 
283
    return 1;
 
284
  }
 
285
 
 
286
  page = (xtpage_t *)&(fileset_inode.di_btroot);
 
287
 
 
288
descend:
 
289
  /* Binary search */
 
290
  for (base = XTENTRYSTART,
 
291
       lim = __le16_to_cpu(page->header.nextindex) - XTENTRYSTART;
 
292
       lim; lim >>=1) {
 
293
    index = base + (lim >> 1);
 
294
    XT_CMP(cmp, iagblock, &(page->xad[index]));
 
295
    if (cmp == 0) {
 
296
      /* HIT! */
 
297
      if (page->header.flag & BT_LEAF) {
 
298
        *address = (addressXAD(&(page->xad[index]))
 
299
                    + (iagblock -
 
300
                       offsetXAD(&(page->xad[index]))))
 
301
                   << l2bsize;
 
302
        return 0;
 
303
      } else {
 
304
        rc = xRead( addressXAD(&(page->xad[index])) << l2bsize,
 
305
                    PSIZE, buffer);
 
306
        if (rc) {
 
307
          fputs("find_iag: Error reading btree node\n", stderr);
 
308
          return 1;
 
309
        }
 
310
        page = (xtpage_t *)buffer;
 
311
 
 
312
        goto descend;
 
313
      }
 
314
    } else if (cmp > 0) {
 
315
      base = index + 1;
 
316
      --lim;
 
317
    }
 
318
  }
 
319
 
 
320
  if (page->header.flag & BT_INTERNAL ) {
 
321
    /* Traverse internal page, it might hit down there
 
322
     * If base is non-zero, decrement base by one to get the parent
 
323
     * entry of the child page to search.
 
324
     */
 
325
    index = base ? base - 1 : base;
 
326
 
 
327
    rc = xRead(addressXAD(&(page->xad[index])) << l2bsize, PSIZE,
 
328
               buffer);
 
329
    if (rc) {
 
330
      fputs("find_iag: Error reading btree node\n", stderr);
 
331
      return 1;
 
332
    }
 
333
    page = (xtpage_t *)buffer;
 
334
 
 
335
    goto descend;
 
336
  }
 
337
 
 
338
  /* Not found! */
 
339
  fprintf(stderr, "find_iag:  IAG %d not found!\n", iagnum);
 
340
  return 1;
 
341
}
 
342
 
 
343
/* display_map is also called from display_page in dmap.c */
 
344
 
 
345
int32_t display_map( uint32_t  *map,
 
346
                     int32_t   size)
 
347
{
 
348
  char     cmdline[80];
 
349
  int32_t  end;
 
350
  int32_t  i;
 
351
  int32_t  index;
 
352
  int32_t  rc = XPEEK_OK;
 
353
  int32_t  start = 0;
 
354
  char     *token;
 
355
 
 
356
map_display:
 
357
  end = MIN(start+128, size);
 
358
  for (i = start; i < end; i+=8) {
 
359
    if ((i+7) < 100)    /* [i-(i+7)] fits in first field */
 
360
      printf("[%d-%d]\t", i, i+7);
 
361
    else
 
362
      printf("[%d- ]\t", i);
 
363
 
 
364
    printf("%08x %08x %08x %08x %08x %08x %08x %08x\n", map[i],
 
365
           map[i+1],map[i+2],map[i+3],map[i+4],map[i+5],map[i+6],
 
366
           map[i+7]);
 
367
  }
 
368
map_retry:
 
369
  fputs("display_map: [m]odify, [b]ack, e[x]it\n", stdout);
 
370
  fgets(cmdline, 80, stdin);
 
371
  token = strtok(cmdline, "     \n");
 
372
  if (token == 0) {
 
373
    start = (size > end)? end : 0;
 
374
    goto map_display;
 
375
  }
 
376
  if (token[0] == 'x')
 
377
    return rc;
 
378
  if (token[0] != 'm') {  /* assuming 'b' */
 
379
    return(rc | XPEEK_REDISPLAY);
 
380
  }
 
381
 
 
382
  index = m_parse(cmdline, size-1, &token);
 
383
  if (index == 0)
 
384
    goto map_retry;
 
385
 
 
386
  map[index] = strtoul(token, 0, 16);
 
387
  rc = XPEEK_CHANGED;
 
388
  goto map_display;
 
389
}
 
390
 
 
391
int32_t display_ext( pxd_t  *ext,
 
392
                     char   *cmdline)
 
393
{
 
394
  int32_t  field;
 
395
  int32_t  index;
 
396
  int32_t  rc = XPEEK_OK;
 
397
  char     *token;
 
398
 
 
399
  token = strtok(0, "   \n");
 
400
  if (token == 0) {
 
401
ext_retry:
 
402
    fputs("Please enter: index [0-127] > ",stdout);
 
403
    fgets(cmdline, 80, stdin);
 
404
    token = strtok(cmdline, "   \n");
 
405
    if (token == 0)
 
406
      return rc | XPEEK_REDISPLAY;
 
407
  }
 
408
newext:
 
409
  index = strtol(token, 0, 0);
 
410
  if (index < 0 || index >= EXTSPERIAG) {
 
411
    fputs("Invalid index\n", stderr);
 
412
    goto ext_retry;
 
413
  }
 
414
ext_changed:
 
415
  printf("[1] inoext[%d].len:\t%d\n", index, ext[index].len);
 
416
  printf("[2] inoext[%d].addr1:\t0x%02x\n", index, ext[index].addr1);
 
417
  printf("[3] inoext[%d].addr2:\t0x%08x\n", index, ext[index].addr2);
 
418
  printf("    addressPXD:\t\t%lld\n", (long long)addressPXD(&ext[index]));
 
419
ext_again:
 
420
  fputs("display_ext: [m]odify, ext [#], [b]ack to iag, e[x]it > ",
 
421
        stdout);
 
422
  fgets(cmdline, 80, stdin);
 
423
  token = strtok(cmdline, "     \n");
 
424
  if (token == 0 || token[0] == 'x')
 
425
    return rc;
 
426
  if (isdigit(token[0]))
 
427
    goto newext;
 
428
  if (token[0] != 'm')    /* assuming 'b' */
 
429
    return rc | XPEEK_REDISPLAY;
 
430
 
 
431
  field = m_parse(cmdline, 3, &token);
 
432
  if (field == 0)
 
433
    goto ext_again;
 
434
 
 
435
  switch (field) {
 
436
    case 1:
 
437
      ext[index].len = strtol(token,0,0);
 
438
      break;
 
439
    case 2:
 
440
      ext[index].addr1 = strtol(token,0,16);
 
441
      break;
 
442
    case 3:
 
443
      ext[index].addr2 = strtol(token,0,16);
 
444
      break;
 
445
  }
 
446
  rc = XPEEK_CHANGED;
 
447
  goto ext_changed;
 
448
}