From: Yu Watanabe Date: Sun, 18 Sep 2022 03:28:45 +0000 (+0900) Subject: loop-util: re-introduce loop_device_open() which takes sd_device object X-Git-Tag: v252-rc1~49^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F24829%2Fhead;p=thirdparty%2Fsystemd.git loop-util: re-introduce loop_device_open() which takes sd_device object Then, this makes loop_device_open_from_fd() or _from_path() be wrappers of loop_device_open() with block_device_new_from_fd() or _from_path(), respectively. --- diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c index 6097d46d29e..84f4e79c07a 100644 --- a/src/shared/loop-util.c +++ b/src/shared/loop-util.c @@ -713,56 +713,40 @@ void loop_device_unrelinquish(LoopDevice *d) { d->relinquished = false; } -int loop_device_open_full( - const char *loop_path, - int loop_fd, +int loop_device_open( + sd_device *dev, int open_flags, int lock_op, LoopDevice **ret) { - _cleanup_(sd_device_unrefp) sd_device *dev = NULL; _cleanup_close_ int fd = -1, lock_fd = -1; - _cleanup_free_ char *p = NULL, *backing_file = NULL; + _cleanup_free_ char *node = NULL, *backing_file = NULL; struct loop_info64 info; uint64_t diskseq = 0; - struct stat st; LoopDevice *d; + const char *s; + dev_t devnum; int r, nr = -1; - assert(loop_path || loop_fd >= 0); + assert(dev); assert(IN_SET(open_flags, O_RDWR, O_RDONLY)); assert(ret); - if (loop_fd < 0) { - fd = open(loop_path, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|open_flags); - if (fd < 0) - return -errno; - loop_fd = fd; - } - - if (fstat(loop_fd, &st) < 0) - return -errno; - if (!S_ISBLK(st.st_mode)) - return -ENOTBLK; - - r = sd_device_new_from_stat_rdev(&dev, &st); - if (r < 0) - return r; + /* Even if fd is provided through the argument in loop_device_open_from_fd(), 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. */ + fd = sd_device_open(dev, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|open_flags); + if (fd < 0) + return fd; - if (fd < 0) { - /* If loop_fd is provided through the argument, then 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.*/ - fd = fd_reopen(loop_fd, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|open_flags); - if (fd < 0) - return fd; - loop_fd = fd; + if ((lock_op & ~LOCK_NB) != LOCK_UN) { + lock_fd = open_lock_fd(fd, lock_op); + if (lock_fd < 0) + return lock_fd; } - if (ioctl(loop_fd, LOOP_GET_STATUS64, &info) >= 0) { - const char *s; - + if (ioctl(fd, LOOP_GET_STATUS64, &info) >= 0) { #if HAVE_VALGRIND_MEMCHECK_H /* Valgrind currently doesn't know LOOP_GET_STATUS64. Remove this once it does */ VALGRIND_MAKE_MEM_DEFINED(&info, sizeof(info)); @@ -776,22 +760,20 @@ int loop_device_open_full( } } - r = fd_get_diskseq(loop_fd, &diskseq); + r = fd_get_diskseq(fd, &diskseq); if (r < 0 && r != -EOPNOTSUPP) return r; - if ((lock_op & ~LOCK_NB) != LOCK_UN) { - lock_fd = open_lock_fd(loop_fd, lock_op); - if (lock_fd < 0) - return lock_fd; - } + r = sd_device_get_devnum(dev, &devnum); + if (r < 0) + return r; - r = sd_device_get_devname(dev, &loop_path); + r = sd_device_get_devname(dev, &s); if (r < 0) return r; - p = strdup(loop_path); - if (!p) + node = strdup(s); + if (!node) return -ENOMEM; d = new(LoopDevice, 1); @@ -803,18 +785,54 @@ int loop_device_open_full( .fd = TAKE_FD(fd), .lock_fd = TAKE_FD(lock_fd), .nr = nr, - .node = TAKE_PTR(p), - .dev = TAKE_PTR(dev), + .node = TAKE_PTR(node), + .dev = sd_device_ref(dev), .backing_file = TAKE_PTR(backing_file), .relinquished = true, /* It's not ours, don't try to destroy it when this object is freed */ - .devno = st.st_rdev, + .devno = devnum, .diskseq = diskseq, .uevent_seqnum_not_before = UINT64_MAX, .timestamp_not_before = USEC_INFINITY, }; *ret = d; - return d->fd; + return 0; +} + +int loop_device_open_from_fd( + int fd, + int open_flags, + int lock_op, + LoopDevice **ret) { + + _cleanup_(sd_device_unrefp) sd_device *dev = NULL; + int r; + + assert(fd >= 0); + + r = block_device_new_from_fd(fd, 0, &dev); + if (r < 0) + return r; + + return loop_device_open(dev, open_flags, lock_op, ret); +} + +int loop_device_open_from_path( + const char *path, + int open_flags, + int lock_op, + LoopDevice **ret) { + + _cleanup_(sd_device_unrefp) sd_device *dev = NULL; + int r; + + assert(path); + + r = block_device_new_from_path(path, 0, &dev); + if (r < 0) + return r; + + return loop_device_open(dev, open_flags, lock_op, ret); } static int resize_partition(int partition_fd, uint64_t offset, uint64_t size) { diff --git a/src/shared/loop-util.h b/src/shared/loop-util.h index 26b8c89f5ff..1658cd35920 100644 --- a/src/shared/loop-util.h +++ b/src/shared/loop-util.h @@ -30,13 +30,9 @@ struct LoopDevice { int loop_device_make(int fd, int open_flags, uint64_t offset, uint64_t size, uint32_t loop_flags, int lock_op, LoopDevice **ret); int loop_device_make_by_path(const char *path, int open_flags, uint32_t loop_flags, int lock_op, LoopDevice **ret); -int loop_device_open_full(const char *loop_path, int loop_fd, int open_flags, int lock_op, LoopDevice **ret); -static inline int loop_device_open_from_fd(int fd, int open_flags, int lock_op, LoopDevice **ret) { - return loop_device_open_full(NULL, fd, open_flags, lock_op, ret); -} -static inline int loop_device_open_from_path(const char *path, int open_flags, int lock_op, LoopDevice **ret) { - return loop_device_open_full(path, -1, open_flags, lock_op, ret); -} +int loop_device_open(sd_device *dev, int open_flags, int lock_op, LoopDevice **ret); +int loop_device_open_from_fd(int fd, int open_flags, int lock_op, LoopDevice **ret); +int loop_device_open_from_path(const char *path, int open_flags, int lock_op, LoopDevice **ret); LoopDevice* loop_device_ref(LoopDevice *d); LoopDevice* loop_device_unref(LoopDevice *d);