summaryrefslogtreecommitdiff
path: root/fs/aufs/hfsnotify.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/aufs/hfsnotify.c')
-rw-r--r--fs/aufs/hfsnotify.c288
1 files changed, 0 insertions, 288 deletions
diff --git a/fs/aufs/hfsnotify.c b/fs/aufs/hfsnotify.c
deleted file mode 100644
index dc4f6c3c9..000000000
--- a/fs/aufs/hfsnotify.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Junjiro R. Okajima
- *
- * This program, aufs is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * fsnotify for the lower directories
- */
-
-#include "aufs.h"
-
-/* FS_IN_IGNORED is unnecessary */
-static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE
- | FS_CREATE | FS_EVENT_ON_CHILD);
-static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq);
-static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0);
-
-static void au_hfsn_free_mark(struct fsnotify_mark *mark)
-{
- struct au_hnotify *hn = container_of(mark, struct au_hnotify,
- hn_mark);
- AuDbg("here\n");
- au_cache_free_hnotify(hn);
- smp_mb__before_atomic();
- if (atomic64_dec_and_test(&au_hfsn_ifree))
- wake_up(&au_hfsn_wq);
-}
-
-static int au_hfsn_alloc(struct au_hinode *hinode)
-{
- int err;
- struct au_hnotify *hn;
- struct super_block *sb;
- struct au_branch *br;
- struct fsnotify_mark *mark;
- aufs_bindex_t bindex;
-
- hn = hinode->hi_notify;
- sb = hn->hn_aufs_inode->i_sb;
- bindex = au_br_index(sb, hinode->hi_id);
- br = au_sbr(sb, bindex);
- AuDebugOn(!br->br_hfsn);
-
- mark = &hn->hn_mark;
- fsnotify_init_mark(mark, au_hfsn_free_mark);
- mark->mask = AuHfsnMask;
- /*
- * by udba rename or rmdir, aufs assign a new inode to the known
- * h_inode, so specify 1 to allow dups.
- */
- lockdep_off();
- err = fsnotify_add_mark(mark, br->br_hfsn->hfsn_group, hinode->hi_inode,
- /*mnt*/NULL, /*allow_dups*/1);
- /* even if err */
- fsnotify_put_mark(mark);
- lockdep_on();
-
- return err;
-}
-
-static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn)
-{
- struct fsnotify_mark *mark;
- unsigned long long ull;
- struct fsnotify_group *group;
-
- ull = atomic64_inc_return(&au_hfsn_ifree);
- BUG_ON(!ull);
-
- mark = &hn->hn_mark;
- spin_lock(&mark->lock);
- group = mark->group;
- fsnotify_get_group(group);
- spin_unlock(&mark->lock);
- lockdep_off();
- fsnotify_destroy_mark(mark, group);
- fsnotify_put_group(group);
- lockdep_on();
-
- /* free hn by myself */
- return 0;
-}
-
-/* ---------------------------------------------------------------------- */
-
-static void au_hfsn_ctl(struct au_hinode *hinode, int do_set)
-{
- struct fsnotify_mark *mark;
-
- mark = &hinode->hi_notify->hn_mark;
- spin_lock(&mark->lock);
- if (do_set) {
- AuDebugOn(mark->mask & AuHfsnMask);
- mark->mask |= AuHfsnMask;
- } else {
- AuDebugOn(!(mark->mask & AuHfsnMask));
- mark->mask &= ~AuHfsnMask;
- }
- spin_unlock(&mark->lock);
- /* fsnotify_recalc_inode_mask(hinode->hi_inode); */
-}
-
-/* ---------------------------------------------------------------------- */
-
-/* #define AuDbgHnotify */
-#ifdef AuDbgHnotify
-static char *au_hfsn_name(u32 mask)
-{
-#ifdef CONFIG_AUFS_DEBUG
-#define test_ret(flag) \
- do { \
- if (mask & flag) \
- return #flag; \
- } while (0)
- test_ret(FS_ACCESS);
- test_ret(FS_MODIFY);
- test_ret(FS_ATTRIB);
- test_ret(FS_CLOSE_WRITE);
- test_ret(FS_CLOSE_NOWRITE);
- test_ret(FS_OPEN);
- test_ret(FS_MOVED_FROM);
- test_ret(FS_MOVED_TO);
- test_ret(FS_CREATE);
- test_ret(FS_DELETE);
- test_ret(FS_DELETE_SELF);
- test_ret(FS_MOVE_SELF);
- test_ret(FS_UNMOUNT);
- test_ret(FS_Q_OVERFLOW);
- test_ret(FS_IN_IGNORED);
- test_ret(FS_ISDIR);
- test_ret(FS_IN_ONESHOT);
- test_ret(FS_EVENT_ON_CHILD);
- return "";
-#undef test_ret
-#else
- return "??";
-#endif
-}
-#endif
-
-/* ---------------------------------------------------------------------- */
-
-static void au_hfsn_free_group(struct fsnotify_group *group)
-{
- struct au_br_hfsnotify *hfsn = group->private;
-
- AuDbg("here\n");
- kfree(hfsn);
-}
-
-static int au_hfsn_handle_event(struct fsnotify_group *group,
- struct inode *inode,
- struct fsnotify_mark *inode_mark,
- struct fsnotify_mark *vfsmount_mark,
- u32 mask, void *data, int data_type,
- const unsigned char *file_name, u32 cookie)
-{
- int err;
- struct au_hnotify *hnotify;
- struct inode *h_dir, *h_inode;
- struct qstr h_child_qstr = QSTR_INIT(file_name, strlen(file_name));
-
- AuDebugOn(data_type != FSNOTIFY_EVENT_INODE);
-
- err = 0;
- /* if FS_UNMOUNT happens, there must be another bug */
- AuDebugOn(mask & FS_UNMOUNT);
- if (mask & (FS_IN_IGNORED | FS_UNMOUNT))
- goto out;
-
- h_dir = inode;
- h_inode = NULL;
-#ifdef AuDbgHnotify
- au_debug_on();
- if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1
- || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) {
- AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n",
- h_dir->i_ino, mask, au_hfsn_name(mask),
- AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0);
- /* WARN_ON(1); */
- }
- au_debug_off();
-#endif
-
- AuDebugOn(!inode_mark);
- hnotify = container_of(inode_mark, struct au_hnotify, hn_mark);
- err = au_hnotify(h_dir, hnotify, mask, &h_child_qstr, h_inode);
-
-out:
- return err;
-}
-
-static struct fsnotify_ops au_hfsn_ops = {
- .handle_event = au_hfsn_handle_event,
- .free_group_priv = au_hfsn_free_group
-};
-
-/* ---------------------------------------------------------------------- */
-
-static void au_hfsn_fin_br(struct au_branch *br)
-{
- struct au_br_hfsnotify *hfsn;
-
- hfsn = br->br_hfsn;
- if (hfsn) {
- lockdep_off();
- fsnotify_put_group(hfsn->hfsn_group);
- lockdep_on();
- }
-}
-
-static int au_hfsn_init_br(struct au_branch *br, int perm)
-{
- int err;
- struct fsnotify_group *group;
- struct au_br_hfsnotify *hfsn;
-
- err = 0;
- br->br_hfsn = NULL;
- if (!au_br_hnotifyable(perm))
- goto out;
-
- err = -ENOMEM;
- hfsn = kmalloc(sizeof(*hfsn), GFP_NOFS);
- if (unlikely(!hfsn))
- goto out;
-
- err = 0;
- group = fsnotify_alloc_group(&au_hfsn_ops);
- if (IS_ERR(group)) {
- err = PTR_ERR(group);
- pr_err("fsnotify_alloc_group() failed, %d\n", err);
- goto out_hfsn;
- }
-
- group->private = hfsn;
- hfsn->hfsn_group = group;
- br->br_hfsn = hfsn;
- goto out; /* success */
-
-out_hfsn:
- kfree(hfsn);
-out:
- return err;
-}
-
-static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm)
-{
- int err;
-
- err = 0;
- if (!br->br_hfsn)
- err = au_hfsn_init_br(br, perm);
-
- return err;
-}
-
-/* ---------------------------------------------------------------------- */
-
-static void au_hfsn_fin(void)
-{
- AuDbg("au_hfsn_ifree %lld\n", (long long)atomic64_read(&au_hfsn_ifree));
- wait_event(au_hfsn_wq, !atomic64_read(&au_hfsn_ifree));
-}
-
-const struct au_hnotify_op au_hnotify_op = {
- .ctl = au_hfsn_ctl,
- .alloc = au_hfsn_alloc,
- .free = au_hfsn_free,
-
- .fin = au_hfsn_fin,
-
- .reset_br = au_hfsn_reset_br,
- .fin_br = au_hfsn_fin_br,
- .init_br = au_hfsn_init_br
-};