1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* Single, monolithic object support (e.g. AFS directory).
3 *
4 * Copyright (C) 2024 Red Hat, Inc. All Rights Reserved.
5 * Written by David Howells (dhowells@redhat.com)
6 */
7
8 #include <linux/export.h>
9 #include <linux/fs.h>
10 #include <linux/mm.h>
11 #include <linux/pagemap.h>
12 #include <linux/slab.h>
13 #include <linux/uio.h>
14 #include <linux/sched/mm.h>
15 #include <linux/task_io_accounting_ops.h>
16 #include <linux/netfs.h>
17 #include "internal.h"
18
19 /**
20 * netfs_single_mark_inode_dirty - Mark a single, monolithic object inode dirty
21 * @inode: The inode to mark
22 *
23 * Mark an inode that contains a single, monolithic object as dirty so that its
24 * writepages op will get called. If set, the SINGLE_NO_UPLOAD flag indicates
25 * that the object will only be written to the cache and not uploaded (e.g. AFS
26 * directory contents).
27 */
netfs_single_mark_inode_dirty(struct inode * inode)28 void netfs_single_mark_inode_dirty(struct inode *inode)
29 {
30 struct netfs_inode *ictx = netfs_inode(inode);
31 bool cache_only = test_bit(NETFS_ICTX_SINGLE_NO_UPLOAD, &ictx->flags);
32 bool caching = fscache_cookie_enabled(netfs_i_cookie(netfs_inode(inode)));
33
34 if (cache_only && !caching)
35 return;
36
37 mark_inode_dirty(inode);
38
39 if (caching && !(inode_state_read_once(inode) & I_PINNING_NETFS_WB)) {
40 bool need_use = false;
41
42 spin_lock(&inode->i_lock);
43 if (!(inode_state_read(inode) & I_PINNING_NETFS_WB)) {
44 inode_state_set(inode, I_PINNING_NETFS_WB);
45 need_use = true;
46 }
47 spin_unlock(&inode->i_lock);
48
49 if (need_use)
50 fscache_use_cookie(netfs_i_cookie(ictx), true);
51 }
52
53 }
54 EXPORT_SYMBOL(netfs_single_mark_inode_dirty);
55
netfs_single_begin_cache_read(struct netfs_io_request * rreq,struct netfs_inode * ctx)56 static int netfs_single_begin_cache_read(struct netfs_io_request *rreq, struct netfs_inode *ctx)
57 {
58 return fscache_begin_read_operation(&rreq->cache_resources, netfs_i_cookie(ctx));
59 }
60
netfs_single_cache_prepare_read(struct netfs_io_request * rreq,struct netfs_io_subrequest * subreq)61 static void netfs_single_cache_prepare_read(struct netfs_io_request *rreq,
62 struct netfs_io_subrequest *subreq)
63 {
64 struct netfs_cache_resources *cres = &rreq->cache_resources;
65
66 if (!cres->ops) {
67 subreq->source = NETFS_DOWNLOAD_FROM_SERVER;
68 return;
69 }
70 subreq->source = cres->ops->prepare_read(subreq, rreq->i_size);
71 trace_netfs_sreq(subreq, netfs_sreq_trace_prepare);
72
73 }
74
netfs_single_read_cache(struct netfs_io_request * rreq,struct netfs_io_subrequest * subreq)75 static void netfs_single_read_cache(struct netfs_io_request *rreq,
76 struct netfs_io_subrequest *subreq)
77 {
78 struct netfs_cache_resources *cres = &rreq->cache_resources;
79
80 _enter("R=%08x[%x]", rreq->debug_id, subreq->debug_index);
81 netfs_stat(&netfs_n_rh_read);
82 cres->ops->read(cres, subreq->start, &subreq->io_iter, NETFS_READ_HOLE_FAIL,
83 netfs_cache_read_terminated, subreq);
84 }
85
86 /*
87 * Perform a read to a buffer from the cache or the server. Only a single
88 * subreq is permitted as the object must be fetched in a single transaction.
89 */
netfs_single_dispatch_read(struct netfs_io_request * rreq)90 static int netfs_single_dispatch_read(struct netfs_io_request *rreq)
91 {
92 struct netfs_io_subrequest *subreq;
93 int ret = 0;
94
95 subreq = netfs_alloc_subrequest(rreq);
96 if (!subreq)
97 return -ENOMEM;
98
99 subreq->source = NETFS_SOURCE_UNKNOWN;
100 subreq->start = 0;
101 subreq->len = rreq->len;
102 subreq->io_iter = rreq->buffer.iter;
103
104 netfs_queue_read(rreq, subreq);
105
106 netfs_single_cache_prepare_read(rreq, subreq);
107 switch (subreq->source) {
108 case NETFS_DOWNLOAD_FROM_SERVER:
109 netfs_stat(&netfs_n_rh_download);
110 if (rreq->netfs_ops->prepare_read) {
111 ret = rreq->netfs_ops->prepare_read(subreq);
112 if (ret < 0)
113 goto cancel;
114 }
115
116 smp_wmb(); /* Write lists before ALL_QUEUED. */
117 set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
118 rreq->netfs_ops->issue_read(subreq);
119 rreq->submitted += subreq->len;
120 break;
121 case NETFS_READ_FROM_CACHE:
122 smp_wmb(); /* Write lists before ALL_QUEUED. */
123 set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
124 trace_netfs_sreq(subreq, netfs_sreq_trace_submit);
125 netfs_single_read_cache(rreq, subreq);
126 rreq->submitted += subreq->len;
127 ret = 0;
128 break;
129 default:
130 pr_warn("Unexpected single-read source %u\n", subreq->source);
131 WARN_ON_ONCE(true);
132 ret = -EIO;
133 goto cancel;
134 }
135
136 return ret;
137 cancel:
138 netfs_cancel_read(subreq, ret);
139 smp_wmb(); /* Write lists before ALL_QUEUED. */
140 set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
141 netfs_wake_collector(rreq);
142 return ret;
143 }
144
145 /**
146 * netfs_read_single - Synchronously read a single blob of pages.
147 * @inode: The inode to read from.
148 * @file: The file we're using to read or NULL.
149 * @iter: The buffer we're reading into.
150 *
151 * Fulfil a read request for a single monolithic object by drawing data from
152 * the cache if possible, or the netfs if not. The buffer may be larger than
153 * the file content; unused beyond the EOF will be zero-filled. The content
154 * will be read with a single I/O request (though this may be retried).
155 *
156 * The calling netfs must initialise a netfs context contiguous to the vfs
157 * inode before calling this.
158 *
159 * This is usable whether or not caching is enabled. If caching is enabled,
160 * the data will be stored as a single object into the cache.
161 */
netfs_read_single(struct inode * inode,struct file * file,struct iov_iter * iter)162 ssize_t netfs_read_single(struct inode *inode, struct file *file, struct iov_iter *iter)
163 {
164 struct netfs_io_request *rreq;
165 struct netfs_inode *ictx = netfs_inode(inode);
166 ssize_t ret;
167
168 rreq = netfs_alloc_request(inode->i_mapping, file, 0, iov_iter_count(iter),
169 NETFS_READ_SINGLE);
170 if (IS_ERR(rreq))
171 return PTR_ERR(rreq);
172
173 ret = netfs_single_begin_cache_read(rreq, ictx);
174 if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS)
175 goto cleanup_free;
176
177 netfs_stat(&netfs_n_rh_read_single);
178 trace_netfs_read(rreq, 0, rreq->len, netfs_read_trace_read_single);
179
180 rreq->buffer.iter = *iter;
181 netfs_single_dispatch_read(rreq);
182
183 ret = netfs_wait_for_read(rreq);
184 netfs_put_request(rreq, netfs_rreq_trace_put_return);
185 return ret;
186
187 cleanup_free:
188 netfs_put_failed_request(rreq);
189 return ret;
190 }
191 EXPORT_SYMBOL(netfs_read_single);
192