forked from Minki/linux
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:
commit
a3969ef463
@ -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)
|
||||
|
@ -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,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 */
|
||||
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;
|
||||
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_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
|
||||
*/
|
||||
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);
|
||||
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.
|
||||
*/
|
||||
do_div(ap->blkno, mp->m_sb.sb_rextsize);
|
||||
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,
|
||||
&ralen, ap->wasdel, prod, &rtb);
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user