link.c 17 KB

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