aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2008-02-14 01:38:30 -0500
committerSteve French <sfrench@us.ibm.com>2008-02-14 01:38:30 -0500
commit03a143c909b808759f188a45c75acb8f043cb209 (patch)
treec530f351a3bff2997b68009bec280c92eb7098c7
parentc1ce264470f000ccd5965d3718f7d905d559fd64 (diff)
[CIFS] fixup prefixpaths which contain multiple path components
Currently, when we get a prefixpath as part of mount, the kernel only changes the first character to be a '/' or '\' depending on whether posix extensions are enabled. This is problematic as it expects mount.cifs to pass in the correct delimiter in the rest of the prefixpath. But, mount.cifs may not know *what* the correct delimiter is. It's a chicken and egg problem. Note that mount.cifs should not do conversion of the prefixpath - if we want posix behavior then '\' is legal in a path (and we have had bugs in the distant path to prove to me that customers sometimes have apps that require '\'). The kernel code assumes that the path passed in is posix (and current code will handle the first path component fine but was broken for Windows mounts for "deep" prefixpaths unless the user specified a prefixpath with '\' deep in it. So e.g. with current kernel code: 1) mount to //server/share/dir1 will work to all server types 2) mount to //server/share/dir1/subdir1 will work to Samba 3) mount to //server/share/dir1\\subdir1 will work to Windows But case two would fail to Windows without the fix. With the kernel cifs module fix case two now works. First analyzed by Jeff Layton and Simo Sorce CC: Jeff Layton <jlayton@redhat.com> CC: Simo Sorce <simo@samba.org> Signed-off-by: Steve French <sfrench@us.ibm.com>
-rw-r--r--fs/cifs/CHANGES4
-rw-r--r--fs/cifs/connect.c23
2 files changed, 25 insertions, 2 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index edd248367b36..dbd91461853c 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -6,7 +6,9 @@ and sync so that events like out of disk space get reported properly on
6cached files. Fix setxattr failure to certain Samba versions. Fix mount 6cached files. Fix setxattr failure to certain Samba versions. Fix mount
7of second share to disconnected server session (autoreconnect on this). 7of second share to disconnected server session (autoreconnect on this).
8Add ability to modify cifs acls for handling chmod (when mounted with 8Add ability to modify cifs acls for handling chmod (when mounted with
9cifsacl flag). 9cifsacl flag). Fix prefixpath path separator so we can handle mounts
10with prefixpaths longer than one directory (one path component) when
11mounted to Windows servers.
10 12
11Version 1.51 13Version 1.51
12------------ 14------------
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 5ccd8b710cc5..e111c69139b7 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1791,6 +1791,20 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
1791 } 1791 }
1792} 1792}
1793 1793
1794static void
1795convert_delimiter(char *path, char delim)
1796{
1797 int i;
1798
1799 if (path == NULL)
1800 return;
1801
1802 for (i = 0; path[i] != '\0'; i++) {
1803 if ((path[i] == '/') || (path[i] == '\\'))
1804 path[i] = delim;
1805 }
1806}
1807
1794int 1808int
1795cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, 1809cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1796 char *mount_data, const char *devname) 1810 char *mount_data, const char *devname)
@@ -2056,7 +2070,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2056 cifs_sb->prepath = volume_info.prepath; 2070 cifs_sb->prepath = volume_info.prepath;
2057 if (cifs_sb->prepath) { 2071 if (cifs_sb->prepath) {
2058 cifs_sb->prepathlen = strlen(cifs_sb->prepath); 2072 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
2059 cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb); 2073 /* we can not convert the / to \ in the path
2074 separators in the prefixpath yet because we do not
2075 know (until reset_cifs_unix_caps is called later)
2076 whether POSIX PATH CAP is available. We normalize
2077 the / to \ after reset_cifs_unix_caps is called */
2060 volume_info.prepath = NULL; 2078 volume_info.prepath = NULL;
2061 } else 2079 } else
2062 cifs_sb->prepathlen = 0; 2080 cifs_sb->prepathlen = 0;
@@ -2224,6 +2242,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2224 else 2242 else
2225 tcon->unix_ext = 0; /* server does not support them */ 2243 tcon->unix_ext = 0; /* server does not support them */
2226 2244
2245 /* convert forward to back slashes in prepath here if needed */
2246 convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb));
2247
2227 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) { 2248 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2228 cifs_sb->rsize = 1024 * 127; 2249 cifs_sb->rsize = 1024 * 127;
2229 cFYI(DBG2, 2250 cFYI(DBG2,