aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2007-07-18 19:21:09 -0400
committerSteve French <sfrench@us.ibm.com>2007-07-18 19:21:09 -0400
commitc18c842b1fdf527717303a4e173cbece7ab2deb8 (patch)
treeb400ad6d711b8474a0516220c98d390d56c508de
parent63135e088a604b955746c51964c195c8d3ebac11 (diff)
[CIFS] Allow disabling CIFS Unix Extensions as mount option
Previously the only way to do this was to umount all mounts to that server, turn off a proc setting (/proc/fs/cifs/LinuxExtensionsEnabled). Fixes Samba bugzilla bug number: 4582 (and also 2008) Signed-off-by: Steve French <sfrench@us.ibm.com>
-rw-r--r--fs/cifs/cifsfs.c4
-rw-r--r--fs/cifs/cifsglob.h4
-rw-r--r--fs/cifs/cifssmb.c21
-rw-r--r--fs/cifs/connect.c31
-rw-r--r--fs/cifs/dir.c11
-rw-r--r--fs/cifs/file.c6
-rw-r--r--fs/cifs/inode.c13
-rw-r--r--fs/cifs/link.c17
-rw-r--r--fs/cifs/readdir.c4
9 files changed, 65 insertions, 46 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index a0a2f3186557..1cebb7e34215 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -316,10 +316,10 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
316 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) 316 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
317 seq_printf(s, ",posixpaths"); 317 seq_printf(s, ",posixpaths");
318 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) || 318 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) ||
319 !(cifs_sb->tcon->ses->capabilities & CAP_UNIX)) 319 !(cifs_sb->tcon->unix_ext))
320 seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); 320 seq_printf(s, ",uid=%d", cifs_sb->mnt_uid);
321 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) || 321 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) ||
322 !(cifs_sb->tcon->ses->capabilities & CAP_UNIX)) 322 !(cifs_sb->tcon->unix_ext))
323 seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); 323 seq_printf(s, ",gid=%d", cifs_sb->mnt_gid);
324 seq_printf(s, ",rsize=%d", cifs_sb->rsize); 324 seq_printf(s, ",rsize=%d", cifs_sb->rsize);
325 seq_printf(s, ",wsize=%d", cifs_sb->wsize); 325 seq_printf(s, ",wsize=%d", cifs_sb->wsize);
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 0a7813175a27..b98742fc3b5a 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -281,7 +281,9 @@ struct cifsTconInfo {
281 FILE_SYSTEM_UNIX_INFO fsUnixInfo; 281 FILE_SYSTEM_UNIX_INFO fsUnixInfo;
282 unsigned retry:1; 282 unsigned retry:1;
283 unsigned nocase:1; 283 unsigned nocase:1;
284 /* BB add field for back pointer to sb struct? */ 284 unsigned unix_ext:1; /* if off disable Linux extensions to CIFS protocol
285 for this mount even if server would support */
286 /* BB add field for back pointer to sb struct(s)? */
285}; 287};
286 288
287/* 289/*
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index a6ff406ac6b4..8eb102f940d4 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -132,10 +132,10 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
132 /* Give Demultiplex thread up to 10 seconds to 132 /* Give Demultiplex thread up to 10 seconds to
133 reconnect, should be greater than cifs socket 133 reconnect, should be greater than cifs socket
134 timeout which is 7 seconds */ 134 timeout which is 7 seconds */
135 while(tcon->ses->server->tcpStatus == 135 while (tcon->ses->server->tcpStatus ==
136 CifsNeedReconnect) { 136 CifsNeedReconnect) {
137 wait_event_interruptible_timeout(tcon->ses->server->response_q, 137 wait_event_interruptible_timeout(tcon->ses->server->response_q,
138 (tcon->ses->server->tcpStatus == 138 (tcon->ses->server->tcpStatus ==
139 CifsGood), 10 * HZ); 139 CifsGood), 10 * HZ);
140 if (tcon->ses->server->tcpStatus == 140 if (tcon->ses->server->tcpStatus ==
141 CifsNeedReconnect) { 141 CifsNeedReconnect) {
@@ -213,7 +213,7 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
213 } 213 }
214 214
215 header_assemble((struct smb_hdr *) *request_buf, smb_command, 215 header_assemble((struct smb_hdr *) *request_buf, smb_command,
216 tcon,wct); 216 tcon, wct);
217 217
218 if (tcon != NULL) 218 if (tcon != NULL)
219 cifs_stats_inc(&tcon->num_smbs_sent); 219 cifs_stats_inc(&tcon->num_smbs_sent);
@@ -387,7 +387,7 @@ static int validate_t2(struct smb_t2_rsp *pSMB)
387 /* check that bcc is less than negotiated smb buffer */ 387 /* check that bcc is less than negotiated smb buffer */
388 total_size = le16_to_cpu(pSMB->t2_rsp.ParameterCount); 388 total_size = le16_to_cpu(pSMB->t2_rsp.ParameterCount);
389 if (total_size < 512) { 389 if (total_size < 512) {
390 total_size += 390 total_size +=
391 le16_to_cpu(pSMB->t2_rsp.DataCount); 391 le16_to_cpu(pSMB->t2_rsp.DataCount);
392 /* BCC le converted in SendReceive */ 392 /* BCC le converted in SendReceive */
393 pBCC = (pSMB->hdr.WordCount * 2) + 393 pBCC = (pSMB->hdr.WordCount * 2) +
@@ -2758,7 +2758,7 @@ static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
2758 return 0; 2758 return 0;
2759 2759
2760 count = posix_acl_xattr_count((size_t)buflen); 2760 count = posix_acl_xattr_count((size_t)buflen);
2761 cFYI(1,("setting acl with %d entries from buf of length %d and " 2761 cFYI(1, ("setting acl with %d entries from buf of length %d and "
2762 "version of %d", 2762 "version of %d",
2763 count, buflen, le32_to_cpu(local_acl->a_version))); 2763 count, buflen, le32_to_cpu(local_acl->a_version)));
2764 if (le32_to_cpu(local_acl->a_version) != 2) { 2764 if (le32_to_cpu(local_acl->a_version) != 2) {
@@ -3638,15 +3638,6 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3638 pSMB->SearchHandle = searchHandle; /* always kept as le */ 3638 pSMB->SearchHandle = searchHandle; /* always kept as le */
3639 pSMB->SearchCount = 3639 pSMB->SearchCount =
3640 cpu_to_le16(CIFSMaxBufSize / sizeof (FILE_UNIX_INFO)); 3640 cpu_to_le16(CIFSMaxBufSize / sizeof (FILE_UNIX_INFO));
3641 /* test for Unix extensions */
3642/* if (tcon->ses->capabilities & CAP_UNIX) {
3643 pSMB->InformationLevel = cpu_to_le16(SMB_FIND_FILE_UNIX);
3644 psrch_inf->info_level = SMB_FIND_FILE_UNIX;
3645 } else {
3646 pSMB->InformationLevel =
3647 cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO);
3648 psrch_inf->info_level = SMB_FIND_FILE_DIRECTORY_INFO;
3649 } */
3650 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); 3641 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
3651 pSMB->ResumeKey = psrch_inf->resume_key; 3642 pSMB->ResumeKey = psrch_inf->resume_key;
3652 pSMB->SearchFlags = 3643 pSMB->SearchFlags =
@@ -3966,7 +3957,7 @@ getDFSRetry:
3966 (8 /* sizeof start of data block */ + 3957 (8 /* sizeof start of data block */ +
3967 data_offset + 3958 data_offset +
3968 (char *) &pSMBr->hdr.Protocol); 3959 (char *) &pSMBr->hdr.Protocol);
3969 cFYI(1,("num_referrals: %d dfs flags: 0x%x ... \n" 3960 cFYI(1, ("num_referrals: %d dfs flags: 0x%x ... \n"
3970 "for referral one refer size: 0x%x srv " 3961 "for referral one refer size: 0x%x srv "
3971 "type: 0x%x refer flags: 0x%x ttl: 0x%x", 3962 "type: 0x%x refer flags: 0x%x ttl: 0x%x",
3972 le16_to_cpu(pSMBr->NumberOfReferrals), 3963 le16_to_cpu(pSMBr->NumberOfReferrals),
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 8b341a8599f8..e93da7ad9002 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -85,6 +85,7 @@ struct smb_vol {
85 unsigned direct_io:1; 85 unsigned direct_io:1;
86 unsigned remap:1; /* set to remap seven reserved chars in filenames */ 86 unsigned remap:1; /* set to remap seven reserved chars in filenames */
87 unsigned posix_paths:1; /* unset to not ask for posix pathnames. */ 87 unsigned posix_paths:1; /* unset to not ask for posix pathnames. */
88 unsigned no_linux_ext:1;
88 unsigned sfu_emul:1; 89 unsigned sfu_emul:1;
89 unsigned nullauth:1; /* attempt to authenticate with null user */ 90 unsigned nullauth:1; /* attempt to authenticate with null user */
90 unsigned nocase; /* request case insensitive filenames */ 91 unsigned nocase; /* request case insensitive filenames */
@@ -1192,6 +1193,10 @@ cifs_parse_mount_options(char *options, const char *devname,
1192 vol->posix_paths = 1; 1193 vol->posix_paths = 1;
1193 } else if (strnicmp(data, "noposixpaths", 12) == 0) { 1194 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1194 vol->posix_paths = 0; 1195 vol->posix_paths = 0;
1196 } else if (strnicmp(data, "nounix", 6) == 0) {
1197 vol->no_linux_ext = 1;
1198 } else if (strnicmp(data, "nolinux", 7) == 0) {
1199 vol->no_linux_ext = 1;
1195 } else if ((strnicmp(data, "nocase", 6) == 0) || 1200 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1196 (strnicmp(data, "ignorecase", 10) == 0)) { 1201 (strnicmp(data, "ignorecase", 10) == 0)) {
1197 vol->nocase = 1; 1202 vol->nocase = 1;
@@ -1665,6 +1670,18 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
1665 * and once without posixacls or posix paths? */ 1670 * and once without posixacls or posix paths? */
1666 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability); 1671 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1667 1672
1673 if (vol_info && vol_info->no_linux_ext) {
1674 tcon->fsUnixInfo.Capability = 0;
1675 tcon->unix_ext = 0; /* Unix Extensions disabled */
1676 cFYI(1, ("Linux protocol extensions disabled"));
1677 return;
1678 } else if (vol_info)
1679 tcon->unix_ext = 1; /* Unix Extensions supported */
1680
1681 if (tcon->unix_ext == 0) {
1682 cFYI(1, ("Unix extensions disabled so not set on reconnect"));
1683 return;
1684 }
1668 1685
1669 if (!CIFSSMBQFSUnixInfo(xid, tcon)) { 1686 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
1670 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability); 1687 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
@@ -1678,10 +1695,6 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
1678 cap &= ~CIFS_UNIX_POSIX_ACL_CAP; 1695 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1679 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) 1696 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0)
1680 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; 1697 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1681
1682
1683
1684
1685 } 1698 }
1686 1699
1687 cap &= CIFS_UNIX_CAP_MASK; 1700 cap &= CIFS_UNIX_CAP_MASK;
@@ -2176,13 +2189,17 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2176 2189
2177 /* tell server which Unix caps we support */ 2190 /* tell server which Unix caps we support */
2178 if (tcon->ses->capabilities & CAP_UNIX) 2191 if (tcon->ses->capabilities & CAP_UNIX)
2192 /* reset of caps checks mount to see if unix extensions
2193 disabled for just this mount */
2179 reset_cifs_unix_caps(xid, tcon, sb, &volume_info); 2194 reset_cifs_unix_caps(xid, tcon, sb, &volume_info);
2180 else if (cifs_sb->rsize > (1024 * 127)) { 2195 else
2196 tcon->unix_ext = 0; /* server does not support them */
2197
2198 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2181 cifs_sb->rsize = 1024 * 127; 2199 cifs_sb->rsize = 1024 * 127;
2182#ifdef CONFIG_CIFS_DEBUG2 2200#ifdef CONFIG_CIFS_DEBUG2
2183 cFYI(1, ("no very large read support, rsize 127K")); 2201 cFYI(1, ("no very large read support, rsize now 127K"));
2184#endif 2202#endif
2185
2186 } 2203 }
2187 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X)) 2204 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2188 cifs_sb->wsize = min(cifs_sb->wsize, 2205 cifs_sb->wsize = min(cifs_sb->wsize,
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index def89f23fe55..4830acc86d74 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -207,8 +207,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
207 } else { 207 } else {
208 /* If Open reported that we actually created a file 208 /* If Open reported that we actually created a file
209 then we now have to set the mode if possible */ 209 then we now have to set the mode if possible */
210 if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) && 210 if ((pTcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) {
211 (oplock & CIFS_CREATE_ACTION)) {
212 mode &= ~current->fs->umask; 211 mode &= ~current->fs->umask;
213 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 212 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
214 CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, 213 CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
@@ -235,8 +234,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
235 /* Could set r/o dos attribute if mode & 0222 == 0 */ 234 /* Could set r/o dos attribute if mode & 0222 == 0 */
236 } 235 }
237 236
238 /* BB server might mask mode so we have to query for Unix case*/ 237 /* server might mask mode so we have to query for it */
239 if (pTcon->ses->capabilities & CAP_UNIX) 238 if (pTcon->unix_ext)
240 rc = cifs_get_inode_info_unix(&newinode, full_path, 239 rc = cifs_get_inode_info_unix(&newinode, full_path,
241 inode->i_sb, xid); 240 inode->i_sb, xid);
242 else { 241 else {
@@ -337,7 +336,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
337 full_path = build_path_from_dentry(direntry); 336 full_path = build_path_from_dentry(direntry);
338 if (full_path == NULL) 337 if (full_path == NULL)
339 rc = -ENOMEM; 338 rc = -ENOMEM;
340 else if (pTcon->ses->capabilities & CAP_UNIX) { 339 else if (pTcon->unix_ext) {
341 mode &= ~current->fs->umask; 340 mode &= ~current->fs->umask;
342 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 341 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
343 rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, 342 rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path,
@@ -491,7 +490,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
491 cFYI(1, 490 cFYI(1,
492 (" Full path: %s inode = 0x%p", full_path, direntry->d_inode)); 491 (" Full path: %s inode = 0x%p", full_path, direntry->d_inode));
493 492
494 if (pTcon->ses->capabilities & CAP_UNIX) 493 if (pTcon->unix_ext)
495 rc = cifs_get_inode_info_unix(&newInode, full_path, 494 rc = cifs_get_inode_info_unix(&newInode, full_path,
496 parent_dir_inode->i_sb, xid); 495 parent_dir_inode->i_sb, xid);
497 else 496 else
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 0a39491280d1..e13592afca9c 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -138,7 +138,7 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file,
138 } 138 }
139 139
140client_can_cache: 140client_can_cache:
141 if (pTcon->ses->capabilities & CAP_UNIX) 141 if (pTcon->unix_ext)
142 rc = cifs_get_inode_info_unix(&file->f_path.dentry->d_inode, 142 rc = cifs_get_inode_info_unix(&file->f_path.dentry->d_inode,
143 full_path, inode->i_sb, xid); 143 full_path, inode->i_sb, xid);
144 else 144 else
@@ -303,7 +303,7 @@ int cifs_open(struct inode *inode, struct file *file)
303 if (oplock & CIFS_CREATE_ACTION) { 303 if (oplock & CIFS_CREATE_ACTION) {
304 /* time to set mode which we can not set earlier due to 304 /* time to set mode which we can not set earlier due to
305 problems creating new read-only files */ 305 problems creating new read-only files */
306 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) { 306 if (pTcon->unix_ext) {
307 CIFSSMBUnixSetPerms(xid, pTcon, full_path, 307 CIFSSMBUnixSetPerms(xid, pTcon, full_path,
308 inode->i_mode, 308 inode->i_mode,
309 (__u64)-1, (__u64)-1, 0 /* dev */, 309 (__u64)-1, (__u64)-1, 0 /* dev */,
@@ -430,7 +430,7 @@ reopen_error_exit:
430 go to server to get inode info */ 430 go to server to get inode info */
431 pCifsInode->clientCanCacheAll = FALSE; 431 pCifsInode->clientCanCacheAll = FALSE;
432 pCifsInode->clientCanCacheRead = FALSE; 432 pCifsInode->clientCanCacheRead = FALSE;
433 if (pTcon->ses->capabilities & CAP_UNIX) 433 if (pTcon->unix_ext)
434 rc = cifs_get_inode_info_unix(&inode, 434 rc = cifs_get_inode_info_unix(&inode,
435 full_path, inode->i_sb, xid); 435 full_path, inode->i_sb, xid);
436 else 436 else
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 3482879b3d3f..dd4167762a8e 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -583,7 +583,8 @@ void cifs_read_inode(struct inode *inode)
583 583
584 cifs_sb = CIFS_SB(inode->i_sb); 584 cifs_sb = CIFS_SB(inode->i_sb);
585 xid = GetXid(); 585 xid = GetXid();
586 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) 586
587 if (cifs_sb->tcon->unix_ext)
587 cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid); 588 cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid);
588 else 589 else
589 cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid); 590 cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid);
@@ -981,7 +982,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
981 } else { 982 } else {
982mkdir_get_info: 983mkdir_get_info:
983 inc_nlink(inode); 984 inc_nlink(inode);
984 if (pTcon->ses->capabilities & CAP_UNIX) 985 if (pTcon->unix_ext)
985 rc = cifs_get_inode_info_unix(&newinode, full_path, 986 rc = cifs_get_inode_info_unix(&newinode, full_path,
986 inode->i_sb, xid); 987 inode->i_sb, xid);
987 else 988 else
@@ -997,7 +998,7 @@ mkdir_get_info:
997 * failed to get it from the server or was set bogus */ 998 * failed to get it from the server or was set bogus */
998 if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2)) 999 if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
999 direntry->d_inode->i_nlink = 2; 1000 direntry->d_inode->i_nlink = 2;
1000 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) { 1001 if (pTcon->unix_ext) {
1001 mode &= ~current->fs->umask; 1002 mode &= ~current->fs->umask;
1002 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 1003 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
1003 CIFSSMBUnixSetPerms(xid, pTcon, full_path, 1004 CIFSSMBUnixSetPerms(xid, pTcon, full_path,
@@ -1130,7 +1131,7 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
1130 kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); 1131 kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
1131 if (info_buf_source != NULL) { 1132 if (info_buf_source != NULL) {
1132 info_buf_target = info_buf_source + 1; 1133 info_buf_target = info_buf_source + 1;
1133 if (pTcon->ses->capabilities & CAP_UNIX) 1134 if (pTcon->unix_ext)
1134 rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName, 1135 rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName,
1135 info_buf_source, 1136 info_buf_source,
1136 cifs_sb_source->local_nls, 1137 cifs_sb_source->local_nls,
@@ -1258,7 +1259,7 @@ int cifs_revalidate(struct dentry *direntry)
1258 local_mtime = direntry->d_inode->i_mtime; 1259 local_mtime = direntry->d_inode->i_mtime;
1259 local_size = direntry->d_inode->i_size; 1260 local_size = direntry->d_inode->i_size;
1260 1261
1261 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) { 1262 if (cifs_sb->tcon->unix_ext) {
1262 rc = cifs_get_inode_info_unix(&direntry->d_inode, full_path, 1263 rc = cifs_get_inode_info_unix(&direntry->d_inode, full_path,
1263 direntry->d_sb, xid); 1264 direntry->d_sb, xid);
1264 if (rc) { 1265 if (rc) {
@@ -1542,7 +1543,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1542 mode = attrs->ia_mode; 1543 mode = attrs->ia_mode;
1543 } 1544 }
1544 1545
1545 if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) 1546 if ((pTcon->unix_ext)
1546 && (attrs->ia_valid & (ATTR_MODE | ATTR_GID | ATTR_UID))) 1547 && (attrs->ia_valid & (ATTR_MODE | ATTR_GID | ATTR_UID)))
1547 rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, uid, gid, 1548 rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, uid, gid,
1548 0 /* dev_t */, cifs_sb->local_nls, 1549 0 /* dev_t */, cifs_sb->local_nls,
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 7da755c6550a..6a85ef7b8797 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -55,7 +55,8 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
55 goto cifs_hl_exit; 55 goto cifs_hl_exit;
56 } 56 }
57 57
58 if (cifs_sb_target->tcon->ses->capabilities & CAP_UNIX) 58/* if (cifs_sb_target->tcon->ses->capabilities & CAP_UNIX)*/
59 if (pTcon->unix_ext)
59 rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName, 60 rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName,
60 cifs_sb_target->local_nls, 61 cifs_sb_target->local_nls,
61 cifs_sb_target->mnt_cifs_flags & 62 cifs_sb_target->mnt_cifs_flags &
@@ -129,14 +130,19 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
129 goto out; 130 goto out;
130 } 131 }
131 132
132 /* BB add read reparse point symlink code and Unix extensions 133 /* We could change this to:
133 symlink code here BB */ 134 if (pTcon->unix_ext)
135 but there does not seem any point in refusing to
136 get symlink info if we can, even if unix extensions
137 turned off for this mount */
138
134 if (pTcon->ses->capabilities & CAP_UNIX) 139 if (pTcon->ses->capabilities & CAP_UNIX)
135 rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path, 140 rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path,
136 target_path, 141 target_path,
137 PATH_MAX-1, 142 PATH_MAX-1,
138 cifs_sb->local_nls); 143 cifs_sb->local_nls);
139 else { 144 else {
145 /* BB add read reparse point symlink code here */
140 /* rc = CIFSSMBQueryReparseLinkInfo */ 146 /* rc = CIFSSMBQueryReparseLinkInfo */
141 /* BB Add code to Query ReparsePoint info */ 147 /* BB Add code to Query ReparsePoint info */
142 /* BB Add MAC style xsymlink check here if enabled */ 148 /* BB Add MAC style xsymlink check here if enabled */
@@ -186,7 +192,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
186 cFYI(1, ("symname is %s", symname)); 192 cFYI(1, ("symname is %s", symname));
187 193
188 /* BB what if DFS and this volume is on different share? BB */ 194 /* BB what if DFS and this volume is on different share? BB */
189 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) 195 if (pTcon->unix_ext)
190 rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname, 196 rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
191 cifs_sb->local_nls); 197 cifs_sb->local_nls);
192 /* else 198 /* else
@@ -194,7 +200,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
194 cifs_sb_target->local_nls); */ 200 cifs_sb_target->local_nls); */
195 201
196 if (rc == 0) { 202 if (rc == 0) {
197 if (pTcon->ses->capabilities & CAP_UNIX) 203 if (pTcon->unix_ext)
198 rc = cifs_get_inode_info_unix(&newinode, full_path, 204 rc = cifs_get_inode_info_unix(&newinode, full_path,
199 inode->i_sb, xid); 205 inode->i_sb, xid);
200 else 206 else
@@ -266,6 +272,7 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
266 272
267/* BB add read reparse point symlink code and 273/* BB add read reparse point symlink code and
268 Unix extensions symlink code here BB */ 274 Unix extensions symlink code here BB */
275/* We could disable this based on pTcon->unix_ext flag instead ... but why? */
269 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) 276 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
270 rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path, 277 rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path,
271 tmpbuffer, 278 tmpbuffer,
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 07f92531f74f..916df9431336 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -463,7 +463,9 @@ static int initiate_cifs_search(const int xid, struct file *file)
463 463
464ffirst_retry: 464ffirst_retry:
465 /* test for Unix extensions */ 465 /* test for Unix extensions */
466 if (pTcon->ses->capabilities & CAP_UNIX) { 466 /* but now check for them on the share/mount not on the SMB session */
467/* if (pTcon->ses->capabilities & CAP_UNIX) { */
468 if (pTcon->unix_ext) {
467 cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX; 469 cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX;
468 } else if ((pTcon->ses->capabilities & 470 } else if ((pTcon->ses->capabilities &
469 (CAP_NT_SMBS | CAP_NT_FIND)) == 0) { 471 (CAP_NT_SMBS | CAP_NT_FIND)) == 0) {