LCOV - code coverage report
Current view: top level - fsck - pass5.c (source / functions) Coverage Total Hit
Test: gfs2-utils.info Lines: 77.1 % 83 64
Test Date: 2024-03-07 16:24:06 Functions: 100.0 % 3 3

            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       132866 : 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       132866 :         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       132866 :         byte = (unsigned char *) buffer;
      31       132866 :         bit = 0;
      32       132866 :         end = (unsigned char *) buffer + buflen;
      33              : 
      34    482876546 :         while (byte < end) {
      35    482743680 :                 rg_status = ((*byte >> bit) & GFS2_BIT_MASK);
      36    482743680 :                 block = rg_data + *rg_block;
      37    482743680 :                 display_progress(block);
      38    482743680 :                 if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
      39            0 :                         return 0;
      40              : 
      41    482743680 :                 q = block_type(bl, block);
      42    482743680 :                 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    482743680 :                 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    482743680 :                 } 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    482743680 :                 (*rg_block)++;
      88    482743680 :                 bit += GFS2_BIT_SIZE;
      89    482743680 :                 if (bit >= 8){
      90    120685920 :                         bit = 0;
      91    120685920 :                         byte++;
      92              :                 }
      93              :         }
      94              : 
      95       132866 :         return 0;
      96              : }
      97              : 
      98         4440 : 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         4440 :         uint64_t rg_block = 0;
     104         4440 :         int update = 0;
     105              : 
     106       137306 :         for(i = 0; i < rgp->rt_length; i++) {
     107       132866 :                 bits = &rgp->rt_bits[i];
     108              : 
     109              :                 /* update the bitmaps */
     110       132866 :                 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       132866 :                 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         4440 :         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         4440 :         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         4440 :         if (rgp->rt_data != count[GFS2_BLKST_FREE] +
     133         4440 :                             count[GFS2_BLKST_USED] +
     134         4440 :                             count[GFS2_BLKST_UNLINKED] +
     135         4440 :                             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         4440 :         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           57 : int pass5(struct fsck_cx *cx, struct bmap *bl)
     162              : {
     163           57 :         struct lgfs2_sbd *sdp = cx->sdp;
     164           57 :         struct osi_node *n, *next = NULL;
     165           57 :         struct lgfs2_rgrp_tree *rgp = NULL;
     166              :         uint32_t count[5]; /* we need 5 because of GFS1 usedmeta */
     167           57 :         uint64_t rg_count = 0;
     168              : 
     169              :         /* Reconcile RG bitmaps with fsck bitmap */
     170         4497 :         for (n = osi_first(&sdp->rgtree); n; n = next) {
     171         4440 :                 next = osi_next(n);
     172         4440 :                 if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
     173            0 :                         return FSCK_OK;
     174         4440 :                 log_info(_("Verifying resource group %"PRIu64"\n"), rg_count);
     175         4440 :                 memset(count, 0, sizeof(count));
     176         4440 :                 rgp = (struct lgfs2_rgrp_tree *)n;
     177              : 
     178         4440 :                 rg_count++;
     179              :                 /* Compare the bitmaps and report the differences */
     180         4440 :                 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           57 :         return FSCK_OK;
     186              : }
        

Generated by: LCOV version 2.0-1