Skip to content

Commit ef9ca17

Browse files
Hongbo Librauner
authored andcommitted
hostfs: fix the host directory parse when mounting.
hostfs not keep the host directory when mounting. When the host directory is none (default), fc->source is used as the host root directory, and this is wrong. Here we use `parse_monolithic` to handle the old mount path for parsing the root directory. For new mount path, The `parse_param` is used for the host directory parse. Reported-and-tested-by: Maciej Żenczykowski <maze@google.com> Fixes: cd140ce ("hostfs: convert hostfs to use the new mount API") Link: https://lore.kernel.org/all/CANP3RGceNzwdb7w=vPf5=7BCid5HVQDmz1K5kC9JG42+HVAh_g@mail.gmail.com/ Cc: Christian Brauner <brauner@kernel.org> Signed-off-by: Hongbo Li <lihongbo22@huawei.com> Link: https://lore.kernel.org/r/20240725065130.1821964-1-lihongbo22@huawei.com [brauner: minor fixes] Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent e1c5ae5 commit ef9ca17

File tree

1 file changed

+55
-10
lines changed

1 file changed

+55
-10
lines changed

fs/hostfs/hostfs_kern.c

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/writeback.h>
1818
#include <linux/mount.h>
1919
#include <linux/fs_context.h>
20+
#include <linux/fs_parser.h>
2021
#include <linux/namei.h>
2122
#include "hostfs.h"
2223
#include <init.h>
@@ -927,7 +928,6 @@ static const struct inode_operations hostfs_link_iops = {
927928
static int hostfs_fill_super(struct super_block *sb, struct fs_context *fc)
928929
{
929930
struct hostfs_fs_info *fsi = sb->s_fs_info;
930-
const char *host_root = fc->source;
931931
struct inode *root_inode;
932932
int err;
933933

@@ -941,15 +941,6 @@ static int hostfs_fill_super(struct super_block *sb, struct fs_context *fc)
941941
if (err)
942942
return err;
943943

944-
/* NULL is printed as '(null)' by printf(): avoid that. */
945-
if (fc->source == NULL)
946-
host_root = "";
947-
948-
fsi->host_root_path =
949-
kasprintf(GFP_KERNEL, "%s/%s", root_ino, host_root);
950-
if (fsi->host_root_path == NULL)
951-
return -ENOMEM;
952-
953944
root_inode = hostfs_iget(sb, fsi->host_root_path);
954945
if (IS_ERR(root_inode))
955946
return PTR_ERR(root_inode);
@@ -975,6 +966,58 @@ static int hostfs_fill_super(struct super_block *sb, struct fs_context *fc)
975966
return 0;
976967
}
977968

969+
enum hostfs_parma {
970+
Opt_hostfs,
971+
};
972+
973+
static const struct fs_parameter_spec hostfs_param_specs[] = {
974+
fsparam_string_empty("hostfs", Opt_hostfs),
975+
{}
976+
};
977+
978+
static int hostfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
979+
{
980+
struct hostfs_fs_info *fsi = fc->s_fs_info;
981+
struct fs_parse_result result;
982+
char *host_root;
983+
int opt;
984+
985+
opt = fs_parse(fc, hostfs_param_specs, param, &result);
986+
if (opt < 0)
987+
return opt;
988+
989+
switch (opt) {
990+
case Opt_hostfs:
991+
host_root = param->string;
992+
if (!*host_root)
993+
host_root = "";
994+
fsi->host_root_path =
995+
kasprintf(GFP_KERNEL, "%s/%s", root_ino, host_root);
996+
if (fsi->host_root_path == NULL)
997+
return -ENOMEM;
998+
break;
999+
}
1000+
1001+
return 0;
1002+
}
1003+
1004+
static int hostfs_parse_monolithic(struct fs_context *fc, void *data)
1005+
{
1006+
struct hostfs_fs_info *fsi = fc->s_fs_info;
1007+
char *host_root = (char *)data;
1008+
1009+
/* NULL is printed as '(null)' by printf(): avoid that. */
1010+
if (host_root == NULL)
1011+
host_root = "";
1012+
1013+
fsi->host_root_path =
1014+
kasprintf(GFP_KERNEL, "%s/%s", root_ino, host_root);
1015+
if (fsi->host_root_path == NULL)
1016+
return -ENOMEM;
1017+
1018+
return 0;
1019+
}
1020+
9781021
static int hostfs_fc_get_tree(struct fs_context *fc)
9791022
{
9801023
return get_tree_nodev(fc, hostfs_fill_super);
@@ -992,6 +1035,8 @@ static void hostfs_fc_free(struct fs_context *fc)
9921035
}
9931036

9941037
static const struct fs_context_operations hostfs_context_ops = {
1038+
.parse_monolithic = hostfs_parse_monolithic,
1039+
.parse_param = hostfs_parse_param,
9951040
.get_tree = hostfs_fc_get_tree,
9961041
.free = hostfs_fc_free,
9971042
};

0 commit comments

Comments
 (0)