From: Amir Goldstein <amir73il@gmail.com>
To: Miklos Szeredi <miklos@szeredi.hu>, Jan Kara <jack@suse.cz>
Cc: Christian Brauner <brauner@kernel.org>,
linux-unionfs@vger.kernel.org, linux-fsdevel@vger.kernel.org
Subject: [RFC][PATCH 1/3] ovl: support encoding non-decodeable file handles
Date: Tue, 25 Apr 2023 16:22:21 +0300 [thread overview]
Message-ID: <20230425132223.2608226-2-amir73il@gmail.com> (raw)
In-Reply-To: <20230425132223.2608226-1-amir73il@gmail.com>
When all layers support file handles, we support encoding non-decodeable
file handles (a.k.a. fid) even with nfs_export=off.
When file handles do not need to be decoded, we do not need to copy up
redirected lower directories on encode, and we encode also non-indexed
upper with lower file handle, so fid will not change on copy up.
This enables reporting fanotify events with file handles on overlayfs
with default config/mount options.
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
fs/overlayfs/export.c | 26 ++++++++++++++++++++------
fs/overlayfs/inode.c | 2 +-
fs/overlayfs/overlayfs.h | 1 +
fs/overlayfs/ovl_entry.h | 1 +
fs/overlayfs/super.c | 9 +++++++++
5 files changed, 32 insertions(+), 7 deletions(-)
diff --git a/fs/overlayfs/export.c b/fs/overlayfs/export.c
index defd4e231ad2..dfd05ad2b722 100644
--- a/fs/overlayfs/export.c
+++ b/fs/overlayfs/export.c
@@ -173,28 +173,37 @@ static int ovl_connect_layer(struct dentry *dentry)
* U = upper file handle
* L = lower file handle
*
- * (*) Connecting an overlay dir from real lower dentry is not always
+ * (*) Decoding a connected overlay dir from real lower dentry is not always
* possible when there are redirects in lower layers and non-indexed merge dirs.
* To mitigate those case, we may copy up the lower dir ancestor before encode
- * a lower dir file handle.
+ * of a decodeable file handle for non-upper dir.
*
* Return 0 for upper file handle, > 0 for lower file handle or < 0 on error.
*/
static int ovl_check_encode_origin(struct dentry *dentry)
{
struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
+ bool decodeable = ofs->config.nfs_export;
+
+ /* Lower file handle for non-upper non-decodeable */
+ if (!ovl_dentry_upper(dentry) && !decodeable)
+ return 0;
/* Upper file handle for pure upper */
if (!ovl_dentry_lower(dentry))
return 0;
/*
- * Upper file handle for non-indexed upper.
- *
* Root is never indexed, so if there's an upper layer, encode upper for
* root.
*/
- if (ovl_dentry_upper(dentry) &&
+ if (dentry == dentry->d_sb->s_root)
+ return 0;
+
+ /*
+ * Upper decodeable file handle for non-indexed upper.
+ */
+ if (ovl_dentry_upper(dentry) && decodeable &&
!ovl_test_flag(OVL_INDEX, d_inode(dentry)))
return 0;
@@ -204,7 +213,7 @@ static int ovl_check_encode_origin(struct dentry *dentry)
* ovl_connect_layer() will try to make origin's layer "connected" by
* copying up a "connectable" ancestor.
*/
- if (d_is_dir(dentry) && ovl_upper_mnt(ofs))
+ if (d_is_dir(dentry) && ovl_upper_mnt(ofs) && decodeable)
return ovl_connect_layer(dentry);
/* Lower file handle for indexed and non-upper dir/non-dir */
@@ -875,3 +884,8 @@ const struct export_operations ovl_export_operations = {
.get_name = ovl_get_name,
.get_parent = ovl_get_parent,
};
+
+/* encode_fh() encodes non-decodeable file handles with nfs_export=off */
+const struct export_operations ovl_export_fid_operations = {
+ .encode_fh = ovl_encode_fh,
+};
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index 541cf3717fc2..b6bec4064390 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -1304,7 +1304,7 @@ static bool ovl_hash_bylower(struct super_block *sb, struct dentry *upper,
return false;
/* No, if non-indexed upper with NFS export */
- if (sb->s_export_op && upper)
+ if (ofs->config.nfs_export && upper)
return false;
/* Otherwise, hash by lower inode for fsnotify */
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index 4d0b278f5630..87d44b889129 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -734,3 +734,4 @@ int ovl_set_origin(struct ovl_fs *ofs, struct dentry *lower,
/* export.c */
extern const struct export_operations ovl_export_operations;
+extern const struct export_operations ovl_export_fid_operations;
diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h
index fd11fe6d6d45..5cc0b6e65488 100644
--- a/fs/overlayfs/ovl_entry.h
+++ b/fs/overlayfs/ovl_entry.h
@@ -67,6 +67,7 @@ struct ovl_fs {
const struct cred *creator_cred;
bool tmpfile;
bool noxattr;
+ bool nofh;
/* Did we take the inuse lock? */
bool upperdir_locked;
bool workdir_locked;
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index f1d9f75f8786..5ed8c2650293 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -954,6 +954,7 @@ static int ovl_lower_dir(const char *name, struct path *path,
pr_warn("fs on '%s' does not support file handles, falling back to index=off,nfs_export=off.\n",
name);
}
+ ofs->nofh |= !fh_type;
/*
* Decoding origin file handle is required for persistent st_ino.
* Without persistent st_ino, xino=auto falls back to xino=off.
@@ -1391,6 +1392,7 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs,
ofs->config.index = false;
pr_warn("upper fs does not support file handles, falling back to index=off.\n");
}
+ ofs->nofh |= !fh_type;
/* Check if upper fs has 32bit inode numbers */
if (fh_type != FILEID_INO32_GEN)
@@ -2049,8 +2051,15 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
ofs->config.nfs_export = false;
}
+ /*
+ * Support encoding decodeable file handles with nfs_export=on
+ * and encoding non-decodeable file handles with nfs_export=off
+ * if all layers support file handles.
+ */
if (ofs->config.nfs_export)
sb->s_export_op = &ovl_export_operations;
+ else if (!ofs->nofh)
+ sb->s_export_op = &ovl_export_fid_operations;
/* Never override disk quota limits or use reserved space */
cap_lower(cred->cap_effective, CAP_SYS_RESOURCE);
--
2.34.1
next prev parent reply other threads:[~2023-04-25 13:22 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-25 13:22 [RFC][PATCH 0/3] Prepare for supporting more filesystems with fanotify Amir Goldstein
2023-04-25 13:22 ` Amir Goldstein [this message]
2023-07-06 7:27 ` [RFC][PATCH 1/3] ovl: support encoding non-decodeable file handles Amir Goldstein
2023-04-25 13:22 ` [RFC][PATCH 2/3] ovl: report a per-instance f_fsid by default Amir Goldstein
2023-04-25 13:22 ` [RFC][PATCH 3/3] ovl: use persistent s_uuid with index=on Amir Goldstein
2023-07-06 7:19 ` Amir Goldstein
2023-07-06 10:14 ` Amir Goldstein
2023-07-06 17:49 ` Amir Goldstein
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=20230425132223.2608226-2-amir73il@gmail.com \
--to=amir73il@gmail.com \
--cc=brauner@kernel.org \
--cc=jack@suse.cz \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-unionfs@vger.kernel.org \
--cc=miklos@szeredi.hu \
/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;
as well as URLs for NNTP newsgroup(s).