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 71 : sdp->qcsize = LGFS2_DEFAULT_QCSIZE; 113 : 114 71 : return 0; 115 : } 116 : 117 : /* rgd_seems_ok - check some general things about the rindex entry 118 : * 119 : * If rg lengths are not consistent, it's not sane (or it's converted from 120 : * gfs1). The first RG will be a different length due to space reserved for 121 : * the superblock, so we can't detect this until we check rgrp 3, when we 122 : * can compare the distance between rgrp 1 and rgrp 2. 123 : * 124 : * Returns: 1 if the rgd seems relatively sane 125 : */ 126 2123044 : static int rgd_seems_ok(struct lgfs2_sbd *sdp, struct lgfs2_rgrp_tree *rgd) 127 : { 128 : uint32_t most_bitmaps_possible; 129 : 130 : /* rg length must be at least 1 */ 131 2123044 : if (rgd->rt_length == 0) 132 3 : return 0; 133 : 134 : /* A max rgrp, 2GB, divided into blocksize, divided by blocks/byte 135 : represented in the bitmap, NBBY. Rough approximation only, due to 136 : metadata headers. I'm doing the math this way to avoid overflow. */ 137 2123041 : most_bitmaps_possible = (LGFS2_MAX_RGSIZE * 1024 * 256) / sdp->sd_bsize; 138 2123041 : if (rgd->rt_length > most_bitmaps_possible) 139 0 : return 0; 140 : 141 2123041 : if (rgd->rt_data0 != rgd->rt_addr + rgd->rt_length) 142 0 : return 0; 143 : 144 2123041 : if (rgd->rt_bitbytes != rgd->rt_data / GFS2_NBBY) 145 0 : return 0; 146 : 147 2123041 : return 1; 148 : } 149 : 150 : /* good_on_disk - check if the rindex points to what looks like an rgrp on disk 151 : * 152 : * This is only called when the rindex pointers aren't spaced evenly, which 153 : * isn't often. The rindex is pointing to an unexpected location, so we 154 : * check if the block it is pointing to is really an rgrp. If so, we count the 155 : * rindex entry as "sane" (after all, it did pass the previous checks above.) 156 : * If not, we count it as not sane, and therefore, the whole rindex is not to 157 : * be trusted by fsck.gfs2. 158 : */ 159 4533 : static int good_on_disk(struct lgfs2_sbd *sdp, struct lgfs2_rgrp_tree *rgd) 160 : { 161 : struct lgfs2_buffer_head *bh; 162 : int is_rgrp; 163 : 164 4533 : bh = lgfs2_bread(sdp, rgd->rt_addr); 165 4533 : is_rgrp = (lgfs2_check_meta(bh->b_data, GFS2_METATYPE_RG) == 0); 166 4533 : lgfs2_brelse(bh); 167 4533 : return is_rgrp; 168 : } 169 : 170 : /** 171 : * lgfs2_rindex_read - read in the rg index file 172 : * @sdp: the incore superblock pointer 173 : * @rgcount: return count of the rgs. 174 : * @ok: return whether rindex is consistent 175 : * 176 : * Returns: 0 on success, -1 on failure 177 : */ 178 4543 : int lgfs2_rindex_read(struct lgfs2_sbd *sdp, uint64_t *rgcount, int *ok) 179 : { 180 : unsigned int rg; 181 : int error; 182 4543 : struct lgfs2_rgrp_tree *rgd = NULL, *prev_rgd = NULL; 183 4543 : uint64_t prev_length = 0; 184 : 185 4543 : *ok = 1; 186 4543 : *rgcount = 0; 187 4543 : if (sdp->md.riinode->i_size % sizeof(struct gfs2_rindex)) 188 0 : *ok = 0; /* rindex file size must be a multiple of 96 */ 189 2132133 : for (rg = 0; ; rg++) { 190 : struct gfs2_rindex ri; 191 : uint64_t addr; 192 : 193 2132133 : error = lgfs2_readi(sdp->md.riinode, &ri, 194 : rg * sizeof(struct gfs2_rindex), 195 : sizeof(struct gfs2_rindex)); 196 2132133 : if (!error) 197 4543 : break; 198 2127590 : if (error != sizeof(struct gfs2_rindex)) 199 0 : return -1; 200 : 201 2127590 : addr = be64_to_cpu(ri.ri_addr); 202 2127590 : if (lgfs2_check_range(sdp, addr) != 0) { 203 6 : *ok = 0; 204 6 : if (prev_rgd == NULL) 205 3 : continue; 206 3 : addr = prev_rgd->rt_data0 + prev_rgd->rt_data; 207 : } 208 2127587 : rgd = lgfs2_rgrp_insert(&sdp->rgtree, addr); 209 2127587 : rgd->rt_length = be32_to_cpu(ri.ri_length); 210 2127587 : rgd->rt_data0 = be64_to_cpu(ri.ri_data0); 211 2127587 : rgd->rt_data = be32_to_cpu(ri.ri_data); 212 2127587 : rgd->rt_bitbytes = be32_to_cpu(ri.ri_bitbytes); 213 2127587 : if (prev_rgd) { 214 2123044 : if (prev_rgd->rt_addr >= rgd->rt_addr) 215 0 : *ok = 0; 216 2123044 : else if (!rgd_seems_ok(sdp, rgd)) 217 3 : *ok = 0; 218 2123041 : else if (*ok && rg > 2 && prev_length && 219 2113494 : prev_length != rgd->rt_addr - prev_rgd->rt_addr) 220 4533 : *ok = good_on_disk(sdp, rgd); 221 2123044 : prev_length = rgd->rt_addr - prev_rgd->rt_addr; 222 : } 223 : 224 2127587 : if(lgfs2_compute_bitstructs(sdp->sd_bsize, rgd)) 225 3 : *ok = 0; 226 : 227 2127587 : (*rgcount)++; 228 2127587 : prev_rgd = rgd; 229 : } 230 4543 : if (*rgcount == 0) 231 0 : return -1; 232 4543 : return 0; 233 : }