LCOV - code coverage report
Current view: top level - edit - extended.c (source / functions) Hit Total Coverage
Test: gfs2-utils.info Lines: 39 382 10.2 %
Date: 2023-09-27 13:48:55 Functions: 2 15 13.3 %

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

Generated by: LCOV version 1.14