]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - fs/aufs/vfsub.h
UBUNTU: SAUCE: aufs: for v4.5, use vfs_clone_file_range() in copy-up
[mirror_ubuntu-zesty-kernel.git] / fs / aufs / vfsub.h
1 /*
2 * Copyright (C) 2005-2016 Junjiro R. Okajima
3 *
4 * This program, aufs is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 /*
19 * sub-routines for VFS
20 */
21
22 #ifndef __AUFS_VFSUB_H__
23 #define __AUFS_VFSUB_H__
24
25 #ifdef __KERNEL__
26
27 #include <linux/fs.h>
28 #include <linux/mount.h>
29 #include <linux/posix_acl.h>
30 #include <linux/xattr.h>
31 #include "debug.h"
32
33 /* copied from linux/fs/internal.h */
34 /* todo: BAD approach!! */
35 extern void __mnt_drop_write(struct vfsmount *);
36 extern int open_check_o_direct(struct file *f);
37
38 /* ---------------------------------------------------------------------- */
39
40 /* lock subclass for lower inode */
41 /* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
42 /* reduce? gave up. */
43 enum {
44 AuLsc_I_Begin = I_MUTEX_PARENT2, /* 5 */
45 AuLsc_I_PARENT, /* lower inode, parent first */
46 AuLsc_I_PARENT2, /* copyup dirs */
47 AuLsc_I_PARENT3, /* copyup wh */
48 AuLsc_I_CHILD,
49 AuLsc_I_CHILD2,
50 AuLsc_I_End
51 };
52
53 /* to debug easier, do not make them inlined functions */
54 #define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx))
55 #define IMustLock(i) AuDebugOn(!inode_is_locked(i))
56
57 /* ---------------------------------------------------------------------- */
58
59 static inline void vfsub_drop_nlink(struct inode *inode)
60 {
61 AuDebugOn(!inode->i_nlink);
62 drop_nlink(inode);
63 }
64
65 static inline void vfsub_dead_dir(struct inode *inode)
66 {
67 AuDebugOn(!S_ISDIR(inode->i_mode));
68 inode->i_flags |= S_DEAD;
69 clear_nlink(inode);
70 }
71
72 static inline int vfsub_native_ro(struct inode *inode)
73 {
74 return (inode->i_sb->s_flags & MS_RDONLY)
75 || IS_RDONLY(inode)
76 /* || IS_APPEND(inode) */
77 || IS_IMMUTABLE(inode);
78 }
79
80 #ifdef CONFIG_AUFS_BR_FUSE
81 int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb);
82 #else
83 AuStubInt0(vfsub_test_mntns, struct vfsmount *mnt, struct super_block *h_sb);
84 #endif
85
86 int vfsub_sync_filesystem(struct super_block *h_sb, int wait);
87
88 /* ---------------------------------------------------------------------- */
89
90 int vfsub_update_h_iattr(struct path *h_path, int *did);
91 struct file *vfsub_dentry_open(struct path *path, int flags);
92 struct file *vfsub_filp_open(const char *path, int oflags, int mode);
93 struct vfsub_aopen_args {
94 struct file *file;
95 unsigned int open_flag;
96 umode_t create_mode;
97 int *opened;
98 };
99 struct au_branch;
100 int vfsub_atomic_open(struct inode *dir, struct dentry *dentry,
101 struct vfsub_aopen_args *args, struct au_branch *br);
102 int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
103
104 struct dentry *vfsub_lookup_one_len_unlocked(const char *name,
105 struct dentry *parent, int len);
106 struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
107 int len);
108
109 struct vfsub_lkup_one_args {
110 struct dentry **errp;
111 struct qstr *name;
112 struct dentry *parent;
113 };
114
115 static inline struct dentry *vfsub_lkup_one(struct qstr *name,
116 struct dentry *parent)
117 {
118 return vfsub_lookup_one_len(name->name, parent, name->len);
119 }
120
121 void vfsub_call_lkup_one(void *args);
122
123 /* ---------------------------------------------------------------------- */
124
125 static inline int vfsub_mnt_want_write(struct vfsmount *mnt)
126 {
127 int err;
128
129 lockdep_off();
130 err = mnt_want_write(mnt);
131 lockdep_on();
132 return err;
133 }
134
135 static inline void vfsub_mnt_drop_write(struct vfsmount *mnt)
136 {
137 lockdep_off();
138 mnt_drop_write(mnt);
139 lockdep_on();
140 }
141
142 #if 0 /* reserved */
143 static inline void vfsub_mnt_drop_write_file(struct file *file)
144 {
145 lockdep_off();
146 mnt_drop_write_file(file);
147 lockdep_on();
148 }
149 #endif
150
151 /* ---------------------------------------------------------------------- */
152
153 struct au_hinode;
154 struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
155 struct dentry *d2, struct au_hinode *hdir2);
156 void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
157 struct dentry *d2, struct au_hinode *hdir2);
158
159 int vfsub_create(struct inode *dir, struct path *path, int mode,
160 bool want_excl);
161 int vfsub_symlink(struct inode *dir, struct path *path,
162 const char *symname);
163 int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
164 int vfsub_link(struct dentry *src_dentry, struct inode *dir,
165 struct path *path, struct inode **delegated_inode);
166 int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
167 struct inode *hdir, struct path *path,
168 struct inode **delegated_inode, unsigned int flags);
169 int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
170 int vfsub_rmdir(struct inode *dir, struct path *path);
171
172 /* ---------------------------------------------------------------------- */
173
174 ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
175 loff_t *ppos);
176 ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
177 loff_t *ppos);
178 ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
179 loff_t *ppos);
180 ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
181 loff_t *ppos);
182 int vfsub_flush(struct file *file, fl_owner_t id);
183 int vfsub_iterate_dir(struct file *file, struct dir_context *ctx);
184
185 static inline loff_t vfsub_f_size_read(struct file *file)
186 {
187 return i_size_read(file_inode(file));
188 }
189
190 static inline unsigned int vfsub_file_flags(struct file *file)
191 {
192 unsigned int flags;
193
194 spin_lock(&file->f_lock);
195 flags = file->f_flags;
196 spin_unlock(&file->f_lock);
197
198 return flags;
199 }
200
201 static inline int vfsub_file_execed(struct file *file)
202 {
203 /* todo: direct access f_flags */
204 return !!(vfsub_file_flags(file) & __FMODE_EXEC);
205 }
206
207 #if 0 /* reserved */
208 static inline void vfsub_file_accessed(struct file *h_file)
209 {
210 file_accessed(h_file);
211 vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
212 }
213 #endif
214
215 #if 0 /* reserved */
216 static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
217 struct dentry *h_dentry)
218 {
219 struct path h_path = {
220 .dentry = h_dentry,
221 .mnt = h_mnt
222 };
223 touch_atime(&h_path);
224 vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
225 }
226 #endif
227
228 static inline int vfsub_update_time(struct inode *h_inode, struct timespec *ts,
229 int flags)
230 {
231 return update_time(h_inode, ts, flags);
232 /* no vfsub_update_h_iattr() since we don't have struct path */
233 }
234
235 #ifdef CONFIG_FS_POSIX_ACL
236 static inline int vfsub_acl_chmod(struct inode *h_inode, umode_t h_mode)
237 {
238 int err;
239
240 err = posix_acl_chmod(h_inode, h_mode);
241 if (err == -EOPNOTSUPP)
242 err = 0;
243 return err;
244 }
245 #else
246 AuStubInt0(vfsub_acl_chmod, struct inode *h_inode, umode_t h_mode);
247 #endif
248
249 long vfsub_splice_to(struct file *in, loff_t *ppos,
250 struct pipe_inode_info *pipe, size_t len,
251 unsigned int flags);
252 long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
253 loff_t *ppos, size_t len, unsigned int flags);
254
255 static inline long vfsub_truncate(struct path *path, loff_t length)
256 {
257 long err;
258
259 lockdep_off();
260 err = vfs_truncate(path, length);
261 lockdep_on();
262 return err;
263 }
264
265 int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
266 struct file *h_file);
267 int vfsub_fsync(struct file *file, struct path *path, int datasync);
268
269 /*
270 * re-use branch fs's ioctl(FICLONE) while aufs itself doesn't support such
271 * ioctl.
272 */
273 static inline int vfsub_clone_file_range(struct file *src, struct file *dst,
274 u64 len)
275 {
276 int err;
277
278 lockdep_off();
279 err = vfs_clone_file_range(src, 0, dst, 0, len);
280 lockdep_on();
281
282 return err;
283 }
284
285 /* ---------------------------------------------------------------------- */
286
287 static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
288 {
289 loff_t err;
290
291 lockdep_off();
292 err = vfs_llseek(file, offset, origin);
293 lockdep_on();
294 return err;
295 }
296
297 /* ---------------------------------------------------------------------- */
298
299 int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
300 int vfsub_sio_rmdir(struct inode *dir, struct path *path);
301 int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
302 struct inode **delegated_inode);
303 int vfsub_notify_change(struct path *path, struct iattr *ia,
304 struct inode **delegated_inode);
305 int vfsub_unlink(struct inode *dir, struct path *path,
306 struct inode **delegated_inode, int force);
307
308 /* ---------------------------------------------------------------------- */
309
310 static inline int vfsub_setxattr(struct dentry *dentry, const char *name,
311 const void *value, size_t size, int flags)
312 {
313 int err;
314
315 lockdep_off();
316 err = vfs_setxattr(dentry, name, value, size, flags);
317 lockdep_on();
318
319 return err;
320 }
321
322 static inline int vfsub_removexattr(struct dentry *dentry, const char *name)
323 {
324 int err;
325
326 lockdep_off();
327 err = vfs_removexattr(dentry, name);
328 lockdep_on();
329
330 return err;
331 }
332
333 #endif /* __KERNEL__ */
334 #endif /* __AUFS_VFSUB_H__ */