LCOV - code coverage report
Current view: top level - libgfs2 - misc.c (source / functions) Hit Total Coverage
Test: gfs2-utils.info Lines: 28 96 29.2 %
Date: 2023-09-27 13:48:55 Functions: 2 6 33.3 %

          Line data    Source code
       1             : #include "clusterautoconfig.h"
       2             : 
       3             : #include <string.h>
       4             : #include <inttypes.h>
       5             : #include <sys/types.h>
       6             : #include <sys/stat.h>
       7             : #include <fcntl.h>
       8             : #include <unistd.h>
       9             : 
      10             : #include "libgfs2.h"
      11             : 
      12             : #define PAGE_SIZE (4096)
      13             : #define DIV_RU(x, y) (((x) + (y) - 1) / (y))
      14             : 
      15        9230 : int lgfs2_compute_heightsize(unsigned bsize, uint64_t *heightsize,
      16             :         uint32_t *maxheight, uint32_t bsize1, int diptrs, int inptrs)
      17             : {
      18        9230 :         heightsize[0] = bsize - sizeof(struct gfs2_dinode);
      19        9230 :         heightsize[1] = (uint64_t)bsize1 * diptrs;
      20        9230 :         for (*maxheight = 2;; (*maxheight)++) {
      21             :                 uint64_t space, d;
      22             :                 uint32_t m;
      23             : 
      24       46368 :                 space = heightsize[*maxheight - 1] * inptrs;
      25       46368 :                 m = space % inptrs;
      26       46368 :                 d = space / inptrs;
      27             : 
      28       46368 :                 if (d != heightsize[*maxheight - 1] || m)
      29             :                         break;
      30       37138 :                 heightsize[*maxheight] = space;
      31             :         }
      32        9230 :         if (*maxheight > GFS2_MAX_META_HEIGHT) {
      33           0 :                 errno = EINVAL;
      34           0 :                 return -1;
      35             :         }
      36        9230 :         return 0;
      37             : }
      38             : 
      39        4615 : int lgfs2_compute_constants(struct lgfs2_sbd *sdp)
      40             : {
      41        4615 :         sdp->md.next_inum = 1;
      42             : 
      43        4615 :         sdp->sd_bsize_shift = ffs(sdp->sd_bsize) - 1;
      44        4615 :         sdp->sd_fsb2bb_shift = sdp->sd_bsize_shift -
      45             :                 GFS2_BASIC_BLOCK_SHIFT;
      46        4615 :         sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift;
      47        4615 :         sdp->sd_diptrs = (sdp->sd_bsize - sizeof(struct gfs2_dinode)) /
      48             :                 sizeof(uint64_t);
      49        4615 :         sdp->sd_inptrs = (sdp->sd_bsize - sizeof(struct gfs2_meta_header)) /
      50             :                 sizeof(uint64_t);
      51        4615 :         sdp->sd_jbsize = sdp->sd_bsize - sizeof(struct gfs2_meta_header);
      52        4615 :         sdp->sd_hash_bsize = sdp->sd_bsize / 2;
      53        4615 :         sdp->sd_hash_bsize_shift = sdp->sd_bsize_shift - 1;
      54        4615 :         sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(uint64_t);
      55        4615 :         sdp->sd_blocks_per_bitmap = (sdp->sd_bsize - sizeof(struct gfs2_meta_header))
      56             :                                      * GFS2_NBBY;
      57             : 
      58        4615 :         if (lgfs2_compute_heightsize(sdp->sd_bsize, sdp->sd_heightsize, &sdp->sd_max_height,
      59        4615 :                                 sdp->sd_bsize, sdp->sd_diptrs, sdp->sd_inptrs)) {
      60           0 :                 return -1;
      61             :         }
      62        4615 :         if (lgfs2_compute_heightsize(sdp->sd_bsize, sdp->sd_jheightsize, &sdp->sd_max_jheight,
      63        4615 :                                 sdp->sd_jbsize, sdp->sd_diptrs, sdp->sd_inptrs)) {
      64           0 :                 return -1;
      65             :         }
      66        4615 :         return 0;
      67             : }
      68             : 
      69             : /* Returns 0 if fd1 and fd2 refer to the same device/file, 1 otherwise, or -1 on error */
      70           0 : static int fdcmp(int fd1, int fd2)
      71             : {
      72             :         struct stat st1, st2;
      73             : 
      74           0 :         if (fd1 < 0 || fd2 < 0)
      75           0 :                 return -1;
      76           0 :         if ((fstat(fd1, &st1) != 0) || (fstat(fd2, &st2) != 0))
      77           0 :                 return -1;
      78           0 :         if (S_ISBLK(st1.st_mode) && S_ISBLK(st2.st_mode)) {
      79           0 :                 if (st1.st_rdev == st2.st_rdev) {
      80           0 :                         return 0;
      81             :                 }
      82           0 :         } else if ((st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino)) {
      83           0 :                         return 0;
      84             :         }
      85           0 :         return 1;
      86             : }
      87             : 
      88           0 : int lgfs2_open_mnt(const char *path, int dirflags, int *dirfd, int devflags, int *devfd, struct mntent **mnt)
      89             : {
      90           0 :         FILE *fp = setmntent("/proc/mounts", "r");
      91           0 :         if (fp == NULL) {
      92           0 :                 perror("open: /proc/mounts");
      93           0 :                 return 1;
      94             :         }
      95             :         /* Assume path is mount point until we know better. */
      96           0 :         *dirfd = open(path, dirflags);
      97           0 :         if (*dirfd < 0)
      98           0 :                 return 1;
      99             : 
     100           0 :         while ((*mnt = getmntent(fp)) != NULL) {
     101             :                 int fd;
     102           0 :                 if (strcmp((*mnt)->mnt_type, "gfs2") != 0)
     103           0 :                         continue;
     104           0 :                 *devfd = open((*mnt)->mnt_fsname, devflags);
     105             :                 /* Defer checking *devfd until later: whether it's ok to ignore
     106             :                  * the error depends on whether we find the mount point. */
     107             : 
     108           0 :                 if (strcmp(path, (*mnt)->mnt_dir) == 0)
     109           0 :                         break;
     110           0 :                 if (strcmp(path, (*mnt)->mnt_fsname) == 0 || fdcmp(*dirfd, *devfd) == 0) {
     111             :                         /* We have a match but our above assumption was
     112             :                            incorrect and *dirfd is actually the device. */
     113           0 :                         close(*dirfd);
     114           0 :                         *dirfd = open((*mnt)->mnt_dir, dirflags);
     115           0 :                         break;
     116             :                 }
     117             : 
     118           0 :                 fd = open((*mnt)->mnt_dir, dirflags);
     119           0 :                 if (fd >= 0) {
     120           0 :                         int diff = fdcmp(*dirfd, fd);
     121           0 :                         close(fd);
     122           0 :                         if (diff == 0)
     123           0 :                                 break;
     124             :                 }
     125           0 :                 if (*devfd >= 0)
     126           0 :                         close(*devfd);
     127             :         }
     128           0 :         endmntent(fp);
     129           0 :         if (*mnt == NULL) {
     130           0 :                 close(*dirfd);
     131           0 :                 return 0; /* Success. Answer is no. Both fds closed. */
     132             :         }
     133           0 :         if (*dirfd < 0) {
     134           0 :                 close(*devfd);
     135           0 :                 return 1;
     136             :         }
     137           0 :         if (*devfd < 0) {
     138           0 :                 close(*dirfd);
     139           0 :                 return 1;
     140             :         }
     141           0 :         return 0; /* Success. Answer is yes. Both fds open. */
     142             : }
     143             : 
     144           0 : int lgfs2_open_mnt_dev(const char *path, int flags, struct mntent **mnt)
     145             : {
     146           0 :         int dirfd = -1;
     147           0 :         int devfd = -1;
     148           0 :         if (lgfs2_open_mnt(path, O_RDONLY, &dirfd, flags, &devfd, mnt) != 0)
     149           0 :                 return -1;
     150           0 :         if (*mnt != NULL)
     151           0 :                 close(dirfd);
     152           0 :         return devfd;
     153             : }
     154             : 
     155           0 : int lgfs2_open_mnt_dir(const char *path, int flags, struct mntent **mnt)
     156             : {
     157           0 :         int dirfd = -1;
     158           0 :         int devfd = -1;
     159           0 :         if (lgfs2_open_mnt(path, flags, &dirfd, O_RDONLY, &devfd, mnt) != 0)
     160           0 :                 return -1;
     161           0 :         if (*mnt != NULL)
     162           0 :                 close(devfd);
     163           0 :         return dirfd;
     164             : }

Generated by: LCOV version 1.14