diff options
author | Dave Chinner <david@fromorbit.com> | 2016-08-16 21:13:37 -0400 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2016-08-16 21:13:37 -0400 |
commit | 32438cf9d54bd53b531f6d98814e84dd278360c1 (patch) | |
tree | 5c6d82509d1f97edc172fcbbd4f2634df12d8436 | |
parent | a03f1a6633144300ef4a3a33e95dfa11866f1299 (diff) | |
parent | 1d4795e7bde075588c90df2175349bb2251802d5 (diff) |
Merge branch 'iomap-fixes-4.8-rc3' into for-next
-rw-r--r-- | fs/iomap.c | 21 | ||||
-rw-r--r-- | fs/xfs/xfs_iomap.c | 59 | ||||
-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 |
5 files changed, 71 insertions, 20 deletions
diff --git a/fs/iomap.c b/fs/iomap.c index 48141b8eff5f..0342254646e3 100644 --- a/fs/iomap.c +++ b/fs/iomap.c | |||
@@ -84,8 +84,11 @@ iomap_apply(struct inode *inode, loff_t pos, loff_t length, unsigned flags, | |||
84 | * Now the data has been copied, commit the range we've copied. This | 84 | * Now the data has been copied, commit the range we've copied. This |
85 | * should not fail unless the filesystem has had a fatal error. | 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, | 87 | if (ops->iomap_end) { |
88 | flags, &iomap); | 88 | ret = ops->iomap_end(inode, pos, length, |
89 | written > 0 ? written : 0, | ||
90 | flags, &iomap); | ||
91 | } | ||
89 | 92 | ||
90 | return written ? written : ret; | 93 | return written ? written : ret; |
91 | } | 94 | } |
@@ -194,12 +197,9 @@ again: | |||
194 | if (mapping_writably_mapped(inode->i_mapping)) | 197 | if (mapping_writably_mapped(inode->i_mapping)) |
195 | flush_dcache_page(page); | 198 | flush_dcache_page(page); |
196 | 199 | ||
197 | pagefault_disable(); | ||
198 | copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes); | 200 | copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes); |
199 | pagefault_enable(); | ||
200 | 201 | ||
201 | flush_dcache_page(page); | 202 | flush_dcache_page(page); |
202 | mark_page_accessed(page); | ||
203 | 203 | ||
204 | status = iomap_write_end(inode, pos, bytes, copied, page); | 204 | status = iomap_write_end(inode, pos, bytes, copied, page); |
205 | if (unlikely(status < 0)) | 205 | if (unlikely(status < 0)) |
@@ -470,13 +470,18 @@ int iomap_fiemap(struct inode *inode, struct fiemap_extent_info *fi, | |||
470 | if (ret) | 470 | if (ret) |
471 | return ret; | 471 | return ret; |
472 | 472 | ||
473 | ret = filemap_write_and_wait(inode->i_mapping); | 473 | if (fi->fi_flags & FIEMAP_FLAG_SYNC) { |
474 | if (ret) | 474 | ret = filemap_write_and_wait(inode->i_mapping); |
475 | return ret; | 475 | if (ret) |
476 | return ret; | ||
477 | } | ||
476 | 478 | ||
477 | while (len > 0) { | 479 | while (len > 0) { |
478 | ret = iomap_apply(inode, start, len, 0, ops, &ctx, | 480 | ret = iomap_apply(inode, start, len, 0, ops, &ctx, |
479 | iomap_fiemap_actor); | 481 | iomap_fiemap_actor); |
482 | /* inode with no (attribute) mapping will give ENOENT */ | ||
483 | if (ret == -ENOENT) | ||
484 | break; | ||
480 | if (ret < 0) | 485 | if (ret < 0) |
481 | return ret; | 486 | return ret; |
482 | if (ret == 0) | 487 | if (ret == 0) |
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 4398932a7d1b..2af0dda1c978 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
@@ -1041,20 +1041,14 @@ xfs_file_iomap_begin( | |||
1041 | return error; | 1041 | return error; |
1042 | 1042 | ||
1043 | trace_xfs_iomap_alloc(ip, offset, length, 0, &imap); | 1043 | trace_xfs_iomap_alloc(ip, offset, length, 0, &imap); |
1044 | xfs_bmbt_to_iomap(ip, iomap, &imap); | ||
1045 | } else if (nimaps) { | ||
1046 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
1047 | trace_xfs_iomap_found(ip, offset, length, 0, &imap); | ||
1048 | xfs_bmbt_to_iomap(ip, iomap, &imap); | ||
1049 | } else { | 1044 | } else { |
1045 | ASSERT(nimaps); | ||
1046 | |||
1050 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 1047 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
1051 | trace_xfs_iomap_not_found(ip, offset, length, 0, &imap); | 1048 | trace_xfs_iomap_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 | } | 1049 | } |
1057 | 1050 | ||
1051 | xfs_bmbt_to_iomap(ip, iomap, &imap); | ||
1058 | return 0; | 1052 | return 0; |
1059 | } | 1053 | } |
1060 | 1054 | ||
@@ -1116,3 +1110,48 @@ struct iomap_ops xfs_iomap_ops = { | |||
1116 | .iomap_begin = xfs_file_iomap_begin, | 1110 | .iomap_begin = xfs_file_iomap_begin, |
1117 | .iomap_end = xfs_file_iomap_end, | 1111 | .iomap_end = xfs_file_iomap_end, |
1118 | }; | 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), |