Skip to content

Commit 72fa39f

Browse files
t-msnkdave
authored andcommitted
btrfs: add btrfs_mount_root() and new file_system_type
Add btrfs_mount_root() and new file_system_type for preparation of cleanup of btrfs_mount(). Code path is not changed yet. btrfs_mount_root() is almost the same as current btrfs_mount(), but doesn't have subvolume related part. Signed-off-by: Tomohiro Misono <misono.tomohiro@jp.fujitsu.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent aab6e9e commit 72fa39f

File tree

1 file changed

+123
-0
lines changed

1 file changed

+123
-0
lines changed

fs/btrfs/super.c

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,15 @@
6565
#include <trace/events/btrfs.h>
6666

6767
static const struct super_operations btrfs_super_ops;
68+
69+
/*
70+
* Types for mounting the default subvolume and a subvolume explicitly
71+
* requested by subvol=/path. That way the callchain is straightforward and we
72+
* don't have to play tricks with the mount options and recursive calls to
73+
* btrfs_mount.
74+
*/
6875
static struct file_system_type btrfs_fs_type;
76+
static struct file_system_type btrfs_root_fs_type;
6977

7078
static int btrfs_remount(struct super_block *sb, int *flags, char *data);
7179

@@ -1549,6 +1557,112 @@ static int setup_security_options(struct btrfs_fs_info *fs_info,
15491557
return ret;
15501558
}
15511559

1560+
static struct dentry *btrfs_mount_root(struct file_system_type *fs_type,
1561+
int flags, const char *device_name, void *data)
1562+
{
1563+
struct block_device *bdev = NULL;
1564+
struct super_block *s;
1565+
struct btrfs_fs_devices *fs_devices = NULL;
1566+
struct btrfs_fs_info *fs_info = NULL;
1567+
struct security_mnt_opts new_sec_opts;
1568+
fmode_t mode = FMODE_READ;
1569+
char *subvol_name = NULL;
1570+
u64 subvol_objectid = 0;
1571+
int error = 0;
1572+
1573+
if (!(flags & SB_RDONLY))
1574+
mode |= FMODE_WRITE;
1575+
1576+
error = btrfs_parse_early_options(data, mode, fs_type,
1577+
&subvol_name, &subvol_objectid,
1578+
&fs_devices);
1579+
if (error) {
1580+
kfree(subvol_name);
1581+
return ERR_PTR(error);
1582+
}
1583+
1584+
security_init_mnt_opts(&new_sec_opts);
1585+
if (data) {
1586+
error = parse_security_options(data, &new_sec_opts);
1587+
if (error)
1588+
return ERR_PTR(error);
1589+
}
1590+
1591+
error = btrfs_scan_one_device(device_name, mode, fs_type, &fs_devices);
1592+
if (error)
1593+
goto error_sec_opts;
1594+
1595+
/*
1596+
* Setup a dummy root and fs_info for test/set super. This is because
1597+
* we don't actually fill this stuff out until open_ctree, but we need
1598+
* it for searching for existing supers, so this lets us do that and
1599+
* then open_ctree will properly initialize everything later.
1600+
*/
1601+
fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_KERNEL);
1602+
if (!fs_info) {
1603+
error = -ENOMEM;
1604+
goto error_sec_opts;
1605+
}
1606+
1607+
fs_info->fs_devices = fs_devices;
1608+
1609+
fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL);
1610+
fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL);
1611+
security_init_mnt_opts(&fs_info->security_opts);
1612+
if (!fs_info->super_copy || !fs_info->super_for_commit) {
1613+
error = -ENOMEM;
1614+
goto error_fs_info;
1615+
}
1616+
1617+
error = btrfs_open_devices(fs_devices, mode, fs_type);
1618+
if (error)
1619+
goto error_fs_info;
1620+
1621+
if (!(flags & SB_RDONLY) && fs_devices->rw_devices == 0) {
1622+
error = -EACCES;
1623+
goto error_close_devices;
1624+
}
1625+
1626+
bdev = fs_devices->latest_bdev;
1627+
s = sget(fs_type, btrfs_test_super, btrfs_set_super, flags | SB_NOSEC,
1628+
fs_info);
1629+
if (IS_ERR(s)) {
1630+
error = PTR_ERR(s);
1631+
goto error_close_devices;
1632+
}
1633+
1634+
if (s->s_root) {
1635+
btrfs_close_devices(fs_devices);
1636+
free_fs_info(fs_info);
1637+
if ((flags ^ s->s_flags) & SB_RDONLY)
1638+
error = -EBUSY;
1639+
} else {
1640+
snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev);
1641+
btrfs_sb(s)->bdev_holder = fs_type;
1642+
error = btrfs_fill_super(s, fs_devices, data);
1643+
}
1644+
if (error) {
1645+
deactivate_locked_super(s);
1646+
goto error_sec_opts;
1647+
}
1648+
1649+
fs_info = btrfs_sb(s);
1650+
error = setup_security_options(fs_info, s, &new_sec_opts);
1651+
if (error) {
1652+
deactivate_locked_super(s);
1653+
goto error_sec_opts;
1654+
}
1655+
1656+
return dget(s->s_root);
1657+
1658+
error_close_devices:
1659+
btrfs_close_devices(fs_devices);
1660+
error_fs_info:
1661+
free_fs_info(fs_info);
1662+
error_sec_opts:
1663+
security_free_mnt_opts(&new_sec_opts);
1664+
return ERR_PTR(error);
1665+
}
15521666
/*
15531667
* Find a superblock for the given device / mount point.
15541668
*
@@ -2170,6 +2284,15 @@ static struct file_system_type btrfs_fs_type = {
21702284
.kill_sb = btrfs_kill_super,
21712285
.fs_flags = FS_REQUIRES_DEV | FS_BINARY_MOUNTDATA,
21722286
};
2287+
2288+
static struct file_system_type btrfs_root_fs_type = {
2289+
.owner = THIS_MODULE,
2290+
.name = "btrfs",
2291+
.mount = btrfs_mount_root,
2292+
.kill_sb = btrfs_kill_super,
2293+
.fs_flags = FS_REQUIRES_DEV | FS_BINARY_MOUNTDATA,
2294+
};
2295+
21732296
MODULE_ALIAS_FS("btrfs");
21742297

21752298
static int btrfs_control_open(struct inode *inode, struct file *file)

0 commit comments

Comments
 (0)