diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-12-17 15:18:35 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-12-17 15:18:35 -0500 |
commit | 73d080d374a509ae887b8a0744ad4d553c5d5d24 (patch) | |
tree | 7103479cbebbafa647d838d9058a9e30aa65cefb | |
parent | 1c6b942d7d39765a81ea0577c893edaddfccad3d (diff) | |
parent | d7ee946942bdd12394809305e3df05aa4c8b7b8f (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs fixes from Al Viro:
"The alloc_super() one is a regression in this merge window, lazytime
thing is older..."
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
VFS: Handle lazytime in do_mount()
alloc_super(): do ->s_umount initialization earlier
-rw-r--r-- | fs/namespace.c | 1 | ||||
-rw-r--r-- | fs/super.c | 37 |
2 files changed, 19 insertions, 19 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index e158ec6b527b..9d1374ab6e06 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -2826,6 +2826,7 @@ long do_mount(const char *dev_name, const char __user *dir_name, | |||
2826 | SB_DIRSYNC | | 2826 | SB_DIRSYNC | |
2827 | SB_SILENT | | 2827 | SB_SILENT | |
2828 | SB_POSIXACL | | 2828 | SB_POSIXACL | |
2829 | SB_LAZYTIME | | ||
2829 | SB_I_VERSION); | 2830 | SB_I_VERSION); |
2830 | 2831 | ||
2831 | if (flags & MS_REMOUNT) | 2832 | if (flags & MS_REMOUNT) |
diff --git a/fs/super.c b/fs/super.c index d4e33e8f1e6f..7ff1349609e4 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -191,6 +191,24 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags, | |||
191 | 191 | ||
192 | INIT_LIST_HEAD(&s->s_mounts); | 192 | INIT_LIST_HEAD(&s->s_mounts); |
193 | s->s_user_ns = get_user_ns(user_ns); | 193 | s->s_user_ns = get_user_ns(user_ns); |
194 | init_rwsem(&s->s_umount); | ||
195 | lockdep_set_class(&s->s_umount, &type->s_umount_key); | ||
196 | /* | ||
197 | * sget() can have s_umount recursion. | ||
198 | * | ||
199 | * When it cannot find a suitable sb, it allocates a new | ||
200 | * one (this one), and tries again to find a suitable old | ||
201 | * one. | ||
202 | * | ||
203 | * In case that succeeds, it will acquire the s_umount | ||
204 | * lock of the old one. Since these are clearly distrinct | ||
205 | * locks, and this object isn't exposed yet, there's no | ||
206 | * risk of deadlocks. | ||
207 | * | ||
208 | * Annotate this by putting this lock in a different | ||
209 | * subclass. | ||
210 | */ | ||
211 | down_write_nested(&s->s_umount, SINGLE_DEPTH_NESTING); | ||
194 | 212 | ||
195 | if (security_sb_alloc(s)) | 213 | if (security_sb_alloc(s)) |
196 | goto fail; | 214 | goto fail; |
@@ -218,25 +236,6 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags, | |||
218 | goto fail; | 236 | goto fail; |
219 | if (list_lru_init_memcg(&s->s_inode_lru)) | 237 | if (list_lru_init_memcg(&s->s_inode_lru)) |
220 | goto fail; | 238 | goto fail; |
221 | |||
222 | init_rwsem(&s->s_umount); | ||
223 | lockdep_set_class(&s->s_umount, &type->s_umount_key); | ||
224 | /* | ||
225 | * sget() can have s_umount recursion. | ||
226 | * | ||
227 | * When it cannot find a suitable sb, it allocates a new | ||
228 | * one (this one), and tries again to find a suitable old | ||
229 | * one. | ||
230 | * | ||
231 | * In case that succeeds, it will acquire the s_umount | ||
232 | * lock of the old one. Since these are clearly distrinct | ||
233 | * locks, and this object isn't exposed yet, there's no | ||
234 | * risk of deadlocks. | ||
235 | * | ||
236 | * Annotate this by putting this lock in a different | ||
237 | * subclass. | ||
238 | */ | ||
239 | down_write_nested(&s->s_umount, SINGLE_DEPTH_NESTING); | ||
240 | s->s_count = 1; | 239 | s->s_count = 1; |
241 | atomic_set(&s->s_active, 1); | 240 | atomic_set(&s->s_active, 1); |
242 | mutex_init(&s->s_vfs_rename_mutex); | 241 | mutex_init(&s->s_vfs_rename_mutex); |