aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifsproto.h3
-rw-r--r--fs/cifs/cifssmb.c36
-rw-r--r--fs/cifs/link.c22
3 files changed, 20 insertions, 41 deletions
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 4167716d32f2..7d54a5a4dd55 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -260,8 +260,7 @@ extern int CIFSUnixCreateSymLink(const int xid,
260 const struct nls_table *nls_codepage); 260 const struct nls_table *nls_codepage);
261extern int CIFSSMBUnixQuerySymLink(const int xid, 261extern int CIFSSMBUnixQuerySymLink(const int xid,
262 struct cifsTconInfo *tcon, 262 struct cifsTconInfo *tcon,
263 const unsigned char *searchName, 263 const unsigned char *searchName, char **syminfo,
264 char *syminfo, const int buflen,
265 const struct nls_table *nls_codepage); 264 const struct nls_table *nls_codepage);
266extern int CIFSSMBQueryReparseLinkInfo(const int xid, 265extern int CIFSSMBQueryReparseLinkInfo(const int xid,
267 struct cifsTconInfo *tcon, 266 struct cifsTconInfo *tcon,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index f15848374cfa..dfb8e391d538 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -2382,8 +2382,7 @@ winCreateHardLinkRetry:
2382 2382
2383int 2383int
2384CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon, 2384CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon,
2385 const unsigned char *searchName, 2385 const unsigned char *searchName, char **symlinkinfo,
2386 char *symlinkinfo, const int buflen,
2387 const struct nls_table *nls_codepage) 2386 const struct nls_table *nls_codepage)
2388{ 2387{
2389/* SMB_QUERY_FILE_UNIX_LINK */ 2388/* SMB_QUERY_FILE_UNIX_LINK */
@@ -2393,6 +2392,7 @@ CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon,
2393 int bytes_returned; 2392 int bytes_returned;
2394 int name_len; 2393 int name_len;
2395 __u16 params, byte_count; 2394 __u16 params, byte_count;
2395 char *data_start;
2396 2396
2397 cFYI(1, ("In QPathSymLinkInfo (Unix) for path %s", searchName)); 2397 cFYI(1, ("In QPathSymLinkInfo (Unix) for path %s", searchName));
2398 2398
@@ -2447,30 +2447,22 @@ querySymLinkRetry:
2447 /* decode response */ 2447 /* decode response */
2448 2448
2449 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 2449 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2450 if (rc || (pSMBr->ByteCount < 2))
2451 /* BB also check enough total bytes returned */ 2450 /* BB also check enough total bytes returned */
2452 rc = -EIO; /* bad smb */ 2451 if (rc || (pSMBr->ByteCount < 2))
2452 rc = -EIO;
2453 else { 2453 else {
2454 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 2454 u16 count = le16_to_cpu(pSMBr->t2.DataCount);
2455 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 2455
2456 data_start = ((char *) &pSMBr->hdr.Protocol) +
2457 le16_to_cpu(pSMBr->t2.DataOffset);
2456 2458
2457 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
2458 name_len = UniStrnlen((wchar_t *) ((char *)
2459 &pSMBr->hdr.Protocol + data_offset),
2460 min_t(const int, buflen, count) / 2);
2461 /* BB FIXME investigate remapping reserved chars here */ 2459 /* BB FIXME investigate remapping reserved chars here */
2462 cifs_strfromUCS_le(symlinkinfo, 2460 *symlinkinfo = cifs_strndup(data_start, count,
2463 (__le16 *) ((char *)&pSMBr->hdr.Protocol 2461 pSMBr->hdr.Flags2 &
2464 + data_offset), 2462 SMBFLG2_UNICODE,
2465 name_len, nls_codepage); 2463 nls_codepage);
2466 } else { 2464 if (!symlinkinfo)
2467 strncpy(symlinkinfo, 2465 rc = -ENOMEM;
2468 (char *) &pSMBr->hdr.Protocol +
2469 data_offset,
2470 min_t(const int, buflen, count));
2471 }
2472 symlinkinfo[buflen] = 0;
2473 /* just in case so calling code does not go off the end of buffer */
2474 } 2466 }
2475 } 2467 }
2476 cifs_buf_release(pSMB); 2468 cifs_buf_release(pSMB);
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 63f644000ce5..e17a092f43ec 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -119,16 +119,11 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
119 full_path = build_path_from_dentry(direntry); 119 full_path = build_path_from_dentry(direntry);
120 120
121 if (!full_path) 121 if (!full_path)
122 goto out_no_free; 122 goto out;
123 123
124 cFYI(1, ("Full path: %s inode = 0x%p", full_path, inode)); 124 cFYI(1, ("Full path: %s inode = 0x%p", full_path, inode));
125 cifs_sb = CIFS_SB(inode->i_sb); 125 cifs_sb = CIFS_SB(inode->i_sb);
126 pTcon = cifs_sb->tcon; 126 pTcon = cifs_sb->tcon;
127 target_path = kmalloc(PATH_MAX, GFP_KERNEL);
128 if (!target_path) {
129 target_path = ERR_PTR(-ENOMEM);
130 goto out;
131 }
132 127
133 /* We could change this to: 128 /* We could change this to:
134 if (pTcon->unix_ext) 129 if (pTcon->unix_ext)
@@ -138,8 +133,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
138 133
139 if (pTcon->ses->capabilities & CAP_UNIX) 134 if (pTcon->ses->capabilities & CAP_UNIX)
140 rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path, 135 rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path,
141 target_path, 136 &target_path,
142 PATH_MAX-1,
143 cifs_sb->local_nls); 137 cifs_sb->local_nls);
144 else { 138 else {
145 /* BB add read reparse point symlink code here */ 139 /* BB add read reparse point symlink code here */
@@ -148,22 +142,16 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
148 /* BB Add MAC style xsymlink check here if enabled */ 142 /* BB Add MAC style xsymlink check here if enabled */
149 } 143 }
150 144
151 if (rc == 0) { 145 if (rc != 0) {
152
153/* BB Add special case check for Samba DFS symlinks */
154
155 target_path[PATH_MAX-1] = 0;
156 } else {
157 kfree(target_path); 146 kfree(target_path);
158 target_path = ERR_PTR(rc); 147 target_path = ERR_PTR(rc);
159 } 148 }
160 149
161out:
162 kfree(full_path); 150 kfree(full_path);
163out_no_free: 151out:
164 FreeXid(xid); 152 FreeXid(xid);
165 nd_set_link(nd, target_path); 153 nd_set_link(nd, target_path);
166 return NULL; /* No cookie */ 154 return NULL;
167} 155}
168 156
169int 157int