2 * Copyright (C) 2005-2017 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, see <http://www.gnu.org/licenses/>.
22 #ifndef __AUFS_FILE_H__
23 #define __AUFS_FILE_H__
27 #include <linux/file.h>
29 #include <linux/mm_types.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 */
66 struct hlist_bl_node fi_hlist
;
67 struct file
*fi_file
; /* very ugly */
68 } ____cacheline_aligned_in_smp
;
70 /* ---------------------------------------------------------------------- */
73 extern const struct address_space_operations aufs_aop
;
74 unsigned int au_file_roflags(unsigned int flags
);
75 struct file
*au_h_open(struct dentry
*dentry
, aufs_bindex_t bindex
, int flags
,
76 struct file
*file
, int force_wr
);
77 struct au_do_open_args
{
79 int (*open
)(struct file
*file
, int flags
,
81 struct au_fidir
*fidir
;
84 int au_do_open(struct file
*file
, struct au_do_open_args
*args
);
85 int au_reopen_nondir(struct file
*file
);
87 int au_ready_to_write(struct file
*file
, loff_t len
, struct au_pin
*pin
);
88 int au_reval_and_lock_fdi(struct file
*file
, int (*reopen
)(struct file
*file
),
89 int wlock
, unsigned int fi_lsc
);
90 int au_do_flush(struct file
*file
, fl_owner_t id
,
91 int (*flush
)(struct file
*file
, fl_owner_t id
));
94 #ifdef CONFIG_AUFS_POLL
95 unsigned int aufs_poll(struct file
*file
, poll_table
*wait
);
98 #ifdef CONFIG_AUFS_BR_HFSPLUS
100 struct file
*au_h_open_pre(struct dentry
*dentry
, aufs_bindex_t bindex
,
102 void au_h_open_post(struct dentry
*dentry
, aufs_bindex_t bindex
,
103 struct file
*h_file
);
105 AuStub(struct file
*, au_h_open_pre
, return NULL
, struct dentry
*dentry
,
106 aufs_bindex_t bindex
, int force_wr
)
107 AuStubVoid(au_h_open_post
, struct dentry
*dentry
, aufs_bindex_t bindex
,
108 struct file
*h_file
);
112 extern const struct file_operations aufs_file_fop
;
113 int au_do_open_nondir(struct file
*file
, int flags
, struct file
*h_file
);
114 int aufs_release_nondir(struct inode
*inode __maybe_unused
, struct file
*file
);
115 struct file
*au_read_pre(struct file
*file
, int keep_fi
, unsigned int lsc
);
118 void au_hfput(struct au_hfile
*hf
, int execed
);
119 void au_set_h_fptr(struct file
*file
, aufs_bindex_t bindex
,
120 struct file
*h_file
);
122 void au_update_figen(struct file
*file
);
123 struct au_fidir
*au_fidir_alloc(struct super_block
*sb
);
124 int au_fidir_realloc(struct au_finfo
*finfo
, int nbr
, int may_shrink
);
126 void au_fi_init_once(void *_fi
);
127 void au_finfo_fin(struct file
*file
);
128 int au_finfo_init(struct file
*file
, struct au_fidir
*fidir
);
131 long aufs_ioctl_nondir(struct file
*file
, unsigned int cmd
, unsigned long arg
);
133 long aufs_compat_ioctl_dir(struct file
*file
, unsigned int cmd
,
135 long aufs_compat_ioctl_nondir(struct file
*file
, unsigned int cmd
,
139 /* ---------------------------------------------------------------------- */
141 static inline struct au_finfo
*au_fi(struct file
*file
)
143 return file
->private_data
;
146 /* ---------------------------------------------------------------------- */
148 #define fi_read_lock(f) au_rw_read_lock(&au_fi(f)->fi_rwsem)
149 #define fi_write_lock(f) au_rw_write_lock(&au_fi(f)->fi_rwsem)
150 #define fi_read_trylock(f) au_rw_read_trylock(&au_fi(f)->fi_rwsem)
151 #define fi_write_trylock(f) au_rw_write_trylock(&au_fi(f)->fi_rwsem)
153 #define fi_read_trylock_nested(f) \
154 au_rw_read_trylock_nested(&au_fi(f)->fi_rwsem)
155 #define fi_write_trylock_nested(f) \
156 au_rw_write_trylock_nested(&au_fi(f)->fi_rwsem)
159 #define fi_read_unlock(f) au_rw_read_unlock(&au_fi(f)->fi_rwsem)
160 #define fi_write_unlock(f) au_rw_write_unlock(&au_fi(f)->fi_rwsem)
161 #define fi_downgrade_lock(f) au_rw_dgrade_lock(&au_fi(f)->fi_rwsem)
163 /* lock subclass for finfo */
169 static inline void fi_read_lock_nested(struct file
*f
, unsigned int lsc
)
171 au_rw_read_lock_nested(&au_fi(f
)->fi_rwsem
, lsc
);
174 static inline void fi_write_lock_nested(struct file
*f
, unsigned int lsc
)
176 au_rw_write_lock_nested(&au_fi(f
)->fi_rwsem
, lsc
);
180 * fi_read_lock_1, fi_write_lock_1,
181 * fi_read_lock_2, fi_write_lock_2
183 #define AuReadLockFunc(name) \
184 static inline void fi_read_lock_##name(struct file *f) \
185 { fi_read_lock_nested(f, AuLsc_FI_##name); }
187 #define AuWriteLockFunc(name) \
188 static inline void fi_write_lock_##name(struct file *f) \
189 { fi_write_lock_nested(f, AuLsc_FI_##name); }
191 #define AuRWLockFuncs(name) \
192 AuReadLockFunc(name) \
193 AuWriteLockFunc(name)
198 #undef AuReadLockFunc
199 #undef AuWriteLockFunc
202 #define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
203 #define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
204 #define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
206 /* ---------------------------------------------------------------------- */
208 /* todo: hard/soft set? */
209 static inline aufs_bindex_t
au_fbtop(struct file
*file
)
212 return au_fi(file
)->fi_btop
;
215 static inline aufs_bindex_t
au_fbbot_dir(struct file
*file
)
218 AuDebugOn(!au_fi(file
)->fi_hdir
);
219 return au_fi(file
)->fi_hdir
->fd_bbot
;
222 static inline struct au_vdir
*au_fvdir_cache(struct file
*file
)
225 AuDebugOn(!au_fi(file
)->fi_hdir
);
226 return au_fi(file
)->fi_hdir
->fd_vdir_cache
;
229 static inline void au_set_fbtop(struct file
*file
, aufs_bindex_t bindex
)
231 FiMustWriteLock(file
);
232 au_fi(file
)->fi_btop
= bindex
;
235 static inline void au_set_fbbot_dir(struct file
*file
, aufs_bindex_t bindex
)
237 FiMustWriteLock(file
);
238 AuDebugOn(!au_fi(file
)->fi_hdir
);
239 au_fi(file
)->fi_hdir
->fd_bbot
= bindex
;
242 static inline void au_set_fvdir_cache(struct file
*file
,
243 struct au_vdir
*vdir_cache
)
245 FiMustWriteLock(file
);
246 AuDebugOn(!au_fi(file
)->fi_hdir
);
247 au_fi(file
)->fi_hdir
->fd_vdir_cache
= vdir_cache
;
250 static inline struct file
*au_hf_top(struct file
*file
)
253 AuDebugOn(au_fi(file
)->fi_hdir
);
254 return au_fi(file
)->fi_htop
.hf_file
;
257 static inline struct file
*au_hf_dir(struct file
*file
, aufs_bindex_t bindex
)
260 AuDebugOn(!au_fi(file
)->fi_hdir
);
261 return au_fi(file
)->fi_hdir
->fd_hfile
[0 + bindex
].hf_file
;
264 /* todo: memory barrier? */
265 static inline unsigned int au_figen(struct file
*f
)
267 return atomic_read(&au_fi(f
)->fi_generation
);
270 static inline void au_set_mmapped(struct file
*f
)
272 if (atomic_inc_return(&au_fi(f
)->fi_mmapped
))
274 pr_warn("fi_mmapped wrapped around\n");
275 while (!atomic_inc_return(&au_fi(f
)->fi_mmapped
))
279 static inline void au_unset_mmapped(struct file
*f
)
281 atomic_dec(&au_fi(f
)->fi_mmapped
);
284 static inline int au_test_mmapped(struct file
*f
)
286 return atomic_read(&au_fi(f
)->fi_mmapped
);
289 /* customize vma->vm_file */
291 static inline void au_do_vm_file_reset(struct vm_area_struct
*vma
,
303 #define AuDbgVmRegion(file, vma) do {} while (0)
305 static inline void au_vm_file_reset(struct vm_area_struct
*vma
,
308 au_do_vm_file_reset(vma
, file
);
311 #define AuDbgVmRegion(file, vma) \
312 AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file))
314 static inline void au_vm_file_reset(struct vm_area_struct
*vma
,
319 au_do_vm_file_reset(vma
, file
);
320 f
= vma
->vm_region
->vm_file
;
322 vma
->vm_region
->vm_file
= file
;
325 #endif /* CONFIG_MMU */
327 /* handle vma->vm_prfile */
328 static inline void au_vm_prfile_set(struct vm_area_struct
*vma
,
332 vma
->vm_prfile
= file
;
335 vma
->vm_region
->vm_prfile
= file
;
339 #endif /* __KERNEL__ */
340 #endif /* __AUFS_FILE_H__ */