xfs_symlink.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2000-2006 Silicon Graphics, Inc.
  4. * Copyright (c) 2012-2013 Red Hat, Inc.
  5. * All rights reserved.
  6. */
  7. #include "xfs.h"
  8. #include "xfs_shared.h"
  9. #include "xfs_fs.h"
  10. #include "xfs_format.h"
  11. #include "xfs_log_format.h"
  12. #include "xfs_trans_resv.h"
  13. #include "xfs_bit.h"
  14. #include "xfs_mount.h"
  15. #include "xfs_da_format.h"
  16. #include "xfs_da_btree.h"
  17. #include "xfs_defer.h"
  18. #include "xfs_dir2.h"
  19. #include "xfs_inode.h"
  20. #include "xfs_ialloc.h"
  21. #include "xfs_alloc.h"
  22. #include "xfs_bmap.h"
  23. #include "xfs_bmap_btree.h"
  24. #include "xfs_bmap_util.h"
  25. #include "xfs_error.h"
  26. #include "xfs_quota.h"
  27. #include "xfs_trans_space.h"
  28. #include "xfs_trace.h"
  29. #include "xfs_symlink.h"
  30. #include "xfs_trans.h"
  31. #include "xfs_log.h"
  32. /* ----- Kernel only functions below ----- */
  33. int
  34. xfs_readlink_bmap_ilocked(
  35. struct xfs_inode *ip,
  36. char *link)
  37. {
  38. struct xfs_mount *mp = ip->i_mount;
  39. struct xfs_bmbt_irec mval[XFS_SYMLINK_MAPS];
  40. struct xfs_buf *bp;
  41. xfs_daddr_t d;
  42. char *cur_chunk;
  43. int pathlen = ip->i_d.di_size;
  44. int nmaps = XFS_SYMLINK_MAPS;
  45. int byte_cnt;
  46. int n;
  47. int error = 0;
  48. int fsblocks = 0;
  49. int offset;
  50. ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
  51. fsblocks = xfs_symlink_blocks(mp, pathlen);
  52. error = xfs_bmapi_read(ip, 0, fsblocks, mval, &nmaps, 0);
  53. if (error)
  54. goto out;
  55. offset = 0;
  56. for (n = 0; n < nmaps; n++) {
  57. d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
  58. byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
  59. bp = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), 0,
  60. &xfs_symlink_buf_ops);
  61. if (!bp)
  62. return -ENOMEM;
  63. error = bp->b_error;
  64. if (error) {
  65. xfs_buf_ioerror_alert(bp, __func__);
  66. xfs_buf_relse(bp);
  67. /* bad CRC means corrupted metadata */
  68. if (error == -EFSBADCRC)
  69. error = -EFSCORRUPTED;
  70. goto out;
  71. }
  72. byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
  73. if (pathlen < byte_cnt)
  74. byte_cnt = pathlen;
  75. cur_chunk = bp->b_addr;
  76. if (xfs_sb_version_hascrc(&mp->m_sb)) {
  77. if (!xfs_symlink_hdr_ok(ip->i_ino, offset,
  78. byte_cnt, bp)) {
  79. error = -EFSCORRUPTED;
  80. xfs_alert(mp,
  81. "symlink header does not match required off/len/owner (0x%x/Ox%x,0x%llx)",
  82. offset, byte_cnt, ip->i_ino);
  83. xfs_buf_relse(bp);
  84. goto out;
  85. }
  86. cur_chunk += sizeof(struct xfs_dsymlink_hdr);
  87. }
  88. memcpy(link + offset, cur_chunk, byte_cnt);
  89. pathlen -= byte_cnt;
  90. offset += byte_cnt;
  91. xfs_buf_relse(bp);
  92. }
  93. ASSERT(pathlen == 0);
  94. link[ip->i_d.di_size] = '\0';
  95. error = 0;
  96. out:
  97. return error;
  98. }
  99. int
  100. xfs_readlink(
  101. struct xfs_inode *ip,
  102. char *link)
  103. {
  104. struct xfs_mount *mp = ip->i_mount;
  105. xfs_fsize_t pathlen;
  106. int error = 0;
  107. trace_xfs_readlink(ip);
  108. ASSERT(!(ip->i_df.if_flags & XFS_IFINLINE));
  109. if (XFS_FORCED_SHUTDOWN(mp))
  110. return -EIO;
  111. xfs_ilock(ip, XFS_ILOCK_SHARED);
  112. pathlen = ip->i_d.di_size;
  113. if (!pathlen)
  114. goto out;
  115. if (pathlen < 0 || pathlen > XFS_SYMLINK_MAXLEN) {
  116. xfs_alert(mp, "%s: inode (%llu) bad symlink length (%lld)",
  117. __func__, (unsigned long long) ip->i_ino,
  118. (long long) pathlen);
  119. ASSERT(0);
  120. error = -EFSCORRUPTED;
  121. goto out;
  122. }
  123. error = xfs_readlink_bmap_ilocked(ip, link);
  124. out:
  125. xfs_iunlock(ip, XFS_ILOCK_SHARED);
  126. return error;
  127. }
  128. int
  129. xfs_symlink(
  130. struct xfs_inode *dp,
  131. struct xfs_name *link_name,
  132. const char *target_path,
  133. umode_t mode,
  134. struct xfs_inode **ipp)
  135. {
  136. struct xfs_mount *mp = dp->i_mount;
  137. struct xfs_trans *tp = NULL;
  138. struct xfs_inode *ip = NULL;
  139. int error = 0;
  140. int pathlen;
  141. struct xfs_defer_ops dfops;
  142. xfs_fsblock_t first_block;
  143. bool unlock_dp_on_error = false;
  144. xfs_fileoff_t first_fsb;
  145. xfs_filblks_t fs_blocks;
  146. int nmaps;
  147. struct xfs_bmbt_irec mval[XFS_SYMLINK_MAPS];
  148. xfs_daddr_t d;
  149. const char *cur_chunk;
  150. int byte_cnt;
  151. int n;
  152. xfs_buf_t *bp;
  153. prid_t prid;
  154. struct xfs_dquot *udqp = NULL;
  155. struct xfs_dquot *gdqp = NULL;
  156. struct xfs_dquot *pdqp = NULL;
  157. uint resblks;
  158. *ipp = NULL;
  159. trace_xfs_symlink(dp, link_name);
  160. if (XFS_FORCED_SHUTDOWN(mp))
  161. return -EIO;
  162. /*
  163. * Check component lengths of the target path name.
  164. */
  165. pathlen = strlen(target_path);
  166. if (pathlen >= XFS_SYMLINK_MAXLEN) /* total string too long */
  167. return -ENAMETOOLONG;
  168. udqp = gdqp = NULL;
  169. prid = xfs_get_initial_prid(dp);
  170. /*
  171. * Make sure that we have allocated dquot(s) on disk.
  172. */
  173. error = xfs_qm_vop_dqalloc(dp,
  174. xfs_kuid_to_uid(current_fsuid()),
  175. xfs_kgid_to_gid(current_fsgid()), prid,
  176. XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT,
  177. &udqp, &gdqp, &pdqp);
  178. if (error)
  179. return error;
  180. /*
  181. * The symlink will fit into the inode data fork?
  182. * There can't be any attributes so we get the whole variable part.
  183. */
  184. if (pathlen <= XFS_LITINO(mp, dp->i_d.di_version))
  185. fs_blocks = 0;
  186. else
  187. fs_blocks = xfs_symlink_blocks(mp, pathlen);
  188. resblks = XFS_SYMLINK_SPACE_RES(mp, link_name->len, fs_blocks);
  189. error = xfs_trans_alloc(mp, &M_RES(mp)->tr_symlink, resblks, 0, 0, &tp);
  190. if (error)
  191. goto out_release_inode;
  192. xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
  193. unlock_dp_on_error = true;
  194. /*
  195. * Check whether the directory allows new symlinks or not.
  196. */
  197. if (dp->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) {
  198. error = -EPERM;
  199. goto out_trans_cancel;
  200. }
  201. /*
  202. * Reserve disk quota : blocks and inode.
  203. */
  204. error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp,
  205. pdqp, resblks, 1, 0);
  206. if (error)
  207. goto out_trans_cancel;
  208. /*
  209. * Initialize the bmap freelist prior to calling either
  210. * bmapi or the directory create code.
  211. */
  212. xfs_defer_init(&dfops, &first_block);
  213. tp->t_agfl_dfops = &dfops;
  214. /*
  215. * Allocate an inode for the symlink.
  216. */
  217. error = xfs_dir_ialloc(&tp, dp, S_IFLNK | (mode & ~S_IFMT), 1, 0,
  218. prid, &ip);
  219. if (error)
  220. goto out_trans_cancel;
  221. /*
  222. * Now we join the directory inode to the transaction. We do not do it
  223. * earlier because xfs_dir_ialloc might commit the previous transaction
  224. * (and release all the locks). An error from here on will result in
  225. * the transaction cancel unlocking dp so don't do it explicitly in the
  226. * error path.
  227. */
  228. xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
  229. unlock_dp_on_error = false;
  230. /*
  231. * Also attach the dquot(s) to it, if applicable.
  232. */
  233. xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp);
  234. if (resblks)
  235. resblks -= XFS_IALLOC_SPACE_RES(mp);
  236. /*
  237. * If the symlink will fit into the inode, write it inline.
  238. */
  239. if (pathlen <= XFS_IFORK_DSIZE(ip)) {
  240. xfs_init_local_fork(ip, XFS_DATA_FORK, target_path, pathlen);
  241. ip->i_d.di_size = pathlen;
  242. ip->i_d.di_format = XFS_DINODE_FMT_LOCAL;
  243. xfs_trans_log_inode(tp, ip, XFS_ILOG_DDATA | XFS_ILOG_CORE);
  244. } else {
  245. int offset;
  246. first_fsb = 0;
  247. nmaps = XFS_SYMLINK_MAPS;
  248. error = xfs_bmapi_write(tp, ip, first_fsb, fs_blocks,
  249. XFS_BMAPI_METADATA, &first_block, resblks,
  250. mval, &nmaps, &dfops);
  251. if (error)
  252. goto out_bmap_cancel;
  253. if (resblks)
  254. resblks -= fs_blocks;
  255. ip->i_d.di_size = pathlen;
  256. xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
  257. cur_chunk = target_path;
  258. offset = 0;
  259. for (n = 0; n < nmaps; n++) {
  260. char *buf;
  261. d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
  262. byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
  263. bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
  264. BTOBB(byte_cnt), 0);
  265. if (!bp) {
  266. error = -ENOMEM;
  267. goto out_bmap_cancel;
  268. }
  269. bp->b_ops = &xfs_symlink_buf_ops;
  270. byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
  271. byte_cnt = min(byte_cnt, pathlen);
  272. buf = bp->b_addr;
  273. buf += xfs_symlink_hdr_set(mp, ip->i_ino, offset,
  274. byte_cnt, bp);
  275. memcpy(buf, cur_chunk, byte_cnt);
  276. cur_chunk += byte_cnt;
  277. pathlen -= byte_cnt;
  278. offset += byte_cnt;
  279. xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SYMLINK_BUF);
  280. xfs_trans_log_buf(tp, bp, 0, (buf + byte_cnt - 1) -
  281. (char *)bp->b_addr);
  282. }
  283. ASSERT(pathlen == 0);
  284. }
  285. /*
  286. * Create the directory entry for the symlink.
  287. */
  288. error = xfs_dir_createname(tp, dp, link_name, ip->i_ino,
  289. &first_block, &dfops, resblks);
  290. if (error)
  291. goto out_bmap_cancel;
  292. xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
  293. xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
  294. /*
  295. * If this is a synchronous mount, make sure that the
  296. * symlink transaction goes to disk before returning to
  297. * the user.
  298. */
  299. if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
  300. xfs_trans_set_sync(tp);
  301. }
  302. error = xfs_defer_finish(&tp, &dfops);
  303. if (error)
  304. goto out_bmap_cancel;
  305. error = xfs_trans_commit(tp);
  306. if (error)
  307. goto out_release_inode;
  308. xfs_qm_dqrele(udqp);
  309. xfs_qm_dqrele(gdqp);
  310. xfs_qm_dqrele(pdqp);
  311. *ipp = ip;
  312. return 0;
  313. out_bmap_cancel:
  314. xfs_defer_cancel(&dfops);
  315. out_trans_cancel:
  316. xfs_trans_cancel(tp);
  317. out_release_inode:
  318. /*
  319. * Wait until after the current transaction is aborted to finish the
  320. * setup of the inode and release the inode. This prevents recursive
  321. * transactions and deadlocks from xfs_inactive.
  322. */
  323. if (ip) {
  324. xfs_finish_inode_setup(ip);
  325. IRELE(ip);
  326. }
  327. xfs_qm_dqrele(udqp);
  328. xfs_qm_dqrele(gdqp);
  329. xfs_qm_dqrele(pdqp);
  330. if (unlock_dp_on_error)
  331. xfs_iunlock(dp, XFS_ILOCK_EXCL);
  332. return error;
  333. }
  334. /*
  335. * Free a symlink that has blocks associated with it.
  336. */
  337. STATIC int
  338. xfs_inactive_symlink_rmt(
  339. struct xfs_inode *ip)
  340. {
  341. xfs_buf_t *bp;
  342. int done;
  343. int error;
  344. xfs_fsblock_t first_block;
  345. struct xfs_defer_ops dfops;
  346. int i;
  347. xfs_mount_t *mp;
  348. xfs_bmbt_irec_t mval[XFS_SYMLINK_MAPS];
  349. int nmaps;
  350. int size;
  351. xfs_trans_t *tp;
  352. mp = ip->i_mount;
  353. ASSERT(ip->i_df.if_flags & XFS_IFEXTENTS);
  354. /*
  355. * We're freeing a symlink that has some
  356. * blocks allocated to it. Free the
  357. * blocks here. We know that we've got
  358. * either 1 or 2 extents and that we can
  359. * free them all in one bunmapi call.
  360. */
  361. ASSERT(ip->i_d.di_nextents > 0 && ip->i_d.di_nextents <= 2);
  362. error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
  363. if (error)
  364. return error;
  365. xfs_ilock(ip, XFS_ILOCK_EXCL);
  366. xfs_trans_ijoin(tp, ip, 0);
  367. /*
  368. * Lock the inode, fix the size, and join it to the transaction.
  369. * Hold it so in the normal path, we still have it locked for
  370. * the second transaction. In the error paths we need it
  371. * held so the cancel won't rele it, see below.
  372. */
  373. size = (int)ip->i_d.di_size;
  374. ip->i_d.di_size = 0;
  375. xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
  376. /*
  377. * Find the block(s) so we can inval and unmap them.
  378. */
  379. done = 0;
  380. xfs_defer_init(&dfops, &first_block);
  381. nmaps = ARRAY_SIZE(mval);
  382. error = xfs_bmapi_read(ip, 0, xfs_symlink_blocks(mp, size),
  383. mval, &nmaps, 0);
  384. if (error)
  385. goto error_trans_cancel;
  386. /*
  387. * Invalidate the block(s). No validation is done.
  388. */
  389. for (i = 0; i < nmaps; i++) {
  390. bp = xfs_trans_get_buf(tp, mp->m_ddev_targp,
  391. XFS_FSB_TO_DADDR(mp, mval[i].br_startblock),
  392. XFS_FSB_TO_BB(mp, mval[i].br_blockcount), 0);
  393. if (!bp) {
  394. error = -ENOMEM;
  395. goto error_bmap_cancel;
  396. }
  397. xfs_trans_binval(tp, bp);
  398. }
  399. /*
  400. * Unmap the dead block(s) to the dfops.
  401. */
  402. error = xfs_bunmapi(tp, ip, 0, size, 0, nmaps,
  403. &first_block, &dfops, &done);
  404. if (error)
  405. goto error_bmap_cancel;
  406. ASSERT(done);
  407. /*
  408. * Commit the first transaction. This logs the EFI and the inode.
  409. */
  410. xfs_defer_ijoin(&dfops, ip);
  411. error = xfs_defer_finish(&tp, &dfops);
  412. if (error)
  413. goto error_bmap_cancel;
  414. /*
  415. * Commit the transaction containing extent freeing and EFDs.
  416. */
  417. xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
  418. error = xfs_trans_commit(tp);
  419. if (error) {
  420. ASSERT(XFS_FORCED_SHUTDOWN(mp));
  421. goto error_unlock;
  422. }
  423. /*
  424. * Remove the memory for extent descriptions (just bookkeeping).
  425. */
  426. if (ip->i_df.if_bytes)
  427. xfs_idata_realloc(ip, -ip->i_df.if_bytes, XFS_DATA_FORK);
  428. ASSERT(ip->i_df.if_bytes == 0);
  429. xfs_iunlock(ip, XFS_ILOCK_EXCL);
  430. return 0;
  431. error_bmap_cancel:
  432. xfs_defer_cancel(&dfops);
  433. error_trans_cancel:
  434. xfs_trans_cancel(tp);
  435. error_unlock:
  436. xfs_iunlock(ip, XFS_ILOCK_EXCL);
  437. return error;
  438. }
  439. /*
  440. * xfs_inactive_symlink - free a symlink
  441. */
  442. int
  443. xfs_inactive_symlink(
  444. struct xfs_inode *ip)
  445. {
  446. struct xfs_mount *mp = ip->i_mount;
  447. int pathlen;
  448. trace_xfs_inactive_symlink(ip);
  449. if (XFS_FORCED_SHUTDOWN(mp))
  450. return -EIO;
  451. xfs_ilock(ip, XFS_ILOCK_EXCL);
  452. /*
  453. * Zero length symlinks _can_ exist.
  454. */
  455. pathlen = (int)ip->i_d.di_size;
  456. if (!pathlen) {
  457. xfs_iunlock(ip, XFS_ILOCK_EXCL);
  458. return 0;
  459. }
  460. if (pathlen < 0 || pathlen > XFS_SYMLINK_MAXLEN) {
  461. xfs_alert(mp, "%s: inode (0x%llx) bad symlink length (%d)",
  462. __func__, (unsigned long long)ip->i_ino, pathlen);
  463. xfs_iunlock(ip, XFS_ILOCK_EXCL);
  464. ASSERT(0);
  465. return -EFSCORRUPTED;
  466. }
  467. if (ip->i_df.if_flags & XFS_IFINLINE) {
  468. if (ip->i_df.if_bytes > 0)
  469. xfs_idata_realloc(ip, -(ip->i_df.if_bytes),
  470. XFS_DATA_FORK);
  471. xfs_iunlock(ip, XFS_ILOCK_EXCL);
  472. ASSERT(ip->i_df.if_bytes == 0);
  473. return 0;
  474. }
  475. xfs_iunlock(ip, XFS_ILOCK_EXCL);
  476. /* remove the remote symlink */
  477. return xfs_inactive_symlink_rmt(ip);
  478. }