Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux...
[cascardo/linux.git] / fs / btrfs / super.c
index 9dbf423..5011aad 100644 (file)
@@ -66,6 +66,8 @@
 static const struct super_operations btrfs_super_ops;
 static struct file_system_type btrfs_fs_type;
 
+static int btrfs_remount(struct super_block *sb, int *flags, char *data);
+
 static const char *btrfs_decode_error(int errno)
 {
        char *errstr = "unknown";
@@ -1185,6 +1187,26 @@ static struct dentry *mount_subvol(const char *subvol_name, int flags,
        mnt = vfs_kern_mount(&btrfs_fs_type, flags, device_name,
                             newargs);
        kfree(newargs);
+
+       if (PTR_RET(mnt) == -EBUSY) {
+               if (flags & MS_RDONLY) {
+                       mnt = vfs_kern_mount(&btrfs_fs_type, flags & ~MS_RDONLY, device_name,
+                                            newargs);
+               } else {
+                       int r;
+                       mnt = vfs_kern_mount(&btrfs_fs_type, flags | MS_RDONLY, device_name,
+                                            newargs);
+                       if (IS_ERR(mnt))
+                               return ERR_CAST(mnt);
+
+                       r = btrfs_remount(mnt->mnt_sb, &flags, NULL);
+                       if (r < 0) {
+                               /* FIXME: release vfsmount mnt ??*/
+                               return ERR_PTR(r);
+                       }
+               }
+       }
+
        if (IS_ERR(mnt))
                return ERR_CAST(mnt);