Whamcloud - gitweb
LU-16025 llite: allow unaligned DIO reaching EOF 18/54718/10
authorBobi Jam <bobijam@whamcloud.com>
Wed, 10 Apr 2024 09:19:53 +0000 (17:19 +0800)
committerOleg Drokin <green@whamcloud.com>
Wed, 5 Jun 2024 04:43:56 +0000 (04:43 +0000)
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 <bobijam@whamcloud.com>
Change-Id: I229e193c3f0df0c21284991809573e312d18a556
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/54718
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Shaun Tancheff <shaun.tancheff@hpe.com>
Reviewed-by: Patrick Farrell <patrick.farrell@oracle.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/llite/file.c
lustre/llite/rw26.c
lustre/utils/lfs.c
lustre/utils/liblustreapi_layout.c
lustre/utils/liblustreapi_mirror.c

index 46d6b9b..6a0ad36 100644 (file)
@@ -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) {
index 2ab74d3..d480db1 100644 (file)
@@ -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),
index d8487b7..4b188b6 100644 (file)
@@ -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;
index bd2a055..6447d6f 100644 (file)
@@ -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;
index 36e02fe..bf63a62 100644 (file)
@@ -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;