]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - fs/aufs/inode.h
Revert "UBUNTU: SAUCE: aufs -- Convert to use xattr handlers"
[mirror_ubuntu-zesty-kernel.git] / fs / aufs / inode.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 * inode operations
20 */
21
22#ifndef __AUFS_INODE_H__
23#define __AUFS_INODE_H__
24
25#ifdef __KERNEL__
26
27#include <linux/fsnotify.h>
28#include "rwsem.h"
29
30struct vfsmount;
31
32struct au_hnotify {
33#ifdef CONFIG_AUFS_HNOTIFY
34#ifdef CONFIG_AUFS_HFSNOTIFY
35 /* never use fsnotify_add_vfsmount_mark() */
36 struct fsnotify_mark hn_mark;
37#endif
38 union {
39 struct inode *hn_aufs_inode; /* no get/put */
40 struct llist_node hn_lnode; /* delayed free */
41 };
42#endif
43} ____cacheline_aligned_in_smp;
44
45struct au_hinode {
46 struct inode *hi_inode;
47 aufs_bindex_t hi_id;
48#ifdef CONFIG_AUFS_HNOTIFY
49 struct au_hnotify *hi_notify;
50#endif
51
52 /* reference to the copied-up whiteout with get/put */
53 struct dentry *hi_whdentry;
54};
55
56/* ig_flags */
57#define AuIG_HALF_REFRESHED 1
58#define au_ig_ftest(flags, name) ((flags) & AuIG_##name)
59#define au_ig_fset(flags, name) \
60 do { (flags) |= AuIG_##name; } while (0)
61#define au_ig_fclr(flags, name) \
62 do { (flags) &= ~AuIG_##name; } while (0)
63
64struct au_iigen {
65 spinlock_t ig_spin;
66 __u32 ig_generation, ig_flags;
67};
68
69struct au_vdir;
70struct au_iinfo {
71 struct au_iigen ii_generation;
72 struct super_block *ii_hsb1; /* no get/put */
73
74 struct au_rwsem ii_rwsem;
75 aufs_bindex_t ii_btop, ii_bbot;
76 __u32 ii_higen;
77 struct au_hinode *ii_hinode;
78 struct au_vdir *ii_vdir;
79};
80
81struct au_icntnr {
82 struct au_iinfo iinfo;
83 struct inode vfs_inode;
84 union {
85 struct hlist_node plink;
86 struct llist_node lnode; /* delayed free */
87 };
88} ____cacheline_aligned_in_smp;
89
90/* au_pin flags */
91#define AuPin_DI_LOCKED 1
92#define AuPin_MNT_WRITE (1 << 1)
93#define au_ftest_pin(flags, name) ((flags) & AuPin_##name)
94#define au_fset_pin(flags, name) \
95 do { (flags) |= AuPin_##name; } while (0)
96#define au_fclr_pin(flags, name) \
97 do { (flags) &= ~AuPin_##name; } while (0)
98
99struct au_pin {
100 /* input */
101 struct dentry *dentry;
102 unsigned int udba;
103 unsigned char lsc_di, lsc_hi, flags;
104 aufs_bindex_t bindex;
105
106 /* output */
107 struct dentry *parent;
108 struct au_hinode *hdir;
109 struct vfsmount *h_mnt;
110
111 /* temporary unlock/relock for copyup */
112 struct dentry *h_dentry, *h_parent;
113 struct au_branch *br;
114 struct task_struct *task;
115};
116
117void au_pin_hdir_unlock(struct au_pin *p);
118int au_pin_hdir_lock(struct au_pin *p);
119int au_pin_hdir_relock(struct au_pin *p);
120void au_pin_hdir_acquire_nest(struct au_pin *p);
121void au_pin_hdir_release(struct au_pin *p);
122
123/* ---------------------------------------------------------------------- */
124
125static inline struct au_iinfo *au_ii(struct inode *inode)
126{
127 BUG_ON(is_bad_inode(inode));
128 return &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
129}
130
131/* ---------------------------------------------------------------------- */
132
133/* inode.c */
134struct inode *au_igrab(struct inode *inode);
135void au_refresh_iop(struct inode *inode, int force_getattr);
136int au_refresh_hinode_self(struct inode *inode);
137int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
138int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
139 unsigned int d_type, ino_t *ino);
140struct inode *au_new_inode(struct dentry *dentry, int must_new);
141int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
142 struct inode *inode);
143int au_test_h_perm(struct inode *h_inode, int mask);
144int au_test_h_perm_sio(struct inode *h_inode, int mask);
145
146static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex,
147 ino_t h_ino, unsigned int d_type, ino_t *ino)
148{
149#ifdef CONFIG_AUFS_SHWH
150 return au_ino(sb, bindex, h_ino, d_type, ino);
151#else
152 return 0;
153#endif
154}
155
156/* i_op.c */
157enum {
158 AuIop_SYMLINK,
159 AuIop_DIR,
160 AuIop_OTHER,
161 AuIop_Last
162};
163extern struct inode_operations aufs_iop[AuIop_Last],
164 aufs_iop_nogetattr[AuIop_Last];
165
166/* au_wr_dir flags */
167#define AuWrDir_ADD_ENTRY 1
168#define AuWrDir_ISDIR (1 << 1)
169#define AuWrDir_TMPFILE (1 << 2)
170#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name)
171#define au_fset_wrdir(flags, name) \
172 do { (flags) |= AuWrDir_##name; } while (0)
173#define au_fclr_wrdir(flags, name) \
174 do { (flags) &= ~AuWrDir_##name; } while (0)
175
176struct au_wr_dir_args {
177 aufs_bindex_t force_btgt;
178 unsigned char flags;
179};
180int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
181 struct au_wr_dir_args *args);
182
183struct dentry *au_pinned_h_parent(struct au_pin *pin);
184void au_pin_init(struct au_pin *pin, struct dentry *dentry,
185 aufs_bindex_t bindex, int lsc_di, int lsc_hi,
186 unsigned int udba, unsigned char flags);
187int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
188 unsigned int udba, unsigned char flags) __must_check;
189int au_do_pin(struct au_pin *pin) __must_check;
190void au_unpin(struct au_pin *pin);
191int au_reval_for_attr(struct dentry *dentry, unsigned int sigen);
192
193#define AuIcpup_DID_CPUP 1
194#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name)
195#define au_fset_icpup(flags, name) \
196 do { (flags) |= AuIcpup_##name; } while (0)
197#define au_fclr_icpup(flags, name) \
198 do { (flags) &= ~AuIcpup_##name; } while (0)
199
200struct au_icpup_args {
201 unsigned char flags;
202 unsigned char pin_flags;
203 aufs_bindex_t btgt;
204 unsigned int udba;
205 struct au_pin pin;
206 struct path h_path;
207 struct inode *h_inode;
208};
209
210int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
211 struct au_icpup_args *a);
212
213int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path);
214
215/* i_op_add.c */
216int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
217 struct dentry *h_parent, int isdir);
218int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
219 dev_t dev);
220int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
221int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
222 bool want_excl);
223struct vfsub_aopen_args;
224int au_aopen_or_create(struct inode *dir, struct dentry *dentry,
225 struct vfsub_aopen_args *args);
226int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode);
227int aufs_link(struct dentry *src_dentry, struct inode *dir,
228 struct dentry *dentry);
229int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
230
231/* i_op_del.c */
232int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
233int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
234 struct dentry *h_parent, int isdir);
235int aufs_unlink(struct inode *dir, struct dentry *dentry);
236int aufs_rmdir(struct inode *dir, struct dentry *dentry);
237
238/* i_op_ren.c */
239int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
240int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
41eff299 241 struct inode *dir, struct dentry *dentry);
5b88fdd9
SF
242
243/* iinfo.c */
244struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
245void au_hiput(struct au_hinode *hinode);
246void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
247 struct dentry *h_wh);
248unsigned int au_hi_flags(struct inode *inode, int isdir);
249
250/* hinode flags */
251#define AuHi_XINO 1
252#define AuHi_HNOTIFY (1 << 1)
253#define au_ftest_hi(flags, name) ((flags) & AuHi_##name)
254#define au_fset_hi(flags, name) \
255 do { (flags) |= AuHi_##name; } while (0)
256#define au_fclr_hi(flags, name) \
257 do { (flags) &= ~AuHi_##name; } while (0)
258
259#ifndef CONFIG_AUFS_HNOTIFY
260#undef AuHi_HNOTIFY
261#define AuHi_HNOTIFY 0
262#endif
263
264void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
265 struct inode *h_inode, unsigned int flags);
266
267void au_update_iigen(struct inode *inode, int half);
268void au_update_ibrange(struct inode *inode, int do_put_zero);
269
270void au_icntnr_init_once(void *_c);
271void au_hinode_init(struct au_hinode *hinode);
272int au_iinfo_init(struct inode *inode);
273void au_iinfo_fin(struct inode *inode);
274int au_hinode_realloc(struct au_iinfo *iinfo, int nbr, int may_shrink);
275
276#ifdef CONFIG_PROC_FS
277/* plink.c */
278int au_plink_maint(struct super_block *sb, int flags);
279struct au_sbinfo;
280void au_plink_maint_leave(struct au_sbinfo *sbinfo);
281int au_plink_maint_enter(struct super_block *sb);
282#ifdef CONFIG_AUFS_DEBUG
283void au_plink_list(struct super_block *sb);
284#else
285AuStubVoid(au_plink_list, struct super_block *sb)
286#endif
287int au_plink_test(struct inode *inode);
288struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex);
289void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
290 struct dentry *h_dentry);
291void au_plink_put(struct super_block *sb, int verbose);
292void au_plink_clean(struct super_block *sb, int verbose);
293void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
294#else
295AuStubInt0(au_plink_maint, struct super_block *sb, int flags);
296AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo);
297AuStubInt0(au_plink_maint_enter, struct super_block *sb);
298AuStubVoid(au_plink_list, struct super_block *sb);
299AuStubInt0(au_plink_test, struct inode *inode);
300AuStub(struct dentry *, au_plink_lkup, return NULL,
301 struct inode *inode, aufs_bindex_t bindex);
302AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex,
303 struct dentry *h_dentry);
304AuStubVoid(au_plink_put, struct super_block *sb, int verbose);
305AuStubVoid(au_plink_clean, struct super_block *sb, int verbose);
306AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id);
307#endif /* CONFIG_PROC_FS */
308
309#ifdef CONFIG_AUFS_XATTR
310/* xattr.c */
311int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags,
312 unsigned int verbose);
313ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size);
b7ca57c6
SF
314ssize_t aufs_getxattr(struct dentry *dentry, struct inode *inode,
315 const char *name, void *value, size_t size);
316int aufs_setxattr(struct dentry *dentry, struct inode *inode, const char *name,
317 const void *value, size_t size, int flags);
318int aufs_removexattr(struct dentry *dentry, const char *name);
319
320/* void au_xattr_init(struct super_block *sb); */
5b88fdd9
SF
321#else
322AuStubInt0(au_cpup_xattr, struct dentry *h_dst, struct dentry *h_src,
323 int ignore_flags, unsigned int verbose);
b7ca57c6 324/* AuStubVoid(au_xattr_init, struct super_block *sb); */
5b88fdd9
SF
325#endif
326
327#ifdef CONFIG_FS_POSIX_ACL
328struct posix_acl *aufs_get_acl(struct inode *inode, int type);
329int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
330#endif
331
332#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL)
333enum {
334 AU_XATTR_SET,
335 AU_XATTR_REMOVE,
336 AU_ACL_SET
337};
338
339struct au_srxattr {
340 int type;
341 union {
342 struct {
343 const char *name;
344 const void *value;
345 size_t size;
346 int flags;
347 } set;
348 struct {
349 const char *name;
350 } remove;
351 struct {
352 struct posix_acl *acl;
353 int type;
354 } acl_set;
355 } u;
356};
357ssize_t au_srxattr(struct dentry *dentry, struct inode *inode,
358 struct au_srxattr *arg);
359#endif
360
361/* ---------------------------------------------------------------------- */
362
363/* lock subclass for iinfo */
364enum {
365 AuLsc_II_CHILD, /* child first */
366 AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */
367 AuLsc_II_CHILD3, /* copyup dirs */
368 AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */
369 AuLsc_II_PARENT2,
370 AuLsc_II_PARENT3, /* copyup dirs */
371 AuLsc_II_NEW_CHILD
372};
373
374/*
375 * ii_read_lock_child, ii_write_lock_child,
376 * ii_read_lock_child2, ii_write_lock_child2,
377 * ii_read_lock_child3, ii_write_lock_child3,
378 * ii_read_lock_parent, ii_write_lock_parent,
379 * ii_read_lock_parent2, ii_write_lock_parent2,
380 * ii_read_lock_parent3, ii_write_lock_parent3,
381 * ii_read_lock_new_child, ii_write_lock_new_child,
382 */
383#define AuReadLockFunc(name, lsc) \
384static inline void ii_read_lock_##name(struct inode *i) \
385{ \
386 au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
387}
388
389#define AuWriteLockFunc(name, lsc) \
390static inline void ii_write_lock_##name(struct inode *i) \
391{ \
392 au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
393}
394
395#define AuRWLockFuncs(name, lsc) \
396 AuReadLockFunc(name, lsc) \
397 AuWriteLockFunc(name, lsc)
398
399AuRWLockFuncs(child, CHILD);
400AuRWLockFuncs(child2, CHILD2);
401AuRWLockFuncs(child3, CHILD3);
402AuRWLockFuncs(parent, PARENT);
403AuRWLockFuncs(parent2, PARENT2);
404AuRWLockFuncs(parent3, PARENT3);
405AuRWLockFuncs(new_child, NEW_CHILD);
406
407#undef AuReadLockFunc
408#undef AuWriteLockFunc
409#undef AuRWLockFuncs
410
411/*
412 * ii_read_unlock, ii_write_unlock, ii_downgrade_lock
413 */
414AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem);
415
416#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
417#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
418#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
419
420/* ---------------------------------------------------------------------- */
421
422static inline void au_icntnr_init(struct au_icntnr *c)
423{
424#ifdef CONFIG_AUFS_DEBUG
425 c->vfs_inode.i_mode = 0;
426#endif
427}
428
429static inline unsigned int au_iigen(struct inode *inode, unsigned int *igflags)
430{
431 unsigned int gen;
432 struct au_iinfo *iinfo;
433 struct au_iigen *iigen;
434
435 iinfo = au_ii(inode);
436 iigen = &iinfo->ii_generation;
437 spin_lock(&iigen->ig_spin);
438 if (igflags)
439 *igflags = iigen->ig_flags;
440 gen = iigen->ig_generation;
441 spin_unlock(&iigen->ig_spin);
442
443 return gen;
444}
445
446/* tiny test for inode number */
447/* tmpfs generation is too rough */
448static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
449{
450 struct au_iinfo *iinfo;
451
452 iinfo = au_ii(inode);
453 AuRwMustAnyLock(&iinfo->ii_rwsem);
454 return !(iinfo->ii_hsb1 == h_inode->i_sb
455 && iinfo->ii_higen == h_inode->i_generation);
456}
457
458static inline void au_iigen_dec(struct inode *inode)
459{
460 struct au_iinfo *iinfo;
461 struct au_iigen *iigen;
462
463 iinfo = au_ii(inode);
464 iigen = &iinfo->ii_generation;
465 spin_lock(&iigen->ig_spin);
466 iigen->ig_generation--;
467 spin_unlock(&iigen->ig_spin);
468}
469
470static inline int au_iigen_test(struct inode *inode, unsigned int sigen)
471{
472 int err;
473
474 err = 0;
475 if (unlikely(inode && au_iigen(inode, NULL) != sigen))
476 err = -EIO;
477
478 return err;
479}
480
481/* ---------------------------------------------------------------------- */
482
483static inline struct au_hinode *au_hinode(struct au_iinfo *iinfo,
484 aufs_bindex_t bindex)
485{
486 return iinfo->ii_hinode + bindex;
487}
488
489static inline int au_is_bad_inode(struct inode *inode)
490{
491 return !!(is_bad_inode(inode) || !au_hinode(au_ii(inode), 0));
492}
493
494static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
495 aufs_bindex_t bindex)
496{
497 IiMustAnyLock(inode);
498 return au_hinode(au_ii(inode), bindex)->hi_id;
499}
500
501static inline aufs_bindex_t au_ibtop(struct inode *inode)
502{
503 IiMustAnyLock(inode);
504 return au_ii(inode)->ii_btop;
505}
506
507static inline aufs_bindex_t au_ibbot(struct inode *inode)
508{
509 IiMustAnyLock(inode);
510 return au_ii(inode)->ii_bbot;
511}
512
513static inline struct au_vdir *au_ivdir(struct inode *inode)
514{
515 IiMustAnyLock(inode);
516 return au_ii(inode)->ii_vdir;
517}
518
519static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
520{
521 IiMustAnyLock(inode);
522 return au_hinode(au_ii(inode), bindex)->hi_whdentry;
523}
524
525static inline void au_set_ibtop(struct inode *inode, aufs_bindex_t bindex)
526{
527 IiMustWriteLock(inode);
528 au_ii(inode)->ii_btop = bindex;
529}
530
531static inline void au_set_ibbot(struct inode *inode, aufs_bindex_t bindex)
532{
533 IiMustWriteLock(inode);
534 au_ii(inode)->ii_bbot = bindex;
535}
536
537static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
538{
539 IiMustWriteLock(inode);
540 au_ii(inode)->ii_vdir = vdir;
541}
542
543static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
544{
545 IiMustAnyLock(inode);
546 return au_hinode(au_ii(inode), bindex);
547}
548
549/* ---------------------------------------------------------------------- */
550
551static inline struct dentry *au_pinned_parent(struct au_pin *pin)
552{
553 if (pin)
554 return pin->parent;
555 return NULL;
556}
557
558static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
559{
560 if (pin && pin->hdir)
561 return pin->hdir->hi_inode;
562 return NULL;
563}
564
565static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin)
566{
567 if (pin)
568 return pin->hdir;
569 return NULL;
570}
571
572static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
573{
574 if (pin)
575 pin->dentry = dentry;
576}
577
578static inline void au_pin_set_parent_lflag(struct au_pin *pin,
579 unsigned char lflag)
580{
581 if (pin) {
582 if (lflag)
583 au_fset_pin(pin->flags, DI_LOCKED);
584 else
585 au_fclr_pin(pin->flags, DI_LOCKED);
586 }
587}
588
589#if 0 /* reserved */
590static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
591{
592 if (pin) {
593 dput(pin->parent);
594 pin->parent = dget(parent);
595 }
596}
597#endif
598
599/* ---------------------------------------------------------------------- */
600
601struct au_branch;
602#ifdef CONFIG_AUFS_HNOTIFY
603struct au_hnotify_op {
604 void (*ctl)(struct au_hinode *hinode, int do_set);
605 int (*alloc)(struct au_hinode *hinode);
606
607 /*
608 * if it returns true, the the caller should free hinode->hi_notify,
609 * otherwise ->free() frees it.
610 */
611 int (*free)(struct au_hinode *hinode,
612 struct au_hnotify *hn) __must_check;
613
614 void (*fin)(void);
615 int (*init)(void);
616
617 int (*reset_br)(unsigned int udba, struct au_branch *br, int perm);
618 void (*fin_br)(struct au_branch *br);
619 int (*init_br)(struct au_branch *br, int perm);
620};
621
622/* hnotify.c */
623int au_hn_alloc(struct au_hinode *hinode, struct inode *inode);
624void au_hn_free(struct au_hinode *hinode);
625void au_hn_ctl(struct au_hinode *hinode, int do_set);
626void au_hn_reset(struct inode *inode, unsigned int flags);
627int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
628 struct qstr *h_child_qstr, struct inode *h_child_inode);
629int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm);
630int au_hnotify_init_br(struct au_branch *br, int perm);
631void au_hnotify_fin_br(struct au_branch *br);
632int __init au_hnotify_init(void);
633void au_hnotify_fin(void);
634
635/* hfsnotify.c */
636extern const struct au_hnotify_op au_hnotify_op;
637
638static inline
639void au_hn_init(struct au_hinode *hinode)
640{
641 hinode->hi_notify = NULL;
642}
643
644static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
645{
646 return hinode->hi_notify;
647}
648
649#else
650AuStub(int, au_hn_alloc, return -EOPNOTSUPP,
651 struct au_hinode *hinode __maybe_unused,
652 struct inode *inode __maybe_unused)
653AuStub(struct au_hnotify *, au_hn, return NULL, struct au_hinode *hinode)
654AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused)
655AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused,
656 int do_set __maybe_unused)
657AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused,
658 unsigned int flags __maybe_unused)
659AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused,
660 struct au_branch *br __maybe_unused,
661 int perm __maybe_unused)
662AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused,
663 int perm __maybe_unused)
664AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused)
665AuStubInt0(__init au_hnotify_init, void)
666AuStubVoid(au_hnotify_fin, void)
667AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused)
668#endif /* CONFIG_AUFS_HNOTIFY */
669
670static inline void au_hn_suspend(struct au_hinode *hdir)
671{
672 au_hn_ctl(hdir, /*do_set*/0);
673}
674
675static inline void au_hn_resume(struct au_hinode *hdir)
676{
677 au_hn_ctl(hdir, /*do_set*/1);
678}
679
680static inline void au_hn_inode_lock(struct au_hinode *hdir)
681{
682 inode_lock(hdir->hi_inode);
683 au_hn_suspend(hdir);
684}
685
686static inline void au_hn_inode_lock_nested(struct au_hinode *hdir,
687 unsigned int sc __maybe_unused)
688{
689 inode_lock_nested(hdir->hi_inode, sc);
690 au_hn_suspend(hdir);
691}
692
693static inline void au_hn_inode_unlock(struct au_hinode *hdir)
694{
695 au_hn_resume(hdir);
696 inode_unlock(hdir->hi_inode);
697}
698
699#endif /* __KERNEL__ */
700#endif /* __AUFS_INODE_H__ */