Actions
Tasks #67559
closedTasks #63293: Implement fscrypt in libcephfs and cephfs-fuse
Tasks #66577: interoperability with multi-client
file size not correct on overwrite
% 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.
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