]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - fs/aufs/vfsub.h
x86/mm: Use WRITE_ONCE() when setting PTEs
[mirror_ubuntu-bionic-kernel.git] / fs / aufs / vfsub.h
CommitLineData
c088e31d
SF
1/*
2 * Copyright (C) 2005-2017 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/* why VFS doesn't define it? */
58static inline
59void vfsub_inode_lock_shared_nested(struct inode *inode, unsigned int sc)
60{
61 down_read_nested(&inode->i_rwsem, sc);
62}
63
64/* ---------------------------------------------------------------------- */
65
66static inline void vfsub_drop_nlink(struct inode *inode)
67{
68 AuDebugOn(!inode->i_nlink);
69 drop_nlink(inode);
70}
71
72static inline void vfsub_dead_dir(struct inode *inode)
73{
74 AuDebugOn(!S_ISDIR(inode->i_mode));
75 inode->i_flags |= S_DEAD;
76 clear_nlink(inode);
77}
78
79static inline int vfsub_native_ro(struct inode *inode)
80{
81 return sb_rdonly(inode->i_sb)
82 || IS_RDONLY(inode)
83 /* || IS_APPEND(inode) */
84 || IS_IMMUTABLE(inode);
85}
86
87#ifdef CONFIG_AUFS_BR_FUSE
88int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb);
89#else
90AuStubInt0(vfsub_test_mntns, struct vfsmount *mnt, struct super_block *h_sb);
91#endif
92
93int vfsub_sync_filesystem(struct super_block *h_sb, int wait);
94
95/* ---------------------------------------------------------------------- */
96
97int vfsub_update_h_iattr(struct path *h_path, int *did);
98struct file *vfsub_dentry_open(struct path *path, int flags);
99struct file *vfsub_filp_open(const char *path, int oflags, int mode);
100struct vfsub_aopen_args {
101 struct file *file;
102 unsigned int open_flag;
103 umode_t create_mode;
104 int *opened;
105};
106struct au_branch;
107int vfsub_atomic_open(struct inode *dir, struct dentry *dentry,
108 struct vfsub_aopen_args *args, struct au_branch *br);
109int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
110
111struct dentry *vfsub_lookup_one_len_unlocked(const char *name,
112 struct dentry *parent, int len);
113struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
114 int len);
115
116struct vfsub_lkup_one_args {
117 struct dentry **errp;
118 struct qstr *name;
119 struct dentry *parent;
120};
121
122static inline struct dentry *vfsub_lkup_one(struct qstr *name,
123 struct dentry *parent)
124{
125 return vfsub_lookup_one_len(name->name, parent, name->len);
126}
127
128void vfsub_call_lkup_one(void *args);
129
130/* ---------------------------------------------------------------------- */
131
132static inline int vfsub_mnt_want_write(struct vfsmount *mnt)
133{
134 int err;
135
136 lockdep_off();
137 err = mnt_want_write(mnt);
138 lockdep_on();
139 return err;
140}
141
142static inline void vfsub_mnt_drop_write(struct vfsmount *mnt)
143{
144 lockdep_off();
145 mnt_drop_write(mnt);
146 lockdep_on();
147}
148
149#if 0 /* reserved */
150static inline void vfsub_mnt_drop_write_file(struct file *file)
151{
152 lockdep_off();
153 mnt_drop_write_file(file);
154 lockdep_on();
155}
156#endif
157
158/* ---------------------------------------------------------------------- */
159
160struct au_hinode;
161struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
162 struct dentry *d2, struct au_hinode *hdir2);
163void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
164 struct dentry *d2, struct au_hinode *hdir2);
165
166int vfsub_create(struct inode *dir, struct path *path, int mode,
167 bool want_excl);
168int vfsub_symlink(struct inode *dir, struct path *path,
169 const char *symname);
170int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
171int vfsub_link(struct dentry *src_dentry, struct inode *dir,
172 struct path *path, struct inode **delegated_inode);
173int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
174 struct inode *hdir, struct path *path,
175 struct inode **delegated_inode, unsigned int flags);
176int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
177int vfsub_rmdir(struct inode *dir, struct path *path);
178
179/* ---------------------------------------------------------------------- */
180
181ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
182 loff_t *ppos);
183ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
184 loff_t *ppos);
185ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
186 loff_t *ppos);
187ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
188 loff_t *ppos);
189int vfsub_flush(struct file *file, fl_owner_t id);
190int vfsub_iterate_dir(struct file *file, struct dir_context *ctx);
191
192static inline loff_t vfsub_f_size_read(struct file *file)
193{
194 return i_size_read(file_inode(file));
195}
196
197static inline unsigned int vfsub_file_flags(struct file *file)
198{
199 unsigned int flags;
200
201 spin_lock(&file->f_lock);
202 flags = file->f_flags;
203 spin_unlock(&file->f_lock);
204
205 return flags;
206}
207
208static inline int vfsub_file_execed(struct file *file)
209{
210 /* todo: direct access f_flags */
211 return !!(vfsub_file_flags(file) & __FMODE_EXEC);
212}
213
214#if 0 /* reserved */
215static inline void vfsub_file_accessed(struct file *h_file)
216{
217 file_accessed(h_file);
218 vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
219}
220#endif
221
222#if 0 /* reserved */
223static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
224 struct dentry *h_dentry)
225{
226 struct path h_path = {
227 .dentry = h_dentry,
228 .mnt = h_mnt
229 };
230 touch_atime(&h_path);
231 vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
232}
233#endif
234
235static inline int vfsub_update_time(struct inode *h_inode, struct timespec *ts,
236 int flags)
237{
238 return update_time(h_inode, ts, flags);
239 /* no vfsub_update_h_iattr() since we don't have struct path */
240}
241
242#ifdef CONFIG_FS_POSIX_ACL
243static inline int vfsub_acl_chmod(struct inode *h_inode, umode_t h_mode)
244{
245 int err;
246
247 err = posix_acl_chmod(h_inode, h_mode);
248 if (err == -EOPNOTSUPP)
249 err = 0;
250 return err;
251}
252#else
253AuStubInt0(vfsub_acl_chmod, struct inode *h_inode, umode_t h_mode);
254#endif
255
256long vfsub_splice_to(struct file *in, loff_t *ppos,
257 struct pipe_inode_info *pipe, size_t len,
258 unsigned int flags);
259long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
260 loff_t *ppos, size_t len, unsigned int flags);
261
262static inline long vfsub_truncate(struct path *path, loff_t length)
263{
264 long err;
265
266 lockdep_off();
267 err = vfs_truncate(path, length);
268 lockdep_on();
269 return err;
270}
271
272int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
273 struct file *h_file);
274int vfsub_fsync(struct file *file, struct path *path, int datasync);
275
276/*
277 * re-use branch fs's ioctl(FICLONE) while aufs itself doesn't support such
278 * ioctl.
279 */
280static inline int vfsub_clone_file_range(struct file *src, struct file *dst,
281 u64 len)
282{
283 int err;
284
285 lockdep_off();
286 err = vfs_clone_file_range(src, 0, dst, 0, len);
287 lockdep_on();
288
289 return err;
290}
291
292/* copy_file_range(2) is a systemcall */
293static inline ssize_t vfsub_copy_file_range(struct file *src, loff_t src_pos,
294 struct file *dst, loff_t dst_pos,
295 size_t len, unsigned int flags)
296{
297 ssize_t ssz;
298
299 lockdep_off();
300 ssz = vfs_copy_file_range(src, src_pos, dst, dst_pos, len, flags);
301 lockdep_on();
302
303 return ssz;
304}
305
306/* ---------------------------------------------------------------------- */
307
308static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
309{
310 loff_t err;
311
312 lockdep_off();
313 err = vfs_llseek(file, offset, origin);
314 lockdep_on();
315 return err;
316}
317
318/* ---------------------------------------------------------------------- */
319
320int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
321int vfsub_sio_rmdir(struct inode *dir, struct path *path);
322int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
323 struct inode **delegated_inode);
324int vfsub_notify_change(struct path *path, struct iattr *ia,
325 struct inode **delegated_inode);
326int vfsub_unlink(struct inode *dir, struct path *path,
327 struct inode **delegated_inode, int force);
328
329static inline int vfsub_getattr(const struct path *path, struct kstat *st)
330{
331 return vfs_getattr(path, st, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT);
332}
333
334/* ---------------------------------------------------------------------- */
335
336static inline int vfsub_setxattr(struct dentry *dentry, const char *name,
337 const void *value, size_t size, int flags)
338{
339 int err;
340
341 lockdep_off();
342 err = vfs_setxattr(dentry, name, value, size, flags);
343 lockdep_on();
344
345 return err;
346}
347
348static inline int vfsub_removexattr(struct dentry *dentry, const char *name)
349{
350 int err;
351
352 lockdep_off();
353 err = vfs_removexattr(dentry, name);
354 lockdep_on();
355
356 return err;
357}
358
359#endif /* __KERNEL__ */
360#endif /* __AUFS_VFSUB_H__ */