link.c 18 KB

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