inode.c 16 KB

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