Skip to content

Commit a3969ef

Browse files
committed
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
2 parents 45af60e + e3c2b04 commit a3969ef

3 files changed

Lines changed: 78 additions & 28 deletions

File tree

fs/xfs/libxfs/xfs_fs.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,8 @@ struct xfs_scrub_metadata {
770770
/*
771771
* ioctl commands that are used by Linux filesystems
772772
*/
773+
#define XFS_IOC_GETXFLAGS FS_IOC_GETFLAGS
774+
#define XFS_IOC_SETXFLAGS FS_IOC_SETFLAGS
773775
#define XFS_IOC_GETVERSION FS_IOC_GETVERSION
774776

775777
/*
@@ -780,6 +782,8 @@ struct xfs_scrub_metadata {
780782
#define XFS_IOC_ALLOCSP _IOW ('X', 10, struct xfs_flock64)
781783
#define XFS_IOC_FREESP _IOW ('X', 11, struct xfs_flock64)
782784
#define XFS_IOC_DIOINFO _IOR ('X', 30, struct dioattr)
785+
#define XFS_IOC_FSGETXATTR FS_IOC_FSGETXATTR
786+
#define XFS_IOC_FSSETXATTR FS_IOC_FSSETXATTR
783787
#define XFS_IOC_ALLOCSP64 _IOW ('X', 36, struct xfs_flock64)
784788
#define XFS_IOC_FREESP64 _IOW ('X', 37, struct xfs_flock64)
785789
#define XFS_IOC_GETBMAP _IOWR('X', 38, struct getbmap)

fs/xfs/scrub/common.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ __xchk_process_error(
7474
return true;
7575
case -EDEADLOCK:
7676
/* Used to restart an op with deadlock avoidance. */
77-
trace_xchk_deadlock_retry(sc->ip, sc->sm, *error);
77+
trace_xchk_deadlock_retry(
78+
sc->ip ? sc->ip : XFS_I(file_inode(sc->file)),
79+
sc->sm, *error);
7880
break;
7981
case -EFSBADCRC:
8082
case -EFSCORRUPTED:

fs/xfs/xfs_bmap_util.c

Lines changed: 71 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -71,18 +71,24 @@ xfs_zero_extent(
7171
#ifdef CONFIG_XFS_RT
7272
int
7373
xfs_bmap_rtalloc(
74-
struct xfs_bmalloca *ap) /* bmap alloc argument struct */
74+
struct xfs_bmalloca *ap)
7575
{
76-
int error; /* error return value */
77-
xfs_mount_t *mp; /* mount point structure */
78-
xfs_extlen_t prod = 0; /* product factor for allocators */
79-
xfs_extlen_t mod = 0; /* product factor for allocators */
80-
xfs_extlen_t ralen = 0; /* realtime allocation length */
81-
xfs_extlen_t align; /* minimum allocation alignment */
82-
xfs_rtblock_t rtb;
83-
84-
mp = ap->ip->i_mount;
76+
struct xfs_mount *mp = ap->ip->i_mount;
77+
xfs_fileoff_t orig_offset = ap->offset;
78+
xfs_rtblock_t rtb;
79+
xfs_extlen_t prod = 0; /* product factor for allocators */
80+
xfs_extlen_t mod = 0; /* product factor for allocators */
81+
xfs_extlen_t ralen = 0; /* realtime allocation length */
82+
xfs_extlen_t align; /* minimum allocation alignment */
83+
xfs_extlen_t orig_length = ap->length;
84+
xfs_extlen_t minlen = mp->m_sb.sb_rextsize;
85+
xfs_extlen_t raminlen;
86+
bool rtlocked = false;
87+
bool ignore_locality = false;
88+
int error;
89+
8590
align = xfs_get_extsz_hint(ap->ip);
91+
retry:
8692
prod = align / mp->m_sb.sb_rextsize;
8793
error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev,
8894
align, 1, ap->eof, 0,
@@ -92,6 +98,15 @@ xfs_bmap_rtalloc(
9298
ASSERT(ap->length);
9399
ASSERT(ap->length % mp->m_sb.sb_rextsize == 0);
94100

101+
/*
102+
* If we shifted the file offset downward to satisfy an extent size
103+
* hint, increase minlen by that amount so that the allocator won't
104+
* give us an allocation that's too short to cover at least one of the
105+
* blocks that the caller asked for.
106+
*/
107+
if (ap->offset != orig_offset)
108+
minlen += orig_offset - ap->offset;
109+
95110
/*
96111
* If the offset & length are not perfectly aligned
97112
* then kill prod, it will just get us in trouble.
@@ -116,10 +131,13 @@ xfs_bmap_rtalloc(
116131
/*
117132
* Lock out modifications to both the RT bitmap and summary inodes
118133
*/
119-
xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL|XFS_ILOCK_RTBITMAP);
120-
xfs_trans_ijoin(ap->tp, mp->m_rbmip, XFS_ILOCK_EXCL);
121-
xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL|XFS_ILOCK_RTSUM);
122-
xfs_trans_ijoin(ap->tp, mp->m_rsumip, XFS_ILOCK_EXCL);
134+
if (!rtlocked) {
135+
xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL|XFS_ILOCK_RTBITMAP);
136+
xfs_trans_ijoin(ap->tp, mp->m_rbmip, XFS_ILOCK_EXCL);
137+
xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL|XFS_ILOCK_RTSUM);
138+
xfs_trans_ijoin(ap->tp, mp->m_rsumip, XFS_ILOCK_EXCL);
139+
rtlocked = true;
140+
}
123141

124142
/*
125143
* If it's an allocation to an empty file at offset 0,
@@ -141,33 +159,59 @@ xfs_bmap_rtalloc(
141159
/*
142160
* Realtime allocation, done through xfs_rtallocate_extent.
143161
*/
144-
do_div(ap->blkno, mp->m_sb.sb_rextsize);
162+
if (ignore_locality)
163+
ap->blkno = 0;
164+
else
165+
do_div(ap->blkno, mp->m_sb.sb_rextsize);
145166
rtb = ap->blkno;
146167
ap->length = ralen;
147-
error = xfs_rtallocate_extent(ap->tp, ap->blkno, 1, ap->length,
148-
&ralen, ap->wasdel, prod, &rtb);
168+
raminlen = max_t(xfs_extlen_t, 1, minlen / mp->m_sb.sb_rextsize);
169+
error = xfs_rtallocate_extent(ap->tp, ap->blkno, raminlen, ap->length,
170+
&ralen, ap->wasdel, prod, &rtb);
149171
if (error)
150172
return error;
151173

152-
ap->blkno = rtb;
153-
if (ap->blkno != NULLFSBLOCK) {
154-
ap->blkno *= mp->m_sb.sb_rextsize;
155-
ralen *= mp->m_sb.sb_rextsize;
156-
ap->length = ralen;
157-
ap->ip->i_nblocks += ralen;
174+
if (rtb != NULLRTBLOCK) {
175+
ap->blkno = rtb * mp->m_sb.sb_rextsize;
176+
ap->length = ralen * mp->m_sb.sb_rextsize;
177+
ap->ip->i_nblocks += ap->length;
158178
xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE);
159179
if (ap->wasdel)
160-
ap->ip->i_delayed_blks -= ralen;
180+
ap->ip->i_delayed_blks -= ap->length;
161181
/*
162182
* Adjust the disk quota also. This was reserved
163183
* earlier.
164184
*/
165185
xfs_trans_mod_dquot_byino(ap->tp, ap->ip,
166186
ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT :
167-
XFS_TRANS_DQ_RTBCOUNT, (long) ralen);
168-
} else {
169-
ap->length = 0;
187+
XFS_TRANS_DQ_RTBCOUNT, ap->length);
188+
return 0;
170189
}
190+
191+
if (align > mp->m_sb.sb_rextsize) {
192+
/*
193+
* We previously enlarged the request length to try to satisfy
194+
* an extent size hint. The allocator didn't return anything,
195+
* so reset the parameters to the original values and try again
196+
* without alignment criteria.
197+
*/
198+
ap->offset = orig_offset;
199+
ap->length = orig_length;
200+
minlen = align = mp->m_sb.sb_rextsize;
201+
goto retry;
202+
}
203+
204+
if (!ignore_locality && ap->blkno != 0) {
205+
/*
206+
* If we can't allocate near a specific rt extent, try again
207+
* without locality criteria.
208+
*/
209+
ignore_locality = true;
210+
goto retry;
211+
}
212+
213+
ap->blkno = NULLFSBLOCK;
214+
ap->length = 0;
171215
return 0;
172216
}
173217
#endif /* CONFIG_XFS_RT */

0 commit comments

Comments
 (0)