diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cifs/CHANGES | 7 | ||||
-rw-r--r-- | fs/cifs/cifs_fs_sb.h | 2 | ||||
-rw-r--r-- | fs/cifs/cifsfs.h | 2 | ||||
-rw-r--r-- | fs/cifs/cifspdu.h | 2 | ||||
-rw-r--r-- | fs/cifs/connect.c | 47 | ||||
-rw-r--r-- | fs/cifs/dir.c | 23 | ||||
-rw-r--r-- | fs/cifs/xattr.c | 2 |
7 files changed, 74 insertions, 11 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 0feb3bd49cb8..1eb9a2ec0a3b 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
@@ -1,3 +1,7 @@ | |||
1 | Version 1.46 | ||
2 | ------------ | ||
3 | Support deep tree mounts. Better support OS/2, Win9x (DOS) time stamps. | ||
4 | |||
1 | Version 1.45 | 5 | Version 1.45 |
2 | ------------ | 6 | ------------ |
3 | Do not time out lockw calls when using posix extensions. Do not | 7 | Do not time out lockw calls when using posix extensions. Do not |
@@ -6,7 +10,8 @@ on requests on other threads. Improve POSIX locking emulation, | |||
6 | (lock cancel now works, and unlock of merged range works even | 10 | (lock cancel now works, and unlock of merged range works even |
7 | to Windows servers now). Fix oops on mount to lanman servers | 11 | to Windows servers now). Fix oops on mount to lanman servers |
8 | (win9x, os/2 etc.) when null password. Do not send listxattr | 12 | (win9x, os/2 etc.) when null password. Do not send listxattr |
9 | (SMB to query all EAs) if nouser_xattr specified. | 13 | (SMB to query all EAs) if nouser_xattr specified. Fix SE Linux |
14 | problem (instantiate inodes/dentries in right order for readdir). | ||
10 | 15 | ||
11 | Version 1.44 | 16 | Version 1.44 |
12 | ------------ | 17 | ------------ |
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index ad58eb0c4d6d..fd1e52ebcee6 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h | |||
@@ -40,5 +40,7 @@ struct cifs_sb_info { | |||
40 | mode_t mnt_file_mode; | 40 | mode_t mnt_file_mode; |
41 | mode_t mnt_dir_mode; | 41 | mode_t mnt_dir_mode; |
42 | int mnt_cifs_flags; | 42 | int mnt_cifs_flags; |
43 | int prepathlen; | ||
44 | char * prepath; | ||
43 | }; | 45 | }; |
44 | #endif /* _CIFS_FS_SB_H */ | 46 | #endif /* _CIFS_FS_SB_H */ |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 39ee8ef3bdeb..bea875d9a46a 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -100,5 +100,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); | |||
100 | extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); | 100 | extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); |
101 | extern int cifs_ioctl (struct inode * inode, struct file * filep, | 101 | extern int cifs_ioctl (struct inode * inode, struct file * filep, |
102 | unsigned int command, unsigned long arg); | 102 | unsigned int command, unsigned long arg); |
103 | #define CIFS_VERSION "1.45" | 103 | #define CIFS_VERSION "1.46" |
104 | #endif /* _CIFSFS_H */ | 104 | #endif /* _CIFSFS_H */ |
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 86239023545b..81df2bf8e75a 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
@@ -1344,6 +1344,7 @@ struct smb_t2_rsp { | |||
1344 | #define SMB_QUERY_ATTR_FLAGS 0x206 /* append,immutable etc. */ | 1344 | #define SMB_QUERY_ATTR_FLAGS 0x206 /* append,immutable etc. */ |
1345 | #define SMB_QUERY_POSIX_PERMISSION 0x207 | 1345 | #define SMB_QUERY_POSIX_PERMISSION 0x207 |
1346 | #define SMB_QUERY_POSIX_LOCK 0x208 | 1346 | #define SMB_QUERY_POSIX_LOCK 0x208 |
1347 | /* #define SMB_POSIX_OPEN 0x209 */ | ||
1347 | #define SMB_QUERY_FILE_INTERNAL_INFO 0x3ee | 1348 | #define SMB_QUERY_FILE_INTERNAL_INFO 0x3ee |
1348 | #define SMB_QUERY_FILE_ACCESS_INFO 0x3f0 | 1349 | #define SMB_QUERY_FILE_ACCESS_INFO 0x3f0 |
1349 | #define SMB_QUERY_FILE_NAME_INFO2 0x3f1 /* 0x30 bytes */ | 1350 | #define SMB_QUERY_FILE_NAME_INFO2 0x3f1 /* 0x30 bytes */ |
@@ -1363,6 +1364,7 @@ struct smb_t2_rsp { | |||
1363 | #define SMB_SET_XATTR 0x205 | 1364 | #define SMB_SET_XATTR 0x205 |
1364 | #define SMB_SET_ATTR_FLAGS 0x206 /* append, immutable etc. */ | 1365 | #define SMB_SET_ATTR_FLAGS 0x206 /* append, immutable etc. */ |
1365 | #define SMB_SET_POSIX_LOCK 0x208 | 1366 | #define SMB_SET_POSIX_LOCK 0x208 |
1367 | #define SMB_POSIX_OPEN 0x209 | ||
1366 | #define SMB_SET_FILE_BASIC_INFO2 0x3ec | 1368 | #define SMB_SET_FILE_BASIC_INFO2 0x3ec |
1367 | #define SMB_SET_FILE_RENAME_INFORMATION 0x3f2 /* BB check if qpathinfo level too */ | 1369 | #define SMB_SET_FILE_RENAME_INFORMATION 0x3f2 /* BB check if qpathinfo level too */ |
1368 | #define SMB_FILE_ALL_INFO2 0x3fa | 1370 | #define SMB_FILE_ALL_INFO2 0x3fa |
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 | ||
94 | static int ipv4_connect(struct sockaddr_in *psin_server, | 95 | static 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) |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 914239d53634..66b825ade3e1 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -46,7 +46,8 @@ char * | |||
46 | build_path_from_dentry(struct dentry *direntry) | 46 | build_path_from_dentry(struct dentry *direntry) |
47 | { | 47 | { |
48 | struct dentry *temp; | 48 | struct dentry *temp; |
49 | int namelen = 0; | 49 | int namelen; |
50 | int pplen; | ||
50 | char *full_path; | 51 | char *full_path; |
51 | char dirsep; | 52 | char dirsep; |
52 | 53 | ||
@@ -56,7 +57,9 @@ build_path_from_dentry(struct dentry *direntry) | |||
56 | when the server crashed */ | 57 | when the server crashed */ |
57 | 58 | ||
58 | dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb)); | 59 | dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb)); |
60 | pplen = CIFS_SB(direntry->d_sb)->prepathlen; | ||
59 | cifs_bp_rename_retry: | 61 | cifs_bp_rename_retry: |
62 | namelen = pplen; | ||
60 | for (temp = direntry; !IS_ROOT(temp);) { | 63 | for (temp = direntry; !IS_ROOT(temp);) { |
61 | namelen += (1 + temp->d_name.len); | 64 | namelen += (1 + temp->d_name.len); |
62 | temp = temp->d_parent; | 65 | temp = temp->d_parent; |
@@ -70,7 +73,6 @@ cifs_bp_rename_retry: | |||
70 | if(full_path == NULL) | 73 | if(full_path == NULL) |
71 | return full_path; | 74 | return full_path; |
72 | full_path[namelen] = 0; /* trailing null */ | 75 | full_path[namelen] = 0; /* trailing null */ |
73 | |||
74 | for (temp = direntry; !IS_ROOT(temp);) { | 76 | for (temp = direntry; !IS_ROOT(temp);) { |
75 | namelen -= 1 + temp->d_name.len; | 77 | namelen -= 1 + temp->d_name.len; |
76 | if (namelen < 0) { | 78 | if (namelen < 0) { |
@@ -79,7 +81,7 @@ cifs_bp_rename_retry: | |||
79 | full_path[namelen] = dirsep; | 81 | full_path[namelen] = dirsep; |
80 | strncpy(full_path + namelen + 1, temp->d_name.name, | 82 | strncpy(full_path + namelen + 1, temp->d_name.name, |
81 | temp->d_name.len); | 83 | temp->d_name.len); |
82 | cFYI(0, (" name: %s ", full_path + namelen)); | 84 | cFYI(0, ("name: %s", full_path + namelen)); |
83 | } | 85 | } |
84 | temp = temp->d_parent; | 86 | temp = temp->d_parent; |
85 | if(temp == NULL) { | 87 | if(temp == NULL) { |
@@ -88,18 +90,23 @@ cifs_bp_rename_retry: | |||
88 | return NULL; | 90 | return NULL; |
89 | } | 91 | } |
90 | } | 92 | } |
91 | if (namelen != 0) { | 93 | if (namelen != pplen) { |
92 | cERROR(1, | 94 | cERROR(1, |
93 | ("We did not end path lookup where we expected namelen is %d", | 95 | ("did not end path lookup where expected namelen is %d", |
94 | namelen)); | 96 | namelen)); |
95 | /* presumably this is only possible if we were racing with a rename | 97 | /* presumably this is only possible if racing with a rename |
96 | of one of the parent directories (we can not lock the dentries | 98 | of one of the parent directories (we can not lock the dentries |
97 | above us to prevent this, but retrying should be harmless) */ | 99 | above us to prevent this, but retrying should be harmless) */ |
98 | kfree(full_path); | 100 | kfree(full_path); |
99 | namelen = 0; | ||
100 | goto cifs_bp_rename_retry; | 101 | goto cifs_bp_rename_retry; |
101 | } | 102 | } |
102 | 103 | /* DIR_SEP already set for byte 0 / vs \ but not for | |
104 | subsequent slashes in prepath which currently must | ||
105 | be entered the right way - not sure if there is an alternative | ||
106 | since the '\' is a valid posix character so we can not switch | ||
107 | those safely to '/' if any are found in the middle of the prepath */ | ||
108 | /* BB test paths to Windows with '/' in the midst of prepath */ | ||
109 | strncpy(full_path,CIFS_SB(direntry->d_sb)->prepath,pplen); | ||
103 | return full_path; | 110 | return full_path; |
104 | } | 111 | } |
105 | 112 | ||
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index 067648b7179b..18fcec190f8b 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c | |||
@@ -269,7 +269,7 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name, | |||
269 | rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, | 269 | rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, |
270 | ea_value, buf_size, | 270 | ea_value, buf_size, |
271 | ACL_TYPE_ACCESS); | 271 | ACL_TYPE_ACCESS); |
272 | CIFSSMBClose(xid, pTcon, fid) | 272 | CIFSSMBClose(xid, pTcon, fid); |
273 | } | 273 | } |
274 | } */ /* BB enable after fixing up return data */ | 274 | } */ /* BB enable after fixing up return data */ |
275 | 275 | ||