1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (C) 2010 Red Hat, Inc.
4*4882a593Smuzhiyun * Copyright (c) 2016-2018 Christoph Hellwig.
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun #include <linux/module.h>
7*4882a593Smuzhiyun #include <linux/compiler.h>
8*4882a593Smuzhiyun #include <linux/fs.h>
9*4882a593Smuzhiyun #include <linux/iomap.h>
10*4882a593Smuzhiyun #include "trace.h"
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun /*
13*4882a593Smuzhiyun * Execute a iomap write on a segment of the mapping that spans a
14*4882a593Smuzhiyun * contiguous range of pages that have identical block mapping state.
15*4882a593Smuzhiyun *
16*4882a593Smuzhiyun * This avoids the need to map pages individually, do individual allocations
17*4882a593Smuzhiyun * for each page and most importantly avoid the need for filesystem specific
18*4882a593Smuzhiyun * locking per page. Instead, all the operations are amortised over the entire
19*4882a593Smuzhiyun * range of pages. It is assumed that the filesystems will lock whatever
20*4882a593Smuzhiyun * resources they require in the iomap_begin call, and release them in the
21*4882a593Smuzhiyun * iomap_end call.
22*4882a593Smuzhiyun */
23*4882a593Smuzhiyun loff_t
iomap_apply(struct inode * inode,loff_t pos,loff_t length,unsigned flags,const struct iomap_ops * ops,void * data,iomap_actor_t actor)24*4882a593Smuzhiyun iomap_apply(struct inode *inode, loff_t pos, loff_t length, unsigned flags,
25*4882a593Smuzhiyun const struct iomap_ops *ops, void *data, iomap_actor_t actor)
26*4882a593Smuzhiyun {
27*4882a593Smuzhiyun struct iomap iomap = { .type = IOMAP_HOLE };
28*4882a593Smuzhiyun struct iomap srcmap = { .type = IOMAP_HOLE };
29*4882a593Smuzhiyun loff_t written = 0, ret;
30*4882a593Smuzhiyun u64 end;
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun trace_iomap_apply(inode, pos, length, flags, ops, actor, _RET_IP_);
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun /*
35*4882a593Smuzhiyun * Need to map a range from start position for length bytes. This can
36*4882a593Smuzhiyun * span multiple pages - it is only guaranteed to return a range of a
37*4882a593Smuzhiyun * single type of pages (e.g. all into a hole, all mapped or all
38*4882a593Smuzhiyun * unwritten). Failure at this point has nothing to undo.
39*4882a593Smuzhiyun *
40*4882a593Smuzhiyun * If allocation is required for this range, reserve the space now so
41*4882a593Smuzhiyun * that the allocation is guaranteed to succeed later on. Once we copy
42*4882a593Smuzhiyun * the data into the page cache pages, then we cannot fail otherwise we
43*4882a593Smuzhiyun * expose transient stale data. If the reserve fails, we can safely
44*4882a593Smuzhiyun * back out at this point as there is nothing to undo.
45*4882a593Smuzhiyun */
46*4882a593Smuzhiyun ret = ops->iomap_begin(inode, pos, length, flags, &iomap, &srcmap);
47*4882a593Smuzhiyun if (ret)
48*4882a593Smuzhiyun return ret;
49*4882a593Smuzhiyun if (WARN_ON(iomap.offset > pos)) {
50*4882a593Smuzhiyun written = -EIO;
51*4882a593Smuzhiyun goto out;
52*4882a593Smuzhiyun }
53*4882a593Smuzhiyun if (WARN_ON(iomap.length == 0)) {
54*4882a593Smuzhiyun written = -EIO;
55*4882a593Smuzhiyun goto out;
56*4882a593Smuzhiyun }
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun trace_iomap_apply_dstmap(inode, &iomap);
59*4882a593Smuzhiyun if (srcmap.type != IOMAP_HOLE)
60*4882a593Smuzhiyun trace_iomap_apply_srcmap(inode, &srcmap);
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun /*
63*4882a593Smuzhiyun * Cut down the length to the one actually provided by the filesystem,
64*4882a593Smuzhiyun * as it might not be able to give us the whole size that we requested.
65*4882a593Smuzhiyun */
66*4882a593Smuzhiyun end = iomap.offset + iomap.length;
67*4882a593Smuzhiyun if (srcmap.type != IOMAP_HOLE)
68*4882a593Smuzhiyun end = min(end, srcmap.offset + srcmap.length);
69*4882a593Smuzhiyun if (pos + length > end)
70*4882a593Smuzhiyun length = end - pos;
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun /*
73*4882a593Smuzhiyun * Now that we have guaranteed that the space allocation will succeed,
74*4882a593Smuzhiyun * we can do the copy-in page by page without having to worry about
75*4882a593Smuzhiyun * failures exposing transient data.
76*4882a593Smuzhiyun *
77*4882a593Smuzhiyun * To support COW operations, we read in data for partially blocks from
78*4882a593Smuzhiyun * the srcmap if the file system filled it in. In that case we the
79*4882a593Smuzhiyun * length needs to be limited to the earlier of the ends of the iomaps.
80*4882a593Smuzhiyun * If the file system did not provide a srcmap we pass in the normal
81*4882a593Smuzhiyun * iomap into the actors so that they don't need to have special
82*4882a593Smuzhiyun * handling for the two cases.
83*4882a593Smuzhiyun */
84*4882a593Smuzhiyun written = actor(inode, pos, length, data, &iomap,
85*4882a593Smuzhiyun srcmap.type != IOMAP_HOLE ? &srcmap : &iomap);
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun out:
88*4882a593Smuzhiyun /*
89*4882a593Smuzhiyun * Now the data has been copied, commit the range we've copied. This
90*4882a593Smuzhiyun * should not fail unless the filesystem has had a fatal error.
91*4882a593Smuzhiyun */
92*4882a593Smuzhiyun if (ops->iomap_end) {
93*4882a593Smuzhiyun ret = ops->iomap_end(inode, pos, length,
94*4882a593Smuzhiyun written > 0 ? written : 0,
95*4882a593Smuzhiyun flags, &iomap);
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun return written ? written : ret;
99*4882a593Smuzhiyun }
100