Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-or-later
2 : /*
3 : * Copyright (C) 2023 Oracle. All Rights Reserved.
4 : * Author: Darrick J. Wong <djwong@kernel.org>
5 : */
6 : #include "xfs.h"
7 : #include "xfs_fs.h"
8 : #include "xfs_buf.h"
9 : #include "xfs_buf_xfile.h"
10 : #include "scrub/xfile.h"
11 :
12 : /* Perform a buffer IO to an xfile. Caller must be in process context. */
13 : int
14 42360 : xfile_buf_ioapply(
15 : struct xfs_buf *bp)
16 : {
17 42360 : struct xfile *xfile = bp->b_target->bt_xfile;
18 42360 : loff_t pos = BBTOB(xfs_buf_daddr(bp));
19 42360 : size_t size = BBTOB(bp->b_length);
20 :
21 42360 : if (bp->b_target->bt_flags & XFS_BUFTARG_DIRECT_MAP) {
22 : /* direct mapping means no io necessary */
23 : return 0;
24 : }
25 :
26 0 : if (bp->b_map_count > 1) {
27 : /* We don't need or support multi-map buffers. */
28 0 : ASSERT(0);
29 0 : return -EIO;
30 : }
31 :
32 0 : if (bp->b_flags & XBF_WRITE)
33 0 : return xfile_obj_store(xfile, bp->b_addr, size, pos);
34 0 : return xfile_obj_load(xfile, bp->b_addr, size, pos);
35 : }
36 :
37 : /* Allocate a buffer cache target for a memory-backed file. */
38 : int
39 21338 : xfile_alloc_buftarg(
40 : struct xfs_mount *mp,
41 : const char *descr,
42 : struct xfs_buftarg **btpp)
43 : {
44 21338 : struct xfs_buftarg *btp;
45 21338 : struct xfile *xfile;
46 21338 : int error;
47 :
48 21338 : error = xfile_create(descr, 0, &xfile);
49 21341 : if (error)
50 : return error;
51 :
52 : /*
53 : * We're hooking the xfile up to the buffer cache, so disable its
54 : * internal page caching because all callers should be using xfs_buf
55 : * functions.
56 : */
57 21341 : xfile_cache_disable(xfile);
58 :
59 21340 : error = xfs_buf_cache_init(&xfile->bcache);
60 21327 : if (error)
61 0 : goto out_xfile;
62 :
63 21327 : btp = xfs_alloc_buftarg_common(mp, descr);
64 21357 : if (!btp) {
65 0 : error = -ENOMEM;
66 0 : goto out_bcache;
67 : }
68 :
69 21357 : btp->bt_xfile = xfile;
70 21357 : btp->bt_dev = (dev_t)-1U;
71 21357 : btp->bt_flags |= XFS_BUFTARG_XFILE;
72 21357 : btp->bt_cache = &xfile->bcache;
73 :
74 21357 : btp->bt_meta_sectorsize = SECTOR_SIZE;
75 21357 : btp->bt_meta_sectormask = SECTOR_SIZE - 1;
76 21357 : btp->bt_logical_sectorsize = SECTOR_SIZE;
77 21357 : btp->bt_logical_sectormask = SECTOR_SIZE - 1;
78 :
79 21357 : *btpp = btp;
80 21357 : return 0;
81 :
82 : out_bcache:
83 0 : xfs_buf_cache_destroy(&xfile->bcache);
84 0 : out_xfile:
85 0 : xfile_destroy(xfile);
86 0 : return error;
87 : }
88 :
89 : /* Free a buffer cache target for a memory-backed file. */
90 : void
91 21346 : xfile_free_buftarg(
92 : struct xfs_buftarg *btp)
93 : {
94 21346 : struct xfile *xfile = btp->bt_xfile;
95 :
96 21346 : ASSERT(btp->bt_flags & XFS_BUFTARG_XFILE);
97 :
98 21346 : xfs_free_buftarg(btp);
99 21357 : xfs_buf_cache_destroy(&xfile->bcache);
100 21352 : xfile_destroy(xfile);
101 21356 : }
102 :
103 : /* Sector count for this xfile buftarg. */
104 : xfs_daddr_t
105 1336966173 : xfile_buftarg_nr_sectors(
106 : struct xfs_buftarg *btp)
107 : {
108 1336966173 : return xfile_size(btp->bt_xfile) >> SECTOR_SHIFT;
109 : }
110 :
111 : /* Free an xfile page that was directly mapped into the buffer cache. */
112 : static int
113 47118 : xfile_buf_put_page(
114 : struct xfile *xfile,
115 : loff_t pos,
116 : struct page *page)
117 : {
118 47118 : struct xfile_page xfpage = {
119 : .page = page,
120 47118 : .pos = round_down(pos, PAGE_SIZE),
121 : };
122 :
123 47118 : lock_page(xfpage.page);
124 :
125 47117 : return xfile_put_page(xfile, &xfpage);
126 : }
127 :
128 : /* Grab the xfile page for this part of the xfile. */
129 : static int
130 47114 : xfile_buf_get_page(
131 : struct xfile *xfile,
132 : loff_t pos,
133 : unsigned int len,
134 : struct page **pagep)
135 : {
136 47114 : struct xfile_page xfpage = { NULL };
137 47114 : int error;
138 :
139 47114 : error = xfile_get_page(xfile, pos, len, &xfpage);
140 47113 : if (error)
141 : return error;
142 :
143 : /*
144 : * Fall back to regular DRAM buffers if tmpfs gives us fsdata or the
145 : * page pos isn't what we were expecting.
146 : */
147 47113 : if (xfpage.fsdata || xfpage.pos != round_down(pos, PAGE_SIZE)) {
148 0 : xfile_put_page(xfile, &xfpage);
149 0 : return -ENOTBLK;
150 : }
151 :
152 : /* Unlock the page before we start using them for the buffer cache. */
153 47113 : ASSERT(PageUptodate(xfpage.page));
154 47117 : unlock_page(xfpage.page);
155 :
156 47113 : *pagep = xfpage.page;
157 47113 : return 0;
158 : }
159 :
160 : /*
161 : * Try to map storage directly, if the target supports it. Returns 0 for
162 : * success, -ENOTBLK to mean "not supported", or the usual negative errno.
163 : */
164 : int
165 47114 : xfile_buf_map_pages(
166 : struct xfs_buf *bp,
167 : xfs_buf_flags_t flags)
168 : {
169 47114 : struct xfs_buf_map *map;
170 47114 : gfp_t gfp_mask = __GFP_NOWARN;
171 47114 : const unsigned int page_align_mask = PAGE_SIZE - 1;
172 47114 : unsigned int m, p, n;
173 47114 : unsigned int first_page_offset;
174 47114 : int error;
175 :
176 47114 : ASSERT(xfile_buftarg_can_direct_map(bp->b_target));
177 :
178 : /*
179 : * For direct-map buffer targets with multiple mappings, the first map
180 : * must end on a page boundary and the rest of the mappings must start
181 : * and end on a page boundary. For single-mapping buffers, we don't
182 : * care.
183 : */
184 47114 : if (bp->b_map_count > 1) {
185 0 : map = &bp->b_maps[0];
186 0 : if (BBTOB(map->bm_bn + map->bm_len) & page_align_mask)
187 : return -ENOTBLK;
188 :
189 0 : for (m = 1, map++; m < bp->b_map_count - 1; m++, map++)
190 0 : if (BBTOB(map->bm_bn | map->bm_len) & page_align_mask)
191 : return -ENOTBLK;
192 : }
193 :
194 47114 : if (flags & XBF_READ_AHEAD)
195 : gfp_mask |= __GFP_NORETRY;
196 : else
197 47114 : gfp_mask |= GFP_NOFS;
198 :
199 47114 : error = xfs_buf_alloc_page_array(bp, gfp_mask);
200 47113 : if (error)
201 : return error;
202 :
203 : /* Map in the xfile pages. */
204 47113 : first_page_offset = offset_in_page(BBTOB(xfs_buf_daddr(bp)));
205 94227 : for (m = 0, p = 0, map = bp->b_maps; m < bp->b_map_count; m++, map++) {
206 94228 : for (n = 0; n < map->bm_len; n += BTOBB(PAGE_SIZE)) {
207 47114 : unsigned int len;
208 :
209 47114 : len = min_t(unsigned int, BBTOB(map->bm_len - n),
210 : PAGE_SIZE);
211 :
212 47114 : error = xfile_buf_get_page(bp->b_target->bt_xfile,
213 47114 : BBTOB(map->bm_bn + n), len,
214 47114 : &bp->b_pages[p++]);
215 47114 : if (error)
216 0 : goto fail;
217 : }
218 : }
219 :
220 47113 : bp->b_flags |= _XBF_DIRECT_MAP;
221 47113 : bp->b_offset = first_page_offset;
222 47113 : return 0;
223 :
224 : fail:
225 : /*
226 : * Release all the xfile pages and free the page array, we're falling
227 : * back to a DRAM buffer, which could be pages or a slab allocation.
228 : */
229 0 : for (m = 0, p = 0, map = bp->b_maps; m < bp->b_map_count; m++, map++) {
230 0 : for (n = 0; n < map->bm_len; n += BTOBB(PAGE_SIZE)) {
231 0 : if (bp->b_pages[p] == NULL)
232 0 : continue;
233 :
234 0 : xfile_buf_put_page(bp->b_target->bt_xfile,
235 0 : BBTOB(map->bm_bn + n),
236 0 : bp->b_pages[p++]);
237 : }
238 : }
239 :
240 0 : xfs_buf_free_page_array(bp);
241 0 : return error;
242 : }
243 :
244 : /* Unmap all the direct-mapped buffer pages. */
245 : void
246 47119 : xfile_buf_unmap_pages(
247 : struct xfs_buf *bp)
248 : {
249 47119 : struct xfs_buf_map *map;
250 47119 : unsigned int m, p, n;
251 47119 : int error = 0, err2;
252 :
253 47119 : ASSERT(xfile_buftarg_can_direct_map(bp->b_target));
254 :
255 94237 : for (m = 0, p = 0, map = bp->b_maps; m < bp->b_map_count; m++, map++) {
256 94237 : for (n = 0; n < map->bm_len; n += BTOBB(PAGE_SIZE)) {
257 47119 : err2 = xfile_buf_put_page(bp->b_target->bt_xfile,
258 47119 : BBTOB(map->bm_bn + n),
259 47119 : bp->b_pages[p++]);
260 47118 : if (!error && err2)
261 0 : error = err2;
262 : }
263 : }
264 :
265 47118 : if (error)
266 0 : xfs_err(bp->b_mount, "%s failed errno %d", __func__, error);
267 :
268 47118 : bp->b_flags &= ~_XBF_DIRECT_MAP;
269 47118 : xfs_buf_free_page_array(bp);
270 47118 : }
|