xfs_inode_item_recover.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2000-2006 Silicon Graphics, Inc.
  4. * All Rights Reserved.
  5. */
  6. #include "xfs.h"
  7. #include "xfs_fs.h"
  8. #include "xfs_shared.h"
  9. #include "xfs_format.h"
  10. #include "xfs_log_format.h"
  11. #include "xfs_trans_resv.h"
  12. #include "xfs_mount.h"
  13. #include "xfs_inode.h"
  14. #include "xfs_trans.h"
  15. #include "xfs_inode_item.h"
  16. #include "xfs_trace.h"
  17. #include "xfs_trans_priv.h"
  18. #include "xfs_buf_item.h"
  19. #include "xfs_log.h"
  20. #include "xfs_error.h"
  21. #include "xfs_log_priv.h"
  22. #include "xfs_log_recover.h"
  23. #include "xfs_icache.h"
  24. #include "xfs_bmap_btree.h"
  25. STATIC void
  26. xlog_recover_inode_ra_pass2(
  27. struct xlog *log,
  28. struct xlog_recover_item *item)
  29. {
  30. if (item->ri_buf[0].i_len == sizeof(struct xfs_inode_log_format)) {
  31. struct xfs_inode_log_format *ilfp = item->ri_buf[0].i_addr;
  32. xlog_buf_readahead(log, ilfp->ilf_blkno, ilfp->ilf_len,
  33. &xfs_inode_buf_ra_ops);
  34. } else {
  35. struct xfs_inode_log_format_32 *ilfp = item->ri_buf[0].i_addr;
  36. xlog_buf_readahead(log, ilfp->ilf_blkno, ilfp->ilf_len,
  37. &xfs_inode_buf_ra_ops);
  38. }
  39. }
  40. /*
  41. * Inode fork owner changes
  42. *
  43. * If we have been told that we have to reparent the inode fork, it's because an
  44. * extent swap operation on a CRC enabled filesystem has been done and we are
  45. * replaying it. We need to walk the BMBT of the appropriate fork and change the
  46. * owners of it.
  47. *
  48. * The complexity here is that we don't have an inode context to work with, so
  49. * after we've replayed the inode we need to instantiate one. This is where the
  50. * fun begins.
  51. *
  52. * We are in the middle of log recovery, so we can't run transactions. That
  53. * means we cannot use cache coherent inode instantiation via xfs_iget(), as
  54. * that will result in the corresponding iput() running the inode through
  55. * xfs_inactive(). If we've just replayed an inode core that changes the link
  56. * count to zero (i.e. it's been unlinked), then xfs_inactive() will run
  57. * transactions (bad!).
  58. *
  59. * So, to avoid this, we instantiate an inode directly from the inode core we've
  60. * just recovered. We have the buffer still locked, and all we really need to
  61. * instantiate is the inode core and the forks being modified. We can do this
  62. * manually, then run the inode btree owner change, and then tear down the
  63. * xfs_inode without having to run any transactions at all.
  64. *
  65. * Also, because we don't have a transaction context available here but need to
  66. * gather all the buffers we modify for writeback so we pass the buffer_list
  67. * instead for the operation to use.
  68. */
  69. STATIC int
  70. xfs_recover_inode_owner_change(
  71. struct xfs_mount *mp,
  72. struct xfs_dinode *dip,
  73. struct xfs_inode_log_format *in_f,
  74. struct list_head *buffer_list)
  75. {
  76. struct xfs_inode *ip;
  77. int error;
  78. ASSERT(in_f->ilf_fields & (XFS_ILOG_DOWNER|XFS_ILOG_AOWNER));
  79. ip = xfs_inode_alloc(mp, in_f->ilf_ino);
  80. if (!ip)
  81. return -ENOMEM;
  82. /* instantiate the inode */
  83. ASSERT(dip->di_version >= 3);
  84. error = xfs_inode_from_disk(ip, dip);
  85. if (error)
  86. goto out_free_ip;
  87. if (in_f->ilf_fields & XFS_ILOG_DOWNER) {
  88. ASSERT(in_f->ilf_fields & XFS_ILOG_DBROOT);
  89. error = xfs_bmbt_change_owner(NULL, ip, XFS_DATA_FORK,
  90. ip->i_ino, buffer_list);
  91. if (error)
  92. goto out_free_ip;
  93. }
  94. if (in_f->ilf_fields & XFS_ILOG_AOWNER) {
  95. ASSERT(in_f->ilf_fields & XFS_ILOG_ABROOT);
  96. error = xfs_bmbt_change_owner(NULL, ip, XFS_ATTR_FORK,
  97. ip->i_ino, buffer_list);
  98. if (error)
  99. goto out_free_ip;
  100. }
  101. out_free_ip:
  102. xfs_inode_free(ip);
  103. return error;
  104. }
  105. static inline bool xfs_log_dinode_has_bigtime(const struct xfs_log_dinode *ld)
  106. {
  107. return ld->di_version >= 3 &&
  108. (ld->di_flags2 & XFS_DIFLAG2_BIGTIME);
  109. }
  110. /* Convert a log timestamp to an ondisk timestamp. */
  111. static inline xfs_timestamp_t
  112. xfs_log_dinode_to_disk_ts(
  113. struct xfs_log_dinode *from,
  114. const xfs_ictimestamp_t its)
  115. {
  116. struct xfs_legacy_timestamp *lts;
  117. struct xfs_legacy_ictimestamp *lits;
  118. xfs_timestamp_t ts;
  119. if (xfs_log_dinode_has_bigtime(from))
  120. return cpu_to_be64(its);
  121. lts = (struct xfs_legacy_timestamp *)&ts;
  122. lits = (struct xfs_legacy_ictimestamp *)&its;
  123. lts->t_sec = cpu_to_be32(lits->t_sec);
  124. lts->t_nsec = cpu_to_be32(lits->t_nsec);
  125. return ts;
  126. }
  127. STATIC void
  128. xfs_log_dinode_to_disk(
  129. struct xfs_log_dinode *from,
  130. struct xfs_dinode *to)
  131. {
  132. to->di_magic = cpu_to_be16(from->di_magic);
  133. to->di_mode = cpu_to_be16(from->di_mode);
  134. to->di_version = from->di_version;
  135. to->di_format = from->di_format;
  136. to->di_onlink = 0;
  137. to->di_uid = cpu_to_be32(from->di_uid);
  138. to->di_gid = cpu_to_be32(from->di_gid);
  139. to->di_nlink = cpu_to_be32(from->di_nlink);
  140. to->di_projid_lo = cpu_to_be16(from->di_projid_lo);
  141. to->di_projid_hi = cpu_to_be16(from->di_projid_hi);
  142. memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
  143. to->di_atime = xfs_log_dinode_to_disk_ts(from, from->di_atime);
  144. to->di_mtime = xfs_log_dinode_to_disk_ts(from, from->di_mtime);
  145. to->di_ctime = xfs_log_dinode_to_disk_ts(from, from->di_ctime);
  146. to->di_size = cpu_to_be64(from->di_size);
  147. to->di_nblocks = cpu_to_be64(from->di_nblocks);
  148. to->di_extsize = cpu_to_be32(from->di_extsize);
  149. to->di_nextents = cpu_to_be32(from->di_nextents);
  150. to->di_anextents = cpu_to_be16(from->di_anextents);
  151. to->di_forkoff = from->di_forkoff;
  152. to->di_aformat = from->di_aformat;
  153. to->di_dmevmask = cpu_to_be32(from->di_dmevmask);
  154. to->di_dmstate = cpu_to_be16(from->di_dmstate);
  155. to->di_flags = cpu_to_be16(from->di_flags);
  156. to->di_gen = cpu_to_be32(from->di_gen);
  157. if (from->di_version == 3) {
  158. to->di_changecount = cpu_to_be64(from->di_changecount);
  159. to->di_crtime = xfs_log_dinode_to_disk_ts(from,
  160. from->di_crtime);
  161. to->di_flags2 = cpu_to_be64(from->di_flags2);
  162. to->di_cowextsize = cpu_to_be32(from->di_cowextsize);
  163. to->di_ino = cpu_to_be64(from->di_ino);
  164. to->di_lsn = cpu_to_be64(from->di_lsn);
  165. memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2));
  166. uuid_copy(&to->di_uuid, &from->di_uuid);
  167. to->di_flushiter = 0;
  168. } else {
  169. to->di_flushiter = cpu_to_be16(from->di_flushiter);
  170. }
  171. }
  172. STATIC int
  173. xlog_recover_inode_commit_pass2(
  174. struct xlog *log,
  175. struct list_head *buffer_list,
  176. struct xlog_recover_item *item,
  177. xfs_lsn_t current_lsn)
  178. {
  179. struct xfs_inode_log_format *in_f;
  180. struct xfs_mount *mp = log->l_mp;
  181. struct xfs_buf *bp;
  182. struct xfs_dinode *dip;
  183. int len;
  184. char *src;
  185. char *dest;
  186. int error;
  187. int attr_index;
  188. uint fields;
  189. struct xfs_log_dinode *ldip;
  190. uint isize;
  191. int need_free = 0;
  192. if (item->ri_buf[0].i_len == sizeof(struct xfs_inode_log_format)) {
  193. in_f = item->ri_buf[0].i_addr;
  194. } else {
  195. in_f = kmem_alloc(sizeof(struct xfs_inode_log_format), 0);
  196. need_free = 1;
  197. error = xfs_inode_item_format_convert(&item->ri_buf[0], in_f);
  198. if (error)
  199. goto error;
  200. }
  201. /*
  202. * Inode buffers can be freed, look out for it,
  203. * and do not replay the inode.
  204. */
  205. if (xlog_is_buffer_cancelled(log, in_f->ilf_blkno, in_f->ilf_len)) {
  206. error = 0;
  207. trace_xfs_log_recover_inode_cancel(log, in_f);
  208. goto error;
  209. }
  210. trace_xfs_log_recover_inode_recover(log, in_f);
  211. error = xfs_buf_read(mp->m_ddev_targp, in_f->ilf_blkno, in_f->ilf_len,
  212. 0, &bp, &xfs_inode_buf_ops);
  213. if (error)
  214. goto error;
  215. ASSERT(in_f->ilf_fields & XFS_ILOG_CORE);
  216. dip = xfs_buf_offset(bp, in_f->ilf_boffset);
  217. /*
  218. * Make sure the place we're flushing out to really looks
  219. * like an inode!
  220. */
  221. if (XFS_IS_CORRUPT(mp, !xfs_verify_magic16(bp, dip->di_magic))) {
  222. xfs_alert(mp,
  223. "%s: Bad inode magic number, dip = "PTR_FMT", dino bp = "PTR_FMT", ino = %Ld",
  224. __func__, dip, bp, in_f->ilf_ino);
  225. error = -EFSCORRUPTED;
  226. goto out_release;
  227. }
  228. ldip = item->ri_buf[1].i_addr;
  229. if (XFS_IS_CORRUPT(mp, ldip->di_magic != XFS_DINODE_MAGIC)) {
  230. xfs_alert(mp,
  231. "%s: Bad inode log record, rec ptr "PTR_FMT", ino %Ld",
  232. __func__, item, in_f->ilf_ino);
  233. error = -EFSCORRUPTED;
  234. goto out_release;
  235. }
  236. /*
  237. * If the inode has an LSN in it, recover the inode only if it's less
  238. * than the lsn of the transaction we are replaying. Note: we still
  239. * need to replay an owner change even though the inode is more recent
  240. * than the transaction as there is no guarantee that all the btree
  241. * blocks are more recent than this transaction, too.
  242. */
  243. if (dip->di_version >= 3) {
  244. xfs_lsn_t lsn = be64_to_cpu(dip->di_lsn);
  245. if (lsn && lsn != -1 && XFS_LSN_CMP(lsn, current_lsn) >= 0) {
  246. trace_xfs_log_recover_inode_skip(log, in_f);
  247. error = 0;
  248. goto out_owner_change;
  249. }
  250. }
  251. /*
  252. * di_flushiter is only valid for v1/2 inodes. All changes for v3 inodes
  253. * are transactional and if ordering is necessary we can determine that
  254. * more accurately by the LSN field in the V3 inode core. Don't trust
  255. * the inode versions we might be changing them here - use the
  256. * superblock flag to determine whether we need to look at di_flushiter
  257. * to skip replay when the on disk inode is newer than the log one
  258. */
  259. if (!xfs_sb_version_has_v3inode(&mp->m_sb) &&
  260. ldip->di_flushiter < be16_to_cpu(dip->di_flushiter)) {
  261. /*
  262. * Deal with the wrap case, DI_MAX_FLUSH is less
  263. * than smaller numbers
  264. */
  265. if (be16_to_cpu(dip->di_flushiter) == DI_MAX_FLUSH &&
  266. ldip->di_flushiter < (DI_MAX_FLUSH >> 1)) {
  267. /* do nothing */
  268. } else {
  269. trace_xfs_log_recover_inode_skip(log, in_f);
  270. error = 0;
  271. goto out_release;
  272. }
  273. }
  274. /* Take the opportunity to reset the flush iteration count */
  275. ldip->di_flushiter = 0;
  276. if (unlikely(S_ISREG(ldip->di_mode))) {
  277. if ((ldip->di_format != XFS_DINODE_FMT_EXTENTS) &&
  278. (ldip->di_format != XFS_DINODE_FMT_BTREE)) {
  279. XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(3)",
  280. XFS_ERRLEVEL_LOW, mp, ldip,
  281. sizeof(*ldip));
  282. xfs_alert(mp,
  283. "%s: Bad regular inode log record, rec ptr "PTR_FMT", "
  284. "ino ptr = "PTR_FMT", ino bp = "PTR_FMT", ino %Ld",
  285. __func__, item, dip, bp, in_f->ilf_ino);
  286. error = -EFSCORRUPTED;
  287. goto out_release;
  288. }
  289. } else if (unlikely(S_ISDIR(ldip->di_mode))) {
  290. if ((ldip->di_format != XFS_DINODE_FMT_EXTENTS) &&
  291. (ldip->di_format != XFS_DINODE_FMT_BTREE) &&
  292. (ldip->di_format != XFS_DINODE_FMT_LOCAL)) {
  293. XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(4)",
  294. XFS_ERRLEVEL_LOW, mp, ldip,
  295. sizeof(*ldip));
  296. xfs_alert(mp,
  297. "%s: Bad dir inode log record, rec ptr "PTR_FMT", "
  298. "ino ptr = "PTR_FMT", ino bp = "PTR_FMT", ino %Ld",
  299. __func__, item, dip, bp, in_f->ilf_ino);
  300. error = -EFSCORRUPTED;
  301. goto out_release;
  302. }
  303. }
  304. if (unlikely(ldip->di_nextents + ldip->di_anextents > ldip->di_nblocks)){
  305. XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(5)",
  306. XFS_ERRLEVEL_LOW, mp, ldip,
  307. sizeof(*ldip));
  308. xfs_alert(mp,
  309. "%s: Bad inode log record, rec ptr "PTR_FMT", dino ptr "PTR_FMT", "
  310. "dino bp "PTR_FMT", ino %Ld, total extents = %d, nblocks = %Ld",
  311. __func__, item, dip, bp, in_f->ilf_ino,
  312. ldip->di_nextents + ldip->di_anextents,
  313. ldip->di_nblocks);
  314. error = -EFSCORRUPTED;
  315. goto out_release;
  316. }
  317. if (unlikely(ldip->di_forkoff > mp->m_sb.sb_inodesize)) {
  318. XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(6)",
  319. XFS_ERRLEVEL_LOW, mp, ldip,
  320. sizeof(*ldip));
  321. xfs_alert(mp,
  322. "%s: Bad inode log record, rec ptr "PTR_FMT", dino ptr "PTR_FMT", "
  323. "dino bp "PTR_FMT", ino %Ld, forkoff 0x%x", __func__,
  324. item, dip, bp, in_f->ilf_ino, ldip->di_forkoff);
  325. error = -EFSCORRUPTED;
  326. goto out_release;
  327. }
  328. isize = xfs_log_dinode_size(mp);
  329. if (unlikely(item->ri_buf[1].i_len > isize)) {
  330. XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(7)",
  331. XFS_ERRLEVEL_LOW, mp, ldip,
  332. sizeof(*ldip));
  333. xfs_alert(mp,
  334. "%s: Bad inode log record length %d, rec ptr "PTR_FMT,
  335. __func__, item->ri_buf[1].i_len, item);
  336. error = -EFSCORRUPTED;
  337. goto out_release;
  338. }
  339. /* recover the log dinode inode into the on disk inode */
  340. xfs_log_dinode_to_disk(ldip, dip);
  341. fields = in_f->ilf_fields;
  342. if (fields & XFS_ILOG_DEV)
  343. xfs_dinode_put_rdev(dip, in_f->ilf_u.ilfu_rdev);
  344. if (in_f->ilf_size == 2)
  345. goto out_owner_change;
  346. len = item->ri_buf[2].i_len;
  347. src = item->ri_buf[2].i_addr;
  348. ASSERT(in_f->ilf_size <= 4);
  349. ASSERT((in_f->ilf_size == 3) || (fields & XFS_ILOG_AFORK));
  350. ASSERT(!(fields & XFS_ILOG_DFORK) ||
  351. (len == in_f->ilf_dsize));
  352. switch (fields & XFS_ILOG_DFORK) {
  353. case XFS_ILOG_DDATA:
  354. case XFS_ILOG_DEXT:
  355. memcpy(XFS_DFORK_DPTR(dip), src, len);
  356. break;
  357. case XFS_ILOG_DBROOT:
  358. xfs_bmbt_to_bmdr(mp, (struct xfs_btree_block *)src, len,
  359. (struct xfs_bmdr_block *)XFS_DFORK_DPTR(dip),
  360. XFS_DFORK_DSIZE(dip, mp));
  361. break;
  362. default:
  363. /*
  364. * There are no data fork flags set.
  365. */
  366. ASSERT((fields & XFS_ILOG_DFORK) == 0);
  367. break;
  368. }
  369. /*
  370. * If we logged any attribute data, recover it. There may or
  371. * may not have been any other non-core data logged in this
  372. * transaction.
  373. */
  374. if (in_f->ilf_fields & XFS_ILOG_AFORK) {
  375. if (in_f->ilf_fields & XFS_ILOG_DFORK) {
  376. attr_index = 3;
  377. } else {
  378. attr_index = 2;
  379. }
  380. len = item->ri_buf[attr_index].i_len;
  381. src = item->ri_buf[attr_index].i_addr;
  382. ASSERT(len == in_f->ilf_asize);
  383. switch (in_f->ilf_fields & XFS_ILOG_AFORK) {
  384. case XFS_ILOG_ADATA:
  385. case XFS_ILOG_AEXT:
  386. dest = XFS_DFORK_APTR(dip);
  387. ASSERT(len <= XFS_DFORK_ASIZE(dip, mp));
  388. memcpy(dest, src, len);
  389. break;
  390. case XFS_ILOG_ABROOT:
  391. dest = XFS_DFORK_APTR(dip);
  392. xfs_bmbt_to_bmdr(mp, (struct xfs_btree_block *)src,
  393. len, (struct xfs_bmdr_block *)dest,
  394. XFS_DFORK_ASIZE(dip, mp));
  395. break;
  396. default:
  397. xfs_warn(log->l_mp, "%s: Invalid flag", __func__);
  398. ASSERT(0);
  399. error = -EFSCORRUPTED;
  400. goto out_release;
  401. }
  402. }
  403. out_owner_change:
  404. /* Recover the swapext owner change unless inode has been deleted */
  405. if ((in_f->ilf_fields & (XFS_ILOG_DOWNER|XFS_ILOG_AOWNER)) &&
  406. (dip->di_mode != 0))
  407. error = xfs_recover_inode_owner_change(mp, dip, in_f,
  408. buffer_list);
  409. /* re-generate the checksum. */
  410. xfs_dinode_calc_crc(log->l_mp, dip);
  411. ASSERT(bp->b_mount == mp);
  412. bp->b_flags |= _XBF_LOGRECOVERY;
  413. xfs_buf_delwri_queue(bp, buffer_list);
  414. out_release:
  415. xfs_buf_relse(bp);
  416. error:
  417. if (need_free)
  418. kmem_free(in_f);
  419. return error;
  420. }
  421. const struct xlog_recover_item_ops xlog_inode_item_ops = {
  422. .item_type = XFS_LI_INODE,
  423. .ra_pass2 = xlog_recover_inode_ra_pass2,
  424. .commit_pass2 = xlog_recover_inode_commit_pass2,
  425. };