Ignore wipe operation on non-block devices.
The implementation of make_ext4fs() calls make_ext4fs_internal() by
forcing the |wipe| parameter to true, which is problematic when the
library is used within the emulator (the wipe operation will always
fail on non-Linux platforms).
This patch does the following:
- Add a 'is_block_device_fd()' function to check that a file descriptor
points to a real block device.
- Modify the implementation of wipe_block_device() uses it to return
silently when trying to wipe a non-block-device file.
- Add a WIPE_IS_SUPPORTED flag in wipe.h that indicates whether
block device wiping is supported on the current platform
(for now, this is only the case on Linux).
BUG=NONE
Change-Id: I62b62b7c3e99b465c3b876154231e7c2fe541b23
diff --git a/ext4_utils/ext4_utils.c b/ext4_utils/ext4_utils.c
index 3755fee..bb6c863 100644
--- a/ext4_utils/ext4_utils.c
+++ b/ext4_utils/ext4_utils.c
@@ -393,6 +393,20 @@
return size;
}
+int is_block_device_fd(int fd)
+{
+#ifdef USE_MINGW
+ return 0;
+#else
+ struct stat st;
+ int ret = fstat(fd, &st);
+ if (ret < 0)
+ return 0;
+
+ return S_ISBLK(st.st_mode);
+#endif
+}
+
u64 get_file_size(int fd)
{
struct stat buf;
diff --git a/ext4_utils/ext4_utils.h b/ext4_utils/ext4_utils.h
index 447d416..c6f52b5 100644
--- a/ext4_utils/ext4_utils.h
+++ b/ext4_utils/ext4_utils.h
@@ -140,6 +140,7 @@
void ext4_update_free(void);
void ext4_queue_sb(void);
u64 get_block_device_size(int fd);
+int is_block_device_fd(int fd);
u64 get_file_size(int fd);
u64 parse_num(const char *arg);
void ext4_parse_sb_info(struct ext4_super_block *sb);
diff --git a/ext4_utils/make_ext4fs.c b/ext4_utils/make_ext4fs.c
index f164883..6a0f875 100644
--- a/ext4_utils/make_ext4fs.c
+++ b/ext4_utils/make_ext4fs.c
@@ -623,8 +623,9 @@
aux_info.sb->s_blocks_count_lo - aux_info.sb->s_free_blocks_count_lo,
aux_info.sb->s_blocks_count_lo);
- if (wipe)
+ if (wipe && WIPE_IS_SUPPORTED) {
wipe_block_device(fd, info.len);
+ }
write_ext4_image(fd, gzip, sparse, crc);
diff --git a/ext4_utils/wipe.c b/ext4_utils/wipe.c
index 3bd33e5..5766632 100644
--- a/ext4_utils/wipe.c
+++ b/ext4_utils/wipe.c
@@ -17,6 +17,8 @@
#include "ext4_utils.h"
#include "wipe.h"
+#if WIPE_IS_SUPPORTED
+
#if defined(__linux__)
#include <linux/fs.h>
@@ -35,6 +37,11 @@
u64 range[2];
int ret;
+ if (!is_block_device_fd(fd)) {
+ // Wiping only makes sense on a block device.
+ return 0;
+ }
+
range[0] = 0;
range[1] = len;
ret = ioctl(fd, BLKSECDISCARD, &range);
@@ -53,11 +60,17 @@
return 0;
}
-#else
-int wipe_block_device(int fd, s64 len)
-{
- error("wipe not supported on non-linux platforms");
- return 1;
-}
+
+#else /* __linux__ */
+#error "Missing block device wiping implementation for this platform!"
#endif
+#else /* WIPE_IS_SUPPORTED */
+
+int wipe_block_device(int fd, s64 len)
+{
+ /* Wiping is not supported on this platform. */
+ return 1;
+}
+
+#endif /* WIPE_IS_SUPPORTED */
diff --git a/ext4_utils/wipe.h b/ext4_utils/wipe.h
index ecde9c1..bd119e3 100644
--- a/ext4_utils/wipe.h
+++ b/ext4_utils/wipe.h
@@ -19,6 +19,15 @@
#include "ext4_utils.h"
+/* Set WIPE_IS_SUPPORTED to 1 if the current platform supports
+ * wiping of block devices. 0 otherwise. For now, only Linux does.
+ */
+#ifdef __linux__
+# define WIPE_IS_SUPPORTED 1
+#else
+# define WIPE_IS_SUPPORTED 0
+#endif
+
int wipe_block_device(int fd, s64 len);
#endif