From a3a0cced416ce9721f5baa7c2da458ff07b33838 Mon Sep 17 00:00:00 2001 From: Bobi Jam Date: Wed, 10 Apr 2024 17:19:53 +0800 Subject: [PATCH] LU-16025 llite: allow unaligned DIO reaching EOF Direct IO requires file offset and iov_iter count be page aligned, if server does not support unaligned DIO. For old servers, they do not have OBD_CONNECT2_UNALIGNED_DIO support, and be deemed as not supporting unaligned DIO. Since mirror resync would use direct IO to read data from a mirror, and if the file size is not page aligned, the last read iov_iter would be truncated by commit 4468f6c9d9 and would contain unaligned iov_iter count, so it would fail with old servers. This patch fixes this interop issue by allowing unaligned DIO reaching the end of the file. Test-Parameters: testlist=sanity-sec serverversion=EXA6 Fixes: 7194eb6431 ("LU-13805 clio: bounce buffer for unaligned DIO") Signed-off-by: Bobi Jam Change-Id: I229e193c3f0df0c21284991809573e312d18a556 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/54718 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Shaun Tancheff Reviewed-by: Patrick Farrell Reviewed-by: Oleg Drokin --- lustre/llite/file.c | 2 +- lustre/llite/rw26.c | 4 ++-- lustre/utils/lfs.c | 40 ++++++++++++++++++++++++++++---------- lustre/utils/liblustreapi_layout.c | 5 +++++ lustre/utils/liblustreapi_mirror.c | 26 +++++++++++++++++++++++-- 5 files changed, 62 insertions(+), 15 deletions(-) diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 46d6b9b..6a0ad36 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -2182,7 +2182,7 @@ fini_io: if (kms > 0 && (iocb->ki_pos >= kms || read_end > kms)) { rc = ll_glimpse_size(inode); if (rc != 0) - return rc; + RETURN(rc); size = i_size_read(inode); if (iocb->ki_pos >= size || read_end > size) { diff --git a/lustre/llite/rw26.c b/lustre/llite/rw26.c index 2ab74d3..d480db1 100644 --- a/lustre/llite/rw26.c +++ b/lustre/llite/rw26.c @@ -494,7 +494,7 @@ ll_direct_IO_impl(struct kiocb *iocb, struct iov_iter *iter, int rw) if (file_offset & ~PAGE_MASK) unaligned = true; - if (count & ~PAGE_MASK) + if ((file_offset + count < i_size_read(inode)) && (count & ~PAGE_MASK)) unaligned = true; /* Check that all user buffers are aligned as well */ @@ -512,7 +512,7 @@ ll_direct_IO_impl(struct kiocb *iocb, struct iov_iter *iter, int rw) LASSERT(io != NULL); CDEBUG(D_VFSTRACE, - "VFS Op:inode="DFID"(%p), size=%zd (max %lu), offset=%lld=%llx, pages %zd (max %lu)%s%s%s%s\n", + "VFS Op:inode="DFID"(%p), size=%zd (max %lu), offset=%lld=%#llx, pages %zd (max %lu)%s%s%s%s\n", PFID(ll_inode2fid(inode)), inode, count, MAX_DIO_SIZE, file_offset, file_offset, (count >> PAGE_SHIFT) + !!(count & ~PAGE_MASK), diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index d8487b7..4b188b6 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -843,6 +843,8 @@ static int migrate_copy_data(int fd_src, int fd_dst, int (*check_file)(int), rc = ftruncate(fd_dst, pos); if (rc < 0) { rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, + "fail to ftruncate dst file to %ld", pos); free(buf); return rc; } @@ -868,8 +870,12 @@ static int migrate_copy_data(int fd_src, int fd_dst, int (*check_file)(int), /* hole at the end of file, truncate up to it */ if (!data_size) { rc = ftruncate(fd_dst, data_off); - if (rc < 0) + if (rc < 0) { + llapi_error(LLAPI_MSG_ERROR, rc, + "fail to ftruncate dst file to %ld", + data_off); goto out; + } } pos = data_off & ~(page_size - 1); data_end = data_off + data_size; @@ -881,14 +887,20 @@ static int migrate_copy_data(int fd_src, int fd_dst, int (*check_file)(int), if (check_file) { rc = check_file(fd_src); - if (rc < 0) + if (rc < 0) { + llapi_error(LLAPI_MSG_ERROR, rc, + "error checking src file"); goto out; + } } rsize = pread(fd_src, buf, to_read, pos); read_bytes += rsize; if (rsize < 0) { rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, + "error reading src bytes %ld-%ld", + pos, to_read); goto out; } /* EOF */ @@ -904,6 +916,9 @@ static int migrate_copy_data(int fd_src, int fd_dst, int (*check_file)(int), written = pwrite(fd_dst, buf, to_write, pos); if (written < 0) { rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, + "error writing dst bytes %ld-%ld", + pos, to_write); goto out; } pos += written; @@ -939,10 +954,8 @@ static int migrate_copy_data(int fd_src, int fd_dst, int (*check_file)(int), if (rc < 0) { if (stats_interval_sec) - fprintf(stderr, - "error %s: delay for bandwidth control failed: %s\n", - progname, - strerror(-rc)); + llapi_error(LLAPI_MSG_WARN, rc, + "delay for bandwidth control failed"); rc = 0; } } @@ -970,8 +983,11 @@ static int migrate_copy_data(int fd_src, int fd_dst, int (*check_file)(int), } rc = fsync(fd_dst); - if (rc < 0) + if (rc < 0) { rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, + "failed to fsync dst file"); + } out: /* Try to avoid page cache pollution after migration. */ (void)posix_fadvise(fd_src, 0, 0, POSIX_FADV_DONTNEED); @@ -11925,8 +11941,8 @@ int lfs_mirror_resync_file(const char *fname, struct ll_ioc_lease *ioc, start, end, stats_interval_sec, bandwidth_bytes_sec); if (rc < 0) - fprintf(stderr, "%s: '%s' llapi_mirror_resync_many: %s.\n", - progname, fname, strerror(-rc)); + llapi_error(LLAPI_MSG_ERROR, rc, + "fail to mirror resync '%s'\n", fname); rc2 = migrate_set_timestamps(fd, &stbuf); if (rc2 < 0) { @@ -12478,8 +12494,12 @@ static inline int lfs_mirror_write(int argc, char **argv) if (pos & (page_size - 1)) { rc = llapi_mirror_truncate(fd, mirror_id, pos); - if (rc < 0) + if (rc < 0) { + llapi_error(LLAPI_MSG_ERROR, rc, + "fail to trucate mirror %u of file '%s' to %ld", + mirror_id, fname, pos); goto free_buf; + } } ioc.lil_mode = LL_LEASE_UNLCK; diff --git a/lustre/utils/liblustreapi_layout.c b/lustre/utils/liblustreapi_layout.c index bd2a055..6447d6f 100644 --- a/lustre/utils/liblustreapi_layout.c +++ b/lustre/utils/liblustreapi_layout.c @@ -3293,6 +3293,8 @@ int llapi_mirror_resync_many_params(int fd, struct llapi_layout *layout, &mirror_end); if (rc < 0) { free(buf); + llapi_error(LLAPI_MSG_ERROR, rc, + "cannot find source mirror"); return rc; } src = rc; @@ -3387,6 +3389,9 @@ do_read: } if (bytes_read < 0) { rc = bytes_read; + llapi_error(LLAPI_MSG_ERROR, rc, + "error reading bytes %ld-%ld of mirror %u", + pos, to_read, src); break; } total_bytes_read += bytes_read; diff --git a/lustre/utils/liblustreapi_mirror.c b/lustre/utils/liblustreapi_mirror.c index 36e02fe..bf63a62 100644 --- a/lustre/utils/liblustreapi_mirror.c +++ b/lustre/utils/liblustreapi_mirror.c @@ -136,6 +136,9 @@ ssize_t llapi_mirror_read(int fd, unsigned int id, void *buf, size_t count, if (bytes_read < 0) { result = -errno; + llapi_error(LLAPI_MSG_WARN, result, + "fail to pread %ld-%ld of mirror %u", + pos, count, id); break; } @@ -182,6 +185,9 @@ ssize_t llapi_mirror_write(int fd, unsigned int id, const void *buf, bytes_written = pwrite(fd, buf, count, pos); if (bytes_written < 0) { result = -errno; + llapi_error(LLAPI_MSG_WARN, result, + "fail to pwrite %ld-%ld of mirror %u", + pos, count, id); break; } @@ -205,8 +211,11 @@ int llapi_mirror_truncate(int fd, unsigned int id, off_t length) return rc; rc = ftruncate(fd, length); - if (rc < 0) + if (rc < 0) { rc = -errno; + llapi_error(LLAPI_MSG_WARN, rc, + "fail to ftruncate mirror %u to %ld", id, length); + } (void) llapi_mirror_clear(fd); @@ -371,6 +380,9 @@ ssize_t llapi_mirror_copy_many(int fd, __u16 src, __u16 *dst, size_t count) } else if (bytes_read < 0) { result = bytes_read; nr = 0; + llapi_error(LLAPI_MSG_ERROR, result, + "error reading bytes %ld-%ld of mirror %u", + pos, to_read, src); break; } @@ -469,6 +481,9 @@ int llapi_mirror_copy(int fd, unsigned int src, unsigned int dst, off_t pos, break; } else if (bytes_read < 0) { result = bytes_read; + llapi_error(LLAPI_MSG_ERROR, result, + "error reading bytes %ld-%ld of mirror %u", + pos, to_read, src); break; } @@ -480,6 +495,9 @@ int llapi_mirror_copy(int fd, unsigned int src, unsigned int dst, off_t pos, pos); if (bytes_written < 0) { result = bytes_written; + llapi_error(LLAPI_MSG_ERROR, result, + "error writing bytes %ld-%ld of mirror %u", + pos, to_write, dst); break; } @@ -496,8 +514,12 @@ int llapi_mirror_copy(int fd, unsigned int src, unsigned int dst, off_t pos, if (result > 0 && pos & (page_size - 1)) { rc = llapi_mirror_truncate(fd, dst, pos); - if (rc < 0) + if (rc < 0) { + llapi_error(LLAPI_MSG_ERROR, result, + "error truncating mirror %u to %ld", + dst, pos); result = rc; + } } return result; -- 1.8.3.1