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

Commit 4aa7c634 authored by Miklos Szeredi's avatar Miklos Szeredi
Browse files

vfs: add i_op->dentry_open()



Add a new inode operation i_op->dentry_open().  This is for stacked filesystems
that want to return a struct file from a different filesystem.

Signed-off-by: default avatarMiklos Szeredi <mszeredi@suse.cz>
parent f114040e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ prototypes:
				struct file *, unsigned open_flag,
				umode_t create_mode, int *opened);
	int (*tmpfile) (struct inode *, struct dentry *, umode_t);
	int (*dentry_open)(struct dentry *, struct file *, const struct cred *);

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

	Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on
victim.
+7 −0
Original line number Diff line number Diff line
@@ -364,6 +364,7 @@ struct inode_operations {
	int (*atomic_open)(struct inode *, struct dentry *, struct file *,
			unsigned open_flag, umode_t create_mode, int *opened);
	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
@@ -696,6 +697,12 @@ struct address_space_operations {
  	but instead uses bmap to find out where the blocks in the file
  	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
        will be called when part or all of the page is to be removed
+6 −3
Original line number Diff line number Diff line
@@ -3064,9 +3064,12 @@ static int do_last(struct nameidata *nd, struct path *path,
	error = may_open(&nd->path, acc_mode, open_flag);
	if (error)
		goto out;
	file->f_path.mnt = nd->path.mnt;
	error = finish_open(file, nd->path.dentry, NULL, opened);
	if (error) {

	BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */
	error = vfs_open(&nd->path, file, current_cred());
	if (!error) {
		*opened |= FILE_OPENED;
	} else {
		if (error == -EOPENSTALE)
			goto stale_open;
		goto out;
+21 −2
Original line number Diff line number Diff line
@@ -823,8 +823,7 @@ struct file *dentry_open(const struct path *path, int flags,
	f = get_empty_filp();
	if (!IS_ERR(f)) {
		f->f_flags = flags;
		f->f_path = *path;
		error = do_dentry_open(f, NULL, cred);
		error = vfs_open(path, f, cred);
		if (!error) {
			/* from now on we need fput() to dispose of f */
			error = open_check_o_direct(f);
@@ -841,6 +840,26 @@ struct file *dentry_open(const struct path *path, int flags,
}
EXPORT_SYMBOL(dentry_open);

/**
 * vfs_open - open the file at the given path
 * @path: path to open
 * @filp: newly allocated file with f_flag initialized
 * @cred: credentials to use
 */
int vfs_open(const struct path *path, struct file *filp,
	     const struct cred *cred)
{
	struct inode *inode = path->dentry->d_inode;

	if (inode->i_op->dentry_open)
		return inode->i_op->dentry_open(path->dentry, filp, cred);
	else {
		filp->f_path = *path;
		return do_dentry_open(filp, NULL, cred);
	}
}
EXPORT_SYMBOL(vfs_open);

static inline int build_open_flags(int flags, umode_t mode, struct open_flags *op)
{
	int lookup_flags = 0;
+4 −0
Original line number Diff line number Diff line
@@ -1528,6 +1528,9 @@ struct inode_operations {
			   umode_t create_mode, int *opened);
	int (*tmpfile) (struct inode *, struct dentry *, umode_t);
	int (*set_acl)(struct inode *, struct posix_acl *, int);

	/* WARNING: probably going away soon, do not use! */
	int (*dentry_open)(struct dentry *, struct file *, const struct cred *);
} ____cacheline_aligned;

ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
@@ -2040,6 +2043,7 @@ extern struct file *file_open_name(struct filename *, int, umode_t);
extern struct file *filp_open(const char *, int, umode_t);
extern struct file *file_open_root(struct dentry *, struct vfsmount *,
				   const char *, int);
extern int vfs_open(const struct path *, struct file *, const struct cred *);
extern struct file * dentry_open(const struct path *, int, const struct cred *);
extern int filp_close(struct file *, fl_owner_t id);