Commit ef9ca17c authored by Hongbo Li's avatar Hongbo Li Committed by Christian Brauner

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: default avatarMaciej Żenczykowski <maze@google.com>
Fixes: cd140ce9 ("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: default avatarHongbo Li <lihongbo22@huawei.com>
Link: https://lore.kernel.org/r/20240725065130.1821964-1-lihongbo22@huawei.com
[brauner: minor fixes]
Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parent e1c5ae59
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/writeback.h> #include <linux/writeback.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/fs_context.h> #include <linux/fs_context.h>
#include <linux/fs_parser.h>
#include <linux/namei.h> #include <linux/namei.h>
#include "hostfs.h" #include "hostfs.h"
#include <init.h> #include <init.h>
...@@ -927,7 +928,6 @@ static const struct inode_operations hostfs_link_iops = { ...@@ -927,7 +928,6 @@ static const struct inode_operations hostfs_link_iops = {
static int hostfs_fill_super(struct super_block *sb, struct fs_context *fc) static int hostfs_fill_super(struct super_block *sb, struct fs_context *fc)
{ {
struct hostfs_fs_info *fsi = sb->s_fs_info; struct hostfs_fs_info *fsi = sb->s_fs_info;
const char *host_root = fc->source;
struct inode *root_inode; struct inode *root_inode;
int err; int err;
...@@ -941,15 +941,6 @@ static int hostfs_fill_super(struct super_block *sb, struct fs_context *fc) ...@@ -941,15 +941,6 @@ static int hostfs_fill_super(struct super_block *sb, struct fs_context *fc)
if (err) if (err)
return err; return err;
/* NULL is printed as '(null)' by printf(): avoid that. */
if (fc->source == NULL)
host_root = "";
fsi->host_root_path =
kasprintf(GFP_KERNEL, "%s/%s", root_ino, host_root);
if (fsi->host_root_path == NULL)
return -ENOMEM;
root_inode = hostfs_iget(sb, fsi->host_root_path); root_inode = hostfs_iget(sb, fsi->host_root_path);
if (IS_ERR(root_inode)) if (IS_ERR(root_inode))
return PTR_ERR(root_inode); return PTR_ERR(root_inode);
...@@ -975,6 +966,58 @@ static int hostfs_fill_super(struct super_block *sb, struct fs_context *fc) ...@@ -975,6 +966,58 @@ static int hostfs_fill_super(struct super_block *sb, struct fs_context *fc)
return 0; return 0;
} }
enum hostfs_parma {
Opt_hostfs,
};
static const struct fs_parameter_spec hostfs_param_specs[] = {
fsparam_string_empty("hostfs", Opt_hostfs),
{}
};
static int hostfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
{
struct hostfs_fs_info *fsi = fc->s_fs_info;
struct fs_parse_result result;
char *host_root;
int opt;
opt = fs_parse(fc, hostfs_param_specs, param, &result);
if (opt < 0)
return opt;
switch (opt) {
case Opt_hostfs:
host_root = param->string;
if (!*host_root)
host_root = "";
fsi->host_root_path =
kasprintf(GFP_KERNEL, "%s/%s", root_ino, host_root);
if (fsi->host_root_path == NULL)
return -ENOMEM;
break;
}
return 0;
}
static int hostfs_parse_monolithic(struct fs_context *fc, void *data)
{
struct hostfs_fs_info *fsi = fc->s_fs_info;
char *host_root = (char *)data;
/* NULL is printed as '(null)' by printf(): avoid that. */
if (host_root == NULL)
host_root = "";
fsi->host_root_path =
kasprintf(GFP_KERNEL, "%s/%s", root_ino, host_root);
if (fsi->host_root_path == NULL)
return -ENOMEM;
return 0;
}
static int hostfs_fc_get_tree(struct fs_context *fc) static int hostfs_fc_get_tree(struct fs_context *fc)
{ {
return get_tree_nodev(fc, hostfs_fill_super); return get_tree_nodev(fc, hostfs_fill_super);
...@@ -992,6 +1035,8 @@ static void hostfs_fc_free(struct fs_context *fc) ...@@ -992,6 +1035,8 @@ static void hostfs_fc_free(struct fs_context *fc)
} }
static const struct fs_context_operations hostfs_context_ops = { static const struct fs_context_operations hostfs_context_ops = {
.parse_monolithic = hostfs_parse_monolithic,
.parse_param = hostfs_parse_param,
.get_tree = hostfs_fc_get_tree, .get_tree = hostfs_fc_get_tree,
.free = hostfs_fc_free, .free = hostfs_fc_free,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment