link.c 17 KB

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