summaryrefslogtreecommitdiffstats
path: root/fs/cifs/dfs.c
diff options
context:
space:
mode:
authorPaulo Alcantara <pc@cjr.nz>2022-10-04 18:41:27 -0300
committerSteve French <stfrench@microsoft.com>2022-12-19 08:03:11 -0600
commitabdb1742a312388651f04ca04e6e2ec2b0af5288 (patch)
tree9c2bede0e6486973dbd2288af1821e10342428e7 /fs/cifs/dfs.c
parent9fd29a5bae6e8f94b410374099a6fddb253d2d5f (diff)
downloadlinux-abdb1742a312388651f04ca04e6e2ec2b0af5288.tar.bz2
cifs: get rid of mount options string parsing
After switching to filesystem context support, we no longer need to handle mount options string when chasing dfs referrals. Now, we set the new values directly into smb3_fs_context. Start working on a separate source file to handle most dfs related mount functions as connect.c has already became too big. The remaining functions will be moved gradually in follow-up patches. Signed-off-by: Paulo Alcantara (SUSE) <pc@cjr.nz> Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/cifs/dfs.c')
-rw-r--r--fs/cifs/dfs.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/fs/cifs/dfs.c b/fs/cifs/dfs.c
new file mode 100644
index 000000000000..0b15d7e9f818
--- /dev/null
+++ b/fs/cifs/dfs.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 Paulo Alcantara <palcantara@suse.de>
+ */
+
+#include "cifsproto.h"
+#include "cifs_debug.h"
+#include "dns_resolve.h"
+#include "fs_context.h"
+#include "dfs.h"
+
+/* Resolve UNC server name and set destination ip address in fs context */
+static int resolve_unc(const char *path, struct smb3_fs_context *ctx)
+{
+ int rc;
+ char *ip = NULL;
+
+ rc = dns_resolve_server_name_to_ip(path, &ip, NULL);
+ if (rc < 0) {
+ cifs_dbg(FYI, "%s: failed to resolve UNC server name: %d\n", __func__, rc);
+ return rc;
+ }
+
+ if (!cifs_convert_address((struct sockaddr *)&ctx->dstaddr, ip, strlen(ip))) {
+ cifs_dbg(VFS, "%s: could not determinate destination address\n", __func__);
+ rc = -EHOSTUNREACH;
+ } else
+ rc = 0;
+
+ kfree(ip);
+ return rc;
+}
+
+/**
+ * dfs_parse_target_referral - set fs context for dfs target referral
+ *
+ * @full_path: full path in UNC format.
+ * @ref: dfs referral pointer.
+ * @ctx: smb3 fs context pointer.
+ *
+ * Return zero if dfs referral was parsed correctly, otherwise non-zero.
+ */
+int dfs_parse_target_referral(const char *full_path, const struct dfs_info3_param *ref,
+ struct smb3_fs_context *ctx)
+{
+ int rc;
+ const char *prepath = NULL;
+ char *path;
+
+ if (!full_path || !*full_path || !ref || !ctx)
+ return -EINVAL;
+
+ if (WARN_ON_ONCE(!ref->node_name || ref->path_consumed < 0))
+ return -EINVAL;
+
+ if (strlen(full_path) - ref->path_consumed) {
+ prepath = full_path + ref->path_consumed;
+ /* skip initial delimiter */
+ if (*prepath == '/' || *prepath == '\\')
+ prepath++;
+ }
+
+ path = cifs_build_devname(ref->node_name, prepath);
+ if (IS_ERR(path))
+ return PTR_ERR(path);
+
+ rc = smb3_parse_devname(path, ctx);
+ if (rc)
+ goto out;
+
+ rc = resolve_unc(path, ctx);
+
+out:
+ kfree(path);
+ return rc;
+}