]>
Commit | Line | Data |
---|---|---|
68184a5a JR |
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 | |
6 | ||
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. | |
9 | ||
10 | Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> | |
11 | --- | |
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(-) | |
18 | ||
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 *); | |
28 | ||
29 | locking rules: | |
30 | all may block | |
31 | @@ -92,6 +93,7 @@ removexattr: yes | |
32 | fiemap: no | |
33 | update_time: no | |
34 | atomic_open: yes | |
35 | +dentry_open: no | |
36 | ||
37 | Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on | |
38 | victim. | |
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 *); | |
48 | }; | |
49 | ||
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. | |
54 | ||
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. | |
60 | + | |
61 | ||
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); | |
70 | if (error) | |
71 | goto out; | |
72 | - file->f_path.mnt = nd->path.mnt; | |
73 | - error = finish_open(file, nd->path.dentry, NULL, opened); | |
74 | - if (error) { | |
75 | + | |
76 | + BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */ | |
77 | + error = vfs_open(&nd->path, file, current_cred()); | |
78 | + if (!error) { | |
79 | + *opened |= FILE_OPENED; | |
80 | + } else { | |
81 | if (error == -EOPENSTALE) | |
82 | goto stale_open; | |
83 | goto out; | |
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 | |
514e5dae AM |
89 | f = get_empty_filp(); |
90 | if (!IS_ERR(f)) { | |
91 | f->f_flags = flags; | |
92 | - f->f_path = *path; | |
93 | - error = do_dentry_open(f, NULL, cred); | |
94 | + error = vfs_open(path, f, cred); | |
95 | if (!error) { | |
96 | /* from now on we need fput() to dispose of f */ | |
97 | error = open_check_o_direct(f); | |
68184a5a JR |
98 | @@ -803,6 +802,26 @@ struct file *dentry_open(const struct pa |
99 | } | |
100 | EXPORT_SYMBOL(dentry_open); | |
101 | ||
102 | +/** | |
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 | |
107 | + */ | |
108 | +int vfs_open(const struct path *path, struct file *filp, | |
109 | + const struct cred *cred) | |
110 | +{ | |
111 | + struct inode *inode = path->dentry->d_inode; | |
112 | + | |
113 | + if (inode->i_op->dentry_open) | |
114 | + return inode->i_op->dentry_open(path->dentry, filp, cred); | |
115 | + else { | |
116 | + filp->f_path = *path; | |
117 | + return do_dentry_open(filp, NULL, cred); | |
118 | + } | |
119 | +} | |
120 | +EXPORT_SYMBOL(vfs_open); | |
121 | + | |
122 | static inline int build_open_flags(int flags, umode_t mode, struct open_flags *op) | |
123 | { | |
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 | |
514e5dae | 129 | @@ -1573,6 +1573,7 @@ struct inode_operations { |
68184a5a JR |
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; | |
135 | ||
514e5dae | 136 | ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, |
68184a5a JR |
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 *, | |
140 | const char *, int); | |
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); | |
144 |