diff options
Diffstat (limited to 'fs/autofs4')
-rw-r--r-- | fs/autofs4/autofs_i.h | 2 | ||||
-rw-r--r-- | fs/autofs4/dev-ioctl.c | 4 | ||||
-rw-r--r-- | fs/autofs4/expire.c | 84 | ||||
-rw-r--r-- | fs/autofs4/root.c | 64 | ||||
-rw-r--r-- | fs/autofs4/waitq.c | 6 |
5 files changed, 92 insertions, 68 deletions
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h index 54f923792728..475f9c597cb7 100644 --- a/fs/autofs4/autofs_i.h +++ b/fs/autofs4/autofs_i.h | |||
@@ -61,8 +61,6 @@ do { \ | |||
61 | current->pid, __func__, ##args); \ | 61 | current->pid, __func__, ##args); \ |
62 | } while (0) | 62 | } while (0) |
63 | 63 | ||
64 | extern spinlock_t autofs4_lock; | ||
65 | |||
66 | /* Unified info structure. This is pointed to by both the dentry and | 64 | /* Unified info structure. This is pointed to by both the dentry and |
67 | inode structures. Each file in the filesystem has an instance of this | 65 | inode structures. Each file in the filesystem has an instance of this |
68 | structure. It holds a reference to the dentry, so dentries are never | 66 | structure. It holds a reference to the dentry, so dentries are never |
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c index 1442da4860e5..509fe1eb66ae 100644 --- a/fs/autofs4/dev-ioctl.c +++ b/fs/autofs4/dev-ioctl.c | |||
@@ -372,6 +372,10 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp, | |||
372 | return -EBUSY; | 372 | return -EBUSY; |
373 | } else { | 373 | } else { |
374 | struct file *pipe = fget(pipefd); | 374 | struct file *pipe = fget(pipefd); |
375 | if (!pipe) { | ||
376 | err = -EBADF; | ||
377 | goto out; | ||
378 | } | ||
375 | if (!pipe->f_op || !pipe->f_op->write) { | 379 | if (!pipe->f_op || !pipe->f_op->write) { |
376 | err = -EPIPE; | 380 | err = -EPIPE; |
377 | fput(pipe); | 381 | fput(pipe); |
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index f43100b9662b..450f529a4eae 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c | |||
@@ -87,18 +87,70 @@ done: | |||
87 | } | 87 | } |
88 | 88 | ||
89 | /* | 89 | /* |
90 | * Calculate and dget next entry in the subdirs list under root. | ||
91 | */ | ||
92 | static struct dentry *get_next_positive_subdir(struct dentry *prev, | ||
93 | struct dentry *root) | ||
94 | { | ||
95 | struct autofs_sb_info *sbi = autofs4_sbi(root->d_sb); | ||
96 | struct list_head *next; | ||
97 | struct dentry *p, *q; | ||
98 | |||
99 | spin_lock(&sbi->lookup_lock); | ||
100 | |||
101 | if (prev == NULL) { | ||
102 | spin_lock(&root->d_lock); | ||
103 | prev = dget_dlock(root); | ||
104 | next = prev->d_subdirs.next; | ||
105 | p = prev; | ||
106 | goto start; | ||
107 | } | ||
108 | |||
109 | p = prev; | ||
110 | spin_lock(&p->d_lock); | ||
111 | again: | ||
112 | next = p->d_u.d_child.next; | ||
113 | start: | ||
114 | if (next == &root->d_subdirs) { | ||
115 | spin_unlock(&p->d_lock); | ||
116 | spin_unlock(&sbi->lookup_lock); | ||
117 | dput(prev); | ||
118 | return NULL; | ||
119 | } | ||
120 | |||
121 | q = list_entry(next, struct dentry, d_u.d_child); | ||
122 | |||
123 | spin_lock_nested(&q->d_lock, DENTRY_D_LOCK_NESTED); | ||
124 | /* Negative dentry - try next */ | ||
125 | if (!simple_positive(q)) { | ||
126 | spin_unlock(&p->d_lock); | ||
127 | p = q; | ||
128 | goto again; | ||
129 | } | ||
130 | dget_dlock(q); | ||
131 | spin_unlock(&q->d_lock); | ||
132 | spin_unlock(&p->d_lock); | ||
133 | spin_unlock(&sbi->lookup_lock); | ||
134 | |||
135 | dput(prev); | ||
136 | |||
137 | return q; | ||
138 | } | ||
139 | |||
140 | /* | ||
90 | * Calculate and dget next entry in top down tree traversal. | 141 | * Calculate and dget next entry in top down tree traversal. |
91 | */ | 142 | */ |
92 | static struct dentry *get_next_positive_dentry(struct dentry *prev, | 143 | static struct dentry *get_next_positive_dentry(struct dentry *prev, |
93 | struct dentry *root) | 144 | struct dentry *root) |
94 | { | 145 | { |
146 | struct autofs_sb_info *sbi = autofs4_sbi(root->d_sb); | ||
95 | struct list_head *next; | 147 | struct list_head *next; |
96 | struct dentry *p, *ret; | 148 | struct dentry *p, *ret; |
97 | 149 | ||
98 | if (prev == NULL) | 150 | if (prev == NULL) |
99 | return dget(root); | 151 | return dget(root); |
100 | 152 | ||
101 | spin_lock(&autofs4_lock); | 153 | spin_lock(&sbi->lookup_lock); |
102 | relock: | 154 | relock: |
103 | p = prev; | 155 | p = prev; |
104 | spin_lock(&p->d_lock); | 156 | spin_lock(&p->d_lock); |
@@ -110,7 +162,7 @@ again: | |||
110 | 162 | ||
111 | if (p == root) { | 163 | if (p == root) { |
112 | spin_unlock(&p->d_lock); | 164 | spin_unlock(&p->d_lock); |
113 | spin_unlock(&autofs4_lock); | 165 | spin_unlock(&sbi->lookup_lock); |
114 | dput(prev); | 166 | dput(prev); |
115 | return NULL; | 167 | return NULL; |
116 | } | 168 | } |
@@ -140,7 +192,7 @@ again: | |||
140 | dget_dlock(ret); | 192 | dget_dlock(ret); |
141 | spin_unlock(&ret->d_lock); | 193 | spin_unlock(&ret->d_lock); |
142 | spin_unlock(&p->d_lock); | 194 | spin_unlock(&p->d_lock); |
143 | spin_unlock(&autofs4_lock); | 195 | spin_unlock(&sbi->lookup_lock); |
144 | 196 | ||
145 | dput(prev); | 197 | dput(prev); |
146 | 198 | ||
@@ -290,11 +342,8 @@ struct dentry *autofs4_expire_direct(struct super_block *sb, | |||
290 | spin_lock(&sbi->fs_lock); | 342 | spin_lock(&sbi->fs_lock); |
291 | ino = autofs4_dentry_ino(root); | 343 | ino = autofs4_dentry_ino(root); |
292 | /* No point expiring a pending mount */ | 344 | /* No point expiring a pending mount */ |
293 | if (ino->flags & AUTOFS_INF_PENDING) { | 345 | if (ino->flags & AUTOFS_INF_PENDING) |
294 | spin_unlock(&sbi->fs_lock); | 346 | goto out; |
295 | return NULL; | ||
296 | } | ||
297 | managed_dentry_set_transit(root); | ||
298 | if (!autofs4_direct_busy(mnt, root, timeout, do_now)) { | 347 | if (!autofs4_direct_busy(mnt, root, timeout, do_now)) { |
299 | struct autofs_info *ino = autofs4_dentry_ino(root); | 348 | struct autofs_info *ino = autofs4_dentry_ino(root); |
300 | ino->flags |= AUTOFS_INF_EXPIRING; | 349 | ino->flags |= AUTOFS_INF_EXPIRING; |
@@ -302,7 +351,7 @@ struct dentry *autofs4_expire_direct(struct super_block *sb, | |||
302 | spin_unlock(&sbi->fs_lock); | 351 | spin_unlock(&sbi->fs_lock); |
303 | return root; | 352 | return root; |
304 | } | 353 | } |
305 | managed_dentry_clear_transit(root); | 354 | out: |
306 | spin_unlock(&sbi->fs_lock); | 355 | spin_unlock(&sbi->fs_lock); |
307 | dput(root); | 356 | dput(root); |
308 | 357 | ||
@@ -336,13 +385,12 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb, | |||
336 | timeout = sbi->exp_timeout; | 385 | timeout = sbi->exp_timeout; |
337 | 386 | ||
338 | dentry = NULL; | 387 | dentry = NULL; |
339 | while ((dentry = get_next_positive_dentry(dentry, root))) { | 388 | while ((dentry = get_next_positive_subdir(dentry, root))) { |
340 | spin_lock(&sbi->fs_lock); | 389 | spin_lock(&sbi->fs_lock); |
341 | ino = autofs4_dentry_ino(dentry); | 390 | ino = autofs4_dentry_ino(dentry); |
342 | /* No point expiring a pending mount */ | 391 | /* No point expiring a pending mount */ |
343 | if (ino->flags & AUTOFS_INF_PENDING) | 392 | if (ino->flags & AUTOFS_INF_PENDING) |
344 | goto cont; | 393 | goto next; |
345 | managed_dentry_set_transit(dentry); | ||
346 | 394 | ||
347 | /* | 395 | /* |
348 | * Case 1: (i) indirect mount or top level pseudo direct mount | 396 | * Case 1: (i) indirect mount or top level pseudo direct mount |
@@ -402,8 +450,6 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb, | |||
402 | } | 450 | } |
403 | } | 451 | } |
404 | next: | 452 | next: |
405 | managed_dentry_clear_transit(dentry); | ||
406 | cont: | ||
407 | spin_unlock(&sbi->fs_lock); | 453 | spin_unlock(&sbi->fs_lock); |
408 | } | 454 | } |
409 | return NULL; | 455 | return NULL; |
@@ -415,13 +461,13 @@ found: | |||
415 | ino->flags |= AUTOFS_INF_EXPIRING; | 461 | ino->flags |= AUTOFS_INF_EXPIRING; |
416 | init_completion(&ino->expire_complete); | 462 | init_completion(&ino->expire_complete); |
417 | spin_unlock(&sbi->fs_lock); | 463 | spin_unlock(&sbi->fs_lock); |
418 | spin_lock(&autofs4_lock); | 464 | spin_lock(&sbi->lookup_lock); |
419 | spin_lock(&expired->d_parent->d_lock); | 465 | spin_lock(&expired->d_parent->d_lock); |
420 | spin_lock_nested(&expired->d_lock, DENTRY_D_LOCK_NESTED); | 466 | spin_lock_nested(&expired->d_lock, DENTRY_D_LOCK_NESTED); |
421 | list_move(&expired->d_parent->d_subdirs, &expired->d_u.d_child); | 467 | list_move(&expired->d_parent->d_subdirs, &expired->d_u.d_child); |
422 | spin_unlock(&expired->d_lock); | 468 | spin_unlock(&expired->d_lock); |
423 | spin_unlock(&expired->d_parent->d_lock); | 469 | spin_unlock(&expired->d_parent->d_lock); |
424 | spin_unlock(&autofs4_lock); | 470 | spin_unlock(&sbi->lookup_lock); |
425 | return expired; | 471 | return expired; |
426 | } | 472 | } |
427 | 473 | ||
@@ -484,8 +530,6 @@ int autofs4_expire_run(struct super_block *sb, | |||
484 | spin_lock(&sbi->fs_lock); | 530 | spin_lock(&sbi->fs_lock); |
485 | ino = autofs4_dentry_ino(dentry); | 531 | ino = autofs4_dentry_ino(dentry); |
486 | ino->flags &= ~AUTOFS_INF_EXPIRING; | 532 | ino->flags &= ~AUTOFS_INF_EXPIRING; |
487 | if (!d_unhashed(dentry)) | ||
488 | managed_dentry_clear_transit(dentry); | ||
489 | complete_all(&ino->expire_complete); | 533 | complete_all(&ino->expire_complete); |
490 | spin_unlock(&sbi->fs_lock); | 534 | spin_unlock(&sbi->fs_lock); |
491 | 535 | ||
@@ -513,9 +557,7 @@ int autofs4_do_expire_multi(struct super_block *sb, struct vfsmount *mnt, | |||
513 | spin_lock(&sbi->fs_lock); | 557 | spin_lock(&sbi->fs_lock); |
514 | ino->flags &= ~AUTOFS_INF_EXPIRING; | 558 | ino->flags &= ~AUTOFS_INF_EXPIRING; |
515 | spin_lock(&dentry->d_lock); | 559 | spin_lock(&dentry->d_lock); |
516 | if (ret) | 560 | if (!ret) { |
517 | __managed_dentry_clear_transit(dentry); | ||
518 | else { | ||
519 | if ((IS_ROOT(dentry) || | 561 | if ((IS_ROOT(dentry) || |
520 | (autofs_type_indirect(sbi->type) && | 562 | (autofs_type_indirect(sbi->type) && |
521 | IS_ROOT(dentry->d_parent))) && | 563 | IS_ROOT(dentry->d_parent))) && |
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index e6f84d26f4cf..f55ae23b137e 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -23,8 +23,6 @@ | |||
23 | 23 | ||
24 | #include "autofs_i.h" | 24 | #include "autofs_i.h" |
25 | 25 | ||
26 | DEFINE_SPINLOCK(autofs4_lock); | ||
27 | |||
28 | static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *); | 26 | static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *); |
29 | static int autofs4_dir_unlink(struct inode *,struct dentry *); | 27 | static int autofs4_dir_unlink(struct inode *,struct dentry *); |
30 | static int autofs4_dir_rmdir(struct inode *,struct dentry *); | 28 | static int autofs4_dir_rmdir(struct inode *,struct dentry *); |
@@ -125,15 +123,15 @@ static int autofs4_dir_open(struct inode *inode, struct file *file) | |||
125 | * autofs file system so just let the libfs routines handle | 123 | * autofs file system so just let the libfs routines handle |
126 | * it. | 124 | * it. |
127 | */ | 125 | */ |
128 | spin_lock(&autofs4_lock); | 126 | spin_lock(&sbi->lookup_lock); |
129 | spin_lock(&dentry->d_lock); | 127 | spin_lock(&dentry->d_lock); |
130 | if (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) { | 128 | if (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) { |
131 | spin_unlock(&dentry->d_lock); | 129 | spin_unlock(&dentry->d_lock); |
132 | spin_unlock(&autofs4_lock); | 130 | spin_unlock(&sbi->lookup_lock); |
133 | return -ENOENT; | 131 | return -ENOENT; |
134 | } | 132 | } |
135 | spin_unlock(&dentry->d_lock); | 133 | spin_unlock(&dentry->d_lock); |
136 | spin_unlock(&autofs4_lock); | 134 | spin_unlock(&sbi->lookup_lock); |
137 | 135 | ||
138 | out: | 136 | out: |
139 | return dcache_dir_open(inode, file); | 137 | return dcache_dir_open(inode, file); |
@@ -171,7 +169,6 @@ static struct dentry *autofs4_lookup_active(struct dentry *dentry) | |||
171 | const unsigned char *str = name->name; | 169 | const unsigned char *str = name->name; |
172 | struct list_head *p, *head; | 170 | struct list_head *p, *head; |
173 | 171 | ||
174 | spin_lock(&autofs4_lock); | ||
175 | spin_lock(&sbi->lookup_lock); | 172 | spin_lock(&sbi->lookup_lock); |
176 | head = &sbi->active_list; | 173 | head = &sbi->active_list; |
177 | list_for_each(p, head) { | 174 | list_for_each(p, head) { |
@@ -204,14 +201,12 @@ static struct dentry *autofs4_lookup_active(struct dentry *dentry) | |||
204 | dget_dlock(active); | 201 | dget_dlock(active); |
205 | spin_unlock(&active->d_lock); | 202 | spin_unlock(&active->d_lock); |
206 | spin_unlock(&sbi->lookup_lock); | 203 | spin_unlock(&sbi->lookup_lock); |
207 | spin_unlock(&autofs4_lock); | ||
208 | return active; | 204 | return active; |
209 | } | 205 | } |
210 | next: | 206 | next: |
211 | spin_unlock(&active->d_lock); | 207 | spin_unlock(&active->d_lock); |
212 | } | 208 | } |
213 | spin_unlock(&sbi->lookup_lock); | 209 | spin_unlock(&sbi->lookup_lock); |
214 | spin_unlock(&autofs4_lock); | ||
215 | 210 | ||
216 | return NULL; | 211 | return NULL; |
217 | } | 212 | } |
@@ -226,7 +221,6 @@ static struct dentry *autofs4_lookup_expiring(struct dentry *dentry) | |||
226 | const unsigned char *str = name->name; | 221 | const unsigned char *str = name->name; |
227 | struct list_head *p, *head; | 222 | struct list_head *p, *head; |
228 | 223 | ||
229 | spin_lock(&autofs4_lock); | ||
230 | spin_lock(&sbi->lookup_lock); | 224 | spin_lock(&sbi->lookup_lock); |
231 | head = &sbi->expiring_list; | 225 | head = &sbi->expiring_list; |
232 | list_for_each(p, head) { | 226 | list_for_each(p, head) { |
@@ -259,14 +253,12 @@ static struct dentry *autofs4_lookup_expiring(struct dentry *dentry) | |||
259 | dget_dlock(expiring); | 253 | dget_dlock(expiring); |
260 | spin_unlock(&expiring->d_lock); | 254 | spin_unlock(&expiring->d_lock); |
261 | spin_unlock(&sbi->lookup_lock); | 255 | spin_unlock(&sbi->lookup_lock); |
262 | spin_unlock(&autofs4_lock); | ||
263 | return expiring; | 256 | return expiring; |
264 | } | 257 | } |
265 | next: | 258 | next: |
266 | spin_unlock(&expiring->d_lock); | 259 | spin_unlock(&expiring->d_lock); |
267 | } | 260 | } |
268 | spin_unlock(&sbi->lookup_lock); | 261 | spin_unlock(&sbi->lookup_lock); |
269 | spin_unlock(&autofs4_lock); | ||
270 | 262 | ||
271 | return NULL; | 263 | return NULL; |
272 | } | 264 | } |
@@ -275,17 +267,16 @@ static int autofs4_mount_wait(struct dentry *dentry) | |||
275 | { | 267 | { |
276 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | 268 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); |
277 | struct autofs_info *ino = autofs4_dentry_ino(dentry); | 269 | struct autofs_info *ino = autofs4_dentry_ino(dentry); |
278 | int status; | 270 | int status = 0; |
279 | 271 | ||
280 | if (ino->flags & AUTOFS_INF_PENDING) { | 272 | if (ino->flags & AUTOFS_INF_PENDING) { |
281 | DPRINTK("waiting for mount name=%.*s", | 273 | DPRINTK("waiting for mount name=%.*s", |
282 | dentry->d_name.len, dentry->d_name.name); | 274 | dentry->d_name.len, dentry->d_name.name); |
283 | status = autofs4_wait(sbi, dentry, NFY_MOUNT); | 275 | status = autofs4_wait(sbi, dentry, NFY_MOUNT); |
284 | DPRINTK("mount wait done status=%d", status); | 276 | DPRINTK("mount wait done status=%d", status); |
285 | ino->last_used = jiffies; | ||
286 | return status; | ||
287 | } | 277 | } |
288 | return 0; | 278 | ino->last_used = jiffies; |
279 | return status; | ||
289 | } | 280 | } |
290 | 281 | ||
291 | static int do_expire_wait(struct dentry *dentry) | 282 | static int do_expire_wait(struct dentry *dentry) |
@@ -319,9 +310,12 @@ static struct dentry *autofs4_mountpoint_changed(struct path *path) | |||
319 | */ | 310 | */ |
320 | if (autofs_type_indirect(sbi->type) && d_unhashed(dentry)) { | 311 | if (autofs_type_indirect(sbi->type) && d_unhashed(dentry)) { |
321 | struct dentry *parent = dentry->d_parent; | 312 | struct dentry *parent = dentry->d_parent; |
313 | struct autofs_info *ino; | ||
322 | struct dentry *new = d_lookup(parent, &dentry->d_name); | 314 | struct dentry *new = d_lookup(parent, &dentry->d_name); |
323 | if (!new) | 315 | if (!new) |
324 | return NULL; | 316 | return NULL; |
317 | ino = autofs4_dentry_ino(new); | ||
318 | ino->last_used = jiffies; | ||
325 | dput(path->dentry); | 319 | dput(path->dentry); |
326 | path->dentry = new; | 320 | path->dentry = new; |
327 | } | 321 | } |
@@ -338,18 +332,6 @@ static struct vfsmount *autofs4_d_automount(struct path *path) | |||
338 | DPRINTK("dentry=%p %.*s", | 332 | DPRINTK("dentry=%p %.*s", |
339 | dentry, dentry->d_name.len, dentry->d_name.name); | 333 | dentry, dentry->d_name.len, dentry->d_name.name); |
340 | 334 | ||
341 | /* | ||
342 | * Someone may have manually umounted this or it was a submount | ||
343 | * that has gone away. | ||
344 | */ | ||
345 | spin_lock(&dentry->d_lock); | ||
346 | if (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) { | ||
347 | if (!(dentry->d_flags & DCACHE_MANAGE_TRANSIT) && | ||
348 | (dentry->d_flags & DCACHE_NEED_AUTOMOUNT)) | ||
349 | __managed_dentry_set_transit(path->dentry); | ||
350 | } | ||
351 | spin_unlock(&dentry->d_lock); | ||
352 | |||
353 | /* The daemon never triggers a mount. */ | 335 | /* The daemon never triggers a mount. */ |
354 | if (autofs4_oz_mode(sbi)) | 336 | if (autofs4_oz_mode(sbi)) |
355 | return NULL; | 337 | return NULL; |
@@ -418,18 +400,17 @@ static struct vfsmount *autofs4_d_automount(struct path *path) | |||
418 | done: | 400 | done: |
419 | if (!(ino->flags & AUTOFS_INF_EXPIRING)) { | 401 | if (!(ino->flags & AUTOFS_INF_EXPIRING)) { |
420 | /* | 402 | /* |
421 | * Any needed mounting has been completed and the path updated | 403 | * Any needed mounting has been completed and the path |
422 | * so turn this into a normal dentry so we don't continually | 404 | * updated so clear DCACHE_NEED_AUTOMOUNT so we don't |
423 | * call ->d_automount() and ->d_manage(). | 405 | * call ->d_automount() on rootless multi-mounts since |
424 | */ | 406 | * it can lead to an incorrect ELOOP error return. |
425 | spin_lock(&dentry->d_lock); | 407 | * |
426 | __managed_dentry_clear_transit(dentry); | ||
427 | /* | ||
428 | * Only clear DMANAGED_AUTOMOUNT for rootless multi-mounts and | 408 | * Only clear DMANAGED_AUTOMOUNT for rootless multi-mounts and |
429 | * symlinks as in all other cases the dentry will be covered by | 409 | * symlinks as in all other cases the dentry will be covered by |
430 | * an actual mount so ->d_automount() won't be called during | 410 | * an actual mount so ->d_automount() won't be called during |
431 | * the follow. | 411 | * the follow. |
432 | */ | 412 | */ |
413 | spin_lock(&dentry->d_lock); | ||
433 | if ((!d_mountpoint(dentry) && | 414 | if ((!d_mountpoint(dentry) && |
434 | !list_empty(&dentry->d_subdirs)) || | 415 | !list_empty(&dentry->d_subdirs)) || |
435 | (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode))) | 416 | (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode))) |
@@ -455,6 +436,8 @@ int autofs4_d_manage(struct dentry *dentry, bool rcu_walk) | |||
455 | 436 | ||
456 | /* The daemon never waits. */ | 437 | /* The daemon never waits. */ |
457 | if (autofs4_oz_mode(sbi)) { | 438 | if (autofs4_oz_mode(sbi)) { |
439 | if (rcu_walk) | ||
440 | return 0; | ||
458 | if (!d_mountpoint(dentry)) | 441 | if (!d_mountpoint(dentry)) |
459 | return -EISDIR; | 442 | return -EISDIR; |
460 | return 0; | 443 | return 0; |
@@ -612,12 +595,12 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry) | |||
612 | 595 | ||
613 | dir->i_mtime = CURRENT_TIME; | 596 | dir->i_mtime = CURRENT_TIME; |
614 | 597 | ||
615 | spin_lock(&autofs4_lock); | 598 | spin_lock(&sbi->lookup_lock); |
616 | autofs4_add_expiring(dentry); | 599 | __autofs4_add_expiring(dentry); |
617 | spin_lock(&dentry->d_lock); | 600 | spin_lock(&dentry->d_lock); |
618 | __d_drop(dentry); | 601 | __d_drop(dentry); |
619 | spin_unlock(&dentry->d_lock); | 602 | spin_unlock(&dentry->d_lock); |
620 | spin_unlock(&autofs4_lock); | 603 | spin_unlock(&sbi->lookup_lock); |
621 | 604 | ||
622 | return 0; | 605 | return 0; |
623 | } | 606 | } |
@@ -629,7 +612,7 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry) | |||
629 | * set the DMANAGED_AUTOMOUNT and DMANAGED_TRANSIT flags on the leaves | 612 | * set the DMANAGED_AUTOMOUNT and DMANAGED_TRANSIT flags on the leaves |
630 | * of the directory tree. There is no need to clear the automount flag | 613 | * of the directory tree. There is no need to clear the automount flag |
631 | * following a mount or restore it after an expire because these mounts | 614 | * following a mount or restore it after an expire because these mounts |
632 | * are always covered. However, it is neccessary to ensure that these | 615 | * are always covered. However, it is necessary to ensure that these |
633 | * flags are clear on non-empty directories to avoid unnecessary calls | 616 | * flags are clear on non-empty directories to avoid unnecessary calls |
634 | * during path walks. | 617 | * during path walks. |
635 | */ | 618 | */ |
@@ -686,20 +669,17 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry) | |||
686 | if (!autofs4_oz_mode(sbi)) | 669 | if (!autofs4_oz_mode(sbi)) |
687 | return -EACCES; | 670 | return -EACCES; |
688 | 671 | ||
689 | spin_lock(&autofs4_lock); | ||
690 | spin_lock(&sbi->lookup_lock); | 672 | spin_lock(&sbi->lookup_lock); |
691 | spin_lock(&dentry->d_lock); | 673 | spin_lock(&dentry->d_lock); |
692 | if (!list_empty(&dentry->d_subdirs)) { | 674 | if (!list_empty(&dentry->d_subdirs)) { |
693 | spin_unlock(&dentry->d_lock); | 675 | spin_unlock(&dentry->d_lock); |
694 | spin_unlock(&sbi->lookup_lock); | 676 | spin_unlock(&sbi->lookup_lock); |
695 | spin_unlock(&autofs4_lock); | ||
696 | return -ENOTEMPTY; | 677 | return -ENOTEMPTY; |
697 | } | 678 | } |
698 | __autofs4_add_expiring(dentry); | 679 | __autofs4_add_expiring(dentry); |
699 | spin_unlock(&sbi->lookup_lock); | ||
700 | __d_drop(dentry); | 680 | __d_drop(dentry); |
701 | spin_unlock(&dentry->d_lock); | 681 | spin_unlock(&dentry->d_lock); |
702 | spin_unlock(&autofs4_lock); | 682 | spin_unlock(&sbi->lookup_lock); |
703 | 683 | ||
704 | if (sbi->version < 5) | 684 | if (sbi->version < 5) |
705 | autofs_clear_leaf_automount_flags(dentry); | 685 | autofs_clear_leaf_automount_flags(dentry); |
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c index 56010056b2e6..25435987d6ae 100644 --- a/fs/autofs4/waitq.c +++ b/fs/autofs4/waitq.c | |||
@@ -197,12 +197,12 @@ rename_retry: | |||
197 | 197 | ||
198 | seq = read_seqbegin(&rename_lock); | 198 | seq = read_seqbegin(&rename_lock); |
199 | rcu_read_lock(); | 199 | rcu_read_lock(); |
200 | spin_lock(&autofs4_lock); | 200 | spin_lock(&sbi->fs_lock); |
201 | for (tmp = dentry ; tmp != root ; tmp = tmp->d_parent) | 201 | for (tmp = dentry ; tmp != root ; tmp = tmp->d_parent) |
202 | len += tmp->d_name.len + 1; | 202 | len += tmp->d_name.len + 1; |
203 | 203 | ||
204 | if (!len || --len > NAME_MAX) { | 204 | if (!len || --len > NAME_MAX) { |
205 | spin_unlock(&autofs4_lock); | 205 | spin_unlock(&sbi->fs_lock); |
206 | rcu_read_unlock(); | 206 | rcu_read_unlock(); |
207 | if (read_seqretry(&rename_lock, seq)) | 207 | if (read_seqretry(&rename_lock, seq)) |
208 | goto rename_retry; | 208 | goto rename_retry; |
@@ -218,7 +218,7 @@ rename_retry: | |||
218 | p -= tmp->d_name.len; | 218 | p -= tmp->d_name.len; |
219 | strncpy(p, tmp->d_name.name, tmp->d_name.len); | 219 | strncpy(p, tmp->d_name.name, tmp->d_name.len); |
220 | } | 220 | } |
221 | spin_unlock(&autofs4_lock); | 221 | spin_unlock(&sbi->fs_lock); |
222 | rcu_read_unlock(); | 222 | rcu_read_unlock(); |
223 | if (read_seqretry(&rename_lock, seq)) | 223 | if (read_seqretry(&rename_lock, seq)) |
224 | goto rename_retry; | 224 | goto rename_retry; |