link.c 18 KB

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