@@ -646,26 +646,31 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
/* if they gave us a subvolume name bind mount into that */
if (strcmp(subvol_name, ".")) {
struct dentry *new_root;
- mutex_lock(&root->d_inode->i_mutex);
- new_root = lookup_one_len(subvol_name, root,
- strlen(subvol_name));
- mutex_unlock(&root->d_inode->i_mutex);
-
- if (IS_ERR(new_root)) {
- deactivate_locked_super(s);
- error = PTR_ERR(new_root);
- dput(root);
- goto error_free_subvol_name;
- }
- if (!new_root->d_inode) {
+ char *subvol_name_next = subvol_name;
+ char *subvol_name_part;
+
+ while ((subvol_name_part = strsep(&subvol_name_next, "/"))) {
+ mutex_lock(&root->d_inode->i_mutex);
+ new_root = lookup_one_len(subvol_name, root,
+ strlen(subvol_name));
+ mutex_unlock(&root->d_inode->i_mutex);
+
+ if (IS_ERR(new_root)) {
+ deactivate_locked_super(s);
+ error = PTR_ERR(new_root);
+ dput(root);
+ goto error_free_subvol_name;
+ }
+ if (!new_root->d_inode) {
+ dput(root);
+ dput(new_root);
+ deactivate_locked_super(s);
+ error = -ENXIO;
+ goto error_free_subvol_name;
+ }
dput(root);
- dput(new_root);
- deactivate_locked_super(s);
- error = -ENXIO;
- goto error_free_subvol_name;
+ root = new_root;
}
- dput(root);
- root = new_root;
}
kfree(subvol_name);