Project

General

Profile

Actions

Tasks #67559

closed

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

Tasks #66577: interoperability with multi-client

file size not correct on overwrite

Added by Christopher Hoffman over 1 year 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

The file size is not correct when writing via kclient, reading via ceph-fuse.

echo contents1 > /mnt/kclient/enc1/filez
echo contents1 > /mnt/kclient/enc1/filez
hexdump /mnt/mycephfs/enc1/filez
0000000 6f63 746e 6e65 7374 0a31 0000 0000 0000
0000010 0000 0000 0000 0000 0000 0000 0000 0000
*
0001000

The trailing 0s indicate that size 4K is believed to be correct size.

Then after a long list a read is correct

ls -l /mnt/mycephfs/enc1/filez
hexdump /mnt/mycephfs/enc1/filez
0000000 6f63 746e 6e65 7374 0a31
000000a

Need to track down why the size is not getting updated correctly.

Actions #1

Updated by Christopher Hoffman over 1 year ago ยท Edited

  • Status changed from In Progress to Resolved

The issue was when calling update_inode_file_size, it was using fscrypt block size and not effective_size. Below is the fix for last remaining case.

commit 8f78aa23a58b5ccf3dd8d2e9b00f121dd8c4cc26 (HEAD -> wip-fscrypt)
Author: Christopher Hoffman <choffman@redhat.com>
Date:   Thu Aug 15 12:45:04 2024 +0000

    client: When calling update_inode_file_size, provide correct size

    Fixes: https://tracker.ceph.com/issues/67559
    Signed-off-by: Christopher Hoffman <choffman@redhat.com>

diff --git a/src/client/Client.cc b/src/client/Client.cc
index 32d0a00f816..cea058ba8b4 100644
--- a/src/client/Client.cc
+++ b/src/client/Client.cc
@@ -895,12 +895,11 @@ void Client::update_inode_file_size(Inode *in, int issued, uint64_t size,
                                    uint64_t truncate_seq, uint64_t truncate_size)
 {
   uint64_t prior_size = in->size;
-
   // In the case of a pending trunc size that is smaller than orig size
   // (i.e. truncating from 8M to 4M) passed truncate_seq will be larger
   // than inode truncate_seq. This shows passed size is latest.
   if (truncate_seq > in->truncate_seq ||
-      (truncate_seq == in->truncate_seq && size > in->size)) {
+      (truncate_seq == in->truncate_seq && size > in->effective_size())) {
     ldout(cct, 10) << "size " << in->size << " -> " << size << dendl;
     if (in->is_fscrypt_enabled()) {
       in->set_effective_size(size);
@@ -5616,7 +5615,7 @@ void Client::handle_cap_trunc(MetaSession *session, Inode *in, const MConstRef<M
   mds_rank_t mds = session->mds_num;
   ceph_assert(in->caps.count(mds));

-  uint64_t size = m->get_size();
+  uint64_t size = m->effective_size();
   ldout(cct, 10) << __func__ << " on ino " << *in
           << " size " << in->size << " -> " << m->get_size()
           << dendl;
@@ -5882,7 +5881,8 @@ void Client::handle_cap_grant(MetaSession *session, Inode *in, Cap *cap, const M

   if (new_caps & (CEPH_CAP_ANY_FILE_RD | CEPH_CAP_ANY_FILE_WR)) {
     in->layout = m->get_layout();
-    update_inode_file_size(in, issued, m->get_size(),
+    uint64_t size = m->effective_size();
+    update_inode_file_size(in, issued, size,
                           m->get_truncate_seq(), m->get_truncate_size());
   }

diff --git a/src/messages/MClientCaps.h b/src/messages/MClientCaps.h
index 96b2cb7d8b8..5e9cf8d0a02 100644
--- a/src/messages/MClientCaps.h
+++ b/src/messages/MClientCaps.h
@@ -62,6 +62,20 @@ private:
   std::vector<uint8_t> fscrypt_auth;
   std::vector<uint8_t> fscrypt_file;

+  bool is_fscrypt_enabled() const {
+    return !!fscrypt_auth.size();
+  }
+
+  uint64_t effective_size() const {
+    if(is_fscrypt_enabled()) {
+      if (fscrypt_file.size() >= sizeof(uint64_t)) {
+        return *(ceph_le64 *)fscrypt_file.data();
+      }
+    }
+
+    return size;
+  }
+

Actions

Also available in: Atom PDF