1*6b855256SChristoph Hellwig // SPDX-License-Identifier: GPL-2.0
2*6b855256SChristoph Hellwig /*
3*6b855256SChristoph Hellwig * Copyright (c) 2016-2025 Christoph Hellwig.
4*6b855256SChristoph Hellwig * All Rights Reserved.
5*6b855256SChristoph Hellwig */
6*6b855256SChristoph Hellwig #include "xfs_platform.h"
7*6b855256SChristoph Hellwig #include "xfs_shared.h"
8*6b855256SChristoph Hellwig #include "xfs_format.h"
9*6b855256SChristoph Hellwig #include "xfs_log_format.h"
10*6b855256SChristoph Hellwig #include "xfs_trans_resv.h"
11*6b855256SChristoph Hellwig #include "xfs_mount.h"
12*6b855256SChristoph Hellwig #include "xfs_inode.h"
13*6b855256SChristoph Hellwig #include "xfs_iomap.h"
14*6b855256SChristoph Hellwig #include "xfs_trace.h"
15*6b855256SChristoph Hellwig #include "xfs_bmap_util.h"
16*6b855256SChristoph Hellwig #include "xfs_reflink.h"
17*6b855256SChristoph Hellwig #include "xfs_zone_alloc.h"
18*6b855256SChristoph Hellwig #include "xfs_ioend.h"
19*6b855256SChristoph Hellwig
20*6b855256SChristoph Hellwig static void
xfs_ioend_put_open_zones(struct iomap_ioend * ioend)21*6b855256SChristoph Hellwig xfs_ioend_put_open_zones(
22*6b855256SChristoph Hellwig struct iomap_ioend *ioend)
23*6b855256SChristoph Hellwig {
24*6b855256SChristoph Hellwig struct iomap_ioend *tmp;
25*6b855256SChristoph Hellwig
26*6b855256SChristoph Hellwig /*
27*6b855256SChristoph Hellwig * Put the open zone for all ioends merged into this one (if any).
28*6b855256SChristoph Hellwig */
29*6b855256SChristoph Hellwig list_for_each_entry(tmp, &ioend->io_list, io_list)
30*6b855256SChristoph Hellwig xfs_open_zone_put(tmp->io_private);
31*6b855256SChristoph Hellwig
32*6b855256SChristoph Hellwig /*
33*6b855256SChristoph Hellwig * The main ioend might not have an open zone if the submission failed
34*6b855256SChristoph Hellwig * before xfs_zone_alloc_and_submit got called.
35*6b855256SChristoph Hellwig */
36*6b855256SChristoph Hellwig if (ioend->io_private)
37*6b855256SChristoph Hellwig xfs_open_zone_put(ioend->io_private);
38*6b855256SChristoph Hellwig }
39*6b855256SChristoph Hellwig
40*6b855256SChristoph Hellwig static void
xfs_end_ioend_write(struct iomap_ioend * ioend)41*6b855256SChristoph Hellwig xfs_end_ioend_write(
42*6b855256SChristoph Hellwig struct iomap_ioend *ioend)
43*6b855256SChristoph Hellwig {
44*6b855256SChristoph Hellwig struct xfs_inode *ip = XFS_I(ioend->io_inode);
45*6b855256SChristoph Hellwig struct xfs_mount *mp = ip->i_mount;
46*6b855256SChristoph Hellwig bool is_zoned = xfs_is_zoned_inode(ip);
47*6b855256SChristoph Hellwig xfs_off_t offset = ioend->io_offset;
48*6b855256SChristoph Hellwig size_t size = ioend->io_size;
49*6b855256SChristoph Hellwig unsigned int nofs_flag;
50*6b855256SChristoph Hellwig int error;
51*6b855256SChristoph Hellwig
52*6b855256SChristoph Hellwig /*
53*6b855256SChristoph Hellwig * We can allocate memory here while doing writeback on behalf of
54*6b855256SChristoph Hellwig * memory reclaim. To avoid memory allocation deadlocks set the
55*6b855256SChristoph Hellwig * task-wide nofs context for the following operations.
56*6b855256SChristoph Hellwig */
57*6b855256SChristoph Hellwig nofs_flag = memalloc_nofs_save();
58*6b855256SChristoph Hellwig
59*6b855256SChristoph Hellwig /*
60*6b855256SChristoph Hellwig * Just clean up the in-memory structures if the fs has been shut down.
61*6b855256SChristoph Hellwig */
62*6b855256SChristoph Hellwig if (xfs_is_shutdown(mp)) {
63*6b855256SChristoph Hellwig error = -EIO;
64*6b855256SChristoph Hellwig goto done;
65*6b855256SChristoph Hellwig }
66*6b855256SChristoph Hellwig
67*6b855256SChristoph Hellwig /*
68*6b855256SChristoph Hellwig * Clean up all COW blocks and underlying data fork delalloc blocks on
69*6b855256SChristoph Hellwig * I/O error. The delalloc punch is required because this ioend was
70*6b855256SChristoph Hellwig * mapped to blocks in the COW fork and the associated pages are no
71*6b855256SChristoph Hellwig * longer dirty. If we don't remove delalloc blocks here, they become
72*6b855256SChristoph Hellwig * stale and can corrupt free space accounting on unmount.
73*6b855256SChristoph Hellwig */
74*6b855256SChristoph Hellwig error = blk_status_to_errno(ioend->io_bio.bi_status);
75*6b855256SChristoph Hellwig if (unlikely(error)) {
76*6b855256SChristoph Hellwig /*
77*6b855256SChristoph Hellwig * Zoned writes update the in-core open zone accounting before
78*6b855256SChristoph Hellwig * I/O submission. A failed write leaves that state
79*6b855256SChristoph Hellwig * inconsistent, so shut down the filesystem instead of letting
80*6b855256SChristoph Hellwig * later writers wait forever for open zone space to become
81*6b855256SChristoph Hellwig * available.
82*6b855256SChristoph Hellwig */
83*6b855256SChristoph Hellwig if (is_zoned) {
84*6b855256SChristoph Hellwig xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
85*6b855256SChristoph Hellwig goto done;
86*6b855256SChristoph Hellwig }
87*6b855256SChristoph Hellwig if (ioend->io_flags & IOMAP_IOEND_SHARED) {
88*6b855256SChristoph Hellwig ASSERT(!is_zoned);
89*6b855256SChristoph Hellwig xfs_reflink_cancel_cow_range(ip, offset, size, true);
90*6b855256SChristoph Hellwig xfs_bmap_punch_delalloc_range(ip, XFS_DATA_FORK, offset,
91*6b855256SChristoph Hellwig offset + size, NULL);
92*6b855256SChristoph Hellwig }
93*6b855256SChristoph Hellwig goto done;
94*6b855256SChristoph Hellwig }
95*6b855256SChristoph Hellwig
96*6b855256SChristoph Hellwig /*
97*6b855256SChristoph Hellwig * Success: commit the COW or unwritten blocks if needed.
98*6b855256SChristoph Hellwig */
99*6b855256SChristoph Hellwig if (is_zoned)
100*6b855256SChristoph Hellwig error = xfs_zoned_end_io(ip, offset, size, ioend->io_sector,
101*6b855256SChristoph Hellwig ioend->io_private, NULLFSBLOCK);
102*6b855256SChristoph Hellwig else if (ioend->io_flags & IOMAP_IOEND_SHARED)
103*6b855256SChristoph Hellwig error = xfs_reflink_end_cow(ip, offset, size);
104*6b855256SChristoph Hellwig else if (ioend->io_flags & IOMAP_IOEND_UNWRITTEN)
105*6b855256SChristoph Hellwig error = xfs_iomap_write_unwritten(ip, offset, size, false);
106*6b855256SChristoph Hellwig
107*6b855256SChristoph Hellwig if (!error &&
108*6b855256SChristoph Hellwig !(ioend->io_flags & IOMAP_IOEND_DIRECT) &&
109*6b855256SChristoph Hellwig xfs_ioend_is_append(ioend))
110*6b855256SChristoph Hellwig error = xfs_setfilesize(ip, offset, size);
111*6b855256SChristoph Hellwig done:
112*6b855256SChristoph Hellwig if (is_zoned)
113*6b855256SChristoph Hellwig xfs_ioend_put_open_zones(ioend);
114*6b855256SChristoph Hellwig iomap_finish_ioends(ioend, error);
115*6b855256SChristoph Hellwig memalloc_nofs_restore(nofs_flag);
116*6b855256SChristoph Hellwig }
117*6b855256SChristoph Hellwig
118*6b855256SChristoph Hellwig /*
119*6b855256SChristoph Hellwig * Finish all pending IO completions that require transactional modifications.
120*6b855256SChristoph Hellwig *
121*6b855256SChristoph Hellwig * We try to merge physical and logically contiguous ioends before completion to
122*6b855256SChristoph Hellwig * minimise the number of transactions we need to perform during IO completion.
123*6b855256SChristoph Hellwig * Both unwritten extent conversion and COW remapping need to iterate and modify
124*6b855256SChristoph Hellwig * one physical extent at a time, so we gain nothing by merging physically
125*6b855256SChristoph Hellwig * discontiguous extents here.
126*6b855256SChristoph Hellwig *
127*6b855256SChristoph Hellwig * The ioend chain length that we can be processing here is largely unbound in
128*6b855256SChristoph Hellwig * length and we may have to perform significant amounts of work on each ioend
129*6b855256SChristoph Hellwig * to complete it. Hence we have to be careful about holding the CPU for too
130*6b855256SChristoph Hellwig * long in this loop.
131*6b855256SChristoph Hellwig */
132*6b855256SChristoph Hellwig void
xfs_end_io(struct work_struct * work)133*6b855256SChristoph Hellwig xfs_end_io(
134*6b855256SChristoph Hellwig struct work_struct *work)
135*6b855256SChristoph Hellwig {
136*6b855256SChristoph Hellwig struct xfs_inode *ip =
137*6b855256SChristoph Hellwig container_of(work, struct xfs_inode, i_ioend_work);
138*6b855256SChristoph Hellwig struct iomap_ioend *ioend;
139*6b855256SChristoph Hellwig struct list_head tmp;
140*6b855256SChristoph Hellwig unsigned long flags;
141*6b855256SChristoph Hellwig
142*6b855256SChristoph Hellwig spin_lock_irqsave(&ip->i_ioend_lock, flags);
143*6b855256SChristoph Hellwig list_replace_init(&ip->i_ioend_list, &tmp);
144*6b855256SChristoph Hellwig spin_unlock_irqrestore(&ip->i_ioend_lock, flags);
145*6b855256SChristoph Hellwig
146*6b855256SChristoph Hellwig iomap_sort_ioends(&tmp);
147*6b855256SChristoph Hellwig while ((ioend = list_first_entry_or_null(&tmp, struct iomap_ioend,
148*6b855256SChristoph Hellwig io_list))) {
149*6b855256SChristoph Hellwig list_del_init(&ioend->io_list);
150*6b855256SChristoph Hellwig iomap_ioend_try_merge(ioend, &tmp);
151*6b855256SChristoph Hellwig if (bio_op(&ioend->io_bio) == REQ_OP_READ)
152*6b855256SChristoph Hellwig iomap_finish_ioends(ioend,
153*6b855256SChristoph Hellwig blk_status_to_errno(ioend->io_bio.bi_status));
154*6b855256SChristoph Hellwig else
155*6b855256SChristoph Hellwig xfs_end_ioend_write(ioend);
156*6b855256SChristoph Hellwig cond_resched();
157*6b855256SChristoph Hellwig }
158*6b855256SChristoph Hellwig }
159*6b855256SChristoph Hellwig
160*6b855256SChristoph Hellwig void
xfs_end_bio(struct bio * bio)161*6b855256SChristoph Hellwig xfs_end_bio(
162*6b855256SChristoph Hellwig struct bio *bio)
163*6b855256SChristoph Hellwig {
164*6b855256SChristoph Hellwig struct iomap_ioend *ioend = iomap_ioend_from_bio(bio);
165*6b855256SChristoph Hellwig struct xfs_inode *ip = XFS_I(ioend->io_inode);
166*6b855256SChristoph Hellwig struct xfs_mount *mp = ip->i_mount;
167*6b855256SChristoph Hellwig unsigned long flags;
168*6b855256SChristoph Hellwig
169*6b855256SChristoph Hellwig /*
170*6b855256SChristoph Hellwig * For Appends record the actually written block number and set the
171*6b855256SChristoph Hellwig * boundary flag if needed.
172*6b855256SChristoph Hellwig */
173*6b855256SChristoph Hellwig if (IS_ENABLED(CONFIG_XFS_RT) && bio_is_zone_append(bio)) {
174*6b855256SChristoph Hellwig ioend->io_sector = bio->bi_iter.bi_sector;
175*6b855256SChristoph Hellwig xfs_mark_rtg_boundary(ioend);
176*6b855256SChristoph Hellwig }
177*6b855256SChristoph Hellwig
178*6b855256SChristoph Hellwig spin_lock_irqsave(&ip->i_ioend_lock, flags);
179*6b855256SChristoph Hellwig if (list_empty(&ip->i_ioend_list))
180*6b855256SChristoph Hellwig WARN_ON_ONCE(!queue_work(mp->m_unwritten_workqueue,
181*6b855256SChristoph Hellwig &ip->i_ioend_work));
182*6b855256SChristoph Hellwig list_add_tail(&ioend->io_list, &ip->i_ioend_list);
183*6b855256SChristoph Hellwig spin_unlock_irqrestore(&ip->i_ioend_lock, flags);
184*6b855256SChristoph Hellwig }
185