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 almost 2 years ago. Updated over 1 year ago.

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

0%

Reviewed:
Affected Versions:
Component(FS):
Labels (FS):
Pull request ID:
Tags (freeform):
Merge Commit:
Fixed In:
Released In:
Upkeep Timestamp:

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.


Related issues 1 (0 open1 closed)

Related to CephFS - Tasks #68431: Strided multi-fuse client write stallsResolvedChristopher Hoffman

Actions
Actions #1

Updated by Christopher Hoffman almost 2 years 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 almost 2 years 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 almost 2 years 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 #4

Updated by Christopher Hoffman over 1 year ago

  • Related to Tasks #68431: Strided multi-fuse client write stalls added
Actions

Also available in: Atom PDF