From ae7b8f4108bcffb42173f867ce845268c7202d48 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Thu, 17 Dec 2009 20:12:04 -0500 Subject: Audit: clean up the audit_watch split No real changes, just cleanup to the audit_watch split patch which we done with minimal code changes for easy review. Now fix interfaces to make things work better. Signed-off-by: Eric Paris --- kernel/auditsc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'kernel/auditsc.c') diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 3828ad5fb8f..240063c370e 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -549,9 +549,8 @@ static int audit_filter_rules(struct task_struct *tsk, } break; case AUDIT_WATCH: - if (name && audit_watch_inode(rule->watch) != (unsigned long)-1) - result = (name->dev == audit_watch_dev(rule->watch) && - name->ino == audit_watch_inode(rule->watch)); + if (name) + result = audit_watch_compare(rule->watch, name->ino, name->dev); break; case AUDIT_DIR: if (ctx) -- cgit v1.2.3 From 28a3a7eb3b1f3e7d834e19f06e794e429058a4dd Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Thu, 17 Dec 2009 20:12:05 -0500 Subject: audit: reimplement audit_trees using fsnotify rather than inotify Simply switch audit_trees from using inotify to using fsnotify for it's inode pinning and disappearing act information. Signed-off-by: Eric Paris --- include/linux/fsnotify_backend.h | 5 +- init/Kconfig | 2 +- kernel/audit_tree.c | 234 ++++++++++++++++++++++----------------- kernel/auditsc.c | 4 +- 4 files changed, 136 insertions(+), 109 deletions(-) (limited to 'kernel/auditsc.c') diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 1679f250d59..e2528437102 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -62,8 +62,9 @@ /* listeners that hard code group numbers near the top */ #define DNOTIFY_GROUP_NUM UINT_MAX -#define AUDIT_WATCH_GROUP_NUM (DNOTIFY_GROUP_NUM-1) -#define INOTIFY_GROUP_NUM (AUDIT_WATCH_GROUP_NUM-1) +#define AUDIT_WATCH_GROUP_NUM (DNOTIFY_GROUP_NUM-1) +#define AUDIT_TREE_GROUP_NUM (AUDIT_WATCH_GROUP_NUM-1) +#define INOTIFY_GROUP_NUM (AUDIT_TREE_GROUP_NUM-1) struct fsnotify_group; struct fsnotify_event; diff --git a/init/Kconfig b/init/Kconfig index 5cff9a980c3..84e33c49a0c 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -326,7 +326,7 @@ config AUDITSYSCALL config AUDIT_TREE def_bool y depends on AUDITSYSCALL - select INOTIFY + select FSNOTIFY menu "RCU Subsystem" diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index 46a57b57a33..a164600dd82 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c @@ -1,5 +1,5 @@ #include "audit.h" -#include +#include #include #include #include @@ -22,7 +22,7 @@ struct audit_tree { struct audit_chunk { struct list_head hash; - struct inotify_watch watch; + struct fsnotify_mark_entry mark; struct list_head trees; /* with root here */ int dead; int count; @@ -59,7 +59,7 @@ static LIST_HEAD(prune_list); * tree is refcounted; one reference for "some rules on rules_list refer to * it", one for each chunk with pointer to it. * - * chunk is refcounted by embedded inotify_watch + .refs (non-zero refcount + * chunk is refcounted by embedded fsnotify_mark + .refs (non-zero refcount * of watch contributes 1 to .refs). * * node.index allows to get from node.list to containing chunk. @@ -68,7 +68,7 @@ static LIST_HEAD(prune_list); * that makes a difference. Some. */ -static struct inotify_handle *rtree_ih; +static struct fsnotify_group *audit_tree_group; static struct audit_tree *alloc_tree(const char *s) { @@ -111,29 +111,6 @@ const char *audit_tree_path(struct audit_tree *tree) return tree->pathname; } -static struct audit_chunk *alloc_chunk(int count) -{ - struct audit_chunk *chunk; - size_t size; - int i; - - size = offsetof(struct audit_chunk, owners) + count * sizeof(struct node); - chunk = kzalloc(size, GFP_KERNEL); - if (!chunk) - return NULL; - - INIT_LIST_HEAD(&chunk->hash); - INIT_LIST_HEAD(&chunk->trees); - chunk->count = count; - atomic_long_set(&chunk->refs, 1); - for (i = 0; i < count; i++) { - INIT_LIST_HEAD(&chunk->owners[i].list); - chunk->owners[i].index = i; - } - inotify_init_watch(&chunk->watch); - return chunk; -} - static void free_chunk(struct audit_chunk *chunk) { int i; @@ -157,6 +134,35 @@ static void __put_chunk(struct rcu_head *rcu) audit_put_chunk(chunk); } +static void audit_tree_destroy_watch(struct fsnotify_mark_entry *entry) +{ + struct audit_chunk *chunk = container_of(entry, struct audit_chunk, mark); + call_rcu(&chunk->head, __put_chunk); +} + +static struct audit_chunk *alloc_chunk(int count) +{ + struct audit_chunk *chunk; + size_t size; + int i; + + size = offsetof(struct audit_chunk, owners) + count * sizeof(struct node); + chunk = kzalloc(size, GFP_KERNEL); + if (!chunk) + return NULL; + + INIT_LIST_HEAD(&chunk->hash); + INIT_LIST_HEAD(&chunk->trees); + chunk->count = count; + atomic_long_set(&chunk->refs, 1); + for (i = 0; i < count; i++) { + INIT_LIST_HEAD(&chunk->owners[i].list); + chunk->owners[i].index = i; + } + fsnotify_init_mark(&chunk->mark, audit_tree_destroy_watch); + return chunk; +} + enum {HASH_SIZE = 128}; static struct list_head chunk_hash_heads[HASH_SIZE]; static __cacheline_aligned_in_smp DEFINE_SPINLOCK(hash_lock); @@ -167,10 +173,15 @@ static inline struct list_head *chunk_hash(const struct inode *inode) return chunk_hash_heads + n % HASH_SIZE; } -/* hash_lock is held by caller */ +/* hash_lock & entry->lock is held by caller */ static void insert_hash(struct audit_chunk *chunk) { - struct list_head *list = chunk_hash(chunk->watch.inode); + struct fsnotify_mark_entry *entry = &chunk->mark; + struct list_head *list; + + if (!entry->inode) + return; + list = chunk_hash(entry->inode); list_add_rcu(&chunk->hash, list); } @@ -181,7 +192,8 @@ struct audit_chunk *audit_tree_lookup(const struct inode *inode) struct audit_chunk *p; list_for_each_entry_rcu(p, list, hash) { - if (p->watch.inode == inode) { + /* mark.inode may have gone NULL, but who cares? */ + if (p->mark.inode == inode) { atomic_long_inc(&p->refs); return p; } @@ -210,38 +222,19 @@ static struct audit_chunk *find_chunk(struct node *p) static void untag_chunk(struct node *p) { struct audit_chunk *chunk = find_chunk(p); + struct fsnotify_mark_entry *entry = &chunk->mark; struct audit_chunk *new; struct audit_tree *owner; int size = chunk->count - 1; int i, j; - if (!pin_inotify_watch(&chunk->watch)) { - /* - * Filesystem is shutting down; all watches are getting - * evicted, just take it off the node list for this - * tree and let the eviction logics take care of the - * rest. - */ - owner = p->owner; - if (owner->root == chunk) { - list_del_init(&owner->same_root); - owner->root = NULL; - } - list_del_init(&p->list); - p->owner = NULL; - put_tree(owner); - return; - } + fsnotify_get_mark(entry); spin_unlock(&hash_lock); - /* - * pin_inotify_watch() succeeded, so the watch won't go away - * from under us. - */ - mutex_lock(&chunk->watch.inode->inotify_mutex); - if (chunk->dead) { - mutex_unlock(&chunk->watch.inode->inotify_mutex); + spin_lock(&entry->lock); + if (chunk->dead || !entry->inode) { + spin_unlock(&entry->lock); goto out; } @@ -256,16 +249,17 @@ static void untag_chunk(struct node *p) list_del_init(&p->list); list_del_rcu(&chunk->hash); spin_unlock(&hash_lock); - inotify_evict_watch(&chunk->watch); - mutex_unlock(&chunk->watch.inode->inotify_mutex); - put_inotify_watch(&chunk->watch); + spin_unlock(&entry->lock); + fsnotify_destroy_mark_by_entry(entry); + fsnotify_put_mark(entry); goto out; } new = alloc_chunk(size); if (!new) goto Fallback; - if (inotify_clone_watch(&chunk->watch, &new->watch) < 0) { + fsnotify_duplicate_mark(&new->mark, entry); + if (fsnotify_add_mark(&new->mark, new->mark.group, new->mark.inode, 1)) { free_chunk(new); goto Fallback; } @@ -298,9 +292,9 @@ static void untag_chunk(struct node *p) list_for_each_entry(owner, &new->trees, same_root) owner->root = new; spin_unlock(&hash_lock); - inotify_evict_watch(&chunk->watch); - mutex_unlock(&chunk->watch.inode->inotify_mutex); - put_inotify_watch(&chunk->watch); + spin_unlock(&entry->lock); + fsnotify_destroy_mark_by_entry(entry); + fsnotify_put_mark(entry); goto out; Fallback: @@ -314,31 +308,33 @@ Fallback: p->owner = NULL; put_tree(owner); spin_unlock(&hash_lock); - mutex_unlock(&chunk->watch.inode->inotify_mutex); + spin_unlock(&entry->lock); out: - unpin_inotify_watch(&chunk->watch); + fsnotify_put_mark(entry); spin_lock(&hash_lock); } static int create_chunk(struct inode *inode, struct audit_tree *tree) { + struct fsnotify_mark_entry *entry; struct audit_chunk *chunk = alloc_chunk(1); if (!chunk) return -ENOMEM; - if (inotify_add_watch(rtree_ih, &chunk->watch, inode, IN_IGNORED | IN_DELETE_SELF) < 0) { + entry = &chunk->mark; + if (fsnotify_add_mark(entry, audit_tree_group, inode, 0)) { free_chunk(chunk); return -ENOSPC; } - mutex_lock(&inode->inotify_mutex); + spin_lock(&entry->lock); spin_lock(&hash_lock); if (tree->goner) { spin_unlock(&hash_lock); chunk->dead = 1; - inotify_evict_watch(&chunk->watch); - mutex_unlock(&inode->inotify_mutex); - put_inotify_watch(&chunk->watch); + spin_unlock(&entry->lock); + fsnotify_destroy_mark_by_entry(entry); + fsnotify_put_mark(entry); return 0; } chunk->owners[0].index = (1U << 31); @@ -351,30 +347,33 @@ static int create_chunk(struct inode *inode, struct audit_tree *tree) } insert_hash(chunk); spin_unlock(&hash_lock); - mutex_unlock(&inode->inotify_mutex); + spin_unlock(&entry->lock); return 0; } /* the first tagged inode becomes root of tree */ static int tag_chunk(struct inode *inode, struct audit_tree *tree) { - struct inotify_watch *watch; + struct fsnotify_mark_entry *old_entry, *chunk_entry; struct audit_tree *owner; struct audit_chunk *chunk, *old; struct node *p; int n; - if (inotify_find_watch(rtree_ih, inode, &watch) < 0) + spin_lock(&inode->i_lock); + old_entry = fsnotify_find_mark_entry(audit_tree_group, inode); + spin_unlock(&inode->i_lock); + if (!old_entry) return create_chunk(inode, tree); - old = container_of(watch, struct audit_chunk, watch); + old = container_of(old_entry, struct audit_chunk, mark); /* are we already there? */ spin_lock(&hash_lock); for (n = 0; n < old->count; n++) { if (old->owners[n].owner == tree) { spin_unlock(&hash_lock); - put_inotify_watch(&old->watch); + fsnotify_put_mark(old_entry); return 0; } } @@ -382,25 +381,44 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) chunk = alloc_chunk(old->count + 1); if (!chunk) { - put_inotify_watch(&old->watch); + fsnotify_put_mark(old_entry); return -ENOMEM; } - mutex_lock(&inode->inotify_mutex); - if (inotify_clone_watch(&old->watch, &chunk->watch) < 0) { - mutex_unlock(&inode->inotify_mutex); - put_inotify_watch(&old->watch); + chunk_entry = &chunk->mark; + + spin_lock(&old_entry->lock); + if (!old_entry->inode) { + /* old_entry is being shot, lets just lie */ + spin_unlock(&old_entry->lock); + fsnotify_put_mark(old_entry); free_chunk(chunk); + return -ENOENT; + } + + fsnotify_duplicate_mark(chunk_entry, old_entry); + if (fsnotify_add_mark(chunk_entry, chunk_entry->group, chunk_entry->inode, 1)) { + spin_unlock(&old_entry->lock); + free_chunk(chunk); + fsnotify_put_mark(old_entry); return -ENOSPC; } + + /* even though we hold old_entry->lock, this is safe since chunk_entry->lock could NEVER have been grabbed before */ + spin_lock(&chunk_entry->lock); spin_lock(&hash_lock); + + /* we now hold old_entry->lock, chunk_entry->lock, and hash_lock */ if (tree->goner) { spin_unlock(&hash_lock); chunk->dead = 1; - inotify_evict_watch(&chunk->watch); - mutex_unlock(&inode->inotify_mutex); - put_inotify_watch(&old->watch); - put_inotify_watch(&chunk->watch); + spin_unlock(&chunk_entry->lock); + spin_unlock(&old_entry->lock); + + fsnotify_destroy_mark_by_entry(chunk_entry); + + fsnotify_put_mark(chunk_entry); + fsnotify_put_mark(old_entry); return 0; } list_replace_init(&old->trees, &chunk->trees); @@ -426,10 +444,11 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) list_add(&tree->same_root, &chunk->trees); } spin_unlock(&hash_lock); - inotify_evict_watch(&old->watch); - mutex_unlock(&inode->inotify_mutex); - put_inotify_watch(&old->watch); /* pair to inotify_find_watch */ - put_inotify_watch(&old->watch); /* and kill it */ + spin_unlock(&chunk_entry->lock); + spin_unlock(&old_entry->lock); + fsnotify_destroy_mark_by_entry(old_entry); + fsnotify_put_mark(old_entry); /* pair to fsnotify_find mark_entry */ + fsnotify_put_mark(old_entry); /* and kill it */ return 0; } @@ -584,7 +603,9 @@ void audit_trim_trees(void) spin_lock(&hash_lock); list_for_each_entry(node, &tree->chunks, list) { - struct inode *inode = find_chunk(node)->watch.inode; + struct audit_chunk *chunk = find_chunk(node); + /* this could be NULL if the watch is dieing else where... */ + struct inode *inode = chunk->mark.inode; node->index |= 1U<<31; if (iterate_mounts(compare_root, inode, root_mnt)) node->index &= ~(1U<<31); @@ -846,7 +867,6 @@ void audit_kill_trees(struct list_head *list) * Here comes the stuff asynchronous to auditctl operations */ -/* inode->inotify_mutex is locked */ static void evict_chunk(struct audit_chunk *chunk) { struct audit_tree *owner; @@ -885,35 +905,41 @@ static void evict_chunk(struct audit_chunk *chunk) mutex_unlock(&audit_filter_mutex); } -static void handle_event(struct inotify_watch *watch, u32 wd, u32 mask, - u32 cookie, const char *dname, struct inode *inode) +static int audit_tree_handle_event(struct fsnotify_group *group, struct fsnotify_event *event) { - struct audit_chunk *chunk = container_of(watch, struct audit_chunk, watch); + BUG(); + return -EOPNOTSUPP; +} - if (mask & IN_IGNORED) { - evict_chunk(chunk); - put_inotify_watch(watch); - } +static void audit_tree_freeing_mark(struct fsnotify_mark_entry *entry, struct fsnotify_group *group) +{ + struct audit_chunk *chunk = container_of(entry, struct audit_chunk, mark); + + evict_chunk(chunk); + fsnotify_put_mark(entry); } -static void destroy_watch(struct inotify_watch *watch) +static bool audit_tree_send_event(struct fsnotify_group *group, struct inode *inode, __u32 mask) { - struct audit_chunk *chunk = container_of(watch, struct audit_chunk, watch); - call_rcu(&chunk->head, __put_chunk); + return 0; } -static const struct inotify_operations rtree_inotify_ops = { - .handle_event = handle_event, - .destroy_watch = destroy_watch, +static const struct fsnotify_ops audit_tree_ops = { + .handle_event = audit_tree_handle_event, + .should_send_event = audit_tree_send_event, + .free_group_priv = NULL, + .free_event_priv = NULL, + .freeing_mark = audit_tree_freeing_mark, }; static int __init audit_tree_init(void) { int i; - rtree_ih = inotify_init(&rtree_inotify_ops); - if (IS_ERR(rtree_ih)) - audit_panic("cannot initialize inotify handle for rectree watches"); + audit_tree_group = fsnotify_obtain_group(AUDIT_TREE_GROUP_NUM, + 0, &audit_tree_ops); + if (IS_ERR(audit_tree_group)) + audit_panic("cannot initialize fsnotify group for rectree watches"); for (i = 0; i < HASH_SIZE; i++) INIT_LIST_HEAD(&chunk_hash_heads[i]); diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 240063c370e..786901cd821 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1725,7 +1725,7 @@ static inline void handle_one(const struct inode *inode) struct audit_tree_refs *p; struct audit_chunk *chunk; int count; - if (likely(list_empty(&inode->inotify_watches))) + if (likely(hlist_empty(&inode->i_fsnotify_mark_entries))) return; context = current->audit_context; p = context->trees; @@ -1768,7 +1768,7 @@ retry: seq = read_seqbegin(&rename_lock); for(;;) { struct inode *inode = d->d_inode; - if (inode && unlikely(!list_empty(&inode->inotify_watches))) { + if (inode && unlikely(!hlist_empty(&inode->i_fsnotify_mark_entries))) { struct audit_chunk *chunk; chunk = audit_tree_lookup(inode); if (chunk) { -- cgit v1.2.3 From 2dfc1cae4c42b93b831b2417540df2b895ab7108 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Thu, 17 Dec 2009 20:30:52 -0500 Subject: inotify: remove inotify in kernel interface nothing uses inotify in the kernel, drop it! Signed-off-by: Eric Paris --- Documentation/feature-removal-schedule.txt | 8 - fs/inode.c | 6 - fs/notify/inotify/Kconfig | 15 - fs/notify/inotify/Makefile | 1 - fs/notify/inotify/inotify.c | 873 ----------------------------- fs/open.c | 1 + include/linux/fs.h | 5 - include/linux/fsnotify.h | 50 +- include/linux/inotify.h | 174 ------ kernel/auditsc.c | 1 - 10 files changed, 4 insertions(+), 1130 deletions(-) delete mode 100644 fs/notify/inotify/inotify.c (limited to 'kernel/auditsc.c') diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 1571c0c83db..a8188bd3dab 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -367,14 +367,6 @@ When: 2.6.33 Why: Should be implemented in userspace, policy daemon. Who: Johannes Berg ---------------------------- - -What: CONFIG_INOTIFY -When: 2.6.33 -Why: last user (audit) will be converted to the newer more generic - and more easily maintained fsnotify subsystem -Who: Eric Paris - ---------------------------- What: lock_policy_rwsem_* and unlock_policy_rwsem_* will not be diff --git a/fs/inode.c b/fs/inode.c index 722860b323a..8e1bee99879 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -264,10 +263,6 @@ void inode_init_once(struct inode *inode) INIT_RAW_PRIO_TREE_ROOT(&inode->i_data.i_mmap); INIT_LIST_HEAD(&inode->i_data.i_mmap_nonlinear); i_size_ordered_init(inode); -#ifdef CONFIG_INOTIFY - INIT_LIST_HEAD(&inode->inotify_watches); - mutex_init(&inode->inotify_mutex); -#endif #ifdef CONFIG_FSNOTIFY INIT_HLIST_HEAD(&inode->i_fsnotify_mark_entries); #endif @@ -413,7 +408,6 @@ int invalidate_inodes(struct super_block *sb) down_write(&iprune_sem); spin_lock(&inode_lock); - inotify_unmount_inodes(&sb->s_inodes); fsnotify_unmount_inodes(&sb->s_inodes); busy = invalidate_list(&sb->s_inodes, &throw_away); spin_unlock(&inode_lock); diff --git a/fs/notify/inotify/Kconfig b/fs/notify/inotify/Kconfig index b3a159b21cf..b981fc0c837 100644 --- a/fs/notify/inotify/Kconfig +++ b/fs/notify/inotify/Kconfig @@ -1,18 +1,3 @@ -config INOTIFY - bool "Inotify file change notification support" - default n - ---help--- - Say Y here to enable legacy in kernel inotify support. Inotify is a - file change notification system. It is a replacement for dnotify. - This option only provides the legacy inotify in kernel API. There - are no in tree kernel users of this interface since it is deprecated. - You only need this if you are loading an out of tree kernel module - that uses inotify. - - For more information, see - - If unsure, say N. - config INOTIFY_USER bool "Inotify support for userspace" select ANON_INODES diff --git a/fs/notify/inotify/Makefile b/fs/notify/inotify/Makefile index 94382817136..a380dabe09d 100644 --- a/fs/notify/inotify/Makefile +++ b/fs/notify/inotify/Makefile @@ -1,2 +1 @@ -obj-$(CONFIG_INOTIFY) += inotify.o obj-$(CONFIG_INOTIFY_USER) += inotify_fsnotify.o inotify_user.o diff --git a/fs/notify/inotify/inotify.c b/fs/notify/inotify/inotify.c deleted file mode 100644 index 27b75ebc746..00000000000 --- a/fs/notify/inotify/inotify.c +++ /dev/null @@ -1,873 +0,0 @@ -/* - * fs/inotify.c - inode-based file event notifications - * - * Authors: - * John McCutchan - * Robert Love - * - * Kernel API added by: Amy Griffis - * - * Copyright (C) 2005 John McCutchan - * Copyright 2006 Hewlett-Packard Development Company, L.P. - * - * This program 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, 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static atomic_t inotify_cookie; - -/* - * Lock ordering: - * - * dentry->d_lock (used to keep d_move() away from dentry->d_parent) - * iprune_mutex (synchronize shrink_icache_memory()) - * inode_lock (protects the super_block->s_inodes list) - * inode->inotify_mutex (protects inode->inotify_watches and watches->i_list) - * inotify_handle->mutex (protects inotify_handle and watches->h_list) - * - * The inode->inotify_mutex and inotify_handle->mutex and held during execution - * of a caller's event handler. Thus, the caller must not hold any locks - * taken in their event handler while calling any of the published inotify - * interfaces. - */ - -/* - * Lifetimes of the three main data structures--inotify_handle, inode, and - * inotify_watch--are managed by reference count. - * - * inotify_handle: Lifetime is from inotify_init() to inotify_destroy(). - * Additional references can bump the count via get_inotify_handle() and drop - * the count via put_inotify_handle(). - * - * inotify_watch: for inotify's purposes, lifetime is from inotify_add_watch() - * to remove_watch_no_event(). Additional references can bump the count via - * get_inotify_watch() and drop the count via put_inotify_watch(). The caller - * is reponsible for the final put after receiving IN_IGNORED, or when using - * IN_ONESHOT after receiving the first event. Inotify does the final put if - * inotify_destroy() is called. - * - * inode: Pinned so long as the inode is associated with a watch, from - * inotify_add_watch() to the final put_inotify_watch(). - */ - -/* - * struct inotify_handle - represents an inotify instance - * - * This structure is protected by the mutex 'mutex'. - */ -struct inotify_handle { - struct idr idr; /* idr mapping wd -> watch */ - struct mutex mutex; /* protects this bad boy */ - struct list_head watches; /* list of watches */ - atomic_t count; /* reference count */ - u32 last_wd; /* the last wd allocated */ - const struct inotify_operations *in_ops; /* inotify caller operations */ -}; - -static inline void get_inotify_handle(struct inotify_handle *ih) -{ - atomic_inc(&ih->count); -} - -static inline void put_inotify_handle(struct inotify_handle *ih) -{ - if (atomic_dec_and_test(&ih->count)) { - idr_destroy(&ih->idr); - kfree(ih); - } -} - -/** - * get_inotify_watch - grab a reference to an inotify_watch - * @watch: watch to grab - */ -void get_inotify_watch(struct inotify_watch *watch) -{ - atomic_inc(&watch->count); -} -EXPORT_SYMBOL_GPL(get_inotify_watch); - -int pin_inotify_watch(struct inotify_watch *watch) -{ - struct super_block *sb = watch->inode->i_sb; - if (atomic_inc_not_zero(&sb->s_active)) { - atomic_inc(&watch->count); - return 1; - } - return 0; -} - -/** - * put_inotify_watch - decrements the ref count on a given watch. cleans up - * watch references if the count reaches zero. inotify_watch is freed by - * inotify callers via the destroy_watch() op. - * @watch: watch to release - */ -void put_inotify_watch(struct inotify_watch *watch) -{ - if (atomic_dec_and_test(&watch->count)) { - struct inotify_handle *ih = watch->ih; - - iput(watch->inode); - ih->in_ops->destroy_watch(watch); - put_inotify_handle(ih); - } -} -EXPORT_SYMBOL_GPL(put_inotify_watch); - -void unpin_inotify_watch(struct inotify_watch *watch) -{ - struct super_block *sb = watch->inode->i_sb; - put_inotify_watch(watch); - deactivate_super(sb); -} - -/* - * inotify_handle_get_wd - returns the next WD for use by the given handle - * - * Callers must hold ih->mutex. This function can sleep. - */ -static int inotify_handle_get_wd(struct inotify_handle *ih, - struct inotify_watch *watch) -{ - int ret; - - do { - if (unlikely(!idr_pre_get(&ih->idr, GFP_NOFS))) - return -ENOSPC; - ret = idr_get_new_above(&ih->idr, watch, ih->last_wd+1, &watch->wd); - } while (ret == -EAGAIN); - - if (likely(!ret)) - ih->last_wd = watch->wd; - - return ret; -} - -/* - * inotify_inode_watched - returns nonzero if there are watches on this inode - * and zero otherwise. We call this lockless, we do not care if we race. - */ -static inline int inotify_inode_watched(struct inode *inode) -{ - return !list_empty(&inode->inotify_watches); -} - -/* - * Get child dentry flag into synch with parent inode. - * Flag should always be clear for negative dentrys. - */ -static void set_dentry_child_flags(struct inode *inode, int watched) -{ - struct dentry *alias; - - spin_lock(&dcache_lock); - list_for_each_entry(alias, &inode->i_dentry, d_alias) { - struct dentry *child; - - list_for_each_entry(child, &alias->d_subdirs, d_u.d_child) { - if (!child->d_inode) - continue; - - spin_lock(&child->d_lock); - if (watched) - child->d_flags |= DCACHE_INOTIFY_PARENT_WATCHED; - else - child->d_flags &=~DCACHE_INOTIFY_PARENT_WATCHED; - spin_unlock(&child->d_lock); - } - } - spin_unlock(&dcache_lock); -} - -/* - * inotify_find_handle - find the watch associated with the given inode and - * handle - * - * Callers must hold inode->inotify_mutex. - */ -static struct inotify_watch *inode_find_handle(struct inode *inode, - struct inotify_handle *ih) -{ - struct inotify_watch *watch; - - list_for_each_entry(watch, &inode->inotify_watches, i_list) { - if (watch->ih == ih) - return watch; - } - - return NULL; -} - -/* - * remove_watch_no_event - remove watch without the IN_IGNORED event. - * - * Callers must hold both inode->inotify_mutex and ih->mutex. - */ -static void remove_watch_no_event(struct inotify_watch *watch, - struct inotify_handle *ih) -{ - list_del(&watch->i_list); - list_del(&watch->h_list); - - if (!inotify_inode_watched(watch->inode)) - set_dentry_child_flags(watch->inode, 0); - - idr_remove(&ih->idr, watch->wd); -} - -/** - * inotify_remove_watch_locked - Remove a watch from both the handle and the - * inode. Sends the IN_IGNORED event signifying that the inode is no longer - * watched. May be invoked from a caller's event handler. - * @ih: inotify handle associated with watch - * @watch: watch to remove - * - * Callers must hold both inode->inotify_mutex and ih->mutex. - */ -void inotify_remove_watch_locked(struct inotify_handle *ih, - struct inotify_watch *watch) -{ - remove_watch_no_event(watch, ih); - ih->in_ops->handle_event(watch, watch->wd, IN_IGNORED, 0, NULL, NULL); -} -EXPORT_SYMBOL_GPL(inotify_remove_watch_locked); - -/* Kernel API for producing events */ - -/* - * inotify_d_instantiate - instantiate dcache entry for inode - */ -void inotify_d_instantiate(struct dentry *entry, struct inode *inode) -{ - struct dentry *parent; - - if (!inode) - return; - - spin_lock(&entry->d_lock); - parent = entry->d_parent; - if (parent->d_inode && inotify_inode_watched(parent->d_inode)) - entry->d_flags |= DCACHE_INOTIFY_PARENT_WATCHED; - spin_unlock(&entry->d_lock); -} - -/* - * inotify_d_move - dcache entry has been moved - */ -void inotify_d_move(struct dentry *entry) -{ - struct dentry *parent; - - parent = entry->d_parent; - if (inotify_inode_watched(parent->d_inode)) - entry->d_flags |= DCACHE_INOTIFY_PARENT_WATCHED; - else - entry->d_flags &= ~DCACHE_INOTIFY_PARENT_WATCHED; -} - -/** - * inotify_inode_queue_event - queue an event to all watches on this inode - * @inode: inode event is originating from - * @mask: event mask describing this event - * @cookie: cookie for synchronization, or zero - * @name: filename, if any - * @n_inode: inode associated with name - */ -void inotify_inode_queue_event(struct inode *inode, u32 mask, u32 cookie, - const char *name, struct inode *n_inode) -{ - struct inotify_watch *watch, *next; - - if (!inotify_inode_watched(inode)) - return; - - mutex_lock(&inode->inotify_mutex); - list_for_each_entry_safe(watch, next, &inode->inotify_watches, i_list) { - u32 watch_mask = watch->mask; - if (watch_mask & mask) { - struct inotify_handle *ih= watch->ih; - mutex_lock(&ih->mutex); - if (watch_mask & IN_ONESHOT) - remove_watch_no_event(watch, ih); - ih->in_ops->handle_event(watch, watch->wd, mask, cookie, - name, n_inode); - mutex_unlock(&ih->mutex); - } - } - mutex_unlock(&inode->inotify_mutex); -} -EXPORT_SYMBOL_GPL(inotify_inode_queue_event); - -/** - * inotify_dentry_parent_queue_event - queue an event to a dentry's parent - * @dentry: the dentry in question, we queue against this dentry's parent - * @mask: event mask describing this event - * @cookie: cookie for synchronization, or zero - * @name: filename, if any - */ -void inotify_dentry_parent_queue_event(struct dentry *dentry, u32 mask, - u32 cookie, const char *name) -{ - struct dentry *parent; - struct inode *inode; - - if (!(dentry->d_flags & DCACHE_INOTIFY_PARENT_WATCHED)) - return; - - spin_lock(&dentry->d_lock); - parent = dentry->d_parent; - inode = parent->d_inode; - - if (inotify_inode_watched(inode)) { - dget(parent); - spin_unlock(&dentry->d_lock); - inotify_inode_queue_event(inode, mask, cookie, name, - dentry->d_inode); - dput(parent); - } else - spin_unlock(&dentry->d_lock); -} -EXPORT_SYMBOL_GPL(inotify_dentry_parent_queue_event); - -/** - * inotify_get_cookie - return a unique cookie for use in synchronizing events. - */ -u32 inotify_get_cookie(void) -{ - return atomic_inc_return(&inotify_cookie); -} -EXPORT_SYMBOL_GPL(inotify_get_cookie); - -/** - * inotify_unmount_inodes - an sb is unmounting. handle any watched inodes. - * @list: list of inodes being unmounted (sb->s_inodes) - * - * Called with inode_lock held, protecting the unmounting super block's list - * of inodes, and with iprune_mutex held, keeping shrink_icache_memory() at bay. - * We temporarily drop inode_lock, however, and CAN block. - */ -void inotify_unmount_inodes(struct list_head *list) -{ - struct inode *inode, *next_i, *need_iput = NULL; - - list_for_each_entry_safe(inode, next_i, list, i_sb_list) { - struct inotify_watch *watch, *next_w; - struct inode *need_iput_tmp; - struct list_head *watches; - - /* - * We cannot __iget() an inode in state I_CLEAR, I_FREEING, - * I_WILL_FREE, or I_NEW which is fine because by that point - * the inode cannot have any associated watches. - */ - if (inode->i_state & (I_CLEAR|I_FREEING|I_WILL_FREE|I_NEW)) - continue; - - /* - * If i_count is zero, the inode cannot have any watches and - * doing an __iget/iput with MS_ACTIVE clear would actually - * evict all inodes with zero i_count from icache which is - * unnecessarily violent and may in fact be illegal to do. - */ - if (!atomic_read(&inode->i_count)) - continue; - - need_iput_tmp = need_iput; - need_iput = NULL; - /* In case inotify_remove_watch_locked() drops a reference. */ - if (inode != need_iput_tmp) - __iget(inode); - else - need_iput_tmp = NULL; - /* In case the dropping of a reference would nuke next_i. */ - if ((&next_i->i_sb_list != list) && - atomic_read(&next_i->i_count) && - !(next_i->i_state & (I_CLEAR | I_FREEING | - I_WILL_FREE))) { - __iget(next_i); - need_iput = next_i; - } - - /* - * We can safely drop inode_lock here because we hold - * references on both inode and next_i. Also no new inodes - * will be added since the umount has begun. Finally, - * iprune_mutex keeps shrink_icache_memory() away. - */ - spin_unlock(&inode_lock); - - if (need_iput_tmp) - iput(need_iput_tmp); - - /* for each watch, send IN_UNMOUNT and then remove it */ - mutex_lock(&inode->inotify_mutex); - watches = &inode->inotify_watches; - list_for_each_entry_safe(watch, next_w, watches, i_list) { - struct inotify_handle *ih= watch->ih; - get_inotify_watch(watch); - mutex_lock(&ih->mutex); - ih->in_ops->handle_event(watch, watch->wd, IN_UNMOUNT, 0, - NULL, NULL); - inotify_remove_watch_locked(ih, watch); - mutex_unlock(&ih->mutex); - put_inotify_watch(watch); - } - mutex_unlock(&inode->inotify_mutex); - iput(inode); - - spin_lock(&inode_lock); - } -} -EXPORT_SYMBOL_GPL(inotify_unmount_inodes); - -/** - * inotify_inode_is_dead - an inode has been deleted, cleanup any watches - * @inode: inode that is about to be removed - */ -void inotify_inode_is_dead(struct inode *inode) -{ - struct inotify_watch *watch, *next; - - mutex_lock(&inode->inotify_mutex); - list_for_each_entry_safe(watch, next, &inode->inotify_watches, i_list) { - struct inotify_handle *ih = watch->ih; - mutex_lock(&ih->mutex); - inotify_remove_watch_locked(ih, watch); - mutex_unlock(&ih->mutex); - } - mutex_unlock(&inode->inotify_mutex); -} -EXPORT_SYMBOL_GPL(inotify_inode_is_dead); - -/* Kernel Consumer API */ - -/** - * inotify_init - allocate and initialize an inotify instance - * @ops: caller's inotify operations - */ -struct inotify_handle *inotify_init(const struct inotify_operations *ops) -{ - struct inotify_handle *ih; - - ih = kmalloc(sizeof(struct inotify_handle), GFP_KERNEL); - if (unlikely(!ih)) - return ERR_PTR(-ENOMEM); - - idr_init(&ih->idr); - INIT_LIST_HEAD(&ih->watches); - mutex_init(&ih->mutex); - ih->last_wd = 0; - ih->in_ops = ops; - atomic_set(&ih->count, 0); - get_inotify_handle(ih); - - return ih; -} -EXPORT_SYMBOL_GPL(inotify_init); - -/** - * inotify_init_watch - initialize an inotify watch - * @watch: watch to initialize - */ -void inotify_init_watch(struct inotify_watch *watch) -{ - INIT_LIST_HEAD(&watch->h_list); - INIT_LIST_HEAD(&watch->i_list); - atomic_set(&watch->count, 0); - get_inotify_watch(watch); /* initial get */ -} -EXPORT_SYMBOL_GPL(inotify_init_watch); - -/* - * Watch removals suck violently. To kick the watch out we need (in this - * order) inode->inotify_mutex and ih->mutex. That's fine if we have - * a hold on inode; however, for all other cases we need to make damn sure - * we don't race with umount. We can *NOT* just grab a reference to a - * watch - inotify_unmount_inodes() will happily sail past it and we'll end - * with reference to inode potentially outliving its superblock. Ideally - * we just want to grab an active reference to superblock if we can; that - * will make sure we won't go into inotify_umount_inodes() until we are - * done. Cleanup is just deactivate_super(). However, that leaves a messy - * case - what if we *are* racing with umount() and active references to - * superblock can't be acquired anymore? We can bump ->s_count, grab - * ->s_umount, which will wait until the superblock is shut down and the - * watch in question is pining for fjords. - * - * And yes, this is far beyond mere "not very pretty"; so's the entire - * concept of inotify to start with. - */ - -/** - * pin_to_kill - pin the watch down for removal - * @ih: inotify handle - * @watch: watch to kill - * - * Called with ih->mutex held, drops it. Possible return values: - * 0 - nothing to do, it has died - * 1 - remove it, drop the reference and deactivate_super() - */ -static int pin_to_kill(struct inotify_handle *ih, struct inotify_watch *watch) -{ - struct super_block *sb = watch->inode->i_sb; - - if (atomic_inc_not_zero(&sb->s_active)) { - get_inotify_watch(watch); - mutex_unlock(&ih->mutex); - return 1; /* the best outcome */ - } - spin_lock(&sb_lock); - sb->s_count++; - spin_unlock(&sb_lock); - mutex_unlock(&ih->mutex); /* can't grab ->s_umount under it */ - down_read(&sb->s_umount); - /* fs is already shut down; the watch is dead */ - drop_super(sb); - return 0; -} - -static void unpin_and_kill(struct inotify_watch *watch) -{ - struct super_block *sb = watch->inode->i_sb; - put_inotify_watch(watch); - deactivate_super(sb); -} - -/** - * inotify_destroy - clean up and destroy an inotify instance - * @ih: inotify handle - */ -void inotify_destroy(struct inotify_handle *ih) -{ - /* - * Destroy all of the watches for this handle. Unfortunately, not very - * pretty. We cannot do a simple iteration over the list, because we - * do not know the inode until we iterate to the watch. But we need to - * hold inode->inotify_mutex before ih->mutex. The following works. - * - * AV: it had to become even uglier to start working ;-/ - */ - while (1) { - struct inotify_watch *watch; - struct list_head *watches; - struct super_block *sb; - struct inode *inode; - - mutex_lock(&ih->mutex); - watches = &ih->watches; - if (list_empty(watches)) { - mutex_unlock(&ih->mutex); - break; - } - watch = list_first_entry(watches, struct inotify_watch, h_list); - sb = watch->inode->i_sb; - if (!pin_to_kill(ih, watch)) - continue; - - inode = watch->inode; - mutex_lock(&inode->inotify_mutex); - mutex_lock(&ih->mutex); - - /* make sure we didn't race with another list removal */ - if (likely(idr_find(&ih->idr, watch->wd))) { - remove_watch_no_event(watch, ih); - put_inotify_watch(watch); - } - - mutex_unlock(&ih->mutex); - mutex_unlock(&inode->inotify_mutex); - unpin_and_kill(watch); - } - - /* free this handle: the put matching the get in inotify_init() */ - put_inotify_handle(ih); -} -EXPORT_SYMBOL_GPL(inotify_destroy); - -/** - * inotify_find_watch - find an existing watch for an (ih,inode) pair - * @ih: inotify handle - * @inode: inode to watch - * @watchp: pointer to existing inotify_watch - * - * Caller must pin given inode (via nameidata). - */ -s32 inotify_find_watch(struct inotify_handle *ih, struct inode *inode, - struct inotify_watch **watchp) -{ - struct inotify_watch *old; - int ret = -ENOENT; - - mutex_lock(&inode->inotify_mutex); - mutex_lock(&ih->mutex); - - old = inode_find_handle(inode, ih); - if (unlikely(old)) { - get_inotify_watch(old); /* caller must put watch */ - *watchp = old; - ret = old->wd; - } - - mutex_unlock(&ih->mutex); - mutex_unlock(&inode->inotify_mutex); - - return ret; -} -EXPORT_SYMBOL_GPL(inotify_find_watch); - -/** - * inotify_find_update_watch - find and update the mask of an existing watch - * @ih: inotify handle - * @inode: inode's watch to update - * @mask: mask of events to watch - * - * Caller must pin given inode (via nameidata). - */ -s32 inotify_find_update_watch(struct inotify_handle *ih, struct inode *inode, - u32 mask) -{ - struct inotify_watch *old; - int mask_add = 0; - int ret; - - if (mask & IN_MASK_ADD) - mask_add = 1; - - /* don't allow invalid bits: we don't want flags set */ - mask &= IN_ALL_EVENTS | IN_ONESHOT; - if (unlikely(!mask)) - return -EINVAL; - - mutex_lock(&inode->inotify_mutex); - mutex_lock(&ih->mutex); - - /* - * Handle the case of re-adding a watch on an (inode,ih) pair that we - * are already watching. We just update the mask and return its wd. - */ - old = inode_find_handle(inode, ih); - if (unlikely(!old)) { - ret = -ENOENT; - goto out; - } - - if (mask_add) - old->mask |= mask; - else - old->mask = mask; - ret = old->wd; -out: - mutex_unlock(&ih->mutex); - mutex_unlock(&inode->inotify_mutex); - return ret; -} -EXPORT_SYMBOL_GPL(inotify_find_update_watch); - -/** - * inotify_add_watch - add a watch to an inotify instance - * @ih: inotify handle - * @watch: caller allocated watch structure - * @inode: inode to watch - * @mask: mask of events to watch - * - * Caller must pin given inode (via nameidata). - * Caller must ensure it only calls inotify_add_watch() once per watch. - * Calls inotify_handle_get_wd() so may sleep. - */ -s32 inotify_add_watch(struct inotify_handle *ih, struct inotify_watch *watch, - struct inode *inode, u32 mask) -{ - int ret = 0; - int newly_watched; - - /* don't allow invalid bits: we don't want flags set */ - mask &= IN_ALL_EVENTS | IN_ONESHOT; - if (unlikely(!mask)) - return -EINVAL; - watch->mask = mask; - - mutex_lock(&inode->inotify_mutex); - mutex_lock(&ih->mutex); - - /* Initialize a new watch */ - ret = inotify_handle_get_wd(ih, watch); - if (unlikely(ret)) - goto out; - ret = watch->wd; - - /* save a reference to handle and bump the count to make it official */ - get_inotify_handle(ih); - watch->ih = ih; - - /* - * Save a reference to the inode and bump the ref count to make it - * official. We hold a reference to nameidata, which makes this safe. - */ - watch->inode = igrab(inode); - - /* Add the watch to the handle's and the inode's list */ - newly_watched = !inotify_inode_watched(inode); - list_add(&watch->h_list, &ih->watches); - list_add(&watch->i_list, &inode->inotify_watches); - /* - * Set child flags _after_ adding the watch, so there is no race - * windows where newly instantiated children could miss their parent's - * watched flag. - */ - if (newly_watched) - set_dentry_child_flags(inode, 1); - -out: - mutex_unlock(&ih->mutex); - mutex_unlock(&inode->inotify_mutex); - return ret; -} -EXPORT_SYMBOL_GPL(inotify_add_watch); - -/** - * inotify_clone_watch - put the watch next to existing one - * @old: already installed watch - * @new: new watch - * - * Caller must hold the inotify_mutex of inode we are dealing with; - * it is expected to remove the old watch before unlocking the inode. - */ -s32 inotify_clone_watch(struct inotify_watch *old, struct inotify_watch *new) -{ - struct inotify_handle *ih = old->ih; - int ret = 0; - - new->mask = old->mask; - new->ih = ih; - - mutex_lock(&ih->mutex); - - /* Initialize a new watch */ - ret = inotify_handle_get_wd(ih, new); - if (unlikely(ret)) - goto out; - ret = new->wd; - - get_inotify_handle(ih); - - new->inode = igrab(old->inode); - - list_add(&new->h_list, &ih->watches); - list_add(&new->i_list, &old->inode->inotify_watches); -out: - mutex_unlock(&ih->mutex); - return ret; -} - -void inotify_evict_watch(struct inotify_watch *watch) -{ - get_inotify_watch(watch); - mutex_lock(&watch->ih->mutex); - inotify_remove_watch_locked(watch->ih, watch); - mutex_unlock(&watch->ih->mutex); -} - -/** - * inotify_rm_wd - remove a watch from an inotify instance - * @ih: inotify handle - * @wd: watch descriptor to remove - * - * Can sleep. - */ -int inotify_rm_wd(struct inotify_handle *ih, u32 wd) -{ - struct inotify_watch *watch; - struct super_block *sb; - struct inode *inode; - - mutex_lock(&ih->mutex); - watch = idr_find(&ih->idr, wd); - if (unlikely(!watch)) { - mutex_unlock(&ih->mutex); - return -EINVAL; - } - sb = watch->inode->i_sb; - if (!pin_to_kill(ih, watch)) - return 0; - - inode = watch->inode; - - mutex_lock(&inode->inotify_mutex); - mutex_lock(&ih->mutex); - - /* make sure that we did not race */ - if (likely(idr_find(&ih->idr, wd) == watch)) - inotify_remove_watch_locked(ih, watch); - - mutex_unlock(&ih->mutex); - mutex_unlock(&inode->inotify_mutex); - unpin_and_kill(watch); - - return 0; -} -EXPORT_SYMBOL_GPL(inotify_rm_wd); - -/** - * inotify_rm_watch - remove a watch from an inotify instance - * @ih: inotify handle - * @watch: watch to remove - * - * Can sleep. - */ -int inotify_rm_watch(struct inotify_handle *ih, - struct inotify_watch *watch) -{ - return inotify_rm_wd(ih, watch->wd); -} -EXPORT_SYMBOL_GPL(inotify_rm_watch); - -/* - * inotify_setup - core initialization function - */ -static int __init inotify_setup(void) -{ - BUILD_BUG_ON(IN_ACCESS != FS_ACCESS); - BUILD_BUG_ON(IN_MODIFY != FS_MODIFY); - BUILD_BUG_ON(IN_ATTRIB != FS_ATTRIB); - BUILD_BUG_ON(IN_CLOSE_WRITE != FS_CLOSE_WRITE); - BUILD_BUG_ON(IN_CLOSE_NOWRITE != FS_CLOSE_NOWRITE); - BUILD_BUG_ON(IN_OPEN != FS_OPEN); - BUILD_BUG_ON(IN_MOVED_FROM != FS_MOVED_FROM); - BUILD_BUG_ON(IN_MOVED_TO != FS_MOVED_TO); - BUILD_BUG_ON(IN_CREATE != FS_CREATE); - BUILD_BUG_ON(IN_DELETE != FS_DELETE); - BUILD_BUG_ON(IN_DELETE_SELF != FS_DELETE_SELF); - BUILD_BUG_ON(IN_MOVE_SELF != FS_MOVE_SELF); - BUILD_BUG_ON(IN_Q_OVERFLOW != FS_Q_OVERFLOW); - - BUILD_BUG_ON(IN_UNMOUNT != FS_UNMOUNT); - BUILD_BUG_ON(IN_ISDIR != FS_IN_ISDIR); - BUILD_BUG_ON(IN_IGNORED != FS_IN_IGNORED); - BUILD_BUG_ON(IN_ONESHOT != FS_IN_ONESHOT); - - atomic_set(&inotify_cookie, 0); - - return 0; -} - -module_init(inotify_setup); diff --git a/fs/open.c b/fs/open.c index 5463266db9e..94d54d3efa8 100644 --- a/fs/open.c +++ b/fs/open.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "internal.h" diff --git a/include/linux/fs.h b/include/linux/fs.h index 68ca1b0491a..e5598d2f99b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -771,11 +771,6 @@ struct inode { struct hlist_head i_fsnotify_mark_entries; /* fsnotify mark entries */ #endif -#ifdef CONFIG_INOTIFY - struct list_head inotify_watches; /* watches on this inode */ - struct mutex inotify_mutex; /* protects the watches list */ -#endif - unsigned long i_state; unsigned long dirtied_when; /* jiffies of first dirtying */ diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 01755909ce8..f958e93feb9 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -11,8 +11,6 @@ * (C) Copyright 2005 Robert Love */ -#include -#include #include #include #include @@ -25,16 +23,12 @@ static inline void fsnotify_d_instantiate(struct dentry *entry, struct inode *inode) { __fsnotify_d_instantiate(entry, inode); - - inotify_d_instantiate(entry, inode); } /* Notify this dentry's parent about a child's events. */ static inline void fsnotify_parent(struct dentry *dentry, __u32 mask) { __fsnotify_parent(dentry, mask); - - inotify_dentry_parent_queue_event(dentry, mask, 0, dentry->d_name.name); } /* @@ -48,8 +42,6 @@ static inline void fsnotify_d_move(struct dentry *entry) * cares about events from this entry. */ __fsnotify_update_dcache_flags(entry); - - inotify_d_move(entry); } /* @@ -57,8 +49,6 @@ static inline void fsnotify_d_move(struct dentry *entry) */ static inline void fsnotify_link_count(struct inode *inode) { - inotify_inode_queue_event(inode, IN_ATTRIB, 0, NULL, NULL); - fsnotify(inode, FS_ATTRIB, inode, FSNOTIFY_EVENT_INODE, NULL, 0); } @@ -70,7 +60,6 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, int isdir, struct inode *target, struct dentry *moved) { struct inode *source = moved->d_inode; - u32 in_cookie = inotify_get_cookie(); u32 fs_cookie = fsnotify_get_cookie(); __u32 old_dir_mask = (FS_EVENT_ON_CHILD | FS_MOVED_FROM); __u32 new_dir_mask = (FS_EVENT_ON_CHILD | FS_MOVED_TO); @@ -80,31 +69,18 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, old_dir_mask |= FS_DN_RENAME; if (isdir) { - isdir = IN_ISDIR; old_dir_mask |= FS_IN_ISDIR; new_dir_mask |= FS_IN_ISDIR; } - inotify_inode_queue_event(old_dir, IN_MOVED_FROM|isdir, in_cookie, old_name, - source); - inotify_inode_queue_event(new_dir, IN_MOVED_TO|isdir, in_cookie, new_name, - source); - fsnotify(old_dir, old_dir_mask, old_dir, FSNOTIFY_EVENT_INODE, old_name, fs_cookie); fsnotify(new_dir, new_dir_mask, new_dir, FSNOTIFY_EVENT_INODE, new_name, fs_cookie); - if (target) { - inotify_inode_queue_event(target, IN_DELETE_SELF, 0, NULL, NULL); - inotify_inode_is_dead(target); - - /* this is really a link_count change not a removal */ + if (target) fsnotify_link_count(target); - } - if (source) { - inotify_inode_queue_event(source, IN_MOVE_SELF, 0, NULL, NULL); + if (source) fsnotify(source, FS_MOVE_SELF, moved->d_inode, FSNOTIFY_EVENT_INODE, NULL, 0); - } audit_inode_child(moved, new_dir); } @@ -134,9 +110,6 @@ static inline void fsnotify_nameremove(struct dentry *dentry, int isdir) */ static inline void fsnotify_inoderemove(struct inode *inode) { - inotify_inode_queue_event(inode, IN_DELETE_SELF, 0, NULL, NULL); - inotify_inode_is_dead(inode); - fsnotify(inode, FS_DELETE_SELF, inode, FSNOTIFY_EVENT_INODE, NULL, 0); __fsnotify_inode_delete(inode); } @@ -146,8 +119,6 @@ static inline void fsnotify_inoderemove(struct inode *inode) */ static inline void fsnotify_create(struct inode *inode, struct dentry *dentry) { - inotify_inode_queue_event(inode, IN_CREATE, 0, dentry->d_name.name, - dentry->d_inode); audit_inode_child(dentry, inode); fsnotify(inode, FS_CREATE, dentry->d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0); @@ -160,8 +131,6 @@ static inline void fsnotify_create(struct inode *inode, struct dentry *dentry) */ static inline void fsnotify_link(struct inode *dir, struct inode *inode, struct dentry *new_dentry) { - inotify_inode_queue_event(dir, IN_CREATE, 0, new_dentry->d_name.name, - inode); fsnotify_link_count(inode); audit_inode_child(new_dentry, dir); @@ -176,7 +145,6 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry) __u32 mask = (FS_CREATE | FS_IN_ISDIR); struct inode *d_inode = dentry->d_inode; - inotify_inode_queue_event(inode, mask, 0, dentry->d_name.name, d_inode); audit_inode_child(dentry, inode); fsnotify(inode, mask, d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0); @@ -193,8 +161,6 @@ static inline void fsnotify_access(struct dentry *dentry) if (S_ISDIR(inode->i_mode)) mask |= FS_IN_ISDIR; - inotify_inode_queue_event(inode, mask, 0, NULL, NULL); - fsnotify_parent(dentry, mask); fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0); } @@ -210,8 +176,6 @@ static inline void fsnotify_modify(struct dentry *dentry) if (S_ISDIR(inode->i_mode)) mask |= FS_IN_ISDIR; - inotify_inode_queue_event(inode, mask, 0, NULL, NULL); - fsnotify_parent(dentry, mask); fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0); } @@ -227,8 +191,6 @@ static inline void fsnotify_open(struct dentry *dentry) if (S_ISDIR(inode->i_mode)) mask |= FS_IN_ISDIR; - inotify_inode_queue_event(inode, mask, 0, NULL, NULL); - fsnotify_parent(dentry, mask); fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0); } @@ -246,8 +208,6 @@ static inline void fsnotify_close(struct file *file) if (S_ISDIR(inode->i_mode)) mask |= FS_IN_ISDIR; - inotify_inode_queue_event(inode, mask, 0, NULL, NULL); - fsnotify_parent(dentry, mask); fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL, 0); } @@ -263,8 +223,6 @@ static inline void fsnotify_xattr(struct dentry *dentry) if (S_ISDIR(inode->i_mode)) mask |= FS_IN_ISDIR; - inotify_inode_queue_event(inode, mask, 0, NULL, NULL); - fsnotify_parent(dentry, mask); fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0); } @@ -299,14 +257,12 @@ static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid) if (mask) { if (S_ISDIR(inode->i_mode)) mask |= FS_IN_ISDIR; - inotify_inode_queue_event(inode, mask, 0, NULL, NULL); - fsnotify_parent(dentry, mask); fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0); } } -#if defined(CONFIG_INOTIFY) || defined(CONFIG_FSNOTIFY) /* notify helpers */ +#if defined(CONFIG_FSNOTIFY) /* notify helpers */ /* * fsnotify_oldname_init - save off the old filename before we change it diff --git a/include/linux/inotify.h b/include/linux/inotify.h index 37ea2894b3c..959a38b8f75 100644 --- a/include/linux/inotify.h +++ b/include/linux/inotify.h @@ -69,178 +69,4 @@ struct inotify_event { #define IN_CLOEXEC O_CLOEXEC #define IN_NONBLOCK O_NONBLOCK -#ifdef __KERNEL__ - -#include -#include - -/* - * struct inotify_watch - represents a watch request on a specific inode - * - * h_list is protected by ih->mutex of the associated inotify_handle. - * i_list, mask are protected by inode->inotify_mutex of the associated inode. - * ih, inode, and wd are never written to once the watch is created. - * - * Callers must use the established inotify interfaces to access inotify_watch - * contents. The content of this structure is private to the inotify - * implementation. - */ -struct inotify_watch { - struct list_head h_list; /* entry in inotify_handle's list */ - struct list_head i_list; /* entry in inode's list */ - atomic_t count; /* reference count */ - struct inotify_handle *ih; /* associated inotify handle */ - struct inode *inode; /* associated inode */ - __s32 wd; /* watch descriptor */ - __u32 mask; /* event mask for this watch */ -}; - -struct inotify_operations { - void (*handle_event)(struct inotify_watch *, u32, u32, u32, - const char *, struct inode *); - void (*destroy_watch)(struct inotify_watch *); -}; - -#ifdef CONFIG_INOTIFY - -/* Kernel API for producing events */ - -extern void inotify_d_instantiate(struct dentry *, struct inode *); -extern void inotify_d_move(struct dentry *); -extern void inotify_inode_queue_event(struct inode *, __u32, __u32, - const char *, struct inode *); -extern void inotify_dentry_parent_queue_event(struct dentry *, __u32, __u32, - const char *); -extern void inotify_unmount_inodes(struct list_head *); -extern void inotify_inode_is_dead(struct inode *); -extern u32 inotify_get_cookie(void); - -/* Kernel Consumer API */ - -extern struct inotify_handle *inotify_init(const struct inotify_operations *); -extern void inotify_init_watch(struct inotify_watch *); -extern void inotify_destroy(struct inotify_handle *); -extern __s32 inotify_find_watch(struct inotify_handle *, struct inode *, - struct inotify_watch **); -extern __s32 inotify_find_update_watch(struct inotify_handle *, struct inode *, - u32); -extern __s32 inotify_add_watch(struct inotify_handle *, struct inotify_watch *, - struct inode *, __u32); -extern __s32 inotify_clone_watch(struct inotify_watch *, struct inotify_watch *); -extern void inotify_evict_watch(struct inotify_watch *); -extern int inotify_rm_watch(struct inotify_handle *, struct inotify_watch *); -extern int inotify_rm_wd(struct inotify_handle *, __u32); -extern void inotify_remove_watch_locked(struct inotify_handle *, - struct inotify_watch *); -extern void get_inotify_watch(struct inotify_watch *); -extern void put_inotify_watch(struct inotify_watch *); -extern int pin_inotify_watch(struct inotify_watch *); -extern void unpin_inotify_watch(struct inotify_watch *); - -#else - -static inline void inotify_d_instantiate(struct dentry *dentry, - struct inode *inode) -{ -} - -static inline void inotify_d_move(struct dentry *dentry) -{ -} - -static inline void inotify_inode_queue_event(struct inode *inode, - __u32 mask, __u32 cookie, - const char *filename, - struct inode *n_inode) -{ -} - -static inline void inotify_dentry_parent_queue_event(struct dentry *dentry, - __u32 mask, __u32 cookie, - const char *filename) -{ -} - -static inline void inotify_unmount_inodes(struct list_head *list) -{ -} - -static inline void inotify_inode_is_dead(struct inode *inode) -{ -} - -static inline u32 inotify_get_cookie(void) -{ - return 0; -} - -static inline struct inotify_handle *inotify_init(const struct inotify_operations *ops) -{ - return ERR_PTR(-EOPNOTSUPP); -} - -static inline void inotify_init_watch(struct inotify_watch *watch) -{ -} - -static inline void inotify_destroy(struct inotify_handle *ih) -{ -} - -static inline __s32 inotify_find_watch(struct inotify_handle *ih, struct inode *inode, - struct inotify_watch **watchp) -{ - return -EOPNOTSUPP; -} - -static inline __s32 inotify_find_update_watch(struct inotify_handle *ih, - struct inode *inode, u32 mask) -{ - return -EOPNOTSUPP; -} - -static inline __s32 inotify_add_watch(struct inotify_handle *ih, - struct inotify_watch *watch, - struct inode *inode, __u32 mask) -{ - return -EOPNOTSUPP; -} - -static inline int inotify_rm_watch(struct inotify_handle *ih, - struct inotify_watch *watch) -{ - return -EOPNOTSUPP; -} - -static inline int inotify_rm_wd(struct inotify_handle *ih, __u32 wd) -{ - return -EOPNOTSUPP; -} - -static inline void inotify_remove_watch_locked(struct inotify_handle *ih, - struct inotify_watch *watch) -{ -} - -static inline void get_inotify_watch(struct inotify_watch *watch) -{ -} - -static inline void put_inotify_watch(struct inotify_watch *watch) -{ -} - -extern inline int pin_inotify_watch(struct inotify_watch *watch) -{ - return 0; -} - -extern inline void unpin_inotify_watch(struct inotify_watch *watch) -{ -} - -#endif /* CONFIG_INOTIFY */ - -#endif /* __KERNEL __ */ - #endif /* _LINUX_INOTIFY_H */ diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 786901cd821..853185f7ba7 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -65,7 +65,6 @@ #include #include #include -#include #include #include -- cgit v1.2.3 From e61ce86737b4d60521e4e71f9892fe4bdcfb688b Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Thu, 17 Dec 2009 21:24:24 -0500 Subject: fsnotify: rename fsnotify_mark_entry to just fsnotify_mark The name is long and it serves no real purpose. So rename fsnotify_mark_entry to just fsnotify_mark. Signed-off-by: Eric Paris --- fs/inode.c | 2 +- fs/notify/dnotify/dnotify.c | 24 +++++++++--------- fs/notify/group.c | 8 +++--- fs/notify/inode_mark.c | 48 ++++++++++++++++++------------------ fs/notify/inotify/inotify.h | 6 ++--- fs/notify/inotify/inotify_fsnotify.c | 8 +++--- fs/notify/inotify/inotify_user.c | 8 +++--- include/linux/fs.h | 2 +- include/linux/fsnotify.h | 18 +++++++------- include/linux/fsnotify_backend.h | 38 ++++++++++++++-------------- kernel/audit_tree.c | 14 +++++------ kernel/audit_watch.c | 8 +++--- kernel/auditsc.c | 4 +-- 13 files changed, 94 insertions(+), 94 deletions(-) (limited to 'kernel/auditsc.c') diff --git a/fs/inode.c b/fs/inode.c index 8e1bee99879..a2da778467b 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -264,7 +264,7 @@ void inode_init_once(struct inode *inode) INIT_LIST_HEAD(&inode->i_data.i_mmap_nonlinear); i_size_ordered_init(inode); #ifdef CONFIG_FSNOTIFY - INIT_HLIST_HEAD(&inode->i_fsnotify_mark_entries); + INIT_HLIST_HEAD(&inode->i_fsnotify_marks); #endif } EXPORT_SYMBOL(inode_init_once); diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c index fc3a9dc567c..e6edae60894 100644 --- a/fs/notify/dnotify/dnotify.c +++ b/fs/notify/dnotify/dnotify.c @@ -34,12 +34,12 @@ static struct fsnotify_group *dnotify_group __read_mostly; static DEFINE_MUTEX(dnotify_mark_mutex); /* - * dnotify will attach one of these to each inode (i_fsnotify_mark_entries) which + * dnotify will attach one of these to each inode (i_fsnotify_marks) which * is being watched by dnotify. If multiple userspace applications are watching * the same directory with dnotify their information is chained in dn */ struct dnotify_mark_entry { - struct fsnotify_mark_entry fsn_entry; + struct fsnotify_mark fsn_entry; struct dnotify_struct *dn; }; @@ -51,7 +51,7 @@ struct dnotify_mark_entry { * it calls the fsnotify function so it can update the set of all events relevant * to this inode. */ -static void dnotify_recalc_inode_mask(struct fsnotify_mark_entry *entry) +static void dnotify_recalc_inode_mask(struct fsnotify_mark *entry) { __u32 new_mask, old_mask; struct dnotify_struct *dn; @@ -85,7 +85,7 @@ static void dnotify_recalc_inode_mask(struct fsnotify_mark_entry *entry) static int dnotify_handle_event(struct fsnotify_group *group, struct fsnotify_event *event) { - struct fsnotify_mark_entry *entry = NULL; + struct fsnotify_mark *entry = NULL; struct dnotify_mark_entry *dnentry; struct inode *to_tell; struct dnotify_struct *dn; @@ -136,7 +136,7 @@ static bool dnotify_should_send_event(struct fsnotify_group *group, struct inode *inode, struct vfsmount *mnt, __u32 mask, void *data, int data_type) { - struct fsnotify_mark_entry *entry; + struct fsnotify_mark *entry; bool send; /* !dir_notify_enable should never get here, don't waste time checking @@ -163,7 +163,7 @@ static bool dnotify_should_send_event(struct fsnotify_group *group, return send; } -static void dnotify_free_mark(struct fsnotify_mark_entry *entry) +static void dnotify_free_mark(struct fsnotify_mark *entry) { struct dnotify_mark_entry *dnentry = container_of(entry, struct dnotify_mark_entry, @@ -184,14 +184,14 @@ static struct fsnotify_ops dnotify_fsnotify_ops = { /* * Called every time a file is closed. Looks first for a dnotify mark on the - * inode. If one is found run all of the ->dn entries attached to that + * inode. If one is found run all of the ->dn structures attached to that * mark for one relevant to this process closing the file and remove that * dnotify_struct. If that was the last dnotify_struct also remove the - * fsnotify_mark_entry. + * fsnotify_mark. */ void dnotify_flush(struct file *filp, fl_owner_t id) { - struct fsnotify_mark_entry *entry; + struct fsnotify_mark *entry; struct dnotify_mark_entry *dnentry; struct dnotify_struct *dn; struct dnotify_struct **prev; @@ -260,7 +260,7 @@ static __u32 convert_arg(unsigned long arg) /* * If multiple processes watch the same inode with dnotify there is only one - * dnotify mark in inode->i_fsnotify_mark_entries but we chain a dnotify_struct + * dnotify mark in inode->i_fsnotify_marks but we chain a dnotify_struct * onto that mark. This function either attaches the new dnotify_struct onto * that list, or it |= the mask onto an existing dnofiy_struct. */ @@ -298,7 +298,7 @@ static int attach_dn(struct dnotify_struct *dn, struct dnotify_mark_entry *dnent int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg) { struct dnotify_mark_entry *new_dnentry, *dnentry; - struct fsnotify_mark_entry *new_entry, *entry; + struct fsnotify_mark *new_entry, *entry; struct dnotify_struct *dn; struct inode *inode; fl_owner_t id = current->files; @@ -378,7 +378,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg) /* if (f != filp) means that we lost a race and another task/thread * actually closed the fd we are still playing with before we grabbed * the dnotify_mark_mutex and entry->lock. Since closing the fd is the - * only time we clean up the mark entries we need to get our mark off + * only time we clean up the marks we need to get our mark off * the list. */ if (f != filp) { /* if we added ourselves, shoot ourselves, it's possible that diff --git a/fs/notify/group.c b/fs/notify/group.c index aa4654fe6ec..b70e7d21dfd 100644 --- a/fs/notify/group.c +++ b/fs/notify/group.c @@ -74,10 +74,10 @@ void fsnotify_recalc_group_mask(struct fsnotify_group *group) { __u32 mask = 0; __u32 old_mask = group->mask; - struct fsnotify_mark_entry *entry; + struct fsnotify_mark *entry; spin_lock(&group->mark_lock); - list_for_each_entry(entry, &group->mark_entries, g_list) + list_for_each_entry(entry, &group->marks_list, g_list) mask |= entry->mask; spin_unlock(&group->mark_lock); @@ -133,7 +133,7 @@ void fsnotify_final_destroy_group(struct fsnotify_group *group) */ static void fsnotify_destroy_group(struct fsnotify_group *group) { - /* clear all inode mark entries for this group */ + /* clear all inode marks for this group */ fsnotify_clear_marks_by_group(group); /* past the point of no return, matches the initial value of 1 */ @@ -224,7 +224,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops) INIT_LIST_HEAD(&group->vfsmount_group_list); spin_lock_init(&group->mark_lock); - INIT_LIST_HEAD(&group->mark_entries); + INIT_LIST_HEAD(&group->marks_list); group->ops = ops; diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c index b00065842b3..7e69f6b08d4 100644 --- a/fs/notify/inode_mark.c +++ b/fs/notify/inode_mark.c @@ -38,12 +38,12 @@ * that lock to dereference either of these things (they could be NULL even with * the lock) * - * group->mark_lock protects the mark_entries list anchored inside a given group + * group->mark_lock protects the marks_list anchored inside a given group * and each entry is hooked via the g_list. It also sorta protects the * free_g_list, which when used is anchored by a private list on the stack of the * task which held the group->mark_lock. * - * inode->i_lock protects the i_fsnotify_mark_entries list anchored inside a + * inode->i_lock protects the i_fsnotify_marks list anchored inside a * given inode and each entry is hooked via the i_list. (and sorta the * free_i_list) * @@ -61,7 +61,7 @@ * need to be cleaned up. (fsnotify_clear_marks_by_group) * * Worst case we are given an inode and need to clean up all the marks on that - * inode. We take i_lock and walk the i_fsnotify_mark_entries safely. For each + * inode. We take i_lock and walk the i_fsnotify_marks safely. For each * mark on the list we take a reference (so the mark can't disappear under us). * We remove that mark form the inode's list of marks and we add this mark to a * private list anchored on the stack using i_free_list; At this point we no @@ -95,12 +95,12 @@ #include #include "fsnotify.h" -void fsnotify_get_mark(struct fsnotify_mark_entry *entry) +void fsnotify_get_mark(struct fsnotify_mark *entry) { atomic_inc(&entry->refcnt); } -void fsnotify_put_mark(struct fsnotify_mark_entry *entry) +void fsnotify_put_mark(struct fsnotify_mark *entry) { if (atomic_dec_and_test(&entry->refcnt)) entry->free_mark(entry); @@ -111,13 +111,13 @@ void fsnotify_put_mark(struct fsnotify_mark_entry *entry) */ static void fsnotify_recalc_inode_mask_locked(struct inode *inode) { - struct fsnotify_mark_entry *entry; + struct fsnotify_mark *entry; struct hlist_node *pos; __u32 new_mask = 0; assert_spin_locked(&inode->i_lock); - hlist_for_each_entry(entry, pos, &inode->i_fsnotify_mark_entries, i.i_list) + hlist_for_each_entry(entry, pos, &inode->i_fsnotify_marks, i.i_list) new_mask |= entry->mask; inode->i_fsnotify_mask = new_mask; } @@ -140,7 +140,7 @@ void fsnotify_recalc_inode_mask(struct inode *inode) * The caller had better be holding a reference to this mark so we don't actually * do the final put under the entry->lock */ -void fsnotify_destroy_mark_by_entry(struct fsnotify_mark_entry *entry) +void fsnotify_destroy_mark_by_entry(struct fsnotify_mark *entry) { struct fsnotify_group *group; struct inode *inode; @@ -174,7 +174,7 @@ void fsnotify_destroy_mark_by_entry(struct fsnotify_mark_entry *entry) fsnotify_put_mark(entry); /* for i_list and g_list */ /* - * this mark is now off the inode->i_fsnotify_mark_entries list and we + * this mark is now off the inode->i_fsnotify_marks list and we * hold the inode->i_lock, so this is the perfect time to update the * inode->i_fsnotify_mask */ @@ -221,11 +221,11 @@ void fsnotify_destroy_mark_by_entry(struct fsnotify_mark_entry *entry) */ void fsnotify_clear_marks_by_group(struct fsnotify_group *group) { - struct fsnotify_mark_entry *lentry, *entry; + struct fsnotify_mark *lentry, *entry; LIST_HEAD(free_list); spin_lock(&group->mark_lock); - list_for_each_entry_safe(entry, lentry, &group->mark_entries, g_list) { + list_for_each_entry_safe(entry, lentry, &group->marks_list, g_list) { list_add(&entry->free_g_list, &free_list); list_del_init(&entry->g_list); fsnotify_get_mark(entry); @@ -243,12 +243,12 @@ void fsnotify_clear_marks_by_group(struct fsnotify_group *group) */ void fsnotify_clear_marks_by_inode(struct inode *inode) { - struct fsnotify_mark_entry *entry, *lentry; + struct fsnotify_mark *entry, *lentry; struct hlist_node *pos, *n; LIST_HEAD(free_list); spin_lock(&inode->i_lock); - hlist_for_each_entry_safe(entry, pos, n, &inode->i_fsnotify_mark_entries, i.i_list) { + hlist_for_each_entry_safe(entry, pos, n, &inode->i_fsnotify_marks, i.i_list) { list_add(&entry->i.free_i_list, &free_list); hlist_del_init(&entry->i.i_list); fsnotify_get_mark(entry); @@ -265,15 +265,15 @@ void fsnotify_clear_marks_by_inode(struct inode *inode) * given a group and inode, find the mark associated with that combination. * if found take a reference to that mark and return it, else return NULL */ -struct fsnotify_mark_entry *fsnotify_find_mark_entry(struct fsnotify_group *group, - struct inode *inode) +struct fsnotify_mark *fsnotify_find_mark_entry(struct fsnotify_group *group, + struct inode *inode) { - struct fsnotify_mark_entry *entry; + struct fsnotify_mark *entry; struct hlist_node *pos; assert_spin_locked(&inode->i_lock); - hlist_for_each_entry(entry, pos, &inode->i_fsnotify_mark_entries, i.i_list) { + hlist_for_each_entry(entry, pos, &inode->i_fsnotify_marks, i.i_list) { if (entry->group == group) { fsnotify_get_mark(entry); return entry; @@ -282,7 +282,7 @@ struct fsnotify_mark_entry *fsnotify_find_mark_entry(struct fsnotify_group *grou return NULL; } -void fsnotify_duplicate_mark(struct fsnotify_mark_entry *new, struct fsnotify_mark_entry *old) +void fsnotify_duplicate_mark(struct fsnotify_mark *new, struct fsnotify_mark *old) { assert_spin_locked(&old->lock); new->i.inode = old->i.inode; @@ -294,8 +294,8 @@ void fsnotify_duplicate_mark(struct fsnotify_mark_entry *new, struct fsnotify_ma /* * Nothing fancy, just initialize lists and locks and counters. */ -void fsnotify_init_mark(struct fsnotify_mark_entry *entry, - void (*free_mark)(struct fsnotify_mark_entry *entry)) +void fsnotify_init_mark(struct fsnotify_mark *entry, + void (*free_mark)(struct fsnotify_mark *entry)) { spin_lock_init(&entry->lock); atomic_set(&entry->refcnt, 1); @@ -311,11 +311,11 @@ void fsnotify_init_mark(struct fsnotify_mark_entry *entry, * These marks may be used for the fsnotify backend to determine which * event types should be delivered to which group and for which inodes. */ -int fsnotify_add_mark(struct fsnotify_mark_entry *entry, +int fsnotify_add_mark(struct fsnotify_mark *entry, struct fsnotify_group *group, struct inode *inode, int allow_dups) { - struct fsnotify_mark_entry *lentry = NULL; + struct fsnotify_mark *lentry = NULL; int ret = 0; inode = igrab(inode); @@ -354,8 +354,8 @@ int fsnotify_add_mark(struct fsnotify_mark_entry *entry, entry->group = group; entry->i.inode = inode; - hlist_add_head(&entry->i.i_list, &inode->i_fsnotify_mark_entries); - list_add(&entry->g_list, &group->mark_entries); + hlist_add_head(&entry->i.i_list, &inode->i_fsnotify_marks); + list_add(&entry->g_list, &group->marks_list); fsnotify_get_mark(entry); /* for i_list and g_list */ diff --git a/fs/notify/inotify/inotify.h b/fs/notify/inotify/inotify.h index f234f3a4c8c..07be6df2428 100644 --- a/fs/notify/inotify/inotify.h +++ b/fs/notify/inotify/inotify.h @@ -10,12 +10,12 @@ struct inotify_event_private_data { }; struct inotify_inode_mark_entry { - /* fsnotify_mark_entry MUST be the first thing */ - struct fsnotify_mark_entry fsn_entry; + /* fsnotify_mark MUST be the first thing */ + struct fsnotify_mark fsn_entry; int wd; }; -extern void inotify_ignored_and_remove_idr(struct fsnotify_mark_entry *entry, +extern void inotify_ignored_and_remove_idr(struct fsnotify_mark *entry, struct fsnotify_group *group); extern void inotify_free_event_priv(struct fsnotify_event_private_data *event_priv); diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index 3edb51cfcfb..f33a9bd32e5 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c @@ -88,7 +88,7 @@ static int inotify_merge(struct list_head *list, struct fsnotify_event *event) static int inotify_handle_event(struct fsnotify_group *group, struct fsnotify_event *event) { - struct fsnotify_mark_entry *entry; + struct fsnotify_mark *entry; struct inotify_inode_mark_entry *ientry; struct inode *to_tell; struct inotify_event_private_data *event_priv; @@ -135,7 +135,7 @@ static int inotify_handle_event(struct fsnotify_group *group, struct fsnotify_ev return ret; } -static void inotify_freeing_mark(struct fsnotify_mark_entry *entry, struct fsnotify_group *group) +static void inotify_freeing_mark(struct fsnotify_mark *entry, struct fsnotify_group *group) { inotify_ignored_and_remove_idr(entry, group); } @@ -144,7 +144,7 @@ static bool inotify_should_send_event(struct fsnotify_group *group, struct inode struct vfsmount *mnt, __u32 mask, void *data, int data_type) { - struct fsnotify_mark_entry *entry; + struct fsnotify_mark *entry; bool send; spin_lock(&inode->i_lock); @@ -171,7 +171,7 @@ static bool inotify_should_send_event(struct fsnotify_group *group, struct inode */ static int idr_callback(int id, void *p, void *data) { - struct fsnotify_mark_entry *entry; + struct fsnotify_mark *entry; struct inotify_inode_mark_entry *ientry; static bool warned = false; diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index 4b1587f9df3..7be5dcf07ac 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c @@ -386,7 +386,7 @@ static struct inotify_inode_mark_entry *inotify_idr_find_locked(struct fsnotify_ ientry = idr_find(idr, wd); if (ientry) { - struct fsnotify_mark_entry *fsn_entry = &ientry->fsn_entry; + struct fsnotify_mark *fsn_entry = &ientry->fsn_entry; fsnotify_get_mark(fsn_entry); /* One ref for being in the idr, one ref we just took */ @@ -499,7 +499,7 @@ out: /* * Send IN_IGNORED for this wd, remove this wd from the idr. */ -void inotify_ignored_and_remove_idr(struct fsnotify_mark_entry *entry, +void inotify_ignored_and_remove_idr(struct fsnotify_mark *entry, struct fsnotify_group *group) { struct inotify_inode_mark_entry *ientry; @@ -541,7 +541,7 @@ skip_send_ignore: } /* ding dong the mark is dead */ -static void inotify_free_mark(struct fsnotify_mark_entry *entry) +static void inotify_free_mark(struct fsnotify_mark *entry) { struct inotify_inode_mark_entry *ientry; @@ -554,7 +554,7 @@ static int inotify_update_existing_watch(struct fsnotify_group *group, struct inode *inode, u32 arg) { - struct fsnotify_mark_entry *entry; + struct fsnotify_mark *entry; struct inotify_inode_mark_entry *ientry; __u32 old_mask, new_mask; __u32 mask; diff --git a/include/linux/fs.h b/include/linux/fs.h index e5598d2f99b..85fe89c4348 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -768,7 +768,7 @@ struct inode { #ifdef CONFIG_FSNOTIFY __u32 i_fsnotify_mask; /* all events this inode cares about */ - struct hlist_head i_fsnotify_mark_entries; /* fsnotify mark entries */ + struct hlist_head i_fsnotify_marks; #endif unsigned long i_state; diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 06d296d85eb..62e93a9dd11 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -19,10 +19,10 @@ * fsnotify_d_instantiate - instantiate a dentry for inode * Called with dcache_lock held. */ -static inline void fsnotify_d_instantiate(struct dentry *entry, - struct inode *inode) +static inline void fsnotify_d_instantiate(struct dentry *dentry, + struct inode *inode) { - __fsnotify_d_instantiate(entry, inode); + __fsnotify_d_instantiate(dentry, inode); } /* Notify this dentry's parent about a child's events. */ @@ -35,16 +35,16 @@ static inline void fsnotify_parent(struct path *path, struct dentry *dentry, __u } /* - * fsnotify_d_move - entry has been moved - * Called with dcache_lock and entry->d_lock held. + * fsnotify_d_move - dentry has been moved + * Called with dcache_lock and dentry->d_lock held. */ -static inline void fsnotify_d_move(struct dentry *entry) +static inline void fsnotify_d_move(struct dentry *dentry) { /* - * On move we need to update entry->d_flags to indicate if the new parent - * cares about events from this entry. + * On move we need to update dentry->d_flags to indicate if the new parent + * cares about events from this dentry. */ - __fsnotify_update_dcache_flags(entry); + __fsnotify_update_dcache_flags(dentry); } /* diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 7a6ba755acc..59c072e8fdd 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -62,7 +62,7 @@ struct fsnotify_group; struct fsnotify_event; -struct fsnotify_mark_entry; +struct fsnotify_mark; struct fsnotify_event_private_data; /* @@ -83,7 +83,7 @@ struct fsnotify_ops { int data_type); int (*handle_event)(struct fsnotify_group *group, struct fsnotify_event *event); void (*free_group_priv)(struct fsnotify_group *group); - void (*freeing_mark)(struct fsnotify_mark_entry *entry, struct fsnotify_group *group); + void (*freeing_mark)(struct fsnotify_mark *entry, struct fsnotify_group *group); void (*free_event_priv)(struct fsnotify_event_private_data *priv); }; @@ -133,12 +133,12 @@ struct fsnotify_group { unsigned int q_len; /* events on the queue */ unsigned int max_events; /* maximum events allowed on the list */ - /* stores all fastapth entries assoc with this group so they can be cleaned on unregister */ - spinlock_t mark_lock; /* protect mark_entries list */ + /* stores all fastpath marks assoc with this group so they can be cleaned on unregister */ + spinlock_t mark_lock; /* protect marks_list */ atomic_t num_marks; /* 1 for each mark entry and 1 for not being * past the point of no return when freeing * a group */ - struct list_head mark_entries; /* all inode mark entries for this group */ + struct list_head marks_list; /* all inode marks for this group */ /* prevents double list_del of group_list. protected by global fsnotify_grp_mutex */ bool on_inode_group_list; @@ -226,20 +226,20 @@ struct fsnotify_event { }; /* - * Inode specific fields in an fsnotify_mark_entry + * Inode specific fields in an fsnotify_mark */ struct fsnotify_inode_mark { struct inode *inode; /* inode this entry is associated with */ - struct hlist_node i_list; /* list of mark_entries by inode->i_fsnotify_mark_entries */ + struct hlist_node i_list; /* list of marks by inode->i_fsnotify_marks */ struct list_head free_i_list; /* tmp list used when freeing this mark */ }; /* - * Mount point specific fields in an fsnotify_mark_entry + * Mount point specific fields in an fsnotify_mark */ struct fsnotify_vfsmount_mark { struct vfsmount *mnt; /* inode this entry is associated with */ - struct hlist_node m_list; /* list of mark_entries by inode->i_fsnotify_mark_entries */ + struct hlist_node m_list; /* list of marks by inode->i_fsnotify_marks */ struct list_head free_m_list; /* tmp list used when freeing this mark */ }; @@ -253,13 +253,13 @@ struct fsnotify_vfsmount_mark { * (such as dnotify) will flush these when the open fd is closed and not at * inode eviction or modification. */ -struct fsnotify_mark_entry { +struct fsnotify_mark { __u32 mask; /* mask this mark entry is for */ /* we hold ref for each i_list and g_list. also one ref for each 'thing' * in kernel that found and may be using this mark. */ atomic_t refcnt; /* active things looking at this mark */ struct fsnotify_group *group; /* group this mark entry is for */ - struct list_head g_list; /* list of mark_entries by group->i_fsnotify_mark_entries */ + struct list_head g_list; /* list of marks by group->i_fsnotify_marks */ spinlock_t lock; /* protect group and inode */ union { struct fsnotify_inode_mark i; @@ -269,7 +269,7 @@ struct fsnotify_mark_entry { #define FSNOTIFY_MARK_FLAG_INODE 0x01 #define FSNOTIFY_MARK_FLAG_VFSMOUNT 0x02 unsigned int flags; /* vfsmount or inode mark? */ - void (*free_mark)(struct fsnotify_mark_entry *entry); /* called on final put+free */ + void (*free_mark)(struct fsnotify_mark *entry); /* called on final put+free */ }; #ifdef CONFIG_FSNOTIFY @@ -361,19 +361,19 @@ extern struct fsnotify_event *fsnotify_remove_notify_event(struct fsnotify_group /* run all marks associated with an inode and update inode->i_fsnotify_mask */ extern void fsnotify_recalc_inode_mask(struct inode *inode); -extern void fsnotify_init_mark(struct fsnotify_mark_entry *entry, void (*free_mark)(struct fsnotify_mark_entry *entry)); +extern void fsnotify_init_mark(struct fsnotify_mark *entry, void (*free_mark)(struct fsnotify_mark *entry)); /* find (and take a reference) to a mark associated with group and inode */ -extern struct fsnotify_mark_entry *fsnotify_find_mark_entry(struct fsnotify_group *group, struct inode *inode); +extern struct fsnotify_mark *fsnotify_find_mark_entry(struct fsnotify_group *group, struct inode *inode); /* copy the values from old into new */ -extern void fsnotify_duplicate_mark(struct fsnotify_mark_entry *new, struct fsnotify_mark_entry *old); +extern void fsnotify_duplicate_mark(struct fsnotify_mark *new, struct fsnotify_mark *old); /* attach the mark to both the group and the inode */ -extern int fsnotify_add_mark(struct fsnotify_mark_entry *entry, struct fsnotify_group *group, struct inode *inode, int allow_dups); +extern int fsnotify_add_mark(struct fsnotify_mark *entry, struct fsnotify_group *group, struct inode *inode, int allow_dups); /* given a mark, flag it to be freed when all references are dropped */ -extern void fsnotify_destroy_mark_by_entry(struct fsnotify_mark_entry *entry); +extern void fsnotify_destroy_mark_by_entry(struct fsnotify_mark *entry); /* run all the marks in a group, and flag them to be freed */ extern void fsnotify_clear_marks_by_group(struct fsnotify_group *group); -extern void fsnotify_get_mark(struct fsnotify_mark_entry *entry); -extern void fsnotify_put_mark(struct fsnotify_mark_entry *entry); +extern void fsnotify_get_mark(struct fsnotify_mark *entry); +extern void fsnotify_put_mark(struct fsnotify_mark *entry); extern void fsnotify_unmount_inodes(struct list_head *list); /* put here because inotify does some weird stuff when destroying watches */ diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index c21b05d2522..f16f909fbbc 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c @@ -22,7 +22,7 @@ struct audit_tree { struct audit_chunk { struct list_head hash; - struct fsnotify_mark_entry mark; + struct fsnotify_mark mark; struct list_head trees; /* with root here */ int dead; int count; @@ -134,7 +134,7 @@ static void __put_chunk(struct rcu_head *rcu) audit_put_chunk(chunk); } -static void audit_tree_destroy_watch(struct fsnotify_mark_entry *entry) +static void audit_tree_destroy_watch(struct fsnotify_mark *entry) { struct audit_chunk *chunk = container_of(entry, struct audit_chunk, mark); call_rcu(&chunk->head, __put_chunk); @@ -176,7 +176,7 @@ static inline struct list_head *chunk_hash(const struct inode *inode) /* hash_lock & entry->lock is held by caller */ static void insert_hash(struct audit_chunk *chunk) { - struct fsnotify_mark_entry *entry = &chunk->mark; + struct fsnotify_mark *entry = &chunk->mark; struct list_head *list; if (!entry->i.inode) @@ -222,7 +222,7 @@ static struct audit_chunk *find_chunk(struct node *p) static void untag_chunk(struct node *p) { struct audit_chunk *chunk = find_chunk(p); - struct fsnotify_mark_entry *entry = &chunk->mark; + struct fsnotify_mark *entry = &chunk->mark; struct audit_chunk *new; struct audit_tree *owner; int size = chunk->count - 1; @@ -316,7 +316,7 @@ out: static int create_chunk(struct inode *inode, struct audit_tree *tree) { - struct fsnotify_mark_entry *entry; + struct fsnotify_mark *entry; struct audit_chunk *chunk = alloc_chunk(1); if (!chunk) return -ENOMEM; @@ -354,7 +354,7 @@ static int create_chunk(struct inode *inode, struct audit_tree *tree) /* the first tagged inode becomes root of tree */ static int tag_chunk(struct inode *inode, struct audit_tree *tree) { - struct fsnotify_mark_entry *old_entry, *chunk_entry; + struct fsnotify_mark *old_entry, *chunk_entry; struct audit_tree *owner; struct audit_chunk *chunk, *old; struct node *p; @@ -911,7 +911,7 @@ static int audit_tree_handle_event(struct fsnotify_group *group, struct fsnotify return -EOPNOTSUPP; } -static void audit_tree_freeing_mark(struct fsnotify_mark_entry *entry, struct fsnotify_group *group) +static void audit_tree_freeing_mark(struct fsnotify_mark *entry, struct fsnotify_group *group) { struct audit_chunk *chunk = container_of(entry, struct audit_chunk, mark); diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c index 6304ee5d764..d8cb55a5c05 100644 --- a/kernel/audit_watch.c +++ b/kernel/audit_watch.c @@ -56,7 +56,7 @@ struct audit_watch { struct audit_parent { struct list_head watches; /* anchor for audit_watch->wlist */ - struct fsnotify_mark_entry mark; /* fsnotify mark on the inode */ + struct fsnotify_mark mark; /* fsnotify mark on the inode */ }; /* fsnotify handle. */ @@ -72,7 +72,7 @@ static void audit_free_parent(struct audit_parent *parent) kfree(parent); } -static void audit_watch_free_mark(struct fsnotify_mark_entry *entry) +static void audit_watch_free_mark(struct fsnotify_mark *entry) { struct audit_parent *parent; @@ -99,7 +99,7 @@ static void audit_put_parent(struct audit_parent *parent) static inline struct audit_parent *audit_find_parent(struct inode *inode) { struct audit_parent *parent = NULL; - struct fsnotify_mark_entry *entry; + struct fsnotify_mark *entry; spin_lock(&inode->i_lock); entry = fsnotify_find_mark_entry(audit_watch_group, inode); @@ -517,7 +517,7 @@ static bool audit_watch_should_send_event(struct fsnotify_group *group, struct i struct vfsmount *mnt, __u32 mask, void *data, int data_type) { - struct fsnotify_mark_entry *entry; + struct fsnotify_mark *entry; bool send; spin_lock(&inode->i_lock); diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 853185f7ba7..b87a63beb66 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1724,7 +1724,7 @@ static inline void handle_one(const struct inode *inode) struct audit_tree_refs *p; struct audit_chunk *chunk; int count; - if (likely(hlist_empty(&inode->i_fsnotify_mark_entries))) + if (likely(hlist_empty(&inode->i_fsnotify_marks))) return; context = current->audit_context; p = context->trees; @@ -1767,7 +1767,7 @@ retry: seq = read_seqbegin(&rename_lock); for(;;) { struct inode *inode = d->d_inode; - if (inode && unlikely(!hlist_empty(&inode->i_fsnotify_mark_entries))) { + if (inode && unlikely(!hlist_empty(&inode->i_fsnotify_marks))) { struct audit_chunk *chunk; chunk = audit_tree_lookup(inode); if (chunk) { -- cgit v1.2.3