link.c 15 KB

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