diff options
Diffstat (limited to 'fs/cifs/link.c')
-rw-r--r-- | fs/cifs/link.c | 61 |
1 files changed, 20 insertions, 41 deletions
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 500bc77a786e..77dbd55795d8 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
@@ -237,55 +237,36 @@ create_mf_symlink(const unsigned int xid, struct cifs_tcon *tcon, | |||
237 | 237 | ||
238 | static int | 238 | static int |
239 | query_mf_symlink(const unsigned int xid, struct cifs_tcon *tcon, | 239 | query_mf_symlink(const unsigned int xid, struct cifs_tcon *tcon, |
240 | const unsigned char *searchName, char **symlinkinfo, | 240 | struct cifs_sb_info *cifs_sb, const unsigned char *path, |
241 | const struct nls_table *nls_codepage, int remap) | 241 | char **symlinkinfo) |
242 | { | 242 | { |
243 | int rc; | 243 | int rc; |
244 | int oplock = 0; | 244 | u8 *buf = NULL; |
245 | __u16 netfid = 0; | ||
246 | u8 *buf; | ||
247 | char *pbuf; | ||
248 | unsigned int bytes_read = 0; | ||
249 | int buf_type = CIFS_NO_BUFFER; | ||
250 | unsigned int link_len = 0; | 245 | unsigned int link_len = 0; |
251 | struct cifs_io_parms io_parms; | 246 | unsigned int bytes_read = 0; |
252 | FILE_ALL_INFO file_info; | ||
253 | |||
254 | rc = CIFSSMBOpen(xid, tcon, searchName, FILE_OPEN, GENERIC_READ, | ||
255 | CREATE_NOT_DIR, &netfid, &oplock, &file_info, | ||
256 | nls_codepage, remap); | ||
257 | if (rc != 0) | ||
258 | return rc; | ||
259 | |||
260 | if (file_info.EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) { | ||
261 | CIFSSMBClose(xid, tcon, netfid); | ||
262 | /* it's not a symlink */ | ||
263 | return -EINVAL; | ||
264 | } | ||
265 | 247 | ||
266 | buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); | 248 | buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); |
267 | if (!buf) | 249 | if (!buf) |
268 | return -ENOMEM; | 250 | return -ENOMEM; |
269 | pbuf = buf; | ||
270 | io_parms.netfid = netfid; | ||
271 | io_parms.pid = current->tgid; | ||
272 | io_parms.tcon = tcon; | ||
273 | io_parms.offset = 0; | ||
274 | io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE; | ||
275 | 251 | ||
276 | rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type); | 252 | if (tcon->ses->server->ops->query_mf_symlink) |
277 | CIFSSMBClose(xid, tcon, netfid); | 253 | rc = tcon->ses->server->ops->query_mf_symlink(xid, tcon, |
278 | if (rc != 0) { | 254 | cifs_sb, path, buf, &bytes_read); |
279 | kfree(buf); | 255 | else |
280 | return rc; | 256 | rc = -ENOSYS; |
257 | |||
258 | if (rc) | ||
259 | goto out; | ||
260 | |||
261 | if (bytes_read == 0) { /* not a symlink */ | ||
262 | rc = -EINVAL; | ||
263 | goto out; | ||
281 | } | 264 | } |
282 | 265 | ||
283 | rc = parse_mf_symlink(buf, bytes_read, &link_len, symlinkinfo); | 266 | rc = parse_mf_symlink(buf, bytes_read, &link_len, symlinkinfo); |
267 | out: | ||
284 | kfree(buf); | 268 | kfree(buf); |
285 | if (rc != 0) | 269 | return rc; |
286 | return rc; | ||
287 | |||
288 | return 0; | ||
289 | } | 270 | } |
290 | 271 | ||
291 | bool | 272 | bool |
@@ -517,10 +498,8 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd) | |||
517 | * and fallback to UNIX Extensions Symlinks. | 498 | * and fallback to UNIX Extensions Symlinks. |
518 | */ | 499 | */ |
519 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) | 500 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) |
520 | rc = query_mf_symlink(xid, tcon, full_path, &target_path, | 501 | rc = query_mf_symlink(xid, tcon, cifs_sb, full_path, |
521 | cifs_sb->local_nls, | 502 | &target_path); |
522 | cifs_sb->mnt_cifs_flags & | ||
523 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
524 | 503 | ||
525 | if ((rc != 0) && cap_unix(tcon->ses)) | 504 | if ((rc != 0) && cap_unix(tcon->ses)) |
526 | rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path, | 505 | rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path, |