inode.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2017 Oracle. All Rights Reserved.
  4. * Author: Darrick J. Wong <darrick.wong@oracle.com>
  5. */
  6. #include "xfs.h"
  7. #include "xfs_fs.h"
  8. #include "xfs_shared.h"
  9. #include "xfs_format.h"
  10. #include "xfs_trans_resv.h"
  11. #include "xfs_mount.h"
  12. #include "xfs_defer.h"
  13. #include "xfs_btree.h"
  14. #include "xfs_bit.h"
  15. #include "xfs_log_format.h"
  16. #include "xfs_trans.h"
  17. #include "xfs_sb.h"
  18. #include "xfs_inode.h"
  19. #include "xfs_icache.h"
  20. #include "xfs_inode_buf.h"
  21. #include "xfs_inode_fork.h"
  22. #include "xfs_ialloc.h"
  23. #include "xfs_da_format.h"
  24. #include "xfs_reflink.h"
  25. #include "xfs_rmap.h"
  26. #include "xfs_bmap.h"
  27. #include "xfs_bmap_util.h"
  28. #include "scrub/xfs_scrub.h"
  29. #include "scrub/scrub.h"
  30. #include "scrub/common.h"
  31. #include "scrub/btree.h"
  32. #include "scrub/trace.h"
  33. /*
  34. * Grab total control of the inode metadata. It doesn't matter here if
  35. * the file data is still changing; exclusive access to the metadata is
  36. * the goal.
  37. */
  38. int
  39. xfs_scrub_setup_inode(
  40. struct xfs_scrub_context *sc,
  41. struct xfs_inode *ip)
  42. {
  43. int error;
  44. /*
  45. * Try to get the inode. If the verifiers fail, we try again
  46. * in raw mode.
  47. */
  48. error = xfs_scrub_get_inode(sc, ip);
  49. switch (error) {
  50. case 0:
  51. break;
  52. case -EFSCORRUPTED:
  53. case -EFSBADCRC:
  54. return xfs_scrub_trans_alloc(sc, 0);
  55. default:
  56. return error;
  57. }
  58. /* Got the inode, lock it and we're ready to go. */
  59. sc->ilock_flags = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL;
  60. xfs_ilock(sc->ip, sc->ilock_flags);
  61. error = xfs_scrub_trans_alloc(sc, 0);
  62. if (error)
  63. goto out;
  64. sc->ilock_flags |= XFS_ILOCK_EXCL;
  65. xfs_ilock(sc->ip, XFS_ILOCK_EXCL);
  66. out:
  67. /* scrub teardown will unlock and release the inode for us */
  68. return error;
  69. }
  70. /* Inode core */
  71. /* Validate di_extsize hint. */
  72. STATIC void
  73. xfs_scrub_inode_extsize(
  74. struct xfs_scrub_context *sc,
  75. struct xfs_dinode *dip,
  76. xfs_ino_t ino,
  77. uint16_t mode,
  78. uint16_t flags)
  79. {
  80. xfs_failaddr_t fa;
  81. fa = xfs_inode_validate_extsize(sc->mp, be32_to_cpu(dip->di_extsize),
  82. mode, flags);
  83. if (fa)
  84. xfs_scrub_ino_set_corrupt(sc, ino);
  85. }
  86. /*
  87. * Validate di_cowextsize hint.
  88. *
  89. * The rules are documented at xfs_ioctl_setattr_check_cowextsize().
  90. * These functions must be kept in sync with each other.
  91. */
  92. STATIC void
  93. xfs_scrub_inode_cowextsize(
  94. struct xfs_scrub_context *sc,
  95. struct xfs_dinode *dip,
  96. xfs_ino_t ino,
  97. uint16_t mode,
  98. uint16_t flags,
  99. uint64_t flags2)
  100. {
  101. xfs_failaddr_t fa;
  102. fa = xfs_inode_validate_cowextsize(sc->mp,
  103. be32_to_cpu(dip->di_cowextsize), mode, flags,
  104. flags2);
  105. if (fa)
  106. xfs_scrub_ino_set_corrupt(sc, ino);
  107. }
  108. /* Make sure the di_flags make sense for the inode. */
  109. STATIC void
  110. xfs_scrub_inode_flags(
  111. struct xfs_scrub_context *sc,
  112. struct xfs_dinode *dip,
  113. xfs_ino_t ino,
  114. uint16_t mode,
  115. uint16_t flags)
  116. {
  117. struct xfs_mount *mp = sc->mp;
  118. if (flags & ~XFS_DIFLAG_ANY)
  119. goto bad;
  120. /* rt flags require rt device */
  121. if ((flags & (XFS_DIFLAG_REALTIME | XFS_DIFLAG_RTINHERIT)) &&
  122. !mp->m_rtdev_targp)
  123. goto bad;
  124. /* new rt bitmap flag only valid for rbmino */
  125. if ((flags & XFS_DIFLAG_NEWRTBM) && ino != mp->m_sb.sb_rbmino)
  126. goto bad;
  127. /* directory-only flags */
  128. if ((flags & (XFS_DIFLAG_RTINHERIT |
  129. XFS_DIFLAG_EXTSZINHERIT |
  130. XFS_DIFLAG_PROJINHERIT |
  131. XFS_DIFLAG_NOSYMLINKS)) &&
  132. !S_ISDIR(mode))
  133. goto bad;
  134. /* file-only flags */
  135. if ((flags & (XFS_DIFLAG_REALTIME | FS_XFLAG_EXTSIZE)) &&
  136. !S_ISREG(mode))
  137. goto bad;
  138. /* filestreams and rt make no sense */
  139. if ((flags & XFS_DIFLAG_FILESTREAM) && (flags & XFS_DIFLAG_REALTIME))
  140. goto bad;
  141. return;
  142. bad:
  143. xfs_scrub_ino_set_corrupt(sc, ino);
  144. }
  145. /* Make sure the di_flags2 make sense for the inode. */
  146. STATIC void
  147. xfs_scrub_inode_flags2(
  148. struct xfs_scrub_context *sc,
  149. struct xfs_dinode *dip,
  150. xfs_ino_t ino,
  151. uint16_t mode,
  152. uint16_t flags,
  153. uint64_t flags2)
  154. {
  155. struct xfs_mount *mp = sc->mp;
  156. if (flags2 & ~XFS_DIFLAG2_ANY)
  157. goto bad;
  158. /* reflink flag requires reflink feature */
  159. if ((flags2 & XFS_DIFLAG2_REFLINK) &&
  160. !xfs_sb_version_hasreflink(&mp->m_sb))
  161. goto bad;
  162. /* cowextsize flag is checked w.r.t. mode separately */
  163. /* file/dir-only flags */
  164. if ((flags2 & XFS_DIFLAG2_DAX) && !(S_ISREG(mode) || S_ISDIR(mode)))
  165. goto bad;
  166. /* file-only flags */
  167. if ((flags2 & XFS_DIFLAG2_REFLINK) && !S_ISREG(mode))
  168. goto bad;
  169. /* realtime and reflink make no sense, currently */
  170. if ((flags & XFS_DIFLAG_REALTIME) && (flags2 & XFS_DIFLAG2_REFLINK))
  171. goto bad;
  172. /* dax and reflink make no sense, currently */
  173. if ((flags2 & XFS_DIFLAG2_DAX) && (flags2 & XFS_DIFLAG2_REFLINK))
  174. goto bad;
  175. return;
  176. bad:
  177. xfs_scrub_ino_set_corrupt(sc, ino);
  178. }
  179. /* Scrub all the ondisk inode fields. */
  180. STATIC void
  181. xfs_scrub_dinode(
  182. struct xfs_scrub_context *sc,
  183. struct xfs_dinode *dip,
  184. xfs_ino_t ino)
  185. {
  186. struct xfs_mount *mp = sc->mp;
  187. size_t fork_recs;
  188. unsigned long long isize;
  189. uint64_t flags2;
  190. uint32_t nextents;
  191. uint16_t flags;
  192. uint16_t mode;
  193. flags = be16_to_cpu(dip->di_flags);
  194. if (dip->di_version >= 3)
  195. flags2 = be64_to_cpu(dip->di_flags2);
  196. else
  197. flags2 = 0;
  198. /* di_mode */
  199. mode = be16_to_cpu(dip->di_mode);
  200. switch (mode & S_IFMT) {
  201. case S_IFLNK:
  202. case S_IFREG:
  203. case S_IFDIR:
  204. case S_IFCHR:
  205. case S_IFBLK:
  206. case S_IFIFO:
  207. case S_IFSOCK:
  208. /* mode is recognized */
  209. break;
  210. default:
  211. xfs_scrub_ino_set_corrupt(sc, ino);
  212. break;
  213. }
  214. /* v1/v2 fields */
  215. switch (dip->di_version) {
  216. case 1:
  217. /*
  218. * We autoconvert v1 inodes into v2 inodes on writeout,
  219. * so just mark this inode for preening.
  220. */
  221. xfs_scrub_ino_set_preen(sc, ino);
  222. break;
  223. case 2:
  224. case 3:
  225. if (dip->di_onlink != 0)
  226. xfs_scrub_ino_set_corrupt(sc, ino);
  227. if (dip->di_mode == 0 && sc->ip)
  228. xfs_scrub_ino_set_corrupt(sc, ino);
  229. if (dip->di_projid_hi != 0 &&
  230. !xfs_sb_version_hasprojid32bit(&mp->m_sb))
  231. xfs_scrub_ino_set_corrupt(sc, ino);
  232. break;
  233. default:
  234. xfs_scrub_ino_set_corrupt(sc, ino);
  235. return;
  236. }
  237. /*
  238. * di_uid/di_gid -- -1 isn't invalid, but there's no way that
  239. * userspace could have created that.
  240. */
  241. if (dip->di_uid == cpu_to_be32(-1U) ||
  242. dip->di_gid == cpu_to_be32(-1U))
  243. xfs_scrub_ino_set_warning(sc, ino);
  244. /* di_format */
  245. switch (dip->di_format) {
  246. case XFS_DINODE_FMT_DEV:
  247. if (!S_ISCHR(mode) && !S_ISBLK(mode) &&
  248. !S_ISFIFO(mode) && !S_ISSOCK(mode))
  249. xfs_scrub_ino_set_corrupt(sc, ino);
  250. break;
  251. case XFS_DINODE_FMT_LOCAL:
  252. if (!S_ISDIR(mode) && !S_ISLNK(mode))
  253. xfs_scrub_ino_set_corrupt(sc, ino);
  254. break;
  255. case XFS_DINODE_FMT_EXTENTS:
  256. if (!S_ISREG(mode) && !S_ISDIR(mode) && !S_ISLNK(mode))
  257. xfs_scrub_ino_set_corrupt(sc, ino);
  258. break;
  259. case XFS_DINODE_FMT_BTREE:
  260. if (!S_ISREG(mode) && !S_ISDIR(mode))
  261. xfs_scrub_ino_set_corrupt(sc, ino);
  262. break;
  263. case XFS_DINODE_FMT_UUID:
  264. default:
  265. xfs_scrub_ino_set_corrupt(sc, ino);
  266. break;
  267. }
  268. /* di_[amc]time.nsec */
  269. if (be32_to_cpu(dip->di_atime.t_nsec) >= NSEC_PER_SEC)
  270. xfs_scrub_ino_set_corrupt(sc, ino);
  271. if (be32_to_cpu(dip->di_mtime.t_nsec) >= NSEC_PER_SEC)
  272. xfs_scrub_ino_set_corrupt(sc, ino);
  273. if (be32_to_cpu(dip->di_ctime.t_nsec) >= NSEC_PER_SEC)
  274. xfs_scrub_ino_set_corrupt(sc, ino);
  275. /*
  276. * di_size. xfs_dinode_verify checks for things that screw up
  277. * the VFS such as the upper bit being set and zero-length
  278. * symlinks/directories, but we can do more here.
  279. */
  280. isize = be64_to_cpu(dip->di_size);
  281. if (isize & (1ULL << 63))
  282. xfs_scrub_ino_set_corrupt(sc, ino);
  283. /* Devices, fifos, and sockets must have zero size */
  284. if (!S_ISDIR(mode) && !S_ISREG(mode) && !S_ISLNK(mode) && isize != 0)
  285. xfs_scrub_ino_set_corrupt(sc, ino);
  286. /* Directories can't be larger than the data section size (32G) */
  287. if (S_ISDIR(mode) && (isize == 0 || isize >= XFS_DIR2_SPACE_SIZE))
  288. xfs_scrub_ino_set_corrupt(sc, ino);
  289. /* Symlinks can't be larger than SYMLINK_MAXLEN */
  290. if (S_ISLNK(mode) && (isize == 0 || isize >= XFS_SYMLINK_MAXLEN))
  291. xfs_scrub_ino_set_corrupt(sc, ino);
  292. /*
  293. * Warn if the running kernel can't handle the kinds of offsets
  294. * needed to deal with the file size. In other words, if the
  295. * pagecache can't cache all the blocks in this file due to
  296. * overly large offsets, flag the inode for admin review.
  297. */
  298. if (isize >= mp->m_super->s_maxbytes)
  299. xfs_scrub_ino_set_warning(sc, ino);
  300. /* di_nblocks */
  301. if (flags2 & XFS_DIFLAG2_REFLINK) {
  302. ; /* nblocks can exceed dblocks */
  303. } else if (flags & XFS_DIFLAG_REALTIME) {
  304. /*
  305. * nblocks is the sum of data extents (in the rtdev),
  306. * attr extents (in the datadev), and both forks' bmbt
  307. * blocks (in the datadev). This clumsy check is the
  308. * best we can do without cross-referencing with the
  309. * inode forks.
  310. */
  311. if (be64_to_cpu(dip->di_nblocks) >=
  312. mp->m_sb.sb_dblocks + mp->m_sb.sb_rblocks)
  313. xfs_scrub_ino_set_corrupt(sc, ino);
  314. } else {
  315. if (be64_to_cpu(dip->di_nblocks) >= mp->m_sb.sb_dblocks)
  316. xfs_scrub_ino_set_corrupt(sc, ino);
  317. }
  318. xfs_scrub_inode_flags(sc, dip, ino, mode, flags);
  319. xfs_scrub_inode_extsize(sc, dip, ino, mode, flags);
  320. /* di_nextents */
  321. nextents = be32_to_cpu(dip->di_nextents);
  322. fork_recs = XFS_DFORK_DSIZE(dip, mp) / sizeof(struct xfs_bmbt_rec);
  323. switch (dip->di_format) {
  324. case XFS_DINODE_FMT_EXTENTS:
  325. if (nextents > fork_recs)
  326. xfs_scrub_ino_set_corrupt(sc, ino);
  327. break;
  328. case XFS_DINODE_FMT_BTREE:
  329. if (nextents <= fork_recs)
  330. xfs_scrub_ino_set_corrupt(sc, ino);
  331. break;
  332. default:
  333. if (nextents != 0)
  334. xfs_scrub_ino_set_corrupt(sc, ino);
  335. break;
  336. }
  337. /* di_forkoff */
  338. if (XFS_DFORK_APTR(dip) >= (char *)dip + mp->m_sb.sb_inodesize)
  339. xfs_scrub_ino_set_corrupt(sc, ino);
  340. if (dip->di_anextents != 0 && dip->di_forkoff == 0)
  341. xfs_scrub_ino_set_corrupt(sc, ino);
  342. if (dip->di_forkoff == 0 && dip->di_aformat != XFS_DINODE_FMT_EXTENTS)
  343. xfs_scrub_ino_set_corrupt(sc, ino);
  344. /* di_aformat */
  345. if (dip->di_aformat != XFS_DINODE_FMT_LOCAL &&
  346. dip->di_aformat != XFS_DINODE_FMT_EXTENTS &&
  347. dip->di_aformat != XFS_DINODE_FMT_BTREE)
  348. xfs_scrub_ino_set_corrupt(sc, ino);
  349. /* di_anextents */
  350. nextents = be16_to_cpu(dip->di_anextents);
  351. fork_recs = XFS_DFORK_ASIZE(dip, mp) / sizeof(struct xfs_bmbt_rec);
  352. switch (dip->di_aformat) {
  353. case XFS_DINODE_FMT_EXTENTS:
  354. if (nextents > fork_recs)
  355. xfs_scrub_ino_set_corrupt(sc, ino);
  356. break;
  357. case XFS_DINODE_FMT_BTREE:
  358. if (nextents <= fork_recs)
  359. xfs_scrub_ino_set_corrupt(sc, ino);
  360. break;
  361. default:
  362. if (nextents != 0)
  363. xfs_scrub_ino_set_corrupt(sc, ino);
  364. }
  365. if (dip->di_version >= 3) {
  366. if (be32_to_cpu(dip->di_crtime.t_nsec) >= NSEC_PER_SEC)
  367. xfs_scrub_ino_set_corrupt(sc, ino);
  368. xfs_scrub_inode_flags2(sc, dip, ino, mode, flags, flags2);
  369. xfs_scrub_inode_cowextsize(sc, dip, ino, mode, flags,
  370. flags2);
  371. }
  372. }
  373. /*
  374. * Make sure the finobt doesn't think this inode is free.
  375. * We don't have to check the inobt ourselves because we got the inode via
  376. * IGET_UNTRUSTED, which checks the inobt for us.
  377. */
  378. static void
  379. xfs_scrub_inode_xref_finobt(
  380. struct xfs_scrub_context *sc,
  381. xfs_ino_t ino)
  382. {
  383. struct xfs_inobt_rec_incore rec;
  384. xfs_agino_t agino;
  385. int has_record;
  386. int error;
  387. if (!sc->sa.fino_cur || xfs_scrub_skip_xref(sc->sm))
  388. return;
  389. agino = XFS_INO_TO_AGINO(sc->mp, ino);
  390. /*
  391. * Try to get the finobt record. If we can't get it, then we're
  392. * in good shape.
  393. */
  394. error = xfs_inobt_lookup(sc->sa.fino_cur, agino, XFS_LOOKUP_LE,
  395. &has_record);
  396. if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.fino_cur) ||
  397. !has_record)
  398. return;
  399. error = xfs_inobt_get_rec(sc->sa.fino_cur, &rec, &has_record);
  400. if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.fino_cur) ||
  401. !has_record)
  402. return;
  403. /*
  404. * Otherwise, make sure this record either doesn't cover this inode,
  405. * or that it does but it's marked present.
  406. */
  407. if (rec.ir_startino > agino ||
  408. rec.ir_startino + XFS_INODES_PER_CHUNK <= agino)
  409. return;
  410. if (rec.ir_free & XFS_INOBT_MASK(agino - rec.ir_startino))
  411. xfs_scrub_btree_xref_set_corrupt(sc, sc->sa.fino_cur, 0);
  412. }
  413. /* Cross reference the inode fields with the forks. */
  414. STATIC void
  415. xfs_scrub_inode_xref_bmap(
  416. struct xfs_scrub_context *sc,
  417. struct xfs_dinode *dip)
  418. {
  419. xfs_extnum_t nextents;
  420. xfs_filblks_t count;
  421. xfs_filblks_t acount;
  422. int error;
  423. if (xfs_scrub_skip_xref(sc->sm))
  424. return;
  425. /* Walk all the extents to check nextents/naextents/nblocks. */
  426. error = xfs_bmap_count_blocks(sc->tp, sc->ip, XFS_DATA_FORK,
  427. &nextents, &count);
  428. if (!xfs_scrub_should_check_xref(sc, &error, NULL))
  429. return;
  430. if (nextents < be32_to_cpu(dip->di_nextents))
  431. xfs_scrub_ino_xref_set_corrupt(sc, sc->ip->i_ino);
  432. error = xfs_bmap_count_blocks(sc->tp, sc->ip, XFS_ATTR_FORK,
  433. &nextents, &acount);
  434. if (!xfs_scrub_should_check_xref(sc, &error, NULL))
  435. return;
  436. if (nextents != be16_to_cpu(dip->di_anextents))
  437. xfs_scrub_ino_xref_set_corrupt(sc, sc->ip->i_ino);
  438. /* Check nblocks against the inode. */
  439. if (count + acount != be64_to_cpu(dip->di_nblocks))
  440. xfs_scrub_ino_xref_set_corrupt(sc, sc->ip->i_ino);
  441. }
  442. /* Cross-reference with the other btrees. */
  443. STATIC void
  444. xfs_scrub_inode_xref(
  445. struct xfs_scrub_context *sc,
  446. xfs_ino_t ino,
  447. struct xfs_dinode *dip)
  448. {
  449. struct xfs_owner_info oinfo;
  450. xfs_agnumber_t agno;
  451. xfs_agblock_t agbno;
  452. int error;
  453. if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
  454. return;
  455. agno = XFS_INO_TO_AGNO(sc->mp, ino);
  456. agbno = XFS_INO_TO_AGBNO(sc->mp, ino);
  457. error = xfs_scrub_ag_init(sc, agno, &sc->sa);
  458. if (!xfs_scrub_xref_process_error(sc, agno, agbno, &error))
  459. return;
  460. xfs_scrub_xref_is_used_space(sc, agbno, 1);
  461. xfs_scrub_inode_xref_finobt(sc, ino);
  462. xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INODES);
  463. xfs_scrub_xref_is_owned_by(sc, agbno, 1, &oinfo);
  464. xfs_scrub_xref_is_not_shared(sc, agbno, 1);
  465. xfs_scrub_inode_xref_bmap(sc, dip);
  466. xfs_scrub_ag_free(sc, &sc->sa);
  467. }
  468. /*
  469. * If the reflink iflag disagrees with a scan for shared data fork extents,
  470. * either flag an error (shared extents w/ no flag) or a preen (flag set w/o
  471. * any shared extents). We already checked for reflink iflag set on a non
  472. * reflink filesystem.
  473. */
  474. static void
  475. xfs_scrub_inode_check_reflink_iflag(
  476. struct xfs_scrub_context *sc,
  477. xfs_ino_t ino)
  478. {
  479. struct xfs_mount *mp = sc->mp;
  480. bool has_shared;
  481. int error;
  482. if (!xfs_sb_version_hasreflink(&mp->m_sb))
  483. return;
  484. error = xfs_reflink_inode_has_shared_extents(sc->tp, sc->ip,
  485. &has_shared);
  486. if (!xfs_scrub_xref_process_error(sc, XFS_INO_TO_AGNO(mp, ino),
  487. XFS_INO_TO_AGBNO(mp, ino), &error))
  488. return;
  489. if (xfs_is_reflink_inode(sc->ip) && !has_shared)
  490. xfs_scrub_ino_set_preen(sc, ino);
  491. else if (!xfs_is_reflink_inode(sc->ip) && has_shared)
  492. xfs_scrub_ino_set_corrupt(sc, ino);
  493. }
  494. /* Scrub an inode. */
  495. int
  496. xfs_scrub_inode(
  497. struct xfs_scrub_context *sc)
  498. {
  499. struct xfs_dinode di;
  500. int error = 0;
  501. /*
  502. * If sc->ip is NULL, that means that the setup function called
  503. * xfs_iget to look up the inode. xfs_iget returned a EFSCORRUPTED
  504. * and a NULL inode, so flag the corruption error and return.
  505. */
  506. if (!sc->ip) {
  507. xfs_scrub_ino_set_corrupt(sc, sc->sm->sm_ino);
  508. return 0;
  509. }
  510. /* Scrub the inode core. */
  511. xfs_inode_to_disk(sc->ip, &di, 0);
  512. xfs_scrub_dinode(sc, &di, sc->ip->i_ino);
  513. if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
  514. goto out;
  515. /*
  516. * Look for discrepancies between file's data blocks and the reflink
  517. * iflag. We already checked the iflag against the file mode when
  518. * we scrubbed the dinode.
  519. */
  520. if (S_ISREG(VFS_I(sc->ip)->i_mode))
  521. xfs_scrub_inode_check_reflink_iflag(sc, sc->ip->i_ino);
  522. xfs_scrub_inode_xref(sc, sc->ip->i_ino, &di);
  523. out:
  524. return error;
  525. }