link.c 18 KB

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