diff options
author | Daan De Meyer <daan.j.demeyer@gmail.com> | 2023-03-23 14:42:35 +0100 |
---|---|---|
committer | Daan De Meyer <daan.j.demeyer@gmail.com> | 2023-03-23 17:36:17 +0100 |
commit | 972c8db589f1f031d1fbbe01d821ddb1795fe285 (patch) | |
tree | 0cdbb576e106733593f3ffddb02a518f32073a99 /src/shared/loop-util.c | |
parent | fs-util: Allow xopenat() to reopen existing file descriptors (diff) | |
download | systemd-972c8db589f1f031d1fbbe01d821ddb1795fe285.tar.xz systemd-972c8db589f1f031d1fbbe01d821ddb1795fe285.zip |
loop-util: Add loop_device_make_by_path_at()
On top of taking a directory file descriptor, we use xopenat() so
that the function can also be used to work on existing file
descriptors to image files including all the logic to use O_DIRECT
and fallback to O_RDONLY if needed.
Diffstat (limited to 'src/shared/loop-util.c')
-rw-r--r-- | src/shared/loop-util.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c index d6b8d086ff..91477ed003 100644 --- a/src/shared/loop-util.c +++ b/src/shared/loop-util.c @@ -24,6 +24,7 @@ #include "env-util.h" #include "errno-util.h" #include "fd-util.h" +#include "fs-util.h" #include "fileio.h" #include "loop-util.h" #include "missing_loop.h" @@ -650,7 +651,8 @@ int loop_device_make( ret); } -int loop_device_make_by_path( +int loop_device_make_by_path_at( + int dir_fd, const char *path, int open_flags, uint32_t sector_size, @@ -662,6 +664,7 @@ int loop_device_make_by_path( _cleanup_close_ int fd = -EBADF; bool direct = false; + assert(dir_fd >= 0 || dir_fd == AT_FDCWD); assert(path); assert(ret); assert(open_flags < 0 || IN_SET(open_flags, O_RDWR, O_RDONLY)); @@ -678,9 +681,9 @@ int loop_device_make_by_path( direct_flags = FLAGS_SET(loop_flags, LO_FLAGS_DIRECT_IO) ? O_DIRECT : 0; rdwr_flags = open_flags >= 0 ? open_flags : O_RDWR; - fd = open(path, basic_flags|direct_flags|rdwr_flags); + fd = xopenat(dir_fd, path, basic_flags|direct_flags|rdwr_flags, 0); if (fd < 0 && direct_flags != 0) /* If we had O_DIRECT on, and things failed with that, let's immediately try again without */ - fd = open(path, basic_flags|rdwr_flags); + fd = xopenat(dir_fd, path, basic_flags|rdwr_flags, 0); else direct = direct_flags != 0; if (fd < 0) { @@ -690,9 +693,9 @@ int loop_device_make_by_path( if (open_flags >= 0 || !(ERRNO_IS_PRIVILEGE(r) || r == -EROFS)) return r; - fd = open(path, basic_flags|direct_flags|O_RDONLY); + fd = xopenat(dir_fd, path, basic_flags|direct_flags|O_RDONLY, 0); if (fd < 0 && direct_flags != 0) /* as above */ - fd = open(path, basic_flags|O_RDONLY); + fd = xopenat(dir_fd, path, basic_flags|O_RDONLY, 0); else direct = direct_flags != 0; if (fd < 0) @@ -709,7 +712,16 @@ int loop_device_make_by_path( direct ? "enabled" : "disabled", direct != (direct_flags != 0) ? " (O_DIRECT was requested but not supported)" : ""); - return loop_device_make_internal(path, fd, open_flags, 0, 0, sector_size, loop_flags, lock_op, ret); + return loop_device_make_internal( + dir_fd == AT_FDCWD ? path : NULL, + fd, + open_flags, + /* offset = */ 0, + /* size = */ 0, + sector_size, + loop_flags, + lock_op, + ret); } int loop_device_make_by_path_memory( |