diff options
Diffstat (limited to 'src/shared/loop-util.c')
-rw-r--r-- | src/shared/loop-util.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c index 2da101b748..49afa4dac6 100644 --- a/src/shared/loop-util.c +++ b/src/shared/loop-util.c @@ -442,11 +442,16 @@ static int loop_device_make_internal( _cleanup_close_ int copy = -1; uint64_t diskseq = 0; - /* If this is already a block device, store a copy of the fd as it is */ - - copy = fcntl(fd, F_DUPFD_CLOEXEC, 3); + /* If this is already a block device and we are supposed to cover the whole of it + * then store an fd to the original open device node — and do not actually create an + * unnecessary loopback device for it. Note that we reopen the inode here, instead of + * keeping just a dup() clone of it around, since we want to ensure that the O_DIRECT + * flag of the handle we keep is off, we have our own file index, and have the right + * read/write mode in effect. */ + + copy = fd_reopen(fd, open_flags|O_NONBLOCK|O_CLOEXEC|O_NOCTTY); if (copy < 0) - return -errno; + return copy; r = loop_get_diskseq(copy, &diskseq); if (r < 0 && r != -EOPNOTSUPP) |