Fixes for 5.13-rc3:

- 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.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEUzaAxoMeQq6m2jMV+H93GTRKtOsFAmCmgSoACgkQ+H93GTRK
 tOvInhAAj9JbQLz/BPt14qVdteNDNBpdFdl/SC5Bow5ABOWi8FSOu9N/F32nMy9y
 fGPXP2G//sYzfW5jwE+ZPEEq7e+K55rLZHxHsbtWXjCL96t9edEDGFS5p6LmgnRW
 aJwE1QxhFHFJZEX1+Y08zmB+fSnwHJ4HzZihYb1f9sTI5cJRh7pvvj26HiqfUk9I
 FUT5Oo/Dy8gSSRmNCPWlLWhXJurrSwAYHmoE44vNHoEYHcodVwAK+ZR/Dj/5DQaS
 DTYgLeHZQmPijcW7/B/RKcEz96hMQ9afg7vBdgZwhG/oFCRKV2m3rYjjjo/AgKv4
 4FkmUoP5+CTT1vt9UKrdyl9uLTMqxiHuU1qvb82DM5XbbsLEFBBa+e3QrWmJqR8D
 3lBp6ogtOmbNEJpgLxCdbVl80HOjB+yaIWUB536nauz4USZvCcRGvdYDQ922q6ig
 1eT5Q6KCNgO3e6WIQ3W5kNJsM+/gXlNvwwhN/jHCQKy//bgVRnNYbODC6K46mjp/
 H8+NWyzQXpFjRWjmQ60LD2/RlyJVbbLbMkPTO1g/vjyZWjgp0fV2wtG6Ag/FlwVF
 DERUdp/0m6V+lPRcKbWCasjEc+pis6TDnvn+tCftXthh3fXGcalC3bnmv3yH9rkP
 YAejnDvuuLVtgPyVARA9DTQR5ch5CSRuFc6sU9SFL5nv2p59RtU=
 =IvUb
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Linus Torvalds 2021-05-21 18:45:09 -10:00
commit a3969ef463
3 changed files with 77 additions and 27 deletions

View File

@ -770,6 +770,8 @@ struct xfs_scrub_metadata {
/* /*
* ioctl commands that are used by Linux filesystems * 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 #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_ALLOCSP _IOW ('X', 10, struct xfs_flock64)
#define XFS_IOC_FREESP _IOW ('X', 11, 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_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_ALLOCSP64 _IOW ('X', 36, struct xfs_flock64)
#define XFS_IOC_FREESP64 _IOW ('X', 37, struct xfs_flock64) #define XFS_IOC_FREESP64 _IOW ('X', 37, struct xfs_flock64)
#define XFS_IOC_GETBMAP _IOWR('X', 38, struct getbmap) #define XFS_IOC_GETBMAP _IOWR('X', 38, struct getbmap)

View File

@ -74,7 +74,9 @@ __xchk_process_error(
return true; return true;
case -EDEADLOCK: case -EDEADLOCK:
/* Used to restart an op with deadlock avoidance. */ /* 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; break;
case -EFSBADCRC: case -EFSBADCRC:
case -EFSCORRUPTED: case -EFSCORRUPTED:

View File

@ -71,18 +71,24 @@ xfs_zero_extent(
#ifdef CONFIG_XFS_RT #ifdef CONFIG_XFS_RT
int int
xfs_bmap_rtalloc( xfs_bmap_rtalloc(
struct xfs_bmalloca *ap) /* bmap alloc argument struct */ struct xfs_bmalloca *ap)
{ {
int error; /* error return value */ struct xfs_mount *mp = ap->ip->i_mount;
xfs_mount_t *mp; /* mount point structure */ xfs_fileoff_t orig_offset = ap->offset;
xfs_rtblock_t rtb;
xfs_extlen_t prod = 0; /* product factor for allocators */ xfs_extlen_t prod = 0; /* product factor for allocators */
xfs_extlen_t mod = 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 ralen = 0; /* realtime allocation length */
xfs_extlen_t align; /* minimum allocation alignment */ 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); align = xfs_get_extsz_hint(ap->ip);
retry:
prod = align / mp->m_sb.sb_rextsize; prod = align / mp->m_sb.sb_rextsize;
error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev, error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev,
align, 1, ap->eof, 0, align, 1, ap->eof, 0,
@ -92,6 +98,15 @@ xfs_bmap_rtalloc(
ASSERT(ap->length); ASSERT(ap->length);
ASSERT(ap->length % mp->m_sb.sb_rextsize == 0); 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 * If the offset & length are not perfectly aligned
* then kill prod, it will just get us in trouble. * 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 * 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_ilock(mp->m_rbmip, XFS_ILOCK_EXCL|XFS_ILOCK_RTBITMAP);
xfs_trans_ijoin(ap->tp, mp->m_rbmip, XFS_ILOCK_EXCL); xfs_trans_ijoin(ap->tp, mp->m_rbmip, XFS_ILOCK_EXCL);
xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL|XFS_ILOCK_RTSUM); xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL|XFS_ILOCK_RTSUM);
xfs_trans_ijoin(ap->tp, mp->m_rsumip, XFS_ILOCK_EXCL); 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, * 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. * Realtime allocation, done through xfs_rtallocate_extent.
*/ */
if (ignore_locality)
ap->blkno = 0;
else
do_div(ap->blkno, mp->m_sb.sb_rextsize); do_div(ap->blkno, mp->m_sb.sb_rextsize);
rtb = ap->blkno; rtb = ap->blkno;
ap->length = ralen; 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); &ralen, ap->wasdel, prod, &rtb);
if (error) if (error)
return error; return error;
ap->blkno = rtb; if (rtb != NULLRTBLOCK) {
if (ap->blkno != NULLFSBLOCK) { ap->blkno = rtb * mp->m_sb.sb_rextsize;
ap->blkno *= mp->m_sb.sb_rextsize; ap->length = ralen * mp->m_sb.sb_rextsize;
ralen *= mp->m_sb.sb_rextsize; ap->ip->i_nblocks += ap->length;
ap->length = ralen;
ap->ip->i_nblocks += ralen;
xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE); xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE);
if (ap->wasdel) if (ap->wasdel)
ap->ip->i_delayed_blks -= ralen; ap->ip->i_delayed_blks -= ap->length;
/* /*
* Adjust the disk quota also. This was reserved * Adjust the disk quota also. This was reserved
* earlier. * earlier.
*/ */
xfs_trans_mod_dquot_byino(ap->tp, ap->ip, xfs_trans_mod_dquot_byino(ap->tp, ap->ip,
ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT : ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT :
XFS_TRANS_DQ_RTBCOUNT, (long) ralen); XFS_TRANS_DQ_RTBCOUNT, ap->length);
} else { return 0;
ap->length = 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; return 0;
} }
#endif /* CONFIG_XFS_RT */ #endif /* CONFIG_XFS_RT */