Merge branch 'stable-3.2' into pandora-3.2
[pandora-kernel.git] / fs / aufs / vfsub.h
1 /*
2  * Copyright (C) 2005-2013 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, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18
19 /*
20  * sub-routines for VFS
21  */
22
23 #ifndef __AUFS_VFSUB_H__
24 #define __AUFS_VFSUB_H__
25
26 #ifdef __KERNEL__
27
28 #include <linux/fs.h>
29 #include <linux/lglock.h>
30 #include "debug.h"
31
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;
37
38 /* copied from linux/fs/file_table.c */
39 DECLARE_LGLOCK(files_lglock);
40 #ifdef CONFIG_SMP
41 /*
42  * These macros iterate all files on all CPUs for a given superblock.
43  * files_lglock must be held globally.
44  */
45 #define do_file_list_for_each_entry(__sb, __file)               \
46 {                                                               \
47         int i;                                                  \
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)
52
53 #define while_file_list_for_each_entry                          \
54         }                                                       \
55 }
56
57 #else
58
59 #define do_file_list_for_each_entry(__sb, __file)               \
60 {                                                               \
61         struct list_head *list;                                 \
62         list = &(sb)->s_files;                                  \
63         list_for_each_entry((__file), list, f_u.fu_list)
64
65 #define while_file_list_for_each_entry                          \
66 }
67 #endif
68
69 /* ---------------------------------------------------------------------- */
70
71 /* lock subclass for lower inode */
72 /* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
73 /* reduce? gave up. */
74 enum {
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 */
79         AuLsc_I_CHILD,
80         AuLsc_I_CHILD2,
81         AuLsc_I_End
82 };
83
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)
87
88 /* ---------------------------------------------------------------------- */
89
90 static inline void vfsub_drop_nlink(struct inode *inode)
91 {
92         AuDebugOn(!inode->i_nlink);
93         drop_nlink(inode);
94 }
95
96 static inline void vfsub_dead_dir(struct inode *inode)
97 {
98         AuDebugOn(!S_ISDIR(inode->i_mode));
99         inode->i_flags |= S_DEAD;
100         clear_nlink(inode);
101 }
102
103 /* ---------------------------------------------------------------------- */
104
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,
110                                     int len);
111 struct dentry *vfsub_lookup_hash(struct nameidata *nd);
112 int vfsub_name_hash(const char *name, struct qstr *this, int len);
113
114 /* ---------------------------------------------------------------------- */
115
116 struct au_hinode;
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);
121
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,
127                struct path *path);
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);
132
133 /* ---------------------------------------------------------------------- */
134
135 ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
136                      loff_t *ppos);
137 ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
138                         loff_t *ppos);
139 ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
140                       loff_t *ppos);
141 ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
142                       loff_t *ppos);
143 int vfsub_flush(struct file *file, fl_owner_t id);
144 int vfsub_readdir(struct file *file, filldir_t filldir, void *arg);
145
146 static inline unsigned int vfsub_file_flags(struct file *file)
147 {
148         unsigned int flags;
149
150         spin_lock(&file->f_lock);
151         flags = file->f_flags;
152         spin_unlock(&file->f_lock);
153
154         return flags;
155 }
156
157 static inline void vfsub_file_accessed(struct file *h_file)
158 {
159         file_accessed(h_file);
160         vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
161 }
162
163 static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
164                                      struct dentry *h_dentry)
165 {
166         struct path h_path = {
167                 .dentry = h_dentry,
168                 .mnt    = h_mnt
169         };
170         touch_atime(h_mnt, h_dentry);
171         vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
172 }
173
174 long vfsub_splice_to(struct file *in, loff_t *ppos,
175                      struct pipe_inode_info *pipe, size_t len,
176                      unsigned int flags);
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);
182
183 /* ---------------------------------------------------------------------- */
184
185 static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
186 {
187         loff_t err;
188
189         lockdep_off();
190         err = vfs_llseek(file, offset, origin);
191         lockdep_on();
192         return err;
193 }
194
195 /* ---------------------------------------------------------------------- */
196
197 /* dirty workaround for strict type of fmode_t */
198 union vfsub_fmu {
199         fmode_t fm;
200         unsigned int ui;
201 };
202
203 static inline unsigned int vfsub_fmode_to_uint(fmode_t fm)
204 {
205         union vfsub_fmu u = {
206                 .fm = fm
207         };
208
209         BUILD_BUG_ON(sizeof(u.fm) != sizeof(u.ui));
210
211         return u.ui;
212 }
213
214 static inline fmode_t vfsub_uint_to_fmode(unsigned int ui)
215 {
216         union vfsub_fmu u = {
217                 .ui = ui
218         };
219
220         return u.fm;
221 }
222
223 /* ---------------------------------------------------------------------- */
224
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);
230
231 #endif /* __KERNEL__ */
232 #endif /* __AUFS_VFSUB_H__ */