Commit 9756b9187eebb093b9f6a154ecceb67648e53391

Authored by Lino Sanfilippo
Committed by Linus Torvalds
1 parent e1e5a9f84e

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>

Showing 1 changed file with 22 additions and 28 deletions Side-by-side Diff

... ... @@ -20,29 +20,30 @@
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)
  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.
40 46 *
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.
45   - *
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
48 49 * free_i_list)
... ... @@ -64,18 +65,11 @@
64 65 * inode. We take i_lock and walk the i_fsnotify_marks safely. For each
65 66 * mark on the list we take a reference (so the mark can't disappear under us).
66 67 * We remove that mark form the inode's list of marks and we add this mark to a
67   - * private list anchored on the stack using i_free_list; At this point we no
68   - * longer fear anything finding the mark using the inode's list of marks.
69   - *
70   - * We can safely and locklessly run the private list on the stack of everything
71   - * we just unattached from the original inode. For each mark on the private list
72   - * we grab the mark-> and can thus dereference mark->group and mark->inode. If
73   - * we see the group and inode are not NULL we take those locks. Now holding all
74   - * 3 locks we can completely remove the mark from other tasks finding it in the
75   - * future. Remember, 10 things might already be referencing this mark, but they
76   - * better be holding a ref. We drop our reference we took before we unhooked it
77   - * from the inode. When the ref hits 0 we can free the mark.
78   - *
  68 + * private list anchored on the stack using i_free_list; we walk i_free_list
  69 + * and before we destroy the mark we make sure that we dont race with a
  70 + * concurrent destroy_group by getting a ref to the marks group and taking the
  71 + * groups mutex.
  72 +
79 73 * Very similarly for freeing by group, except we use free_g_list.
80 74 *
81 75 * This has the very interesting property of being able to run concurrently with