LCOV - code coverage report
Current view: top level - edit - extended.c (source / functions) Coverage Total Hit
Test: gfs2-utils.info Lines: 10.2 % 382 39
Test Date: 2024-03-07 16:24:06 Functions: 13.3 % 15 2

            Line data    Source code
       1              : #include "clusterautoconfig.h"
       2              : 
       3              : #include <stdio.h>
       4              : #include <stdlib.h>
       5              : #include <ctype.h>
       6              : #include <string.h>
       7              : #include <inttypes.h>
       8              : #include <sys/types.h>
       9              : #include <sys/stat.h>
      10              : #include <fcntl.h>
      11              : #include <unistd.h>
      12              : #include <errno.h>
      13              : #include <curses.h>
      14              : #include <term.h>
      15              : #include <signal.h>
      16              : #include <sys/ioctl.h>
      17              : #include <sys/mount.h>
      18              : #include <dirent.h>
      19              : #include <libgfs2.h>
      20              : 
      21              : #include "copyright.cf"
      22              : 
      23              : #include "hexedit.h"
      24              : #include "extended.h"
      25              : #include "gfs2hex.h"
      26              : #include "struct_print.h"
      27              : 
      28              : static void print_block_details(struct iinfo *ind, int level, int cur_height,
      29              :                                 int pndx, uint64_t file_offset);
      30              : 
      31            0 : static int get_height(void)
      32              : {
      33            0 :         int cur_height = 0, i;
      34              : 
      35            0 :         if (gfs2_struct_type != GFS2_METATYPE_DI) {
      36            0 :                 for (i = 0; i <= blockhist && i < 5; i++) {
      37            0 :                         if (blockstack[(blockhist - i) %
      38            0 :                                        BLOCK_STACK_SIZE].gfs2_struct_type ==
      39              :                             GFS2_METATYPE_DI)
      40            0 :                                 break;
      41            0 :                         cur_height++;
      42              :                 }
      43              :         }
      44            0 :         return cur_height;
      45              : }
      46              : 
      47            0 : static int _do_indirect_extended(char *diebuf, struct iinfo *iinf, int hgt)
      48              : {
      49              :         unsigned int x, y;
      50              :         off_t headoff;
      51              :         uint64_t p;
      52              :         int i_blocks;
      53              : 
      54            0 :         i_blocks = 0;
      55            0 :         for (x = 0; x < 512; x++) {
      56            0 :                 iinf->ii[x].is_dir = 0;
      57            0 :                 iinf->ii[x].height = 0;
      58            0 :                 iinf->ii[x].block = 0;
      59            0 :                 iinf->ii[x].dirents = 0;
      60            0 :                 memset(&iinf->ii[x].dirent, 0, sizeof(struct idirent));
      61              :         }
      62            0 :         headoff = sizeof(struct gfs2_meta_header);
      63            0 :         for (x = headoff, y = 0; x < sbd.sd_bsize; x += sizeof(uint64_t), y++) {
      64            0 :                 p = be64_to_cpu(*(__be64 *)(diebuf + x));
      65            0 :                 if (p) {
      66            0 :                         iinf->ii[i_blocks].block = p;
      67            0 :                         iinf->ii[i_blocks].mp.mp_list[hgt] = i_blocks;
      68            0 :                         iinf->ii[i_blocks].is_dir = FALSE;
      69            0 :                         iinf->ii[i_blocks].ptroff = (x - headoff) / sizeof(uint64_t);
      70            0 :                         i_blocks++;
      71              :                 }
      72              :         }
      73            0 :         return i_blocks;
      74              : }
      75              : 
      76            0 : int do_indirect_extended(char *diebuf, struct iinfo *iinf)
      77              : {
      78            0 :         return _do_indirect_extended(diebuf, iinf, get_height());
      79              : }
      80              : 
      81              : /* ------------------------------------------------------------------------ */
      82              : /* dinode_valid - check if we have a dinode in recent history               */
      83              : /* ------------------------------------------------------------------------ */
      84            0 : static int dinode_valid(void)
      85              : {
      86              :         int i;
      87              : 
      88            0 :         if (gfs2_struct_type == GFS2_METATYPE_DI)
      89            0 :                 return 1;
      90            0 :         for (i = 0; i <= blockhist && i < 5; i++) {
      91            0 :                 if (blockstack[(blockhist - i) %
      92            0 :                                BLOCK_STACK_SIZE].gfs2_struct_type ==
      93              :                     GFS2_METATYPE_DI)
      94            0 :                         return 1;
      95              :         }
      96            0 :         return 0;
      97              : }
      98              : 
      99            0 : static uint64_t metapath_to_lblock(struct lgfs2_metapath *mp, int hgt)
     100              : {
     101              :         int h;
     102            0 :         uint64_t lblock = 0;
     103              :         uint64_t factor[GFS2_MAX_META_HEIGHT];
     104            0 :         uint16_t height = be16_to_cpu(di->di_height);
     105              : 
     106            0 :         if (height < 2)
     107            0 :                 return mp->mp_list[0];
     108              :         /* figure out multiplication factors for each height */
     109            0 :         memset(&factor, 0, sizeof(factor));
     110            0 :         factor[height - 1] = 1ull;
     111            0 :         for (h = height - 2; h >= 0; h--)
     112            0 :                 factor[h] = factor[h + 1] * sbd.sd_inptrs;
     113            0 :         for (h = 0; h <= hgt; h++)
     114            0 :                 lblock += (mp->mp_list[h] * factor[h]);
     115            0 :         return lblock;
     116              : }
     117              : 
     118            0 : static int display_indirect(struct iinfo *ind, int indblocks, int level,
     119              :                             uint64_t startoff)
     120              : {
     121              :         int start_line;
     122            0 :         int cur_height = -1, pndx;
     123              : 
     124            0 :         last_entry_onscreen[dmode] = 0;
     125            0 :         if (!has_indirect_blocks())
     126            0 :                 return -1;
     127            0 :         if (!level) {
     128            0 :                 if (gfs2_struct_type == GFS2_METATYPE_DI) {
     129            0 :                         if (S_ISDIR(be32_to_cpu(di->di_mode)))
     130            0 :                                 print_gfs2("This directory contains %d indirect blocks",
     131              :                                            indblocks);
     132              :                         else
     133            0 :                                 print_gfs2("This inode contains %d indirect blocks",
     134              :                                            indblocks);
     135              :                 } else
     136            0 :                         print_gfs2("This indirect block contains %d indirect blocks",
     137              :                                    indblocks);
     138              :         }
     139            0 :         if (dinode_valid() && !S_ISDIR(be32_to_cpu(di->di_mode))) {
     140              :                 /* See if we are on an inode or have one in history. */
     141            0 :                 if (level)
     142            0 :                         cur_height = level;
     143              :                 else {
     144            0 :                         cur_height = get_height();
     145            0 :                         print_gfs2("  (at height %d of %d)",
     146            0 :                                    cur_height, be16_to_cpu(di->di_height));
     147              :                 }
     148              :         }
     149            0 :         eol(0);
     150            0 :         if (!level && indblocks) {
     151            0 :                 print_gfs2("Indirect blocks:");
     152            0 :                 eol(0);
     153              :         }
     154            0 :         start_line = line;
     155            0 :         for (pndx = start_row[dmode];
     156            0 :                  (!termlines || pndx < termlines - start_line - 1
     157            0 :                   + start_row[dmode]) && pndx < indblocks;
     158            0 :                  pndx++) {
     159              :                 uint64_t file_offset;
     160              : 
     161            0 :                 if (pndx && ind->ii[pndx].block == ind->ii[pndx - 1].block)
     162            0 :                         continue;
     163            0 :                 print_entry_ndx = pndx;
     164            0 :                 if (termlines) {
     165            0 :                         if (edit_row[dmode] >= 0 &&
     166            0 :                             line - start_line ==
     167            0 :                             edit_row[dmode] - start_row[dmode])
     168            0 :                                 COLORS_HIGHLIGHT;
     169            0 :                         move(line, 1);
     170              :                 }
     171            0 :                 if (!termlines) {
     172              :                         int h;
     173              : 
     174            0 :                         for (h = 0; h < level; h++)
     175            0 :                                 print_gfs2("   ");
     176              :                 }
     177            0 :                 print_gfs2("%d: 0x%"PRIx64" => ", pndx, ind->ii[pndx].ptroff);
     178            0 :                 print_gfs2("0x%"PRIx64" / %"PRId64, ind->ii[pndx].block,
     179              :                            ind->ii[pndx].block);
     180            0 :                 if (termlines) {
     181            0 :                         if (edit_row[dmode] >= 0 &&
     182            0 :                             line - start_line ==
     183            0 :                             edit_row[dmode] - start_row[dmode]) { 
     184            0 :                                 sprintf(estring, "%"PRIx64,
     185              :                                         ind->ii[print_entry_ndx].block);
     186            0 :                                 strcpy(edit_fmt, "%"PRIx64);
     187            0 :                                 edit_size[dmode] = strlen(estring);
     188            0 :                                 COLORS_NORMAL;
     189              :                         }
     190              :                 }
     191            0 :                 if (dinode_valid() && !S_ISDIR(be32_to_cpu(di->di_mode))) {
     192              :                         float human_off;
     193              :                         char h;
     194              : 
     195            0 :                         file_offset = metapath_to_lblock(&ind->ii[pndx].mp,
     196              :                                                          cur_height) *
     197            0 :                                 sbd.sd_bsize;
     198            0 :                         print_gfs2("     ");
     199            0 :                         h = 'K';
     200            0 :                         human_off = (file_offset / 1024.0);
     201            0 :                         if (human_off > 1024.0) { h = 'M'; human_off /= 1024.0; }
     202            0 :                         if (human_off > 1024.0) { h = 'G'; human_off /= 1024.0; }
     203            0 :                         if (human_off > 1024.0) { h = 'T'; human_off /= 1024.0; }
     204            0 :                         if (human_off > 1024.0) { h = 'P'; human_off /= 1024.0; }
     205            0 :                         if (human_off > 1024.0) { h = 'E'; human_off /= 1024.0; }
     206            0 :                         print_gfs2("(data offset 0x%"PRIx64" / %"PRId64" / %6.2f%c)",
     207              :                                    file_offset, file_offset, human_off, h);
     208            0 :                         print_gfs2("   ");
     209              :                 }
     210              :                 else
     211            0 :                         file_offset = 0;
     212            0 :                 if (dinode_valid() && !termlines &&
     213            0 :                     ((level + 1 < be16_to_cpu(di->di_height)) ||
     214            0 :                      (S_ISDIR(be32_to_cpu(di->di_mode)) && level <= be16_to_cpu(di->di_height)))) {
     215            0 :                         print_block_details(ind, level, cur_height, pndx,
     216              :                                             file_offset);
     217              :                 }
     218            0 :                 print_entry_ndx = pndx; /* restore after recursion */
     219            0 :                 eol(0);
     220              :         } /* for each display row */
     221            0 :         if (line >= 7) /* 7 because it was bumped at the end */
     222            0 :                 last_entry_onscreen[dmode] = line - 7;
     223            0 :         eol(0);
     224            0 :         end_row[dmode] = indblocks;
     225            0 :         if (end_row[dmode] < last_entry_onscreen[dmode])
     226            0 :                 end_row[dmode] = last_entry_onscreen[dmode];
     227            0 :         lines_per_row[dmode] = 1;
     228            0 :         return 0;
     229              : }
     230              : 
     231            0 : static void print_inode_type(uint16_t de_type)
     232              : {
     233            0 :         switch(de_type) {
     234            0 :         case DT_UNKNOWN:
     235            0 :                 print_gfs2("Unknown");
     236            0 :                 break;
     237            0 :         case DT_REG:
     238            0 :                 print_gfs2("File   ");
     239            0 :                 break;
     240            0 :         case DT_DIR:
     241            0 :                 print_gfs2("Dir    ");
     242            0 :                 break;
     243            0 :         case DT_LNK:
     244            0 :                 print_gfs2("Symlink");
     245            0 :                 break;
     246            0 :         case DT_BLK:
     247            0 :                 print_gfs2("BlkDev ");
     248            0 :                 break;
     249            0 :         case DT_CHR:
     250            0 :                 print_gfs2("ChrDev ");
     251            0 :                 break;
     252            0 :         case DT_FIFO:
     253            0 :                 print_gfs2("Fifo   ");
     254            0 :                 break;
     255            0 :         case DT_SOCK:
     256            0 :                 print_gfs2("Socket ");
     257            0 :                 break;
     258            0 :         default:
     259            0 :                 print_gfs2("%04x   ", de_type);
     260            0 :                 break;
     261              :         }
     262            0 : }
     263              : 
     264            0 : static int display_leaf(struct iinfo *ind)
     265              : {
     266            0 :         struct gfs2_leaf *leaf = &ind->ii[0].lf;
     267            0 :         int start_line, total_dirents = start_row[dmode];
     268              :         int d;
     269              : 
     270            0 :         eol(0);
     271            0 :         if (gfs2_struct_type == GFS2_METATYPE_SB)
     272            0 :                 print_gfs2("The superblock has 2 directories");
     273              :         else
     274            0 :                 print_gfs2("Directory block: "
     275              :                            "lf_depth:%"PRIu16", lf_entries:%"PRIu16", lf_inode: 0x%"PRIx64", "
     276              :                            "lf_dist: %"PRIu32", lf_nsec: %"PRIu32", lf_sec: %"PRIu64", "
     277              :                            "fmt:%"PRIu32" next=0x%"PRIx64" (%d dirents).",
     278            0 :                            be16_to_cpu(leaf->lf_depth), be16_to_cpu(leaf->lf_entries),
     279            0 :                            be64_to_cpu(leaf->lf_inode), be32_to_cpu(leaf->lf_dist),
     280            0 :                            be32_to_cpu(leaf->lf_nsec), be64_to_cpu(leaf->lf_sec),
     281              :                            leaf->lf_dirent_format,
     282              :                            leaf->lf_next,
     283              :                            ind->ii[0].dirents);
     284              : 
     285            0 :         start_line = line;
     286            0 :         for (d = start_row[dmode]; d < ind->ii[0].dirents; d++) {
     287            0 :                 if (termlines && d >= termlines - start_line - 2
     288            0 :                     + start_row[dmode])
     289            0 :                         break;
     290            0 :                 total_dirents++;
     291            0 :                 if (ind->ii[0].dirents >= 1) {
     292            0 :                         eol(3);
     293            0 :                         if (termlines) {
     294            0 :                                 if (edit_row[dmode] >=0 &&
     295            0 :                                     line - start_line - 1 ==
     296            0 :                                     edit_row[dmode] - start_row[dmode]) {
     297            0 :                                         COLORS_HIGHLIGHT;
     298            0 :                                         sprintf(estring, "%"PRIx64, ind->ii[0].dirent[d].inum.in_addr);
     299            0 :                                         strcpy(edit_fmt, "%llx");
     300              :                                 }
     301              :                         }
     302            0 :                         print_gfs2("%d/%d [%08"PRIX32"] %"PRIu64"/%"PRIu64" (0x%"PRIx64"/0x%"PRIx64") +%"PRIu16": ",
     303              :                                    total_dirents, d + 1,
     304              :                                    ind->ii[0].dirent[d].hash,
     305              :                                    ind->ii[0].dirent[d].inum.in_formal_ino,
     306              :                                    ind->ii[0].dirent[d].inum.in_addr,
     307              :                                    ind->ii[0].dirent[d].inum.in_formal_ino,
     308              :                                    ind->ii[0].dirent[d].inum.in_addr,
     309            0 :                                    ind->ii[0].dirent[d].rahead
     310              :                         );
     311              :                 }
     312            0 :                 print_inode_type(ind->ii[0].dirent[d].type);
     313            0 :                 print_gfs2(" %s", ind->ii[0].dirent[d].filename);
     314            0 :                 if (termlines) {
     315            0 :                         if (edit_row[dmode] >= 0 &&
     316            0 :                             line - start_line - 1 == edit_row[dmode] -
     317            0 :                             start_row[dmode])
     318            0 :                                 COLORS_NORMAL;
     319              :                 }
     320              :         }
     321            0 :         if (line >= 4)
     322            0 :                 last_entry_onscreen[dmode] = line - 4;
     323            0 :         eol(0);
     324            0 :         end_row[dmode] = ind->ii[0].dirents;
     325            0 :         if (end_row[dmode] < last_entry_onscreen[dmode])
     326            0 :                 end_row[dmode] = last_entry_onscreen[dmode];
     327            0 :         return 0;
     328              : }
     329              : 
     330            0 : static void print_block_details(struct iinfo *ind, int level, int cur_height,
     331              :                                 int pndx, uint64_t file_offset)
     332              : {
     333              :         struct iinfo *more_indir;
     334              :         int more_ind;
     335              :         char *tmpbuf;
     336              :         uint64_t thisblk;
     337              : 
     338            0 :         thisblk = ind->ii[pndx].block;
     339            0 :         more_indir = malloc(sizeof(struct iinfo));
     340            0 :         if (!more_indir) {
     341            0 :                 fprintf(stderr, "Out of memory in function "
     342              :                         "display_indirect\n");
     343            0 :                 return;
     344              :         }
     345            0 :         tmpbuf = malloc(sbd.sd_bsize);
     346            0 :         if (!tmpbuf) {
     347            0 :                 fprintf(stderr, "Out of memory in function "
     348              :                         "display_indirect\n");
     349            0 :                 free(more_indir);
     350            0 :                 return;
     351              :         }
     352            0 :         while (thisblk) {
     353              :                 /* read in the desired block */
     354            0 :                 if (pread(sbd.device_fd, tmpbuf, sbd.sd_bsize, thisblk * sbd.sd_bsize) != sbd.sd_bsize) {
     355            0 :                         fprintf(stderr, "bad read: %s from %s:%d: block %"PRIu64
     356            0 :                                 " (0x%"PRIx64")\n", strerror(errno), __FUNCTION__,
     357              :                                 __LINE__, ind->ii[pndx].block, ind->ii[pndx].block);
     358            0 :                         exit(-1);
     359              :                 }
     360            0 :                 thisblk = 0;
     361            0 :                 memset(more_indir, 0, sizeof(struct iinfo));
     362            0 :                 if (S_ISDIR(be32_to_cpu(di->di_mode)) && level == be16_to_cpu(di->di_height)) {
     363            0 :                         thisblk = do_leaf_extended(tmpbuf, more_indir);
     364            0 :                         display_leaf(more_indir);
     365              :                 } else {
     366              :                         int x;
     367              : 
     368            0 :                         for (x = 0; x < 512; x++) {
     369            0 :                                 memcpy(&more_indir->ii[x].mp,
     370            0 :                                        &ind->ii[pndx].mp,
     371              :                                        sizeof(struct lgfs2_metapath));
     372            0 :                                 more_indir->ii[x].mp.mp_list[cur_height+1] = x;
     373              :                         }
     374            0 :                         more_ind = _do_indirect_extended(tmpbuf, more_indir,
     375              :                                                          cur_height + 1);
     376            0 :                         display_indirect(more_indir, more_ind, level + 1,
     377              :                                          file_offset);
     378              :                 }
     379            0 :                 if (thisblk) {
     380            0 :                         eol(0);
     381            0 :                         if (termlines)
     382            0 :                                 move(line,9);
     383            0 :                         print_gfs2("Continuation block 0x%"PRIx64" / %"PRId64,
     384              :                                    thisblk, thisblk);
     385              :                 }
     386              :         }
     387            0 :         free(tmpbuf);
     388            0 :         free(more_indir);
     389              : }
     390              : 
     391            0 : static int print_gfs2_jindex(void)
     392              : {
     393              :         int d, error;
     394              :         struct lgfs2_log_header head;
     395              :         struct lgfs2_inode *ip;
     396              : 
     397            0 :         for (d = 0; d < indirect->ii[0].dirents; d++) {
     398            0 :                 if (strncmp(indirect->ii[0].dirent[d].filename, "journal", 7))
     399            0 :                         continue;
     400            0 :                 ip = lgfs2_inode_read(&sbd, indirect->ii[0].dirent[d].inum.in_addr);
     401            0 :                 print_gfs2("%s: 0x%-5"PRIx64" %"PRIu64"MB ",
     402            0 :                            indirect->ii[0].dirent[d].filename,
     403            0 :                            indirect->ii[0].dirent[d].inum.in_addr,
     404            0 :                            ip->i_size / 1048576);
     405            0 :                 error = lgfs2_find_jhead(ip, &head);
     406            0 :                 if (error) {
     407            0 :                         print_gfs2("corrupt.");
     408              :                 } else {
     409            0 :                         if (head.lh_flags & GFS2_LOG_HEAD_UNMOUNT)
     410            0 :                                 print_gfs2("clean.");
     411              :                         else
     412            0 :                                 print_gfs2("dirty.");
     413              :                 }
     414            0 :                 eol(0);
     415            0 :                 lgfs2_inode_put(&ip);
     416              :         }
     417            0 :         return 0;
     418              : }
     419              : 
     420            7 : static int parse_rindex(struct lgfs2_inode *dip, int print_rindex)
     421              : {
     422              :         int error, start_line;
     423              :         struct gfs2_rindex ri;
     424              :         char highlighted_addr[32];
     425            7 :         struct lgfs2_rgrp_tree rg = {0};
     426              : 
     427            7 :         start_line = line;
     428            7 :         print_gfs2("RG index entries found: %"PRIu64".",
     429            7 :                    dip->i_size / sizeof(struct gfs2_rindex));
     430            7 :         eol(0);
     431            7 :         lines_per_row[dmode] = 6;
     432            7 :         memset(highlighted_addr, 0, sizeof(highlighted_addr));
     433              : 
     434          973 :         for (print_entry_ndx=0; ; print_entry_ndx++) {
     435              :                 uint64_t roff;
     436              : 
     437          973 :                 roff = print_entry_ndx * sizeof(struct gfs2_rindex);
     438              : 
     439          973 :                 error = lgfs2_readi(dip, &ri, roff, sizeof(struct gfs2_rindex));
     440          973 :                 if (!error) /* end of file */
     441            7 :                         break;
     442          966 :                 lgfs2_rindex_in(&rg, &ri);
     443          966 :                 if (!termlines ||
     444            0 :                         (print_entry_ndx >= start_row[dmode] &&
     445            0 :                          ((print_entry_ndx - start_row[dmode])+1) * lines_per_row[dmode] <=
     446            0 :                          termlines - start_line - 2)) {
     447          966 :                         if (edit_row[dmode] == print_entry_ndx) {
     448            7 :                                 COLORS_HIGHLIGHT;
     449            7 :                                 sprintf(highlighted_addr, "%"PRIx64, rg.rt_addr);
     450              :                         }
     451          966 :                         print_gfs2("RG #%d", print_entry_ndx);
     452          966 :                         if (!print_rindex)
     453            0 :                                 print_gfs2(" located at: %"PRIu64" (0x%"PRIx64")",
     454              :                                            rg.rt_addr, rg.rt_addr);
     455          966 :                         eol(0);
     456          966 :                         if (edit_row[dmode] == print_entry_ndx)
     457            7 :                                 COLORS_NORMAL;
     458          966 :                         if (print_rindex)
     459          966 :                                 rindex_print(&ri);
     460              :                         else {
     461            0 :                                 struct gfs2_rgrp r = {0};
     462              :                                 ssize_t ret;
     463              : 
     464            0 :                                 ret = pread(sbd.device_fd, &r, sizeof(r), rg.rt_addr * sbd.sd_bsize);
     465            0 :                                 if (ret != sizeof(r)) {
     466            0 :                                         perror("Failed to read resource group");
     467              :                                 } else {
     468            0 :                                         rgrp_print(&r);
     469              :                                 }
     470              :                         }
     471          966 :                         last_entry_onscreen[dmode] = print_entry_ndx;
     472              :                 }
     473              :         }
     474            7 :         strcpy(estring, highlighted_addr);
     475            7 :         end_row[dmode] = print_entry_ndx;
     476            7 :         return error;
     477              : }
     478              : 
     479            0 : static int print_inum(struct lgfs2_inode *dii)
     480              : {
     481              :         uint64_t inodenum;
     482              :         __be64 inum;
     483              :         int rc;
     484              :         
     485            0 :         rc = lgfs2_readi(dii, (void *)&inum, 0, sizeof(inum));
     486            0 :         if (!rc) {
     487            0 :                 print_gfs2("The inum file is empty.");
     488            0 :                 eol(0);
     489            0 :                 return 0;
     490              :         }
     491            0 :         if (rc != sizeof(inum)) {
     492            0 :                 print_gfs2("Error reading inum file.");
     493            0 :                 eol(0);
     494            0 :                 return -1;
     495              :         }
     496            0 :         inodenum = be64_to_cpu(inum);
     497            0 :         print_gfs2("Next inode num = %"PRId64" (0x%"PRIx64")", inodenum, inodenum);
     498            0 :         eol(0);
     499            0 :         return 0;
     500              : }
     501              : 
     502            0 : static int print_statfs(struct lgfs2_inode *dis)
     503              : {
     504              :         struct gfs2_statfs_change sc;
     505              :         int rc;
     506              : 
     507            0 :         rc = lgfs2_readi(dis, (void *)&sc, 0, sizeof(sc));
     508            0 :         if (!rc) {
     509            0 :                 print_gfs2("The statfs file is empty.");
     510            0 :                 eol(0);
     511            0 :                 return 0;
     512              :         }
     513            0 :         if (rc != sizeof(sc)) {
     514            0 :                 print_gfs2("Error reading statfs file.");
     515            0 :                 eol(0);
     516            0 :                 return -1;
     517              :         }
     518            0 :         print_gfs2("statfs file contents:");
     519            0 :         eol(0);
     520            0 :         statfs_change_print(&sc);
     521            0 :         return 0;
     522              : }
     523              : 
     524            0 : static int print_quota(struct lgfs2_inode *diq)
     525              : {
     526              :         struct gfs2_quota q;
     527              :         int i, error;
     528              : 
     529            0 :         print_gfs2("quota file contents:");
     530            0 :         eol(0);
     531            0 :         print_gfs2("quota entries found: %"PRIu64".", diq->i_size / sizeof(q));
     532            0 :         eol(0);
     533            0 :         for (i=0; ; i++) {
     534            0 :                 error = lgfs2_readi(diq, &q, i * sizeof(q), sizeof(q));
     535            0 :                 if (!error)
     536            0 :                         break;
     537            0 :                 if (error != sizeof(q)) {
     538            0 :                         print_gfs2("Error reading quota file.");
     539            0 :                         eol(0);
     540            0 :                         return -1;
     541              :                 }
     542            0 :                 print_gfs2("Entry #%d", i + 1);
     543            0 :                 eol(0);
     544            0 :                 quota_print(&q);
     545              :         }
     546            0 :         return 0;
     547              : }
     548              : 
     549            7 : int display_extended(void)
     550              : {
     551              :         struct lgfs2_inode *tmp_inode;
     552              :         struct lgfs2_buffer_head *tmp_bh;
     553              : 
     554            7 :         dsplines = termlines - line - 1;
     555              :         /* Display any indirect pointers that we have. */
     556            7 :         if (block_is_rindex(block)) {
     557            7 :                 tmp_bh = lgfs2_bread(&sbd, block);
     558            7 :                 tmp_inode = lgfs2_inode_get(&sbd, tmp_bh);
     559            7 :                 if (tmp_inode == NULL)
     560            0 :                         return -1;
     561            7 :                 parse_rindex(tmp_inode, TRUE);
     562            7 :                 lgfs2_inode_put(&tmp_inode);
     563            7 :                 lgfs2_brelse(tmp_bh);
     564            0 :         } else if (block_is_journals(block)) {
     565            0 :                 block = masterblock("jindex");
     566            0 :                 print_gfs2_jindex();
     567            0 :         } else if (has_indirect_blocks() && !indirect_blocks &&
     568            0 :                  !display_leaf(indirect))
     569            0 :                 return -1;
     570            0 :         else if (display_indirect(indirect, indirect_blocks, 0, 0) == 0)
     571            0 :                 return -1;
     572            0 :         else if (block_is_rgtree(block)) {
     573            0 :                 tmp_bh = lgfs2_bread(&sbd, masterblock("rindex"));
     574            0 :                 tmp_inode = lgfs2_inode_get(&sbd, tmp_bh);
     575            0 :                 if (tmp_inode == NULL)
     576            0 :                         return -1;
     577            0 :                 parse_rindex(tmp_inode, FALSE);
     578            0 :                 lgfs2_inode_put(&tmp_inode);
     579            0 :                 lgfs2_brelse(tmp_bh);
     580              :         }
     581            0 :         else if (block_is_inum_file(block)) {
     582            0 :                 tmp_bh = lgfs2_bread(&sbd, block);
     583            0 :                 tmp_inode = lgfs2_inode_get(&sbd, tmp_bh);
     584            0 :                 if (tmp_inode == NULL)
     585            0 :                         return -1;
     586            0 :                 print_inum(tmp_inode);
     587            0 :                 lgfs2_inode_put(&tmp_inode);
     588            0 :                 lgfs2_brelse(tmp_bh);
     589              :         }
     590            0 :         else if (block_is_statfs_file(block)) {
     591            0 :                 tmp_bh = lgfs2_bread(&sbd, block);
     592            0 :                 tmp_inode = lgfs2_inode_get(&sbd, tmp_bh);
     593            0 :                 if (tmp_inode == NULL)
     594            0 :                         return -1;
     595            0 :                 print_statfs(tmp_inode);
     596            0 :                 lgfs2_inode_put(&tmp_inode);
     597            0 :                 lgfs2_brelse(tmp_bh);
     598              :         }
     599            0 :         else if (block_is_quota_file(block)) {
     600            0 :                 tmp_bh = lgfs2_bread(&sbd, block);
     601            0 :                 tmp_inode = lgfs2_inode_get(&sbd, tmp_bh);
     602            0 :                 if (tmp_inode == NULL)
     603            0 :                         return -1;
     604            0 :                 print_quota(tmp_inode);
     605            0 :                 lgfs2_inode_put(&tmp_inode);
     606            0 :                 lgfs2_brelse(tmp_bh);
     607              :         }
     608            7 :         return 0;
     609              : }
     610              : 
        

Generated by: LCOV version 2.0-1