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-10-25 12:04:14 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 <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 1.14