diff --git a/fs/super.c b/fs/super.c
index e781226e2880..d35545364c5d 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -1228,7 +1228,8 @@ static const struct blk_holder_ops fs_holder_ops = {
 
 static int set_bdev_super(struct super_block *s, void *data)
 {
-	s->s_bdev = data;
+	s->s_bdev_handle = data;
+	s->s_bdev = s->s_bdev_handle->bdev;
 	s->s_dev = s->s_bdev->bd_dev;
 	s->s_bdi = bdi_get(s->s_bdev->bd_disk->bdi);
 
@@ -1244,7 +1245,8 @@ static int set_bdev_super_fc(struct super_block *s, struct fs_context *fc)
 
 static int test_bdev_super_fc(struct super_block *s, struct fs_context *fc)
 {
-	return !(s->s_iflags & SB_I_RETIRED) && s->s_bdev == fc->sget_key;
+	return !(s->s_iflags & SB_I_RETIRED) &&
+		s->s_bdev == ((struct bdev_handle *)fc->sget_key)->bdev;
 }
 
 /**
@@ -1256,6 +1258,7 @@ int get_tree_bdev(struct fs_context *fc,
 		int (*fill_super)(struct super_block *,
 				  struct fs_context *))
 {
+	struct bdev_handle *bdev_handle;
 	struct block_device *bdev;
 	struct super_block *s;
 	int error = 0;
@@ -1263,12 +1266,14 @@ int get_tree_bdev(struct fs_context *fc,
 	if (!fc->source)
 		return invalf(fc, "No source specified");
 
-	bdev = blkdev_get_by_path(fc->source, sb_open_mode(fc->sb_flags),
-				  fc->fs_type, &fs_holder_ops);
-	if (IS_ERR(bdev)) {
+	bdev_handle = blkdev_get_handle_by_path(fc->source,
+			sb_open_mode(fc->sb_flags), fc->fs_type,
+			&fs_holder_ops);
+	if (IS_ERR(bdev_handle)) {
 		errorf(fc, "%s: Can't open blockdev", fc->source);
-		return PTR_ERR(bdev);
+		return PTR_ERR(bdev_handle);
 	}
+	bdev = bdev_handle->bdev;
 
 	/* Once the superblock is inserted into the list by sget_fc(), s_umount
 	 * will protect the lockfs code from trying to start a snapshot while
@@ -1278,16 +1283,16 @@ int get_tree_bdev(struct fs_context *fc,
 	if (bdev->bd_fsfreeze_count > 0) {
 		mutex_unlock(&bdev->bd_fsfreeze_mutex);
 		warnf(fc, "%pg: Can't mount, blockdev is frozen", bdev);
-		blkdev_put(bdev, fc->fs_type);
+		blkdev_handle_put(bdev_handle);
 		return -EBUSY;
 	}
 
 	fc->sb_flags |= SB_NOSEC;
-	fc->sget_key = bdev;
+	fc->sget_key = bdev_handle;
 	s = sget_fc(fc, test_bdev_super_fc, set_bdev_super_fc);
 	mutex_unlock(&bdev->bd_fsfreeze_mutex);
 	if (IS_ERR(s)) {
-		blkdev_put(bdev, fc->fs_type);
+		blkdev_handle_put(bdev_handle);
 		return PTR_ERR(s);
 	}
 
@@ -1296,19 +1301,19 @@ int get_tree_bdev(struct fs_context *fc,
 		if ((fc->sb_flags ^ s->s_flags) & SB_RDONLY) {
 			warnf(fc, "%pg: Can't mount, would change RO state", bdev);
 			deactivate_locked_super(s);
-			blkdev_put(bdev, fc->fs_type);
+			blkdev_handle_put(bdev_handle);
 			return -EBUSY;
 		}
 
 		/*
 		 * s_umount nests inside open_mutex during
-		 * __invalidate_device().  blkdev_put() acquires
+		 * __invalidate_device().  blkdev_handle_put() acquires
 		 * open_mutex and can't be called under s_umount.  Drop
 		 * s_umount temporarily.  This is safe as we're
 		 * holding an active reference.
 		 */
 		up_write(&s->s_umount);
-		blkdev_put(bdev, fc->fs_type);
+		blkdev_handle_put(bdev_handle);
 		down_write(&s->s_umount);
 	} else {
 		snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev);
@@ -1333,21 +1338,24 @@ EXPORT_SYMBOL(get_tree_bdev);
 
 static int test_bdev_super(struct super_block *s, void *data)
 {
-	return !(s->s_iflags & SB_I_RETIRED) && (void *)s->s_bdev == data;
+	return !(s->s_iflags & SB_I_RETIRED) &&
+		s->s_bdev == ((struct bdev_handle *)data)->bdev;
 }
 
 struct dentry *mount_bdev(struct file_system_type *fs_type,
 	int flags, const char *dev_name, void *data,
 	int (*fill_super)(struct super_block *, void *, int))
 {
+	struct bdev_handle *bdev_handle;
 	struct block_device *bdev;
 	struct super_block *s;
 	int error = 0;
 
-	bdev = blkdev_get_by_path(dev_name, sb_open_mode(flags), fs_type,
-				  &fs_holder_ops);
-	if (IS_ERR(bdev))
-		return ERR_CAST(bdev);
+	bdev_handle = blkdev_get_handle_by_path(dev_name, sb_open_mode(flags),
+				fs_type, &fs_holder_ops);
+	if (IS_ERR(bdev_handle))
+		return ERR_CAST(bdev_handle);
+	bdev = bdev_handle->bdev;
 
 	/*
 	 * once the super is inserted into the list by sget, s_umount
@@ -1361,7 +1369,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
 		goto error_bdev;
 	}
 	s = sget(fs_type, test_bdev_super, set_bdev_super, flags | SB_NOSEC,
-		 bdev);
+		 bdev_handle);
 	mutex_unlock(&bdev->bd_fsfreeze_mutex);
 	if (IS_ERR(s))
 		goto error_s;
@@ -1375,13 +1383,13 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
 
 		/*
 		 * s_umount nests inside open_mutex during
-		 * __invalidate_device().  blkdev_put() acquires
+		 * __invalidate_device().  blkdev_handle_put() acquires
 		 * open_mutex and can't be called under s_umount.  Drop
 		 * s_umount temporarily.  This is safe as we're
 		 * holding an active reference.
 		 */
 		up_write(&s->s_umount);
-		blkdev_put(bdev, fs_type);
+		blkdev_handle_put(bdev_handle);
 		down_write(&s->s_umount);
 	} else {
 		snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev);
@@ -1403,7 +1411,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
 error_s:
 	error = PTR_ERR(s);
 error_bdev:
-	blkdev_put(bdev, fs_type);
+	blkdev_handle_put(bdev_handle);
 error:
 	return ERR_PTR(error);
 }
@@ -1416,7 +1424,7 @@ void kill_block_super(struct super_block *sb)
 	bdev->bd_super = NULL;
 	generic_shutdown_super(sb);
 	sync_blockdev(bdev);
-	blkdev_put(bdev, sb->s_type);
+	blkdev_handle_put(sb->s_bdev_handle);
 }
 
 EXPORT_SYMBOL(kill_block_super);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 6867512907d6..44a224b91570 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1187,6 +1187,7 @@ struct super_block {
 	struct hlist_bl_head	s_roots;	/* alternate root dentries for NFS */
 	struct list_head	s_mounts;	/* list of mounts; _not_ for fs use */
 	struct block_device	*s_bdev;
+	struct bdev_handle	*s_bdev_handle;
 	struct backing_dev_info *s_bdi;
 	struct mtd_info		*s_mtd;
 	struct hlist_node	s_instances;
