Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

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