8
8
#include < algorithm>
9
9
#include < mutex>
10
10
11
+ #include < api/assert.h>
11
12
#include < osv/debug.h>
12
13
#include < osv/uio.h>
13
14
18
19
19
20
namespace virtiofs {
20
21
21
- int dax_manager::read (virtiofs_inode& inode, uint64_t file_handle, u64 read_amt,
22
- struct uio & uio, bool aggressive)
22
+ template <typename W>
23
+ int dax_manager<W>::read(virtiofs_inode& inode, uint64_t file_handle,
24
+ u64 read_amt, struct uio & uio, bool aggressive)
23
25
{
24
26
std::lock_guard<mutex> guard {_lock};
25
27
@@ -63,7 +65,7 @@ int dax_manager::read(virtiofs_inode& inode, uint64_t file_handle, u64 read_amt,
63
65
}
64
66
65
67
out:
66
- auto req_data = _window-> addr + (mp.mstart * _chunk_size) + coffset;
68
+ auto req_data = _window. data () + (mp.mstart * _chunk_size) + coffset;
67
69
auto read_amt_act = std::min<size_t >(read_amt,
68
70
(mp.nchunks * _chunk_size) - coffset);
69
71
// NOTE: It shouldn't be necessary to use the mmio* interface (i.e. volatile
@@ -76,7 +78,8 @@ int dax_manager::read(virtiofs_inode& inode, uint64_t file_handle, u64 read_amt,
76
78
return error;
77
79
}
78
80
79
- int dax_manager::map (uint64_t nodeid, uint64_t file_handle, chunk nchunks,
81
+ template <typename W>
82
+ int dax_manager<W>::map(uint64_t nodeid, uint64_t file_handle, chunk nchunks,
80
83
chunk fstart, mapping_part& mapped, bool evict)
81
84
{
82
85
// If necessary, unmap just enough chunks
@@ -99,7 +102,8 @@ int dax_manager::map(uint64_t nodeid, uint64_t file_handle, chunk nchunks,
99
102
100
103
// Map new chunks
101
104
auto mstart = _window_chunks - empty;
102
- auto error = map_ll (nodeid, file_handle, to_map, fstart, mstart);
105
+ auto error = _window.map (nodeid, file_handle, to_map * _chunk_size,
106
+ fstart * _chunk_size, mstart * _chunk_size);
103
107
if (error) {
104
108
return error;
105
109
}
@@ -119,7 +123,8 @@ int dax_manager::map(uint64_t nodeid, uint64_t file_handle, chunk nchunks,
119
123
return 0 ;
120
124
}
121
125
122
- int dax_manager::unmap (chunk nchunks, mapping_part& unmapped, bool deep)
126
+ template <typename W>
127
+ int dax_manager<W>::unmap(chunk nchunks, mapping_part& unmapped, bool deep)
123
128
{
124
129
// Determine necessary changes
125
130
chunk to_unmap = 0 ;
@@ -148,7 +153,8 @@ int dax_manager::unmap(chunk nchunks, mapping_part& unmapped, bool deep)
148
153
// Apply changes
149
154
if (deep) {
150
155
auto mstart = first_empty () - to_unmap;
151
- auto error = unmap_ll (to_unmap, mstart);
156
+ auto error = _window.unmap (to_unmap * _chunk_size,
157
+ mstart * _chunk_size);
152
158
if (error) {
153
159
return error;
154
160
}
@@ -163,10 +169,10 @@ int dax_manager::unmap(chunk nchunks, mapping_part& unmapped, bool deep)
163
169
return 0 ;
164
170
}
165
171
166
- int dax_manager::map_ll (uint64_t nodeid, uint64_t file_handle, chunk nchunks ,
167
- chunk fstart, chunk mstart)
172
+ int dax_window_impl::map (uint64_t nodeid, uint64_t fh, uint64_t len ,
173
+ uint64_t fstart, uint64_t mstart)
168
174
{
169
- assert (mstart + nchunks <= _window_chunks );
175
+ assert (mstart + len <= _window-> len );
170
176
171
177
// NOTE: There are restrictions on the arguments to FUSE_SETUPMAPPING, from
172
178
// the spec: "Alignment constraints for FUSE_SETUPMAPPING and
@@ -177,18 +183,18 @@ int dax_manager::map_ll(uint64_t nodeid, uint64_t file_handle, chunk nchunks,
177
183
// - moffset: multiple of map_alignment from FUSE_INIT
178
184
// In practice, map_alignment is the host's page size, because foffset and
179
185
// moffset are passed to mmap() on the host. These are satisfied by
180
- // _chunk_size being a multiple of map_alignment .
186
+ // the caller (chunk size being a multiple of map alignment in dax_manager) .
181
187
182
188
std::unique_ptr<fuse_setupmapping_in> in_args {
183
189
new (std::nothrow) fuse_setupmapping_in ()};
184
190
if (!in_args) {
185
191
return ENOMEM;
186
192
}
187
- in_args->fh = file_handle ;
188
- in_args->foffset = fstart * _chunk_size ;
189
- in_args->len = nchunks * _chunk_size ;
193
+ in_args->fh = fh ;
194
+ in_args->foffset = fstart;
195
+ in_args->len = len ;
190
196
in_args->flags = 0 ; // Read-only
191
- in_args->moffset = mstart * _chunk_size ;
197
+ in_args->moffset = mstart;
192
198
193
199
virtiofs_debug (" inode %lld, setting up mapping (foffset=%lld, len=%lld, "
194
200
" moffset=%lld)\n " , nodeid, in_args->foffset , in_args->len ,
@@ -203,9 +209,9 @@ int dax_manager::map_ll(uint64_t nodeid, uint64_t file_handle, chunk nchunks,
203
209
return 0 ;
204
210
}
205
211
206
- int dax_manager::unmap_ll (chunk nchunks, chunk mstart)
212
+ int dax_window_impl::unmap ( uint64_t len, uint64_t mstart)
207
213
{
208
- assert (mstart + nchunks <= _window_chunks );
214
+ assert (mstart + len <= _window-> len );
209
215
210
216
// NOTE: FUSE_REMOVEMAPPING accepts a fuse_removemapping_in followed by
211
217
// fuse_removemapping_in.count fuse_removemapping_one arguments in general.
@@ -219,8 +225,8 @@ int dax_manager::unmap_ll(chunk nchunks, chunk mstart)
219
225
auto r_one = new (in_args.get () + sizeof (fuse_removemapping_in))
220
226
fuse_removemapping_one ();
221
227
r_in->count = 1 ;
222
- r_one->moffset = mstart * _chunk_size ;
223
- r_one->len = nchunks * _chunk_size ;
228
+ r_one->moffset = mstart;
229
+ r_one->len = len ;
224
230
225
231
// The nodeid is irrelevant for the current implementation of
226
232
// FUSE_REMOVEMAPPING. If it needed to be set, would we need to make a
@@ -239,7 +245,9 @@ int dax_manager::unmap_ll(chunk nchunks, chunk mstart)
239
245
return 0 ;
240
246
}
241
247
242
- bool dax_manager::find (uint64_t nodeid, chunk fstart, mapping_part& found) const
248
+ template <typename W>
249
+ bool dax_manager<W>::find(uint64_t nodeid, chunk fstart, mapping_part& found)
250
+ const
243
251
{
244
252
for (auto & m : _mappings) {
245
253
if (m.nodeid == nodeid &&
@@ -256,7 +264,8 @@ bool dax_manager::find(uint64_t nodeid, chunk fstart, mapping_part& found) const
256
264
return false ;
257
265
}
258
266
259
- dax_manager::chunk dax_manager::first_empty () const
267
+ template <typename W>
268
+ typename dax_manager<W>::chunk dax_manager<W>::first_empty() const
260
269
{
261
270
if (_mappings.empty ()) {
262
271
return 0 ;
@@ -265,4 +274,8 @@ dax_manager::chunk dax_manager::first_empty() const
265
274
return m.mstart + m.nchunks ;
266
275
}
267
276
277
+ // Explicitly instantiate the only uses of dax_manager.
278
+ template class dax_manager <dax_window_impl>;
279
+ template class dax_manager <dax_window_stub>;
280
+
268
281
}
0 commit comments