diff options
Diffstat (limited to 'fs/super.c')
-rw-r--r-- | fs/super.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/fs/super.c b/fs/super.c index 645e5403f2a0..8349ed6b1412 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -82,7 +82,22 @@ static struct super_block *alloc_super(struct file_system_type *type) | |||
82 | * lock ordering than usbfs: | 82 | * lock ordering than usbfs: |
83 | */ | 83 | */ |
84 | lockdep_set_class(&s->s_lock, &type->s_lock_key); | 84 | lockdep_set_class(&s->s_lock, &type->s_lock_key); |
85 | down_write(&s->s_umount); | 85 | /* |
86 | * sget() can have s_umount recursion. | ||
87 | * | ||
88 | * When it cannot find a suitable sb, it allocates a new | ||
89 | * one (this one), and tries again to find a suitable old | ||
90 | * one. | ||
91 | * | ||
92 | * In case that succeeds, it will acquire the s_umount | ||
93 | * lock of the old one. Since these are clearly distrinct | ||
94 | * locks, and this object isn't exposed yet, there's no | ||
95 | * risk of deadlocks. | ||
96 | * | ||
97 | * Annotate this by putting this lock in a different | ||
98 | * subclass. | ||
99 | */ | ||
100 | down_write_nested(&s->s_umount, SINGLE_DEPTH_NESTING); | ||
86 | s->s_count = S_BIAS; | 101 | s->s_count = S_BIAS; |
87 | atomic_set(&s->s_active, 1); | 102 | atomic_set(&s->s_active, 1); |
88 | mutex_init(&s->s_vfs_rename_mutex); | 103 | mutex_init(&s->s_vfs_rename_mutex); |
@@ -301,7 +316,7 @@ void generic_shutdown_super(struct super_block *sb) | |||
301 | /* | 316 | /* |
302 | * wait for asynchronous fs operations to finish before going further | 317 | * wait for asynchronous fs operations to finish before going further |
303 | */ | 318 | */ |
304 | async_synchronize_full_special(&sb->s_async_list); | 319 | async_synchronize_full_domain(&sb->s_async_list); |
305 | 320 | ||
306 | /* bad name - it should be evict_inodes() */ | 321 | /* bad name - it should be evict_inodes() */ |
307 | invalidate_inodes(sb); | 322 | invalidate_inodes(sb); |
@@ -470,7 +485,7 @@ restart: | |||
470 | sb->s_count++; | 485 | sb->s_count++; |
471 | spin_unlock(&sb_lock); | 486 | spin_unlock(&sb_lock); |
472 | down_read(&sb->s_umount); | 487 | down_read(&sb->s_umount); |
473 | async_synchronize_full_special(&sb->s_async_list); | 488 | async_synchronize_full_domain(&sb->s_async_list); |
474 | if (sb->s_root && (wait || sb->s_dirt)) | 489 | if (sb->s_root && (wait || sb->s_dirt)) |
475 | sb->s_op->sync_fs(sb, wait); | 490 | sb->s_op->sync_fs(sb, wait); |
476 | up_read(&sb->s_umount); | 491 | up_read(&sb->s_umount); |