Skip to content

Commit 4aa7c63

Browse files
author
Miklos Szeredi
committed
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: Miklos Szeredi <[email protected]>
1 parent f114040 commit 4aa7c63

File tree

5 files changed

+40
-5
lines changed

5 files changed

+40
-5
lines changed

Documentation/filesystems/Locking

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ prototypes:
6767
struct file *, unsigned open_flag,
6868
umode_t create_mode, int *opened);
6969
int (*tmpfile) (struct inode *, struct dentry *, umode_t);
70+
int (*dentry_open)(struct dentry *, struct file *, const struct cred *);
7071

7172
locking rules:
7273
all may block
@@ -96,6 +97,7 @@ fiemap: no
9697
update_time: no
9798
atomic_open: yes
9899
tmpfile: no
100+
dentry_open: no
99101

100102
Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on
101103
victim.

Documentation/filesystems/vfs.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,7 @@ struct inode_operations {
364364
int (*atomic_open)(struct inode *, struct dentry *, struct file *,
365365
unsigned open_flag, umode_t create_mode, int *opened);
366366
int (*tmpfile) (struct inode *, struct dentry *, umode_t);
367+
int (*dentry_open)(struct dentry *, struct file *, const struct cred *);
367368
};
368369

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

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

700707
invalidatepage: If a page has PagePrivate set, then invalidatepage
701708
will be called when part or all of the page is to be removed

fs/namei.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3064,9 +3064,12 @@ static int do_last(struct nameidata *nd, struct path *path,
30643064
error = may_open(&nd->path, acc_mode, open_flag);
30653065
if (error)
30663066
goto out;
3067-
file->f_path.mnt = nd->path.mnt;
3068-
error = finish_open(file, nd->path.dentry, NULL, opened);
3069-
if (error) {
3067+
3068+
BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */
3069+
error = vfs_open(&nd->path, file, current_cred());
3070+
if (!error) {
3071+
*opened |= FILE_OPENED;
3072+
} else {
30703073
if (error == -EOPENSTALE)
30713074
goto stale_open;
30723075
goto out;

fs/open.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -823,8 +823,7 @@ struct file *dentry_open(const struct path *path, int flags,
823823
f = get_empty_filp();
824824
if (!IS_ERR(f)) {
825825
f->f_flags = flags;
826-
f->f_path = *path;
827-
error = do_dentry_open(f, NULL, cred);
826+
error = vfs_open(path, f, cred);
828827
if (!error) {
829828
/* from now on we need fput() to dispose of f */
830829
error = open_check_o_direct(f);
@@ -841,6 +840,26 @@ struct file *dentry_open(const struct path *path, int flags,
841840
}
842841
EXPORT_SYMBOL(dentry_open);
843842

843+
/**
844+
* vfs_open - open the file at the given path
845+
* @path: path to open
846+
* @filp: newly allocated file with f_flag initialized
847+
* @cred: credentials to use
848+
*/
849+
int vfs_open(const struct path *path, struct file *filp,
850+
const struct cred *cred)
851+
{
852+
struct inode *inode = path->dentry->d_inode;
853+
854+
if (inode->i_op->dentry_open)
855+
return inode->i_op->dentry_open(path->dentry, filp, cred);
856+
else {
857+
filp->f_path = *path;
858+
return do_dentry_open(filp, NULL, cred);
859+
}
860+
}
861+
EXPORT_SYMBOL(vfs_open);
862+
844863
static inline int build_open_flags(int flags, umode_t mode, struct open_flags *op)
845864
{
846865
int lookup_flags = 0;

include/linux/fs.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,6 +1528,9 @@ struct inode_operations {
15281528
umode_t create_mode, int *opened);
15291529
int (*tmpfile) (struct inode *, struct dentry *, umode_t);
15301530
int (*set_acl)(struct inode *, struct posix_acl *, int);
1531+
1532+
/* WARNING: probably going away soon, do not use! */
1533+
int (*dentry_open)(struct dentry *, struct file *, const struct cred *);
15311534
} ____cacheline_aligned;
15321535

15331536
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);
20402043
extern struct file *filp_open(const char *, int, umode_t);
20412044
extern struct file *file_open_root(struct dentry *, struct vfsmount *,
20422045
const char *, int);
2046+
extern int vfs_open(const struct path *, struct file *, const struct cred *);
20432047
extern struct file * dentry_open(const struct path *, int, const struct cred *);
20442048
extern int filp_close(struct file *, fl_owner_t id);
20452049

0 commit comments

Comments
 (0)