Commit 7b63ce86 authored by Chandan Babu R's avatar Chandan Babu R
Browse files

Merge tag 'repair-inodes-6.8_2023-12-15' of...

Merge tag 'repair-inodes-6.8_2023-12-15' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux

 into xfs-6.8-mergeB

xfs: online repair of inodes and forks

In this series, online repair gains the ability to repair inode records.
To do this, we must repair the ondisk inode and fork information enough
to pass the iget verifiers and hence make the inode igettable again.
Once that's done, we can perform higher level repairs on the incore
inode.  The fstests counterpart of this patchset implements stress
testing of repair.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarChandan Babu R <chandanbabu@kernel.org>

* tag 'repair-inodes-6.8_2023-12-15' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux:
  xfs: skip the rmapbt search on an empty attr fork unless we know it was zapped
  xfs: abort directory parent scrub scans if we encounter a zapped directory
  xfs: zap broken inode forks
  xfs: repair inode records
  xfs: set inode sick state flags when we zap either ondisk fork
  xfs: dont cast to char * for XFS_DFORK_*PTR macros
  xfs: add missing nrext64 inode flag check to scrub
  xfs: try to attach dquots to files before repairing them
  xfs: disable online repair quota helpers when quota not enabled
parents 6e1d7b89 c3a22c2e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -184,6 +184,7 @@ xfs-y += $(addprefix scrub/, \
				   agheader_repair.o \
				   alloc_repair.o \
				   ialloc_repair.o \
				   inode_repair.o \
				   newbt.o \
				   reap.o \
				   refcount_repair.o \
+3 −10
Original line number Diff line number Diff line
@@ -1040,23 +1040,16 @@ xfs_attr_shortform_allfit(
	return xfs_attr_shortform_bytesfit(dp, bytes);
}

/* Verify the consistency of an inline attribute fork. */
/* Verify the consistency of a raw inline attribute fork. */
xfs_failaddr_t
xfs_attr_shortform_verify(
	struct xfs_inode		*ip)
	struct xfs_attr_shortform	*sfp,
	size_t				size)
{
	struct xfs_attr_shortform	*sfp;
	struct xfs_attr_sf_entry	*sfep;
	struct xfs_attr_sf_entry	*next_sfep;
	char				*endp;
	struct xfs_ifork		*ifp;
	int				i;
	int64_t				size;

	ASSERT(ip->i_af.if_format == XFS_DINODE_FMT_LOCAL);
	ifp = xfs_ifork_ptr(ip, XFS_ATTR_FORK);
	sfp = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
	size = ifp->if_bytes;

	/*
	 * Give up if the attribute is way too short.
+2 −1
Original line number Diff line number Diff line
@@ -56,7 +56,8 @@ int xfs_attr_sf_findname(struct xfs_da_args *args,
			     unsigned int *basep);
int	xfs_attr_shortform_allfit(struct xfs_buf *bp, struct xfs_inode *dp);
int	xfs_attr_shortform_bytesfit(struct xfs_inode *dp, int bytes);
xfs_failaddr_t xfs_attr_shortform_verify(struct xfs_inode *ip);
xfs_failaddr_t xfs_attr_shortform_verify(struct xfs_attr_shortform *sfp,
		size_t size);
void	xfs_attr_fork_remove(struct xfs_inode *ip, struct xfs_trans *tp);

/*
+16 −6
Original line number Diff line number Diff line
@@ -6168,19 +6168,18 @@ xfs_bmap_finish_one(
	return error;
}

/* Check that an inode's extent does not have invalid flags or bad ranges. */
/* Check that an extent does not have invalid flags or bad ranges. */
xfs_failaddr_t
xfs_bmap_validate_extent(
	struct xfs_inode	*ip,
xfs_bmap_validate_extent_raw(
	struct xfs_mount	*mp,
	bool			rtfile,
	int			whichfork,
	struct xfs_bmbt_irec	*irec)
{
	struct xfs_mount	*mp = ip->i_mount;

	if (!xfs_verify_fileext(mp, irec->br_startoff, irec->br_blockcount))
		return __this_address;

	if (XFS_IS_REALTIME_INODE(ip) && whichfork == XFS_DATA_FORK) {
	if (rtfile && whichfork == XFS_DATA_FORK) {
		if (!xfs_verify_rtbext(mp, irec->br_startblock,
					   irec->br_blockcount))
			return __this_address;
@@ -6210,3 +6209,14 @@ xfs_bmap_intent_destroy_cache(void)
	kmem_cache_destroy(xfs_bmap_intent_cache);
	xfs_bmap_intent_cache = NULL;
}

/* Check that an inode's extent does not have invalid flags or bad ranges. */
xfs_failaddr_t
xfs_bmap_validate_extent(
	struct xfs_inode	*ip,
	int			whichfork,
	struct xfs_bmbt_irec	*irec)
{
	return xfs_bmap_validate_extent_raw(ip->i_mount,
			XFS_IS_REALTIME_INODE(ip), whichfork, irec);
}
+2 −0
Original line number Diff line number Diff line
@@ -263,6 +263,8 @@ static inline uint32_t xfs_bmap_fork_to_state(int whichfork)
	}
}

xfs_failaddr_t xfs_bmap_validate_extent_raw(struct xfs_mount *mp, bool rtfile,
		int whichfork, struct xfs_bmbt_irec *irec);
xfs_failaddr_t xfs_bmap_validate_extent(struct xfs_inode *ip, int whichfork,
		struct xfs_bmbt_irec *irec);
int xfs_bmap_complain_bad_rec(struct xfs_inode *ip, int whichfork,
Loading