Skip to content

Commit 3b266a5

Browse files
committed
Merge tag 'iomap-5.5-merge-11' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull iomap updates from Darrick Wong: "In this release, we hoisted as much of XFS' writeback code into iomap as was practicable, refactored the unshare file data function, added the ability to perform buffered io copy on write, and tweaked various parts of the directio implementation as needed to port ext4's directio code (that will be a separate pull). Summary: - Make iomap_dio_rw callers explicitly tell us if they want us to wait - Port the xfs writeback code to iomap to complete the buffered io library functions - Refactor the unshare code to share common pieces - Add support for performing copy on write with buffered writes - Other minor fixes - Fix unchecked return in iomap_bmap - Fix a type casting bug in a ternary statement in iomap_dio_bio_actor - Improve tracepoints for easier diagnostic ability - Fix pipe page leakage in directio reads" * tag 'iomap-5.5-merge-11' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: (31 commits) iomap: Fix pipe page leakage during splicing iomap: trace iomap_appply results iomap: fix return value of iomap_dio_bio_actor on 32bit systems iomap: iomap_bmap should check iomap_apply return value iomap: Fix overflow in iomap_page_mkwrite fs/iomap: remove redundant check in iomap_dio_rw() iomap: use a srcmap for a read-modify-write I/O iomap: renumber IOMAP_HOLE to 0 iomap: use write_begin to read pages to unshare iomap: move the zeroing case out of iomap_read_page_sync iomap: ignore non-shared or non-data blocks in xfs_file_dirty iomap: always use AOP_FLAG_NOFS in iomap_write_begin iomap: remove the unused iomap argument to __iomap_write_end iomap: better document the IOMAP_F_* flags iomap: enhance writeback error message iomap: pass a struct page to iomap_finish_page_writeback iomap: cleanup iomap_ioend_compare iomap: move struct iomap_page out of iomap.h iomap: warn on inline maps in iomap_writepage_map iomap: lift the xfs writeback code to iomap ...
2 parents aa32f11 + 419e9c3 commit 3b266a5

26 files changed

+1215
-922
lines changed

fs/dax.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,7 +1091,7 @@ EXPORT_SYMBOL_GPL(__dax_zero_page_range);
10911091

10921092
static loff_t
10931093
dax_iomap_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
1094-
struct iomap *iomap)
1094+
struct iomap *iomap, struct iomap *srcmap)
10951095
{
10961096
struct block_device *bdev = iomap->bdev;
10971097
struct dax_device *dax_dev = iomap->dax_dev;
@@ -1248,7 +1248,8 @@ static vm_fault_t dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp,
12481248
struct inode *inode = mapping->host;
12491249
unsigned long vaddr = vmf->address;
12501250
loff_t pos = (loff_t)vmf->pgoff << PAGE_SHIFT;
1251-
struct iomap iomap = { 0 };
1251+
struct iomap iomap = { .type = IOMAP_HOLE };
1252+
struct iomap srcmap = { .type = IOMAP_HOLE };
12521253
unsigned flags = IOMAP_FAULT;
12531254
int error, major = 0;
12541255
bool write = vmf->flags & FAULT_FLAG_WRITE;
@@ -1293,7 +1294,7 @@ static vm_fault_t dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp,
12931294
* the file system block size to be equal the page size, which means
12941295
* that we never have to deal with more than a single extent here.
12951296
*/
1296-
error = ops->iomap_begin(inode, pos, PAGE_SIZE, flags, &iomap);
1297+
error = ops->iomap_begin(inode, pos, PAGE_SIZE, flags, &iomap, &srcmap);
12971298
if (iomap_errp)
12981299
*iomap_errp = error;
12991300
if (error) {
@@ -1472,7 +1473,8 @@ static vm_fault_t dax_iomap_pmd_fault(struct vm_fault *vmf, pfn_t *pfnp,
14721473
unsigned int iomap_flags = (write ? IOMAP_WRITE : 0) | IOMAP_FAULT;
14731474
struct inode *inode = mapping->host;
14741475
vm_fault_t result = VM_FAULT_FALLBACK;
1475-
struct iomap iomap = { 0 };
1476+
struct iomap iomap = { .type = IOMAP_HOLE };
1477+
struct iomap srcmap = { .type = IOMAP_HOLE };
14761478
pgoff_t max_pgoff;
14771479
void *entry;
14781480
loff_t pos;
@@ -1547,7 +1549,8 @@ static vm_fault_t dax_iomap_pmd_fault(struct vm_fault *vmf, pfn_t *pfnp,
15471549
* to look up our filesystem block.
15481550
*/
15491551
pos = (loff_t)xas.xa_index << PAGE_SHIFT;
1550-
error = ops->iomap_begin(inode, pos, PMD_SIZE, iomap_flags, &iomap);
1552+
error = ops->iomap_begin(inode, pos, PMD_SIZE, iomap_flags, &iomap,
1553+
&srcmap);
15511554
if (error)
15521555
goto unlock_entry;
15531556

fs/ext2/inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,7 @@ int ext2_get_block(struct inode *inode, sector_t iblock,
801801

802802
#ifdef CONFIG_FS_DAX
803803
static int ext2_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
804-
unsigned flags, struct iomap *iomap)
804+
unsigned flags, struct iomap *iomap, struct iomap *srcmap)
805805
{
806806
unsigned int blkbits = inode->i_blkbits;
807807
unsigned long first_block = offset >> blkbits;

fs/ext4/inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3407,7 +3407,7 @@ static bool ext4_inode_datasync_dirty(struct inode *inode)
34073407
}
34083408

34093409
static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
3410-
unsigned flags, struct iomap *iomap)
3410+
unsigned flags, struct iomap *iomap, struct iomap *srcmap)
34113411
{
34123412
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
34133413
unsigned int blkbits = inode->i_blkbits;

fs/gfs2/bmap.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1149,7 +1149,8 @@ static inline bool gfs2_iomap_need_write_lock(unsigned flags)
11491149
}
11501150

11511151
static int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length,
1152-
unsigned flags, struct iomap *iomap)
1152+
unsigned flags, struct iomap *iomap,
1153+
struct iomap *srcmap)
11531154
{
11541155
struct gfs2_inode *ip = GFS2_I(inode);
11551156
struct metapath mp = { .mp_aheight = 1, };

fs/gfs2/file.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,8 @@ static ssize_t gfs2_file_direct_read(struct kiocb *iocb, struct iov_iter *to)
732732
if (ret)
733733
goto out_uninit;
734734

735-
ret = iomap_dio_rw(iocb, to, &gfs2_iomap_ops, NULL);
735+
ret = iomap_dio_rw(iocb, to, &gfs2_iomap_ops, NULL,
736+
is_sync_kiocb(iocb));
736737

737738
gfs2_glock_dq(&gh);
738739
out_uninit:
@@ -767,7 +768,8 @@ static ssize_t gfs2_file_direct_write(struct kiocb *iocb, struct iov_iter *from)
767768
if (offset + len > i_size_read(&ip->i_inode))
768769
goto out;
769770

770-
ret = iomap_dio_rw(iocb, from, &gfs2_iomap_ops, NULL);
771+
ret = iomap_dio_rw(iocb, from, &gfs2_iomap_ops, NULL,
772+
is_sync_kiocb(iocb));
771773

772774
out:
773775
gfs2_glock_dq(&gh);

fs/iomap/Makefile

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
# Copyright (c) 2019 Oracle.
44
# All Rights Reserved.
55
#
6-
obj-$(CONFIG_FS_IOMAP) += iomap.o
76

8-
iomap-y += \
9-
apply.o \
10-
buffered-io.o \
11-
direct-io.o \
12-
fiemap.o \
13-
seek.o
7+
ccflags-y += -I $(srctree)/$(src) # needed for trace events
8+
9+
obj-$(CONFIG_FS_IOMAP) += iomap.o
1410

11+
iomap-y += trace.o \
12+
apply.o \
13+
buffered-io.o \
14+
direct-io.o \
15+
fiemap.o \
16+
seek.o
1517
iomap-$(CONFIG_SWAP) += swapfile.o

fs/iomap/apply.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <linux/compiler.h>
88
#include <linux/fs.h>
99
#include <linux/iomap.h>
10+
#include "trace.h"
1011

1112
/*
1213
* Execute a iomap write on a segment of the mapping that spans a
@@ -23,8 +24,12 @@ loff_t
2324
iomap_apply(struct inode *inode, loff_t pos, loff_t length, unsigned flags,
2425
const struct iomap_ops *ops, void *data, iomap_actor_t actor)
2526
{
26-
struct iomap iomap = { 0 };
27+
struct iomap iomap = { .type = IOMAP_HOLE };
28+
struct iomap srcmap = { .type = IOMAP_HOLE };
2729
loff_t written = 0, ret;
30+
u64 end;
31+
32+
trace_iomap_apply(inode, pos, length, flags, ops, actor, _RET_IP_);
2833

2934
/*
3035
* Need to map a range from start position for length bytes. This can
@@ -38,27 +43,42 @@ iomap_apply(struct inode *inode, loff_t pos, loff_t length, unsigned flags,
3843
* expose transient stale data. If the reserve fails, we can safely
3944
* back out at this point as there is nothing to undo.
4045
*/
41-
ret = ops->iomap_begin(inode, pos, length, flags, &iomap);
46+
ret = ops->iomap_begin(inode, pos, length, flags, &iomap, &srcmap);
4247
if (ret)
4348
return ret;
4449
if (WARN_ON(iomap.offset > pos))
4550
return -EIO;
4651
if (WARN_ON(iomap.length == 0))
4752
return -EIO;
4853

54+
trace_iomap_apply_dstmap(inode, &iomap);
55+
if (srcmap.type != IOMAP_HOLE)
56+
trace_iomap_apply_srcmap(inode, &srcmap);
57+
4958
/*
5059
* Cut down the length to the one actually provided by the filesystem,
5160
* as it might not be able to give us the whole size that we requested.
5261
*/
53-
if (iomap.offset + iomap.length < pos + length)
54-
length = iomap.offset + iomap.length - pos;
62+
end = iomap.offset + iomap.length;
63+
if (srcmap.type != IOMAP_HOLE)
64+
end = min(end, srcmap.offset + srcmap.length);
65+
if (pos + length > end)
66+
length = end - pos;
5567

5668
/*
57-
* Now that we have guaranteed that the space allocation will succeed.
69+
* Now that we have guaranteed that the space allocation will succeed,
5870
* we can do the copy-in page by page without having to worry about
5971
* failures exposing transient data.
72+
*
73+
* To support COW operations, we read in data for partially blocks from
74+
* the srcmap if the file system filled it in. In that case we the
75+
* length needs to be limited to the earlier of the ends of the iomaps.
76+
* If the file system did not provide a srcmap we pass in the normal
77+
* iomap into the actors so that they don't need to have special
78+
* handling for the two cases.
6079
*/
61-
written = actor(inode, pos, length, data, &iomap);
80+
written = actor(inode, pos, length, data, &iomap,
81+
srcmap.type != IOMAP_HOLE ? &srcmap : &iomap);
6282

6383
/*
6484
* Now the data has been copied, commit the range we've copied. This

0 commit comments

Comments
 (0)