LCOV - code coverage report
Current view: top level - fsck - pass5.c (source / functions) Hit Total Coverage
Test: gfs2-utils.info Lines: 64 83 77.1 %
Date: 2023-09-27 13:48:55 Functions: 3 3 100.0 %

          Line data    Source code
       1             : #include "clusterautoconfig.h"
       2             : 
       3             : #include <stdio.h>
       4             : #include <string.h>
       5             : #include <inttypes.h>
       6             : #include <stdlib.h>
       7             : #include <libintl.h>
       8             : #define _(String) gettext(String)
       9             : 
      10             : #include <logging.h>
      11             : #include "libgfs2.h"
      12             : #include "fsck.h"
      13             : #include "util.h"
      14             : 
      15             : #define GFS1_BLKST_USEDMETA 4
      16             : 
      17      132463 : static int check_block_status(struct fsck_cx *cx,  struct bmap *bl,
      18             :                               char *buffer, unsigned int buflen,
      19             :                               uint64_t *rg_block, uint64_t rg_data,
      20             :                               uint32_t *count)
      21             : {
      22      132463 :         struct lgfs2_sbd *sdp = cx->sdp;
      23             :         unsigned char *byte, *end;
      24             :         unsigned int bit;
      25             :         unsigned char rg_status;
      26             :         int q;
      27             :         uint64_t block;
      28             : 
      29             :         /* FIXME verify cast */
      30      132463 :         byte = (unsigned char *) buffer;
      31      132463 :         bit = 0;
      32      132463 :         end = (unsigned char *) buffer + buflen;
      33             : 
      34   477633707 :         while (byte < end) {
      35   477501244 :                 rg_status = ((*byte >> bit) & GFS2_BIT_MASK);
      36   477501244 :                 block = rg_data + *rg_block;
      37   477501244 :                 display_progress(block);
      38   477501244 :                 if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
      39           0 :                         return 0;
      40             : 
      41   477501244 :                 q = block_type(bl, block);
      42   477501244 :                 count[q]++;
      43             : 
      44             :                 /* If one node opens a file and another node deletes it, we
      45             :                    may be left with a block that appears to be "unlinked" in
      46             :                    the bitmap, but nothing links to it. This is a valid case
      47             :                    and should be cleaned up by the file system eventually.
      48             :                    So we ignore it. */
      49   477501244 :                 if (q == GFS2_BLKST_UNLINKED) {
      50           0 :                         log_err(_("Unlinked inode found at block %"PRIu64" (0x%"PRIx64").\n"),
      51             :                                 block, block);
      52           0 :                         if (query(cx, _("Do you want to reclaim the block? (y/n) "))) {
      53           0 :                                 lgfs2_rgrp_t rg = lgfs2_blk2rgrpd(sdp, block);
      54           0 :                                 if (lgfs2_set_bitmap(rg, block, GFS2_BLKST_FREE))
      55           0 :                                         log_err(_("Unlinked block %"PRIu64" (0x%"PRIx64") bitmap not fixed.\n"),
      56             :                                                 block, block);
      57             :                                 else {
      58           0 :                                         log_err(_("Unlinked block %"PRIu64" (0x%"PRIx64") bitmap fixed.\n"),
      59             :                                                 block, block);
      60           0 :                                         count[GFS2_BLKST_UNLINKED]--;
      61           0 :                                         count[GFS2_BLKST_FREE]++;
      62             :                                 }
      63             :                         } else {
      64           0 :                                 log_info(_("Unlinked block found at block %"PRIu64" (0x%"PRIx64"), left unchanged.\n"),
      65             :                                          block, block);
      66             :                         }
      67   477501244 :                 } else if (rg_status != q) {
      68       32833 :                         log_err(_("Block %"PRIu64" (0x%"PRIx64") bitmap says %u (%s) but FSCK saw %u (%s)\n"),
      69             :                                  block, block, rg_status,
      70             :                                  block_type_string(rg_status), q,
      71             :                                  block_type_string(q));
      72       32833 :                         if (q) /* Don't print redundant "free" */
      73           0 :                                 log_err( _("Metadata type is %u (%s)\n"), q,
      74             :                                          block_type_string(q));
      75             : 
      76       32833 :                         if (query(cx, _("Fix bitmap for block %"PRIu64" (0x%"PRIx64")? (y/n) "),
      77             :                                   block, block)) {
      78       32833 :                                 lgfs2_rgrp_t rg = lgfs2_blk2rgrpd(sdp, block);
      79       32833 :                                 if (lgfs2_set_bitmap(rg, block, q))
      80           0 :                                         log_err( _("Repair failed.\n"));
      81             :                                 else
      82       32833 :                                         log_err( _("Fixed.\n"));
      83             :                         } else
      84           0 :                                 log_err(_("Bitmap at block %"PRIu64" (0x%"PRIx64") left inconsistent\n"),
      85             :                                         block, block);
      86             :                 }
      87   477501244 :                 (*rg_block)++;
      88   477501244 :                 bit += GFS2_BIT_SIZE;
      89   477501244 :                 if (bit >= 8){
      90   119375311 :                         bit = 0;
      91   119375311 :                         byte++;
      92             :                 }
      93             :         }
      94             : 
      95      132463 :         return 0;
      96             : }
      97             : 
      98        4359 : static void update_rgrp(struct fsck_cx *cx, struct lgfs2_rgrp_tree *rgp,
      99             :                         struct bmap *bl, uint32_t *count)
     100             : {
     101             :         uint32_t i;
     102             :         struct lgfs2_bitmap *bits;
     103        4359 :         uint64_t rg_block = 0;
     104        4359 :         int update = 0;
     105             : 
     106      136822 :         for(i = 0; i < rgp->rt_length; i++) {
     107      132463 :                 bits = &rgp->rt_bits[i];
     108             : 
     109             :                 /* update the bitmaps */
     110      132463 :                 if (check_block_status(cx, bl, bits->bi_data + bits->bi_offset,
     111             :                                        bits->bi_len, &rg_block, rgp->rt_data0, count))
     112           0 :                         return;
     113      132463 :                 if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
     114           0 :                         return;
     115             :         }
     116             : 
     117             :         /* actually adjust counters and write out to disk */
     118        4359 :         if (rgp->rt_free != count[GFS2_BLKST_FREE]) {
     119           1 :                 log_err(_("RG #%"PRIu64" (0x%"PRIx64") free count inconsistent: "
     120             :                         "is %u should be %u\n"),
     121             :                         rgp->rt_addr, rgp->rt_addr, rgp->rt_free, count[GFS2_BLKST_FREE]);
     122           1 :                 rgp->rt_free = count[GFS2_BLKST_FREE];
     123           1 :                 update = 1;
     124             :         }
     125        4359 :         if (rgp->rt_dinodes != count[GFS2_BLKST_DINODE]) {
     126           4 :                 log_err(_("RG #%"PRIu64" (0x%"PRIx64") Inode count inconsistent: is "
     127             :                           "%u should be %u\n"),
     128             :                         rgp->rt_addr, rgp->rt_addr, rgp->rt_dinodes, count[GFS2_BLKST_DINODE]);
     129           4 :                 rgp->rt_dinodes = count[GFS2_BLKST_DINODE];
     130           4 :                 update = 1;
     131             :         }
     132        4359 :         if (rgp->rt_data != count[GFS2_BLKST_FREE] +
     133        4359 :                             count[GFS2_BLKST_USED] +
     134        4359 :                             count[GFS2_BLKST_UNLINKED] +
     135        4359 :                             count[GFS2_BLKST_DINODE]) {
     136             :                 /* FIXME not sure how to handle this case ATM - it
     137             :                  * means that the total number of blocks we've counted
     138             :                  * exceeds the blocks in the rg */
     139           0 :                 log_err( _("Internal fsck error: %u != %u + %u + %u + %u\n"),
     140             :                          rgp->rt_data, count[GFS2_BLKST_FREE],
     141             :                          count[GFS2_BLKST_USED], count[GFS2_BLKST_UNLINKED],
     142             :                          count[GFS2_BLKST_DINODE]);
     143           0 :                 exit(FSCK_ERROR);
     144             :         }
     145        4359 :         if (update) {
     146           5 :                 if (query(cx, _("Update resource group counts? (y/n) "))) {
     147           5 :                         log_warn( _("Resource group counts updated\n"));
     148           5 :                         lgfs2_rgrp_out(rgp, rgp->rt_bits[0].bi_data);
     149           5 :                         rgp->rt_bits[0].bi_modified = 1;
     150             :                 } else
     151           0 :                         log_err( _("Resource group counts left inconsistent\n"));
     152             :         }
     153             : }
     154             : 
     155             : /**
     156             :  * pass5 - check resource groups
     157             :  *
     158             :  * fix free block maps
     159             :  * fix used inode maps
     160             :  */
     161          56 : int pass5(struct fsck_cx *cx, struct bmap *bl)
     162             : {
     163          56 :         struct lgfs2_sbd *sdp = cx->sdp;
     164          56 :         struct osi_node *n, *next = NULL;
     165          56 :         struct lgfs2_rgrp_tree *rgp = NULL;
     166             :         uint32_t count[5]; /* we need 5 because of GFS1 usedmeta */
     167          56 :         uint64_t rg_count = 0;
     168             : 
     169             :         /* Reconcile RG bitmaps with fsck bitmap */
     170        4415 :         for (n = osi_first(&sdp->rgtree); n; n = next) {
     171        4359 :                 next = osi_next(n);
     172        4359 :                 if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
     173           0 :                         return FSCK_OK;
     174        4359 :                 log_info(_("Verifying resource group %"PRIu64"\n"), rg_count);
     175        4359 :                 memset(count, 0, sizeof(count));
     176        4359 :                 rgp = (struct lgfs2_rgrp_tree *)n;
     177             : 
     178        4359 :                 rg_count++;
     179             :                 /* Compare the bitmaps and report the differences */
     180        4359 :                 update_rgrp(cx, rgp, bl, count);
     181             :         }
     182             :         /* Fix up superblock info based on this - don't think there's
     183             :          * anything to do here... */
     184             : 
     185          56 :         return FSCK_OK;
     186             : }

Generated by: LCOV version 1.14