Skip to content

Commit ee1235a

Browse files
committed
fscache: Pass object size in rather than calling back for it
Pass the object size in to fscache_acquire_cookie() and fscache_write_page() rather than the netfs providing a callback by which it can be received. This makes it easier to update the size of the object when a new page is written that extends the object. The current object size is also passed by fscache to the check_aux function, obviating the need to store it in the aux data. Signed-off-by: David Howells <dhowells@redhat.com> Acked-by: Anna Schumaker <anna.schumaker@netapp.com> Tested-by: Steve Dickson <steved@redhat.com>
1 parent 402cb8d commit ee1235a

File tree

21 files changed

+127
-166
lines changed

21 files changed

+127
-166
lines changed

Documentation/filesystems/caching/netfs-api.txt

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,10 @@ To define an object, a structure of the following type should be filled out:
129129
const void *parent_netfs_data,
130130
const void *cookie_netfs_data);
131131

132-
void (*get_attr)(const void *cookie_netfs_data,
133-
uint64_t *size);
134-
135132
enum fscache_checkaux (*check_aux)(void *cookie_netfs_data,
136133
const void *data,
137-
uint16_t datalen);
134+
uint16_t datalen,
135+
loff_t object_size);
138136

139137
void (*get_context)(void *cookie_netfs_data, void *context);
140138

@@ -179,16 +177,7 @@ This has the following fields:
179177
cache in the parent's list will be chosen, or failing that, the first
180178
cache in the master list.
181179

182-
(4) A function to retrieve attribute data from the netfs [optional].
183-
184-
This function will be called with the netfs data that was passed to the
185-
cookie acquisition function. It should return the size of the file if
186-
this is a data file. The size may be used to govern how much cache must
187-
be reserved for this file in the cache.
188-
189-
If the function is absent, a file size of 0 is assumed.
190-
191-
(5) A function to check the auxiliary data [optional].
180+
(4) A function to check the auxiliary data [optional].
192181

193182
This function will be called to check that a match found in the cache for
194183
this object is valid. For instance with AFS it could check the auxiliary
@@ -198,6 +187,9 @@ This has the following fields:
198187
If this function is absent, it will be assumed that matching objects in a
199188
cache are always valid.
200189

190+
The function is also passed the cache's idea of the object size and may
191+
use this to manage coherency also.
192+
201193
If present, the function should return one of the following values:
202194

203195
(*) FSCACHE_CHECKAUX_OKAY - the entry is okay as is
@@ -207,7 +199,7 @@ This has the following fields:
207199
This function can also be used to extract data from the auxiliary data in
208200
the cache and copy it into the netfs's structures.
209201

210-
(6) A pair of functions to manage contexts for the completion callback
202+
(5) A pair of functions to manage contexts for the completion callback
211203
[optional].
212204

213205
The cache read/write functions are passed a context which is then passed
@@ -221,7 +213,7 @@ This has the following fields:
221213
required for indices as indices may not contain data. These functions may
222214
be called in interrupt context and so may not sleep.
223215

224-
(7) A function to mark a page as retaining cache metadata [optional].
216+
(6) A function to mark a page as retaining cache metadata [optional].
225217

226218
This is called by the cache to indicate that it is retaining in-memory
227219
information for this page and that the netfs should uncache the page when
@@ -233,7 +225,7 @@ This has the following fields:
233225

234226
This function is not required for indices as they're not permitted data.
235227

236-
(8) A function to unmark all the pages retaining cache metadata [mandatory].
228+
(7) A function to unmark all the pages retaining cache metadata [mandatory].
237229

238230
This is called by FS-Cache to indicate that a backing store is being
239231
unbound from a cookie and that all the marks on the pages should be
@@ -310,6 +302,7 @@ the path to the file:
310302
const void *aux_data,
311303
size_t aux_data_len,
312304
void *netfs_data,
305+
loff_t object_size,
313306
bool enable);
314307

315308
This function creates an index entry in the index represented by parent,
@@ -326,6 +319,10 @@ The netfs may pass an arbitrary value in netfs_data and this will be presented
326319
to it in the event of any calling back. This may also be used in tracing or
327320
logging of messages.
328321

322+
The cache tracks the size of the data attached to an object and this set to be
323+
object_size. For indices, this should be 0. This value will be passed to the
324+
->check_aux() callback.
325+
329326
Note that this function never returns an error - all errors are handled
330327
internally. It may, however, return NULL to indicate no cookie. It is quite
331328
acceptable to pass this token back to this function as the parent to another
@@ -349,7 +346,7 @@ entry would have a dependent inode containing volume mappings within this cell:
349346
&afs_cell_cache_index_def,
350347
cell->name, strlen(cell->name),
351348
NULL, 0,
352-
cell, true);
349+
cell, 0, true);
353350

354351
And then a particular volume could be added to that index by ID, creating
355352
another index for vnodes (AFS inode equivalents):
@@ -359,7 +356,7 @@ another index for vnodes (AFS inode equivalents):
359356
&afs_volume_cache_index_def,
360357
&volume->vid, sizeof(volume->vid),
361358
NULL, 0,
362-
volume, true);
359+
volume, 0, true);
363360

364361

365362
======================
@@ -375,7 +372,7 @@ the object definition should be something other than index type.
375372
&afs_vnode_cache_object_def,
376373
&key, sizeof(key),
377374
&aux, sizeof(aux),
378-
vnode, true);
375+
vnode, vnode->status.size, true);
379376

380377

381378
=================================
@@ -393,7 +390,7 @@ it would be some other type of object such as a data file.
393390
&afs_xattr_cache_object_def,
394391
&xattr->name, strlen(xattr->name),
395392
NULL, 0,
396-
xattr, true);
393+
xattr, strlen(xattr->val), true);
397394

398395
Miscellaneous objects might be used to store extended attributes or directory
399396
entries for example.
@@ -410,8 +407,7 @@ cache to adjust its metadata for data tracking appropriately:
410407
int fscache_attr_changed(struct fscache_cookie *cookie);
411408

412409
The cache will return -ENOBUFS if there is no backing cache or if there is no
413-
space to allocate any extra metadata required in the cache. The attributes
414-
will be accessed with the get_attr() cookie definition operation.
410+
space to allocate any extra metadata required in the cache.
415411

416412
Note that attempts to read or write data pages in the cache over this size may
417413
be rebuffed with -ENOBUFS.
@@ -536,12 +532,13 @@ written back to the cache:
536532

537533
int fscache_write_page(struct fscache_cookie *cookie,
538534
struct page *page,
535+
loff_t object_size,
539536
gfp_t gfp);
540537

541538
The cookie argument must specify a data file cookie, the page specified should
542539
contain the data to be written (and is also used to specify the page number),
543-
and the gfp argument is used to control how any memory allocations made are
544-
satisfied.
540+
object_size is the revised size of the object and the gfp argument is used to
541+
control how any memory allocations made are satisfied.
545542

546543
The page must have first been read or allocated successfully and must not have
547544
been uncached before writing is performed.
@@ -735,11 +732,11 @@ still possible to uncache pages and relinquish the cookie.
735732

736733
The initial enablement state is set by fscache_acquire_cookie(), but the cookie
737734
can be enabled or disabled later. To disable a cookie, call:
738-
735+
739736
void fscache_disable_cookie(struct fscache_cookie *cookie,
740737
const void *aux_data,
741738
bool invalidate);
742-
739+
743740
If the cookie is not already disabled, this locks the cookie against other
744741
enable and disable ops, marks the cookie as being disabled, discards or
745742
invalidates any backing objects and waits for cessation of activity on any
@@ -748,14 +745,15 @@ associated object before unlocking the cookie.
748745
All possible failures are handled internally. The caller should consider
749746
calling fscache_uncache_all_inode_pages() afterwards to make sure all page
750747
markings are cleared up.
751-
748+
752749
Cookies can be enabled or reenabled with:
753-
750+
754751
void fscache_enable_cookie(struct fscache_cookie *cookie,
755752
const void *aux_data,
753+
loff_t object_size,
756754
bool (*can_enable)(void *data),
757755
void *data)
758-
756+
759757
If the cookie is not already enabled, this locks the cookie against other
760758
enable and disable ops, invokes can_enable() and, if the cookie is not an index
761759
cookie, will begin the procedure of acquiring backing objects.
@@ -766,6 +764,9 @@ ruling as to whether or not enablement should actually be permitted to begin.
766764
All possible failures are handled internally. The cookie will only be marked
767765
as enabled if provisional backing objects are allocated.
768766

767+
The object's data size is updated from object_size and is passed to the
768+
->check_aux() function.
769+
769770
In both cases, the cookie's auxiliary data buffer is updated from aux_data if
770771
that is non-NULL inside the enablement lock before proceeding.
771772

fs/9p/cache.c

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ void v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses)
7575
v9ses->cachetag,
7676
strlen(v9ses->cachetag),
7777
NULL, 0,
78-
v9ses, true);
78+
v9ses, 0, true);
7979
p9_debug(P9_DEBUG_FSC, "session %p get cookie %p\n",
8080
v9ses, v9ses->fscache);
8181
}
@@ -88,20 +88,11 @@ void v9fs_cache_session_put_cookie(struct v9fs_session_info *v9ses)
8888
v9ses->fscache = NULL;
8989
}
9090

91-
static void v9fs_cache_inode_get_attr(const void *cookie_netfs_data,
92-
uint64_t *size)
93-
{
94-
const struct v9fs_inode *v9inode = cookie_netfs_data;
95-
*size = i_size_read(&v9inode->vfs_inode);
96-
97-
p9_debug(P9_DEBUG_FSC, "inode %p get attr %llu\n",
98-
&v9inode->vfs_inode, *size);
99-
}
100-
10191
static enum
10292
fscache_checkaux v9fs_cache_inode_check_aux(void *cookie_netfs_data,
10393
const void *buffer,
104-
uint16_t buflen)
94+
uint16_t buflen,
95+
loff_t object_size)
10596
{
10697
const struct v9fs_inode *v9inode = cookie_netfs_data;
10798

@@ -118,7 +109,6 @@ fscache_checkaux v9fs_cache_inode_check_aux(void *cookie_netfs_data,
118109
const struct fscache_cookie_def v9fs_cache_inode_index_def = {
119110
.name = "9p.inode",
120111
.type = FSCACHE_COOKIE_TYPE_DATAFILE,
121-
.get_attr = v9fs_cache_inode_get_attr,
122112
.check_aux = v9fs_cache_inode_check_aux,
123113
};
124114

@@ -141,7 +131,9 @@ void v9fs_cache_inode_get_cookie(struct inode *inode)
141131
sizeof(v9inode->qid.path),
142132
&v9inode->qid.version,
143133
sizeof(v9inode->qid.version),
144-
v9inode, true);
134+
v9inode,
135+
i_size_read(&v9inode->vfs_inode),
136+
true);
145137

146138
p9_debug(P9_DEBUG_FSC, "inode %p get cookie %p\n",
147139
inode, v9inode->fscache);
@@ -212,7 +204,9 @@ void v9fs_cache_inode_reset_cookie(struct inode *inode)
212204
sizeof(v9inode->qid.path),
213205
&v9inode->qid.version,
214206
sizeof(v9inode->qid.version),
215-
v9inode, true);
207+
v9inode,
208+
i_size_read(&v9inode->vfs_inode),
209+
true);
216210
p9_debug(P9_DEBUG_FSC, "inode %p revalidating cookie old %p new %p\n",
217211
inode, old, v9inode->fscache);
218212

@@ -338,7 +332,8 @@ void __v9fs_readpage_to_fscache(struct inode *inode, struct page *page)
338332
const struct v9fs_inode *v9inode = V9FS_I(inode);
339333

340334
p9_debug(P9_DEBUG_FSC, "inode %p page %p\n", inode, page);
341-
ret = fscache_write_page(v9inode->fscache, page, GFP_KERNEL);
335+
ret = fscache_write_page(v9inode->fscache, page,
336+
i_size_read(&v9inode->vfs_inode), GFP_KERNEL);
342337
p9_debug(P9_DEBUG_FSC, "ret = %d\n", ret);
343338
if (ret != 0)
344339
v9fs_uncache_page(inode, page);

fs/afs/cache.c

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,10 @@
1212
#include <linux/sched.h>
1313
#include "internal.h"
1414

15-
static void afs_vnode_cache_get_attr(const void *cookie_netfs_data,
16-
uint64_t *size);
1715
static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data,
1816
const void *buffer,
19-
uint16_t buflen);
17+
uint16_t buflen,
18+
loff_t object_size);
2019

2120
struct fscache_netfs afs_cache_netfs = {
2221
.name = "afs",
@@ -36,31 +35,16 @@ struct fscache_cookie_def afs_volume_cache_index_def = {
3635
struct fscache_cookie_def afs_vnode_cache_index_def = {
3736
.name = "AFS.vnode",
3837
.type = FSCACHE_COOKIE_TYPE_DATAFILE,
39-
.get_attr = afs_vnode_cache_get_attr,
4038
.check_aux = afs_vnode_cache_check_aux,
4139
};
4240

43-
/*
44-
* provide updated file attributes
45-
*/
46-
static void afs_vnode_cache_get_attr(const void *cookie_netfs_data,
47-
uint64_t *size)
48-
{
49-
const struct afs_vnode *vnode = cookie_netfs_data;
50-
51-
_enter("{%x,%x,%llx},",
52-
vnode->fid.vnode, vnode->fid.unique,
53-
vnode->status.data_version);
54-
55-
*size = vnode->status.size;
56-
}
57-
5841
/*
5942
* check that the auxiliary data indicates that the entry is still valid
6043
*/
6144
static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data,
6245
const void *buffer,
63-
uint16_t buflen)
46+
uint16_t buflen,
47+
loff_t object_size)
6448
{
6549
struct afs_vnode *vnode = cookie_netfs_data;
6650
struct afs_vnode_cache_aux aux;

fs/afs/cell.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@ static int afs_activate_cell(struct afs_net *net, struct afs_cell *cell)
524524
&afs_cell_cache_index_def,
525525
cell->name, strlen(cell->name),
526526
NULL, 0,
527-
cell, true);
527+
cell, 0, true);
528528
#endif
529529
ret = afs_proc_cell_setup(net, cell);
530530
if (ret < 0)

fs/afs/file.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,8 @@ int afs_page_filler(void *data, struct page *page)
339339
/* send the page to the cache */
340340
#ifdef CONFIG_AFS_FSCACHE
341341
if (PageFsCache(page) &&
342-
fscache_write_page(vnode->cache, page, GFP_KERNEL) != 0) {
342+
fscache_write_page(vnode->cache, page, vnode->status.size,
343+
GFP_KERNEL) != 0) {
343344
fscache_uncache_page(vnode->cache, page);
344345
BUG_ON(PageFsCache(page));
345346
}
@@ -403,7 +404,8 @@ static void afs_readpages_page_done(struct afs_call *call, struct afs_read *req)
403404
/* send the page to the cache */
404405
#ifdef CONFIG_AFS_FSCACHE
405406
if (PageFsCache(page) &&
406-
fscache_write_page(vnode->cache, page, GFP_KERNEL) != 0) {
407+
fscache_write_page(vnode->cache, page, vnode->status.size,
408+
GFP_KERNEL) != 0) {
407409
fscache_uncache_page(vnode->cache, page);
408410
BUG_ON(PageFsCache(page));
409411
}

fs/afs/inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ static void afs_get_inode_cache(struct afs_vnode *vnode)
265265
&afs_vnode_cache_index_def,
266266
&key, sizeof(key),
267267
&aux, sizeof(aux),
268-
vnode, true);
268+
vnode, vnode->status.size, true);
269269
#endif
270270
}
271271

fs/afs/volume.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ void afs_activate_volume(struct afs_volume *volume)
227227
&afs_volume_cache_index_def,
228228
&volume->vid, sizeof(volume->vid),
229229
NULL, 0,
230-
volume, true);
230+
volume, 0, true);
231231
#endif
232232

233233
write_lock(&volume->cell->proc_lock);

fs/cachefiles/interface.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ static int cachefiles_attr_changed(struct fscache_object *_object)
441441
loff_t oi_size;
442442
int ret;
443443

444-
_object->cookie->def->get_attr(_object->cookie->netfs_data, &ni_size);
444+
ni_size = _object->store_limit_l;
445445

446446
_enter("{OBJ%x},[%llu]",
447447
_object->debug_id, (unsigned long long) ni_size);
@@ -513,8 +513,7 @@ static void cachefiles_invalidate_object(struct fscache_operation *op)
513513
cache = container_of(object->fscache.cache,
514514
struct cachefiles_cache, cache);
515515

516-
op->object->cookie->def->get_attr(op->object->cookie->netfs_data,
517-
&ni_size);
516+
ni_size = op->object->store_limit_l;
518517

519518
_enter("{OBJ%x},[%llu]",
520519
op->object->debug_id, (unsigned long long)ni_size);

fs/cachefiles/xattr.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,8 @@ int cachefiles_check_auxdata(struct cachefiles_object *object)
182182
goto error;
183183

184184
xlen--;
185-
validity = fscache_check_aux(&object->fscache, &auxbuf->data, xlen);
185+
validity = fscache_check_aux(&object->fscache, &auxbuf->data, xlen,
186+
i_size_read(d_backing_inode(dentry)));
186187
if (validity != FSCACHE_CHECKAUX_OKAY)
187188
goto error;
188189

@@ -251,7 +252,8 @@ int cachefiles_check_object_xattr(struct cachefiles_object *object,
251252
object->fscache.cookie->def->name, dlen);
252253

253254
result = fscache_check_aux(&object->fscache,
254-
&auxbuf->data, dlen);
255+
&auxbuf->data, dlen,
256+
i_size_read(d_backing_inode(dentry)));
255257

256258
switch (result) {
257259
/* entry okay as is */

0 commit comments

Comments
 (0)