diff options
| -rw-r--r-- | fs/autofs4/expire.c | 31 |
1 files changed, 13 insertions, 18 deletions
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index 1feb68ecef95..8c0e56d92938 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c | |||
| @@ -94,25 +94,21 @@ static struct dentry *get_next_positive_subdir(struct dentry *prev, | |||
| 94 | { | 94 | { |
| 95 | struct autofs_sb_info *sbi = autofs4_sbi(root->d_sb); | 95 | struct autofs_sb_info *sbi = autofs4_sbi(root->d_sb); |
| 96 | struct list_head *next; | 96 | struct list_head *next; |
| 97 | struct dentry *p, *q; | 97 | struct dentry *q; |
| 98 | 98 | ||
| 99 | spin_lock(&sbi->lookup_lock); | 99 | spin_lock(&sbi->lookup_lock); |
| 100 | spin_lock(&root->d_lock); | ||
| 100 | 101 | ||
| 101 | if (prev == NULL) { | 102 | if (prev) |
| 102 | spin_lock(&root->d_lock); | 103 | next = prev->d_u.d_child.next; |
| 104 | else { | ||
| 103 | prev = dget_dlock(root); | 105 | prev = dget_dlock(root); |
| 104 | next = prev->d_subdirs.next; | 106 | next = prev->d_subdirs.next; |
| 105 | p = prev; | ||
| 106 | goto start; | ||
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | p = prev; | 109 | cont: |
| 110 | spin_lock(&p->d_lock); | ||
| 111 | again: | ||
| 112 | next = p->d_u.d_child.next; | ||
| 113 | start: | ||
| 114 | if (next == &root->d_subdirs) { | 110 | if (next == &root->d_subdirs) { |
| 115 | spin_unlock(&p->d_lock); | 111 | spin_unlock(&root->d_lock); |
| 116 | spin_unlock(&sbi->lookup_lock); | 112 | spin_unlock(&sbi->lookup_lock); |
| 117 | dput(prev); | 113 | dput(prev); |
| 118 | return NULL; | 114 | return NULL; |
| @@ -121,16 +117,15 @@ start: | |||
| 121 | q = list_entry(next, struct dentry, d_u.d_child); | 117 | q = list_entry(next, struct dentry, d_u.d_child); |
| 122 | 118 | ||
| 123 | spin_lock_nested(&q->d_lock, DENTRY_D_LOCK_NESTED); | 119 | spin_lock_nested(&q->d_lock, DENTRY_D_LOCK_NESTED); |
| 124 | /* Negative dentry - try next */ | 120 | /* Already gone or negative dentry (under construction) - try next */ |
| 125 | if (!simple_positive(q)) { | 121 | if (q->d_count == 0 || !simple_positive(q)) { |
| 126 | spin_unlock(&p->d_lock); | 122 | spin_unlock(&q->d_lock); |
| 127 | lock_set_subclass(&q->d_lock.dep_map, 0, _RET_IP_); | 123 | next = q->d_u.d_child.next; |
| 128 | p = q; | 124 | goto cont; |
| 129 | goto again; | ||
| 130 | } | 125 | } |
| 131 | dget_dlock(q); | 126 | dget_dlock(q); |
| 132 | spin_unlock(&q->d_lock); | 127 | spin_unlock(&q->d_lock); |
| 133 | spin_unlock(&p->d_lock); | 128 | spin_unlock(&root->d_lock); |
| 134 | spin_unlock(&sbi->lookup_lock); | 129 | spin_unlock(&sbi->lookup_lock); |
| 135 | 130 | ||
| 136 | dput(prev); | 131 | dput(prev); |
