From: Jeff Layton <jlayton@kernel.org>
To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Subject: [RFC PATCH v3 12/16] ceph: add encrypted fname handling to ceph_mdsc_build_path
Date: Mon, 14 Sep 2020 15:17:03 -0400 [thread overview]
Message-ID: <20200914191707.380444-13-jlayton@kernel.org> (raw)
In-Reply-To: <20200914191707.380444-1-jlayton@kernel.org>
Allow ceph_mdsc_build_path to encrypt and base64 encode the filename
when the parent is encrypted and we're sending the path to the MDS.
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
fs/ceph/mds_client.c | 70 ++++++++++++++++++++++++++++++++++----------
1 file changed, 54 insertions(+), 16 deletions(-)
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index e3dc061252d4..7eb504170981 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -2314,18 +2314,27 @@ static inline u64 __get_oldest_tid(struct ceph_mds_client *mdsc)
return mdsc->oldest_tid;
}
-/*
- * Build a dentry's path. Allocate on heap; caller must kfree. Based
- * on build_path_from_dentry in fs/cifs/dir.c.
+/**
+ * ceph_mdsc_build_path - build a path string to a given dentry
+ * @dentry: dentry to which path should be built
+ * @plen: returned length of string
+ * @pbase: returned base inode number
+ * @for_wire: is this path going to be sent to the MDS?
+ *
+ * Build a string that represents the path to the dentry. This is mostly called
+ * for two different purposes:
+ *
+ * 1) we need to build a path string to send to the MDS (for_wire == true)
+ * 2) we need a path string for local presentation (e.g. debugfs) (for_wire == false)
*
- * If @stop_on_nosnap, generate path relative to the first non-snapped
- * inode.
+ * The path is built in reverse, starting with the dentry. Walk back up toward
+ * the root, building the path until the first non-snapped inode is reached (for_wire)
+ * or the root inode is reached (!for_wire).
*
* Encode hidden .snap dirs as a double /, i.e.
* foo/.snap/bar -> foo//bar
*/
-char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *pbase,
- int stop_on_nosnap)
+char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *pbase, int for_wire)
{
struct dentry *cur;
struct inode *inode;
@@ -2347,30 +2356,59 @@ char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *pbase,
seq = read_seqbegin(&rename_lock);
cur = dget(dentry);
for (;;) {
- struct dentry *temp;
+ struct dentry *parent;
spin_lock(&cur->d_lock);
inode = d_inode(cur);
+ parent = cur->d_parent;
if (inode && ceph_snap(inode) == CEPH_SNAPDIR) {
dout("build_path path+%d: %p SNAPDIR\n",
pos, cur);
- } else if (stop_on_nosnap && inode && dentry != cur &&
- ceph_snap(inode) == CEPH_NOSNAP) {
+ dget(parent);
+ spin_unlock(&cur->d_lock);
+ } else if (for_wire && inode && dentry != cur && ceph_snap(inode) == CEPH_NOSNAP) {
spin_unlock(&cur->d_lock);
pos++; /* get rid of any prepended '/' */
break;
- } else {
+ } else if (!for_wire || !IS_ENCRYPTED(d_inode(parent))) {
pos -= cur->d_name.len;
if (pos < 0) {
spin_unlock(&cur->d_lock);
break;
}
memcpy(path + pos, cur->d_name.name, cur->d_name.len);
+ dget(parent);
+ spin_unlock(&cur->d_lock);
+ } else {
+ int err;
+ struct fscrypt_name fname = { };
+ int len;
+ char buf[FSCRYPT_BASE64_CHARS(NAME_MAX)];
+
+ dget(parent);
+ spin_unlock(&cur->d_lock);
+
+ err = fscrypt_setup_filename(d_inode(parent), &cur->d_name, 1, &fname);
+ if (err) {
+ dput(parent);
+ dput(cur);
+ return ERR_PTR(err);
+ }
+
+ /* base64 encode the encrypted name */
+ len = fscrypt_base64_encode(fname.disk_name.name, fname.disk_name.len, buf);
+ pos -= len;
+ if (pos < 0) {
+ dput(parent);
+ fscrypt_free_filename(&fname);
+ break;
+ }
+ memcpy(path + pos, buf, len);
+ dout("non-ciphertext name = %.*s\n", len, buf);
+ fscrypt_free_filename(&fname);
}
- temp = cur;
- cur = dget(temp->d_parent);
- spin_unlock(&temp->d_lock);
- dput(temp);
+ dput(cur);
+ cur = parent;
/* Are we at the root? */
if (IS_ROOT(cur))
@@ -2415,7 +2453,7 @@ static int build_dentry_path(struct dentry *dentry, struct inode *dir,
rcu_read_lock();
if (!dir)
dir = d_inode_rcu(dentry->d_parent);
- if (dir && parent_locked && ceph_snap(dir) == CEPH_NOSNAP) {
+ if (dir && parent_locked && ceph_snap(dir) == CEPH_NOSNAP && !IS_ENCRYPTED(dir)) {
*pino = ceph_ino(dir);
rcu_read_unlock();
*ppath = dentry->d_name.name;
--
2.26.2
next prev parent reply other threads:[~2020-09-14 19:18 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-09-14 19:16 [RFC PATCH v3 00/16] ceph+fscrypt: context, filename and symlink support Jeff Layton
2020-09-14 19:16 ` [RFC PATCH v3 01/16] vfs: export new_inode_pseudo Jeff Layton
2020-09-14 23:33 ` Eric Biggers
2020-09-23 3:41 ` Al Viro
2020-09-23 11:19 ` Jeff Layton
2020-09-14 19:16 ` [RFC PATCH v3 02/16] fscrypt: export fscrypt_base64_encode and fscrypt_base64_decode Jeff Layton
2020-09-14 23:44 ` Eric Biggers
2020-09-14 19:16 ` [RFC PATCH v3 03/16] fscrypt: export fscrypt_d_revalidate Jeff Layton
2020-09-15 0:04 ` Eric Biggers
2020-09-14 19:16 ` [RFC PATCH v3 04/16] fscrypt: add fscrypt_context_for_new_inode Jeff Layton
2020-09-15 0:15 ` Eric Biggers
2020-09-14 19:16 ` [RFC PATCH v3 05/16] fscrypt: make fscrypt_fname_disk_to_usr return whether result is nokey name Jeff Layton
2020-09-15 0:23 ` Eric Biggers
2020-09-14 19:16 ` [RFC PATCH v3 06/16] ceph: add fscrypt ioctls Jeff Layton
2020-09-15 0:45 ` Eric Biggers
2020-09-15 12:08 ` Jeff Layton
2020-09-14 19:16 ` [RFC PATCH v3 07/16] ceph: crypto context handling for ceph Jeff Layton
2020-09-15 1:00 ` Eric Biggers
2020-09-14 19:16 ` [RFC PATCH v3 08/16] ceph: implement -o test_dummy_encryption mount option Jeff Layton
2020-09-15 1:23 ` Eric Biggers
2020-09-16 12:49 ` Jeff Layton
2020-09-14 19:17 ` [RFC PATCH v3 09/16] ceph: preallocate inode for ops that may create one Jeff Layton
2020-09-15 1:30 ` Eric Biggers
2020-09-16 12:41 ` Jeff Layton
2020-09-14 19:17 ` [RFC PATCH v3 10/16] ceph: add routine to create context prior to RPC Jeff Layton
2020-09-15 1:37 ` Eric Biggers
2020-09-16 12:18 ` Jeff Layton
2020-09-14 19:17 ` [RFC PATCH v3 11/16] ceph: make ceph_msdc_build_path use ref-walk Jeff Layton
2020-09-14 19:17 ` Jeff Layton [this message]
2020-09-15 1:41 ` [RFC PATCH v3 12/16] ceph: add encrypted fname handling to ceph_mdsc_build_path Eric Biggers
2020-09-16 12:30 ` Jeff Layton
2020-09-16 17:36 ` Eric Biggers
2020-09-16 18:04 ` Jeff Layton
2020-09-16 18:42 ` Eric Biggers
2020-09-14 19:17 ` [RFC PATCH v3 13/16] ceph: make d_revalidate call fscrypt revalidator for encrypted dentries Jeff Layton
2020-09-14 19:17 ` [RFC PATCH v3 14/16] ceph: add support to readdir for encrypted filenames Jeff Layton
2020-09-15 1:57 ` Eric Biggers
2020-09-15 13:27 ` Jeff Layton
2020-09-15 20:40 ` Eric Biggers
2020-09-16 12:16 ` Jeff Layton
2020-09-14 19:17 ` [RFC PATCH v3 15/16] ceph: add fscrypt support to ceph_fill_trace Jeff Layton
2020-09-14 19:17 ` [RFC PATCH v3 16/16] ceph: create symlinks with encrypted and base64-encoded targets Jeff Layton
2020-09-15 2:07 ` Eric Biggers
2020-09-15 14:05 ` Jeff Layton
2020-09-15 20:49 ` Eric Biggers
2020-09-16 12:15 ` Jeff Layton
2020-09-15 2:13 ` [RFC PATCH v3 00/16] ceph+fscrypt: context, filename and symlink support Eric Biggers
2020-09-15 13:38 ` Jeff Layton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200914191707.380444-13-jlayton@kernel.org \
--to=jlayton@kernel.org \
--cc=ceph-devel@vger.kernel.org \
--cc=linux-fscrypt@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox