/* Scrub an inode. */ int xchk_inode( struct xfs_scrub *sc) { struct xfs_dinode di; int error = 0; /* * If sc->ip is NULL, that means that the setup function called * xfs_iget to look up the inode. xfs_iget returned a EFSCORRUPTED * and a NULL inode, so flag the corruption error and return. */ if (!sc->ip) { xchk_ino_set_corrupt(sc, sc->sm->sm_ino); return 0; } /* Scrub the inode core. */ xfs_inode_to_disk(sc->ip, &di, 0); xchk_dinode(sc, &di, sc->ip->i_ino); if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) goto out; /* * Look for discrepancies between file's data blocks and the reflink * iflag. We already checked the iflag against the file mode when * we scrubbed the dinode. */ if (S_ISREG(VFS_I(sc->ip)->i_mode)) xchk_inode_check_reflink_iflag(sc, sc->ip->i_ino); xchk_inode_xref(sc, sc->ip->i_ino, &di); out: return error; }
/* * Writes a modified inode's changes out to the inode's on disk home. * Originally based on xfs_iflush_int() from xfs_inode.c in the kernel. */ int libxfs_iflush_int(xfs_inode_t *ip, xfs_buf_t *bp) { xfs_inode_log_item_t *iip; xfs_dinode_t *dip; xfs_mount_t *mp; ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL); ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || ip->i_d.di_nextents > ip->i_df.if_ext_max); ASSERT(ip->i_d.di_version > 1); iip = ip->i_itemp; mp = ip->i_mount; /* set *dip = inode's place in the buffer */ dip = xfs_buf_offset(bp, ip->i_imap.im_boffset); ASSERT(ip->i_d.di_magic == XFS_DINODE_MAGIC); if (XFS_ISREG(ip)) { ASSERT( (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS) || (ip->i_d.di_format == XFS_DINODE_FMT_BTREE) ); } else if (XFS_ISDIR(ip)) { ASSERT( (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS) || (ip->i_d.di_format == XFS_DINODE_FMT_BTREE) || (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL) ); } ASSERT(ip->i_d.di_nextents+ip->i_d.di_anextents <= ip->i_d.di_nblocks); ASSERT(ip->i_d.di_forkoff <= mp->m_sb.sb_inodesize); /* bump the change count on v3 inodes */ if (ip->i_d.di_version == 3) VFS_I(ip)->i_version++; /* * Copy the dirty parts of the inode into the on-disk * inode. We always copy out the core of the inode, * because if the inode is dirty at all the core must * be. */ xfs_inode_to_disk(ip, dip, iip->ili_item.li_lsn); xfs_iflush_fork(ip, dip, iip, XFS_DATA_FORK); if (XFS_IFORK_Q(ip)) xfs_iflush_fork(ip, dip, iip, XFS_ATTR_FORK); /* generate the checksum. */ xfs_dinode_calc_crc(mp, dip); return 0; }