diff options
author | LaMont Jones <lamont@debian.org> | 2010-02-03 16:26:41 -0700 |
---|---|---|
committer | LaMont Jones <lamont@debian.org> | 2010-02-03 16:26:41 -0700 |
commit | 2bd3ccad2133d3aefdc2caeb3034c0725414d2e9 (patch) | |
tree | 64db9a6968f1d398d386ddc1d46d2e0a7396ff44 | |
parent | c3701c1d965cdc905bd580ece68a1c4008b4d1b0 (diff) | |
parent | cdfb1e88228c10c28f8bfe0f4b0ff1b3b06d1ed4 (diff) | |
download | util-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
43 files changed, 1044 insertions, 525 deletions
@@ -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, §or, 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, §or_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 |