]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - fs/aufs/branch.h
PCI: Disable VF decoding before pcibios_sriov_disable() updates resources
[mirror_ubuntu-artful-kernel.git] / fs / aufs / branch.h
CommitLineData
18507e1a
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 * branch filesystems and xino for them
20 */
21
22#ifndef __AUFS_BRANCH_H__
23#define __AUFS_BRANCH_H__
24
25#ifdef __KERNEL__
26
27#include <linux/mount.h>
28#include "dynop.h"
29#include "rwsem.h"
30#include "super.h"
31
32/* ---------------------------------------------------------------------- */
33
34/* a xino file */
35struct au_xino_file {
36 struct file *xi_file;
37 struct {
38 spinlock_t spin;
39 ino_t *array;
40 int total;
41 /* reserved for future use */
42 /* unsigned long *bitmap; */
43 wait_queue_head_t wqh;
44 } xi_nondir;
45
46 /* todo: make xino files an array to support huge inode number */
47
48#ifdef CONFIG_DEBUG_FS
49 struct dentry *xi_dbgaufs;
50#endif
51};
52
53/* File-based Hierarchical Storage Management */
54struct au_br_fhsm {
55#ifdef CONFIG_AUFS_FHSM
56 struct mutex bf_lock;
57 unsigned long bf_jiffy;
58 struct aufs_stfs bf_stfs;
59 int bf_readable;
60#endif
61};
62
63/* members for writable branch only */
64enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
65struct au_wbr {
66 struct au_rwsem wbr_wh_rwsem;
67 struct dentry *wbr_wh[AuBrWh_Last];
68 atomic_t wbr_wh_running;
69#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */
70#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */
71#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */
72
73 /* mfs mode */
74 unsigned long long wbr_bytes;
75};
76
77/* ext2 has 3 types of operations at least, ext3 has 4 */
78#define AuBrDynOp (AuDyLast * 4)
79
80#ifdef CONFIG_AUFS_HFSNOTIFY
81/* support for asynchronous destruction */
82struct au_br_hfsnotify {
83 struct fsnotify_group *hfsn_group;
84};
85#endif
86
87/* sysfs entries */
88struct au_brsysfs {
89 char name[16];
90 struct attribute attr;
91};
92
93enum {
94 AuBrSysfs_BR,
95 AuBrSysfs_BRID,
96 AuBrSysfs_Last
97};
98
99/* protected by superblock rwsem */
100struct au_branch {
101 struct au_xino_file br_xino;
102
103 aufs_bindex_t br_id;
104
105 int br_perm;
106 struct path br_path;
107 spinlock_t br_dykey_lock;
108 struct au_dykey *br_dykey[AuBrDynOp];
109 struct percpu_counter br_count;
110
111 struct au_wbr *br_wbr;
112 struct au_br_fhsm *br_fhsm;
113
114 /* xino truncation */
115 atomic_t br_xino_running;
116
117#ifdef CONFIG_AUFS_HFSNOTIFY
118 struct au_br_hfsnotify *br_hfsn;
119#endif
120
121#ifdef CONFIG_SYSFS
122 /* entries under sysfs per mount-point */
123 struct au_brsysfs br_sysfs[AuBrSysfs_Last];
124#endif
125};
126
127/* ---------------------------------------------------------------------- */
128
129static inline struct vfsmount *au_br_mnt(struct au_branch *br)
130{
131 return br->br_path.mnt;
132}
133
134static inline struct dentry *au_br_dentry(struct au_branch *br)
135{
136 return br->br_path.dentry;
137}
138
139static inline struct super_block *au_br_sb(struct au_branch *br)
140{
141 return au_br_mnt(br)->mnt_sb;
142}
143
144static inline void au_br_get(struct au_branch *br)
145{
146 percpu_counter_inc(&br->br_count);
147}
148
149static inline void au_br_put(struct au_branch *br)
150{
151 percpu_counter_dec(&br->br_count);
152}
153
154static inline s64 au_br_count(struct au_branch *br)
155{
156 return percpu_counter_sum(&br->br_count);
157}
158
159static inline void au_br_count_init(struct au_branch *br)
160{
161 percpu_counter_init(&br->br_count, 0, GFP_NOFS);
162}
163
164static inline void au_br_count_fin(struct au_branch *br)
165{
166 percpu_counter_destroy(&br->br_count);
167}
168
169static inline int au_br_rdonly(struct au_branch *br)
170{
171 return ((au_br_sb(br)->s_flags & MS_RDONLY)
172 || !au_br_writable(br->br_perm))
173 ? -EROFS : 0;
174}
175
176static inline int au_br_hnotifyable(int brperm __maybe_unused)
177{
178#ifdef CONFIG_AUFS_HNOTIFY
179 return !(brperm & AuBrPerm_RR);
180#else
181 return 0;
182#endif
183}
184
185static inline int au_br_test_oflag(int oflag, struct au_branch *br)
186{
187 int err, exec_flag;
188
189 err = 0;
190 exec_flag = oflag & __FMODE_EXEC;
191 if (unlikely(exec_flag && path_noexec(&br->br_path)))
192 err = -EACCES;
193
194 return err;
195}
196
197/* ---------------------------------------------------------------------- */
198
199/* branch.c */
200struct au_sbinfo;
201void au_br_free(struct au_sbinfo *sinfo);
202int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
203struct au_opt_add;
204int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
205struct au_opt_del;
206int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
207long au_ibusy_ioctl(struct file *file, unsigned long arg);
208#ifdef CONFIG_COMPAT
209long au_ibusy_compat_ioctl(struct file *file, unsigned long arg);
210#endif
211struct au_opt_mod;
212int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
213 int *do_refresh);
214struct aufs_stfs;
215int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs);
216
217/* xino.c */
218static const loff_t au_loff_max = LLONG_MAX;
219
220int au_xib_trunc(struct super_block *sb);
221ssize_t xino_fread(vfs_readf_t func, struct file *file, void *buf, size_t size,
222 loff_t *pos);
223ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf,
224 size_t size, loff_t *pos);
225struct file *au_xino_create2(struct file *base_file, struct file *copy_src);
226struct file *au_xino_create(struct super_block *sb, char *fname, int silent);
227ino_t au_xino_new_ino(struct super_block *sb);
228void au_xino_delete_inode(struct inode *inode, const int unlinked);
229int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
230 ino_t ino);
231int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
232 ino_t *ino);
233int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino,
234 struct file *base_file, int do_test);
235int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex);
236
237struct au_opt_xino;
238int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount);
239void au_xino_clr(struct super_block *sb);
240struct file *au_xino_def(struct super_block *sb);
241int au_xino_path(struct seq_file *seq, struct file *file);
242
243void au_xinondir_leave(struct super_block *sb, aufs_bindex_t bindex,
244 ino_t h_ino, int idx);
245int au_xinondir_enter(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
246 int *idx);
247
248/* ---------------------------------------------------------------------- */
249
250/* Superblock to branch */
251static inline
252aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
253{
254 return au_sbr(sb, bindex)->br_id;
255}
256
257static inline
258struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
259{
260 return au_br_mnt(au_sbr(sb, bindex));
261}
262
263static inline
264struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
265{
266 return au_br_sb(au_sbr(sb, bindex));
267}
268
269static inline void au_sbr_get(struct super_block *sb, aufs_bindex_t bindex)
270{
271 au_br_get(au_sbr(sb, bindex));
272}
273
274static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex)
275{
276 au_br_put(au_sbr(sb, bindex));
277}
278
279static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
280{
281 return au_sbr(sb, bindex)->br_perm;
282}
283
284static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
285{
286 return au_br_whable(au_sbr_perm(sb, bindex));
287}
288
289/* ---------------------------------------------------------------------- */
290
291/*
292 * wbr_wh_read_lock, wbr_wh_write_lock
293 * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock
294 */
295AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem);
296
297#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&wbr->wbr_wh_rwsem)
298#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&wbr->wbr_wh_rwsem)
299#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&wbr->wbr_wh_rwsem)
300
301/* ---------------------------------------------------------------------- */
302
303#ifdef CONFIG_AUFS_FHSM
304static inline void au_br_fhsm_init(struct au_br_fhsm *brfhsm)
305{
306 mutex_init(&brfhsm->bf_lock);
307 brfhsm->bf_jiffy = 0;
308 brfhsm->bf_readable = 0;
309}
310
311static inline void au_br_fhsm_fin(struct au_br_fhsm *brfhsm)
312{
313 mutex_destroy(&brfhsm->bf_lock);
314}
315#else
316AuStubVoid(au_br_fhsm_init, struct au_br_fhsm *brfhsm)
317AuStubVoid(au_br_fhsm_fin, struct au_br_fhsm *brfhsm)
318#endif
319
320#endif /* __KERNEL__ */
321#endif /* __AUFS_BRANCH_H__ */