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 { ...@@ -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 { ...@@ -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)
......
...@@ -74,7 +74,9 @@ __xchk_process_error( ...@@ -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:
......
...@@ -71,18 +71,24 @@ xfs_zero_extent( ...@@ -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( ...@@ -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( ...@@ -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( ...@@ -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 */
......
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