1 From b0c34c08a36aafbbb2240d384935343feefb68f3 Mon Sep 17 00:00:00 2001
2 From: Miklos Szeredi <mszeredi@suse.cz>
3 Date: Thu, 30 Aug 2012 16:13:49 +0200
4 Subject: [PATCH 01/13] vfs: add i_op->dentry_open()
5 Patch-mainline: not yet
7 Add a new inode operation i_op->dentry_open(). This is for stacked filesystems
8 that want to return a struct file from a different filesystem.
10 Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
12 Documentation/filesystems/Locking | 2 ++
13 Documentation/filesystems/vfs.txt | 7 +++++++
14 fs/namei.c | 9 ++++++---
15 fs/open.c | 23 +++++++++++++++++++++--
16 include/linux/fs.h | 2 ++
17 5 files changed, 38 insertions(+), 5 deletions(-)
19 Index: linux-3.6-rc7-master/Documentation/filesystems/Locking
20 ===================================================================
21 --- linux-3.6-rc7-master.orig/Documentation/filesystems/Locking 2012-09-28 13:36:40.000000000 +0200
22 +++ linux-3.6-rc7-master/Documentation/filesystems/Locking 2012-09-28 13:36:47.000000000 +0200
23 @@ -64,6 +64,7 @@ d_manage: no no yes (ref-walk) maybe
24 int (*atomic_open)(struct inode *, struct dentry *,
25 struct file *, unsigned open_flag,
26 umode_t create_mode, int *opened);
27 + int (*dentry_open)(struct dentry *, struct file *, const struct cred *);
31 @@ -92,6 +93,7 @@ removexattr: yes
37 Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on
39 Index: linux-3.6-rc7-master/Documentation/filesystems/vfs.txt
40 ===================================================================
41 --- linux-3.6-rc7-master.orig/Documentation/filesystems/vfs.txt 2012-09-28 13:36:40.000000000 +0200
42 +++ linux-3.6-rc7-master/Documentation/filesystems/vfs.txt 2012-09-28 13:36:47.000000000 +0200
43 @@ -363,6 +363,7 @@ struct inode_operations {
44 int (*atomic_open)(struct inode *, struct dentry *,
45 struct file *, unsigned open_flag,
46 umode_t create_mode, int *opened);
47 + int (*dentry_open)(struct dentry *, struct file *, const struct cred *);
50 Again, all methods are called without any locks being held, unless
51 @@ -692,6 +693,12 @@ struct address_space_operations {
52 but instead uses bmap to find out where the blocks in the file
53 are and uses those addresses directly.
55 + dentry_open: this is an alternative to f_op->open(), the difference is that
56 + this method may open a file not necessarily originating from the same
57 + filesystem as the one i_op->open() was called on. It may be
58 + useful for stacking filesystems which want to allow native I/O directly
59 + on underlying files.
62 invalidatepage: If a page has PagePrivate set, then invalidatepage
63 will be called when part or all of the page is to be removed
64 Index: linux-3.6-rc7-master/fs/namei.c
65 ===================================================================
66 --- linux-3.6-rc7-master.orig/fs/namei.c 2012-09-28 13:36:40.000000000 +0200
67 +++ linux-3.6-rc7-master/fs/namei.c 2012-09-28 13:36:47.000000000 +0200
68 @@ -2870,9 +2870,12 @@ static int do_last(struct nameidata *nd,
69 error = may_open(&nd->path, acc_mode, open_flag);
72 - file->f_path.mnt = nd->path.mnt;
73 - error = finish_open(file, nd->path.dentry, NULL, opened);
76 + BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */
77 + error = vfs_open(&nd->path, file, current_cred());
79 + *opened |= FILE_OPENED;
81 if (error == -EOPENSTALE)
84 Index: linux-3.6-rc7-master/fs/open.c
85 ===================================================================
86 --- linux-3.6-rc7-master.orig/fs/open.c 2012-09-28 13:36:40.000000000 +0200
87 +++ linux-3.6-rc7-master/fs/open.c 2012-09-28 13:36:47.000000000 +0200
88 @@ -787,8 +787,7 @@ struct file *dentry_open(const struct pa
93 - error = do_dentry_open(f, NULL, cred);
94 + error = vfs_open(path, f, cred);
96 /* from now on we need fput() to dispose of f */
97 error = open_check_o_direct(f);
98 @@ -803,6 +802,26 @@ struct file *dentry_open(const struct pa
100 EXPORT_SYMBOL(dentry_open);
103 + * vfs_open - open the file at the given path
104 + * @path: path to open
105 + * @filp: newly allocated file with f_flag initialized
106 + * @cred: credentials to use
108 +int vfs_open(const struct path *path, struct file *filp,
109 + const struct cred *cred)
111 + struct inode *inode = path->dentry->d_inode;
113 + if (inode->i_op->dentry_open)
114 + return inode->i_op->dentry_open(path->dentry, filp, cred);
116 + filp->f_path = *path;
117 + return do_dentry_open(filp, NULL, cred);
120 +EXPORT_SYMBOL(vfs_open);
122 static inline int build_open_flags(int flags, umode_t mode, struct open_flags *op)
124 int lookup_flags = 0;
125 Index: linux-3.6-rc7-master/include/linux/fs.h
126 ===================================================================
127 --- linux-3.6-rc7-master.orig/include/linux/fs.h 2012-09-28 13:36:40.000000000 +0200
128 +++ linux-3.6-rc7-master/include/linux/fs.h 2012-09-28 13:36:47.000000000 +0200
129 @@ -1573,6 +1573,7 @@ struct inode_operations {
130 int (*atomic_open)(struct inode *, struct dentry *,
131 struct file *, unsigned open_flag,
132 umode_t create_mode, int *opened);
133 + int (*dentry_open)(struct dentry *, struct file *, const struct cred *);
134 } ____cacheline_aligned;
136 ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
137 @@ -2211,6 +2212,7 @@ extern long do_sys_open(int dfd, const c
138 extern struct file *filp_open(const char *, int, umode_t);
139 extern struct file *file_open_root(struct dentry *, struct vfsmount *,
141 +extern int vfs_open(const struct path *, struct file *, const struct cred *);
142 extern struct file * dentry_open(const struct path *, int, const struct cred *);
143 extern int filp_close(struct file *, fl_owner_t id);