]> err.no Git - util-linux/commitdiff
blkid: add UFS
authorKarel Zak <kzak@redhat.com>
Fri, 28 Nov 2008 12:39:48 +0000 (13:39 +0100)
committerKarel Zak <kzak@redhat.com>
Wed, 11 Feb 2009 22:21:48 +0000 (23:21 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
libs/blkid/src/blkidP.h
libs/blkid/src/probe.c
libs/blkid/src/probers/Makefile.am
libs/blkid/src/probers/probers.h
libs/blkid/src/probers/ufs.c [new file with mode: 0644]

index 8927947cf433b9524d6f0540a3441a441649ab54..6ae046e003b93a3700aab8a3e35116a9654ae2b8 100644 (file)
 #define __BLKID_ATTR(x)
 #endif
 
+/* TODO: move to some top-level util-linux include file */
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+#endif
 
 /*
  * This describes the attributes of a specific device.
index fb1615b7fe053b1e56a5dd937d1ae5a3d8019065..76105cbea469a79818bc5452cfbfbd16cfada758 100644 (file)
@@ -71,7 +71,7 @@ static const struct blkid_idinfo *idinfos[] =
        /* TODO: zfs */
        &hfsplus_idinfo,
        &hfs_idinfo,
-       /* TODO: ufs */
+       &ufs_idinfo,
        /* TODO: hpfs */
        /* TODO: sysv / xenix */
        &ntfs_idinfo,
index a09608b9f19af9c7b741fb34e767d94163f827aa..2529e7efb92d440d5f8e0d62217e53e3592c9d36 100644 (file)
@@ -33,6 +33,7 @@ libprobers_a_SOURCES =        probers.h \
                        highpoint_raid.c \
                        vxfs.c \
                        minix.c \
+                       ufs.c
                        lvm.c
 
 all-local: $(lib_LIBRARIES)
index 36271275b5ccc727ca97138ad905d45350bbbae4..4c2f1f6f1e549ce02b00cb4037756ad3e9124242 100644 (file)
@@ -51,6 +51,7 @@ extern const struct blkid_idinfo udf_idinfo;
 extern const struct blkid_idinfo vxfs_idinfo;
 extern const struct blkid_idinfo minix_idinfo;
 extern const struct blkid_idinfo vfat_idinfo;
+extern const struct blkid_idinfo ufs_idinfo;
 extern const struct blkid_idinfo lvm2_idinfo;
 extern const struct blkid_idinfo lvm1_idinfo;
 extern const struct blkid_idinfo luks_idinfo;
diff --git a/libs/blkid/src/probers/ufs.c b/libs/blkid/src/probers/ufs.c
new file mode 100644 (file)
index 0000000..a474bf6
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 1999 by Andries Brouwer
+ * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
+ * Copyright (C) 2001 by Andreas Dilger
+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct ufs_super_block {
+       uint32_t        fs_link;
+       uint32_t        fs_rlink;
+       uint32_t        fs_sblkno;
+       uint32_t        fs_cblkno;
+       uint32_t        fs_iblkno;
+       uint32_t        fs_dblkno;
+       uint32_t        fs_cgoffset;
+       uint32_t        fs_cgmask;
+       uint32_t        fs_time;
+       uint32_t        fs_size;
+       uint32_t        fs_dsize;
+       uint32_t        fs_ncg;
+       uint32_t        fs_bsize;
+       uint32_t        fs_fsize;
+       uint32_t        fs_frag;
+       uint32_t        fs_minfree;
+       uint32_t        fs_rotdelay;
+       uint32_t        fs_rps;
+       uint32_t        fs_bmask;
+       uint32_t        fs_fmask;
+       uint32_t        fs_bshift;
+       uint32_t        fs_fshift;
+       uint32_t        fs_maxcontig;
+       uint32_t        fs_maxbpg;
+       uint32_t        fs_fragshift;
+       uint32_t        fs_fsbtodb;
+       uint32_t        fs_sbsize;
+       uint32_t        fs_csmask;
+       uint32_t        fs_csshift;
+       uint32_t        fs_nindir;
+       uint32_t        fs_inopb;
+       uint32_t        fs_nspf;
+       uint32_t        fs_optim;
+       uint32_t        fs_npsect_state;
+       uint32_t        fs_interleave;
+       uint32_t        fs_trackskew;
+       uint32_t        fs_id[2];
+       uint32_t        fs_csaddr;
+       uint32_t        fs_cssize;
+       uint32_t        fs_cgsize;
+       uint32_t        fs_ntrak;
+       uint32_t        fs_nsect;
+       uint32_t        fs_spc;
+       uint32_t        fs_ncyl;
+       uint32_t        fs_cpg;
+       uint32_t        fs_ipg;
+       uint32_t        fs_fpg;
+       struct ufs_csum {
+               uint32_t        cs_ndir;
+               uint32_t        cs_nbfree;
+               uint32_t        cs_nifree;
+               uint32_t        cs_nffree;
+       } fs_cstotal;
+       int8_t          fs_fmod;
+       int8_t          fs_clean;
+       int8_t          fs_ronly;
+       int8_t          fs_flags;
+       union {
+               struct {
+                       int8_t  fs_fsmnt[512];
+                       uint32_t        fs_cgrotor;
+                       uint32_t        fs_csp[31];
+                       uint32_t        fs_maxcluster;
+                       uint32_t        fs_cpc;
+                       uint16_t        fs_opostbl[16][8];
+               } fs_u1;
+               struct {
+                       int8_t          fs_fsmnt[468];
+                       uint8_t         fs_volname[32];
+                       uint64_t        fs_swuid;
+                       int32_t         fs_pad;
+                       uint32_t        fs_cgrotor;
+                       uint32_t        fs_ocsp[28];
+                       uint32_t        fs_contigdirs;
+                       uint32_t        fs_csp;
+                       uint32_t        fs_maxcluster;
+                       uint32_t        fs_active;
+                       int32_t         fs_old_cpc;
+                       int32_t         fs_maxbsize;
+                       int64_t         fs_sparecon64[17];
+                       int64_t         fs_sblockloc;
+                       struct ufs2_csum_total {
+                               uint64_t        cs_ndir;
+                               uint64_t        cs_nbfree;
+                               uint64_t        cs_nifree;
+                               uint64_t        cs_nffree;
+                               uint64_t        cs_numclusters;
+                               uint64_t        cs_spare[3];
+                       } fs_cstotal;
+                       struct ufs_timeval {
+                               int32_t         tv_sec;
+                               int32_t         tv_usec;
+                       } fs_time;
+                       int64_t         fs_size;
+                       int64_t         fs_dsize;
+                       uint64_t        fs_csaddr;
+                       int64_t         fs_pendingblocks;
+                       int32_t         fs_pendinginodes;
+               } fs_u2;
+       }  fs_u11;
+       union {
+               struct {
+                       int32_t         fs_sparecon[53];
+                       int32_t         fs_reclaim;
+                       int32_t         fs_sparecon2[1];
+                       int32_t         fs_state;
+                       uint32_t        fs_qbmask[2];
+                       uint32_t        fs_qfmask[2];
+               } fs_sun;
+               struct {
+                       int32_t         fs_sparecon[53];
+                       int32_t         fs_reclaim;
+                       int32_t         fs_sparecon2[1];
+                       uint32_t        fs_npsect;
+                       uint32_t        fs_qbmask[2];
+                       uint32_t        fs_qfmask[2];
+               } fs_sunx86;
+               struct {
+                       int32_t         fs_sparecon[50];
+                       int32_t         fs_contigsumsize;
+                       int32_t         fs_maxsymlinklen;
+                       int32_t         fs_inodefmt;
+                       uint32_t        fs_maxfilesize[2];
+                       uint32_t        fs_qbmask[2];
+                       uint32_t        fs_qfmask[2];
+                       int32_t         fs_state;
+               } fs_44;
+       } fs_u2;
+       int32_t         fs_postblformat;
+       int32_t         fs_nrpos;
+       int32_t         fs_postbloff;
+       int32_t         fs_rotbloff;
+       uint32_t        fs_magic;
+       uint8_t         fs_space[1];
+};
+
+#define UFS_MAGIC                      0x00011954
+#define UFS2_MAGIC                     0x19540119
+#define UFS_MAGIC_FEA                  0x00195612
+#define UFS_MAGIC_LFN                  0x00095014
+
+static int probe_ufs(blkid_probe pr, const struct blkid_idmag *mag)
+{
+       int offsets[] = { 0, 8, 64, 256 };
+       int mags[] = { UFS2_MAGIC, UFS_MAGIC, UFS_MAGIC_FEA, UFS_MAGIC_LFN };
+       int i;
+       uint32_t magic;
+       struct ufs_super_block *ufs;
+
+       for (i = 0; i < ARRAY_SIZE(offsets); i++) {
+               uint32_t magLE, magBE;
+               int y;
+
+               ufs = (struct ufs_super_block *)
+                               blkid_probe_get_buffer(pr,
+                                       offsets[i] * 1024,
+                                       sizeof(struct ufs_super_block));
+               if (!ufs)
+                       return -1;
+
+               magBE = be32_to_cpu(ufs->fs_magic);
+               magLE = le32_to_cpu(ufs->fs_magic);
+
+               for (y = 0; y < ARRAY_SIZE(mags); y++) {
+                       if (magLE == mags[y] || magBE == mags[y]) {
+                               magic = mags[y];
+                               goto found;
+                       }
+               }
+       }
+
+       return 1;
+
+found:
+       if (magic == UFS2_MAGIC) {
+               blkid_probe_set_version(pr, "2");
+               blkid_probe_set_label(pr, ufs->fs_u11.fs_u2.fs_volname,
+                               sizeof(ufs->fs_u11.fs_u2.fs_volname));
+       } else
+               blkid_probe_set_version(pr, "1");
+
+       return 0;
+}
+
+/*
+ * According to libvolume_id the UFS superblock could be on four positions.
+ * The original libblkid has checked one position (.kboff=8) only.
+ *
+ * We know four UFS magic strings and UFS could be both little-endian and
+ * big-endian. ... so we have:
+ *
+ *     4 position * 4 string * 2 version = 32 magic strings
+ *
+ * It seems simpler to check for these string in probing function that hardcode
+ * all in the .magic array.
+ */
+const struct blkid_idinfo ufs_idinfo =
+{
+       .name           = "ufs",
+       .usage          = BLKID_USAGE_FILESYSTEM,
+       .probefunc      = probe_ufs,
+       .magics         = BLKID_NONE_MAGIC
+};
+