diff options
Diffstat (limited to 'fs/autofs4/root.c')
-rw-r--r-- | fs/autofs4/root.c | 44 |
1 files changed, 23 insertions, 21 deletions
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 7a9ed6b88291..10ca68a96dc7 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -23,6 +23,8 @@ | |||
23 | 23 | ||
24 | #include "autofs_i.h" | 24 | #include "autofs_i.h" |
25 | 25 | ||
26 | DEFINE_SPINLOCK(autofs4_lock); | ||
27 | |||
26 | static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *); | 28 | static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *); |
27 | static int autofs4_dir_unlink(struct inode *,struct dentry *); | 29 | static int autofs4_dir_unlink(struct inode *,struct dentry *); |
28 | static int autofs4_dir_rmdir(struct inode *,struct dentry *); | 30 | static int autofs4_dir_rmdir(struct inode *,struct dentry *); |
@@ -142,15 +144,15 @@ static int autofs4_dir_open(struct inode *inode, struct file *file) | |||
142 | * autofs file system so just let the libfs routines handle | 144 | * autofs file system so just let the libfs routines handle |
143 | * it. | 145 | * it. |
144 | */ | 146 | */ |
145 | spin_lock(&dcache_lock); | 147 | spin_lock(&autofs4_lock); |
146 | spin_lock(&dentry->d_lock); | 148 | spin_lock(&dentry->d_lock); |
147 | if (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) { | 149 | if (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) { |
148 | spin_unlock(&dentry->d_lock); | 150 | spin_unlock(&dentry->d_lock); |
149 | spin_unlock(&dcache_lock); | 151 | spin_unlock(&autofs4_lock); |
150 | return -ENOENT; | 152 | return -ENOENT; |
151 | } | 153 | } |
152 | spin_unlock(&dentry->d_lock); | 154 | spin_unlock(&dentry->d_lock); |
153 | spin_unlock(&dcache_lock); | 155 | spin_unlock(&autofs4_lock); |
154 | 156 | ||
155 | out: | 157 | out: |
156 | return dcache_dir_open(inode, file); | 158 | return dcache_dir_open(inode, file); |
@@ -255,11 +257,11 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
255 | /* We trigger a mount for almost all flags */ | 257 | /* We trigger a mount for almost all flags */ |
256 | lookup_type = autofs4_need_mount(nd->flags); | 258 | lookup_type = autofs4_need_mount(nd->flags); |
257 | spin_lock(&sbi->fs_lock); | 259 | spin_lock(&sbi->fs_lock); |
258 | spin_lock(&dcache_lock); | 260 | spin_lock(&autofs4_lock); |
259 | spin_lock(&dentry->d_lock); | 261 | spin_lock(&dentry->d_lock); |
260 | if (!(lookup_type || ino->flags & AUTOFS_INF_PENDING)) { | 262 | if (!(lookup_type || ino->flags & AUTOFS_INF_PENDING)) { |
261 | spin_unlock(&dentry->d_lock); | 263 | spin_unlock(&dentry->d_lock); |
262 | spin_unlock(&dcache_lock); | 264 | spin_unlock(&autofs4_lock); |
263 | spin_unlock(&sbi->fs_lock); | 265 | spin_unlock(&sbi->fs_lock); |
264 | goto follow; | 266 | goto follow; |
265 | } | 267 | } |
@@ -272,7 +274,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
272 | if (ino->flags & AUTOFS_INF_PENDING || | 274 | if (ino->flags & AUTOFS_INF_PENDING || |
273 | (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs))) { | 275 | (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs))) { |
274 | spin_unlock(&dentry->d_lock); | 276 | spin_unlock(&dentry->d_lock); |
275 | spin_unlock(&dcache_lock); | 277 | spin_unlock(&autofs4_lock); |
276 | spin_unlock(&sbi->fs_lock); | 278 | spin_unlock(&sbi->fs_lock); |
277 | 279 | ||
278 | status = try_to_fill_dentry(dentry, nd->flags); | 280 | status = try_to_fill_dentry(dentry, nd->flags); |
@@ -282,7 +284,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
282 | goto follow; | 284 | goto follow; |
283 | } | 285 | } |
284 | spin_unlock(&dentry->d_lock); | 286 | spin_unlock(&dentry->d_lock); |
285 | spin_unlock(&dcache_lock); | 287 | spin_unlock(&autofs4_lock); |
286 | spin_unlock(&sbi->fs_lock); | 288 | spin_unlock(&sbi->fs_lock); |
287 | follow: | 289 | follow: |
288 | /* | 290 | /* |
@@ -353,14 +355,14 @@ static int autofs4_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
353 | return 0; | 355 | return 0; |
354 | 356 | ||
355 | /* Check for a non-mountpoint directory with no contents */ | 357 | /* Check for a non-mountpoint directory with no contents */ |
356 | spin_lock(&dcache_lock); | 358 | spin_lock(&autofs4_lock); |
357 | spin_lock(&dentry->d_lock); | 359 | spin_lock(&dentry->d_lock); |
358 | if (S_ISDIR(dentry->d_inode->i_mode) && | 360 | if (S_ISDIR(dentry->d_inode->i_mode) && |
359 | !d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) { | 361 | !d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) { |
360 | DPRINTK("dentry=%p %.*s, emptydir", | 362 | DPRINTK("dentry=%p %.*s, emptydir", |
361 | dentry, dentry->d_name.len, dentry->d_name.name); | 363 | dentry, dentry->d_name.len, dentry->d_name.name); |
362 | spin_unlock(&dentry->d_lock); | 364 | spin_unlock(&dentry->d_lock); |
363 | spin_unlock(&dcache_lock); | 365 | spin_unlock(&autofs4_lock); |
364 | 366 | ||
365 | /* The daemon never causes a mount to trigger */ | 367 | /* The daemon never causes a mount to trigger */ |
366 | if (oz_mode) | 368 | if (oz_mode) |
@@ -377,7 +379,7 @@ static int autofs4_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
377 | return status; | 379 | return status; |
378 | } | 380 | } |
379 | spin_unlock(&dentry->d_lock); | 381 | spin_unlock(&dentry->d_lock); |
380 | spin_unlock(&dcache_lock); | 382 | spin_unlock(&autofs4_lock); |
381 | 383 | ||
382 | return 1; | 384 | return 1; |
383 | } | 385 | } |
@@ -432,7 +434,7 @@ static struct dentry *autofs4_lookup_active(struct dentry *dentry) | |||
432 | const unsigned char *str = name->name; | 434 | const unsigned char *str = name->name; |
433 | struct list_head *p, *head; | 435 | struct list_head *p, *head; |
434 | 436 | ||
435 | spin_lock(&dcache_lock); | 437 | spin_lock(&autofs4_lock); |
436 | spin_lock(&sbi->lookup_lock); | 438 | spin_lock(&sbi->lookup_lock); |
437 | head = &sbi->active_list; | 439 | head = &sbi->active_list; |
438 | list_for_each(p, head) { | 440 | list_for_each(p, head) { |
@@ -465,14 +467,14 @@ static struct dentry *autofs4_lookup_active(struct dentry *dentry) | |||
465 | dget_dlock(active); | 467 | dget_dlock(active); |
466 | spin_unlock(&active->d_lock); | 468 | spin_unlock(&active->d_lock); |
467 | spin_unlock(&sbi->lookup_lock); | 469 | spin_unlock(&sbi->lookup_lock); |
468 | spin_unlock(&dcache_lock); | 470 | spin_unlock(&autofs4_lock); |
469 | return active; | 471 | return active; |
470 | } | 472 | } |
471 | next: | 473 | next: |
472 | spin_unlock(&active->d_lock); | 474 | spin_unlock(&active->d_lock); |
473 | } | 475 | } |
474 | spin_unlock(&sbi->lookup_lock); | 476 | spin_unlock(&sbi->lookup_lock); |
475 | spin_unlock(&dcache_lock); | 477 | spin_unlock(&autofs4_lock); |
476 | 478 | ||
477 | return NULL; | 479 | return NULL; |
478 | } | 480 | } |
@@ -487,7 +489,7 @@ static struct dentry *autofs4_lookup_expiring(struct dentry *dentry) | |||
487 | const unsigned char *str = name->name; | 489 | const unsigned char *str = name->name; |
488 | struct list_head *p, *head; | 490 | struct list_head *p, *head; |
489 | 491 | ||
490 | spin_lock(&dcache_lock); | 492 | spin_lock(&autofs4_lock); |
491 | spin_lock(&sbi->lookup_lock); | 493 | spin_lock(&sbi->lookup_lock); |
492 | head = &sbi->expiring_list; | 494 | head = &sbi->expiring_list; |
493 | list_for_each(p, head) { | 495 | list_for_each(p, head) { |
@@ -520,14 +522,14 @@ static struct dentry *autofs4_lookup_expiring(struct dentry *dentry) | |||
520 | dget_dlock(expiring); | 522 | dget_dlock(expiring); |
521 | spin_unlock(&expiring->d_lock); | 523 | spin_unlock(&expiring->d_lock); |
522 | spin_unlock(&sbi->lookup_lock); | 524 | spin_unlock(&sbi->lookup_lock); |
523 | spin_unlock(&dcache_lock); | 525 | spin_unlock(&autofs4_lock); |
524 | return expiring; | 526 | return expiring; |
525 | } | 527 | } |
526 | next: | 528 | next: |
527 | spin_unlock(&expiring->d_lock); | 529 | spin_unlock(&expiring->d_lock); |
528 | } | 530 | } |
529 | spin_unlock(&sbi->lookup_lock); | 531 | spin_unlock(&sbi->lookup_lock); |
530 | spin_unlock(&dcache_lock); | 532 | spin_unlock(&autofs4_lock); |
531 | 533 | ||
532 | return NULL; | 534 | return NULL; |
533 | } | 535 | } |
@@ -763,12 +765,12 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry) | |||
763 | 765 | ||
764 | dir->i_mtime = CURRENT_TIME; | 766 | dir->i_mtime = CURRENT_TIME; |
765 | 767 | ||
766 | spin_lock(&dcache_lock); | 768 | spin_lock(&autofs4_lock); |
767 | autofs4_add_expiring(dentry); | 769 | autofs4_add_expiring(dentry); |
768 | spin_lock(&dentry->d_lock); | 770 | spin_lock(&dentry->d_lock); |
769 | __d_drop(dentry); | 771 | __d_drop(dentry); |
770 | spin_unlock(&dentry->d_lock); | 772 | spin_unlock(&dentry->d_lock); |
771 | spin_unlock(&dcache_lock); | 773 | spin_unlock(&autofs4_lock); |
772 | 774 | ||
773 | return 0; | 775 | return 0; |
774 | } | 776 | } |
@@ -785,20 +787,20 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry) | |||
785 | if (!autofs4_oz_mode(sbi)) | 787 | if (!autofs4_oz_mode(sbi)) |
786 | return -EACCES; | 788 | return -EACCES; |
787 | 789 | ||
788 | spin_lock(&dcache_lock); | 790 | spin_lock(&autofs4_lock); |
789 | spin_lock(&sbi->lookup_lock); | 791 | spin_lock(&sbi->lookup_lock); |
790 | spin_lock(&dentry->d_lock); | 792 | spin_lock(&dentry->d_lock); |
791 | if (!list_empty(&dentry->d_subdirs)) { | 793 | if (!list_empty(&dentry->d_subdirs)) { |
792 | spin_unlock(&dentry->d_lock); | 794 | spin_unlock(&dentry->d_lock); |
793 | spin_unlock(&sbi->lookup_lock); | 795 | spin_unlock(&sbi->lookup_lock); |
794 | spin_unlock(&dcache_lock); | 796 | spin_unlock(&autofs4_lock); |
795 | return -ENOTEMPTY; | 797 | return -ENOTEMPTY; |
796 | } | 798 | } |
797 | __autofs4_add_expiring(dentry); | 799 | __autofs4_add_expiring(dentry); |
798 | spin_unlock(&sbi->lookup_lock); | 800 | spin_unlock(&sbi->lookup_lock); |
799 | __d_drop(dentry); | 801 | __d_drop(dentry); |
800 | spin_unlock(&dentry->d_lock); | 802 | spin_unlock(&dentry->d_lock); |
801 | spin_unlock(&dcache_lock); | 803 | spin_unlock(&autofs4_lock); |
802 | 804 | ||
803 | if (atomic_dec_and_test(&ino->count)) { | 805 | if (atomic_dec_and_test(&ino->count)) { |
804 | p_ino = autofs4_dentry_ino(dentry->d_parent); | 806 | p_ino = autofs4_dentry_ino(dentry->d_parent); |