diff options
author | Steve French <sfrench@us.ibm.com> | 2007-07-18 19:21:09 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2007-07-18 19:21:09 -0400 |
commit | c18c842b1fdf527717303a4e173cbece7ab2deb8 (patch) | |
tree | b400ad6d711b8474a0516220c98d390d56c508de | |
parent | 63135e088a604b955746c51964c195c8d3ebac11 (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.c | 4 | ||||
-rw-r--r-- | fs/cifs/cifsglob.h | 4 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 21 | ||||
-rw-r--r-- | fs/cifs/connect.c | 31 | ||||
-rw-r--r-- | fs/cifs/dir.c | 11 | ||||
-rw-r--r-- | fs/cifs/file.c | 6 | ||||
-rw-r--r-- | fs/cifs/inode.c | 13 | ||||
-rw-r--r-- | fs/cifs/link.c | 17 | ||||
-rw-r--r-- | fs/cifs/readdir.c | 4 |
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 | ||
140 | client_can_cache: | 140 | client_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 { |
982 | mkdir_get_info: | 983 | mkdir_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 | ||
464 | ffirst_retry: | 464 | ffirst_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) { |