1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* Cache data I/O routines
4 * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
5 * Written by David Howells (dhowells@redhat.com)
7 #define FSCACHE_DEBUG_LEVEL OPERATION
8 #include <linux/fscache-cache.h>
10 #include <linux/bvec.h>
11 #include <linux/slab.h>
12 #include <linux/uio.h>
16 * fscache_wait_for_operation - Wait for an object become accessible
17 * @cres: The cache resources for the operation being performed
18 * @want_state: The minimum state the object must be at
20 * See if the target cache object is at the specified minimum state of
21 * accessibility yet, and if not, wait for it.
23 bool fscache_wait_for_operation(struct netfs_cache_resources
*cres
,
24 enum fscache_want_state want_state
)
26 struct fscache_cookie
*cookie
= fscache_cres_cookie(cres
);
27 enum fscache_cookie_state state
;
30 if (!fscache_cache_is_live(cookie
->volume
->cache
)) {
35 state
= fscache_cookie_state(cookie
);
36 _enter("c=%08x{%u},%x", cookie
->debug_id
, state
, want_state
);
39 case FSCACHE_COOKIE_STATE_CREATING
:
40 case FSCACHE_COOKIE_STATE_INVALIDATING
:
41 if (want_state
== FSCACHE_WANT_PARAMS
)
42 goto ready
; /* There can be no content */
44 case FSCACHE_COOKIE_STATE_LOOKING_UP
:
45 case FSCACHE_COOKIE_STATE_LRU_DISCARDING
:
46 wait_var_event(&cookie
->state
,
47 fscache_cookie_state(cookie
) != state
);
50 case FSCACHE_COOKIE_STATE_ACTIVE
:
52 case FSCACHE_COOKIE_STATE_DROPPED
:
53 case FSCACHE_COOKIE_STATE_RELINQUISHING
:
55 _leave(" [not live]");
60 if (!cres
->cache_priv2
)
61 return cookie
->volume
->cache
->ops
->begin_operation(cres
, want_state
);
64 EXPORT_SYMBOL(fscache_wait_for_operation
);
67 * Begin an I/O operation on the cache, waiting till we reach the right state.
69 * Attaches the resources required to the operation resources record.
71 static int fscache_begin_operation(struct netfs_cache_resources
*cres
,
72 struct fscache_cookie
*cookie
,
73 enum fscache_want_state want_state
,
74 enum fscache_access_trace why
)
76 enum fscache_cookie_state state
;
78 bool once_only
= false;
81 cres
->cache_priv
= cookie
;
82 cres
->cache_priv2
= NULL
;
83 cres
->debug_id
= cookie
->debug_id
;
84 cres
->inval_counter
= cookie
->inval_counter
;
86 if (!fscache_begin_cookie_access(cookie
, why
))
90 spin_lock(&cookie
->lock
);
92 state
= fscache_cookie_state(cookie
);
93 _enter("c=%08x{%u},%x", cookie
->debug_id
, state
, want_state
);
96 case FSCACHE_COOKIE_STATE_LOOKING_UP
:
97 case FSCACHE_COOKIE_STATE_LRU_DISCARDING
:
98 case FSCACHE_COOKIE_STATE_INVALIDATING
:
99 goto wait_for_file_wrangling
;
100 case FSCACHE_COOKIE_STATE_CREATING
:
101 if (want_state
== FSCACHE_WANT_PARAMS
)
102 goto ready
; /* There can be no content */
103 goto wait_for_file_wrangling
;
104 case FSCACHE_COOKIE_STATE_ACTIVE
:
106 case FSCACHE_COOKIE_STATE_DROPPED
:
107 case FSCACHE_COOKIE_STATE_RELINQUISHING
:
108 WARN(1, "Can't use cookie in state %u\n", cookie
->state
);
115 spin_unlock(&cookie
->lock
);
116 if (!cookie
->volume
->cache
->ops
->begin_operation(cres
, want_state
))
120 wait_for_file_wrangling
:
121 spin_unlock(&cookie
->lock
);
122 trace_fscache_access(cookie
->debug_id
, refcount_read(&cookie
->ref
),
123 atomic_read(&cookie
->n_accesses
),
124 fscache_access_io_wait
);
125 timeo
= wait_var_event_timeout(&cookie
->state
,
126 fscache_cookie_state(cookie
) != state
, 20 * HZ
);
127 if (timeo
<= 1 && !once_only
) {
128 pr_warn("%s: cookie state change wait timed out: cookie->state=%u state=%u",
129 __func__
, fscache_cookie_state(cookie
), state
);
130 fscache_print_cookie(cookie
, 'O');
136 spin_unlock(&cookie
->lock
);
138 cres
->cache_priv
= NULL
;
140 fscache_end_cookie_access(cookie
, fscache_access_io_not_live
);
141 _leave(" = -ENOBUFS");
145 int __fscache_begin_read_operation(struct netfs_cache_resources
*cres
,
146 struct fscache_cookie
*cookie
)
148 return fscache_begin_operation(cres
, cookie
, FSCACHE_WANT_PARAMS
,
149 fscache_access_io_read
);
151 EXPORT_SYMBOL(__fscache_begin_read_operation
);
153 int __fscache_begin_write_operation(struct netfs_cache_resources
*cres
,
154 struct fscache_cookie
*cookie
)
156 return fscache_begin_operation(cres
, cookie
, FSCACHE_WANT_PARAMS
,
157 fscache_access_io_write
);
159 EXPORT_SYMBOL(__fscache_begin_write_operation
);
162 * fscache_dirty_folio - Mark folio dirty and pin a cache object for writeback
163 * @mapping: The mapping the folio belongs to.
164 * @folio: The folio being dirtied.
165 * @cookie: The cookie referring to the cache object
167 * Set the dirty flag on a folio and pin an in-use cache object in memory
168 * so that writeback can later write to it. This is intended
169 * to be called from the filesystem's ->dirty_folio() method.
171 * Return: true if the dirty flag was set on the folio, false otherwise.
173 bool fscache_dirty_folio(struct address_space
*mapping
, struct folio
*folio
,
174 struct fscache_cookie
*cookie
)
176 struct inode
*inode
= mapping
->host
;
177 bool need_use
= false;
181 if (!filemap_dirty_folio(mapping
, folio
))
183 if (!fscache_cookie_valid(cookie
))
186 if (!(inode
->i_state
& I_PINNING_FSCACHE_WB
)) {
187 spin_lock(&inode
->i_lock
);
188 if (!(inode
->i_state
& I_PINNING_FSCACHE_WB
)) {
189 inode
->i_state
|= I_PINNING_FSCACHE_WB
;
192 spin_unlock(&inode
->i_lock
);
195 fscache_use_cookie(cookie
, true);
199 EXPORT_SYMBOL(fscache_dirty_folio
);
201 struct fscache_write_request
{
202 struct netfs_cache_resources cache_resources
;
203 struct address_space
*mapping
;
207 netfs_io_terminated_t term_func
;
208 void *term_func_priv
;
211 void __fscache_clear_page_bits(struct address_space
*mapping
,
212 loff_t start
, size_t len
)
214 pgoff_t first
= start
/ PAGE_SIZE
;
215 pgoff_t last
= (start
+ len
- 1) / PAGE_SIZE
;
219 XA_STATE(xas
, &mapping
->i_pages
, first
);
222 xas_for_each(&xas
, page
, last
) {
223 end_page_fscache(page
);
228 EXPORT_SYMBOL(__fscache_clear_page_bits
);
231 * Deal with the completion of writing the data to the cache.
233 static void fscache_wreq_done(void *priv
, ssize_t transferred_or_error
,
236 struct fscache_write_request
*wreq
= priv
;
238 fscache_clear_page_bits(wreq
->mapping
, wreq
->start
, wreq
->len
,
242 wreq
->term_func(wreq
->term_func_priv
, transferred_or_error
,
244 fscache_end_operation(&wreq
->cache_resources
);
248 void __fscache_write_to_cache(struct fscache_cookie
*cookie
,
249 struct address_space
*mapping
,
250 loff_t start
, size_t len
, loff_t i_size
,
251 netfs_io_terminated_t term_func
,
252 void *term_func_priv
,
255 struct fscache_write_request
*wreq
;
256 struct netfs_cache_resources
*cres
;
257 struct iov_iter iter
;
263 _enter("%llx,%zx", start
, len
);
265 wreq
= kzalloc(sizeof(struct fscache_write_request
), GFP_NOFS
);
268 wreq
->mapping
= mapping
;
271 wreq
->set_bits
= cond
;
272 wreq
->term_func
= term_func
;
273 wreq
->term_func_priv
= term_func_priv
;
275 cres
= &wreq
->cache_resources
;
276 if (fscache_begin_operation(cres
, cookie
, FSCACHE_WANT_WRITE
,
277 fscache_access_io_write
) < 0)
280 ret
= cres
->ops
->prepare_write(cres
, &start
, &len
, i_size
, false);
284 /* TODO: Consider clearing page bits now for space the write isn't
285 * covering. This is more complicated than it appears when THPs are
286 * taken into account.
289 iov_iter_xarray(&iter
, ITER_SOURCE
, &mapping
->i_pages
, start
, len
);
290 fscache_write(cres
, start
, &iter
, fscache_wreq_done
, wreq
);
294 return fscache_wreq_done(wreq
, ret
, false);
298 fscache_clear_page_bits(mapping
, start
, len
, cond
);
300 term_func(term_func_priv
, ret
, false);
302 EXPORT_SYMBOL(__fscache_write_to_cache
);
305 * Change the size of a backing object.
307 void __fscache_resize_cookie(struct fscache_cookie
*cookie
, loff_t new_size
)
309 struct netfs_cache_resources cres
;
311 trace_fscache_resize(cookie
, new_size
);
312 if (fscache_begin_operation(&cres
, cookie
, FSCACHE_WANT_WRITE
,
313 fscache_access_io_resize
) == 0) {
314 fscache_stat(&fscache_n_resizes
);
315 set_bit(FSCACHE_COOKIE_NEEDS_UPDATE
, &cookie
->flags
);
317 /* We cannot defer a resize as we need to do it inside the
318 * netfs's inode lock so that we're serialised with respect to
321 cookie
->volume
->cache
->ops
->resize_cookie(&cres
, new_size
);
322 fscache_end_operation(&cres
);
324 fscache_stat(&fscache_n_resizes_null
);
327 EXPORT_SYMBOL(__fscache_resize_cookie
);