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

Commit 1b91dbdd authored by Miklos Szeredi's avatar Miklos Szeredi
Browse files

Merge branch 'd_real' into overlayfs-next

parents 523d939e 0cac643c
Loading
Loading
Loading
Loading
+3 −2
Original line number Original line Diff line number Diff line
@@ -20,6 +20,8 @@ prototypes:
	char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen);
	char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen);
	struct vfsmount *(*d_automount)(struct path *path);
	struct vfsmount *(*d_automount)(struct path *path);
	int (*d_manage)(struct dentry *, bool);
	int (*d_manage)(struct dentry *, bool);
	struct dentry *(*d_real)(struct dentry *, const struct inode *,
				 unsigned int);


locking rules:
locking rules:
		rename_lock	->d_lock	may block	rcu-walk
		rename_lock	->d_lock	may block	rcu-walk
@@ -34,6 +36,7 @@ d_iput: no no yes no
d_dname:	no		no		no		no
d_dname:	no		no		no		no
d_automount:	no		no		yes		no
d_automount:	no		no		yes		no
d_manage:	no		no		yes (ref-walk)	maybe
d_manage:	no		no		yes (ref-walk)	maybe
d_real		no		no		yes 		no


--------------------------- inode_operations --------------------------- 
--------------------------- inode_operations --------------------------- 
prototypes:
prototypes:
@@ -66,7 +69,6 @@ prototypes:
				struct file *, unsigned open_flag,
				struct file *, unsigned open_flag,
				umode_t create_mode, int *opened);
				umode_t create_mode, int *opened);
	int (*tmpfile) (struct inode *, struct dentry *, umode_t);
	int (*tmpfile) (struct inode *, struct dentry *, umode_t);
	int (*dentry_open)(struct dentry *, struct file *, const struct cred *);


locking rules:
locking rules:
	all may block
	all may block
@@ -95,7 +97,6 @@ fiemap: no
update_time:	no
update_time:	no
atomic_open:	yes
atomic_open:	yes
tmpfile:	no
tmpfile:	no
dentry_open:	no


	Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on
	Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on
victim.
victim.
+26 −14
Original line number Original line Diff line number Diff line
@@ -364,7 +364,6 @@ struct inode_operations {
	int (*atomic_open)(struct inode *, struct dentry *, struct file *,
	int (*atomic_open)(struct inode *, struct dentry *, struct file *,
			unsigned open_flag, umode_t create_mode, int *opened);
			unsigned open_flag, umode_t create_mode, int *opened);
	int (*tmpfile) (struct inode *, struct dentry *, umode_t);
	int (*tmpfile) (struct inode *, struct dentry *, umode_t);
	int (*dentry_open)(struct dentry *, struct file *, const struct cred *);
};
};


Again, all methods are called without any locks being held, unless
Again, all methods are called without any locks being held, unless
@@ -696,13 +695,6 @@ struct address_space_operations {
  	but instead uses bmap to find out where the blocks in the file
  	but instead uses bmap to find out where the blocks in the file
  	are and uses those addresses directly.
  	are and uses those addresses directly.


  dentry_open: *WARNING: probably going away soon, do not use!* This is an
	alternative to f_op->open(), the difference is that this method may open
	a file not necessarily originating from the same filesystem as the one
	i_op->open() was called on.  It may be useful for stacking filesystems
	which want to allow native I/O directly on underlying files.


  invalidatepage: If a page has PagePrivate set, then invalidatepage
  invalidatepage: If a page has PagePrivate set, then invalidatepage
        will be called when part or all of the page is to be removed
        will be called when part or all of the page is to be removed
	from the address space.  This generally corresponds to either a
	from the address space.  This generally corresponds to either a
@@ -938,6 +930,8 @@ struct dentry_operations {
	char *(*d_dname)(struct dentry *, char *, int);
	char *(*d_dname)(struct dentry *, char *, int);
	struct vfsmount *(*d_automount)(struct path *);
	struct vfsmount *(*d_automount)(struct path *);
	int (*d_manage)(struct dentry *, bool);
	int (*d_manage)(struct dentry *, bool);
	struct dentry *(*d_real)(struct dentry *, const struct inode *,
				 unsigned int);
};
};


  d_revalidate: called when the VFS needs to revalidate a dentry. This
  d_revalidate: called when the VFS needs to revalidate a dentry. This
@@ -1022,6 +1016,14 @@ struct dentry_operations {
	at the end of the buffer, and returns a pointer to the first char.
	at the end of the buffer, and returns a pointer to the first char.
	dynamic_dname() helper function is provided to take care of this.
	dynamic_dname() helper function is provided to take care of this.


	Example :

	static char *pipefs_dname(struct dentry *dent, char *buffer, int buflen)
	{
		return dynamic_dname(dentry, buffer, buflen, "pipe:[%lu]",
				dentry->d_inode->i_ino);
	}

  d_automount: called when an automount dentry is to be traversed (optional).
  d_automount: called when an automount dentry is to be traversed (optional).
	This should create a new VFS mount record and return the record to the
	This should create a new VFS mount record and return the record to the
	caller.  The caller is supplied with a path parameter giving the
	caller.  The caller is supplied with a path parameter giving the
@@ -1060,13 +1062,23 @@ struct dentry_operations {
	This function is only used if DCACHE_MANAGE_TRANSIT is set on the
	This function is only used if DCACHE_MANAGE_TRANSIT is set on the
	dentry being transited from.
	dentry being transited from.


Example :
  d_real: overlay/union type filesystems implement this method to return one of
	the underlying dentries hidden by the overlay.  It is used in three
	different modes:


static char *pipefs_dname(struct dentry *dent, char *buffer, int buflen)
	Called from open it may need to copy-up the file depending on the
{
	supplied open flags.  This mode is selected with a non-zero flags
	return dynamic_dname(dentry, buffer, buflen, "pipe:[%lu]",
	argument.  In this mode the d_real method can return an error.
				dentry->d_inode->i_ino);

}
	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.  This will always succeed.

	With NULL inode and zero flags the topmost real underlying dentry is
	returned.  This will always succeed.

	This method is never called with both non-NULL inode and non-zero flags.


Each dentry has a pointer to its parent dentry, as well as a hash list
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
of child dentries. Child dentries are basically like files in a
+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,
Loading