···3030 * There are 3 spinlocks involved with fsnotify inode marks and they MUST3131 * be taken in order as follows:3232 *3333- * entry->lock3333+ * mark->lock3434 * group->mark_lock3535 * inode->i_lock3636 *3737- * entry->lock protects 2 things, entry->group and entry->inode. You must hold3737+ * mark->lock protects 2 things, mark->group and mark->inode. You must hold3838 * that lock to dereference either of these things (they could be NULL even with3939 * the lock)4040 *4141 * group->mark_lock protects the marks_list anchored inside a given group4242- * and each entry is hooked via the g_list. It also sorta protects the4242+ * and each mark is hooked via the g_list. It also sorta protects the4343 * free_g_list, which when used is anchored by a private list on the stack of the4444 * task which held the group->mark_lock.4545 *4646 * inode->i_lock protects the i_fsnotify_marks list anchored inside a4747- * given inode and each entry is hooked via the i_list. (and sorta the4747+ * given inode and each mark is hooked via the i_list. (and sorta the4848 * free_i_list)4949 *5050 *···9595#include <linux/fsnotify_backend.h>9696#include "fsnotify.h"97979898-void fsnotify_get_mark(struct fsnotify_mark *entry)9898+void fsnotify_get_mark(struct fsnotify_mark *mark)9999{100100- atomic_inc(&entry->refcnt);100100+ atomic_inc(&mark->refcnt);101101}102102103103-void fsnotify_put_mark(struct fsnotify_mark *entry)103103+void fsnotify_put_mark(struct fsnotify_mark *mark)104104{105105- if (atomic_dec_and_test(&entry->refcnt))106106- entry->free_mark(entry);105105+ if (atomic_dec_and_test(&mark->refcnt))106106+ mark->free_mark(mark);107107}108108109109/*···111111 */112112static void fsnotify_recalc_inode_mask_locked(struct inode *inode)113113{114114- struct fsnotify_mark *entry;114114+ struct fsnotify_mark *mark;115115 struct hlist_node *pos;116116 __u32 new_mask = 0;117117118118 assert_spin_locked(&inode->i_lock);119119120120- hlist_for_each_entry(entry, pos, &inode->i_fsnotify_marks, i.i_list)121121- new_mask |= entry->mask;120120+ hlist_for_each_entry(mark, pos, &inode->i_fsnotify_marks, i.i_list)121121+ new_mask |= mark->mask;122122 inode->i_fsnotify_mask = new_mask;123123}124124···138138/*139139 * Any time a mark is getting freed we end up here.140140 * The caller had better be holding a reference to this mark so we don't actually141141- * do the final put under the entry->lock141141+ * do the final put under the mark->lock142142 */143143-void fsnotify_destroy_mark(struct fsnotify_mark *entry)143143+void fsnotify_destroy_mark(struct fsnotify_mark *mark)144144{145145 struct fsnotify_group *group;146146 struct inode *inode;147147148148- spin_lock(&entry->lock);148148+ spin_lock(&mark->lock);149149150150- group = entry->group;151151- inode = entry->i.inode;150150+ group = mark->group;151151+ inode = mark->i.inode;152152153153 BUG_ON(group && !inode);154154 BUG_ON(!group && inode);155155156156 /* if !group something else already marked this to die */157157 if (!group) {158158- spin_unlock(&entry->lock);158158+ spin_unlock(&mark->lock);159159 return;160160 }161161162162 /* 1 from caller and 1 for being on i_list/g_list */163163- BUG_ON(atomic_read(&entry->refcnt) < 2);163163+ BUG_ON(atomic_read(&mark->refcnt) < 2);164164165165 spin_lock(&group->mark_lock);166166 spin_lock(&inode->i_lock);167167168168- hlist_del_init(&entry->i.i_list);169169- entry->i.inode = NULL;168168+ hlist_del_init(&mark->i.i_list);169169+ mark->i.inode = NULL;170170171171- list_del_init(&entry->g_list);172172- entry->group = NULL;171171+ list_del_init(&mark->g_list);172172+ mark->group = NULL;173173174174- fsnotify_put_mark(entry); /* for i_list and g_list */174174+ fsnotify_put_mark(mark); /* for i_list and g_list */175175176176 /*177177 * this mark is now off the inode->i_fsnotify_marks list and we···182182183183 spin_unlock(&inode->i_lock);184184 spin_unlock(&group->mark_lock);185185- spin_unlock(&entry->lock);185185+ spin_unlock(&mark->lock);186186187187 /*188188 * Some groups like to know that marks are being freed. This is a189189- * callback to the group function to let it know that this entry189189+ * callback to the group function to let it know that this mark190190 * is being freed.191191 */192192 if (group->ops->freeing_mark)193193- group->ops->freeing_mark(entry, group);193193+ group->ops->freeing_mark(mark, group);194194195195 /*196196 * __fsnotify_update_child_dentry_flags(inode);197197 *198198 * I really want to call that, but we can't, we have no idea if the inode199199- * still exists the second we drop the entry->lock.199199+ * still exists the second we drop the mark->lock.200200 *201201 * The next time an event arrive to this inode from one of it's children202202 * __fsnotify_parent will see that the inode doesn't care about it's···221221 */222222void fsnotify_clear_marks_by_group(struct fsnotify_group *group)223223{224224- struct fsnotify_mark *lentry, *entry;224224+ struct fsnotify_mark *lmark, *mark;225225 LIST_HEAD(free_list);226226227227 spin_lock(&group->mark_lock);228228- list_for_each_entry_safe(entry, lentry, &group->marks_list, g_list) {229229- list_add(&entry->free_g_list, &free_list);230230- list_del_init(&entry->g_list);231231- fsnotify_get_mark(entry);228228+ list_for_each_entry_safe(mark, lmark, &group->marks_list, g_list) {229229+ list_add(&mark->free_g_list, &free_list);230230+ list_del_init(&mark->g_list);231231+ fsnotify_get_mark(mark);232232 }233233 spin_unlock(&group->mark_lock);234234235235- list_for_each_entry_safe(entry, lentry, &free_list, free_g_list) {236236- fsnotify_destroy_mark(entry);237237- fsnotify_put_mark(entry);235235+ list_for_each_entry_safe(mark, lmark, &free_list, free_g_list) {236236+ fsnotify_destroy_mark(mark);237237+ fsnotify_put_mark(mark);238238 }239239}240240···243243 */244244void fsnotify_clear_marks_by_inode(struct inode *inode)245245{246246- struct fsnotify_mark *entry, *lentry;246246+ struct fsnotify_mark *mark, *lmark;247247 struct hlist_node *pos, *n;248248 LIST_HEAD(free_list);249249250250 spin_lock(&inode->i_lock);251251- hlist_for_each_entry_safe(entry, pos, n, &inode->i_fsnotify_marks, i.i_list) {252252- list_add(&entry->i.free_i_list, &free_list);253253- hlist_del_init(&entry->i.i_list);254254- fsnotify_get_mark(entry);251251+ hlist_for_each_entry_safe(mark, pos, n, &inode->i_fsnotify_marks, i.i_list) {252252+ list_add(&mark->i.free_i_list, &free_list);253253+ hlist_del_init(&mark->i.i_list);254254+ fsnotify_get_mark(mark);255255 }256256 spin_unlock(&inode->i_lock);257257258258- list_for_each_entry_safe(entry, lentry, &free_list, i.free_i_list) {259259- fsnotify_destroy_mark(entry);260260- fsnotify_put_mark(entry);258258+ list_for_each_entry_safe(mark, lmark, &free_list, i.free_i_list) {259259+ fsnotify_destroy_mark(mark);260260+ fsnotify_put_mark(mark);261261 }262262}263263···268268struct fsnotify_mark *fsnotify_find_mark(struct fsnotify_group *group,269269 struct inode *inode)270270{271271- struct fsnotify_mark *entry;271271+ struct fsnotify_mark *mark;272272 struct hlist_node *pos;273273274274 assert_spin_locked(&inode->i_lock);275275276276- hlist_for_each_entry(entry, pos, &inode->i_fsnotify_marks, i.i_list) {277277- if (entry->group == group) {278278- fsnotify_get_mark(entry);279279- return entry;276276+ hlist_for_each_entry(mark, pos, &inode->i_fsnotify_marks, i.i_list) {277277+ if (mark->group == group) {278278+ fsnotify_get_mark(mark);279279+ return mark;280280 }281281 }282282 return NULL;···294294/*295295 * Nothing fancy, just initialize lists and locks and counters.296296 */297297-void fsnotify_init_mark(struct fsnotify_mark *entry,298298- void (*free_mark)(struct fsnotify_mark *entry))297297+void fsnotify_init_mark(struct fsnotify_mark *mark,298298+ void (*free_mark)(struct fsnotify_mark *mark))299299{300300- spin_lock_init(&entry->lock);301301- atomic_set(&entry->refcnt, 1);302302- INIT_HLIST_NODE(&entry->i.i_list);303303- entry->group = NULL;304304- entry->mask = 0;305305- entry->i.inode = NULL;306306- entry->free_mark = free_mark;300300+ spin_lock_init(&mark->lock);301301+ atomic_set(&mark->refcnt, 1);302302+ INIT_HLIST_NODE(&mark->i.i_list);303303+ mark->group = NULL;304304+ mark->mask = 0;305305+ mark->i.inode = NULL;306306+ mark->free_mark = free_mark;307307}308308309309/*310310- * Attach an initialized mark entry to a given group and inode.310310+ * Attach an initialized mark mark to a given group and inode.311311 * These marks may be used for the fsnotify backend to determine which312312 * event types should be delivered to which group and for which inodes.313313 */314314-int fsnotify_add_mark(struct fsnotify_mark *entry,314314+int fsnotify_add_mark(struct fsnotify_mark *mark,315315 struct fsnotify_group *group, struct inode *inode,316316 int allow_dups)317317{318318- struct fsnotify_mark *lentry = NULL;318318+ struct fsnotify_mark *lmark = NULL;319319 int ret = 0;320320321321 inode = igrab(inode);322322 if (unlikely(!inode))323323 return -EINVAL;324324325325- entry->flags = FSNOTIFY_MARK_FLAG_INODE;325325+ mark->flags = FSNOTIFY_MARK_FLAG_INODE;326326327327 /*328328 * if this group isn't being testing for inode type events we need···340340341341 /*342342 * LOCKING ORDER!!!!343343- * entry->lock343343+ * mark->lock344344 * group->mark_lock345345 * inode->i_lock346346 */347347- spin_lock(&entry->lock);347347+ spin_lock(&mark->lock);348348 spin_lock(&group->mark_lock);349349 spin_lock(&inode->i_lock);350350351351 if (!allow_dups)352352- lentry = fsnotify_find_mark(group, inode);353353- if (!lentry) {354354- entry->group = group;355355- entry->i.inode = inode;352352+ lmark = fsnotify_find_mark(group, inode);353353+ if (!lmark) {354354+ mark->group = group;355355+ mark->i.inode = inode;356356357357- hlist_add_head(&entry->i.i_list, &inode->i_fsnotify_marks);358358- list_add(&entry->g_list, &group->marks_list);357357+ hlist_add_head(&mark->i.i_list, &inode->i_fsnotify_marks);358358+ list_add(&mark->g_list, &group->marks_list);359359360360- fsnotify_get_mark(entry); /* for i_list and g_list */360360+ fsnotify_get_mark(mark); /* for i_list and g_list */361361362362 atomic_inc(&group->num_marks);363363···366366367367 spin_unlock(&inode->i_lock);368368 spin_unlock(&group->mark_lock);369369- spin_unlock(&entry->lock);369369+ spin_unlock(&mark->lock);370370371371- if (lentry) {371371+ if (lmark) {372372 ret = -EEXIST;373373 iput(inode);374374- fsnotify_put_mark(lentry);374374+ fsnotify_put_mark(lmark);375375 } else {376376 __fsnotify_update_child_dentry_flags(inode);377377 }
+13-13
include/linux/fsnotify_backend.h
···8383 int data_type);8484 int (*handle_event)(struct fsnotify_group *group, struct fsnotify_event *event);8585 void (*free_group_priv)(struct fsnotify_group *group);8686- void (*freeing_mark)(struct fsnotify_mark *entry, struct fsnotify_group *group);8686+ void (*freeing_mark)(struct fsnotify_mark *mark, struct fsnotify_group *group);8787 void (*free_event_priv)(struct fsnotify_event_private_data *priv);8888};8989···135135136136 /* stores all fastpath marks assoc with this group so they can be cleaned on unregister */137137 spinlock_t mark_lock; /* protect marks_list */138138- atomic_t num_marks; /* 1 for each mark entry and 1 for not being138138+ atomic_t num_marks; /* 1 for each mark and 1 for not being139139 * past the point of no return when freeing140140 * a group */141141 struct list_head marks_list; /* all inode marks for this group */···229229 * Inode specific fields in an fsnotify_mark230230 */231231struct fsnotify_inode_mark {232232- struct inode *inode; /* inode this entry is associated with */232232+ struct inode *inode; /* inode this mark is associated with */233233 struct hlist_node i_list; /* list of marks by inode->i_fsnotify_marks */234234 struct list_head free_i_list; /* tmp list used when freeing this mark */235235};···238238 * Mount point specific fields in an fsnotify_mark239239 */240240struct fsnotify_vfsmount_mark {241241- struct vfsmount *mnt; /* inode this entry is associated with */241241+ struct vfsmount *mnt; /* vfsmount this mark is associated with */242242 struct hlist_node m_list; /* list of marks by inode->i_fsnotify_marks */243243 struct list_head free_m_list; /* tmp list used when freeing this mark */244244};245245246246/*247247- * a mark is simply an entry attached to an in core inode which allows an247247+ * a mark is simply an object attached to an in core inode which allows an248248 * fsnotify listener to indicate they are either no longer interested in events249249 * of a type matching mask or only interested in those events.250250 *···254254 * inode eviction or modification.255255 */256256struct fsnotify_mark {257257- __u32 mask; /* mask this mark entry is for */257257+ __u32 mask; /* mask this mark is for */258258 /* we hold ref for each i_list and g_list. also one ref for each 'thing'259259 * in kernel that found and may be using this mark. */260260 atomic_t refcnt; /* active things looking at this mark */261261- struct fsnotify_group *group; /* group this mark entry is for */261261+ struct fsnotify_group *group; /* group this mark is for */262262 struct list_head g_list; /* list of marks by group->i_fsnotify_marks */263263 spinlock_t lock; /* protect group and inode */264264 union {···269269#define FSNOTIFY_MARK_FLAG_INODE 0x01270270#define FSNOTIFY_MARK_FLAG_VFSMOUNT 0x02271271 unsigned int flags; /* vfsmount or inode mark? */272272- void (*free_mark)(struct fsnotify_mark *entry); /* called on final put+free */272272+ void (*free_mark)(struct fsnotify_mark *mark); /* called on final put+free */273273};274274275275#ifdef CONFIG_FSNOTIFY···361361362362/* run all marks associated with an inode and update inode->i_fsnotify_mask */363363extern void fsnotify_recalc_inode_mask(struct inode *inode);364364-extern void fsnotify_init_mark(struct fsnotify_mark *entry, void (*free_mark)(struct fsnotify_mark *entry));364364+extern void fsnotify_init_mark(struct fsnotify_mark *mark, void (*free_mark)(struct fsnotify_mark *mark));365365/* find (and take a reference) to a mark associated with group and inode */366366extern struct fsnotify_mark *fsnotify_find_mark(struct fsnotify_group *group, struct inode *inode);367367/* copy the values from old into new */368368extern void fsnotify_duplicate_mark(struct fsnotify_mark *new, struct fsnotify_mark *old);369369/* attach the mark to both the group and the inode */370370-extern int fsnotify_add_mark(struct fsnotify_mark *entry, struct fsnotify_group *group, struct inode *inode, int allow_dups);370370+extern int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group, struct inode *inode, int allow_dups);371371/* given a mark, flag it to be freed when all references are dropped */372372-extern void fsnotify_destroy_mark(struct fsnotify_mark *entry);372372+extern void fsnotify_destroy_mark(struct fsnotify_mark *mark);373373/* run all the marks in a group, and flag them to be freed */374374extern void fsnotify_clear_marks_by_group(struct fsnotify_group *group);375375-extern void fsnotify_get_mark(struct fsnotify_mark *entry);376376-extern void fsnotify_put_mark(struct fsnotify_mark *entry);375375+extern void fsnotify_get_mark(struct fsnotify_mark *mark);376376+extern void fsnotify_put_mark(struct fsnotify_mark *mark);377377extern void fsnotify_unmount_inodes(struct list_head *list);378378379379/* put here because inotify does some weird stuff when destroying watches */