Skip to content

Commit d0efc9e

Browse files
committed
Merge tag 'xfs-fixes-6.17-rc2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull xfs fixes from Carlos Maiolino: - Fix an assert trigger introduced during the merge window - Prevent atomic writes to be used with DAX - Prevent users from using the max_atomic_write mount option without reflink, as atomic writes > 1block are not supported without reflink - Fix a null-pointer-deref in a tracepoint * tag 'xfs-fixes-6.17-rc2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: xfs: split xfs_zone_record_blocks xfs: fix scrub trace with null pointer in quotacheck xfs: reject max_atomic_write mount option for no reflink xfs: disallow atomic writes on DAX fs/dax: Reject IOCB_ATOMIC in dax_iomap_rw() xfs: remove XFS_IBULK_SAME_AG xfs: fully decouple XFS_IBULK* flags from XFS_IWALK* flags xfs: fix frozen file system assert in xfs_trans_alloc
2 parents ee94b00 + f76823e commit d0efc9e

File tree

12 files changed

+78
-33
lines changed

12 files changed

+78
-33
lines changed

fs/dax.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,6 +1743,9 @@ dax_iomap_rw(struct kiocb *iocb, struct iov_iter *iter,
17431743
loff_t done = 0;
17441744
int ret;
17451745

1746+
if (WARN_ON_ONCE(iocb->ki_flags & IOCB_ATOMIC))
1747+
return -EIO;
1748+
17461749
if (!iomi.len)
17471750
return 0;
17481751

fs/xfs/scrub/trace.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ DECLARE_EVENT_CLASS(xchk_dqiter_class,
479479
__field(xfs_exntst_t, state)
480480
),
481481
TP_fast_assign(
482-
__entry->dev = cursor->sc->ip->i_mount->m_super->s_dev;
482+
__entry->dev = cursor->sc->mp->m_super->s_dev;
483483
__entry->dqtype = cursor->dqtype;
484484
__entry->ino = cursor->quota_ip->i_ino;
485485
__entry->cur_id = cursor->id;

fs/xfs/xfs_file.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,9 +1101,6 @@ xfs_file_write_iter(
11011101
if (xfs_is_shutdown(ip->i_mount))
11021102
return -EIO;
11031103

1104-
if (IS_DAX(inode))
1105-
return xfs_file_dax_write(iocb, from);
1106-
11071104
if (iocb->ki_flags & IOCB_ATOMIC) {
11081105
if (ocount < xfs_get_atomic_write_min(ip))
11091106
return -EINVAL;
@@ -1116,6 +1113,9 @@ xfs_file_write_iter(
11161113
return ret;
11171114
}
11181115

1116+
if (IS_DAX(inode))
1117+
return xfs_file_dax_write(iocb, from);
1118+
11191119
if (iocb->ki_flags & IOCB_DIRECT) {
11201120
/*
11211121
* Allow a directio write to fall back to a buffered

fs/xfs/xfs_inode.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,9 +358,20 @@ static inline bool xfs_inode_has_bigrtalloc(const struct xfs_inode *ip)
358358

359359
static inline bool xfs_inode_can_hw_atomic_write(const struct xfs_inode *ip)
360360
{
361+
if (IS_DAX(VFS_IC(ip)))
362+
return false;
363+
361364
return xfs_inode_buftarg(ip)->bt_awu_max > 0;
362365
}
363366

367+
static inline bool xfs_inode_can_sw_atomic_write(const struct xfs_inode *ip)
368+
{
369+
if (IS_DAX(VFS_IC(ip)))
370+
return false;
371+
372+
return xfs_can_sw_atomic_write(ip->i_mount);
373+
}
374+
364375
/*
365376
* In-core inode flags.
366377
*/

fs/xfs/xfs_ioctl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ xfs_bulk_ireq_setup(
219219
else if (XFS_INO_TO_AGNO(mp, breq->startino) < hdr->agno)
220220
return -EINVAL;
221221

222-
breq->flags |= XFS_IBULK_SAME_AG;
222+
breq->iwalk_flags |= XFS_IWALK_SAME_AG;
223223

224224
/* Asking for an inode past the end of the AG? We're done! */
225225
if (XFS_INO_TO_AGNO(mp, breq->startino) > hdr->agno)

fs/xfs/xfs_iops.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,8 @@ xfs_get_atomic_write_min(
616616
* write of exactly one single fsblock if the bdev will make that
617617
* guarantee for us.
618618
*/
619-
if (xfs_inode_can_hw_atomic_write(ip) || xfs_can_sw_atomic_write(mp))
619+
if (xfs_inode_can_hw_atomic_write(ip) ||
620+
xfs_inode_can_sw_atomic_write(ip))
620621
return mp->m_sb.sb_blocksize;
621622

622623
return 0;
@@ -633,7 +634,7 @@ xfs_get_atomic_write_max(
633634
* write of exactly one single fsblock if the bdev will make that
634635
* guarantee for us.
635636
*/
636-
if (!xfs_can_sw_atomic_write(mp)) {
637+
if (!xfs_inode_can_sw_atomic_write(ip)) {
637638
if (xfs_inode_can_hw_atomic_write(ip))
638639
return mp->m_sb.sb_blocksize;
639640
return 0;

fs/xfs/xfs_itable.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,6 @@ xfs_bulkstat(
307307
.breq = breq,
308308
};
309309
struct xfs_trans *tp;
310-
unsigned int iwalk_flags = 0;
311310
int error;
312311

313312
if (breq->idmap != &nop_mnt_idmap) {
@@ -328,10 +327,7 @@ xfs_bulkstat(
328327
* locking abilities to detect cycles in the inobt without deadlocking.
329328
*/
330329
tp = xfs_trans_alloc_empty(breq->mp);
331-
if (breq->flags & XFS_IBULK_SAME_AG)
332-
iwalk_flags |= XFS_IWALK_SAME_AG;
333-
334-
error = xfs_iwalk(breq->mp, tp, breq->startino, iwalk_flags,
330+
error = xfs_iwalk(breq->mp, tp, breq->startino, breq->iwalk_flags,
335331
xfs_bulkstat_iwalk, breq->icount, &bc);
336332
xfs_trans_cancel(tp);
337333
kfree(bc.buf);
@@ -457,7 +453,7 @@ xfs_inumbers(
457453
* locking abilities to detect cycles in the inobt without deadlocking.
458454
*/
459455
tp = xfs_trans_alloc_empty(breq->mp);
460-
error = xfs_inobt_walk(breq->mp, tp, breq->startino, breq->flags,
456+
error = xfs_inobt_walk(breq->mp, tp, breq->startino, breq->iwalk_flags,
461457
xfs_inumbers_walk, breq->icount, &ic);
462458
xfs_trans_cancel(tp);
463459

fs/xfs/xfs_itable.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,15 @@ struct xfs_ibulk {
1313
xfs_ino_t startino; /* start with this inode */
1414
unsigned int icount; /* number of elements in ubuffer */
1515
unsigned int ocount; /* number of records returned */
16-
unsigned int flags; /* see XFS_IBULK_FLAG_* */
16+
unsigned int flags; /* XFS_IBULK_FLAG_* */
17+
unsigned int iwalk_flags; /* XFS_IWALK_FLAG_* */
1718
};
1819

19-
/* Only iterate within the same AG as startino */
20-
#define XFS_IBULK_SAME_AG (1U << 0)
21-
2220
/* Fill out the bs_extents64 field if set. */
23-
#define XFS_IBULK_NREXT64 (1U << 1)
21+
#define XFS_IBULK_NREXT64 (1U << 0)
2422

2523
/* Signal that we can return metadata directories. */
26-
#define XFS_IBULK_METADIR (1U << 2)
24+
#define XFS_IBULK_METADIR (1U << 1)
2725

2826
/*
2927
* Advance the user buffer pointer by one record of the given size. If the

fs/xfs/xfs_mount.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,25 @@ xfs_set_max_atomic_write_opt(
779779
return -EINVAL;
780780
}
781781

782+
if (xfs_has_reflink(mp))
783+
goto set_limit;
784+
785+
if (new_max_fsbs == 1) {
786+
if (mp->m_ddev_targp->bt_awu_max ||
787+
(mp->m_rtdev_targp && mp->m_rtdev_targp->bt_awu_max)) {
788+
} else {
789+
xfs_warn(mp,
790+
"cannot support atomic writes of size %lluk with no reflink or HW support",
791+
new_max_bytes >> 10);
792+
return -EINVAL;
793+
}
794+
} else {
795+
xfs_warn(mp,
796+
"cannot support atomic writes of size %lluk with no reflink support",
797+
new_max_bytes >> 10);
798+
return -EINVAL;
799+
}
800+
782801
set_limit:
783802
error = xfs_calc_atomic_write_reservation(mp, new_max_fsbs);
784803
if (error) {

fs/xfs/xfs_trace.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,7 @@ DEFINE_EVENT(xfs_zone_alloc_class, name, \
455455
xfs_extlen_t len), \
456456
TP_ARGS(oz, rgbno, len))
457457
DEFINE_ZONE_ALLOC_EVENT(xfs_zone_record_blocks);
458+
DEFINE_ZONE_ALLOC_EVENT(xfs_zone_skip_blocks);
458459
DEFINE_ZONE_ALLOC_EVENT(xfs_zone_alloc_blocks);
459460

460461
TRACE_EVENT(xfs_zone_gc_select_victim,

0 commit comments

Comments
 (0)