From: Theodore Ts'o Date: Mon, 28 Aug 2017 22:04:11 +0000 (-0400) Subject: Fix FreeBSD portability problem caused by it using character mode disk devices X-Git-Tag: v1.43.6~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f61aa76e456567b622cb0b6e5eb33de394600948;p=thirdparty%2Fe2fsprogs.git Fix FreeBSD portability problem caused by it using character mode disk devices We were using S_ISBLK() to test if a device could be used as a disk device. This doesn't work for FreeBSD. We need to test for S_ISBLK() || S_ISCHR(). Signed-off-by: Theodore Ts'o --- diff --git a/lib/blkid/blkidP.h b/lib/blkid/blkidP.h index b90bfedb8..b3fe4a668 100644 --- a/lib/blkid/blkidP.h +++ b/lib/blkid/blkidP.h @@ -15,6 +15,12 @@ #include #include +#if HAVE_SYS_TYPES_H +#include +#endif +#if HAVE_SYS_STAT_H +#include +#endif #include @@ -152,6 +158,15 @@ extern void blkid_debug_dump_dev(blkid_dev dev); extern void blkid_debug_dump_tag(blkid_tag tag); #endif +static inline int blkidP_is_disk_device(mode_t mode) +{ +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + return S_ISBLK(mode) || S_ISCHR(mode); +#else + return S_ISBLK(mode); +#endif +} + /* devno.c */ struct dir_list { char *name; diff --git a/lib/blkid/devname.c b/lib/blkid/devname.c index 671e781f0..f3956da74 100644 --- a/lib/blkid/devname.c +++ b/lib/blkid/devname.c @@ -231,7 +231,8 @@ static void probe_one(blkid_cache cache, const char *ptname, dev->bid_devno == devno) goto set_pri; - if (stat(device, &st) == 0 && S_ISBLK(st.st_mode) && + if (stat(device, &st) == 0 && + blkidP_is_disk_device(st.st_mode) && st.st_rdev == devno) { devname = blkid_strdup(device); goto get_dev; diff --git a/lib/blkid/devno.c b/lib/blkid/devno.c index 480030f20..34ceb3c48 100644 --- a/lib/blkid/devno.c +++ b/lib/blkid/devno.c @@ -119,7 +119,7 @@ void blkid__scan_dir(const char *dirname, dev_t devno, struct dir_list **list, if (stat(path, &st) < 0) continue; - if (S_ISBLK(st.st_mode) && st.st_rdev == devno) { + if (blkidP_is_disk_device(st.st_mode) && st.st_rdev == devno) { *devname = blkid_strdup(path); DBG(DEBUG_DEVNO, printf("found 0x%llx at %s (%p)\n", (long long)devno, diff --git a/lib/blkid/getsize.c b/lib/blkid/getsize.c index 8e8eb4c45..4e2835f65 100644 --- a/lib/blkid/getsize.c +++ b/lib/blkid/getsize.c @@ -149,7 +149,7 @@ blkid_loff_t blkid_get_dev_size(int fd) * character) devices, so we need to check for S_ISCHR, too. */ if (fstat(fd, &st) >= 0 && - (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode))) + blkidP_is_disk_device(st.st_mode)) part = st.st_rdev & 7; if (part >= 0 && (ioctl(fd, DIOCGDINFO, (char *)&lab) >= 0)) { diff --git a/lib/ext2fs/blkmap64_rb.c b/lib/ext2fs/blkmap64_rb.c index 7e7e29d4b..448318c74 100644 --- a/lib/ext2fs/blkmap64_rb.c +++ b/lib/ext2fs/blkmap64_rb.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H diff --git a/lib/ext2fs/ext2fsP.h b/lib/ext2fs/ext2fsP.h index 8de9d33f5..9d001d5d7 100644 --- a/lib/ext2fs/ext2fsP.h +++ b/lib/ext2fs/ext2fsP.h @@ -9,10 +9,23 @@ * %End-Header% */ +#if HAVE_SYS_STAT_H +#include +#endif + #include "ext2fs.h" #define EXT2FS_MAX_NESTED_LINKS 8 +static inline int ext2fsP_is_disk_device(mode_t mode) +{ +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + return S_ISBLK(mode) || S_ISCHR(mode); +#else + return S_ISBLK(mode); +#endif +} + /* * Badblocks list */ diff --git a/lib/ext2fs/finddev.c b/lib/ext2fs/finddev.c index 62fa0dbe7..cd85ef5c4 100644 --- a/lib/ext2fs/finddev.c +++ b/lib/ext2fs/finddev.c @@ -104,7 +104,8 @@ static int scan_dir(char *dirname, dev_t device, struct dir_list **list, goto skip_to_next; if (S_ISDIR(st.st_mode)) add_to_dirlist(path, list); - if (S_ISBLK(st.st_mode) && st.st_rdev == device) { + if (ext2fsP_is_disk_device(st.st_mode) && + st.st_rdev == device) { cp = malloc(strlen(path)+1); if (!cp) { closedir(dir); diff --git a/lib/ext2fs/ismounted.c b/lib/ext2fs/ismounted.c index 120299c4f..6cd497dc5 100644 --- a/lib/ext2fs/ismounted.c +++ b/lib/ext2fs/ismounted.c @@ -55,6 +55,7 @@ #include "ext2_fs.h" #include "ext2fs.h" +#include "ext2fsP.h" #ifdef HAVE_SETMNTENT /* @@ -115,7 +116,7 @@ static errcode_t check_mntent_file(const char *mtab_file, const char *file, return errno; } if (stat(file, &st_buf) == 0) { - if (S_ISBLK(st_buf.st_mode)) { + if (ext2fsP_is_disk_device(st_buf.st_mode)) { #ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */ file_rdev = st_buf.st_rdev; #endif /* __GNU__ */ @@ -130,7 +131,7 @@ static errcode_t check_mntent_file(const char *mtab_file, const char *file, if (strcmp(file, mnt->mnt_fsname) == 0) break; if (stat(mnt->mnt_fsname, &st_buf) == 0) { - if (S_ISBLK(st_buf.st_mode)) { + if (ext2fsP_is_disk_device(st_buf.st_mode)) { #ifndef __GNU__ if (file_rdev && (file_rdev == st_buf.st_rdev)) break; @@ -310,7 +311,7 @@ static int is_swap_device(const char *file) file_dev = 0; #ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */ if ((stat(file, &st_buf) == 0) && - S_ISBLK(st_buf.st_mode)) + ext2fsP_is_disk_device(st_buf.st_mode)) file_dev = st_buf.st_rdev; #endif /* __GNU__ */ @@ -337,7 +338,7 @@ valid_first_line: } #ifndef __GNU__ if (file_dev && (stat(buf, &st_buf) == 0) && - S_ISBLK(st_buf.st_mode) && + ext2fsP_is_disk_device(st_buf.st_mode) && file_dev == st_buf.st_rdev) { ret++; break; @@ -404,7 +405,8 @@ errcode_t ext2fs_check_mount_point(const char *device, int *mount_flags, { struct stat st_buf; - if (stat(device, &st_buf) == 0 && S_ISBLK(st_buf.st_mode)) { + if (stat(device, &st_buf) == 0 && + ext2fsP_is_disk_device(st_buf.st_mode)) { int fd = open(device, O_RDONLY | O_EXCL); if (fd >= 0) diff --git a/lib/ext2fs/unix_io.c b/lib/ext2fs/unix_io.c index 64141954e..c2ce9a10f 100644 --- a/lib/ext2fs/unix_io.c +++ b/lib/ext2fs/unix_io.c @@ -76,6 +76,7 @@ #include "ext2_fs.h" #include "ext2fs.h" +#include "ext2fsP.h" /* * For checking structure magic numbers... @@ -611,7 +612,7 @@ static errcode_t unix_open_channel(const char *name, int fd, * zero. */ if (ext2fs_fstat(data->dev, &st) == 0) { - if (S_ISBLK(st.st_mode)) + if (ext2fsP_is_disk_device(st.st_mode)) io->flags |= CHANNEL_FLAGS_BLOCK_DEVICE; else io->flags |= CHANNEL_FLAGS_DISCARD_ZEROES; @@ -682,7 +683,7 @@ static errcode_t unix_open_channel(const char *name, int fd, (ut.release[4] == '1') && (ut.release[5] >= '0') && (ut.release[5] < '8')) && (ext2fs_fstat(data->dev, &st) == 0) && - (S_ISBLK(st.st_mode))) { + (ext2fsP_is_disk_device(st.st_mode))) { struct rlimit rlim; rlim.rlim_cur = rlim.rlim_max = (unsigned long) RLIM_INFINITY; diff --git a/misc/e2image.c b/misc/e2image.c index e0c318839..030f9cbe3 100644 --- a/misc/e2image.c +++ b/misc/e2image.c @@ -43,6 +43,7 @@ extern int optind; #include "ext2fs/ext2_fs.h" #include "ext2fs/ext2fs.h" +#include "ext2fs/ext2fsP.h" #include "et/com_err.h" #include "uuid/uuid.h" #include "e2p/e2p.h" @@ -1620,7 +1621,7 @@ skip_device: _("Can not stat output\n")); exit(1); } - if (S_ISBLK(st.st_mode)) + if (ext2fsP_is_disk_device(st.st_mode)) output_is_blk = 1; } if (flags & E2IMAGE_IS_QCOW2_FLAG) {