Project

General

Profile

Actions

Tasks #65613

closed

Tasks #63293: Implement fscrypt in libcephfs and cephfs-fuse

Tasks #64133: Make pjd work on fscrypt

truncate failing when using path

Added by Christopher Hoffman 13 days ago. Updated 12 days ago.

Status:
Resolved
Priority:
Normal
Category:
-
Target version:
-
% Done:

0%

Tags:
Reviewed:
Affected Versions:
Component(FS):
Labels (FS):
Pull request ID:

Description

Reproducer:

echo -n =====creating file!=====
fstest create test1 0644;
echo -n =====truncating file!=====
fstest truncate test1 68686;
echo -n =====stating file!=====
fstest stat test1 size

stat above command returns 69632 instead of truncated value.
Only reproducers when using truncate(path, size) and not fd as parameter.

Actions #1

Updated by Christopher Hoffman 13 days ago

  • Status changed from In Progress to Resolved

The fix:

diff --git a/src/client/Client.cc b/src/client/Client.cc
index 3b45ed8453f..6876573ba6e 100644
--- a/src/client/Client.cc
+++ b/src/client/Client.cc
@@ -1088,7 +1088,13 @@ Inode * Client::add_update_inode(InodeStat *st, utime_t from,
   if (new_version ||
       (new_issued & (CEPH_CAP_ANY_FILE_RD | CEPH_CAP_ANY_FILE_WR))) {
     in->layout = st->layout;
-    update_inode_file_size(in, issued, st->size, st->truncate_seq, st->truncate_size);
+    int size = st->size;
+    if (in->is_fscrypt_enabled()) {
+      if (st->fscrypt_file.size() >= sizeof(uint64_t)) {
+       size = *(ceph_le64 *)st->fscrypt_file.data();
+      }
+    }
+    update_inode_file_size(in, issued, size, st->truncate_seq, st->truncate_size);
   }

   if (in->is_dir()) {
diff --git a/src/mds/Server.cc b/src/mds/Server.cc
index aae51735d91..66a3b36568c 100644
--- a/src/mds/Server.cc
+++ b/src/mds/Server.cc
@@ -5521,6 +5521,8 @@ void Server::do_open_truncate(const MDRequestRef& mdr, int cmode)

   uint64_t old_size = std::max<uint64_t>(pi.inode->size, mdr->client_request->head.args.open.old_size);
   if (old_size > 0) {
+    if (pi.inode->fscrypt_file.size() >= sizeof(uint64_t))
+      *(ceph_le64 *)pi.inode->fscrypt_file.data() = 0;
     pi.inode->truncate(old_size, 0);
     le->metablob.add_truncate_start(in->ino()

Description:
add_update_inode() was not passing the effective_size when on fscrypt enabled dirs to update_inode_file_size. Also, during a truncate, effective_size was not reset to 0. MDS needed to be updated in this case as mds has newest version.

Actions #2

Updated by Greg Farnum 12 days ago

Hmm, I'm surprised you found missing Server logic here. Shouldn't that have turned up in kernel fscrypt testing? Xiubo, you should have insight here.

Actions #3

Updated by Xiubo Li 12 days ago

Greg Farnum wrote in #note-2:

Hmm, I'm surprised you found missing Server logic here. Shouldn't that have turned up in kernel fscrypt testing? Xiubo, you should have insight here.

The logic in kclient is a little different with libcephfs. The VFS will do the truncate itself later when it triggers the atomic_open() and at the same time in kceph the atomic_open() won't pass the O_TRUNC to mds. So I think this is why the test cases in xfstests-dev missed this.

Actions

Also available in: Atom PDF