From d94142999499f467995fcbe94111d99eefca89ec Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Fri, 20 Jan 2023 07:35:45 +0100 Subject: [PATCH 1/4] Increase size via truncate implemented. --- src/client/gkfs_functions.cpp | 22 ++++++++++++++++++++-- tests/integration/data/test_truncate.py | 7 +++++-- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/client/gkfs_functions.cpp b/src/client/gkfs_functions.cpp index 23db5e0f0..b42ed42ed 100644 --- a/src/client/gkfs_functions.cpp +++ b/src/client/gkfs_functions.cpp @@ -579,8 +579,26 @@ gkfs_truncate(const std::string& path, off_t length) { auto size = md->size(); if(static_cast(length) > size) { LOG(DEBUG, "Length is greater then file size: {} > {}", length, size); - errno = EINVAL; - return -1; + auto output_fd = gkfs_open(path, md->mode(), O_APPEND | O_WRONLY); + if(output_fd == -1) { + errno = EINVAL; + return -1; + } + gkfs_lseek(output_fd, 0, SEEK_END); + ssize_t n = static_cast(length) - size; + void* buffer = (void*) malloc(n); + if(buffer == nullptr) { + return -1; + } + // We need to extend using 0s + memset(buffer, 0, n); + if(gkfs_write(output_fd, buffer, (size_t) n) != n) { + free(buffer); + return -1; + } + free(buffer); + CTX->file_map()->remove(output_fd); + return 0; } return gkfs_truncate(path, size, length); } diff --git a/tests/integration/data/test_truncate.py b/tests/integration/data/test_truncate.py index 4d6fc40da..425e6f746 100644 --- a/tests/integration/data/test_truncate.py +++ b/tests/integration/data/test_truncate.py @@ -150,7 +150,10 @@ def test_fail_truncate(gkfs_daemon, gkfs_client): # Truncate to a size greater than the file size ret = gkfs_client.truncate(truncfile, buf_length + 1) - assert ret.retval == -1 - assert ret.errno == errno.EINVAL + assert ret.retval == 0 + + # Size should increase + ret = gkfs_client.stat(truncfile) + assert ret.statbuf.st_size == buf_length+1 -- GitLab From 7e5db352be900f7daa7c005aec22fdb31657f127 Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Fri, 20 Jan 2023 11:56:53 +0100 Subject: [PATCH 2/4] Truncate increasing size should not use APPEND --- src/client/gkfs_functions.cpp | 9 +++++++-- tests/integration/data/test_truncate.py | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/client/gkfs_functions.cpp b/src/client/gkfs_functions.cpp index b42ed42ed..c8481985f 100644 --- a/src/client/gkfs_functions.cpp +++ b/src/client/gkfs_functions.cpp @@ -143,6 +143,7 @@ gkfs_open(const std::string& path, mode_t mode, int flags) { errno = ENOTSUP; return -1; } + // metadata object filled during create or stat gkfs::metadata::Metadata md{}; if(flags & O_CREAT) { @@ -579,7 +580,7 @@ gkfs_truncate(const std::string& path, off_t length) { auto size = md->size(); if(static_cast(length) > size) { LOG(DEBUG, "Length is greater then file size: {} > {}", length, size); - auto output_fd = gkfs_open(path, md->mode(), O_APPEND | O_WRONLY); + auto output_fd = gkfs_open(path, md->mode(), O_WRONLY); if(output_fd == -1) { errno = EINVAL; return -1; @@ -588,12 +589,14 @@ gkfs_truncate(const std::string& path, off_t length) { ssize_t n = static_cast(length) - size; void* buffer = (void*) malloc(n); if(buffer == nullptr) { + errno = ENOMEM; return -1; } // We need to extend using 0s memset(buffer, 0, n); if(gkfs_write(output_fd, buffer, (size_t) n) != n) { free(buffer); + errno = EINVAL; return -1; } free(buffer); @@ -695,8 +698,10 @@ ssize_t gkfs_write(int fd, const void* buf, size_t count) { auto gkfs_fd = CTX->file_map()->get(fd); auto pos = gkfs_fd->pos(); // retrieve the current offset - if(gkfs_fd->get_flag(gkfs::filemap::OpenFile_flags::append)) + if(gkfs_fd->get_flag(gkfs::filemap::OpenFile_flags::append)) { gkfs_lseek(gkfs_fd, 0, SEEK_END); + pos = gkfs_fd->pos(); // Pos should be updated with append + } auto ret = gkfs_pwrite(gkfs_fd, reinterpret_cast(buf), count, pos); // Update offset in file descriptor in the file map diff --git a/tests/integration/data/test_truncate.py b/tests/integration/data/test_truncate.py index 425e6f746..b1321dfdc 100644 --- a/tests/integration/data/test_truncate.py +++ b/tests/integration/data/test_truncate.py @@ -151,6 +151,7 @@ def test_fail_truncate(gkfs_daemon, gkfs_client): # Truncate to a size greater than the file size ret = gkfs_client.truncate(truncfile, buf_length + 1) assert ret.retval == 0 + # Size should increase ret = gkfs_client.stat(truncfile) -- GitLab From b800bce48cf57f22a601081dc332ab1f46083ca0 Mon Sep 17 00:00:00 2001 From: Marc Vef Date: Mon, 30 Jan 2023 15:50:50 +0100 Subject: [PATCH 3/4] Review + replacing malloc with unique_ptr --- src/client/gkfs_functions.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/client/gkfs_functions.cpp b/src/client/gkfs_functions.cpp index c8481985f..95a09f1c1 100644 --- a/src/client/gkfs_functions.cpp +++ b/src/client/gkfs_functions.cpp @@ -579,7 +579,8 @@ gkfs_truncate(const std::string& path, off_t length) { auto size = md->size(); if(static_cast(length) > size) { - LOG(DEBUG, "Length is greater then file size: {} > {}", length, size); + LOG(DEBUG, "Length is greater then file size: '{}' > '{}'", length, + size); auto output_fd = gkfs_open(path, md->mode(), O_WRONLY); if(output_fd == -1) { errno = EINVAL; @@ -587,19 +588,16 @@ gkfs_truncate(const std::string& path, off_t length) { } gkfs_lseek(output_fd, 0, SEEK_END); ssize_t n = static_cast(length) - size; - void* buffer = (void*) malloc(n); - if(buffer == nullptr) { + // Zeroes the buffer. All make_* are value initialized + auto buf = std::make_unique(n); + if(!buf) { errno = ENOMEM; return -1; } - // We need to extend using 0s - memset(buffer, 0, n); - if(gkfs_write(output_fd, buffer, (size_t) n) != n) { - free(buffer); + if(gkfs_write(output_fd, buf.get(), (size_t) n) != n) { errno = EINVAL; return -1; } - free(buffer); CTX->file_map()->remove(output_fd); return 0; } -- GitLab From 89762ca9677325c854673232beb7ec77d89bbb40 Mon Sep 17 00:00:00 2001 From: Marc Vef Date: Mon, 30 Jan 2023 16:00:24 +0100 Subject: [PATCH 4/4] Adding changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12ec77526..1db35e733 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - Additional tests to increase code coverage ([!141](https://storage.bsc.es/gitlab/hpc/gekkofs/-/merge_requests/141)). - GKFS_ENABLE_UNUSED_FUNCTIONS added to disable code to increase code coverage. - Updated Parallax version to new API (parallax option needs kv_format.parallax in the path, and the database in a device with O_DIRECT) +- Support for increasing file size via `truncate()` added ([!159](https://storage.bsc.es/gitlab/hpc/gekkofs/-/merge_requests/159) ### Changed -- GitLab