diff options
author | Nick Piggin <npiggin@kernel.dk> | 2011-01-07 01:49:38 -0500 |
---|---|---|
committer | Nick Piggin <npiggin@kernel.dk> | 2011-01-07 01:50:23 -0500 |
commit | b5c84bf6f6fa3a7dfdcb556023a62953574b60ee (patch) | |
tree | 7a2c299a180713e21d5cb653cb933121adf53c31 /Documentation/filesystems/dentry-locking.txt | |
parent | 949854d02455080d20cd3e1db28a3a18daf7599d (diff) |
fs: dcache remove dcache_lock
dcache_lock no longer protects anything. remove it.
Signed-off-by: Nick Piggin <npiggin@kernel.dk>
Diffstat (limited to 'Documentation/filesystems/dentry-locking.txt')
-rw-r--r-- | Documentation/filesystems/dentry-locking.txt | 40 |
1 files changed, 19 insertions, 21 deletions
diff --git a/Documentation/filesystems/dentry-locking.txt b/Documentation/filesystems/dentry-locking.txt index 79334ed5daa..30b6a40f565 100644 --- a/Documentation/filesystems/dentry-locking.txt +++ b/Documentation/filesystems/dentry-locking.txt | |||
@@ -31,6 +31,7 @@ significant change is the way d_lookup traverses the hash chain, it | |||
31 | doesn't acquire the dcache_lock for this and rely on RCU to ensure | 31 | doesn't acquire the dcache_lock for this and rely on RCU to ensure |
32 | that the dentry has not been *freed*. | 32 | that the dentry has not been *freed*. |
33 | 33 | ||
34 | dcache_lock no longer exists, dentry locking is explained in fs/dcache.c | ||
34 | 35 | ||
35 | Dcache locking details | 36 | Dcache locking details |
36 | ====================== | 37 | ====================== |
@@ -50,14 +51,12 @@ Safe lock-free look-up of dcache hash table | |||
50 | 51 | ||
51 | Dcache is a complex data structure with the hash table entries also | 52 | Dcache is a complex data structure with the hash table entries also |
52 | linked together in other lists. In 2.4 kernel, dcache_lock protected | 53 | linked together in other lists. In 2.4 kernel, dcache_lock protected |
53 | all the lists. We applied RCU only on hash chain walking. The rest of | 54 | all the lists. RCU dentry hash walking works like this: |
54 | the lists are still protected by dcache_lock. Some of the important | ||
55 | changes are : | ||
56 | 55 | ||
57 | 1. The deletion from hash chain is done using hlist_del_rcu() macro | 56 | 1. The deletion from hash chain is done using hlist_del_rcu() macro |
58 | which doesn't initialize next pointer of the deleted dentry and | 57 | which doesn't initialize next pointer of the deleted dentry and |
59 | this allows us to walk safely lock-free while a deletion is | 58 | this allows us to walk safely lock-free while a deletion is |
60 | happening. | 59 | happening. This is a standard hlist_rcu iteration. |
61 | 60 | ||
62 | 2. Insertion of a dentry into the hash table is done using | 61 | 2. Insertion of a dentry into the hash table is done using |
63 | hlist_add_head_rcu() which take care of ordering the writes - the | 62 | hlist_add_head_rcu() which take care of ordering the writes - the |
@@ -66,19 +65,18 @@ changes are : | |||
66 | which has since been replaced by hlist_for_each_entry_rcu(), while | 65 | which has since been replaced by hlist_for_each_entry_rcu(), while |
67 | walking the hash chain. The only requirement is that all | 66 | walking the hash chain. The only requirement is that all |
68 | initialization to the dentry must be done before | 67 | initialization to the dentry must be done before |
69 | hlist_add_head_rcu() since we don't have dcache_lock protection | 68 | hlist_add_head_rcu() since we don't have lock protection |
70 | while traversing the hash chain. This isn't different from the | 69 | while traversing the hash chain. |
71 | existing code. | 70 | |
72 | 71 | 3. The dentry looked up without holding locks cannot be returned for | |
73 | 3. The dentry looked up without holding dcache_lock by cannot be | 72 | walking if it is unhashed. It then may have a NULL d_inode or other |
74 | returned for walking if it is unhashed. It then may have a NULL | 73 | bogosity since RCU doesn't protect the other fields in the dentry. We |
75 | d_inode or other bogosity since RCU doesn't protect the other | 74 | therefore use a flag DCACHE_UNHASHED to indicate unhashed dentries |
76 | fields in the dentry. We therefore use a flag DCACHE_UNHASHED to | 75 | and use this in conjunction with a per-dentry lock (d_lock). Once |
77 | indicate unhashed dentries and use this in conjunction with a | 76 | looked up without locks, we acquire the per-dentry lock (d_lock) and |
78 | per-dentry lock (d_lock). Once looked up without the dcache_lock, | 77 | check if the dentry is unhashed. If so, the look-up is failed. If not, |
79 | we acquire the per-dentry lock (d_lock) and check if the dentry is | 78 | the reference count of the dentry is increased and the dentry is |
80 | unhashed. If so, the look-up is failed. If not, the reference count | 79 | returned. |
81 | of the dentry is increased and the dentry is returned. | ||
82 | 80 | ||
83 | 4. Once a dentry is looked up, it must be ensured during the path walk | 81 | 4. Once a dentry is looked up, it must be ensured during the path walk |
84 | for that component it doesn't go away. In pre-2.5.10 code, this was | 82 | for that component it doesn't go away. In pre-2.5.10 code, this was |
@@ -86,10 +84,10 @@ changes are : | |||
86 | In some sense, dcache_rcu path walking looks like the pre-2.5.10 | 84 | In some sense, dcache_rcu path walking looks like the pre-2.5.10 |
87 | version. | 85 | version. |
88 | 86 | ||
89 | 5. All dentry hash chain updates must take the dcache_lock as well as | 87 | 5. All dentry hash chain updates must take the per-dentry lock (see |
90 | the per-dentry lock in that order. dput() does this to ensure that | 88 | fs/dcache.c). This excludes dput() to ensure that a dentry that has |
91 | a dentry that has just been looked up in another CPU doesn't get | 89 | been looked up concurrently does not get deleted before dget() can |
92 | deleted before dget() can be done on it. | 90 | take a ref. |
93 | 91 | ||
94 | 6. There are several ways to do reference counting of RCU protected | 92 | 6. There are several ways to do reference counting of RCU protected |
95 | objects. One such example is in ipv4 route cache where deferred | 93 | objects. One such example is in ipv4 route cache where deferred |