|
@@ -82,7 +82,22 @@ static struct super_block *alloc_super(struct file_system_type *type)
|
|
* lock ordering than usbfs:
|
|
* lock ordering than usbfs:
|
|
*/
|
|
*/
|
|
lockdep_set_class(&s->s_lock, &type->s_lock_key);
|
|
lockdep_set_class(&s->s_lock, &type->s_lock_key);
|
|
- down_write(&s->s_umount);
|
|
|
|
|
|
+ /*
|
|
|
|
+ * sget() can have s_umount recursion.
|
|
|
|
+ *
|
|
|
|
+ * When it cannot find a suitable sb, it allocates a new
|
|
|
|
+ * one (this one), and tries again to find a suitable old
|
|
|
|
+ * one.
|
|
|
|
+ *
|
|
|
|
+ * In case that succeeds, it will acquire the s_umount
|
|
|
|
+ * lock of the old one. Since these are clearly distrinct
|
|
|
|
+ * locks, and this object isn't exposed yet, there's no
|
|
|
|
+ * risk of deadlocks.
|
|
|
|
+ *
|
|
|
|
+ * Annotate this by putting this lock in a different
|
|
|
|
+ * subclass.
|
|
|
|
+ */
|
|
|
|
+ down_write_nested(&s->s_umount, SINGLE_DEPTH_NESTING);
|
|
s->s_count = S_BIAS;
|
|
s->s_count = S_BIAS;
|
|
atomic_set(&s->s_active, 1);
|
|
atomic_set(&s->s_active, 1);
|
|
mutex_init(&s->s_vfs_rename_mutex);
|
|
mutex_init(&s->s_vfs_rename_mutex);
|