2
* Copyright (C) 2005-2013 Junjiro R. Okajima
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.
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.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
* sub-routines for VFS
23
#ifndef __AUFS_VFSUB_H__
24
#define __AUFS_VFSUB_H__
29
#include <linux/lglock.h>
30
#include <linux/mount.h>
33
/* copied from linux/fs/internal.h */
34
/* todo: BAD approach!! */
35
extern struct lglock vfsmount_lock;
36
extern void __mnt_drop_write(struct vfsmount *);
37
extern spinlock_t inode_sb_list_lock;
39
/* copied from linux/fs/file_table.c */
40
extern struct lglock files_lglock;
43
* These macros iterate all files on all CPUs for a given superblock.
44
* files_lglock must be held globally.
46
#define do_file_list_for_each_entry(__sb, __file) \
49
for_each_possible_cpu(i) { \
50
struct list_head *list; \
51
list = per_cpu_ptr((__sb)->s_files, i); \
52
list_for_each_entry((__file), list, f_u.fu_list)
54
#define while_file_list_for_each_entry \
60
#define do_file_list_for_each_entry(__sb, __file) \
62
struct list_head *list; \
63
list = &(sb)->s_files; \
64
list_for_each_entry((__file), list, f_u.fu_list)
66
#define while_file_list_for_each_entry \
70
/* ---------------------------------------------------------------------- */
72
/* lock subclass for lower inode */
73
/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
74
/* reduce? gave up. */
76
AuLsc_I_Begin = I_MUTEX_QUOTA, /* 4 */
77
AuLsc_I_PARENT, /* lower inode, parent first */
78
AuLsc_I_PARENT2, /* copyup dirs */
79
AuLsc_I_PARENT3, /* copyup wh */
85
/* to debug easier, do not make them inlined functions */
86
#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx))
87
#define IMustLock(i) MtxMustLock(&(i)->i_mutex)
89
/* ---------------------------------------------------------------------- */
91
static inline void vfsub_drop_nlink(struct inode *inode)
93
AuDebugOn(!inode->i_nlink);
97
static inline void vfsub_dead_dir(struct inode *inode)
99
AuDebugOn(!S_ISDIR(inode->i_mode));
100
inode->i_flags |= S_DEAD;
104
static inline int vfsub_native_ro(struct inode *inode)
106
return (inode->i_sb->s_flags & MS_RDONLY)
108
/* || IS_APPEND(inode) */
109
|| IS_IMMUTABLE(inode);
112
/* ---------------------------------------------------------------------- */
114
int vfsub_update_h_iattr(struct path *h_path, int *did);
115
struct file *vfsub_dentry_open(struct path *path, int flags);
116
struct file *vfsub_filp_open(const char *path, int oflags, int mode);
117
int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
119
struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
122
struct vfsub_lkup_one_args {
123
struct dentry **errp;
125
struct dentry *parent;
128
static inline struct dentry *vfsub_lkup_one(struct qstr *name,
129
struct dentry *parent)
131
return vfsub_lookup_one_len(name->name, parent, name->len);
134
void vfsub_call_lkup_one(void *args);
136
/* ---------------------------------------------------------------------- */
138
static inline int vfsub_mnt_want_write(struct vfsmount *mnt)
142
err = mnt_want_write(mnt);
147
static inline void vfsub_mnt_drop_write(struct vfsmount *mnt)
154
static inline void vfsub_mnt_drop_write_file(struct file *file)
157
mnt_drop_write_file(file);
161
/* ---------------------------------------------------------------------- */
164
struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
165
struct dentry *d2, struct au_hinode *hdir2);
166
void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
167
struct dentry *d2, struct au_hinode *hdir2);
169
int vfsub_create(struct inode *dir, struct path *path, int mode,
171
int vfsub_symlink(struct inode *dir, struct path *path,
172
const char *symname);
173
int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
174
int vfsub_link(struct dentry *src_dentry, struct inode *dir,
176
int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
177
struct inode *hdir, struct path *path);
178
int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
179
int vfsub_rmdir(struct inode *dir, struct path *path);
181
/* ---------------------------------------------------------------------- */
183
ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
185
ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
187
ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
189
ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
191
int vfsub_flush(struct file *file, fl_owner_t id);
192
int vfsub_iterate_dir(struct file *file, struct dir_context *ctx);
194
/* just for type-check */
195
static inline filldir_t au_diractor(int (*func)(struct dir_context *,
196
const char *, int, loff_t, u64,
199
return (filldir_t)func;
203
static inline loff_t vfsub_f_size_read(struct file *file)
205
return i_size_read(file_inode(file));
208
static inline unsigned int vfsub_file_flags(struct file *file)
212
spin_lock(&file->f_lock);
213
flags = file->f_flags;
214
spin_unlock(&file->f_lock);
219
static inline void vfsub_file_accessed(struct file *h_file)
221
file_accessed(h_file);
222
vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
225
static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
226
struct dentry *h_dentry)
228
struct path h_path = {
232
touch_atime(&h_path);
233
vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
236
static inline int vfsub_update_time(struct inode *h_inode, struct timespec *ts,
239
return update_time(h_inode, ts, flags);
240
/* no vfsub_update_h_iattr() since we don't have struct path */
243
long vfsub_splice_to(struct file *in, loff_t *ppos,
244
struct pipe_inode_info *pipe, size_t len,
246
long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
247
loff_t *ppos, size_t len, unsigned int flags);
249
static inline long vfsub_truncate(struct path *path, loff_t length)
253
err = vfs_truncate(path, length);
258
int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
259
struct file *h_file);
260
int vfsub_fsync(struct file *file, struct path *path, int datasync);
262
/* ---------------------------------------------------------------------- */
264
static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
269
err = vfs_llseek(file, offset, origin);
274
/* ---------------------------------------------------------------------- */
276
/* dirty workaround for strict type of fmode_t */
282
static inline unsigned int vfsub_fmode_to_uint(fmode_t fm)
284
union vfsub_fmu u = {
288
BUILD_BUG_ON(sizeof(u.fm) != sizeof(u.ui));
293
static inline fmode_t vfsub_uint_to_fmode(unsigned int ui)
295
union vfsub_fmu u = {
302
/* ---------------------------------------------------------------------- */
304
int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
305
int vfsub_sio_rmdir(struct inode *dir, struct path *path);
306
int vfsub_sio_notify_change(struct path *path, struct iattr *ia);
307
int vfsub_notify_change(struct path *path, struct iattr *ia);
308
int vfsub_unlink(struct inode *dir, struct path *path, int force);
310
#endif /* __KERNEL__ */
311
#endif /* __AUFS_VFSUB_H__ */