summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaMont Jones <lamont@debian.org>2010-02-03 16:26:41 -0700
committerLaMont Jones <lamont@debian.org>2010-02-03 16:26:41 -0700
commit2bd3ccad2133d3aefdc2caeb3034c0725414d2e9 (patch)
tree64db9a6968f1d398d386ddc1d46d2e0a7396ff44
parentc3701c1d965cdc905bd580ece68a1c4008b4d1b0 (diff)
parentcdfb1e88228c10c28f8bfe0f4b0ff1b3b06d1ed4 (diff)
downloadutil-linux-old-2bd3ccad2133d3aefdc2caeb3034c0725414d2e9.tar.gz
Merge remote branch 'origin/master'
Conflicts: tests/ts/blkid/images-fs/adaptec-raid.img.bz2 tests/ts/blkid/images-fs/ddf-raid.img.bz2 tests/ts/blkid/images-fs/gfs2.img.bz2 tests/ts/blkid/images-fs/hpt37x-raid.img.bz2 tests/ts/blkid/images-fs/isw-raid.img.bz2 tests/ts/blkid/images-fs/jbd.img.bz2 tests/ts/blkid/images-fs/jmicron-raid.img.bz2 tests/ts/blkid/images-fs/lvm2.img.bz2 tests/ts/blkid/images-fs/nvidia-raid.img.bz2 tests/ts/blkid/images-fs/ocfs2.img.bz2 tests/ts/blkid/images-fs/promise-raid.img.bz2 tests/ts/blkid/images-fs/reiser4.img.bz2 tests/ts/blkid/images-fs/romfs.img.bz2 tests/ts/blkid/images-fs/silicon-raid.img.bz2 tests/ts/blkid/images-fs/swap0.img.bz2 tests/ts/blkid/images-fs/swap1.img.bz2 tests/ts/blkid/images-fs/via-raid.img.bz2 tests/ts/blkid/images-fs/vmfs_volume.img.bz2 tests/ts/blkid/images-fs/zfs.img.bz2
-rw-r--r--.gitignore1
-rw-r--r--configure.ac29
-rw-r--r--disk-utils/mkfs.c2
-rw-r--r--fdisk/Makefile.am23
-rw-r--r--fdisk/cfdisk.c232
-rw-r--r--fdisk/fdisk.c32
-rw-r--r--fsck/fsck.c2
-rw-r--r--include/pathnames.h2
-rw-r--r--login-utils/Makefile.am32
-rw-r--r--login-utils/login.c30
-rw-r--r--misc-utils/blkid.c42
-rw-r--r--misc-utils/namei.12
-rw-r--r--mount/mount.815
-rw-r--r--mount/mount.c149
-rw-r--r--schedutils/chrt.114
-rw-r--r--schedutils/chrt.c29
-rw-r--r--shlibs/blkid/src/Makefile.am2
-rw-r--r--shlibs/blkid/src/blkid.h.in1
-rw-r--r--shlibs/blkid/src/blkid.sym8
-rw-r--r--shlibs/blkid/src/blkidP.h25
-rw-r--r--shlibs/blkid/src/devname.c110
-rw-r--r--shlibs/blkid/src/devno.c24
-rw-r--r--shlibs/blkid/src/fat.h90
-rw-r--r--shlibs/blkid/src/partitions/dos.c25
-rw-r--r--shlibs/blkid/src/partitions/gpt.c1
-rw-r--r--shlibs/blkid/src/partitions/partitions.c3
-rw-r--r--shlibs/blkid/src/partitions/unixware.c1
-rw-r--r--shlibs/blkid/src/probe.c161
-rw-r--r--shlibs/blkid/src/save.c2
-rw-r--r--shlibs/blkid/src/superblocks/Makefile.am3
-rw-r--r--shlibs/blkid/src/superblocks/befs.c207
-rw-r--r--shlibs/blkid/src/superblocks/drbd.c3
-rw-r--r--shlibs/blkid/src/superblocks/gfs.c2
-rw-r--r--shlibs/blkid/src/superblocks/jfs.c1
-rw-r--r--shlibs/blkid/src/superblocks/minix.c70
-rw-r--r--shlibs/blkid/src/superblocks/ocfs.c3
-rw-r--r--shlibs/blkid/src/superblocks/reiserfs.c2
-rw-r--r--shlibs/blkid/src/superblocks/superblocks.c35
-rw-r--r--shlibs/blkid/src/superblocks/superblocks.h1
-rw-r--r--shlibs/blkid/src/superblocks/swap.c2
-rw-r--r--shlibs/blkid/src/superblocks/vfat.c143
-rw-r--r--shlibs/blkid/src/superblocks/zfs.c1
-rw-r--r--tests/expected/blkid/low-probe-befs7
43 files changed, 1044 insertions, 525 deletions
diff --git a/.gitignore b/.gitignore
index 5c872c2f..f2f7f51a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -52,3 +52,4 @@ libtool
# cannot deal with bz2 files
tests/ts/blkid/images-fs/*.bz2
+tests/ts/blkid/images-fs/*.bz2
diff --git a/configure.ac b/configure.ac
index 5ddeaa5d..e36b8f6b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -163,6 +163,7 @@ AC_CHECK_FUNCS(
setresuid \
inotify_init \
prctl \
+ posix_fadvise \
getmntinfo \
__secure_getenv \
rpmatch])
@@ -959,6 +960,34 @@ if test "x$enable_require_password" = xyes; then
fi
+AC_DEFUN([FS_PATHS_DEFAULT], [/sbin:/sbin/fs.d:/sbin/fs])
+AC_ARG_ENABLE([fs-paths-default],
+ AS_HELP_STRING([--enable-fs-paths-default=paths], [default search path for fs helpers @<:@FS_PATHS_DEFAULT@:>@]),
+ [case "$enableval" in
+ yes) fs_paths_defaults="FS_PATHS_DEFAULT" ;;
+ no) fs_paths_defaults="" ;;
+ *) fs_paths_defaults="$enableval" ;;
+ esac],
+ [fs_paths_defaults="FS_PATHS_DEFAULT"]
+)
+AC_ARG_ENABLE([fs-paths-extra],
+ AS_HELP_STRING([--enable-fs-paths-extra=paths], [additional search paths for fs helpers]),
+ [case "$enableval" in
+ yes|no) fs_paths_extra="" ;;
+ *) fs_paths_extra="$enableval" ;;
+ esac],
+ [fs_paths_extra=""]
+)
+fs_paths="$fs_paths_defaults"
+if test "x$fs_paths_extra" != "x"; then
+ if test "x$fs_paths" != "x"; then
+ fs_paths="${fs_paths}:"
+ fi
+ fs_paths="${fs_paths}${fs_paths_extra}"
+fi
+AC_DEFINE_UNQUOTED([FS_SEARCH_PATH], "$fs_paths", [search path for fs helpers])
+
+
AC_ARG_ENABLE([use-tty-group],
AS_HELP_STRING([--disable-use-tty-group], [do not install wall and write setgid tty]),
[], enable_use_tty_group=yes
diff --git a/disk-utils/mkfs.c b/disk-utils/mkfs.c
index 120da063..a0ccd16f 100644
--- a/disk-utils/mkfs.c
+++ b/disk-utils/mkfs.c
@@ -27,7 +27,7 @@
# define DEFAULT_FSTYPE "ext2"
#endif
-#define SEARCH_PATH "PATH=/sbin:/sbin/fs:/sbin/fs.d:/etc/fs:/etc"
+#define SEARCH_PATH "PATH=" FS_SEARCH_PATH
#define PROGNAME "mkfs.%s"
diff --git a/fdisk/Makefile.am b/fdisk/Makefile.am
index 5496e240..50f1dbe8 100644
--- a/fdisk/Makefile.am
+++ b/fdisk/Makefile.am
@@ -18,26 +18,25 @@ fdisk_SOURCES = fdisk.c fdiskbsdlabel.c fdisksgilabel.c \
fdisk.h fdisksunlabel.h fdisksgilabel.h fdiskaixlabel.h \
fdiskbsdlabel.h fdiskmaclabel.h $(fdisk_common)
-cflags_fdisk = $(AM_CFLAGS)
-ldadd_fdisk =
+cflags_blkid = $(AM_CFLAGS)
+ldadd_blkid =
if BUILD_LIBBLKID
# only in-tree libblkid has topology support
-ldadd_fdisk += $(ul_libblkid_la)
-cflags_fdisk += -I$(ul_libblkid_incdir)
+ldadd_blkid += $(ul_libblkid_la)
+cflags_blkid += -I$(ul_libblkid_incdir)
endif
if HAVE_STATIC_FDISK
sbin_PROGRAMS += fdisk.static
fdisk_static_SOURCES = $(fdisk_SOURCES)
fdisk_static_LDFLAGS = -all-static
-fdisk_static_CFLAGS = $(cflags_fdisk)
-fdisk_static_LDADD = $(ldadd_fdisk)
+fdisk_static_CFLAGS = $(cflags_blkid)
+fdisk_static_LDADD = $(ldadd_blkid)
endif
-fdisk_CFLAGS = $(cflags_fdisk)
-fdisk_LDADD = $(ldadd_fdisk)
-
+fdisk_CFLAGS = $(cflags_blkid)
+fdisk_LDADD = $(ldadd_blkid)
if !ARCH_SPARC
@@ -55,13 +54,15 @@ if USE_SLANG
sbin_PROGRAMS += cfdisk
dist_man_MANS += cfdisk.8
cfdisk_SOURCES = cfdisk.c $(fdisk_common)
-cfdisk_LDADD = -lslang
+cfdisk_CFLAGS = $(cflags_blkid)
+cfdisk_LDADD = -lslang $(ldadd_blkid)
else
if HAVE_NCURSES
sbin_PROGRAMS += cfdisk
dist_man_MANS += cfdisk.8
cfdisk_SOURCES = cfdisk.c $(fdisk_common)
-cfdisk_LDADD = @NCURSES_LIBS@
+cfdisk_CFLAGS = $(cflags_blkid)
+cfdisk_LDADD = @NCURSES_LIBS@ $(ldadd_blkid)
endif
endif
diff --git a/fdisk/cfdisk.c b/fdisk/cfdisk.c
index eec16893..eaf766c8 100644
--- a/fdisk/cfdisk.c
+++ b/fdisk/cfdisk.c
@@ -79,6 +79,10 @@
#include <sys/stat.h>
#include <sys/ioctl.h>
+#ifdef HAVE_LIBBLKID_INTERNAL
+#include <blkid.h>
+#endif
+
#include "nls.h"
#include "blkdev.h"
#include "xstrncpy.h"
@@ -222,11 +226,6 @@ set_hsc_end(struct partition *p, long long sector) {
#define is_extended(x) ((x) == DOS_EXTENDED || (x) == WIN98_EXTENDED || \
(x) == LINUX_EXTENDED)
-#define is_dos_partition(x) ((x) == 1 || (x) == 4 || (x) == 6)
-#define may_have_dos_label(x) (is_dos_partition(x) \
- || (x) == 7 || (x) == 0xb || (x) == 0xc || (x) == 0xe \
- || (x) == 0x11 || (x) == 0x14 || (x) == 0x16 || (x) == 0x17)
-
/* start_sect and nr_sects are stored little endian on all machines */
/* moreover, they are not aligned correctly */
static void
@@ -289,7 +288,7 @@ typedef struct {
char volume_label[LABELSZ+1];
#define OSTYPESZ 8
char ostype[OSTYPESZ+1];
-#define FSTYPESZ 8
+#define FSTYPESZ 12
char fstype[FSTYPESZ+1];
} partition_info;
@@ -378,29 +377,9 @@ partition_type_text(int i) {
return _("Unusable");
else if (p_info[i].id == FREE_SPACE)
return _("Free Space");
- else if (p_info[i].id == LINUX) {
- if (!strcmp(p_info[i].fstype, "ext2"))
- return _("Linux ext2");
- else if (!strcmp(p_info[i].fstype, "ext3"))
- return _("Linux ext3");
- else if (!strcmp(p_info[i].fstype, "xfs"))
- return _("Linux XFS");
- else if (!strcmp(p_info[i].fstype, "jfs"))
- return _("Linux JFS");
- else if (!strcmp(p_info[i].fstype, "reiserfs"))
- return _("Linux ReiserFS");
- else
- return _("Linux");
- } else if (p_info[i].id == OS2_OR_NTFS) {
- if (!strncmp(p_info[i].fstype, "HPFS", 4))
- return _("OS/2 HPFS");
- else if (!strncmp(p_info[i].ostype, "OS2", 3))
- return _("OS/2 IFS");
- else if (!p_info[i].ostype)
- return p_info[i].ostype;
- else
- return _("NTFS");
- } else
+ else if (*p_info[i].fstype)
+ return p_info[i].fstype;
+ else
return _(partition_type_name(p_info[i].id));
}
@@ -574,171 +553,36 @@ write_sector(unsigned char *buffer, long long sect_num) {
fatal(_("Cannot write disk drive"), 2);
}
+#ifdef HAVE_LIBBLKID_INTERNAL
static void
-dos_copy_to_info(char *to, int tosz, char *from, int fromsz) {
- int i;
-
- for(i=0; i<tosz && i<fromsz && isascii(from[i]); i++)
- to[i] = from[i];
- to[i] = 0;
-}
-
-static void
-get_dos_label(int i) {
- char sector[128];
-#define DOS_OSTYPE_OFFSET 3
-#define DOS_LABEL_OFFSET 43
-#define DOS_FSTYPE_OFFSET 54
-#define DOS_OSTYPE_SZ 8
-#define DOS_LABEL_SZ 11
-#define DOS_FSTYPE_SZ 8
- long long offset;
+get_fsinfo(int i)
+{
+ blkid_probe pr;
+ blkid_loff_t offset, size;
+ const char *data;
offset = (p_info[i].first_sector + p_info[i].offset) * SECTOR_SIZE;
- if (lseek(fd, offset, SEEK_SET) == offset
- && read(fd, &sector, sizeof(sector)) == sizeof(sector)) {
- dos_copy_to_info(p_info[i].ostype, OSTYPESZ,
- sector+DOS_OSTYPE_OFFSET, DOS_OSTYPE_SZ);
- dos_copy_to_info(p_info[i].volume_label, LABELSZ,
- sector+DOS_LABEL_OFFSET, DOS_LABEL_SZ);
- dos_copy_to_info(p_info[i].fstype, FSTYPESZ,
- sector+DOS_FSTYPE_OFFSET, DOS_FSTYPE_SZ);
- }
-}
-
-#define REISERFS_SUPER_MAGIC_STRING "ReIsErFs"
-#define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs"
-struct reiserfs_super_block {
- char s_dummy0[52];
- char s_magic [10];
- char s_dummy1[38];
- u_char s_label[16];
-};
-#define REISERFSLABELSZ sizeof(reiserfsb.s_label)
-
-static int
-has_reiserfs_magic_string(const struct reiserfs_super_block *rs, int *is_3_6) {
- if (!strncmp(rs->s_magic, REISERFS_SUPER_MAGIC_STRING,
- strlen(REISERFS_SUPER_MAGIC_STRING))) {
- *is_3_6 = 0;
- return 1;
- }
- if (!strncmp(rs->s_magic, REISER2FS_SUPER_MAGIC_STRING,
- strlen(REISER2FS_SUPER_MAGIC_STRING))) {
- *is_3_6 = 1;
- return 1;
- }
- return 0;
-}
-
-static void
-get_linux_label(int i) {
-
-#define EXT2LABELSZ 16
-#define EXT2_SUPER_MAGIC 0xEF53
-#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004
- struct ext2_super_block {
- char s_dummy0[56];
- unsigned char s_magic[2];
- char s_dummy1[34];
- unsigned char s_feature_compat[4];
- char s_dummy2[24];
- char s_volume_name[EXT2LABELSZ];
- char s_last_mounted[64];
- char s_dummy3[824];
- } e2fsb;
-
-#define REISERFS_DISK_OFFSET_IN_BYTES (64 * 1024)
- struct reiserfs_super_block reiserfsb;
- int reiserfs_is_3_6;
-
-#define JFS_SUPER1_OFF 0x8000
-#define JFS_MAGIC "JFS1"
-#define JFSLABELSZ 16
- struct jfs_super_block {
- char s_magic[4];
- u_char s_version[4];
- u_char s_dummy1[93];
- char s_fpack[11];
- u_char s_dummy2[24];
- u_char s_uuid[16];
- char s_label[JFSLABELSZ];
- } jfsb;
-
-#define XFS_SUPER_MAGIC "XFSB"
-#define XFSLABELSZ 12
- struct xfs_super_block {
- unsigned char s_magic[4];
- unsigned char s_dummy0[104];
- unsigned char s_fname[XFSLABELSZ];
- unsigned char s_dummy1[904];
- } xfsb;
-
- char *label;
- long long offset;
- int j;
-
- offset = (p_info[i].first_sector + p_info[i].offset) * SECTOR_SIZE
- + 1024;
- if (lseek(fd, offset, SEEK_SET) == offset
- && read(fd, &e2fsb, sizeof(e2fsb)) == sizeof(e2fsb)
- && e2fsb.s_magic[0] + (e2fsb.s_magic[1]<<8) == EXT2_SUPER_MAGIC) {
- label = e2fsb.s_volume_name;
- for(j=0; j<EXT2LABELSZ && j<LABELSZ && isprint(label[j]); j++)
- p_info[i].volume_label[j] = label[j];
- p_info[i].volume_label[j] = 0;
- /* ext2 or ext3? */
- if (e2fsb.s_feature_compat[0]&EXT3_FEATURE_COMPAT_HAS_JOURNAL)
- strncpy(p_info[i].fstype, "ext3", FSTYPESZ);
- else
- strncpy(p_info[i].fstype, "ext2", FSTYPESZ);
+ size = (p_info[i].last_sector - p_info[i].first_sector + 1) * SECTOR_SIZE;
+ pr = blkid_new_probe();
+ if (!pr)
return;
- }
-
- offset = (p_info[i].first_sector + p_info[i].offset) * SECTOR_SIZE + 0;
- if (lseek(fd, offset, SEEK_SET) == offset
- && read(fd, &xfsb, sizeof(xfsb)) == sizeof(xfsb)
- && !strncmp((char *) xfsb.s_magic, XFS_SUPER_MAGIC, 4)) {
- label = (char *) xfsb.s_fname;
- for(j=0; j<XFSLABELSZ && j<LABELSZ && isprint(label[j]); j++)
- p_info[i].volume_label[j] = label[j];
- p_info[i].volume_label[j] = 0;
- strncpy(p_info[i].fstype, "xfs", FSTYPESZ);
- return;
- }
-
- /* jfs? */
- offset = (p_info[i].first_sector + p_info[i].offset) * SECTOR_SIZE
- + JFS_SUPER1_OFF;
- if (lseek(fd, offset, SEEK_SET) == offset
- && read(fd, &jfsb, sizeof(jfsb)) == sizeof(jfsb)
- && !strncmp(jfsb.s_magic, JFS_MAGIC, strlen(JFS_MAGIC))) {
- label = jfsb.s_label;
- for(j=0; j<JFSLABELSZ && j<LABELSZ && isprint(label[j]); j++)
- p_info[i].volume_label[j] = label[j];
- p_info[i].volume_label[j] = 0;
- strncpy(p_info[i].fstype, "jfs", FSTYPESZ);
- return;
- }
-
- /* reiserfs? */
- offset = (p_info[i].first_sector + p_info[i].offset) * SECTOR_SIZE
- + REISERFS_DISK_OFFSET_IN_BYTES;
- if (lseek(fd, offset, SEEK_SET) == offset
- && read(fd, &reiserfsb, sizeof(reiserfsb)) == sizeof(reiserfsb)
- && has_reiserfs_magic_string(&reiserfsb, &reiserfs_is_3_6)) {
- if (reiserfs_is_3_6) {
- /* label only on version 3.6 onward */
- label = (char *) reiserfsb.s_label;
- for(j=0; j<REISERFSLABELSZ && j<LABELSZ &&
- isprint(label[j]); j++)
- p_info[i].volume_label[j] = label[j];
- p_info[i].volume_label[j] = 0;
- }
- strncpy(p_info[i].fstype, "reiserfs", FSTYPESZ);
- return;
- }
+ blkid_probe_enable_superblocks(pr, 1);
+ blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_LABEL |
+ BLKID_SUBLKS_TYPE);
+ if (blkid_probe_set_device(pr, fd, offset, size))
+ goto done;
+ if (blkid_do_safeprobe(pr))
+ goto done;
+
+ if (!blkid_probe_lookup_value(pr, "TYPE", &data, 0))
+ strncpy(p_info[i].fstype, data, FSTYPESZ);
+
+ if (!blkid_probe_lookup_value(pr, "LABEL", &data, 0))
+ strncpy(p_info[i].volume_label, data, LABELSZ);
+done:
+ blkid_free_probe(pr);
}
+#endif
static void
check_part_info(void) {
@@ -1050,13 +894,11 @@ add_part(int num, int id, int flags, long long first, long long last,
p_info[i].volume_label[0] = 0;
p_info[i].fstype[0] = 0;
p_info[i].ostype[0] = 0;
- if (want_label) {
- if (may_have_dos_label(id))
- get_dos_label(i);
- else if (id == LINUX)
- get_linux_label(i);
- }
+#ifdef HAVE_LIBBLKID_INTERNAL
+ if (want_label)
+ get_fsinfo(i);
+#endif
check_part_info();
return 0;
diff --git a/fdisk/fdisk.c b/fdisk/fdisk.c
index 5ef24f66..cc573646 100644
--- a/fdisk/fdisk.c
+++ b/fdisk/fdisk.c
@@ -222,7 +222,7 @@ unsigned int heads,
display_in_cyl_units = 1;
unsigned long long total_number_of_sectors; /* (!) 512-byte sectors */
-unsigned long minimum_io_size, alignment_offset;
+unsigned long io_size, alignment_offset;
#define dos_label (!sun_label && !sgi_label && !aix_label && !mac_label && !osf_label)
int sun_label = 0; /* looking at sun disklabel */
@@ -637,7 +637,7 @@ test_c(char **m, char *mesg) {
return val;
}
-#define alignment_required (minimum_io_size != sector_size)
+#define alignment_required (io_size != sector_size)
static int
lba_is_aligned(unsigned long long lba)
@@ -645,9 +645,9 @@ lba_is_aligned(unsigned long long lba)
unsigned long long bytes, phy_sectors;
bytes = lba * sector_size;
- phy_sectors = bytes / minimum_io_size;
+ phy_sectors = bytes / io_size;
- return (alignment_offset + (phy_sectors * minimum_io_size) == bytes);
+ return (alignment_offset + (phy_sectors * io_size) == bytes);
}
#define ALIGN_UP 1
@@ -662,7 +662,7 @@ align_lba(unsigned long long lba, int direction)
if (lba_is_aligned(lba))
return lba;
- sects_in_phy = minimum_io_size / sector_size;
+ sects_in_phy = io_size / sector_size;
if (lba < sects_in_phy)
/* align to the first physical sector */
@@ -685,7 +685,7 @@ align_lba(unsigned long long lba, int direction)
* at LBA < 0 (usually LBA -1). It means we have to move LBA
* according the offset to be on the physical boundary.
*/
- res -= (minimum_io_size - alignment_offset) / sector_size;
+ res -= (io_size - alignment_offset) / sector_size;
/* fprintf(stderr, "LBA %llu -align-> %llu (%s)\n", lba, res,
* lba_is_aligned(res) ? "OK" : "FALSE");
@@ -779,8 +779,8 @@ warn_alignment(void) {
fprintf(stderr, _("\n"
"The device presents a logical sector size that is smaller than\n"
-"the physical sector size. Aligning to a physical sector boundary\n"
-"is recommended, or performance may be impacted.\n\n"));
+"the optimal I/O size (often physical sector size). Aligning to a optimal\n"
+"I/O size boundary is recommended, or performance may be impacted.\n\n"));
/*
* Print warning when sector_offset is not aligned for DOS mode
@@ -968,7 +968,9 @@ get_topology(int fd) {
blkid_topology tp = blkid_probe_get_topology(pr);
if (tp) {
- minimum_io_size = blkid_topology_get_minimum_io_size(tp);
+ io_size = blkid_topology_get_optimal_io_size(tp);
+ if (!io_size)
+ io_size = blkid_topology_get_minimum_io_size(tp);
alignment_offset = blkid_topology_get_alignment_offset(tp);
}
}
@@ -980,8 +982,8 @@ get_topology(int fd) {
else if (blkdev_get_sector_size(fd, &arg) == 0)
sector_size = arg;
- if (!minimum_io_size)
- minimum_io_size = sector_size;
+ if (!io_size)
+ io_size = sector_size;
if (sector_size != DEFAULT_SECTOR_SIZE)
printf(_("Note: sector size is %d (not %d)\n"),
@@ -1054,7 +1056,7 @@ update_sector_offset(void)
/*
* Align the begin of the first partition to the physical block
*/
- unsigned long long x = minimum_io_size / sector_size;
+ unsigned long long x = io_size / sector_size;
sector_offset = align_lba(x, ALIGN_UP);
}
@@ -1810,7 +1812,7 @@ static void
check_alignment(struct partition *p, int partition)
{
if (!lba_is_aligned(get_start_sect(p)))
- printf(_("Partition %i does not start on physical block boundary.\n"),
+ printf(_("Partition %i does not start on optimal I/O size boundary.\n"),
partition + 1);
}
@@ -1837,8 +1839,8 @@ list_disk_geometry(void) {
str_units(PLURAL),
units_per_sector, sector_size, units_per_sector * sector_size);
- printf(_("Sector size (logical/physical): %u bytes / %lu bytes\n"),
- sector_size, minimum_io_size);
+ printf(_("Sector size (logical / optimal IO): %u bytes / %lu bytes\n"),
+ sector_size, io_size);
if (alignment_offset)
printf(_("Alignment offset: %lu bytes\n"), alignment_offset);
if (dos_label)
diff --git a/fsck/fsck.c b/fsck/fsck.c
index 66c027c7..45d8484a 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -105,7 +105,7 @@ char *progname;
char *fstype = NULL;
struct fs_info *filesys_info = NULL, *filesys_last = NULL;
struct fsck_instance *instance_list;
-const char *fsck_prefix_path = "/sbin:/sbin/fs.d:/sbin/fs:/etc/fs:/etc";
+const char fsck_prefix_path[] = FS_SEARCH_PATH;
char *fsck_path = 0;
static char *string_copy(const char *s)
diff --git a/include/pathnames.h b/include/pathnames.h
index efe5c3bc..9c4eb009 100644
--- a/include/pathnames.h
+++ b/include/pathnames.h
@@ -76,6 +76,8 @@
#define _PATH_PROC_PARTITIONS "/proc/partitions"
#define _PATH_PROC_DEVICES "/proc/devices"
+#define _PATH_SYS_BLOCK "/sys/block"
+
#ifndef _PATH_MOUNTED
# ifdef MOUNTED /* deprecated */
# define _PATH_MOUNTED MOUNTED
diff --git a/login-utils/Makefile.am b/login-utils/Makefile.am
index 6d82f401..6e11abec 100644
--- a/login-utils/Makefile.am
+++ b/login-utils/Makefile.am
@@ -27,7 +27,7 @@ if NEED_LIBCRYPT
simpleinit_LDADD = -lcrypt
endif
-endif
+endif # BUILD_INIT
if BUILD_LAST
usrbin_exec_PROGRAMS += last
@@ -41,6 +41,9 @@ usrbin_exec_PROGRAMS += chfn chsh newgrp
usrsbin_exec_PROGRAMS += vipw
dist_man_MANS += chfn.1 chsh.1 login.1 newgrp.1 vipw.8 vigr.8
+# login, chfn and chsh libs
+login_ldadd_common =
+
chfn_SOURCES = chfn.c $(chfn_chsh_common)
chsh_SOURCES = chsh.c $(chfn_chsh_common)
chfn_chsh_common = islocal.c setpwnam.c islocal.h my_crypt.h setpwnam.h \
@@ -49,9 +52,9 @@ login_SOURCES = login.c login.h my_crypt.h ../lib/setproctitle.c
newgrp_SOURCES = newgrp.c my_crypt.h
vipw_SOURCES = vipw.c setpwnam.h
-chfn_LDADD =
-chsh_LDADD =
-login_LDADD =
+chfn_LDADD = $(login_ldadd_common)
+chsh_LDADD = $(login_ldadd_common)
+login_LDADD = $(login_ldadd_common)
newgrp_LDADD =
vipw_LDADD =
@@ -63,19 +66,17 @@ chfn_LDFLAGS = $(SUID_LDFLAGS) $(AM_LDFLAGS)
chsh_LDFLAGS = $(SUID_LDFLAGS) $(AM_LDFLAGS)
newgrp_LDFLAGS = $(SUID_LDFLAGS) $(AM_LDFLAGS)
-if NEED_LIBCRYPT
-chfn_LDADD += -lcrypt
-chsh_LDADD += -lcrypt
-login_LDADD += -lcrypt
-newgrp_LDADD += -lcrypt
-endif
-
if HAVE_PAM
-chfn_LDADD += -lpam -lpam_misc
-chsh_LDADD += -lpam -lpam_misc
-login_LDADD += -lpam -lpam_misc
+login_ldadd_common += -lpam -lpam_misc
else
+if NEED_LIBCRYPT
+login_ldadd_common += -lcrypt
+endif
login_SOURCES += checktty.c
+endif #! HAVE_PAM
+
+if NEED_LIBCRYPT
+newgrp_LDADD += -lcrypt
endif
if HAVE_AUDIT
@@ -84,10 +85,9 @@ endif
if HAVE_SELINUX
chfn_SOURCES += selinux_utils.c selinux_utils.h
-chfn_LDADD += -lselinux
chsh_SOURCES += selinux_utils.c selinux_utils.h
-chsh_LDADD += -lselinux
vipw_LDADD += -lselinux
+login_ldadd_common += -lselinux
endif
diff --git a/login-utils/login.c b/login-utils/login.c
index 486b30bf..1550388c 100644
--- a/login-utils/login.c
+++ b/login-utils/login.c
@@ -200,6 +200,13 @@ opentty(const char * tty) {
exit(1);
}
+ if (!isatty(fd)) {
+ close(fd);
+ syslog(LOG_ERR, _("FATAL: %s is not a terminal"), tty);
+ sleep(1);
+ exit(1);
+ }
+
flags = fcntl(fd, F_GETFL);
flags &= ~O_NONBLOCK;
fcntl(fd, F_SETFL, flags);
@@ -222,7 +229,9 @@ static void
check_ttyname(char *ttyn) {
struct stat statbuf;
- if (lstat(ttyn, &statbuf)
+ if (ttyn == NULL
+ || *ttyn == '\0'
+ || lstat(ttyn, &statbuf)
|| !S_ISCHR(statbuf.st_mode)
|| (statbuf.st_nlink > 1 && strncmp(ttyn, "/dev/", 5))
|| (access(ttyn, R_OK | W_OK) != 0)) {
@@ -378,7 +387,7 @@ main(int argc, char **argv)
int ask, fflag, hflag, pflag, cnt, errsv;
int quietlog, passwd_req;
char *domain, *ttyn;
- char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_DEV_TTY) + 10];
+ char tbuf[MAXPATHLEN + 2];
char *termenv;
char *childArgv[10];
char *buff;
@@ -495,14 +504,9 @@ main(int argc, char **argv)
for (cnt = getdtablesize(); cnt > 2; cnt--)
close(cnt);
+ /* note that libc checks that the file descriptor is a terminal, so we don't
+ * have to call isatty() here */
ttyn = ttyname(0);
-
- if (ttyn == NULL || *ttyn == '\0') {
- /* no snprintf required - see definition of tname */
- snprintf(tname, sizeof(tname), "%s??", _PATH_DEV_TTY);
- ttyn = tname;
- }
-
check_ttyname(ttyn);
if (strncmp(ttyn, "/dev/", 5) == 0)
@@ -536,8 +540,8 @@ main(int argc, char **argv)
ttt.c_cflag &= ~HUPCL;
/* These can fail, e.g. with ttyn on a read-only filesystem */
- chown(ttyn, 0, 0);
- chmod(ttyn, TTY_MODE);
+ fchown(0, 0, 0);
+ fchmod(0, TTY_MODE);
/* Kill processes left on this tty */
tcsetattr(0,TCSAFLUSH,&ttt);
@@ -1009,9 +1013,9 @@ Michael Riepe <michael@stud.uni-hannover.de>
logaudit(tty_name, username, hostname, pwd, 1);
dolastlog(quietlog);
- chown(ttyn, pwd->pw_uid,
+ fchown(0, pwd->pw_uid,
(gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
- chmod(ttyn, TTY_MODE);
+ fchmod(0, TTY_MODE);
#ifdef LOGIN_CHOWN_VCS
/* if tty is one of the VC's then change owner and mode of the
diff --git a/misc-utils/blkid.c b/misc-utils/blkid.c
index 6e055a95..56b25b8b 100644
--- a/misc-utils/blkid.c
+++ b/misc-utils/blkid.c
@@ -255,7 +255,12 @@ static void print_udev_format(const char *name, const char *value, size_t sz)
blkid_encode_string(value, enc, sizeof(enc));
printf("ID_FS_%s_ENC=%s\n", name, enc);
- }
+
+ } else if (!strcmp(name, "PTTYPE"))
+ printf("ID_PART_TABLE_TYPE=%s\n", value);
+
+ /* TODO: ID_PART_ENTRY_{UUID,NAME,FLAG} */
+
else
printf("ID_FS_%s=%s\n", name, value);
}
@@ -410,6 +415,7 @@ static int lowprobe_device(blkid_probe pr, const char *devname, char *show[],
size_t len;
int fd;
int rc = 0;
+ struct stat st;
fd = open(devname, O_RDONLY);
if (fd < 0)
@@ -417,9 +423,35 @@ static int lowprobe_device(blkid_probe pr, const char *devname, char *show[],
if (blkid_probe_set_device(pr, fd, offset, size))
goto done;
- rc = blkid_do_safeprobe(pr);
- if (rc)
+
+ if (fstat(fd, &st))
goto done;
+ /*
+ * partitions probing
+ */
+ blkid_probe_enable_superblocks(pr, 0); /* enabled by default ;-( */
+
+ blkid_probe_enable_partitions(pr, 1);
+ rc = blkid_do_fullprobe(pr);
+ blkid_probe_enable_partitions(pr, 0);
+
+ if (rc < 0)
+ goto done; /* -1 = error, 1 = nothing, 0 = succes */
+
+ /*
+ * Don't probe for FS/RAIDs on small devices
+ */
+ if (rc || S_ISCHR(st.st_mode) ||
+ blkid_probe_get_size(pr) > 1024 * 1440) {
+ /*
+ * filesystems/RAIDs probing
+ */
+ blkid_probe_enable_superblocks(pr, 1);
+
+ rc = blkid_do_safeprobe(pr);
+ if (rc < 0)
+ goto done;
+ }
nvals = blkid_probe_numof_values(pr);
@@ -437,7 +469,7 @@ static int lowprobe_device(blkid_probe pr, const char *devname, char *show[],
print_value(output, num++, devname, (char *) data, name, len);
}
- if (nvals > 1 && !(output & (OUTPUT_VALUE_ONLY | OUTPUT_UDEV_LIST)))
+ if (nvals >= 1 && !(output & (OUTPUT_VALUE_ONLY | OUTPUT_UDEV_LIST)))
printf("\n");
done:
if (rc == -2) {
@@ -648,8 +680,6 @@ int main(int argc, char **argv)
if (!pr)
goto exit;
- blkid_probe_enable_superblocks(pr, 1);
-
blkid_probe_set_superblocks_flags(pr,
BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID |
BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE |
diff --git a/misc-utils/namei.1 b/misc-utils/namei.1
index f9617dab..a54fa8ac 100644
--- a/misc-utils/namei.1
+++ b/misc-utils/namei.1
@@ -5,7 +5,7 @@
.SH NAME
namei - follow a pathname until a terminal point is found
.SH SYNOPSIS
-.B fBnamei
+.B namei
.RI [ options ]
.IR pathname ...
.SH DESCRIPTION
diff --git a/mount/mount.8 b/mount/mount.8
index e766d353..bb807167 100644
--- a/mount/mount.8
+++ b/mount/mount.8
@@ -1277,7 +1277,11 @@ in files after a crash and journal recovery.
.TP
.BR barrier=0 " / " barrier=1 "
This enables/disables barriers. barrier=0 disables it, barrier=1 enables it.
-The ext3 filesystem does not enable write barriers by default.
+Write barriers enforce proper on-disk ordering of journal commits, making
+volatile disk write caches safe to use, at some performance penalty. The ext3
+filesystem does not enable write barriers by default. Be sure to enable
+barriers unless your disks are battery-backed one way or another. Otherwise
+you risk filesystem corruption in case of power failure.
.TP
.BI commit= nrsec
Sync all data and metadata every
@@ -1942,6 +1946,15 @@ manual page.
Enable POSIX Access Control Lists. See the
.BR acl (5)
manual page.
+.TP
+.BR barrier=none " / " barrier=flush "
+This enables/disables the use of write barriers in the journaling code.
+barrier=none disables it, barrier=flush enables it. Write barriers enforce
+proper on-disk ordering of journal commits, making volatile disk write caches
+safe to use, at some performance penalty. The reiserfs filesystem does not
+enable write barriers by default. Be sure to enable barriers unless your disks
+are battery-backed one way or another. Otherwise you risk filesystem
+corruption in case of power failure.
.SH "Mount options for romfs"
None.
diff --git a/mount/mount.c b/mount/mount.c
index dc20bedc..464ca54f 100644
--- a/mount/mount.c
+++ b/mount/mount.c
@@ -651,74 +651,89 @@ do_mount (struct mountargs *args, int *special, int *status) {
static int
check_special_mountprog(const char *spec, const char *node, const char *type, int flags,
char *extra_opts, int *status) {
- char mountprog[120];
- struct stat statbuf;
- int res;
-
- if (!external_allowed)
- return 0;
-
- if (type == NULL || strcmp(type, "none") == 0)
- return 0;
-
- if (strlen(type) < 100) {
- sprintf(mountprog, "/sbin/mount.%s", type);
- if (stat(mountprog, &statbuf) == 0) {
- if (verbose)
- fflush(stdout);
- res = fork();
- if (res == 0) {
- char *oo, *mountargs[10];
- int i = 0;
-
- if(setgid(getgid()) < 0)
- die(EX_FAIL, _("mount: cannot set group id: %s"), strerror(errno));
-
- if(setuid(getuid()) < 0)
- die(EX_FAIL, _("mount: cannot set user id: %s"), strerror(errno));
-
- oo = fix_opts_string (flags, extra_opts, NULL);
- mountargs[i++] = mountprog; /* 1 */
- mountargs[i++] = (char *) spec; /* 2 */
- mountargs[i++] = (char *) node; /* 3 */
- if (sloppy && strncmp(type, "nfs", 3) == 0)
- mountargs[i++] = "-s"; /* 4 */
- if (fake)
- mountargs[i++] = "-f"; /* 5 */
- if (nomtab)
- mountargs[i++] = "-n"; /* 6 */
- if (verbose)
- mountargs[i++] = "-v"; /* 7 */
- if (oo && *oo) {
- mountargs[i++] = "-o"; /* 8 */
- mountargs[i++] = oo; /* 9 */
- }
- mountargs[i] = NULL; /* 10 */
-
- if (verbose > 2) {
- i = 0;
- while(mountargs[i]) {
- printf("mount: external mount: argv[%d] = \"%s\"\n",
- i, mountargs[i]);
- i++;
- }
+ char search_path[] = FS_SEARCH_PATH;
+ char *path, mountprog[150];
+ struct stat statbuf;
+ int res;
+
+ if (!external_allowed)
+ return 0;
+
+ if (type == NULL || strcmp(type, "none") == 0)
+ return 0;
+
+ path = strtok(search_path, ":");
+ while (path) {
+ res = snprintf(mountprog, sizeof(mountprog), "%s/mount.%s",
+ path, type);
+ path = strtok(NULL, ":");
+ if (res >= sizeof(mountprog) || res < 0)
+ continue;
+
+ if (stat(mountprog, &statbuf))
+ continue;
+
+ if (verbose)
fflush(stdout);
- }
-
- execv(mountprog, mountargs);
- exit(1); /* exec failed */
- } else if (res != -1) {
- int st;
- wait(&st);
- *status = (WIFEXITED(st) ? WEXITSTATUS(st) : EX_SYSERR);
- return 1;
- } else {
- int errsv = errno;
- error(_("mount: cannot fork: %s"), strerror(errsv));
- }
- }
- }
- return 0;
+
+ switch (fork()) {
+ case 0: { /* child */
+ char *oo, *mountargs[10];
+ int i = 0;
+
+ if (setgid(getgid()) < 0)
+ die(EX_FAIL, _("mount: cannot set group id: %s"), strerror(errno));
+
+ if (setuid(getuid()) < 0)
+ die(EX_FAIL, _("mount: cannot set user id: %s"), strerror(errno));
+
+ oo = fix_opts_string (flags, extra_opts, NULL);
+ mountargs[i++] = mountprog; /* 1 */
+ mountargs[i++] = (char *) spec; /* 2 */
+ mountargs[i++] = (char *) node; /* 3 */
+ if (sloppy && strncmp(type, "nfs", 3) == 0)
+ mountargs[i++] = "-s"; /* 4 */
+ if (fake)
+ mountargs[i++] = "-f"; /* 5 */
+ if (nomtab)
+ mountargs[i++] = "-n"; /* 6 */
+ if (verbose)
+ mountargs[i++] = "-v"; /* 7 */
+ if (oo && *oo) {
+ mountargs[i++] = "-o"; /* 8 */
+ mountargs[i++] = oo; /* 9 */
+ }
+ mountargs[i] = NULL; /* 10 */
+
+ if (verbose > 2) {
+ i = 0;
+ while (mountargs[i]) {
+ printf("mount: external mount: argv[%d] = \"%s\"\n",
+ i, mountargs[i]);
+ i++;
+ }
+ fflush(stdout);
+ }
+
+ execv(mountprog, mountargs);
+ exit(1); /* exec failed */
+ }
+
+ default: { /* parent */
+ int st;
+ wait(&st);
+ *status = (WIFEXITED(st) ? WEXITSTATUS(st) : EX_SYSERR);
+ return 1;
+ }
+
+ case -1: { /* error */
+ int errsv = errno;
+ error(_("mount: cannot fork: %s"), strerror(errsv));
+ }
+ }
+ }
+
+ return 0;
}
diff --git a/schedutils/chrt.1 b/schedutils/chrt.1
index 06c58b47..9016cfef 100644
--- a/schedutils/chrt.1
+++ b/schedutils/chrt.1
@@ -55,6 +55,11 @@ The
policy is supported since Linux 2.6.16. The
.BR SCHED_IDLE
policy is supported since Linux 2.6.23.
+.PP
+The
+.BR SCHED_RESET_ON_FORK
+flag for policies SCHED_RR and SCHED_FIFO is supported
+since Linux 2.6.31.
.SH OPTIONS
.TP
.B -p, --pid
@@ -69,6 +74,15 @@ set scheduling policy to
set scheduling policy to
.BR SCHED_FIFO
.TP
+.B -R, --reset-on-fork
+add
+.B SCHED_RESET_ON_FORK
+flag to the
+.B SCHED_FIFO
+or
+.B SCHED_RR
+scheduling policy (Linux specific)
+.TP
.B -i, --idle
set schedulng policy to
.BR SCHED_IDLE
diff --git a/schedutils/chrt.c b/schedutils/chrt.c
index 6953addd..0ff9b9bb 100644
--- a/schedutils/chrt.c
+++ b/schedutils/chrt.c
@@ -47,6 +47,11 @@
# define SCHED_IDLE 5
#endif
+#if defined(__linux__) && !defined(SCHED_RESET_ON_FORK)
+#define SCHED_RESET_ON_FORK 0x40000000
+#endif
+
+
static void show_usage(int rc)
{
fprintf(stdout, _(
@@ -61,6 +66,8 @@ static void show_usage(int rc)
" -i | --idle set policy to SCHED_IDLE\n"
" -o | --other set policy to SCHED_OTHER\n"
" -r | --rr set policy to SCHED_RR (default)\n"
+ "\nScheduling flags:\n"
+ " -R | --reset-on-fork set SCHED_RESET_ON_FORK for FIFO or RR\n"
"\nOptions:\n"
" -h | --help display this help\n"
" -p | --pid operate on existing given pid\n"
@@ -92,6 +99,9 @@ static void show_rt_info(const char *what, pid_t pid)
case SCHED_FIFO:
printf("SCHED_FIFO\n");
break;
+ case SCHED_FIFO|SCHED_RESET_ON_FORK:
+ printf("SCHED_FIFO|SCHED_RESET_ON_FORK\n");
+ break;
#ifdef SCHED_IDLE
case SCHED_IDLE:
printf("SCHED_IDLE\n");
@@ -100,6 +110,9 @@ static void show_rt_info(const char *what, pid_t pid)
case SCHED_RR:
printf("SCHED_RR\n");
break;
+ case SCHED_RR|SCHED_RESET_ON_FORK:
+ printf("SCHED_RR|SCHED_RESET_ON_FORK\n");
+ break;
#ifdef SCHED_BATCH
case SCHED_BATCH:
printf("SCHED_BATCH\n");
@@ -150,7 +163,7 @@ static void show_min_max(void)
int main(int argc, char *argv[])
{
- int i, policy = SCHED_RR, priority = 0, verbose = 0;
+ int i, policy = SCHED_RR, priority = 0, verbose = 0, policy_flag = 0;
struct sched_param sp;
pid_t pid = -1;
@@ -163,6 +176,7 @@ int main(int argc, char *argv[])
{ "max", 0, NULL, 'm' },
{ "other", 0, NULL, 'o' },
{ "rr", 0, NULL, 'r' },
+ { "reset-on-fork", 0, NULL, 'R' },
{ "verbose", 0, NULL, 'v' },
{ "version", 0, NULL, 'V' },
{ NULL, 0, NULL, 0 }
@@ -172,7 +186,7 @@ int main(int argc, char *argv[])
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
- while((i = getopt_long(argc, argv, "+bfiphmorvV", longopts, NULL)) != -1)
+ while((i = getopt_long(argc, argv, "+bfiphmoRrvV", longopts, NULL)) != -1)
{
int ret = EXIT_FAILURE;
@@ -185,6 +199,9 @@ int main(int argc, char *argv[])
case 'f':
policy = SCHED_FIFO;
break;
+ case 'R':
+ policy_flag |= SCHED_RESET_ON_FORK;
+ break;
case 'i':
#ifdef SCHED_IDLE
policy = SCHED_IDLE;
@@ -232,6 +249,14 @@ int main(int argc, char *argv[])
if (errno)
err(EXIT_FAILURE, _("failed to parse priority"));
+ /* sanity check */
+ if ((policy_flag & SCHED_RESET_ON_FORK) &&
+ !(policy == SCHED_FIFO || policy == SCHED_RR))
+ errx(EXIT_FAILURE, _("SCHED_RESET_ON_FORK flag is suppoted for "
+ "SCHED_FIFO and SCHED_RR policies only"));
+
+ policy |= policy_flag;
+
if (pid == -1)
pid = 0;
sp.sched_priority = priority;
diff --git a/shlibs/blkid/src/Makefile.am b/shlibs/blkid/src/Makefile.am
index 90ce9bfc..2d798b6a 100644
--- a/shlibs/blkid/src/Makefile.am
+++ b/shlibs/blkid/src/Makefile.am
@@ -25,7 +25,7 @@ usrlib_exec_LTLIBRARIES = libblkid.la
libblkid_la_SOURCES = cache.c dev.c devname.c devno.c getsize.c llseek.c \
probe.c read.c resolve.c save.c tag.c version.c verify.c \
encode.c list.h blkidP.h superblocks/superblocks.h \
- config.c evaluate.c \
+ config.c evaluate.c fat.h \
$(blkidinc_HEADERS) \
$(top_srcdir)/lib/blkdev.c \
$(top_srcdir)/lib/linux_version.c \
diff --git a/shlibs/blkid/src/blkid.h.in b/shlibs/blkid/src/blkid.h.in
index febb4372..4e53b39f 100644
--- a/shlibs/blkid/src/blkid.h.in
+++ b/shlibs/blkid/src/blkid.h.in
@@ -142,6 +142,7 @@ extern int blkid_devno_to_wholedisk(dev_t dev, char *diskname,
/* devname.c */
extern int blkid_probe_all(blkid_cache cache);
extern int blkid_probe_all_new(blkid_cache cache);
+extern int blkid_probe_all_removable(blkid_cache cache);
extern blkid_dev blkid_get_dev(blkid_cache cache, const char *devname,
int flags);
diff --git a/shlibs/blkid/src/blkid.sym b/shlibs/blkid/src/blkid.sym
index 97255526..4d01aa20 100644
--- a/shlibs/blkid/src/blkid.sym
+++ b/shlibs/blkid/src/blkid.sym
@@ -114,3 +114,11 @@ global:
blkid_topology_get_optimal_io_size;
blkid_topology_get_physical_sector_size;
} BLKID_2.15;
+
+/*
+ * version(s) since util-linux-ng 2.18
+ */
+BLKID_2.18 {
+global:
+ blkid_probe_all_removable;
+} BLKID_2.17;
diff --git a/shlibs/blkid/src/blkidP.h b/shlibs/blkid/src/blkidP.h
index 90900e27..d15b5305 100644
--- a/shlibs/blkid/src/blkidP.h
+++ b/shlibs/blkid/src/blkidP.h
@@ -51,6 +51,7 @@ struct blkid_struct_dev
#define BLKID_BID_FL_VERIFIED 0x0001 /* Device data validated from disk */
#define BLKID_BID_FL_INVALID 0x0004 /* Device is invalid */
+#define BLKID_BID_FL_REMOVABLE 0x0008 /* Device added by blkid_probe_all_removable() */
/*
* Each tag defines a NAME=value pair for a particular device. The tags
@@ -133,8 +134,6 @@ struct blkid_prval
struct blkid_chain *chain; /* owner */
};
-#define BLKID_SB_BUFSIZ 0x11000
-
/*
* Filesystem / Raid magic strings
*/
@@ -155,6 +154,7 @@ struct blkid_idinfo
const char *name; /* fs, raid or partition table name */
int usage; /* BLKID_USAGE_* flag */
int flags; /* BLKID_IDINFO_* flags */
+ int minsz; /* minimal device size */
/* probe function */
int (*probefunc)(blkid_probe pr, const struct blkid_idmag *mag);
@@ -171,6 +171,13 @@ struct blkid_idinfo
*/
#define BLKID_IDINFO_TOLERANT (1 << 1)
+struct blkid_bufinfo {
+ unsigned char *data;
+ blkid_loff_t off;
+ blkid_loff_t len;
+ struct list_head bufs; /* list of buffers */
+};
+
/*
* Low-level probing control struct
*/
@@ -186,13 +193,7 @@ struct blkid_struct_probe
int flags; /* private libray flags */
- unsigned char *sbbuf; /* superblok buffer */
- size_t sbbuf_len; /* size of data in superblock buffer */
-
- unsigned char *buf; /* seek buffer */
- blkid_loff_t buf_off; /* offset of seek buffer */
- size_t buf_len; /* size of data in seek buffer */
- size_t buf_max; /* allocated size of seek buffer */
+ struct list_head buffers; /* list of buffers */
struct blkid_chain chains[BLKID_NCHAINS]; /* array of chains */
struct blkid_chain *cur_chain; /* current chain */
@@ -203,6 +204,7 @@ struct blkid_struct_probe
/* flags */
#define BLKID_PRIVATE_FD (1 << 1) /* see blkid_new_probe_from_filename() */
+#define BLKID_TINY_DEV (1 << 2) /* <= 1.47MiB (floppy or so) */
/*
* Evaluation methods (for blkid_eval_* API)
@@ -266,6 +268,8 @@ extern char *blkid_strndup(const char *s, const int length);
extern char *blkid_strconcat(const char *a, const char *b, const char *c);
extern int blkid_fstatat(DIR *dir, const char *dirname, const char *filename,
struct stat *st, int nofollow);
+extern int blkid_openat(DIR *dir, const char *dirname, const char *filename,
+ int flags);
#define BLKID_CACHE_FILE "/etc/blkid.tab"
#define BLKID_CONFIG_FILE "/etc/blkid.conf"
@@ -357,7 +361,8 @@ extern blkid_dev blkid_new_dev(void);
extern void blkid_free_dev(blkid_dev dev);
/* probe.c */
-unsigned char *blkid_probe_get_buffer(blkid_probe pr,
+extern int blkid_probe_is_tiny(blkid_probe pr);
+extern unsigned char *blkid_probe_get_buffer(blkid_probe pr,
blkid_loff_t off, blkid_loff_t len);
extern unsigned char *blkid_probe_get_sector(blkid_probe pr, unsigned int sector);
diff --git a/shlibs/blkid/src/devname.c b/shlibs/blkid/src/devname.c
index d048c722..5d6da891 100644
--- a/shlibs/blkid/src/devname.c
+++ b/shlibs/blkid/src/devname.c
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
+#include <fcntl.h>
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
@@ -38,7 +39,9 @@
#include <time.h>
#include "blkidP.h"
+
#include "canonicalize.h" /* $(top_srcdir)/include */
+#include "pathnames.h"
/*
* Find a dev struct in the cache by device name, if available.
@@ -157,7 +160,7 @@ static int is_dm_leaf(const char *devname)
* Probe a single block device to add to the device cache.
*/
static void probe_one(blkid_cache cache, const char *ptname,
- dev_t devno, int pri, int only_if_new)
+ dev_t devno, int pri, int only_if_new, int removable)
{
blkid_dev dev = NULL;
struct list_head *p, *pnext;
@@ -237,6 +240,8 @@ set_pri:
dev->bid_pri += 5;
} else if (!strncmp(ptname, "md", 2))
dev->bid_pri = BLKID_PRI_MD;
+ if (removable)
+ dev->bid_flags |= BLKID_BID_FL_REMOVABLE;
}
return;
}
@@ -328,7 +333,7 @@ static void lvm_probe_all(blkid_cache cache, int only_if_new)
lvm_device,
(unsigned int) dev));
probe_one(cache, lvm_device, dev, BLKID_PRI_LVM,
- only_if_new);
+ only_if_new, 0);
free(lvm_device);
}
closedir(lv_list);
@@ -360,7 +365,7 @@ evms_probe_all(blkid_cache cache, int only_if_new)
device, ma, mi));
probe_one(cache, device, makedev(ma, mi), BLKID_PRI_EVMS,
- only_if_new);
+ only_if_new, 0);
num++;
}
fclose(procpt);
@@ -408,7 +413,7 @@ ubi_probe_all(blkid_cache cache, int only_if_new)
continue;
DBG(DEBUG_DEVNAME, printf("UBI vol %s/%s: devno 0x%04X\n",
*dirname, name, (int) dev));
- probe_one(cache, name, dev, BLKID_PRI_UBI, only_if_new);
+ probe_one(cache, name, dev, BLKID_PRI_UBI, only_if_new, 0);
}
closedir(dir);
}
@@ -485,7 +490,7 @@ static int probe_all(blkid_cache cache, int only_if_new)
if (sz > 1)
probe_one(cache, ptname, devs[which], 0,
- only_if_new);
+ only_if_new, 0);
lens[which] = 0; /* mark as checked */
}
@@ -522,20 +527,81 @@ static int probe_all(blkid_cache cache, int only_if_new)
printf("whole dev %s, devno 0x%04X\n",
ptnames[last], (unsigned int) devs[last]));
probe_one(cache, ptnames[last], devs[last], 0,
- only_if_new);
+ only_if_new, 0);
lens[last] = 0;
}
}
/* Handle the last device if it wasn't partitioned */
if (lens[which])
- probe_one(cache, ptname, devs[which], 0, only_if_new);
+ probe_one(cache, ptname, devs[which], 0, only_if_new, 0);
fclose(proc);
blkid_flush_cache(cache);
return 0;
}
+/* Don't use it by default -- it's pretty slow (because cdroms, floppy, ...)
+ */
+static int probe_all_removable(blkid_cache cache)
+{
+ DIR *dir;
+ struct dirent *d;
+ char buf[PATH_MAX];
+
+ if (!cache)
+ return -BLKID_ERR_PARAM;
+
+ dir = opendir(_PATH_SYS_BLOCK);
+ if (!dir)
+ return -BLKID_ERR_PROC;
+
+ while((d = readdir(dir))) {
+ int fd, rc, ma, mi;
+
+#ifdef _DIRENT_HAVE_D_TYPE
+ if (d->d_type != DT_UNKNOWN && d->d_type != DT_LNK)
+ continue;
+#endif
+ if (d->d_name[0] == '.' &&
+ ((d->d_name[1] == 0) ||
+ ((d->d_name[1] == '.') && (d->d_name[2] == 0))))
+ continue;
+
+ snprintf(buf, sizeof(buf), "%s/removable", d->d_name);
+ fd = blkid_openat(dir, _PATH_SYS_BLOCK, buf, O_RDONLY);
+ if (fd < 0)
+ continue;
+
+ rc = read(fd, buf, 1);
+ close(fd);
+
+ if (rc != 1 || *buf != '1')
+ continue; /* not removable device */
+
+ /* get devno */
+ snprintf(buf, sizeof(buf), "%s/dev", d->d_name);
+ fd = blkid_openat(dir, _PATH_SYS_BLOCK, buf, O_RDONLY);
+ if (fd < 0)
+ continue;
+
+ rc = read(fd, buf, sizeof(buf));
+ close(fd);
+
+ if (rc < 3)
+ continue; /* M:N */
+ buf[rc] = '\0';
+ if (sscanf(buf, "%d:%d", &ma, &mi) != 2)
+ continue;
+
+ probe_one(cache, d->d_name, makedev(ma, mi), 0, 0, 1);
+ }
+
+ closedir(dir);
+ return 0;
+}
+
+
/**
* blkid_probe_all:
* @cache: cache handler
@@ -574,6 +640,33 @@ int blkid_probe_all_new(blkid_cache cache)
return ret;
}
+/**
+ * blkid_probe_all_removable:
+ * @cache: cache handler
+ *
+ * The libblkid probing is based on devices from /proc/partitions by default.
+ * This file usually does not contain removable devices (e.g. CDROMs) and this kind
+ * of devices are invisible for libblkid.
+ *
+ * This function adds removable block devices to @cache (probing is based on
+ * information from the /sys directory). Don't forget that removable devices
+ * (floppies, CDROMs, ...) could be pretty slow. It's very bad idea to call
+ * this function by default.
+ *
+ * Note that devices which were detected by this function won't be written to
+ * blkid.tab cache file.
+ *
+ * Returns: 0 on success, or number less than zero in case of error.
+ */
+int blkid_probe_all_removable(blkid_cache cache)
+{
+ int ret;
+
+ DBG(DEBUG_PROBE, printf("Begin blkid_probe_all_removable()\n"));
+ ret = probe_all_removable(cache);
+ DBG(DEBUG_PROBE, printf("End blkid_probe_all_removable()\n"));
+ return ret;
+}
#ifdef TEST_PROGRAM
int main(int argc, char **argv)
@@ -595,6 +688,9 @@ int main(int argc, char **argv)
if (blkid_probe_all(cache) < 0)
printf("%s: error probing devices\n", argv[0]);
+ if (blkid_probe_all_removable(cache) < 0)
+ printf("%s: error probing removable devices\n", argv[0]);
+
blkid_put_cache(cache);
return (0);
}
diff --git a/shlibs/blkid/src/devno.c b/shlibs/blkid/src/devno.c
index 7b9438ff..284f8733 100644
--- a/shlibs/blkid/src/devno.c
+++ b/shlibs/blkid/src/devno.c
@@ -96,14 +96,30 @@ int blkid_fstatat(DIR *dir, const char *dirname, const char *filename,
return fstatat(dirfd(dir), filename, st,
nofollow ? AT_SYMLINK_NOFOLLOW : 0);
#else
- char device[PATH_MAX];
+ char path[PATH_MAX];
+ int len;
+
+ len = snprintf(path, sizeof(path), "%s/%s", dirname, filename);
+ if (len < 0 || len + 1 > sizeof(path))
+ return -1;
+
+ return nofollow ? lstat(path, st) : stat(path, st);
+#endif
+}
+
+int blkid_openat(DIR *dir, const char *dirname, const char *filename, int flags)
+{
+#ifdef HAVE_FSTATAT
+ return openat(dirfd(dir), filename, flags);
+#else
+ char path[PATH_MAX];
int len;
- len = snprintf(device, sizeof(device), "%s/%s", dirname, filename);
- if (len < 0 || len + 1 > sizeof(device))
+ len = snprintf(path, sizeof(path), "%s/%s", dirname, filename);
+ if (len < 0 || len + 1 > sizeof(path))
return -1;
- return nofollow ? lstat(device, st) : stat(device, st);
+ return open(path, flags);
#endif
}
diff --git a/shlibs/blkid/src/fat.h b/shlibs/blkid/src/fat.h
new file mode 100644
index 00000000..b3664641
--- /dev/null
+++ b/shlibs/blkid/src/fat.h
@@ -0,0 +1,90 @@
+#ifndef _BLKID_FAT_H
+#define _BLKID_FAT_H
+
+/* This FAT superblock is required for:
+ *
+ * superblocks/vfat.c
+ * partitions/dos.c
+ */
+
+/* Yucky misaligned values */
+struct vfat_super_block {
+/* 00*/ unsigned char vs_ignored[3];
+/* 03*/ unsigned char vs_sysid[8];
+/* 0b*/ unsigned char vs_sector_size[2];
+/* 0d*/ uint8_t vs_cluster_size;
+/* 0e*/ uint16_t vs_reserved;
+/* 10*/ uint8_t vs_fats;
+/* 11*/ unsigned char vs_dir_entries[2];
+/* 13*/ unsigned char vs_sectors[2];
+/* 15*/ unsigned char vs_media;
+/* 16*/ uint16_t vs_fat_length;
+/* 18*/ uint16_t vs_secs_track;
+/* 1a*/ uint16_t vs_heads;
+/* 1c*/ uint32_t vs_hidden;
+/* 20*/ uint32_t vs_total_sect;
+/* 24*/ uint32_t vs_fat32_length;
+/* 28*/ uint16_t vs_flags;
+/* 2a*/ uint8_t vs_version[2];
+/* 2c*/ uint32_t vs_root_cluster;
+/* 30*/ uint16_t vs_fsinfo_sector;
+/* 32*/ uint16_t vs_backup_boot;
+/* 34*/ uint16_t vs_reserved2[6];
+/* 40*/ unsigned char vs_unknown[3];
+/* 43*/ unsigned char vs_serno[4];
+/* 47*/ unsigned char vs_label[11];
+/* 52*/ unsigned char vs_magic[8];
+/* 5a*/ unsigned char vs_dummy2[0x1fe - 0x5a];
+/*1fe*/ unsigned char vs_pmagic[2];
+} __attribute__((packed));
+
+/* Yucky misaligned values */
+struct msdos_super_block {
+/* 00*/ unsigned char ms_ignored[3];
+/* 03*/ unsigned char ms_sysid[8];
+/* 0b*/ unsigned char ms_sector_size[2];
+/* 0d*/ uint8_t ms_cluster_size;
+/* 0e*/ uint16_t ms_reserved;
+/* 10*/ uint8_t ms_fats;
+/* 11*/ unsigned char ms_dir_entries[2];
+/* 13*/ unsigned char ms_sectors[2]; /* =0 iff V3 or later */
+/* 15*/ unsigned char ms_media;
+/* 16*/ uint16_t ms_fat_length; /* Sectors per FAT */
+/* 18*/ uint16_t ms_secs_track;
+/* 1a*/ uint16_t ms_heads;
+/* 1c*/ uint32_t ms_hidden;
+/* V3 BPB */
+/* 20*/ uint32_t ms_total_sect; /* iff ms_sectors == 0 */
+/* V4 BPB */
+/* 24*/ unsigned char ms_unknown[3]; /* Phys drive no., resvd, V4 sig (0x29) */
+/* 27*/ unsigned char ms_serno[4];
+/* 2b*/ unsigned char ms_label[11];
+/* 36*/ unsigned char ms_magic[8];
+/* 3e*/ unsigned char ms_dummy2[0x1fe - 0x3e];
+/*1fe*/ unsigned char ms_pmagic[2];
+} __attribute__((packed));
+
+
+static inline int blkid_fat_valid_media(struct msdos_super_block *ms)
+{
+ return 0xf8 <= ms->ms_media || ms->ms_media == 0xf0;
+}
+
+static inline int blkid_fat_valid_sectorsize(
+ struct msdos_super_block *ms,
+ uint16_t *sector_size)
+{
+ unsigned char *tmp = (unsigned char *) &ms->ms_sector_size;
+ uint16_t ssz;
+
+ ssz = tmp[0] + (tmp[1] << 8);
+
+ if (ssz != 0x200 && ssz != 0x400 && ssz != 0x800 && ssz != 0x1000)
+ return 0;
+ if (sector_size)
+ *sector_size = ssz;
+ return 1;
+}
+
+
+#endif /* _BLKID_FAT_H */
diff --git a/shlibs/blkid/src/partitions/dos.c b/shlibs/blkid/src/partitions/dos.c
index 21728a5a..ec2ca1eb 100644
--- a/shlibs/blkid/src/partitions/dos.c
+++ b/shlibs/blkid/src/partitions/dos.c
@@ -16,6 +16,7 @@
#include "partitions.h"
#include "dos.h"
#include "aix.h"
+#include "fat.h"
static const struct dos_subtypes {
unsigned char type;
@@ -139,18 +140,30 @@ static int probe_dos_pt(blkid_probe pr, const struct blkid_idmag *mag)
if (memcmp(data, BLKID_AIX_MAGIC_STRING, BLKID_AIX_MAGIC_STRLEN) == 0)
goto nothing;
- p0 = (struct dos_partition *) (data + BLKID_MSDOS_PT_OFFSET);
-
/*
* Now that the 55aa signature is present, this is probably
* either the boot sector of a FAT filesystem or a DOS-type
- * partition table. Reject this in case the boot indicator
- * is not 0 or 0x80.
+ * partition table.
*/
- for (p = p0, i = 0; i < 4; i++, p++) {
+ {
+ struct msdos_super_block *ms =
+ (struct msdos_super_block *) data;
+
+ if (ms->ms_fats && ms->ms_reserved &&
+ ms->ms_cluster_size &&
+ blkid_fat_valid_media(ms) &&
+ blkid_fat_valid_sectorsize(ms, NULL))
+ goto nothing; /* FAT */
+ }
+
+ p0 = (struct dos_partition *) (data + BLKID_MSDOS_PT_OFFSET);
+
+ /*
+ * Reject PT where boot indicator is not 0 or 0x80.
+ */
+ for (p = p0, i = 0; i < 4; i++, p++)
if (p->boot_ind != 0 && p->boot_ind != 0x80)
goto nothing;
- }
/*
* GPT uses valid MBR
diff --git a/shlibs/blkid/src/partitions/gpt.c b/shlibs/blkid/src/partitions/gpt.c
index 2ec3f739..2c3a3267 100644
--- a/shlibs/blkid/src/partitions/gpt.c
+++ b/shlibs/blkid/src/partitions/gpt.c
@@ -368,6 +368,7 @@ const struct blkid_idinfo gpt_pt_idinfo =
{
.name = "gpt",
.probefunc = probe_gpt_pt,
+ .minsz = 1024 * 1440 + 1, /* ignore floppies */
/*
* It would be possible to check for DOS signature (0xAA55), but
diff --git a/shlibs/blkid/src/partitions/partitions.c b/shlibs/blkid/src/partitions/partitions.c
index 82861a5b..154365d7 100644
--- a/shlibs/blkid/src/partitions/partitions.c
+++ b/shlibs/blkid/src/partitions/partitions.c
@@ -505,6 +505,9 @@ static int idinfo_probe(blkid_probe pr, const struct blkid_idinfo *id)
int hasmag = 0;
int rc = 1; /* = nothing detected */
+ if (id->minsz && id->minsz > pr->size)
+ goto nothing; /* the device is too small */
+
mag = id->magics ? &id->magics[0] : NULL;
/* try to detect by magic string */
diff --git a/shlibs/blkid/src/partitions/unixware.c b/shlibs/blkid/src/partitions/unixware.c
index 70b6626f..62dba764 100644
--- a/shlibs/blkid/src/partitions/unixware.c
+++ b/shlibs/blkid/src/partitions/unixware.c
@@ -173,6 +173,7 @@ const struct blkid_idinfo unixware_pt_idinfo =
{
.name = "unixware",
.probefunc = probe_unixware_pt,
+ .minsz = 1024 * 1440 + 1, /* ignore floppies */
.magics =
{
{
diff --git a/shlibs/blkid/src/probe.c b/shlibs/blkid/src/probe.c
index 7ed80072..91366851 100644
--- a/shlibs/blkid/src/probe.c
+++ b/shlibs/blkid/src/probe.c
@@ -115,6 +115,7 @@ static const struct blkid_chaindrv *chains_drvs[] = {
};
static void blkid_probe_reset_vals(blkid_probe pr);
+static void blkid_probe_reset_buffer(blkid_probe pr);
/**
* blkid_new_probe:
@@ -137,6 +138,7 @@ blkid_probe blkid_new_probe(void)
pr->chains[i].flags = chains_drvs[i]->dflt_flags;
pr->chains[i].enabled = chains_drvs[i]->dflt_enabled;
}
+ INIT_LIST_HEAD(&pr->buffers);
return pr;
}
@@ -202,26 +204,13 @@ void blkid_free_probe(blkid_probe pr)
ch->driver->free_data(pr, ch->data);
free(ch->fltr);
}
- free(pr->buf);
- free(pr->sbbuf);
if ((pr->flags & BLKID_PRIVATE_FD) && pr->fd >= 0)
close(pr->fd);
+ blkid_probe_reset_buffer(pr);
free(pr);
}
-static void blkid_probe_reset_buffer(blkid_probe pr)
-{
- DBG(DEBUG_LOWPROBE, printf("reseting blkid probe buffer\n"));
- if (pr->buf)
- memset(pr->buf, 0, pr->buf_max);
- pr->buf_off = 0;
- pr->buf_len = 0;
- if (pr->sbbuf)
- memset(pr->sbbuf, 0, BLKID_SB_BUFSIZ);
- pr->sbbuf_len = 0;
-}
-
/*
* Removes chain values from probing result.
@@ -470,73 +459,87 @@ int __blkid_probe_filter_types(blkid_probe pr, int chain, int flag, char *names[
return 0;
}
-/*
- * Note that we have two offsets:
- *
- * 1/ general device offset (pr->off), that's useful for example when we
- * probe a partition from whole disk image:
- * blkid-low --offset <partition_position> disk.img
- *
- * 2/ buffer offset (the 'off' argument), that useful for offsets in
- * superbloks, ...
- *
- * That means never use lseek(fd, 0, SEEK_SET), the zero position is always
- * pr->off, so lseek(fd, pr->off, SEEK_SET).
- *
- */
unsigned char *blkid_probe_get_buffer(blkid_probe pr,
blkid_loff_t off, blkid_loff_t len)
{
- ssize_t ret_read = 0;
+ struct list_head *p;
+ struct blkid_bufinfo *bf = NULL;
+
+ list_for_each(p, &pr->buffers) {
+ struct blkid_bufinfo *x =
+ list_entry(p, struct blkid_bufinfo, bufs);
+
+ if (x->off <= off && off + len <= x->off + x->len) {
+ DBG(DEBUG_LOWPROBE,
+ printf("\treuse buffer: off=%jd len=%jd\n",
+ x->off, x->len));
+ bf = x;
+ break;
+ }
+ }
+ if (!bf) {
+ ssize_t ret;
+
+ if (blkid_llseek(pr->fd, pr->off + off, SEEK_SET) < 0)
+ return NULL;
+
+ /* allocate info and space for data by why call */
+ bf = calloc(1, sizeof(struct blkid_bufinfo) + len);
+ if (!bf)
+ return NULL;
+
+ bf->data = ((unsigned char *) bf) + sizeof(struct blkid_bufinfo);
+ bf->len = len;
+ bf->off = off;
+ INIT_LIST_HEAD(&bf->bufs);
- if (off < 0 || len < 0) {
DBG(DEBUG_LOWPROBE,
- printf("unexpected offset or length of buffer requested\n"));
- return NULL;
- }
- if (off + len <= BLKID_SB_BUFSIZ) {
- if (!pr->sbbuf) {
- pr->sbbuf = malloc(BLKID_SB_BUFSIZ);
- if (!pr->sbbuf)
- return NULL;
- }
- if (!pr->sbbuf_len) {
- if (lseek(pr->fd, pr->off, SEEK_SET) < 0)
- return NULL;
- ret_read = read(pr->fd, pr->sbbuf, BLKID_SB_BUFSIZ);
- if (ret_read < 0)
- ret_read = 0;
- pr->sbbuf_len = ret_read;
- }
- if (off + len > pr->sbbuf_len)
+ printf("\tbuffer read: off=%jd len=%jd\n", off, len));
+
+ ret = read(pr->fd, bf->data, len);
+ if (ret != (ssize_t) len) {
+ free(bf);
return NULL;
- return pr->sbbuf + off;
- } else {
- unsigned char *newbuf = NULL;
-
- if (len > pr->buf_max) {
- newbuf = realloc(pr->buf, len);
- if (!newbuf)
- return NULL;
- pr->buf = newbuf;
- pr->buf_max = len;
- pr->buf_off = 0;
- pr->buf_len = 0;
}
- if (newbuf || off < pr->buf_off ||
- off + len > pr->buf_off + pr->buf_len) {
+ list_add_tail(&bf->bufs, &pr->buffers);
+ }
- if (blkid_llseek(pr->fd, pr->off + off, SEEK_SET) < 0)
- return NULL;
+ return off ? bf->data + (off - bf->off) : bf->data;
+}
- ret_read = read(pr->fd, pr->buf, len);
- if (ret_read != (ssize_t) len)
- return NULL;
- pr->buf_off = off;
- pr->buf_len = len;
- }
- return off ? pr->buf + (off - pr->buf_off) : pr->buf;
+
+static void blkid_probe_reset_buffer(blkid_probe pr)
+{
+ ssize_t read_ct = 0, len_ct = 0;
+
+ if (!pr || list_empty(&pr->buffers))
+ return;
+
+ DBG(DEBUG_LOWPROBE, printf("reseting probing buffers\n"));
+
+ while (!list_empty(&pr->buffers)) {
+ struct blkid_bufinfo *bf = list_entry(pr->buffers.next,
+ struct blkid_bufinfo, bufs);
+
+ read_ct++;
+ len_ct += bf->len;
+ list_del(&bf->bufs);
+ free(bf);
}
+
+ DBG(DEBUG_LOWPROBE,
+ printf("buffers summary: %jd bytes by %jd read() call(s)\n",
+ len_ct, read_ct));
+
+ INIT_LIST_HEAD(&pr->buffers);
+}
+
+/*
+ * Small devices need a special care.
+ */
+int blkid_probe_is_tiny(blkid_probe pr)
+{
+ return pr && (pr->flags & BLKID_TINY_DEV);
}
/**
@@ -570,6 +573,10 @@ int blkid_probe_set_device(blkid_probe pr, int fd,
pr->mode = 0;
pr->blkssz = 0;
+#if defined(POSIX_FADV_RANDOM) && defined(HAVE_POSIX_FADVISE)
+ /* Disable read-ahead */
+ posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM);
+#endif
if (size)
pr->size = size;
else {
@@ -589,13 +596,23 @@ int blkid_probe_set_device(blkid_probe pr, int fd,
if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode))
pr->devno = sb.st_rdev;
+
+ if (pr->off > pr->size)
+ goto err;
+
+ /* The probing area cannot be larger than whole device, pr->off
+ * is offset within the device */
+ pr->size -= pr->off;
}
if (!pr->size)
goto err;
-
DBG(DEBUG_LOWPROBE, printf("ready for low-probing, offset=%zd, size=%zd\n",
pr->off, pr->size));
+
+ if (pr->size <= 1440 * 1024 && !S_ISCHR(pr->mode))
+ pr->flags |= BLKID_TINY_DEV;
+
return 0;
err:
DBG(DEBUG_LOWPROBE,
diff --git a/shlibs/blkid/src/save.c b/shlibs/blkid/src/save.c
index c61373d5..a1583ecc 100644
--- a/shlibs/blkid/src/save.c
+++ b/shlibs/blkid/src/save.c
@@ -119,7 +119,7 @@ int blkid_flush_cache(blkid_cache cache)
list_for_each(p, &cache->bic_devs) {
blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs);
- if (!dev->bid_type)
+ if (!dev->bid_type || (dev->bid_flags & BLKID_BID_FL_REMOVABLE))
continue;
if ((ret = save_dev(dev, file)) < 0)
break;
diff --git a/shlibs/blkid/src/superblocks/Makefile.am b/shlibs/blkid/src/superblocks/Makefile.am
index 33e5d0c3..f5b88b8e 100644
--- a/shlibs/blkid/src/superblocks/Makefile.am
+++ b/shlibs/blkid/src/superblocks/Makefile.am
@@ -45,4 +45,5 @@ libblkid_superblocks_la_SOURCES = \
ubifs.c \
bfs.c \
drbd.c \
- vmfs.c
+ vmfs.c \
+ befs.c
diff --git a/shlibs/blkid/src/superblocks/befs.c b/shlibs/blkid/src/superblocks/befs.c
new file mode 100644
index 00000000..b341402a
--- /dev/null
+++ b/shlibs/blkid/src/superblocks/befs.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2010 Jeroen Oortwijn <oortwijn@gmail.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "superblocks.h"
+
+#define B_OS_NAME_LENGTH 0x20
+#define SUPER_BLOCK_MAGIC1 0x42465331 /* BFS1 */
+#define SUPER_BLOCK_MAGIC2 0xdd121031
+#define SUPER_BLOCK_MAGIC3 0x15b6830e
+#define SUPER_BLOCK_FS_ENDIAN 0x42494745 /* BIGE */
+#define INODE_MAGIC1 0x3bbe0ad9
+#define B_UINT64_TYPE 0x554C4C47 /* ULLG */
+
+#define FS16_TO_CPU(value, fs_is_le) (fs_is_le ? le16_to_cpu(value) \
+ : be16_to_cpu(value))
+#define FS32_TO_CPU(value, fs_is_le) (fs_is_le ? le32_to_cpu(value) \
+ : be32_to_cpu(value))
+#define FS64_TO_CPU(value, fs_is_le) (fs_is_le ? le64_to_cpu(value) \
+ : be64_to_cpu(value))
+
+typedef struct block_run {
+ int32_t allocation_group;
+ uint16_t start;
+ uint16_t len;
+} __attribute__((packed)) block_run, inode_addr;
+
+struct befs_super_block {
+ char name[B_OS_NAME_LENGTH];
+ int32_t magic1;
+ int32_t fs_byte_order;
+ uint32_t block_size;
+ uint32_t block_shift;
+ int64_t num_blocks;
+ int64_t used_blocks;
+ int32_t inode_size;
+ int32_t magic2;
+ int32_t blocks_per_ag;
+ int32_t ag_shift;
+ int32_t num_ags;
+ int32_t flags;
+ block_run log_blocks;
+ int64_t log_start;
+ int64_t log_end;
+ int32_t magic3;
+ inode_addr root_dir;
+ inode_addr indices;
+ int32_t pad[8];
+} __attribute__((packed));
+
+typedef struct data_stream {
+ block_run direct[12];
+ int64_t max_direct_range;
+ block_run indirect;
+ int64_t max_indirect_range;
+ block_run double_indirect;
+ int64_t max_double_indirect_range;
+ int64_t size;
+} __attribute__((packed)) data_stream;
+
+struct befs_inode {
+ int32_t magic1;
+ inode_addr inode_num;
+ int32_t uid;
+ int32_t gid;
+ int32_t mode;
+ int32_t flags;
+ int64_t create_time;
+ int64_t last_modified_time;
+ inode_addr parent;
+ inode_addr attributes;
+ uint32_t type;
+ int32_t inode_size;
+ uint32_t etc;
+ data_stream data;
+ int32_t pad[4];
+ int32_t small_data[1];
+} __attribute__((packed));
+
+struct small_data {
+ uint32_t type;
+ uint16_t name_size;
+ uint16_t data_size;
+ char name[0];
+} __attribute__((packed));
+
+static int probe_befs(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct befs_super_block *bs;
+ struct befs_inode *bi;
+ struct small_data *sd;
+ int fs_le;
+ uint64_t volume_id = 0;
+ const char *version = NULL;
+
+ bs = (struct befs_super_block *) blkid_probe_get_buffer(pr,
+ mag->sboff - B_OS_NAME_LENGTH,
+ sizeof(struct befs_super_block));
+ if (!bs)
+ return -1;
+
+ if (le32_to_cpu(bs->magic1) == SUPER_BLOCK_MAGIC1
+ && le32_to_cpu(bs->magic2) == SUPER_BLOCK_MAGIC2
+ && le32_to_cpu(bs->magic3) == SUPER_BLOCK_MAGIC3
+ && le32_to_cpu(bs->fs_byte_order) == SUPER_BLOCK_FS_ENDIAN) {
+ fs_le = 1;
+ version = "little-endian";
+ } else if (be32_to_cpu(bs->magic1) == SUPER_BLOCK_MAGIC1
+ && be32_to_cpu(bs->magic2) == SUPER_BLOCK_MAGIC2
+ && be32_to_cpu(bs->magic3) == SUPER_BLOCK_MAGIC3
+ && be32_to_cpu(bs->fs_byte_order) == SUPER_BLOCK_FS_ENDIAN) {
+ fs_le = 0;
+ version = "big-endian";
+ } else
+ return -1;
+
+ bi = (struct befs_inode *) blkid_probe_get_buffer(pr,
+ (FS32_TO_CPU(bs->root_dir.allocation_group, fs_le)
+ << FS32_TO_CPU(bs->ag_shift, fs_le)
+ << FS32_TO_CPU(bs->block_shift, fs_le))
+ + (FS16_TO_CPU(bs->root_dir.start, fs_le)
+ << FS32_TO_CPU(bs->block_shift, fs_le)),
+ FS16_TO_CPU(bs->root_dir.len, fs_le)
+ << FS32_TO_CPU(bs->block_shift, fs_le));
+ if (!bi)
+ return -1;
+
+ if (FS32_TO_CPU(bi->magic1, fs_le) != INODE_MAGIC1)
+ return -1;
+
+ /*
+ * all checks pass, set LABEL and VERSION
+ */
+ if (strlen(bs->name))
+ blkid_probe_set_label(pr, (unsigned char *) bs->name,
+ sizeof(bs->name));
+ if (version)
+ blkid_probe_set_version(pr, version);
+
+ /*
+ * search for UUID
+ */
+ sd = (struct small_data *) bi->small_data;
+
+ do {
+ if (FS32_TO_CPU(sd->type, fs_le) == B_UINT64_TYPE
+ && FS16_TO_CPU(sd->name_size, fs_le) == 12
+ && FS16_TO_CPU(sd->data_size, fs_le) == 8
+ && strcmp(sd->name, "be:volume_id") == 0) {
+ volume_id = *(uint64_t *) ((uint8_t *) sd->name
+ + FS16_TO_CPU(sd->name_size, fs_le)
+ + 3);
+ blkid_probe_sprintf_uuid(pr,
+ (unsigned char *) &volume_id,
+ sizeof(volume_id),
+ "%016" PRIx64,
+ FS64_TO_CPU(volume_id, fs_le));
+ break;
+ } else if (FS32_TO_CPU(sd->type, fs_le) == 0
+ && FS16_TO_CPU(sd->name_size, fs_le) == 0
+ && FS16_TO_CPU(sd->data_size, fs_le) == 0) {
+ break;
+ }
+
+ sd = (struct small_data *) ((uint8_t *) sd
+ + sizeof(struct small_data)
+ + FS16_TO_CPU(sd->name_size, fs_le) + 3
+ + FS16_TO_CPU(sd->data_size, fs_le) + 1);
+
+ } while ((intptr_t) sd < (intptr_t) bi
+ + FS32_TO_CPU(bi->inode_size, fs_le)
+ - sizeof(struct small_data));
+
+ if (volume_id == 0) {
+ /*
+ * TODO: Search for the be:volume_id attribute in the
+ * attributes directory of the root directory.
+ */
+ }
+
+ return 0;
+}
+
+const struct blkid_idinfo befs_idinfo =
+{
+ .name = "befs",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_befs,
+ .minsz = 1024 * 1440,
+ .magics = {
+ { .magic = "BFS1", .len = 4, .sboff = B_OS_NAME_LENGTH },
+ { .magic = "1SFB", .len = 4, .sboff = B_OS_NAME_LENGTH },
+ { .magic = "BFS1", .len = 4, .sboff = 0x200 +
+ B_OS_NAME_LENGTH },
+ { .magic = "1SFB", .len = 4, .sboff = 0x200 +
+ B_OS_NAME_LENGTH },
+ { NULL }
+ }
+};
diff --git a/shlibs/blkid/src/superblocks/drbd.c b/shlibs/blkid/src/superblocks/drbd.c
index e0bbb4d6..a56486e9 100644
--- a/shlibs/blkid/src/superblocks/drbd.c
+++ b/shlibs/blkid/src/superblocks/drbd.c
@@ -78,7 +78,8 @@ static int probe_drbd(blkid_probe pr, const struct blkid_idmag *mag)
blkid_probe_get_buffer(pr,
off,
sizeof(struct md_on_disk_08));
-
+ if (!md)
+ return -1;
if (be32_to_cpu(md->magic) != DRBD_MD_MAGIC_08)
return -1;
diff --git a/shlibs/blkid/src/superblocks/gfs.c b/shlibs/blkid/src/superblocks/gfs.c
index 8ad81bcb..b2c01630 100644
--- a/shlibs/blkid/src/superblocks/gfs.c
+++ b/shlibs/blkid/src/superblocks/gfs.c
@@ -108,6 +108,7 @@ const struct blkid_idinfo gfs_idinfo =
.name = "gfs",
.usage = BLKID_USAGE_FILESYSTEM,
.probefunc = probe_gfs,
+ .minsz = 32 * 1024 * 1024, /* minimal size of GFS journal */
.magics =
{
{ .magic = "\x01\x16\x19\x70", .len = 4, .kboff = 64 },
@@ -120,6 +121,7 @@ const struct blkid_idinfo gfs2_idinfo =
.name = "gfs2",
.usage = BLKID_USAGE_FILESYSTEM,
.probefunc = probe_gfs2,
+ .minsz = 32 * 1024 * 1024, /* minimal size of GFS journal */
.magics =
{
{ .magic = "\x01\x16\x19\x70", .len = 4, .kboff = 64 },
diff --git a/shlibs/blkid/src/superblocks/jfs.c b/shlibs/blkid/src/superblocks/jfs.c
index e6e44505..9a49c674 100644
--- a/shlibs/blkid/src/superblocks/jfs.c
+++ b/shlibs/blkid/src/superblocks/jfs.c
@@ -61,6 +61,7 @@ const struct blkid_idinfo jfs_idinfo =
.name = "jfs",
.usage = BLKID_USAGE_FILESYSTEM,
.probefunc = probe_jfs,
+ .minsz = 16 * 1024 * 1024,
.magics =
{
{ .magic = "JFS1", .len = 4, .kboff = 32 },
diff --git a/shlibs/blkid/src/superblocks/minix.c b/shlibs/blkid/src/superblocks/minix.c
index 784f0758..7b314abc 100644
--- a/shlibs/blkid/src/superblocks/minix.c
+++ b/shlibs/blkid/src/superblocks/minix.c
@@ -11,20 +11,84 @@
#include "superblocks.h"
+struct minix_super_block {
+ uint16_t s_ninodes;
+ uint16_t s_nzones;
+ uint16_t s_imap_blocks;
+ uint16_t s_zmap_blocks;
+ uint16_t s_firstdatazone;
+ uint16_t s_log_zone_size;
+ uint32_t s_max_size;
+ uint16_t s_magic;
+ uint16_t s_state;
+ uint32_t s_zones;
+};
+
+struct minix3_super_block {
+ uint32_t s_ninodes;
+ uint16_t s_pad0;
+ uint16_t s_imap_blocks;
+ uint16_t s_zmap_blocks;
+ uint16_t s_firstdatazone;
+ uint16_t s_log_zone_size;
+ uint16_t s_pad1;
+ uint32_t s_max_size;
+ uint32_t s_zones;
+ uint16_t s_magic;
+ uint16_t s_pad2;
+ uint16_t s_blocksize;
+ uint8_t s_disk_version;
+};
+
+#define MINIX_BLOCK_SIZE_BITS 10
+#define MINIX_BLOCK_SIZE (1 << MINIX_BLOCK_SIZE_BITS)
+
static int probe_minix(blkid_probe pr, const struct blkid_idmag *mag)
{
+ int version;
+
/* for more details see magic strings below */
switch(mag->magic[1]) {
case '\023':
- blkid_probe_set_version(pr, "1");
+ version = 1;
break;
case '\044':
- blkid_probe_set_version(pr, "2");
+ version = 2;
break;
case '\115':
- blkid_probe_set_version(pr, "3");
+ version = 3;
break;
+ default:
+ return -1;
+ break;
+ }
+
+ if (version <= 2) {
+ struct minix_super_block *sb;
+ uint32_t zones;
+
+ sb = blkid_probe_get_sb(pr, mag, struct minix_super_block);
+ if (!sb || sb->s_imap_blocks == 0 || sb->s_zmap_blocks == 0)
+ return -1;
+
+ zones = version == 2 ? sb->s_zones : sb->s_nzones;
+
+ /* sanity checks to be sure that the FS is really minix */
+ if (sb->s_imap_blocks * MINIX_BLOCK_SIZE * 8 < sb->s_ninodes + 1)
+ return -1;
+ if (sb->s_zmap_blocks * MINIX_BLOCK_SIZE * 8 < zones - sb->s_firstdatazone + 1)
+ return -1;
+
+ } else if (version == 3) {
+ struct minix3_super_block *sb;
+
+ sb = blkid_probe_get_sb(pr, mag, struct minix3_super_block);
+ if (!sb || sb->s_imap_blocks == 0 || sb->s_zmap_blocks == 0)
+ return -1;
+
}
+
+ blkid_probe_sprintf_version(pr, "%d", version);
return 0;
}
diff --git a/shlibs/blkid/src/superblocks/ocfs.c b/shlibs/blkid/src/superblocks/ocfs.c
index 6e58b37a..9dbf41b1 100644
--- a/shlibs/blkid/src/superblocks/ocfs.c
+++ b/shlibs/blkid/src/superblocks/ocfs.c
@@ -174,6 +174,7 @@ const struct blkid_idinfo ocfs_idinfo =
.name = "ocfs",
.usage = BLKID_USAGE_FILESYSTEM,
.probefunc = probe_ocfs,
+ .minsz = 108 * 1024 * 1024,
.magics =
{
{ .magic = "OracleCFS", .len = 9, .kboff = 8 },
@@ -186,6 +187,7 @@ const struct blkid_idinfo ocfs2_idinfo =
.name = "ocfs2",
.usage = BLKID_USAGE_FILESYSTEM,
.probefunc = probe_ocfs2,
+ .minsz = 108 * 1024 * 1024,
.magics =
{
{ .magic = "OCFSV2", .len = 6, .kboff = 1 },
@@ -196,6 +198,7 @@ const struct blkid_idinfo ocfs2_idinfo =
}
};
+/* Oracle ASM (Automatic Storage Management) */
const struct blkid_idinfo oracleasm_idinfo =
{
.name = "oracleasm",
diff --git a/shlibs/blkid/src/superblocks/reiserfs.c b/shlibs/blkid/src/superblocks/reiserfs.c
index 4222a307..921f5237 100644
--- a/shlibs/blkid/src/superblocks/reiserfs.c
+++ b/shlibs/blkid/src/superblocks/reiserfs.c
@@ -98,6 +98,7 @@ const struct blkid_idinfo reiser_idinfo =
.name = "reiserfs",
.usage = BLKID_USAGE_FILESYSTEM,
.probefunc = probe_reiser,
+ .minsz = 4096 * 512, /* not sure, this is minimal size of journal */
.magics =
{
{ .magic = "ReIsErFs", .len = 8, .kboff = 8, .sboff = 0x34 },
@@ -114,6 +115,7 @@ const struct blkid_idinfo reiser4_idinfo =
.name = "reiser4",
.usage = BLKID_USAGE_FILESYSTEM,
.probefunc = probe_reiser4,
+ .minsz = 4096 * 512, /* not sure, this is minimal size of journal */
.magics =
{
{ .magic = "ReIsEr4", .len = 7, .kboff = 64 },
diff --git a/shlibs/blkid/src/superblocks/superblocks.c b/shlibs/blkid/src/superblocks/superblocks.c
index e77c511d..fd12e5ec 100644
--- a/shlibs/blkid/src/superblocks/superblocks.c
+++ b/shlibs/blkid/src/superblocks/superblocks.c
@@ -138,7 +138,8 @@ static const struct blkid_idinfo *idinfos[] =
&btrfs_idinfo,
&ubifs_idinfo,
&bfs_idinfo,
- &vmfs_fs_idinfo
+ &vmfs_fs_idinfo,
+ &befs_idinfo
};
/*
@@ -310,6 +311,12 @@ static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn)
printf("--> starting probing loop [SUBLKS idx=%d]\n",
chn->idx));
+ if (pr->size <= 1024 && !S_ISCHR(pr->mode))
+ /* Ignore very very small block devices or regular files (e.g.
+ * extended partitions). Note that size of the UBI char devices
+ * is 1 byte */
+ return 1;
+
i = chn->idx + 1;
for ( ; i < ARRAY_SIZE(idinfos); i++) {
@@ -325,8 +332,19 @@ static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn)
continue;
id = idinfos[i];
+
+ if (id->minsz && id->minsz > pr->size)
+ continue; /* the device is too small */
+
mag = id->magics ? &id->magics[0] : NULL;
+ /* don't probe for RAIDs, swap or journal on floppies */
+ if ((id->usage & (BLKID_USAGE_RAID | BLKID_USAGE_OTHER)) &&
+ blkid_probe_is_tiny(pr))
+ continue;
+
+ DBG(DEBUG_LOWPROBE, printf("[%d] %s:\n", i, id->name));
+
/* try to detect by magic string */
while(mag && mag->magic) {
unsigned char *buf;
@@ -337,8 +355,8 @@ static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn)
if (buf && !memcmp(mag->magic,
buf + (mag->sboff & 0x3ff), mag->len)) {
DBG(DEBUG_LOWPROBE, printf(
- "%s: magic sboff=%u, kboff=%ld\n",
- id->name, mag->sboff, mag->kboff));
+ "\tmagic sboff=%u, kboff=%ld\n",
+ mag->sboff, mag->kboff));
hasmag = 1;
off += mag->sboff & 0x3ff;
break;
@@ -352,8 +370,7 @@ static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn)
/* final check by probing function */
if (id->probefunc) {
- DBG(DEBUG_LOWPROBE, printf(
- "%s: call probefunc()\n", id->name));
+ DBG(DEBUG_LOWPROBE, printf("\tcall probefunc()\n"));
if (id->probefunc(pr, mag) != 0)
continue;
}
@@ -393,6 +410,9 @@ static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn)
* The function does not check for filesystems when a RAID or crypto signature
* is detected. The function also does not check for collision between RAIDs
* and crypto devices. The first detected RAID or crypto device is returned.
+ *
+ * The function does not probe for ambivalent results on very small devices
+ * (e.g. floppies), on small devices the first detected filesystem is returned.
*/
static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn)
{
@@ -404,6 +424,11 @@ static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn)
int rc;
while ((rc = superblocks_probe(pr, chn)) == 0) {
+
+ if (blkid_probe_is_tiny(pr) && !count)
+ /* floppy or so -- returns the first result. */
+ return 0;
+
if (!count) {
/* save the first result */
nvals = blkid_probe_chain_copy_vals(pr, chn, vals, nvals);
diff --git a/shlibs/blkid/src/superblocks/superblocks.h b/shlibs/blkid/src/superblocks/superblocks.h
index 893ae72a..12f197e5 100644
--- a/shlibs/blkid/src/superblocks/superblocks.h
+++ b/shlibs/blkid/src/superblocks/superblocks.h
@@ -64,6 +64,7 @@ extern const struct blkid_idinfo bfs_idinfo;
extern const struct blkid_idinfo vmfs_volume_idinfo;
extern const struct blkid_idinfo vmfs_fs_idinfo;
extern const struct blkid_idinfo drbd_idinfo;
+extern const struct blkid_idinfo befs_idinfo;
/*
* superblock functions
diff --git a/shlibs/blkid/src/superblocks/swap.c b/shlibs/blkid/src/superblocks/swap.c
index 4fb4ab7a..8aaa6f31 100644
--- a/shlibs/blkid/src/superblocks/swap.c
+++ b/shlibs/blkid/src/superblocks/swap.c
@@ -99,6 +99,7 @@ const struct blkid_idinfo swap_idinfo =
.name = "swap",
.usage = BLKID_USAGE_OTHER,
.probefunc = probe_swap,
+ .minsz = 10 * 4096, /* 10 pages */
.magics =
{
{ "SWAP-SPACE", 10, 0, 0xff6 },
@@ -121,6 +122,7 @@ const struct blkid_idinfo swsuspend_idinfo =
.name = "swsuspend",
.usage = BLKID_USAGE_OTHER,
.probefunc = probe_swsuspend,
+ .minsz = 10 * 4096, /* 10 pages */
.magics =
{
{ "S1SUSPEND", 9, 0, 0xff6 },
diff --git a/shlibs/blkid/src/superblocks/vfat.c b/shlibs/blkid/src/superblocks/vfat.c
index 7587f8dd..b24f6075 100644
--- a/shlibs/blkid/src/superblocks/vfat.c
+++ b/shlibs/blkid/src/superblocks/vfat.c
@@ -18,62 +18,8 @@
#include "superblocks.h"
-/* Yucky misaligned values */
-struct vfat_super_block {
-/* 00*/ unsigned char vs_ignored[3];
-/* 03*/ unsigned char vs_sysid[8];
-/* 0b*/ unsigned char vs_sector_size[2];
-/* 0d*/ uint8_t vs_cluster_size;
-/* 0e*/ uint16_t vs_reserved;
-/* 10*/ uint8_t vs_fats;
-/* 11*/ unsigned char vs_dir_entries[2];
-/* 13*/ unsigned char vs_sectors[2];
-/* 15*/ unsigned char vs_media;
-/* 16*/ uint16_t vs_fat_length;
-/* 18*/ uint16_t vs_secs_track;
-/* 1a*/ uint16_t vs_heads;
-/* 1c*/ uint32_t vs_hidden;
-/* 20*/ uint32_t vs_total_sect;
-/* 24*/ uint32_t vs_fat32_length;
-/* 28*/ uint16_t vs_flags;
-/* 2a*/ uint8_t vs_version[2];
-/* 2c*/ uint32_t vs_root_cluster;
-/* 30*/ uint16_t vs_fsinfo_sector;
-/* 32*/ uint16_t vs_backup_boot;
-/* 34*/ uint16_t vs_reserved2[6];
-/* 40*/ unsigned char vs_unknown[3];
-/* 43*/ unsigned char vs_serno[4];
-/* 47*/ unsigned char vs_label[11];
-/* 52*/ unsigned char vs_magic[8];
-/* 5a*/ unsigned char vs_dummy2[0x1fe - 0x5a];
-/*1fe*/ unsigned char vs_pmagic[2];
-} __attribute__((packed));
-
-/* Yucky misaligned values */
-struct msdos_super_block {
-/* 00*/ unsigned char ms_ignored[3];
-/* 03*/ unsigned char ms_sysid[8];
-/* 0b*/ unsigned char ms_sector_size[2];
-/* 0d*/ uint8_t ms_cluster_size;
-/* 0e*/ uint16_t ms_reserved;
-/* 10*/ uint8_t ms_fats;
-/* 11*/ unsigned char ms_dir_entries[2];
-/* 13*/ unsigned char ms_sectors[2]; /* =0 iff V3 or later */
-/* 15*/ unsigned char ms_media;
-/* 16*/ uint16_t ms_fat_length; /* Sectors per FAT */
-/* 18*/ uint16_t ms_secs_track;
-/* 1a*/ uint16_t ms_heads;
-/* 1c*/ uint32_t ms_hidden;
-/* V3 BPB */
-/* 20*/ uint32_t ms_total_sect; /* iff ms_sectors == 0 */
-/* V4 BPB */
-/* 24*/ unsigned char ms_unknown[3]; /* Phys drive no., resvd, V4 sig (0x29) */
-/* 27*/ unsigned char ms_serno[4];
-/* 2b*/ unsigned char ms_label[11];
-/* 36*/ unsigned char ms_magic[8];
-/* 3e*/ unsigned char ms_dummy2[0x1fe - 0x3e];
-/*1fe*/ unsigned char ms_pmagic[2];
-} __attribute__((packed));
+/* {msdos,vfat}_super_block is defined in ../fat.h */
+#include "fat.h"
struct vfat_dir_entry {
uint8_t name[11];
@@ -111,25 +57,59 @@ struct fat32_fsinfo {
static const char *no_name = "NO NAME ";
-static unsigned char *search_fat_label(struct vfat_dir_entry *dir, int count)
+/*
+ * Look for LABEL (name) in the FAT root directory.
+ */
+static unsigned char *search_fat_label(blkid_probe pr,
+ uint32_t offset, uint32_t entries)
{
+ struct vfat_dir_entry *ent, *dir = NULL;
int i;
- for (i = 0; i < count; i++) {
- if (dir[i].name[0] == 0x00)
+ DBG(DEBUG_LOWPROBE,
+ printf("\tlook for label in root-dir "
+ "(entries: %d, offset: %d)\n", entries, offset));
+
+ if (!blkid_probe_is_tiny(pr)) {
+ /* large disk, read whole root directory */
+ dir = (struct vfat_dir_entry *)
+ blkid_probe_get_buffer(pr,
+ offset,
+ entries * sizeof(struct vfat_dir_entry));
+ if (!dir)
+ return NULL;
+ }
+
+ for (i = 0; i < entries; i++) {
+ /*
+ * The root directory could be relatively large (4-16kB).
+ * Fortunately, the LABEL is usually the first entry in the
+ * directory. On tiny disks we call read() per entry.
+ */
+ if (!dir)
+ ent = (struct vfat_dir_entry *)
+ blkid_probe_get_buffer(pr,
+ offset + (i * sizeof(struct vfat_dir_entry)),
+ sizeof(struct vfat_dir_entry));
+ else
+ ent = &dir[i];
+
+ if (!ent || ent->name[0] == 0x00)
break;
- if ((dir[i].name[0] == FAT_ENTRY_FREE) ||
- (dir[i].cluster_high != 0 || dir[i].cluster_low != 0) ||
- ((dir[i].attr & FAT_ATTR_MASK) == FAT_ATTR_LONG_NAME))
+ if ((ent->name[0] == FAT_ENTRY_FREE) ||
+ (ent->cluster_high != 0 || ent->cluster_low != 0) ||
+ ((ent->attr & FAT_ATTR_MASK) == FAT_ATTR_LONG_NAME))
continue;
- if ((dir[i].attr & (FAT_ATTR_VOLUME_ID | FAT_ATTR_DIR)) ==
+ if ((ent->attr & (FAT_ATTR_VOLUME_ID | FAT_ATTR_DIR)) ==
FAT_ATTR_VOLUME_ID) {
- return dir[i].name;
+ DBG(DEBUG_LOWPROBE,
+ printf("\tfound fs LABEL at entry %d\n", i));
+ return ent->name;
}
}
- return 0;
+ return NULL;
}
/*
@@ -159,7 +139,7 @@ static int probe_fat_nomagic(blkid_probe pr, const struct blkid_idmag *mag)
return 1;
/* media check */
- if (ms->ms_media < 0xf8 && ms->ms_media != 0xf0)
+ if (!blkid_fat_valid_media(ms))
return 1;
/* fat counts(Linux kernel expects at least 1 FAT table) */
@@ -188,16 +168,14 @@ static int probe_vfat(blkid_probe pr, const struct blkid_idmag *mag)
{
struct vfat_super_block *vs;
struct msdos_super_block *ms;
- struct vfat_dir_entry *dir;
const unsigned char *vol_label = 0, *tmp;
- unsigned char *vol_serno;
+ unsigned char *vol_serno, vol_label_buf[11];
int maxloop = 100;
uint16_t sector_size, dir_entries, reserved;
uint32_t sect_count, fat_size, dir_size, cluster_count, fat_length;
uint32_t buf_size, start_data_sect, next, root_start, root_dir_entries;
const char *version = NULL;
-
/* non-standard magic strings */
if (mag->len <= 2 && probe_fat_nomagic(pr, mag) != 0)
return 1;
@@ -211,10 +189,7 @@ static int probe_vfat(blkid_probe pr, const struct blkid_idmag *mag)
return -1;
/* sector size check */
- tmp = (unsigned char *) &ms->ms_sector_size;
- sector_size = tmp[0] + (tmp[1] << 8);
- if (sector_size != 0x200 && sector_size != 0x400 &&
- sector_size != 0x800 && sector_size != 0x1000)
+ if (!blkid_fat_valid_sectorsize(ms, &sector_size))
return 1;
tmp = (unsigned char *) &ms->ms_dir_entries;
@@ -247,11 +222,11 @@ static int probe_vfat(blkid_probe pr, const struct blkid_idmag *mag)
root_dir_entries = vs->vs_dir_entries[0] +
(vs->vs_dir_entries[1] << 8);
- buf_size = root_dir_entries * sizeof(struct vfat_dir_entry);
- dir = (struct vfat_dir_entry *)
- blkid_probe_get_buffer(pr, root_start, buf_size);
- if (dir)
- vol_label = search_fat_label(dir, root_dir_entries);
+ vol_label = search_fat_label(pr, root_start, root_dir_entries);
+ if (vol_label) {
+ memcpy(vol_label_buf, vol_label, 11);
+ vol_label = vol_label_buf;
+ }
if (!vol_label || !memcmp(vol_label, no_name, 11))
vol_label = ms->ms_label;
@@ -284,16 +259,14 @@ static int probe_vfat(blkid_probe pr, const struct blkid_idmag *mag)
next_off = (start_data_sect + next_sect_off) *
sector_size;
- dir = (struct vfat_dir_entry *)
- blkid_probe_get_buffer(pr, next_off, buf_size);
- if (dir == NULL)
- break;
-
count = buf_size / sizeof(struct vfat_dir_entry);
- vol_label = search_fat_label(dir, count);
- if (vol_label)
+ vol_label = search_fat_label(pr, next_off, count);
+ if (vol_label) {
+ memcpy(vol_label_buf, vol_label, 11);
+ vol_label = vol_label_buf;
break;
+ }
/* get FAT entry */
fat_entry_off = (reserved * sector_size) +
diff --git a/shlibs/blkid/src/superblocks/zfs.c b/shlibs/blkid/src/superblocks/zfs.c
index 2d626427..0f580262 100644
--- a/shlibs/blkid/src/superblocks/zfs.c
+++ b/shlibs/blkid/src/superblocks/zfs.c
@@ -54,6 +54,7 @@ const struct blkid_idinfo zfs_idinfo =
.name = "zfs",
.usage = BLKID_USAGE_FILESYSTEM,
.probefunc = probe_zfs,
+ .minsz = 64 * 1024 * 1024,
.magics =
{
{ .magic = "\0\0\x02\xf5\xb0\x07\xb1\x0c", .len = 8, .kboff = 8 },
diff --git a/tests/expected/blkid/low-probe-befs b/tests/expected/blkid/low-probe-befs
new file mode 100644
index 00000000..b7f25cdd
--- /dev/null
+++ b/tests/expected/blkid/low-probe-befs
@@ -0,0 +1,7 @@
+ID_FS_LABEL=befs_test
+ID_FS_LABEL_ENC=befs_test
+ID_FS_TYPE=befs
+ID_FS_USAGE=filesystem
+ID_FS_UUID=95d89dec82f6b73b
+ID_FS_UUID_ENC=95d89dec82f6b73b
+ID_FS_VERSION=little-endian