Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2d902671 authored by Miklos Szeredi's avatar Miklos Szeredi
Browse files

vfs: merge .d_select_inode() into .d_real()



The two methods essentially do the same: find the real dentry/inode
belonging to an overlay dentry.  The difference is in the usage:

vfs_open() uses ->d_select_inode() and expects the function to perform
copy-up if necessary based on the open flags argument.

file_dentry() uses ->d_real() passing in the overlay dentry as well as the
underlying inode.

vfs_rename() uses ->d_select_inode() but passes zero flags.  ->d_real()
with a zero inode would have worked just as well here.

This patch merges the functionality of ->d_select_inode() into ->d_real()
by adding an 'open_flags' argument to the latter.

[Al Viro] Make the signature of d_real() match that of ->d_real() again.
And constify the inode argument, while we are at it.

Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent 4c2e07c6
Loading
Loading
Loading
Loading
+0 −3
Original line number Original line Diff line number Diff line
@@ -1729,7 +1729,6 @@ void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op)
				DCACHE_OP_REVALIDATE	|
				DCACHE_OP_REVALIDATE	|
				DCACHE_OP_WEAK_REVALIDATE	|
				DCACHE_OP_WEAK_REVALIDATE	|
				DCACHE_OP_DELETE	|
				DCACHE_OP_DELETE	|
				DCACHE_OP_SELECT_INODE	|
				DCACHE_OP_REAL));
				DCACHE_OP_REAL));
	dentry->d_op = op;
	dentry->d_op = op;
	if (!op)
	if (!op)
@@ -1746,8 +1745,6 @@ void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op)
		dentry->d_flags |= DCACHE_OP_DELETE;
		dentry->d_flags |= DCACHE_OP_DELETE;
	if (op->d_prune)
	if (op->d_prune)
		dentry->d_flags |= DCACHE_OP_PRUNE;
		dentry->d_flags |= DCACHE_OP_PRUNE;
	if (op->d_select_inode)
		dentry->d_flags |= DCACHE_OP_SELECT_INODE;
	if (op->d_real)
	if (op->d_real)
		dentry->d_flags |= DCACHE_OP_REAL;
		dentry->d_flags |= DCACHE_OP_REAL;


+1 −1
Original line number Original line Diff line number Diff line
@@ -4328,7 +4328,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
	 * Check source == target.
	 * Check source == target.
	 * On overlayfs need to look at underlying inodes.
	 * On overlayfs need to look at underlying inodes.
	 */
	 */
	if (vfs_select_inode(old_dentry, 0) == vfs_select_inode(new_dentry, 0))
	if (d_real_inode(old_dentry) == d_real_inode(new_dentry))
		return 0;
		return 0;


	error = may_delete(old_dir, old_dentry, is_dir);
	error = may_delete(old_dir, old_dentry, is_dir);
+4 −4
Original line number Original line Diff line number Diff line
@@ -840,13 +840,13 @@ EXPORT_SYMBOL(file_path);
int vfs_open(const struct path *path, struct file *file,
int vfs_open(const struct path *path, struct file *file,
	     const struct cred *cred)
	     const struct cred *cred)
{
{
	struct inode *inode = vfs_select_inode(path->dentry, file->f_flags);
	struct dentry *dentry = d_real(path->dentry, NULL, file->f_flags);


	if (IS_ERR(inode))
	if (IS_ERR(dentry))
		return PTR_ERR(inode);
		return PTR_ERR(dentry);


	file->f_path = *path;
	file->f_path = *path;
	return do_dentry_open(file, inode, NULL, cred);
	return do_dentry_open(file, d_backing_inode(dentry), NULL, cred);
}
}


struct file *dentry_open(const struct path *path, int flags,
struct file *dentry_open(const struct path *path, int flags,
+10 −21
Original line number Original line Diff line number Diff line
@@ -325,36 +325,25 @@ static bool ovl_open_need_copy_up(int flags, enum ovl_path_type type,
	return true;
	return true;
}
}


struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags)
int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags)
{
{
	int err;
	int err = 0;
	struct path realpath;
	struct path realpath;
	enum ovl_path_type type;
	enum ovl_path_type type;


	if (d_is_dir(dentry))
		return d_backing_inode(dentry);

	type = ovl_path_real(dentry, &realpath);
	type = ovl_path_real(dentry, &realpath);
	if (ovl_open_need_copy_up(file_flags, type, realpath.dentry)) {
	if (ovl_open_need_copy_up(file_flags, type, realpath.dentry)) {
		err = ovl_want_write(dentry);
		err = ovl_want_write(dentry);
		if (err)
		if (!err) {
			return ERR_PTR(err);

			if (file_flags & O_TRUNC)
			if (file_flags & O_TRUNC)
				err = ovl_copy_up_truncate(dentry);
				err = ovl_copy_up_truncate(dentry);
			else
			else
				err = ovl_copy_up(dentry);
				err = ovl_copy_up(dentry);
			ovl_drop_write(dentry);
			ovl_drop_write(dentry);
		if (err)
		}
			return ERR_PTR(err);

		ovl_path_upper(dentry, &realpath);
	}
	}


	if (realpath.dentry->d_flags & DCACHE_OP_SELECT_INODE)
	return err;
		return realpath.dentry->d_op->d_select_inode(realpath.dentry, file_flags);

	return d_backing_inode(realpath.dentry);
}
}


static const struct inode_operations ovl_file_inode_operations = {
static const struct inode_operations ovl_file_inode_operations = {
+1 −1
Original line number Original line Diff line number Diff line
@@ -179,7 +179,7 @@ ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode,
		     const char *name, void *value, size_t size);
		     const char *name, void *value, size_t size);
ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size);
ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size);
int ovl_removexattr(struct dentry *dentry, const char *name);
int ovl_removexattr(struct dentry *dentry, const char *name);
struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags);
int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags);


struct inode *ovl_new_inode(struct super_block *sb, umode_t mode,
struct inode *ovl_new_inode(struct super_block *sb, umode_t mode,
			    struct ovl_entry *oe);
			    struct ovl_entry *oe);
Loading