diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-05-27 14:09:16 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-05-27 14:09:16 -0700 | 
| commit | de182468d1bb726198abaab315820542425270b7 (patch) | |
| tree | 2a24412b734c6e7911ef4268ed3b52750b3cdf75 | |
| parent | 8f98bcdf8f9638ee012ff09c6c8732e0fda6018a (diff) | |
| parent | 4afe260bab50290a05e5732570329a530ed023f3 (diff) | |
Merge branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6
Pull cifs fixes from Steve French:
 "Back from SambaXP - now have 8 small CIFS bug fixes to merge"
* 'for-next' of git://git.samba.org/sfrench/cifs-2.6:
  CIFS: Fix race condition on RFC1002_NEGATIVE_SESSION_RESPONSE
  Fix to convert SURROGATE PAIR
  cifs: potential missing check for posix_lock_file_wait
  Fix to check Unique id and FileType when client refer file directly.
  CIFS: remove an unneeded NULL check
  [cifs] fix null pointer check
  Fix that several functions handle incorrect value of mapchars
  cifs: Don't replace dentries for dfs mounts
| -rw-r--r-- | fs/cifs/cifs_dfs_ref.c | 3 | ||||
| -rw-r--r-- | fs/cifs/cifs_unicode.c | 182 | ||||
| -rw-r--r-- | fs/cifs/cifsfs.c | 2 | ||||
| -rw-r--r-- | fs/cifs/cifsproto.h | 4 | ||||
| -rw-r--r-- | fs/cifs/cifssmb.c | 23 | ||||
| -rw-r--r-- | fs/cifs/connect.c | 3 | ||||
| -rw-r--r-- | fs/cifs/dir.c | 3 | ||||
| -rw-r--r-- | fs/cifs/file.c | 7 | ||||
| -rw-r--r-- | fs/cifs/inode.c | 31 | ||||
| -rw-r--r-- | fs/cifs/link.c | 3 | ||||
| -rw-r--r-- | fs/cifs/readdir.c | 2 | ||||
| -rw-r--r-- | fs/cifs/smb1ops.c | 3 | ||||
| -rw-r--r-- | fs/cifs/smb2pdu.c | 2 | 
13 files changed, 194 insertions, 74 deletions
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c index 430e0348c99e..7dc886c9a78f 100644 --- a/fs/cifs/cifs_dfs_ref.c +++ b/fs/cifs/cifs_dfs_ref.c @@ -24,6 +24,7 @@  #include "cifsfs.h"  #include "dns_resolve.h"  #include "cifs_debug.h" +#include "cifs_unicode.h"  static LIST_HEAD(cifs_dfs_automount_list); @@ -312,7 +313,7 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)  	xid = get_xid();  	rc = get_dfs_path(xid, ses, full_path + 1, cifs_sb->local_nls,  		&num_referrals, &referrals, -		cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); +		cifs_remap(cifs_sb));  	free_xid(xid);  	cifs_put_tlink(tlink); diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c index 0303c6793d90..5a53ac6b1e02 100644 --- a/fs/cifs/cifs_unicode.c +++ b/fs/cifs/cifs_unicode.c @@ -27,41 +27,6 @@  #include "cifsglob.h"  #include "cifs_debug.h" -/* - * cifs_utf16_bytes - how long will a string be after conversion? - * @utf16 - pointer to input string - * @maxbytes - don't go past this many bytes of input string - * @codepage - destination codepage - * - * Walk a utf16le string and return the number of bytes that the string will - * be after being converted to the given charset, not including any null - * termination required. Don't walk past maxbytes in the source buffer. - */ -int -cifs_utf16_bytes(const __le16 *from, int maxbytes, -		const struct nls_table *codepage) -{ -	int i; -	int charlen, outlen = 0; -	int maxwords = maxbytes / 2; -	char tmp[NLS_MAX_CHARSET_SIZE]; -	__u16 ftmp; - -	for (i = 0; i < maxwords; i++) { -		ftmp = get_unaligned_le16(&from[i]); -		if (ftmp == 0) -			break; - -		charlen = codepage->uni2char(ftmp, tmp, NLS_MAX_CHARSET_SIZE); -		if (charlen > 0) -			outlen += charlen; -		else -			outlen++; -	} - -	return outlen; -} -  int cifs_remap(struct cifs_sb_info *cifs_sb)  {  	int map_type; @@ -155,10 +120,13 @@ convert_sfm_char(const __u16 src_char, char *target)   * enough to hold the result of the conversion (at least NLS_MAX_CHARSET_SIZE).   */  static int -cifs_mapchar(char *target, const __u16 src_char, const struct nls_table *cp, +cifs_mapchar(char *target, const __u16 *from, const struct nls_table *cp,  	     int maptype)  {  	int len = 1; +	__u16 src_char; + +	src_char = *from;  	if ((maptype == SFM_MAP_UNI_RSVD) && convert_sfm_char(src_char, target))  		return len; @@ -168,10 +136,23 @@ cifs_mapchar(char *target, const __u16 src_char, const struct nls_table *cp,  	/* if character not one of seven in special remap set */  	len = cp->uni2char(src_char, target, NLS_MAX_CHARSET_SIZE); -	if (len <= 0) { -		*target = '?'; -		len = 1; -	} +	if (len <= 0) +		goto surrogate_pair; + +	return len; + +surrogate_pair: +	/* convert SURROGATE_PAIR and IVS */ +	if (strcmp(cp->charset, "utf8")) +		goto unknown; +	len = utf16s_to_utf8s(from, 3, UTF16_LITTLE_ENDIAN, target, 6); +	if (len <= 0) +		goto unknown; +	return len; + +unknown: +	*target = '?'; +	len = 1;  	return len;  } @@ -206,7 +187,7 @@ cifs_from_utf16(char *to, const __le16 *from, int tolen, int fromlen,  	int nullsize = nls_nullsize(codepage);  	int fromwords = fromlen / 2;  	char tmp[NLS_MAX_CHARSET_SIZE]; -	__u16 ftmp; +	__u16 ftmp[3];		/* ftmp[3] = 3array x 2bytes = 6bytes UTF-16 */  	/*  	 * because the chars can be of varying widths, we need to take care @@ -217,9 +198,17 @@ cifs_from_utf16(char *to, const __le16 *from, int tolen, int fromlen,  	safelen = tolen - (NLS_MAX_CHARSET_SIZE + nullsize);  	for (i = 0; i < fromwords; i++) { -		ftmp = get_unaligned_le16(&from[i]); -		if (ftmp == 0) +		ftmp[0] = get_unaligned_le16(&from[i]); +		if (ftmp[0] == 0)  			break; +		if (i + 1 < fromwords) +			ftmp[1] = get_unaligned_le16(&from[i + 1]); +		else +			ftmp[1] = 0; +		if (i + 2 < fromwords) +			ftmp[2] = get_unaligned_le16(&from[i + 2]); +		else +			ftmp[2] = 0;  		/*  		 * check to see if converting this character might make the @@ -234,6 +223,17 @@ cifs_from_utf16(char *to, const __le16 *from, int tolen, int fromlen,  		/* put converted char into 'to' buffer */  		charlen = cifs_mapchar(&to[outlen], ftmp, codepage, map_type);  		outlen += charlen; + +		/* charlen (=bytes of UTF-8 for 1 character) +		 * 4bytes UTF-8(surrogate pair) is charlen=4 +		 *   (4bytes UTF-16 code) +		 * 7-8bytes UTF-8(IVS) is charlen=3+4 or 4+4 +		 *   (2 UTF-8 pairs divided to 2 UTF-16 pairs) */ +		if (charlen == 4) +			i++; +		else if (charlen >= 5) +			/* 5-6bytes UTF-8 */ +			i += 2;  	}  	/* properly null-terminate string */ @@ -296,6 +296,46 @@ success:  }  /* + * cifs_utf16_bytes - how long will a string be after conversion? + * @utf16 - pointer to input string + * @maxbytes - don't go past this many bytes of input string + * @codepage - destination codepage + * + * Walk a utf16le string and return the number of bytes that the string will + * be after being converted to the given charset, not including any null + * termination required. Don't walk past maxbytes in the source buffer. + */ +int +cifs_utf16_bytes(const __le16 *from, int maxbytes, +		const struct nls_table *codepage) +{ +	int i; +	int charlen, outlen = 0; +	int maxwords = maxbytes / 2; +	char tmp[NLS_MAX_CHARSET_SIZE]; +	__u16 ftmp[3]; + +	for (i = 0; i < maxwords; i++) { +		ftmp[0] = get_unaligned_le16(&from[i]); +		if (ftmp[0] == 0) +			break; +		if (i + 1 < maxwords) +			ftmp[1] = get_unaligned_le16(&from[i + 1]); +		else +			ftmp[1] = 0; +		if (i + 2 < maxwords) +			ftmp[2] = get_unaligned_le16(&from[i + 2]); +		else +			ftmp[2] = 0; + +		charlen = cifs_mapchar(tmp, ftmp, codepage, NO_MAP_UNI_RSVD); +		outlen += charlen; +	} + +	return outlen; +} + +/*   * cifs_strndup_from_utf16 - copy a string from wire format to the local   * codepage   * @src - source string @@ -409,10 +449,15 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen,  	char src_char;  	__le16 dst_char;  	wchar_t tmp; +	wchar_t *wchar_to;	/* UTF-16 */ +	int ret; +	unicode_t u;  	if (map_chars == NO_MAP_UNI_RSVD)  		return cifs_strtoUTF16(target, source, PATH_MAX, cp); +	wchar_to = kzalloc(6, GFP_KERNEL); +  	for (i = 0; i < srclen; j++) {  		src_char = source[i];  		charlen = 1; @@ -441,11 +486,55 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen,  			 * if no match, use question mark, which at least in  			 * some cases serves as wild card  			 */ -			if (charlen < 1) { -				dst_char = cpu_to_le16(0x003f); -				charlen = 1; +			if (charlen > 0) +				goto ctoUTF16; + +			/* convert SURROGATE_PAIR */ +			if (strcmp(cp->charset, "utf8") || !wchar_to) +				goto unknown; +			if (*(source + i) & 0x80) { +				charlen = utf8_to_utf32(source + i, 6, &u); +				if (charlen < 0) +					goto unknown; +			} else +				goto unknown; +			ret  = utf8s_to_utf16s(source + i, charlen, +					       UTF16_LITTLE_ENDIAN, +					       wchar_to, 6); +			if (ret < 0) +				goto unknown; + +			i += charlen; +			dst_char = cpu_to_le16(*wchar_to); +			if (charlen <= 3) +				/* 1-3bytes UTF-8 to 2bytes UTF-16 */ +				put_unaligned(dst_char, &target[j]); +			else if (charlen == 4) { +				/* 4bytes UTF-8(surrogate pair) to 4bytes UTF-16 +				 * 7-8bytes UTF-8(IVS) divided to 2 UTF-16 +				 *   (charlen=3+4 or 4+4) */ +				put_unaligned(dst_char, &target[j]); +				dst_char = cpu_to_le16(*(wchar_to + 1)); +				j++; +				put_unaligned(dst_char, &target[j]); +			} else if (charlen >= 5) { +				/* 5-6bytes UTF-8 to 6bytes UTF-16 */ +				put_unaligned(dst_char, &target[j]); +				dst_char = cpu_to_le16(*(wchar_to + 1)); +				j++; +				put_unaligned(dst_char, &target[j]); +				dst_char = cpu_to_le16(*(wchar_to + 2)); +				j++; +				put_unaligned(dst_char, &target[j]);  			} +			continue; + +unknown: +			dst_char = cpu_to_le16(0x003f); +			charlen = 1;  		} + +ctoUTF16:  		/*  		 * character may take more than one byte in the source string,  		 * but will take exactly two bytes in the target string @@ -456,6 +545,7 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen,  ctoUTF16_out:  	put_unaligned(0, &target[j]); /* Null terminate target unicode string */ +	kfree(wchar_to);  	return j;  } diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index f5089bde3635..0a9fb6b53126 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -469,6 +469,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)  		seq_puts(s, ",nouser_xattr");  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)  		seq_puts(s, ",mapchars"); +	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SFM_CHR) +		seq_puts(s, ",mapposix");  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)  		seq_puts(s, ",sfu");  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index c31ce98c1704..c63fd1dde25b 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -361,11 +361,11 @@ extern int CIFSUnixCreateHardLink(const unsigned int xid,  extern int CIFSUnixCreateSymLink(const unsigned int xid,  			struct cifs_tcon *tcon,  			const char *fromName, const char *toName, -			const struct nls_table *nls_codepage); +			const struct nls_table *nls_codepage, int remap);  extern int CIFSSMBUnixQuerySymLink(const unsigned int xid,  			struct cifs_tcon *tcon,  			const unsigned char *searchName, char **syminfo, -			const struct nls_table *nls_codepage); +			const struct nls_table *nls_codepage, int remap);  extern int CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,  			       __u16 fid, char **symlinkinfo,  			       const struct nls_table *nls_codepage); diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 84650a51c7c4..f26ffbfc64d8 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -2784,7 +2784,7 @@ copyRetry:  int  CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,  		      const char *fromName, const char *toName, -		      const struct nls_table *nls_codepage) +		      const struct nls_table *nls_codepage, int remap)  {  	TRANSACTION2_SPI_REQ *pSMB = NULL;  	TRANSACTION2_SPI_RSP *pSMBr = NULL; @@ -2804,9 +2804,9 @@ createSymLinkRetry:  	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {  		name_len = -		    cifs_strtoUTF16((__le16 *) pSMB->FileName, fromName, -				    /* find define for this maxpathcomponent */ -				    PATH_MAX, nls_codepage); +		    cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName, +				/* find define for this maxpathcomponent */ +					PATH_MAX, nls_codepage, remap);  		name_len++;	/* trailing null */  		name_len *= 2; @@ -2828,9 +2828,9 @@ createSymLinkRetry:  	data_offset = (char *) (&pSMB->hdr.Protocol) + offset;  	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {  		name_len_target = -		    cifs_strtoUTF16((__le16 *) data_offset, toName, PATH_MAX -				    /* find define for this maxpathcomponent */ -				    , nls_codepage); +		    cifsConvertToUTF16((__le16 *) data_offset, toName, +				/* find define for this maxpathcomponent */ +					PATH_MAX, nls_codepage, remap);  		name_len_target++;	/* trailing null */  		name_len_target *= 2;  	} else {	/* BB improve the check for buffer overruns BB */ @@ -3034,7 +3034,7 @@ winCreateHardLinkRetry:  int  CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,  			const unsigned char *searchName, char **symlinkinfo, -			const struct nls_table *nls_codepage) +			const struct nls_table *nls_codepage, int remap)  {  /* SMB_QUERY_FILE_UNIX_LINK */  	TRANSACTION2_QPI_REQ *pSMB = NULL; @@ -3055,8 +3055,9 @@ querySymLinkRetry:  	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {  		name_len = -			cifs_strtoUTF16((__le16 *) pSMB->FileName, searchName, -					PATH_MAX, nls_codepage); +			cifsConvertToUTF16((__le16 *) pSMB->FileName, +					   searchName, PATH_MAX, nls_codepage, +					   remap);  		name_len++;	/* trailing null */  		name_len *= 2;  	} else {	/* BB improve the check for buffer overruns BB */ @@ -4917,7 +4918,7 @@ getDFSRetry:  		strncpy(pSMB->RequestFileName, search_name, name_len);  	} -	if (ses->server && ses->server->sign) +	if (ses->server->sign)  		pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;  	pSMB->hdr.Uid = ses->Suid; diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index f3bfe08e177b..8383d5ea4202 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -386,6 +386,7 @@ cifs_reconnect(struct TCP_Server_Info *server)  		rc = generic_ip_connect(server);  		if (rc) {  			cifs_dbg(FYI, "reconnect error %d\n", rc); +			mutex_unlock(&server->srv_mutex);  			msleep(3000);  		} else {  			atomic_inc(&tcpSesReconnectCount); @@ -393,8 +394,8 @@ cifs_reconnect(struct TCP_Server_Info *server)  			if (server->tcpStatus != CifsExiting)  				server->tcpStatus = CifsNeedNegotiate;  			spin_unlock(&GlobalMid_Lock); +			mutex_unlock(&server->srv_mutex);  		} -		mutex_unlock(&server->srv_mutex);  	} while (server->tcpStatus == CifsNeedReconnect);  	return rc; diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 338d56936f6a..c3eb998a99bd 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -620,8 +620,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode,  		}  		rc = CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args,  					    cifs_sb->local_nls, -					    cifs_sb->mnt_cifs_flags & -						CIFS_MOUNT_MAP_SPECIAL_CHR); +					    cifs_remap(cifs_sb));  		if (rc)  			goto mknod_out; diff --git a/fs/cifs/file.c b/fs/cifs/file.c index cafbf10521d5..3f50cee79df9 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -140,8 +140,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode,  	posix_flags = cifs_posix_convert_flags(f_flags);  	rc = CIFSPOSIXCreate(xid, tcon, posix_flags, mode, pnetfid, presp_data,  			     poplock, full_path, cifs_sb->local_nls, -			     cifs_sb->mnt_cifs_flags & -					CIFS_MOUNT_MAP_SPECIAL_CHR); +			     cifs_remap(cifs_sb));  	cifs_put_tlink(tlink);  	if (rc) @@ -1553,8 +1552,8 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,  		rc = server->ops->mand_unlock_range(cfile, flock, xid);  out: -	if (flock->fl_flags & FL_POSIX) -		posix_lock_file_wait(file, flock); +	if (flock->fl_flags & FL_POSIX && !rc) +		rc = posix_lock_file_wait(file, flock);  	return rc;  } diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 55b58112d122..f621b44cb800 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -373,8 +373,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,  	/* could have done a find first instead but this returns more info */  	rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data, -				  cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & -					CIFS_MOUNT_MAP_SPECIAL_CHR); +				  cifs_sb->local_nls, cifs_remap(cifs_sb));  	cifs_put_tlink(tlink);  	if (!rc) { @@ -402,9 +401,25 @@ int cifs_get_inode_info_unix(struct inode **pinode,  			rc = -ENOMEM;  	} else {  		/* we already have inode, update it */ + +		/* if uniqueid is different, return error */ +		if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM && +		    CIFS_I(*pinode)->uniqueid != fattr.cf_uniqueid)) { +			rc = -ESTALE; +			goto cgiiu_exit; +		} + +		/* if filetype is different, return error */ +		if (unlikely(((*pinode)->i_mode & S_IFMT) != +		    (fattr.cf_mode & S_IFMT))) { +			rc = -ESTALE; +			goto cgiiu_exit; +		} +  		cifs_fattr_to_inode(*pinode, &fattr);  	} +cgiiu_exit:  	return rc;  } @@ -839,6 +854,15 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,  		if (!*inode)  			rc = -ENOMEM;  	} else { +		/* we already have inode, update it */ + +		/* if filetype is different, return error */ +		if (unlikely(((*inode)->i_mode & S_IFMT) != +		    (fattr.cf_mode & S_IFMT))) { +			rc = -ESTALE; +			goto cgii_exit; +		} +  		cifs_fattr_to_inode(*inode, &fattr);  	} @@ -2215,8 +2239,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)  		pTcon = tlink_tcon(tlink);  		rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args,  				    cifs_sb->local_nls, -				    cifs_sb->mnt_cifs_flags & -					CIFS_MOUNT_MAP_SPECIAL_CHR); +				    cifs_remap(cifs_sb));  		cifs_put_tlink(tlink);  	} diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 252e672d5604..e6c707cc62b3 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c @@ -717,7 +717,8 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)  		rc = create_mf_symlink(xid, pTcon, cifs_sb, full_path, symname);  	else if (pTcon->unix_ext)  		rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname, -					   cifs_sb->local_nls); +					   cifs_sb->local_nls, +					   cifs_remap(cifs_sb));  	/* else  	   rc = CIFSCreateReparseSymLink(xid, pTcon, fromName, toName,  					cifs_sb_target->local_nls); */ diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index b4a47237486b..b1eede3678a9 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -90,6 +90,8 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name,  	if (dentry) {  		inode = d_inode(dentry);  		if (inode) { +			if (d_mountpoint(dentry)) +				goto out;  			/*  			 * If we're generating inode numbers, then we don't  			 * want to clobber the existing one with the one that diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index 7bfdd6066276..fc537c29044e 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c @@ -960,7 +960,8 @@ cifs_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,  	/* Check for unix extensions */  	if (cap_unix(tcon->ses)) {  		rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, target_path, -					     cifs_sb->local_nls); +					     cifs_sb->local_nls, +					     cifs_remap(cifs_sb));  		if (rc == -EREMOTE)  			rc = cifs_unix_dfs_readlink(xid, tcon, full_path,  						    target_path, diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 65cd7a84c8bc..54cbe19d9c08 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -110,7 +110,7 @@ smb2_hdr_assemble(struct smb2_hdr *hdr, __le16 smb2_cmd /* command */ ,  	/* GLOBAL_CAP_LARGE_MTU will only be set if dialect > SMB2.02 */  	/* See sections 2.2.4 and 3.2.4.1.5 of MS-SMB2 */ -	if ((tcon->ses) && +	if ((tcon->ses) && (tcon->ses->server) &&  	    (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU))  		hdr->CreditCharge = cpu_to_le16(1);  	/* else CreditCharge MBZ */  | 
