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-6.7-fixes-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull xfs fixes from Chandan Babu:

- Fix deadlock arising due to intent items in AIL not being cleared
when log recovery fails

- Fix stale data exposure bug when remapping COW fork extents to data
fork

- Fix deadlock when data device flush fails

- Fix AGFL minimum size calculation

- Select DEBUG_FS instead of XFS_DEBUG when XFS_ONLINE_SCRUB_STATS is
selected

- Fix corruption of log inode's extent count field when NREXT64 feature
is enabled

* tag 'xfs-6.7-fixes-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
xfs: recovery should not clear di_flushiter unconditionally
xfs: inode recovery does not validate the recovered inode
xfs: fix again select in kconfig XFS_ONLINE_SCRUB_STATS
xfs: fix internal error from AGFL exhaustion
xfs: up(ic_sema) if flushing data device fails
xfs: only remap the written blocks in xfs_reflink_end_cow_extent
XFS: Update MAINTAINERS to catch all XFS documentation
xfs: abort intent items when recovery intents fail
xfs: factor out xfs_defer_pending_abort

+97 -50
+1 -2
MAINTAINERS
··· 23882 23882 P: Documentation/filesystems/xfs-maintainer-entry-profile.rst 23883 23883 F: Documentation/ABI/testing/sysfs-fs-xfs 23884 23884 F: Documentation/admin-guide/xfs.rst 23885 - F: Documentation/filesystems/xfs-delayed-logging-design.rst 23886 - F: Documentation/filesystems/xfs-self-describing-metadata.rst 23885 + F: Documentation/filesystems/xfs-* 23887 23886 F: fs/xfs/ 23888 23887 F: include/uapi/linux/dqblk_xfs.h 23889 23888 F: include/uapi/linux/fsmap.h
+1 -1
fs/xfs/Kconfig
··· 147 147 bool "XFS online metadata check usage data collection" 148 148 default y 149 149 depends on XFS_ONLINE_SCRUB 150 - select XFS_DEBUG 150 + select DEBUG_FS 151 151 help 152 152 If you say Y here, the kernel will gather usage data about 153 153 the online metadata check subsystem. This includes the number
+24 -3
fs/xfs/libxfs/xfs_alloc.c
··· 2275 2275 2276 2276 ASSERT(mp->m_alloc_maxlevels > 0); 2277 2277 2278 + /* 2279 + * For a btree shorter than the maximum height, the worst case is that 2280 + * every level gets split and a new level is added, then while inserting 2281 + * another entry to refill the AGFL, every level under the old root gets 2282 + * split again. This is: 2283 + * 2284 + * (full height split reservation) + (AGFL refill split height) 2285 + * = (current height + 1) + (current height - 1) 2286 + * = (new height) + (new height - 2) 2287 + * = 2 * new height - 2 2288 + * 2289 + * For a btree of maximum height, the worst case is that every level 2290 + * under the root gets split, then while inserting another entry to 2291 + * refill the AGFL, every level under the root gets split again. This is 2292 + * also: 2293 + * 2294 + * 2 * (current height - 1) 2295 + * = 2 * (new height - 1) 2296 + * = 2 * new height - 2 2297 + */ 2298 + 2278 2299 /* space needed by-bno freespace btree */ 2279 2300 min_free = min_t(unsigned int, levels[XFS_BTNUM_BNOi] + 1, 2280 - mp->m_alloc_maxlevels); 2301 + mp->m_alloc_maxlevels) * 2 - 2; 2281 2302 /* space needed by-size freespace btree */ 2282 2303 min_free += min_t(unsigned int, levels[XFS_BTNUM_CNTi] + 1, 2283 - mp->m_alloc_maxlevels); 2304 + mp->m_alloc_maxlevels) * 2 - 2; 2284 2305 /* space needed reverse mapping used space btree */ 2285 2306 if (xfs_has_rmapbt(mp)) 2286 2307 min_free += min_t(unsigned int, levels[XFS_BTNUM_RMAPi] + 1, 2287 - mp->m_rmap_maxlevels); 2308 + mp->m_rmap_maxlevels) * 2 - 2; 2288 2309 2289 2310 return min_free; 2290 2311 }
+23 -15
fs/xfs/libxfs/xfs_defer.c
··· 245 245 return ret; 246 246 } 247 247 248 + STATIC void 249 + xfs_defer_pending_abort( 250 + struct xfs_mount *mp, 251 + struct list_head *dop_list) 252 + { 253 + struct xfs_defer_pending *dfp; 254 + const struct xfs_defer_op_type *ops; 255 + 256 + /* Abort intent items that don't have a done item. */ 257 + list_for_each_entry(dfp, dop_list, dfp_list) { 258 + ops = defer_op_types[dfp->dfp_type]; 259 + trace_xfs_defer_pending_abort(mp, dfp); 260 + if (dfp->dfp_intent && !dfp->dfp_done) { 261 + ops->abort_intent(dfp->dfp_intent); 262 + dfp->dfp_intent = NULL; 263 + } 264 + } 265 + } 266 + 248 267 /* Abort all the intents that were committed. */ 249 268 STATIC void 250 269 xfs_defer_trans_abort( 251 270 struct xfs_trans *tp, 252 271 struct list_head *dop_pending) 253 272 { 254 - struct xfs_defer_pending *dfp; 255 - const struct xfs_defer_op_type *ops; 256 - 257 273 trace_xfs_defer_trans_abort(tp, _RET_IP_); 258 - 259 - /* Abort intent items that don't have a done item. */ 260 - list_for_each_entry(dfp, dop_pending, dfp_list) { 261 - ops = defer_op_types[dfp->dfp_type]; 262 - trace_xfs_defer_pending_abort(tp->t_mountp, dfp); 263 - if (dfp->dfp_intent && !dfp->dfp_done) { 264 - ops->abort_intent(dfp->dfp_intent); 265 - dfp->dfp_intent = NULL; 266 - } 267 - } 274 + xfs_defer_pending_abort(tp->t_mountp, dop_pending); 268 275 } 269 276 270 277 /* ··· 763 756 764 757 /* Release all resources that we used to capture deferred ops. */ 765 758 void 766 - xfs_defer_ops_capture_free( 759 + xfs_defer_ops_capture_abort( 767 760 struct xfs_mount *mp, 768 761 struct xfs_defer_capture *dfc) 769 762 { 770 763 unsigned short i; 771 764 765 + xfs_defer_pending_abort(mp, &dfc->dfc_dfops); 772 766 xfs_defer_cancel_list(mp, &dfc->dfc_dfops); 773 767 774 768 for (i = 0; i < dfc->dfc_held.dr_bufs; i++) ··· 810 802 /* Commit the transaction and add the capture structure to the list. */ 811 803 error = xfs_trans_commit(tp); 812 804 if (error) { 813 - xfs_defer_ops_capture_free(mp, dfc); 805 + xfs_defer_ops_capture_abort(mp, dfc); 814 806 return error; 815 807 } 816 808
+1 -1
fs/xfs/libxfs/xfs_defer.h
··· 121 121 struct list_head *capture_list); 122 122 void xfs_defer_ops_continue(struct xfs_defer_capture *d, struct xfs_trans *tp, 123 123 struct xfs_defer_resources *dres); 124 - void xfs_defer_ops_capture_free(struct xfs_mount *mp, 124 + void xfs_defer_ops_capture_abort(struct xfs_mount *mp, 125 125 struct xfs_defer_capture *d); 126 126 void xfs_defer_resources_rele(struct xfs_defer_resources *dres); 127 127
+3
fs/xfs/libxfs/xfs_inode_buf.c
··· 510 510 if (mode && nextents + naextents > nblocks) 511 511 return __this_address; 512 512 513 + if (nextents + naextents == 0 && nblocks != 0) 514 + return __this_address; 515 + 513 516 if (S_ISDIR(mode) && nextents > mp->m_dir_geo->max_extents) 514 517 return __this_address; 515 518
+30 -16
fs/xfs/xfs_inode_item_recover.c
··· 286 286 struct xfs_log_dinode *ldip; 287 287 uint isize; 288 288 int need_free = 0; 289 + xfs_failaddr_t fa; 289 290 290 291 if (item->ri_buf[0].i_len == sizeof(struct xfs_inode_log_format)) { 291 292 in_f = item->ri_buf[0].i_addr; ··· 370 369 * superblock flag to determine whether we need to look at di_flushiter 371 370 * to skip replay when the on disk inode is newer than the log one 372 371 */ 373 - if (!xfs_has_v3inodes(mp) && 374 - ldip->di_flushiter < be16_to_cpu(dip->di_flushiter)) { 375 - /* 376 - * Deal with the wrap case, DI_MAX_FLUSH is less 377 - * than smaller numbers 378 - */ 379 - if (be16_to_cpu(dip->di_flushiter) == DI_MAX_FLUSH && 380 - ldip->di_flushiter < (DI_MAX_FLUSH >> 1)) { 381 - /* do nothing */ 382 - } else { 383 - trace_xfs_log_recover_inode_skip(log, in_f); 384 - error = 0; 385 - goto out_release; 372 + if (!xfs_has_v3inodes(mp)) { 373 + if (ldip->di_flushiter < be16_to_cpu(dip->di_flushiter)) { 374 + /* 375 + * Deal with the wrap case, DI_MAX_FLUSH is less 376 + * than smaller numbers 377 + */ 378 + if (be16_to_cpu(dip->di_flushiter) == DI_MAX_FLUSH && 379 + ldip->di_flushiter < (DI_MAX_FLUSH >> 1)) { 380 + /* do nothing */ 381 + } else { 382 + trace_xfs_log_recover_inode_skip(log, in_f); 383 + error = 0; 384 + goto out_release; 385 + } 386 386 } 387 + 388 + /* Take the opportunity to reset the flush iteration count */ 389 + ldip->di_flushiter = 0; 387 390 } 388 391 389 - /* Take the opportunity to reset the flush iteration count */ 390 - ldip->di_flushiter = 0; 391 392 392 393 if (unlikely(S_ISREG(ldip->di_mode))) { 393 394 if ((ldip->di_format != XFS_DINODE_FMT_EXTENTS) && ··· 531 528 (dip->di_mode != 0)) 532 529 error = xfs_recover_inode_owner_change(mp, dip, in_f, 533 530 buffer_list); 534 - /* re-generate the checksum. */ 531 + /* re-generate the checksum and validate the recovered inode. */ 535 532 xfs_dinode_calc_crc(log->l_mp, dip); 533 + fa = xfs_dinode_verify(log->l_mp, in_f->ilf_ino, dip); 534 + if (fa) { 535 + XFS_CORRUPTION_ERROR( 536 + "Bad dinode after recovery", 537 + XFS_ERRLEVEL_LOW, mp, dip, sizeof(*dip)); 538 + xfs_alert(mp, 539 + "Metadata corruption detected at %pS, inode 0x%llx", 540 + fa, in_f->ilf_ino); 541 + error = -EFSCORRUPTED; 542 + goto out_release; 543 + } 536 544 537 545 ASSERT(bp->b_mount == mp); 538 546 bp->b_flags |= _XBF_LOGRECOVERY;
+12 -11
fs/xfs/xfs_log.c
··· 1893 1893 * the buffer manually, the code needs to be kept in sync 1894 1894 * with the I/O completion path. 1895 1895 */ 1896 - xlog_state_done_syncing(iclog); 1897 - up(&iclog->ic_sema); 1898 - return; 1896 + goto sync; 1899 1897 } 1900 1898 1901 1899 /* ··· 1923 1925 * avoid shutdown re-entering this path and erroring out again. 1924 1926 */ 1925 1927 if (log->l_targ != log->l_mp->m_ddev_targp && 1926 - blkdev_issue_flush(log->l_mp->m_ddev_targp->bt_bdev)) { 1927 - xlog_force_shutdown(log, SHUTDOWN_LOG_IO_ERROR); 1928 - return; 1929 - } 1928 + blkdev_issue_flush(log->l_mp->m_ddev_targp->bt_bdev)) 1929 + goto shutdown; 1930 1930 } 1931 1931 if (iclog->ic_flags & XLOG_ICL_NEED_FUA) 1932 1932 iclog->ic_bio.bi_opf |= REQ_FUA; 1933 1933 1934 1934 iclog->ic_flags &= ~(XLOG_ICL_NEED_FLUSH | XLOG_ICL_NEED_FUA); 1935 1935 1936 - if (xlog_map_iclog_data(&iclog->ic_bio, iclog->ic_data, count)) { 1937 - xlog_force_shutdown(log, SHUTDOWN_LOG_IO_ERROR); 1938 - return; 1939 - } 1936 + if (xlog_map_iclog_data(&iclog->ic_bio, iclog->ic_data, count)) 1937 + goto shutdown; 1938 + 1940 1939 if (is_vmalloc_addr(iclog->ic_data)) 1941 1940 flush_kernel_vmap_range(iclog->ic_data, count); 1942 1941 ··· 1954 1959 } 1955 1960 1956 1961 submit_bio(&iclog->ic_bio); 1962 + return; 1963 + shutdown: 1964 + xlog_force_shutdown(log, SHUTDOWN_LOG_IO_ERROR); 1965 + sync: 1966 + xlog_state_done_syncing(iclog); 1967 + up(&iclog->ic_sema); 1957 1968 } 1958 1969 1959 1970 /*
+1 -1
fs/xfs/xfs_log_recover.c
··· 2511 2511 2512 2512 list_for_each_entry_safe(dfc, next, capture_list, dfc_list) { 2513 2513 list_del_init(&dfc->dfc_list); 2514 - xfs_defer_ops_capture_free(mp, dfc); 2514 + xfs_defer_ops_capture_abort(mp, dfc); 2515 2515 } 2516 2516 } 2517 2517
+1
fs/xfs/xfs_reflink.c
··· 784 784 } 785 785 } 786 786 del = got; 787 + xfs_trim_extent(&del, *offset_fsb, end_fsb - *offset_fsb); 787 788 788 789 /* Grab the corresponding mapping in the data fork. */ 789 790 nmaps = 1;