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-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs

Pull xfs and iomap fixes from Dave Chinner:
"Changes in this update:

Regression fixes for XFS changes introduce in 4.8-rc1:
- buffer IO accounting assert failure
- ENOSPC block accounting reservation issue
- DAX IO path page cache invalidation fix
- rmapbt on-disk block count in agf
- correct classification of rmap block type when updating AGFL.
- iomap support for attribute fork mapping

Regression fixes for iomap infrastructure in 4.8-rc1:
- fiemap: honor FIEMAP_FLAG_SYNC
- fiemap: implement FIEMAP_FLAG_XATTR support to fix XFS regression
- make mark_page_accessed and pagefault_disable usage consistent with
other IO paths"

* tag 'xfs-iomap-for-linus-4.8-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs:
xfs: remove OWN_AG rmap when allocating a block from the AGFL
xfs: (re-)implement FIEMAP_FLAG_XATTR
xfs: simplify xfs_file_iomap_begin
iomap: mark ->iomap_end as optional
iomap: prepare iomap_fiemap for attribute mappings
iomap: fiemap should honor the FIEMAP_FLAG_SYNC flag
iomap: remove superflous pagefault_disable from iomap_write_actor
iomap: remove superflous mark_page_accessed from iomap_write_actor
xfs: store rmapbt block count in the AGF
xfs: don't invalidate whole file on DAX read/write
xfs: fix bogus space reservation in xfs_iomap_write_allocate
xfs: don't assert fail on non-async buffers on ioacct decrement

+119 -28
+13 -8
fs/iomap.c
··· 84 84 * Now the data has been copied, commit the range we've copied. This 85 85 * should not fail unless the filesystem has had a fatal error. 86 86 */ 87 - ret = ops->iomap_end(inode, pos, length, written > 0 ? written : 0, 88 - flags, &iomap); 87 + if (ops->iomap_end) { 88 + ret = ops->iomap_end(inode, pos, length, 89 + written > 0 ? written : 0, 90 + flags, &iomap); 91 + } 89 92 90 93 return written ? written : ret; 91 94 } ··· 197 194 if (mapping_writably_mapped(inode->i_mapping)) 198 195 flush_dcache_page(page); 199 196 200 - pagefault_disable(); 201 197 copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes); 202 - pagefault_enable(); 203 198 204 199 flush_dcache_page(page); 205 - mark_page_accessed(page); 206 200 207 201 status = iomap_write_end(inode, pos, bytes, copied, page); 208 202 if (unlikely(status < 0)) ··· 470 470 if (ret) 471 471 return ret; 472 472 473 - ret = filemap_write_and_wait(inode->i_mapping); 474 - if (ret) 475 - return ret; 473 + if (fi->fi_flags & FIEMAP_FLAG_SYNC) { 474 + ret = filemap_write_and_wait(inode->i_mapping); 475 + if (ret) 476 + return ret; 477 + } 476 478 477 479 while (len > 0) { 478 480 ret = iomap_apply(inode, start, len, 0, ops, &ctx, 479 481 iomap_fiemap_actor); 482 + /* inode with no (attribute) mapping will give ENOENT */ 483 + if (ret == -ENOENT) 484 + break; 480 485 if (ret < 0) 481 486 return ret; 482 487 if (ret == 0)
+14
fs/xfs/libxfs/xfs_alloc.c
··· 1582 1582 xfs_extlen_t *flenp, /* result length */ 1583 1583 int *stat) /* status: 0-freelist, 1-normal/none */ 1584 1584 { 1585 + struct xfs_owner_info oinfo; 1585 1586 int error; 1586 1587 xfs_agblock_t fbno; 1587 1588 xfs_extlen_t flen; ··· 1625 1624 error0); 1626 1625 args->wasfromfl = 1; 1627 1626 trace_xfs_alloc_small_freelist(args); 1627 + 1628 + /* 1629 + * If we're feeding an AGFL block to something that 1630 + * doesn't live in the free space, we need to clear 1631 + * out the OWN_AG rmap. 1632 + */ 1633 + xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_AG); 1634 + error = xfs_rmap_free(args->tp, args->agbp, args->agno, 1635 + fbno, 1, &oinfo); 1636 + if (error) 1637 + goto error0; 1638 + 1628 1639 *stat = 0; 1629 1640 return 0; 1630 1641 } ··· 2277 2264 offsetof(xfs_agf_t, agf_longest), 2278 2265 offsetof(xfs_agf_t, agf_btreeblks), 2279 2266 offsetof(xfs_agf_t, agf_uuid), 2267 + offsetof(xfs_agf_t, agf_rmap_blocks), 2280 2268 sizeof(xfs_agf_t) 2281 2269 }; 2282 2270
+8 -3
fs/xfs/libxfs/xfs_format.h
··· 640 640 __be32 agf_btreeblks; /* # of blocks held in AGF btrees */ 641 641 uuid_t agf_uuid; /* uuid of filesystem */ 642 642 643 + __be32 agf_rmap_blocks; /* rmapbt blocks used */ 644 + __be32 agf_padding; /* padding */ 645 + 643 646 /* 644 647 * reserve some contiguous space for future logged fields before we add 645 648 * the unlogged fields. This makes the range logging via flags and 646 649 * structure offsets much simpler. 647 650 */ 648 - __be64 agf_spare64[16]; 651 + __be64 agf_spare64[15]; 649 652 650 653 /* unlogged fields, written during buffer writeback. */ 651 654 __be64 agf_lsn; /* last write sequence */ ··· 673 670 #define XFS_AGF_LONGEST 0x00000400 674 671 #define XFS_AGF_BTREEBLKS 0x00000800 675 672 #define XFS_AGF_UUID 0x00001000 676 - #define XFS_AGF_NUM_BITS 13 673 + #define XFS_AGF_RMAP_BLOCKS 0x00002000 674 + #define XFS_AGF_NUM_BITS 14 677 675 #define XFS_AGF_ALL_BITS ((1 << XFS_AGF_NUM_BITS) - 1) 678 676 679 677 #define XFS_AGF_FLAGS \ ··· 690 686 { XFS_AGF_FREEBLKS, "FREEBLKS" }, \ 691 687 { XFS_AGF_LONGEST, "LONGEST" }, \ 692 688 { XFS_AGF_BTREEBLKS, "BTREEBLKS" }, \ 693 - { XFS_AGF_UUID, "UUID" } 689 + { XFS_AGF_UUID, "UUID" }, \ 690 + { XFS_AGF_RMAP_BLOCKS, "RMAP_BLOCKS" } 694 691 695 692 /* disk block (xfs_daddr_t) in the AG */ 696 693 #define XFS_AGF_DADDR(mp) ((xfs_daddr_t)(1 << (mp)->m_sectbb_log))
+6
fs/xfs/libxfs/xfs_rmap_btree.c
··· 98 98 union xfs_btree_ptr *new, 99 99 int *stat) 100 100 { 101 + struct xfs_buf *agbp = cur->bc_private.a.agbp; 102 + struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); 101 103 int error; 102 104 xfs_agblock_t bno; 103 105 ··· 126 124 127 125 xfs_trans_agbtree_delta(cur->bc_tp, 1); 128 126 new->s = cpu_to_be32(bno); 127 + be32_add_cpu(&agf->agf_rmap_blocks, 1); 128 + xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_RMAP_BLOCKS); 129 129 130 130 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); 131 131 *stat = 1; ··· 147 143 bno = xfs_daddr_to_agbno(cur->bc_mp, XFS_BUF_ADDR(bp)); 148 144 trace_xfs_rmapbt_free_block(cur->bc_mp, cur->bc_private.a.agno, 149 145 bno, 1); 146 + be32_add_cpu(&agf->agf_rmap_blocks, -1); 147 + xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_RMAP_BLOCKS); 150 148 error = xfs_alloc_put_freelist(cur->bc_tp, agbp, NULL, bno, 1); 151 149 if (error) 152 150 return error;
-1
fs/xfs/xfs_buf.c
··· 115 115 if (!(bp->b_flags & _XBF_IN_FLIGHT)) 116 116 return; 117 117 118 - ASSERT(bp->b_flags & XBF_ASYNC); 119 118 bp->b_flags &= ~_XBF_IN_FLIGHT; 120 119 percpu_counter_dec(&bp->b_target->bt_io_count); 121 120 }
+12 -1
fs/xfs/xfs_file.c
··· 741 741 * page is inserted into the pagecache when we have to serve a write 742 742 * fault on a hole. It should never be dirtied and can simply be 743 743 * dropped from the pagecache once we get real data for the page. 744 + * 745 + * XXX: This is racy against mmap, and there's nothing we can do about 746 + * it. dax_do_io() should really do this invalidation internally as 747 + * it will know if we've allocated over a holei for this specific IO and 748 + * if so it needs to update the mapping tree and invalidate existing 749 + * PTEs over the newly allocated range. Remove this invalidation when 750 + * dax_do_io() is fixed up. 744 751 */ 745 752 if (mapping->nrpages) { 746 - ret = invalidate_inode_pages2(mapping); 753 + loff_t end = iocb->ki_pos + iov_iter_count(from) - 1; 754 + 755 + ret = invalidate_inode_pages2_range(mapping, 756 + iocb->ki_pos >> PAGE_SHIFT, 757 + end >> PAGE_SHIFT); 747 758 WARN_ON_ONCE(ret); 748 759 } 749 760
+1
fs/xfs/xfs_fsops.c
··· 248 248 agf->agf_roots[XFS_BTNUM_RMAPi] = 249 249 cpu_to_be32(XFS_RMAP_BLOCK(mp)); 250 250 agf->agf_levels[XFS_BTNUM_RMAPi] = cpu_to_be32(1); 251 + agf->agf_rmap_blocks = cpu_to_be32(1); 251 252 } 252 253 253 254 agf->agf_flfirst = cpu_to_be32(1);
+56 -13
fs/xfs/xfs_iomap.c
··· 715 715 * is in the delayed allocation extent on which we sit 716 716 * but before our buffer starts. 717 717 */ 718 - 719 718 nimaps = 0; 720 719 while (nimaps == 0) { 721 720 nres = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK); 722 - 723 - error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, nres, 721 + /* 722 + * We have already reserved space for the extent and any 723 + * indirect blocks when creating the delalloc extent, 724 + * there is no need to reserve space in this transaction 725 + * again. 726 + */ 727 + error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, 0, 724 728 0, XFS_TRANS_RESERVE, &tp); 725 729 if (error) 726 730 return error; ··· 1041 1037 return error; 1042 1038 1043 1039 trace_xfs_iomap_alloc(ip, offset, length, 0, &imap); 1044 - xfs_bmbt_to_iomap(ip, iomap, &imap); 1045 - } else if (nimaps) { 1040 + } else { 1041 + ASSERT(nimaps); 1042 + 1046 1043 xfs_iunlock(ip, XFS_ILOCK_EXCL); 1047 1044 trace_xfs_iomap_found(ip, offset, length, 0, &imap); 1048 - xfs_bmbt_to_iomap(ip, iomap, &imap); 1049 - } else { 1050 - xfs_iunlock(ip, XFS_ILOCK_EXCL); 1051 - trace_xfs_iomap_not_found(ip, offset, length, 0, &imap); 1052 - iomap->blkno = IOMAP_NULL_BLOCK; 1053 - iomap->type = IOMAP_HOLE; 1054 - iomap->offset = offset; 1055 - iomap->length = length; 1056 1045 } 1057 1046 1047 + xfs_bmbt_to_iomap(ip, iomap, &imap); 1058 1048 return 0; 1059 1049 } 1060 1050 ··· 1109 1111 struct iomap_ops xfs_iomap_ops = { 1110 1112 .iomap_begin = xfs_file_iomap_begin, 1111 1113 .iomap_end = xfs_file_iomap_end, 1114 + }; 1115 + 1116 + static int 1117 + xfs_xattr_iomap_begin( 1118 + struct inode *inode, 1119 + loff_t offset, 1120 + loff_t length, 1121 + unsigned flags, 1122 + struct iomap *iomap) 1123 + { 1124 + struct xfs_inode *ip = XFS_I(inode); 1125 + struct xfs_mount *mp = ip->i_mount; 1126 + xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset); 1127 + xfs_fileoff_t end_fsb = XFS_B_TO_FSB(mp, offset + length); 1128 + struct xfs_bmbt_irec imap; 1129 + int nimaps = 1, error = 0; 1130 + unsigned lockmode; 1131 + 1132 + if (XFS_FORCED_SHUTDOWN(mp)) 1133 + return -EIO; 1134 + 1135 + lockmode = xfs_ilock_data_map_shared(ip); 1136 + 1137 + /* if there are no attribute fork or extents, return ENOENT */ 1138 + if (XFS_IFORK_Q(ip) || !ip->i_d.di_anextents) { 1139 + error = -ENOENT; 1140 + goto out_unlock; 1141 + } 1142 + 1143 + ASSERT(ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL); 1144 + error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, &imap, 1145 + &nimaps, XFS_BMAPI_ENTIRE | XFS_BMAPI_ATTRFORK); 1146 + out_unlock: 1147 + xfs_iunlock(ip, lockmode); 1148 + 1149 + if (!error) { 1150 + ASSERT(nimaps); 1151 + xfs_bmbt_to_iomap(ip, iomap, &imap); 1152 + } 1153 + 1154 + return error; 1155 + } 1156 + 1157 + struct iomap_ops xfs_xattr_iomap_ops = { 1158 + .iomap_begin = xfs_xattr_iomap_begin, 1112 1159 };
+1
fs/xfs/xfs_iomap.h
··· 35 35 struct xfs_bmbt_irec *); 36 36 37 37 extern struct iomap_ops xfs_iomap_ops; 38 + extern struct iomap_ops xfs_xattr_iomap_ops; 38 39 39 40 #endif /* __XFS_IOMAP_H__*/
+8 -1
fs/xfs/xfs_iops.c
··· 1009 1009 int error; 1010 1010 1011 1011 xfs_ilock(XFS_I(inode), XFS_IOLOCK_SHARED); 1012 - error = iomap_fiemap(inode, fieinfo, start, length, &xfs_iomap_ops); 1012 + if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR) { 1013 + fieinfo->fi_flags &= ~FIEMAP_FLAG_XATTR; 1014 + error = iomap_fiemap(inode, fieinfo, start, length, 1015 + &xfs_xattr_iomap_ops); 1016 + } else { 1017 + error = iomap_fiemap(inode, fieinfo, start, length, 1018 + &xfs_iomap_ops); 1019 + } 1013 1020 xfs_iunlock(XFS_I(inode), XFS_IOLOCK_SHARED); 1014 1021 1015 1022 return error;
-1
fs/xfs/xfs_trace.h
··· 1298 1298 DEFINE_IOMAP_EVENT(xfs_get_blocks_map_direct); 1299 1299 DEFINE_IOMAP_EVENT(xfs_iomap_alloc); 1300 1300 DEFINE_IOMAP_EVENT(xfs_iomap_found); 1301 - DEFINE_IOMAP_EVENT(xfs_iomap_not_found); 1302 1301 1303 1302 DECLARE_EVENT_CLASS(xfs_simple_io_class, 1304 1303 TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count),