diff options
Diffstat (limited to 'fs/autofs4/root.c')
-rw-r--r-- | fs/autofs4/root.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 7922509b5b2b..7a9ed6b88291 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -143,10 +143,13 @@ static int autofs4_dir_open(struct inode *inode, struct file *file) | |||
143 | * it. | 143 | * it. |
144 | */ | 144 | */ |
145 | spin_lock(&dcache_lock); | 145 | spin_lock(&dcache_lock); |
146 | spin_lock(&dentry->d_lock); | ||
146 | if (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) { | 147 | if (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) { |
148 | spin_unlock(&dentry->d_lock); | ||
147 | spin_unlock(&dcache_lock); | 149 | spin_unlock(&dcache_lock); |
148 | return -ENOENT; | 150 | return -ENOENT; |
149 | } | 151 | } |
152 | spin_unlock(&dentry->d_lock); | ||
150 | spin_unlock(&dcache_lock); | 153 | spin_unlock(&dcache_lock); |
151 | 154 | ||
152 | out: | 155 | out: |
@@ -253,7 +256,9 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
253 | lookup_type = autofs4_need_mount(nd->flags); | 256 | lookup_type = autofs4_need_mount(nd->flags); |
254 | spin_lock(&sbi->fs_lock); | 257 | spin_lock(&sbi->fs_lock); |
255 | spin_lock(&dcache_lock); | 258 | spin_lock(&dcache_lock); |
259 | spin_lock(&dentry->d_lock); | ||
256 | if (!(lookup_type || ino->flags & AUTOFS_INF_PENDING)) { | 260 | if (!(lookup_type || ino->flags & AUTOFS_INF_PENDING)) { |
261 | spin_unlock(&dentry->d_lock); | ||
257 | spin_unlock(&dcache_lock); | 262 | spin_unlock(&dcache_lock); |
258 | spin_unlock(&sbi->fs_lock); | 263 | spin_unlock(&sbi->fs_lock); |
259 | goto follow; | 264 | goto follow; |
@@ -266,6 +271,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
266 | */ | 271 | */ |
267 | if (ino->flags & AUTOFS_INF_PENDING || | 272 | if (ino->flags & AUTOFS_INF_PENDING || |
268 | (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs))) { | 273 | (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs))) { |
274 | spin_unlock(&dentry->d_lock); | ||
269 | spin_unlock(&dcache_lock); | 275 | spin_unlock(&dcache_lock); |
270 | spin_unlock(&sbi->fs_lock); | 276 | spin_unlock(&sbi->fs_lock); |
271 | 277 | ||
@@ -275,6 +281,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
275 | 281 | ||
276 | goto follow; | 282 | goto follow; |
277 | } | 283 | } |
284 | spin_unlock(&dentry->d_lock); | ||
278 | spin_unlock(&dcache_lock); | 285 | spin_unlock(&dcache_lock); |
279 | spin_unlock(&sbi->fs_lock); | 286 | spin_unlock(&sbi->fs_lock); |
280 | follow: | 287 | follow: |
@@ -347,10 +354,12 @@ static int autofs4_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
347 | 354 | ||
348 | /* Check for a non-mountpoint directory with no contents */ | 355 | /* Check for a non-mountpoint directory with no contents */ |
349 | spin_lock(&dcache_lock); | 356 | spin_lock(&dcache_lock); |
357 | spin_lock(&dentry->d_lock); | ||
350 | if (S_ISDIR(dentry->d_inode->i_mode) && | 358 | if (S_ISDIR(dentry->d_inode->i_mode) && |
351 | !d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) { | 359 | !d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) { |
352 | DPRINTK("dentry=%p %.*s, emptydir", | 360 | DPRINTK("dentry=%p %.*s, emptydir", |
353 | dentry, dentry->d_name.len, dentry->d_name.name); | 361 | dentry, dentry->d_name.len, dentry->d_name.name); |
362 | spin_unlock(&dentry->d_lock); | ||
354 | spin_unlock(&dcache_lock); | 363 | spin_unlock(&dcache_lock); |
355 | 364 | ||
356 | /* The daemon never causes a mount to trigger */ | 365 | /* The daemon never causes a mount to trigger */ |
@@ -367,6 +376,7 @@ static int autofs4_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
367 | 376 | ||
368 | return status; | 377 | return status; |
369 | } | 378 | } |
379 | spin_unlock(&dentry->d_lock); | ||
370 | spin_unlock(&dcache_lock); | 380 | spin_unlock(&dcache_lock); |
371 | 381 | ||
372 | return 1; | 382 | return 1; |
@@ -776,12 +786,16 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry) | |||
776 | return -EACCES; | 786 | return -EACCES; |
777 | 787 | ||
778 | spin_lock(&dcache_lock); | 788 | spin_lock(&dcache_lock); |
789 | spin_lock(&sbi->lookup_lock); | ||
790 | spin_lock(&dentry->d_lock); | ||
779 | if (!list_empty(&dentry->d_subdirs)) { | 791 | if (!list_empty(&dentry->d_subdirs)) { |
792 | spin_unlock(&dentry->d_lock); | ||
793 | spin_unlock(&sbi->lookup_lock); | ||
780 | spin_unlock(&dcache_lock); | 794 | spin_unlock(&dcache_lock); |
781 | return -ENOTEMPTY; | 795 | return -ENOTEMPTY; |
782 | } | 796 | } |
783 | autofs4_add_expiring(dentry); | 797 | __autofs4_add_expiring(dentry); |
784 | spin_lock(&dentry->d_lock); | 798 | spin_unlock(&sbi->lookup_lock); |
785 | __d_drop(dentry); | 799 | __d_drop(dentry); |
786 | spin_unlock(&dentry->d_lock); | 800 | spin_unlock(&dentry->d_lock); |
787 | spin_unlock(&dcache_lock); | 801 | spin_unlock(&dcache_lock); |