| // SPDX-License-Identifier: GPL-2.0 | |
| #include "kublk.h" | |
| void backing_file_tgt_deinit(struct ublk_dev *dev) | |
| { | |
| int i; | |
| for (i = 1; i < dev->nr_fds; i++) { | |
| fsync(dev->fds[i]); | |
| close(dev->fds[i]); | |
| } | |
| } | |
| int backing_file_tgt_init(struct ublk_dev *dev, unsigned int nr_direct) | |
| { | |
| int fd, i; | |
| ublk_assert(dev->nr_fds == 1); | |
| for (i = 0; i < dev->tgt.nr_backing_files; i++) { | |
| char *file = dev->tgt.backing_file[i]; | |
| unsigned long bytes; | |
| struct stat st; | |
| ublk_dbg(UBLK_DBG_DEV, "%s: file %d: %s\n", __func__, i, file); | |
| fd = open(file, O_RDWR | (i < nr_direct ? O_DIRECT : 0)); | |
| if (fd < 0) { | |
| ublk_err("%s: backing file %s can't be opened: %s\n", | |
| __func__, file, strerror(errno)); | |
| return -EBADF; | |
| } | |
| if (fstat(fd, &st) < 0) { | |
| close(fd); | |
| return -EBADF; | |
| } | |
| if (S_ISREG(st.st_mode)) | |
| bytes = st.st_size; | |
| else if (S_ISBLK(st.st_mode)) { | |
| if (ioctl(fd, BLKGETSIZE64, &bytes) != 0) | |
| return -1; | |
| } else { | |
| return -EINVAL; | |
| } | |
| dev->tgt.backing_file_size[i] = bytes; | |
| dev->fds[dev->nr_fds] = fd; | |
| dev->nr_fds += 1; | |
| } | |
| return 0; | |
| } |