mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	smb: client: get rid of dfs code dep in namespace.c
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>
This commit is contained in:
		
							parent
							
								
									0a049935e4
								
							
						
					
					
						commit
						348a04a8d1
					
				
					 7 changed files with 57 additions and 72 deletions
				
			
		| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 *,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -263,12 +263,28 @@ static int __dfs_mount_share(struct cifs_mount_ctx *mnt_ctx)
 | 
			
		|||
	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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
 | 
			
		||||
	rc = dns_resolve_server_name_to_ip(ctx->source, addr, NULL);
 | 
			
		||||
	if (!rc)
 | 
			
		||||
		cifs_set_port(addr, ctx->port);
 | 
			
		||||
	return rc;
 | 
			
		||||
	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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue