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