From 2abaf59502a6165a9b80f849419950350a6b3011 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=BE=90=E6=AD=A5=E9=AA=A5?= <xubuji20@mails.ucas.ac.cn>
Date: Sat, 19 Aug 2023 18:44:08 -0700
Subject: [PATCH] fix: attempt to fix copy_file_range

---
 kernel/fs/fs.cpp | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/kernel/fs/fs.cpp b/kernel/fs/fs.cpp
index f54aee4f..1873fde0 100644
--- a/kernel/fs/fs.cpp
+++ b/kernel/fs/fs.cpp
@@ -1255,29 +1255,37 @@ ssize_t copy_file_range(int fd_in, int64_t *off_in,
 
     ssize_t old_offset_in = offset_in, old_offset_out = offset_out;
     if (off_in) {
-        fs_lseek(fd_in, offset_in, SEEK_CUR);
+        fs_lseek(fd_in, offset_in, SEEK_SET);
     }
     if (off_out) {
-        fs_lseek(fd_out, offset_out, SEEK_CUR);
+        fs_lseek(fd_out, offset_out, SEEK_SET);
     }
     Slice<char> buf = buddy_allocator->alloc<char>(PAGE_SIZE).value();
     ssize_t ret = 0, _len, tmp;
     while (ret < len) {
         _len = (len - ret) < PAGE_SIZE ? (len - ret) : PAGE_SIZE;
         tmp = fs_read(fd_in, buf.data(), _len);
-        if (tmp <= 0) goto cleanup;
+        if (tmp <= 0) {
+            if (tmp < 0) ret = tmp;
+            goto cleanup;
+        }
         _len = tmp;
         tmp = fs_write(fd_out, buf.data(), _len);
-        if (tmp <= 0) goto cleanup;
+        if (tmp <= 0) {
+            if (tmp < 0) ret = tmp;
+            goto cleanup;
+        }
         _len = tmp;
         ret += _len;
     }
 cleanup:
     if (off_in) {
-        fs_lseek(fd_in, old_offset_in, SEEK_CUR);
+        fs_lseek(fd_in, old_offset_in, SEEK_SET);
+        if (ret >= 0) *off_in += ret;
     }
     if (off_out) {
-        fs_lseek(fd_out, old_offset_out, SEEK_CUR);
+        fs_lseek(fd_out, old_offset_out, SEEK_SET);
+        if (ret >= 0) *off_out += ret;
     }
     buddy_allocator->free(buf);
     return ret;
-- 
GitLab