]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - fs/aufs/super.h
PCI: Disable VF decoding before pcibios_sriov_disable() updates resources
[mirror_ubuntu-artful-kernel.git] / fs / aufs / super.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 * super_block operations
20 */
21
22#ifndef __AUFS_SUPER_H__
23#define __AUFS_SUPER_H__
24
25#ifdef __KERNEL__
26
27#include <linux/fs.h>
28#include <linux/kobject.h>
29#include "rwsem.h"
30#include "spl.h"
31#include "wkq.h"
32
33/* policies to select one among multiple writable branches */
34struct au_wbr_copyup_operations {
35 int (*copyup)(struct dentry *dentry);
36};
37
38#define AuWbr_DIR 1 /* target is a dir */
39#define AuWbr_PARENT (1 << 1) /* always require a parent */
40
41#define au_ftest_wbr(flags, name) ((flags) & AuWbr_##name)
42#define au_fset_wbr(flags, name) { (flags) |= AuWbr_##name; }
43#define au_fclr_wbr(flags, name) { (flags) &= ~AuWbr_##name; }
44
45struct au_wbr_create_operations {
46 int (*create)(struct dentry *dentry, unsigned int flags);
47 int (*init)(struct super_block *sb);
48 int (*fin)(struct super_block *sb);
49};
50
51struct au_wbr_mfs {
52 struct mutex mfs_lock; /* protect this structure */
53 unsigned long mfs_jiffy;
54 unsigned long mfs_expire;
55 aufs_bindex_t mfs_bindex;
56
57 unsigned long long mfsrr_bytes;
58 unsigned long long mfsrr_watermark;
59};
60
61#define AuPlink_NHASH 100
62static inline int au_plink_hash(ino_t ino)
63{
64 return ino % AuPlink_NHASH;
65}
66
67/* File-based Hierarchical Storage Management */
68struct au_fhsm {
69#ifdef CONFIG_AUFS_FHSM
70 /* allow only one process who can receive the notification */
71 spinlock_t fhsm_spin;
72 pid_t fhsm_pid;
73 wait_queue_head_t fhsm_wqh;
74 atomic_t fhsm_readable;
75
76 /* these are protected by si_rwsem */
77 unsigned long fhsm_expire;
78 aufs_bindex_t fhsm_bottom;
79#endif
80};
81
82struct au_branch;
83struct au_sbinfo {
84 /* nowait tasks in the system-wide workqueue */
85 struct au_nowait_tasks si_nowait;
86
87 /*
88 * tried sb->s_umount, but failed due to the dependecy between i_mutex.
89 * rwsem for au_sbinfo is necessary.
90 */
91 struct au_rwsem si_rwsem;
92
93 /*
94 * dirty approach to protect sb->sb_inodes and ->s_files (gone) from
95 * remount.
96 */
97 struct percpu_counter si_ninodes, si_nfiles;
98
99 /* branch management */
100 unsigned int si_generation;
101
102 /* see AuSi_ flags */
103 unsigned char au_si_status;
104
105 aufs_bindex_t si_bbot;
106
107 /* dirty trick to keep br_id plus */
108 unsigned int si_last_br_id :
109 sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1;
110 struct au_branch **si_branch;
111
112 /* policy to select a writable branch */
113 unsigned char si_wbr_copyup;
114 unsigned char si_wbr_create;
115 struct au_wbr_copyup_operations *si_wbr_copyup_ops;
116 struct au_wbr_create_operations *si_wbr_create_ops;
117
118 /* round robin */
119 atomic_t si_wbr_rr_next;
120
121 /* most free space */
122 struct au_wbr_mfs si_wbr_mfs;
123
124 /* File-based Hierarchical Storage Management */
125 struct au_fhsm si_fhsm;
126
127 /* mount flags */
128 /* include/asm-ia64/siginfo.h defines a macro named si_flags */
129 unsigned int si_mntflags;
130
131 /* external inode number (bitmap and translation table) */
132 vfs_readf_t si_xread;
133 vfs_writef_t si_xwrite;
134 struct file *si_xib;
135 struct mutex si_xib_mtx; /* protect xib members */
136 unsigned long *si_xib_buf;
137 unsigned long si_xib_last_pindex;
138 int si_xib_next_bit;
139 aufs_bindex_t si_xino_brid;
140 unsigned long si_xino_jiffy;
141 unsigned long si_xino_expire;
142 /* reserved for future use */
143 /* unsigned long long si_xib_limit; */ /* Max xib file size */
144
145#ifdef CONFIG_AUFS_EXPORT
146 /* i_generation */
147 struct file *si_xigen;
148 atomic_t si_xigen_next;
149#endif
150
151 /* dirty trick to suppoer atomic_open */
152 struct au_sphlhead si_aopen;
153
154 /* vdir parameters */
155 unsigned long si_rdcache; /* max cache time in jiffies */
156 unsigned int si_rdblk; /* deblk size */
157 unsigned int si_rdhash; /* hash size */
158
159 /*
160 * If the number of whiteouts are larger than si_dirwh, leave all of
161 * them after au_whtmp_ren to reduce the cost of rmdir(2).
162 * future fsck.aufs or kernel thread will remove them later.
163 * Otherwise, remove all whiteouts and the dir in rmdir(2).
164 */
165 unsigned int si_dirwh;
166
167 /* pseudo_link list */
168 struct au_sphlhead si_plink[AuPlink_NHASH];
169 wait_queue_head_t si_plink_wq;
170 spinlock_t si_plink_maint_lock;
171 pid_t si_plink_maint_pid;
172
173 /* file list */
174 struct au_sphlhead si_files;
175
176 /* with/without getattr, brother of sb->s_d_op */
177 struct inode_operations *si_iop_array;
178
179 /*
180 * sysfs and lifetime management.
181 * this is not a small structure and it may be a waste of memory in case
182 * of sysfs is disabled, particulary when many aufs-es are mounted.
183 * but using sysfs is majority.
184 */
185 struct kobject si_kobj;
186#ifdef CONFIG_DEBUG_FS
187 struct dentry *si_dbgaufs;
188 struct dentry *si_dbgaufs_plink;
189 struct dentry *si_dbgaufs_xib;
190#ifdef CONFIG_AUFS_EXPORT
191 struct dentry *si_dbgaufs_xigen;
192#endif
193#endif
194
195#ifdef CONFIG_AUFS_SBILIST
196 struct hlist_node si_list;
197#endif
198
199 /* dirty, necessary for unmounting, sysfs and sysrq */
200 struct super_block *si_sb;
201};
202
203/* sbinfo status flags */
204/*
205 * set true when refresh_dirs() failed at remount time.
206 * then try refreshing dirs at access time again.
207 * if it is false, refreshing dirs at access time is unnecesary
208 */
209#define AuSi_FAILED_REFRESH_DIR 1
210#define AuSi_FHSM (1 << 1) /* fhsm is active now */
211#define AuSi_NO_DREVAL (1 << 2) /* disable all d_revalidate */
212
213#ifndef CONFIG_AUFS_FHSM
214#undef AuSi_FHSM
215#define AuSi_FHSM 0
216#endif
217
218static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi,
219 unsigned int flag)
220{
221 AuRwMustAnyLock(&sbi->si_rwsem);
222 return sbi->au_si_status & flag;
223}
224#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name)
225#define au_fset_si(sbinfo, name) do { \
226 AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
227 (sbinfo)->au_si_status |= AuSi_##name; \
228} while (0)
229#define au_fclr_si(sbinfo, name) do { \
230 AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
231 (sbinfo)->au_si_status &= ~AuSi_##name; \
232} while (0)
233
234/* ---------------------------------------------------------------------- */
235
236/* policy to select one among writable branches */
237#define AuWbrCopyup(sbinfo, ...) \
238 ((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__))
239#define AuWbrCreate(sbinfo, ...) \
240 ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__))
241
242/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
243#define AuLock_DW 1 /* write-lock dentry */
244#define AuLock_IR (1 << 1) /* read-lock inode */
245#define AuLock_IW (1 << 2) /* write-lock inode */
246#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */
247#define AuLock_DIRS (1 << 4) /* target is a pair of dirs */
248 /* except RENAME_EXCHANGE */
249#define AuLock_NOPLM (1 << 5) /* return err in plm mode */
250#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */
251#define AuLock_GEN (1 << 7) /* test digen/iigen */
252#define au_ftest_lock(flags, name) ((flags) & AuLock_##name)
253#define au_fset_lock(flags, name) \
254 do { (flags) |= AuLock_##name; } while (0)
255#define au_fclr_lock(flags, name) \
256 do { (flags) &= ~AuLock_##name; } while (0)
257
258/* ---------------------------------------------------------------------- */
259
260/* super.c */
261extern struct file_system_type aufs_fs_type;
262struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
263typedef unsigned long long (*au_arraycb_t)(struct super_block *sb, void *array,
264 unsigned long long max, void *arg);
265void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb,
266 struct super_block *sb, void *arg);
267struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max);
268void au_iarray_free(struct inode **a, unsigned long long max);
269
270/* sbinfo.c */
271void au_si_free(struct kobject *kobj);
272int au_si_alloc(struct super_block *sb);
273int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr, int may_shrink);
274
275unsigned int au_sigen_inc(struct super_block *sb);
276aufs_bindex_t au_new_br_id(struct super_block *sb);
277
278int si_read_lock(struct super_block *sb, int flags);
279int si_write_lock(struct super_block *sb, int flags);
280int aufs_read_lock(struct dentry *dentry, int flags);
281void aufs_read_unlock(struct dentry *dentry, int flags);
282void aufs_write_lock(struct dentry *dentry);
283void aufs_write_unlock(struct dentry *dentry);
284int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags);
285void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
286
287/* wbr_policy.c */
288extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
289extern struct au_wbr_create_operations au_wbr_create_ops[];
290int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst);
291int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex);
292int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t btop);
293
294/* mvdown.c */
295int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *arg);
296
297#ifdef CONFIG_AUFS_FHSM
298/* fhsm.c */
299
300static inline pid_t au_fhsm_pid(struct au_fhsm *fhsm)
301{
302 pid_t pid;
303
304 spin_lock(&fhsm->fhsm_spin);
305 pid = fhsm->fhsm_pid;
306 spin_unlock(&fhsm->fhsm_spin);
307
308 return pid;
309}
310
311void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force);
312void au_fhsm_wrote_all(struct super_block *sb, int force);
313int au_fhsm_fd(struct super_block *sb, int oflags);
314int au_fhsm_br_alloc(struct au_branch *br);
315void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex);
316void au_fhsm_fin(struct super_block *sb);
317void au_fhsm_init(struct au_sbinfo *sbinfo);
318void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec);
319void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo);
320#else
321AuStubVoid(au_fhsm_wrote, struct super_block *sb, aufs_bindex_t bindex,
322 int force)
323AuStubVoid(au_fhsm_wrote_all, struct super_block *sb, int force)
324AuStub(int, au_fhsm_fd, return -EOPNOTSUPP, struct super_block *sb, int oflags)
325AuStub(pid_t, au_fhsm_pid, return 0, struct au_fhsm *fhsm)
326AuStubInt0(au_fhsm_br_alloc, struct au_branch *br)
327AuStubVoid(au_fhsm_set_bottom, struct super_block *sb, aufs_bindex_t bindex)
328AuStubVoid(au_fhsm_fin, struct super_block *sb)
329AuStubVoid(au_fhsm_init, struct au_sbinfo *sbinfo)
330AuStubVoid(au_fhsm_set, struct au_sbinfo *sbinfo, unsigned int sec)
331AuStubVoid(au_fhsm_show, struct seq_file *seq, struct au_sbinfo *sbinfo)
332#endif
333
334/* ---------------------------------------------------------------------- */
335
336static inline struct au_sbinfo *au_sbi(struct super_block *sb)
337{
338 return sb->s_fs_info;
339}
340
341/* ---------------------------------------------------------------------- */
342
343#ifdef CONFIG_AUFS_EXPORT
344int au_test_nfsd(void);
345void au_export_init(struct super_block *sb);
346void au_xigen_inc(struct inode *inode);
347int au_xigen_new(struct inode *inode);
348int au_xigen_set(struct super_block *sb, struct file *base);
349void au_xigen_clr(struct super_block *sb);
350
351static inline int au_busy_or_stale(void)
352{
353 if (!au_test_nfsd())
354 return -EBUSY;
355 return -ESTALE;
356}
357#else
358AuStubInt0(au_test_nfsd, void)
359AuStubVoid(au_export_init, struct super_block *sb)
360AuStubVoid(au_xigen_inc, struct inode *inode)
361AuStubInt0(au_xigen_new, struct inode *inode)
362AuStubInt0(au_xigen_set, struct super_block *sb, struct file *base)
363AuStubVoid(au_xigen_clr, struct super_block *sb)
364AuStub(int, au_busy_or_stale, return -EBUSY, void)
365#endif /* CONFIG_AUFS_EXPORT */
366
367/* ---------------------------------------------------------------------- */
368
369#ifdef CONFIG_AUFS_SBILIST
370/* module.c */
371extern struct au_sphlhead au_sbilist;
372
373static inline void au_sbilist_init(void)
374{
375 au_sphl_init(&au_sbilist);
376}
377
378static inline void au_sbilist_add(struct super_block *sb)
379{
380 au_sphl_add(&au_sbi(sb)->si_list, &au_sbilist);
381}
382
383static inline void au_sbilist_del(struct super_block *sb)
384{
385 au_sphl_del(&au_sbi(sb)->si_list, &au_sbilist);
386}
387
388#ifdef CONFIG_AUFS_MAGIC_SYSRQ
389static inline void au_sbilist_lock(void)
390{
391 spin_lock(&au_sbilist.spin);
392}
393
394static inline void au_sbilist_unlock(void)
395{
396 spin_unlock(&au_sbilist.spin);
397}
398#define AuGFP_SBILIST GFP_ATOMIC
399#else
400AuStubVoid(au_sbilist_lock, void)
401AuStubVoid(au_sbilist_unlock, void)
402#define AuGFP_SBILIST GFP_NOFS
403#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
404#else
405AuStubVoid(au_sbilist_init, void)
406AuStubVoid(au_sbilist_add, struct super_block *sb)
407AuStubVoid(au_sbilist_del, struct super_block *sb)
408AuStubVoid(au_sbilist_lock, void)
409AuStubVoid(au_sbilist_unlock, void)
410#define AuGFP_SBILIST GFP_NOFS
411#endif
412
413/* ---------------------------------------------------------------------- */
414
415static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
416{
417 /*
418 * This function is a dynamic '__init' function actually,
419 * so the tiny check for si_rwsem is unnecessary.
420 */
421 /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
422#ifdef CONFIG_DEBUG_FS
423 sbinfo->si_dbgaufs = NULL;
424 sbinfo->si_dbgaufs_plink = NULL;
425 sbinfo->si_dbgaufs_xib = NULL;
426#ifdef CONFIG_AUFS_EXPORT
427 sbinfo->si_dbgaufs_xigen = NULL;
428#endif
429#endif
430}
431
432/* ---------------------------------------------------------------------- */
433
434/* current->atomic_flags */
435/* this value should never corrupt the ones defined in linux/sched.h */
436#define PFA_AUFS 7
437
438TASK_PFA_TEST(AUFS, test_aufs) /* task_test_aufs */
439TASK_PFA_SET(AUFS, aufs) /* task_set_aufs */
440TASK_PFA_CLEAR(AUFS, aufs) /* task_clear_aufs */
441
442static inline int si_pid_test(struct super_block *sb)
443{
444 return !!task_test_aufs(current);
445}
446
447static inline void si_pid_clr(struct super_block *sb)
448{
449 AuDebugOn(!task_test_aufs(current));
450 task_clear_aufs(current);
451}
452
453static inline void si_pid_set(struct super_block *sb)
454{
455 AuDebugOn(task_test_aufs(current));
456 task_set_aufs(current);
457}
458
459/* ---------------------------------------------------------------------- */
460
461/* lock superblock. mainly for entry point functions */
462/*
463 * __si_read_lock, __si_write_lock,
464 * __si_read_unlock, __si_write_unlock, __si_downgrade_lock
465 */
466AuSimpleRwsemFuncs(__si, struct super_block *sb, &au_sbi(sb)->si_rwsem);
467
468#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem)
469#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
470#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
471
472static inline void si_noflush_read_lock(struct super_block *sb)
473{
474 __si_read_lock(sb);
475 si_pid_set(sb);
476}
477
478static inline int si_noflush_read_trylock(struct super_block *sb)
479{
480 int locked;
481
482 locked = __si_read_trylock(sb);
483 if (locked)
484 si_pid_set(sb);
485 return locked;
486}
487
488static inline void si_noflush_write_lock(struct super_block *sb)
489{
490 __si_write_lock(sb);
491 si_pid_set(sb);
492}
493
494static inline int si_noflush_write_trylock(struct super_block *sb)
495{
496 int locked;
497
498 locked = __si_write_trylock(sb);
499 if (locked)
500 si_pid_set(sb);
501 return locked;
502}
503
504#if 0 /* reserved */
505static inline int si_read_trylock(struct super_block *sb, int flags)
506{
507 if (au_ftest_lock(flags, FLUSH))
508 au_nwt_flush(&au_sbi(sb)->si_nowait);
509 return si_noflush_read_trylock(sb);
510}
511#endif
512
513static inline void si_read_unlock(struct super_block *sb)
514{
515 si_pid_clr(sb);
516 __si_read_unlock(sb);
517}
518
519#if 0 /* reserved */
520static inline int si_write_trylock(struct super_block *sb, int flags)
521{
522 if (au_ftest_lock(flags, FLUSH))
523 au_nwt_flush(&au_sbi(sb)->si_nowait);
524 return si_noflush_write_trylock(sb);
525}
526#endif
527
528static inline void si_write_unlock(struct super_block *sb)
529{
530 si_pid_clr(sb);
531 __si_write_unlock(sb);
532}
533
534#if 0 /* reserved */
535static inline void si_downgrade_lock(struct super_block *sb)
536{
537 __si_downgrade_lock(sb);
538}
539#endif
540
541/* ---------------------------------------------------------------------- */
542
543static inline aufs_bindex_t au_sbbot(struct super_block *sb)
544{
545 SiMustAnyLock(sb);
546 return au_sbi(sb)->si_bbot;
547}
548
549static inline unsigned int au_mntflags(struct super_block *sb)
550{
551 SiMustAnyLock(sb);
552 return au_sbi(sb)->si_mntflags;
553}
554
555static inline unsigned int au_sigen(struct super_block *sb)
556{
557 SiMustAnyLock(sb);
558 return au_sbi(sb)->si_generation;
559}
560
561static inline unsigned long long au_ninodes(struct super_block *sb)
562{
563 s64 n = percpu_counter_sum(&au_sbi(sb)->si_ninodes);
564
565 BUG_ON(n < 0);
566 return n;
567}
568
569static inline void au_ninodes_inc(struct super_block *sb)
570{
571 percpu_counter_inc(&au_sbi(sb)->si_ninodes);
572}
573
574static inline void au_ninodes_dec(struct super_block *sb)
575{
576 percpu_counter_dec(&au_sbi(sb)->si_ninodes);
577}
578
579static inline unsigned long long au_nfiles(struct super_block *sb)
580{
581 s64 n = percpu_counter_sum(&au_sbi(sb)->si_nfiles);
582
583 BUG_ON(n < 0);
584 return n;
585}
586
587static inline void au_nfiles_inc(struct super_block *sb)
588{
589 percpu_counter_inc(&au_sbi(sb)->si_nfiles);
590}
591
592static inline void au_nfiles_dec(struct super_block *sb)
593{
594 percpu_counter_dec(&au_sbi(sb)->si_nfiles);
595}
596
597static inline struct au_branch *au_sbr(struct super_block *sb,
598 aufs_bindex_t bindex)
599{
600 SiMustAnyLock(sb);
601 return au_sbi(sb)->si_branch[0 + bindex];
602}
603
604static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid)
605{
606 SiMustWriteLock(sb);
607 au_sbi(sb)->si_xino_brid = brid;
608}
609
610static inline aufs_bindex_t au_xino_brid(struct super_block *sb)
611{
612 SiMustAnyLock(sb);
613 return au_sbi(sb)->si_xino_brid;
614}
615
616#endif /* __KERNEL__ */
617#endif /* __AUFS_SUPER_H__ */