(root)/
util-linux-2.39/
libblkid/
src/
superblocks/
gfs.c
       1  /*
       2   * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
       3   *
       4   * This file may be redistributed under the terms of the
       5   * GNU Lesser General Public License.
       6   */
       7  #include <stdio.h>
       8  #include <stdlib.h>
       9  #include <unistd.h>
      10  #include <string.h>
      11  #include <stdint.h>
      12  
      13  #include "superblocks.h"
      14  
      15  /* Common gfs/gfs2 constants: */
      16  #define GFS_LOCKNAME_LEN        64
      17  
      18  /* gfs1 constants: */
      19  #define GFS_FORMAT_FS           1309
      20  #define GFS_FORMAT_MULTI        1401
      21  
      22  struct gfs2_meta_header {
      23  	uint32_t mh_magic;
      24  	uint32_t mh_type;
      25  	uint64_t __pad0;          /* Was generation number in gfs1 */
      26  	uint32_t mh_format;
      27  	uint32_t __pad1;          /* Was incarnation number in gfs1 */
      28  };
      29  
      30  struct gfs2_inum {
      31  	uint64_t no_formal_ino;
      32  	uint64_t no_addr;
      33  };
      34  
      35  struct gfs2_sb {
      36  	struct gfs2_meta_header sb_header;
      37  
      38  	uint32_t sb_fs_format;
      39  	uint32_t sb_multihost_format;
      40  	uint32_t  __pad0;  /* Was superblock flags in gfs1 */
      41  
      42  	uint32_t sb_bsize;
      43  	uint32_t sb_bsize_shift;
      44  	uint32_t __pad1;   /* Was journal segment size in gfs1 */
      45  
      46  	struct gfs2_inum sb_master_dir; /* Was jindex dinode in gfs1 */
      47  	struct gfs2_inum __pad2; /* Was rindex dinode in gfs1 */
      48  	struct gfs2_inum sb_root_dir;
      49  
      50  	char sb_lockproto[GFS_LOCKNAME_LEN];
      51  	char sb_locktable[GFS_LOCKNAME_LEN];
      52  
      53  	struct gfs2_inum __pad3; /* Was quota inode in gfs1 */
      54  	struct gfs2_inum __pad4; /* Was license inode in gfs1 */
      55  	uint8_t sb_uuid[16]; /* The UUID maybe 0 for backwards compat */
      56  } __attribute__((packed));
      57  
      58  
      59  
      60  static int probe_gfs(blkid_probe pr, const struct blkid_idmag *mag)
      61  {
      62  	struct gfs2_sb *sbd;
      63  
      64  	sbd = blkid_probe_get_sb(pr, mag, struct gfs2_sb);
      65  	if (!sbd)
      66  		return errno ? -errno : 1;
      67  
      68  	if (be32_to_cpu(sbd->sb_fs_format) == GFS_FORMAT_FS &&
      69  	    be32_to_cpu(sbd->sb_multihost_format) == GFS_FORMAT_MULTI)
      70  	{
      71  		if (*sbd->sb_locktable)
      72  			blkid_probe_set_label(pr,
      73  				(unsigned char *) sbd->sb_locktable,
      74  				sizeof(sbd->sb_locktable));
      75  
      76  		blkid_probe_set_uuid(pr, sbd->sb_uuid);
      77  		return 0;
      78  	}
      79  
      80  	return 1;
      81  }
      82  
      83  static inline int gfs2_format_is_valid(uint32_t format)
      84  {
      85  	return (format >= 1800 && format < 1900);
      86  }
      87  static inline int gfs2_multiformat_is_valid(uint32_t multi)
      88  {
      89  	return (multi >= 1900 && multi < 2000);
      90  }
      91  
      92  static int probe_gfs2(blkid_probe pr, const struct blkid_idmag *mag)
      93  {
      94  	struct gfs2_sb *sbd;
      95  
      96  	sbd = blkid_probe_get_sb(pr, mag, struct gfs2_sb);
      97  	if (!sbd)
      98  		return errno ? -errno : 1;
      99  
     100  	if (gfs2_format_is_valid(be32_to_cpu(sbd->sb_fs_format)) &&
     101  	    gfs2_multiformat_is_valid(be32_to_cpu(sbd->sb_multihost_format)))
     102  	{
     103  		if (*sbd->sb_locktable)
     104  			blkid_probe_set_label(pr,
     105  				(unsigned char *) sbd->sb_locktable,
     106  				sizeof(sbd->sb_locktable));
     107  		blkid_probe_set_uuid(pr, sbd->sb_uuid);
     108  		blkid_probe_set_version(pr, "1");
     109  		blkid_probe_set_fsblocksize(pr, be32_to_cpu(sbd->sb_bsize));
     110  		blkid_probe_set_block_size(pr, be32_to_cpu(sbd->sb_bsize));
     111  		return 0;
     112  	}
     113  	return 1;
     114  }
     115  
     116  const struct blkid_idinfo gfs_idinfo =
     117  {
     118  	.name		= "gfs",
     119  	.usage		= BLKID_USAGE_FILESYSTEM,
     120  	.probefunc	= probe_gfs,
     121  	.minsz		= 32 * 1024 * 1024,	/* minimal size of GFS journal */
     122  	.magics		=
     123  	{
     124  		{ .magic = "\x01\x16\x19\x70", .len = 4, .kboff = 64 },
     125  		{ NULL }
     126  	}
     127  };
     128  
     129  const struct blkid_idinfo gfs2_idinfo =
     130  {
     131  	.name		= "gfs2",
     132  	.usage		= BLKID_USAGE_FILESYSTEM,
     133  	.probefunc	= probe_gfs2,
     134  	.minsz		= 32 * 1024 * 1024,	/* minimal size of GFS journal */
     135  	.magics		=
     136  	{
     137  		{ .magic = "\x01\x16\x19\x70", .len = 4, .kboff = 64 },
     138  		{ NULL }
     139  	}
     140  };
     141