Tasks #64137
closedTasks #63293: Implement fscrypt in libcephfs and cephfs-fuse
Implement way to see locked status
0%
Description
Currently, there's a notion of "fscrypt_ctx" within Inode on Client. When this is non-nullptr, that means the inode should be unlocked.
On a new filesystem, without fscrypt unlocked, fscrypt_ctx is non-nullptr. Need to track down why this gets set.
From a comment:
// userland clients are only allowed to read if fscrypt enabled but no fscrypt ctx exists
// (is locked)
Steps to reproduce:
1. encrypt dir w/fscrypt
2. umount/remount file system
3. list encrypted dir contents
At this point, in->fscrypt_ctx will not be nullptr and comment above is false.
Updated by Patrick Donnelly about 2 years ago
- Assignee set to Christopher Hoffman
Updated by Christopher Hoffman over 1 year ago
- Status changed from New to In Progress
Updated by Igor Golikov over 1 year ago
- Assignee changed from Christopher Hoffman to Igor Golikov
Updated by Igor Golikov over 1 year ago
- Assignee changed from Igor Golikov to Christopher Hoffman
Updated by Christopher Hoffman about 1 year ago ยท Edited
- Status changed from In Progress to Resolved
fscrypt_ctx is a representation of fscrypt_auth. Whenever fscrypt_auth gets set or updated, fscrypt_ctx gets created. The preferred way to see locked status is to use is_inode_locked()
Did an audit of fscrypt_ctx usage and fixed cases where needed. See below. Changed the boolean to is_inode_locked, as fscrypt_ctx will always be set when fscrypt is enabled. Also added in a return statement that got removed.
Author: Christopher Hoffman <[email protected]> Date: Wed Jan 8 15:32:23 2025 +0000 client: change conditional to check for is locked. Fixes: https://tracker.ceph.com/issues/64137 Signed-off-by: Christopher Hoffman <[email protected]> diff --git a/src/client/Client.cc b/src/client/Client.cc index 9560593311f..4288de9e7f2 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -3832,10 +3832,9 @@ int Client::get_caps(Fh *fh, int need, int want, int *phave, loff_t endoff) if ((need & CEPH_CAP_FILE_WR) && ((in->auth_cap && in->auth_cap->session->readonly) || - // userland clients are only allowed to read if fscrypt enabled but no fscrypt ctx exists - // (is locked) - (in->is_fscrypt_enabled() && !in->fscrypt_ctx))) - + // userland clients are only allowed to read if fscrypt enabled and is locked + (in->is_fscrypt_enabled() && is_inode_locked(in)))) + return -CEPHFS_EROFS; if (in->flags & I_CAP_DROPPED) { int mds_wanted = in->caps_mds_wanted(); if ((mds_wanted & need) != need) { diff --git a/src/client/fuse_ll.cc b/src/client/fuse_ll.cc index 0dfaa4568c9..1940f5572e2 100644 --- a/src/client/fuse_ll.cc +++ b/src/client/fuse_ll.cc @@ -969,7 +969,7 @@ static void fuse_ll_ioctl(fuse_req_t req, fuse_ino_t ino, Fh *fh = (Fh*)fi->fh; Inode *in = fh->inode.get(); - if (in->fscrypt_ctx) { + if (in->is_fscrypt_enabled()) { in->fscrypt_ctx->convert_to(&out_arg.policy.v2); out_arg.policy_size = sizeof(out_arg.policy);