diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-21 04:59:33 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-21 04:59:33 +0000 |
commit | 73193347133e750faf27f88fd3ab31ce43aff062 (patch) | |
tree | e28a6d9512d1787b1fcbe9167188c9d134bf51d9 /lib/ext2fs/unix_io.c | |
parent | Adding upstream version 1.47.0. (diff) | |
download | e2fsprogs-upstream.tar.xz e2fsprogs-upstream.zip |
Adding upstream version 1.47.1.upstream/1.47.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | lib/ext2fs/unix_io.c | 74 |
1 files changed, 27 insertions, 47 deletions
diff --git a/lib/ext2fs/unix_io.c b/lib/ext2fs/unix_io.c index 3171c73..4b4f25a 100644 --- a/lib/ext2fs/unix_io.c +++ b/lib/ext2fs/unix_io.c @@ -18,7 +18,6 @@ #if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) #define _XOPEN_SOURCE 600 #define _DARWIN_C_SOURCE -#define _FILE_OFFSET_BITS 64 #ifndef _LARGEFILE_SOURCE #define _LARGEFILE_SOURCE #endif @@ -53,11 +52,6 @@ #ifdef HAVE_SYS_MOUNT_H #include <sys/mount.h> #endif -#ifdef HAVE_SYS_PRCTL_H -#include <sys/prctl.h> -#else -#define PR_GET_DUMPABLE 3 -#endif #if HAVE_SYS_STAT_H #include <sys/stat.h> #endif @@ -182,29 +176,6 @@ static errcode_t unix_get_stats(io_channel channel, io_stats *stats) return retval; } -static char *safe_getenv(const char *arg) -{ - if ((getuid() != geteuid()) || (getgid() != getegid())) - return NULL; -#ifdef HAVE_PRCTL - if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 0) - return NULL; -#else -#if (defined(linux) && defined(SYS_prctl)) - if (syscall(SYS_prctl, PR_GET_DUMPABLE, 0, 0, 0, 0) == 0) - return NULL; -#endif -#endif - -#if defined(HAVE_SECURE_GETENV) - return secure_getenv(arg); -#elif defined(HAVE___SECURE_GETENV) - return __secure_getenv(arg); -#else - return getenv(arg); -#endif -} - /* * Here are the raw I/O functions */ @@ -728,7 +699,7 @@ static errcode_t unix_open_channel(const char *name, int fd, struct utsname ut; #endif - if (safe_getenv("UNIX_IO_FORCE_BOUNCE")) + if (ext2fs_safe_getenv("UNIX_IO_FORCE_BOUNCE")) flags |= IO_FLAG_FORCE_BOUNCE; #ifdef __linux__ @@ -761,6 +732,9 @@ static errcode_t unix_open_channel(const char *name, int fd, io->refcount = 1; io->flags = 0; + if (ext2fs_safe_getenv("UNIX_IO_NOZEROOUT")) + io->flags |= CHANNEL_FLAGS_NOZEROOUT; + memset(data, 0, sizeof(struct unix_private_data)); data->magic = EXT2_ET_MAGIC_UNIX_IO_CHANNEL; data->io_stats.num_fields = 2; @@ -783,20 +757,19 @@ static errcode_t unix_open_channel(const char *name, int fd, * zero. */ if (ext2fs_fstat(data->dev, &st) == 0) { - if (ext2fsP_is_disk_device(st.st_mode)) - io->flags |= CHANNEL_FLAGS_BLOCK_DEVICE; - else - io->flags |= CHANNEL_FLAGS_DISCARD_ZEROES; - } - + if (ext2fsP_is_disk_device(st.st_mode)) { #ifdef BLKDISCARDZEROES - { - int zeroes = 0; - if (ioctl(data->dev, BLKDISCARDZEROES, &zeroes) == 0 && - zeroes) + int zeroes = 0; + + if (ioctl(data->dev, BLKDISCARDZEROES, &zeroes) == 0 && + zeroes) + io->flags |= CHANNEL_FLAGS_DISCARD_ZEROES; +#endif + io->flags |= CHANNEL_FLAGS_BLOCK_DEVICE; + } else { io->flags |= CHANNEL_FLAGS_DISCARD_ZEROES; + } } -#endif #if defined(__CYGWIN__) /* @@ -1344,12 +1317,15 @@ static errcode_t unix_discard(io_channel channel, unsigned long long block, unsigned long long count) { struct unix_private_data *data; - int ret; + int ret = EOPNOTSUPP; EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); data = (struct unix_private_data *) channel->private_data; EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL); + if (channel->flags & CHANNEL_FLAGS_NODISCARD) + goto unimplemented; + if (channel->flags & CHANNEL_FLAGS_BLOCK_DEVICE) { #ifdef BLKDISCARD __u64 range[2]; @@ -1376,8 +1352,10 @@ static errcode_t unix_discard(io_channel channel, unsigned long long block, #endif } if (ret < 0) { - if (errno == EOPNOTSUPP) + if (errno == EOPNOTSUPP) { + channel->flags |= CHANNEL_FLAGS_NODISCARD; goto unimplemented; + } return errno; } return 0; @@ -1425,9 +1403,6 @@ static errcode_t unix_zeroout(io_channel channel, unsigned long long block, data = (struct unix_private_data *) channel->private_data; EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL); - if (safe_getenv("UNIX_IO_NOZEROOUT")) - goto unimplemented; - if (!(channel->flags & CHANNEL_FLAGS_BLOCK_DEVICE)) { /* Regular file, try to use truncate/punch/zero. */ struct stat statbuf; @@ -1450,13 +1425,18 @@ static errcode_t unix_zeroout(io_channel channel, unsigned long long block, } } + if (channel->flags & CHANNEL_FLAGS_NOZEROOUT) + goto unimplemented; + ret = __unix_zeroout(data->dev, (off_t)(block) * channel->block_size + data->offset, (off_t)(count) * channel->block_size); err: if (ret < 0) { - if (errno == EOPNOTSUPP) + if (errno == EOPNOTSUPP) { + channel->flags |= CHANNEL_FLAGS_NOZEROOUT; goto unimplemented; + } return errno; } return 0; |