Commit a3969ef4 authored by Linus Torvalds's avatar Linus Torvalds

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
......@@ -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;
mp = ap->ip->i_mount;
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;
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 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment