Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+78 -33
+3
fs/dax.c
··· 1743 1743 loff_t done = 0; 1744 1744 int ret; 1745 1745 1746 + if (WARN_ON_ONCE(iocb->ki_flags & IOCB_ATOMIC)) 1747 + return -EIO; 1748 + 1746 1749 if (!iomi.len) 1747 1750 return 0; 1748 1751
+1 -1
fs/xfs/scrub/trace.h
··· 479 479 __field(xfs_exntst_t, state) 480 480 ), 481 481 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; 483 483 __entry->dqtype = cursor->dqtype; 484 484 __entry->ino = cursor->quota_ip->i_ino; 485 485 __entry->cur_id = cursor->id;
+3 -3
fs/xfs/xfs_file.c
··· 1101 1101 if (xfs_is_shutdown(ip->i_mount)) 1102 1102 return -EIO; 1103 1103 1104 - if (IS_DAX(inode)) 1105 - return xfs_file_dax_write(iocb, from); 1106 - 1107 1104 if (iocb->ki_flags & IOCB_ATOMIC) { 1108 1105 if (ocount < xfs_get_atomic_write_min(ip)) 1109 1106 return -EINVAL; ··· 1112 1115 if (ret) 1113 1116 return ret; 1114 1117 } 1118 + 1119 + if (IS_DAX(inode)) 1120 + return xfs_file_dax_write(iocb, from); 1115 1121 1116 1122 if (iocb->ki_flags & IOCB_DIRECT) { 1117 1123 /*
+11
fs/xfs/xfs_inode.h
··· 358 358 359 359 static inline bool xfs_inode_can_hw_atomic_write(const struct xfs_inode *ip) 360 360 { 361 + if (IS_DAX(VFS_IC(ip))) 362 + return false; 363 + 361 364 return xfs_inode_buftarg(ip)->bt_awu_max > 0; 365 + } 366 + 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); 362 373 } 363 374 364 375 /*
+1 -1
fs/xfs/xfs_ioctl.c
··· 219 219 else if (XFS_INO_TO_AGNO(mp, breq->startino) < hdr->agno) 220 220 return -EINVAL; 221 221 222 - breq->flags |= XFS_IBULK_SAME_AG; 222 + breq->iwalk_flags |= XFS_IWALK_SAME_AG; 223 223 224 224 /* Asking for an inode past the end of the AG? We're done! */ 225 225 if (XFS_INO_TO_AGNO(mp, breq->startino) > hdr->agno)
+3 -2
fs/xfs/xfs_iops.c
··· 616 616 * write of exactly one single fsblock if the bdev will make that 617 617 * guarantee for us. 618 618 */ 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)) 620 621 return mp->m_sb.sb_blocksize; 621 622 622 623 return 0; ··· 634 633 * write of exactly one single fsblock if the bdev will make that 635 634 * guarantee for us. 636 635 */ 637 - if (!xfs_can_sw_atomic_write(mp)) { 636 + if (!xfs_inode_can_sw_atomic_write(ip)) { 638 637 if (xfs_inode_can_hw_atomic_write(ip)) 639 638 return mp->m_sb.sb_blocksize; 640 639 return 0;
+2 -6
fs/xfs/xfs_itable.c
··· 307 307 .breq = breq, 308 308 }; 309 309 struct xfs_trans *tp; 310 - unsigned int iwalk_flags = 0; 311 310 int error; 312 311 313 312 if (breq->idmap != &nop_mnt_idmap) { ··· 327 328 * locking abilities to detect cycles in the inobt without deadlocking. 328 329 */ 329 330 tp = xfs_trans_alloc_empty(breq->mp); 330 - if (breq->flags & XFS_IBULK_SAME_AG) 331 - iwalk_flags |= XFS_IWALK_SAME_AG; 332 - 333 - error = xfs_iwalk(breq->mp, tp, breq->startino, iwalk_flags, 331 + error = xfs_iwalk(breq->mp, tp, breq->startino, breq->iwalk_flags, 334 332 xfs_bulkstat_iwalk, breq->icount, &bc); 335 333 xfs_trans_cancel(tp); 336 334 kfree(bc.buf); ··· 453 457 * locking abilities to detect cycles in the inobt without deadlocking. 454 458 */ 455 459 tp = xfs_trans_alloc_empty(breq->mp); 456 - error = xfs_inobt_walk(breq->mp, tp, breq->startino, breq->flags, 460 + error = xfs_inobt_walk(breq->mp, tp, breq->startino, breq->iwalk_flags, 457 461 xfs_inumbers_walk, breq->icount, &ic); 458 462 xfs_trans_cancel(tp); 459 463
+4 -6
fs/xfs/xfs_itable.h
··· 13 13 xfs_ino_t startino; /* start with this inode */ 14 14 unsigned int icount; /* number of elements in ubuffer */ 15 15 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_* */ 17 18 }; 18 19 19 - /* Only iterate within the same AG as startino */ 20 - #define XFS_IBULK_SAME_AG (1U << 0) 21 - 22 20 /* Fill out the bs_extents64 field if set. */ 23 - #define XFS_IBULK_NREXT64 (1U << 1) 21 + #define XFS_IBULK_NREXT64 (1U << 0) 24 22 25 23 /* Signal that we can return metadata directories. */ 26 - #define XFS_IBULK_METADIR (1U << 2) 24 + #define XFS_IBULK_METADIR (1U << 1) 27 25 28 26 /* 29 27 * Advance the user buffer pointer by one record of the given size. If the
+19
fs/xfs/xfs_mount.c
··· 779 779 return -EINVAL; 780 780 } 781 781 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 + 782 801 set_limit: 783 802 error = xfs_calc_atomic_write_reservation(mp, new_max_fsbs); 784 803 if (error) {
+1
fs/xfs/xfs_trace.h
··· 455 455 xfs_extlen_t len), \ 456 456 TP_ARGS(oz, rgbno, len)) 457 457 DEFINE_ZONE_ALLOC_EVENT(xfs_zone_record_blocks); 458 + DEFINE_ZONE_ALLOC_EVENT(xfs_zone_skip_blocks); 458 459 DEFINE_ZONE_ALLOC_EVENT(xfs_zone_alloc_blocks); 459 460 460 461 TRACE_EVENT(xfs_zone_gc_select_victim,
+1 -1
fs/xfs/xfs_trans.c
··· 253 253 * by doing GFP_KERNEL allocations inside sb_start_intwrite(). 254 254 */ 255 255 retry: 256 - WARN_ON(mp->m_super->s_writers.frozen == SB_FREEZE_COMPLETE); 257 256 tp = __xfs_trans_alloc(mp, flags); 257 + WARN_ON(mp->m_super->s_writers.frozen == SB_FREEZE_COMPLETE); 258 258 error = xfs_trans_reserve(tp, resp, blocks, rtextents); 259 259 if (error == -ENOSPC && want_retry) { 260 260 xfs_trans_cancel(tp);
+29 -13
fs/xfs/xfs_zone_alloc.c
··· 166 166 static void 167 167 xfs_zone_record_blocks( 168 168 struct xfs_trans *tp, 169 - xfs_fsblock_t fsbno, 170 - xfs_filblks_t len, 171 169 struct xfs_open_zone *oz, 172 - bool used) 170 + xfs_fsblock_t fsbno, 171 + xfs_filblks_t len) 173 172 { 174 173 struct xfs_mount *mp = tp->t_mountp; 175 174 struct xfs_rtgroup *rtg = oz->oz_rtg; ··· 178 179 179 180 xfs_rtgroup_lock(rtg, XFS_RTGLOCK_RMAP); 180 181 xfs_rtgroup_trans_join(tp, rtg, XFS_RTGLOCK_RMAP); 181 - if (used) { 182 - rmapip->i_used_blocks += len; 183 - ASSERT(rmapip->i_used_blocks <= rtg_blocks(rtg)); 184 - } else { 185 - xfs_add_frextents(mp, len); 186 - } 182 + rmapip->i_used_blocks += len; 183 + ASSERT(rmapip->i_used_blocks <= rtg_blocks(rtg)); 187 184 oz->oz_written += len; 188 185 if (oz->oz_written == rtg_blocks(rtg)) 189 186 xfs_open_zone_mark_full(oz); 190 187 xfs_trans_log_inode(tp, rmapip, XFS_ILOG_CORE); 188 + } 189 + 190 + /* 191 + * Called for blocks that have been written to disk, but not actually linked to 192 + * an inode, which can happen when garbage collection races with user data 193 + * writes to a file. 194 + */ 195 + static void 196 + xfs_zone_skip_blocks( 197 + struct xfs_open_zone *oz, 198 + xfs_filblks_t len) 199 + { 200 + struct xfs_rtgroup *rtg = oz->oz_rtg; 201 + 202 + trace_xfs_zone_skip_blocks(oz, 0, len); 203 + 204 + xfs_rtgroup_lock(rtg, XFS_RTGLOCK_RMAP); 205 + oz->oz_written += len; 206 + if (oz->oz_written == rtg_blocks(rtg)) 207 + xfs_open_zone_mark_full(oz); 208 + xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_RMAP); 209 + 210 + xfs_add_frextents(rtg_mount(rtg), len); 191 211 } 192 212 193 213 static int ··· 268 250 } 269 251 } 270 252 271 - xfs_zone_record_blocks(tp, new->br_startblock, new->br_blockcount, oz, 272 - true); 253 + xfs_zone_record_blocks(tp, oz, new->br_startblock, new->br_blockcount); 273 254 274 255 /* Map the new blocks into the data fork. */ 275 256 xfs_bmap_map_extent(tp, ip, XFS_DATA_FORK, new); ··· 276 259 277 260 skip: 278 261 trace_xfs_reflink_cow_remap_skip(ip, new); 279 - xfs_zone_record_blocks(tp, new->br_startblock, new->br_blockcount, oz, 280 - false); 262 + xfs_zone_skip_blocks(oz, new->br_blockcount); 281 263 return 0; 282 264 } 283 265