diff options
Diffstat (limited to 'fs/autofs4/expire.c')
-rw-r--r-- | fs/autofs4/expire.c | 36 |
1 files changed, 13 insertions, 23 deletions
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index 1feb68ecef95..842d00048a65 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); |
@@ -404,11 +399,6 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb, | |||
404 | DPRINTK("checking mountpoint %p %.*s", | 399 | DPRINTK("checking mountpoint %p %.*s", |
405 | dentry, (int)dentry->d_name.len, dentry->d_name.name); | 400 | dentry, (int)dentry->d_name.len, dentry->d_name.name); |
406 | 401 | ||
407 | /* Path walk currently on this dentry? */ | ||
408 | ino_count = atomic_read(&ino->count) + 2; | ||
409 | if (dentry->d_count > ino_count) | ||
410 | goto next; | ||
411 | |||
412 | /* Can we umount this guy */ | 402 | /* Can we umount this guy */ |
413 | if (autofs4_mount_busy(mnt, dentry)) | 403 | if (autofs4_mount_busy(mnt, dentry)) |
414 | goto next; | 404 | goto next; |