From: Amir Goldstein <amir73il@gmail.com>
To: Miklos Szeredi <miklos@szeredi.hu>
Cc: Christian Brauner <brauner@kernel.org>,
Al Viro <viro@zeniv.linux.org.uk>, Jan Kara <jack@suse.cz>,
linux-fsdevel@vger.kernel.org, linux-unionfs@vger.kernel.org
Subject: [PATCH v2 2/3] fs: introduce f_real_path() helper
Date: Sun, 11 Jun 2023 16:27:31 +0300 [thread overview]
Message-ID: <20230611132732.1502040-3-amir73il@gmail.com> (raw)
In-Reply-To: <20230611132732.1502040-1-amir73il@gmail.com>
Overlayfs knows the real path of underlying dentries. Add an optional
struct vfsmount out argument to ->d_real(), so callers could compose the
real path.
Add a helper f_real_path() that uses this new interface to return the
real path of f_inode, for overlayfs internal files whose f_path if a
"fake" overlayfs path and f_inode is the underlying real inode.
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
Documentation/filesystems/locking.rst | 3 ++-
Documentation/filesystems/vfs.rst | 3 ++-
fs/file_table.c | 23 +++++++++++++++++++++++
fs/overlayfs/super.c | 27 ++++++++++++++++++---------
include/linux/dcache.h | 11 +++++++----
include/linux/fs.h | 4 +++-
6 files changed, 55 insertions(+), 16 deletions(-)
diff --git a/Documentation/filesystems/locking.rst b/Documentation/filesystems/locking.rst
index aa1a233b0fa8..a6063b0c79fd 100644
--- a/Documentation/filesystems/locking.rst
+++ b/Documentation/filesystems/locking.rst
@@ -29,7 +29,8 @@ prototypes::
char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen);
struct vfsmount *(*d_automount)(struct path *path);
int (*d_manage)(const struct path *, bool);
- struct dentry *(*d_real)(struct dentry *, const struct inode *);
+ struct dentry *(*d_real)(struct dentry *, const struct inode *,
+ struct vfsmount **pmnt);
locking rules:
diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst
index 769be5230210..edafe824fca4 100644
--- a/Documentation/filesystems/vfs.rst
+++ b/Documentation/filesystems/vfs.rst
@@ -1264,7 +1264,8 @@ defined:
char *(*d_dname)(struct dentry *, char *, int);
struct vfsmount *(*d_automount)(struct path *);
int (*d_manage)(const struct path *, bool);
- struct dentry *(*d_real)(struct dentry *, const struct inode *);
+ struct dentry *(*d_real)(struct dentry *, const struct inode *,
+ struct vfsmount **pmnt);
};
``d_revalidate``
diff --git a/fs/file_table.c b/fs/file_table.c
index d64d3933f3e4..fa187ceb54d6 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -215,6 +215,29 @@ struct file *alloc_empty_file_internal(int flags, const struct cred *cred)
return f;
}
+/**
+ * f_real_path - return the real path of an internal file with fake path
+ *
+ * @file: The file to query
+ *
+ * If f_path is on a union/overlay and f_inode is not, then return the
+ * underlying real path of f_inode.
+ * Otherwise return f_path (by value).
+ */
+struct path f_real_path(const struct file *f)
+{
+ struct path path;
+
+ if (!(f->f_mode & FMODE_INTERNAL) ||
+ (d_inode(f->f_path.dentry) == f->f_inode))
+ return f->f_path;
+
+ path.mnt = f->f_path.mnt;
+ path.dentry = d_real(f->f_path.dentry, f->f_inode, &path.mnt);
+ return path;
+}
+EXPORT_SYMBOL(f_real_path);
+
/**
* alloc_file - allocate and initialize a 'struct file'
*
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index d9be5d318e1b..591c77b33ff3 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -60,9 +60,11 @@ MODULE_PARM_DESC(metacopy,
"Default to on or off for the metadata only copy up feature");
static struct dentry *ovl_d_real(struct dentry *dentry,
- const struct inode *inode)
+ const struct inode *inode,
+ struct vfsmount **pmnt)
{
struct dentry *real = NULL, *lower;
+ struct path realpath;
/* It's an overlay file */
if (inode && d_inode(dentry) == inode)
@@ -74,12 +76,13 @@ static struct dentry *ovl_d_real(struct dentry *dentry,
goto bug;
}
- real = ovl_dentry_upper(dentry);
+ ovl_path_upper(dentry, &realpath);
+ real = realpath.dentry;
if (real && (inode == d_inode(real)))
- return real;
+ goto found;
if (real && !inode && ovl_has_upperdata(d_inode(dentry)))
- return real;
+ goto found;
/*
* Best effort lazy lookup of lowerdata for !inode case to return
@@ -90,16 +93,22 @@ static struct dentry *ovl_d_real(struct dentry *dentry,
* when setting the uprobe.
*/
ovl_maybe_lookup_lowerdata(dentry);
- lower = ovl_dentry_lowerdata(dentry);
+ ovl_path_lowerdata(dentry, &realpath);
+ lower = realpath.dentry;
if (!lower)
goto bug;
- real = lower;
/* Handle recursion */
- real = d_real(real, inode);
+ real = d_real(lower, inode, &realpath.mnt);
+
+ if (inode && inode != d_inode(real))
+ goto bug;
+
+found:
+ if (pmnt)
+ *pmnt = realpath.mnt;
+ return real;
- if (!inode || inode == d_inode(real))
- return real;
bug:
WARN(1, "%s(%pd4, %s:%lu): real dentry (%p/%lu) not found\n",
__func__, dentry, inode ? inode->i_sb->s_id : "NULL",
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 6b351e009f59..78a54d175662 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -139,7 +139,8 @@ struct dentry_operations {
char *(*d_dname)(struct dentry *, char *, int);
struct vfsmount *(*d_automount)(struct path *);
int (*d_manage)(const struct path *, bool);
- struct dentry *(*d_real)(struct dentry *, const struct inode *);
+ struct dentry *(*d_real)(struct dentry *, const struct inode *,
+ struct vfsmount **);
} ____cacheline_aligned;
/*
@@ -564,6 +565,7 @@ static inline struct dentry *d_backing_dentry(struct dentry *upper)
* d_real - Return the real dentry
* @dentry: the dentry to query
* @inode: inode to select the dentry from multiple layers (can be NULL)
+ * @pmnt: returns the real mnt in case @dentry is not real
*
* If dentry is on a union/overlay, then return the underlying, real dentry.
* Otherwise return the dentry itself.
@@ -571,10 +573,11 @@ static inline struct dentry *d_backing_dentry(struct dentry *upper)
* See also: Documentation/filesystems/vfs.rst
*/
static inline struct dentry *d_real(struct dentry *dentry,
- const struct inode *inode)
+ const struct inode *inode,
+ struct vfsmount **pmnt)
{
if (unlikely(dentry->d_flags & DCACHE_OP_REAL))
- return dentry->d_op->d_real(dentry, inode);
+ return dentry->d_op->d_real(dentry, inode, pmnt);
else
return dentry;
}
@@ -589,7 +592,7 @@ static inline struct dentry *d_real(struct dentry *dentry,
static inline struct inode *d_real_inode(const struct dentry *dentry)
{
/* This usage of d_real() results in const dentry */
- return d_backing_inode(d_real((struct dentry *) dentry, NULL));
+ return d_inode(d_real((struct dentry *) dentry, NULL, NULL));
}
struct name_snapshot {
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 13eec1e8ca86..d0129e9e0ae5 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1042,7 +1042,7 @@ static inline struct inode *file_inode(const struct file *f)
static inline struct dentry *file_dentry(const struct file *file)
{
- return d_real(file->f_path.dentry, file_inode(file));
+ return d_real(file->f_path.dentry, file_inode(file), NULL);
}
struct fasync_struct {
@@ -2354,6 +2354,8 @@ extern struct file *dentry_create(const struct path *path, int flags,
umode_t mode, const struct cred *cred);
extern struct file * open_with_fake_path(const struct path *, int,
struct inode*, const struct cred *);
+extern struct path f_real_path(const struct file *f);
+
static inline struct file *file_clone_open(struct file *file)
{
return dentry_open(&file->f_path, file->f_flags, file->f_cred);
--
2.34.1
next prev parent reply other threads:[~2023-06-11 13:27 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-11 13:27 [PATCH v2 0/3] Handle notifications on overlayfs fake path files Amir Goldstein
2023-06-11 13:27 ` [PATCH v2 1/3] fs: rename FMODE_NOACCOUNT to FMODE_INTERNAL Amir Goldstein
2023-06-12 4:27 ` Christoph Hellwig
2023-06-12 6:08 ` Amir Goldstein
2023-06-12 6:11 ` Christoph Hellwig
2023-06-12 6:15 ` Christoph Hellwig
2023-06-12 6:32 ` Amir Goldstein
2023-06-12 6:35 ` Christoph Hellwig
2023-06-11 13:27 ` Amir Goldstein [this message]
2023-06-12 4:36 ` [PATCH v2 2/3] fs: introduce f_real_path() helper Christoph Hellwig
2023-06-12 6:28 ` Amir Goldstein
2023-06-12 6:36 ` Christoph Hellwig
2023-06-12 8:13 ` Amir Goldstein
2023-06-11 13:27 ` [PATCH v2 3/3] ovl: enable fsnotify events on underlying real files Amir Goldstein
2023-06-11 14:23 ` [PATCH v2 0/3] Handle notifications on overlayfs fake path files Miklos Szeredi
2023-06-11 16:55 ` Amir Goldstein
2023-06-11 17:52 ` Amir Goldstein
2023-06-11 19:12 ` Miklos Szeredi
2023-06-11 19:25 ` Amir Goldstein
2023-06-11 19:37 ` Miklos Szeredi
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=20230611132732.1502040-3-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 \
--cc=viro@zeniv.linux.org.uk \
/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).