Commit a3969ef4 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'xfs-5.13-fixes-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull xfs fixes from Darrick Wong:

 - Fix some math errors in the realtime allocator when extent size hints
   are applied.

 - Fix unnecessary short writes to realtime files when free space is
   fragmented.

 - Fix a crash when using scrub tracepoints.

 - Restore ioctl uapi definitions that were accidentally removed in
   5.13-rc1.

* tag 'xfs-5.13-fixes-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
  xfs: restore old ioctl definitions
  xfs: fix deadlock retry tracepoint arguments
  xfs: retry allocations when locality-based search fails
  xfs: adjust rt allocation minlen when extszhint > rtextsize
parents 45af60e7 e3c2b047
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -770,6 +770,8 @@ struct xfs_scrub_metadata {
/*
 * ioctl commands that are used by Linux filesystems
 */
#define XFS_IOC_GETXFLAGS	FS_IOC_GETFLAGS
#define XFS_IOC_SETXFLAGS	FS_IOC_SETFLAGS
#define XFS_IOC_GETVERSION	FS_IOC_GETVERSION

/*
@@ -780,6 +782,8 @@ struct xfs_scrub_metadata {
#define XFS_IOC_ALLOCSP		_IOW ('X', 10, struct xfs_flock64)
#define XFS_IOC_FREESP		_IOW ('X', 11, struct xfs_flock64)
#define XFS_IOC_DIOINFO		_IOR ('X', 30, struct dioattr)
#define XFS_IOC_FSGETXATTR	FS_IOC_FSGETXATTR
#define XFS_IOC_FSSETXATTR	FS_IOC_FSSETXATTR
#define XFS_IOC_ALLOCSP64	_IOW ('X', 36, struct xfs_flock64)
#define XFS_IOC_FREESP64	_IOW ('X', 37, struct xfs_flock64)
#define XFS_IOC_GETBMAP		_IOWR('X', 38, struct getbmap)
+3 −1
Original line number Diff line number Diff line
@@ -74,7 +74,9 @@ __xchk_process_error(
		return true;
	case -EDEADLOCK:
		/* Used to restart an op with deadlock avoidance. */
		trace_xchk_deadlock_retry(sc->ip, sc->sm, *error);
		trace_xchk_deadlock_retry(
				sc->ip ? sc->ip : XFS_I(file_inode(sc->file)),
				sc->sm, *error);
		break;
	case -EFSBADCRC:
	case -EFSCORRUPTED:
+71 −27
Original line number Diff line number Diff line
@@ -71,18 +71,24 @@ xfs_zero_extent(
#ifdef CONFIG_XFS_RT
int
xfs_bmap_rtalloc(
	struct xfs_bmalloca	*ap)	/* bmap alloc argument struct */
	struct xfs_bmalloca	*ap)
{
	int		error;		/* error return value */
	xfs_mount_t	*mp;		/* mount point structure */
	struct xfs_mount	*mp = ap->ip->i_mount;
	xfs_fileoff_t		orig_offset = ap->offset;
	xfs_rtblock_t		rtb;
	xfs_extlen_t		prod = 0;  /* product factor for allocators */
	xfs_extlen_t		mod = 0;   /* product factor for allocators */
	xfs_extlen_t		ralen = 0; /* realtime allocation length */
	xfs_extlen_t		align;     /* minimum allocation alignment */
	xfs_rtblock_t	rtb;
	xfs_extlen_t		orig_length = ap->length;
	xfs_extlen_t		minlen = mp->m_sb.sb_rextsize;
	xfs_extlen_t		raminlen;
	bool			rtlocked = false;
	bool			ignore_locality = false;
	int			error;

	mp = ap->ip->i_mount;
	align = xfs_get_extsz_hint(ap->ip);
retry:
	prod = align / mp->m_sb.sb_rextsize;
	error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev,
					align, 1, ap->eof, 0,
@@ -92,6 +98,15 @@ xfs_bmap_rtalloc(
	ASSERT(ap->length);
	ASSERT(ap->length % mp->m_sb.sb_rextsize == 0);

	/*
	 * If we shifted the file offset downward to satisfy an extent size
	 * hint, increase minlen by that amount so that the allocator won't
	 * give us an allocation that's too short to cover at least one of the
	 * blocks that the caller asked for.
	 */
	if (ap->offset != orig_offset)
		minlen += orig_offset - ap->offset;

	/*
	 * If the offset & length are not perfectly aligned
	 * then kill prod, it will just get us in trouble.
@@ -116,10 +131,13 @@ xfs_bmap_rtalloc(
	/*
	 * Lock out modifications to both the RT bitmap and summary inodes
	 */
	if (!rtlocked) {
		xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL|XFS_ILOCK_RTBITMAP);
		xfs_trans_ijoin(ap->tp, mp->m_rbmip, XFS_ILOCK_EXCL);
		xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL|XFS_ILOCK_RTSUM);
		xfs_trans_ijoin(ap->tp, mp->m_rsumip, XFS_ILOCK_EXCL);
		rtlocked = true;
	}

	/*
	 * If it's an allocation to an empty file at offset 0,
@@ -141,33 +159,59 @@ xfs_bmap_rtalloc(
	/*
	 * Realtime allocation, done through xfs_rtallocate_extent.
	 */
	if (ignore_locality)
		ap->blkno = 0;
	else
		do_div(ap->blkno, mp->m_sb.sb_rextsize);
	rtb = ap->blkno;
	ap->length = ralen;
	error = xfs_rtallocate_extent(ap->tp, ap->blkno, 1, ap->length,
	raminlen = max_t(xfs_extlen_t, 1, minlen / mp->m_sb.sb_rextsize);
	error = xfs_rtallocate_extent(ap->tp, ap->blkno, raminlen, ap->length,
			&ralen, ap->wasdel, prod, &rtb);
	if (error)
		return error;

	ap->blkno = rtb;
	if (ap->blkno != NULLFSBLOCK) {
		ap->blkno *= mp->m_sb.sb_rextsize;
		ralen *= mp->m_sb.sb_rextsize;
		ap->length = ralen;
		ap->ip->i_nblocks += ralen;
	if (rtb != NULLRTBLOCK) {
		ap->blkno = rtb * mp->m_sb.sb_rextsize;
		ap->length = ralen * mp->m_sb.sb_rextsize;
		ap->ip->i_nblocks += ap->length;
		xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE);
		if (ap->wasdel)
			ap->ip->i_delayed_blks -= ralen;
			ap->ip->i_delayed_blks -= ap->length;
		/*
		 * Adjust the disk quota also. This was reserved
		 * earlier.
		 */
		xfs_trans_mod_dquot_byino(ap->tp, ap->ip,
			ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT :
					XFS_TRANS_DQ_RTBCOUNT, (long) ralen);
	} else {
		ap->length = 0;
					XFS_TRANS_DQ_RTBCOUNT, ap->length);
		return 0;
	}

	if (align > mp->m_sb.sb_rextsize) {
		/*
		 * We previously enlarged the request length to try to satisfy
		 * an extent size hint.  The allocator didn't return anything,
		 * so reset the parameters to the original values and try again
		 * without alignment criteria.
		 */
		ap->offset = orig_offset;
		ap->length = orig_length;
		minlen = align = mp->m_sb.sb_rextsize;
		goto retry;
	}

	if (!ignore_locality && ap->blkno != 0) {
		/*
		 * If we can't allocate near a specific rt extent, try again
		 * without locality criteria.
		 */
		ignore_locality = true;
		goto retry;
	}

	ap->blkno = NULLFSBLOCK;
	ap->length = 0;
	return 0;
}
#endif /* CONFIG_XFS_RT */