LCOV - code coverage report
Current view: top level - libgfs2 - structures.c (source / functions) Hit Total Coverage
Test: gfs2-utils.info Lines: 247 291 84.9 %
Date: 2023-09-27 13:48:55 Functions: 21 21 100.0 %

          Line data    Source code
       1             : #include "clusterautoconfig.h"
       2             : 
       3             : #include <stdio.h>
       4             : #include <stdlib.h>
       5             : #include <string.h>
       6             : #include <stdint.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 <sys/time.h>
      14             : #include <uuid.h>
      15             : 
      16             : #include "libgfs2.h"
      17             : #include "crc32c.h"
      18             : 
      19          70 : int lgfs2_build_master(struct lgfs2_sbd *sdp)
      20             : {
      21             :         struct lgfs2_inum inum;
      22             :         uint64_t bn;
      23          70 :         struct lgfs2_buffer_head *bh = NULL;
      24          70 :         int err = lgfs2_dinode_alloc(sdp, 1, &bn);
      25             : 
      26          70 :         if (err != 0)
      27           0 :                 return -1;
      28             : 
      29          70 :         inum.in_formal_ino = sdp->md.next_inum++;
      30          70 :         inum.in_addr = bn;
      31             : 
      32          70 :         err = lgfs2_init_dinode(sdp, &bh, &inum, S_IFDIR | 0755, GFS2_DIF_SYSTEM, &inum);
      33          70 :         if (err != 0)
      34           0 :                 return -1;
      35             : 
      36          70 :         sdp->master_dir = lgfs2_inode_get(sdp, bh);
      37          70 :         if (sdp->master_dir == NULL)
      38           0 :                 return -1;
      39             : 
      40          70 :         sdp->master_dir->bh_owned = 1;
      41          70 :         return 0;
      42             : }
      43             : 
      44         109 : int lgfs2_sb_write(const struct lgfs2_sbd *sdp, int fd)
      45             : {
      46         109 :         int i, err = -1;
      47             :         struct iovec *iov;
      48         109 :         const size_t sb_addr = GFS2_SB_ADDR * GFS2_BASIC_BLOCK / sdp->sd_bsize;
      49         109 :         const size_t len = sb_addr + 1;
      50             : 
      51             :         /* We only need 2 blocks: one for zeroing and a second for the superblock */
      52         109 :         char *buf = calloc(2, sdp->sd_bsize);
      53         109 :         if (buf == NULL)
      54           0 :                 return -1;
      55             : 
      56         109 :         iov = malloc(len * sizeof(*iov));
      57         109 :         if (iov == NULL)
      58           0 :                 goto out_buf;
      59             : 
      60        2906 :         for (i = 0; i < len; i++) {
      61        2797 :                 iov[i].iov_base = buf;
      62        2797 :                 iov[i].iov_len = sdp->sd_bsize;
      63             :         }
      64             : 
      65         109 :         lgfs2_sb_out(sdp, buf + sdp->sd_bsize);
      66         109 :         iov[sb_addr].iov_base = buf + sdp->sd_bsize;
      67             : 
      68         109 :         if (pwritev(fd, iov, len, 0) < (len * sdp->sd_bsize))
      69           0 :                 goto out_iov;
      70             : 
      71         109 :         err = 0;
      72         109 : out_iov:
      73         109 :         free(iov);
      74         109 : out_buf:
      75         109 :         free(buf);
      76         109 :         return err;
      77             : }
      78             : 
      79     4310964 : uint32_t lgfs2_log_header_hash(char *buf)
      80             : {
      81             :         /* lh_hash only CRCs the fields in the old lh, which ends where lh_crc is now */
      82     4310964 :         const off_t v1_end = offsetof(struct gfs2_log_header, lh_hash) + 4;
      83             : 
      84     4310964 :         return lgfs2_disk_hash(buf, v1_end);
      85             : }
      86             : 
      87     4310964 : uint32_t lgfs2_log_header_crc(char *buf, unsigned bsize)
      88             : {
      89             :         /* lh_crc CRCs the rest of the block starting after lh_crc */
      90     4310964 :         const off_t v1_end = offsetof(struct gfs2_log_header, lh_hash) + 4;
      91     4310964 :         const unsigned char *lb = (const unsigned char *)buf;
      92             : 
      93     4310964 :         return crc32c(~0, lb + v1_end + 4, bsize - v1_end - 4);
      94             : }
      95             : 
      96             : /**
      97             :  * Intialise and write the data blocks for a new journal as a contiguous
      98             :  * extent. The indirect blocks pointing to these data blocks should have been
      99             :  * written separately using lgfs2_write_filemeta() and the extent should have
     100             :  * been allocated using lgfs2_file_alloc().
     101             :  * ip: The journal's inode
     102             :  * Returns 0 on success or -1 with errno set on error.
     103             :  */
     104          77 : int lgfs2_write_journal_data(struct lgfs2_inode *ip)
     105             : {
     106          77 :         struct lgfs2_sbd *sdp = ip->i_sbd;
     107          77 :         unsigned blocks = (ip->i_size + sdp->sd_bsize - 1) / sdp->sd_bsize;
     108          77 :         uint64_t jext0 = ip->i_num.in_addr + ip->i_blocks - blocks;
     109             :         /* Not a security sensitive use of random() */
     110             :         /* coverity[dont_call:SUPPRESS] */
     111          77 :         uint64_t seq = blocks * (random() / (RAND_MAX + 1.0));
     112             :         struct gfs2_log_header *lh;
     113          77 :         uint64_t jblk = jext0;
     114             :         char *buf;
     115             : 
     116          77 :         buf = calloc(1, sdp->sd_bsize);
     117          77 :         if (buf == NULL)
     118           0 :                 return -1;
     119             : 
     120          77 :         lh = (void *)buf;
     121          77 :         lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
     122          77 :         lh->lh_header.mh_type = cpu_to_be32(GFS2_METATYPE_LH);
     123          77 :         lh->lh_header.mh_format = cpu_to_be32(GFS2_FORMAT_LH);
     124          77 :         lh->lh_flags = cpu_to_be32(GFS2_LOG_HEAD_UNMOUNT | GFS2_LOG_HEAD_USERSPACE);
     125          77 :         lh->lh_jinode = cpu_to_be64(ip->i_num.in_addr);
     126             : 
     127          77 :         crc32c_optimization_init();
     128             :         do {
     129             :                 uint32_t hash;
     130             : 
     131     2383872 :                 lh->lh_sequence = cpu_to_be64(seq);
     132     2383872 :                 lh->lh_blkno = cpu_to_be32(jblk - jext0);
     133     2383872 :                 hash = lgfs2_log_header_hash(buf);
     134     2383872 :                 lh->lh_hash = cpu_to_be32(hash);
     135     2383872 :                 lh->lh_addr = cpu_to_be64(jblk);
     136     2383872 :                 hash = lgfs2_log_header_crc(buf, sdp->sd_bsize);
     137     2383872 :                 lh->lh_crc = cpu_to_be32(hash);
     138             : 
     139     2383872 :                 if (pwrite(sdp->device_fd, buf, sdp->sd_bsize, jblk * sdp->sd_bsize) != sdp->sd_bsize) {
     140           0 :                         free(buf);
     141           0 :                         return -1;
     142             :                 }
     143             : 
     144     2383872 :                 lh->lh_crc = 0;
     145     2383872 :                 lh->lh_hash = 0;
     146             : 
     147     2383872 :                 if (++seq == blocks)
     148          77 :                         seq = 0;
     149             : 
     150     2383872 :         } while (++jblk < jext0 + blocks);
     151             : 
     152          77 :         free(buf);
     153          77 :         return 0;
     154             : }
     155             : 
     156      118272 : static struct lgfs2_buffer_head *lgfs2_get_file_buf(struct lgfs2_inode *ip, uint64_t lbn, int prealloc)
     157             : {
     158      118272 :         struct lgfs2_sbd *sdp = ip->i_sbd;
     159             :         uint64_t dbn;
     160      118272 :         int new = 1;
     161             : 
     162      118272 :         if (ip->i_height == 0 && lgfs2_unstuff_dinode(ip))
     163           0 :                 return NULL;
     164             : 
     165      118272 :         if (lgfs2_block_map(ip, lbn, &new, &dbn, NULL, prealloc))
     166           0 :                 return NULL;
     167      118272 :         if (!dbn)
     168           0 :                 return NULL;
     169             : 
     170      118272 :         if (!prealloc && new &&
     171       85504 :             ip->i_size < (lbn + 1) << sdp->sd_bsize_shift) {
     172       85504 :                 lgfs2_bmodified(ip->i_bh);
     173       85504 :                 ip->i_size = (lbn + 1) << sdp->sd_bsize_shift;
     174             :         }
     175      118272 :         if (dbn == ip->i_num.in_addr)
     176           0 :                 return ip->i_bh;
     177             :         else
     178      118272 :                 return lgfs2_bread(sdp, dbn);
     179             : }
     180             : 
     181           1 : int lgfs2_write_journal(struct lgfs2_inode *jnl, unsigned bsize, unsigned int blocks)
     182             : {
     183             :         struct gfs2_log_header *lh;
     184             :         uint32_t x;
     185             :         /* Not a security sensitive use of random() */
     186             :         /* coverity[dont_call:SUPPRESS] */
     187           1 :         uint64_t seq = blocks * (random() / (RAND_MAX + 1.0));
     188             :         uint32_t hash;
     189             :         unsigned int height;
     190             : 
     191             :         /* Build the height up so our journal blocks will be contiguous and */
     192             :         /* not broken up by indirect block pages.                           */
     193           1 :         height = lgfs2_calc_tree_height(jnl, (blocks + 1) * bsize);
     194           1 :         if (lgfs2_build_height(jnl, height))
     195           0 :                 return -1;
     196             : 
     197       32769 :         for (x = 0; x < blocks; x++) {
     198       32768 :                 struct lgfs2_buffer_head *bh = lgfs2_get_file_buf(jnl, x, 1);
     199       32768 :                 if (!bh)
     200           0 :                         return -1;
     201       32768 :                 lgfs2_bmodified(bh);
     202       32768 :                 lgfs2_brelse(bh);
     203             :         }
     204           1 :         crc32c_optimization_init();
     205       32769 :         for (x = 0; x < blocks; x++) {
     206       32768 :                 struct lgfs2_buffer_head *bh = lgfs2_get_file_buf(jnl, x, 0);
     207       32768 :                 if (!bh)
     208           0 :                         return -1;
     209             : 
     210       32768 :                 memset(bh->b_data, 0, bsize);
     211       32768 :                 lh = (void *)bh->b_data;
     212       32768 :                 lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
     213       32768 :                 lh->lh_header.mh_type = cpu_to_be32(GFS2_METATYPE_LH);
     214       32768 :                 lh->lh_header.mh_format = cpu_to_be32(GFS2_FORMAT_LH);
     215       32768 :                 lh->lh_flags = cpu_to_be32(GFS2_LOG_HEAD_UNMOUNT | GFS2_LOG_HEAD_USERSPACE);
     216       32768 :                 lh->lh_jinode = cpu_to_be64(jnl->i_num.in_addr);
     217       32768 :                 lh->lh_sequence = cpu_to_be64(seq);
     218       32768 :                 lh->lh_blkno = cpu_to_be32(x);
     219             : 
     220       32768 :                 hash = lgfs2_log_header_hash(bh->b_data);
     221       32768 :                 lh->lh_hash = cpu_to_be32(hash);
     222       32768 :                 lh->lh_addr = cpu_to_be64(bh->b_blocknr);
     223             : 
     224       32768 :                 hash = lgfs2_log_header_crc(bh->b_data, bsize);
     225       32768 :                 lh->lh_crc = cpu_to_be32(hash);
     226       32768 :                 lgfs2_bmodified(bh);
     227       32768 :                 lgfs2_brelse(bh);
     228             : 
     229       32768 :                 if (++seq == blocks)
     230           1 :                         seq = 0;
     231             :         }
     232             : 
     233           1 :         return 0;
     234             : }
     235             : 
     236           1 : int lgfs2_build_journal(struct lgfs2_sbd *sdp, int j, struct lgfs2_inode *jindex)
     237             : {
     238             :         char name[256];
     239             :         int ret;
     240             : 
     241           1 :         sprintf(name, "journal%u", j);
     242           1 :         sdp->md.journal[j] = lgfs2_createi(jindex, name, S_IFREG | 0600,
     243             :                                            GFS2_DIF_SYSTEM);
     244           1 :         if (sdp->md.journal[j] == NULL) {
     245           0 :                 return errno;
     246             :         }
     247           1 :         ret = lgfs2_write_journal(sdp->md.journal[j], sdp->sd_bsize,
     248           1 :                                   sdp->jsize << 20 >> sdp->sd_bsize_shift);
     249           1 :         return ret;
     250             : }
     251             : 
     252             : /**
     253             :  * Write a jindex file given a list of journal inums.
     254             :  * master: Inode of the master directory
     255             :  * jnls: List of inum structures relating to previously created journals.
     256             :  * nmemb: The number of entries in the list (number of journals).
     257             :  * Returns 0 on success or non-zero on error with errno set.
     258             :  */
     259          70 : struct lgfs2_inode *lgfs2_build_jindex(struct lgfs2_inode *master, struct lgfs2_inum *jnls, size_t nmemb)
     260             : {
     261             :         char fname[GFS2_FNAMESIZE + 1];
     262             :         struct lgfs2_inode *jindex;
     263             : 
     264          70 :         if (nmemb == 0 || jnls == NULL) {
     265           0 :                 errno = EINVAL;
     266           0 :                 return NULL;
     267             :         }
     268          70 :         jindex = lgfs2_createi(master, "jindex", S_IFDIR | 0700, GFS2_DIF_SYSTEM);
     269          70 :         if (jindex == NULL)
     270           0 :                 return NULL;
     271             : 
     272          70 :         fname[GFS2_FNAMESIZE] = '\0';
     273             : 
     274         147 :         for (unsigned j = 0; j < nmemb; j++) {
     275             :                 int ret;
     276             : 
     277          77 :                 snprintf(fname, GFS2_FNAMESIZE, "journal%u", j);
     278          77 :                 ret = lgfs2_dir_add(jindex, fname, strlen(fname), &jnls[j], IF2DT(S_IFREG | 0600));
     279          77 :                 if (ret) {
     280           0 :                         lgfs2_inode_put(&jindex);
     281           0 :                         return NULL;
     282             :                 }
     283             :         }
     284          70 :         return jindex;
     285             : }
     286             : 
     287          77 : struct lgfs2_inode *lgfs2_build_inum_range(struct lgfs2_inode *per_node, unsigned int j)
     288             : {
     289             :         char name[256];
     290             :         struct lgfs2_inode *ip;
     291             : 
     292          77 :         sprintf(name, "inum_range%u", j);
     293          77 :         ip = lgfs2_createi(per_node, name, S_IFREG | 0600,
     294             :                      GFS2_DIF_SYSTEM | GFS2_DIF_JDATA);
     295          77 :         if (ip == NULL)
     296           0 :                 return NULL;
     297             : 
     298          77 :         ip->i_size = sizeof(struct gfs2_inum_range);
     299          77 :         lgfs2_dinode_out(ip, ip->i_bh->b_data);
     300          77 :         lgfs2_bmodified(ip->i_bh);
     301          77 :         return ip;
     302             : }
     303             : 
     304          77 : struct lgfs2_inode *lgfs2_build_statfs_change(struct lgfs2_inode *per_node, unsigned int j)
     305             : {
     306             :         char name[256];
     307             :         struct lgfs2_inode *ip;
     308             : 
     309          77 :         sprintf(name, "statfs_change%u", j);
     310          77 :         ip = lgfs2_createi(per_node, name, S_IFREG | 0600,
     311             :                      GFS2_DIF_SYSTEM | GFS2_DIF_JDATA);
     312          77 :         if (ip == NULL)
     313           0 :                 return NULL;
     314             : 
     315          77 :         ip->i_size = sizeof(struct gfs2_statfs_change);
     316          77 :         lgfs2_dinode_out(ip, ip->i_bh->b_data);
     317          77 :         lgfs2_bmodified(ip->i_bh);
     318          77 :         return ip;
     319             : }
     320             : 
     321          77 : struct lgfs2_inode *lgfs2_build_quota_change(struct lgfs2_inode *per_node, unsigned int j)
     322             : {
     323          77 :         struct lgfs2_sbd *sdp = per_node->i_sbd;
     324             :         struct gfs2_meta_header mh;
     325             :         char name[256];
     326             :         struct lgfs2_inode *ip;
     327          77 :         unsigned int blocks = sdp->qcsize << (20 - sdp->sd_bsize_shift);
     328             :         unsigned int x;
     329             :         unsigned int hgt;
     330             :         struct lgfs2_buffer_head *bh;
     331             : 
     332          77 :         memset(&mh, 0, sizeof(struct gfs2_meta_header));
     333          77 :         mh.mh_magic = cpu_to_be32(GFS2_MAGIC);
     334          77 :         mh.mh_type = cpu_to_be32(GFS2_METATYPE_QC);
     335          77 :         mh.mh_format = cpu_to_be32(GFS2_FORMAT_QC);
     336             : 
     337          77 :         sprintf(name, "quota_change%u", j);
     338          77 :         ip = lgfs2_createi(per_node, name, S_IFREG | 0600, GFS2_DIF_SYSTEM);
     339          77 :         if (ip == NULL)
     340           0 :                 return NULL;
     341             : 
     342          77 :         hgt = lgfs2_calc_tree_height(ip, (blocks + 1) * sdp->sd_bsize);
     343          77 :         if (lgfs2_build_height(ip, hgt)) {
     344           0 :                 lgfs2_inode_free(&ip);
     345           0 :                 return NULL;
     346             :         }
     347             : 
     348       52813 :         for (x = 0; x < blocks; x++) {
     349       52736 :                 bh = lgfs2_get_file_buf(ip, x, 0);
     350       52736 :                 if (!bh) {
     351           0 :                         lgfs2_inode_free(&ip);
     352           0 :                         return NULL;
     353             :                 }
     354             : 
     355       52736 :                 memset(bh->b_data, 0, sdp->sd_bsize);
     356       52736 :                 memcpy(bh->b_data, &mh, sizeof(mh));
     357       52736 :                 lgfs2_bmodified(bh);
     358       52736 :                 lgfs2_brelse(bh);
     359             :         }
     360          77 :         return ip;
     361             : }
     362             : 
     363          70 : struct lgfs2_inode *lgfs2_build_inum(struct lgfs2_sbd *sdp)
     364             : {
     365             :         struct lgfs2_inode *ip;
     366             : 
     367          70 :         ip = lgfs2_createi(sdp->master_dir, "inum", S_IFREG | 0600,
     368             :                      GFS2_DIF_SYSTEM | GFS2_DIF_JDATA);
     369          70 :         return ip;
     370             : }
     371             : 
     372          70 : struct lgfs2_inode *lgfs2_build_statfs(struct lgfs2_sbd *sdp)
     373             : {
     374             :         struct lgfs2_inode *ip;
     375             : 
     376          70 :         ip = lgfs2_createi(sdp->master_dir, "statfs", S_IFREG | 0600,
     377             :                      GFS2_DIF_SYSTEM | GFS2_DIF_JDATA);
     378          70 :         return ip;
     379             : }
     380             : 
     381          70 : struct lgfs2_inode *lgfs2_build_rindex(struct lgfs2_sbd *sdp)
     382             : {
     383             :         struct lgfs2_inode *ip;
     384          70 :         struct osi_node *n, *next = NULL;
     385             :         struct lgfs2_rgrp_tree *rl;
     386             :         struct gfs2_rindex ri;
     387             :         int count;
     388             : 
     389          70 :         ip = lgfs2_createi(sdp->master_dir, "rindex", S_IFREG | 0600,
     390             :                      GFS2_DIF_SYSTEM | GFS2_DIF_JDATA);
     391          70 :         if (ip == NULL)
     392           0 :                 return NULL;
     393             : 
     394          70 :         ip->i_payload_format = GFS2_FORMAT_RI;
     395          70 :         lgfs2_bmodified(ip->i_bh);
     396             : 
     397          70 :         memset(&ri, 0, sizeof(struct gfs2_rindex));
     398        6499 :         for (n = osi_first(&sdp->rgtree); n; n = next) {
     399        6429 :                 next = osi_next(n);
     400        6429 :                 rl = (struct lgfs2_rgrp_tree *)n;
     401             : 
     402        6429 :                 lgfs2_rindex_out(rl, &ri);
     403             : 
     404        6429 :                 count = lgfs2_writei(ip, &ri, ip->i_size, sizeof(struct gfs2_rindex));
     405        6429 :                 if (count != sizeof(struct gfs2_rindex)) {
     406           0 :                         lgfs2_inode_free(&ip);
     407           0 :                         return NULL;
     408             :                 }
     409             :         }
     410          70 :         memset(&ri, 0, sizeof(struct gfs2_rindex));
     411          70 :         count = __lgfs2_writei(ip, &ri, ip->i_size, sizeof(struct gfs2_rindex), 0);
     412          70 :         if (count != sizeof(struct gfs2_rindex)) {
     413           0 :                 lgfs2_inode_free(&ip);
     414           0 :                 return NULL;
     415             :         }
     416          70 :         return ip;
     417             : }
     418             : 
     419          70 : struct lgfs2_inode *lgfs2_build_quota(struct lgfs2_sbd *sdp)
     420             : {
     421             :         struct lgfs2_inode *ip;
     422             :         struct gfs2_quota qu;
     423             :         int count;
     424             : 
     425          70 :         ip = lgfs2_createi(sdp->master_dir, "quota", S_IFREG | 0600,
     426             :                      GFS2_DIF_SYSTEM | GFS2_DIF_JDATA);
     427          70 :         if (ip == NULL)
     428           0 :                 return NULL;
     429             : 
     430          70 :         ip->i_payload_format = GFS2_FORMAT_QU;
     431          70 :         lgfs2_bmodified(ip->i_bh);
     432             : 
     433          70 :         memset(&qu, 0, sizeof(struct gfs2_quota));
     434          70 :         qu.qu_value = cpu_to_be64(1);
     435             : 
     436          70 :         count = lgfs2_writei(ip, &qu, ip->i_size, sizeof(struct gfs2_quota));
     437          70 :         if (count != sizeof(struct gfs2_quota)) {
     438           0 :                 lgfs2_inode_free(&ip);
     439           0 :                 return NULL;
     440             :         }
     441          70 :         count = lgfs2_writei(ip, &qu, ip->i_size, sizeof(struct gfs2_quota));
     442          70 :         if (count != sizeof(struct gfs2_quota)) {
     443           0 :                 lgfs2_inode_free(&ip);
     444           0 :                 return NULL;
     445             :         }
     446             : 
     447          70 :         return ip;
     448             : }
     449             : 
     450          70 : int lgfs2_build_root(struct lgfs2_sbd *sdp)
     451             : {
     452             :         struct lgfs2_inum inum;
     453             :         uint64_t bn;
     454          70 :         struct lgfs2_buffer_head *bh = NULL;
     455          70 :         int err = lgfs2_dinode_alloc(sdp, 1, &bn);
     456             : 
     457          70 :         if (err != 0)
     458           0 :                 return -1;
     459             : 
     460          70 :         inum.in_formal_ino = sdp->md.next_inum++;
     461          70 :         inum.in_addr = bn;
     462             : 
     463          70 :         err = lgfs2_init_dinode(sdp, &bh, &inum, S_IFDIR | 0755, 0, &inum);
     464          70 :         if (err != 0)
     465           0 :                 return -1;
     466             : 
     467          70 :         sdp->md.rooti = lgfs2_inode_get(sdp, bh);
     468          70 :         if (sdp->md.rooti == NULL)
     469           0 :                 return -1;
     470             : 
     471          70 :         sdp->md.rooti->bh_owned = 1;
     472          70 :         return 0;
     473             : }
     474             : 
     475          70 : int lgfs2_init_inum(struct lgfs2_sbd *sdp)
     476             : {
     477          70 :         struct lgfs2_inode *ip = sdp->md.inum;
     478             :         __be64 buf;
     479             :         int count;
     480             : 
     481          70 :         buf = cpu_to_be64(sdp->md.next_inum);
     482          70 :         count = lgfs2_writei(ip, &buf, 0, sizeof(uint64_t));
     483          70 :         if (count != sizeof(uint64_t))
     484           0 :                 return -1;
     485             : 
     486          70 :         return 0;
     487             : }
     488             : 
     489          70 : int lgfs2_init_statfs(struct lgfs2_sbd *sdp, struct gfs2_statfs_change *res)
     490             : {
     491          70 :         struct lgfs2_inode *ip = sdp->md.statfs;
     492             :         struct gfs2_statfs_change sc;
     493             :         int count;
     494             : 
     495          70 :         sc.sc_total = cpu_to_be64(sdp->blks_total);
     496          70 :         sc.sc_free = cpu_to_be64(sdp->blks_total - sdp->blks_alloced);
     497          70 :         sc.sc_dinodes = cpu_to_be64(sdp->dinodes_alloced);
     498             : 
     499          70 :         count = lgfs2_writei(ip, &sc, 0, sizeof(sc));
     500          70 :         if (count != sizeof(sc))
     501           0 :                 return -1;
     502             : 
     503          70 :         if (res)
     504          70 :                 *res = sc;
     505          70 :         return 0;
     506             : }
     507             : 
     508    16473741 : int lgfs2_check_meta(const char *buf, int type)
     509             : {
     510    16473741 :         struct gfs2_meta_header *mh = (struct gfs2_meta_header *)buf;
     511    16473741 :         uint32_t check_magic = be32_to_cpu(mh->mh_magic);
     512    16473741 :         uint32_t check_type = be32_to_cpu(mh->mh_type);
     513             : 
     514    16473741 :         if((check_magic != GFS2_MAGIC) || (type && (check_type != type)))
     515     7429035 :                 return -1;
     516     9044706 :         return 0;
     517             : }
     518             : 
     519      177171 : unsigned lgfs2_bm_scan(struct lgfs2_rgrp_tree *rgd, unsigned idx, uint64_t *buf, uint8_t state)
     520             : {
     521      177171 :         struct lgfs2_bitmap *bi = &rgd->rt_bits[idx];
     522      177171 :         unsigned n = 0;
     523      177171 :         uint32_t blk = 0;
     524             : 
     525      177980 :         while(blk < (bi->bi_len * GFS2_NBBY)) {
     526      177913 :                 blk = lgfs2_bitfit((uint8_t *)bi->bi_data + bi->bi_offset,
     527             :                                   bi->bi_len, blk, state);
     528      177913 :                 if (blk == LGFS2_BFITNOENT)
     529      177104 :                         break;
     530         809 :                 buf[n++] = blk + (bi->bi_start * GFS2_NBBY) + rgd->rt_data0;
     531         809 :                 blk++;
     532             :         }
     533      177171 :         return n;
     534             : }

Generated by: LCOV version 1.14