summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2018-04-04 08:41:28 -0400
committerDavid Howells <dhowells@redhat.com>2018-04-06 09:05:14 -0400
commitee1235a9a06813429c201bf186397a6feeea07bf (patch)
tree444566605bfafce0b155a76e061a73c264329424
parent402cb8dda949d9b8c0df20ad2527d139faad7ca1 (diff)
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>
-rw-r--r--Documentation/filesystems/caching/netfs-api.txt61
-rw-r--r--fs/9p/cache.c27
-rw-r--r--fs/afs/cache.c24
-rw-r--r--fs/afs/cell.c2
-rw-r--r--fs/afs/file.c6
-rw-r--r--fs/afs/inode.c2
-rw-r--r--fs/afs/volume.c2
-rw-r--r--fs/cachefiles/interface.c5
-rw-r--r--fs/cachefiles/xattr.c6
-rw-r--r--fs/ceph/cache.c26
-rw-r--r--fs/cifs/cache.c15
-rw-r--r--fs/cifs/fscache.c14
-rw-r--r--fs/fscache/cookie.c18
-rw-r--r--fs/fscache/fsdef.c6
-rw-r--r--fs/fscache/object.c5
-rw-r--r--fs/fscache/page.c5
-rw-r--r--fs/nfs/fscache-index.c19
-rw-r--r--fs/nfs/fscache.c14
-rw-r--r--fs/nfs/fscache.h1
-rw-r--r--include/linux/fscache-cache.h3
-rw-r--r--include/linux/fscache.h32
21 files changed, 127 insertions, 166 deletions
diff --git a/Documentation/filesystems/caching/netfs-api.txt b/Documentation/filesystems/caching/netfs-api.txt
index 332840ad4151..2a6f7399c1f3 100644
--- a/Documentation/filesystems/caching/netfs-api.txt
+++ b/Documentation/filesystems/caching/netfs-api.txt
@@ -129,12 +129,10 @@ To define an object, a structure of the following type should be filled out:
129 const void *parent_netfs_data, 129 const void *parent_netfs_data,
130 const void *cookie_netfs_data); 130 const void *cookie_netfs_data);
131 131
132 void (*get_attr)(const void *cookie_netfs_data,
133 uint64_t *size);
134
135 enum fscache_checkaux (*check_aux)(void *cookie_netfs_data, 132 enum fscache_checkaux (*check_aux)(void *cookie_netfs_data,
136 const void *data, 133 const void *data,
137 uint16_t datalen); 134 uint16_t datalen,
135 loff_t object_size);
138 136
139 void (*get_context)(void *cookie_netfs_data, void *context); 137 void (*get_context)(void *cookie_netfs_data, void *context);
140 138
@@ -179,16 +177,7 @@ This has the following fields:
179 cache in the parent's list will be chosen, or failing that, the first 177 cache in the parent's list will be chosen, or failing that, the first
180 cache in the master list. 178 cache in the master list.
181 179
182 (4) A function to retrieve attribute data from the netfs [optional]. 180 (4) A function to check the auxiliary data [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].
192 181
193 This function will be called to check that a match found in the cache for 182 This function will be called to check that a match found in the cache for
194 this object is valid. For instance with AFS it could check the auxiliary 183 this object is valid. For instance with AFS it could check the auxiliary
@@ -198,6 +187,9 @@ This has the following fields:
198 If this function is absent, it will be assumed that matching objects in a 187 If this function is absent, it will be assumed that matching objects in a
199 cache are always valid. 188 cache are always valid.
200 189
190 The function is also passed the cache's idea of the object size and may
191 use this to manage coherency also.
192
201 If present, the function should return one of the following values: 193 If present, the function should return one of the following values:
202 194
203 (*) FSCACHE_CHECKAUX_OKAY - the entry is okay as is 195 (*) FSCACHE_CHECKAUX_OKAY - the entry is okay as is
@@ -207,7 +199,7 @@ This has the following fields:
207 This function can also be used to extract data from the auxiliary data in 199 This function can also be used to extract data from the auxiliary data in
208 the cache and copy it into the netfs's structures. 200 the cache and copy it into the netfs's structures.
209 201
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
211 [optional]. 203 [optional].
212 204
213 The cache read/write functions are passed a context which is then passed 205 The cache read/write functions are passed a context which is then passed
@@ -221,7 +213,7 @@ This has the following fields:
221 required for indices as indices may not contain data. These functions may 213 required for indices as indices may not contain data. These functions may
222 be called in interrupt context and so may not sleep. 214 be called in interrupt context and so may not sleep.
223 215
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].
225 217
226 This is called by the cache to indicate that it is retaining in-memory 218 This is called by the cache to indicate that it is retaining in-memory
227 information for this page and that the netfs should uncache the page when 219 information for this page and that the netfs should uncache the page when
@@ -233,7 +225,7 @@ This has the following fields:
233 225
234 This function is not required for indices as they're not permitted data. 226 This function is not required for indices as they're not permitted data.
235 227
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].
237 229
238 This is called by FS-Cache to indicate that a backing store is being 230 This is called by FS-Cache to indicate that a backing store is being
239 unbound from a cookie and that all the marks on the pages should be 231 unbound from a cookie and that all the marks on the pages should be
@@ -310,6 +302,7 @@ the path to the file:
310 const void *aux_data, 302 const void *aux_data,
311 size_t aux_data_len, 303 size_t aux_data_len,
312 void *netfs_data, 304 void *netfs_data,
305 loff_t object_size,
313 bool enable); 306 bool enable);
314 307
315This function creates an index entry in the index represented by parent, 308This 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
326to it in the event of any calling back. This may also be used in tracing or 319to it in the event of any calling back. This may also be used in tracing or
327logging of messages. 320logging of messages.
328 321
322The cache tracks the size of the data attached to an object and this set to be
323object_size. For indices, this should be 0. This value will be passed to the
324->check_aux() callback.
325
329Note that this function never returns an error - all errors are handled 326Note that this function never returns an error - all errors are handled
330internally. It may, however, return NULL to indicate no cookie. It is quite 327internally. It may, however, return NULL to indicate no cookie. It is quite
331acceptable to pass this token back to this function as the parent to another 328acceptable 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:
349 &afs_cell_cache_index_def, 346 &afs_cell_cache_index_def,
350 cell->name, strlen(cell->name), 347 cell->name, strlen(cell->name),
351 NULL, 0, 348 NULL, 0,
352 cell, true); 349 cell, 0, true);
353 350
354And then a particular volume could be added to that index by ID, creating 351And then a particular volume could be added to that index by ID, creating
355another index for vnodes (AFS inode equivalents): 352another index for vnodes (AFS inode equivalents):
@@ -359,7 +356,7 @@ another index for vnodes (AFS inode equivalents):
359 &afs_volume_cache_index_def, 356 &afs_volume_cache_index_def,
360 &volume->vid, sizeof(volume->vid), 357 &volume->vid, sizeof(volume->vid),
361 NULL, 0, 358 NULL, 0,
362 volume, true); 359 volume, 0, true);
363 360
364 361
365====================== 362======================
@@ -375,7 +372,7 @@ the object definition should be something other than index type.
375 &afs_vnode_cache_object_def, 372 &afs_vnode_cache_object_def,
376 &key, sizeof(key), 373 &key, sizeof(key),
377 &aux, sizeof(aux), 374 &aux, sizeof(aux),
378 vnode, true); 375 vnode, vnode->status.size, true);
379 376
380 377
381================================= 378=================================
@@ -393,7 +390,7 @@ it would be some other type of object such as a data file.
393 &afs_xattr_cache_object_def, 390 &afs_xattr_cache_object_def,
394 &xattr->name, strlen(xattr->name), 391 &xattr->name, strlen(xattr->name),
395 NULL, 0, 392 NULL, 0,
396 xattr, true); 393 xattr, strlen(xattr->val), true);
397 394
398Miscellaneous objects might be used to store extended attributes or directory 395Miscellaneous objects might be used to store extended attributes or directory
399entries for example. 396entries for example.
@@ -410,8 +407,7 @@ cache to adjust its metadata for data tracking appropriately:
410 int fscache_attr_changed(struct fscache_cookie *cookie); 407 int fscache_attr_changed(struct fscache_cookie *cookie);
411 408
412The cache will return -ENOBUFS if there is no backing cache or if there is no 409The cache will return -ENOBUFS if there is no backing cache or if there is no
413space to allocate any extra metadata required in the cache. The attributes 410space to allocate any extra metadata required in the cache.
414will be accessed with the get_attr() cookie definition operation.
415 411
416Note that attempts to read or write data pages in the cache over this size may 412Note that attempts to read or write data pages in the cache over this size may
417be rebuffed with -ENOBUFS. 413be rebuffed with -ENOBUFS.
@@ -536,12 +532,13 @@ written back to the cache:
536 532
537 int fscache_write_page(struct fscache_cookie *cookie, 533 int fscache_write_page(struct fscache_cookie *cookie,
538 struct page *page, 534 struct page *page,
535 loff_t object_size,
539 gfp_t gfp); 536 gfp_t gfp);
540 537
541The cookie argument must specify a data file cookie, the page specified should 538The cookie argument must specify a data file cookie, the page specified should
542contain the data to be written (and is also used to specify the page number), 539contain the data to be written (and is also used to specify the page number),
543and the gfp argument is used to control how any memory allocations made are 540object_size is the revised size of the object and the gfp argument is used to
544satisfied. 541control how any memory allocations made are satisfied.
545 542
546The page must have first been read or allocated successfully and must not have 543The page must have first been read or allocated successfully and must not have
547been uncached before writing is performed. 544been uncached before writing is performed.
@@ -735,11 +732,11 @@ still possible to uncache pages and relinquish the cookie.
735 732
736The initial enablement state is set by fscache_acquire_cookie(), but the cookie 733The initial enablement state is set by fscache_acquire_cookie(), but the cookie
737can be enabled or disabled later. To disable a cookie, call: 734can be enabled or disabled later. To disable a cookie, call:
738 735
739 void fscache_disable_cookie(struct fscache_cookie *cookie, 736 void fscache_disable_cookie(struct fscache_cookie *cookie,
740 const void *aux_data, 737 const void *aux_data,
741 bool invalidate); 738 bool invalidate);
742 739
743If the cookie is not already disabled, this locks the cookie against other 740If the cookie is not already disabled, this locks the cookie against other
744enable and disable ops, marks the cookie as being disabled, discards or 741enable and disable ops, marks the cookie as being disabled, discards or
745invalidates any backing objects and waits for cessation of activity on any 742invalidates any backing objects and waits for cessation of activity on any
@@ -748,14 +745,15 @@ associated object before unlocking the cookie.
748All possible failures are handled internally. The caller should consider 745All possible failures are handled internally. The caller should consider
749calling fscache_uncache_all_inode_pages() afterwards to make sure all page 746calling fscache_uncache_all_inode_pages() afterwards to make sure all page
750markings are cleared up. 747markings are cleared up.
751 748
752Cookies can be enabled or reenabled with: 749Cookies can be enabled or reenabled with:
753 750
754 void fscache_enable_cookie(struct fscache_cookie *cookie, 751 void fscache_enable_cookie(struct fscache_cookie *cookie,
755 const void *aux_data, 752 const void *aux_data,
753 loff_t object_size,
756 bool (*can_enable)(void *data), 754 bool (*can_enable)(void *data),
757 void *data) 755 void *data)
758 756
759If the cookie is not already enabled, this locks the cookie against other 757If the cookie is not already enabled, this locks the cookie against other
760enable and disable ops, invokes can_enable() and, if the cookie is not an index 758enable and disable ops, invokes can_enable() and, if the cookie is not an index
761cookie, will begin the procedure of acquiring backing objects. 759cookie, 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.
766All possible failures are handled internally. The cookie will only be marked 764All possible failures are handled internally. The cookie will only be marked
767as enabled if provisional backing objects are allocated. 765as enabled if provisional backing objects are allocated.
768 766
767The object's data size is updated from object_size and is passed to the
768->check_aux() function.
769
769In both cases, the cookie's auxiliary data buffer is updated from aux_data if 770In both cases, the cookie's auxiliary data buffer is updated from aux_data if
770that is non-NULL inside the enablement lock before proceeding. 771that is non-NULL inside the enablement lock before proceeding.
771 772
diff --git a/fs/9p/cache.c b/fs/9p/cache.c
index 9d0030af5672..9eb34701a566 100644
--- a/fs/9p/cache.c
+++ b/fs/9p/cache.c
@@ -75,7 +75,7 @@ void v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses)
75 v9ses->cachetag, 75 v9ses->cachetag,
76 strlen(v9ses->cachetag), 76 strlen(v9ses->cachetag),
77 NULL, 0, 77 NULL, 0,
78 v9ses, true); 78 v9ses, 0, true);
79 p9_debug(P9_DEBUG_FSC, "session %p get cookie %p\n", 79 p9_debug(P9_DEBUG_FSC, "session %p get cookie %p\n",
80 v9ses, v9ses->fscache); 80 v9ses, v9ses->fscache);
81} 81}
@@ -88,20 +88,11 @@ void v9fs_cache_session_put_cookie(struct v9fs_session_info *v9ses)
88 v9ses->fscache = NULL; 88 v9ses->fscache = NULL;
89} 89}
90 90
91static 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
101static enum 91static enum
102fscache_checkaux v9fs_cache_inode_check_aux(void *cookie_netfs_data, 92fscache_checkaux v9fs_cache_inode_check_aux(void *cookie_netfs_data,
103 const void *buffer, 93 const void *buffer,
104 uint16_t buflen) 94 uint16_t buflen,
95 loff_t object_size)
105{ 96{
106 const struct v9fs_inode *v9inode = cookie_netfs_data; 97 const struct v9fs_inode *v9inode = cookie_netfs_data;
107 98
@@ -118,7 +109,6 @@ fscache_checkaux v9fs_cache_inode_check_aux(void *cookie_netfs_data,
118const struct fscache_cookie_def v9fs_cache_inode_index_def = { 109const struct fscache_cookie_def v9fs_cache_inode_index_def = {
119 .name = "9p.inode", 110 .name = "9p.inode",
120 .type = FSCACHE_COOKIE_TYPE_DATAFILE, 111 .type = FSCACHE_COOKIE_TYPE_DATAFILE,
121 .get_attr = v9fs_cache_inode_get_attr,
122 .check_aux = v9fs_cache_inode_check_aux, 112 .check_aux = v9fs_cache_inode_check_aux,
123}; 113};
124 114
@@ -141,7 +131,9 @@ void v9fs_cache_inode_get_cookie(struct inode *inode)
141 sizeof(v9inode->qid.path), 131 sizeof(v9inode->qid.path),
142 &v9inode->qid.version, 132 &v9inode->qid.version,
143 sizeof(v9inode->qid.version), 133 sizeof(v9inode->qid.version),
144 v9inode, true); 134 v9inode,
135 i_size_read(&v9inode->vfs_inode),
136 true);
145 137
146 p9_debug(P9_DEBUG_FSC, "inode %p get cookie %p\n", 138 p9_debug(P9_DEBUG_FSC, "inode %p get cookie %p\n",
147 inode, v9inode->fscache); 139 inode, v9inode->fscache);
@@ -212,7 +204,9 @@ void v9fs_cache_inode_reset_cookie(struct inode *inode)
212 sizeof(v9inode->qid.path), 204 sizeof(v9inode->qid.path),
213 &v9inode->qid.version, 205 &v9inode->qid.version,
214 sizeof(v9inode->qid.version), 206 sizeof(v9inode->qid.version),
215 v9inode, true); 207 v9inode,
208 i_size_read(&v9inode->vfs_inode),
209 true);
216 p9_debug(P9_DEBUG_FSC, "inode %p revalidating cookie old %p new %p\n", 210 p9_debug(P9_DEBUG_FSC, "inode %p revalidating cookie old %p new %p\n",
217 inode, old, v9inode->fscache); 211 inode, old, v9inode->fscache);
218 212
@@ -338,7 +332,8 @@ void __v9fs_readpage_to_fscache(struct inode *inode, struct page *page)
338 const struct v9fs_inode *v9inode = V9FS_I(inode); 332 const struct v9fs_inode *v9inode = V9FS_I(inode);
339 333
340 p9_debug(P9_DEBUG_FSC, "inode %p page %p\n", inode, page); 334 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);
342 p9_debug(P9_DEBUG_FSC, "ret = %d\n", ret); 337 p9_debug(P9_DEBUG_FSC, "ret = %d\n", ret);
343 if (ret != 0) 338 if (ret != 0)
344 v9fs_uncache_page(inode, page); 339 v9fs_uncache_page(inode, page);
diff --git a/fs/afs/cache.c b/fs/afs/cache.c
index a16f1e024cf3..b1c31ec4523a 100644
--- a/fs/afs/cache.c
+++ b/fs/afs/cache.c
@@ -12,11 +12,10 @@
12#include <linux/sched.h> 12#include <linux/sched.h>
13#include "internal.h" 13#include "internal.h"
14 14
15static void afs_vnode_cache_get_attr(const void *cookie_netfs_data,
16 uint64_t *size);
17static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data, 15static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data,
18 const void *buffer, 16 const void *buffer,
19 uint16_t buflen); 17 uint16_t buflen,
18 loff_t object_size);
20 19
21struct fscache_netfs afs_cache_netfs = { 20struct fscache_netfs afs_cache_netfs = {
22 .name = "afs", 21 .name = "afs",
@@ -36,31 +35,16 @@ struct fscache_cookie_def afs_volume_cache_index_def = {
36struct fscache_cookie_def afs_vnode_cache_index_def = { 35struct fscache_cookie_def afs_vnode_cache_index_def = {
37 .name = "AFS.vnode", 36 .name = "AFS.vnode",
38 .type = FSCACHE_COOKIE_TYPE_DATAFILE, 37 .type = FSCACHE_COOKIE_TYPE_DATAFILE,
39 .get_attr = afs_vnode_cache_get_attr,
40 .check_aux = afs_vnode_cache_check_aux, 38 .check_aux = afs_vnode_cache_check_aux,
41}; 39};
42 40
43/* 41/*
44 * provide updated file attributes
45 */
46static 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
58/*
59 * check that the auxiliary data indicates that the entry is still valid 42 * check that the auxiliary data indicates that the entry is still valid
60 */ 43 */
61static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data, 44static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data,
62 const void *buffer, 45 const void *buffer,
63 uint16_t buflen) 46 uint16_t buflen,
47 loff_t object_size)
64{ 48{
65 struct afs_vnode *vnode = cookie_netfs_data; 49 struct afs_vnode *vnode = cookie_netfs_data;
66 struct afs_vnode_cache_aux aux; 50 struct afs_vnode_cache_aux aux;
diff --git a/fs/afs/cell.c b/fs/afs/cell.c
index 0747460221cb..4235a05afc76 100644
--- a/fs/afs/cell.c
+++ b/fs/afs/cell.c
@@ -524,7 +524,7 @@ static int afs_activate_cell(struct afs_net *net, struct afs_cell *cell)
524 &afs_cell_cache_index_def, 524 &afs_cell_cache_index_def,
525 cell->name, strlen(cell->name), 525 cell->name, strlen(cell->name),
526 NULL, 0, 526 NULL, 0,
527 cell, true); 527 cell, 0, true);
528#endif 528#endif
529 ret = afs_proc_cell_setup(net, cell); 529 ret = afs_proc_cell_setup(net, cell);
530 if (ret < 0) 530 if (ret < 0)
diff --git a/fs/afs/file.c b/fs/afs/file.c
index a39192ced99e..79e665a35fea 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -339,7 +339,8 @@ int afs_page_filler(void *data, struct page *page)
339 /* send the page to the cache */ 339 /* send the page to the cache */
340#ifdef CONFIG_AFS_FSCACHE 340#ifdef CONFIG_AFS_FSCACHE
341 if (PageFsCache(page) && 341 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) {
343 fscache_uncache_page(vnode->cache, page); 344 fscache_uncache_page(vnode->cache, page);
344 BUG_ON(PageFsCache(page)); 345 BUG_ON(PageFsCache(page));
345 } 346 }
@@ -403,7 +404,8 @@ static void afs_readpages_page_done(struct afs_call *call, struct afs_read *req)
403 /* send the page to the cache */ 404 /* send the page to the cache */
404#ifdef CONFIG_AFS_FSCACHE 405#ifdef CONFIG_AFS_FSCACHE
405 if (PageFsCache(page) && 406 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) {
407 fscache_uncache_page(vnode->cache, page); 409 fscache_uncache_page(vnode->cache, page);
408 BUG_ON(PageFsCache(page)); 410 BUG_ON(PageFsCache(page));
409 } 411 }
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index e499713efd2e..65c5b1edd338 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -265,7 +265,7 @@ static void afs_get_inode_cache(struct afs_vnode *vnode)
265 &afs_vnode_cache_index_def, 265 &afs_vnode_cache_index_def,
266 &key, sizeof(key), 266 &key, sizeof(key),
267 &aux, sizeof(aux), 267 &aux, sizeof(aux),
268 vnode, true); 268 vnode, vnode->status.size, true);
269#endif 269#endif
270} 270}
271 271
diff --git a/fs/afs/volume.c b/fs/afs/volume.c
index 345cb2d675d2..3037bd01f617 100644
--- a/fs/afs/volume.c
+++ b/fs/afs/volume.c
@@ -227,7 +227,7 @@ void afs_activate_volume(struct afs_volume *volume)
227 &afs_volume_cache_index_def, 227 &afs_volume_cache_index_def,
228 &volume->vid, sizeof(volume->vid), 228 &volume->vid, sizeof(volume->vid),
229 NULL, 0, 229 NULL, 0,
230 volume, true); 230 volume, 0, true);
231#endif 231#endif
232 232
233 write_lock(&volume->cell->proc_lock); 233 write_lock(&volume->cell->proc_lock);
diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
index 3264dcfdc92a..222bc5d8b62c 100644
--- a/fs/cachefiles/interface.c
+++ b/fs/cachefiles/interface.c
@@ -441,7 +441,7 @@ static int cachefiles_attr_changed(struct fscache_object *_object)
441 loff_t oi_size; 441 loff_t oi_size;
442 int ret; 442 int ret;
443 443
444 _object->cookie->def->get_attr(_object->cookie->netfs_data, &ni_size); 444 ni_size = _object->store_limit_l;
445 445
446 _enter("{OBJ%x},[%llu]", 446 _enter("{OBJ%x},[%llu]",
447 _object->debug_id, (unsigned long long) ni_size); 447 _object->debug_id, (unsigned long long) ni_size);
@@ -513,8 +513,7 @@ static void cachefiles_invalidate_object(struct fscache_operation *op)
513 cache = container_of(object->fscache.cache, 513 cache = container_of(object->fscache.cache,
514 struct cachefiles_cache, cache); 514 struct cachefiles_cache, cache);
515 515
516 op->object->cookie->def->get_attr(op->object->cookie->netfs_data, 516 ni_size = op->object->store_limit_l;
517 &ni_size);
518 517
519 _enter("{OBJ%x},[%llu]", 518 _enter("{OBJ%x},[%llu]",
520 op->object->debug_id, (unsigned long long)ni_size); 519 op->object->debug_id, (unsigned long long)ni_size);
diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c
index d84423c264af..0a29a00aed2e 100644
--- a/fs/cachefiles/xattr.c
+++ b/fs/cachefiles/xattr.c
@@ -182,7 +182,8 @@ int cachefiles_check_auxdata(struct cachefiles_object *object)
182 goto error; 182 goto error;
183 183
184 xlen--; 184 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)));
186 if (validity != FSCACHE_CHECKAUX_OKAY) 187 if (validity != FSCACHE_CHECKAUX_OKAY)
187 goto error; 188 goto error;
188 189
@@ -251,7 +252,8 @@ int cachefiles_check_object_xattr(struct cachefiles_object *object,
251 object->fscache.cookie->def->name, dlen); 252 object->fscache.cookie->def->name, dlen);
252 253
253 result = fscache_check_aux(&object->fscache, 254 result = fscache_check_aux(&object->fscache,
254 &auxbuf->data, dlen); 255 &auxbuf->data, dlen,
256 i_size_read(d_backing_inode(dentry)));
255 257
256 switch (result) { 258 switch (result) {
257 /* entry okay as is */ 259 /* entry okay as is */
diff --git a/fs/ceph/cache.c b/fs/ceph/cache.c
index fee869061f05..33a211b364ed 100644
--- a/fs/ceph/cache.c
+++ b/fs/ceph/cache.c
@@ -27,7 +27,6 @@
27struct ceph_aux_inode { 27struct ceph_aux_inode {
28 u64 version; 28 u64 version;
29 struct timespec mtime; 29 struct timespec mtime;
30 loff_t size;
31}; 30};
32 31
33struct fscache_netfs ceph_cache_netfs = { 32struct fscache_netfs ceph_cache_netfs = {
@@ -101,7 +100,7 @@ int ceph_fscache_register_fs(struct ceph_fs_client* fsc)
101 &ceph_fscache_fsid_object_def, 100 &ceph_fscache_fsid_object_def,
102 &ent->fsid, sizeof(ent->fsid) + uniq_len, 101 &ent->fsid, sizeof(ent->fsid) + uniq_len,
103 NULL, 0, 102 NULL, 0,
104 fsc, true); 103 fsc, 0, true);
105 104
106 if (fsc->fscache) { 105 if (fsc->fscache) {
107 ent->fscache = fsc->fscache; 106 ent->fscache = fsc->fscache;
@@ -117,27 +116,21 @@ out_unlock:
117 return err; 116 return err;
118} 117}
119 118
120static void ceph_fscache_inode_get_attr(const void *cookie_netfs_data,
121 uint64_t *size)
122{
123 const struct ceph_inode_info* ci = cookie_netfs_data;
124 *size = i_size_read(&ci->vfs_inode);
125}
126
127static enum fscache_checkaux ceph_fscache_inode_check_aux( 119static enum fscache_checkaux ceph_fscache_inode_check_aux(
128 void *cookie_netfs_data, const void *data, uint16_t dlen) 120 void *cookie_netfs_data, const void *data, uint16_t dlen,
121 loff_t object_size)
129{ 122{
130 struct ceph_aux_inode aux; 123 struct ceph_aux_inode aux;
131 struct ceph_inode_info* ci = cookie_netfs_data; 124 struct ceph_inode_info* ci = cookie_netfs_data;
132 struct inode* inode = &ci->vfs_inode; 125 struct inode* inode = &ci->vfs_inode;
133 126
134 if (dlen != sizeof(aux)) 127 if (dlen != sizeof(aux) ||
128 i_size_read(inode) != object_size)
135 return FSCACHE_CHECKAUX_OBSOLETE; 129 return FSCACHE_CHECKAUX_OBSOLETE;
136 130
137 memset(&aux, 0, sizeof(aux)); 131 memset(&aux, 0, sizeof(aux));
138 aux.version = ci->i_version; 132 aux.version = ci->i_version;
139 aux.mtime = inode->i_mtime; 133 aux.mtime = inode->i_mtime;
140 aux.size = i_size_read(inode);
141 134
142 if (memcmp(data, &aux, sizeof(aux)) != 0) 135 if (memcmp(data, &aux, sizeof(aux)) != 0)
143 return FSCACHE_CHECKAUX_OBSOLETE; 136 return FSCACHE_CHECKAUX_OBSOLETE;
@@ -149,7 +142,6 @@ static enum fscache_checkaux ceph_fscache_inode_check_aux(
149static const struct fscache_cookie_def ceph_fscache_inode_object_def = { 142static const struct fscache_cookie_def ceph_fscache_inode_object_def = {
150 .name = "CEPH.inode", 143 .name = "CEPH.inode",
151 .type = FSCACHE_COOKIE_TYPE_DATAFILE, 144 .type = FSCACHE_COOKIE_TYPE_DATAFILE,
152 .get_attr = ceph_fscache_inode_get_attr,
153 .check_aux = ceph_fscache_inode_check_aux, 145 .check_aux = ceph_fscache_inode_check_aux,
154}; 146};
155 147
@@ -172,12 +164,11 @@ void ceph_fscache_register_inode_cookie(struct inode *inode)
172 memset(&aux, 0, sizeof(aux)); 164 memset(&aux, 0, sizeof(aux));
173 aux.version = ci->i_version; 165 aux.version = ci->i_version;
174 aux.mtime = inode->i_mtime; 166 aux.mtime = inode->i_mtime;
175 aux.size = i_size_read(inode);
176 ci->fscache = fscache_acquire_cookie(fsc->fscache, 167 ci->fscache = fscache_acquire_cookie(fsc->fscache,
177 &ceph_fscache_inode_object_def, 168 &ceph_fscache_inode_object_def,
178 &ci->i_vino, sizeof(ci->i_vino), 169 &ci->i_vino, sizeof(ci->i_vino),
179 &aux, sizeof(aux), 170 &aux, sizeof(aux),
180 ci, false); 171 ci, i_size_read(inode), false);
181 } 172 }
182 inode_unlock(inode); 173 inode_unlock(inode);
183} 174}
@@ -214,7 +205,7 @@ void ceph_fscache_file_set_cookie(struct inode *inode, struct file *filp)
214 fscache_disable_cookie(ci->fscache, &ci->i_vino, false); 205 fscache_disable_cookie(ci->fscache, &ci->i_vino, false);
215 fscache_uncache_all_inode_pages(ci->fscache, inode); 206 fscache_uncache_all_inode_pages(ci->fscache, inode);
216 } else { 207 } else {
217 fscache_enable_cookie(ci->fscache, &ci->i_vino, 208 fscache_enable_cookie(ci->fscache, &ci->i_vino, i_size_read(inode),
218 ceph_fscache_can_enable, inode); 209 ceph_fscache_can_enable, inode);
219 if (fscache_cookie_enabled(ci->fscache)) { 210 if (fscache_cookie_enabled(ci->fscache)) {
220 dout("fscache_file_set_cookie %p %p enabling cache\n", 211 dout("fscache_file_set_cookie %p %p enabling cache\n",
@@ -308,7 +299,8 @@ void ceph_readpage_to_fscache(struct inode *inode, struct page *page)
308 if (!cache_valid(ci)) 299 if (!cache_valid(ci))
309 return; 300 return;
310 301
311 ret = fscache_write_page(ci->fscache, page, GFP_KERNEL); 302 ret = fscache_write_page(ci->fscache, page, i_size_read(inode),
303 GFP_KERNEL);
312 if (ret) 304 if (ret)
313 fscache_uncache_page(ci->fscache, page); 305 fscache_uncache_page(ci->fscache, page);
314} 306}
diff --git a/fs/cifs/cache.c b/fs/cifs/cache.c
index b4fa270ef532..edf5f40898bf 100644
--- a/fs/cifs/cache.c
+++ b/fs/cifs/cache.c
@@ -87,7 +87,8 @@ char *extract_sharename(const char *treename)
87static enum 87static enum
88fscache_checkaux cifs_fscache_super_check_aux(void *cookie_netfs_data, 88fscache_checkaux cifs_fscache_super_check_aux(void *cookie_netfs_data,
89 const void *data, 89 const void *data,
90 uint16_t datalen) 90 uint16_t datalen,
91 loff_t object_size)
91{ 92{
92 struct cifs_fscache_super_auxdata auxdata; 93 struct cifs_fscache_super_auxdata auxdata;
93 const struct cifs_tcon *tcon = cookie_netfs_data; 94 const struct cifs_tcon *tcon = cookie_netfs_data;
@@ -113,18 +114,11 @@ const struct fscache_cookie_def cifs_fscache_super_index_def = {
113 .check_aux = cifs_fscache_super_check_aux, 114 .check_aux = cifs_fscache_super_check_aux,
114}; 115};
115 116
116static void
117cifs_fscache_inode_get_attr(const void *cookie_netfs_data, uint64_t *size)
118{
119 const struct cifsInodeInfo *cifsi = cookie_netfs_data;
120
121 *size = cifsi->vfs_inode.i_size;
122}
123
124static enum 117static enum
125fscache_checkaux cifs_fscache_inode_check_aux(void *cookie_netfs_data, 118fscache_checkaux cifs_fscache_inode_check_aux(void *cookie_netfs_data,
126 const void *data, 119 const void *data,
127 uint16_t datalen) 120 uint16_t datalen,
121 loff_t object_size)
128{ 122{
129 struct cifs_fscache_inode_auxdata auxdata; 123 struct cifs_fscache_inode_auxdata auxdata;
130 struct cifsInodeInfo *cifsi = cookie_netfs_data; 124 struct cifsInodeInfo *cifsi = cookie_netfs_data;
@@ -146,6 +140,5 @@ fscache_checkaux cifs_fscache_inode_check_aux(void *cookie_netfs_data,
146const struct fscache_cookie_def cifs_fscache_inode_object_def = { 140const struct fscache_cookie_def cifs_fscache_inode_object_def = {
147 .name = "CIFS.uniqueid", 141 .name = "CIFS.uniqueid",
148 .type = FSCACHE_COOKIE_TYPE_DATAFILE, 142 .type = FSCACHE_COOKIE_TYPE_DATAFILE,
149 .get_attr = cifs_fscache_inode_get_attr,
150 .check_aux = cifs_fscache_inode_check_aux, 143 .check_aux = cifs_fscache_inode_check_aux,
151}; 144};
diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c
index b89b59b01759..25d3f66b2d50 100644
--- a/fs/cifs/fscache.c
+++ b/fs/cifs/fscache.c
@@ -79,7 +79,7 @@ void cifs_fscache_get_client_cookie(struct TCP_Server_Info *server)
79 &cifs_fscache_server_index_def, 79 &cifs_fscache_server_index_def,
80 &key, key_len, 80 &key, key_len,
81 NULL, 0, 81 NULL, 0,
82 server, true); 82 server, 0, true);
83 cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", 83 cifs_dbg(FYI, "%s: (0x%p/0x%p)\n",
84 __func__, server, server->fscache); 84 __func__, server, server->fscache);
85} 85}
@@ -109,7 +109,7 @@ void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
109 &cifs_fscache_super_index_def, 109 &cifs_fscache_super_index_def,
110 sharename, strlen(sharename), 110 sharename, strlen(sharename),
111 &tcon->resource_id, sizeof(tcon->resource_id), 111 &tcon->resource_id, sizeof(tcon->resource_id),
112 tcon, true); 112 tcon, 0, true);
113 kfree(sharename); 113 kfree(sharename);
114 cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", 114 cifs_dbg(FYI, "%s: (0x%p/0x%p)\n",
115 __func__, server->fscache, tcon->fscache); 115 __func__, server->fscache, tcon->fscache);
@@ -137,7 +137,7 @@ static void cifs_fscache_acquire_inode_cookie(struct cifsInodeInfo *cifsi,
137 &cifs_fscache_inode_object_def, 137 &cifs_fscache_inode_object_def,
138 &cifsi->uniqueid, sizeof(cifsi->uniqueid), 138 &cifsi->uniqueid, sizeof(cifsi->uniqueid),
139 &auxdata, sizeof(auxdata), 139 &auxdata, sizeof(auxdata),
140 cifsi, true); 140 cifsi, cifsi->vfs_inode.i_size, true);
141} 141}
142 142
143static void cifs_fscache_enable_inode_cookie(struct inode *inode) 143static void cifs_fscache_enable_inode_cookie(struct inode *inode)
@@ -301,13 +301,15 @@ int __cifs_readpages_from_fscache(struct inode *inode,
301 301
302void __cifs_readpage_to_fscache(struct inode *inode, struct page *page) 302void __cifs_readpage_to_fscache(struct inode *inode, struct page *page)
303{ 303{
304 struct cifsInodeInfo *cifsi = CIFS_I(inode);
304 int ret; 305 int ret;
305 306
306 cifs_dbg(FYI, "%s: (fsc: %p, p: %p, i: %p)\n", 307 cifs_dbg(FYI, "%s: (fsc: %p, p: %p, i: %p)\n",
307 __func__, CIFS_I(inode)->fscache, page, inode); 308 __func__, cifsi->fscache, page, inode);
308 ret = fscache_write_page(CIFS_I(inode)->fscache, page, GFP_KERNEL); 309 ret = fscache_write_page(cifsi->fscache, page,
310 cifsi->vfs_inode.i_size, GFP_KERNEL);
309 if (ret != 0) 311 if (ret != 0)
310 fscache_uncache_page(CIFS_I(inode)->fscache, page); 312 fscache_uncache_page(cifsi->fscache, page);
311} 313}
312 314
313void __cifs_fscache_readpages_cancel(struct inode *inode, struct list_head *pages) 315void __cifs_fscache_readpages_cancel(struct inode *inode, struct list_head *pages)
diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c
index 4d6210082a60..8ca9a932d225 100644
--- a/fs/fscache/cookie.c
+++ b/fs/fscache/cookie.c
@@ -21,7 +21,8 @@ struct kmem_cache *fscache_cookie_jar;
21 21
22static atomic_t fscache_object_debug_id = ATOMIC_INIT(0); 22static atomic_t fscache_object_debug_id = ATOMIC_INIT(0);
23 23
24static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie); 24static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie,
25 loff_t object_size);
25static int fscache_alloc_object(struct fscache_cache *cache, 26static int fscache_alloc_object(struct fscache_cache *cache,
26 struct fscache_cookie *cookie); 27 struct fscache_cookie *cookie);
27static int fscache_attach_object(struct fscache_cookie *cookie, 28static int fscache_attach_object(struct fscache_cookie *cookie,
@@ -61,6 +62,7 @@ struct fscache_cookie *__fscache_acquire_cookie(
61 const void *index_key, size_t index_key_len, 62 const void *index_key, size_t index_key_len,
62 const void *aux_data, size_t aux_data_len, 63 const void *aux_data, size_t aux_data_len,
63 void *netfs_data, 64 void *netfs_data,
65 loff_t object_size,
64 bool enable) 66 bool enable)
65{ 67{
66 struct fscache_cookie *cookie; 68 struct fscache_cookie *cookie;
@@ -160,7 +162,7 @@ struct fscache_cookie *__fscache_acquire_cookie(
160 * - we create indices on disk when we need them as an index 162 * - we create indices on disk when we need them as an index
161 * may exist in multiple caches */ 163 * may exist in multiple caches */
162 if (cookie->type != FSCACHE_COOKIE_TYPE_INDEX) { 164 if (cookie->type != FSCACHE_COOKIE_TYPE_INDEX) {
163 if (fscache_acquire_non_index_cookie(cookie) == 0) { 165 if (fscache_acquire_non_index_cookie(cookie, object_size) == 0) {
164 set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags); 166 set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
165 } else { 167 } else {
166 atomic_dec(&parent->n_children); 168 atomic_dec(&parent->n_children);
@@ -194,6 +196,7 @@ EXPORT_SYMBOL(__fscache_acquire_cookie);
194 */ 196 */
195void __fscache_enable_cookie(struct fscache_cookie *cookie, 197void __fscache_enable_cookie(struct fscache_cookie *cookie,
196 const void *aux_data, 198 const void *aux_data,
199 loff_t object_size,
197 bool (*can_enable)(void *data), 200 bool (*can_enable)(void *data),
198 void *data) 201 void *data)
199{ 202{
@@ -215,7 +218,7 @@ void __fscache_enable_cookie(struct fscache_cookie *cookie,
215 /* Wait for outstanding disablement to complete */ 218 /* Wait for outstanding disablement to complete */
216 __fscache_wait_on_invalidate(cookie); 219 __fscache_wait_on_invalidate(cookie);
217 220
218 if (fscache_acquire_non_index_cookie(cookie) == 0) 221 if (fscache_acquire_non_index_cookie(cookie, object_size) == 0)
219 set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags); 222 set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
220 } else { 223 } else {
221 set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags); 224 set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
@@ -232,11 +235,11 @@ EXPORT_SYMBOL(__fscache_enable_cookie);
232 * - this must make sure the index chain is instantiated and instantiate the 235 * - this must make sure the index chain is instantiated and instantiate the
233 * object representation too 236 * object representation too
234 */ 237 */
235static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie) 238static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie,
239 loff_t object_size)
236{ 240{
237 struct fscache_object *object; 241 struct fscache_object *object;
238 struct fscache_cache *cache; 242 struct fscache_cache *cache;
239 uint64_t i_size;
240 int ret; 243 int ret;
241 244
242 _enter(""); 245 _enter("");
@@ -275,9 +278,6 @@ static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie)
275 return ret; 278 return ret;
276 } 279 }
277 280
278 /* pass on how big the object we're caching is supposed to be */
279 cookie->def->get_attr(cookie->netfs_data, &i_size);
280
281 spin_lock(&cookie->lock); 281 spin_lock(&cookie->lock);
282 if (hlist_empty(&cookie->backing_objects)) { 282 if (hlist_empty(&cookie->backing_objects)) {
283 spin_unlock(&cookie->lock); 283 spin_unlock(&cookie->lock);
@@ -287,7 +287,7 @@ static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie)
287 object = hlist_entry(cookie->backing_objects.first, 287 object = hlist_entry(cookie->backing_objects.first,
288 struct fscache_object, cookie_link); 288 struct fscache_object, cookie_link);
289 289
290 fscache_set_store_limit(object, i_size); 290 fscache_set_store_limit(object, object_size);
291 291
292 /* initiate the process of looking up all the objects in the chain 292 /* initiate the process of looking up all the objects in the chain
293 * (done by fscache_initialise_object()) */ 293 * (done by fscache_initialise_object()) */
diff --git a/fs/fscache/fsdef.c b/fs/fscache/fsdef.c
index 1122e97d56e8..aa46e48d8c75 100644
--- a/fs/fscache/fsdef.c
+++ b/fs/fscache/fsdef.c
@@ -16,7 +16,8 @@
16static 16static
17enum fscache_checkaux fscache_fsdef_netfs_check_aux(void *cookie_netfs_data, 17enum fscache_checkaux fscache_fsdef_netfs_check_aux(void *cookie_netfs_data,
18 const void *data, 18 const void *data,
19 uint16_t datalen); 19 uint16_t datalen,
20 loff_t object_size);
20 21
21/* 22/*
22 * The root index is owned by FS-Cache itself. 23 * The root index is owned by FS-Cache itself.
@@ -76,7 +77,8 @@ struct fscache_cookie_def fscache_fsdef_netfs_def = {
76static enum fscache_checkaux fscache_fsdef_netfs_check_aux( 77static enum fscache_checkaux fscache_fsdef_netfs_check_aux(
77 void *cookie_netfs_data, 78 void *cookie_netfs_data,
78 const void *data, 79 const void *data,
79 uint16_t datalen) 80 uint16_t datalen,
81 loff_t object_size)
80{ 82{
81 struct fscache_netfs *netfs = cookie_netfs_data; 83 struct fscache_netfs *netfs = cookie_netfs_data;
82 uint32_t version; 84 uint32_t version;
diff --git a/fs/fscache/object.c b/fs/fscache/object.c
index a7b28f876fde..1085ca12e25c 100644
--- a/fs/fscache/object.c
+++ b/fs/fscache/object.c
@@ -922,7 +922,8 @@ static void fscache_dequeue_object(struct fscache_object *object)
922 * and creation). 922 * and creation).
923 */ 923 */
924enum fscache_checkaux fscache_check_aux(struct fscache_object *object, 924enum fscache_checkaux fscache_check_aux(struct fscache_object *object,
925 const void *data, uint16_t datalen) 925 const void *data, uint16_t datalen,
926 loff_t object_size)
926{ 927{
927 enum fscache_checkaux result; 928 enum fscache_checkaux result;
928 929
@@ -932,7 +933,7 @@ enum fscache_checkaux fscache_check_aux(struct fscache_object *object,
932 } 933 }
933 934
934 result = object->cookie->def->check_aux(object->cookie->netfs_data, 935 result = object->cookie->def->check_aux(object->cookie->netfs_data,
935 data, datalen); 936 data, datalen, object_size);
936 switch (result) { 937 switch (result) {
937 /* entry okay as is */ 938 /* entry okay as is */
938 case FSCACHE_CHECKAUX_OKAY: 939 case FSCACHE_CHECKAUX_OKAY:
diff --git a/fs/fscache/page.c b/fs/fscache/page.c
index 810b33aced1c..111349f67d98 100644
--- a/fs/fscache/page.c
+++ b/fs/fscache/page.c
@@ -963,6 +963,7 @@ void fscache_invalidate_writes(struct fscache_cookie *cookie)
963 */ 963 */
964int __fscache_write_page(struct fscache_cookie *cookie, 964int __fscache_write_page(struct fscache_cookie *cookie,
965 struct page *page, 965 struct page *page,
966 loff_t object_size,
966 gfp_t gfp) 967 gfp_t gfp)
967{ 968{
968 struct fscache_storage *op; 969 struct fscache_storage *op;
@@ -1014,6 +1015,10 @@ int __fscache_write_page(struct fscache_cookie *cookie,
1014 /* add the page to the pending-storage radix tree on the backing 1015 /* add the page to the pending-storage radix tree on the backing
1015 * object */ 1016 * object */
1016 spin_lock(&object->lock); 1017 spin_lock(&object->lock);
1018
1019 if (object->store_limit_l != object_size)
1020 fscache_set_store_limit(object, object_size);
1021
1017 spin_lock(&cookie->stores_lock); 1022 spin_lock(&cookie->stores_lock);
1018 1023
1019 _debug("store limit %llx", (unsigned long long) object->store_limit); 1024 _debug("store limit %llx", (unsigned long long) object->store_limit);
diff --git a/fs/nfs/fscache-index.c b/fs/nfs/fscache-index.c
index 6fd3679b7137..1c5d8d31fc0a 100644
--- a/fs/nfs/fscache-index.c
+++ b/fs/nfs/fscache-index.c
@@ -70,20 +70,6 @@ const struct fscache_cookie_def nfs_fscache_super_index_def = {
70}; 70};
71 71
72/* 72/*
73 * Get certain file attributes from the netfs data
74 * - This function can be absent for an index
75 * - Not permitted to return an error
76 * - The netfs data from the cookie being used as the source is presented
77 */
78static void nfs_fscache_inode_get_attr(const void *cookie_netfs_data,
79 uint64_t *size)
80{
81 const struct nfs_inode *nfsi = cookie_netfs_data;
82
83 *size = nfsi->vfs_inode.i_size;
84}
85
86/*
87 * Consult the netfs about the state of an object 73 * Consult the netfs about the state of an object
88 * - This function can be absent if the index carries no state data 74 * - This function can be absent if the index carries no state data
89 * - The netfs data from the cookie being used as the target is 75 * - The netfs data from the cookie being used as the target is
@@ -92,7 +78,8 @@ static void nfs_fscache_inode_get_attr(const void *cookie_netfs_data,
92static 78static
93enum fscache_checkaux nfs_fscache_inode_check_aux(void *cookie_netfs_data, 79enum fscache_checkaux nfs_fscache_inode_check_aux(void *cookie_netfs_data,
94 const void *data, 80 const void *data,
95 uint16_t datalen) 81 uint16_t datalen,
82 loff_t object_size)
96{ 83{
97 struct nfs_fscache_inode_auxdata auxdata; 84 struct nfs_fscache_inode_auxdata auxdata;
98 struct nfs_inode *nfsi = cookie_netfs_data; 85 struct nfs_inode *nfsi = cookie_netfs_data;
@@ -101,7 +88,6 @@ enum fscache_checkaux nfs_fscache_inode_check_aux(void *cookie_netfs_data,
101 return FSCACHE_CHECKAUX_OBSOLETE; 88 return FSCACHE_CHECKAUX_OBSOLETE;
102 89
103 memset(&auxdata, 0, sizeof(auxdata)); 90 memset(&auxdata, 0, sizeof(auxdata));
104 auxdata.size = nfsi->vfs_inode.i_size;
105 auxdata.mtime = nfsi->vfs_inode.i_mtime; 91 auxdata.mtime = nfsi->vfs_inode.i_mtime;
106 auxdata.ctime = nfsi->vfs_inode.i_ctime; 92 auxdata.ctime = nfsi->vfs_inode.i_ctime;
107 93
@@ -150,7 +136,6 @@ static void nfs_fh_put_context(void *cookie_netfs_data, void *context)
150const struct fscache_cookie_def nfs_fscache_inode_object_def = { 136const struct fscache_cookie_def nfs_fscache_inode_object_def = {
151 .name = "NFS.fh", 137 .name = "NFS.fh",
152 .type = FSCACHE_COOKIE_TYPE_DATAFILE, 138 .type = FSCACHE_COOKIE_TYPE_DATAFILE,
153 .get_attr = nfs_fscache_inode_get_attr,
154 .check_aux = nfs_fscache_inode_check_aux, 139 .check_aux = nfs_fscache_inode_check_aux,
155 .get_context = nfs_fh_get_context, 140 .get_context = nfs_fh_get_context,
156 .put_context = nfs_fh_put_context, 141 .put_context = nfs_fh_put_context,
diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c
index c45ba2691cee..b55fc7920c3b 100644
--- a/fs/nfs/fscache.c
+++ b/fs/nfs/fscache.c
@@ -86,7 +86,7 @@ void nfs_fscache_get_client_cookie(struct nfs_client *clp)
86 &nfs_fscache_server_index_def, 86 &nfs_fscache_server_index_def,
87 &key, len, 87 &key, len,
88 NULL, 0, 88 NULL, 0,
89 clp, true); 89 clp, 0, true);
90 dfprintk(FSCACHE, "NFS: get client cookie (0x%p/0x%p)\n", 90 dfprintk(FSCACHE, "NFS: get client cookie (0x%p/0x%p)\n",
91 clp, clp->fscache); 91 clp, clp->fscache);
92} 92}
@@ -188,7 +188,7 @@ void nfs_fscache_get_super_cookie(struct super_block *sb, const char *uniq, int
188 &nfs_fscache_super_index_def, 188 &nfs_fscache_super_index_def,
189 key, sizeof(*key) + ulen, 189 key, sizeof(*key) + ulen,
190 NULL, 0, 190 NULL, 0,
191 nfss, true); 191 nfss, 0, true);
192 dfprintk(FSCACHE, "NFS: get superblock cookie (0x%p/0x%p)\n", 192 dfprintk(FSCACHE, "NFS: get superblock cookie (0x%p/0x%p)\n",
193 nfss, nfss->fscache); 193 nfss, nfss->fscache);
194 return; 194 return;
@@ -237,7 +237,6 @@ void nfs_fscache_init_inode(struct inode *inode)
237 return; 237 return;
238 238
239 memset(&auxdata, 0, sizeof(auxdata)); 239 memset(&auxdata, 0, sizeof(auxdata));
240 auxdata.size = nfsi->vfs_inode.i_size;
241 auxdata.mtime = nfsi->vfs_inode.i_mtime; 240 auxdata.mtime = nfsi->vfs_inode.i_mtime;
242 auxdata.ctime = nfsi->vfs_inode.i_ctime; 241 auxdata.ctime = nfsi->vfs_inode.i_ctime;
243 242
@@ -248,7 +247,7 @@ void nfs_fscache_init_inode(struct inode *inode)
248 &nfs_fscache_inode_object_def, 247 &nfs_fscache_inode_object_def,
249 nfsi->fh.data, nfsi->fh.size, 248 nfsi->fh.data, nfsi->fh.size,
250 &auxdata, sizeof(auxdata), 249 &auxdata, sizeof(auxdata),
251 nfsi, false); 250 nfsi, nfsi->vfs_inode.i_size, false);
252} 251}
253 252
254/* 253/*
@@ -263,7 +262,6 @@ void nfs_fscache_clear_inode(struct inode *inode)
263 dfprintk(FSCACHE, "NFS: clear cookie (0x%p/0x%p)\n", nfsi, cookie); 262 dfprintk(FSCACHE, "NFS: clear cookie (0x%p/0x%p)\n", nfsi, cookie);
264 263
265 memset(&auxdata, 0, sizeof(auxdata)); 264 memset(&auxdata, 0, sizeof(auxdata));
266 auxdata.size = nfsi->vfs_inode.i_size;
267 auxdata.mtime = nfsi->vfs_inode.i_mtime; 265 auxdata.mtime = nfsi->vfs_inode.i_mtime;
268 auxdata.ctime = nfsi->vfs_inode.i_ctime; 266 auxdata.ctime = nfsi->vfs_inode.i_ctime;
269 fscache_relinquish_cookie(cookie, &auxdata, false); 267 fscache_relinquish_cookie(cookie, &auxdata, false);
@@ -306,7 +304,6 @@ void nfs_fscache_open_file(struct inode *inode, struct file *filp)
306 return; 304 return;
307 305
308 memset(&auxdata, 0, sizeof(auxdata)); 306 memset(&auxdata, 0, sizeof(auxdata));
309 auxdata.size = nfsi->vfs_inode.i_size;
310 auxdata.mtime = nfsi->vfs_inode.i_mtime; 307 auxdata.mtime = nfsi->vfs_inode.i_mtime;
311 auxdata.ctime = nfsi->vfs_inode.i_ctime; 308 auxdata.ctime = nfsi->vfs_inode.i_ctime;
312 309
@@ -317,7 +314,7 @@ void nfs_fscache_open_file(struct inode *inode, struct file *filp)
317 fscache_uncache_all_inode_pages(cookie, inode); 314 fscache_uncache_all_inode_pages(cookie, inode);
318 } else { 315 } else {
319 dfprintk(FSCACHE, "NFS: nfsi 0x%p enabling cache\n", nfsi); 316 dfprintk(FSCACHE, "NFS: nfsi 0x%p enabling cache\n", nfsi);
320 fscache_enable_cookie(cookie, &auxdata, 317 fscache_enable_cookie(cookie, &auxdata, nfsi->vfs_inode.i_size,
321 nfs_fscache_can_enable, inode); 318 nfs_fscache_can_enable, inode);
322 if (fscache_cookie_enabled(cookie)) 319 if (fscache_cookie_enabled(cookie))
323 set_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags); 320 set_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags);
@@ -495,7 +492,8 @@ void __nfs_readpage_to_fscache(struct inode *inode, struct page *page, int sync)
495 "NFS: readpage_to_fscache(fsc:%p/p:%p(i:%lx f:%lx)/%d)\n", 492 "NFS: readpage_to_fscache(fsc:%p/p:%p(i:%lx f:%lx)/%d)\n",
496 nfs_i_fscache(inode), page, page->index, page->flags, sync); 493 nfs_i_fscache(inode), page, page->index, page->flags, sync);
497 494
498 ret = fscache_write_page(nfs_i_fscache(inode), page, GFP_KERNEL); 495 ret = fscache_write_page(nfs_i_fscache(inode), page,
496 inode->i_size, GFP_KERNEL);
499 dfprintk(FSCACHE, 497 dfprintk(FSCACHE,
500 "NFS: readpage_to_fscache: p:%p(i:%lu f:%lx) ret %d\n", 498 "NFS: readpage_to_fscache: p:%p(i:%lu f:%lx) ret %d\n",
501 page, page->index, page->flags, ret); 499 page, page->index, page->flags, ret);
diff --git a/fs/nfs/fscache.h b/fs/nfs/fscache.h
index 96e989f579d1..161ba2edb9d0 100644
--- a/fs/nfs/fscache.h
+++ b/fs/nfs/fscache.h
@@ -68,7 +68,6 @@ struct nfs_fscache_key {
68struct nfs_fscache_inode_auxdata { 68struct nfs_fscache_inode_auxdata {
69 struct timespec mtime; 69 struct timespec mtime;
70 struct timespec ctime; 70 struct timespec ctime;
71 loff_t size;
72 u64 change_attr; 71 u64 change_attr;
73}; 72};
74 73
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h
index 3e764fd38d9f..34cf0fdd7dc7 100644
--- a/include/linux/fscache-cache.h
+++ b/include/linux/fscache-cache.h
@@ -553,7 +553,8 @@ extern bool fscache_object_sleep_till_congested(signed long *timeoutp);
553 553
554extern enum fscache_checkaux fscache_check_aux(struct fscache_object *object, 554extern enum fscache_checkaux fscache_check_aux(struct fscache_object *object,
555 const void *data, 555 const void *data,
556 uint16_t datalen); 556 uint16_t datalen,
557 loff_t object_size);
557 558
558extern void fscache_object_retrying_stale(struct fscache_object *object); 559extern void fscache_object_retrying_stale(struct fscache_object *object);
559 560
diff --git a/include/linux/fscache.h b/include/linux/fscache.h
index a2d3a2116248..eb38f39cf832 100644
--- a/include/linux/fscache.h
+++ b/include/linux/fscache.h
@@ -83,22 +83,15 @@ struct fscache_cookie_def {
83 const void *parent_netfs_data, 83 const void *parent_netfs_data,
84 const void *cookie_netfs_data); 84 const void *cookie_netfs_data);
85 85
86 /* get certain file attributes from the netfs data
87 * - this function can be absent for an index
88 * - not permitted to return an error
89 * - the netfs data from the cookie being used as the source is
90 * presented
91 */
92 void (*get_attr)(const void *cookie_netfs_data, uint64_t *size);
93
94 /* consult the netfs about the state of an object 86 /* consult the netfs about the state of an object
95 * - this function can be absent if the index carries no state data 87 * - this function can be absent if the index carries no state data
96 * - the netfs data from the cookie being used as the target is 88 * - the netfs data from the cookie being used as the target is
97 * presented, as is the auxiliary data 89 * presented, as is the auxiliary data and the object size
98 */ 90 */
99 enum fscache_checkaux (*check_aux)(void *cookie_netfs_data, 91 enum fscache_checkaux (*check_aux)(void *cookie_netfs_data,
100 const void *data, 92 const void *data,
101 uint16_t datalen); 93 uint16_t datalen,
94 loff_t object_size);
102 95
103 /* get an extra reference on a read context 96 /* get an extra reference on a read context
104 * - this function can be absent if the completion function doesn't 97 * - this function can be absent if the completion function doesn't
@@ -200,7 +193,7 @@ extern struct fscache_cookie *__fscache_acquire_cookie(
200 const struct fscache_cookie_def *, 193 const struct fscache_cookie_def *,
201 const void *, size_t, 194 const void *, size_t,
202 const void *, size_t, 195 const void *, size_t,
203 void *, bool); 196 void *, loff_t, bool);
204extern void __fscache_relinquish_cookie(struct fscache_cookie *, const void *, bool); 197extern void __fscache_relinquish_cookie(struct fscache_cookie *, const void *, bool);
205extern int __fscache_check_consistency(struct fscache_cookie *, const void *); 198extern int __fscache_check_consistency(struct fscache_cookie *, const void *);
206extern void __fscache_update_cookie(struct fscache_cookie *, const void *); 199extern void __fscache_update_cookie(struct fscache_cookie *, const void *);
@@ -220,7 +213,7 @@ extern int __fscache_read_or_alloc_pages(struct fscache_cookie *,
220 void *, 213 void *,
221 gfp_t); 214 gfp_t);
222extern int __fscache_alloc_page(struct fscache_cookie *, struct page *, gfp_t); 215extern int __fscache_alloc_page(struct fscache_cookie *, struct page *, gfp_t);
223extern int __fscache_write_page(struct fscache_cookie *, struct page *, gfp_t); 216extern int __fscache_write_page(struct fscache_cookie *, struct page *, loff_t, gfp_t);
224extern void __fscache_uncache_page(struct fscache_cookie *, struct page *); 217extern void __fscache_uncache_page(struct fscache_cookie *, struct page *);
225extern bool __fscache_check_page_write(struct fscache_cookie *, struct page *); 218extern bool __fscache_check_page_write(struct fscache_cookie *, struct page *);
226extern void __fscache_wait_on_page_write(struct fscache_cookie *, struct page *); 219extern void __fscache_wait_on_page_write(struct fscache_cookie *, struct page *);
@@ -231,7 +224,7 @@ extern void __fscache_uncache_all_inode_pages(struct fscache_cookie *,
231extern void __fscache_readpages_cancel(struct fscache_cookie *cookie, 224extern void __fscache_readpages_cancel(struct fscache_cookie *cookie,
232 struct list_head *pages); 225 struct list_head *pages);
233extern void __fscache_disable_cookie(struct fscache_cookie *, const void *, bool); 226extern void __fscache_disable_cookie(struct fscache_cookie *, const void *, bool);
234extern void __fscache_enable_cookie(struct fscache_cookie *, const void *, 227extern void __fscache_enable_cookie(struct fscache_cookie *, const void *, loff_t,
235 bool (*)(void *), void *); 228 bool (*)(void *), void *);
236 229
237/** 230/**
@@ -315,6 +308,7 @@ void fscache_release_cache_tag(struct fscache_cache_tag *tag)
315 * @aux_data_len: Size of the auxiliary data buffer 308 * @aux_data_len: Size of the auxiliary data buffer
316 * @netfs_data: An arbitrary piece of data to be kept in the cookie to 309 * @netfs_data: An arbitrary piece of data to be kept in the cookie to
317 * represent the cache object to the netfs 310 * represent the cache object to the netfs
311 * @object_size: The initial size of object
318 * @enable: Whether or not to enable a data cookie immediately 312 * @enable: Whether or not to enable a data cookie immediately
319 * 313 *
320 * This function is used to inform FS-Cache about part of an index hierarchy 314 * This function is used to inform FS-Cache about part of an index hierarchy
@@ -333,13 +327,14 @@ struct fscache_cookie *fscache_acquire_cookie(
333 const void *aux_data, 327 const void *aux_data,
334 size_t aux_data_len, 328 size_t aux_data_len,
335 void *netfs_data, 329 void *netfs_data,
330 loff_t object_size,
336 bool enable) 331 bool enable)
337{ 332{
338 if (fscache_cookie_valid(parent) && fscache_cookie_enabled(parent)) 333 if (fscache_cookie_valid(parent) && fscache_cookie_enabled(parent))
339 return __fscache_acquire_cookie(parent, def, 334 return __fscache_acquire_cookie(parent, def,
340 index_key, index_key_len, 335 index_key, index_key_len,
341 aux_data, aux_data_len, 336 aux_data, aux_data_len,
342 netfs_data, enable); 337 netfs_data, object_size, enable);
343 else 338 else
344 return NULL; 339 return NULL;
345} 340}
@@ -660,6 +655,7 @@ void fscache_readpages_cancel(struct fscache_cookie *cookie,
660 * fscache_write_page - Request storage of a page in the cache 655 * fscache_write_page - Request storage of a page in the cache
661 * @cookie: The cookie representing the cache object 656 * @cookie: The cookie representing the cache object
662 * @page: The netfs page to store 657 * @page: The netfs page to store
658 * @object_size: Updated size of object
663 * @gfp: The conditions under which memory allocation should be made 659 * @gfp: The conditions under which memory allocation should be made
664 * 660 *
665 * Request the contents of the netfs page be written into the cache. This 661 * Request the contents of the netfs page be written into the cache. This
@@ -677,10 +673,11 @@ void fscache_readpages_cancel(struct fscache_cookie *cookie,
677static inline 673static inline
678int fscache_write_page(struct fscache_cookie *cookie, 674int fscache_write_page(struct fscache_cookie *cookie,
679 struct page *page, 675 struct page *page,
676 loff_t object_size,
680 gfp_t gfp) 677 gfp_t gfp)
681{ 678{
682 if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) 679 if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
683 return __fscache_write_page(cookie, page, gfp); 680 return __fscache_write_page(cookie, page, object_size, gfp);
684 else 681 else
685 return -ENOBUFS; 682 return -ENOBUFS;
686} 683}
@@ -819,6 +816,7 @@ void fscache_disable_cookie(struct fscache_cookie *cookie,
819 * fscache_enable_cookie - Reenable a cookie 816 * fscache_enable_cookie - Reenable a cookie
820 * @cookie: The cookie representing the cache object 817 * @cookie: The cookie representing the cache object
821 * @aux_data: The updated auxiliary data for the cookie (may be NULL) 818 * @aux_data: The updated auxiliary data for the cookie (may be NULL)
819 * @object_size: Current size of object
822 * @can_enable: A function to permit enablement once lock is held 820 * @can_enable: A function to permit enablement once lock is held
823 * @data: Data for can_enable() 821 * @data: Data for can_enable()
824 * 822 *
@@ -833,11 +831,13 @@ void fscache_disable_cookie(struct fscache_cookie *cookie,
833static inline 831static inline
834void fscache_enable_cookie(struct fscache_cookie *cookie, 832void fscache_enable_cookie(struct fscache_cookie *cookie,
835 const void *aux_data, 833 const void *aux_data,
834 loff_t object_size,
836 bool (*can_enable)(void *data), 835 bool (*can_enable)(void *data),
837 void *data) 836 void *data)
838{ 837{
839 if (fscache_cookie_valid(cookie) && !fscache_cookie_enabled(cookie)) 838 if (fscache_cookie_valid(cookie) && !fscache_cookie_enabled(cookie))
840 __fscache_enable_cookie(cookie, aux_data, can_enable, data); 839 __fscache_enable_cookie(cookie, aux_data, object_size,
840 can_enable, data);
841} 841}
842 842
843#endif /* _LINUX_FSCACHE_H */ 843#endif /* _LINUX_FSCACHE_H */