diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2016-09-01 12:33:46 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2016-09-01 12:33:46 -0400 |
commit | 0cb7bf61b1e9f05027de58c80f9b46a714d24e35 (patch) | |
tree | 41fb55cf62d07b425122f9a8b96412c0d8eb99c5 /fs/xfs | |
parent | aa877175e7a9982233ed8f10cb4bfddd78d82741 (diff) | |
parent | 3eab887a55424fc2c27553b7bfe32330df83f7b8 (diff) |
Merge branch 'linus' into smp/hotplug
Apply upstream changes to avoid conflicts with pending patches.
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/libxfs/xfs_alloc.c | 14 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_format.h | 11 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_rmap_btree.c | 6 | ||||
-rw-r--r-- | fs/xfs/xfs_buf.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_file.c | 13 | ||||
-rw-r--r-- | fs/xfs/xfs_fsops.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_iomap.c | 69 | ||||
-rw-r--r-- | fs/xfs/xfs_iomap.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_iops.c | 9 | ||||
-rw-r--r-- | fs/xfs/xfs_trace.h | 1 |
10 files changed, 106 insertions, 20 deletions
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 776ae2f325d1..3dd8f1d54498 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c | |||
@@ -1582,6 +1582,7 @@ xfs_alloc_ag_vextent_small( | |||
1582 | xfs_extlen_t *flenp, /* result length */ | 1582 | xfs_extlen_t *flenp, /* result length */ |
1583 | int *stat) /* status: 0-freelist, 1-normal/none */ | 1583 | int *stat) /* status: 0-freelist, 1-normal/none */ |
1584 | { | 1584 | { |
1585 | struct xfs_owner_info oinfo; | ||
1585 | int error; | 1586 | int error; |
1586 | xfs_agblock_t fbno; | 1587 | xfs_agblock_t fbno; |
1587 | xfs_extlen_t flen; | 1588 | xfs_extlen_t flen; |
@@ -1624,6 +1625,18 @@ xfs_alloc_ag_vextent_small( | |||
1624 | error0); | 1625 | error0); |
1625 | args->wasfromfl = 1; | 1626 | args->wasfromfl = 1; |
1626 | trace_xfs_alloc_small_freelist(args); | 1627 | trace_xfs_alloc_small_freelist(args); |
1628 | |||
1629 | /* | ||
1630 | * If we're feeding an AGFL block to something that | ||
1631 | * doesn't live in the free space, we need to clear | ||
1632 | * out the OWN_AG rmap. | ||
1633 | */ | ||
1634 | xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_AG); | ||
1635 | error = xfs_rmap_free(args->tp, args->agbp, args->agno, | ||
1636 | fbno, 1, &oinfo); | ||
1637 | if (error) | ||
1638 | goto error0; | ||
1639 | |||
1627 | *stat = 0; | 1640 | *stat = 0; |
1628 | return 0; | 1641 | return 0; |
1629 | } | 1642 | } |
@@ -2264,6 +2277,7 @@ xfs_alloc_log_agf( | |||
2264 | offsetof(xfs_agf_t, agf_longest), | 2277 | offsetof(xfs_agf_t, agf_longest), |
2265 | offsetof(xfs_agf_t, agf_btreeblks), | 2278 | offsetof(xfs_agf_t, agf_btreeblks), |
2266 | offsetof(xfs_agf_t, agf_uuid), | 2279 | offsetof(xfs_agf_t, agf_uuid), |
2280 | offsetof(xfs_agf_t, agf_rmap_blocks), | ||
2267 | sizeof(xfs_agf_t) | 2281 | sizeof(xfs_agf_t) |
2268 | }; | 2282 | }; |
2269 | 2283 | ||
diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index f814d42c73b2..e6a8bea0f7ba 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h | |||
@@ -640,12 +640,15 @@ typedef struct xfs_agf { | |||
640 | __be32 agf_btreeblks; /* # of blocks held in AGF btrees */ | 640 | __be32 agf_btreeblks; /* # of blocks held in AGF btrees */ |
641 | uuid_t agf_uuid; /* uuid of filesystem */ | 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 | * reserve some contiguous space for future logged fields before we add | 647 | * reserve some contiguous space for future logged fields before we add |
645 | * the unlogged fields. This makes the range logging via flags and | 648 | * the unlogged fields. This makes the range logging via flags and |
646 | * structure offsets much simpler. | 649 | * structure offsets much simpler. |
647 | */ | 650 | */ |
648 | __be64 agf_spare64[16]; | 651 | __be64 agf_spare64[15]; |
649 | 652 | ||
650 | /* unlogged fields, written during buffer writeback. */ | 653 | /* unlogged fields, written during buffer writeback. */ |
651 | __be64 agf_lsn; /* last write sequence */ | 654 | __be64 agf_lsn; /* last write sequence */ |
@@ -670,7 +673,8 @@ typedef struct xfs_agf { | |||
670 | #define XFS_AGF_LONGEST 0x00000400 | 673 | #define XFS_AGF_LONGEST 0x00000400 |
671 | #define XFS_AGF_BTREEBLKS 0x00000800 | 674 | #define XFS_AGF_BTREEBLKS 0x00000800 |
672 | #define XFS_AGF_UUID 0x00001000 | 675 | #define XFS_AGF_UUID 0x00001000 |
673 | #define XFS_AGF_NUM_BITS 13 | 676 | #define XFS_AGF_RMAP_BLOCKS 0x00002000 |
677 | #define XFS_AGF_NUM_BITS 14 | ||
674 | #define XFS_AGF_ALL_BITS ((1 << XFS_AGF_NUM_BITS) - 1) | 678 | #define XFS_AGF_ALL_BITS ((1 << XFS_AGF_NUM_BITS) - 1) |
675 | 679 | ||
676 | #define XFS_AGF_FLAGS \ | 680 | #define XFS_AGF_FLAGS \ |
@@ -686,7 +690,8 @@ typedef struct xfs_agf { | |||
686 | { XFS_AGF_FREEBLKS, "FREEBLKS" }, \ | 690 | { XFS_AGF_FREEBLKS, "FREEBLKS" }, \ |
687 | { XFS_AGF_LONGEST, "LONGEST" }, \ | 691 | { XFS_AGF_LONGEST, "LONGEST" }, \ |
688 | { XFS_AGF_BTREEBLKS, "BTREEBLKS" }, \ | 692 | { XFS_AGF_BTREEBLKS, "BTREEBLKS" }, \ |
689 | { XFS_AGF_UUID, "UUID" } | 693 | { XFS_AGF_UUID, "UUID" }, \ |
694 | { XFS_AGF_RMAP_BLOCKS, "RMAP_BLOCKS" } | ||
690 | 695 | ||
691 | /* disk block (xfs_daddr_t) in the AG */ | 696 | /* disk block (xfs_daddr_t) in the AG */ |
692 | #define XFS_AGF_DADDR(mp) ((xfs_daddr_t)(1 << (mp)->m_sectbb_log)) | 697 | #define XFS_AGF_DADDR(mp) ((xfs_daddr_t)(1 << (mp)->m_sectbb_log)) |
diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index bc1faebc84ec..17b8eeb34ac8 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c | |||
@@ -98,6 +98,8 @@ xfs_rmapbt_alloc_block( | |||
98 | union xfs_btree_ptr *new, | 98 | union xfs_btree_ptr *new, |
99 | int *stat) | 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 | int error; | 103 | int error; |
102 | xfs_agblock_t bno; | 104 | xfs_agblock_t bno; |
103 | 105 | ||
@@ -124,6 +126,8 @@ xfs_rmapbt_alloc_block( | |||
124 | 126 | ||
125 | xfs_trans_agbtree_delta(cur->bc_tp, 1); | 127 | xfs_trans_agbtree_delta(cur->bc_tp, 1); |
126 | new->s = cpu_to_be32(bno); | 128 | new->s = cpu_to_be32(bno); |
129 | be32_add_cpu(&agf->agf_rmap_blocks, 1); | ||
130 | xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_RMAP_BLOCKS); | ||
127 | 131 | ||
128 | XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); | 132 | XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); |
129 | *stat = 1; | 133 | *stat = 1; |
@@ -143,6 +147,8 @@ xfs_rmapbt_free_block( | |||
143 | bno = xfs_daddr_to_agbno(cur->bc_mp, XFS_BUF_ADDR(bp)); | 147 | bno = xfs_daddr_to_agbno(cur->bc_mp, XFS_BUF_ADDR(bp)); |
144 | trace_xfs_rmapbt_free_block(cur->bc_mp, cur->bc_private.a.agno, | 148 | trace_xfs_rmapbt_free_block(cur->bc_mp, cur->bc_private.a.agno, |
145 | bno, 1); | 149 | bno, 1); |
150 | be32_add_cpu(&agf->agf_rmap_blocks, -1); | ||
151 | xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_RMAP_BLOCKS); | ||
146 | error = xfs_alloc_put_freelist(cur->bc_tp, agbp, NULL, bno, 1); | 152 | error = xfs_alloc_put_freelist(cur->bc_tp, agbp, NULL, bno, 1); |
147 | if (error) | 153 | if (error) |
148 | return error; | 154 | return error; |
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 47a318ce82e0..607cc29bba21 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c | |||
@@ -115,7 +115,6 @@ xfs_buf_ioacct_dec( | |||
115 | if (!(bp->b_flags & _XBF_IN_FLIGHT)) | 115 | if (!(bp->b_flags & _XBF_IN_FLIGHT)) |
116 | return; | 116 | return; |
117 | 117 | ||
118 | ASSERT(bp->b_flags & XBF_ASYNC); | ||
119 | bp->b_flags &= ~_XBF_IN_FLIGHT; | 118 | bp->b_flags &= ~_XBF_IN_FLIGHT; |
120 | percpu_counter_dec(&bp->b_target->bt_io_count); | 119 | percpu_counter_dec(&bp->b_target->bt_io_count); |
121 | } | 120 | } |
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index ed95e5bb04e6..e612a0233710 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
@@ -741,9 +741,20 @@ xfs_file_dax_write( | |||
741 | * page is inserted into the pagecache when we have to serve a write | 741 | * page is inserted into the pagecache when we have to serve a write |
742 | * fault on a hole. It should never be dirtied and can simply be | 742 | * fault on a hole. It should never be dirtied and can simply be |
743 | * dropped from the pagecache once we get real data for the page. | 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 | if (mapping->nrpages) { | 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 | WARN_ON_ONCE(ret); | 758 | WARN_ON_ONCE(ret); |
748 | } | 759 | } |
749 | 760 | ||
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 0f96847b90e1..0b7f986745c1 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c | |||
@@ -248,6 +248,7 @@ xfs_growfs_data_private( | |||
248 | agf->agf_roots[XFS_BTNUM_RMAPi] = | 248 | agf->agf_roots[XFS_BTNUM_RMAPi] = |
249 | cpu_to_be32(XFS_RMAP_BLOCK(mp)); | 249 | cpu_to_be32(XFS_RMAP_BLOCK(mp)); |
250 | agf->agf_levels[XFS_BTNUM_RMAPi] = cpu_to_be32(1); | 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 | agf->agf_flfirst = cpu_to_be32(1); | 254 | agf->agf_flfirst = cpu_to_be32(1); |
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 2114d53df433..2af0dda1c978 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
@@ -715,12 +715,16 @@ xfs_iomap_write_allocate( | |||
715 | * is in the delayed allocation extent on which we sit | 715 | * is in the delayed allocation extent on which we sit |
716 | * but before our buffer starts. | 716 | * but before our buffer starts. |
717 | */ | 717 | */ |
718 | |||
719 | nimaps = 0; | 718 | nimaps = 0; |
720 | while (nimaps == 0) { | 719 | while (nimaps == 0) { |
721 | nres = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK); | 720 | nres = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK); |
722 | 721 | /* | |
723 | error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, nres, | 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 | 0, XFS_TRANS_RESERVE, &tp); | 728 | 0, XFS_TRANS_RESERVE, &tp); |
725 | if (error) | 729 | if (error) |
726 | return error; | 730 | return error; |
@@ -1037,20 +1041,14 @@ xfs_file_iomap_begin( | |||
1037 | return error; | 1041 | return error; |
1038 | 1042 | ||
1039 | trace_xfs_iomap_alloc(ip, offset, length, 0, &imap); | 1043 | trace_xfs_iomap_alloc(ip, offset, length, 0, &imap); |
1040 | xfs_bmbt_to_iomap(ip, iomap, &imap); | ||
1041 | } else if (nimaps) { | ||
1042 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
1043 | trace_xfs_iomap_found(ip, offset, length, 0, &imap); | ||
1044 | xfs_bmbt_to_iomap(ip, iomap, &imap); | ||
1045 | } else { | 1044 | } else { |
1045 | ASSERT(nimaps); | ||
1046 | |||
1046 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 1047 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
1047 | trace_xfs_iomap_not_found(ip, offset, length, 0, &imap); | 1048 | trace_xfs_iomap_found(ip, offset, length, 0, &imap); |
1048 | iomap->blkno = IOMAP_NULL_BLOCK; | ||
1049 | iomap->type = IOMAP_HOLE; | ||
1050 | iomap->offset = offset; | ||
1051 | iomap->length = length; | ||
1052 | } | 1049 | } |
1053 | 1050 | ||
1051 | xfs_bmbt_to_iomap(ip, iomap, &imap); | ||
1054 | return 0; | 1052 | return 0; |
1055 | } | 1053 | } |
1056 | 1054 | ||
@@ -1112,3 +1110,48 @@ struct iomap_ops xfs_iomap_ops = { | |||
1112 | .iomap_begin = xfs_file_iomap_begin, | 1110 | .iomap_begin = xfs_file_iomap_begin, |
1113 | .iomap_end = xfs_file_iomap_end, | 1111 | .iomap_end = xfs_file_iomap_end, |
1114 | }; | 1112 | }; |
1113 | |||
1114 | static int | ||
1115 | xfs_xattr_iomap_begin( | ||
1116 | struct inode *inode, | ||
1117 | loff_t offset, | ||
1118 | loff_t length, | ||
1119 | unsigned flags, | ||
1120 | struct iomap *iomap) | ||
1121 | { | ||
1122 | struct xfs_inode *ip = XFS_I(inode); | ||
1123 | struct xfs_mount *mp = ip->i_mount; | ||
1124 | xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset); | ||
1125 | xfs_fileoff_t end_fsb = XFS_B_TO_FSB(mp, offset + length); | ||
1126 | struct xfs_bmbt_irec imap; | ||
1127 | int nimaps = 1, error = 0; | ||
1128 | unsigned lockmode; | ||
1129 | |||
1130 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
1131 | return -EIO; | ||
1132 | |||
1133 | lockmode = xfs_ilock_data_map_shared(ip); | ||
1134 | |||
1135 | /* if there are no attribute fork or extents, return ENOENT */ | ||
1136 | if (XFS_IFORK_Q(ip) || !ip->i_d.di_anextents) { | ||
1137 | error = -ENOENT; | ||
1138 | goto out_unlock; | ||
1139 | } | ||
1140 | |||
1141 | ASSERT(ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL); | ||
1142 | error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, &imap, | ||
1143 | &nimaps, XFS_BMAPI_ENTIRE | XFS_BMAPI_ATTRFORK); | ||
1144 | out_unlock: | ||
1145 | xfs_iunlock(ip, lockmode); | ||
1146 | |||
1147 | if (!error) { | ||
1148 | ASSERT(nimaps); | ||
1149 | xfs_bmbt_to_iomap(ip, iomap, &imap); | ||
1150 | } | ||
1151 | |||
1152 | return error; | ||
1153 | } | ||
1154 | |||
1155 | struct iomap_ops xfs_xattr_iomap_ops = { | ||
1156 | .iomap_begin = xfs_xattr_iomap_begin, | ||
1157 | }; | ||
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h index e066d045e2ff..fb8aca3d69ab 100644 --- a/fs/xfs/xfs_iomap.h +++ b/fs/xfs/xfs_iomap.h | |||
@@ -35,5 +35,6 @@ void xfs_bmbt_to_iomap(struct xfs_inode *, struct iomap *, | |||
35 | struct xfs_bmbt_irec *); | 35 | struct xfs_bmbt_irec *); |
36 | 36 | ||
37 | extern struct iomap_ops xfs_iomap_ops; | 37 | extern struct iomap_ops xfs_iomap_ops; |
38 | extern struct iomap_ops xfs_xattr_iomap_ops; | ||
38 | 39 | ||
39 | #endif /* __XFS_IOMAP_H__*/ | 40 | #endif /* __XFS_IOMAP_H__*/ |
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index ab820f84ed50..b24c3102fa93 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c | |||
@@ -1009,7 +1009,14 @@ xfs_vn_fiemap( | |||
1009 | int error; | 1009 | int error; |
1010 | 1010 | ||
1011 | xfs_ilock(XFS_I(inode), XFS_IOLOCK_SHARED); | 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 | xfs_iunlock(XFS_I(inode), XFS_IOLOCK_SHARED); | 1020 | xfs_iunlock(XFS_I(inode), XFS_IOLOCK_SHARED); |
1014 | 1021 | ||
1015 | return error; | 1022 | return error; |
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 551b7e26980c..7e88bec3f359 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h | |||
@@ -1298,7 +1298,6 @@ DEFINE_IOMAP_EVENT(xfs_get_blocks_alloc); | |||
1298 | DEFINE_IOMAP_EVENT(xfs_get_blocks_map_direct); | 1298 | DEFINE_IOMAP_EVENT(xfs_get_blocks_map_direct); |
1299 | DEFINE_IOMAP_EVENT(xfs_iomap_alloc); | 1299 | DEFINE_IOMAP_EVENT(xfs_iomap_alloc); |
1300 | DEFINE_IOMAP_EVENT(xfs_iomap_found); | 1300 | DEFINE_IOMAP_EVENT(xfs_iomap_found); |
1301 | DEFINE_IOMAP_EVENT(xfs_iomap_not_found); | ||
1302 | 1301 | ||
1303 | DECLARE_EVENT_CLASS(xfs_simple_io_class, | 1302 | DECLARE_EVENT_CLASS(xfs_simple_io_class, |
1304 | TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count), | 1303 | TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count), |