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>
32 /* copied from linux/fs/internal.h */
33 /* todo: BAD approach!! */
34 DECLARE_BRLOCK(vfsmount_lock);
35 extern void file_sb_list_del(struct file *f);
36 extern spinlock_t inode_sb_list_lock;
38 /* copied from linux/fs/file_table.c */
39 DECLARE_LGLOCK(files_lglock);
42 * These macros iterate all files on all CPUs for a given superblock.
43 * files_lglock must be held globally.
45 #define do_file_list_for_each_entry(__sb, __file) \
48 for_each_possible_cpu(i) { \
49 struct list_head *list; \
50 list = per_cpu_ptr((__sb)->s_files, i); \
51 list_for_each_entry((__file), list, f_u.fu_list)
53 #define while_file_list_for_each_entry \
59 #define do_file_list_for_each_entry(__sb, __file) \
61 struct list_head *list; \
62 list = &(sb)->s_files; \
63 list_for_each_entry((__file), list, f_u.fu_list)
65 #define while_file_list_for_each_entry \
69 /* ---------------------------------------------------------------------- */
71 /* lock subclass for lower inode */
72 /* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
73 /* reduce? gave up. */
75 AuLsc_I_Begin = I_MUTEX_QUOTA, /* 4 */
76 AuLsc_I_PARENT, /* lower inode, parent first */
77 AuLsc_I_PARENT2, /* copyup dirs */
78 AuLsc_I_PARENT3, /* copyup wh */
84 /* to debug easier, do not make them inlined functions */
85 #define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx))
86 #define IMustLock(i) MtxMustLock(&(i)->i_mutex)
88 /* ---------------------------------------------------------------------- */
90 static inline void vfsub_drop_nlink(struct inode *inode)
92 AuDebugOn(!inode->i_nlink);
96 static inline void vfsub_dead_dir(struct inode *inode)
98 AuDebugOn(!S_ISDIR(inode->i_mode));
99 inode->i_flags |= S_DEAD;
103 /* ---------------------------------------------------------------------- */
105 int vfsub_update_h_iattr(struct path *h_path, int *did);
106 struct file *vfsub_dentry_open(struct path *path, int flags);
107 struct file *vfsub_filp_open(const char *path, int oflags, int mode);
108 int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
109 struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
111 struct dentry *vfsub_lookup_hash(struct nameidata *nd);
112 int vfsub_name_hash(const char *name, struct qstr *this, int len);
114 /* ---------------------------------------------------------------------- */
117 struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
118 struct dentry *d2, struct au_hinode *hdir2);
119 void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
120 struct dentry *d2, struct au_hinode *hdir2);
122 int vfsub_create(struct inode *dir, struct path *path, int mode);
123 int vfsub_symlink(struct inode *dir, struct path *path,
124 const char *symname);
125 int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
126 int vfsub_link(struct dentry *src_dentry, struct inode *dir,
128 int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
129 struct inode *hdir, struct path *path);
130 int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
131 int vfsub_rmdir(struct inode *dir, struct path *path);
133 /* ---------------------------------------------------------------------- */
135 ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
137 ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
139 ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
141 ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
143 int vfsub_flush(struct file *file, fl_owner_t id);
144 int vfsub_readdir(struct file *file, filldir_t filldir, void *arg);
146 static inline unsigned int vfsub_file_flags(struct file *file)
150 spin_lock(&file->f_lock);
151 flags = file->f_flags;
152 spin_unlock(&file->f_lock);
157 static inline void vfsub_file_accessed(struct file *h_file)
159 file_accessed(h_file);
160 vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
163 static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
164 struct dentry *h_dentry)
166 struct path h_path = {
170 touch_atime(h_mnt, h_dentry);
171 vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
174 long vfsub_splice_to(struct file *in, loff_t *ppos,
175 struct pipe_inode_info *pipe, size_t len,
177 long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
178 loff_t *ppos, size_t len, unsigned int flags);
179 int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
180 struct file *h_file);
181 int vfsub_fsync(struct file *file, struct path *path, int datasync);
183 /* ---------------------------------------------------------------------- */
185 static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
190 err = vfs_llseek(file, offset, origin);
195 /* ---------------------------------------------------------------------- */
197 /* dirty workaround for strict type of fmode_t */
203 static inline unsigned int vfsub_fmode_to_uint(fmode_t fm)
205 union vfsub_fmu u = {
209 BUILD_BUG_ON(sizeof(u.fm) != sizeof(u.ui));
214 static inline fmode_t vfsub_uint_to_fmode(unsigned int ui)
216 union vfsub_fmu u = {
223 /* ---------------------------------------------------------------------- */
225 int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
226 int vfsub_sio_rmdir(struct inode *dir, struct path *path);
227 int vfsub_sio_notify_change(struct path *path, struct iattr *ia);
228 int vfsub_notify_change(struct path *path, struct iattr *ia);
229 int vfsub_unlink(struct inode *dir, struct path *path, int force);
231 #endif /* __KERNEL__ */
232 #endif /* __AUFS_VFSUB_H__ */