linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Stefan Berger <stefanb@linux.ibm.com>
To: Amir Goldstein <amir73il@gmail.com>, Miklos Szeredi <miklos@szeredi.hu>
Cc: Al Viro <viro@zeniv.linux.org.uk>,
	Christian Brauner <brauner@kernel.org>,
	Mimi Zohar <zohar@linux.ibm.com>,
	linux-unionfs@vger.kernel.org, linux-integrity@vger.kernel.org,
	linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH 2/2] fs: remove the inode argument to ->d_real() method
Date: Fri, 2 Feb 2024 10:17:27 -0500	[thread overview]
Message-ID: <0bfb559c-5b35-480f-99f6-c3b7552244e1@linux.ibm.com> (raw)
In-Reply-To: <20240202110132.1584111-3-amir73il@gmail.com>



On 2/2/24 06:01, Amir Goldstein wrote:
> The only remaining user of ->d_real() method is d_real_inode(), which
> passed NULL inode argument to get the real data dentry.
> 
> There are no longer any users that call ->d_real() with a non-NULL
> inode argument for getting a detry from a specific underlying layer.
> 
> Remove the inode argument of the method and replace it with an integer
> 'type' argument, to allow callers to request the real metadata dentry
> instead of the real data dentry.
> 
> All the current users of d_real_inode() (e.g. uprobe) continue to get
> the real data inode.  Caller that need to get the real metadata inode
> (e.g. IMA/EVM) can use d_inode(d_real(dentry, D_REAL_METADATA)).
> 
> Signed-off-by: Amir Goldstein <amir73il@gmail.com>

Tested-by: Stefan Berger <stefanb@linux.ibm.com>


> ---
>   Documentation/filesystems/locking.rst |  2 +-
>   Documentation/filesystems/vfs.rst     | 16 ++++-----
>   fs/overlayfs/super.c                  | 52 ++++++++++++---------------
>   include/linux/dcache.h                | 18 ++++++----
>   4 files changed, 41 insertions(+), 47 deletions(-)
> 
> diff --git a/Documentation/filesystems/locking.rst b/Documentation/filesystems/locking.rst
> index d5bf4b6b7509..453039a2e49b 100644
> --- a/Documentation/filesystems/locking.rst
> +++ b/Documentation/filesystems/locking.rst
> @@ -29,7 +29,7 @@ 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 *, int type);
>   
>   locking rules:
>   
> diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst
> index eebcc0f9e2bc..2a39e718fdf8 100644
> --- a/Documentation/filesystems/vfs.rst
> +++ b/Documentation/filesystems/vfs.rst
> @@ -1264,7 +1264,7 @@ 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 *, int type);
>   	};
>   
>   ``d_revalidate``
> @@ -1419,16 +1419,14 @@ defined:
>   	the dentry being transited from.
>   
>   ``d_real``
> -	overlay/union type filesystems implement this method to return
> -	one of the underlying dentries hidden by the overlay.  It is
> -	used in two different modes:
> +	overlay/union type filesystems implement this method to return one
> +	of the underlying dentries of a regular file hidden by the overlay.
>   
> -	Called from file_dentry() it returns the real dentry matching
> -	the inode argument.  The real dentry may be from a lower layer
> -	already copied up, but still referenced from the file.  This
> -	mode is selected with a non-NULL inode argument.
> +	The 'type' argument takes the values D_REAL_DATA or D_REAL_METADATA
> +	for returning the real underlying dentry that refers to the inode
> +	hosting the file's data or metadata respectively.
>   
> -	With NULL inode the topmost real underlying dentry is returned.
> +	For non-regular files, the 'dentry' argument is returned.
>   
>   Each dentry has a pointer to its parent dentry, as well as a hash list
>   of child dentries.  Child dentries are basically like files in a
> diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
> index 2eef6c70b2ae..938852a0a92b 100644
> --- a/fs/overlayfs/super.c
> +++ b/fs/overlayfs/super.c
> @@ -28,41 +28,38 @@ MODULE_LICENSE("GPL");
>   
>   struct ovl_dir_cache;
>   
> -static struct dentry *ovl_d_real(struct dentry *dentry,
> -				 const struct inode *inode)
> +static struct dentry *ovl_d_real(struct dentry *dentry, int type)
>   {
> -	struct dentry *real = NULL, *lower;
> +	struct dentry *upper, *lower;
>   	int err;
>   
> -	/*
> -	 * vfs is only expected to call d_real() with NULL from d_real_inode()
> -	 * and with overlay inode from file_dentry() on an overlay file.
> -	 *
> -	 * TODO: remove @inode argument from d_real() API, remove code in this
> -	 * function that deals with non-NULL @inode and remove d_real() call
> -	 * from file_dentry().
> -	 */
> -	if (inode && d_inode(dentry) == inode)
> -		return dentry;
> -	else if (inode)
> +	switch (type) {
> +	case D_REAL_DATA:
> +	case D_REAL_METADATA:
> +		break;
> +	default:
>   		goto bug;
> +	}
>   
>   	if (!d_is_reg(dentry)) {
>   		/* d_real_inode() is only relevant for regular files */
>   		return dentry;
>   	}
>   
> -	real = ovl_dentry_upper(dentry);
> -	if (real && (inode == d_inode(real)))
> -		return real;
> +	upper = ovl_dentry_upper(dentry);
> +	if (upper && (type == D_REAL_METADATA ||
> +		      ovl_has_upperdata(d_inode(dentry))))
> +		return upper;
>   
> -	if (real && !inode && ovl_has_upperdata(d_inode(dentry)))
> -		return real;
> +	if (type == D_REAL_METADATA) {
> +		lower = ovl_dentry_lower(dentry);
> +		goto real_lower;
> +	}
>   
>   	/*
> -	 * Best effort lazy lookup of lowerdata for !inode case to return
> +	 * Best effort lazy lookup of lowerdata for D_REAL_DATA case to return
>   	 * the real lowerdata dentry.  The only current caller of d_real() with
> -	 * NULL inode is d_real_inode() from trace_uprobe and this caller is
> +	 * D_REAL_DATA is d_real_inode() from trace_uprobe and this caller is
>   	 * likely going to be followed reading from the file, before placing
>   	 * uprobes on offset within the file, so lowerdata should be available
>   	 * when setting the uprobe.
> @@ -73,18 +70,13 @@ static struct dentry *ovl_d_real(struct dentry *dentry,
>   	lower = ovl_dentry_lowerdata(dentry);
>   	if (!lower)
>   		goto bug;
> -	real = lower;
>   
> -	/* Handle recursion */
> -	real = d_real(real, inode);
> +real_lower:
> +	/* Handle recursion into stacked lower fs */
> +	return d_real(lower, type);
>   
> -	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",
> -	     inode ? inode->i_ino : 0, real,
> -	     real && d_inode(real) ? d_inode(real)->i_ino : 0);
> +	WARN(1, "%s(%pd4, %d): real dentry not found\n", __func__, dentry, type);
>   	return dentry;
>   }
>   
> diff --git a/include/linux/dcache.h b/include/linux/dcache.h
> index 1666c387861f..019ad02f2b7e 100644
> --- a/include/linux/dcache.h
> +++ b/include/linux/dcache.h
> @@ -139,7 +139,7 @@ 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 *, int type);
>   } ____cacheline_aligned;
>   
>   /*
> @@ -543,27 +543,31 @@ static inline struct inode *d_backing_inode(const struct dentry *upper)
>   	return inode;
>   }
>   
> +enum d_real_type {
> +	D_REAL_DATA,
> +	D_REAL_METADATA,
> +};
> +
>   /**
>    * d_real - Return the real dentry
>    * @dentry: the dentry to query
> - * @inode: inode to select the dentry from multiple layers (can be NULL)
> + * @type: the type of real dentry (data or metadata)
>    *
>    * If dentry is on a union/overlay, then return the underlying, real dentry.
>    * Otherwise return the dentry itself.
>    *
>    * See also: Documentation/filesystems/vfs.rst
>    */
> -static inline struct dentry *d_real(struct dentry *dentry,
> -				    const struct inode *inode)
> +static inline struct dentry *d_real(struct dentry *dentry, int type)
>   {
>   	if (unlikely(dentry->d_flags & DCACHE_OP_REAL))
> -		return dentry->d_op->d_real(dentry, inode);
> +		return dentry->d_op->d_real(dentry, type);
>   	else
>   		return dentry;
>   }
>   
>   /**
> - * d_real_inode - Return the real inode
> + * d_real_inode - Return the real inode hosting the data
>    * @dentry: The dentry to query
>    *
>    * If dentry is on a union/overlay, then return the underlying, real inode.
> @@ -572,7 +576,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, D_REAL_DATA));
>   }
>   
>   struct name_snapshot {

  parent reply	other threads:[~2024-02-02 15:17 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-02 11:01 [PATCH 0/2] Decomplicate file_dentry() Amir Goldstein
2024-02-02 11:01 ` [PATCH 1/2] fs: make file_dentry() a simple accessor Amir Goldstein
2024-02-02 15:16   ` Stefan Berger
2024-02-02 11:01 ` [PATCH 2/2] fs: remove the inode argument to ->d_real() method Amir Goldstein
2024-02-02 12:19   ` Miklos Szeredi
2024-02-02 12:41     ` Amir Goldstein
2024-02-02 13:54       ` Christian Brauner
2024-02-06 15:28         ` Amir Goldstein
2024-02-02 15:17   ` Stefan Berger [this message]
2024-02-02 16:05   ` Al Viro
2024-02-02 16:16     ` Al Viro
2024-02-02 17:34       ` Stefan Berger
2024-02-02 18:27         ` Al Viro
2024-02-02 18:32           ` Stefan Berger
2024-02-02 18:50             ` Al Viro
2024-02-02 18:38           ` Al Viro
2024-02-06 16:02 ` [PATCH 0/2] Decomplicate file_dentry() Christian Brauner

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=0bfb559c-5b35-480f-99f6-c3b7552244e1@linux.ibm.com \
    --to=stefanb@linux.ibm.com \
    --cc=amir73il@gmail.com \
    --cc=brauner@kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-unionfs@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    --cc=viro@zeniv.linux.org.uk \
    --cc=zohar@linux.ibm.com \
    /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).