aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-04-07 12:08:24 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-07 12:08:24 -0400
commit62f8e6c5dcb6666e7da402aea28fcf846eea144c (patch)
tree2fb8ea1b55b4f0b0592fce715dc7816533609a23
parentf605ba97fb80522656c7dce9825a908f1e765b57 (diff)
parentec0328e46d6e5d0f17372eb90ab8e333c2ac7ca9 (diff)
Merge tag 'fscache-next-20180406' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
Pull fscache updates from David Howells: "Three patches that fix some of AFS's usage of fscache: (1) Need to invalidate the cache if a foreign data change is detected on the server. (2) Move the vnode ID uniquifier (equivalent to i_generation) from the auxiliary data to the index key to prevent a race between file delete and a subsequent file create seeing the same index key. (3) Need to retire cookies that correspond to files that we think got deleted on the server. Four patches to fix some things in fscache and cachefiles: (4) Fix a couple of checker warnings. (5) Correctly indicate to the end-of-operation callback whether an operation completed or was cancelled. (6) Add a check for multiple cookie relinquishment. (7) Fix a path through the asynchronous write that doesn't wake up a waiter for a page if the cache decides not to write that page, but discards it instead. A couple of patches to add tracepoints to fscache and cachefiles: (8) Add tracepoints for cookie operators, object state machine execution, cachefiles object management and cachefiles VFS operations. (9) Add tracepoints for fscache operation management and page wrangling. And then three development patches: (10) Attach the index key and auxiliary data to the cookie, pass this information through various fscache-netfs API functions and get rid of the callbacks to the netfs to get it. This means that the cache can get at this information, even if the netfs goes away. It also means that the cache can be lazy in updating the coherency data. (11) Pass the object data size through various fscache-netfs API rather than calling back to the netfs for it, and store the value in the object. This makes it easier to correctly resize the object, as the size is updated on writes to the cache, rather than calling back out to the netfs. (12) Maintain a catalogue of allocated cookies. This makes it possible to catch cookie collision up front rather than down in the bowels of the cache being run from a service thread from the object state machine. This will also make it possible in the future to reconnect to a cookie that's not gone dead yet because it's waiting for finalisation of the storage and also make it possible to bring cookies online if the cache is added after the cookie has been obtained" * tag 'fscache-next-20180406' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs: fscache: Maintain a catalogue of allocated cookies fscache: Pass object size in rather than calling back for it fscache: Attach the index key and aux data to the cookie fscache: Add more tracepoints fscache: Add tracepoints fscache: Fix hanging wait on page discarded by writeback fscache: Detect multiple relinquishment of a cookie fscache: Pass the correct cancelled indications to fscache_op_complete() fscache, cachefiles: Fix checker warnings afs: Be more aggressive in retiring cached vnodes afs: Use the vnode ID uniquifier in the cache key not the aux data afs: Invalidate cache on server data change
-rw-r--r--Documentation/filesystems/caching/netfs-api.txt157
-rw-r--r--fs/9p/cache.c100
-rw-r--r--fs/afs/cache.c150
-rw-r--r--fs/afs/cell.c6
-rw-r--r--fs/afs/file.c6
-rw-r--r--fs/afs/inode.c49
-rw-r--r--fs/afs/internal.h7
-rw-r--r--fs/afs/volume.c6
-rw-r--r--fs/cachefiles/interface.c61
-rw-r--r--fs/cachefiles/internal.h2
-rw-r--r--fs/cachefiles/main.c1
-rw-r--r--fs/cachefiles/namei.c75
-rw-r--r--fs/cachefiles/rdwr.c1
-rw-r--r--fs/cachefiles/xattr.c8
-rw-r--r--fs/ceph/cache.c113
-rw-r--r--fs/cifs/cache.c168
-rw-r--r--fs/cifs/fscache.c130
-rw-r--r--fs/cifs/fscache.h13
-rw-r--r--fs/fscache/cache.c2
-rw-r--r--fs/fscache/cookie.c386
-rw-r--r--fs/fscache/fsdef.c55
-rw-r--r--fs/fscache/internal.h44
-rw-r--r--fs/fscache/main.c1
-rw-r--r--fs/fscache/netfs.c71
-rw-r--r--fs/fscache/object-list.c28
-rw-r--r--fs/fscache/object.c66
-rw-r--r--fs/fscache/operation.c26
-rw-r--r--fs/fscache/page.c84
-rw-r--r--fs/fscache/stats.c1
-rw-r--r--fs/nfs/fscache-index.c159
-rw-r--r--fs/nfs/fscache.c89
-rw-r--r--fs/nfs/fscache.h15
-rw-r--r--include/linux/fscache-cache.h26
-rw-r--r--include/linux/fscache.h142
-rw-r--r--include/trace/events/cachefiles.h325
-rw-r--r--include/trace/events/fscache.h537
36 files changed, 2029 insertions, 1081 deletions
diff --git a/Documentation/filesystems/caching/netfs-api.txt b/Documentation/filesystems/caching/netfs-api.txt
index 0eb31de3a2c1..2a6f7399c1f3 100644
--- a/Documentation/filesystems/caching/netfs-api.txt
+++ b/Documentation/filesystems/caching/netfs-api.txt
@@ -129,20 +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 uint16_t (*get_key)(const void *cookie_netfs_data,
133 void *buffer,
134 uint16_t bufmax);
135
136 void (*get_attr)(const void *cookie_netfs_data,
137 uint64_t *size);
138
139 uint16_t (*get_aux)(const void *cookie_netfs_data,
140 void *buffer,
141 uint16_t bufmax);
142
143 enum fscache_checkaux (*check_aux)(void *cookie_netfs_data, 132 enum fscache_checkaux (*check_aux)(void *cookie_netfs_data,
144 const void *data, 133 const void *data,
145 uint16_t datalen); 134 uint16_t datalen,
135 loff_t object_size);
146 136
147 void (*get_context)(void *cookie_netfs_data, void *context); 137 void (*get_context)(void *cookie_netfs_data, void *context);
148 138
@@ -187,36 +177,7 @@ This has the following fields:
187 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
188 cache in the master list. 178 cache in the master list.
189 179
190 (4) A function to retrieve an object's key from the netfs [mandatory]. 180 (4) A function to check the auxiliary data [optional].
191
192 This function will be called with the netfs data that was passed to the
193 cookie acquisition function and the maximum length of key data that it may
194 provide. It should write the required key data into the given buffer and
195 return the quantity it wrote.
196
197 (5) A function to retrieve attribute data from the netfs [optional].
198
199 This function will be called with the netfs data that was passed to the
200 cookie acquisition function. It should return the size of the file if
201 this is a data file. The size may be used to govern how much cache must
202 be reserved for this file in the cache.
203
204 If the function is absent, a file size of 0 is assumed.
205
206 (6) A function to retrieve auxiliary data from the netfs [optional].
207
208 This function will be called with the netfs data that was passed to the
209 cookie acquisition function and the maximum length of auxiliary data that
210 it may provide. It should write the auxiliary data into the given buffer
211 and return the quantity it wrote.
212
213 If this function is absent, the auxiliary data length will be set to 0.
214
215 The length of the auxiliary data buffer may be dependent on the key
216 length. A netfs mustn't rely on being able to provide more than 400 bytes
217 for both.
218
219 (7) A function to check the auxiliary data [optional].
220 181
221 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
222 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
@@ -226,6 +187,9 @@ This has the following fields:
226 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
227 cache are always valid. 188 cache are always valid.
228 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
229 If present, the function should return one of the following values: 193 If present, the function should return one of the following values:
230 194
231 (*) FSCACHE_CHECKAUX_OKAY - the entry is okay as is 195 (*) FSCACHE_CHECKAUX_OKAY - the entry is okay as is
@@ -235,7 +199,7 @@ This has the following fields:
235 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
236 the cache and copy it into the netfs's structures. 200 the cache and copy it into the netfs's structures.
237 201
238 (8) A pair of functions to manage contexts for the completion callback 202 (5) A pair of functions to manage contexts for the completion callback
239 [optional]. 203 [optional].
240 204
241 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
@@ -249,7 +213,7 @@ This has the following fields:
249 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
250 be called in interrupt context and so may not sleep. 214 be called in interrupt context and so may not sleep.
251 215
252 (9) A function to mark a page as retaining cache metadata [optional]. 216 (6) A function to mark a page as retaining cache metadata [optional].
253 217
254 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
255 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
@@ -261,7 +225,7 @@ This has the following fields:
261 225
262 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.
263 227
264(10) A function to unmark all the pages retaining cache metadata [mandatory]. 228 (7) A function to unmark all the pages retaining cache metadata [mandatory].
265 229
266 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
267 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
@@ -333,12 +297,32 @@ the path to the file:
333 struct fscache_cookie * 297 struct fscache_cookie *
334 fscache_acquire_cookie(struct fscache_cookie *parent, 298 fscache_acquire_cookie(struct fscache_cookie *parent,
335 const struct fscache_object_def *def, 299 const struct fscache_object_def *def,
300 const void *index_key,
301 size_t index_key_len,
302 const void *aux_data,
303 size_t aux_data_len,
336 void *netfs_data, 304 void *netfs_data,
305 loff_t object_size,
337 bool enable); 306 bool enable);
338 307
339This function creates an index entry in the index represented by parent, 308This function creates an index entry in the index represented by parent,
340filling in the index entry by calling the operations pointed to by def. 309filling in the index entry by calling the operations pointed to by def.
341 310
311A unique key that represents the object within the parent must be pointed to by
312index_key and is of length index_key_len.
313
314An optional blob of auxiliary data that is to be stored within the cache can be
315pointed to with aux_data and should be of length aux_data_len. This would
316typically be used for storing coherency data.
317
318The netfs may pass an arbitrary value in netfs_data and this will be presented
319to it in the event of any calling back. This may also be used in tracing or
320logging of messages.
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
342Note that this function never returns an error - all errors are handled 326Note that this function never returns an error - all errors are handled
343internally. 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
344acceptable 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
@@ -355,30 +339,24 @@ must be enabled to do anything with it. A disabled cookie can be enabled by
355calling fscache_enable_cookie() (see below). 339calling fscache_enable_cookie() (see below).
356 340
357For example, with AFS, a cell would be added to the primary index. This index 341For example, with AFS, a cell would be added to the primary index. This index
358entry would have a dependent inode containing a volume location index for the 342entry would have a dependent inode containing volume mappings within this cell:
359volume mappings within this cell:
360 343
361 cell->cache = 344 cell->cache =
362 fscache_acquire_cookie(afs_cache_netfs.primary_index, 345 fscache_acquire_cookie(afs_cache_netfs.primary_index,
363 &afs_cell_cache_index_def, 346 &afs_cell_cache_index_def,
364 cell, true); 347 cell->name, strlen(cell->name),
365 348 NULL, 0,
366Then when a volume location was accessed, it would be entered into the cell's 349 cell, 0, true);
367index and an inode would be allocated that acts as a volume type and hash chain
368combination:
369 350
370 vlocation->cache = 351And then a particular volume could be added to that index by ID, creating
371 fscache_acquire_cookie(cell->cache, 352another index for vnodes (AFS inode equivalents):
372 &afs_vlocation_cache_index_def,
373 vlocation, true);
374
375And then a particular flavour of volume (R/O for example) could be added to
376that index, creating another index for vnodes (AFS inode equivalents):
377 353
378 volume->cache = 354 volume->cache =
379 fscache_acquire_cookie(vlocation->cache, 355 fscache_acquire_cookie(volume->cell->cache,
380 &afs_volume_cache_index_def, 356 &afs_volume_cache_index_def,
381 volume, true); 357 &volume->vid, sizeof(volume->vid),
358 NULL, 0,
359 volume, 0, true);
382 360
383 361
384====================== 362======================
@@ -392,7 +370,9 @@ the object definition should be something other than index type.
392 vnode->cache = 370 vnode->cache =
393 fscache_acquire_cookie(volume->cache, 371 fscache_acquire_cookie(volume->cache,
394 &afs_vnode_cache_object_def, 372 &afs_vnode_cache_object_def,
395 vnode, true); 373 &key, sizeof(key),
374 &aux, sizeof(aux),
375 vnode, vnode->status.size, true);
396 376
397 377
398================================= 378=================================
@@ -408,7 +388,9 @@ it would be some other type of object such as a data file.
408 xattr->cache = 388 xattr->cache =
409 fscache_acquire_cookie(vnode->cache, 389 fscache_acquire_cookie(vnode->cache,
410 &afs_xattr_cache_object_def, 390 &afs_xattr_cache_object_def,
411 xattr, true); 391 &xattr->name, strlen(xattr->name),
392 NULL, 0,
393 xattr, strlen(xattr->val), true);
412 394
413Miscellaneous objects might be used to store extended attributes or directory 395Miscellaneous objects might be used to store extended attributes or directory
414entries for example. 396entries for example.
@@ -425,8 +407,7 @@ cache to adjust its metadata for data tracking appropriately:
425 int fscache_attr_changed(struct fscache_cookie *cookie); 407 int fscache_attr_changed(struct fscache_cookie *cookie);
426 408
427The 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
428space to allocate any extra metadata required in the cache. The attributes 410space to allocate any extra metadata required in the cache.
429will be accessed with the get_attr() cookie definition operation.
430 411
431Note 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
432be rebuffed with -ENOBUFS. 413be rebuffed with -ENOBUFS.
@@ -551,12 +532,13 @@ written back to the cache:
551 532
552 int fscache_write_page(struct fscache_cookie *cookie, 533 int fscache_write_page(struct fscache_cookie *cookie,
553 struct page *page, 534 struct page *page,
535 loff_t object_size,
554 gfp_t gfp); 536 gfp_t gfp);
555 537
556The 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
557contain 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),
558and 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
559satisfied. 541control how any memory allocations made are satisfied.
560 542
561The 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
562been uncached before writing is performed. 544been uncached before writing is performed.
@@ -717,21 +699,23 @@ INDEX AND DATA FILE CONSISTENCY
717To find out whether auxiliary data for an object is up to data within the 699To find out whether auxiliary data for an object is up to data within the
718cache, the following function can be called: 700cache, the following function can be called:
719 701
720 int fscache_check_consistency(struct fscache_cookie *cookie) 702 int fscache_check_consistency(struct fscache_cookie *cookie,
703 const void *aux_data);
721 704
722This will call back to the netfs to check whether the auxiliary data associated 705This will call back to the netfs to check whether the auxiliary data associated
723with a cookie is correct. It returns 0 if it is and -ESTALE if it isn't; it 706with a cookie is correct; if aux_data is non-NULL, it will update the auxiliary
724may also return -ENOMEM and -ERESTARTSYS. 707data buffer first. It returns 0 if it is and -ESTALE if it isn't; it may also
708return -ENOMEM and -ERESTARTSYS.
725 709
726To request an update of the index data for an index or other object, the 710To request an update of the index data for an index or other object, the
727following function should be called: 711following function should be called:
728 712
729 void fscache_update_cookie(struct fscache_cookie *cookie); 713 void fscache_update_cookie(struct fscache_cookie *cookie,
714 const void *aux_data);
730 715
731This function will refer back to the netfs_data pointer stored in the cookie by 716This function will update the cookie's auxiliary data buffer from aux_data if
732the acquisition function to obtain the data to write into each revised index 717that is non-NULL and then schedule this to be stored on disk. The update
733entry. The update method in the parent index definition will be called to 718method in the parent index definition will be called to transfer the data.
734transfer the data.
735 719
736Note that partial updates may happen automatically at other times, such as when 720Note that partial updates may happen automatically at other times, such as when
737data blocks are added to a data file object. 721data blocks are added to a data file object.
@@ -748,10 +732,11 @@ still possible to uncache pages and relinquish the cookie.
748 732
749The 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
750can be enabled or disabled later. To disable a cookie, call: 734can be enabled or disabled later. To disable a cookie, call:
751 735
752 void fscache_disable_cookie(struct fscache_cookie *cookie, 736 void fscache_disable_cookie(struct fscache_cookie *cookie,
737 const void *aux_data,
753 bool invalidate); 738 bool invalidate);
754 739
755If 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
756enable and disable ops, marks the cookie as being disabled, discards or 741enable and disable ops, marks the cookie as being disabled, discards or
757invalidates any backing objects and waits for cessation of activity on any 742invalidates any backing objects and waits for cessation of activity on any
@@ -760,13 +745,15 @@ associated object before unlocking the cookie.
760All possible failures are handled internally. The caller should consider 745All possible failures are handled internally. The caller should consider
761calling fscache_uncache_all_inode_pages() afterwards to make sure all page 746calling fscache_uncache_all_inode_pages() afterwards to make sure all page
762markings are cleared up. 747markings are cleared up.
763 748
764Cookies can be enabled or reenabled with: 749Cookies can be enabled or reenabled with:
765 750
766 void fscache_enable_cookie(struct fscache_cookie *cookie, 751 void fscache_enable_cookie(struct fscache_cookie *cookie,
752 const void *aux_data,
753 loff_t object_size,
767 bool (*can_enable)(void *data), 754 bool (*can_enable)(void *data),
768 void *data) 755 void *data)
769 756
770If 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
771enable 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
772cookie, will begin the procedure of acquiring backing objects. 759cookie, will begin the procedure of acquiring backing objects.
@@ -777,6 +764,12 @@ ruling as to whether or not enablement should actually be permitted to begin.
777All possible failures are handled internally. The cookie will only be marked 764All possible failures are handled internally. The cookie will only be marked
778as enabled if provisional backing objects are allocated. 765as enabled if provisional backing objects are allocated.
779 766
767The object's data size is updated from object_size and is passed to the
768->check_aux() function.
769
770In both cases, the cookie's auxiliary data buffer is updated from aux_data if
771that is non-NULL inside the enablement lock before proceeding.
772
780 773
781=============================== 774===============================
782MISCELLANEOUS COOKIE OPERATIONS 775MISCELLANEOUS COOKIE OPERATIONS
@@ -823,6 +816,7 @@ COOKIE UNREGISTRATION
823To get rid of a cookie, this function should be called. 816To get rid of a cookie, this function should be called.
824 817
825 void fscache_relinquish_cookie(struct fscache_cookie *cookie, 818 void fscache_relinquish_cookie(struct fscache_cookie *cookie,
819 const void *aux_data,
826 bool retire); 820 bool retire);
827 821
828If retire is non-zero, then the object will be marked for recycling, and all 822If retire is non-zero, then the object will be marked for recycling, and all
@@ -833,6 +827,9 @@ If retire is zero, then the object may be available again when next the
833acquisition function is called. Retirement here will overrule the pinning on a 827acquisition function is called. Retirement here will overrule the pinning on a
834cookie. 828cookie.
835 829
830The cookie's auxiliary data will be updated from aux_data if that is non-NULL
831so that the cache can lazily update it on disk.
832
836One very important note - relinquish must NOT be called for a cookie unless all 833One very important note - relinquish must NOT be called for a cookie unless all
837the cookies for "child" indices, objects and pages have been relinquished 834the cookies for "child" indices, objects and pages have been relinquished
838first. 835first.
diff --git a/fs/9p/cache.c b/fs/9p/cache.c
index 64c58eb26159..9eb34701a566 100644
--- a/fs/9p/cache.c
+++ b/fs/9p/cache.c
@@ -55,42 +55,27 @@ int v9fs_random_cachetag(struct v9fs_session_info *v9ses)
55 return scnprintf(v9ses->cachetag, CACHETAG_LEN, "%lu", jiffies); 55 return scnprintf(v9ses->cachetag, CACHETAG_LEN, "%lu", jiffies);
56} 56}
57 57
58static uint16_t v9fs_cache_session_get_key(const void *cookie_netfs_data,
59 void *buffer, uint16_t bufmax)
60{
61 struct v9fs_session_info *v9ses;
62 uint16_t klen = 0;
63
64 v9ses = (struct v9fs_session_info *)cookie_netfs_data;
65 p9_debug(P9_DEBUG_FSC, "session %p buf %p size %u\n",
66 v9ses, buffer, bufmax);
67
68 if (v9ses->cachetag)
69 klen = strlen(v9ses->cachetag);
70
71 if (klen > bufmax)
72 return 0;
73
74 memcpy(buffer, v9ses->cachetag, klen);
75 p9_debug(P9_DEBUG_FSC, "cache session tag %s\n", v9ses->cachetag);
76 return klen;
77}
78
79const struct fscache_cookie_def v9fs_cache_session_index_def = { 58const struct fscache_cookie_def v9fs_cache_session_index_def = {
80 .name = "9P.session", 59 .name = "9P.session",
81 .type = FSCACHE_COOKIE_TYPE_INDEX, 60 .type = FSCACHE_COOKIE_TYPE_INDEX,
82 .get_key = v9fs_cache_session_get_key,
83}; 61};
84 62
85void v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses) 63void v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses)
86{ 64{
87 /* If no cache session tag was specified, we generate a random one. */ 65 /* If no cache session tag was specified, we generate a random one. */
88 if (!v9ses->cachetag) 66 if (!v9ses->cachetag) {
89 v9fs_random_cachetag(v9ses); 67 if (v9fs_random_cachetag(v9ses) < 0) {
68 v9ses->fscache = NULL;
69 return;
70 }
71 }
90 72
91 v9ses->fscache = fscache_acquire_cookie(v9fs_cache_netfs.primary_index, 73 v9ses->fscache = fscache_acquire_cookie(v9fs_cache_netfs.primary_index,
92 &v9fs_cache_session_index_def, 74 &v9fs_cache_session_index_def,
93 v9ses, true); 75 v9ses->cachetag,
76 strlen(v9ses->cachetag),
77 NULL, 0,
78 v9ses, 0, true);
94 p9_debug(P9_DEBUG_FSC, "session %p get cookie %p\n", 79 p9_debug(P9_DEBUG_FSC, "session %p get cookie %p\n",
95 v9ses, v9ses->fscache); 80 v9ses, v9ses->fscache);
96} 81}
@@ -99,45 +84,15 @@ void v9fs_cache_session_put_cookie(struct v9fs_session_info *v9ses)
99{ 84{
100 p9_debug(P9_DEBUG_FSC, "session %p put cookie %p\n", 85 p9_debug(P9_DEBUG_FSC, "session %p put cookie %p\n",
101 v9ses, v9ses->fscache); 86 v9ses, v9ses->fscache);
102 fscache_relinquish_cookie(v9ses->fscache, 0); 87 fscache_relinquish_cookie(v9ses->fscache, NULL, false);
103 v9ses->fscache = NULL; 88 v9ses->fscache = NULL;
104} 89}
105 90
106
107static uint16_t v9fs_cache_inode_get_key(const void *cookie_netfs_data,
108 void *buffer, uint16_t bufmax)
109{
110 const struct v9fs_inode *v9inode = cookie_netfs_data;
111 memcpy(buffer, &v9inode->qid.path, sizeof(v9inode->qid.path));
112 p9_debug(P9_DEBUG_FSC, "inode %p get key %llu\n",
113 &v9inode->vfs_inode, v9inode->qid.path);
114 return sizeof(v9inode->qid.path);
115}
116
117static void v9fs_cache_inode_get_attr(const void *cookie_netfs_data,
118 uint64_t *size)
119{
120 const struct v9fs_inode *v9inode = cookie_netfs_data;
121 *size = i_size_read(&v9inode->vfs_inode);
122
123 p9_debug(P9_DEBUG_FSC, "inode %p get attr %llu\n",
124 &v9inode->vfs_inode, *size);
125}
126
127static uint16_t v9fs_cache_inode_get_aux(const void *cookie_netfs_data,
128 void *buffer, uint16_t buflen)
129{
130 const struct v9fs_inode *v9inode = cookie_netfs_data;
131 memcpy(buffer, &v9inode->qid.version, sizeof(v9inode->qid.version));
132 p9_debug(P9_DEBUG_FSC, "inode %p get aux %u\n",
133 &v9inode->vfs_inode, v9inode->qid.version);
134 return sizeof(v9inode->qid.version);
135}
136
137static enum 91static enum
138fscache_checkaux v9fs_cache_inode_check_aux(void *cookie_netfs_data, 92fscache_checkaux v9fs_cache_inode_check_aux(void *cookie_netfs_data,
139 const void *buffer, 93 const void *buffer,
140 uint16_t buflen) 94 uint16_t buflen,
95 loff_t object_size)
141{ 96{
142 const struct v9fs_inode *v9inode = cookie_netfs_data; 97 const struct v9fs_inode *v9inode = cookie_netfs_data;
143 98
@@ -154,9 +109,6 @@ fscache_checkaux v9fs_cache_inode_check_aux(void *cookie_netfs_data,
154const struct fscache_cookie_def v9fs_cache_inode_index_def = { 109const struct fscache_cookie_def v9fs_cache_inode_index_def = {
155 .name = "9p.inode", 110 .name = "9p.inode",
156 .type = FSCACHE_COOKIE_TYPE_DATAFILE, 111 .type = FSCACHE_COOKIE_TYPE_DATAFILE,
157 .get_key = v9fs_cache_inode_get_key,
158 .get_attr = v9fs_cache_inode_get_attr,
159 .get_aux = v9fs_cache_inode_get_aux,
160 .check_aux = v9fs_cache_inode_check_aux, 112 .check_aux = v9fs_cache_inode_check_aux,
161}; 113};
162 114
@@ -175,7 +127,13 @@ void v9fs_cache_inode_get_cookie(struct inode *inode)
175 v9ses = v9fs_inode2v9ses(inode); 127 v9ses = v9fs_inode2v9ses(inode);
176 v9inode->fscache = fscache_acquire_cookie(v9ses->fscache, 128 v9inode->fscache = fscache_acquire_cookie(v9ses->fscache,
177 &v9fs_cache_inode_index_def, 129 &v9fs_cache_inode_index_def,
178 v9inode, true); 130 &v9inode->qid.path,
131 sizeof(v9inode->qid.path),
132 &v9inode->qid.version,
133 sizeof(v9inode->qid.version),
134 v9inode,
135 i_size_read(&v9inode->vfs_inode),
136 true);
179 137
180 p9_debug(P9_DEBUG_FSC, "inode %p get cookie %p\n", 138 p9_debug(P9_DEBUG_FSC, "inode %p get cookie %p\n",
181 inode, v9inode->fscache); 139 inode, v9inode->fscache);
@@ -190,7 +148,8 @@ void v9fs_cache_inode_put_cookie(struct inode *inode)
190 p9_debug(P9_DEBUG_FSC, "inode %p put cookie %p\n", 148 p9_debug(P9_DEBUG_FSC, "inode %p put cookie %p\n",
191 inode, v9inode->fscache); 149 inode, v9inode->fscache);
192 150
193 fscache_relinquish_cookie(v9inode->fscache, 0); 151 fscache_relinquish_cookie(v9inode->fscache, &v9inode->qid.version,
152 false);
194 v9inode->fscache = NULL; 153 v9inode->fscache = NULL;
195} 154}
196 155
@@ -203,7 +162,7 @@ void v9fs_cache_inode_flush_cookie(struct inode *inode)
203 p9_debug(P9_DEBUG_FSC, "inode %p flush cookie %p\n", 162 p9_debug(P9_DEBUG_FSC, "inode %p flush cookie %p\n",
204 inode, v9inode->fscache); 163 inode, v9inode->fscache);
205 164
206 fscache_relinquish_cookie(v9inode->fscache, 1); 165 fscache_relinquish_cookie(v9inode->fscache, NULL, true);
207 v9inode->fscache = NULL; 166 v9inode->fscache = NULL;
208} 167}
209 168
@@ -236,12 +195,18 @@ void v9fs_cache_inode_reset_cookie(struct inode *inode)
236 old = v9inode->fscache; 195 old = v9inode->fscache;
237 196
238 mutex_lock(&v9inode->fscache_lock); 197 mutex_lock(&v9inode->fscache_lock);
239 fscache_relinquish_cookie(v9inode->fscache, 1); 198 fscache_relinquish_cookie(v9inode->fscache, NULL, true);
240 199
241 v9ses = v9fs_inode2v9ses(inode); 200 v9ses = v9fs_inode2v9ses(inode);
242 v9inode->fscache = fscache_acquire_cookie(v9ses->fscache, 201 v9inode->fscache = fscache_acquire_cookie(v9ses->fscache,
243 &v9fs_cache_inode_index_def, 202 &v9fs_cache_inode_index_def,
244 v9inode, true); 203 &v9inode->qid.path,
204 sizeof(v9inode->qid.path),
205 &v9inode->qid.version,
206 sizeof(v9inode->qid.version),
207 v9inode,
208 i_size_read(&v9inode->vfs_inode),
209 true);
245 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",
246 inode, old, v9inode->fscache); 211 inode, old, v9inode->fscache);
247 212
@@ -367,7 +332,8 @@ void __v9fs_readpage_to_fscache(struct inode *inode, struct page *page)
367 const struct v9fs_inode *v9inode = V9FS_I(inode); 332 const struct v9fs_inode *v9inode = V9FS_I(inode);
368 333
369 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);
370 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);
371 p9_debug(P9_DEBUG_FSC, "ret = %d\n", ret); 337 p9_debug(P9_DEBUG_FSC, "ret = %d\n", ret);
372 if (ret != 0) 338 if (ret != 0)
373 v9fs_uncache_page(inode, page); 339 v9fs_uncache_page(inode, page);
diff --git a/fs/afs/cache.c b/fs/afs/cache.c
index f62ff71d28c9..b1c31ec4523a 100644
--- a/fs/afs/cache.c
+++ b/fs/afs/cache.c
@@ -12,167 +12,39 @@
12#include <linux/sched.h> 12#include <linux/sched.h>
13#include "internal.h" 13#include "internal.h"
14 14
15static uint16_t afs_cell_cache_get_key(const void *cookie_netfs_data,
16 void *buffer, uint16_t buflen);
17static uint16_t afs_volume_cache_get_key(const void *cookie_netfs_data,
18 void *buffer, uint16_t buflen);
19
20static uint16_t afs_vnode_cache_get_key(const void *cookie_netfs_data,
21 void *buffer, uint16_t buflen);
22static void afs_vnode_cache_get_attr(const void *cookie_netfs_data,
23 uint64_t *size);
24static uint16_t afs_vnode_cache_get_aux(const void *cookie_netfs_data,
25 void *buffer, uint16_t buflen);
26static 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,
27 const void *buffer, 16 const void *buffer,
28 uint16_t buflen); 17 uint16_t buflen,
18 loff_t object_size);
29 19
30struct fscache_netfs afs_cache_netfs = { 20struct fscache_netfs afs_cache_netfs = {
31 .name = "afs", 21 .name = "afs",
32 .version = 1, 22 .version = 2,
33}; 23};
34 24
35struct fscache_cookie_def afs_cell_cache_index_def = { 25struct fscache_cookie_def afs_cell_cache_index_def = {
36 .name = "AFS.cell", 26 .name = "AFS.cell",
37 .type = FSCACHE_COOKIE_TYPE_INDEX, 27 .type = FSCACHE_COOKIE_TYPE_INDEX,
38 .get_key = afs_cell_cache_get_key,
39}; 28};
40 29
41struct fscache_cookie_def afs_volume_cache_index_def = { 30struct fscache_cookie_def afs_volume_cache_index_def = {
42 .name = "AFS.volume", 31 .name = "AFS.volume",
43 .type = FSCACHE_COOKIE_TYPE_INDEX, 32 .type = FSCACHE_COOKIE_TYPE_INDEX,
44 .get_key = afs_volume_cache_get_key,
45}; 33};
46 34
47struct fscache_cookie_def afs_vnode_cache_index_def = { 35struct fscache_cookie_def afs_vnode_cache_index_def = {
48 .name = "AFS.vnode", 36 .name = "AFS.vnode",
49 .type = FSCACHE_COOKIE_TYPE_DATAFILE, 37 .type = FSCACHE_COOKIE_TYPE_DATAFILE,
50 .get_key = afs_vnode_cache_get_key, 38 .check_aux = afs_vnode_cache_check_aux,
51 .get_attr = afs_vnode_cache_get_attr,
52 .get_aux = afs_vnode_cache_get_aux,
53 .check_aux = afs_vnode_cache_check_aux,
54}; 39};
55 40
56/* 41/*
57 * set the key for the index entry
58 */
59static uint16_t afs_cell_cache_get_key(const void *cookie_netfs_data,
60 void *buffer, uint16_t bufmax)
61{
62 const struct afs_cell *cell = cookie_netfs_data;
63 uint16_t klen;
64
65 _enter("%p,%p,%u", cell, buffer, bufmax);
66
67 klen = strlen(cell->name);
68 if (klen > bufmax)
69 return 0;
70
71 memcpy(buffer, cell->name, klen);
72 return klen;
73}
74
75/*****************************************************************************/
76/*
77 * set the key for the volume index entry
78 */
79static uint16_t afs_volume_cache_get_key(const void *cookie_netfs_data,
80 void *buffer, uint16_t bufmax)
81{
82 const struct afs_volume *volume = cookie_netfs_data;
83 struct {
84 u64 volid;
85 } __packed key;
86
87 _enter("{%u},%p,%u", volume->type, buffer, bufmax);
88
89 if (bufmax < sizeof(key))
90 return 0;
91
92 key.volid = volume->vid;
93 memcpy(buffer, &key, sizeof(key));
94 return sizeof(key);
95}
96
97/*****************************************************************************/
98/*
99 * set the key for the index entry
100 */
101static uint16_t afs_vnode_cache_get_key(const void *cookie_netfs_data,
102 void *buffer, uint16_t bufmax)
103{
104 const struct afs_vnode *vnode = cookie_netfs_data;
105 struct {
106 u32 vnode_id[3];
107 } __packed key;
108
109 _enter("{%x,%x,%llx},%p,%u",
110 vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version,
111 buffer, bufmax);
112
113 /* Allow for a 96-bit key */
114 memset(&key, 0, sizeof(key));
115 key.vnode_id[0] = vnode->fid.vnode;
116 key.vnode_id[1] = 0;
117 key.vnode_id[2] = 0;
118
119 if (sizeof(key) > bufmax)
120 return 0;
121
122 memcpy(buffer, &key, sizeof(key));
123 return sizeof(key);
124}
125
126/*
127 * provide updated file attributes
128 */
129static void afs_vnode_cache_get_attr(const void *cookie_netfs_data,
130 uint64_t *size)
131{
132 const struct afs_vnode *vnode = cookie_netfs_data;
133
134 _enter("{%x,%x,%llx},",
135 vnode->fid.vnode, vnode->fid.unique,
136 vnode->status.data_version);
137
138 *size = vnode->status.size;
139}
140
141struct afs_vnode_cache_aux {
142 u64 data_version;
143 u32 fid_unique;
144} __packed;
145
146/*
147 * provide new auxiliary cache data
148 */
149static uint16_t afs_vnode_cache_get_aux(const void *cookie_netfs_data,
150 void *buffer, uint16_t bufmax)
151{
152 const struct afs_vnode *vnode = cookie_netfs_data;
153 struct afs_vnode_cache_aux aux;
154
155 _enter("{%x,%x,%Lx},%p,%u",
156 vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version,
157 buffer, bufmax);
158
159 memset(&aux, 0, sizeof(aux));
160 aux.data_version = vnode->status.data_version;
161 aux.fid_unique = vnode->fid.unique;
162
163 if (bufmax < sizeof(aux))
164 return 0;
165
166 memcpy(buffer, &aux, sizeof(aux));
167 return sizeof(aux);
168}
169
170/*
171 * 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
172 */ 43 */
173static 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,
174 const void *buffer, 45 const void *buffer,
175 uint16_t buflen) 46 uint16_t buflen,
47 loff_t object_size)
176{ 48{
177 struct afs_vnode *vnode = cookie_netfs_data; 49 struct afs_vnode *vnode = cookie_netfs_data;
178 struct afs_vnode_cache_aux aux; 50 struct afs_vnode_cache_aux aux;
@@ -189,12 +61,6 @@ static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data,
189 return FSCACHE_CHECKAUX_OBSOLETE; 61 return FSCACHE_CHECKAUX_OBSOLETE;
190 } 62 }
191 63
192 if (vnode->fid.unique != aux.fid_unique) {
193 _leave(" = OBSOLETE [uniq %x != %x]",
194 aux.fid_unique, vnode->fid.unique);
195 return FSCACHE_CHECKAUX_OBSOLETE;
196 }
197
198 if (vnode->status.data_version != aux.data_version) { 64 if (vnode->status.data_version != aux.data_version) {
199 _leave(" = OBSOLETE [vers %llx != %llx]", 65 _leave(" = OBSOLETE [vers %llx != %llx]",
200 aux.data_version, vnode->status.data_version); 66 aux.data_version, vnode->status.data_version);
diff --git a/fs/afs/cell.c b/fs/afs/cell.c
index 3d2c5e0e854e..4235a05afc76 100644
--- a/fs/afs/cell.c
+++ b/fs/afs/cell.c
@@ -522,7 +522,9 @@ static int afs_activate_cell(struct afs_net *net, struct afs_cell *cell)
522#ifdef CONFIG_AFS_FSCACHE 522#ifdef CONFIG_AFS_FSCACHE
523 cell->cache = fscache_acquire_cookie(afs_cache_netfs.primary_index, 523 cell->cache = fscache_acquire_cookie(afs_cache_netfs.primary_index,
524 &afs_cell_cache_index_def, 524 &afs_cell_cache_index_def,
525 cell, true); 525 cell->name, strlen(cell->name),
526 NULL, 0,
527 cell, 0, true);
526#endif 528#endif
527 ret = afs_proc_cell_setup(net, cell); 529 ret = afs_proc_cell_setup(net, cell);
528 if (ret < 0) 530 if (ret < 0)
@@ -547,7 +549,7 @@ static void afs_deactivate_cell(struct afs_net *net, struct afs_cell *cell)
547 spin_unlock(&net->proc_cells_lock); 549 spin_unlock(&net->proc_cells_lock);
548 550
549#ifdef CONFIG_AFS_FSCACHE 551#ifdef CONFIG_AFS_FSCACHE
550 fscache_relinquish_cookie(cell->cache, 0); 552 fscache_relinquish_cookie(cell->cache, NULL, false);
551 cell->cache = NULL; 553 cell->cache = NULL;
552#endif 554#endif
553 555
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 6b39d0255b72..65c5b1edd338 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -243,6 +243,33 @@ struct inode *afs_iget_pseudo_dir(struct super_block *sb, bool root)
243} 243}
244 244
245/* 245/*
246 * Get a cache cookie for an inode.
247 */
248static void afs_get_inode_cache(struct afs_vnode *vnode)
249{
250#ifdef CONFIG_AFS_FSCACHE
251 struct {
252 u32 vnode_id;
253 u32 unique;
254 u32 vnode_id_ext[2]; /* Allow for a 96-bit key */
255 } __packed key;
256 struct afs_vnode_cache_aux aux;
257
258 key.vnode_id = vnode->fid.vnode;
259 key.unique = vnode->fid.unique;
260 key.vnode_id_ext[0] = 0;
261 key.vnode_id_ext[1] = 0;
262 aux.data_version = vnode->status.data_version;
263
264 vnode->cache = fscache_acquire_cookie(vnode->volume->cache,
265 &afs_vnode_cache_index_def,
266 &key, sizeof(key),
267 &aux, sizeof(aux),
268 vnode, vnode->status.size, true);
269#endif
270}
271
272/*
246 * inode retrieval 273 * inode retrieval
247 */ 274 */
248struct inode *afs_iget(struct super_block *sb, struct key *key, 275struct inode *afs_iget(struct super_block *sb, struct key *key,
@@ -307,11 +334,7 @@ struct inode *afs_iget(struct super_block *sb, struct key *key,
307 /* set up caching before mapping the status, as map-status reads the 334 /* set up caching before mapping the status, as map-status reads the
308 * first page of symlinks to see if they're really mountpoints */ 335 * first page of symlinks to see if they're really mountpoints */
309 inode->i_size = vnode->status.size; 336 inode->i_size = vnode->status.size;
310#ifdef CONFIG_AFS_FSCACHE 337 afs_get_inode_cache(vnode);
311 vnode->cache = fscache_acquire_cookie(vnode->volume->cache,
312 &afs_vnode_cache_index_def,
313 vnode, true);
314#endif
315 338
316 ret = afs_inode_map_status(vnode, key); 339 ret = afs_inode_map_status(vnode, key);
317 if (ret < 0) 340 if (ret < 0)
@@ -327,7 +350,7 @@ struct inode *afs_iget(struct super_block *sb, struct key *key,
327 /* failure */ 350 /* failure */
328bad_inode: 351bad_inode:
329#ifdef CONFIG_AFS_FSCACHE 352#ifdef CONFIG_AFS_FSCACHE
330 fscache_relinquish_cookie(vnode->cache, 0); 353 fscache_relinquish_cookie(vnode->cache, NULL, ret == -ENOENT);
331 vnode->cache = NULL; 354 vnode->cache = NULL;
332#endif 355#endif
333 iget_failed(inode); 356 iget_failed(inode);
@@ -343,6 +366,10 @@ void afs_zap_data(struct afs_vnode *vnode)
343{ 366{
344 _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode); 367 _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode);
345 368
369#ifdef CONFIG_AFS_FSCACHE
370 fscache_invalidate(vnode->cache);
371#endif
372
346 /* nuke all the non-dirty pages that aren't locked, mapped or being 373 /* nuke all the non-dirty pages that aren't locked, mapped or being
347 * written back in a regular file and completely discard the pages in a 374 * written back in a regular file and completely discard the pages in a
348 * directory or symlink */ 375 * directory or symlink */
@@ -507,8 +534,14 @@ void afs_evict_inode(struct inode *inode)
507 } 534 }
508 535
509#ifdef CONFIG_AFS_FSCACHE 536#ifdef CONFIG_AFS_FSCACHE
510 fscache_relinquish_cookie(vnode->cache, 0); 537 {
511 vnode->cache = NULL; 538 struct afs_vnode_cache_aux aux;
539
540 aux.data_version = vnode->status.data_version;
541 fscache_relinquish_cookie(vnode->cache, &aux,
542 test_bit(AFS_VNODE_DELETED, &vnode->flags));
543 vnode->cache = NULL;
544 }
512#endif 545#endif
513 546
514 afs_put_permits(vnode->permit_cache); 547 afs_put_permits(vnode->permit_cache);
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index 72217170b155..a6a1d75eee41 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -559,6 +559,13 @@ struct afs_fs_cursor {
559#define AFS_FS_CURSOR_NO_VSLEEP 0x0020 /* Set to prevent sleep on VBUSY, VOFFLINE, ... */ 559#define AFS_FS_CURSOR_NO_VSLEEP 0x0020 /* Set to prevent sleep on VBUSY, VOFFLINE, ... */
560}; 560};
561 561
562/*
563 * Cache auxiliary data.
564 */
565struct afs_vnode_cache_aux {
566 u64 data_version;
567} __packed;
568
562#include <trace/events/afs.h> 569#include <trace/events/afs.h>
563 570
564/*****************************************************************************/ 571/*****************************************************************************/
diff --git a/fs/afs/volume.c b/fs/afs/volume.c
index b517a588781f..3037bd01f617 100644
--- a/fs/afs/volume.c
+++ b/fs/afs/volume.c
@@ -225,7 +225,9 @@ void afs_activate_volume(struct afs_volume *volume)
225#ifdef CONFIG_AFS_FSCACHE 225#ifdef CONFIG_AFS_FSCACHE
226 volume->cache = fscache_acquire_cookie(volume->cell->cache, 226 volume->cache = fscache_acquire_cookie(volume->cell->cache,
227 &afs_volume_cache_index_def, 227 &afs_volume_cache_index_def,
228 volume, true); 228 &volume->vid, sizeof(volume->vid),
229 NULL, 0,
230 volume, 0, true);
229#endif 231#endif
230 232
231 write_lock(&volume->cell->proc_lock); 233 write_lock(&volume->cell->proc_lock);
@@ -245,7 +247,7 @@ void afs_deactivate_volume(struct afs_volume *volume)
245 write_unlock(&volume->cell->proc_lock); 247 write_unlock(&volume->cell->proc_lock);
246 248
247#ifdef CONFIG_AFS_FSCACHE 249#ifdef CONFIG_AFS_FSCACHE
248 fscache_relinquish_cookie(volume->cache, 250 fscache_relinquish_cookie(volume->cache, NULL,
249 test_bit(AFS_VOLUME_DELETED, &volume->flags)); 251 test_bit(AFS_VOLUME_DELETED, &volume->flags));
250 volume->cache = NULL; 252 volume->cache = NULL;
251#endif 253#endif
diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
index e7f16a77a22a..222bc5d8b62c 100644
--- a/fs/cachefiles/interface.c
+++ b/fs/cachefiles/interface.c
@@ -32,7 +32,7 @@ static struct fscache_object *cachefiles_alloc_object(
32 struct cachefiles_cache *cache; 32 struct cachefiles_cache *cache;
33 struct cachefiles_xattr *auxdata; 33 struct cachefiles_xattr *auxdata;
34 unsigned keylen, auxlen; 34 unsigned keylen, auxlen;
35 void *buffer; 35 void *buffer, *p;
36 char *key; 36 char *key;
37 37
38 cache = container_of(_cache, struct cachefiles_cache, cache); 38 cache = container_of(_cache, struct cachefiles_cache, cache);
@@ -65,8 +65,12 @@ static struct fscache_object *cachefiles_alloc_object(
65 if (!buffer) 65 if (!buffer)
66 goto nomem_buffer; 66 goto nomem_buffer;
67 67
68 keylen = cookie->def->get_key(cookie->netfs_data, buffer + 2, 512); 68 keylen = cookie->key_len;
69 ASSERTCMP(keylen, <, 512); 69 if (keylen <= sizeof(cookie->inline_key))
70 p = cookie->inline_key;
71 else
72 p = cookie->key;
73 memcpy(buffer + 2, p, keylen);
70 74
71 *(uint16_t *)buffer = keylen; 75 *(uint16_t *)buffer = keylen;
72 ((char *)buffer)[keylen + 2] = 0; 76 ((char *)buffer)[keylen + 2] = 0;
@@ -80,15 +84,17 @@ static struct fscache_object *cachefiles_alloc_object(
80 84
81 /* get hold of the auxiliary data and prepend the object type */ 85 /* get hold of the auxiliary data and prepend the object type */
82 auxdata = buffer; 86 auxdata = buffer;
83 auxlen = 0; 87 auxlen = cookie->aux_len;
84 if (cookie->def->get_aux) { 88 if (auxlen) {
85 auxlen = cookie->def->get_aux(cookie->netfs_data, 89 if (auxlen <= sizeof(cookie->inline_aux))
86 auxdata->data, 511); 90 p = cookie->inline_aux;
87 ASSERTCMP(auxlen, <, 511); 91 else
92 p = cookie->aux;
93 memcpy(auxdata->data, p, auxlen);
88 } 94 }
89 95
90 auxdata->len = auxlen + 1; 96 auxdata->len = auxlen + 1;
91 auxdata->type = cookie->def->type; 97 auxdata->type = cookie->type;
92 98
93 lookup_data->auxdata = auxdata; 99 lookup_data->auxdata = auxdata;
94 lookup_data->key = key; 100 lookup_data->key = key;
@@ -177,10 +183,12 @@ static void cachefiles_lookup_complete(struct fscache_object *_object)
177 * increment the usage count on an inode object (may fail if unmounting) 183 * increment the usage count on an inode object (may fail if unmounting)
178 */ 184 */
179static 185static
180struct fscache_object *cachefiles_grab_object(struct fscache_object *_object) 186struct fscache_object *cachefiles_grab_object(struct fscache_object *_object,
187 enum fscache_obj_ref_trace why)
181{ 188{
182 struct cachefiles_object *object = 189 struct cachefiles_object *object =
183 container_of(_object, struct cachefiles_object, fscache); 190 container_of(_object, struct cachefiles_object, fscache);
191 int u;
184 192
185 _enter("{OBJ%x,%d}", _object->debug_id, atomic_read(&object->usage)); 193 _enter("{OBJ%x,%d}", _object->debug_id, atomic_read(&object->usage));
186 194
@@ -188,7 +196,9 @@ struct fscache_object *cachefiles_grab_object(struct fscache_object *_object)
188 ASSERT((atomic_read(&object->usage) & 0xffff0000) != 0x6b6b0000); 196 ASSERT((atomic_read(&object->usage) & 0xffff0000) != 0x6b6b0000);
189#endif 197#endif
190 198
191 atomic_inc(&object->usage); 199 u = atomic_inc_return(&object->usage);
200 trace_cachefiles_ref(object, _object->cookie,
201 (enum cachefiles_obj_ref_trace)why, u);
192 return &object->fscache; 202 return &object->fscache;
193} 203}
194 204
@@ -202,6 +212,7 @@ static void cachefiles_update_object(struct fscache_object *_object)
202 struct cachefiles_cache *cache; 212 struct cachefiles_cache *cache;
203 struct fscache_cookie *cookie; 213 struct fscache_cookie *cookie;
204 const struct cred *saved_cred; 214 const struct cred *saved_cred;
215 const void *aux;
205 unsigned auxlen; 216 unsigned auxlen;
206 217
207 _enter("{OBJ%x}", _object->debug_id); 218 _enter("{OBJ%x}", _object->debug_id);
@@ -216,26 +227,29 @@ static void cachefiles_update_object(struct fscache_object *_object)
216 } 227 }
217 228
218 cookie = object->fscache.cookie; 229 cookie = object->fscache.cookie;
230 auxlen = cookie->aux_len;
219 231
220 if (!cookie->def->get_aux) { 232 if (!auxlen) {
221 fscache_unuse_cookie(_object); 233 fscache_unuse_cookie(_object);
222 _leave(" [no aux]"); 234 _leave(" [no aux]");
223 return; 235 return;
224 } 236 }
225 237
226 auxdata = kmalloc(2 + 512 + 3, cachefiles_gfp); 238 auxdata = kmalloc(2 + auxlen + 3, cachefiles_gfp);
227 if (!auxdata) { 239 if (!auxdata) {
228 fscache_unuse_cookie(_object); 240 fscache_unuse_cookie(_object);
229 _leave(" [nomem]"); 241 _leave(" [nomem]");
230 return; 242 return;
231 } 243 }
232 244
233 auxlen = cookie->def->get_aux(cookie->netfs_data, auxdata->data, 511); 245 aux = (auxlen <= sizeof(cookie->inline_aux)) ?
246 cookie->inline_aux : cookie->aux;
247
248 memcpy(auxdata->data, aux, auxlen);
234 fscache_unuse_cookie(_object); 249 fscache_unuse_cookie(_object);
235 ASSERTCMP(auxlen, <, 511);
236 250
237 auxdata->len = auxlen + 1; 251 auxdata->len = auxlen + 1;
238 auxdata->type = cookie->def->type; 252 auxdata->type = cookie->type;
239 253
240 cachefiles_begin_secure(cache, &saved_cred); 254 cachefiles_begin_secure(cache, &saved_cred);
241 cachefiles_update_object_xattr(object, auxdata); 255 cachefiles_update_object_xattr(object, auxdata);
@@ -309,10 +323,12 @@ static void cachefiles_drop_object(struct fscache_object *_object)
309/* 323/*
310 * dispose of a reference to an object 324 * dispose of a reference to an object
311 */ 325 */
312static void cachefiles_put_object(struct fscache_object *_object) 326static void cachefiles_put_object(struct fscache_object *_object,
327 enum fscache_obj_ref_trace why)
313{ 328{
314 struct cachefiles_object *object; 329 struct cachefiles_object *object;
315 struct fscache_cache *cache; 330 struct fscache_cache *cache;
331 int u;
316 332
317 ASSERT(_object); 333 ASSERT(_object);
318 334
@@ -328,7 +344,11 @@ static void cachefiles_put_object(struct fscache_object *_object)
328 ASSERTIFCMP(object->fscache.parent, 344 ASSERTIFCMP(object->fscache.parent,
329 object->fscache.parent->n_children, >, 0); 345 object->fscache.parent->n_children, >, 0);
330 346
331 if (atomic_dec_and_test(&object->usage)) { 347 u = atomic_dec_return(&object->usage);
348 trace_cachefiles_ref(object, _object->cookie,
349 (enum cachefiles_obj_ref_trace)why, u);
350 ASSERTCMP(u, !=, -1);
351 if (u == 0) {
332 _debug("- kill object OBJ%x", object->fscache.debug_id); 352 _debug("- kill object OBJ%x", object->fscache.debug_id);
333 353
334 ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)); 354 ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags));
@@ -421,7 +441,7 @@ static int cachefiles_attr_changed(struct fscache_object *_object)
421 loff_t oi_size; 441 loff_t oi_size;
422 int ret; 442 int ret;
423 443
424 _object->cookie->def->get_attr(_object->cookie->netfs_data, &ni_size); 444 ni_size = _object->store_limit_l;
425 445
426 _enter("{OBJ%x},[%llu]", 446 _enter("{OBJ%x},[%llu]",
427 _object->debug_id, (unsigned long long) ni_size); 447 _object->debug_id, (unsigned long long) ni_size);
@@ -493,8 +513,7 @@ static void cachefiles_invalidate_object(struct fscache_operation *op)
493 cache = container_of(object->fscache.cache, 513 cache = container_of(object->fscache.cache,
494 struct cachefiles_cache, cache); 514 struct cachefiles_cache, cache);
495 515
496 op->object->cookie->def->get_attr(op->object->cookie->netfs_data, 516 ni_size = op->object->store_limit_l;
497 &ni_size);
498 517
499 _enter("{OBJ%x},[%llu]", 518 _enter("{OBJ%x},[%llu]",
500 op->object->debug_id, (unsigned long long)ni_size); 519 op->object->debug_id, (unsigned long long)ni_size);
diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h
index bb3a02ca9da4..d2f6f996e65a 100644
--- a/fs/cachefiles/internal.h
+++ b/fs/cachefiles/internal.h
@@ -124,6 +124,8 @@ struct cachefiles_xattr {
124 uint8_t data[]; 124 uint8_t data[];
125}; 125};
126 126
127#include <trace/events/cachefiles.h>
128
127/* 129/*
128 * note change of state for daemon 130 * note change of state for daemon
129 */ 131 */
diff --git a/fs/cachefiles/main.c b/fs/cachefiles/main.c
index 711f13d8c2de..f54d3f5b2e40 100644
--- a/fs/cachefiles/main.c
+++ b/fs/cachefiles/main.c
@@ -22,6 +22,7 @@
22#include <linux/statfs.h> 22#include <linux/statfs.h>
23#include <linux/sysctl.h> 23#include <linux/sysctl.h>
24#include <linux/miscdevice.h> 24#include <linux/miscdevice.h>
25#define CREATE_TRACE_POINTS
25#include "internal.h" 26#include "internal.h"
26 27
27unsigned cachefiles_debug; 28unsigned cachefiles_debug;
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
index 3978b324cbca..0daa1e3fe0df 100644
--- a/fs/cachefiles/namei.c
+++ b/fs/cachefiles/namei.c
@@ -30,11 +30,11 @@
30 */ 30 */
31static noinline 31static noinline
32void __cachefiles_printk_object(struct cachefiles_object *object, 32void __cachefiles_printk_object(struct cachefiles_object *object,
33 const char *prefix, 33 const char *prefix)
34 u8 *keybuf)
35{ 34{
36 struct fscache_cookie *cookie; 35 struct fscache_cookie *cookie;
37 unsigned keylen, loop; 36 const u8 *k;
37 unsigned loop;
38 38
39 pr_err("%sobject: OBJ%x\n", prefix, object->fscache.debug_id); 39 pr_err("%sobject: OBJ%x\n", prefix, object->fscache.debug_id);
40 pr_err("%sobjstate=%s fl=%lx wbusy=%x ev=%lx[%lx]\n", 40 pr_err("%sobjstate=%s fl=%lx wbusy=%x ev=%lx[%lx]\n",
@@ -56,23 +56,16 @@ void __cachefiles_printk_object(struct cachefiles_object *object,
56 object->fscache.cookie->parent, 56 object->fscache.cookie->parent,
57 object->fscache.cookie->netfs_data, 57 object->fscache.cookie->netfs_data,
58 object->fscache.cookie->flags); 58 object->fscache.cookie->flags);
59 if (keybuf && cookie->def) 59 pr_err("%skey=[%u] '", prefix, cookie->key_len);
60 keylen = cookie->def->get_key(cookie->netfs_data, keybuf, 60 k = (cookie->key_len <= sizeof(cookie->inline_key)) ?
61 CACHEFILES_KEYBUF_SIZE); 61 cookie->inline_key : cookie->key;
62 else 62 for (loop = 0; loop < cookie->key_len; loop++)
63 keylen = 0; 63 pr_cont("%02x", k[loop]);
64 pr_cont("'\n");
64 } else { 65 } else {
65 pr_err("%scookie=NULL\n", prefix); 66 pr_err("%scookie=NULL\n", prefix);
66 keylen = 0;
67 } 67 }
68 spin_unlock(&object->fscache.lock); 68 spin_unlock(&object->fscache.lock);
69
70 if (keylen) {
71 pr_err("%skey=[%u] '", prefix, keylen);
72 for (loop = 0; loop < keylen; loop++)
73 pr_cont("%02x", keybuf[loop]);
74 pr_cont("'\n");
75 }
76} 69}
77 70
78/* 71/*
@@ -81,14 +74,10 @@ void __cachefiles_printk_object(struct cachefiles_object *object,
81static noinline void cachefiles_printk_object(struct cachefiles_object *object, 74static noinline void cachefiles_printk_object(struct cachefiles_object *object,
82 struct cachefiles_object *xobject) 75 struct cachefiles_object *xobject)
83{ 76{
84 u8 *keybuf;
85
86 keybuf = kmalloc(CACHEFILES_KEYBUF_SIZE, GFP_NOIO);
87 if (object) 77 if (object)
88 __cachefiles_printk_object(object, "", keybuf); 78 __cachefiles_printk_object(object, "");
89 if (xobject) 79 if (xobject)
90 __cachefiles_printk_object(xobject, "x", keybuf); 80 __cachefiles_printk_object(xobject, "x");
91 kfree(keybuf);
92} 81}
93 82
94/* 83/*
@@ -120,6 +109,7 @@ static void cachefiles_mark_object_buried(struct cachefiles_cache *cache,
120 } 109 }
121 110
122 write_unlock(&cache->active_lock); 111 write_unlock(&cache->active_lock);
112 trace_cachefiles_mark_buried(NULL, dentry, why);
123 _leave(" [no owner]"); 113 _leave(" [no owner]");
124 return; 114 return;
125 115
@@ -130,6 +120,8 @@ found_dentry:
130 object->fscache.state->name, 120 object->fscache.state->name,
131 dentry); 121 dentry);
132 122
123 trace_cachefiles_mark_buried(object, dentry, why);
124
133 if (fscache_object_is_live(&object->fscache)) { 125 if (fscache_object_is_live(&object->fscache)) {
134 pr_err("\n"); 126 pr_err("\n");
135 pr_err("Error: Can't preemptively bury live object\n"); 127 pr_err("Error: Can't preemptively bury live object\n");
@@ -158,13 +150,15 @@ static int cachefiles_mark_object_active(struct cachefiles_cache *cache,
158try_again: 150try_again:
159 write_lock(&cache->active_lock); 151 write_lock(&cache->active_lock);
160 152
153 dentry = object->dentry;
154 trace_cachefiles_mark_active(object, dentry);
155
161 if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) { 156 if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) {
162 pr_err("Error: Object already active\n"); 157 pr_err("Error: Object already active\n");
163 cachefiles_printk_object(object, NULL); 158 cachefiles_printk_object(object, NULL);
164 BUG(); 159 BUG();
165 } 160 }
166 161
167 dentry = object->dentry;
168 _p = &cache->active_nodes.rb_node; 162 _p = &cache->active_nodes.rb_node;
169 while (*_p) { 163 while (*_p) {
170 _parent = *_p; 164 _parent = *_p;
@@ -191,6 +185,8 @@ try_again:
191 /* an old object from a previous incarnation is hogging the slot - we 185 /* an old object from a previous incarnation is hogging the slot - we
192 * need to wait for it to be destroyed */ 186 * need to wait for it to be destroyed */
193wait_for_old_object: 187wait_for_old_object:
188 trace_cachefiles_wait_active(object, dentry, xobject);
189
194 if (fscache_object_is_live(&xobject->fscache)) { 190 if (fscache_object_is_live(&xobject->fscache)) {
195 pr_err("\n"); 191 pr_err("\n");
196 pr_err("Error: Unexpected object collision\n"); 192 pr_err("Error: Unexpected object collision\n");
@@ -248,12 +244,12 @@ wait_for_old_object:
248 244
249 ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)); 245 ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags));
250 246
251 cache->cache.ops->put_object(&xobject->fscache); 247 cache->cache.ops->put_object(&xobject->fscache, cachefiles_obj_put_wait_retry);
252 goto try_again; 248 goto try_again;
253 249
254requeue: 250requeue:
255 clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); 251 clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
256 cache->cache.ops->put_object(&xobject->fscache); 252 cache->cache.ops->put_object(&xobject->fscache, cachefiles_obj_put_wait_timeo);
257 _leave(" = -ETIMEDOUT"); 253 _leave(" = -ETIMEDOUT");
258 return -ETIMEDOUT; 254 return -ETIMEDOUT;
259} 255}
@@ -265,6 +261,11 @@ void cachefiles_mark_object_inactive(struct cachefiles_cache *cache,
265 struct cachefiles_object *object, 261 struct cachefiles_object *object,
266 blkcnt_t i_blocks) 262 blkcnt_t i_blocks)
267{ 263{
264 struct dentry *dentry = object->dentry;
265 struct inode *inode = d_backing_inode(dentry);
266
267 trace_cachefiles_mark_inactive(object, dentry, inode);
268
268 write_lock(&cache->active_lock); 269 write_lock(&cache->active_lock);
269 rb_erase(&object->active_node, &cache->active_nodes); 270 rb_erase(&object->active_node, &cache->active_nodes);
270 clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); 271 clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
@@ -288,6 +289,7 @@ void cachefiles_mark_object_inactive(struct cachefiles_cache *cache,
288 * - unlocks the directory mutex 289 * - unlocks the directory mutex
289 */ 290 */
290static int cachefiles_bury_object(struct cachefiles_cache *cache, 291static int cachefiles_bury_object(struct cachefiles_cache *cache,
292 struct cachefiles_object *object,
291 struct dentry *dir, 293 struct dentry *dir,
292 struct dentry *rep, 294 struct dentry *rep,
293 bool preemptive, 295 bool preemptive,
@@ -312,6 +314,7 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache,
312 if (ret < 0) { 314 if (ret < 0) {
313 cachefiles_io_error(cache, "Unlink security error"); 315 cachefiles_io_error(cache, "Unlink security error");
314 } else { 316 } else {
317 trace_cachefiles_unlink(object, rep, why);
315 ret = vfs_unlink(d_inode(dir), rep, NULL); 318 ret = vfs_unlink(d_inode(dir), rep, NULL);
316 319
317 if (preemptive) 320 if (preemptive)
@@ -413,6 +416,7 @@ try_again:
413 if (ret < 0) { 416 if (ret < 0) {
414 cachefiles_io_error(cache, "Rename security error %d", ret); 417 cachefiles_io_error(cache, "Rename security error %d", ret);
415 } else { 418 } else {
419 trace_cachefiles_rename(object, rep, grave, why);
416 ret = vfs_rename(d_inode(dir), rep, 420 ret = vfs_rename(d_inode(dir), rep,
417 d_inode(cache->graveyard), grave, NULL, 0); 421 d_inode(cache->graveyard), grave, NULL, 0);
418 if (ret != 0 && ret != -ENOMEM) 422 if (ret != 0 && ret != -ENOMEM)
@@ -458,7 +462,7 @@ int cachefiles_delete_object(struct cachefiles_cache *cache,
458 /* we need to check that our parent is _still_ our parent - it 462 /* we need to check that our parent is _still_ our parent - it
459 * may have been renamed */ 463 * may have been renamed */
460 if (dir == object->dentry->d_parent) { 464 if (dir == object->dentry->d_parent) {
461 ret = cachefiles_bury_object(cache, dir, 465 ret = cachefiles_bury_object(cache, object, dir,
462 object->dentry, false, 466 object->dentry, false,
463 FSCACHE_OBJECT_WAS_RETIRED); 467 FSCACHE_OBJECT_WAS_RETIRED);
464 } else { 468 } else {
@@ -486,6 +490,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent,
486{ 490{
487 struct cachefiles_cache *cache; 491 struct cachefiles_cache *cache;
488 struct dentry *dir, *next = NULL; 492 struct dentry *dir, *next = NULL;
493 struct inode *inode;
489 struct path path; 494 struct path path;
490 unsigned long start; 495 unsigned long start;
491 const char *name; 496 const char *name;
@@ -529,13 +534,17 @@ lookup_again:
529 start = jiffies; 534 start = jiffies;
530 next = lookup_one_len(name, dir, nlen); 535 next = lookup_one_len(name, dir, nlen);
531 cachefiles_hist(cachefiles_lookup_histogram, start); 536 cachefiles_hist(cachefiles_lookup_histogram, start);
532 if (IS_ERR(next)) 537 if (IS_ERR(next)) {
538 trace_cachefiles_lookup(object, next, NULL);
533 goto lookup_error; 539 goto lookup_error;
540 }
534 541
535 _debug("next -> %p %s", next, d_backing_inode(next) ? "positive" : "negative"); 542 inode = d_backing_inode(next);
543 trace_cachefiles_lookup(object, next, inode);
544 _debug("next -> %p %s", next, inode ? "positive" : "negative");
536 545
537 if (!key) 546 if (!key)
538 object->new = !d_backing_inode(next); 547 object->new = !inode;
539 548
540 /* if this element of the path doesn't exist, then the lookup phase 549 /* if this element of the path doesn't exist, then the lookup phase
541 * failed, and we can release any readers in the certain knowledge that 550 * failed, and we can release any readers in the certain knowledge that
@@ -558,6 +567,8 @@ lookup_again:
558 start = jiffies; 567 start = jiffies;
559 ret = vfs_mkdir(d_inode(dir), next, 0); 568 ret = vfs_mkdir(d_inode(dir), next, 0);
560 cachefiles_hist(cachefiles_mkdir_histogram, start); 569 cachefiles_hist(cachefiles_mkdir_histogram, start);
570 if (!key)
571 trace_cachefiles_mkdir(object, next, ret);
561 if (ret < 0) 572 if (ret < 0)
562 goto create_error; 573 goto create_error;
563 574
@@ -587,6 +598,7 @@ lookup_again:
587 start = jiffies; 598 start = jiffies;
588 ret = vfs_create(d_inode(dir), next, S_IFREG, true); 599 ret = vfs_create(d_inode(dir), next, S_IFREG, true);
589 cachefiles_hist(cachefiles_create_histogram, start); 600 cachefiles_hist(cachefiles_create_histogram, start);
601 trace_cachefiles_create(object, next, ret);
590 if (ret < 0) 602 if (ret < 0)
591 goto create_error; 603 goto create_error;
592 604
@@ -629,7 +641,8 @@ lookup_again:
629 * mutex) */ 641 * mutex) */
630 object->dentry = NULL; 642 object->dentry = NULL;
631 643
632 ret = cachefiles_bury_object(cache, dir, next, true, 644 ret = cachefiles_bury_object(cache, object, dir, next,
645 true,
633 FSCACHE_OBJECT_IS_STALE); 646 FSCACHE_OBJECT_IS_STALE);
634 dput(next); 647 dput(next);
635 next = NULL; 648 next = NULL;
@@ -955,7 +968,7 @@ int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
955 /* actually remove the victim (drops the dir mutex) */ 968 /* actually remove the victim (drops the dir mutex) */
956 _debug("bury"); 969 _debug("bury");
957 970
958 ret = cachefiles_bury_object(cache, dir, victim, false, 971 ret = cachefiles_bury_object(cache, NULL, dir, victim, false,
959 FSCACHE_OBJECT_WAS_CULLED); 972 FSCACHE_OBJECT_WAS_CULLED);
960 if (ret < 0) 973 if (ret < 0)
961 goto error; 974 goto error;
diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c
index 883bc7bb12c5..5082c8a49686 100644
--- a/fs/cachefiles/rdwr.c
+++ b/fs/cachefiles/rdwr.c
@@ -952,6 +952,7 @@ error:
952 * - cache withdrawal is prevented by the caller 952 * - cache withdrawal is prevented by the caller
953 */ 953 */
954void cachefiles_uncache_page(struct fscache_object *_object, struct page *page) 954void cachefiles_uncache_page(struct fscache_object *_object, struct page *page)
955 __releases(&object->fscache.cookie->lock)
955{ 956{
956 struct cachefiles_object *object; 957 struct cachefiles_object *object;
957 struct cachefiles_cache *cache; 958 struct cachefiles_cache *cache;
diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c
index d31c1a72d8a5..0a29a00aed2e 100644
--- a/fs/cachefiles/xattr.c
+++ b/fs/cachefiles/xattr.c
@@ -113,6 +113,7 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object,
113 /* attempt to install the cache metadata directly */ 113 /* attempt to install the cache metadata directly */
114 _debug("SET #%u", auxdata->len); 114 _debug("SET #%u", auxdata->len);
115 115
116 clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->fscache.cookie->flags);
116 ret = vfs_setxattr(dentry, cachefiles_xattr_cache, 117 ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
117 &auxdata->type, auxdata->len, 118 &auxdata->type, auxdata->len,
118 XATTR_CREATE); 119 XATTR_CREATE);
@@ -141,6 +142,7 @@ int cachefiles_update_object_xattr(struct cachefiles_object *object,
141 /* attempt to install the cache metadata directly */ 142 /* attempt to install the cache metadata directly */
142 _debug("SET #%u", auxdata->len); 143 _debug("SET #%u", auxdata->len);
143 144
145 clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->fscache.cookie->flags);
144 ret = vfs_setxattr(dentry, cachefiles_xattr_cache, 146 ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
145 &auxdata->type, auxdata->len, 147 &auxdata->type, auxdata->len,
146 XATTR_REPLACE); 148 XATTR_REPLACE);
@@ -180,7 +182,8 @@ int cachefiles_check_auxdata(struct cachefiles_object *object)
180 goto error; 182 goto error;
181 183
182 xlen--; 184 xlen--;
183 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)));
184 if (validity != FSCACHE_CHECKAUX_OKAY) 187 if (validity != FSCACHE_CHECKAUX_OKAY)
185 goto error; 188 goto error;
186 189
@@ -249,7 +252,8 @@ int cachefiles_check_object_xattr(struct cachefiles_object *object,
249 object->fscache.cookie->def->name, dlen); 252 object->fscache.cookie->def->name, dlen);
250 253
251 result = fscache_check_aux(&object->fscache, 254 result = fscache_check_aux(&object->fscache,
252 &auxbuf->data, dlen); 255 &auxbuf->data, dlen,
256 i_size_read(d_backing_inode(dentry)));
253 257
254 switch (result) { 258 switch (result) {
255 /* entry okay as is */ 259 /* entry okay as is */
diff --git a/fs/ceph/cache.c b/fs/ceph/cache.c
index a3ab265d3215..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 = {
@@ -41,34 +40,15 @@ static LIST_HEAD(ceph_fscache_list);
41struct ceph_fscache_entry { 40struct ceph_fscache_entry {
42 struct list_head list; 41 struct list_head list;
43 struct fscache_cookie *fscache; 42 struct fscache_cookie *fscache;
44 struct ceph_fsid fsid;
45 size_t uniq_len; 43 size_t uniq_len;
44 /* The following members must be last */
45 struct ceph_fsid fsid;
46 char uniquifier[0]; 46 char uniquifier[0];
47}; 47};
48 48
49static uint16_t ceph_fscache_session_get_key(const void *cookie_netfs_data,
50 void *buffer, uint16_t maxbuf)
51{
52 const struct ceph_fs_client* fsc = cookie_netfs_data;
53 const char *fscache_uniq = fsc->mount_options->fscache_uniq;
54 uint16_t fsid_len, uniq_len;
55
56 fsid_len = sizeof(fsc->client->fsid);
57 uniq_len = fscache_uniq ? strlen(fscache_uniq) : 0;
58 if (fsid_len + uniq_len > maxbuf)
59 return 0;
60
61 memcpy(buffer, &fsc->client->fsid, fsid_len);
62 if (uniq_len)
63 memcpy(buffer + fsid_len, fscache_uniq, uniq_len);
64
65 return fsid_len + uniq_len;
66}
67
68static const struct fscache_cookie_def ceph_fscache_fsid_object_def = { 49static const struct fscache_cookie_def ceph_fscache_fsid_object_def = {
69 .name = "CEPH.fsid", 50 .name = "CEPH.fsid",
70 .type = FSCACHE_COOKIE_TYPE_INDEX, 51 .type = FSCACHE_COOKIE_TYPE_INDEX,
71 .get_key = ceph_fscache_session_get_key,
72}; 52};
73 53
74int ceph_fscache_register(void) 54int ceph_fscache_register(void)
@@ -110,16 +90,19 @@ int ceph_fscache_register_fs(struct ceph_fs_client* fsc)
110 goto out_unlock; 90 goto out_unlock;
111 } 91 }
112 92
93 memcpy(&ent->fsid, fsid, sizeof(*fsid));
94 if (uniq_len > 0) {
95 memcpy(&ent->uniquifier, fscache_uniq, uniq_len);
96 ent->uniq_len = uniq_len;
97 }
98
113 fsc->fscache = fscache_acquire_cookie(ceph_cache_netfs.primary_index, 99 fsc->fscache = fscache_acquire_cookie(ceph_cache_netfs.primary_index,
114 &ceph_fscache_fsid_object_def, 100 &ceph_fscache_fsid_object_def,
115 fsc, true); 101 &ent->fsid, sizeof(ent->fsid) + uniq_len,
102 NULL, 0,
103 fsc, 0, true);
116 104
117 if (fsc->fscache) { 105 if (fsc->fscache) {
118 memcpy(&ent->fsid, fsid, sizeof(*fsid));
119 if (uniq_len > 0) {
120 memcpy(&ent->uniquifier, fscache_uniq, uniq_len);
121 ent->uniq_len = uniq_len;
122 }
123 ent->fscache = fsc->fscache; 106 ent->fscache = fsc->fscache;
124 list_add_tail(&ent->list, &ceph_fscache_list); 107 list_add_tail(&ent->list, &ceph_fscache_list);
125 } else { 108 } else {
@@ -133,59 +116,21 @@ out_unlock:
133 return err; 116 return err;
134} 117}
135 118
136static uint16_t ceph_fscache_inode_get_key(const void *cookie_netfs_data,
137 void *buffer, uint16_t maxbuf)
138{
139 const struct ceph_inode_info* ci = cookie_netfs_data;
140 uint16_t klen;
141
142 /* use ceph virtual inode (id + snapshot) */
143 klen = sizeof(ci->i_vino);
144 if (klen > maxbuf)
145 return 0;
146
147 memcpy(buffer, &ci->i_vino, klen);
148 return klen;
149}
150
151static uint16_t ceph_fscache_inode_get_aux(const void *cookie_netfs_data,
152 void *buffer, uint16_t bufmax)
153{
154 struct ceph_aux_inode aux;
155 const struct ceph_inode_info* ci = cookie_netfs_data;
156 const struct inode* inode = &ci->vfs_inode;
157
158 memset(&aux, 0, sizeof(aux));
159 aux.version = ci->i_version;
160 aux.mtime = inode->i_mtime;
161 aux.size = i_size_read(inode);
162
163 memcpy(buffer, &aux, sizeof(aux));
164
165 return sizeof(aux);
166}
167
168static void ceph_fscache_inode_get_attr(const void *cookie_netfs_data,
169 uint64_t *size)
170{
171 const struct ceph_inode_info* ci = cookie_netfs_data;
172 *size = i_size_read(&ci->vfs_inode);
173}
174
175static enum fscache_checkaux ceph_fscache_inode_check_aux( 119static enum fscache_checkaux ceph_fscache_inode_check_aux(
176 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)
177{ 122{
178 struct ceph_aux_inode aux; 123 struct ceph_aux_inode aux;
179 struct ceph_inode_info* ci = cookie_netfs_data; 124 struct ceph_inode_info* ci = cookie_netfs_data;
180 struct inode* inode = &ci->vfs_inode; 125 struct inode* inode = &ci->vfs_inode;
181 126
182 if (dlen != sizeof(aux)) 127 if (dlen != sizeof(aux) ||
128 i_size_read(inode) != object_size)
183 return FSCACHE_CHECKAUX_OBSOLETE; 129 return FSCACHE_CHECKAUX_OBSOLETE;
184 130
185 memset(&aux, 0, sizeof(aux)); 131 memset(&aux, 0, sizeof(aux));
186 aux.version = ci->i_version; 132 aux.version = ci->i_version;
187 aux.mtime = inode->i_mtime; 133 aux.mtime = inode->i_mtime;
188 aux.size = i_size_read(inode);
189 134
190 if (memcmp(data, &aux, sizeof(aux)) != 0) 135 if (memcmp(data, &aux, sizeof(aux)) != 0)
191 return FSCACHE_CHECKAUX_OBSOLETE; 136 return FSCACHE_CHECKAUX_OBSOLETE;
@@ -197,9 +142,6 @@ static enum fscache_checkaux ceph_fscache_inode_check_aux(
197static const struct fscache_cookie_def ceph_fscache_inode_object_def = { 142static const struct fscache_cookie_def ceph_fscache_inode_object_def = {
198 .name = "CEPH.inode", 143 .name = "CEPH.inode",
199 .type = FSCACHE_COOKIE_TYPE_DATAFILE, 144 .type = FSCACHE_COOKIE_TYPE_DATAFILE,
200 .get_key = ceph_fscache_inode_get_key,
201 .get_attr = ceph_fscache_inode_get_attr,
202 .get_aux = ceph_fscache_inode_get_aux,
203 .check_aux = ceph_fscache_inode_check_aux, 145 .check_aux = ceph_fscache_inode_check_aux,
204}; 146};
205 147
@@ -207,6 +149,7 @@ void ceph_fscache_register_inode_cookie(struct inode *inode)
207{ 149{
208 struct ceph_inode_info *ci = ceph_inode(inode); 150 struct ceph_inode_info *ci = ceph_inode(inode);
209 struct ceph_fs_client *fsc = ceph_inode_to_client(inode); 151 struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
152 struct ceph_aux_inode aux;
210 153
211 /* No caching for filesystem */ 154 /* No caching for filesystem */
212 if (!fsc->fscache) 155 if (!fsc->fscache)
@@ -218,9 +161,14 @@ void ceph_fscache_register_inode_cookie(struct inode *inode)
218 161
219 inode_lock_nested(inode, I_MUTEX_CHILD); 162 inode_lock_nested(inode, I_MUTEX_CHILD);
220 if (!ci->fscache) { 163 if (!ci->fscache) {
164 memset(&aux, 0, sizeof(aux));
165 aux.version = ci->i_version;
166 aux.mtime = inode->i_mtime;
221 ci->fscache = fscache_acquire_cookie(fsc->fscache, 167 ci->fscache = fscache_acquire_cookie(fsc->fscache,
222 &ceph_fscache_inode_object_def, 168 &ceph_fscache_inode_object_def,
223 ci, false); 169 &ci->i_vino, sizeof(ci->i_vino),
170 &aux, sizeof(aux),
171 ci, i_size_read(inode), false);
224 } 172 }
225 inode_unlock(inode); 173 inode_unlock(inode);
226} 174}
@@ -235,7 +183,7 @@ void ceph_fscache_unregister_inode_cookie(struct ceph_inode_info* ci)
235 ci->fscache = NULL; 183 ci->fscache = NULL;
236 184
237 fscache_uncache_all_inode_pages(cookie, &ci->vfs_inode); 185 fscache_uncache_all_inode_pages(cookie, &ci->vfs_inode);
238 fscache_relinquish_cookie(cookie, 0); 186 fscache_relinquish_cookie(cookie, &ci->i_vino, false);
239} 187}
240 188
241static bool ceph_fscache_can_enable(void *data) 189static bool ceph_fscache_can_enable(void *data)
@@ -254,11 +202,11 @@ void ceph_fscache_file_set_cookie(struct inode *inode, struct file *filp)
254 if (inode_is_open_for_write(inode)) { 202 if (inode_is_open_for_write(inode)) {
255 dout("fscache_file_set_cookie %p %p disabling cache\n", 203 dout("fscache_file_set_cookie %p %p disabling cache\n",
256 inode, filp); 204 inode, filp);
257 fscache_disable_cookie(ci->fscache, false); 205 fscache_disable_cookie(ci->fscache, &ci->i_vino, false);
258 fscache_uncache_all_inode_pages(ci->fscache, inode); 206 fscache_uncache_all_inode_pages(ci->fscache, inode);
259 } else { 207 } else {
260 fscache_enable_cookie(ci->fscache, ceph_fscache_can_enable, 208 fscache_enable_cookie(ci->fscache, &ci->i_vino, i_size_read(inode),
261 inode); 209 ceph_fscache_can_enable, inode);
262 if (fscache_cookie_enabled(ci->fscache)) { 210 if (fscache_cookie_enabled(ci->fscache)) {
263 dout("fscache_file_set_cookie %p %p enabling cache\n", 211 dout("fscache_file_set_cookie %p %p enabling cache\n",
264 inode, filp); 212 inode, filp);
@@ -351,7 +299,8 @@ void ceph_readpage_to_fscache(struct inode *inode, struct page *page)
351 if (!cache_valid(ci)) 299 if (!cache_valid(ci))
352 return; 300 return;
353 301
354 ret = fscache_write_page(ci->fscache, page, GFP_KERNEL); 302 ret = fscache_write_page(ci->fscache, page, i_size_read(inode),
303 GFP_KERNEL);
355 if (ret) 304 if (ret)
356 fscache_uncache_page(ci->fscache, page); 305 fscache_uncache_page(ci->fscache, page);
357} 306}
@@ -385,7 +334,7 @@ void ceph_fscache_unregister_fs(struct ceph_fs_client* fsc)
385 WARN_ON_ONCE(!found); 334 WARN_ON_ONCE(!found);
386 mutex_unlock(&ceph_fscache_lock); 335 mutex_unlock(&ceph_fscache_lock);
387 336
388 __fscache_relinquish_cookie(fsc->fscache, 0); 337 __fscache_relinquish_cookie(fsc->fscache, NULL, false);
389 } 338 }
390 fsc->fscache = NULL; 339 fsc->fscache = NULL;
391} 340}
@@ -402,7 +351,7 @@ void ceph_fscache_revalidate_cookie(struct ceph_inode_info *ci)
402 * truncate while the caller holds CEPH_CAP_FILE_RD */ 351 * truncate while the caller holds CEPH_CAP_FILE_RD */
403 mutex_lock(&ci->i_truncate_mutex); 352 mutex_lock(&ci->i_truncate_mutex);
404 if (!cache_valid(ci)) { 353 if (!cache_valid(ci)) {
405 if (fscache_check_consistency(ci->fscache)) 354 if (fscache_check_consistency(ci->fscache, &ci->i_vino))
406 fscache_invalidate(ci->fscache); 355 fscache_invalidate(ci->fscache);
407 spin_lock(&ci->i_ceph_lock); 356 spin_lock(&ci->i_ceph_lock);
408 ci->i_fscache_gen = ci->i_rdcache_gen; 357 ci->i_fscache_gen = ci->i_rdcache_gen;
diff --git a/fs/cifs/cache.c b/fs/cifs/cache.c
index 2c14020e5e1d..edf5f40898bf 100644
--- a/fs/cifs/cache.c
+++ b/fs/cifs/cache.c
@@ -46,67 +46,11 @@ void cifs_fscache_unregister(void)
46} 46}
47 47
48/* 48/*
49 * Key layout of CIFS server cache index object
50 */
51struct cifs_server_key {
52 uint16_t family; /* address family */
53 __be16 port; /* IP port */
54 union {
55 struct in_addr ipv4_addr;
56 struct in6_addr ipv6_addr;
57 } addr[0];
58};
59
60/*
61 * Server object keyed by {IPaddress,port,family} tuple
62 */
63static uint16_t cifs_server_get_key(const void *cookie_netfs_data,
64 void *buffer, uint16_t maxbuf)
65{
66 const struct TCP_Server_Info *server = cookie_netfs_data;
67 const struct sockaddr *sa = (struct sockaddr *) &server->dstaddr;
68 const struct sockaddr_in *addr = (struct sockaddr_in *) sa;
69 const struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) sa;
70 struct cifs_server_key *key = buffer;
71 uint16_t key_len = sizeof(struct cifs_server_key);
72
73 memset(key, 0, key_len);
74
75 /*
76 * Should not be a problem as sin_family/sin6_family overlays
77 * sa_family field
78 */
79 switch (sa->sa_family) {
80 case AF_INET:
81 key->family = sa->sa_family;
82 key->port = addr->sin_port;
83 key->addr[0].ipv4_addr = addr->sin_addr;
84 key_len += sizeof(key->addr[0].ipv4_addr);
85 break;
86
87 case AF_INET6:
88 key->family = sa->sa_family;
89 key->port = addr6->sin6_port;
90 key->addr[0].ipv6_addr = addr6->sin6_addr;
91 key_len += sizeof(key->addr[0].ipv6_addr);
92 break;
93
94 default:
95 cifs_dbg(VFS, "Unknown network family '%d'\n", sa->sa_family);
96 key_len = 0;
97 break;
98 }
99
100 return key_len;
101}
102
103/*
104 * Server object for FS-Cache 49 * Server object for FS-Cache
105 */ 50 */
106const struct fscache_cookie_def cifs_fscache_server_index_def = { 51const struct fscache_cookie_def cifs_fscache_server_index_def = {
107 .name = "CIFS.server", 52 .name = "CIFS.server",
108 .type = FSCACHE_COOKIE_TYPE_INDEX, 53 .type = FSCACHE_COOKIE_TYPE_INDEX,
109 .get_key = cifs_server_get_key,
110}; 54};
111 55
112/* 56/*
@@ -116,7 +60,7 @@ struct cifs_fscache_super_auxdata {
116 u64 resource_id; /* unique server resource id */ 60 u64 resource_id; /* unique server resource id */
117}; 61};
118 62
119static char *extract_sharename(const char *treename) 63char *extract_sharename(const char *treename)
120{ 64{
121 const char *src; 65 const char *src;
122 char *delim, *dst; 66 char *delim, *dst;
@@ -140,56 +84,11 @@ static char *extract_sharename(const char *treename)
140 return dst; 84 return dst;
141} 85}
142 86
143/*
144 * Superblock object currently keyed by share name
145 */
146static uint16_t cifs_super_get_key(const void *cookie_netfs_data, void *buffer,
147 uint16_t maxbuf)
148{
149 const struct cifs_tcon *tcon = cookie_netfs_data;
150 char *sharename;
151 uint16_t len;
152
153 sharename = extract_sharename(tcon->treeName);
154 if (IS_ERR(sharename)) {
155 cifs_dbg(FYI, "%s: couldn't extract sharename\n", __func__);
156 sharename = NULL;
157 return 0;
158 }
159
160 len = strlen(sharename);
161 if (len > maxbuf)
162 return 0;
163
164 memcpy(buffer, sharename, len);
165
166 kfree(sharename);
167
168 return len;
169}
170
171static uint16_t
172cifs_fscache_super_get_aux(const void *cookie_netfs_data, void *buffer,
173 uint16_t maxbuf)
174{
175 struct cifs_fscache_super_auxdata auxdata;
176 const struct cifs_tcon *tcon = cookie_netfs_data;
177
178 memset(&auxdata, 0, sizeof(auxdata));
179 auxdata.resource_id = tcon->resource_id;
180
181 if (maxbuf > sizeof(auxdata))
182 maxbuf = sizeof(auxdata);
183
184 memcpy(buffer, &auxdata, maxbuf);
185
186 return maxbuf;
187}
188
189static enum 87static enum
190fscache_checkaux cifs_fscache_super_check_aux(void *cookie_netfs_data, 88fscache_checkaux cifs_fscache_super_check_aux(void *cookie_netfs_data,
191 const void *data, 89 const void *data,
192 uint16_t datalen) 90 uint16_t datalen,
91 loff_t object_size)
193{ 92{
194 struct cifs_fscache_super_auxdata auxdata; 93 struct cifs_fscache_super_auxdata auxdata;
195 const struct cifs_tcon *tcon = cookie_netfs_data; 94 const struct cifs_tcon *tcon = cookie_netfs_data;
@@ -212,68 +111,14 @@ fscache_checkaux cifs_fscache_super_check_aux(void *cookie_netfs_data,
212const struct fscache_cookie_def cifs_fscache_super_index_def = { 111const struct fscache_cookie_def cifs_fscache_super_index_def = {
213 .name = "CIFS.super", 112 .name = "CIFS.super",
214 .type = FSCACHE_COOKIE_TYPE_INDEX, 113 .type = FSCACHE_COOKIE_TYPE_INDEX,
215 .get_key = cifs_super_get_key,
216 .get_aux = cifs_fscache_super_get_aux,
217 .check_aux = cifs_fscache_super_check_aux, 114 .check_aux = cifs_fscache_super_check_aux,
218}; 115};
219 116
220/*
221 * Auxiliary data attached to CIFS inode within the cache
222 */
223struct cifs_fscache_inode_auxdata {
224 struct timespec last_write_time;
225 struct timespec last_change_time;
226 u64 eof;
227};
228
229static uint16_t cifs_fscache_inode_get_key(const void *cookie_netfs_data,
230 void *buffer, uint16_t maxbuf)
231{
232 const struct cifsInodeInfo *cifsi = cookie_netfs_data;
233 uint16_t keylen;
234
235 /* use the UniqueId as the key */
236 keylen = sizeof(cifsi->uniqueid);
237 if (keylen > maxbuf)
238 keylen = 0;
239 else
240 memcpy(buffer, &cifsi->uniqueid, keylen);
241
242 return keylen;
243}
244
245static void
246cifs_fscache_inode_get_attr(const void *cookie_netfs_data, uint64_t *size)
247{
248 const struct cifsInodeInfo *cifsi = cookie_netfs_data;
249
250 *size = cifsi->vfs_inode.i_size;
251}
252
253static uint16_t
254cifs_fscache_inode_get_aux(const void *cookie_netfs_data, void *buffer,
255 uint16_t maxbuf)
256{
257 struct cifs_fscache_inode_auxdata auxdata;
258 const struct cifsInodeInfo *cifsi = cookie_netfs_data;
259
260 memset(&auxdata, 0, sizeof(auxdata));
261 auxdata.eof = cifsi->server_eof;
262 auxdata.last_write_time = cifsi->vfs_inode.i_mtime;
263 auxdata.last_change_time = cifsi->vfs_inode.i_ctime;
264
265 if (maxbuf > sizeof(auxdata))
266 maxbuf = sizeof(auxdata);
267
268 memcpy(buffer, &auxdata, maxbuf);
269
270 return maxbuf;
271}
272
273static enum 117static enum
274fscache_checkaux cifs_fscache_inode_check_aux(void *cookie_netfs_data, 118fscache_checkaux cifs_fscache_inode_check_aux(void *cookie_netfs_data,
275 const void *data, 119 const void *data,
276 uint16_t datalen) 120 uint16_t datalen,
121 loff_t object_size)
277{ 122{
278 struct cifs_fscache_inode_auxdata auxdata; 123 struct cifs_fscache_inode_auxdata auxdata;
279 struct cifsInodeInfo *cifsi = cookie_netfs_data; 124 struct cifsInodeInfo *cifsi = cookie_netfs_data;
@@ -295,8 +140,5 @@ fscache_checkaux cifs_fscache_inode_check_aux(void *cookie_netfs_data,
295const struct fscache_cookie_def cifs_fscache_inode_object_def = { 140const struct fscache_cookie_def cifs_fscache_inode_object_def = {
296 .name = "CIFS.uniqueid", 141 .name = "CIFS.uniqueid",
297 .type = FSCACHE_COOKIE_TYPE_DATAFILE, 142 .type = FSCACHE_COOKIE_TYPE_DATAFILE,
298 .get_key = cifs_fscache_inode_get_key,
299 .get_attr = cifs_fscache_inode_get_attr,
300 .get_aux = cifs_fscache_inode_get_aux,
301 .check_aux = cifs_fscache_inode_check_aux, 143 .check_aux = cifs_fscache_inode_check_aux,
302}; 144};
diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c
index 8d4b7bc8ae91..25d3f66b2d50 100644
--- a/fs/cifs/fscache.c
+++ b/fs/cifs/fscache.c
@@ -23,11 +23,63 @@
23#include "cifs_debug.h" 23#include "cifs_debug.h"
24#include "cifs_fs_sb.h" 24#include "cifs_fs_sb.h"
25 25
26/*
27 * Key layout of CIFS server cache index object
28 */
29struct cifs_server_key {
30 struct {
31 uint16_t family; /* address family */
32 __be16 port; /* IP port */
33 } hdr;
34 union {
35 struct in_addr ipv4_addr;
36 struct in6_addr ipv6_addr;
37 };
38} __packed;
39
40/*
41 * Get a cookie for a server object keyed by {IPaddress,port,family} tuple
42 */
26void cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) 43void cifs_fscache_get_client_cookie(struct TCP_Server_Info *server)
27{ 44{
45 const struct sockaddr *sa = (struct sockaddr *) &server->dstaddr;
46 const struct sockaddr_in *addr = (struct sockaddr_in *) sa;
47 const struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) sa;
48 struct cifs_server_key key;
49 uint16_t key_len = sizeof(key.hdr);
50
51 memset(&key, 0, sizeof(key));
52
53 /*
54 * Should not be a problem as sin_family/sin6_family overlays
55 * sa_family field
56 */
57 key.hdr.family = sa->sa_family;
58 switch (sa->sa_family) {
59 case AF_INET:
60 key.hdr.port = addr->sin_port;
61 key.ipv4_addr = addr->sin_addr;
62 key_len += sizeof(key.ipv4_addr);
63 break;
64
65 case AF_INET6:
66 key.hdr.port = addr6->sin6_port;
67 key.ipv6_addr = addr6->sin6_addr;
68 key_len += sizeof(key.ipv6_addr);
69 break;
70
71 default:
72 cifs_dbg(VFS, "Unknown network family '%d'\n", sa->sa_family);
73 server->fscache = NULL;
74 return;
75 }
76
28 server->fscache = 77 server->fscache =
29 fscache_acquire_cookie(cifs_fscache_netfs.primary_index, 78 fscache_acquire_cookie(cifs_fscache_netfs.primary_index,
30 &cifs_fscache_server_index_def, server, true); 79 &cifs_fscache_server_index_def,
80 &key, key_len,
81 NULL, 0,
82 server, 0, true);
31 cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", 83 cifs_dbg(FYI, "%s: (0x%p/0x%p)\n",
32 __func__, server, server->fscache); 84 __func__, server, server->fscache);
33} 85}
@@ -36,17 +88,29 @@ void cifs_fscache_release_client_cookie(struct TCP_Server_Info *server)
36{ 88{
37 cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", 89 cifs_dbg(FYI, "%s: (0x%p/0x%p)\n",
38 __func__, server, server->fscache); 90 __func__, server, server->fscache);
39 fscache_relinquish_cookie(server->fscache, 0); 91 fscache_relinquish_cookie(server->fscache, NULL, false);
40 server->fscache = NULL; 92 server->fscache = NULL;
41} 93}
42 94
43void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon) 95void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
44{ 96{
45 struct TCP_Server_Info *server = tcon->ses->server; 97 struct TCP_Server_Info *server = tcon->ses->server;
98 char *sharename;
99
100 sharename = extract_sharename(tcon->treeName);
101 if (IS_ERR(sharename)) {
102 cifs_dbg(FYI, "%s: couldn't extract sharename\n", __func__);
103 tcon->fscache = NULL;
104 return;
105 }
46 106
47 tcon->fscache = 107 tcon->fscache =
48 fscache_acquire_cookie(server->fscache, 108 fscache_acquire_cookie(server->fscache,
49 &cifs_fscache_super_index_def, tcon, true); 109 &cifs_fscache_super_index_def,
110 sharename, strlen(sharename),
111 &tcon->resource_id, sizeof(tcon->resource_id),
112 tcon, 0, true);
113 kfree(sharename);
50 cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", 114 cifs_dbg(FYI, "%s: (0x%p/0x%p)\n",
51 __func__, server->fscache, tcon->fscache); 115 __func__, server->fscache, tcon->fscache);
52} 116}
@@ -54,10 +118,28 @@ void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
54void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon) 118void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon)
55{ 119{
56 cifs_dbg(FYI, "%s: (0x%p)\n", __func__, tcon->fscache); 120 cifs_dbg(FYI, "%s: (0x%p)\n", __func__, tcon->fscache);
57 fscache_relinquish_cookie(tcon->fscache, 0); 121 fscache_relinquish_cookie(tcon->fscache, &tcon->resource_id, false);
58 tcon->fscache = NULL; 122 tcon->fscache = NULL;
59} 123}
60 124
125static void cifs_fscache_acquire_inode_cookie(struct cifsInodeInfo *cifsi,
126 struct cifs_tcon *tcon)
127{
128 struct cifs_fscache_inode_auxdata auxdata;
129
130 memset(&auxdata, 0, sizeof(auxdata));
131 auxdata.eof = cifsi->server_eof;
132 auxdata.last_write_time = cifsi->vfs_inode.i_mtime;
133 auxdata.last_change_time = cifsi->vfs_inode.i_ctime;
134
135 cifsi->fscache =
136 fscache_acquire_cookie(tcon->fscache,
137 &cifs_fscache_inode_object_def,
138 &cifsi->uniqueid, sizeof(cifsi->uniqueid),
139 &auxdata, sizeof(auxdata),
140 cifsi, cifsi->vfs_inode.i_size, true);
141}
142
61static void cifs_fscache_enable_inode_cookie(struct inode *inode) 143static void cifs_fscache_enable_inode_cookie(struct inode *inode)
62{ 144{
63 struct cifsInodeInfo *cifsi = CIFS_I(inode); 145 struct cifsInodeInfo *cifsi = CIFS_I(inode);
@@ -67,21 +149,28 @@ static void cifs_fscache_enable_inode_cookie(struct inode *inode)
67 if (cifsi->fscache) 149 if (cifsi->fscache)
68 return; 150 return;
69 151
70 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE) { 152 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE))
71 cifsi->fscache = fscache_acquire_cookie(tcon->fscache, 153 return;
72 &cifs_fscache_inode_object_def, cifsi, true); 154
73 cifs_dbg(FYI, "%s: got FH cookie (0x%p/0x%p)\n", 155 cifs_fscache_acquire_inode_cookie(cifsi, tcon);
74 __func__, tcon->fscache, cifsi->fscache); 156
75 } 157 cifs_dbg(FYI, "%s: got FH cookie (0x%p/0x%p)\n",
158 __func__, tcon->fscache, cifsi->fscache);
76} 159}
77 160
78void cifs_fscache_release_inode_cookie(struct inode *inode) 161void cifs_fscache_release_inode_cookie(struct inode *inode)
79{ 162{
163 struct cifs_fscache_inode_auxdata auxdata;
80 struct cifsInodeInfo *cifsi = CIFS_I(inode); 164 struct cifsInodeInfo *cifsi = CIFS_I(inode);
81 165
82 if (cifsi->fscache) { 166 if (cifsi->fscache) {
167 memset(&auxdata, 0, sizeof(auxdata));
168 auxdata.eof = cifsi->server_eof;
169 auxdata.last_write_time = cifsi->vfs_inode.i_mtime;
170 auxdata.last_change_time = cifsi->vfs_inode.i_ctime;
171
83 cifs_dbg(FYI, "%s: (0x%p)\n", __func__, cifsi->fscache); 172 cifs_dbg(FYI, "%s: (0x%p)\n", __func__, cifsi->fscache);
84 fscache_relinquish_cookie(cifsi->fscache, 0); 173 fscache_relinquish_cookie(cifsi->fscache, &auxdata, false);
85 cifsi->fscache = NULL; 174 cifsi->fscache = NULL;
86 } 175 }
87} 176}
@@ -93,7 +182,7 @@ static void cifs_fscache_disable_inode_cookie(struct inode *inode)
93 if (cifsi->fscache) { 182 if (cifsi->fscache) {
94 cifs_dbg(FYI, "%s: (0x%p)\n", __func__, cifsi->fscache); 183 cifs_dbg(FYI, "%s: (0x%p)\n", __func__, cifsi->fscache);
95 fscache_uncache_all_inode_pages(cifsi->fscache, inode); 184 fscache_uncache_all_inode_pages(cifsi->fscache, inode);
96 fscache_relinquish_cookie(cifsi->fscache, 1); 185 fscache_relinquish_cookie(cifsi->fscache, NULL, true);
97 cifsi->fscache = NULL; 186 cifsi->fscache = NULL;
98 } 187 }
99} 188}
@@ -110,16 +199,14 @@ void cifs_fscache_reset_inode_cookie(struct inode *inode)
110{ 199{
111 struct cifsInodeInfo *cifsi = CIFS_I(inode); 200 struct cifsInodeInfo *cifsi = CIFS_I(inode);
112 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 201 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
202 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
113 struct fscache_cookie *old = cifsi->fscache; 203 struct fscache_cookie *old = cifsi->fscache;
114 204
115 if (cifsi->fscache) { 205 if (cifsi->fscache) {
116 /* retire the current fscache cache and get a new one */ 206 /* retire the current fscache cache and get a new one */
117 fscache_relinquish_cookie(cifsi->fscache, 1); 207 fscache_relinquish_cookie(cifsi->fscache, NULL, true);
118 208
119 cifsi->fscache = fscache_acquire_cookie( 209 cifs_fscache_acquire_inode_cookie(cifsi, tcon);
120 cifs_sb_master_tcon(cifs_sb)->fscache,
121 &cifs_fscache_inode_object_def,
122 cifsi, true);
123 cifs_dbg(FYI, "%s: new cookie 0x%p oldcookie 0x%p\n", 210 cifs_dbg(FYI, "%s: new cookie 0x%p oldcookie 0x%p\n",
124 __func__, cifsi->fscache, old); 211 __func__, cifsi->fscache, old);
125 } 212 }
@@ -214,13 +301,15 @@ int __cifs_readpages_from_fscache(struct inode *inode,
214 301
215void __cifs_readpage_to_fscache(struct inode *inode, struct page *page) 302void __cifs_readpage_to_fscache(struct inode *inode, struct page *page)
216{ 303{
304 struct cifsInodeInfo *cifsi = CIFS_I(inode);
217 int ret; 305 int ret;
218 306
219 cifs_dbg(FYI, "%s: (fsc: %p, p: %p, i: %p)\n", 307 cifs_dbg(FYI, "%s: (fsc: %p, p: %p, i: %p)\n",
220 __func__, CIFS_I(inode)->fscache, page, inode); 308 __func__, cifsi->fscache, page, inode);
221 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);
222 if (ret != 0) 311 if (ret != 0)
223 fscache_uncache_page(CIFS_I(inode)->fscache, page); 312 fscache_uncache_page(cifsi->fscache, page);
224} 313}
225 314
226void __cifs_fscache_readpages_cancel(struct inode *inode, struct list_head *pages) 315void __cifs_fscache_readpages_cancel(struct inode *inode, struct list_head *pages)
@@ -239,4 +328,3 @@ void __cifs_fscache_invalidate_page(struct page *page, struct inode *inode)
239 fscache_wait_on_page_write(cookie, page); 328 fscache_wait_on_page_write(cookie, page);
240 fscache_uncache_page(cookie, page); 329 fscache_uncache_page(cookie, page);
241} 330}
242
diff --git a/fs/cifs/fscache.h b/fs/cifs/fscache.h
index 24794b6cd8ec..c7e3ac251e16 100644
--- a/fs/cifs/fscache.h
+++ b/fs/cifs/fscache.h
@@ -27,6 +27,18 @@
27 27
28#ifdef CONFIG_CIFS_FSCACHE 28#ifdef CONFIG_CIFS_FSCACHE
29 29
30/*
31 * Auxiliary data attached to CIFS inode within the cache
32 */
33struct cifs_fscache_inode_auxdata {
34 struct timespec last_write_time;
35 struct timespec last_change_time;
36 u64 eof;
37};
38
39/*
40 * cache.c
41 */
30extern struct fscache_netfs cifs_fscache_netfs; 42extern struct fscache_netfs cifs_fscache_netfs;
31extern const struct fscache_cookie_def cifs_fscache_server_index_def; 43extern const struct fscache_cookie_def cifs_fscache_server_index_def;
32extern const struct fscache_cookie_def cifs_fscache_super_index_def; 44extern const struct fscache_cookie_def cifs_fscache_super_index_def;
@@ -34,6 +46,7 @@ extern const struct fscache_cookie_def cifs_fscache_inode_object_def;
34 46
35extern int cifs_fscache_register(void); 47extern int cifs_fscache_register(void);
36extern void cifs_fscache_unregister(void); 48extern void cifs_fscache_unregister(void);
49extern char *extract_sharename(const char *);
37 50
38/* 51/*
39 * fscache.c 52 * fscache.c
diff --git a/fs/fscache/cache.c b/fs/fscache/cache.c
index 56cce7fdd39e..c184c5a356ff 100644
--- a/fs/fscache/cache.c
+++ b/fs/fscache/cache.c
@@ -125,7 +125,7 @@ struct fscache_cache *fscache_select_cache_for_object(
125 } 125 }
126 126
127 /* the parent is unbacked */ 127 /* the parent is unbacked */
128 if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) { 128 if (cookie->type != FSCACHE_COOKIE_TYPE_INDEX) {
129 /* cookie not an index and is unbacked */ 129 /* cookie not an index and is unbacked */
130 spin_unlock(&cookie->lock); 130 spin_unlock(&cookie->lock);
131 _leave(" = NULL [cookie ub,ni]"); 131 _leave(" = NULL [cookie ub,ni]");
diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c
index d705125665f0..7dc55b93a830 100644
--- a/fs/fscache/cookie.c
+++ b/fs/fscache/cookie.c
@@ -21,12 +21,54 @@ 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); 24#define fscache_cookie_hash_shift 15
25static struct hlist_bl_head fscache_cookie_hash[1 << fscache_cookie_hash_shift];
26
27static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie,
28 loff_t object_size);
25static int fscache_alloc_object(struct fscache_cache *cache, 29static int fscache_alloc_object(struct fscache_cache *cache,
26 struct fscache_cookie *cookie); 30 struct fscache_cookie *cookie);
27static int fscache_attach_object(struct fscache_cookie *cookie, 31static int fscache_attach_object(struct fscache_cookie *cookie,
28 struct fscache_object *object); 32 struct fscache_object *object);
29 33
34static void fscache_print_cookie(struct fscache_cookie *cookie, char prefix)
35{
36 struct hlist_node *object;
37 const u8 *k;
38 unsigned loop;
39
40 pr_err("%c-cookie c=%p [p=%p fl=%lx nc=%u na=%u]\n",
41 prefix, cookie, cookie->parent, cookie->flags,
42 atomic_read(&cookie->n_children),
43 atomic_read(&cookie->n_active));
44 pr_err("%c-cookie d=%p n=%p\n",
45 prefix, cookie->def, cookie->netfs_data);
46
47 object = READ_ONCE(cookie->backing_objects.first);
48 if (object)
49 pr_err("%c-cookie o=%p\n",
50 prefix, hlist_entry(object, struct fscache_object, cookie_link));
51
52 pr_err("%c-key=[%u] '", prefix, cookie->key_len);
53 k = (cookie->key_len <= sizeof(cookie->inline_key)) ?
54 cookie->inline_key : cookie->key;
55 for (loop = 0; loop < cookie->key_len; loop++)
56 pr_cont("%02x", k[loop]);
57 pr_cont("'\n");
58}
59
60void fscache_free_cookie(struct fscache_cookie *cookie)
61{
62 if (cookie) {
63 BUG_ON(!hlist_empty(&cookie->backing_objects));
64 if (cookie->aux_len > sizeof(cookie->inline_aux))
65 kfree(cookie->aux);
66 if (cookie->key_len > sizeof(cookie->inline_key))
67 kfree(cookie->key);
68 kmem_cache_free(fscache_cookie_jar, cookie);
69 }
70}
71
30/* 72/*
31 * initialise an cookie jar slab element prior to any use 73 * initialise an cookie jar slab element prior to any use
32 */ 74 */
@@ -41,6 +83,170 @@ void fscache_cookie_init_once(void *_cookie)
41} 83}
42 84
43/* 85/*
86 * Set the index key in a cookie. The cookie struct has space for a 12-byte
87 * key plus length and hash, but if that's not big enough, it's instead a
88 * pointer to a buffer containing 3 bytes of hash, 1 byte of length and then
89 * the key data.
90 */
91static int fscache_set_key(struct fscache_cookie *cookie,
92 const void *index_key, size_t index_key_len)
93{
94 unsigned long long h;
95 u32 *buf;
96 int i;
97
98 cookie->key_len = index_key_len;
99
100 if (index_key_len > sizeof(cookie->inline_key)) {
101 buf = kzalloc(index_key_len, GFP_KERNEL);
102 if (!buf)
103 return -ENOMEM;
104 cookie->key = buf;
105 } else {
106 buf = (u32 *)cookie->inline_key;
107 buf[0] = 0;
108 buf[1] = 0;
109 buf[2] = 0;
110 }
111
112 memcpy(buf, index_key, index_key_len);
113
114 /* Calculate a hash and combine this with the length in the first word
115 * or first half word
116 */
117 h = (unsigned long)cookie->parent;
118 h += index_key_len + cookie->type;
119 for (i = 0; i < (index_key_len + sizeof(u32) - 1) / sizeof(u32); i++)
120 h += buf[i];
121
122 cookie->key_hash = h ^ (h >> 32);
123 return 0;
124}
125
126static long fscache_compare_cookie(const struct fscache_cookie *a,
127 const struct fscache_cookie *b)
128{
129 const void *ka, *kb;
130
131 if (a->key_hash != b->key_hash)
132 return (long)a->key_hash - (long)b->key_hash;
133 if (a->parent != b->parent)
134 return (long)a->parent - (long)b->parent;
135 if (a->key_len != b->key_len)
136 return (long)a->key_len - (long)b->key_len;
137 if (a->type != b->type)
138 return (long)a->type - (long)b->type;
139
140 if (a->key_len <= sizeof(a->inline_key)) {
141 ka = &a->inline_key;
142 kb = &b->inline_key;
143 } else {
144 ka = a->key;
145 kb = b->key;
146 }
147 return memcmp(ka, kb, a->key_len);
148}
149
150/*
151 * Allocate a cookie.
152 */
153struct fscache_cookie *fscache_alloc_cookie(
154 struct fscache_cookie *parent,
155 const struct fscache_cookie_def *def,
156 const void *index_key, size_t index_key_len,
157 const void *aux_data, size_t aux_data_len,
158 void *netfs_data,
159 loff_t object_size)
160{
161 struct fscache_cookie *cookie;
162
163 /* allocate and initialise a cookie */
164 cookie = kmem_cache_alloc(fscache_cookie_jar, GFP_KERNEL);
165 if (!cookie)
166 return NULL;
167
168 cookie->key_len = index_key_len;
169 cookie->aux_len = aux_data_len;
170
171 if (fscache_set_key(cookie, index_key, index_key_len) < 0)
172 goto nomem;
173
174 if (cookie->aux_len <= sizeof(cookie->inline_aux)) {
175 memcpy(cookie->inline_aux, aux_data, cookie->aux_len);
176 } else {
177 cookie->aux = kmemdup(aux_data, cookie->aux_len, GFP_KERNEL);
178 if (!cookie->aux)
179 goto nomem;
180 }
181
182 atomic_set(&cookie->usage, 1);
183 atomic_set(&cookie->n_children, 0);
184
185 /* We keep the active count elevated until relinquishment to prevent an
186 * attempt to wake up every time the object operations queue quiesces.
187 */
188 atomic_set(&cookie->n_active, 1);
189
190 cookie->def = def;
191 cookie->parent = parent;
192 cookie->netfs_data = netfs_data;
193 cookie->flags = (1 << FSCACHE_COOKIE_NO_DATA_YET);
194 cookie->type = def->type;
195
196 /* radix tree insertion won't use the preallocation pool unless it's
197 * told it may not wait */
198 INIT_RADIX_TREE(&cookie->stores, GFP_NOFS & ~__GFP_DIRECT_RECLAIM);
199 return cookie;
200
201nomem:
202 fscache_free_cookie(cookie);
203 return NULL;
204}
205
206/*
207 * Attempt to insert the new cookie into the hash. If there's a collision, we
208 * return the old cookie if it's not in use and an error otherwise.
209 */
210struct fscache_cookie *fscache_hash_cookie(struct fscache_cookie *candidate)
211{
212 struct fscache_cookie *cursor;
213 struct hlist_bl_head *h;
214 struct hlist_bl_node *p;
215 unsigned int bucket;
216
217 bucket = candidate->key_hash & (ARRAY_SIZE(fscache_cookie_hash) - 1);
218 h = &fscache_cookie_hash[bucket];
219
220 hlist_bl_lock(h);
221 hlist_bl_for_each_entry(cursor, p, h, hash_link) {
222 if (fscache_compare_cookie(candidate, cursor) == 0)
223 goto collision;
224 }
225
226 __set_bit(FSCACHE_COOKIE_ACQUIRED, &candidate->flags);
227 fscache_cookie_get(candidate->parent, fscache_cookie_get_acquire_parent);
228 atomic_inc(&candidate->parent->n_children);
229 hlist_bl_add_head(&candidate->hash_link, h);
230 hlist_bl_unlock(h);
231 return candidate;
232
233collision:
234 if (test_and_set_bit(FSCACHE_COOKIE_ACQUIRED, &cursor->flags)) {
235 trace_fscache_cookie(cursor, fscache_cookie_collision,
236 atomic_read(&cursor->usage));
237 pr_err("Duplicate cookie detected\n");
238 fscache_print_cookie(cursor, 'O');
239 fscache_print_cookie(candidate, 'N');
240 hlist_bl_unlock(h);
241 return NULL;
242 }
243
244 fscache_cookie_get(cursor, fscache_cookie_get_reacquire);
245 hlist_bl_unlock(h);
246 return cursor;
247}
248
249/*
44 * request a cookie to represent an object (index, datafile, xattr, etc) 250 * request a cookie to represent an object (index, datafile, xattr, etc)
45 * - parent specifies the parent object 251 * - parent specifies the parent object
46 * - the top level index cookie for each netfs is stored in the fscache_netfs 252 * - the top level index cookie for each netfs is stored in the fscache_netfs
@@ -58,10 +264,13 @@ void fscache_cookie_init_once(void *_cookie)
58struct fscache_cookie *__fscache_acquire_cookie( 264struct fscache_cookie *__fscache_acquire_cookie(
59 struct fscache_cookie *parent, 265 struct fscache_cookie *parent,
60 const struct fscache_cookie_def *def, 266 const struct fscache_cookie_def *def,
267 const void *index_key, size_t index_key_len,
268 const void *aux_data, size_t aux_data_len,
61 void *netfs_data, 269 void *netfs_data,
270 loff_t object_size,
62 bool enable) 271 bool enable)
63{ 272{
64 struct fscache_cookie *cookie; 273 struct fscache_cookie *candidate, *cookie;
65 274
66 BUG_ON(!def); 275 BUG_ON(!def);
67 276
@@ -69,6 +278,13 @@ struct fscache_cookie *__fscache_acquire_cookie(
69 parent ? (char *) parent->def->name : "<no-parent>", 278 parent ? (char *) parent->def->name : "<no-parent>",
70 def->name, netfs_data, enable); 279 def->name, netfs_data, enable);
71 280
281 if (!index_key || !index_key_len || index_key_len > 255 || aux_data_len > 255)
282 return NULL;
283 if (!aux_data || !aux_data_len) {
284 aux_data = NULL;
285 aux_data_len = 0;
286 }
287
72 fscache_stat(&fscache_n_acquires); 288 fscache_stat(&fscache_n_acquires);
73 289
74 /* if there's no parent cookie, then we don't create one here either */ 290 /* if there's no parent cookie, then we don't create one here either */
@@ -79,41 +295,31 @@ struct fscache_cookie *__fscache_acquire_cookie(
79 } 295 }
80 296
81 /* validate the definition */ 297 /* validate the definition */
82 BUG_ON(!def->get_key);
83 BUG_ON(!def->name[0]); 298 BUG_ON(!def->name[0]);
84 299
85 BUG_ON(def->type == FSCACHE_COOKIE_TYPE_INDEX && 300 BUG_ON(def->type == FSCACHE_COOKIE_TYPE_INDEX &&
86 parent->def->type != FSCACHE_COOKIE_TYPE_INDEX); 301 parent->type != FSCACHE_COOKIE_TYPE_INDEX);
87 302
88 /* allocate and initialise a cookie */ 303 candidate = fscache_alloc_cookie(parent, def,
89 cookie = kmem_cache_alloc(fscache_cookie_jar, GFP_KERNEL); 304 index_key, index_key_len,
90 if (!cookie) { 305 aux_data, aux_data_len,
306 netfs_data, object_size);
307 if (!candidate) {
91 fscache_stat(&fscache_n_acquires_oom); 308 fscache_stat(&fscache_n_acquires_oom);
92 _leave(" [ENOMEM]"); 309 _leave(" [ENOMEM]");
93 return NULL; 310 return NULL;
94 } 311 }
95 312
96 atomic_set(&cookie->usage, 1); 313 cookie = fscache_hash_cookie(candidate);
97 atomic_set(&cookie->n_children, 0); 314 if (!cookie) {
98 315 trace_fscache_cookie(candidate, fscache_cookie_discard, 1);
99 /* We keep the active count elevated until relinquishment to prevent an 316 goto out;
100 * attempt to wake up every time the object operations queue quiesces. 317 }
101 */
102 atomic_set(&cookie->n_active, 1);
103
104 atomic_inc(&parent->usage);
105 atomic_inc(&parent->n_children);
106 318
107 cookie->def = def; 319 if (cookie == candidate)
108 cookie->parent = parent; 320 candidate = NULL;
109 cookie->netfs_data = netfs_data;
110 cookie->flags = (1 << FSCACHE_COOKIE_NO_DATA_YET);
111 321
112 /* radix tree insertion won't use the preallocation pool unless it's 322 switch (cookie->type) {
113 * told it may not wait */
114 INIT_RADIX_TREE(&cookie->stores, GFP_NOFS & ~__GFP_DIRECT_RECLAIM);
115
116 switch (cookie->def->type) {
117 case FSCACHE_COOKIE_TYPE_INDEX: 323 case FSCACHE_COOKIE_TYPE_INDEX:
118 fscache_stat(&fscache_n_cookie_index); 324 fscache_stat(&fscache_n_cookie_index);
119 break; 325 break;
@@ -125,16 +331,19 @@ struct fscache_cookie *__fscache_acquire_cookie(
125 break; 331 break;
126 } 332 }
127 333
334 trace_fscache_acquire(cookie);
335
128 if (enable) { 336 if (enable) {
129 /* if the object is an index then we need do nothing more here 337 /* if the object is an index then we need do nothing more here
130 * - we create indices on disk when we need them as an index 338 * - we create indices on disk when we need them as an index
131 * may exist in multiple caches */ 339 * may exist in multiple caches */
132 if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) { 340 if (cookie->type != FSCACHE_COOKIE_TYPE_INDEX) {
133 if (fscache_acquire_non_index_cookie(cookie) == 0) { 341 if (fscache_acquire_non_index_cookie(cookie, object_size) == 0) {
134 set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags); 342 set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
135 } else { 343 } else {
136 atomic_dec(&parent->n_children); 344 atomic_dec(&parent->n_children);
137 __fscache_cookie_put(cookie); 345 fscache_cookie_put(cookie,
346 fscache_cookie_put_acquire_nobufs);
138 fscache_stat(&fscache_n_acquires_nobufs); 347 fscache_stat(&fscache_n_acquires_nobufs);
139 _leave(" = NULL"); 348 _leave(" = NULL");
140 return NULL; 349 return NULL;
@@ -145,7 +354,9 @@ struct fscache_cookie *__fscache_acquire_cookie(
145 } 354 }
146 355
147 fscache_stat(&fscache_n_acquires_ok); 356 fscache_stat(&fscache_n_acquires_ok);
148 _leave(" = %p", cookie); 357
358out:
359 fscache_free_cookie(candidate);
149 return cookie; 360 return cookie;
150} 361}
151EXPORT_SYMBOL(__fscache_acquire_cookie); 362EXPORT_SYMBOL(__fscache_acquire_cookie);
@@ -154,24 +365,30 @@ EXPORT_SYMBOL(__fscache_acquire_cookie);
154 * Enable a cookie to permit it to accept new operations. 365 * Enable a cookie to permit it to accept new operations.
155 */ 366 */
156void __fscache_enable_cookie(struct fscache_cookie *cookie, 367void __fscache_enable_cookie(struct fscache_cookie *cookie,
368 const void *aux_data,
369 loff_t object_size,
157 bool (*can_enable)(void *data), 370 bool (*can_enable)(void *data),
158 void *data) 371 void *data)
159{ 372{
160 _enter("%p", cookie); 373 _enter("%p", cookie);
161 374
375 trace_fscache_enable(cookie);
376
162 wait_on_bit_lock(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK, 377 wait_on_bit_lock(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK,
163 TASK_UNINTERRUPTIBLE); 378 TASK_UNINTERRUPTIBLE);
164 379
380 fscache_update_aux(cookie, aux_data);
381
165 if (test_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags)) 382 if (test_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags))
166 goto out_unlock; 383 goto out_unlock;
167 384
168 if (can_enable && !can_enable(data)) { 385 if (can_enable && !can_enable(data)) {
169 /* The netfs decided it didn't want to enable after all */ 386 /* The netfs decided it didn't want to enable after all */
170 } else if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) { 387 } else if (cookie->type != FSCACHE_COOKIE_TYPE_INDEX) {
171 /* Wait for outstanding disablement to complete */ 388 /* Wait for outstanding disablement to complete */
172 __fscache_wait_on_invalidate(cookie); 389 __fscache_wait_on_invalidate(cookie);
173 390
174 if (fscache_acquire_non_index_cookie(cookie) == 0) 391 if (fscache_acquire_non_index_cookie(cookie, object_size) == 0)
175 set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags); 392 set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
176 } else { 393 } else {
177 set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags); 394 set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
@@ -188,11 +405,11 @@ EXPORT_SYMBOL(__fscache_enable_cookie);
188 * - this must make sure the index chain is instantiated and instantiate the 405 * - this must make sure the index chain is instantiated and instantiate the
189 * object representation too 406 * object representation too
190 */ 407 */
191static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie) 408static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie,
409 loff_t object_size)
192{ 410{
193 struct fscache_object *object; 411 struct fscache_object *object;
194 struct fscache_cache *cache; 412 struct fscache_cache *cache;
195 uint64_t i_size;
196 int ret; 413 int ret;
197 414
198 _enter(""); 415 _enter("");
@@ -231,9 +448,6 @@ static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie)
231 return ret; 448 return ret;
232 } 449 }
233 450
234 /* pass on how big the object we're caching is supposed to be */
235 cookie->def->get_attr(cookie->netfs_data, &i_size);
236
237 spin_lock(&cookie->lock); 451 spin_lock(&cookie->lock);
238 if (hlist_empty(&cookie->backing_objects)) { 452 if (hlist_empty(&cookie->backing_objects)) {
239 spin_unlock(&cookie->lock); 453 spin_unlock(&cookie->lock);
@@ -243,7 +457,7 @@ static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie)
243 object = hlist_entry(cookie->backing_objects.first, 457 object = hlist_entry(cookie->backing_objects.first,
244 struct fscache_object, cookie_link); 458 struct fscache_object, cookie_link);
245 459
246 fscache_set_store_limit(object, i_size); 460 fscache_set_store_limit(object, object_size);
247 461
248 /* initiate the process of looking up all the objects in the chain 462 /* initiate the process of looking up all the objects in the chain
249 * (done by fscache_initialise_object()) */ 463 * (done by fscache_initialise_object()) */
@@ -318,7 +532,7 @@ static int fscache_alloc_object(struct fscache_cache *cache,
318 * attached to the cookie */ 532 * attached to the cookie */
319 if (fscache_attach_object(cookie, object) < 0) { 533 if (fscache_attach_object(cookie, object) < 0) {
320 fscache_stat(&fscache_n_cop_put_object); 534 fscache_stat(&fscache_n_cop_put_object);
321 cache->ops->put_object(object); 535 cache->ops->put_object(object, fscache_obj_put_attach_fail);
322 fscache_stat_d(&fscache_n_cop_put_object); 536 fscache_stat_d(&fscache_n_cop_put_object);
323 } 537 }
324 538
@@ -338,7 +552,7 @@ object_already_extant:
338 552
339error_put: 553error_put:
340 fscache_stat(&fscache_n_cop_put_object); 554 fscache_stat(&fscache_n_cop_put_object);
341 cache->ops->put_object(object); 555 cache->ops->put_object(object, fscache_obj_put_alloc_fail);
342 fscache_stat_d(&fscache_n_cop_put_object); 556 fscache_stat_d(&fscache_n_cop_put_object);
343error: 557error:
344 _leave(" = %d", ret); 558 _leave(" = %d", ret);
@@ -398,7 +612,7 @@ static int fscache_attach_object(struct fscache_cookie *cookie,
398 612
399 /* attach to the cookie */ 613 /* attach to the cookie */
400 object->cookie = cookie; 614 object->cookie = cookie;
401 atomic_inc(&cookie->usage); 615 fscache_cookie_get(cookie, fscache_cookie_get_attach_object);
402 hlist_add_head(&object->cookie_link, &cookie->backing_objects); 616 hlist_add_head(&object->cookie_link, &cookie->backing_objects);
403 617
404 fscache_objlist_add(object); 618 fscache_objlist_add(object);
@@ -426,10 +640,7 @@ void __fscache_invalidate(struct fscache_cookie *cookie)
426 * there, and if it's doing that, it may as well just retire the 640 * there, and if it's doing that, it may as well just retire the
427 * cookie. 641 * cookie.
428 */ 642 */
429 ASSERTCMP(cookie->def->type, ==, FSCACHE_COOKIE_TYPE_DATAFILE); 643 ASSERTCMP(cookie->type, ==, FSCACHE_COOKIE_TYPE_DATAFILE);
430
431 /* We will be updating the cookie too. */
432 BUG_ON(!cookie->def->get_aux);
433 644
434 /* If there's an object, we tell the object state machine to handle the 645 /* If there's an object, we tell the object state machine to handle the
435 * invalidation on our behalf, otherwise there's nothing to do. 646 * invalidation on our behalf, otherwise there's nothing to do.
@@ -473,7 +684,7 @@ EXPORT_SYMBOL(__fscache_wait_on_invalidate);
473/* 684/*
474 * update the index entries backing a cookie 685 * update the index entries backing a cookie
475 */ 686 */
476void __fscache_update_cookie(struct fscache_cookie *cookie) 687void __fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data)
477{ 688{
478 struct fscache_object *object; 689 struct fscache_object *object;
479 690
@@ -487,10 +698,10 @@ void __fscache_update_cookie(struct fscache_cookie *cookie)
487 698
488 _enter("{%s}", cookie->def->name); 699 _enter("{%s}", cookie->def->name);
489 700
490 BUG_ON(!cookie->def->get_aux);
491
492 spin_lock(&cookie->lock); 701 spin_lock(&cookie->lock);
493 702
703 fscache_update_aux(cookie, aux_data);
704
494 if (fscache_cookie_enabled(cookie)) { 705 if (fscache_cookie_enabled(cookie)) {
495 /* update the index entry on disk in each cache backing this 706 /* update the index entry on disk in each cache backing this
496 * cookie. 707 * cookie.
@@ -509,13 +720,17 @@ EXPORT_SYMBOL(__fscache_update_cookie);
509/* 720/*
510 * Disable a cookie to stop it from accepting new requests from the netfs. 721 * Disable a cookie to stop it from accepting new requests from the netfs.
511 */ 722 */
512void __fscache_disable_cookie(struct fscache_cookie *cookie, bool invalidate) 723void __fscache_disable_cookie(struct fscache_cookie *cookie,
724 const void *aux_data,
725 bool invalidate)
513{ 726{
514 struct fscache_object *object; 727 struct fscache_object *object;
515 bool awaken = false; 728 bool awaken = false;
516 729
517 _enter("%p,%u", cookie, invalidate); 730 _enter("%p,%u", cookie, invalidate);
518 731
732 trace_fscache_disable(cookie);
733
519 ASSERTCMP(atomic_read(&cookie->n_active), >, 0); 734 ASSERTCMP(atomic_read(&cookie->n_active), >, 0);
520 735
521 if (atomic_read(&cookie->n_children) != 0) { 736 if (atomic_read(&cookie->n_children) != 0) {
@@ -526,6 +741,9 @@ void __fscache_disable_cookie(struct fscache_cookie *cookie, bool invalidate)
526 741
527 wait_on_bit_lock(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK, 742 wait_on_bit_lock(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK,
528 TASK_UNINTERRUPTIBLE); 743 TASK_UNINTERRUPTIBLE);
744
745 fscache_update_aux(cookie, aux_data);
746
529 if (!test_and_clear_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags)) 747 if (!test_and_clear_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags))
530 goto out_unlock_enable; 748 goto out_unlock_enable;
531 749
@@ -563,7 +781,7 @@ void __fscache_disable_cookie(struct fscache_cookie *cookie, bool invalidate)
563 } 781 }
564 782
565 /* Make sure any pending writes are cancelled. */ 783 /* Make sure any pending writes are cancelled. */
566 if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) 784 if (cookie->type != FSCACHE_COOKIE_TYPE_INDEX)
567 fscache_invalidate_writes(cookie); 785 fscache_invalidate_writes(cookie);
568 786
569 /* Reset the cookie state if it wasn't relinquished */ 787 /* Reset the cookie state if it wasn't relinquished */
@@ -585,7 +803,9 @@ EXPORT_SYMBOL(__fscache_disable_cookie);
585 * - all dependents of this cookie must have already been unregistered 803 * - all dependents of this cookie must have already been unregistered
586 * (indices/files/pages) 804 * (indices/files/pages)
587 */ 805 */
588void __fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire) 806void __fscache_relinquish_cookie(struct fscache_cookie *cookie,
807 const void *aux_data,
808 bool retire)
589{ 809{
590 fscache_stat(&fscache_n_relinquishes); 810 fscache_stat(&fscache_n_relinquishes);
591 if (retire) 811 if (retire)
@@ -601,10 +821,13 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire)
601 cookie, cookie->def->name, cookie->netfs_data, 821 cookie, cookie->def->name, cookie->netfs_data,
602 atomic_read(&cookie->n_active), retire); 822 atomic_read(&cookie->n_active), retire);
603 823
824 trace_fscache_relinquish(cookie, retire);
825
604 /* No further netfs-accessing operations on this cookie permitted */ 826 /* No further netfs-accessing operations on this cookie permitted */
605 set_bit(FSCACHE_COOKIE_RELINQUISHED, &cookie->flags); 827 if (test_and_set_bit(FSCACHE_COOKIE_RELINQUISHED, &cookie->flags))
828 BUG();
606 829
607 __fscache_disable_cookie(cookie, retire); 830 __fscache_disable_cookie(cookie, aux_data, retire);
608 831
609 /* Clear pointers back to the netfs */ 832 /* Clear pointers back to the netfs */
610 cookie->netfs_data = NULL; 833 cookie->netfs_data = NULL;
@@ -619,35 +842,54 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire)
619 842
620 /* Dispose of the netfs's link to the cookie */ 843 /* Dispose of the netfs's link to the cookie */
621 ASSERTCMP(atomic_read(&cookie->usage), >, 0); 844 ASSERTCMP(atomic_read(&cookie->usage), >, 0);
622 fscache_cookie_put(cookie); 845 fscache_cookie_put(cookie, fscache_cookie_put_relinquish);
623 846
624 _leave(""); 847 _leave("");
625} 848}
626EXPORT_SYMBOL(__fscache_relinquish_cookie); 849EXPORT_SYMBOL(__fscache_relinquish_cookie);
627 850
628/* 851/*
629 * destroy a cookie 852 * Remove a cookie from the hash table.
630 */ 853 */
631void __fscache_cookie_put(struct fscache_cookie *cookie) 854static void fscache_unhash_cookie(struct fscache_cookie *cookie)
855{
856 struct hlist_bl_head *h;
857 unsigned int bucket;
858
859 bucket = cookie->key_hash & (ARRAY_SIZE(fscache_cookie_hash) - 1);
860 h = &fscache_cookie_hash[bucket];
861
862 hlist_bl_lock(h);
863 hlist_bl_del(&cookie->hash_link);
864 hlist_bl_unlock(h);
865}
866
867/*
868 * Drop a reference to a cookie.
869 */
870void fscache_cookie_put(struct fscache_cookie *cookie,
871 enum fscache_cookie_trace where)
632{ 872{
633 struct fscache_cookie *parent; 873 struct fscache_cookie *parent;
874 int usage;
634 875
635 _enter("%p", cookie); 876 _enter("%p", cookie);
636 877
637 for (;;) { 878 do {
638 _debug("FREE COOKIE %p", cookie); 879 usage = atomic_dec_return(&cookie->usage);
639 parent = cookie->parent; 880 trace_fscache_cookie(cookie, where, usage);
640 BUG_ON(!hlist_empty(&cookie->backing_objects));
641 kmem_cache_free(fscache_cookie_jar, cookie);
642 881
643 if (!parent) 882 if (usage > 0)
644 break; 883 return;
884 BUG_ON(usage < 0);
885
886 parent = cookie->parent;
887 fscache_unhash_cookie(cookie);
888 fscache_free_cookie(cookie);
645 889
646 cookie = parent; 890 cookie = parent;
647 BUG_ON(atomic_read(&cookie->usage) <= 0); 891 where = fscache_cookie_put_parent;
648 if (!atomic_dec_and_test(&cookie->usage)) 892 } while (cookie);
649 break;
650 }
651 893
652 _leave(""); 894 _leave("");
653} 895}
@@ -657,7 +899,8 @@ void __fscache_cookie_put(struct fscache_cookie *cookie)
657 * 899 *
658 * NOTE: it only serves no-index type 900 * NOTE: it only serves no-index type
659 */ 901 */
660int __fscache_check_consistency(struct fscache_cookie *cookie) 902int __fscache_check_consistency(struct fscache_cookie *cookie,
903 const void *aux_data)
661{ 904{
662 struct fscache_operation *op; 905 struct fscache_operation *op;
663 struct fscache_object *object; 906 struct fscache_object *object;
@@ -666,7 +909,7 @@ int __fscache_check_consistency(struct fscache_cookie *cookie)
666 909
667 _enter("%p,", cookie); 910 _enter("%p,", cookie);
668 911
669 ASSERTCMP(cookie->def->type, ==, FSCACHE_COOKIE_TYPE_DATAFILE); 912 ASSERTCMP(cookie->type, ==, FSCACHE_COOKIE_TYPE_DATAFILE);
670 913
671 if (fscache_wait_for_deferred_lookup(cookie) < 0) 914 if (fscache_wait_for_deferred_lookup(cookie) < 0)
672 return -ERESTARTSYS; 915 return -ERESTARTSYS;
@@ -678,13 +921,16 @@ int __fscache_check_consistency(struct fscache_cookie *cookie)
678 if (!op) 921 if (!op)
679 return -ENOMEM; 922 return -ENOMEM;
680 923
681 fscache_operation_init(op, NULL, NULL, NULL); 924 fscache_operation_init(cookie, op, NULL, NULL, NULL);
682 op->flags = FSCACHE_OP_MYTHREAD | 925 op->flags = FSCACHE_OP_MYTHREAD |
683 (1 << FSCACHE_OP_WAITING) | 926 (1 << FSCACHE_OP_WAITING) |
684 (1 << FSCACHE_OP_UNUSE_COOKIE); 927 (1 << FSCACHE_OP_UNUSE_COOKIE);
928 trace_fscache_page_op(cookie, NULL, op, fscache_page_op_check_consistency);
685 929
686 spin_lock(&cookie->lock); 930 spin_lock(&cookie->lock);
687 931
932 fscache_update_aux(cookie, aux_data);
933
688 if (!fscache_cookie_enabled(cookie) || 934 if (!fscache_cookie_enabled(cookie) ||
689 hlist_empty(&cookie->backing_objects)) 935 hlist_empty(&cookie->backing_objects))
690 goto inconsistent; 936 goto inconsistent;
diff --git a/fs/fscache/fsdef.c b/fs/fscache/fsdef.c
index 5a117df2a9ef..aa46e48d8c75 100644
--- a/fs/fscache/fsdef.c
+++ b/fs/fscache/fsdef.c
@@ -13,16 +13,11 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include "internal.h" 14#include "internal.h"
15 15
16static uint16_t fscache_fsdef_netfs_get_key(const void *cookie_netfs_data,
17 void *buffer, uint16_t bufmax);
18
19static uint16_t fscache_fsdef_netfs_get_aux(const void *cookie_netfs_data,
20 void *buffer, uint16_t bufmax);
21
22static 16static
23enum fscache_checkaux fscache_fsdef_netfs_check_aux(void *cookie_netfs_data, 17enum fscache_checkaux fscache_fsdef_netfs_check_aux(void *cookie_netfs_data,
24 const void *data, 18 const void *data,
25 uint16_t datalen); 19 uint16_t datalen,
20 loff_t object_size);
26 21
27/* 22/*
28 * The root index is owned by FS-Cache itself. 23 * The root index is owned by FS-Cache itself.
@@ -60,6 +55,7 @@ struct fscache_cookie fscache_fsdef_index = {
60 .backing_objects = HLIST_HEAD_INIT, 55 .backing_objects = HLIST_HEAD_INIT,
61 .def = &fscache_fsdef_index_def, 56 .def = &fscache_fsdef_index_def,
62 .flags = 1 << FSCACHE_COOKIE_ENABLED, 57 .flags = 1 << FSCACHE_COOKIE_ENABLED,
58 .type = FSCACHE_COOKIE_TYPE_INDEX,
63}; 59};
64EXPORT_SYMBOL(fscache_fsdef_index); 60EXPORT_SYMBOL(fscache_fsdef_index);
65 61
@@ -71,59 +67,18 @@ EXPORT_SYMBOL(fscache_fsdef_index);
71struct fscache_cookie_def fscache_fsdef_netfs_def = { 67struct fscache_cookie_def fscache_fsdef_netfs_def = {
72 .name = "FSDEF.netfs", 68 .name = "FSDEF.netfs",
73 .type = FSCACHE_COOKIE_TYPE_INDEX, 69 .type = FSCACHE_COOKIE_TYPE_INDEX,
74 .get_key = fscache_fsdef_netfs_get_key,
75 .get_aux = fscache_fsdef_netfs_get_aux,
76 .check_aux = fscache_fsdef_netfs_check_aux, 70 .check_aux = fscache_fsdef_netfs_check_aux,
77}; 71};
78 72
79/* 73/*
80 * get the key data for an FSDEF index record - this is the name of the netfs
81 * for which this entry is created
82 */
83static uint16_t fscache_fsdef_netfs_get_key(const void *cookie_netfs_data,
84 void *buffer, uint16_t bufmax)
85{
86 const struct fscache_netfs *netfs = cookie_netfs_data;
87 unsigned klen;
88
89 _enter("{%s.%u},", netfs->name, netfs->version);
90
91 klen = strlen(netfs->name);
92 if (klen > bufmax)
93 return 0;
94
95 memcpy(buffer, netfs->name, klen);
96 return klen;
97}
98
99/*
100 * get the auxiliary data for an FSDEF index record - this is the index
101 * structure version number of the netfs for which this version is created
102 */
103static uint16_t fscache_fsdef_netfs_get_aux(const void *cookie_netfs_data,
104 void *buffer, uint16_t bufmax)
105{
106 const struct fscache_netfs *netfs = cookie_netfs_data;
107 unsigned dlen;
108
109 _enter("{%s.%u},", netfs->name, netfs->version);
110
111 dlen = sizeof(uint32_t);
112 if (dlen > bufmax)
113 return 0;
114
115 memcpy(buffer, &netfs->version, dlen);
116 return dlen;
117}
118
119/*
120 * check that the index structure version number stored in the auxiliary data 74 * check that the index structure version number stored in the auxiliary data
121 * matches the one the netfs gave us 75 * matches the one the netfs gave us
122 */ 76 */
123static enum fscache_checkaux fscache_fsdef_netfs_check_aux( 77static enum fscache_checkaux fscache_fsdef_netfs_check_aux(
124 void *cookie_netfs_data, 78 void *cookie_netfs_data,
125 const void *data, 79 const void *data,
126 uint16_t datalen) 80 uint16_t datalen,
81 loff_t object_size)
127{ 82{
128 struct fscache_netfs *netfs = cookie_netfs_data; 83 struct fscache_netfs *netfs = cookie_netfs_data;
129 uint32_t version; 84 uint32_t version;
diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h
index 0ff4b49a0037..500650f938fe 100644
--- a/fs/fscache/internal.h
+++ b/fs/fscache/internal.h
@@ -29,6 +29,7 @@
29#define pr_fmt(fmt) "FS-Cache: " fmt 29#define pr_fmt(fmt) "FS-Cache: " fmt
30 30
31#include <linux/fscache-cache.h> 31#include <linux/fscache-cache.h>
32#include <trace/events/fscache.h>
32#include <linux/sched.h> 33#include <linux/sched.h>
33 34
34#define FSCACHE_MIN_THREADS 4 35#define FSCACHE_MIN_THREADS 4
@@ -48,8 +49,16 @@ extern struct fscache_cache *fscache_select_cache_for_object(
48 */ 49 */
49extern struct kmem_cache *fscache_cookie_jar; 50extern struct kmem_cache *fscache_cookie_jar;
50 51
52extern void fscache_free_cookie(struct fscache_cookie *);
51extern void fscache_cookie_init_once(void *); 53extern void fscache_cookie_init_once(void *);
52extern void __fscache_cookie_put(struct fscache_cookie *); 54extern struct fscache_cookie *fscache_alloc_cookie(struct fscache_cookie *,
55 const struct fscache_cookie_def *,
56 const void *, size_t,
57 const void *, size_t,
58 void *, loff_t);
59extern struct fscache_cookie *fscache_hash_cookie(struct fscache_cookie *);
60extern void fscache_cookie_put(struct fscache_cookie *,
61 enum fscache_cookie_trace);
53 62
54/* 63/*
55 * fsdef.c 64 * fsdef.c
@@ -311,14 +320,12 @@ static inline void fscache_raise_event(struct fscache_object *object,
311 fscache_enqueue_object(object); 320 fscache_enqueue_object(object);
312} 321}
313 322
314/* 323static inline void fscache_cookie_get(struct fscache_cookie *cookie,
315 * drop a reference to a cookie 324 enum fscache_cookie_trace where)
316 */
317static inline void fscache_cookie_put(struct fscache_cookie *cookie)
318{ 325{
319 BUG_ON(atomic_read(&cookie->usage) <= 0); 326 int usage = atomic_inc_return(&cookie->usage);
320 if (atomic_dec_and_test(&cookie->usage)) 327
321 __fscache_cookie_put(cookie); 328 trace_fscache_cookie(cookie, where, usage);
322} 329}
323 330
324/* 331/*
@@ -342,6 +349,27 @@ void fscache_put_context(struct fscache_cookie *cookie, void *context)
342 cookie->def->put_context(cookie->netfs_data, context); 349 cookie->def->put_context(cookie->netfs_data, context);
343} 350}
344 351
352/*
353 * Update the auxiliary data on a cookie.
354 */
355static inline
356void fscache_update_aux(struct fscache_cookie *cookie, const void *aux_data)
357{
358 void *p;
359
360 if (!aux_data)
361 return;
362 if (cookie->aux_len <= sizeof(cookie->inline_aux))
363 p = cookie->inline_aux;
364 else
365 p = cookie->aux;
366
367 if (memcmp(p, aux_data, cookie->aux_len) != 0) {
368 memcpy(p, aux_data, cookie->aux_len);
369 set_bit(FSCACHE_COOKIE_AUX_UPDATED, &cookie->flags);
370 }
371}
372
345/*****************************************************************************/ 373/*****************************************************************************/
346/* 374/*
347 * debug tracing 375 * debug tracing
diff --git a/fs/fscache/main.c b/fs/fscache/main.c
index 249968dcbf5c..7dce110bf17d 100644
--- a/fs/fscache/main.c
+++ b/fs/fscache/main.c
@@ -16,6 +16,7 @@
16#include <linux/completion.h> 16#include <linux/completion.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/seq_file.h> 18#include <linux/seq_file.h>
19#define CREATE_TRACE_POINTS
19#include "internal.h" 20#include "internal.h"
20 21
21MODULE_DESCRIPTION("FS Cache Manager"); 22MODULE_DESCRIPTION("FS Cache Manager");
diff --git a/fs/fscache/netfs.c b/fs/fscache/netfs.c
index a8aa00be4444..c2f605483cc5 100644
--- a/fs/fscache/netfs.c
+++ b/fs/fscache/netfs.c
@@ -14,69 +14,51 @@
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include "internal.h" 15#include "internal.h"
16 16
17static LIST_HEAD(fscache_netfs_list);
18
19/* 17/*
20 * register a network filesystem for caching 18 * register a network filesystem for caching
21 */ 19 */
22int __fscache_register_netfs(struct fscache_netfs *netfs) 20int __fscache_register_netfs(struct fscache_netfs *netfs)
23{ 21{
24 struct fscache_netfs *ptr; 22 struct fscache_cookie *candidate, *cookie;
25 struct fscache_cookie *cookie;
26 int ret;
27 23
28 _enter("{%s}", netfs->name); 24 _enter("{%s}", netfs->name);
29 25
30 INIT_LIST_HEAD(&netfs->link);
31
32 /* allocate a cookie for the primary index */ 26 /* allocate a cookie for the primary index */
33 cookie = kmem_cache_zalloc(fscache_cookie_jar, GFP_KERNEL); 27 candidate = fscache_alloc_cookie(&fscache_fsdef_index,
34 28 &fscache_fsdef_netfs_def,
35 if (!cookie) { 29 netfs->name, strlen(netfs->name),
30 &netfs->version, sizeof(netfs->version),
31 netfs, 0);
32 if (!candidate) {
36 _leave(" = -ENOMEM"); 33 _leave(" = -ENOMEM");
37 return -ENOMEM; 34 return -ENOMEM;
38 } 35 }
39 36
40 /* initialise the primary index cookie */ 37 candidate->flags = 1 << FSCACHE_COOKIE_ENABLED;
41 atomic_set(&cookie->usage, 1);
42 atomic_set(&cookie->n_children, 0);
43 atomic_set(&cookie->n_active, 1);
44
45 cookie->def = &fscache_fsdef_netfs_def;
46 cookie->parent = &fscache_fsdef_index;
47 cookie->netfs_data = netfs;
48 cookie->flags = 1 << FSCACHE_COOKIE_ENABLED;
49
50 spin_lock_init(&cookie->lock);
51 spin_lock_init(&cookie->stores_lock);
52 INIT_HLIST_HEAD(&cookie->backing_objects);
53 38
54 /* check the netfs type is not already present */ 39 /* check the netfs type is not already present */
55 down_write(&fscache_addremove_sem); 40 cookie = fscache_hash_cookie(candidate);
56 41 if (!cookie)
57 ret = -EEXIST; 42 goto already_registered;
58 list_for_each_entry(ptr, &fscache_netfs_list, link) { 43 if (cookie != candidate) {
59 if (strcmp(ptr->name, netfs->name) == 0) 44 trace_fscache_cookie(candidate, fscache_cookie_discard, 1);
60 goto already_registered; 45 fscache_free_cookie(candidate);
61 } 46 }
62 47
63 atomic_inc(&cookie->parent->usage); 48 fscache_cookie_get(cookie->parent, fscache_cookie_get_register_netfs);
64 atomic_inc(&cookie->parent->n_children); 49 atomic_inc(&cookie->parent->n_children);
65 50
66 netfs->primary_index = cookie; 51 netfs->primary_index = cookie;
67 list_add(&netfs->link, &fscache_netfs_list);
68 ret = 0;
69 52
70 pr_notice("Netfs '%s' registered for caching\n", netfs->name); 53 pr_notice("Netfs '%s' registered for caching\n", netfs->name);
54 trace_fscache_netfs(netfs);
55 _leave(" = 0");
56 return 0;
71 57
72already_registered: 58already_registered:
73 up_write(&fscache_addremove_sem); 59 fscache_cookie_put(candidate, fscache_cookie_put_dup_netfs);
74 60 _leave(" = -EEXIST");
75 if (ret < 0) 61 return -EEXIST;
76 kmem_cache_free(fscache_cookie_jar, cookie);
77
78 _leave(" = %d", ret);
79 return ret;
80} 62}
81EXPORT_SYMBOL(__fscache_register_netfs); 63EXPORT_SYMBOL(__fscache_register_netfs);
82 64
@@ -88,15 +70,8 @@ void __fscache_unregister_netfs(struct fscache_netfs *netfs)
88{ 70{
89 _enter("{%s.%u}", netfs->name, netfs->version); 71 _enter("{%s.%u}", netfs->name, netfs->version);
90 72
91 down_write(&fscache_addremove_sem); 73 fscache_relinquish_cookie(netfs->primary_index, NULL, false);
92 74 pr_notice("Netfs '%s' unregistered from caching\n", netfs->name);
93 list_del(&netfs->link);
94 fscache_relinquish_cookie(netfs->primary_index, 0);
95
96 up_write(&fscache_addremove_sem);
97
98 pr_notice("Netfs '%s' unregistered from caching\n",
99 netfs->name);
100 75
101 _leave(""); 76 _leave("");
102} 77}
diff --git a/fs/fscache/object-list.c b/fs/fscache/object-list.c
index 0438d4cd91ef..43e6e28c164f 100644
--- a/fs/fscache/object-list.c
+++ b/fs/fscache/object-list.c
@@ -36,8 +36,6 @@ struct fscache_objlist_data {
36#define FSCACHE_OBJLIST_CONFIG_NOEVENTS 0x00000800 /* show objects without no events */ 36#define FSCACHE_OBJLIST_CONFIG_NOEVENTS 0x00000800 /* show objects without no events */
37#define FSCACHE_OBJLIST_CONFIG_WORK 0x00001000 /* show objects with work */ 37#define FSCACHE_OBJLIST_CONFIG_WORK 0x00001000 /* show objects with work */
38#define FSCACHE_OBJLIST_CONFIG_NOWORK 0x00002000 /* show objects without work */ 38#define FSCACHE_OBJLIST_CONFIG_NOWORK 0x00002000 /* show objects without work */
39
40 u8 buf[512]; /* key and aux data buffer */
41}; 39};
42 40
43/* 41/*
@@ -170,7 +168,7 @@ static int fscache_objlist_show(struct seq_file *m, void *v)
170 struct fscache_cookie *cookie; 168 struct fscache_cookie *cookie;
171 unsigned long config = data->config; 169 unsigned long config = data->config;
172 char _type[3], *type; 170 char _type[3], *type;
173 u8 *buf = data->buf, *p; 171 u8 *p;
174 172
175 if ((unsigned long) v == 1) { 173 if ((unsigned long) v == 1) {
176 seq_puts(m, "OBJECT PARENT STAT CHLDN OPS OOP IPR EX READS" 174 seq_puts(m, "OBJECT PARENT STAT CHLDN OPS OOP IPR EX READS"
@@ -254,7 +252,7 @@ static int fscache_objlist_show(struct seq_file *m, void *v)
254 if (fscache_use_cookie(obj)) { 252 if (fscache_use_cookie(obj)) {
255 uint16_t keylen = 0, auxlen = 0; 253 uint16_t keylen = 0, auxlen = 0;
256 254
257 switch (cookie->def->type) { 255 switch (cookie->type) {
258 case 0: 256 case 0:
259 type = "IX"; 257 type = "IX";
260 break; 258 break;
@@ -263,7 +261,7 @@ static int fscache_objlist_show(struct seq_file *m, void *v)
263 break; 261 break;
264 default: 262 default:
265 snprintf(_type, sizeof(_type), "%02u", 263 snprintf(_type, sizeof(_type), "%02u",
266 cookie->def->type); 264 cookie->type);
267 type = _type; 265 type = _type;
268 break; 266 break;
269 } 267 }
@@ -274,30 +272,30 @@ static int fscache_objlist_show(struct seq_file *m, void *v)
274 cookie->flags, 272 cookie->flags,
275 cookie->netfs_data); 273 cookie->netfs_data);
276 274
277 if (cookie->def->get_key && 275 if (config & FSCACHE_OBJLIST_CONFIG_KEY)
278 config & FSCACHE_OBJLIST_CONFIG_KEY) 276 keylen = cookie->key_len;
279 keylen = cookie->def->get_key(cookie->netfs_data,
280 buf, 400);
281 277
282 if (cookie->def->get_aux && 278 if (config & FSCACHE_OBJLIST_CONFIG_AUX)
283 config & FSCACHE_OBJLIST_CONFIG_AUX) 279 auxlen = cookie->aux_len;
284 auxlen = cookie->def->get_aux(cookie->netfs_data,
285 buf + keylen, 512 - keylen);
286 fscache_unuse_cookie(obj);
287 280
288 if (keylen > 0 || auxlen > 0) { 281 if (keylen > 0 || auxlen > 0) {
289 seq_puts(m, " "); 282 seq_puts(m, " ");
290 for (p = buf; keylen > 0; keylen--) 283 p = keylen <= sizeof(cookie->inline_key) ?
284 cookie->inline_key : cookie->key;
285 for (; keylen > 0; keylen--)
291 seq_printf(m, "%02x", *p++); 286 seq_printf(m, "%02x", *p++);
292 if (auxlen > 0) { 287 if (auxlen > 0) {
293 if (config & FSCACHE_OBJLIST_CONFIG_KEY) 288 if (config & FSCACHE_OBJLIST_CONFIG_KEY)
294 seq_puts(m, ", "); 289 seq_puts(m, ", ");
290 p = auxlen <= sizeof(cookie->inline_aux) ?
291 cookie->inline_aux : cookie->aux;
295 for (; auxlen > 0; auxlen--) 292 for (; auxlen > 0; auxlen--)
296 seq_printf(m, "%02x", *p++); 293 seq_printf(m, "%02x", *p++);
297 } 294 }
298 } 295 }
299 296
300 seq_puts(m, "\n"); 297 seq_puts(m, "\n");
298 fscache_unuse_cookie(obj);
301 } else { 299 } else {
302 seq_puts(m, "<no_netfs>\n"); 300 seq_puts(m, "<no_netfs>\n");
303 } 301 }
diff --git a/fs/fscache/object.c b/fs/fscache/object.c
index 7a182c87f378..1085ca12e25c 100644
--- a/fs/fscache/object.c
+++ b/fs/fscache/object.c
@@ -138,10 +138,13 @@ static const struct fscache_transition fscache_osm_run_oob[] = {
138 { 0, NULL } 138 { 0, NULL }
139}; 139};
140 140
141static int fscache_get_object(struct fscache_object *); 141static int fscache_get_object(struct fscache_object *,
142static void fscache_put_object(struct fscache_object *); 142 enum fscache_obj_ref_trace);
143static void fscache_put_object(struct fscache_object *,
144 enum fscache_obj_ref_trace);
143static bool fscache_enqueue_dependents(struct fscache_object *, int); 145static bool fscache_enqueue_dependents(struct fscache_object *, int);
144static void fscache_dequeue_object(struct fscache_object *); 146static void fscache_dequeue_object(struct fscache_object *);
147static void fscache_update_aux_data(struct fscache_object *);
145 148
146/* 149/*
147 * we need to notify the parent when an op completes that we had outstanding 150 * we need to notify the parent when an op completes that we had outstanding
@@ -170,6 +173,7 @@ static void fscache_object_sm_dispatcher(struct fscache_object *object)
170 const struct fscache_transition *t; 173 const struct fscache_transition *t;
171 const struct fscache_state *state, *new_state; 174 const struct fscache_state *state, *new_state;
172 unsigned long events, event_mask; 175 unsigned long events, event_mask;
176 bool oob;
173 int event = -1; 177 int event = -1;
174 178
175 ASSERT(object != NULL); 179 ASSERT(object != NULL);
@@ -188,6 +192,7 @@ restart_masked:
188 if (events & object->oob_event_mask) { 192 if (events & object->oob_event_mask) {
189 _debug("{OBJ%x} oob %lx", 193 _debug("{OBJ%x} oob %lx",
190 object->debug_id, events & object->oob_event_mask); 194 object->debug_id, events & object->oob_event_mask);
195 oob = true;
191 for (t = object->oob_table; t->events; t++) { 196 for (t = object->oob_table; t->events; t++) {
192 if (events & t->events) { 197 if (events & t->events) {
193 state = t->transit_to; 198 state = t->transit_to;
@@ -199,6 +204,7 @@ restart_masked:
199 } 204 }
200 } 205 }
201 } 206 }
207 oob = false;
202 208
203 /* Wait states are just transition tables */ 209 /* Wait states are just transition tables */
204 if (!state->work) { 210 if (!state->work) {
@@ -207,6 +213,8 @@ restart_masked:
207 if (events & t->events) { 213 if (events & t->events) {
208 new_state = t->transit_to; 214 new_state = t->transit_to;
209 event = fls(events & t->events) - 1; 215 event = fls(events & t->events) - 1;
216 trace_fscache_osm(object, state,
217 true, false, event);
210 clear_bit(event, &object->events); 218 clear_bit(event, &object->events);
211 _debug("{OBJ%x} ev %d: %s -> %s", 219 _debug("{OBJ%x} ev %d: %s -> %s",
212 object->debug_id, event, 220 object->debug_id, event,
@@ -226,6 +234,7 @@ restart_masked:
226execute_work_state: 234execute_work_state:
227 _debug("{OBJ%x} exec %s", object->debug_id, state->name); 235 _debug("{OBJ%x} exec %s", object->debug_id, state->name);
228 236
237 trace_fscache_osm(object, state, false, oob, event);
229 new_state = state->work(object, event); 238 new_state = state->work(object, event);
230 event = -1; 239 event = -1;
231 if (new_state == NO_TRANSIT) { 240 if (new_state == NO_TRANSIT) {
@@ -279,7 +288,7 @@ static void fscache_object_work_func(struct work_struct *work)
279 start = jiffies; 288 start = jiffies;
280 fscache_object_sm_dispatcher(object); 289 fscache_object_sm_dispatcher(object);
281 fscache_hist(fscache_objs_histogram, start); 290 fscache_hist(fscache_objs_histogram, start);
282 fscache_put_object(object); 291 fscache_put_object(object, fscache_obj_put_work);
283} 292}
284 293
285/** 294/**
@@ -397,7 +406,7 @@ static const struct fscache_state *fscache_initialise_object(struct fscache_obje
397 fscache_stat(&fscache_n_cop_grab_object); 406 fscache_stat(&fscache_n_cop_grab_object);
398 success = false; 407 success = false;
399 if (fscache_object_is_live(parent) && 408 if (fscache_object_is_live(parent) &&
400 object->cache->ops->grab_object(object)) { 409 object->cache->ops->grab_object(object, fscache_obj_get_add_to_deps)) {
401 list_add(&object->dep_link, &parent->dependents); 410 list_add(&object->dep_link, &parent->dependents);
402 success = true; 411 success = true;
403 } 412 }
@@ -703,6 +712,11 @@ static const struct fscache_state *fscache_drop_object(struct fscache_object *ob
703 ASSERT(cookie != NULL); 712 ASSERT(cookie != NULL);
704 ASSERT(!hlist_unhashed(&object->cookie_link)); 713 ASSERT(!hlist_unhashed(&object->cookie_link));
705 714
715 if (test_bit(FSCACHE_COOKIE_AUX_UPDATED, &cookie->flags)) {
716 _debug("final update");
717 fscache_update_aux_data(object);
718 }
719
706 /* Make sure the cookie no longer points here and that the netfs isn't 720 /* Make sure the cookie no longer points here and that the netfs isn't
707 * waiting for us. 721 * waiting for us.
708 */ 722 */
@@ -745,7 +759,7 @@ static const struct fscache_state *fscache_drop_object(struct fscache_object *ob
745 } 759 }
746 760
747 /* this just shifts the object release to the work processor */ 761 /* this just shifts the object release to the work processor */
748 fscache_put_object(object); 762 fscache_put_object(object, fscache_obj_put_drop_obj);
749 fscache_stat(&fscache_n_object_dead); 763 fscache_stat(&fscache_n_object_dead);
750 764
751 _leave(""); 765 _leave("");
@@ -755,12 +769,13 @@ static const struct fscache_state *fscache_drop_object(struct fscache_object *ob
755/* 769/*
756 * get a ref on an object 770 * get a ref on an object
757 */ 771 */
758static int fscache_get_object(struct fscache_object *object) 772static int fscache_get_object(struct fscache_object *object,
773 enum fscache_obj_ref_trace why)
759{ 774{
760 int ret; 775 int ret;
761 776
762 fscache_stat(&fscache_n_cop_grab_object); 777 fscache_stat(&fscache_n_cop_grab_object);
763 ret = object->cache->ops->grab_object(object) ? 0 : -EAGAIN; 778 ret = object->cache->ops->grab_object(object, why) ? 0 : -EAGAIN;
764 fscache_stat_d(&fscache_n_cop_grab_object); 779 fscache_stat_d(&fscache_n_cop_grab_object);
765 return ret; 780 return ret;
766} 781}
@@ -768,10 +783,11 @@ static int fscache_get_object(struct fscache_object *object)
768/* 783/*
769 * Discard a ref on an object 784 * Discard a ref on an object
770 */ 785 */
771static void fscache_put_object(struct fscache_object *object) 786static void fscache_put_object(struct fscache_object *object,
787 enum fscache_obj_ref_trace why)
772{ 788{
773 fscache_stat(&fscache_n_cop_put_object); 789 fscache_stat(&fscache_n_cop_put_object);
774 object->cache->ops->put_object(object); 790 object->cache->ops->put_object(object, why);
775 fscache_stat_d(&fscache_n_cop_put_object); 791 fscache_stat_d(&fscache_n_cop_put_object);
776} 792}
777 793
@@ -786,7 +802,7 @@ void fscache_object_destroy(struct fscache_object *object)
786 fscache_objlist_remove(object); 802 fscache_objlist_remove(object);
787 803
788 /* We can get rid of the cookie now */ 804 /* We can get rid of the cookie now */
789 fscache_cookie_put(object->cookie); 805 fscache_cookie_put(object->cookie, fscache_cookie_put_object);
790 object->cookie = NULL; 806 object->cookie = NULL;
791} 807}
792EXPORT_SYMBOL(fscache_object_destroy); 808EXPORT_SYMBOL(fscache_object_destroy);
@@ -798,7 +814,7 @@ void fscache_enqueue_object(struct fscache_object *object)
798{ 814{
799 _enter("{OBJ%x}", object->debug_id); 815 _enter("{OBJ%x}", object->debug_id);
800 816
801 if (fscache_get_object(object) >= 0) { 817 if (fscache_get_object(object, fscache_obj_get_queue) >= 0) {
802 wait_queue_head_t *cong_wq = 818 wait_queue_head_t *cong_wq =
803 &get_cpu_var(fscache_object_cong_wait); 819 &get_cpu_var(fscache_object_cong_wait);
804 820
@@ -806,7 +822,7 @@ void fscache_enqueue_object(struct fscache_object *object)
806 if (fscache_object_congested()) 822 if (fscache_object_congested())
807 wake_up(cong_wq); 823 wake_up(cong_wq);
808 } else 824 } else
809 fscache_put_object(object); 825 fscache_put_object(object, fscache_obj_put_queue);
810 826
811 put_cpu_var(fscache_object_cong_wait); 827 put_cpu_var(fscache_object_cong_wait);
812 } 828 }
@@ -866,7 +882,7 @@ static bool fscache_enqueue_dependents(struct fscache_object *object, int event)
866 list_del_init(&dep->dep_link); 882 list_del_init(&dep->dep_link);
867 883
868 fscache_raise_event(dep, event); 884 fscache_raise_event(dep, event);
869 fscache_put_object(dep); 885 fscache_put_object(dep, fscache_obj_put_enq_dep);
870 886
871 if (!list_empty(&object->dependents) && need_resched()) { 887 if (!list_empty(&object->dependents) && need_resched()) {
872 ret = false; 888 ret = false;
@@ -906,7 +922,8 @@ static void fscache_dequeue_object(struct fscache_object *object)
906 * and creation). 922 * and creation).
907 */ 923 */
908enum fscache_checkaux fscache_check_aux(struct fscache_object *object, 924enum fscache_checkaux fscache_check_aux(struct fscache_object *object,
909 const void *data, uint16_t datalen) 925 const void *data, uint16_t datalen,
926 loff_t object_size)
910{ 927{
911 enum fscache_checkaux result; 928 enum fscache_checkaux result;
912 929
@@ -916,7 +933,7 @@ enum fscache_checkaux fscache_check_aux(struct fscache_object *object,
916 } 933 }
917 934
918 result = object->cookie->def->check_aux(object->cookie->netfs_data, 935 result = object->cookie->def->check_aux(object->cookie->netfs_data,
919 data, datalen); 936 data, datalen, object_size);
920 switch (result) { 937 switch (result) {
921 /* entry okay as is */ 938 /* entry okay as is */
922 case FSCACHE_CHECKAUX_OKAY: 939 case FSCACHE_CHECKAUX_OKAY:
@@ -972,11 +989,12 @@ static const struct fscache_state *_fscache_invalidate_object(struct fscache_obj
972 if (!op) 989 if (!op)
973 goto nomem; 990 goto nomem;
974 991
975 fscache_operation_init(op, object->cache->ops->invalidate_object, 992 fscache_operation_init(cookie, op, object->cache->ops->invalidate_object,
976 NULL, NULL); 993 NULL, NULL);
977 op->flags = FSCACHE_OP_ASYNC | 994 op->flags = FSCACHE_OP_ASYNC |
978 (1 << FSCACHE_OP_EXCLUSIVE) | 995 (1 << FSCACHE_OP_EXCLUSIVE) |
979 (1 << FSCACHE_OP_UNUSE_COOKIE); 996 (1 << FSCACHE_OP_UNUSE_COOKIE);
997 trace_fscache_page_op(cookie, NULL, op, fscache_page_op_invalidate);
980 998
981 spin_lock(&cookie->lock); 999 spin_lock(&cookie->lock);
982 if (fscache_submit_exclusive_op(object, op) < 0) 1000 if (fscache_submit_exclusive_op(object, op) < 0)
@@ -1026,6 +1044,17 @@ static const struct fscache_state *fscache_invalidate_object(struct fscache_obje
1026} 1044}
1027 1045
1028/* 1046/*
1047 * Update auxiliary data.
1048 */
1049static void fscache_update_aux_data(struct fscache_object *object)
1050{
1051 fscache_stat(&fscache_n_updates_run);
1052 fscache_stat(&fscache_n_cop_update_object);
1053 object->cache->ops->update_object(object);
1054 fscache_stat_d(&fscache_n_cop_update_object);
1055}
1056
1057/*
1029 * Asynchronously update an object. 1058 * Asynchronously update an object.
1030 */ 1059 */
1031static const struct fscache_state *fscache_update_object(struct fscache_object *object, 1060static const struct fscache_state *fscache_update_object(struct fscache_object *object,
@@ -1033,10 +1062,7 @@ static const struct fscache_state *fscache_update_object(struct fscache_object *
1033{ 1062{
1034 _enter("{OBJ%x},%d", object->debug_id, event); 1063 _enter("{OBJ%x},%d", object->debug_id, event);
1035 1064
1036 fscache_stat(&fscache_n_updates_run); 1065 fscache_update_aux_data(object);
1037 fscache_stat(&fscache_n_cop_update_object);
1038 object->cache->ops->update_object(object);
1039 fscache_stat_d(&fscache_n_cop_update_object);
1040 1066
1041 _leave(""); 1067 _leave("");
1042 return transit_to(WAIT_FOR_CMD); 1068 return transit_to(WAIT_FOR_CMD);
diff --git a/fs/fscache/operation.c b/fs/fscache/operation.c
index de67745e1cd7..e30c5975ea58 100644
--- a/fs/fscache/operation.c
+++ b/fs/fscache/operation.c
@@ -32,7 +32,8 @@ static void fscache_operation_dummy_cancel(struct fscache_operation *op)
32 * Do basic initialisation of an operation. The caller must still set flags, 32 * Do basic initialisation of an operation. The caller must still set flags,
33 * object and processor if needed. 33 * object and processor if needed.
34 */ 34 */
35void fscache_operation_init(struct fscache_operation *op, 35void fscache_operation_init(struct fscache_cookie *cookie,
36 struct fscache_operation *op,
36 fscache_operation_processor_t processor, 37 fscache_operation_processor_t processor,
37 fscache_operation_cancel_t cancel, 38 fscache_operation_cancel_t cancel,
38 fscache_operation_release_t release) 39 fscache_operation_release_t release)
@@ -46,6 +47,7 @@ void fscache_operation_init(struct fscache_operation *op,
46 op->release = release; 47 op->release = release;
47 INIT_LIST_HEAD(&op->pend_link); 48 INIT_LIST_HEAD(&op->pend_link);
48 fscache_stat(&fscache_n_op_initialised); 49 fscache_stat(&fscache_n_op_initialised);
50 trace_fscache_op(cookie, op, fscache_op_init);
49} 51}
50EXPORT_SYMBOL(fscache_operation_init); 52EXPORT_SYMBOL(fscache_operation_init);
51 53
@@ -59,6 +61,8 @@ EXPORT_SYMBOL(fscache_operation_init);
59 */ 61 */
60void fscache_enqueue_operation(struct fscache_operation *op) 62void fscache_enqueue_operation(struct fscache_operation *op)
61{ 63{
64 struct fscache_cookie *cookie = op->object->cookie;
65
62 _enter("{OBJ%x OP%x,%u}", 66 _enter("{OBJ%x OP%x,%u}",
63 op->object->debug_id, op->debug_id, atomic_read(&op->usage)); 67 op->object->debug_id, op->debug_id, atomic_read(&op->usage));
64 68
@@ -71,12 +75,14 @@ void fscache_enqueue_operation(struct fscache_operation *op)
71 fscache_stat(&fscache_n_op_enqueue); 75 fscache_stat(&fscache_n_op_enqueue);
72 switch (op->flags & FSCACHE_OP_TYPE) { 76 switch (op->flags & FSCACHE_OP_TYPE) {
73 case FSCACHE_OP_ASYNC: 77 case FSCACHE_OP_ASYNC:
78 trace_fscache_op(cookie, op, fscache_op_enqueue_async);
74 _debug("queue async"); 79 _debug("queue async");
75 atomic_inc(&op->usage); 80 atomic_inc(&op->usage);
76 if (!queue_work(fscache_op_wq, &op->work)) 81 if (!queue_work(fscache_op_wq, &op->work))
77 fscache_put_operation(op); 82 fscache_put_operation(op);
78 break; 83 break;
79 case FSCACHE_OP_MYTHREAD: 84 case FSCACHE_OP_MYTHREAD:
85 trace_fscache_op(cookie, op, fscache_op_enqueue_mythread);
80 _debug("queue for caller's attention"); 86 _debug("queue for caller's attention");
81 break; 87 break;
82 default: 88 default:
@@ -101,6 +107,8 @@ static void fscache_run_op(struct fscache_object *object,
101 wake_up_bit(&op->flags, FSCACHE_OP_WAITING); 107 wake_up_bit(&op->flags, FSCACHE_OP_WAITING);
102 if (op->processor) 108 if (op->processor)
103 fscache_enqueue_operation(op); 109 fscache_enqueue_operation(op);
110 else
111 trace_fscache_op(object->cookie, op, fscache_op_run);
104 fscache_stat(&fscache_n_op_run); 112 fscache_stat(&fscache_n_op_run);
105} 113}
106 114
@@ -155,6 +163,8 @@ int fscache_submit_exclusive_op(struct fscache_object *object,
155 163
156 _enter("{OBJ%x OP%x},", object->debug_id, op->debug_id); 164 _enter("{OBJ%x OP%x},", object->debug_id, op->debug_id);
157 165
166 trace_fscache_op(object->cookie, op, fscache_op_submit_ex);
167
158 ASSERTCMP(op->state, ==, FSCACHE_OP_ST_INITIALISED); 168 ASSERTCMP(op->state, ==, FSCACHE_OP_ST_INITIALISED);
159 ASSERTCMP(atomic_read(&op->usage), >, 0); 169 ASSERTCMP(atomic_read(&op->usage), >, 0);
160 170
@@ -240,6 +250,8 @@ int fscache_submit_op(struct fscache_object *object,
240 _enter("{OBJ%x OP%x},{%u}", 250 _enter("{OBJ%x OP%x},{%u}",
241 object->debug_id, op->debug_id, atomic_read(&op->usage)); 251 object->debug_id, op->debug_id, atomic_read(&op->usage));
242 252
253 trace_fscache_op(object->cookie, op, fscache_op_submit);
254
243 ASSERTCMP(op->state, ==, FSCACHE_OP_ST_INITIALISED); 255 ASSERTCMP(op->state, ==, FSCACHE_OP_ST_INITIALISED);
244 ASSERTCMP(atomic_read(&op->usage), >, 0); 256 ASSERTCMP(atomic_read(&op->usage), >, 0);
245 257
@@ -357,6 +369,8 @@ int fscache_cancel_op(struct fscache_operation *op,
357 369
358 _enter("OBJ%x OP%x}", op->object->debug_id, op->debug_id); 370 _enter("OBJ%x OP%x}", op->object->debug_id, op->debug_id);
359 371
372 trace_fscache_op(object->cookie, op, fscache_op_cancel);
373
360 ASSERTCMP(op->state, >=, FSCACHE_OP_ST_PENDING); 374 ASSERTCMP(op->state, >=, FSCACHE_OP_ST_PENDING);
361 ASSERTCMP(op->state, !=, FSCACHE_OP_ST_CANCELLED); 375 ASSERTCMP(op->state, !=, FSCACHE_OP_ST_CANCELLED);
362 ASSERTCMP(atomic_read(&op->usage), >, 0); 376 ASSERTCMP(atomic_read(&op->usage), >, 0);
@@ -419,6 +433,8 @@ void fscache_cancel_all_ops(struct fscache_object *object)
419 fscache_stat(&fscache_n_op_cancelled); 433 fscache_stat(&fscache_n_op_cancelled);
420 list_del_init(&op->pend_link); 434 list_del_init(&op->pend_link);
421 435
436 trace_fscache_op(object->cookie, op, fscache_op_cancel_all);
437
422 ASSERTCMP(op->state, ==, FSCACHE_OP_ST_PENDING); 438 ASSERTCMP(op->state, ==, FSCACHE_OP_ST_PENDING);
423 op->cancel(op); 439 op->cancel(op);
424 op->state = FSCACHE_OP_ST_CANCELLED; 440 op->state = FSCACHE_OP_ST_CANCELLED;
@@ -454,9 +470,11 @@ void fscache_op_complete(struct fscache_operation *op, bool cancelled)
454 spin_lock(&object->lock); 470 spin_lock(&object->lock);
455 471
456 if (!cancelled) { 472 if (!cancelled) {
473 trace_fscache_op(object->cookie, op, fscache_op_completed);
457 op->state = FSCACHE_OP_ST_COMPLETE; 474 op->state = FSCACHE_OP_ST_COMPLETE;
458 } else { 475 } else {
459 op->cancel(op); 476 op->cancel(op);
477 trace_fscache_op(object->cookie, op, fscache_op_cancelled);
460 op->state = FSCACHE_OP_ST_CANCELLED; 478 op->state = FSCACHE_OP_ST_CANCELLED;
461 } 479 }
462 480
@@ -488,6 +506,8 @@ void fscache_put_operation(struct fscache_operation *op)
488 if (!atomic_dec_and_test(&op->usage)) 506 if (!atomic_dec_and_test(&op->usage))
489 return; 507 return;
490 508
509 trace_fscache_op(op->object ? op->object->cookie : NULL, op, fscache_op_put);
510
491 _debug("PUT OP"); 511 _debug("PUT OP");
492 ASSERTIFCMP(op->state != FSCACHE_OP_ST_INITIALISED && 512 ASSERTIFCMP(op->state != FSCACHE_OP_ST_INITIALISED &&
493 op->state != FSCACHE_OP_ST_COMPLETE, 513 op->state != FSCACHE_OP_ST_COMPLETE,
@@ -563,6 +583,8 @@ void fscache_operation_gc(struct work_struct *work)
563 spin_unlock(&cache->op_gc_list_lock); 583 spin_unlock(&cache->op_gc_list_lock);
564 584
565 object = op->object; 585 object = op->object;
586 trace_fscache_op(object->cookie, op, fscache_op_gc);
587
566 spin_lock(&object->lock); 588 spin_lock(&object->lock);
567 589
568 _debug("GC DEFERRED REL OBJ%x OP%x", 590 _debug("GC DEFERRED REL OBJ%x OP%x",
@@ -601,6 +623,8 @@ void fscache_op_work_func(struct work_struct *work)
601 _enter("{OBJ%x OP%x,%d}", 623 _enter("{OBJ%x OP%x,%d}",
602 op->object->debug_id, op->debug_id, atomic_read(&op->usage)); 624 op->object->debug_id, op->debug_id, atomic_read(&op->usage));
603 625
626 trace_fscache_op(op->object->cookie, op, fscache_op_work);
627
604 ASSERT(op->processor != NULL); 628 ASSERT(op->processor != NULL);
605 start = jiffies; 629 start = jiffies;
606 op->processor(op); 630 op->processor(op);
diff --git a/fs/fscache/page.c b/fs/fscache/page.c
index 961029e04027..111349f67d98 100644
--- a/fs/fscache/page.c
+++ b/fs/fscache/page.c
@@ -27,6 +27,7 @@ bool __fscache_check_page_write(struct fscache_cookie *cookie, struct page *page
27 rcu_read_lock(); 27 rcu_read_lock();
28 val = radix_tree_lookup(&cookie->stores, page->index); 28 val = radix_tree_lookup(&cookie->stores, page->index);
29 rcu_read_unlock(); 29 rcu_read_unlock();
30 trace_fscache_check_page(cookie, page, val, 0);
30 31
31 return val != NULL; 32 return val != NULL;
32} 33}
@@ -39,6 +40,8 @@ void __fscache_wait_on_page_write(struct fscache_cookie *cookie, struct page *pa
39{ 40{
40 wait_queue_head_t *wq = bit_waitqueue(&cookie->flags, 0); 41 wait_queue_head_t *wq = bit_waitqueue(&cookie->flags, 0);
41 42
43 trace_fscache_page(cookie, page, fscache_page_write_wait);
44
42 wait_event(*wq, !__fscache_check_page_write(cookie, page)); 45 wait_event(*wq, !__fscache_check_page_write(cookie, page));
43} 46}
44EXPORT_SYMBOL(__fscache_wait_on_page_write); 47EXPORT_SYMBOL(__fscache_wait_on_page_write);
@@ -69,6 +72,8 @@ bool __fscache_maybe_release_page(struct fscache_cookie *cookie,
69 72
70 _enter("%p,%p,%x", cookie, page, gfp); 73 _enter("%p,%p,%x", cookie, page, gfp);
71 74
75 trace_fscache_page(cookie, page, fscache_page_maybe_release);
76
72try_again: 77try_again:
73 rcu_read_lock(); 78 rcu_read_lock();
74 val = radix_tree_lookup(&cookie->stores, page->index); 79 val = radix_tree_lookup(&cookie->stores, page->index);
@@ -101,6 +106,7 @@ try_again:
101 } 106 }
102 107
103 xpage = radix_tree_delete(&cookie->stores, page->index); 108 xpage = radix_tree_delete(&cookie->stores, page->index);
109 trace_fscache_page(cookie, page, fscache_page_radix_delete);
104 spin_unlock(&cookie->stores_lock); 110 spin_unlock(&cookie->stores_lock);
105 111
106 if (xpage) { 112 if (xpage) {
@@ -112,6 +118,7 @@ try_again:
112 } 118 }
113 119
114 wake_up_bit(&cookie->flags, 0); 120 wake_up_bit(&cookie->flags, 0);
121 trace_fscache_wake_cookie(cookie);
115 if (xpage) 122 if (xpage)
116 put_page(xpage); 123 put_page(xpage);
117 __fscache_uncache_page(cookie, page); 124 __fscache_uncache_page(cookie, page);
@@ -144,7 +151,7 @@ static void fscache_end_page_write(struct fscache_object *object,
144 struct page *page) 151 struct page *page)
145{ 152{
146 struct fscache_cookie *cookie; 153 struct fscache_cookie *cookie;
147 struct page *xpage = NULL; 154 struct page *xpage = NULL, *val;
148 155
149 spin_lock(&object->lock); 156 spin_lock(&object->lock);
150 cookie = object->cookie; 157 cookie = object->cookie;
@@ -154,13 +161,24 @@ static void fscache_end_page_write(struct fscache_object *object,
154 spin_lock(&cookie->stores_lock); 161 spin_lock(&cookie->stores_lock);
155 radix_tree_tag_clear(&cookie->stores, page->index, 162 radix_tree_tag_clear(&cookie->stores, page->index,
156 FSCACHE_COOKIE_STORING_TAG); 163 FSCACHE_COOKIE_STORING_TAG);
164 trace_fscache_page(cookie, page, fscache_page_radix_clear_store);
157 if (!radix_tree_tag_get(&cookie->stores, page->index, 165 if (!radix_tree_tag_get(&cookie->stores, page->index,
158 FSCACHE_COOKIE_PENDING_TAG)) { 166 FSCACHE_COOKIE_PENDING_TAG)) {
159 fscache_stat(&fscache_n_store_radix_deletes); 167 fscache_stat(&fscache_n_store_radix_deletes);
160 xpage = radix_tree_delete(&cookie->stores, page->index); 168 xpage = radix_tree_delete(&cookie->stores, page->index);
169 trace_fscache_page(cookie, page, fscache_page_radix_delete);
170 trace_fscache_page(cookie, page, fscache_page_write_end);
171
172 val = radix_tree_lookup(&cookie->stores, page->index);
173 trace_fscache_check_page(cookie, page, val, 1);
174 } else {
175 trace_fscache_page(cookie, page, fscache_page_write_end_pend);
161 } 176 }
162 spin_unlock(&cookie->stores_lock); 177 spin_unlock(&cookie->stores_lock);
163 wake_up_bit(&cookie->flags, 0); 178 wake_up_bit(&cookie->flags, 0);
179 trace_fscache_wake_cookie(cookie);
180 } else {
181 trace_fscache_page(cookie, page, fscache_page_write_end_noc);
164 } 182 }
165 spin_unlock(&object->lock); 183 spin_unlock(&object->lock);
166 if (xpage) 184 if (xpage)
@@ -185,9 +203,11 @@ static void fscache_attr_changed_op(struct fscache_operation *op)
185 fscache_stat_d(&fscache_n_cop_attr_changed); 203 fscache_stat_d(&fscache_n_cop_attr_changed);
186 if (ret < 0) 204 if (ret < 0)
187 fscache_abort_object(object); 205 fscache_abort_object(object);
206 fscache_op_complete(op, ret < 0);
207 } else {
208 fscache_op_complete(op, true);
188 } 209 }
189 210
190 fscache_op_complete(op, true);
191 _leave(""); 211 _leave("");
192} 212}
193 213
@@ -213,7 +233,8 @@ int __fscache_attr_changed(struct fscache_cookie *cookie)
213 return -ENOMEM; 233 return -ENOMEM;
214 } 234 }
215 235
216 fscache_operation_init(op, fscache_attr_changed_op, NULL, NULL); 236 fscache_operation_init(cookie, op, fscache_attr_changed_op, NULL, NULL);
237 trace_fscache_page_op(cookie, NULL, op, fscache_page_op_attr_changed);
217 op->flags = FSCACHE_OP_ASYNC | 238 op->flags = FSCACHE_OP_ASYNC |
218 (1 << FSCACHE_OP_EXCLUSIVE) | 239 (1 << FSCACHE_OP_EXCLUSIVE) |
219 (1 << FSCACHE_OP_UNUSE_COOKIE); 240 (1 << FSCACHE_OP_UNUSE_COOKIE);
@@ -297,7 +318,7 @@ static struct fscache_retrieval *fscache_alloc_retrieval(
297 return NULL; 318 return NULL;
298 } 319 }
299 320
300 fscache_operation_init(&op->op, NULL, 321 fscache_operation_init(cookie, &op->op, NULL,
301 fscache_do_cancel_retrieval, 322 fscache_do_cancel_retrieval,
302 fscache_release_retrieval_op); 323 fscache_release_retrieval_op);
303 op->op.flags = FSCACHE_OP_MYTHREAD | 324 op->op.flags = FSCACHE_OP_MYTHREAD |
@@ -368,6 +389,7 @@ int fscache_wait_for_operation_activation(struct fscache_object *object,
368 fscache_stat(stat_op_waits); 389 fscache_stat(stat_op_waits);
369 if (wait_on_bit(&op->flags, FSCACHE_OP_WAITING, 390 if (wait_on_bit(&op->flags, FSCACHE_OP_WAITING,
370 TASK_INTERRUPTIBLE) != 0) { 391 TASK_INTERRUPTIBLE) != 0) {
392 trace_fscache_op(object->cookie, op, fscache_op_signal);
371 ret = fscache_cancel_op(op, false); 393 ret = fscache_cancel_op(op, false);
372 if (ret == 0) 394 if (ret == 0)
373 return -ERESTARTSYS; 395 return -ERESTARTSYS;
@@ -389,6 +411,7 @@ check_if_dead:
389 if (unlikely(fscache_object_is_dying(object) || 411 if (unlikely(fscache_object_is_dying(object) ||
390 fscache_cache_is_broken(object))) { 412 fscache_cache_is_broken(object))) {
391 enum fscache_operation_state state = op->state; 413 enum fscache_operation_state state = op->state;
414 trace_fscache_op(object->cookie, op, fscache_op_signal);
392 fscache_cancel_op(op, true); 415 fscache_cancel_op(op, true);
393 if (stat_object_dead) 416 if (stat_object_dead)
394 fscache_stat(stat_object_dead); 417 fscache_stat(stat_object_dead);
@@ -443,6 +466,7 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
443 return -ENOMEM; 466 return -ENOMEM;
444 } 467 }
445 atomic_set(&op->n_pages, 1); 468 atomic_set(&op->n_pages, 1);
469 trace_fscache_page_op(cookie, page, &op->op, fscache_page_op_retr_one);
446 470
447 spin_lock(&cookie->lock); 471 spin_lock(&cookie->lock);
448 472
@@ -571,6 +595,7 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
571 if (!op) 595 if (!op)
572 return -ENOMEM; 596 return -ENOMEM;
573 atomic_set(&op->n_pages, *nr_pages); 597 atomic_set(&op->n_pages, *nr_pages);
598 trace_fscache_page_op(cookie, NULL, &op->op, fscache_page_op_retr_multi);
574 599
575 spin_lock(&cookie->lock); 600 spin_lock(&cookie->lock);
576 601
@@ -682,6 +707,7 @@ int __fscache_alloc_page(struct fscache_cookie *cookie,
682 if (!op) 707 if (!op)
683 return -ENOMEM; 708 return -ENOMEM;
684 atomic_set(&op->n_pages, 1); 709 atomic_set(&op->n_pages, 1);
710 trace_fscache_page_op(cookie, page, &op->op, fscache_page_op_alloc_one);
685 711
686 spin_lock(&cookie->lock); 712 spin_lock(&cookie->lock);
687 713
@@ -776,15 +802,17 @@ static void fscache_write_op(struct fscache_operation *_op)
776 802
777 _enter("{OP%x,%d}", op->op.debug_id, atomic_read(&op->op.usage)); 803 _enter("{OP%x,%d}", op->op.debug_id, atomic_read(&op->op.usage));
778 804
805again:
779 spin_lock(&object->lock); 806 spin_lock(&object->lock);
780 cookie = object->cookie; 807 cookie = object->cookie;
781 808
782 if (!fscache_object_is_active(object)) { 809 if (!fscache_object_is_active(object)) {
783 /* If we get here, then the on-disk cache object likely longer 810 /* If we get here, then the on-disk cache object likely no
784 * exists, so we should just cancel this write operation. 811 * longer exists, so we should just cancel this write
812 * operation.
785 */ 813 */
786 spin_unlock(&object->lock); 814 spin_unlock(&object->lock);
787 fscache_op_complete(&op->op, false); 815 fscache_op_complete(&op->op, true);
788 _leave(" [inactive]"); 816 _leave(" [inactive]");
789 return; 817 return;
790 } 818 }
@@ -797,7 +825,7 @@ static void fscache_write_op(struct fscache_operation *_op)
797 * cancel this write operation. 825 * cancel this write operation.
798 */ 826 */
799 spin_unlock(&object->lock); 827 spin_unlock(&object->lock);
800 fscache_op_complete(&op->op, false); 828 fscache_op_complete(&op->op, true);
801 _leave(" [cancel] op{f=%lx s=%u} obj{s=%s f=%lx}", 829 _leave(" [cancel] op{f=%lx s=%u} obj{s=%s f=%lx}",
802 _op->flags, _op->state, object->state->short_name, 830 _op->flags, _op->state, object->state->short_name,
803 object->flags); 831 object->flags);
@@ -809,30 +837,33 @@ static void fscache_write_op(struct fscache_operation *_op)
809 fscache_stat(&fscache_n_store_calls); 837 fscache_stat(&fscache_n_store_calls);
810 838
811 /* find a page to store */ 839 /* find a page to store */
840 results[0] = NULL;
812 page = NULL; 841 page = NULL;
813 n = radix_tree_gang_lookup_tag(&cookie->stores, results, 0, 1, 842 n = radix_tree_gang_lookup_tag(&cookie->stores, results, 0, 1,
814 FSCACHE_COOKIE_PENDING_TAG); 843 FSCACHE_COOKIE_PENDING_TAG);
844 trace_fscache_gang_lookup(cookie, &op->op, results, n, op->store_limit);
815 if (n != 1) 845 if (n != 1)
816 goto superseded; 846 goto superseded;
817 page = results[0]; 847 page = results[0];
818 _debug("gang %d [%lx]", n, page->index); 848 _debug("gang %d [%lx]", n, page->index);
819 if (page->index >= op->store_limit) {
820 fscache_stat(&fscache_n_store_pages_over_limit);
821 goto superseded;
822 }
823 849
824 radix_tree_tag_set(&cookie->stores, page->index, 850 radix_tree_tag_set(&cookie->stores, page->index,
825 FSCACHE_COOKIE_STORING_TAG); 851 FSCACHE_COOKIE_STORING_TAG);
826 radix_tree_tag_clear(&cookie->stores, page->index, 852 radix_tree_tag_clear(&cookie->stores, page->index,
827 FSCACHE_COOKIE_PENDING_TAG); 853 FSCACHE_COOKIE_PENDING_TAG);
854 trace_fscache_page(cookie, page, fscache_page_radix_pend2store);
828 855
829 spin_unlock(&cookie->stores_lock); 856 spin_unlock(&cookie->stores_lock);
830 spin_unlock(&object->lock); 857 spin_unlock(&object->lock);
831 858
859 if (page->index >= op->store_limit)
860 goto discard_page;
861
832 fscache_stat(&fscache_n_store_pages); 862 fscache_stat(&fscache_n_store_pages);
833 fscache_stat(&fscache_n_cop_write_page); 863 fscache_stat(&fscache_n_cop_write_page);
834 ret = object->cache->ops->write_page(op, page); 864 ret = object->cache->ops->write_page(op, page);
835 fscache_stat_d(&fscache_n_cop_write_page); 865 fscache_stat_d(&fscache_n_cop_write_page);
866 trace_fscache_wrote_page(cookie, page, &op->op, ret);
836 fscache_end_page_write(object, page); 867 fscache_end_page_write(object, page);
837 if (ret < 0) { 868 if (ret < 0) {
838 fscache_abort_object(object); 869 fscache_abort_object(object);
@@ -844,6 +875,12 @@ static void fscache_write_op(struct fscache_operation *_op)
844 _leave(""); 875 _leave("");
845 return; 876 return;
846 877
878discard_page:
879 fscache_stat(&fscache_n_store_pages_over_limit);
880 trace_fscache_wrote_page(cookie, page, &op->op, -ENOBUFS);
881 fscache_end_page_write(object, page);
882 goto again;
883
847superseded: 884superseded:
848 /* this writer is going away and there aren't any more things to 885 /* this writer is going away and there aren't any more things to
849 * write */ 886 * write */
@@ -851,7 +888,7 @@ superseded:
851 spin_unlock(&cookie->stores_lock); 888 spin_unlock(&cookie->stores_lock);
852 clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags); 889 clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags);
853 spin_unlock(&object->lock); 890 spin_unlock(&object->lock);
854 fscache_op_complete(&op->op, true); 891 fscache_op_complete(&op->op, false);
855 _leave(""); 892 _leave("");
856} 893}
857 894
@@ -879,6 +916,8 @@ void fscache_invalidate_writes(struct fscache_cookie *cookie)
879 for (i = n - 1; i >= 0; i--) { 916 for (i = n - 1; i >= 0; i--) {
880 page = results[i]; 917 page = results[i];
881 radix_tree_delete(&cookie->stores, page->index); 918 radix_tree_delete(&cookie->stores, page->index);
919 trace_fscache_page(cookie, page, fscache_page_radix_delete);
920 trace_fscache_page(cookie, page, fscache_page_inval);
882 } 921 }
883 922
884 spin_unlock(&cookie->stores_lock); 923 spin_unlock(&cookie->stores_lock);
@@ -888,6 +927,7 @@ void fscache_invalidate_writes(struct fscache_cookie *cookie)
888 } 927 }
889 928
890 wake_up_bit(&cookie->flags, 0); 929 wake_up_bit(&cookie->flags, 0);
930 trace_fscache_wake_cookie(cookie);
891 931
892 _leave(""); 932 _leave("");
893} 933}
@@ -923,6 +963,7 @@ void fscache_invalidate_writes(struct fscache_cookie *cookie)
923 */ 963 */
924int __fscache_write_page(struct fscache_cookie *cookie, 964int __fscache_write_page(struct fscache_cookie *cookie,
925 struct page *page, 965 struct page *page,
966 loff_t object_size,
926 gfp_t gfp) 967 gfp_t gfp)
927{ 968{
928 struct fscache_storage *op; 969 struct fscache_storage *op;
@@ -946,7 +987,7 @@ int __fscache_write_page(struct fscache_cookie *cookie,
946 if (!op) 987 if (!op)
947 goto nomem; 988 goto nomem;
948 989
949 fscache_operation_init(&op->op, fscache_write_op, NULL, 990 fscache_operation_init(cookie, &op->op, fscache_write_op, NULL,
950 fscache_release_write_op); 991 fscache_release_write_op);
951 op->op.flags = FSCACHE_OP_ASYNC | 992 op->op.flags = FSCACHE_OP_ASYNC |
952 (1 << FSCACHE_OP_WAITING) | 993 (1 << FSCACHE_OP_WAITING) |
@@ -956,6 +997,8 @@ int __fscache_write_page(struct fscache_cookie *cookie,
956 if (ret < 0) 997 if (ret < 0)
957 goto nomem_free; 998 goto nomem_free;
958 999
1000 trace_fscache_page_op(cookie, page, &op->op, fscache_page_op_write_one);
1001
959 ret = -ENOBUFS; 1002 ret = -ENOBUFS;
960 spin_lock(&cookie->lock); 1003 spin_lock(&cookie->lock);
961 1004
@@ -967,9 +1010,15 @@ int __fscache_write_page(struct fscache_cookie *cookie,
967 if (test_bit(FSCACHE_IOERROR, &object->cache->flags)) 1010 if (test_bit(FSCACHE_IOERROR, &object->cache->flags))
968 goto nobufs; 1011 goto nobufs;
969 1012
1013 trace_fscache_page(cookie, page, fscache_page_write);
1014
970 /* 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
971 * object */ 1016 * object */
972 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
973 spin_lock(&cookie->stores_lock); 1022 spin_lock(&cookie->stores_lock);
974 1023
975 _debug("store limit %llx", (unsigned long long) object->store_limit); 1024 _debug("store limit %llx", (unsigned long long) object->store_limit);
@@ -982,8 +1031,10 @@ int __fscache_write_page(struct fscache_cookie *cookie,
982 goto nobufs_unlock_obj; 1031 goto nobufs_unlock_obj;
983 } 1032 }
984 1033
1034 trace_fscache_page(cookie, page, fscache_page_radix_insert);
985 radix_tree_tag_set(&cookie->stores, page->index, 1035 radix_tree_tag_set(&cookie->stores, page->index,
986 FSCACHE_COOKIE_PENDING_TAG); 1036 FSCACHE_COOKIE_PENDING_TAG);
1037 trace_fscache_page(cookie, page, fscache_page_radix_set_pend);
987 get_page(page); 1038 get_page(page);
988 1039
989 /* we only want one writer at a time, but we do need to queue new 1040 /* we only want one writer at a time, but we do need to queue new
@@ -1026,6 +1077,7 @@ already_pending:
1026submit_failed: 1077submit_failed:
1027 spin_lock(&cookie->stores_lock); 1078 spin_lock(&cookie->stores_lock);
1028 radix_tree_delete(&cookie->stores, page->index); 1079 radix_tree_delete(&cookie->stores, page->index);
1080 trace_fscache_page(cookie, page, fscache_page_radix_delete);
1029 spin_unlock(&cookie->stores_lock); 1081 spin_unlock(&cookie->stores_lock);
1030 wake_cookie = __fscache_unuse_cookie(cookie); 1082 wake_cookie = __fscache_unuse_cookie(cookie);
1031 put_page(page); 1083 put_page(page);
@@ -1072,6 +1124,8 @@ void __fscache_uncache_page(struct fscache_cookie *cookie, struct page *page)
1072 if (!PageFsCache(page)) 1124 if (!PageFsCache(page))
1073 goto done; 1125 goto done;
1074 1126
1127 trace_fscache_page(cookie, page, fscache_page_uncache);
1128
1075 /* get the object */ 1129 /* get the object */
1076 spin_lock(&cookie->lock); 1130 spin_lock(&cookie->lock);
1077 1131
@@ -1120,6 +1174,8 @@ void fscache_mark_page_cached(struct fscache_retrieval *op, struct page *page)
1120 atomic_inc(&fscache_n_marks); 1174 atomic_inc(&fscache_n_marks);
1121#endif 1175#endif
1122 1176
1177 trace_fscache_page(cookie, page, fscache_page_cached);
1178
1123 _debug("- mark %p{%lx}", page, page->index); 1179 _debug("- mark %p{%lx}", page, page->index);
1124 if (TestSetPageFsCache(page)) { 1180 if (TestSetPageFsCache(page)) {
1125 static bool once_only; 1181 static bool once_only;
diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c
index 7ac6e839b065..fcc8c2f2690e 100644
--- a/fs/fscache/stats.c
+++ b/fs/fscache/stats.c
@@ -21,7 +21,6 @@
21atomic_t fscache_n_op_pend; 21atomic_t fscache_n_op_pend;
22atomic_t fscache_n_op_run; 22atomic_t fscache_n_op_run;
23atomic_t fscache_n_op_enqueue; 23atomic_t fscache_n_op_enqueue;
24atomic_t fscache_n_op_requeue;
25atomic_t fscache_n_op_deferred_release; 24atomic_t fscache_n_op_deferred_release;
26atomic_t fscache_n_op_initialised; 25atomic_t fscache_n_op_initialised;
27atomic_t fscache_n_op_release; 26atomic_t fscache_n_op_release;
diff --git a/fs/nfs/fscache-index.c b/fs/nfs/fscache-index.c
index 0ee4b93d36ea..1c5d8d31fc0a 100644
--- a/fs/nfs/fscache-index.c
+++ b/fs/nfs/fscache-index.c
@@ -50,59 +50,6 @@ void nfs_fscache_unregister(void)
50} 50}
51 51
52/* 52/*
53 * Layout of the key for an NFS server cache object.
54 */
55struct nfs_server_key {
56 uint16_t nfsversion; /* NFS protocol version */
57 uint16_t family; /* address family */
58 uint16_t port; /* IP port */
59 union {
60 struct in_addr ipv4_addr; /* IPv4 address */
61 struct in6_addr ipv6_addr; /* IPv6 address */
62 } addr[0];
63};
64
65/*
66 * Generate a key to describe a server in the main NFS index
67 * - We return the length of the key, or 0 if we can't generate one
68 */
69static uint16_t nfs_server_get_key(const void *cookie_netfs_data,
70 void *buffer, uint16_t bufmax)
71{
72 const struct nfs_client *clp = cookie_netfs_data;
73 const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &clp->cl_addr;
74 const struct sockaddr_in *sin = (struct sockaddr_in *) &clp->cl_addr;
75 struct nfs_server_key *key = buffer;
76 uint16_t len = sizeof(struct nfs_server_key);
77
78 memset(key, 0, len);
79 key->nfsversion = clp->rpc_ops->version;
80 key->family = clp->cl_addr.ss_family;
81
82 switch (clp->cl_addr.ss_family) {
83 case AF_INET:
84 key->port = sin->sin_port;
85 key->addr[0].ipv4_addr = sin->sin_addr;
86 len += sizeof(key->addr[0].ipv4_addr);
87 break;
88
89 case AF_INET6:
90 key->port = sin6->sin6_port;
91 key->addr[0].ipv6_addr = sin6->sin6_addr;
92 len += sizeof(key->addr[0].ipv6_addr);
93 break;
94
95 default:
96 printk(KERN_WARNING "NFS: Unknown network family '%d'\n",
97 clp->cl_addr.ss_family);
98 len = 0;
99 break;
100 }
101
102 return len;
103}
104
105/*
106 * Define the server object for FS-Cache. This is used to describe a server 53 * Define the server object for FS-Cache. This is used to describe a server
107 * object to fscache_acquire_cookie(). It is keyed by the NFS protocol and 54 * object to fscache_acquire_cookie(). It is keyed by the NFS protocol and
108 * server address parameters. 55 * server address parameters.
@@ -110,33 +57,9 @@ static uint16_t nfs_server_get_key(const void *cookie_netfs_data,
110const struct fscache_cookie_def nfs_fscache_server_index_def = { 57const struct fscache_cookie_def nfs_fscache_server_index_def = {
111 .name = "NFS.server", 58 .name = "NFS.server",
112 .type = FSCACHE_COOKIE_TYPE_INDEX, 59 .type = FSCACHE_COOKIE_TYPE_INDEX,
113 .get_key = nfs_server_get_key,
114}; 60};
115 61
116/* 62/*
117 * Generate a key to describe a superblock key in the main NFS index
118 */
119static uint16_t nfs_super_get_key(const void *cookie_netfs_data,
120 void *buffer, uint16_t bufmax)
121{
122 const struct nfs_fscache_key *key;
123 const struct nfs_server *nfss = cookie_netfs_data;
124 uint16_t len;
125
126 key = nfss->fscache_key;
127 len = sizeof(key->key) + key->key.uniq_len;
128 if (len > bufmax) {
129 len = 0;
130 } else {
131 memcpy(buffer, &key->key, sizeof(key->key));
132 memcpy(buffer + sizeof(key->key),
133 key->key.uniquifier, key->key.uniq_len);
134 }
135
136 return len;
137}
138
139/*
140 * Define the superblock object for FS-Cache. This is used to describe a 63 * Define the superblock object for FS-Cache. This is used to describe a
141 * superblock object to fscache_acquire_cookie(). It is keyed by all the NFS 64 * superblock object to fscache_acquire_cookie(). It is keyed by all the NFS
142 * parameters that might cause a separate superblock. 65 * parameters that might cause a separate superblock.
@@ -144,84 +67,9 @@ static uint16_t nfs_super_get_key(const void *cookie_netfs_data,
144const struct fscache_cookie_def nfs_fscache_super_index_def = { 67const struct fscache_cookie_def nfs_fscache_super_index_def = {
145 .name = "NFS.super", 68 .name = "NFS.super",
146 .type = FSCACHE_COOKIE_TYPE_INDEX, 69 .type = FSCACHE_COOKIE_TYPE_INDEX,
147 .get_key = nfs_super_get_key,
148}; 70};
149 71
150/* 72/*
151 * Definition of the auxiliary data attached to NFS inode storage objects
152 * within the cache.
153 *
154 * The contents of this struct are recorded in the on-disk local cache in the
155 * auxiliary data attached to the data storage object backing an inode. This
156 * permits coherency to be managed when a new inode binds to an already extant
157 * cache object.
158 */
159struct nfs_fscache_inode_auxdata {
160 struct timespec mtime;
161 struct timespec ctime;
162 loff_t size;
163 u64 change_attr;
164};
165
166/*
167 * Generate a key to describe an NFS inode in an NFS server's index
168 */
169static uint16_t nfs_fscache_inode_get_key(const void *cookie_netfs_data,
170 void *buffer, uint16_t bufmax)
171{
172 const struct nfs_inode *nfsi = cookie_netfs_data;
173 uint16_t nsize;
174
175 /* use the inode's NFS filehandle as the key */
176 nsize = nfsi->fh.size;
177 memcpy(buffer, nfsi->fh.data, nsize);
178 return nsize;
179}
180
181/*
182 * Get certain file attributes from the netfs data
183 * - This function can be absent for an index
184 * - Not permitted to return an error
185 * - The netfs data from the cookie being used as the source is presented
186 */
187static void nfs_fscache_inode_get_attr(const void *cookie_netfs_data,
188 uint64_t *size)
189{
190 const struct nfs_inode *nfsi = cookie_netfs_data;
191
192 *size = nfsi->vfs_inode.i_size;
193}
194
195/*
196 * Get the auxiliary data from netfs data
197 * - This function can be absent if the index carries no state data
198 * - Should store the auxiliary data in the buffer
199 * - Should return the amount of amount stored
200 * - Not permitted to return an error
201 * - The netfs data from the cookie being used as the source is presented
202 */
203static uint16_t nfs_fscache_inode_get_aux(const void *cookie_netfs_data,
204 void *buffer, uint16_t bufmax)
205{
206 struct nfs_fscache_inode_auxdata auxdata;
207 const struct nfs_inode *nfsi = cookie_netfs_data;
208
209 memset(&auxdata, 0, sizeof(auxdata));
210 auxdata.size = nfsi->vfs_inode.i_size;
211 auxdata.mtime = nfsi->vfs_inode.i_mtime;
212 auxdata.ctime = nfsi->vfs_inode.i_ctime;
213
214 if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4)
215 auxdata.change_attr = inode_peek_iversion_raw(&nfsi->vfs_inode);
216
217 if (bufmax > sizeof(auxdata))
218 bufmax = sizeof(auxdata);
219
220 memcpy(buffer, &auxdata, bufmax);
221 return bufmax;
222}
223
224/*
225 * Consult the netfs about the state of an object 73 * Consult the netfs about the state of an object
226 * - 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
227 * - 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
@@ -230,7 +78,8 @@ static uint16_t nfs_fscache_inode_get_aux(const void *cookie_netfs_data,
230static 78static
231enum fscache_checkaux nfs_fscache_inode_check_aux(void *cookie_netfs_data, 79enum fscache_checkaux nfs_fscache_inode_check_aux(void *cookie_netfs_data,
232 const void *data, 80 const void *data,
233 uint16_t datalen) 81 uint16_t datalen,
82 loff_t object_size)
234{ 83{
235 struct nfs_fscache_inode_auxdata auxdata; 84 struct nfs_fscache_inode_auxdata auxdata;
236 struct nfs_inode *nfsi = cookie_netfs_data; 85 struct nfs_inode *nfsi = cookie_netfs_data;
@@ -239,7 +88,6 @@ enum fscache_checkaux nfs_fscache_inode_check_aux(void *cookie_netfs_data,
239 return FSCACHE_CHECKAUX_OBSOLETE; 88 return FSCACHE_CHECKAUX_OBSOLETE;
240 89
241 memset(&auxdata, 0, sizeof(auxdata)); 90 memset(&auxdata, 0, sizeof(auxdata));
242 auxdata.size = nfsi->vfs_inode.i_size;
243 auxdata.mtime = nfsi->vfs_inode.i_mtime; 91 auxdata.mtime = nfsi->vfs_inode.i_mtime;
244 auxdata.ctime = nfsi->vfs_inode.i_ctime; 92 auxdata.ctime = nfsi->vfs_inode.i_ctime;
245 93
@@ -288,9 +136,6 @@ static void nfs_fh_put_context(void *cookie_netfs_data, void *context)
288const struct fscache_cookie_def nfs_fscache_inode_object_def = { 136const struct fscache_cookie_def nfs_fscache_inode_object_def = {
289 .name = "NFS.fh", 137 .name = "NFS.fh",
290 .type = FSCACHE_COOKIE_TYPE_DATAFILE, 138 .type = FSCACHE_COOKIE_TYPE_DATAFILE,
291 .get_key = nfs_fscache_inode_get_key,
292 .get_attr = nfs_fscache_inode_get_attr,
293 .get_aux = nfs_fscache_inode_get_aux,
294 .check_aux = nfs_fscache_inode_check_aux, 139 .check_aux = nfs_fscache_inode_check_aux,
295 .get_context = nfs_fh_get_context, 140 .get_context = nfs_fh_get_context,
296 .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 d63bea8bbfbb..b55fc7920c3b 100644
--- a/fs/nfs/fscache.c
+++ b/fs/nfs/fscache.c
@@ -18,6 +18,7 @@
18#include <linux/in6.h> 18#include <linux/in6.h>
19#include <linux/seq_file.h> 19#include <linux/seq_file.h>
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/iversion.h>
21 22
22#include "internal.h" 23#include "internal.h"
23#include "iostat.h" 24#include "iostat.h"
@@ -29,6 +30,21 @@ static struct rb_root nfs_fscache_keys = RB_ROOT;
29static DEFINE_SPINLOCK(nfs_fscache_keys_lock); 30static DEFINE_SPINLOCK(nfs_fscache_keys_lock);
30 31
31/* 32/*
33 * Layout of the key for an NFS server cache object.
34 */
35struct nfs_server_key {
36 struct {
37 uint16_t nfsversion; /* NFS protocol version */
38 uint16_t family; /* address family */
39 __be16 port; /* IP port */
40 } hdr;
41 union {
42 struct in_addr ipv4_addr; /* IPv4 address */
43 struct in6_addr ipv6_addr; /* IPv6 address */
44 };
45} __packed;
46
47/*
32 * Get the per-client index cookie for an NFS client if the appropriate mount 48 * Get the per-client index cookie for an NFS client if the appropriate mount
33 * flag was set 49 * flag was set
34 * - We always try and get an index cookie for the client, but get filehandle 50 * - We always try and get an index cookie for the client, but get filehandle
@@ -36,10 +52,41 @@ static DEFINE_SPINLOCK(nfs_fscache_keys_lock);
36 */ 52 */
37void nfs_fscache_get_client_cookie(struct nfs_client *clp) 53void nfs_fscache_get_client_cookie(struct nfs_client *clp)
38{ 54{
55 const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &clp->cl_addr;
56 const struct sockaddr_in *sin = (struct sockaddr_in *) &clp->cl_addr;
57 struct nfs_server_key key;
58 uint16_t len = sizeof(key.hdr);
59
60 memset(&key, 0, sizeof(key));
61 key.hdr.nfsversion = clp->rpc_ops->version;
62 key.hdr.family = clp->cl_addr.ss_family;
63
64 switch (clp->cl_addr.ss_family) {
65 case AF_INET:
66 key.hdr.port = sin->sin_port;
67 key.ipv4_addr = sin->sin_addr;
68 len += sizeof(key.ipv4_addr);
69 break;
70
71 case AF_INET6:
72 key.hdr.port = sin6->sin6_port;
73 key.ipv6_addr = sin6->sin6_addr;
74 len += sizeof(key.ipv6_addr);
75 break;
76
77 default:
78 printk(KERN_WARNING "NFS: Unknown network family '%d'\n",
79 clp->cl_addr.ss_family);
80 clp->fscache = NULL;
81 return;
82 }
83
39 /* create a cache index for looking up filehandles */ 84 /* create a cache index for looking up filehandles */
40 clp->fscache = fscache_acquire_cookie(nfs_fscache_netfs.primary_index, 85 clp->fscache = fscache_acquire_cookie(nfs_fscache_netfs.primary_index,
41 &nfs_fscache_server_index_def, 86 &nfs_fscache_server_index_def,
42 clp, true); 87 &key, len,
88 NULL, 0,
89 clp, 0, true);
43 dfprintk(FSCACHE, "NFS: get client cookie (0x%p/0x%p)\n", 90 dfprintk(FSCACHE, "NFS: get client cookie (0x%p/0x%p)\n",
44 clp, clp->fscache); 91 clp, clp->fscache);
45} 92}
@@ -52,7 +99,7 @@ void nfs_fscache_release_client_cookie(struct nfs_client *clp)
52 dfprintk(FSCACHE, "NFS: releasing client cookie (0x%p/0x%p)\n", 99 dfprintk(FSCACHE, "NFS: releasing client cookie (0x%p/0x%p)\n",
53 clp, clp->fscache); 100 clp, clp->fscache);
54 101
55 fscache_relinquish_cookie(clp->fscache, 0); 102 fscache_relinquish_cookie(clp->fscache, NULL, false);
56 clp->fscache = NULL; 103 clp->fscache = NULL;
57} 104}
58 105
@@ -139,7 +186,9 @@ void nfs_fscache_get_super_cookie(struct super_block *sb, const char *uniq, int
139 /* create a cache index for looking up filehandles */ 186 /* create a cache index for looking up filehandles */
140 nfss->fscache = fscache_acquire_cookie(nfss->nfs_client->fscache, 187 nfss->fscache = fscache_acquire_cookie(nfss->nfs_client->fscache,
141 &nfs_fscache_super_index_def, 188 &nfs_fscache_super_index_def,
142 nfss, true); 189 key, sizeof(*key) + ulen,
190 NULL, 0,
191 nfss, 0, true);
143 dfprintk(FSCACHE, "NFS: get superblock cookie (0x%p/0x%p)\n", 192 dfprintk(FSCACHE, "NFS: get superblock cookie (0x%p/0x%p)\n",
144 nfss, nfss->fscache); 193 nfss, nfss->fscache);
145 return; 194 return;
@@ -163,7 +212,7 @@ void nfs_fscache_release_super_cookie(struct super_block *sb)
163 dfprintk(FSCACHE, "NFS: releasing superblock cookie (0x%p/0x%p)\n", 212 dfprintk(FSCACHE, "NFS: releasing superblock cookie (0x%p/0x%p)\n",
164 nfss, nfss->fscache); 213 nfss, nfss->fscache);
165 214
166 fscache_relinquish_cookie(nfss->fscache, 0); 215 fscache_relinquish_cookie(nfss->fscache, NULL, false);
167 nfss->fscache = NULL; 216 nfss->fscache = NULL;
168 217
169 if (nfss->fscache_key) { 218 if (nfss->fscache_key) {
@@ -180,14 +229,25 @@ void nfs_fscache_release_super_cookie(struct super_block *sb)
180 */ 229 */
181void nfs_fscache_init_inode(struct inode *inode) 230void nfs_fscache_init_inode(struct inode *inode)
182{ 231{
232 struct nfs_fscache_inode_auxdata auxdata;
183 struct nfs_inode *nfsi = NFS_I(inode); 233 struct nfs_inode *nfsi = NFS_I(inode);
184 234
185 nfsi->fscache = NULL; 235 nfsi->fscache = NULL;
186 if (!S_ISREG(inode->i_mode)) 236 if (!S_ISREG(inode->i_mode))
187 return; 237 return;
238
239 memset(&auxdata, 0, sizeof(auxdata));
240 auxdata.mtime = nfsi->vfs_inode.i_mtime;
241 auxdata.ctime = nfsi->vfs_inode.i_ctime;
242
243 if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4)
244 auxdata.change_attr = inode_peek_iversion_raw(&nfsi->vfs_inode);
245
188 nfsi->fscache = fscache_acquire_cookie(NFS_SB(inode->i_sb)->fscache, 246 nfsi->fscache = fscache_acquire_cookie(NFS_SB(inode->i_sb)->fscache,
189 &nfs_fscache_inode_object_def, 247 &nfs_fscache_inode_object_def,
190 nfsi, false); 248 nfsi->fh.data, nfsi->fh.size,
249 &auxdata, sizeof(auxdata),
250 nfsi, nfsi->vfs_inode.i_size, false);
191} 251}
192 252
193/* 253/*
@@ -195,12 +255,16 @@ void nfs_fscache_init_inode(struct inode *inode)
195 */ 255 */
196void nfs_fscache_clear_inode(struct inode *inode) 256void nfs_fscache_clear_inode(struct inode *inode)
197{ 257{
258 struct nfs_fscache_inode_auxdata auxdata;
198 struct nfs_inode *nfsi = NFS_I(inode); 259 struct nfs_inode *nfsi = NFS_I(inode);
199 struct fscache_cookie *cookie = nfs_i_fscache(inode); 260 struct fscache_cookie *cookie = nfs_i_fscache(inode);
200 261
201 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);
202 263
203 fscache_relinquish_cookie(cookie, false); 264 memset(&auxdata, 0, sizeof(auxdata));
265 auxdata.mtime = nfsi->vfs_inode.i_mtime;
266 auxdata.ctime = nfsi->vfs_inode.i_ctime;
267 fscache_relinquish_cookie(cookie, &auxdata, false);
204 nfsi->fscache = NULL; 268 nfsi->fscache = NULL;
205} 269}
206 270
@@ -232,20 +296,26 @@ static bool nfs_fscache_can_enable(void *data)
232 */ 296 */
233void nfs_fscache_open_file(struct inode *inode, struct file *filp) 297void nfs_fscache_open_file(struct inode *inode, struct file *filp)
234{ 298{
299 struct nfs_fscache_inode_auxdata auxdata;
235 struct nfs_inode *nfsi = NFS_I(inode); 300 struct nfs_inode *nfsi = NFS_I(inode);
236 struct fscache_cookie *cookie = nfs_i_fscache(inode); 301 struct fscache_cookie *cookie = nfs_i_fscache(inode);
237 302
238 if (!fscache_cookie_valid(cookie)) 303 if (!fscache_cookie_valid(cookie))
239 return; 304 return;
240 305
306 memset(&auxdata, 0, sizeof(auxdata));
307 auxdata.mtime = nfsi->vfs_inode.i_mtime;
308 auxdata.ctime = nfsi->vfs_inode.i_ctime;
309
241 if (inode_is_open_for_write(inode)) { 310 if (inode_is_open_for_write(inode)) {
242 dfprintk(FSCACHE, "NFS: nfsi 0x%p disabling cache\n", nfsi); 311 dfprintk(FSCACHE, "NFS: nfsi 0x%p disabling cache\n", nfsi);
243 clear_bit(NFS_INO_FSCACHE, &nfsi->flags); 312 clear_bit(NFS_INO_FSCACHE, &nfsi->flags);
244 fscache_disable_cookie(cookie, true); 313 fscache_disable_cookie(cookie, &auxdata, true);
245 fscache_uncache_all_inode_pages(cookie, inode); 314 fscache_uncache_all_inode_pages(cookie, inode);
246 } else { 315 } else {
247 dfprintk(FSCACHE, "NFS: nfsi 0x%p enabling cache\n", nfsi); 316 dfprintk(FSCACHE, "NFS: nfsi 0x%p enabling cache\n", nfsi);
248 fscache_enable_cookie(cookie, nfs_fscache_can_enable, inode); 317 fscache_enable_cookie(cookie, &auxdata, nfsi->vfs_inode.i_size,
318 nfs_fscache_can_enable, inode);
249 if (fscache_cookie_enabled(cookie)) 319 if (fscache_cookie_enabled(cookie))
250 set_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags); 320 set_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags);
251 } 321 }
@@ -422,7 +492,8 @@ void __nfs_readpage_to_fscache(struct inode *inode, struct page *page, int sync)
422 "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",
423 nfs_i_fscache(inode), page, page->index, page->flags, sync); 493 nfs_i_fscache(inode), page, page->index, page->flags, sync);
424 494
425 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);
426 dfprintk(FSCACHE, 497 dfprintk(FSCACHE,
427 "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",
428 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 d7fe3e799f2f..161ba2edb9d0 100644
--- a/fs/nfs/fscache.h
+++ b/fs/nfs/fscache.h
@@ -57,6 +57,21 @@ struct nfs_fscache_key {
57}; 57};
58 58
59/* 59/*
60 * Definition of the auxiliary data attached to NFS inode storage objects
61 * within the cache.
62 *
63 * The contents of this struct are recorded in the on-disk local cache in the
64 * auxiliary data attached to the data storage object backing an inode. This
65 * permits coherency to be managed when a new inode binds to an already extant
66 * cache object.
67 */
68struct nfs_fscache_inode_auxdata {
69 struct timespec mtime;
70 struct timespec ctime;
71 u64 change_attr;
72};
73
74/*
60 * fscache-index.c 75 * fscache-index.c
61 */ 76 */
62extern struct fscache_netfs nfs_fscache_netfs; 77extern struct fscache_netfs nfs_fscache_netfs;
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h
index 3b03e29e2f1a..34cf0fdd7dc7 100644
--- a/include/linux/fscache-cache.h
+++ b/include/linux/fscache-cache.h
@@ -29,6 +29,18 @@ struct fscache_cache_ops;
29struct fscache_object; 29struct fscache_object;
30struct fscache_operation; 30struct fscache_operation;
31 31
32enum fscache_obj_ref_trace {
33 fscache_obj_get_add_to_deps,
34 fscache_obj_get_queue,
35 fscache_obj_put_alloc_fail,
36 fscache_obj_put_attach_fail,
37 fscache_obj_put_drop_obj,
38 fscache_obj_put_enq_dep,
39 fscache_obj_put_queue,
40 fscache_obj_put_work,
41 fscache_obj_ref__nr_traces
42};
43
32/* 44/*
33 * cache tag definition 45 * cache tag definition
34 */ 46 */
@@ -123,7 +135,8 @@ extern void fscache_op_work_func(struct work_struct *work);
123extern void fscache_enqueue_operation(struct fscache_operation *); 135extern void fscache_enqueue_operation(struct fscache_operation *);
124extern void fscache_op_complete(struct fscache_operation *, bool); 136extern void fscache_op_complete(struct fscache_operation *, bool);
125extern void fscache_put_operation(struct fscache_operation *); 137extern void fscache_put_operation(struct fscache_operation *);
126extern void fscache_operation_init(struct fscache_operation *, 138extern void fscache_operation_init(struct fscache_cookie *,
139 struct fscache_operation *,
127 fscache_operation_processor_t, 140 fscache_operation_processor_t,
128 fscache_operation_cancel_t, 141 fscache_operation_cancel_t,
129 fscache_operation_release_t); 142 fscache_operation_release_t);
@@ -185,7 +198,7 @@ static inline void fscache_retrieval_complete(struct fscache_retrieval *op,
185{ 198{
186 atomic_sub(n_pages, &op->n_pages); 199 atomic_sub(n_pages, &op->n_pages);
187 if (atomic_read(&op->n_pages) <= 0) 200 if (atomic_read(&op->n_pages) <= 0)
188 fscache_op_complete(&op->op, true); 201 fscache_op_complete(&op->op, false);
189} 202}
190 203
191/** 204/**
@@ -231,7 +244,8 @@ struct fscache_cache_ops {
231 void (*lookup_complete)(struct fscache_object *object); 244 void (*lookup_complete)(struct fscache_object *object);
232 245
233 /* increment the usage count on this object (may fail if unmounting) */ 246 /* increment the usage count on this object (may fail if unmounting) */
234 struct fscache_object *(*grab_object)(struct fscache_object *object); 247 struct fscache_object *(*grab_object)(struct fscache_object *object,
248 enum fscache_obj_ref_trace why);
235 249
236 /* pin an object in the cache */ 250 /* pin an object in the cache */
237 int (*pin_object)(struct fscache_object *object); 251 int (*pin_object)(struct fscache_object *object);
@@ -254,7 +268,8 @@ struct fscache_cache_ops {
254 void (*drop_object)(struct fscache_object *object); 268 void (*drop_object)(struct fscache_object *object);
255 269
256 /* dispose of a reference to an object */ 270 /* dispose of a reference to an object */
257 void (*put_object)(struct fscache_object *object); 271 void (*put_object)(struct fscache_object *object,
272 enum fscache_obj_ref_trace why);
258 273
259 /* sync a cache */ 274 /* sync a cache */
260 void (*sync_cache)(struct fscache_cache *cache); 275 void (*sync_cache)(struct fscache_cache *cache);
@@ -538,7 +553,8 @@ extern bool fscache_object_sleep_till_congested(signed long *timeoutp);
538 553
539extern enum fscache_checkaux fscache_check_aux(struct fscache_object *object, 554extern enum fscache_checkaux fscache_check_aux(struct fscache_object *object,
540 const void *data, 555 const void *data,
541 uint16_t datalen); 556 uint16_t datalen,
557 loff_t object_size);
542 558
543extern void fscache_object_retrying_stale(struct fscache_object *object); 559extern void fscache_object_retrying_stale(struct fscache_object *object);
544 560
diff --git a/include/linux/fscache.h b/include/linux/fscache.h
index fe0c349684fa..84b90a79d75a 100644
--- a/include/linux/fscache.h
+++ b/include/linux/fscache.h
@@ -22,6 +22,7 @@
22#include <linux/list.h> 22#include <linux/list.h>
23#include <linux/pagemap.h> 23#include <linux/pagemap.h>
24#include <linux/pagevec.h> 24#include <linux/pagevec.h>
25#include <linux/list_bl.h>
25 26
26#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) 27#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
27#define fscache_available() (1) 28#define fscache_available() (1)
@@ -83,45 +84,15 @@ struct fscache_cookie_def {
83 const void *parent_netfs_data, 84 const void *parent_netfs_data,
84 const void *cookie_netfs_data); 85 const void *cookie_netfs_data);
85 86
86 /* get an index key
87 * - should store the key data in the buffer
88 * - should return the amount of data stored
89 * - not permitted to return an error
90 * - the netfs data from the cookie being used as the source is
91 * presented
92 */
93 uint16_t (*get_key)(const void *cookie_netfs_data,
94 void *buffer,
95 uint16_t bufmax);
96
97 /* get certain file attributes from the netfs data
98 * - this function can be absent for an index
99 * - not permitted to return an error
100 * - the netfs data from the cookie being used as the source is
101 * presented
102 */
103 void (*get_attr)(const void *cookie_netfs_data, uint64_t *size);
104
105 /* get the auxiliary data from netfs data
106 * - this function can be absent if the index carries no state data
107 * - should store the auxiliary data in the buffer
108 * - should return the amount of amount stored
109 * - not permitted to return an error
110 * - the netfs data from the cookie being used as the source is
111 * presented
112 */
113 uint16_t (*get_aux)(const void *cookie_netfs_data,
114 void *buffer,
115 uint16_t bufmax);
116
117 /* consult the netfs about the state of an object 87 /* consult the netfs about the state of an object
118 * - this function can be absent if the index carries no state data 88 * - this function can be absent if the index carries no state data
119 * - the netfs data from the cookie being used as the target is 89 * - the netfs data from the cookie being used as the target is
120 * presented, as is the auxiliary data 90 * presented, as is the auxiliary data and the object size
121 */ 91 */
122 enum fscache_checkaux (*check_aux)(void *cookie_netfs_data, 92 enum fscache_checkaux (*check_aux)(void *cookie_netfs_data,
123 const void *data, 93 const void *data,
124 uint16_t datalen); 94 uint16_t datalen,
95 loff_t object_size);
125 96
126 /* get an extra reference on a read context 97 /* get an extra reference on a read context
127 * - this function can be absent if the completion function doesn't 98 * - this function can be absent if the completion function doesn't
@@ -154,7 +125,6 @@ struct fscache_netfs {
154 uint32_t version; /* indexing version */ 125 uint32_t version; /* indexing version */
155 const char *name; /* filesystem name */ 126 const char *name; /* filesystem name */
156 struct fscache_cookie *primary_index; 127 struct fscache_cookie *primary_index;
157 struct list_head link; /* internal link */
158}; 128};
159 129
160/* 130/*
@@ -173,6 +143,7 @@ struct fscache_cookie {
173 struct hlist_head backing_objects; /* object(s) backing this file/index */ 143 struct hlist_head backing_objects; /* object(s) backing this file/index */
174 const struct fscache_cookie_def *def; /* definition */ 144 const struct fscache_cookie_def *def; /* definition */
175 struct fscache_cookie *parent; /* parent of this entry */ 145 struct fscache_cookie *parent; /* parent of this entry */
146 struct hlist_bl_node hash_link; /* Link in hash table */
176 void *netfs_data; /* back pointer to netfs */ 147 void *netfs_data; /* back pointer to netfs */
177 struct radix_tree_root stores; /* pages to be stored on this cookie */ 148 struct radix_tree_root stores; /* pages to be stored on this cookie */
178#define FSCACHE_COOKIE_PENDING_TAG 0 /* pages tag: pending write to cache */ 149#define FSCACHE_COOKIE_PENDING_TAG 0 /* pages tag: pending write to cache */
@@ -186,6 +157,22 @@ struct fscache_cookie {
186#define FSCACHE_COOKIE_RELINQUISHED 4 /* T if cookie has been relinquished */ 157#define FSCACHE_COOKIE_RELINQUISHED 4 /* T if cookie has been relinquished */
187#define FSCACHE_COOKIE_ENABLED 5 /* T if cookie is enabled */ 158#define FSCACHE_COOKIE_ENABLED 5 /* T if cookie is enabled */
188#define FSCACHE_COOKIE_ENABLEMENT_LOCK 6 /* T if cookie is being en/disabled */ 159#define FSCACHE_COOKIE_ENABLEMENT_LOCK 6 /* T if cookie is being en/disabled */
160#define FSCACHE_COOKIE_AUX_UPDATED 8 /* T if the auxiliary data was updated */
161#define FSCACHE_COOKIE_ACQUIRED 9 /* T if cookie is in use */
162#define FSCACHE_COOKIE_RELINQUISHING 10 /* T if cookie is being relinquished */
163
164 u8 type; /* Type of object */
165 u8 key_len; /* Length of index key */
166 u8 aux_len; /* Length of auxiliary data */
167 u32 key_hash; /* Hash of parent, type, key, len */
168 union {
169 void *key; /* Index key */
170 u8 inline_key[16]; /* - If the key is short enough */
171 };
172 union {
173 void *aux; /* Auxiliary data */
174 u8 inline_aux[8]; /* - If the aux data is short enough */
175 };
189}; 176};
190 177
191static inline bool fscache_cookie_enabled(struct fscache_cookie *cookie) 178static inline bool fscache_cookie_enabled(struct fscache_cookie *cookie)
@@ -208,10 +195,12 @@ extern void __fscache_release_cache_tag(struct fscache_cache_tag *);
208extern struct fscache_cookie *__fscache_acquire_cookie( 195extern struct fscache_cookie *__fscache_acquire_cookie(
209 struct fscache_cookie *, 196 struct fscache_cookie *,
210 const struct fscache_cookie_def *, 197 const struct fscache_cookie_def *,
211 void *, bool); 198 const void *, size_t,
212extern void __fscache_relinquish_cookie(struct fscache_cookie *, bool); 199 const void *, size_t,
213extern int __fscache_check_consistency(struct fscache_cookie *); 200 void *, loff_t, bool);
214extern void __fscache_update_cookie(struct fscache_cookie *); 201extern void __fscache_relinquish_cookie(struct fscache_cookie *, const void *, bool);
202extern int __fscache_check_consistency(struct fscache_cookie *, const void *);
203extern void __fscache_update_cookie(struct fscache_cookie *, const void *);
215extern int __fscache_attr_changed(struct fscache_cookie *); 204extern int __fscache_attr_changed(struct fscache_cookie *);
216extern void __fscache_invalidate(struct fscache_cookie *); 205extern void __fscache_invalidate(struct fscache_cookie *);
217extern void __fscache_wait_on_invalidate(struct fscache_cookie *); 206extern void __fscache_wait_on_invalidate(struct fscache_cookie *);
@@ -228,7 +217,7 @@ extern int __fscache_read_or_alloc_pages(struct fscache_cookie *,
228 void *, 217 void *,
229 gfp_t); 218 gfp_t);
230extern int __fscache_alloc_page(struct fscache_cookie *, struct page *, gfp_t); 219extern int __fscache_alloc_page(struct fscache_cookie *, struct page *, gfp_t);
231extern int __fscache_write_page(struct fscache_cookie *, struct page *, gfp_t); 220extern int __fscache_write_page(struct fscache_cookie *, struct page *, loff_t, gfp_t);
232extern void __fscache_uncache_page(struct fscache_cookie *, struct page *); 221extern void __fscache_uncache_page(struct fscache_cookie *, struct page *);
233extern bool __fscache_check_page_write(struct fscache_cookie *, struct page *); 222extern bool __fscache_check_page_write(struct fscache_cookie *, struct page *);
234extern void __fscache_wait_on_page_write(struct fscache_cookie *, struct page *); 223extern void __fscache_wait_on_page_write(struct fscache_cookie *, struct page *);
@@ -238,8 +227,8 @@ extern void __fscache_uncache_all_inode_pages(struct fscache_cookie *,
238 struct inode *); 227 struct inode *);
239extern void __fscache_readpages_cancel(struct fscache_cookie *cookie, 228extern void __fscache_readpages_cancel(struct fscache_cookie *cookie,
240 struct list_head *pages); 229 struct list_head *pages);
241extern void __fscache_disable_cookie(struct fscache_cookie *, bool); 230extern void __fscache_disable_cookie(struct fscache_cookie *, const void *, bool);
242extern void __fscache_enable_cookie(struct fscache_cookie *, 231extern void __fscache_enable_cookie(struct fscache_cookie *, const void *, loff_t,
243 bool (*)(void *), void *); 232 bool (*)(void *), void *);
244 233
245/** 234/**
@@ -317,8 +306,13 @@ void fscache_release_cache_tag(struct fscache_cache_tag *tag)
317 * fscache_acquire_cookie - Acquire a cookie to represent a cache object 306 * fscache_acquire_cookie - Acquire a cookie to represent a cache object
318 * @parent: The cookie that's to be the parent of this one 307 * @parent: The cookie that's to be the parent of this one
319 * @def: A description of the cache object, including callback operations 308 * @def: A description of the cache object, including callback operations
309 * @index_key: The index key for this cookie
310 * @index_key_len: Size of the index key
311 * @aux_data: The auxiliary data for the cookie (may be NULL)
312 * @aux_data_len: Size of the auxiliary data buffer
320 * @netfs_data: An arbitrary piece of data to be kept in the cookie to 313 * @netfs_data: An arbitrary piece of data to be kept in the cookie to
321 * represent the cache object to the netfs 314 * represent the cache object to the netfs
315 * @object_size: The initial size of object
322 * @enable: Whether or not to enable a data cookie immediately 316 * @enable: Whether or not to enable a data cookie immediately
323 * 317 *
324 * This function is used to inform FS-Cache about part of an index hierarchy 318 * This function is used to inform FS-Cache about part of an index hierarchy
@@ -332,12 +326,19 @@ static inline
332struct fscache_cookie *fscache_acquire_cookie( 326struct fscache_cookie *fscache_acquire_cookie(
333 struct fscache_cookie *parent, 327 struct fscache_cookie *parent,
334 const struct fscache_cookie_def *def, 328 const struct fscache_cookie_def *def,
329 const void *index_key,
330 size_t index_key_len,
331 const void *aux_data,
332 size_t aux_data_len,
335 void *netfs_data, 333 void *netfs_data,
334 loff_t object_size,
336 bool enable) 335 bool enable)
337{ 336{
338 if (fscache_cookie_valid(parent) && fscache_cookie_enabled(parent)) 337 if (fscache_cookie_valid(parent) && fscache_cookie_enabled(parent))
339 return __fscache_acquire_cookie(parent, def, netfs_data, 338 return __fscache_acquire_cookie(parent, def,
340 enable); 339 index_key, index_key_len,
340 aux_data, aux_data_len,
341 netfs_data, object_size, enable);
341 else 342 else
342 return NULL; 343 return NULL;
343} 344}
@@ -346,36 +347,44 @@ struct fscache_cookie *fscache_acquire_cookie(
346 * fscache_relinquish_cookie - Return the cookie to the cache, maybe discarding 347 * fscache_relinquish_cookie - Return the cookie to the cache, maybe discarding
347 * it 348 * it
348 * @cookie: The cookie being returned 349 * @cookie: The cookie being returned
350 * @aux_data: The updated auxiliary data for the cookie (may be NULL)
349 * @retire: True if the cache object the cookie represents is to be discarded 351 * @retire: True if the cache object the cookie represents is to be discarded
350 * 352 *
351 * This function returns a cookie to the cache, forcibly discarding the 353 * This function returns a cookie to the cache, forcibly discarding the
352 * associated cache object if retire is set to true. 354 * associated cache object if retire is set to true. The opportunity is
355 * provided to update the auxiliary data in the cache before the object is
356 * disconnected.
353 * 357 *
354 * See Documentation/filesystems/caching/netfs-api.txt for a complete 358 * See Documentation/filesystems/caching/netfs-api.txt for a complete
355 * description. 359 * description.
356 */ 360 */
357static inline 361static inline
358void fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire) 362void fscache_relinquish_cookie(struct fscache_cookie *cookie,
363 const void *aux_data,
364 bool retire)
359{ 365{
360 if (fscache_cookie_valid(cookie)) 366 if (fscache_cookie_valid(cookie))
361 __fscache_relinquish_cookie(cookie, retire); 367 __fscache_relinquish_cookie(cookie, aux_data, retire);
362} 368}
363 369
364/** 370/**
365 * fscache_check_consistency - Request that if the cache is updated 371 * fscache_check_consistency - Request validation of a cache's auxiliary data
366 * @cookie: The cookie representing the cache object 372 * @cookie: The cookie representing the cache object
373 * @aux_data: The updated auxiliary data for the cookie (may be NULL)
367 * 374 *
368 * Request an consistency check from fscache, which passes the request 375 * Request an consistency check from fscache, which passes the request to the
369 * to the backing cache. 376 * backing cache. The auxiliary data on the cookie will be updated first if
377 * @aux_data is set.
370 * 378 *
371 * Returns 0 if consistent and -ESTALE if inconsistent. May also 379 * Returns 0 if consistent and -ESTALE if inconsistent. May also
372 * return -ENOMEM and -ERESTARTSYS. 380 * return -ENOMEM and -ERESTARTSYS.
373 */ 381 */
374static inline 382static inline
375int fscache_check_consistency(struct fscache_cookie *cookie) 383int fscache_check_consistency(struct fscache_cookie *cookie,
384 const void *aux_data)
376{ 385{
377 if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) 386 if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
378 return __fscache_check_consistency(cookie); 387 return __fscache_check_consistency(cookie, aux_data);
379 else 388 else
380 return 0; 389 return 0;
381} 390}
@@ -383,18 +392,20 @@ int fscache_check_consistency(struct fscache_cookie *cookie)
383/** 392/**
384 * fscache_update_cookie - Request that a cache object be updated 393 * fscache_update_cookie - Request that a cache object be updated
385 * @cookie: The cookie representing the cache object 394 * @cookie: The cookie representing the cache object
395 * @aux_data: The updated auxiliary data for the cookie (may be NULL)
386 * 396 *
387 * Request an update of the index data for the cache object associated with the 397 * Request an update of the index data for the cache object associated with the
388 * cookie. 398 * cookie. The auxiliary data on the cookie will be updated first if @aux_data
399 * is set.
389 * 400 *
390 * See Documentation/filesystems/caching/netfs-api.txt for a complete 401 * See Documentation/filesystems/caching/netfs-api.txt for a complete
391 * description. 402 * description.
392 */ 403 */
393static inline 404static inline
394void fscache_update_cookie(struct fscache_cookie *cookie) 405void fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data)
395{ 406{
396 if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) 407 if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
397 __fscache_update_cookie(cookie); 408 __fscache_update_cookie(cookie, aux_data);
398} 409}
399 410
400/** 411/**
@@ -648,6 +659,7 @@ void fscache_readpages_cancel(struct fscache_cookie *cookie,
648 * fscache_write_page - Request storage of a page in the cache 659 * fscache_write_page - Request storage of a page in the cache
649 * @cookie: The cookie representing the cache object 660 * @cookie: The cookie representing the cache object
650 * @page: The netfs page to store 661 * @page: The netfs page to store
662 * @object_size: Updated size of object
651 * @gfp: The conditions under which memory allocation should be made 663 * @gfp: The conditions under which memory allocation should be made
652 * 664 *
653 * Request the contents of the netfs page be written into the cache. This 665 * Request the contents of the netfs page be written into the cache. This
@@ -665,10 +677,11 @@ void fscache_readpages_cancel(struct fscache_cookie *cookie,
665static inline 677static inline
666int fscache_write_page(struct fscache_cookie *cookie, 678int fscache_write_page(struct fscache_cookie *cookie,
667 struct page *page, 679 struct page *page,
680 loff_t object_size,
668 gfp_t gfp) 681 gfp_t gfp)
669{ 682{
670 if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) 683 if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
671 return __fscache_write_page(cookie, page, gfp); 684 return __fscache_write_page(cookie, page, object_size, gfp);
672 else 685 else
673 return -ENOBUFS; 686 return -ENOBUFS;
674} 687}
@@ -780,6 +793,7 @@ void fscache_uncache_all_inode_pages(struct fscache_cookie *cookie,
780/** 793/**
781 * fscache_disable_cookie - Disable a cookie 794 * fscache_disable_cookie - Disable a cookie
782 * @cookie: The cookie representing the cache object 795 * @cookie: The cookie representing the cache object
796 * @aux_data: The updated auxiliary data for the cookie (may be NULL)
783 * @invalidate: Invalidate the backing object 797 * @invalidate: Invalidate the backing object
784 * 798 *
785 * Disable a cookie from accepting further alloc, read, write, invalidate, 799 * Disable a cookie from accepting further alloc, read, write, invalidate,
@@ -790,34 +804,44 @@ void fscache_uncache_all_inode_pages(struct fscache_cookie *cookie,
790 * 804 *
791 * If @invalidate is set, then the backing object will be invalidated and 805 * If @invalidate is set, then the backing object will be invalidated and
792 * detached, otherwise it will just be detached. 806 * detached, otherwise it will just be detached.
807 *
808 * If @aux_data is set, then auxiliary data will be updated from that.
793 */ 809 */
794static inline 810static inline
795void fscache_disable_cookie(struct fscache_cookie *cookie, bool invalidate) 811void fscache_disable_cookie(struct fscache_cookie *cookie,
812 const void *aux_data,
813 bool invalidate)
796{ 814{
797 if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) 815 if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
798 __fscache_disable_cookie(cookie, invalidate); 816 __fscache_disable_cookie(cookie, aux_data, invalidate);
799} 817}
800 818
801/** 819/**
802 * fscache_enable_cookie - Reenable a cookie 820 * fscache_enable_cookie - Reenable a cookie
803 * @cookie: The cookie representing the cache object 821 * @cookie: The cookie representing the cache object
822 * @aux_data: The updated auxiliary data for the cookie (may be NULL)
823 * @object_size: Current size of object
804 * @can_enable: A function to permit enablement once lock is held 824 * @can_enable: A function to permit enablement once lock is held
805 * @data: Data for can_enable() 825 * @data: Data for can_enable()
806 * 826 *
807 * Reenable a previously disabled cookie, allowing it to accept further alloc, 827 * Reenable a previously disabled cookie, allowing it to accept further alloc,
808 * read, write, invalidate, update or acquire operations. An attempt will be 828 * read, write, invalidate, update or acquire operations. An attempt will be
809 * made to immediately reattach the cookie to a backing object. 829 * made to immediately reattach the cookie to a backing object. If @aux_data
830 * is set, the auxiliary data attached to the cookie will be updated.
810 * 831 *
811 * The can_enable() function is called (if not NULL) once the enablement lock 832 * The can_enable() function is called (if not NULL) once the enablement lock
812 * is held to rule on whether enablement is still permitted to go ahead. 833 * is held to rule on whether enablement is still permitted to go ahead.
813 */ 834 */
814static inline 835static inline
815void fscache_enable_cookie(struct fscache_cookie *cookie, 836void fscache_enable_cookie(struct fscache_cookie *cookie,
837 const void *aux_data,
838 loff_t object_size,
816 bool (*can_enable)(void *data), 839 bool (*can_enable)(void *data),
817 void *data) 840 void *data)
818{ 841{
819 if (fscache_cookie_valid(cookie) && !fscache_cookie_enabled(cookie)) 842 if (fscache_cookie_valid(cookie) && !fscache_cookie_enabled(cookie))
820 __fscache_enable_cookie(cookie, can_enable, data); 843 __fscache_enable_cookie(cookie, aux_data, object_size,
844 can_enable, data);
821} 845}
822 846
823#endif /* _LINUX_FSCACHE_H */ 847#endif /* _LINUX_FSCACHE_H */
diff --git a/include/trace/events/cachefiles.h b/include/trace/events/cachefiles.h
new file mode 100644
index 000000000000..aa86e7dba511
--- /dev/null
+++ b/include/trace/events/cachefiles.h
@@ -0,0 +1,325 @@
1/* CacheFiles tracepoints
2 *
3 * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11#undef TRACE_SYSTEM
12#define TRACE_SYSTEM cachefiles
13
14#if !defined(_TRACE_CACHEFILES_H) || defined(TRACE_HEADER_MULTI_READ)
15#define _TRACE_CACHEFILES_H
16
17#include <linux/tracepoint.h>
18
19/*
20 * Define enums for tracing information.
21 */
22#ifndef __CACHEFILES_DECLARE_TRACE_ENUMS_ONCE_ONLY
23#define __CACHEFILES_DECLARE_TRACE_ENUMS_ONCE_ONLY
24
25enum cachefiles_obj_ref_trace {
26 cachefiles_obj_put_wait_retry = fscache_obj_ref__nr_traces,
27 cachefiles_obj_put_wait_timeo,
28 cachefiles_obj_ref__nr_traces
29};
30
31#endif
32
33/*
34 * Define enum -> string mappings for display.
35 */
36#define cachefiles_obj_kill_traces \
37 EM(FSCACHE_OBJECT_IS_STALE, "stale") \
38 EM(FSCACHE_OBJECT_NO_SPACE, "no_space") \
39 EM(FSCACHE_OBJECT_WAS_RETIRED, "was_retired") \
40 E_(FSCACHE_OBJECT_WAS_CULLED, "was_culled")
41
42#define cachefiles_obj_ref_traces \
43 EM(fscache_obj_get_add_to_deps, "GET add_to_deps") \
44 EM(fscache_obj_get_queue, "GET queue") \
45 EM(fscache_obj_put_alloc_fail, "PUT alloc_fail") \
46 EM(fscache_obj_put_attach_fail, "PUT attach_fail") \
47 EM(fscache_obj_put_drop_obj, "PUT drop_obj") \
48 EM(fscache_obj_put_enq_dep, "PUT enq_dep") \
49 EM(fscache_obj_put_queue, "PUT queue") \
50 EM(fscache_obj_put_work, "PUT work") \
51 EM(cachefiles_obj_put_wait_retry, "PUT wait_retry") \
52 E_(cachefiles_obj_put_wait_timeo, "PUT wait_timeo")
53
54/*
55 * Export enum symbols via userspace.
56 */
57#undef EM
58#undef E_
59#define EM(a, b) TRACE_DEFINE_ENUM(a);
60#define E_(a, b) TRACE_DEFINE_ENUM(a);
61
62cachefiles_obj_kill_traces;
63cachefiles_obj_ref_traces;
64
65/*
66 * Now redefine the EM() and E_() macros to map the enums to the strings that
67 * will be printed in the output.
68 */
69#undef EM
70#undef E_
71#define EM(a, b) { a, b },
72#define E_(a, b) { a, b }
73
74
75TRACE_EVENT(cachefiles_ref,
76 TP_PROTO(struct cachefiles_object *obj,
77 struct fscache_cookie *cookie,
78 enum cachefiles_obj_ref_trace why,
79 int usage),
80
81 TP_ARGS(obj, cookie, why, usage),
82
83 /* Note that obj may be NULL */
84 TP_STRUCT__entry(
85 __field(struct cachefiles_object *, obj )
86 __field(struct fscache_cookie *, cookie )
87 __field(enum cachefiles_obj_ref_trace, why )
88 __field(int, usage )
89 ),
90
91 TP_fast_assign(
92 __entry->obj = obj;
93 __entry->cookie = cookie;
94 __entry->usage = usage;
95 __entry->why = why;
96 ),
97
98 TP_printk("c=%p o=%p u=%d %s",
99 __entry->cookie, __entry->obj, __entry->usage,
100 __print_symbolic(__entry->why, cachefiles_obj_ref_traces))
101 );
102
103TRACE_EVENT(cachefiles_lookup,
104 TP_PROTO(struct cachefiles_object *obj,
105 struct dentry *de,
106 struct inode *inode),
107
108 TP_ARGS(obj, de, inode),
109
110 TP_STRUCT__entry(
111 __field(struct cachefiles_object *, obj )
112 __field(struct dentry *, de )
113 __field(struct inode *, inode )
114 ),
115
116 TP_fast_assign(
117 __entry->obj = obj;
118 __entry->de = de;
119 __entry->inode = inode;
120 ),
121
122 TP_printk("o=%p d=%p i=%p",
123 __entry->obj, __entry->de, __entry->inode)
124 );
125
126TRACE_EVENT(cachefiles_mkdir,
127 TP_PROTO(struct cachefiles_object *obj,
128 struct dentry *de, int ret),
129
130 TP_ARGS(obj, de, ret),
131
132 TP_STRUCT__entry(
133 __field(struct cachefiles_object *, obj )
134 __field(struct dentry *, de )
135 __field(int, ret )
136 ),
137
138 TP_fast_assign(
139 __entry->obj = obj;
140 __entry->de = de;
141 __entry->ret = ret;
142 ),
143
144 TP_printk("o=%p d=%p r=%u",
145 __entry->obj, __entry->de, __entry->ret)
146 );
147
148TRACE_EVENT(cachefiles_create,
149 TP_PROTO(struct cachefiles_object *obj,
150 struct dentry *de, int ret),
151
152 TP_ARGS(obj, de, ret),
153
154 TP_STRUCT__entry(
155 __field(struct cachefiles_object *, obj )
156 __field(struct dentry *, de )
157 __field(int, ret )
158 ),
159
160 TP_fast_assign(
161 __entry->obj = obj;
162 __entry->de = de;
163 __entry->ret = ret;
164 ),
165
166 TP_printk("o=%p d=%p r=%u",
167 __entry->obj, __entry->de, __entry->ret)
168 );
169
170TRACE_EVENT(cachefiles_unlink,
171 TP_PROTO(struct cachefiles_object *obj,
172 struct dentry *de,
173 enum fscache_why_object_killed why),
174
175 TP_ARGS(obj, de, why),
176
177 /* Note that obj may be NULL */
178 TP_STRUCT__entry(
179 __field(struct cachefiles_object *, obj )
180 __field(struct dentry *, de )
181 __field(enum fscache_why_object_killed, why )
182 ),
183
184 TP_fast_assign(
185 __entry->obj = obj;
186 __entry->de = de;
187 __entry->why = why;
188 ),
189
190 TP_printk("o=%p d=%p w=%s",
191 __entry->obj, __entry->de,
192 __print_symbolic(__entry->why, cachefiles_obj_kill_traces))
193 );
194
195TRACE_EVENT(cachefiles_rename,
196 TP_PROTO(struct cachefiles_object *obj,
197 struct dentry *de,
198 struct dentry *to,
199 enum fscache_why_object_killed why),
200
201 TP_ARGS(obj, de, to, why),
202
203 /* Note that obj may be NULL */
204 TP_STRUCT__entry(
205 __field(struct cachefiles_object *, obj )
206 __field(struct dentry *, de )
207 __field(struct dentry *, to )
208 __field(enum fscache_why_object_killed, why )
209 ),
210
211 TP_fast_assign(
212 __entry->obj = obj;
213 __entry->de = de;
214 __entry->to = to;
215 __entry->why = why;
216 ),
217
218 TP_printk("o=%p d=%p t=%p w=%s",
219 __entry->obj, __entry->de, __entry->to,
220 __print_symbolic(__entry->why, cachefiles_obj_kill_traces))
221 );
222
223TRACE_EVENT(cachefiles_mark_active,
224 TP_PROTO(struct cachefiles_object *obj,
225 struct dentry *de),
226
227 TP_ARGS(obj, de),
228
229 /* Note that obj may be NULL */
230 TP_STRUCT__entry(
231 __field(struct cachefiles_object *, obj )
232 __field(struct dentry *, de )
233 ),
234
235 TP_fast_assign(
236 __entry->obj = obj;
237 __entry->de = de;
238 ),
239
240 TP_printk("o=%p d=%p",
241 __entry->obj, __entry->de)
242 );
243
244TRACE_EVENT(cachefiles_wait_active,
245 TP_PROTO(struct cachefiles_object *obj,
246 struct dentry *de,
247 struct cachefiles_object *xobj),
248
249 TP_ARGS(obj, de, xobj),
250
251 /* Note that obj may be NULL */
252 TP_STRUCT__entry(
253 __field(struct cachefiles_object *, obj )
254 __field(struct dentry *, de )
255 __field(struct cachefiles_object *, xobj )
256 __field(u16, flags )
257 __field(u16, fsc_flags )
258 ),
259
260 TP_fast_assign(
261 __entry->obj = obj;
262 __entry->de = de;
263 __entry->xobj = xobj;
264 __entry->flags = xobj->flags;
265 __entry->fsc_flags = xobj->fscache.flags;
266 ),
267
268 TP_printk("o=%p d=%p wo=%p wf=%x wff=%x",
269 __entry->obj, __entry->de, __entry->xobj,
270 __entry->flags, __entry->fsc_flags)
271 );
272
273TRACE_EVENT(cachefiles_mark_inactive,
274 TP_PROTO(struct cachefiles_object *obj,
275 struct dentry *de,
276 struct inode *inode),
277
278 TP_ARGS(obj, de, inode),
279
280 /* Note that obj may be NULL */
281 TP_STRUCT__entry(
282 __field(struct cachefiles_object *, obj )
283 __field(struct dentry *, de )
284 __field(struct inode *, inode )
285 ),
286
287 TP_fast_assign(
288 __entry->obj = obj;
289 __entry->de = de;
290 __entry->inode = inode;
291 ),
292
293 TP_printk("o=%p d=%p i=%p",
294 __entry->obj, __entry->de, __entry->inode)
295 );
296
297TRACE_EVENT(cachefiles_mark_buried,
298 TP_PROTO(struct cachefiles_object *obj,
299 struct dentry *de,
300 enum fscache_why_object_killed why),
301
302 TP_ARGS(obj, de, why),
303
304 /* Note that obj may be NULL */
305 TP_STRUCT__entry(
306 __field(struct cachefiles_object *, obj )
307 __field(struct dentry *, de )
308 __field(enum fscache_why_object_killed, why )
309 ),
310
311 TP_fast_assign(
312 __entry->obj = obj;
313 __entry->de = de;
314 __entry->why = why;
315 ),
316
317 TP_printk("o=%p d=%p w=%s",
318 __entry->obj, __entry->de,
319 __print_symbolic(__entry->why, cachefiles_obj_kill_traces))
320 );
321
322#endif /* _TRACE_CACHEFILES_H */
323
324/* This part must be outside protection */
325#include <trace/define_trace.h>
diff --git a/include/trace/events/fscache.h b/include/trace/events/fscache.h
new file mode 100644
index 000000000000..686cfe997ed2
--- /dev/null
+++ b/include/trace/events/fscache.h
@@ -0,0 +1,537 @@
1/* FS-Cache tracepoints
2 *
3 * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11#undef TRACE_SYSTEM
12#define TRACE_SYSTEM fscache
13
14#if !defined(_TRACE_FSCACHE_H) || defined(TRACE_HEADER_MULTI_READ)
15#define _TRACE_FSCACHE_H
16
17#include <linux/fscache.h>
18#include <linux/tracepoint.h>
19
20/*
21 * Define enums for tracing information.
22 */
23#ifndef __FSCACHE_DECLARE_TRACE_ENUMS_ONCE_ONLY
24#define __FSCACHE_DECLARE_TRACE_ENUMS_ONCE_ONLY
25
26enum fscache_cookie_trace {
27 fscache_cookie_collision,
28 fscache_cookie_discard,
29 fscache_cookie_get_acquire_parent,
30 fscache_cookie_get_attach_object,
31 fscache_cookie_get_reacquire,
32 fscache_cookie_get_register_netfs,
33 fscache_cookie_put_acquire_nobufs,
34 fscache_cookie_put_dup_netfs,
35 fscache_cookie_put_relinquish,
36 fscache_cookie_put_object,
37 fscache_cookie_put_parent,
38};
39
40enum fscache_page_trace {
41 fscache_page_cached,
42 fscache_page_inval,
43 fscache_page_maybe_release,
44 fscache_page_radix_clear_store,
45 fscache_page_radix_delete,
46 fscache_page_radix_insert,
47 fscache_page_radix_pend2store,
48 fscache_page_radix_set_pend,
49 fscache_page_uncache,
50 fscache_page_write,
51 fscache_page_write_end,
52 fscache_page_write_end_pend,
53 fscache_page_write_end_noc,
54 fscache_page_write_wait,
55 fscache_page_trace__nr
56};
57
58enum fscache_op_trace {
59 fscache_op_cancel,
60 fscache_op_cancel_all,
61 fscache_op_cancelled,
62 fscache_op_completed,
63 fscache_op_enqueue_async,
64 fscache_op_enqueue_mythread,
65 fscache_op_gc,
66 fscache_op_init,
67 fscache_op_put,
68 fscache_op_run,
69 fscache_op_signal,
70 fscache_op_submit,
71 fscache_op_submit_ex,
72 fscache_op_work,
73 fscache_op_trace__nr
74};
75
76enum fscache_page_op_trace {
77 fscache_page_op_alloc_one,
78 fscache_page_op_attr_changed,
79 fscache_page_op_check_consistency,
80 fscache_page_op_invalidate,
81 fscache_page_op_retr_multi,
82 fscache_page_op_retr_one,
83 fscache_page_op_write_one,
84 fscache_page_op_trace__nr
85};
86
87#endif
88
89/*
90 * Declare tracing information enums and their string mappings for display.
91 */
92#define fscache_cookie_traces \
93 EM(fscache_cookie_collision, "*COLLISION*") \
94 EM(fscache_cookie_discard, "DISCARD") \
95 EM(fscache_cookie_get_acquire_parent, "GET prn") \
96 EM(fscache_cookie_get_attach_object, "GET obj") \
97 EM(fscache_cookie_get_reacquire, "GET raq") \
98 EM(fscache_cookie_get_register_netfs, "GET net") \
99 EM(fscache_cookie_put_acquire_nobufs, "PUT nbf") \
100 EM(fscache_cookie_put_dup_netfs, "PUT dnt") \
101 EM(fscache_cookie_put_relinquish, "PUT rlq") \
102 EM(fscache_cookie_put_object, "PUT obj") \
103 E_(fscache_cookie_put_parent, "PUT prn")
104
105#define fscache_page_traces \
106 EM(fscache_page_cached, "Cached ") \
107 EM(fscache_page_inval, "InvalPg") \
108 EM(fscache_page_maybe_release, "MayRels") \
109 EM(fscache_page_uncache, "Uncache") \
110 EM(fscache_page_radix_clear_store, "RxCStr ") \
111 EM(fscache_page_radix_delete, "RxDel ") \
112 EM(fscache_page_radix_insert, "RxIns ") \
113 EM(fscache_page_radix_pend2store, "RxP2S ") \
114 EM(fscache_page_radix_set_pend, "RxSPend ") \
115 EM(fscache_page_write, "WritePg") \
116 EM(fscache_page_write_end, "EndPgWr") \
117 EM(fscache_page_write_end_pend, "EndPgWP") \
118 EM(fscache_page_write_end_noc, "EndPgNC") \
119 E_(fscache_page_write_wait, "WtOnWrt")
120
121#define fscache_op_traces \
122 EM(fscache_op_cancel, "Cancel1") \
123 EM(fscache_op_cancel_all, "CancelA") \
124 EM(fscache_op_cancelled, "Canclld") \
125 EM(fscache_op_completed, "Complet") \
126 EM(fscache_op_enqueue_async, "EnqAsyn") \
127 EM(fscache_op_enqueue_mythread, "EnqMyTh") \
128 EM(fscache_op_gc, "GC ") \
129 EM(fscache_op_init, "Init ") \
130 EM(fscache_op_put, "Put ") \
131 EM(fscache_op_run, "Run ") \
132 EM(fscache_op_signal, "Signal ") \
133 EM(fscache_op_submit, "Submit ") \
134 EM(fscache_op_submit_ex, "SubmitX") \
135 E_(fscache_op_work, "Work ")
136
137#define fscache_page_op_traces \
138 EM(fscache_page_op_alloc_one, "Alloc1 ") \
139 EM(fscache_page_op_attr_changed, "AttrChg") \
140 EM(fscache_page_op_check_consistency, "CheckCn") \
141 EM(fscache_page_op_invalidate, "Inval ") \
142 EM(fscache_page_op_retr_multi, "RetrMul") \
143 EM(fscache_page_op_retr_one, "Retr1 ") \
144 E_(fscache_page_op_write_one, "Write1 ")
145
146/*
147 * Export enum symbols via userspace.
148 */
149#undef EM
150#undef E_
151#define EM(a, b) TRACE_DEFINE_ENUM(a);
152#define E_(a, b) TRACE_DEFINE_ENUM(a);
153
154fscache_cookie_traces;
155
156/*
157 * Now redefine the EM() and E_() macros to map the enums to the strings that
158 * will be printed in the output.
159 */
160#undef EM
161#undef E_
162#define EM(a, b) { a, b },
163#define E_(a, b) { a, b }
164
165
166TRACE_EVENT(fscache_cookie,
167 TP_PROTO(struct fscache_cookie *cookie,
168 enum fscache_cookie_trace where,
169 int usage),
170
171 TP_ARGS(cookie, where, usage),
172
173 TP_STRUCT__entry(
174 __field(struct fscache_cookie *, cookie )
175 __field(struct fscache_cookie *, parent )
176 __field(enum fscache_cookie_trace, where )
177 __field(int, usage )
178 __field(int, n_children )
179 __field(int, n_active )
180 __field(u8, flags )
181 ),
182
183 TP_fast_assign(
184 __entry->cookie = cookie;
185 __entry->parent = cookie->parent;
186 __entry->where = where;
187 __entry->usage = usage;
188 __entry->n_children = atomic_read(&cookie->n_children);
189 __entry->n_active = atomic_read(&cookie->n_active);
190 __entry->flags = cookie->flags;
191 ),
192
193 TP_printk("%s c=%p u=%d p=%p Nc=%d Na=%d f=%02x",
194 __print_symbolic(__entry->where, fscache_cookie_traces),
195 __entry->cookie, __entry->usage,
196 __entry->parent, __entry->n_children, __entry->n_active,
197 __entry->flags)
198 );
199
200TRACE_EVENT(fscache_netfs,
201 TP_PROTO(struct fscache_netfs *netfs),
202
203 TP_ARGS(netfs),
204
205 TP_STRUCT__entry(
206 __field(struct fscache_cookie *, cookie )
207 __array(char, name, 8 )
208 ),
209
210 TP_fast_assign(
211 __entry->cookie = netfs->primary_index;
212 strncpy(__entry->name, netfs->name, 8);
213 __entry->name[7] = 0;
214 ),
215
216 TP_printk("c=%p n=%s",
217 __entry->cookie, __entry->name)
218 );
219
220TRACE_EVENT(fscache_acquire,
221 TP_PROTO(struct fscache_cookie *cookie),
222
223 TP_ARGS(cookie),
224
225 TP_STRUCT__entry(
226 __field(struct fscache_cookie *, cookie )
227 __field(struct fscache_cookie *, parent )
228 __array(char, name, 8 )
229 __field(int, p_usage )
230 __field(int, p_n_children )
231 __field(u8, p_flags )
232 ),
233
234 TP_fast_assign(
235 __entry->cookie = cookie;
236 __entry->parent = cookie->parent;
237 __entry->p_usage = atomic_read(&cookie->parent->usage);
238 __entry->p_n_children = atomic_read(&cookie->parent->n_children);
239 __entry->p_flags = cookie->parent->flags;
240 memcpy(__entry->name, cookie->def->name, 8);
241 __entry->name[7] = 0;
242 ),
243
244 TP_printk("c=%p p=%p pu=%d pc=%d pf=%02x n=%s",
245 __entry->cookie, __entry->parent, __entry->p_usage,
246 __entry->p_n_children, __entry->p_flags, __entry->name)
247 );
248
249TRACE_EVENT(fscache_relinquish,
250 TP_PROTO(struct fscache_cookie *cookie, bool retire),
251
252 TP_ARGS(cookie, retire),
253
254 TP_STRUCT__entry(
255 __field(struct fscache_cookie *, cookie )
256 __field(struct fscache_cookie *, parent )
257 __field(int, usage )
258 __field(int, n_children )
259 __field(int, n_active )
260 __field(u8, flags )
261 __field(bool, retire )
262 ),
263
264 TP_fast_assign(
265 __entry->cookie = cookie;
266 __entry->parent = cookie->parent;
267 __entry->usage = atomic_read(&cookie->usage);
268 __entry->n_children = atomic_read(&cookie->n_children);
269 __entry->n_active = atomic_read(&cookie->n_active);
270 __entry->flags = cookie->flags;
271 __entry->retire = retire;
272 ),
273
274 TP_printk("c=%p u=%d p=%p Nc=%d Na=%d f=%02x r=%u",
275 __entry->cookie, __entry->usage,
276 __entry->parent, __entry->n_children, __entry->n_active,
277 __entry->flags, __entry->retire)
278 );
279
280TRACE_EVENT(fscache_enable,
281 TP_PROTO(struct fscache_cookie *cookie),
282
283 TP_ARGS(cookie),
284
285 TP_STRUCT__entry(
286 __field(struct fscache_cookie *, cookie )
287 __field(int, usage )
288 __field(int, n_children )
289 __field(int, n_active )
290 __field(u8, flags )
291 ),
292
293 TP_fast_assign(
294 __entry->cookie = cookie;
295 __entry->usage = atomic_read(&cookie->usage);
296 __entry->n_children = atomic_read(&cookie->n_children);
297 __entry->n_active = atomic_read(&cookie->n_active);
298 __entry->flags = cookie->flags;
299 ),
300
301 TP_printk("c=%p u=%d Nc=%d Na=%d f=%02x",
302 __entry->cookie, __entry->usage,
303 __entry->n_children, __entry->n_active, __entry->flags)
304 );
305
306TRACE_EVENT(fscache_disable,
307 TP_PROTO(struct fscache_cookie *cookie),
308
309 TP_ARGS(cookie),
310
311 TP_STRUCT__entry(
312 __field(struct fscache_cookie *, cookie )
313 __field(int, usage )
314 __field(int, n_children )
315 __field(int, n_active )
316 __field(u8, flags )
317 ),
318
319 TP_fast_assign(
320 __entry->cookie = cookie;
321 __entry->usage = atomic_read(&cookie->usage);
322 __entry->n_children = atomic_read(&cookie->n_children);
323 __entry->n_active = atomic_read(&cookie->n_active);
324 __entry->flags = cookie->flags;
325 ),
326
327 TP_printk("c=%p u=%d Nc=%d Na=%d f=%02x",
328 __entry->cookie, __entry->usage,
329 __entry->n_children, __entry->n_active, __entry->flags)
330 );
331
332TRACE_EVENT(fscache_osm,
333 TP_PROTO(struct fscache_object *object,
334 const struct fscache_state *state,
335 bool wait, bool oob, s8 event_num),
336
337 TP_ARGS(object, state, wait, oob, event_num),
338
339 TP_STRUCT__entry(
340 __field(struct fscache_cookie *, cookie )
341 __field(struct fscache_object *, object )
342 __array(char, state, 8 )
343 __field(bool, wait )
344 __field(bool, oob )
345 __field(s8, event_num )
346 ),
347
348 TP_fast_assign(
349 __entry->cookie = object->cookie;
350 __entry->object = object;
351 __entry->wait = wait;
352 __entry->oob = oob;
353 __entry->event_num = event_num;
354 memcpy(__entry->state, state->short_name, 8);
355 ),
356
357 TP_printk("c=%p o=%p %s %s%sev=%d",
358 __entry->cookie,
359 __entry->object,
360 __entry->state,
361 __print_symbolic(__entry->wait,
362 { true, "WAIT" },
363 { false, "WORK" }),
364 __print_symbolic(__entry->oob,
365 { true, " OOB " },
366 { false, " " }),
367 __entry->event_num)
368 );
369
370TRACE_EVENT(fscache_page,
371 TP_PROTO(struct fscache_cookie *cookie, struct page *page,
372 enum fscache_page_trace why),
373
374 TP_ARGS(cookie, page, why),
375
376 TP_STRUCT__entry(
377 __field(struct fscache_cookie *, cookie )
378 __field(pgoff_t, page )
379 __field(enum fscache_page_trace, why )
380 ),
381
382 TP_fast_assign(
383 __entry->cookie = cookie;
384 __entry->page = page->index;
385 __entry->why = why;
386 ),
387
388 TP_printk("c=%p %s pg=%lx",
389 __entry->cookie,
390 __print_symbolic(__entry->why, fscache_page_traces),
391 __entry->page)
392 );
393
394TRACE_EVENT(fscache_check_page,
395 TP_PROTO(struct fscache_cookie *cookie, struct page *page,
396 void *val, int n),
397
398 TP_ARGS(cookie, page, val, n),
399
400 TP_STRUCT__entry(
401 __field(struct fscache_cookie *, cookie )
402 __field(void *, page )
403 __field(void *, val )
404 __field(int, n )
405 ),
406
407 TP_fast_assign(
408 __entry->cookie = cookie;
409 __entry->page = page;
410 __entry->val = val;
411 __entry->n = n;
412 ),
413
414 TP_printk("c=%p pg=%p val=%p n=%d",
415 __entry->cookie, __entry->page, __entry->val, __entry->n)
416 );
417
418TRACE_EVENT(fscache_wake_cookie,
419 TP_PROTO(struct fscache_cookie *cookie),
420
421 TP_ARGS(cookie),
422
423 TP_STRUCT__entry(
424 __field(struct fscache_cookie *, cookie )
425 ),
426
427 TP_fast_assign(
428 __entry->cookie = cookie;
429 ),
430
431 TP_printk("c=%p", __entry->cookie)
432 );
433
434TRACE_EVENT(fscache_op,
435 TP_PROTO(struct fscache_cookie *cookie, struct fscache_operation *op,
436 enum fscache_op_trace why),
437
438 TP_ARGS(cookie, op, why),
439
440 TP_STRUCT__entry(
441 __field(struct fscache_cookie *, cookie )
442 __field(struct fscache_operation *, op )
443 __field(enum fscache_op_trace, why )
444 ),
445
446 TP_fast_assign(
447 __entry->cookie = cookie;
448 __entry->op = op;
449 __entry->why = why;
450 ),
451
452 TP_printk("c=%p op=%p %s",
453 __entry->cookie, __entry->op,
454 __print_symbolic(__entry->why, fscache_op_traces))
455 );
456
457TRACE_EVENT(fscache_page_op,
458 TP_PROTO(struct fscache_cookie *cookie, struct page *page,
459 struct fscache_operation *op, enum fscache_page_op_trace what),
460
461 TP_ARGS(cookie, page, op, what),
462
463 TP_STRUCT__entry(
464 __field(struct fscache_cookie *, cookie )
465 __field(pgoff_t, page )
466 __field(struct fscache_operation *, op )
467 __field(enum fscache_page_op_trace, what )
468 ),
469
470 TP_fast_assign(
471 __entry->cookie = cookie;
472 __entry->page = page ? page->index : 0;
473 __entry->op = op;
474 __entry->what = what;
475 ),
476
477 TP_printk("c=%p %s pg=%lx op=%p",
478 __entry->cookie,
479 __print_symbolic(__entry->what, fscache_page_op_traces),
480 __entry->page, __entry->op)
481 );
482
483TRACE_EVENT(fscache_wrote_page,
484 TP_PROTO(struct fscache_cookie *cookie, struct page *page,
485 struct fscache_operation *op, int ret),
486
487 TP_ARGS(cookie, page, op, ret),
488
489 TP_STRUCT__entry(
490 __field(struct fscache_cookie *, cookie )
491 __field(pgoff_t, page )
492 __field(struct fscache_operation *, op )
493 __field(int, ret )
494 ),
495
496 TP_fast_assign(
497 __entry->cookie = cookie;
498 __entry->page = page->index;
499 __entry->op = op;
500 __entry->ret = ret;
501 ),
502
503 TP_printk("c=%p pg=%lx op=%p ret=%d",
504 __entry->cookie, __entry->page, __entry->op, __entry->ret)
505 );
506
507TRACE_EVENT(fscache_gang_lookup,
508 TP_PROTO(struct fscache_cookie *cookie, struct fscache_operation *op,
509 void **results, int n, pgoff_t store_limit),
510
511 TP_ARGS(cookie, op, results, n, store_limit),
512
513 TP_STRUCT__entry(
514 __field(struct fscache_cookie *, cookie )
515 __field(struct fscache_operation *, op )
516 __field(pgoff_t, results0 )
517 __field(int, n )
518 __field(pgoff_t, store_limit )
519 ),
520
521 TP_fast_assign(
522 __entry->cookie = cookie;
523 __entry->op = op;
524 __entry->results0 = results[0] ? ((struct page *)results[0])->index : (pgoff_t)-1;
525 __entry->n = n;
526 __entry->store_limit = store_limit;
527 ),
528
529 TP_printk("c=%p op=%p r0=%lx n=%d sl=%lx",
530 __entry->cookie, __entry->op, __entry->results0, __entry->n,
531 __entry->store_limit)
532 );
533
534#endif /* _TRACE_FSCACHE_H */
535
536/* This part must be outside protection */
537#include <trace/define_trace.h>