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

Generated by: LCOV version 1.14