summaryrefslogtreecommitdiff
path: root/libblkid
diff options
context:
space:
mode:
authorRichard Maw <richard.maw@codethink.co.uk>2014-06-12 12:04:01 +0100
committerRichard Maw <richard.maw@codethink.co.uk>2014-06-12 12:04:01 +0100
commitc5c1033c5c7deda8abe3448ec81bbb33c72219e0 (patch)
tree6e5cef29b85161eea8a7488a029f5a32f982c6ab /libblkid
parent462008f79be9e195670b202cb43827b8aeb1e60b (diff)
parent2fb567c080e1762ec6a2147564f03068f55d4f14 (diff)
downloadutil-linux-baserock/morph.tar.gz
Merge branch 'baserock/richardmaw/yakshave/util-linux-blkid' into baserock/morphbaserock/morph
Reviewed-by: Lars Wirzenius Reviewed-by: Sam Thursfield
Diffstat (limited to 'libblkid')
-rw-r--r--libblkid/COPYING4
-rw-r--r--libblkid/docs/libblkid-docs.xml1
-rw-r--r--libblkid/docs/libblkid-sections.txt1
-rw-r--r--libblkid/src/Makemodule.am18
-rw-r--r--libblkid/src/blkid.h.in1
-rw-r--r--libblkid/src/blkidP.h5
-rw-r--r--libblkid/src/evaluate.c4
-rw-r--r--libblkid/src/init.c2
-rw-r--r--libblkid/src/partitions/blkid_parttypes.h121
-rw-r--r--libblkid/src/partitions/bsd.c89
-rw-r--r--libblkid/src/partitions/dos.c82
-rw-r--r--libblkid/src/partitions/dos.h41
-rw-r--r--libblkid/src/partitions/gpt.c67
-rw-r--r--libblkid/src/partitions/minix.c19
-rw-r--r--libblkid/src/partitions/partitions.c84
-rw-r--r--libblkid/src/partitions/partitions.h9
-rw-r--r--libblkid/src/partitions/sgi.c80
-rw-r--r--libblkid/src/probe.c45
-rw-r--r--libblkid/src/save.c7
-rw-r--r--libblkid/src/superblocks/bcache.c136
-rw-r--r--libblkid/src/superblocks/ext.c2
-rw-r--r--libblkid/src/superblocks/lvm.c11
-rw-r--r--libblkid/src/superblocks/nilfs.c66
-rw-r--r--libblkid/src/superblocks/silicon_raid.c14
-rw-r--r--libblkid/src/superblocks/superblocks.c19
-rw-r--r--libblkid/src/superblocks/superblocks.h2
-rw-r--r--libblkid/src/superblocks/swap.c6
-rw-r--r--libblkid/src/superblocks/via_raid.c16
-rw-r--r--libblkid/src/superblocks/xfs.c246
-rw-r--r--libblkid/src/tag.c14
30 files changed, 723 insertions, 489 deletions
diff --git a/libblkid/COPYING b/libblkid/COPYING
index 41fe6fd62..be1a5b3a1 100644
--- a/libblkid/COPYING
+++ b/libblkid/COPYING
@@ -4,5 +4,5 @@ License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later
version.
-The complete text of the license is available at the
-Documentation/licenses/COPYING.LGPLv2.1 file.
+The complete text of the license is available in the
+../Documentation/licenses/COPYING.LGPLv2.1 file.
diff --git a/libblkid/docs/libblkid-docs.xml b/libblkid/docs/libblkid-docs.xml
index 3ff754aa7..1f412c105 100644
--- a/libblkid/docs/libblkid-docs.xml
+++ b/libblkid/docs/libblkid-docs.xml
@@ -50,6 +50,7 @@ available from ftp://ftp.kernel.org/pub/linux/utils/util-linux/.
</part>
<part>
<title>Low-level</title>
+ <xi:include href="xml/init.xml"/>
<xi:include href="xml/lowprobe.xml"/>
<xi:include href="xml/lowprobe-tags.xml"/>
<xi:include href="xml/superblocks.xml"/>
diff --git a/libblkid/docs/libblkid-sections.txt b/libblkid/docs/libblkid-sections.txt
index 86b8040fa..69723459e 100644
--- a/libblkid/docs/libblkid-sections.txt
+++ b/libblkid/docs/libblkid-sections.txt
@@ -180,6 +180,7 @@ BLKID_PROBREQ_USAGE
BLKID_PROBREQ_UUID
BLKID_PROBREQ_UUIDRAW
BLKID_PROBREQ_VERSION
+BLKID_SUBLKS_BADCSUM
BLKID_SUBLKS_DEFAULT
BLKID_SUBLKS_LABEL
BLKID_SUBLKS_LABELRAW
diff --git a/libblkid/src/Makemodule.am b/libblkid/src/Makemodule.am
index 04d862100..013877e60 100644
--- a/libblkid/src/Makemodule.am
+++ b/libblkid/src/Makemodule.am
@@ -26,14 +26,12 @@ libblkid_la_SOURCES = \
libblkid/src/tag.c \
libblkid/src/verify.c \
libblkid/src/version.c \
- $(blkidinc_HEADERS) \
+ $(nodist_blkidinc_HEADERS) \
\
libblkid/src/partitions/aix.c \
libblkid/src/partitions/aix.h \
- libblkid/src/partitions/blkid_parttypes.h \
libblkid/src/partitions/bsd.c \
libblkid/src/partitions/dos.c \
- libblkid/src/partitions/dos.h \
libblkid/src/partitions/gpt.c \
libblkid/src/partitions/mac.c \
libblkid/src/partitions/minix.c \
@@ -46,6 +44,7 @@ libblkid_la_SOURCES = \
libblkid/src/partitions/unixware.c \
\
libblkid/src/superblocks/adaptec_raid.c \
+ libblkid/src/superblocks/bcache.c \
libblkid/src/superblocks/befs.c \
libblkid/src/superblocks/bfs.c \
libblkid/src/superblocks/btrfs.c \
@@ -111,23 +110,24 @@ endif
nodist_libblkid_la_SOURCES = libblkid/src/blkid.h
libblkid_la_LIBADD = libcommon.la
+libblkid_la_DEPENDENCIES = \
+ libcommon.la \
+ libblkid/src/blkid.sym \
+ libblkid/src/blkid.h.in
libblkid_la_CFLAGS = \
+ $(SOLIB_CFLAGS) \
-I$(ul_libblkid_incdir) \
-I$(top_srcdir)/libblkid/src
if BUILD_LIBUUID
libblkid_la_LIBADD += libuuid.la
+libblkid_la_DEPENDENCIES += libuuid.la
libblkid_la_CFLAGS += -I$(ul_libuuid_incdir)
endif
-
-libblkid_la_DEPENDENCIES = \
- $(libblkid_la_LIBADD) \
- libblkid/src/blkid.sym \
- libblkid/src/blkid.h.in
-
libblkid_la_LDFLAGS = \
+ $(SOLIB_LDFLAGS) \
-Wl,--version-script=$(top_srcdir)/libblkid/src/blkid.sym \
-version-info $(LIBBLKID_VERSION_INFO)
diff --git a/libblkid/src/blkid.h.in b/libblkid/src/blkid.h.in
index 2a7d6b47c..c140fc6b2 100644
--- a/libblkid/src/blkid.h.in
+++ b/libblkid/src/blkid.h.in
@@ -260,6 +260,7 @@ extern int blkid_probe_enable_superblocks(blkid_probe pr, int enable);
#define BLKID_SUBLKS_USAGE (1 << 7) /* define USAGE result value */
#define BLKID_SUBLKS_VERSION (1 << 8) /* read FS type from superblock */
#define BLKID_SUBLKS_MAGIC (1 << 9) /* define SBMAGIC and SBMAGIC_OFFSET */
+#define BLKID_SUBLKS_BADCSUM (1 << 10) /* allow a bad checksum */
#define BLKID_SUBLKS_DEFAULT (BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID | \
BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE)
diff --git a/libblkid/src/blkidP.h b/libblkid/src/blkidP.h
index 7cc585932..0bbf310a0 100644
--- a/libblkid/src/blkidP.h
+++ b/libblkid/src/blkidP.h
@@ -516,8 +516,13 @@ extern int blkid_probe_set_magic(blkid_probe pr, blkid_loff_t offset,
size_t len, unsigned char *magic)
__attribute__((nonnull));
+extern int blkid_probe_verify_csum(blkid_probe pr, uint64_t csum, uint64_t expected)
+ __attribute__((nonnull));
+
extern void blkid_unparse_uuid(const unsigned char *uuid, char *str, size_t len)
__attribute__((nonnull));
+extern int blkid_uuid_is_empty(const unsigned char *buf, size_t len);
+
extern size_t blkid_rtrim_whitespace(unsigned char *str)
__attribute__((nonnull));
extern size_t blkid_ltrim_whitespace(unsigned char *str)
diff --git a/libblkid/src/evaluate.c b/libblkid/src/evaluate.c
index 8853009c9..8ef927756 100644
--- a/libblkid/src/evaluate.c
+++ b/libblkid/src/evaluate.c
@@ -24,6 +24,7 @@
#include "pathnames.h"
#include "canonicalize.h"
+#include "closestream.h"
#include "blkidP.h"
@@ -123,7 +124,8 @@ int blkid_send_uevent(const char *devname, const char *action)
rc = 0;
if (fputs(action, f) >= 0)
rc = 0;
- fclose(f);
+ if (close_stream(f) != 0)
+ DBG(EVALUATE, blkid_debug("write failed: %s", uevent));
}
DBG(EVALUATE, blkid_debug("%s: send uevent %s",
uevent, rc == 0 ? "SUCCES" : "FAILED"));
diff --git a/libblkid/src/init.c b/libblkid/src/init.c
index 4ca4db171..bb6f950fb 100644
--- a/libblkid/src/init.c
+++ b/libblkid/src/init.c
@@ -40,7 +40,7 @@ void blkid_init_debug(int mask)
libblkid_debug_mask |= BLKID_DEBUG_INIT;
- if (libblkid_debug_mask && libblkid_debug_mask != BLKID_DEBUG_INIT) {
+ if (libblkid_debug_mask != BLKID_DEBUG_INIT) {
const char *ver = NULL;
const char *date = NULL;
diff --git a/libblkid/src/partitions/blkid_parttypes.h b/libblkid/src/partitions/blkid_parttypes.h
deleted file mode 100644
index b0aad86e6..000000000
--- a/libblkid/src/partitions/blkid_parttypes.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Partition types
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/* Note, _L32M means <32M (less), for example FAT16_L32M */
-
-enum {
- BLKID_EMPTY_PARTITION = 0x00,
- BLKID_FAT12_PARTITION = 0x01,
- BLKID_XENIX_ROOT_PARTITION = 0x02,
- BLKID_XENIX_USR_PARTITION = 0x03,
- BLKID_FAT16_LESS32M_PARTITION = 0x04,
- BLKID_DOS_EXTENDED_PARTITION = 0x05,
- BLKID_FAT16_PARTITION = 0x06, /* DOS 16-bit >=32M */
- BLKID_HPFS_NTFS_PARTITION = 0x07, /* OS/2 IFS, eg, HPFS or NTFS or QNX */
- BLKID_AIX_PARTITION = 0x08, /* AIX boot (AIX -- PS/2 port) or SplitDrive */
- BLKID_AIX_BOOTABLE_PARTITION = 0x09, /* AIX data or Coherent */
- BLKID_OS2_BOOTMNGR_PARTITION = 0x0a, /* OS/2 Boot Manager */
- BLKID_W95_FAT32_PARTITION = 0x0b,
- BLKID_W95_FAT32_LBA_PARTITION = 0x0c, /* LBA really is `Extended Int 13h' */
- BLKID_W95_FAT16_LBA_PARTITION = 0x0e,
- BLKID_W95_EXTENDED_PARTITION = 0x0f,
- BLKID_OPUS_PARTITION = 0x10,
- BLKID_HIDDEN_FAT12_PARTITION = 0x11,
- BLKID_COMPAQ_DIAGNOSTICS_PARTITION = 0x12,
- BLKID_HIDDEN_FAT16_L32M_PARTITION = 0x14,
- BLKID_HIDDEN_FAT16_PARTITION = 0x16,
- BLKID_HIDDEN_HPFS_NTFS_PARTITION = 0x17,
- BLKID_AST_SMARTSLEEP_PARTITION = 0x18,
- BLKID_HIDDEN_W95_FAT32_PARTITION = 0x1b,
- BLKID_HIDDEN_W95_FAT32LBA_PARTITION = 0x1c,
- BLKID_HIDDEN_W95_FAT16LBA_PARTITION = 0x1e,
- BLKID_NEC_DOS_PARTITION = 0x24,
- BLKID_PLAN9_PARTITION = 0x39,
- BLKID_PARTITIONMAGIC_PARTITION = 0x3c,
- BLKID_VENIX80286_PARTITION = 0x40,
- BLKID_PPC_PREP_BOOT_PARTITION = 0x41,
- BLKID_SFS_PARTITION = 0x42,
- BLKID_QNX_4X_PARTITION = 0x4d,
- BLKID_QNX_4X_2ND_PARTITION = 0x4e,
- BLKID_QNX_4X_3RD_PARTITION = 0x4f,
- BLKID_DM_PARTITION = 0x50,
- BLKID_DM6_AUX1_PARTITION = 0x51, /* (or Novell) */
- BLKID_CPM_PARTITION = 0x52, /* CP/M or Microport SysV/AT */
- BLKID_DM6_AUX3_PARTITION = 0x53,
- BLKID_DM6_PARTITION = 0x54,
- BLKID_EZ_DRIVE_PARTITION = 0x55,
- BLKID_GOLDEN_BOW_PARTITION = 0x56,
- BLKID_PRIAM_EDISK_PARTITION = 0x5c,
- BLKID_SPEEDSTOR_PARTITION = 0x61,
- BLKID_GNU_HURD_PARTITION = 0x63, /* GNU HURD or Mach or Sys V/386 (such as ISC UNIX) */
- BLKID_UNIXWARE_PARTITION = BLKID_GNU_HURD_PARTITION,
- BLKID_NETWARE_286_PARTITION = 0x64,
- BLKID_NETWARE_386_PARTITION = 0x65,
- BLKID_DISKSECURE_MULTIBOOT_PARTITION = 0x70,
- BLKID_PC_IX_PARTITION = 0x75,
- BLKID_OLD_MINIX_PARTITION = 0x80, /* Minix 1.4a and earlier */
- BLKID_MINIX_PARTITION = 0x81, /* Minix 1.4b and later */
- BLKID_LINUX_SWAP_PARTITION = 0x82,
- BLKID_SOLARIS_X86_PARTITION = BLKID_LINUX_SWAP_PARTITION,
- BLKID_LINUX_DATA_PARTITION = 0x83,
- BLKID_OS2_HIDDEN_DRIVE_PARTITION = 0x84,
- BLKID_LINUX_EXTENDED_PARTITION = 0x85,
- BLKID_NTFS_VOL_SET1_PARTITION = 0x86,
- BLKID_NTFS_VOL_SET2_PARTITION = 0x87,
- BLKID_LINUX_PLAINTEXT_PARTITION = 0x88,
- BLKID_LINUX_LVM_PARTITION = 0x8e,
- BLKID_AMOEBA_PARTITION = 0x93,
- BLKID_AMOEBA_BBT_PARTITION = 0x94, /* (bad block table) */
- BLKID_BSD_OS_PARTITION = 0x9f, /* BSDI */
- BLKID_THINKPAD_HIBERNATION_PARTITION = 0xa0,
- BLKID_FREEBSD_PARTITION = 0xa5, /* various BSD flavours */
- BLKID_OPENBSD_PARTITION = 0xa6,
- BLKID_NEXTSTEP_PARTITION = 0xa7,
- BLKID_DARWIN_UFS_PARTITION = 0xa8,
- BLKID_NETBSD_PARTITION = 0xa9,
- BLKID_DARWIN_BOOT_PARTITION = 0xab,
- BLKID_HFS_HFS_PARTITION = 0xaf,
- BLKID_BSDI_FS_PARTITION = 0xb7,
- BLKID_BSDI_SWAP_PARTITION = 0xb8,
- BLKID_BOOTWIZARD_HIDDEN_PARTITION = 0xbb,
- BLKID_SOLARIS_BOOT_PARTITION = 0xbe,
- BLKID_SOLARIS_PARTITION = 0xbf,
- BLKID_DRDOS_FAT12_PARTITION = 0xc1,
- BLKID_DRDOS_FAT16_L32M_PARTITION = 0xc4,
- BLKID_DRDOS_FAT16_PARTITION = 0xc6,
- BLKID_SYRINX_PARTITION = 0xc7,
- BLKID_NONFS_DATA_PARTITION = 0xda,
- BLKID_CPM_CTOS_PARTITION = 0xdb, /* CP/M or Concurrent CP/M or Concurrent DOS or CTOS */
- BLKID_DELL_UTILITY_PARTITION = 0xde, /* Dell PowerEdge Server utilities */
- BLKID_BOOTIT_PARTITION = 0xdf, /* BootIt EMBRM */
- BLKID_DOS_ACCESS_PARTITION = 0xe1, /* DOS access or SpeedStor 12-bit FAT extended partition */
- BLKID_DOS_RO_PARTITION = 0xe3, /* DOS R/O or SpeedStor */
- BLKID_SPEEDSTOR_EXTENDED_PARTITION = 0xe4, /* SpeedStor 16-bit FAT extended partition < 1024 cyl. */
- BLKID_BEOS_FS_PARTITION = 0xeb,
- BLKID_GPT_PARTITION = 0xee, /* Intel EFI GUID Partition Table */
- BLKID_EFI_SYSTEM_PARTITION = 0xef, /* Intel EFI System Partition */
- BLKID_LINUX_PARISC_BOOT_PARTITION = 0xf0, /* Linux/PA-RISC boot loader */
- BLKID_SPEEDSTOR1_PARTITION = 0xf1,
- BLKID_SPEEDSTOR2_PARTITION = 0xf4, /* SpeedStor large partition */
- BLKID_DOS_SECONDARY_PARTITION = 0xf2, /* DOS 3.3+ secondary */
- BLKID_VMWARE_VMFS_PARTITION = 0xfb,
- BLKID_VMWARE_VMKCORE_PARTITION = 0xfc, /* VMware kernel dump partition */
- BLKID_LINUX_RAID_PARTITION = 0xfd, /* New (2.2.x) raid partition with autodetect using persistent superblock */
- BLKID_LANSTEP_PARTITION = 0xfe, /* SpeedStor >1024 cyl. or LANstep */
- BLKID_XENIX_BBT_PARTITION = 0xff, /* Xenix Bad Block Table */
-};
diff --git a/libblkid/src/partitions/bsd.c b/libblkid/src/partitions/bsd.c
index 08fcad892..3de6a589e 100644
--- a/libblkid/src/partitions/bsd.c
+++ b/libblkid/src/partitions/bsd.c
@@ -14,90 +14,13 @@
#include <stdint.h>
#include "partitions.h"
-
-#define BSD_MAXPARTITIONS 16
-#define BSD_FS_UNUSED 0
-
-struct bsd_disklabel {
- uint32_t d_magic; /* the magic number */
- int16_t d_type; /* drive type */
- int16_t d_subtype; /* controller/d_type specific */
- char d_typename[16]; /* type name, e.g. "eagle" */
- char d_packname[16]; /* pack identifier */
-
- /* disk geometry: */
- uint32_t d_secsize; /* # of bytes per sector */
- uint32_t d_nsectors; /* # of data sectors per track */
- uint32_t d_ntracks; /* # of tracks per cylinder */
- uint32_t d_ncylinders; /* # of data cylinders per unit */
- uint32_t d_secpercyl; /* # of data sectors per cylinder */
- uint32_t d_secperunit; /* # of data sectors per unit */
-
- /*
- * Spares (bad sector replacements) below
- * are not counted in d_nsectors or d_secpercyl.
- * Spare sectors are assumed to be physical sectors
- * which occupy space at the end of each track and/or cylinder.
- */
- uint16_t d_sparespertrack; /* # of spare sectors per track */
- uint16_t d_sparespercyl; /* # of spare sectors per cylinder */
-
- /*
- * Alternate cylinders include maintenance, replacement,
- * configuration description areas, etc.
- */
- uint32_t d_acylinders; /* # of alt. cylinders per unit */
-
- /* hardware characteristics: */
- /*
- * d_interleave, d_trackskew and d_cylskew describe perturbations
- * in the media format used to compensate for a slow controller.
- * Interleave is physical sector interleave, set up by the formatter
- * or controller when formatting. When interleaving is in use,
- * logically adjacent sectors are not physically contiguous,
- * but instead are separated by some number of sectors.
- * It is specified as the ratio of physical sectors traversed
- * per logical sector. Thus an interleave of 1:1 implies contiguous
- * layout, while 2:1 implies that logical sector 0 is separated
- * by one sector from logical sector 1.
- * d_trackskew is the offset of sector 0 on track N
- * relative to sector 0 on track N-1 on the same cylinder.
- * Finally, d_cylskew is the offset of sector 0 on cylinder N
- * relative to sector 0 on cylinder N-1.
- */
- uint16_t d_rpm; /* rotational speed */
- uint16_t d_interleave; /* hardware sector interleave */
- uint16_t d_trackskew; /* sector 0 skew, per track */
- uint16_t d_cylskew; /* sector 0 skew, per cylinder */
- uint32_t d_headswitch; /* head switch time, usec */
- uint32_t d_trkseek; /* track-to-track seek, usec */
- uint32_t d_flags; /* generic flags */
- uint32_t d_drivedata[5]; /* drive-type specific information */
- uint32_t d_spare[5]; /* reserved for future use */
- uint32_t d_magic2; /* the magic number (again) */
- uint16_t d_checksum; /* xor of data incl. partitions */
-
- /* filesystem and partition information: */
- uint16_t d_npartitions; /* number of partitions in following */
- uint32_t d_bbsize; /* size of boot area at sn0, bytes */
- uint32_t d_sbsize; /* max size of fs superblock, bytes */
-
- struct bsd_partition { /* the partition table */
- uint32_t p_size; /* number of sectors in partition */
- uint32_t p_offset; /* starting sector */
- uint32_t p_fsize; /* filesystem basic fragment size */
- uint8_t p_fstype; /* filesystem type, see below */
- uint8_t p_frag; /* filesystem fragments per block */
- uint16_t p_cpg; /* filesystem cylinders per group */
- } __attribute__((packed)) d_partitions[BSD_MAXPARTITIONS]; /* actually may be more */
-} __attribute__((packed));
-
+#include "pt-bsd.h"
/* Returns 'blkid_idmag' in 512-sectors */
-#define BLKID_MAG_SECTOR(_mag) (((_mag)->kboff * 2) + ((_mag)->sboff >> 9))
+#define BLKID_MAG_SECTOR(_mag) (((_mag)->kboff / 2) + ((_mag)->sboff >> 9))
/* Returns 'blkid_idmag' in bytes */
-#define BLKID_MAG_OFFSET(_mag) ((_mag)->kboff >> 10) + ((_mag)->sboff)
+#define BLKID_MAG_OFFSET(_mag) ((_mag)->kboff << 10) + ((_mag)->sboff)
/* Returns 'blkid_idmag' offset in bytes within the last sector */
#define BLKID_MAG_LASTOFFSET(_mag) \
@@ -133,13 +56,13 @@ static int probe_bsd_pt(blkid_probe pr, const struct blkid_idmag *mag)
parent = blkid_partlist_get_parent(ls);
if (parent) {
switch(blkid_partition_get_type(parent)) {
- case BLKID_FREEBSD_PARTITION:
+ case MBR_FREEBSD_PARTITION:
name = "freebsd";
break;
- case BLKID_NETBSD_PARTITION:
+ case MBR_NETBSD_PARTITION:
name = "netbsd";
break;
- case BLKID_OPENBSD_PARTITION:
+ case MBR_OPENBSD_PARTITION:
name = "openbsd";
break;
default:
diff --git a/libblkid/src/partitions/dos.c b/libblkid/src/partitions/dos.c
index 3a0a6d73e..14f326d20 100644
--- a/libblkid/src/partitions/dos.c
+++ b/libblkid/src/partitions/dos.c
@@ -14,7 +14,6 @@
#include <stdint.h>
#include "partitions.h"
-#include "dos.h"
#include "aix.h"
/* see superblocks/vfat.c */
@@ -24,19 +23,19 @@ static const struct dos_subtypes {
unsigned char type;
const struct blkid_idinfo *id;
} dos_nested[] = {
- { BLKID_FREEBSD_PARTITION, &bsd_pt_idinfo },
- { BLKID_NETBSD_PARTITION, &bsd_pt_idinfo },
- { BLKID_OPENBSD_PARTITION, &bsd_pt_idinfo },
- { BLKID_UNIXWARE_PARTITION, &unixware_pt_idinfo },
- { BLKID_SOLARIS_X86_PARTITION, &solaris_x86_pt_idinfo },
- { BLKID_MINIX_PARTITION, &minix_pt_idinfo }
+ { MBR_FREEBSD_PARTITION, &bsd_pt_idinfo },
+ { MBR_NETBSD_PARTITION, &bsd_pt_idinfo },
+ { MBR_OPENBSD_PARTITION, &bsd_pt_idinfo },
+ { MBR_UNIXWARE_PARTITION, &unixware_pt_idinfo },
+ { MBR_SOLARIS_X86_PARTITION, &solaris_x86_pt_idinfo },
+ { MBR_MINIX_PARTITION, &minix_pt_idinfo }
};
static inline int is_extended(struct dos_partition *p)
{
- return (p->sys_type == BLKID_DOS_EXTENDED_PARTITION ||
- p->sys_type == BLKID_W95_EXTENDED_PARTITION ||
- p->sys_type == BLKID_LINUX_EXTENDED_PARTITION);
+ return (p->sys_ind == MBR_DOS_EXTENDED_PARTITION ||
+ p->sys_ind == MBR_W95_EXTENDED_PARTITION ||
+ p->sys_ind == MBR_LINUX_EXTENDED_PARTITION);
}
static int parse_dos_extended(blkid_probe pr, blkid_parttable tab,
@@ -58,10 +57,10 @@ static int parse_dos_extended(blkid_probe pr, blkid_parttable tab,
if (!data)
goto leave; /* malformed partition? */
- if (!is_valid_mbr_signature(data))
+ if (!mbr_is_valid_magic(data))
goto leave;
- p0 = (struct dos_partition *) (data + BLKID_MSDOS_PT_OFFSET);
+ p0 = mbr_get_partition(data, 0);
/* Usually, the first entry is the real data partition,
* the 2nd entry is the next extended partition, or empty,
@@ -80,8 +79,8 @@ static int parse_dos_extended(blkid_probe pr, blkid_parttable tab,
blkid_partition par;
/* the start is relative to the parental ext.partition */
- start = dos_partition_start(p) * ssf;
- size = dos_partition_size(p) * ssf;
+ start = dos_partition_get_start(p) * ssf;
+ size = dos_partition_get_size(p) * ssf;
abs_start = cur_start + start; /* absolute start */
if (!size || is_extended(p))
@@ -101,8 +100,9 @@ static int parse_dos_extended(blkid_probe pr, blkid_parttable tab,
if (!par)
goto err;
- blkid_partition_set_type(par, p->sys_type);
+ blkid_partition_set_type(par, p->sys_ind);
blkid_partition_set_flags(par, p->boot_ind);
+ blkid_partition_gen_uuid(par);
ct_nodata = 0;
}
/* The first nested ext.partition should be a link to the next
@@ -110,8 +110,8 @@ static int parse_dos_extended(blkid_probe pr, blkid_parttable tab,
* is junk.
*/
for (p = p0, i = 0; i < 4; i++, p++) {
- start = dos_partition_start(p) * ssf;
- size = dos_partition_size(p) * ssf;
+ start = dos_partition_get_start(p) * ssf;
+ size = dos_partition_get_size(p) * ssf;
if (size && is_extended(p))
break;
@@ -138,6 +138,8 @@ static int probe_dos_pt(blkid_probe pr,
struct dos_partition *p0, *p;
unsigned char *data;
uint32_t start, size, id;
+ char idstr[37];
+
data = blkid_probe_get_sector(pr, 0);
if (!data)
@@ -157,7 +159,7 @@ static int probe_dos_pt(blkid_probe pr,
goto nothing;
}
- p0 = (struct dos_partition *) (data + BLKID_MSDOS_PT_OFFSET);
+ p0 = mbr_get_partition(data, 0);
/*
* Reject PT where boot indicator is not 0 or 0x80.
@@ -172,21 +174,28 @@ static int probe_dos_pt(blkid_probe pr,
* GPT uses valid MBR
*/
for (p = p0, i = 0; i < 4; i++, p++) {
- if (p->sys_type == BLKID_GPT_PARTITION) {
+ if (p->sys_ind == MBR_GPT_PARTITION) {
DBG(LOWPROBE, blkid_debug("probably GPT -- ignore"));
goto nothing;
}
}
- blkid_probe_use_wiper(pr, BLKID_MSDOS_PT_OFFSET,
- 512 - BLKID_MSDOS_PT_OFFSET);
+ blkid_probe_use_wiper(pr, MBR_PT_OFFSET, 512 - MBR_PT_OFFSET);
+
+ id = mbr_get_id(data);
+ if (id)
+ snprintf(idstr, sizeof(idstr), "%08x", id);
/*
* Well, all checks pass, it's MS-DOS partiton table
*/
- if (blkid_partitions_need_typeonly(pr))
- /* caller does not ask for details about partitions */
+ if (blkid_partitions_need_typeonly(pr)) {
+ /* Non-binary interface -- caller does not ask for details
+ * about partitions, just set generic varibles only. */
+ if (id)
+ blkid_partitions_strcpy_ptuuid(pr, idstr);
return 0;
+ }
ls = blkid_probe_get_partlist(pr);
@@ -196,25 +205,19 @@ static int probe_dos_pt(blkid_probe pr,
ssf = blkid_probe_get_sectorsize(pr) / 512;
/* allocate a new partition table */
- tab = blkid_partlist_new_parttable(ls, "dos", BLKID_MSDOS_PT_OFFSET);
+ tab = blkid_partlist_new_parttable(ls, "dos", MBR_PT_OFFSET);
if (!tab)
goto err;
- id = dos_parttable_id(data);
- if (id) {
- char buf[37];
-
- snprintf(buf, sizeof(buf), "0x%08x", id);
- blkid_parttable_set_id(tab, (unsigned char *) buf);
- }
-
+ if (id)
+ blkid_parttable_set_id(tab, (unsigned char *) idstr);
/* Parse primary partitions */
for (p = p0, i = 0; i < 4; i++, p++) {
blkid_partition par;
- start = dos_partition_start(p) * ssf;
- size = dos_partition_size(p) * ssf;
+ start = dos_partition_get_start(p) * ssf;
+ size = dos_partition_get_size(p) * ssf;
if (!size) {
/* Linux kernel ignores empty partitions, but partno for
@@ -226,8 +229,9 @@ static int probe_dos_pt(blkid_probe pr,
if (!par)
goto err;
- blkid_partition_set_type(par, p->sys_type);
+ blkid_partition_set_type(par, p->sys_ind);
blkid_partition_set_flags(par, p->boot_ind);
+ blkid_partition_gen_uuid(par);
}
/* Linux uses partition numbers greater than 4
@@ -237,8 +241,8 @@ static int probe_dos_pt(blkid_probe pr,
/* Parse logical partitions */
for (p = p0, i = 0; i < 4; i++, p++) {
- start = dos_partition_start(p) * ssf;
- size = dos_partition_size(p) * ssf;
+ start = dos_partition_get_start(p) * ssf;
+ size = dos_partition_get_size(p) * ssf;
if (!size)
continue;
@@ -252,11 +256,11 @@ static int probe_dos_pt(blkid_probe pr,
for (p = p0, i = 0; i < 4; i++, p++) {
size_t n;
- if (!dos_partition_size(p) || is_extended(p))
+ if (!dos_partition_get_size(p) || is_extended(p))
continue;
for (n = 0; n < ARRAY_SIZE(dos_nested); n++) {
- if (dos_nested[n].type != p->sys_type)
+ if (dos_nested[n].type != p->sys_ind)
continue;
if (blkid_partitions_do_subprobe(pr,
diff --git a/libblkid/src/partitions/dos.h b/libblkid/src/partitions/dos.h
deleted file mode 100644
index d7588a856..000000000
--- a/libblkid/src/partitions/dos.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef BLKID_PARTITIONS_DOS_H
-#define BLKID_PARTITIONS_DOS_H
-
-struct dos_partition {
- unsigned char boot_ind; /* 0x80 - active */
- unsigned char bh, bs, bc; /* begin CHS */
- unsigned char sys_type;
- unsigned char eh, es, ec; /* end CHS */
- unsigned char start_sect[4];
- unsigned char nr_sects[4];
-} __attribute__((packed));
-
-#define BLKID_MSDOS_PT_OFFSET 0x1be
-
-/* assemble badly aligned little endian integer */
-static inline unsigned int assemble4le(const unsigned char *p)
-{
- return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
-}
-
-static inline unsigned int dos_partition_start(struct dos_partition *p)
-{
- return assemble4le(&(p->start_sect[0]));
-}
-
-static inline unsigned int dos_partition_size(struct dos_partition *p)
-{
- return assemble4le(&(p->nr_sects[0]));
-}
-
-static inline int is_valid_mbr_signature(const unsigned char *mbr)
-{
- return mbr[510] == 0x55 && mbr[511] == 0xaa ? 1 : 0;
-}
-
-static inline unsigned int dos_parttable_id(const unsigned char *mbr)
-{
- return assemble4le(&mbr[440]);
-}
-
-#endif /* BLKID_PARTITIONS_DOS_H */
diff --git a/libblkid/src/partitions/gpt.c b/libblkid/src/partitions/gpt.c
index 444193929..14a255af6 100644
--- a/libblkid/src/partitions/gpt.c
+++ b/libblkid/src/partitions/gpt.c
@@ -20,7 +20,6 @@
#include "partitions.h"
#include "crc32.h"
-#include "dos.h"
#define GPT_PRIMARY_LBA 1
@@ -156,13 +155,15 @@ static int last_lba(blkid_probe pr, uint64_t *lba)
* Note that the PMBR detection is optional (enabled by default) and could be
* disabled by BLKID_PARTS_FOPCE_GPT flag (see also blkid_paertitions_set_flags()).
*/
-static int is_pmbr_valid(blkid_probe pr)
+static int is_pmbr_valid(blkid_probe pr, int *has)
{
int flags = blkid_partitions_get_flags(pr);
unsigned char *data;
struct dos_partition *p;
int i;
+ if (has)
+ *has = 0;
if (flags & BLKID_PARTS_FORCE_GPT)
goto ok; /* skip PMBR check */
@@ -170,18 +171,18 @@ static int is_pmbr_valid(blkid_probe pr)
if (!data)
goto failed;
- if (!is_valid_mbr_signature(data))
+ if (!mbr_is_valid_magic(data))
goto failed;
- p = (struct dos_partition *) (data + BLKID_MSDOS_PT_OFFSET);
-
- for (i = 0; i < 4; i++, p++) {
- if (p->sys_type == BLKID_GPT_PARTITION)
+ for (i = 0, p = mbr_get_partition(data, 0); i < 4; i++, p++) {
+ if (p->sys_ind == MBR_GPT_PARTITION)
goto ok;
}
failed:
return 0;
ok:
+ if (has)
+ *has = 1;
return 1;
}
@@ -305,7 +306,7 @@ static int probe_gpt_pt(blkid_probe pr,
if (last_lba(pr, &lastlba))
goto nothing;
- if (!is_pmbr_valid(pr))
+ if (!is_pmbr_valid(pr, NULL))
goto nothing;
h = get_gpt_header(pr, &hdr, &e, (lba = GPT_PRIMARY_LBA), lastlba);
@@ -322,9 +323,15 @@ static int probe_gpt_pt(blkid_probe pr,
(unsigned char *) GPT_HEADER_SIGNATURE_STR))
goto err;
- if (blkid_partitions_need_typeonly(pr))
- /* caller does not ask for details about partitions */
+ guid = h->disk_guid;
+ swap_efi_guid(&guid);
+
+ if (blkid_partitions_need_typeonly(pr)) {
+ /* Non-binary interface -- caller does not ask for details
+ * about partitions, just set generic varibles only. */
+ blkid_partitions_set_ptuuid(pr, (unsigned char *) &guid);
return 0;
+ }
ls = blkid_probe_get_partlist(pr);
if (!ls)
@@ -334,9 +341,7 @@ static int probe_gpt_pt(blkid_probe pr,
if (!tab)
goto err;
- guid = h->disk_guid;
- swap_efi_guid(&guid);
- blkid_parttable_set_id(tab, (const unsigned char *) &guid);
+ blkid_parttable_set_uuid(tab, (const unsigned char *) &guid);
ssf = blkid_probe_get_sectorsize(pr) / 512;
@@ -410,3 +415,39 @@ const struct blkid_idinfo gpt_pt_idinfo =
.magics = BLKID_NONE_MAGIC
};
+
+
+/* probe for *alone* protective MBR */
+static int probe_pmbr_pt(blkid_probe pr,
+ const struct blkid_idmag *mag __attribute__((__unused__)))
+{
+ int has = 0;
+ struct gpt_entry *e;
+ uint64_t lastlba = 0;
+ struct gpt_header hdr;
+
+ if (last_lba(pr, &lastlba))
+ goto nothing;
+
+ is_pmbr_valid(pr, &has);
+ if (!has)
+ goto nothing;
+
+ if (!get_gpt_header(pr, &hdr, &e, GPT_PRIMARY_LBA, lastlba) &&
+ !get_gpt_header(pr, &hdr, &e, lastlba, lastlba))
+ return 0;
+nothing:
+ return 1;
+}
+
+const struct blkid_idinfo pmbr_pt_idinfo =
+{
+ .name = "PMBR",
+ .probefunc = probe_pmbr_pt,
+ .magics =
+ {
+ { .magic = "\x55\xAA", .len = 2, .sboff = 510 },
+ { NULL }
+ }
+};
+
diff --git a/libblkid/src/partitions/minix.c b/libblkid/src/partitions/minix.c
index 0cd9f432e..0a597fbc4 100644
--- a/libblkid/src/partitions/minix.c
+++ b/libblkid/src/partitions/minix.c
@@ -12,7 +12,6 @@
#include <stdint.h>
#include "partitions.h"
-#include "dos.h"
#include "minix.h"
static int probe_minix_pt(blkid_probe pr,
@@ -40,28 +39,28 @@ static int probe_minix_pt(blkid_probe pr,
if (!parent)
goto nothing;
- if (blkid_partition_get_type(parent) != BLKID_MINIX_PARTITION)
+ if (blkid_partition_get_type(parent) != MBR_MINIX_PARTITION)
goto nothing;
if (blkid_partitions_need_typeonly(pr))
/* caller does not ask for details about partitions */
return 0;
- p = (struct dos_partition *) (data + BLKID_MSDOS_PT_OFFSET);
-
- tab = blkid_partlist_new_parttable(ls, "minix", BLKID_MSDOS_PT_OFFSET);
+ tab = blkid_partlist_new_parttable(ls, "minix", MBR_PT_OFFSET);
if (!tab)
goto err;
- for (i = 0; i < MINIX_MAXPARTITIONS; i++, p++) {
+ for (i = 0, p = mbr_get_partition(data, 0);
+ i < MINIX_MAXPARTITIONS; i++, p++) {
+
uint32_t start, size;
blkid_partition par;
- if (p->sys_type != BLKID_MINIX_PARTITION)
+ if (p->sys_ind != MBR_MINIX_PARTITION)
continue;
- start = dos_partition_start(p);
- size = dos_partition_size(p);
+ start = dos_partition_get_start(p);
+ size = dos_partition_get_size(p);
if (parent && !blkid_is_nested_dimension(parent, start, size)) {
DBG(LOWPROBE, blkid_debug(
@@ -74,7 +73,7 @@ static int probe_minix_pt(blkid_probe pr,
if (!par)
goto err;
- blkid_partition_set_type(par, p->sys_type);
+ blkid_partition_set_type(par, p->sys_ind);
blkid_partition_set_flags(par, p->boot_ind);
}
diff --git a/libblkid/src/partitions/partitions.c b/libblkid/src/partitions/partitions.c
index 87ca0c1f8..6c915d92f 100644
--- a/libblkid/src/partitions/partitions.c
+++ b/libblkid/src/partitions/partitions.c
@@ -37,6 +37,8 @@
*
* @PTTYPE: partition table type (dos, gpt, etc.).
*
+ * @PTUUID: partition table id (uuid for gpt, hex for dos).
+
* @PART_ENTRY_SCHEME: partition table type
*
* @PART_ENTRY_NAME: partition name (gpt and mac only)
@@ -125,6 +127,7 @@ static const struct blkid_idinfo *idinfos[] =
&sun_pt_idinfo,
&dos_pt_idinfo,
&gpt_pt_idinfo,
+ &pmbr_pt_idinfo, /* always after GPT */
&mac_pt_idinfo,
&ultrix_pt_idinfo,
&bsd_pt_idinfo,
@@ -601,11 +604,16 @@ static int partitions_probe(blkid_probe pr, struct blkid_chain *chn)
name = idinfos[i]->name;
- /* all checks passed */
if (!chn->binary)
+ /*
+ * Non-binary interface, set generic variables. Note
+ * that the another variables could be set in prober
+ * functions.
+ */
blkid_probe_set_value(pr, "PTTYPE",
(unsigned char *) name,
strlen(name) + 1);
+
DBG(LOWPROBE, blkid_debug("<-- leaving probing loop (type=%s) [PARTS idx=%d]",
name, chn->idx));
rc = 0;
@@ -994,19 +1002,69 @@ blkid_partition blkid_partlist_devno_to_partition(blkid_partlist ls, dev_t devno
return NULL;
}
+int blkid_parttable_set_uuid(blkid_parttable tab, const unsigned char *id)
+{
+ if (!tab)
+ return -1;
+
+ blkid_unparse_uuid(id, tab->id, sizeof(tab->id));
+ return 0;
+}
+
int blkid_parttable_set_id(blkid_parttable tab, const unsigned char *id)
{
if (!tab)
return -1;
- if (strcmp(tab->type, "gpt") == 0)
- blkid_unparse_uuid(id, tab->id, sizeof(tab->id));
- else if (strcmp(tab->type, "dos") == 0)
- strncpy(tab->id, (const char *) id, sizeof(tab->id));
+ strncpy(tab->id, (const char *) id, sizeof(tab->id));
+ return 0;
+}
+
+/* set PTUUID variable for non-binary API */
+int blkid_partitions_set_ptuuid(blkid_probe pr, unsigned char *uuid)
+{
+ struct blkid_chain *chn = blkid_probe_get_chain(pr);
+ struct blkid_prval *v;
+
+ if (chn->binary || blkid_uuid_is_empty(uuid, 16))
+ return 0;
+
+ v = blkid_probe_assign_value(pr, "PTUUID");
+
+ blkid_unparse_uuid(uuid, (char *) v->data, sizeof(v->data));
+ v->len = 37;
return 0;
}
+/* set PTUUID variable for non-binary API for tables where
+ * the ID is just a string */
+int blkid_partitions_strcpy_ptuuid(blkid_probe pr, char *str)
+{
+ struct blkid_chain *chn = blkid_probe_get_chain(pr);
+ struct blkid_prval *v;
+ size_t len;
+
+ if (chn->binary || !str || !*str)
+ return 0;
+
+ len = strlen((char *) str);
+ if (len > BLKID_PROBVAL_BUFSIZ)
+ len = BLKID_PROBVAL_BUFSIZ;
+
+ v = blkid_probe_assign_value(pr, "PTUUID");
+ if (v) {
+ if (len == BLKID_PROBVAL_BUFSIZ)
+ len--; /* make a space for \0 */
+
+ memcpy((char *) v->data, str, len);
+ v->data[len] = '\0';
+ v->len = len + 1;
+ return 0;
+ }
+ return -1;
+}
+
/**
* blkid_parttable_get_id:
* @tab: partition table
@@ -1134,9 +1192,9 @@ static int partition_get_logical_type(blkid_partition par)
if (par->partno > 4)
return 'L'; /* logical */
- if(par->type == BLKID_DOS_EXTENDED_PARTITION ||
- par->type == BLKID_W95_EXTENDED_PARTITION ||
- par->type == BLKID_LINUX_EXTENDED_PARTITION)
+ if(par->type == MBR_DOS_EXTENDED_PARTITION ||
+ par->type == MBR_W95_EXTENDED_PARTITION ||
+ par->type == MBR_LINUX_EXTENDED_PARTITION)
return 'E';
}
return 'P';
@@ -1224,6 +1282,16 @@ int blkid_partition_set_uuid(blkid_partition par, const unsigned char *uuid)
return 0;
}
+int blkid_partition_gen_uuid(blkid_partition par)
+{
+ if (!par || !par->tab || !*par->tab->id)
+ return -1;
+
+ snprintf(par->uuid, sizeof(par->uuid), "%s-%02x",
+ par->tab->id, par->partno);
+ return 0;
+}
+
/**
* blkid_partition_get_name:
* @par: partition
diff --git a/libblkid/src/partitions/partitions.h b/libblkid/src/partitions/partitions.h
index 496bd4a1e..3651bbb4d 100644
--- a/libblkid/src/partitions/partitions.h
+++ b/libblkid/src/partitions/partitions.h
@@ -2,13 +2,14 @@
#define BLKID_PARTITIONS_H
#include "blkidP.h"
-#include "blkid_parttypes.h"
+#include "pt-mbr.h"
extern int blkid_partitions_get_flags(blkid_probe pr);
extern blkid_parttable blkid_partlist_new_parttable(blkid_partlist ls,
const char *type, blkid_loff_t offset);
+extern int blkid_parttable_set_uuid(blkid_parttable tab, const unsigned char *id);
extern int blkid_parttable_set_id(blkid_parttable tab, const unsigned char *id);
extern blkid_partition blkid_partlist_add_partition(blkid_partlist ls,
@@ -24,6 +25,10 @@ extern int blkid_partitions_do_subprobe(blkid_probe pr,
blkid_partition parent, const struct blkid_idinfo *id);
extern int blkid_partitions_need_typeonly(blkid_probe pr);
+extern int blkid_partitions_set_ptuuid(blkid_probe pr, unsigned char *uuid);
+extern int blkid_partitions_strcpy_ptuuid(blkid_probe pr, char *str);
+
+
extern int blkid_is_nested_dimension(blkid_partition par,
blkid_loff_t start, blkid_loff_t size);
@@ -35,6 +40,7 @@ extern int blkid_partition_set_utf8name(blkid_partition par,
extern int blkid_partition_set_uuid(blkid_partition par,
const unsigned char *uuid);
+extern int blkid_partition_gen_uuid(blkid_partition par);
extern int blkid_partition_set_type(blkid_partition par, int type);
@@ -59,6 +65,7 @@ extern const struct blkid_idinfo mac_pt_idinfo;
extern const struct blkid_idinfo dos_pt_idinfo;
extern const struct blkid_idinfo minix_pt_idinfo;
extern const struct blkid_idinfo gpt_pt_idinfo;
+extern const struct blkid_idinfo pmbr_pt_idinfo;
extern const struct blkid_idinfo ultrix_pt_idinfo;
#endif /* BLKID_PARTITIONS_H */
diff --git a/libblkid/src/partitions/sgi.c b/libblkid/src/partitions/sgi.c
index b292e7150..bcde84f2a 100644
--- a/libblkid/src/partitions/sgi.c
+++ b/libblkid/src/partitions/sgi.c
@@ -13,81 +13,7 @@
#include <stdint.h>
#include "partitions.h"
-
-#define SGI_MAXPARTITIONS 16
-
-/* partition type */
-#define SGI_TYPE_VOLHDR 0x00
-#define SGI_TYPE_VOLULME 0x06 /* entire disk */
-
-struct sgi_device_parameter {
- unsigned char skew;
- unsigned char gap1;
- unsigned char gap2;
- unsigned char sparecyl;
-
- uint16_t pcylcount;
- uint16_t head_vol0;
- uint16_t ntrks; /* tracks in cyl 0 or vol 0 */
-
- unsigned char cmd_tag_queue_depth;
- unsigned char unused0;
-
- uint16_t unused1;
- uint16_t nsect; /* sectors/tracks in cyl 0 or vol 0 */
- uint16_t bytes;
- uint16_t ilfact;
- uint32_t flags; /* controller flags */
- uint32_t datarate;
- uint32_t retries_on_error;
- uint32_t ms_per_word;
- uint16_t xylogics_gap1;
- uint16_t xylogics_syncdelay;
- uint16_t xylogics_readdelay;
- uint16_t xylogics_gap2;
- uint16_t xylogics_readgate;
- uint16_t xylogics_writecont;
-} __attribute__((packed));
-
-struct sgi_disklabel {
- uint32_t magic; /* magic number */
- uint16_t root_part_num; /* # root partition */
- uint16_t swap_part_num; /* # swap partition */
- unsigned char boot_file[16]; /* name of boot file */
-
- struct sgi_device_parameter devparam; /* not used now */
-
- struct sgi_volume {
- unsigned char name[8]; /* name of volume */
- uint32_t block_num; /* logical block number */
- uint32_t num_bytes; /* how big, in bytes */
- } __attribute__((packed)) volume[15];
-
- struct sgi_partition {
- uint32_t num_blocks; /* size in logical blocks */
- uint32_t first_block; /* first logical block */
- uint32_t type; /* type of this partition */
- } __attribute__((packed)) partitions[SGI_MAXPARTITIONS];
-
- /* checksum is the 32bit 2's complement sum of the disklabel */
- uint32_t csum; /* disk label checksum */
- uint32_t padding; /* padding */
-} __attribute__((packed));
-
-static uint32_t count_checksum(struct sgi_disklabel *label)
-{
- int i;
- uint32_t *ptr = (uint32_t *) label;
- uint32_t sum = 0;
-
- i = sizeof(*label) / sizeof(*ptr);
-
- while (i--)
- sum += be32_to_cpu(ptr[i]);
-
- return sum;
-}
-
+#include "pt-sgi.h"
static int probe_sgi_pt(blkid_probe pr,
const struct blkid_idmag *mag __attribute__((__unused__)))
@@ -102,7 +28,7 @@ static int probe_sgi_pt(blkid_probe pr,
if (!l)
goto nothing;
- if (count_checksum(l)) {
+ if (sgi_pt_checksum(l)) {
DBG(LOWPROBE, blkid_debug(
"detected corrupted sgi disk label -- ignore"));
goto nothing;
@@ -126,7 +52,7 @@ static int probe_sgi_pt(blkid_probe pr,
uint32_t type = be32_to_cpu(p->type);
blkid_partition par;
- if (size == 0 || type == SGI_TYPE_VOLULME ||
+ if (size == 0 || type == SGI_TYPE_ENTIRE_DISK ||
type == SGI_TYPE_VOLHDR) {
blkid_partlist_increment_partno(ls);
continue;
diff --git a/libblkid/src/probe.c b/libblkid/src/probe.c
index 954b08708..4b0c99796 100644
--- a/libblkid/src/probe.c
+++ b/libblkid/src/probe.c
@@ -336,6 +336,16 @@ struct blkid_chain *blkid_probe_get_chain(blkid_probe pr)
return pr->cur_chain;
}
+static const char *blkid_probe_get_probername(blkid_probe pr)
+{
+ struct blkid_chain *chn = blkid_probe_get_chain(pr);
+
+ if (chn && chn->idx >= 0 && chn->idx < chn->driver->nidinfos)
+ return chn->driver->idinfos[chn->idx]->name;
+
+ return NULL;
+}
+
void *blkid_probe_get_binary_data(blkid_probe pr, struct blkid_chain *chn)
{
int rc, org_prob_flags;
@@ -1341,6 +1351,31 @@ int blkid_probe_set_magic(blkid_probe pr, blkid_loff_t offset,
return rc;
}
+int blkid_probe_verify_csum(blkid_probe pr, uint64_t csum, uint64_t expected)
+{
+ if (csum != expected) {
+ struct blkid_chain *chn = blkid_probe_get_chain(pr);
+
+ DBG(LOWPROBE, blkid_debug(
+ "incorrect checksum for type %s,"
+ " got %jX, expected %jX",
+ blkid_probe_get_probername(pr),
+ csum, expected));
+ /*
+ * Accept bad checksum if BLKID_SUBLKS_BADCSUM flags is set
+ */
+ if (chn->driver->id == BLKID_CHAIN_SUBLKS
+ && (chn->flags & BLKID_SUBLKS_BADCSUM)) {
+ blkid_probe_set_value(pr, "SBBADCSUM", (unsigned char *) "1", 2);
+ goto accept;
+ }
+ return 0; /* bad checksum */
+ }
+
+accept:
+ return 1;
+}
+
/**
* blkid_probe_get_devno:
* @pr: probe
@@ -1637,6 +1672,16 @@ void blkid_unparse_uuid(const unsigned char *uuid, char *str, size_t len)
}
#endif
+/* like uuid_is_null() from libuuid, but works with arbitrary size of UUID */
+int blkid_uuid_is_empty(const unsigned char *buf, size_t len)
+{
+ size_t i;
+
+ for (i = 0; i < len; i++)
+ if (buf[i])
+ return 0;
+ return 1;
+}
/* Removes whitespace from the right-hand side of a string (trailing
* whitespace).
diff --git a/libblkid/src/save.c b/libblkid/src/save.c
index 86eda6cbc..424017a32 100644
--- a/libblkid/src/save.c
+++ b/libblkid/src/save.c
@@ -21,6 +21,9 @@
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
+
+#include "closestream.h"
+
#include "blkidP.h"
static int save_dev(blkid_dev dev, FILE *file)
@@ -148,7 +151,9 @@ int blkid_flush_cache(blkid_cache cache)
ret = 1;
}
- fclose(file);
+ if (close_stream(file) != 0)
+ DBG(SAVE, blkid_debug("write failed: %s", filename));
+
if (opened != filename) {
if (ret < 0) {
unlink(opened);
diff --git a/libblkid/src/superblocks/bcache.c b/libblkid/src/superblocks/bcache.c
new file mode 100644
index 000000000..303f7eeb9
--- /dev/null
+++ b/libblkid/src/superblocks/bcache.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2013 Rolf Fokkens <rolf@fokkens.nl>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ *
+ * Based on code fragments from bcache-tools by Kent Overstreet:
+ * http://evilpiepirate.org/git/bcache-tools.git
+ */
+
+#include <stddef.h>
+#include <stdio.h>
+
+#include "superblocks.h"
+#include "crc64.h"
+
+#define SB_LABEL_SIZE 32
+#define SB_JOURNAL_BUCKETS 256U
+
+#define node(i, j) ((i)->d + (j))
+#define end(i) node(i, (i)->keys)
+
+static const char bcache_magic[] = {
+ 0xc6, 0x85, 0x73, 0xf6, 0x4e, 0x1a, 0x45, 0xca,
+ 0x82, 0x65, 0xf5, 0x7f, 0x48, 0xba, 0x6d, 0x81
+};
+
+struct bcache_super_block {
+ uint64_t csum;
+ uint64_t offset; /* sector where this sb was written */
+ uint64_t version;
+
+ uint8_t magic[16];
+
+ uint8_t uuid[16];
+ union {
+ uint8_t set_uuid[16];
+ uint64_t set_magic;
+ };
+ uint8_t label[SB_LABEL_SIZE];
+
+ uint64_t flags;
+ uint64_t seq;
+ uint64_t pad[8];
+
+ union {
+ struct {
+ /* Cache devices */
+ uint64_t nbuckets; /* device size */
+
+ uint16_t block_size; /* sectors */
+ uint16_t bucket_size; /* sectors */
+
+ uint16_t nr_in_set;
+ uint16_t nr_this_dev;
+ };
+ struct {
+ /* Backing devices */
+ uint64_t data_offset;
+
+ /*
+ * block_size from the cache device section is still used by
+ * backing devices, so don't add anything here until we fix
+ * things to not need it for backing devices anymore
+ */
+ };
+ };
+
+ uint32_t last_mount; /* time_t */
+
+ uint16_t first_bucket;
+ union {
+ uint16_t njournal_buckets;
+ uint16_t keys;
+ };
+ uint64_t d[SB_JOURNAL_BUCKETS]; /* journal buckets */
+};
+
+/* magic string */
+#define BCACHE_SB_MAGIC bcache_magic
+/* magic string len */
+#define BCACHE_SB_MAGIC_LEN sizeof (bcache_magic)
+/* super block offset */
+#define BCACHE_SB_OFF 0x1000
+/* supper block offset in kB */
+#define BCACHE_SB_KBOFF (BCACHE_SB_OFF >> 10)
+/* magic string offset within super block */
+#define BCACHE_SB_MAGIC_OFF offsetof (struct bcache_super_block, magic)
+
+static uint64_t bcache_crc64(struct bcache_super_block *bcs)
+{
+ unsigned char *data = (unsigned char *) bcs;
+ size_t sz;
+
+ data += 8; /* skip csum field */
+ sz = (unsigned char *) end(bcs) - data;
+
+ return crc64(0xFFFFFFFFFFFFFFFFULL, data, sz) ^ 0xFFFFFFFFFFFFFFFFULL;
+}
+
+static int probe_bcache (blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct bcache_super_block *bcs;
+
+ bcs = blkid_probe_get_sb(pr, mag, struct bcache_super_block);
+ if (!bcs)
+ return -1;
+
+ if (le64_to_cpu(bcs->offset) != BCACHE_SB_OFF / 512)
+ return 1;
+ if (!blkid_probe_verify_csum(pr, bcache_crc64(bcs), le64_to_cpu(bcs->csum)))
+ return 1;
+
+ if (blkid_probe_set_uuid(pr, bcs->uuid) < 0)
+ return -1;
+
+ return 0;
+};
+
+const struct blkid_idinfo bcache_idinfo =
+{
+ .name = "bcache",
+ .usage = BLKID_USAGE_OTHER,
+ .probefunc = probe_bcache,
+ .minsz = 8192,
+ .magics =
+ {
+ { .magic = BCACHE_SB_MAGIC
+ , .len = BCACHE_SB_MAGIC_LEN
+ , .kboff = BCACHE_SB_KBOFF
+ , .sboff = BCACHE_SB_MAGIC_OFF
+ } ,
+ { NULL }
+ }
+};
+
diff --git a/libblkid/src/superblocks/ext.c b/libblkid/src/superblocks/ext.c
index c23959322..8d57cb5e4 100644
--- a/libblkid/src/superblocks/ext.c
+++ b/libblkid/src/superblocks/ext.c
@@ -333,6 +333,8 @@ static int probe_jbd(blkid_probe pr,
return -BLKID_ERR_PARAM;
ext_get_info(pr, 2, es);
+ blkid_probe_set_uuid_as(pr, es->s_uuid, "LOGUUID");
+
return 0;
}
diff --git a/libblkid/src/superblocks/lvm.c b/libblkid/src/superblocks/lvm.c
index dc38f2e2c..65c7c35a4 100644
--- a/libblkid/src/superblocks/lvm.c
+++ b/libblkid/src/superblocks/lvm.c
@@ -97,13 +97,12 @@ static int probe_lvm2(blkid_probe pr, const struct blkid_idmag *mag)
if (le64_to_cpu(label->sector_xl) != (unsigned) sector)
return 1;
- if (lvm2_calc_crc(&label->offset_xl, LVM2_LABEL_SIZE -
- ((char *) &label->offset_xl - (char *) label)) !=
- le32_to_cpu(label->crc_xl)) {
- DBG(PROBE, blkid_debug("LVM2: label checksum incorrect at sector %d",
- sector));
+ if (!blkid_probe_verify_csum(
+ pr, lvm2_calc_crc(
+ &label->offset_xl, LVM2_LABEL_SIZE -
+ ((char *) &label->offset_xl - (char *) label)),
+ le32_to_cpu(label->crc_xl)))
return 1;
- }
format_lvm_uuid(uuid, (char *) label->pv_uuid);
blkid_probe_sprintf_uuid(pr, label->pv_uuid, sizeof(label->pv_uuid),
diff --git a/libblkid/src/superblocks/nilfs.c b/libblkid/src/superblocks/nilfs.c
index 1f8f3a69f..24ccf633e 100644
--- a/libblkid/src/superblocks/nilfs.c
+++ b/libblkid/src/superblocks/nilfs.c
@@ -63,35 +63,60 @@ struct nilfs_super_block {
uint32_t s_reserved[192];
};
-/* nilfs2 magic string */
-#define NILFS_SB_MAGIC "\x34\x34"
-/* nilfs2 super block offset */
-#define NILFS_SB_OFF 0x400
-/* nilfs2 super block offset in kB */
-#define NILFS_SB_KBOFF (NILFS_SB_OFF >> 10)
-/* nilfs2 magic string offset within super block */
-#define NILFS_MAG_OFF 6
+#define NILFS_SB_MAGIC 0x3434
+#define NILFS_SB_OFFSET 0x400
-static int probe_nilfs2(blkid_probe pr, const struct blkid_idmag *mag)
+static int nilfs_valid_sb(blkid_probe pr, struct nilfs_super_block *sb)
{
- struct nilfs_super_block *sb;
static unsigned char sum[4];
const int sumoff = offsetof(struct nilfs_super_block, s_sum);
size_t bytes;
uint32_t crc;
- sb = blkid_probe_get_sb(pr, mag, struct nilfs_super_block);
- if (!sb)
- return -1;
+ if (!sb || le16_to_cpu(sb->s_magic) != NILFS_SB_MAGIC)
+ return 0;
bytes = le16_to_cpu(sb->s_bytes);
crc = crc32(le32_to_cpu(sb->s_crc_seed), (unsigned char *)sb, sumoff);
crc = crc32(crc, sum, 4);
crc = crc32(crc, (unsigned char *)sb + sumoff + 4, bytes - sumoff - 4);
- if (crc != le32_to_cpu(sb->s_sum))
+ return blkid_probe_verify_csum(pr, crc, le32_to_cpu(sb->s_sum));
+}
+
+static int probe_nilfs2(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct nilfs_super_block *sb, *sbp, *sbb;
+ int valid[2], swp = 0;
+
+ /* primary */
+ sbp = (struct nilfs_super_block *) blkid_probe_get_buffer(
+ pr, NILFS_SB_OFFSET, sizeof(struct nilfs_super_block));
+ if (!sbp)
+ return -1;
+ /* backup */
+ sbb = (struct nilfs_super_block *) blkid_probe_get_buffer(
+ pr, ((pr->size / 0x200) - 8) * 0x200, sizeof(struct nilfs_super_block));
+ if (!sbp)
return -1;
+ /*
+ * Compare two super blocks and set 1 in swp if the secondary
+ * super block is valid and newer. Otherwise, set 0 in swp.
+ */
+ valid[0] = nilfs_valid_sb(pr, sbp);
+ valid[1] = nilfs_valid_sb(pr, sbb);
+ if (!valid[0] && !valid[1])
+ return 1;
+
+ swp = valid[1] && (!valid[0] ||
+ le64_to_cpu(sbp->s_last_cno) >
+ le64_to_cpu(sbb->s_last_cno));
+ sb = swp ? sbb : sbp;
+
+ DBG(LOWPROBE, blkid_debug("nilfs2: primary=%d, backup=%d, swap=%d",
+ valid[0], valid[1], swp));
+
if (strlen(sb->s_volume_name))
blkid_probe_set_label(pr, (unsigned char *) sb->s_volume_name,
sizeof(sb->s_volume_name));
@@ -107,14 +132,7 @@ const struct blkid_idinfo nilfs2_idinfo =
.name = "nilfs2",
.usage = BLKID_USAGE_FILESYSTEM,
.probefunc = probe_nilfs2,
- .magics =
- {
- {
- .magic = NILFS_SB_MAGIC,
- .len = 2,
- .kboff = NILFS_SB_KBOFF,
- .sboff = NILFS_MAG_OFF
- },
- { NULL }
- }
+ /* default min.size is 128MiB, but 1MiB for "mkfs.nilfs2 -b 1024 -B 16" */
+ .minsz = (1024 * 1024),
+ .magics = BLKID_NONE_MAGIC
};
diff --git a/libblkid/src/superblocks/silicon_raid.c b/libblkid/src/superblocks/silicon_raid.c
index aeab4bf31..10a302313 100644
--- a/libblkid/src/superblocks/silicon_raid.c
+++ b/libblkid/src/superblocks/silicon_raid.c
@@ -67,7 +67,7 @@ struct silicon_metadata {
#define SILICON_MAGIC 0x2F000000
-static int checksum(struct silicon_metadata *sil)
+static uint16_t silraid_checksum(struct silicon_metadata *sil)
{
int sum = 0;
unsigned short count = offsetof(struct silicon_metadata, checksum1) / 2;
@@ -78,7 +78,7 @@ static int checksum(struct silicon_metadata *sil)
sum += le16_to_cpu(x);
}
- return (-sum & 0xFFFF) == le16_to_cpu(sil->checksum1);
+ return (-sum & 0xFFFF);
}
static int probe_silraid(blkid_probe pr,
@@ -101,13 +101,11 @@ static int probe_silraid(blkid_probe pr,
return -1;
if (le32_to_cpu(sil->magic) != SILICON_MAGIC)
- return -1;
+ return 1;
if (sil->disk_number >= 8)
- return -1;
- if (!checksum(sil)) {
- DBG(LOWPROBE, blkid_debug("silicon raid: incorrect checksum"));
- return -1;
- }
+ return 1;
+ if (!blkid_probe_verify_csum(pr, silraid_checksum(sil), le16_to_cpu(sil->checksum1)))
+ return 1;
if (blkid_probe_sprintf_version(pr, "%u.%u",
le16_to_cpu(sil->major_ver),
diff --git a/libblkid/src/superblocks/superblocks.c b/libblkid/src/superblocks/superblocks.c
index 03bcabc91..c6394c4b3 100644
--- a/libblkid/src/superblocks/superblocks.c
+++ b/libblkid/src/superblocks/superblocks.c
@@ -49,6 +49,8 @@
*
* @UUID_SUB: subvolume uuid (e.g. btrfs)
*
+ * @LOGUUID: external log UUID (e.g. xfs)
+ *
* @UUID_RAW: raw UUID from FS superblock
*
* @EXT_JOURNAL: external journal UUID
@@ -99,6 +101,7 @@ static const struct blkid_idinfo *idinfos[] =
&adraid_idinfo,
&jmraid_idinfo,
+ &bcache_idinfo,
&drbd_idinfo,
&drbdproxy_datalog_idinfo,
&lvm2_idinfo,
@@ -113,6 +116,7 @@ static const struct blkid_idinfo *idinfos[] =
&swsuspend_idinfo,
&swap_idinfo,
&xfs_idinfo,
+ &xfs_log_idinfo,
&ext4dev_idinfo,
&ext4_idinfo,
&ext3_idinfo,
@@ -617,17 +621,6 @@ int blkid_probe_set_utf8label(blkid_probe pr, unsigned char *label,
return 0;
}
-/* like uuid_is_null() from libuuid, but works with arbitrary size of UUID */
-static int uuid_is_empty(const unsigned char *buf, size_t len)
-{
- size_t i;
-
- for (i = 0; i < len; i++)
- if (buf[i])
- return 0;
- return 1;
-}
-
int blkid_probe_sprintf_uuid(blkid_probe pr, unsigned char *uuid,
size_t len, const char *fmt, ...)
{
@@ -638,7 +631,7 @@ int blkid_probe_sprintf_uuid(blkid_probe pr, unsigned char *uuid,
if (len > BLKID_PROBVAL_BUFSIZ)
len = BLKID_PROBVAL_BUFSIZ;
- if (uuid_is_empty(uuid, len))
+ if (blkid_uuid_is_empty(uuid, len))
return 0;
if ((chn->flags & BLKID_SUBLKS_UUIDRAW) &&
@@ -703,7 +696,7 @@ int blkid_probe_set_uuid_as(blkid_probe pr, unsigned char *uuid, const char *nam
struct blkid_chain *chn = blkid_probe_get_chain(pr);
struct blkid_prval *v;
- if (uuid_is_empty(uuid, 16))
+ if (blkid_uuid_is_empty(uuid, 16))
return 0;
if (!name) {
diff --git a/libblkid/src/superblocks/superblocks.h b/libblkid/src/superblocks/superblocks.h
index 2e5235113..2cae66a41 100644
--- a/libblkid/src/superblocks/superblocks.h
+++ b/libblkid/src/superblocks/superblocks.h
@@ -29,6 +29,7 @@ extern const struct blkid_idinfo ext2_idinfo;
extern const struct blkid_idinfo jbd_idinfo;
extern const struct blkid_idinfo jfs_idinfo;
extern const struct blkid_idinfo xfs_idinfo;
+extern const struct blkid_idinfo xfs_log_idinfo;
extern const struct blkid_idinfo gfs_idinfo;
extern const struct blkid_idinfo gfs2_idinfo;
extern const struct blkid_idinfo romfs_idinfo;
@@ -71,6 +72,7 @@ extern const struct blkid_idinfo befs_idinfo;
extern const struct blkid_idinfo nilfs2_idinfo;
extern const struct blkid_idinfo exfat_idinfo;
extern const struct blkid_idinfo f2fs_idinfo;
+extern const struct blkid_idinfo bcache_idinfo;
/*
* superblock functions
diff --git a/libblkid/src/superblocks/swap.c b/libblkid/src/superblocks/swap.c
index 679c81804..4297a9c40 100644
--- a/libblkid/src/superblocks/swap.c
+++ b/libblkid/src/superblocks/swap.c
@@ -47,7 +47,7 @@ static int swap_set_info(blkid_probe pr, const char *version)
return -1;
/* SWAPSPACE2 - check for wrong version or zeroed pagecount */
- if (strcmp(version, "2") == 0) {
+ if (strcmp(version, "1") == 0) {
if (hdr->version != 1 && swab32(hdr->version) != 1) {
DBG(LOWPROBE, blkid_debug("incorrect swap version"));
return -1;
@@ -88,11 +88,11 @@ static int probe_swap(blkid_probe pr, const struct blkid_idmag *mag)
if (!memcmp(mag->magic, "SWAP-SPACE", mag->len)) {
/* swap v0 doesn't support LABEL or UUID */
- blkid_probe_set_version(pr, "1");
+ blkid_probe_set_version(pr, "0");
return 0;
} else if (!memcmp(mag->magic, "SWAPSPACE2", mag->len))
- return swap_set_info(pr, "2");
+ return swap_set_info(pr, "1");
return -1;
}
diff --git a/libblkid/src/superblocks/via_raid.c b/libblkid/src/superblocks/via_raid.c
index eba7e4bf2..5c15167aa 100644
--- a/libblkid/src/superblocks/via_raid.c
+++ b/libblkid/src/superblocks/via_raid.c
@@ -42,7 +42,7 @@ static uint8_t via_checksum(struct via_metadata *v)
while (i--)
cs += ((uint8_t*) v)[i];
- return cs == v->checksum;
+ return cs;
}
static int probe_viaraid(blkid_probe pr,
@@ -52,9 +52,9 @@ static int probe_viaraid(blkid_probe pr,
struct via_metadata *v;
if (pr->size < 0x10000)
- return -1;
+ return 1;
if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr))
- return -1;
+ return 1;
off = ((pr->size / 0x200)-1) * 0x200;
@@ -64,12 +64,14 @@ static int probe_viaraid(blkid_probe pr,
sizeof(struct via_metadata));
if (!v)
return -1;
+
if (le16_to_cpu(v->signature) != VIA_SIGNATURE)
- return -1;
+ return 1;
if (v->version_number > 2)
- return -1;
- if (!via_checksum(v))
- return -1;
+ return 1;
+ if (!blkid_probe_verify_csum(pr, via_checksum(v), v->checksum))
+ return 1;
+
if (blkid_probe_sprintf_version(pr, "%u", v->version_number) != 0)
return -1;
if (blkid_probe_set_magic(pr, off,
diff --git a/libblkid/src/superblocks/xfs.c b/libblkid/src/superblocks/xfs.c
index 1399fe13a..f4bb72188 100644
--- a/libblkid/src/superblocks/xfs.c
+++ b/libblkid/src/superblocks/xfs.c
@@ -4,6 +4,7 @@
* Copyright (C) 2001 by Andreas Dilger
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
* Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ * Copyright (C) 2013 Eric Sandeen <sandeen@redhat.com>
*
* This file may be redistributed under the terms of the
* GNU Lesser General Public License.
@@ -20,20 +21,143 @@
#include "superblocks.h"
struct xfs_super_block {
- unsigned char xs_magic[4];
- uint32_t xs_blocksize;
- uint64_t xs_dblocks;
- uint64_t xs_rblocks;
- uint32_t xs_dummy1[2];
- unsigned char xs_uuid[16];
- uint32_t xs_dummy2[15];
- char xs_fname[12];
- uint32_t xs_dummy3[2];
- uint64_t xs_icount;
- uint64_t xs_ifree;
- uint64_t xs_fdblocks;
+ uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */
+ uint32_t sb_blocksize; /* logical block size, bytes */
+ uint64_t sb_dblocks; /* number of data blocks */
+ uint64_t sb_rblocks; /* number of realtime blocks */
+ uint64_t sb_rextents; /* number of realtime extents */
+ unsigned char sb_uuid[16]; /* file system unique id */
+ uint64_t sb_logstart; /* starting block of log if internal */
+ uint64_t sb_rootino; /* root inode number */
+ uint64_t sb_rbmino; /* bitmap inode for realtime extents */
+ uint64_t sb_rsumino; /* summary inode for rt bitmap */
+ uint32_t sb_rextsize; /* realtime extent size, blocks */
+ uint32_t sb_agblocks; /* size of an allocation group */
+ uint32_t sb_agcount; /* number of allocation groups */
+ uint32_t sb_rbmblocks; /* number of rt bitmap blocks */
+ uint32_t sb_logblocks; /* number of log blocks */
+
+ uint16_t sb_versionnum; /* header version == XFS_SB_VERSION */
+ uint16_t sb_sectsize; /* volume sector size, bytes */
+ uint16_t sb_inodesize; /* inode size, bytes */
+ uint16_t sb_inopblock; /* inodes per block */
+ char sb_fname[12]; /* file system name */
+ uint8_t sb_blocklog; /* log2 of sb_blocksize */
+ uint8_t sb_sectlog; /* log2 of sb_sectsize */
+ uint8_t sb_inodelog; /* log2 of sb_inodesize */
+ uint8_t sb_inopblog; /* log2 of sb_inopblock */
+ uint8_t sb_agblklog; /* log2 of sb_agblocks (rounded up) */
+ uint8_t sb_rextslog; /* log2 of sb_rextents */
+ uint8_t sb_inprogress; /* mkfs is in progress, don't mount */
+ uint8_t sb_imax_pct; /* max % of fs for inode space */
+ /* statistics */
+ uint64_t sb_icount; /* allocated inodes */
+ uint64_t sb_ifree; /* free inodes */
+ uint64_t sb_fdblocks; /* free data blocks */
+ uint64_t sb_frextents; /* free realtime extents */
+
+ /* this is not all... but enough for libblkid */
+
} __attribute__((packed));
+#define XFS_MIN_BLOCKSIZE_LOG 9 /* i.e. 512 bytes */
+#define XFS_MAX_BLOCKSIZE_LOG 16 /* i.e. 65536 bytes */
+#define XFS_MIN_BLOCKSIZE (1 << XFS_MIN_BLOCKSIZE_LOG)
+#define XFS_MAX_BLOCKSIZE (1 << XFS_MAX_BLOCKSIZE_LOG)
+#define XFS_MIN_SECTORSIZE_LOG 9 /* i.e. 512 bytes */
+#define XFS_MAX_SECTORSIZE_LOG 15 /* i.e. 32768 bytes */
+#define XFS_MIN_SECTORSIZE (1 << XFS_MIN_SECTORSIZE_LOG)
+#define XFS_MAX_SECTORSIZE (1 << XFS_MAX_SECTORSIZE_LOG)
+
+#define XFS_DINODE_MIN_LOG 8
+#define XFS_DINODE_MAX_LOG 11
+#define XFS_DINODE_MIN_SIZE (1 << XFS_DINODE_MIN_LOG)
+#define XFS_DINODE_MAX_SIZE (1 << XFS_DINODE_MAX_LOG)
+
+#define XFS_MAX_RTEXTSIZE (1024 * 1024 * 1024) /* 1GB */
+#define XFS_DFL_RTEXTSIZE (64 * 1024) /* 64kB */
+#define XFS_MIN_RTEXTSIZE (4 * 1024) /* 4kB */
+
+#define XFS_MIN_AG_BLOCKS 64
+#define XFS_MAX_DBLOCKS(s) ((uint64_t)(s)->sb_agcount * (s)->sb_agblocks)
+#define XFS_MIN_DBLOCKS(s) ((uint64_t)((s)->sb_agcount - 1) * \
+ (s)->sb_agblocks + XFS_MIN_AG_BLOCKS)
+
+
+static void sb_from_disk(struct xfs_super_block *from,
+ struct xfs_super_block *to)
+{
+
+ to->sb_magicnum = be32_to_cpu(from->sb_magicnum);
+ to->sb_blocksize = be32_to_cpu(from->sb_blocksize);
+ to->sb_dblocks = be64_to_cpu(from->sb_dblocks);
+ to->sb_rblocks = be64_to_cpu(from->sb_rblocks);
+ to->sb_rextents = be64_to_cpu(from->sb_rextents);
+ to->sb_logstart = be64_to_cpu(from->sb_logstart);
+ to->sb_rootino = be64_to_cpu(from->sb_rootino);
+ to->sb_rbmino = be64_to_cpu(from->sb_rbmino);
+ to->sb_rsumino = be64_to_cpu(from->sb_rsumino);
+ to->sb_rextsize = be32_to_cpu(from->sb_rextsize);
+ to->sb_agblocks = be32_to_cpu(from->sb_agblocks);
+ to->sb_agcount = be32_to_cpu(from->sb_agcount);
+ to->sb_rbmblocks = be32_to_cpu(from->sb_rbmblocks);
+ to->sb_logblocks = be32_to_cpu(from->sb_logblocks);
+ to->sb_versionnum = be16_to_cpu(from->sb_versionnum);
+ to->sb_sectsize = be16_to_cpu(from->sb_sectsize);
+ to->sb_inodesize = be16_to_cpu(from->sb_inodesize);
+ to->sb_inopblock = be16_to_cpu(from->sb_inopblock);
+ to->sb_blocklog = from->sb_blocklog;
+ to->sb_sectlog = from->sb_sectlog;
+ to->sb_inodelog = from->sb_inodelog;
+ to->sb_inopblog = from->sb_inopblog;
+ to->sb_agblklog = from->sb_agblklog;
+ to->sb_rextslog = from->sb_rextslog;
+ to->sb_inprogress = from->sb_inprogress;
+ to->sb_imax_pct = from->sb_imax_pct;
+ to->sb_icount = be64_to_cpu(from->sb_icount);
+ to->sb_ifree = be64_to_cpu(from->sb_ifree);
+ to->sb_fdblocks = be64_to_cpu(from->sb_fdblocks);
+ to->sb_frextents = be64_to_cpu(from->sb_frextents);
+}
+
+static int xfs_verify_sb(struct xfs_super_block *ondisk)
+{
+ struct xfs_super_block sb, *sbp = &sb;
+
+ /* beXX_to_cpu(), but don't convert UUID and fsname! */
+ sb_from_disk(ondisk, sbp);
+
+ /* sanity checks, we don't want to rely on magic string only */
+ if (sbp->sb_agcount <= 0 ||
+ sbp->sb_sectsize < XFS_MIN_SECTORSIZE ||
+ sbp->sb_sectsize > XFS_MAX_SECTORSIZE ||
+ sbp->sb_sectlog < XFS_MIN_SECTORSIZE_LOG ||
+ sbp->sb_sectlog > XFS_MAX_SECTORSIZE_LOG ||
+ sbp->sb_sectsize != (1 << sbp->sb_sectlog) ||
+ sbp->sb_blocksize < XFS_MIN_BLOCKSIZE ||
+ sbp->sb_blocksize > XFS_MAX_BLOCKSIZE ||
+ sbp->sb_blocklog < XFS_MIN_BLOCKSIZE_LOG ||
+ sbp->sb_blocklog > XFS_MAX_BLOCKSIZE_LOG ||
+ sbp->sb_blocksize != (1 << sbp->sb_blocklog) ||
+ sbp->sb_inodesize < XFS_DINODE_MIN_SIZE ||
+ sbp->sb_inodesize > XFS_DINODE_MAX_SIZE ||
+ sbp->sb_inodelog < XFS_DINODE_MIN_LOG ||
+ sbp->sb_inodelog > XFS_DINODE_MAX_LOG ||
+ sbp->sb_inodesize != (1 << sbp->sb_inodelog) ||
+ (sbp->sb_blocklog - sbp->sb_inodelog != sbp->sb_inopblog) ||
+ (sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE) ||
+ (sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE) ||
+ (sbp->sb_imax_pct > 100 /* zero sb_imax_pct is valid */) ||
+ sbp->sb_dblocks == 0 ||
+ sbp->sb_dblocks > XFS_MAX_DBLOCKS(sbp) ||
+ sbp->sb_dblocks < XFS_MIN_DBLOCKS(sbp))
+ return 0;
+
+ /* TODO: version 5 has also checksum CRC32, maybe we can check it too */
+
+ return 1;
+}
+
static int probe_xfs(blkid_probe pr, const struct blkid_idmag *mag)
{
struct xfs_super_block *xs;
@@ -42,10 +166,13 @@ static int probe_xfs(blkid_probe pr, const struct blkid_idmag *mag)
if (!xs)
return -1;
- if (strlen(xs->xs_fname))
- blkid_probe_set_label(pr, (unsigned char *) xs->xs_fname,
- sizeof(xs->xs_fname));
- blkid_probe_set_uuid(pr, xs->xs_uuid);
+ if (!xfs_verify_sb(xs))
+ return 1;
+
+ if (strlen(xs->sb_fname))
+ blkid_probe_set_label(pr, (unsigned char *) xs->sb_fname,
+ sizeof(xs->sb_fname));
+ blkid_probe_set_uuid(pr, xs->sb_uuid);
return 0;
}
@@ -61,3 +188,90 @@ const struct blkid_idinfo xfs_idinfo =
}
};
+struct xlog_rec_header {
+ uint32_t h_magicno;
+ uint32_t h_dummy1[1];
+ uint32_t h_version;
+ uint32_t h_len;
+ uint32_t h_dummy2[71];
+ uint32_t h_fmt;
+ unsigned char h_uuid[16];
+} __attribute__((packed));
+
+#define XLOG_HEADER_MAGIC_NUM 0xFEEDbabe
+
+/*
+ * For very small filesystems, the minimum log size
+ * can be smaller, but that seems vanishingly unlikely
+ * when used with an external log (which is used for
+ * performance reasons; tiny conflicts with that goal).
+ */
+#define XFS_MIN_LOG_BYTES (10 * 1024 * 1024)
+
+#define XLOG_FMT_LINUX_LE 1
+#define XLOG_FMT_LINUX_BE 2
+#define XLOG_FMT_IRIX_BE 3
+
+#define XLOG_VERSION_1 1
+#define XLOG_VERSION_2 2 /* Large IClogs, Log sunit */
+#define XLOG_VERSION_OKBITS (XLOG_VERSION_1 | XLOG_VERSION_2)
+
+static int xlog_valid_rec_header(struct xlog_rec_header *rhead)
+{
+ uint32_t hlen;
+
+ if (rhead->h_magicno != cpu_to_be32(XLOG_HEADER_MAGIC_NUM))
+ return 0;
+
+ if (!rhead->h_version ||
+ (be32_to_cpu(rhead->h_version) & (~XLOG_VERSION_OKBITS)))
+ return 0;
+
+ /* LR body must have data or it wouldn't have been written */
+ hlen = be32_to_cpu(rhead->h_len);
+ if (hlen <= 0 || hlen > INT_MAX)
+ return 0;
+
+ if (rhead->h_fmt != cpu_to_be32(XLOG_FMT_LINUX_LE) &&
+ rhead->h_fmt != cpu_to_be32(XLOG_FMT_LINUX_BE) &&
+ rhead->h_fmt != cpu_to_be32(XLOG_FMT_IRIX_BE))
+ return 0;
+
+ return 1;
+}
+
+/* xlog record header will be in some sector in the first 256k */
+static int probe_xfs_log(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ int i;
+ struct xlog_rec_header *rhead;
+ unsigned char *buf;
+
+ buf = blkid_probe_get_buffer(pr, 0, 256*1024);
+ if (!buf)
+ return -1;
+
+ if (memcmp(buf, "XFSB", 4) == 0)
+ return 1; /* this is regular XFS, ignore */
+
+ /* check the first 512 512-byte sectors */
+ for (i = 0; i < 512; i++) {
+ rhead = (struct xlog_rec_header *)&buf[i*512];
+
+ if (xlog_valid_rec_header(rhead)) {
+ blkid_probe_set_uuid_as(pr, rhead->h_uuid, "LOGUUID");
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+const struct blkid_idinfo xfs_log_idinfo =
+{
+ .name = "xfs_external_log",
+ .usage = BLKID_USAGE_OTHER,
+ .probefunc = probe_xfs_log,
+ .magics = BLKID_NONE_MAGIC,
+ .minsz = XFS_MIN_LOG_BYTES,
+};
diff --git a/libblkid/src/tag.c b/libblkid/src/tag.c
index 3a7095013..e095ab1be 100644
--- a/libblkid/src/tag.c
+++ b/libblkid/src/tag.c
@@ -237,14 +237,18 @@ int blkid_parse_tag_string(const char *token, char **ret_type, char **ret_val)
goto errout; /* missing closing quote */
*cp = '\0';
}
- value = value && *value ? strdup(value) : NULL;
- if (!value)
- goto errout;
+
+ if (ret_val) {
+ value = value && *value ? strdup(value) : NULL;
+ if (!value)
+ goto errout;
+ *ret_val = value;
+ }
if (ret_type)
*ret_type = name;
- if (ret_val)
- *ret_val = value;
+ else
+ free(name);
return 0;