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-iomap-for-linus-4.8-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs

Pull xfs and iomap fixes from Dave Chinner:
"Most of these changes are small regression fixes that address problems
introduced in the 4.8-rc1 window. The two fixes that aren't (IO
completion fix and superblock inprogress check) are fixes for problems
introduced some time ago and need to be pushed back to stable kernels.

Changes in this update:
- iomap FIEMAP_EXTENT_MERGED usage fix
- additional mount-time feature restrictions
- rmap btree query fixes
- freeze/unmount io completion workqueue fix
- memory corruption fix for deferred operations handling"

* tag 'xfs-iomap-for-linus-4.8-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs:
xfs: track log done items directly in the deferred pending work item
iomap: don't set FIEMAP_EXTENT_MERGED for extent based filesystems
xfs: prevent dropping ioend completions during buftarg wait
xfs: fix superblock inprogress check
xfs: simple btree query range should look right if LE lookup fails
xfs: fix some key handling problems in _btree_simple_query_range
xfs: don't log the entire end of the AGF
xfs: disallow mounting of realtime + rmap filesystems
xfs: don't perform lookups on zero-height btrees

+47 -23
+4 -1
fs/iomap.c
··· 428 428 break; 429 429 } 430 430 431 + if (iomap->flags & IOMAP_F_MERGED) 432 + flags |= FIEMAP_EXTENT_MERGED; 433 + 431 434 return fiemap_fill_next_extent(fi, iomap->offset, 432 435 iomap->blkno != IOMAP_NULL_BLOCK ? iomap->blkno << 9: 0, 433 - iomap->length, flags | FIEMAP_EXTENT_MERGED); 436 + iomap->length, flags); 434 437 435 438 } 436 439
+2
fs/xfs/libxfs/xfs_alloc.c
··· 2278 2278 offsetof(xfs_agf_t, agf_btreeblks), 2279 2279 offsetof(xfs_agf_t, agf_uuid), 2280 2280 offsetof(xfs_agf_t, agf_rmap_blocks), 2281 + /* needed so that we don't log the whole rest of the structure: */ 2282 + offsetof(xfs_agf_t, agf_spare64), 2281 2283 sizeof(xfs_agf_t) 2282 2284 }; 2283 2285
+13 -1
fs/xfs/libxfs/xfs_btree.c
··· 1814 1814 1815 1815 XFS_BTREE_STATS_INC(cur, lookup); 1816 1816 1817 + /* No such thing as a zero-level tree. */ 1818 + if (cur->bc_nlevels == 0) 1819 + return -EFSCORRUPTED; 1820 + 1817 1821 block = NULL; 1818 1822 keyno = 0; 1819 1823 ··· 4558 4554 if (error) 4559 4555 goto out; 4560 4556 4557 + /* Nothing? See if there's anything to the right. */ 4558 + if (!stat) { 4559 + error = xfs_btree_increment(cur, 0, &stat); 4560 + if (error) 4561 + goto out; 4562 + } 4563 + 4561 4564 while (stat) { 4562 4565 /* Find the record. */ 4563 4566 error = xfs_btree_get_rec(cur, &recp, &stat); 4564 4567 if (error || !stat) 4565 4568 break; 4566 - cur->bc_ops->init_high_key_from_rec(&rec_key, recp); 4567 4569 4568 4570 /* Skip if high_key(rec) < low_key. */ 4569 4571 if (firstrec) { 4572 + cur->bc_ops->init_high_key_from_rec(&rec_key, recp); 4570 4573 firstrec = false; 4571 4574 diff = cur->bc_ops->diff_two_keys(cur, low_key, 4572 4575 &rec_key); ··· 4582 4571 } 4583 4572 4584 4573 /* Stop if high_key < low_key(rec). */ 4574 + cur->bc_ops->init_key_from_rec(&rec_key, recp); 4585 4575 diff = cur->bc_ops->diff_two_keys(cur, &rec_key, high_key); 4586 4576 if (diff > 0) 4587 4577 break;
+4 -13
fs/xfs/libxfs/xfs_defer.c
··· 194 194 /* Abort intent items. */ 195 195 list_for_each_entry(dfp, &dop->dop_pending, dfp_list) { 196 196 trace_xfs_defer_pending_abort(tp->t_mountp, dfp); 197 - if (dfp->dfp_committed) 197 + if (!dfp->dfp_done) 198 198 dfp->dfp_type->abort_intent(dfp->dfp_intent); 199 199 } 200 200 ··· 290 290 struct xfs_defer_pending *dfp; 291 291 struct list_head *li; 292 292 struct list_head *n; 293 - void *done_item = NULL; 294 293 void *state; 295 294 int error = 0; 296 295 void (*cleanup_fn)(struct xfs_trans *, void *, int); ··· 308 309 if (error) 309 310 goto out; 310 311 311 - /* Mark all pending intents as committed. */ 312 - list_for_each_entry_reverse(dfp, &dop->dop_pending, dfp_list) { 313 - if (dfp->dfp_committed) 314 - break; 315 - trace_xfs_defer_pending_commit((*tp)->t_mountp, dfp); 316 - dfp->dfp_committed = true; 317 - } 318 - 319 312 /* Log an intent-done item for the first pending item. */ 320 313 dfp = list_first_entry(&dop->dop_pending, 321 314 struct xfs_defer_pending, dfp_list); 322 315 trace_xfs_defer_pending_finish((*tp)->t_mountp, dfp); 323 - done_item = dfp->dfp_type->create_done(*tp, dfp->dfp_intent, 316 + dfp->dfp_done = dfp->dfp_type->create_done(*tp, dfp->dfp_intent, 324 317 dfp->dfp_count); 325 318 cleanup_fn = dfp->dfp_type->finish_cleanup; 326 319 ··· 322 331 list_del(li); 323 332 dfp->dfp_count--; 324 333 error = dfp->dfp_type->finish_item(*tp, dop, li, 325 - done_item, &state); 334 + dfp->dfp_done, &state); 326 335 if (error) { 327 336 /* 328 337 * Clean up after ourselves and jump out. ··· 419 428 dfp = kmem_alloc(sizeof(struct xfs_defer_pending), 420 429 KM_SLEEP | KM_NOFS); 421 430 dfp->dfp_type = defer_op_types[type]; 422 - dfp->dfp_committed = false; 423 431 dfp->dfp_intent = NULL; 432 + dfp->dfp_done = NULL; 424 433 dfp->dfp_count = 0; 425 434 INIT_LIST_HEAD(&dfp->dfp_work); 426 435 list_add_tail(&dfp->dfp_list, &dop->dop_intake);
+1 -1
fs/xfs/libxfs/xfs_defer.h
··· 30 30 struct xfs_defer_pending { 31 31 const struct xfs_defer_op_type *dfp_type; /* function pointers */ 32 32 struct list_head dfp_list; /* pending items */ 33 - bool dfp_committed; /* committed trans? */ 34 33 void *dfp_intent; /* log intent item */ 34 + void *dfp_done; /* log done item */ 35 35 struct list_head dfp_work; /* work items */ 36 36 unsigned int dfp_count; /* # extent items */ 37 37 };
+4 -2
fs/xfs/libxfs/xfs_format.h
··· 674 674 #define XFS_AGF_BTREEBLKS 0x00000800 675 675 #define XFS_AGF_UUID 0x00001000 676 676 #define XFS_AGF_RMAP_BLOCKS 0x00002000 677 - #define XFS_AGF_NUM_BITS 14 677 + #define XFS_AGF_SPARE64 0x00004000 678 + #define XFS_AGF_NUM_BITS 15 678 679 #define XFS_AGF_ALL_BITS ((1 << XFS_AGF_NUM_BITS) - 1) 679 680 680 681 #define XFS_AGF_FLAGS \ ··· 692 691 { XFS_AGF_LONGEST, "LONGEST" }, \ 693 692 { XFS_AGF_BTREEBLKS, "BTREEBLKS" }, \ 694 693 { XFS_AGF_UUID, "UUID" }, \ 695 - { XFS_AGF_RMAP_BLOCKS, "RMAP_BLOCKS" } 694 + { XFS_AGF_RMAP_BLOCKS, "RMAP_BLOCKS" }, \ 695 + { XFS_AGF_SPARE64, "SPARE64" } 696 696 697 697 /* disk block (xfs_daddr_t) in the AG */ 698 698 #define XFS_AGF_DADDR(mp) ((xfs_daddr_t)(1 << (mp)->m_sectbb_log))
+2 -1
fs/xfs/libxfs/xfs_sb.c
··· 583 583 * Only check the in progress field for the primary superblock as 584 584 * mkfs.xfs doesn't clear it from secondary superblocks. 585 585 */ 586 - return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR, 586 + return xfs_mount_validate_sb(mp, &sb, 587 + bp->b_maps[0].bm_bn == XFS_SB_DADDR, 587 588 check_version); 588 589 } 589 590
+1 -1
fs/xfs/xfs_buf.c
··· 1611 1611 */ 1612 1612 while (percpu_counter_sum(&btp->bt_io_count)) 1613 1613 delay(100); 1614 - drain_workqueue(btp->bt_mount->m_buf_workqueue); 1614 + flush_workqueue(btp->bt_mount->m_buf_workqueue); 1615 1615 1616 1616 /* loop until there is nothing left on the lru list. */ 1617 1617 while (list_lru_count(&btp->bt_lru)) {
+8 -1
fs/xfs/xfs_super.c
··· 1574 1574 } 1575 1575 } 1576 1576 1577 - if (xfs_sb_version_hasrmapbt(&mp->m_sb)) 1577 + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) { 1578 + if (mp->m_sb.sb_rblocks) { 1579 + xfs_alert(mp, 1580 + "EXPERIMENTAL reverse mapping btree not compatible with realtime device!"); 1581 + error = -EINVAL; 1582 + goto out_filestream_unmount; 1583 + } 1578 1584 xfs_alert(mp, 1579 1585 "EXPERIMENTAL reverse mapping btree feature enabled. Use at your own risk!"); 1586 + } 1580 1587 1581 1588 error = xfs_mountfs(mp); 1582 1589 if (error)
+1 -1
fs/xfs/xfs_trace.h
··· 2295 2295 __entry->dev = mp ? mp->m_super->s_dev : 0; 2296 2296 __entry->type = dfp->dfp_type->type; 2297 2297 __entry->intent = dfp->dfp_intent; 2298 - __entry->committed = dfp->dfp_committed; 2298 + __entry->committed = dfp->dfp_done != NULL; 2299 2299 __entry->nr = dfp->dfp_count; 2300 2300 ), 2301 2301 TP_printk("dev %d:%d optype %d intent %p committed %d nr %d\n",
+7 -1
include/linux/iomap.h
··· 19 19 #define IOMAP_UNWRITTEN 0x04 /* blocks allocated @blkno in unwritten state */ 20 20 21 21 /* 22 + * Flags for iomap mappings: 23 + */ 24 + #define IOMAP_F_MERGED 0x01 /* contains multiple blocks/extents */ 25 + 26 + /* 22 27 * Magic value for blkno: 23 28 */ 24 29 #define IOMAP_NULL_BLOCK -1LL /* blkno is not valid */ ··· 32 27 sector_t blkno; /* 1st sector of mapping, 512b units */ 33 28 loff_t offset; /* file offset of mapping, bytes */ 34 29 u64 length; /* length of mapping, bytes */ 35 - int type; /* type of mapping */ 30 + u16 type; /* type of mapping */ 31 + u16 flags; /* flags for mapping */ 36 32 struct block_device *bdev; /* block device for I/O */ 37 33 }; 38 34