smb: client: get rid of dfs code dep in namespace.c
authorPaulo Alcantara <pc@manguebit.com>
Thu, 17 Aug 2023 15:34:05 +0000 (12:34 -0300)
committerSteve French <stfrench@microsoft.com>
Sun, 20 Aug 2023 21:05:50 +0000 (16:05 -0500)
Make namespace.c being built without requiring
CONFIG_CIFS_DFS_UPCALL=y by moving set_dest_addr() to dfs.c and call
it at the beginning of dfs_mount_share() so it can chase the DFS link
starting from the correct server in @ctx->dstaddr.

Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/Makefile
fs/smb/client/cifsfs.h
fs/smb/client/cifsproto.h
fs/smb/client/dfs.c
fs/smb/client/dfs.h
fs/smb/client/inode.c
fs/smb/client/namespace.c

index 851e6ba..0b07eb9 100644 (file)
@@ -11,7 +11,8 @@ cifs-y := trace.o cifsfs.o cifs_debug.o connect.o dir.o file.o \
          readdir.o ioctl.o sess.o export.o unc.o winucase.o \
          smb2ops.o smb2maperror.o smb2transport.o \
          smb2misc.o smb2pdu.o smb2inode.o smb2file.o cifsacl.o fs_context.o \
-         dns_resolve.o cifs_spnego_negtokeninit.asn1.o asn1.o
+         dns_resolve.o cifs_spnego_negtokeninit.asn1.o asn1.o \
+         namespace.o
 
 $(obj)/asn1.o: $(obj)/cifs_spnego_negtokeninit.asn1.h
 
@@ -21,7 +22,7 @@ cifs-$(CONFIG_CIFS_XATTR) += xattr.o
 
 cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o
 
-cifs-$(CONFIG_CIFS_DFS_UPCALL) += namespace.o dfs_cache.o dfs.o
+cifs-$(CONFIG_CIFS_DFS_UPCALL) += dfs_cache.o dfs.o
 
 cifs-$(CONFIG_CIFS_SWN_UPCALL) += netlink.o cifs_swn.o
 
index 9907597..532c38f 100644 (file)
@@ -118,14 +118,7 @@ extern void cifs_pages_write_redirty(struct inode *inode, loff_t start, unsigned
 extern const struct dentry_operations cifs_dentry_ops;
 extern const struct dentry_operations cifs_ci_dentry_ops;
 
-#ifdef CONFIG_CIFS_DFS_UPCALL
 extern struct vfsmount *cifs_d_automount(struct path *path);
-#else
-static inline struct vfsmount *cifs_d_automount(struct path *path)
-{
-       return ERR_PTR(-EREMOTE);
-}
-#endif
 
 /* Functions related to symlinks */
 extern const char *cifs_get_link(struct dentry *, struct inode *,
index c7a7484..694d16a 100644 (file)
@@ -295,11 +295,7 @@ extern void cifs_put_tcp_session(struct TCP_Server_Info *server,
                                 int from_reconnect);
 extern void cifs_put_tcon(struct cifs_tcon *tcon);
 
-#if IS_ENABLED(CONFIG_CIFS_DFS_UPCALL)
 extern void cifs_release_automount_timer(void);
-#else /* ! IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) */
-#define cifs_release_automount_timer() do { } while (0)
-#endif /* ! IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) */
 
 void cifs_proc_init(void);
 void cifs_proc_clean(void);
index 71ee740..81b8415 100644 (file)
@@ -263,12 +263,28 @@ out:
        return rc;
 }
 
+/* Resolve UNC hostname in @ctx->source and set ip addr in @ctx->dstaddr */
+static int update_fs_context_dstaddr(struct smb3_fs_context *ctx)
+{
+       struct sockaddr *addr = (struct sockaddr *)&ctx->dstaddr;
+       int rc;
+
+       rc = dns_resolve_server_name_to_ip(ctx->source, addr, NULL);
+       if (!rc)
+               cifs_set_port(addr, ctx->port);
+       return rc;
+}
+
 int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx, bool *isdfs)
 {
        struct smb3_fs_context *ctx = mnt_ctx->fs_ctx;
        bool nodfs = ctx->nodfs;
        int rc;
 
+       rc = update_fs_context_dstaddr(ctx);
+       if (rc)
+               return rc;
+
        *isdfs = false;
        rc = get_session(mnt_ctx, NULL);
        if (rc)
index c0a9eea..875ab7a 100644 (file)
@@ -138,43 +138,6 @@ static inline int dfs_get_referral(struct cifs_mount_ctx *mnt_ctx, const char *p
                              cifs_remap(cifs_sb), path, ref, tl);
 }
 
-/* Return DFS full path out of a dentry set for automount */
-static inline char *dfs_get_automount_devname(struct dentry *dentry, void *page)
-{
-       struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
-       struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
-       size_t len;
-       char *s;
-
-       spin_lock(&tcon->tc_lock);
-       if (unlikely(!tcon->origin_fullpath)) {
-               spin_unlock(&tcon->tc_lock);
-               return ERR_PTR(-EREMOTE);
-       }
-       spin_unlock(&tcon->tc_lock);
-
-       s = dentry_path_raw(dentry, page, PATH_MAX);
-       if (IS_ERR(s))
-               return s;
-       /* for root, we want "" */
-       if (!s[1])
-               s++;
-
-       spin_lock(&tcon->tc_lock);
-       len = strlen(tcon->origin_fullpath);
-       if (s < (char *)page + len) {
-               spin_unlock(&tcon->tc_lock);
-               return ERR_PTR(-ENAMETOOLONG);
-       }
-
-       s -= len;
-       memcpy(s, tcon->origin_fullpath, len);
-       spin_unlock(&tcon->tc_lock);
-       convert_delimiter(s, '/');
-
-       return s;
-}
-
 static inline void dfs_put_root_smb_sessions(struct list_head *head)
 {
        struct dfs_root_ses *root, *tmp;
index 0d4a785..da2ec48 100644 (file)
@@ -58,13 +58,9 @@ static void cifs_set_ops(struct inode *inode)
                        inode->i_data.a_ops = &cifs_addr_ops;
                break;
        case S_IFDIR:
-#ifdef CONFIG_CIFS_DFS_UPCALL
                if (IS_AUTOMOUNT(inode)) {
                        inode->i_op = &cifs_namespace_inode_operations;
                } else {
-#else /* NO DFS support, treat as a directory */
-               {
-#endif
                        inode->i_op = &cifs_dir_inode_ops;
                        inode->i_fop = &cifs_dir_ops;
                }
index af64f2a..3252fe3 100644 (file)
@@ -6,6 +6,7 @@
  *   Copyright (C) International Business Machines  Corp., 2008
  *   Author(s): Igor Mammedov (niallain@gmail.com)
  *             Steve French (sfrench@us.ibm.com)
+ *   Copyright (c) 2023 Paulo Alcantara <palcantara@suse.de>
  */
 
 #include <linux/dcache.h>
@@ -18,9 +19,7 @@
 #include "cifsglob.h"
 #include "cifsproto.h"
 #include "cifsfs.h"
-#include "dns_resolve.h"
 #include "cifs_debug.h"
-#include "dfs.h"
 #include "fs_context.h"
 
 static LIST_HEAD(cifs_automount_list);
@@ -118,15 +117,41 @@ cifs_build_devname(char *nodename, const char *prepath)
        return dev;
 }
 
-static int set_dest_addr(struct smb3_fs_context *ctx)
+/* Return full path out of a dentry set for automount */
+static char *automount_fullpath(struct dentry *dentry, void *page)
 {
-       struct sockaddr *addr = (struct sockaddr *)&ctx->dstaddr;
-       int rc;
+       struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
+       struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
+       size_t len;
+       char *s;
+
+       spin_lock(&tcon->tc_lock);
+       if (unlikely(!tcon->origin_fullpath)) {
+               spin_unlock(&tcon->tc_lock);
+               return ERR_PTR(-EREMOTE);
+       }
+       spin_unlock(&tcon->tc_lock);
+
+       s = dentry_path_raw(dentry, page, PATH_MAX);
+       if (IS_ERR(s))
+               return s;
+       /* for root, we want "" */
+       if (!s[1])
+               s++;
+
+       spin_lock(&tcon->tc_lock);
+       len = strlen(tcon->origin_fullpath);
+       if (s < (char *)page + len) {
+               spin_unlock(&tcon->tc_lock);
+               return ERR_PTR(-ENAMETOOLONG);
+       }
 
-       rc = dns_resolve_server_name_to_ip(ctx->source, addr, NULL);
-       if (!rc)
-               cifs_set_port(addr, ctx->port);
-       return rc;
+       s -= len;
+       memcpy(s, tcon->origin_fullpath, len);
+       spin_unlock(&tcon->tc_lock);
+       convert_delimiter(s, '/');
+
+       return s;
 }
 
 /*
@@ -166,7 +191,7 @@ static struct vfsmount *cifs_do_automount(struct path *path)
        ctx = smb3_fc2context(fc);
 
        page = alloc_dentry_path();
-       full_path = dfs_get_automount_devname(mntpt, page);
+       full_path = automount_fullpath(mntpt, page);
        if (IS_ERR(full_path)) {
                mnt = ERR_CAST(full_path);
                goto out;
@@ -196,15 +221,10 @@ static struct vfsmount *cifs_do_automount(struct path *path)
                ctx->source = NULL;
                goto out;
        }
-       cifs_dbg(FYI, "%s: ctx: source=%s UNC=%s prepath=%s dstaddr=%pISpc\n",
-                __func__, ctx->source, ctx->UNC, ctx->prepath, &ctx->dstaddr);
-
-       rc = set_dest_addr(ctx);
-       if (!rc)
-               mnt = fc_mount(fc);
-       else
-               mnt = ERR_PTR(rc);
+       cifs_dbg(FYI, "%s: ctx: source=%s UNC=%s prepath=%s\n",
+                __func__, ctx->source, ctx->UNC, ctx->prepath);
 
+       mnt = fc_mount(fc);
 out:
        put_fs_context(fc);
        free_dentry_path(page);