1 // SPDX-License-Identifier: LGPL-2.1
2 /*
3 *
4 * Copyright (C) International Business Machines Corp., 2002,2008
5 * Author(s): Steve French (sfrench@us.ibm.com)
6 *
7 */
8 #include <crypto/md5.h>
9 #include <linux/fs.h>
10 #include <linux/stat.h>
11 #include <linux/slab.h>
12 #include <linux/namei.h>
13 #include "cifsfs.h"
14 #include "cifspdu.h"
15 #include "cifsglob.h"
16 #include "cifsproto.h"
17 #include "cifs_debug.h"
18 #include "cifs_fs_sb.h"
19 #include "cifs_unicode.h"
20 #include "smb2proto.h"
21 #include "cifs_ioctl.h"
22 #include "fs_context.h"
23 #include "reparse.h"
24
25 /*
26 * M-F Symlink Functions - Begin
27 */
28
29 #define CIFS_MF_SYMLINK_LEN_OFFSET (4+1)
30 #define CIFS_MF_SYMLINK_MD5_OFFSET (CIFS_MF_SYMLINK_LEN_OFFSET+(4+1))
31 #define CIFS_MF_SYMLINK_LINK_OFFSET (CIFS_MF_SYMLINK_MD5_OFFSET+(32+1))
32 #define CIFS_MF_SYMLINK_LINK_MAXLEN (1024)
33 #define CIFS_MF_SYMLINK_FILE_SIZE \
34 (CIFS_MF_SYMLINK_LINK_OFFSET + CIFS_MF_SYMLINK_LINK_MAXLEN)
35
36 #define CIFS_MF_SYMLINK_LEN_FORMAT "XSym\n%04u\n"
37 #define CIFS_MF_SYMLINK_MD5_FORMAT "%16phN\n"
38 #define CIFS_MF_SYMLINK_MD5_ARGS(md5_hash) md5_hash
39
40 static int
parse_mf_symlink(const u8 * buf,unsigned int buf_len,unsigned int * _link_len,char ** _link_str)41 parse_mf_symlink(const u8 *buf, unsigned int buf_len, unsigned int *_link_len,
42 char **_link_str)
43 {
44 int rc;
45 unsigned int link_len;
46 const char *md5_str1;
47 const char *link_str;
48 u8 md5_hash[16];
49 char md5_str2[34];
50
51 if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE)
52 return -EINVAL;
53
54 md5_str1 = (const char *)&buf[CIFS_MF_SYMLINK_MD5_OFFSET];
55 link_str = (const char *)&buf[CIFS_MF_SYMLINK_LINK_OFFSET];
56
57 rc = sscanf(buf, CIFS_MF_SYMLINK_LEN_FORMAT, &link_len);
58 if (rc != 1)
59 return -EINVAL;
60
61 if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN)
62 return -EINVAL;
63
64 md5(link_str, link_len, md5_hash);
65
66 scnprintf(md5_str2, sizeof(md5_str2),
67 CIFS_MF_SYMLINK_MD5_FORMAT,
68 CIFS_MF_SYMLINK_MD5_ARGS(md5_hash));
69
70 if (strncmp(md5_str1, md5_str2, 17) != 0)
71 return -EINVAL;
72
73 if (_link_str) {
74 *_link_str = kstrndup(link_str, link_len, GFP_KERNEL);
75 if (!*_link_str)
76 return -ENOMEM;
77 }
78
79 *_link_len = link_len;
80 return 0;
81 }
82
83 static int
format_mf_symlink(u8 * buf,unsigned int buf_len,const char * link_str)84 format_mf_symlink(u8 *buf, unsigned int buf_len, const char *link_str)
85 {
86 unsigned int link_len;
87 unsigned int ofs;
88 u8 md5_hash[16];
89
90 if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE)
91 return -EINVAL;
92
93 link_len = strlen(link_str);
94
95 if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN)
96 return -ENAMETOOLONG;
97
98 md5(link_str, link_len, md5_hash);
99
100 scnprintf(buf, buf_len,
101 CIFS_MF_SYMLINK_LEN_FORMAT CIFS_MF_SYMLINK_MD5_FORMAT,
102 link_len,
103 CIFS_MF_SYMLINK_MD5_ARGS(md5_hash));
104
105 ofs = CIFS_MF_SYMLINK_LINK_OFFSET;
106 memcpy(buf + ofs, link_str, link_len);
107
108 ofs += link_len;
109 if (ofs < CIFS_MF_SYMLINK_FILE_SIZE) {
110 buf[ofs] = '\n';
111 ofs++;
112 }
113
114 while (ofs < CIFS_MF_SYMLINK_FILE_SIZE) {
115 buf[ofs] = ' ';
116 ofs++;
117 }
118
119 return 0;
120 }
121
122 bool
couldbe_mf_symlink(const struct cifs_fattr * fattr)123 couldbe_mf_symlink(const struct cifs_fattr *fattr)
124 {
125 if (!S_ISREG(fattr->cf_mode))
126 /* it's not a symlink */
127 return false;
128
129 if (fattr->cf_eof != CIFS_MF_SYMLINK_FILE_SIZE)
130 /* it's not a symlink */
131 return false;
132
133 return true;
134 }
135
136 static int
create_mf_symlink(const unsigned int xid,struct cifs_tcon * tcon,struct cifs_sb_info * cifs_sb,const char * fromName,const char * toName)137 create_mf_symlink(const unsigned int xid, struct cifs_tcon *tcon,
138 struct cifs_sb_info *cifs_sb, const char *fromName,
139 const char *toName)
140 {
141 int rc;
142 u8 *buf;
143 unsigned int bytes_written = 0;
144
145 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
146 if (!buf)
147 return -ENOMEM;
148
149 rc = format_mf_symlink(buf, CIFS_MF_SYMLINK_FILE_SIZE, toName);
150 if (rc)
151 goto out;
152
153 if (tcon->ses->server->ops->create_mf_symlink)
154 rc = tcon->ses->server->ops->create_mf_symlink(xid, tcon,
155 cifs_sb, fromName, buf, &bytes_written);
156 else
157 rc = -EOPNOTSUPP;
158
159 if (rc)
160 goto out;
161
162 if (bytes_written != CIFS_MF_SYMLINK_FILE_SIZE)
163 rc = -EIO;
164 out:
165 kfree(buf);
166 return rc;
167 }
168
169 int
check_mf_symlink(unsigned int xid,struct cifs_tcon * tcon,struct cifs_sb_info * cifs_sb,struct cifs_fattr * fattr,const unsigned char * path)170 check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
171 struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
172 const unsigned char *path)
173 {
174 int rc;
175 u8 *buf = NULL;
176 unsigned int link_len = 0;
177 unsigned int bytes_read = 0;
178 char *symlink = NULL;
179
180 if (!couldbe_mf_symlink(fattr))
181 /* it's not a symlink */
182 return 0;
183
184 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
185 if (!buf)
186 return -ENOMEM;
187
188 if (tcon->ses->server->ops->query_mf_symlink)
189 rc = tcon->ses->server->ops->query_mf_symlink(xid, tcon,
190 cifs_sb, path, buf, &bytes_read);
191 else
192 rc = -ENOSYS;
193
194 if (rc)
195 goto out;
196
197 if (bytes_read == 0) /* not a symlink */
198 goto out;
199
200 rc = parse_mf_symlink(buf, bytes_read, &link_len, &symlink);
201 if (rc == -EINVAL) {
202 /* it's not a symlink */
203 rc = 0;
204 goto out;
205 }
206
207 if (rc != 0)
208 goto out;
209
210 /* it is a symlink */
211 fattr->cf_eof = link_len;
212 fattr->cf_mode &= ~S_IFMT;
213 fattr->cf_mode |= S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
214 fattr->cf_dtype = DT_LNK;
215 fattr->cf_symlink_target = symlink;
216 out:
217 kfree(buf);
218 return rc;
219 }
220
221 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
222 /*
223 * SMB 1.0 Protocol specific functions
224 */
225
226 int
cifs_query_mf_symlink(unsigned int xid,struct cifs_tcon * tcon,struct cifs_sb_info * cifs_sb,const unsigned char * path,char * pbuf,unsigned int * pbytes_read)227 cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
228 struct cifs_sb_info *cifs_sb, const unsigned char *path,
229 char *pbuf, unsigned int *pbytes_read)
230 {
231 int rc;
232 int oplock = 0;
233 struct cifs_fid fid;
234 struct cifs_open_parms oparms;
235 struct cifs_io_parms io_parms = {0};
236 int buf_type = CIFS_NO_BUFFER;
237 struct cifs_open_info_data query_data;
238
239 oparms = (struct cifs_open_parms) {
240 .tcon = tcon,
241 .cifs_sb = cifs_sb,
242 .desired_access = GENERIC_READ,
243 .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR),
244 .disposition = FILE_OPEN,
245 .path = path,
246 .fid = &fid,
247 };
248
249 rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, &query_data);
250 if (rc)
251 return rc;
252
253 if (query_data.fi.EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) {
254 rc = -ENOENT;
255 /* it's not a symlink */
256 goto out;
257 }
258
259 io_parms.netfid = fid.netfid;
260 io_parms.pid = current->tgid;
261 io_parms.tcon = tcon;
262 io_parms.offset = 0;
263 io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
264
265 rc = CIFSSMBRead(xid, &io_parms, pbytes_read, &pbuf, &buf_type);
266 out:
267 CIFSSMBClose(xid, tcon, fid.netfid);
268 return rc;
269 }
270
271 int
cifs_create_mf_symlink(unsigned int xid,struct cifs_tcon * tcon,struct cifs_sb_info * cifs_sb,const unsigned char * path,char * pbuf,unsigned int * pbytes_written)272 cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
273 struct cifs_sb_info *cifs_sb, const unsigned char *path,
274 char *pbuf, unsigned int *pbytes_written)
275 {
276 int rc;
277 int oplock = 0;
278 struct cifs_fid fid;
279 struct cifs_open_parms oparms;
280 struct cifs_io_parms io_parms = {0};
281
282 oparms = (struct cifs_open_parms) {
283 .tcon = tcon,
284 .cifs_sb = cifs_sb,
285 .desired_access = GENERIC_WRITE,
286 .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR),
287 .disposition = FILE_CREATE,
288 .path = path,
289 .fid = &fid,
290 };
291
292 rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, NULL);
293 if (rc)
294 return rc;
295
296 io_parms.netfid = fid.netfid;
297 io_parms.pid = current->tgid;
298 io_parms.tcon = tcon;
299 io_parms.offset = 0;
300 io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
301
302 rc = CIFSSMBWrite(xid, &io_parms, pbytes_written, pbuf);
303 CIFSSMBClose(xid, tcon, fid.netfid);
304 return rc;
305 }
306 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
307
308 /*
309 * SMB 2.1/SMB3 Protocol specific functions
310 */
311 int
smb3_query_mf_symlink(unsigned int xid,struct cifs_tcon * tcon,struct cifs_sb_info * cifs_sb,const unsigned char * path,char * pbuf,unsigned int * pbytes_read)312 smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
313 struct cifs_sb_info *cifs_sb, const unsigned char *path,
314 char *pbuf, unsigned int *pbytes_read)
315 {
316 int rc;
317 struct cifs_fid fid;
318 struct cifs_open_parms oparms;
319 struct cifs_io_parms io_parms = {0};
320 int buf_type = CIFS_NO_BUFFER;
321 __le16 *utf16_path;
322 __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
323 struct smb2_file_all_info *pfile_info = NULL;
324
325 oparms = (struct cifs_open_parms) {
326 .tcon = tcon,
327 .cifs_sb = cifs_sb,
328 .path = path,
329 .desired_access = GENERIC_READ,
330 .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR),
331 .disposition = FILE_OPEN,
332 .fid = &fid,
333 };
334
335 utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
336 if (utf16_path == NULL)
337 return -ENOMEM;
338
339 pfile_info = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2,
340 GFP_KERNEL);
341
342 if (pfile_info == NULL) {
343 kfree(utf16_path);
344 return -ENOMEM;
345 }
346
347 rc = SMB2_open(xid, &oparms, utf16_path, &oplock, pfile_info, NULL,
348 NULL, NULL);
349 if (rc)
350 goto qmf_out_open_fail;
351
352 if (pfile_info->EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) {
353 /* it's not a symlink */
354 rc = -ENOENT; /* Is there a better rc to return? */
355 goto qmf_out;
356 }
357
358 io_parms.netfid = fid.netfid;
359 io_parms.pid = current->tgid;
360 io_parms.tcon = tcon;
361 io_parms.offset = 0;
362 io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
363 io_parms.persistent_fid = fid.persistent_fid;
364 io_parms.volatile_fid = fid.volatile_fid;
365 rc = SMB2_read(xid, &io_parms, pbytes_read, &pbuf, &buf_type);
366 qmf_out:
367 SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
368 qmf_out_open_fail:
369 kfree(utf16_path);
370 kfree(pfile_info);
371 return rc;
372 }
373
374 int
smb3_create_mf_symlink(unsigned int xid,struct cifs_tcon * tcon,struct cifs_sb_info * cifs_sb,const unsigned char * path,char * pbuf,unsigned int * pbytes_written)375 smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
376 struct cifs_sb_info *cifs_sb, const unsigned char *path,
377 char *pbuf, unsigned int *pbytes_written)
378 {
379 int rc;
380 struct cifs_fid fid;
381 struct cifs_open_parms oparms;
382 struct cifs_io_parms io_parms = {0};
383 __le16 *utf16_path;
384 __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
385 struct kvec iov[2];
386
387 cifs_dbg(FYI, "%s: path: %s\n", __func__, path);
388
389 utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
390 if (!utf16_path)
391 return -ENOMEM;
392
393 oparms = (struct cifs_open_parms) {
394 .tcon = tcon,
395 .cifs_sb = cifs_sb,
396 .path = path,
397 .desired_access = GENERIC_WRITE,
398 .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR),
399 .disposition = FILE_CREATE,
400 .fid = &fid,
401 .mode = 0644,
402 };
403
404 rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL,
405 NULL, NULL);
406 if (rc) {
407 kfree(utf16_path);
408 return rc;
409 }
410
411 io_parms.netfid = fid.netfid;
412 io_parms.pid = current->tgid;
413 io_parms.tcon = tcon;
414 io_parms.offset = 0;
415 io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
416 io_parms.persistent_fid = fid.persistent_fid;
417 io_parms.volatile_fid = fid.volatile_fid;
418
419 /* iov[0] is reserved for smb header */
420 iov[1].iov_base = pbuf;
421 iov[1].iov_len = CIFS_MF_SYMLINK_FILE_SIZE;
422
423 rc = SMB2_write(xid, &io_parms, pbytes_written, iov, 1);
424
425 /* Make sure we wrote all of the symlink data */
426 if ((rc == 0) && (*pbytes_written != CIFS_MF_SYMLINK_FILE_SIZE))
427 rc = -EIO;
428
429 SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
430
431 kfree(utf16_path);
432 return rc;
433 }
434
435 /*
436 * M-F Symlink Functions - End
437 */
438
439 int
cifs_hardlink(struct dentry * old_file,struct inode * inode,struct dentry * direntry)440 cifs_hardlink(struct dentry *old_file, struct inode *inode,
441 struct dentry *direntry)
442 {
443 int rc = -EACCES;
444 unsigned int xid;
445 const char *from_name, *to_name;
446 void *page1, *page2;
447 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
448 struct tcon_link *tlink;
449 struct cifs_tcon *tcon;
450 struct TCP_Server_Info *server;
451 struct cifsInodeInfo *cifsInode;
452
453 if (unlikely(cifs_forced_shutdown(cifs_sb)))
454 return -EIO;
455
456 tlink = cifs_sb_tlink(cifs_sb);
457 if (IS_ERR(tlink))
458 return PTR_ERR(tlink);
459 tcon = tlink_tcon(tlink);
460
461 xid = get_xid();
462 page1 = alloc_dentry_path();
463 page2 = alloc_dentry_path();
464
465 from_name = build_path_from_dentry(old_file, page1);
466 if (IS_ERR(from_name)) {
467 rc = PTR_ERR(from_name);
468 goto cifs_hl_exit;
469 }
470 to_name = build_path_from_dentry(direntry, page2);
471 if (IS_ERR(to_name)) {
472 rc = PTR_ERR(to_name);
473 goto cifs_hl_exit;
474 }
475
476 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
477 if (tcon->unix_ext)
478 rc = CIFSUnixCreateHardLink(xid, tcon, from_name, to_name,
479 cifs_sb->local_nls,
480 cifs_remap(cifs_sb));
481 else {
482 #else
483 {
484 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
485 server = tcon->ses->server;
486 if (!server->ops->create_hardlink) {
487 rc = -ENOSYS;
488 goto cifs_hl_exit;
489 }
490 rc = server->ops->create_hardlink(xid, tcon, old_file,
491 from_name, to_name, cifs_sb);
492 if ((rc == -EIO) || (rc == -EINVAL))
493 rc = -EOPNOTSUPP;
494 }
495
496 d_drop(direntry); /* force new lookup from server of target */
497
498 /*
499 * if source file is cached (oplocked) revalidate will not go to server
500 * until the file is closed or oplock broken so update nlinks locally
501 */
502 if (d_really_is_positive(old_file)) {
503 cifsInode = CIFS_I(d_inode(old_file));
504 if (rc == 0) {
505 spin_lock(&d_inode(old_file)->i_lock);
506 inc_nlink(d_inode(old_file));
507 spin_unlock(&d_inode(old_file)->i_lock);
508
509 /*
510 * parent dir timestamps will update from srv within a
511 * second, would it really be worth it to set the parent
512 * dir cifs inode time to zero to force revalidate
513 * (faster) for it too?
514 */
515 }
516 /*
517 * if not oplocked will force revalidate to get info on source
518 * file from srv. Note Samba server prior to 4.2 has bug -
519 * not updating src file ctime on hardlinks but Windows servers
520 * handle it properly
521 */
522 cifsInode->time = 0;
523
524 /*
525 * Will update parent dir timestamps from srv within a second.
526 * Would it really be worth it to set the parent dir (cifs
527 * inode) time field to zero to force revalidate on parent
528 * directory faster ie
529 *
530 * CIFS_I(inode)->time = 0;
531 */
532 }
533
534 cifs_hl_exit:
535 free_dentry_path(page1);
536 free_dentry_path(page2);
537 free_xid(xid);
538 cifs_put_tlink(tlink);
539 return rc;
540 }
541
542 int
543 cifs_symlink(struct mnt_idmap *idmap, struct inode *inode,
544 struct dentry *direntry, const char *symname)
545 {
546 int rc = -EOPNOTSUPP;
547 unsigned int xid;
548 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
549 struct tcon_link *tlink;
550 struct cifs_tcon *pTcon;
551 const char *full_path;
552 void *page;
553 struct inode *newinode = NULL;
554
555 if (unlikely(cifs_forced_shutdown(cifs_sb)))
556 return -EIO;
557
558 page = alloc_dentry_path();
559 if (!page)
560 return -ENOMEM;
561
562 xid = get_xid();
563
564 tlink = cifs_sb_tlink(cifs_sb);
565 if (IS_ERR(tlink)) {
566 rc = PTR_ERR(tlink);
567 /* BB could be clearer if skipped put_tlink on error here, but harmless */
568 goto symlink_exit;
569 }
570 pTcon = tlink_tcon(tlink);
571
572 full_path = build_path_from_dentry(direntry, page);
573 if (IS_ERR(full_path)) {
574 rc = PTR_ERR(full_path);
575 goto symlink_exit;
576 }
577
578 cifs_dbg(FYI, "Full path: %s\n", full_path);
579 cifs_dbg(FYI, "symname is %s\n", symname);
580
581 /* BB what if DFS and this volume is on different share? BB */
582 rc = -EOPNOTSUPP;
583 switch (cifs_symlink_type(cifs_sb)) {
584 case CIFS_SYMLINK_TYPE_UNIX:
585 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
586 if (pTcon->unix_ext) {
587 rc = CIFSUnixCreateSymLink(xid, pTcon, full_path,
588 symname,
589 cifs_sb->local_nls,
590 cifs_remap(cifs_sb));
591 }
592 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
593 break;
594
595 case CIFS_SYMLINK_TYPE_MFSYMLINKS:
596 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
597 rc = create_mf_symlink(xid, pTcon, cifs_sb,
598 full_path, symname);
599 }
600 break;
601
602 case CIFS_SYMLINK_TYPE_SFU:
603 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
604 rc = __cifs_sfu_make_node(xid, inode, direntry, pTcon,
605 full_path, S_IFLNK,
606 0, symname);
607 }
608 break;
609
610 case CIFS_SYMLINK_TYPE_NATIVE:
611 case CIFS_SYMLINK_TYPE_NFS:
612 case CIFS_SYMLINK_TYPE_WSL:
613 if (CIFS_REPARSE_SUPPORT(pTcon)) {
614 rc = create_reparse_symlink(xid, inode, direntry, pTcon,
615 full_path, symname);
616 goto symlink_exit;
617 }
618 break;
619 default:
620 break;
621 }
622
623 if (rc == 0) {
624 if (pTcon->posix_extensions) {
625 rc = smb311_posix_get_inode_info(&newinode, full_path,
626 NULL, inode->i_sb, xid);
627 } else if (pTcon->unix_ext) {
628 rc = cifs_get_inode_info_unix(&newinode, full_path,
629 inode->i_sb, xid);
630 } else {
631 rc = cifs_get_inode_info(&newinode, full_path, NULL,
632 inode->i_sb, xid, NULL);
633 }
634
635 if (rc != 0) {
636 cifs_dbg(FYI, "Create symlink ok, getinodeinfo fail rc = %d\n",
637 rc);
638 } else {
639 d_instantiate(direntry, newinode);
640 }
641 }
642 symlink_exit:
643 free_dentry_path(page);
644 cifs_put_tlink(tlink);
645 free_xid(xid);
646 return rc;
647 }
648