|
Kmods SIG |
d83023 |
From 610f8f5a7baf998e70a61c63e53869b676d9b04c Mon Sep 17 00:00:00 2001
|
|
Kmods SIG |
d83023 |
From: Kari Argillander <kari.argillander@gmail.com>
|
|
Kmods SIG |
d83023 |
Date: Tue, 7 Sep 2021 18:35:52 +0300
|
|
Kmods SIG |
d83023 |
Subject: [Backport 610f8f5a7baf] src: Use new api for mounting
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
We have now new mount api as described in Documentation/filesystems. We
|
|
Kmods SIG |
d83023 |
should use it as it gives us some benefits which are desribed here
|
|
Kmods SIG |
d83023 |
lore.kernel.org/linux-fsdevel/159646178122.1784947.11705396571718464082.stgit@warthog.procyon.org.uk/
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
Nls loading is changed a to load with string. This did make code also
|
|
Kmods SIG |
d83023 |
little cleaner.
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
Also try to use fsparam_flag_no as much as possible. This is just nice
|
|
Kmods SIG |
d83023 |
little touch and is not mandatory but it should not make any harm. It
|
|
Kmods SIG |
d83023 |
is just convenient that we can use example acl/noacl mount options.
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
Signed-off-by: Kari Argillander <kari.argillander@gmail.com>
|
|
Kmods SIG |
d83023 |
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
|
|
Kmods SIG |
d83023 |
---
|
|
Kmods SIG |
d83023 |
src/ntfs_fs.h | 1 +
|
|
Kmods SIG |
d83023 |
src/super.c | 433 ++++++++++++++++++++++++---------------------
|
|
Kmods SIG |
d83023 |
2 files changed, 229 insertions(+), 205 deletions(-)
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
diff --git a/src/ntfs_fs.h b/src/ntfs_fs.h
|
|
Kmods SIG |
d83023 |
index 98c90c399ee2f447f3ad5f0847c56ca7561f17fb..aa18f12b7096e2ecd7e6db365aaa0152d4fb2327 100644
|
|
Kmods SIG |
d83023 |
--- a/src/ntfs_fs.h
|
|
Kmods SIG |
d83023 |
+++ b/src/ntfs_fs.h
|
|
Kmods SIG |
d83023 |
@@ -52,6 +52,7 @@
|
|
Kmods SIG |
d83023 |
// clang-format on
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
struct ntfs_mount_options {
|
|
Kmods SIG |
d83023 |
+ char *nls_name;
|
|
Kmods SIG |
d83023 |
struct nls_table *nls;
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
kuid_t fs_uid;
|
|
Kmods SIG |
d83023 |
diff --git a/src/super.c b/src/super.c
|
|
Kmods SIG |
d83023 |
index 0f38203420515b6386bdd51e83c402c431743946..befa78d3cb26767e401c84cc87a40006c4603186 100644
|
|
Kmods SIG |
d83023 |
--- a/src/super.c
|
|
Kmods SIG |
d83023 |
+++ b/src/super.c
|
|
Kmods SIG |
d83023 |
@@ -28,11 +28,12 @@
|
|
Kmods SIG |
d83023 |
#include <linux/buffer_head.h>
|
|
Kmods SIG |
d83023 |
#include <linux/exportfs.h>
|
|
Kmods SIG |
d83023 |
#include <linux/fs.h>
|
|
Kmods SIG |
d83023 |
+#include <linux/fs_context.h>
|
|
Kmods SIG |
d83023 |
+#include <linux/fs_parser.h>
|
|
Kmods SIG |
d83023 |
#include <linux/iversion.h>
|
|
Kmods SIG |
d83023 |
#include <linux/log2.h>
|
|
Kmods SIG |
d83023 |
#include <linux/module.h>
|
|
Kmods SIG |
d83023 |
#include <linux/nls.h>
|
|
Kmods SIG |
d83023 |
-#include <linux/parser.h>
|
|
Kmods SIG |
d83023 |
#include <linux/seq_file.h>
|
|
Kmods SIG |
d83023 |
#include <linux/statfs.h>
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
@@ -205,9 +206,11 @@ void *ntfs_put_shared(void *ptr)
|
|
Kmods SIG |
d83023 |
return ret;
|
|
Kmods SIG |
d83023 |
}
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
-static inline void clear_mount_options(struct ntfs_mount_options *options)
|
|
Kmods SIG |
d83023 |
+static inline void put_mount_options(struct ntfs_mount_options *options)
|
|
Kmods SIG |
d83023 |
{
|
|
Kmods SIG |
d83023 |
+ kfree(options->nls_name);
|
|
Kmods SIG |
d83023 |
unload_nls(options->nls);
|
|
Kmods SIG |
d83023 |
+ kfree(options);
|
|
Kmods SIG |
d83023 |
}
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
enum Opt {
|
|
Kmods SIG |
d83023 |
@@ -229,205 +232,171 @@ enum Opt {
|
|
Kmods SIG |
d83023 |
Opt_err,
|
|
Kmods SIG |
d83023 |
};
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
-static const match_table_t ntfs_tokens = {
|
|
Kmods SIG |
d83023 |
- { Opt_uid, "uid=%u" },
|
|
Kmods SIG |
d83023 |
- { Opt_gid, "gid=%u" },
|
|
Kmods SIG |
d83023 |
- { Opt_umask, "umask=%o" },
|
|
Kmods SIG |
d83023 |
- { Opt_dmask, "dmask=%o" },
|
|
Kmods SIG |
d83023 |
- { Opt_fmask, "fmask=%o" },
|
|
Kmods SIG |
d83023 |
- { Opt_immutable, "sys_immutable" },
|
|
Kmods SIG |
d83023 |
- { Opt_discard, "discard" },
|
|
Kmods SIG |
d83023 |
- { Opt_force, "force" },
|
|
Kmods SIG |
d83023 |
- { Opt_sparse, "sparse" },
|
|
Kmods SIG |
d83023 |
- { Opt_nohidden, "nohidden" },
|
|
Kmods SIG |
d83023 |
- { Opt_acl, "acl" },
|
|
Kmods SIG |
d83023 |
- { Opt_showmeta, "showmeta" },
|
|
Kmods SIG |
d83023 |
- { Opt_nls, "nls=%s" },
|
|
Kmods SIG |
d83023 |
- { Opt_prealloc, "prealloc" },
|
|
Kmods SIG |
d83023 |
- { Opt_no_acs_rules, "no_acs_rules" },
|
|
Kmods SIG |
d83023 |
- { Opt_err, NULL },
|
|
Kmods SIG |
d83023 |
+static const struct fs_parameter_spec ntfs_fs_parameters[] = {
|
|
Kmods SIG |
d83023 |
+ fsparam_u32("uid", Opt_uid),
|
|
Kmods SIG |
d83023 |
+ fsparam_u32("gid", Opt_gid),
|
|
Kmods SIG |
d83023 |
+ fsparam_u32oct("umask", Opt_umask),
|
|
Kmods SIG |
d83023 |
+ fsparam_u32oct("dmask", Opt_dmask),
|
|
Kmods SIG |
d83023 |
+ fsparam_u32oct("fmask", Opt_fmask),
|
|
Kmods SIG |
d83023 |
+ fsparam_flag_no("sys_immutable", Opt_immutable),
|
|
Kmods SIG |
d83023 |
+ fsparam_flag_no("discard", Opt_discard),
|
|
Kmods SIG |
d83023 |
+ fsparam_flag_no("force", Opt_force),
|
|
Kmods SIG |
d83023 |
+ fsparam_flag_no("sparse", Opt_sparse),
|
|
Kmods SIG |
d83023 |
+ fsparam_flag("nohidden", Opt_nohidden),
|
|
Kmods SIG |
d83023 |
+ fsparam_flag_no("acl", Opt_acl),
|
|
Kmods SIG |
d83023 |
+ fsparam_flag_no("showmeta", Opt_showmeta),
|
|
Kmods SIG |
d83023 |
+ fsparam_string("nls", Opt_nls),
|
|
Kmods SIG |
d83023 |
+ fsparam_flag_no("prealloc", Opt_prealloc),
|
|
Kmods SIG |
d83023 |
+ fsparam_flag("no_acs_rules", Opt_no_acs_rules),
|
|
Kmods SIG |
d83023 |
+ {}
|
|
Kmods SIG |
d83023 |
};
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
-static noinline int ntfs_parse_options(struct super_block *sb, char *options,
|
|
Kmods SIG |
d83023 |
- int silent,
|
|
Kmods SIG |
d83023 |
- struct ntfs_mount_options *opts)
|
|
Kmods SIG |
d83023 |
+/*
|
|
Kmods SIG |
d83023 |
+ * Load nls table or if @nls is utf8 then return NULL.
|
|
Kmods SIG |
d83023 |
+ */
|
|
Kmods SIG |
d83023 |
+static struct nls_table *ntfs_load_nls(char *nls)
|
|
Kmods SIG |
d83023 |
{
|
|
Kmods SIG |
d83023 |
- char *p;
|
|
Kmods SIG |
d83023 |
- substring_t args[MAX_OPT_ARGS];
|
|
Kmods SIG |
d83023 |
- int option;
|
|
Kmods SIG |
d83023 |
- char nls_name[30];
|
|
Kmods SIG |
d83023 |
- struct nls_table *nls;
|
|
Kmods SIG |
d83023 |
+ struct nls_table *ret;
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
- opts->fs_uid = current_uid();
|
|
Kmods SIG |
d83023 |
- opts->fs_gid = current_gid();
|
|
Kmods SIG |
d83023 |
- opts->fs_fmask_inv = opts->fs_dmask_inv = ~current_umask();
|
|
Kmods SIG |
d83023 |
- nls_name[0] = 0;
|
|
Kmods SIG |
d83023 |
+ if (!nls)
|
|
Kmods SIG |
d83023 |
+ nls = CONFIG_NLS_DEFAULT;
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
- if (!options)
|
|
Kmods SIG |
d83023 |
- goto out;
|
|
Kmods SIG |
d83023 |
+ if (strcmp(nls, "utf8") == 0)
|
|
Kmods SIG |
d83023 |
+ return NULL;
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
- while ((p = strsep(&options, ","))) {
|
|
Kmods SIG |
d83023 |
- int token;
|
|
Kmods SIG |
d83023 |
+ if (strcmp(nls, CONFIG_NLS_DEFAULT) == 0)
|
|
Kmods SIG |
d83023 |
+ return load_nls_default();
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
- if (!*p)
|
|
Kmods SIG |
d83023 |
- continue;
|
|
Kmods SIG |
d83023 |
+ ret = load_nls(nls);
|
|
Kmods SIG |
d83023 |
+ if (ret)
|
|
Kmods SIG |
d83023 |
+ return ret;
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
- token = match_token(p, ntfs_tokens, args);
|
|
Kmods SIG |
d83023 |
- switch (token) {
|
|
Kmods SIG |
d83023 |
- case Opt_immutable:
|
|
Kmods SIG |
d83023 |
- opts->sys_immutable = 1;
|
|
Kmods SIG |
d83023 |
- break;
|
|
Kmods SIG |
d83023 |
- case Opt_uid:
|
|
Kmods SIG |
d83023 |
- if (match_int(&args[0], &option))
|
|
Kmods SIG |
d83023 |
- return -EINVAL;
|
|
Kmods SIG |
d83023 |
- opts->fs_uid = make_kuid(current_user_ns(), option);
|
|
Kmods SIG |
d83023 |
- if (!uid_valid(opts->fs_uid))
|
|
Kmods SIG |
d83023 |
- return -EINVAL;
|
|
Kmods SIG |
d83023 |
- opts->uid = 1;
|
|
Kmods SIG |
d83023 |
- break;
|
|
Kmods SIG |
d83023 |
- case Opt_gid:
|
|
Kmods SIG |
d83023 |
- if (match_int(&args[0], &option))
|
|
Kmods SIG |
d83023 |
- return -EINVAL;
|
|
Kmods SIG |
d83023 |
- opts->fs_gid = make_kgid(current_user_ns(), option);
|
|
Kmods SIG |
d83023 |
- if (!gid_valid(opts->fs_gid))
|
|
Kmods SIG |
d83023 |
- return -EINVAL;
|
|
Kmods SIG |
d83023 |
- opts->gid = 1;
|
|
Kmods SIG |
d83023 |
- break;
|
|
Kmods SIG |
d83023 |
- case Opt_umask:
|
|
Kmods SIG |
d83023 |
- if (match_octal(&args[0], &option))
|
|
Kmods SIG |
d83023 |
- return -EINVAL;
|
|
Kmods SIG |
d83023 |
- opts->fs_fmask_inv = opts->fs_dmask_inv = ~option;
|
|
Kmods SIG |
d83023 |
- opts->fmask = opts->dmask = 1;
|
|
Kmods SIG |
d83023 |
- break;
|
|
Kmods SIG |
d83023 |
- case Opt_dmask:
|
|
Kmods SIG |
d83023 |
- if (match_octal(&args[0], &option))
|
|
Kmods SIG |
d83023 |
- return -EINVAL;
|
|
Kmods SIG |
d83023 |
- opts->fs_dmask_inv = ~option;
|
|
Kmods SIG |
d83023 |
- opts->dmask = 1;
|
|
Kmods SIG |
d83023 |
- break;
|
|
Kmods SIG |
d83023 |
- case Opt_fmask:
|
|
Kmods SIG |
d83023 |
- if (match_octal(&args[0], &option))
|
|
Kmods SIG |
d83023 |
- return -EINVAL;
|
|
Kmods SIG |
d83023 |
- opts->fs_fmask_inv = ~option;
|
|
Kmods SIG |
d83023 |
- opts->fmask = 1;
|
|
Kmods SIG |
d83023 |
- break;
|
|
Kmods SIG |
d83023 |
- case Opt_discard:
|
|
Kmods SIG |
d83023 |
- opts->discard = 1;
|
|
Kmods SIG |
d83023 |
- break;
|
|
Kmods SIG |
d83023 |
- case Opt_force:
|
|
Kmods SIG |
d83023 |
- opts->force = 1;
|
|
Kmods SIG |
d83023 |
- break;
|
|
Kmods SIG |
d83023 |
- case Opt_sparse:
|
|
Kmods SIG |
d83023 |
- opts->sparse = 1;
|
|
Kmods SIG |
d83023 |
- break;
|
|
Kmods SIG |
d83023 |
- case Opt_nohidden:
|
|
Kmods SIG |
d83023 |
- opts->nohidden = 1;
|
|
Kmods SIG |
d83023 |
- break;
|
|
Kmods SIG |
d83023 |
- case Opt_acl:
|
|
Kmods SIG |
d83023 |
+ return ERR_PTR(-EINVAL);
|
|
Kmods SIG |
d83023 |
+}
|
|
Kmods SIG |
d83023 |
+
|
|
Kmods SIG |
d83023 |
+static int ntfs_fs_parse_param(struct fs_context *fc,
|
|
Kmods SIG |
d83023 |
+ struct fs_parameter *param)
|
|
Kmods SIG |
d83023 |
+{
|
|
Kmods SIG |
d83023 |
+ struct ntfs_mount_options *opts = fc->fs_private;
|
|
Kmods SIG |
d83023 |
+ struct fs_parse_result result;
|
|
Kmods SIG |
d83023 |
+ int opt;
|
|
Kmods SIG |
d83023 |
+
|
|
Kmods SIG |
d83023 |
+ opt = fs_parse(fc, ntfs_fs_parameters, param, &result);
|
|
Kmods SIG |
d83023 |
+ if (opt < 0)
|
|
Kmods SIG |
d83023 |
+ return opt;
|
|
Kmods SIG |
d83023 |
+
|
|
Kmods SIG |
d83023 |
+ switch (opt) {
|
|
Kmods SIG |
d83023 |
+ case Opt_uid:
|
|
Kmods SIG |
d83023 |
+ opts->fs_uid = make_kuid(current_user_ns(), result.uint_32);
|
|
Kmods SIG |
d83023 |
+ if (!uid_valid(opts->fs_uid))
|
|
Kmods SIG |
d83023 |
+ return invalf(fc, "ntfs3: Invalid value for uid.");
|
|
Kmods SIG |
d83023 |
+ opts->uid = 1;
|
|
Kmods SIG |
d83023 |
+ break;
|
|
Kmods SIG |
d83023 |
+ case Opt_gid:
|
|
Kmods SIG |
d83023 |
+ opts->fs_gid = make_kgid(current_user_ns(), result.uint_32);
|
|
Kmods SIG |
d83023 |
+ if (!gid_valid(opts->fs_gid))
|
|
Kmods SIG |
d83023 |
+ return invalf(fc, "ntfs3: Invalid value for gid.");
|
|
Kmods SIG |
d83023 |
+ opts->gid = 1;
|
|
Kmods SIG |
d83023 |
+ break;
|
|
Kmods SIG |
d83023 |
+ case Opt_umask:
|
|
Kmods SIG |
d83023 |
+ if (result.uint_32 & ~07777)
|
|
Kmods SIG |
d83023 |
+ return invalf(fc, "ntfs3: Invalid value for umask.");
|
|
Kmods SIG |
d83023 |
+ opts->fs_fmask_inv = ~result.uint_32;
|
|
Kmods SIG |
d83023 |
+ opts->fs_dmask_inv = ~result.uint_32;
|
|
Kmods SIG |
d83023 |
+ opts->fmask = 1;
|
|
Kmods SIG |
d83023 |
+ opts->dmask = 1;
|
|
Kmods SIG |
d83023 |
+ break;
|
|
Kmods SIG |
d83023 |
+ case Opt_dmask:
|
|
Kmods SIG |
d83023 |
+ if (result.uint_32 & ~07777)
|
|
Kmods SIG |
d83023 |
+ return invalf(fc, "ntfs3: Invalid value for dmask.");
|
|
Kmods SIG |
d83023 |
+ opts->fs_dmask_inv = ~result.uint_32;
|
|
Kmods SIG |
d83023 |
+ opts->dmask = 1;
|
|
Kmods SIG |
d83023 |
+ break;
|
|
Kmods SIG |
d83023 |
+ case Opt_fmask:
|
|
Kmods SIG |
d83023 |
+ if (result.uint_32 & ~07777)
|
|
Kmods SIG |
d83023 |
+ return invalf(fc, "ntfs3: Invalid value for fmask.");
|
|
Kmods SIG |
d83023 |
+ opts->fs_fmask_inv = ~result.uint_32;
|
|
Kmods SIG |
d83023 |
+ opts->fmask = 1;
|
|
Kmods SIG |
d83023 |
+ break;
|
|
Kmods SIG |
d83023 |
+ case Opt_immutable:
|
|
Kmods SIG |
d83023 |
+ opts->sys_immutable = result.negated ? 0 : 1;
|
|
Kmods SIG |
d83023 |
+ break;
|
|
Kmods SIG |
d83023 |
+ case Opt_discard:
|
|
Kmods SIG |
d83023 |
+ opts->discard = result.negated ? 0 : 1;
|
|
Kmods SIG |
d83023 |
+ break;
|
|
Kmods SIG |
d83023 |
+ case Opt_force:
|
|
Kmods SIG |
d83023 |
+ opts->force = result.negated ? 0 : 1;
|
|
Kmods SIG |
d83023 |
+ break;
|
|
Kmods SIG |
d83023 |
+ case Opt_sparse:
|
|
Kmods SIG |
d83023 |
+ opts->sparse = result.negated ? 0 : 1;
|
|
Kmods SIG |
d83023 |
+ break;
|
|
Kmods SIG |
d83023 |
+ case Opt_nohidden:
|
|
Kmods SIG |
d83023 |
+ opts->nohidden = 1;
|
|
Kmods SIG |
d83023 |
+ break;
|
|
Kmods SIG |
d83023 |
+ case Opt_acl:
|
|
Kmods SIG |
d83023 |
+ if (!result.negated)
|
|
Kmods SIG |
d83023 |
#ifdef CONFIG_NTFS3_FS_POSIX_ACL
|
|
Kmods SIG |
d83023 |
- sb->s_flags |= SB_POSIXACL;
|
|
Kmods SIG |
d83023 |
- break;
|
|
Kmods SIG |
d83023 |
+ fc->sb_flags |= SB_POSIXACL;
|
|
Kmods SIG |
d83023 |
#else
|
|
Kmods SIG |
d83023 |
- ntfs_err(sb, "support for ACL not compiled in!");
|
|
Kmods SIG |
d83023 |
- return -EINVAL;
|
|
Kmods SIG |
d83023 |
+ return invalf(fc, "ntfs3: Support for ACL not compiled in!");
|
|
Kmods SIG |
d83023 |
#endif
|
|
Kmods SIG |
d83023 |
- case Opt_showmeta:
|
|
Kmods SIG |
d83023 |
- opts->showmeta = 1;
|
|
Kmods SIG |
d83023 |
- break;
|
|
Kmods SIG |
d83023 |
- case Opt_nls:
|
|
Kmods SIG |
d83023 |
- match_strlcpy(nls_name, &args[0], sizeof(nls_name));
|
|
Kmods SIG |
d83023 |
- break;
|
|
Kmods SIG |
d83023 |
- case Opt_prealloc:
|
|
Kmods SIG |
d83023 |
- opts->prealloc = 1;
|
|
Kmods SIG |
d83023 |
- break;
|
|
Kmods SIG |
d83023 |
- case Opt_no_acs_rules:
|
|
Kmods SIG |
d83023 |
- opts->no_acs_rules = 1;
|
|
Kmods SIG |
d83023 |
- break;
|
|
Kmods SIG |
d83023 |
- default:
|
|
Kmods SIG |
d83023 |
- if (!silent)
|
|
Kmods SIG |
d83023 |
- ntfs_err(
|
|
Kmods SIG |
d83023 |
- sb,
|
|
Kmods SIG |
d83023 |
- "Unrecognized mount option \"%s\" or missing value",
|
|
Kmods SIG |
d83023 |
- p);
|
|
Kmods SIG |
d83023 |
- //return -EINVAL;
|
|
Kmods SIG |
d83023 |
- }
|
|
Kmods SIG |
d83023 |
- }
|
|
Kmods SIG |
d83023 |
-
|
|
Kmods SIG |
d83023 |
-out:
|
|
Kmods SIG |
d83023 |
- if (!strcmp(nls_name[0] ? nls_name : CONFIG_NLS_DEFAULT, "utf8")) {
|
|
Kmods SIG |
d83023 |
- /*
|
|
Kmods SIG |
d83023 |
- * For UTF-8 use utf16s_to_utf8s()/utf8s_to_utf16s()
|
|
Kmods SIG |
d83023 |
- * instead of NLS.
|
|
Kmods SIG |
d83023 |
- */
|
|
Kmods SIG |
d83023 |
- nls = NULL;
|
|
Kmods SIG |
d83023 |
- } else if (nls_name[0]) {
|
|
Kmods SIG |
d83023 |
- nls = load_nls(nls_name);
|
|
Kmods SIG |
d83023 |
- if (!nls) {
|
|
Kmods SIG |
d83023 |
- ntfs_err(sb, "failed to load \"%s\"", nls_name);
|
|
Kmods SIG |
d83023 |
- return -EINVAL;
|
|
Kmods SIG |
d83023 |
- }
|
|
Kmods SIG |
d83023 |
- } else {
|
|
Kmods SIG |
d83023 |
- nls = load_nls_default();
|
|
Kmods SIG |
d83023 |
- if (!nls) {
|
|
Kmods SIG |
d83023 |
- ntfs_err(sb, "failed to load default nls");
|
|
Kmods SIG |
d83023 |
- return -EINVAL;
|
|
Kmods SIG |
d83023 |
- }
|
|
Kmods SIG |
d83023 |
+ else
|
|
Kmods SIG |
d83023 |
+ fc->sb_flags &= ~SB_POSIXACL;
|
|
Kmods SIG |
d83023 |
+ break;
|
|
Kmods SIG |
d83023 |
+ case Opt_showmeta:
|
|
Kmods SIG |
d83023 |
+ opts->showmeta = result.negated ? 0 : 1;
|
|
Kmods SIG |
d83023 |
+ break;
|
|
Kmods SIG |
d83023 |
+ case Opt_nls:
|
|
Kmods SIG |
d83023 |
+ kfree(opts->nls_name);
|
|
Kmods SIG |
d83023 |
+ opts->nls_name = param->string;
|
|
Kmods SIG |
d83023 |
+ param->string = NULL;
|
|
Kmods SIG |
d83023 |
+ break;
|
|
Kmods SIG |
d83023 |
+ case Opt_prealloc:
|
|
Kmods SIG |
d83023 |
+ opts->prealloc = result.negated ? 0 : 1;
|
|
Kmods SIG |
d83023 |
+ break;
|
|
Kmods SIG |
d83023 |
+ case Opt_no_acs_rules:
|
|
Kmods SIG |
d83023 |
+ opts->no_acs_rules = 1;
|
|
Kmods SIG |
d83023 |
+ break;
|
|
Kmods SIG |
d83023 |
+ default:
|
|
Kmods SIG |
d83023 |
+ /* Should not be here unless we forget add case. */
|
|
Kmods SIG |
d83023 |
+ return -EINVAL;
|
|
Kmods SIG |
d83023 |
}
|
|
Kmods SIG |
d83023 |
- opts->nls = nls;
|
|
Kmods SIG |
d83023 |
-
|
|
Kmods SIG |
d83023 |
return 0;
|
|
Kmods SIG |
d83023 |
}
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
-static int ntfs_remount(struct super_block *sb, int *flags, char *data)
|
|
Kmods SIG |
d83023 |
+static int ntfs_fs_reconfigure(struct fs_context *fc)
|
|
Kmods SIG |
d83023 |
{
|
|
Kmods SIG |
d83023 |
- int err, ro_rw;
|
|
Kmods SIG |
d83023 |
+ struct super_block *sb = fc->root->d_sb;
|
|
Kmods SIG |
d83023 |
struct ntfs_sb_info *sbi = sb->s_fs_info;
|
|
Kmods SIG |
d83023 |
- struct ntfs_mount_options old_opts;
|
|
Kmods SIG |
d83023 |
- char *orig_data = kstrdup(data, GFP_KERNEL);
|
|
Kmods SIG |
d83023 |
-
|
|
Kmods SIG |
d83023 |
- if (data && !orig_data)
|
|
Kmods SIG |
d83023 |
- return -ENOMEM;
|
|
Kmods SIG |
d83023 |
-
|
|
Kmods SIG |
d83023 |
- /* Store original options. */
|
|
Kmods SIG |
d83023 |
- memcpy(&old_opts, sbi->options, sizeof(old_opts));
|
|
Kmods SIG |
d83023 |
- clear_mount_options(sbi->options);
|
|
Kmods SIG |
d83023 |
- memset(sbi->options, 0, sizeof(old_opts));
|
|
Kmods SIG |
d83023 |
-
|
|
Kmods SIG |
d83023 |
- err = ntfs_parse_options(sb, data, 0, sbi->options);
|
|
Kmods SIG |
d83023 |
- if (err)
|
|
Kmods SIG |
d83023 |
- goto restore_opts;
|
|
Kmods SIG |
d83023 |
+ struct ntfs_mount_options *new_opts = fc->fs_private;
|
|
Kmods SIG |
d83023 |
+ int ro_rw;
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
- ro_rw = sb_rdonly(sb) && !(*flags & SB_RDONLY);
|
|
Kmods SIG |
d83023 |
+ ro_rw = sb_rdonly(sb) && !(fc->sb_flags & SB_RDONLY);
|
|
Kmods SIG |
d83023 |
if (ro_rw && (sbi->flags & NTFS_FLAGS_NEED_REPLAY)) {
|
|
Kmods SIG |
d83023 |
- ntfs_warn(
|
|
Kmods SIG |
d83023 |
- sb,
|
|
Kmods SIG |
d83023 |
- "Couldn't remount rw because journal is not replayed. Please umount/remount instead\n");
|
|
Kmods SIG |
d83023 |
- err = -EINVAL;
|
|
Kmods SIG |
d83023 |
- goto restore_opts;
|
|
Kmods SIG |
d83023 |
+ errorf(fc, "ntfs3: Couldn't remount rw because journal is not replayed. Please umount/remount instead\n");
|
|
Kmods SIG |
d83023 |
+ return -EINVAL;
|
|
Kmods SIG |
d83023 |
+ }
|
|
Kmods SIG |
d83023 |
+
|
|
Kmods SIG |
d83023 |
+ new_opts->nls = ntfs_load_nls(new_opts->nls_name);
|
|
Kmods SIG |
d83023 |
+ if (IS_ERR(new_opts->nls)) {
|
|
Kmods SIG |
d83023 |
+ new_opts->nls = NULL;
|
|
Kmods SIG |
d83023 |
+ errorf(fc, "ntfs3: Cannot load nls %s", new_opts->nls_name);
|
|
Kmods SIG |
d83023 |
+ return -EINVAL;
|
|
Kmods SIG |
d83023 |
}
|
|
Kmods SIG |
d83023 |
+ if (new_opts->nls != sbi->options->nls)
|
|
Kmods SIG |
d83023 |
+ return invalf(fc, "ntfs3: Cannot use different nls when remounting!");
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
sync_filesystem(sb);
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
if (ro_rw && (sbi->volume.flags & VOLUME_FLAG_DIRTY) &&
|
|
Kmods SIG |
d83023 |
- !sbi->options->force) {
|
|
Kmods SIG |
d83023 |
- ntfs_warn(sb, "volume is dirty and \"force\" flag is not set!");
|
|
Kmods SIG |
d83023 |
- err = -EINVAL;
|
|
Kmods SIG |
d83023 |
- goto restore_opts;
|
|
Kmods SIG |
d83023 |
+ !new_opts->force) {
|
|
Kmods SIG |
d83023 |
+ errorf(fc, "ntfs3: Volume is dirty and \"force\" flag is not set!");
|
|
Kmods SIG |
d83023 |
+ return -EINVAL;
|
|
Kmods SIG |
d83023 |
}
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
- clear_mount_options(&old_opts);
|
|
Kmods SIG |
d83023 |
-
|
|
Kmods SIG |
d83023 |
- ntfs_info(sb, "re-mounted. Opts: %s", orig_data);
|
|
Kmods SIG |
d83023 |
- err = 0;
|
|
Kmods SIG |
d83023 |
- goto out;
|
|
Kmods SIG |
d83023 |
-
|
|
Kmods SIG |
d83023 |
-restore_opts:
|
|
Kmods SIG |
d83023 |
- clear_mount_options(sbi->options);
|
|
Kmods SIG |
d83023 |
- memcpy(sbi->options, &old_opts, sizeof(old_opts));
|
|
Kmods SIG |
d83023 |
+ memcpy(sbi->options, new_opts, sizeof(*new_opts));
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
-out:
|
|
Kmods SIG |
d83023 |
- kfree(orig_data);
|
|
Kmods SIG |
d83023 |
- return err;
|
|
Kmods SIG |
d83023 |
+ return 0;
|
|
Kmods SIG |
d83023 |
}
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
static struct kmem_cache *ntfs_inode_cachep;
|
|
Kmods SIG |
d83023 |
@@ -506,9 +475,6 @@ static noinline void put_ntfs(struct ntfs_sb_info *sbi)
|
|
Kmods SIG |
d83023 |
xpress_free_decompressor(sbi->compress.xpress);
|
|
Kmods SIG |
d83023 |
lzx_free_decompressor(sbi->compress.lzx);
|
|
Kmods SIG |
d83023 |
#endif
|
|
Kmods SIG |
d83023 |
- clear_mount_options(sbi->options);
|
|
Kmods SIG |
d83023 |
- kfree(sbi->options);
|
|
Kmods SIG |
d83023 |
-
|
|
Kmods SIG |
d83023 |
kfree(sbi);
|
|
Kmods SIG |
d83023 |
}
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
@@ -519,7 +485,9 @@ static void ntfs_put_super(struct super_block *sb)
|
|
Kmods SIG |
d83023 |
/* Mark rw ntfs as clear, if possible. */
|
|
Kmods SIG |
d83023 |
ntfs_set_state(sbi, NTFS_DIRTY_CLEAR);
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
+ put_mount_options(sbi->options);
|
|
Kmods SIG |
d83023 |
put_ntfs(sbi);
|
|
Kmods SIG |
d83023 |
+ sb->s_fs_info = NULL;
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
sync_blockdev(sb->s_bdev);
|
|
Kmods SIG |
d83023 |
}
|
|
Kmods SIG |
d83023 |
@@ -635,7 +603,6 @@ static const struct super_operations ntfs_sops = {
|
|
Kmods SIG |
d83023 |
.statfs = ntfs_statfs,
|
|
Kmods SIG |
d83023 |
.show_options = ntfs_show_options,
|
|
Kmods SIG |
d83023 |
.sync_fs = ntfs_sync_fs,
|
|
Kmods SIG |
d83023 |
- .remount_fs = ntfs_remount,
|
|
Kmods SIG |
d83023 |
.write_inode = ntfs3_write_inode,
|
|
Kmods SIG |
d83023 |
};
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
@@ -905,10 +872,10 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
|
|
Kmods SIG |
d83023 |
/*
|
|
Kmods SIG |
d83023 |
* ntfs_fill_super - Try to mount.
|
|
Kmods SIG |
d83023 |
*/
|
|
Kmods SIG |
d83023 |
-static int ntfs_fill_super(struct super_block *sb, void *data, int silent)
|
|
Kmods SIG |
d83023 |
+static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc)
|
|
Kmods SIG |
d83023 |
{
|
|
Kmods SIG |
d83023 |
int err;
|
|
Kmods SIG |
d83023 |
- struct ntfs_sb_info *sbi;
|
|
Kmods SIG |
d83023 |
+ struct ntfs_sb_info *sbi = sb->s_fs_info;
|
|
Kmods SIG |
d83023 |
struct block_device *bdev = sb->s_bdev;
|
|
Kmods SIG |
d83023 |
struct inode *bd_inode = bdev->bd_inode;
|
|
Kmods SIG |
d83023 |
struct request_queue *rq = bdev_get_queue(bdev);
|
|
Kmods SIG |
d83023 |
@@ -927,17 +894,6 @@ static int ntfs_fill_super(struct super_block *sb, void *data, int silent)
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
ref.high = 0;
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
- sbi = kzalloc(sizeof(struct ntfs_sb_info), GFP_NOFS);
|
|
Kmods SIG |
d83023 |
- if (!sbi)
|
|
Kmods SIG |
d83023 |
- return -ENOMEM;
|
|
Kmods SIG |
d83023 |
-
|
|
Kmods SIG |
d83023 |
- sbi->options = kzalloc(sizeof(struct ntfs_mount_options), GFP_NOFS);
|
|
Kmods SIG |
d83023 |
- if (!sbi->options) {
|
|
Kmods SIG |
d83023 |
- kfree(sbi);
|
|
Kmods SIG |
d83023 |
- return -ENOMEM;
|
|
Kmods SIG |
d83023 |
- }
|
|
Kmods SIG |
d83023 |
-
|
|
Kmods SIG |
d83023 |
- sb->s_fs_info = sbi;
|
|
Kmods SIG |
d83023 |
sbi->sb = sb;
|
|
Kmods SIG |
d83023 |
sb->s_flags |= SB_NODIRATIME;
|
|
Kmods SIG |
d83023 |
sb->s_magic = 0x7366746e; // "ntfs"
|
|
Kmods SIG |
d83023 |
@@ -949,9 +905,12 @@ static int ntfs_fill_super(struct super_block *sb, void *data, int silent)
|
|
Kmods SIG |
d83023 |
ratelimit_state_init(&sbi->msg_ratelimit, DEFAULT_RATELIMIT_INTERVAL,
|
|
Kmods SIG |
d83023 |
DEFAULT_RATELIMIT_BURST);
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
- err = ntfs_parse_options(sb, data, silent, sbi->options);
|
|
Kmods SIG |
d83023 |
- if (err)
|
|
Kmods SIG |
d83023 |
- goto out;
|
|
Kmods SIG |
d83023 |
+ sbi->options->nls = ntfs_load_nls(sbi->options->nls_name);
|
|
Kmods SIG |
d83023 |
+ if (IS_ERR(sbi->options->nls)) {
|
|
Kmods SIG |
d83023 |
+ sbi->options->nls = NULL;
|
|
Kmods SIG |
d83023 |
+ errorf(fc, "Cannot load nls %s", sbi->options->nls_name);
|
|
Kmods SIG |
d83023 |
+ return -EINVAL;
|
|
Kmods SIG |
d83023 |
+ }
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
if (!rq || !blk_queue_discard(rq) || !rq->limits.discard_granularity) {
|
|
Kmods SIG |
d83023 |
;
|
|
Kmods SIG |
d83023 |
@@ -1344,6 +1303,9 @@ static int ntfs_fill_super(struct super_block *sb, void *data, int silent)
|
|
Kmods SIG |
d83023 |
goto out;
|
|
Kmods SIG |
d83023 |
}
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
+ fc->fs_private = NULL;
|
|
Kmods SIG |
d83023 |
+ fc->s_fs_info = NULL;
|
|
Kmods SIG |
d83023 |
+
|
|
Kmods SIG |
d83023 |
return 0;
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
out:
|
|
Kmods SIG |
d83023 |
@@ -1354,9 +1316,6 @@ static int ntfs_fill_super(struct super_block *sb, void *data, int silent)
|
|
Kmods SIG |
d83023 |
sb->s_root = NULL;
|
|
Kmods SIG |
d83023 |
}
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
- put_ntfs(sbi);
|
|
Kmods SIG |
d83023 |
-
|
|
Kmods SIG |
d83023 |
- sb->s_fs_info = NULL;
|
|
Kmods SIG |
d83023 |
return err;
|
|
Kmods SIG |
d83023 |
}
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
@@ -1426,19 +1385,83 @@ int ntfs_discard(struct ntfs_sb_info *sbi, CLST lcn, CLST len)
|
|
Kmods SIG |
d83023 |
return err;
|
|
Kmods SIG |
d83023 |
}
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
-static struct dentry *ntfs_mount(struct file_system_type *fs_type, int flags,
|
|
Kmods SIG |
d83023 |
- const char *dev_name, void *data)
|
|
Kmods SIG |
d83023 |
+static int ntfs_fs_get_tree(struct fs_context *fc)
|
|
Kmods SIG |
d83023 |
+{
|
|
Kmods SIG |
d83023 |
+ return get_tree_bdev(fc, ntfs_fill_super);
|
|
Kmods SIG |
d83023 |
+}
|
|
Kmods SIG |
d83023 |
+
|
|
Kmods SIG |
d83023 |
+/*
|
|
Kmods SIG |
d83023 |
+ * ntfs_fs_free - Free fs_context.
|
|
Kmods SIG |
d83023 |
+ *
|
|
Kmods SIG |
d83023 |
+ * Note that this will be called after fill_super and reconfigure
|
|
Kmods SIG |
d83023 |
+ * even when they pass. So they have to take pointers if they pass.
|
|
Kmods SIG |
d83023 |
+ */
|
|
Kmods SIG |
d83023 |
+static void ntfs_fs_free(struct fs_context *fc)
|
|
Kmods SIG |
d83023 |
+{
|
|
Kmods SIG |
d83023 |
+ struct ntfs_mount_options *opts = fc->fs_private;
|
|
Kmods SIG |
d83023 |
+ struct ntfs_sb_info *sbi = fc->s_fs_info;
|
|
Kmods SIG |
d83023 |
+
|
|
Kmods SIG |
d83023 |
+ if (sbi)
|
|
Kmods SIG |
d83023 |
+ put_ntfs(sbi);
|
|
Kmods SIG |
d83023 |
+
|
|
Kmods SIG |
d83023 |
+ if (opts)
|
|
Kmods SIG |
d83023 |
+ put_mount_options(opts);
|
|
Kmods SIG |
d83023 |
+}
|
|
Kmods SIG |
d83023 |
+
|
|
Kmods SIG |
d83023 |
+static const struct fs_context_operations ntfs_context_ops = {
|
|
Kmods SIG |
d83023 |
+ .parse_param = ntfs_fs_parse_param,
|
|
Kmods SIG |
d83023 |
+ .get_tree = ntfs_fs_get_tree,
|
|
Kmods SIG |
d83023 |
+ .reconfigure = ntfs_fs_reconfigure,
|
|
Kmods SIG |
d83023 |
+ .free = ntfs_fs_free,
|
|
Kmods SIG |
d83023 |
+};
|
|
Kmods SIG |
d83023 |
+
|
|
Kmods SIG |
d83023 |
+/*
|
|
Kmods SIG |
d83023 |
+ * ntfs_init_fs_context - Initialize spi and opts
|
|
Kmods SIG |
d83023 |
+ *
|
|
Kmods SIG |
d83023 |
+ * This will called when mount/remount. We will first initiliaze
|
|
Kmods SIG |
d83023 |
+ * options so that if remount we can use just that.
|
|
Kmods SIG |
d83023 |
+ */
|
|
Kmods SIG |
d83023 |
+static int ntfs_init_fs_context(struct fs_context *fc)
|
|
Kmods SIG |
d83023 |
{
|
|
Kmods SIG |
d83023 |
- return mount_bdev(fs_type, flags, dev_name, data, ntfs_fill_super);
|
|
Kmods SIG |
d83023 |
+ struct ntfs_mount_options *opts;
|
|
Kmods SIG |
d83023 |
+ struct ntfs_sb_info *sbi;
|
|
Kmods SIG |
d83023 |
+
|
|
Kmods SIG |
d83023 |
+ opts = kzalloc(sizeof(struct ntfs_mount_options), GFP_NOFS);
|
|
Kmods SIG |
d83023 |
+ if (!opts)
|
|
Kmods SIG |
d83023 |
+ return -ENOMEM;
|
|
Kmods SIG |
d83023 |
+
|
|
Kmods SIG |
d83023 |
+ /* Default options. */
|
|
Kmods SIG |
d83023 |
+ opts->fs_uid = current_uid();
|
|
Kmods SIG |
d83023 |
+ opts->fs_gid = current_gid();
|
|
Kmods SIG |
d83023 |
+ opts->fs_fmask_inv = ~current_umask();
|
|
Kmods SIG |
d83023 |
+ opts->fs_dmask_inv = ~current_umask();
|
|
Kmods SIG |
d83023 |
+
|
|
Kmods SIG |
d83023 |
+ if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE)
|
|
Kmods SIG |
d83023 |
+ goto ok;
|
|
Kmods SIG |
d83023 |
+
|
|
Kmods SIG |
d83023 |
+ sbi = kzalloc(sizeof(struct ntfs_sb_info), GFP_NOFS);
|
|
Kmods SIG |
d83023 |
+ if (!sbi) {
|
|
Kmods SIG |
d83023 |
+ kfree(opts);
|
|
Kmods SIG |
d83023 |
+ return -ENOMEM;
|
|
Kmods SIG |
d83023 |
+ }
|
|
Kmods SIG |
d83023 |
+
|
|
Kmods SIG |
d83023 |
+ sbi->options = opts;
|
|
Kmods SIG |
d83023 |
+ fc->s_fs_info = sbi;
|
|
Kmods SIG |
d83023 |
+ok:
|
|
Kmods SIG |
d83023 |
+ fc->fs_private = opts;
|
|
Kmods SIG |
d83023 |
+ fc->ops = &ntfs_context_ops;
|
|
Kmods SIG |
d83023 |
+
|
|
Kmods SIG |
d83023 |
+ return 0;
|
|
Kmods SIG |
d83023 |
}
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
// clang-format off
|
|
Kmods SIG |
d83023 |
static struct file_system_type ntfs_fs_type = {
|
|
Kmods SIG |
d83023 |
- .owner = THIS_MODULE,
|
|
Kmods SIG |
d83023 |
- .name = "ntfs3",
|
|
Kmods SIG |
d83023 |
- .mount = ntfs_mount,
|
|
Kmods SIG |
d83023 |
- .kill_sb = kill_block_super,
|
|
Kmods SIG |
d83023 |
- .fs_flags = FS_REQUIRES_DEV | FS_ALLOW_IDMAP,
|
|
Kmods SIG |
d83023 |
+ .owner = THIS_MODULE,
|
|
Kmods SIG |
d83023 |
+ .name = "ntfs3",
|
|
Kmods SIG |
d83023 |
+ .init_fs_context = ntfs_init_fs_context,
|
|
Kmods SIG |
d83023 |
+ .parameters = ntfs_fs_parameters,
|
|
Kmods SIG |
d83023 |
+ .kill_sb = kill_block_super,
|
|
Kmods SIG |
d83023 |
+ .fs_flags = FS_REQUIRES_DEV | FS_ALLOW_IDMAP,
|
|
Kmods SIG |
d83023 |
};
|
|
Kmods SIG |
d83023 |
// clang-format on
|
|
Kmods SIG |
d83023 |
|
|
Kmods SIG |
d83023 |
--
|
|
Kmods SIG |
d83023 |
2.31.1
|
|
Kmods SIG |
d83023 |
|