From: Lennart Poettering Date: Wed, 21 Jan 2026 21:29:22 +0000 (+0100) Subject: loop-util: when open_flags is unspecified derive it from passed in fd X-Git-Tag: v260-rc1~321 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ca088266bc5bd4fdd91a96e9979677b9a6b3923e;p=thirdparty%2Fsystemd.git loop-util: when open_flags is unspecified derive it from passed in fd --- diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c index b64953c65d3..8c924296488 100644 --- a/src/shared/loop-util.c +++ b/src/shared/loop-util.c @@ -431,10 +431,25 @@ static int loop_device_make_internal( 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)) { @@ -461,10 +476,6 @@ static int loop_device_make_internal( 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