link.c 15 KB

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