Skip to content

Commit 32438cf

Browse files
committed
Merge branch 'iomap-fixes-4.8-rc3' into for-next
2 parents a03f1a6 + 1d4795e commit 32438cf

File tree

5 files changed

+71
-20
lines changed

5 files changed

+71
-20
lines changed

fs/iomap.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,11 @@ iomap_apply(struct inode *inode, loff_t pos, loff_t length, unsigned flags,
8484
* Now the data has been copied, commit the range we've copied. This
8585
* should not fail unless the filesystem has had a fatal error.
8686
*/
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+
}
8992

9093
return written ? written : ret;
9194
}
@@ -194,12 +197,9 @@ iomap_write_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
194197
if (mapping_writably_mapped(inode->i_mapping))
195198
flush_dcache_page(page);
196199

197-
pagefault_disable();
198200
copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes);
199-
pagefault_enable();
200201

201202
flush_dcache_page(page);
202-
mark_page_accessed(page);
203203

204204
status = iomap_write_end(inode, pos, bytes, copied, page);
205205
if (unlikely(status < 0))
@@ -470,13 +470,18 @@ int iomap_fiemap(struct inode *inode, struct fiemap_extent_info *fi,
470470
if (ret)
471471
return ret;
472472

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+
}
476478

477479
while (len > 0) {
478480
ret = iomap_apply(inode, start, len, 0, ops, &ctx,
479481
iomap_fiemap_actor);
482+
/* inode with no (attribute) mapping will give ENOENT */
483+
if (ret == -ENOENT)
484+
break;
480485
if (ret < 0)
481486
return ret;
482487
if (ret == 0)

fs/xfs/xfs_iomap.c

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,20 +1041,14 @@ xfs_file_iomap_begin(
10411041
return error;
10421042

10431043
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);
10491044
} else {
1045+
ASSERT(nimaps);
1046+
10501047
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;
1048+
trace_xfs_iomap_found(ip, offset, length, 0, &imap);
10561049
}
10571050

1051+
xfs_bmbt_to_iomap(ip, iomap, &imap);
10581052
return 0;
10591053
}
10601054

@@ -1116,3 +1110,48 @@ struct iomap_ops xfs_iomap_ops = {
11161110
.iomap_begin = xfs_file_iomap_begin,
11171111
.iomap_end = xfs_file_iomap_end,
11181112
};
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+
};

fs/xfs/xfs_iomap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,6 @@ void xfs_bmbt_to_iomap(struct xfs_inode *, struct iomap *,
3535
struct xfs_bmbt_irec *);
3636

3737
extern struct iomap_ops xfs_iomap_ops;
38+
extern struct iomap_ops xfs_xattr_iomap_ops;
3839

3940
#endif /* __XFS_IOMAP_H__*/

fs/xfs/xfs_iops.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1009,7 +1009,14 @@ xfs_vn_fiemap(
10091009
int error;
10101010

10111011
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+
}
10131020
xfs_iunlock(XFS_I(inode), XFS_IOLOCK_SHARED);
10141021

10151022
return error;

fs/xfs/xfs_trace.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1298,7 +1298,6 @@ DEFINE_IOMAP_EVENT(xfs_get_blocks_alloc);
12981298
DEFINE_IOMAP_EVENT(xfs_get_blocks_map_direct);
12991299
DEFINE_IOMAP_EVENT(xfs_iomap_alloc);
13001300
DEFINE_IOMAP_EVENT(xfs_iomap_found);
1301-
DEFINE_IOMAP_EVENT(xfs_iomap_not_found);
13021301

13031302
DECLARE_EVENT_CLASS(xfs_simple_io_class,
13041303
TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count),

0 commit comments

Comments
 (0)