Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fsnotify: update comments concerning locking scheme

There have been changes in the locking scheme of fsnotify but the
comments in the source code have not been updated yet. This patch
corrects this.

Signed-off-by: Lino Sanfilippo <LinoSanfilippo@gmx.de>
Cc: Eric Paris <eparis@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Lino Sanfilippo and committed by
Linus Torvalds
9756b918 e1e5a9f8

+22 -28
+22 -28
fs/notify/mark.c
··· 20 20 * fsnotify inode mark locking/lifetime/and refcnting 21 21 * 22 22 * REFCNT: 23 - * The mark->refcnt tells how many "things" in the kernel currently are 24 - * referencing this object. The object typically will live inside the kernel 25 - * with a refcnt of 2, one for each list it is on (i_list, g_list). Any task 26 - * which can find this object holding the appropriete locks, can take a reference 27 - * and the object itself is guaranteed to survive until the reference is dropped. 23 + * The group->recnt and mark->refcnt tell how many "things" in the kernel 24 + * currently are referencing the objects. Both kind of objects typically will 25 + * live inside the kernel with a refcnt of 2, one for its creation and one for 26 + * the reference a group and a mark hold to each other. 27 + * If you are holding the appropriate locks, you can take a reference and the 28 + * object itself is guaranteed to survive until the reference is dropped. 28 29 * 29 30 * LOCKING: 30 - * There are 3 spinlocks involved with fsnotify inode marks and they MUST 31 - * be taken in order as follows: 31 + * There are 3 locks involved with fsnotify inode marks and they MUST be taken 32 + * in order as follows: 32 33 * 34 + * group->mark_mutex 33 35 * mark->lock 34 - * group->mark_lock 35 36 * inode->i_lock 36 37 * 37 - * mark->lock protects 2 things, mark->group and mark->inode. You must hold 38 - * that lock to dereference either of these things (they could be NULL even with 39 - * the lock) 40 - * 41 - * group->mark_lock protects the marks_list anchored inside a given group 42 - * and each mark is hooked via the g_list. It also sorta protects the 43 - * free_g_list, which when used is anchored by a private list on the stack of the 44 - * task which held the group->mark_lock. 38 + * group->mark_mutex protects the marks_list anchored inside a given group and 39 + * each mark is hooked via the g_list. It also protects the groups private 40 + * data (i.e group limits). 41 + 42 + * mark->lock protects the marks attributes like its masks and flags. 43 + * Furthermore it protects the access to a reference of the group that the mark 44 + * is assigned to as well as the access to a reference of the inode/vfsmount 45 + * that is being watched by the mark. 45 46 * 46 47 * inode->i_lock protects the i_fsnotify_marks list anchored inside a 47 48 * given inode and each mark is hooked via the i_list. (and sorta the ··· 65 64 * inode. We take i_lock and walk the i_fsnotify_marks safely. For each 66 65 * mark on the list we take a reference (so the mark can't disappear under us). 67 66 * We remove that mark form the inode's list of marks and we add this mark to a 68 - * private list anchored on the stack using i_free_list; At this point we no 69 - * longer fear anything finding the mark using the inode's list of marks. 70 - * 71 - * We can safely and locklessly run the private list on the stack of everything 72 - * we just unattached from the original inode. For each mark on the private list 73 - * we grab the mark-> and can thus dereference mark->group and mark->inode. If 74 - * we see the group and inode are not NULL we take those locks. Now holding all 75 - * 3 locks we can completely remove the mark from other tasks finding it in the 76 - * future. Remember, 10 things might already be referencing this mark, but they 77 - * better be holding a ref. We drop our reference we took before we unhooked it 78 - * from the inode. When the ref hits 0 we can free the mark. 79 - * 67 + * private list anchored on the stack using i_free_list; we walk i_free_list 68 + * and before we destroy the mark we make sure that we dont race with a 69 + * concurrent destroy_group by getting a ref to the marks group and taking the 70 + * groups mutex. 71 + 80 72 * Very similarly for freeing by group, except we use free_g_list. 81 73 * 82 74 * This has the very interesting property of being able to run concurrently with