int r, f_flags;
struct stat st;
+ assert(fd >= 0);
+ assert(open_flags < 0 || IN_SET(open_flags, O_RDWR, O_RDONLY));
assert(ret);
- assert(IN_SET(open_flags, O_RDWR, O_RDONLY));
- if (fstat(ASSERT_FD(fd), &st) < 0)
+ f_flags = fcntl(fd, F_GETFL);
+ if (f_flags < 0)
+ return -errno;
+
+ if (open_flags < 0) {
+ /* If open_flags is unset, initialize it from the open fd */
+ if (FLAGS_SET(f_flags, O_PATH))
+ return log_debug_errno(SYNTHETIC_ERRNO(EBADFD), "Access mode of image file indicates O_PATH, cannot determine read/write flags.");
+
+ open_flags = f_flags & O_ACCMODE_STRICT;
+ if (!IN_SET(open_flags, O_RDWR, O_RDONLY))
+ return log_debug_errno(SYNTHETIC_ERRNO(EBADFD), "Access mode of image file is write only (?)");
+ }
+
+ if (fstat(fd, &st) < 0)
return -errno;
if (S_ISBLK(st.st_mode)) {
return r;
}
- f_flags = fcntl(fd, F_GETFL);
- if (f_flags < 0)
- return -errno;
-
if (FLAGS_SET(loop_flags, LO_FLAGS_DIRECT_IO) != FLAGS_SET(f_flags, O_DIRECT)) {
/* If LO_FLAGS_DIRECT_IO is requested, then make sure we have the fd open with O_DIRECT, as
* that's required. Conversely, if it's off require that O_DIRECT is off too (that's because