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 | |
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')
-rw-r--r-- | Documentation/filesystems/Locking | 16 | ||||
-rw-r--r-- | Documentation/filesystems/dentry-locking.txt | 40 | ||||
-rw-r--r-- | Documentation/filesystems/porting | 8 |
3 files changed, 34 insertions, 30 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index a15ee207b449..bdad6414dfa0 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking | |||
@@ -21,14 +21,14 @@ prototypes: | |||
21 | char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen); | 21 | char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen); |
22 | 22 | ||
23 | locking rules: | 23 | locking rules: |
24 | dcache_lock rename_lock ->d_lock may block | 24 | rename_lock ->d_lock may block |
25 | d_revalidate: no no no yes | 25 | d_revalidate: no no yes |
26 | d_hash no no no no | 26 | d_hash no no no |
27 | d_compare: no yes no no | 27 | d_compare: yes no no |
28 | d_delete: yes no yes no | 28 | d_delete: no yes no |
29 | d_release: no no no yes | 29 | d_release: no no yes |
30 | d_iput: no no no yes | 30 | d_iput: no no yes |
31 | d_dname: no no no no | 31 | d_dname: no no no |
32 | 32 | ||
33 | --------------------------- inode_operations --------------------------- | 33 | --------------------------- inode_operations --------------------------- |
34 | prototypes: | 34 | prototypes: |
diff --git a/Documentation/filesystems/dentry-locking.txt b/Documentation/filesystems/dentry-locking.txt index 79334ed5daa7..30b6a40f5650 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 |
diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting index 9fd31940a8ef..1eb76959d096 100644 --- a/Documentation/filesystems/porting +++ b/Documentation/filesystems/porting | |||
@@ -216,7 +216,6 @@ had ->revalidate()) add calls in ->follow_link()/->readlink(). | |||
216 | ->d_parent changes are not protected by BKL anymore. Read access is safe | 216 | ->d_parent changes are not protected by BKL anymore. Read access is safe |
217 | if at least one of the following is true: | 217 | if at least one of the following is true: |
218 | * filesystem has no cross-directory rename() | 218 | * filesystem has no cross-directory rename() |
219 | * dcache_lock is held | ||
220 | * we know that parent had been locked (e.g. we are looking at | 219 | * we know that parent had been locked (e.g. we are looking at |
221 | ->d_parent of ->lookup() argument). | 220 | ->d_parent of ->lookup() argument). |
222 | * we are called from ->rename(). | 221 | * we are called from ->rename(). |
@@ -340,3 +339,10 @@ look at examples of other filesystems) for guidance. | |||
340 | .d_hash() calling convention and locking rules are significantly | 339 | .d_hash() calling convention and locking rules are significantly |
341 | changed. Read updated documentation in Documentation/filesystems/vfs.txt (and | 340 | changed. Read updated documentation in Documentation/filesystems/vfs.txt (and |
342 | look at examples of other filesystems) for guidance. | 341 | look at examples of other filesystems) for guidance. |
342 | |||
343 | --- | ||
344 | [mandatory] | ||
345 | dcache_lock is gone, replaced by fine grained locks. See fs/dcache.c | ||
346 | for details of what locks to replace dcache_lock with in order to protect | ||
347 | particular things. Most of the time, a filesystem only needs ->d_lock, which | ||
348 | protects *all* the dcache state of a given dentry. | ||