Re: dfs path construction fix - send dfs paths on all path based operations on share in dfs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Steve French wrote:
> Samba was not handling paths without the \\server\share prefix (which
> our current code sends on QueryPathInfo) when "SHARE_IN_DFS" on
> operations such as rmdir and delete.
> 
> This patch fixes that:

A set of patches that fixes path handling (broken by 646dd539878a194) 
in the DFS related parts of code in accordance with
a new 'build_path_from_dentry' behavior.


-- 

Best regards,

-------------------------
Igor Mammedov,
niallain "at" gmail.com




>From b5a37238de56db6a99db746b169fe3deba27b510 Mon Sep 17 00:00:00 2001
From: Igor Mammedov <niallain@xxxxxxxxx>
Date: Fri, 16 May 2008 13:10:32 +0400
Subject: [PATCH] Fixed DFS code to work with new 'build_path_from_dentry', that returns
 full path if share in the dfs, now.

Signed-off-by: Igor Mammedov <niallain@xxxxxxxxx>
---
 fs/cifs/cifs_dfs_ref.c |   49 +-----------------------------------------------
 1 files changed, 1 insertions(+), 48 deletions(-)

diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index f6fdecf..d82374c 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -219,53 +219,6 @@ static struct vfsmount *cifs_dfs_do_refmount(const struct vfsmount *mnt_parent,
 
 }
 
-static char *build_full_dfs_path_from_dentry(struct dentry *dentry)
-{
-	char *full_path = NULL;
-	char *search_path;
-	char *tmp_path;
-	size_t l_max_len;
-	struct cifs_sb_info *cifs_sb;
-
-	if (dentry->d_inode == NULL)
-		return NULL;
-
-	cifs_sb = CIFS_SB(dentry->d_inode->i_sb);
-
-	if (cifs_sb->tcon == NULL)
-		return NULL;
-
-	search_path = build_path_from_dentry(dentry);
-	if (search_path == NULL)
-		return NULL;
-
-	if (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS) {
-		int i;
-		/* we should use full path name for correct working with DFS */
-		l_max_len = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE+1) +
-					strnlen(search_path, MAX_PATHCONF) + 1;
-		tmp_path = kmalloc(l_max_len, GFP_KERNEL);
-		if (tmp_path == NULL) {
-			kfree(search_path);
-			return NULL;
-		}
-		strncpy(tmp_path, cifs_sb->tcon->treeName, l_max_len);
-		tmp_path[l_max_len-1] = 0;
-		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
-			for (i = 0; i < l_max_len; i++) {
-				if (tmp_path[i] == '\\')
-					tmp_path[i] = '/';
-			}
-		strncat(tmp_path, search_path, l_max_len - strlen(tmp_path));
-
-		full_path = tmp_path;
-		kfree(search_path);
-	} else {
-		full_path = search_path;
-	}
-	return full_path;
-}
-
 static int add_mount_helper(struct vfsmount *newmnt, struct nameidata *nd,
 				struct list_head *mntlist)
 {
@@ -333,7 +286,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
 		goto out_err;
 	}
 
-	full_path = build_full_dfs_path_from_dentry(dentry);
+	full_path = build_path_from_dentry(dentry);
 	if (full_path == NULL) {
 		rc = -ENOMEM;
 		goto out_err;
-- 
1.5.3.7

>From fd33ede1ca0b157ecf26711bdf12c2b15336e0cd Mon Sep 17 00:00:00 2001
From: Igor Mammedov <niallain@xxxxxxxxx>
Date: Fri, 16 May 2008 13:24:59 +0400
Subject: [PATCH] Fixed inode lookup code (DFS related part) to support
 new build_path_from_dentry behaviour.

Signed-off-by: Igor Mammedov <niallain@xxxxxxxxx>
---
 fs/cifs/inode.c |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 9d9b56a..c7c5242 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -184,6 +184,9 @@ try_again_CIFSSMBUnixQPathInfo:
 	if (rc) {
 		if (rc == -EREMOTE && !is_dfs_referral) {
 			is_dfs_referral = true;
+			full_path = strchr(full_path + 2, '/');
+			full_path++;
+			full_path = strchr(full_path + 2, '/');
 			goto try_again_CIFSSMBUnixQPathInfo;
 		}
 		goto cgiiu_exit;
@@ -230,6 +233,11 @@ try_again_CIFSSMBUnixQPathInfo:
 			(unsigned long) inode->i_size,
 			(unsigned long long)inode->i_blocks));
 
+		if (is_dfs_referral && ((inode->i_mode & S_IFMT) == S_IFLNK)) {
+			inode->i_mode &= ~S_IFLNK;
+			inode->i_mode |= S_IFDIR;
+		}
+
 		cifs_set_ops(inode, is_dfs_referral);
 	}
 cgiiu_exit:
@@ -389,6 +397,9 @@ try_again_CIFSSMBQPathInfo:
 	if (rc) {
 		if (rc == -EREMOTE && !is_dfs_referral) {
 			is_dfs_referral = true;
+			full_path = strchr(full_path + 2, '\\');
+			full_path++;
+			full_path = strchr(full_path + 2, '\\');
 			goto try_again_CIFSSMBQPathInfo;
 		}
 		goto cgii_exit;
-- 
1.5.3.7


[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux