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
23 #ifndef __AUFS_FILE_H__
24 #define __AUFS_FILE_H__
28 #include <linux/file.h>
30 #include <linux/poll.h>
36 struct au_branch *hf_br;
41 aufs_bindex_t fd_bbot;
42 aufs_bindex_t fd_nent;
43 struct au_vdir *fd_vdir_cache;
44 struct au_hfile fd_hfile[];
47 static inline int au_fidir_sz(int nent)
50 return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent;
54 atomic_t fi_generation;
56 struct au_rwsem fi_rwsem;
57 aufs_bindex_t fi_btop;
59 /* do not union them */
60 struct { /* for non-dir */
61 struct au_hfile fi_htop;
64 struct au_fidir *fi_hdir; /* for dir only */
65 } ____cacheline_aligned_in_smp;
67 /* ---------------------------------------------------------------------- */
70 extern const struct address_space_operations aufs_aop;
71 unsigned int au_file_roflags(unsigned int flags);
72 struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
74 int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
75 struct au_fidir *fidir);
76 int au_reopen_nondir(struct file *file);
78 int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
79 int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
81 int au_do_flush(struct file *file, fl_owner_t id,
82 int (*flush)(struct file *file, fl_owner_t id));
85 #ifdef CONFIG_AUFS_POLL
86 unsigned int aufs_poll(struct file *file, poll_table *wait);
89 #ifdef CONFIG_AUFS_BR_HFSPLUS
91 struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex);
92 void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
96 struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex)
101 AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex,
102 struct file *h_file);
106 extern const struct file_operations aufs_file_fop;
107 int au_do_open_nondir(struct file *file, int flags);
108 int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file);
110 #ifdef CONFIG_AUFS_SP_IATTR
112 int au_special_file(umode_t mode);
113 void au_init_special_fop(struct inode *inode, umode_t mode, dev_t rdev);
115 AuStubInt0(au_special_file, umode_t mode)
116 static inline void au_init_special_fop(struct inode *inode, umode_t mode,
119 init_special_inode(inode, mode, rdev);
124 void au_hfput(struct au_hfile *hf, struct file *file);
125 void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
126 struct file *h_file);
128 void au_update_figen(struct file *file);
129 struct au_fidir *au_fidir_alloc(struct super_block *sb);
130 int au_fidir_realloc(struct au_finfo *finfo, int nbr);
132 void au_fi_init_once(void *_fi);
133 void au_finfo_fin(struct file *file);
134 int au_finfo_init(struct file *file, struct au_fidir *fidir);
137 long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg);
139 long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
143 /* ---------------------------------------------------------------------- */
145 static inline struct au_finfo *au_fi(struct file *file)
147 return file->private_data;
150 /* ---------------------------------------------------------------------- */
153 * fi_read_lock, fi_write_lock,
154 * fi_read_unlock, fi_write_unlock, fi_downgrade_lock
156 AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem);
158 #define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
159 #define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
160 #define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
162 /* ---------------------------------------------------------------------- */
164 /* todo: hard/soft set? */
165 static inline aufs_bindex_t au_fbstart(struct file *file)
168 return au_fi(file)->fi_btop;
171 static inline aufs_bindex_t au_fbend_dir(struct file *file)
174 AuDebugOn(!au_fi(file)->fi_hdir);
175 return au_fi(file)->fi_hdir->fd_bbot;
178 static inline struct au_vdir *au_fvdir_cache(struct file *file)
181 AuDebugOn(!au_fi(file)->fi_hdir);
182 return au_fi(file)->fi_hdir->fd_vdir_cache;
185 static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex)
187 FiMustWriteLock(file);
188 au_fi(file)->fi_btop = bindex;
191 static inline void au_set_fbend_dir(struct file *file, aufs_bindex_t bindex)
193 FiMustWriteLock(file);
194 AuDebugOn(!au_fi(file)->fi_hdir);
195 au_fi(file)->fi_hdir->fd_bbot = bindex;
198 static inline void au_set_fvdir_cache(struct file *file,
199 struct au_vdir *vdir_cache)
201 FiMustWriteLock(file);
202 AuDebugOn(!au_fi(file)->fi_hdir);
203 au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache;
206 static inline struct file *au_hf_top(struct file *file)
209 AuDebugOn(au_fi(file)->fi_hdir);
210 return au_fi(file)->fi_htop.hf_file;
213 static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex)
216 AuDebugOn(!au_fi(file)->fi_hdir);
217 return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file;
220 /* todo: memory barrier? */
221 static inline unsigned int au_figen(struct file *f)
223 return atomic_read(&au_fi(f)->fi_generation);
226 static inline void au_set_mmapped(struct file *f)
228 if (atomic_inc_return(&au_fi(f)->fi_mmapped))
230 pr_warn("fi_mmapped wrapped around\n");
231 while (!atomic_inc_return(&au_fi(f)->fi_mmapped))
235 static inline void au_unset_mmapped(struct file *f)
237 atomic_dec(&au_fi(f)->fi_mmapped);
240 static inline int au_test_mmapped(struct file *f)
242 return atomic_read(&au_fi(f)->fi_mmapped);
245 /* customize vma->vm_file */
247 static inline void au_do_vm_file_reset(struct vm_area_struct *vma,
259 #define AuDbgVmRegion(file, vma) do {} while (0)
261 static inline void au_vm_file_reset(struct vm_area_struct *vma,
264 au_do_vm_file_reset(vma, file);
267 #define AuDbgVmRegion(file, vma) \
268 AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file))
270 static inline void au_vm_file_reset(struct vm_area_struct *vma,
275 au_do_vm_file_reset(vma, file);
276 f = vma->vm_region->vm_file;
278 vma->vm_region->vm_file = file;
281 #endif /* CONFIG_MMU */
283 /* handle vma->vm_prfile */
284 static inline void au_vm_prfile_set(struct vm_area_struct *vma,
287 #ifdef CONFIG_AUFS_PROC_MAP
289 vma->vm_prfile = file;
292 vma->vm_region->vm_prfile = file;
297 #endif /* __KERNEL__ */
298 #endif /* __AUFS_FILE_H__ */