From 83b935ae4fa5fb2cef0fe8b5c17edee69d03651a Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Fri, 28 Nov 2008 13:39:48 +0100 Subject: [PATCH] blkid: add UFS Signed-off-by: Karel Zak --- libs/blkid/src/blkidP.h | 4 + libs/blkid/src/probe.c | 2 +- libs/blkid/src/probers/Makefile.am | 1 + libs/blkid/src/probers/probers.h | 1 + libs/blkid/src/probers/ufs.c | 233 +++++++++++++++++++++++++++++ 5 files changed, 240 insertions(+), 1 deletion(-) create mode 100644 libs/blkid/src/probers/ufs.c diff --git a/libs/blkid/src/blkidP.h b/libs/blkid/src/blkidP.h index 8927947c..6ae046e0 100644 --- a/libs/blkid/src/blkidP.h +++ b/libs/blkid/src/blkidP.h @@ -27,6 +27,10 @@ #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. diff --git a/libs/blkid/src/probe.c b/libs/blkid/src/probe.c index fb1615b7..76105cbe 100644 --- a/libs/blkid/src/probe.c +++ b/libs/blkid/src/probe.c @@ -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, diff --git a/libs/blkid/src/probers/Makefile.am b/libs/blkid/src/probers/Makefile.am index a09608b9..2529e7ef 100644 --- a/libs/blkid/src/probers/Makefile.am +++ b/libs/blkid/src/probers/Makefile.am @@ -33,6 +33,7 @@ libprobers_a_SOURCES = probers.h \ highpoint_raid.c \ vxfs.c \ minix.c \ + ufs.c lvm.c all-local: $(lib_LIBRARIES) diff --git a/libs/blkid/src/probers/probers.h b/libs/blkid/src/probers/probers.h index 36271275..4c2f1f6f 100644 --- a/libs/blkid/src/probers/probers.h +++ b/libs/blkid/src/probers/probers.h @@ -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 index 00000000..a474bf6e --- /dev/null +++ b/libs/blkid/src/probers/ufs.c @@ -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 + * Copyright (C) 2008 Karel Zak + * + * 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 +#include +#include +#include +#include +#include +#include + +#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 +}; + -- 2.39.5