LCOV - code coverage report
Current view: top level - libgfs2 - super.c (source / functions) Hit Total Coverage
Test: gfs2-utils.info Lines: 96 109 88.1 %
Date: 2023-10-25 12:04:14 Functions: 5 5 100.0 %

          Line data    Source code
       1             : #include "clusterautoconfig.h"
       2             : 
       3             : #include <unistd.h>
       4             : #include <inttypes.h>
       5             : #include <stdio.h>
       6             : #include <stdint.h>
       7             : #include <stdlib.h>
       8             : #include <string.h>
       9             : #include <errno.h>
      10             : #include <fcntl.h>
      11             : 
      12             : #include "libgfs2.h"
      13             : #include "osi_list.h"
      14             : 
      15             : /**
      16             :  * lgfs2_check_sb - Check superblock
      17             :  * @sb: The superblock
      18             :  *
      19             :  * Checks the version code of the FS is one that we understand how to
      20             :  * read and that the sizes of the various on-disk structures have not
      21             :  * changed.
      22             :  *
      23             :  * Returns: -1 on failure, 2 if this is gfs2
      24             :  */
      25          82 : int lgfs2_check_sb(void *sbp)
      26             : {
      27          82 :         struct gfs2_sb *sb = sbp;
      28             : 
      29         164 :         if (be32_to_cpu(sb->sb_header.mh_magic) != GFS2_MAGIC ||
      30          82 :             be32_to_cpu(sb->sb_header.mh_type) != GFS2_METATYPE_SB) {
      31           0 :                 errno = EIO;
      32           0 :                 return -1;
      33             :         }
      34             :         /* It's gfs2. Check format number is in a sensible range. */
      35         164 :         if (be32_to_cpu(sb->sb_fs_format) < LGFS2_FS_FORMAT_MIN ||
      36          82 :             be32_to_cpu(sb->sb_fs_format) > 1899) {
      37           1 :                 errno = EINVAL;
      38           1 :                 return -1;
      39             :         }
      40          81 :         return 2;
      41             : }
      42             : 
      43             : 
      44             : /*
      45             :  * lgfs2_read_sb: read the super block from disk
      46             :  * sdp: in-core super block
      47             :  *
      48             :  * This function reads in the super block from disk and
      49             :  * initializes various constants maintained in the super
      50             :  * block
      51             :  *
      52             :  * Returns: 0 on success, -1 on failure
      53             :  */
      54          77 : int lgfs2_read_sb(struct lgfs2_sbd *sdp)
      55             : {
      56             :         struct lgfs2_buffer_head *bh;
      57          77 :         uint64_t space = 0;
      58             :         unsigned int x;
      59             :         int ret;
      60             : 
      61          77 :         bh = lgfs2_bread(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift);
      62             : 
      63          77 :         ret = lgfs2_check_sb(bh->b_data);
      64          77 :         if (ret < 0) {
      65           1 :                 lgfs2_brelse(bh);
      66           1 :                 return ret;
      67             :         }
      68          76 :         lgfs2_sb_in(sdp, bh->b_data);
      69          76 :         lgfs2_brelse(bh);
      70          76 :         sdp->sd_fsb2bb_shift = sdp->sd_bsize_shift - GFS2_BASIC_BLOCK_SHIFT;
      71          76 :         if (sdp->sd_bsize < 512 || sdp->sd_bsize != (sdp->sd_bsize & -sdp->sd_bsize)) {
      72           5 :                 return -1;
      73             :         }
      74          71 :         sdp->sd_diptrs = (sdp->sd_bsize - sizeof(struct gfs2_dinode)) / sizeof(uint64_t);
      75          71 :         sdp->sd_inptrs = (sdp->sd_bsize - sizeof(struct gfs2_meta_header)) / sizeof(uint64_t);
      76          71 :         sdp->sd_jbsize = sdp->sd_bsize - sizeof(struct gfs2_meta_header);
      77          71 :         sdp->sd_hash_bsize = sdp->sd_bsize / 2;
      78          71 :         sdp->sd_hash_bsize_shift = sdp->sd_bsize_shift - 1;
      79          71 :         sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(uint64_t);
      80          71 :         sdp->sd_heightsize[0] = sdp->sd_bsize - sizeof(struct gfs2_dinode);
      81          71 :         sdp->sd_heightsize[1] = sdp->sd_bsize * sdp->sd_diptrs;
      82         380 :         for (x = 2; x < GFS2_MAX_META_HEIGHT; x++){
      83         375 :                 space = sdp->sd_heightsize[x - 1] * sdp->sd_inptrs;
      84             :                 /* FIXME: Do we really need this first check?? */
      85         375 :                 if (space / sdp->sd_inptrs != sdp->sd_heightsize[x - 1] ||
      86         309 :                     space % sdp->sd_inptrs != 0)
      87             :                         break;
      88         309 :                 sdp->sd_heightsize[x] = space;
      89             :         }
      90          71 :         if (x > GFS2_MAX_META_HEIGHT){
      91           0 :                 errno = E2BIG;
      92           0 :                 return -1;
      93             :         }
      94             : 
      95          71 :         sdp->sd_jheightsize[0] = sdp->sd_bsize - sizeof(struct gfs2_dinode);
      96          71 :         sdp->sd_jheightsize[1] = sdp->sd_jbsize * sdp->sd_diptrs;
      97          71 :         for (x = 2; ; x++){
      98         380 :                 space = sdp->sd_jheightsize[x - 1] * sdp->sd_inptrs;
      99         380 :                 if (space / sdp->sd_inptrs != sdp->sd_jheightsize[x - 1] ||
     100         309 :                         space % sdp->sd_inptrs != 0)
     101             :                         break;
     102         309 :                 sdp->sd_jheightsize[x] = space;
     103             :         }
     104          71 :         sdp->sd_max_jheight = x;
     105          71 :         if(sdp->sd_max_jheight > GFS2_MAX_META_HEIGHT) {
     106           0 :                 errno = E2BIG;
     107           0 :                 return -1;
     108             :         }
     109          71 :         sdp->fssize = lseek(sdp->device_fd, 0, SEEK_END) / sdp->sd_bsize;
     110          71 :         sdp->sd_blocks_per_bitmap = (sdp->sd_bsize - sizeof(struct gfs2_meta_header))
     111             :                                      * GFS2_NBBY;
     112             : 
     113          71 :         return 0;
     114             : }
     115             : 
     116             : /* rgd_seems_ok - check some general things about the rindex entry
     117             :  *
     118             :  * If rg lengths are not consistent, it's not sane (or it's converted from
     119             :  * gfs1). The first RG will be a different length due to space reserved for
     120             :  * the superblock, so we can't detect this until we check rgrp 3, when we
     121             :  * can compare the distance between rgrp 1 and rgrp 2.
     122             :  *
     123             :  * Returns: 1 if the rgd seems relatively sane
     124             :  */
     125     2123044 : static int rgd_seems_ok(struct lgfs2_sbd *sdp, struct lgfs2_rgrp_tree *rgd)
     126             : {
     127             :         uint32_t most_bitmaps_possible;
     128             : 
     129             :         /* rg length must be at least 1 */
     130     2123044 :         if (rgd->rt_length == 0)
     131           3 :                 return 0;
     132             : 
     133             :         /* A max rgrp, 2GB, divided into blocksize, divided by blocks/byte
     134             :            represented in the bitmap, NBBY. Rough approximation only, due to
     135             :            metadata headers. I'm doing the math this way to avoid overflow. */
     136     2123041 :         most_bitmaps_possible = (LGFS2_MAX_RGSIZE * 1024 * 256) / sdp->sd_bsize;
     137     2123041 :         if (rgd->rt_length > most_bitmaps_possible)
     138           0 :                 return 0;
     139             : 
     140     2123041 :         if (rgd->rt_data0 != rgd->rt_addr + rgd->rt_length)
     141           0 :                 return 0;
     142             : 
     143     2123041 :         if (rgd->rt_bitbytes != rgd->rt_data / GFS2_NBBY)
     144           0 :                 return 0;
     145             : 
     146     2123041 :         return 1;
     147             : }
     148             : 
     149             : /* good_on_disk - check if the rindex points to what looks like an rgrp on disk
     150             :  *
     151             :  * This is only called when the rindex pointers aren't spaced evenly, which
     152             :  * isn't often. The rindex is pointing to an unexpected location, so we
     153             :  * check if the block it is pointing to is really an rgrp. If so, we count the
     154             :  * rindex entry as "sane" (after all, it did pass the previous checks above.)
     155             :  * If not, we count it as not sane, and therefore, the whole rindex is not to
     156             :  * be trusted by fsck.gfs2.
     157             :  */
     158        4533 : static int good_on_disk(struct lgfs2_sbd *sdp, struct lgfs2_rgrp_tree *rgd)
     159             : {
     160             :         struct lgfs2_buffer_head *bh;
     161             :         int is_rgrp;
     162             : 
     163        4533 :         bh = lgfs2_bread(sdp, rgd->rt_addr);
     164        4533 :         is_rgrp = (lgfs2_check_meta(bh->b_data, GFS2_METATYPE_RG) == 0);
     165        4533 :         lgfs2_brelse(bh);
     166        4533 :         return is_rgrp;
     167             : }
     168             : 
     169             : /**
     170             :  * lgfs2_rindex_read - read in the rg index file
     171             :  * @sdp: the incore superblock pointer
     172             :  * @rgcount: return count of the rgs.
     173             :  * @ok: return whether rindex is consistent
     174             :  *
     175             :  * Returns: 0 on success, -1 on failure
     176             :  */
     177        4543 : int lgfs2_rindex_read(struct lgfs2_sbd *sdp, uint64_t *rgcount, int *ok)
     178             : {
     179             :         unsigned int rg;
     180             :         int error;
     181        4543 :         struct lgfs2_rgrp_tree *rgd = NULL, *prev_rgd = NULL;
     182        4543 :         uint64_t prev_length = 0;
     183             : 
     184        4543 :         *ok = 1;
     185        4543 :         *rgcount = 0;
     186        4543 :         if (sdp->md.riinode->i_size % sizeof(struct gfs2_rindex))
     187           0 :                 *ok = 0; /* rindex file size must be a multiple of 96 */
     188     2132133 :         for (rg = 0; ; rg++) {
     189             :                 struct gfs2_rindex ri;
     190             :                 uint64_t addr;
     191             : 
     192     2132133 :                 error = lgfs2_readi(sdp->md.riinode, &ri,
     193             :                                    rg * sizeof(struct gfs2_rindex),
     194             :                                    sizeof(struct gfs2_rindex));
     195     2132133 :                 if (!error)
     196        4543 :                         break;
     197     2127590 :                 if (error != sizeof(struct gfs2_rindex))
     198           0 :                         return -1;
     199             : 
     200     2127590 :                 addr = be64_to_cpu(ri.ri_addr);
     201     2127590 :                 if (lgfs2_check_range(sdp, addr) != 0) {
     202           6 :                         *ok = 0;
     203           6 :                         if (prev_rgd == NULL)
     204           3 :                                 continue;
     205           3 :                         addr = prev_rgd->rt_data0 + prev_rgd->rt_data;
     206             :                 }
     207     2127587 :                 rgd = lgfs2_rgrp_insert(&sdp->rgtree, addr);
     208     2127587 :                 rgd->rt_length = be32_to_cpu(ri.ri_length);
     209     2127587 :                 rgd->rt_data0 = be64_to_cpu(ri.ri_data0);
     210     2127587 :                 rgd->rt_data = be32_to_cpu(ri.ri_data);
     211     2127587 :                 rgd->rt_bitbytes = be32_to_cpu(ri.ri_bitbytes);
     212     2127587 :                 if (prev_rgd) {
     213     2123044 :                         if (prev_rgd->rt_addr >= rgd->rt_addr)
     214           0 :                                 *ok = 0;
     215     2123044 :                         else if (!rgd_seems_ok(sdp, rgd))
     216           3 :                                 *ok = 0;
     217     2123041 :                         else if (*ok && rg > 2 && prev_length &&
     218     2113494 :                             prev_length != rgd->rt_addr - prev_rgd->rt_addr)
     219        4533 :                                 *ok = good_on_disk(sdp, rgd);
     220     2123044 :                         prev_length = rgd->rt_addr - prev_rgd->rt_addr;
     221             :                 }
     222             : 
     223     2127587 :                 if(lgfs2_compute_bitstructs(sdp->sd_bsize, rgd))
     224           3 :                         *ok = 0;
     225             : 
     226     2127587 :                 (*rgcount)++;
     227     2127587 :                 prev_rgd = rgd;
     228             :         }
     229        4543 :         if (*rgcount == 0)
     230           0 :                 return -1;
     231        4543 :         return 0;
     232             : }

Generated by: LCOV version 1.14