aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2006-09-21 03:02:52 -0400
committerSteve French <sfrench@us.ibm.com>2006-09-21 03:02:52 -0400
commit2fe87f02a04ad6e7075023a87fe38eb458a4bb9d (patch)
treeec095fecdccad724faa6560cf7a81a9494a5a093 /fs/cifs/connect.c
parentb835bebe95608c81270636a78b70333afb011925 (diff)
[CIFS] Support deep tree mounts (e.g. mounts to //server/share/path)
Samba bugzilla #4040 Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 5d394c726860..0e9ba0b9d71e 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -89,6 +89,7 @@ struct smb_vol {
89 unsigned int wsize; 89 unsigned int wsize;
90 unsigned int sockopt; 90 unsigned int sockopt;
91 unsigned short int port; 91 unsigned short int port;
92 char * prepath;
92}; 93};
93 94
94static int ipv4_connect(struct sockaddr_in *psin_server, 95static int ipv4_connect(struct sockaddr_in *psin_server,
@@ -993,6 +994,28 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
993 printk(KERN_WARNING "CIFS: domain name too long\n"); 994 printk(KERN_WARNING "CIFS: domain name too long\n");
994 return 1; 995 return 1;
995 } 996 }
997 } else if (strnicmp(data, "prefixpath", 10) == 0) {
998 if (!value || !*value) {
999 printk(KERN_WARNING
1000 "CIFS: invalid path prefix\n");
1001 return 1; /* needs_arg; */
1002 }
1003 if ((temp_len = strnlen(value, 1024)) < 1024) {
1004 if(value[0] != '/')
1005 temp_len++; /* missing leading slash */
1006 vol->prepath = kmalloc(temp_len+1,GFP_KERNEL);
1007 if(vol->prepath == NULL)
1008 return 1;
1009 if(value[0] != '/') {
1010 vol->prepath[0] = '/';
1011 strcpy(vol->prepath+1,value);
1012 } else
1013 strcpy(vol->prepath,value);
1014 cFYI(1,("prefix path %s",vol->prepath));
1015 } else {
1016 printk(KERN_WARNING "CIFS: prefix too long\n");
1017 return 1;
1018 }
996 } else if (strnicmp(data, "iocharset", 9) == 0) { 1019 } else if (strnicmp(data, "iocharset", 9) == 0) {
997 if (!value || !*value) { 1020 if (!value || !*value) {
998 printk(KERN_WARNING "CIFS: invalid iocharset specified\n"); 1021 printk(KERN_WARNING "CIFS: invalid iocharset specified\n");
@@ -1605,6 +1628,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1605 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) { 1628 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
1606 kfree(volume_info.UNC); 1629 kfree(volume_info.UNC);
1607 kfree(volume_info.password); 1630 kfree(volume_info.password);
1631 kfree(volume_info.prepath);
1608 FreeXid(xid); 1632 FreeXid(xid);
1609 return -EINVAL; 1633 return -EINVAL;
1610 } 1634 }
@@ -1619,6 +1643,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1619 locations such as env variables and files on disk */ 1643 locations such as env variables and files on disk */
1620 kfree(volume_info.UNC); 1644 kfree(volume_info.UNC);
1621 kfree(volume_info.password); 1645 kfree(volume_info.password);
1646 kfree(volume_info.prepath);
1622 FreeXid(xid); 1647 FreeXid(xid);
1623 return -EINVAL; 1648 return -EINVAL;
1624 } 1649 }
@@ -1639,6 +1664,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1639 /* we failed translating address */ 1664 /* we failed translating address */
1640 kfree(volume_info.UNC); 1665 kfree(volume_info.UNC);
1641 kfree(volume_info.password); 1666 kfree(volume_info.password);
1667 kfree(volume_info.prepath);
1642 FreeXid(xid); 1668 FreeXid(xid);
1643 return -EINVAL; 1669 return -EINVAL;
1644 } 1670 }
@@ -1651,6 +1677,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1651 cERROR(1,("Connecting to DFS root not implemented yet")); 1677 cERROR(1,("Connecting to DFS root not implemented yet"));
1652 kfree(volume_info.UNC); 1678 kfree(volume_info.UNC);
1653 kfree(volume_info.password); 1679 kfree(volume_info.password);
1680 kfree(volume_info.prepath);
1654 FreeXid(xid); 1681 FreeXid(xid);
1655 return -EINVAL; 1682 return -EINVAL;
1656 } else /* which servers DFS root would we conect to */ { 1683 } else /* which servers DFS root would we conect to */ {
@@ -1658,6 +1685,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1658 ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified")); 1685 ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified"));
1659 kfree(volume_info.UNC); 1686 kfree(volume_info.UNC);
1660 kfree(volume_info.password); 1687 kfree(volume_info.password);
1688 kfree(volume_info.prepath);
1661 FreeXid(xid); 1689 FreeXid(xid);
1662 return -EINVAL; 1690 return -EINVAL;
1663 } 1691 }
@@ -1672,6 +1700,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1672 cERROR(1,("CIFS mount error: iocharset %s not found",volume_info.iocharset)); 1700 cERROR(1,("CIFS mount error: iocharset %s not found",volume_info.iocharset));
1673 kfree(volume_info.UNC); 1701 kfree(volume_info.UNC);
1674 kfree(volume_info.password); 1702 kfree(volume_info.password);
1703 kfree(volume_info.prepath);
1675 FreeXid(xid); 1704 FreeXid(xid);
1676 return -ELIBACC; 1705 return -ELIBACC;
1677 } 1706 }
@@ -1688,6 +1717,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1688 else { 1717 else {
1689 kfree(volume_info.UNC); 1718 kfree(volume_info.UNC);
1690 kfree(volume_info.password); 1719 kfree(volume_info.password);
1720 kfree(volume_info.prepath);
1691 FreeXid(xid); 1721 FreeXid(xid);
1692 return -EINVAL; 1722 return -EINVAL;
1693 } 1723 }
@@ -1710,6 +1740,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1710 sock_release(csocket); 1740 sock_release(csocket);
1711 kfree(volume_info.UNC); 1741 kfree(volume_info.UNC);
1712 kfree(volume_info.password); 1742 kfree(volume_info.password);
1743 kfree(volume_info.prepath);
1713 FreeXid(xid); 1744 FreeXid(xid);
1714 return rc; 1745 return rc;
1715 } 1746 }
@@ -1720,6 +1751,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1720 sock_release(csocket); 1751 sock_release(csocket);
1721 kfree(volume_info.UNC); 1752 kfree(volume_info.UNC);
1722 kfree(volume_info.password); 1753 kfree(volume_info.password);
1754 kfree(volume_info.prepath);
1723 FreeXid(xid); 1755 FreeXid(xid);
1724 return rc; 1756 return rc;
1725 } else { 1757 } else {
@@ -1744,6 +1776,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1744 sock_release(csocket); 1776 sock_release(csocket);
1745 kfree(volume_info.UNC); 1777 kfree(volume_info.UNC);
1746 kfree(volume_info.password); 1778 kfree(volume_info.password);
1779 kfree(volume_info.prepath);
1747 FreeXid(xid); 1780 FreeXid(xid);
1748 return rc; 1781 return rc;
1749 } 1782 }
@@ -1831,6 +1864,14 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1831 /* Windows ME may prefer this */ 1864 /* Windows ME may prefer this */
1832 cFYI(1,("readsize set to minimum 2048")); 1865 cFYI(1,("readsize set to minimum 2048"));
1833 } 1866 }
1867 /* calculate prepath */
1868 cifs_sb->prepath = volume_info.prepath;
1869 if(cifs_sb->prepath) {
1870 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
1871 cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb);
1872 volume_info.prepath = NULL;
1873 } else
1874 cifs_sb->prepathlen = 0;
1834 cifs_sb->mnt_uid = volume_info.linux_uid; 1875 cifs_sb->mnt_uid = volume_info.linux_uid;
1835 cifs_sb->mnt_gid = volume_info.linux_gid; 1876 cifs_sb->mnt_gid = volume_info.linux_gid;
1836 cifs_sb->mnt_file_mode = volume_info.file_mode; 1877 cifs_sb->mnt_file_mode = volume_info.file_mode;
@@ -2008,6 +2049,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2008 the password ptr is put in the new session structure (in which case the 2049 the password ptr is put in the new session structure (in which case the
2009 password will be freed at unmount time) */ 2050 password will be freed at unmount time) */
2010 kfree(volume_info.UNC); 2051 kfree(volume_info.UNC);
2052 kfree(volume_info.prepath);
2011 FreeXid(xid); 2053 FreeXid(xid);
2012 return rc; 2054 return rc;
2013} 2055}
@@ -3195,6 +3237,7 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3195 int xid; 3237 int xid;
3196 struct cifsSesInfo *ses = NULL; 3238 struct cifsSesInfo *ses = NULL;
3197 struct task_struct *cifsd_task; 3239 struct task_struct *cifsd_task;
3240 char * tmp;
3198 3241
3199 xid = GetXid(); 3242 xid = GetXid();
3200 3243
@@ -3228,6 +3271,10 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3228 } 3271 }
3229 3272
3230 cifs_sb->tcon = NULL; 3273 cifs_sb->tcon = NULL;
3274 tmp = cifs_sb->prepath;
3275 cifs_sb->prepathlen = 0;
3276 cifs_sb->prepath = NULL;
3277 kfree(tmp);
3231 if (ses) 3278 if (ses)
3232 schedule_timeout_interruptible(msecs_to_jiffies(500)); 3279 schedule_timeout_interruptible(msecs_to_jiffies(500));
3233 if (ses) 3280 if (ses)