]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - fs/aufs/vfsub.h
ext4: preserve the needs_recovery flag when the journal is aborted
[mirror_ubuntu-zesty-kernel.git] / fs / aufs / vfsub.h
CommitLineData
e14748e8
SF
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!! */
35extern void __mnt_drop_write(struct vfsmount *);
36extern 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. */
43enum {
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
59static inline void vfsub_drop_nlink(struct inode *inode)
60{
61 AuDebugOn(!inode->i_nlink);
62 drop_nlink(inode);
63}
64
65static 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
72static 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
81int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb);
82#else
83AuStubInt0(vfsub_test_mntns, struct vfsmount *mnt, struct super_block *h_sb);
84#endif
85
86int vfsub_sync_filesystem(struct super_block *h_sb, int wait);
87
88/* ---------------------------------------------------------------------- */
89
90int vfsub_update_h_iattr(struct path *h_path, int *did);
91struct file *vfsub_dentry_open(struct path *path, int flags);
92struct file *vfsub_filp_open(const char *path, int oflags, int mode);
93struct vfsub_aopen_args {
94 struct file *file;
95 unsigned int open_flag;
96 umode_t create_mode;
97 int *opened;
98};
99struct au_branch;
100int vfsub_atomic_open(struct inode *dir, struct dentry *dentry,
101 struct vfsub_aopen_args *args, struct au_branch *br);
102int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
103
104struct dentry *vfsub_lookup_one_len_unlocked(const char *name,
105 struct dentry *parent, int len);
106struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
107 int len);
108
109struct vfsub_lkup_one_args {
110 struct dentry **errp;
111 struct qstr *name;
112 struct dentry *parent;
113};
114
115static 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
121void vfsub_call_lkup_one(void *args);
122
123/* ---------------------------------------------------------------------- */
124
125static 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
135static 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 */
143static 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
153struct au_hinode;
154struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
155 struct dentry *d2, struct au_hinode *hdir2);
156void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
157 struct dentry *d2, struct au_hinode *hdir2);
158
159int vfsub_create(struct inode *dir, struct path *path, int mode,
160 bool want_excl);
161int vfsub_symlink(struct inode *dir, struct path *path,
162 const char *symname);
163int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
164int vfsub_link(struct dentry *src_dentry, struct inode *dir,
165 struct path *path, struct inode **delegated_inode);
166int 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);
169int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
170int vfsub_rmdir(struct inode *dir, struct path *path);
171
172/* ---------------------------------------------------------------------- */
173
174ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
175 loff_t *ppos);
176ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
177 loff_t *ppos);
178ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
179 loff_t *ppos);
180ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
181 loff_t *ppos);
182int vfsub_flush(struct file *file, fl_owner_t id);
183int vfsub_iterate_dir(struct file *file, struct dir_context *ctx);
184
185static inline loff_t vfsub_f_size_read(struct file *file)
186{
187 return i_size_read(file_inode(file));
188}
189
190static 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
201static 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 */
208static 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 */
216static 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
228static 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
236static 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
246AuStubInt0(vfsub_acl_chmod, struct inode *h_inode, umode_t h_mode);
247#endif
248
249long vfsub_splice_to(struct file *in, loff_t *ppos,
250 struct pipe_inode_info *pipe, size_t len,
251 unsigned int flags);
252long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
253 loff_t *ppos, size_t len, unsigned int flags);
254
255static 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
265int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
266 struct file *h_file);
267int vfsub_fsync(struct file *file, struct path *path, int datasync);
268
269/* ---------------------------------------------------------------------- */
270
271static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
272{
273 loff_t err;
274
275 lockdep_off();
276 err = vfs_llseek(file, offset, origin);
277 lockdep_on();
278 return err;
279}
280
281/* ---------------------------------------------------------------------- */
282
283int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
284int vfsub_sio_rmdir(struct inode *dir, struct path *path);
285int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
286 struct inode **delegated_inode);
287int vfsub_notify_change(struct path *path, struct iattr *ia,
288 struct inode **delegated_inode);
289int vfsub_unlink(struct inode *dir, struct path *path,
290 struct inode **delegated_inode, int force);
291
292/* ---------------------------------------------------------------------- */
293
294static inline int vfsub_setxattr(struct dentry *dentry, const char *name,
295 const void *value, size_t size, int flags)
296{
297 int err;
298
299 lockdep_off();
300 err = vfs_setxattr(dentry, name, value, size, flags);
301 lockdep_on();
302
303 return err;
304}
305
306static inline int vfsub_removexattr(struct dentry *dentry, const char *name)
307{
308 int err;
309
310 lockdep_off();
311 err = vfs_removexattr(dentry, name);
312 lockdep_on();
313
314 return err;
315}
316
317#endif /* __KERNEL__ */
318#endif /* __AUFS_VFSUB_H__ */