]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - fs/aufs/file.h
UBUNTU: SAUCE: i2c: i801: Restore the presence state of P2SB PCI device after reading BAR
[mirror_ubuntu-artful-kernel.git] / fs / aufs / file.h
CommitLineData
fe9d3fa6
SF
1/*
2 * Copyright (C) 2005-2017 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, see <http://www.gnu.org/licenses/>.
16 */
17
18/*
19 * file operations
20 */
21
22#ifndef __AUFS_FILE_H__
23#define __AUFS_FILE_H__
24
25#ifdef __KERNEL__
26
27#include <linux/file.h>
28#include <linux/fs.h>
29#include <linux/poll.h>
30#include "rwsem.h"
31
32struct au_branch;
33struct au_hfile {
34 struct file *hf_file;
35 struct au_branch *hf_br;
36};
37
38struct au_vdir;
39struct au_fidir {
40 aufs_bindex_t fd_bbot;
41 aufs_bindex_t fd_nent;
42 struct au_vdir *fd_vdir_cache;
43 struct au_hfile fd_hfile[];
44};
45
46static inline int au_fidir_sz(int nent)
47{
48 AuDebugOn(nent < 0);
49 return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent;
50}
51
52struct au_finfo {
53 atomic_t fi_generation;
54
55 struct au_rwsem fi_rwsem;
56 aufs_bindex_t fi_btop;
57
58 /* do not union them */
59 struct { /* for non-dir */
60 struct au_hfile fi_htop;
61 atomic_t fi_mmapped;
62 };
63 struct au_fidir *fi_hdir; /* for dir only */
64
65 struct hlist_node fi_hlist;
66 struct file *fi_file; /* very ugly */
67} ____cacheline_aligned_in_smp;
68
69/* ---------------------------------------------------------------------- */
70
71/* file.c */
72extern const struct address_space_operations aufs_aop;
73unsigned int au_file_roflags(unsigned int flags);
74struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
75 struct file *file, int force_wr);
76struct au_do_open_args {
77 int no_lock;
78 int (*open)(struct file *file, int flags,
79 struct file *h_file);
80 struct au_fidir *fidir;
81 struct file *h_file;
82};
83int au_do_open(struct file *file, struct au_do_open_args *args);
84int au_reopen_nondir(struct file *file);
85struct au_pin;
86int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
87int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
88 int wlock, unsigned int fi_lsc);
89int au_do_flush(struct file *file, fl_owner_t id,
90 int (*flush)(struct file *file, fl_owner_t id));
91
92/* poll.c */
93#ifdef CONFIG_AUFS_POLL
94unsigned int aufs_poll(struct file *file, poll_table *wait);
95#endif
96
97#ifdef CONFIG_AUFS_BR_HFSPLUS
98/* hfsplus.c */
99struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
100 int force_wr);
101void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
102 struct file *h_file);
103#else
104AuStub(struct file *, au_h_open_pre, return NULL, struct dentry *dentry,
105 aufs_bindex_t bindex, int force_wr)
106AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex,
107 struct file *h_file);
108#endif
109
110/* f_op.c */
111extern const struct file_operations aufs_file_fop;
112int au_do_open_nondir(struct file *file, int flags, struct file *h_file);
113int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file);
114struct file *au_read_pre(struct file *file, int keep_fi, unsigned int lsc);
115
116/* finfo.c */
117void au_hfput(struct au_hfile *hf, int execed);
118void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
119 struct file *h_file);
120
121void au_update_figen(struct file *file);
122struct au_fidir *au_fidir_alloc(struct super_block *sb);
123int au_fidir_realloc(struct au_finfo *finfo, int nbr, int may_shrink);
124
125void au_fi_init_once(void *_fi);
126void au_finfo_fin(struct file *file);
127int au_finfo_init(struct file *file, struct au_fidir *fidir);
128
129/* ioctl.c */
130long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg);
131#ifdef CONFIG_COMPAT
132long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
133 unsigned long arg);
134long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
135 unsigned long arg);
136#endif
137
138/* ---------------------------------------------------------------------- */
139
140static inline struct au_finfo *au_fi(struct file *file)
141{
142 return file->private_data;
143}
144
145/* ---------------------------------------------------------------------- */
146
147/*
148 * fi_read_lock, fi_write_lock,
149 * fi_read_unlock, fi_write_unlock, fi_downgrade_lock
150 */
151AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem);
152
153/* lock subclass for finfo */
154enum {
155 AuLsc_FI_1,
156 AuLsc_FI_2
157};
158
159static inline void fi_read_lock_nested(struct file *f, unsigned int lsc)
160{
161 au_rw_read_lock_nested(&au_fi(f)->fi_rwsem, lsc);
162}
163
164static inline void fi_write_lock_nested(struct file *f, unsigned int lsc)
165{
166 au_rw_write_lock_nested(&au_fi(f)->fi_rwsem, lsc);
167}
168
169/*
170 * fi_read_lock_1, fi_write_lock_1,
171 * fi_read_lock_2, fi_write_lock_2
172 */
173#define AuReadLockFunc(name) \
174static inline void fi_read_lock_##name(struct file *f) \
175{ fi_read_lock_nested(f, AuLsc_FI_##name); }
176
177#define AuWriteLockFunc(name) \
178static inline void fi_write_lock_##name(struct file *f) \
179{ fi_write_lock_nested(f, AuLsc_FI_##name); }
180
181#define AuRWLockFuncs(name) \
182 AuReadLockFunc(name) \
183 AuWriteLockFunc(name)
184
185AuRWLockFuncs(1);
186AuRWLockFuncs(2);
187
188#undef AuReadLockFunc
189#undef AuWriteLockFunc
190#undef AuRWLockFuncs
191
192#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
193#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
194#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
195
196/* ---------------------------------------------------------------------- */
197
198/* todo: hard/soft set? */
199static inline aufs_bindex_t au_fbtop(struct file *file)
200{
201 FiMustAnyLock(file);
202 return au_fi(file)->fi_btop;
203}
204
205static inline aufs_bindex_t au_fbbot_dir(struct file *file)
206{
207 FiMustAnyLock(file);
208 AuDebugOn(!au_fi(file)->fi_hdir);
209 return au_fi(file)->fi_hdir->fd_bbot;
210}
211
212static inline struct au_vdir *au_fvdir_cache(struct file *file)
213{
214 FiMustAnyLock(file);
215 AuDebugOn(!au_fi(file)->fi_hdir);
216 return au_fi(file)->fi_hdir->fd_vdir_cache;
217}
218
219static inline void au_set_fbtop(struct file *file, aufs_bindex_t bindex)
220{
221 FiMustWriteLock(file);
222 au_fi(file)->fi_btop = bindex;
223}
224
225static inline void au_set_fbbot_dir(struct file *file, aufs_bindex_t bindex)
226{
227 FiMustWriteLock(file);
228 AuDebugOn(!au_fi(file)->fi_hdir);
229 au_fi(file)->fi_hdir->fd_bbot = bindex;
230}
231
232static inline void au_set_fvdir_cache(struct file *file,
233 struct au_vdir *vdir_cache)
234{
235 FiMustWriteLock(file);
236 AuDebugOn(!au_fi(file)->fi_hdir);
237 au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache;
238}
239
240static inline struct file *au_hf_top(struct file *file)
241{
242 FiMustAnyLock(file);
243 AuDebugOn(au_fi(file)->fi_hdir);
244 return au_fi(file)->fi_htop.hf_file;
245}
246
247static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex)
248{
249 FiMustAnyLock(file);
250 AuDebugOn(!au_fi(file)->fi_hdir);
251 return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file;
252}
253
254/* todo: memory barrier? */
255static inline unsigned int au_figen(struct file *f)
256{
257 return atomic_read(&au_fi(f)->fi_generation);
258}
259
260static inline void au_set_mmapped(struct file *f)
261{
262 if (atomic_inc_return(&au_fi(f)->fi_mmapped))
263 return;
264 pr_warn("fi_mmapped wrapped around\n");
265 while (!atomic_inc_return(&au_fi(f)->fi_mmapped))
266 ;
267}
268
269static inline void au_unset_mmapped(struct file *f)
270{
271 atomic_dec(&au_fi(f)->fi_mmapped);
272}
273
274static inline int au_test_mmapped(struct file *f)
275{
276 return atomic_read(&au_fi(f)->fi_mmapped);
277}
278
279/* customize vma->vm_file */
280
281static inline void au_do_vm_file_reset(struct vm_area_struct *vma,
282 struct file *file)
283{
284 struct file *f;
285
286 f = vma->vm_file;
287 get_file(file);
288 vma->vm_file = file;
289 fput(f);
290}
291
292#ifdef CONFIG_MMU
293#define AuDbgVmRegion(file, vma) do {} while (0)
294
295static inline void au_vm_file_reset(struct vm_area_struct *vma,
296 struct file *file)
297{
298 au_do_vm_file_reset(vma, file);
299}
300#else
301#define AuDbgVmRegion(file, vma) \
302 AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file))
303
304static inline void au_vm_file_reset(struct vm_area_struct *vma,
305 struct file *file)
306{
307 struct file *f;
308
309 au_do_vm_file_reset(vma, file);
310 f = vma->vm_region->vm_file;
311 get_file(file);
312 vma->vm_region->vm_file = file;
313 fput(f);
314}
315#endif /* CONFIG_MMU */
316
317/* handle vma->vm_prfile */
318static inline void au_vm_prfile_set(struct vm_area_struct *vma,
319 struct file *file)
320{
321 get_file(file);
322 vma->vm_prfile = file;
323#ifndef CONFIG_MMU
324 get_file(file);
325 vma->vm_region->vm_prfile = file;
326#endif
327}
328
329#endif /* __KERNEL__ */
330#endif /* __AUFS_FILE_H__ */