aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/filesystems/caching/netfs-api.txt73
-rw-r--r--fs/9p/cache.c6
-rw-r--r--fs/afs/cell.c2
-rw-r--r--fs/afs/inode.c2
-rw-r--r--fs/afs/vlocation.c3
-rw-r--r--fs/afs/volume.c2
-rw-r--r--fs/cachefiles/interface.c2
-rw-r--r--fs/ceph/cache.c4
-rw-r--r--fs/cifs/fscache.c8
-rw-r--r--fs/fscache/cookie.c186
-rw-r--r--fs/fscache/fsdef.c1
-rw-r--r--fs/fscache/netfs.c1
-rw-r--r--fs/fscache/object.c7
-rw-r--r--fs/fscache/page.c17
-rw-r--r--fs/nfs/fscache.c8
-rw-r--r--include/linux/fscache-cache.h31
-rw-r--r--include/linux/fscache.h113
17 files changed, 334 insertions, 132 deletions
diff --git a/Documentation/filesystems/caching/netfs-api.txt b/Documentation/filesystems/caching/netfs-api.txt
index 11a0a40ce445..aed6b94160b1 100644
--- a/Documentation/filesystems/caching/netfs-api.txt
+++ b/Documentation/filesystems/caching/netfs-api.txt
@@ -29,15 +29,16 @@ This document contains the following sections:
29 (6) Index registration 29 (6) Index registration
30 (7) Data file registration 30 (7) Data file registration
31 (8) Miscellaneous object registration 31 (8) Miscellaneous object registration
32 (9) Setting the data file size 32 (9) Setting the data file size
33 (10) Page alloc/read/write 33 (10) Page alloc/read/write
34 (11) Page uncaching 34 (11) Page uncaching
35 (12) Index and data file consistency 35 (12) Index and data file consistency
36 (13) Miscellaneous cookie operations 36 (13) Cookie enablement
37 (14) Cookie unregistration 37 (14) Miscellaneous cookie operations
38 (15) Index invalidation 38 (15) Cookie unregistration
39 (16) Data file invalidation 39 (16) Index invalidation
40 (17) FS-Cache specific page flags. 40 (17) Data file invalidation
41 (18) FS-Cache specific page flags.
41 42
42 43
43============================= 44=============================
@@ -334,7 +335,8 @@ the path to the file:
334 struct fscache_cookie * 335 struct fscache_cookie *
335 fscache_acquire_cookie(struct fscache_cookie *parent, 336 fscache_acquire_cookie(struct fscache_cookie *parent,
336 const struct fscache_object_def *def, 337 const struct fscache_object_def *def,
337 void *netfs_data); 338 void *netfs_data,
339 bool enable);
338 340
339This function creates an index entry in the index represented by parent, 341This function creates an index entry in the index represented by parent,
340filling in the index entry by calling the operations pointed to by def. 342filling in the index entry by calling the operations pointed to by def.
@@ -350,6 +352,10 @@ object needs to be created somewhere down the hierarchy. Furthermore, an index
350may be created in several different caches independently at different times. 352may be created in several different caches independently at different times.
351This is all handled transparently, and the netfs doesn't see any of it. 353This is all handled transparently, and the netfs doesn't see any of it.
352 354
355A cookie will be created in the disabled state if enabled is false. A cookie
356must be enabled to do anything with it. A disabled cookie can be enabled by
357calling fscache_enable_cookie() (see below).
358
353For example, with AFS, a cell would be added to the primary index. This index 359For example, with AFS, a cell would be added to the primary index. This index
354entry would have a dependent inode containing a volume location index for the 360entry would have a dependent inode containing a volume location index for the
355volume mappings within this cell: 361volume mappings within this cell:
@@ -357,7 +363,7 @@ volume mappings within this cell:
357 cell->cache = 363 cell->cache =
358 fscache_acquire_cookie(afs_cache_netfs.primary_index, 364 fscache_acquire_cookie(afs_cache_netfs.primary_index,
359 &afs_cell_cache_index_def, 365 &afs_cell_cache_index_def,
360 cell); 366 cell, true);
361 367
362Then when a volume location was accessed, it would be entered into the cell's 368Then when a volume location was accessed, it would be entered into the cell's
363index and an inode would be allocated that acts as a volume type and hash chain 369index and an inode would be allocated that acts as a volume type and hash chain
@@ -366,7 +372,7 @@ combination:
366 vlocation->cache = 372 vlocation->cache =
367 fscache_acquire_cookie(cell->cache, 373 fscache_acquire_cookie(cell->cache,
368 &afs_vlocation_cache_index_def, 374 &afs_vlocation_cache_index_def,
369 vlocation); 375 vlocation, true);
370 376
371And then a particular flavour of volume (R/O for example) could be added to 377And then a particular flavour of volume (R/O for example) could be added to
372that index, creating another index for vnodes (AFS inode equivalents): 378that index, creating another index for vnodes (AFS inode equivalents):
@@ -374,7 +380,7 @@ that index, creating another index for vnodes (AFS inode equivalents):
374 volume->cache = 380 volume->cache =
375 fscache_acquire_cookie(vlocation->cache, 381 fscache_acquire_cookie(vlocation->cache,
376 &afs_volume_cache_index_def, 382 &afs_volume_cache_index_def,
377 volume); 383 volume, true);
378 384
379 385
380====================== 386======================
@@ -388,7 +394,7 @@ the object definition should be something other than index type.
388 vnode->cache = 394 vnode->cache =
389 fscache_acquire_cookie(volume->cache, 395 fscache_acquire_cookie(volume->cache,
390 &afs_vnode_cache_object_def, 396 &afs_vnode_cache_object_def,
391 vnode); 397 vnode, true);
392 398
393 399
394================================= 400=================================
@@ -404,7 +410,7 @@ it would be some other type of object such as a data file.
404 xattr->cache = 410 xattr->cache =
405 fscache_acquire_cookie(vnode->cache, 411 fscache_acquire_cookie(vnode->cache,
406 &afs_xattr_cache_object_def, 412 &afs_xattr_cache_object_def,
407 xattr); 413 xattr, true);
408 414
409Miscellaneous objects might be used to store extended attributes or directory 415Miscellaneous objects might be used to store extended attributes or directory
410entries for example. 416entries for example.
@@ -733,6 +739,47 @@ Note that partial updates may happen automatically at other times, such as when
733data blocks are added to a data file object. 739data blocks are added to a data file object.
734 740
735 741
742=================
743COOKIE ENABLEMENT
744=================
745
746Cookies exist in one of two states: enabled and disabled. If a cookie is
747disabled, it ignores all attempts to acquire child cookies; check, update or
748invalidate its state; allocate, read or write backing pages - though it is
749still possible to uncache pages and relinquish the cookie.
750
751The initial enablement state is set by fscache_acquire_cookie(), but the cookie
752can be enabled or disabled later. To disable a cookie, call:
753
754 void fscache_disable_cookie(struct fscache_cookie *cookie,
755 bool invalidate);
756
757If the cookie is not already disabled, this locks the cookie against other
758enable and disable ops, marks the cookie as being disabled, discards or
759invalidates any backing objects and waits for cessation of activity on any
760associated object before unlocking the cookie.
761
762All possible failures are handled internally. The caller should consider
763calling fscache_uncache_all_inode_pages() afterwards to make sure all page
764markings are cleared up.
765
766Cookies can be enabled or reenabled with:
767
768 void fscache_enable_cookie(struct fscache_cookie *cookie,
769 bool (*can_enable)(void *data),
770 void *data)
771
772If the cookie is not already enabled, this locks the cookie against other
773enable and disable ops, invokes can_enable() and, if the cookie is not an index
774cookie, will begin the procedure of acquiring backing objects.
775
776The optional can_enable() function is passed the data argument and returns a
777ruling as to whether or not enablement should actually be permitted to begin.
778
779All possible failures are handled internally. The cookie will only be marked
780as enabled if provisional backing objects are allocated.
781
782
736=============================== 783===============================
737MISCELLANEOUS COOKIE OPERATIONS 784MISCELLANEOUS COOKIE OPERATIONS
738=============================== 785===============================
@@ -778,7 +825,7 @@ COOKIE UNREGISTRATION
778To get rid of a cookie, this function should be called. 825To get rid of a cookie, this function should be called.
779 826
780 void fscache_relinquish_cookie(struct fscache_cookie *cookie, 827 void fscache_relinquish_cookie(struct fscache_cookie *cookie,
781 int retire); 828 bool retire);
782 829
783If retire is non-zero, then the object will be marked for recycling, and all 830If retire is non-zero, then the object will be marked for recycling, and all
784copies of it will be removed from all active caches in which it is present. 831copies of it will be removed from all active caches in which it is present.
diff --git a/fs/9p/cache.c b/fs/9p/cache.c
index a9ea73d6dcf3..2b7a032c37bc 100644
--- a/fs/9p/cache.c
+++ b/fs/9p/cache.c
@@ -90,7 +90,7 @@ void v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses)
90 90
91 v9ses->fscache = fscache_acquire_cookie(v9fs_cache_netfs.primary_index, 91 v9ses->fscache = fscache_acquire_cookie(v9fs_cache_netfs.primary_index,
92 &v9fs_cache_session_index_def, 92 &v9fs_cache_session_index_def,
93 v9ses); 93 v9ses, true);
94 p9_debug(P9_DEBUG_FSC, "session %p get cookie %p\n", 94 p9_debug(P9_DEBUG_FSC, "session %p get cookie %p\n",
95 v9ses, v9ses->fscache); 95 v9ses, v9ses->fscache);
96} 96}
@@ -204,7 +204,7 @@ void v9fs_cache_inode_get_cookie(struct inode *inode)
204 v9ses = v9fs_inode2v9ses(inode); 204 v9ses = v9fs_inode2v9ses(inode);
205 v9inode->fscache = fscache_acquire_cookie(v9ses->fscache, 205 v9inode->fscache = fscache_acquire_cookie(v9ses->fscache,
206 &v9fs_cache_inode_index_def, 206 &v9fs_cache_inode_index_def,
207 v9inode); 207 v9inode, true);
208 208
209 p9_debug(P9_DEBUG_FSC, "inode %p get cookie %p\n", 209 p9_debug(P9_DEBUG_FSC, "inode %p get cookie %p\n",
210 inode, v9inode->fscache); 210 inode, v9inode->fscache);
@@ -271,7 +271,7 @@ void v9fs_cache_inode_reset_cookie(struct inode *inode)
271 v9ses = v9fs_inode2v9ses(inode); 271 v9ses = v9fs_inode2v9ses(inode);
272 v9inode->fscache = fscache_acquire_cookie(v9ses->fscache, 272 v9inode->fscache = fscache_acquire_cookie(v9ses->fscache,
273 &v9fs_cache_inode_index_def, 273 &v9fs_cache_inode_index_def,
274 v9inode); 274 v9inode, true);
275 p9_debug(P9_DEBUG_FSC, "inode %p revalidating cookie old %p new %p\n", 275 p9_debug(P9_DEBUG_FSC, "inode %p revalidating cookie old %p new %p\n",
276 inode, old, v9inode->fscache); 276 inode, old, v9inode->fscache);
277 277
diff --git a/fs/afs/cell.c b/fs/afs/cell.c
index 3c090b7555ea..ca0a3cf93791 100644
--- a/fs/afs/cell.c
+++ b/fs/afs/cell.c
@@ -179,7 +179,7 @@ struct afs_cell *afs_cell_create(const char *name, unsigned namesz,
179 /* put it up for caching (this never returns an error) */ 179 /* put it up for caching (this never returns an error) */
180 cell->cache = fscache_acquire_cookie(afs_cache_netfs.primary_index, 180 cell->cache = fscache_acquire_cookie(afs_cache_netfs.primary_index,
181 &afs_cell_cache_index_def, 181 &afs_cell_cache_index_def,
182 cell); 182 cell, true);
183#endif 183#endif
184 184
185 /* add to the cell lists */ 185 /* add to the cell lists */
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index 789bc253b5f6..ce25d755b7aa 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -259,7 +259,7 @@ struct inode *afs_iget(struct super_block *sb, struct key *key,
259#ifdef CONFIG_AFS_FSCACHE 259#ifdef CONFIG_AFS_FSCACHE
260 vnode->cache = fscache_acquire_cookie(vnode->volume->cache, 260 vnode->cache = fscache_acquire_cookie(vnode->volume->cache,
261 &afs_vnode_cache_index_def, 261 &afs_vnode_cache_index_def,
262 vnode); 262 vnode, true);
263#endif 263#endif
264 264
265 ret = afs_inode_map_status(vnode, key); 265 ret = afs_inode_map_status(vnode, key);
diff --git a/fs/afs/vlocation.c b/fs/afs/vlocation.c
index 57bcb1596530..b6df2e83809f 100644
--- a/fs/afs/vlocation.c
+++ b/fs/afs/vlocation.c
@@ -308,7 +308,8 @@ static int afs_vlocation_fill_in_record(struct afs_vlocation *vl,
308 /* see if we have an in-cache copy (will set vl->valid if there is) */ 308 /* see if we have an in-cache copy (will set vl->valid if there is) */
309#ifdef CONFIG_AFS_FSCACHE 309#ifdef CONFIG_AFS_FSCACHE
310 vl->cache = fscache_acquire_cookie(vl->cell->cache, 310 vl->cache = fscache_acquire_cookie(vl->cell->cache,
311 &afs_vlocation_cache_index_def, vl); 311 &afs_vlocation_cache_index_def, vl,
312 true);
312#endif 313#endif
313 314
314 if (vl->valid) { 315 if (vl->valid) {
diff --git a/fs/afs/volume.c b/fs/afs/volume.c
index 401eeb21869f..2b607257820c 100644
--- a/fs/afs/volume.c
+++ b/fs/afs/volume.c
@@ -131,7 +131,7 @@ struct afs_volume *afs_volume_lookup(struct afs_mount_params *params)
131#ifdef CONFIG_AFS_FSCACHE 131#ifdef CONFIG_AFS_FSCACHE
132 volume->cache = fscache_acquire_cookie(vlocation->cache, 132 volume->cache = fscache_acquire_cookie(vlocation->cache,
133 &afs_volume_cache_index_def, 133 &afs_volume_cache_index_def,
134 volume); 134 volume, true);
135#endif 135#endif
136 afs_get_vlocation(vlocation); 136 afs_get_vlocation(vlocation);
137 volume->vlocation = vlocation; 137 volume->vlocation = vlocation;
diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
index 43eb5592cdea..00baf1419989 100644
--- a/fs/cachefiles/interface.c
+++ b/fs/cachefiles/interface.c
@@ -270,7 +270,7 @@ static void cachefiles_drop_object(struct fscache_object *_object)
270#endif 270#endif
271 271
272 /* delete retired objects */ 272 /* delete retired objects */
273 if (test_bit(FSCACHE_COOKIE_RETIRED, &object->fscache.cookie->flags) && 273 if (test_bit(FSCACHE_OBJECT_RETIRED, &object->fscache.flags) &&
274 _object != cache->cache.fsdef 274 _object != cache->cache.fsdef
275 ) { 275 ) {
276 _debug("- retire object OBJ%x", object->fscache.debug_id); 276 _debug("- retire object OBJ%x", object->fscache.debug_id);
diff --git a/fs/ceph/cache.c b/fs/ceph/cache.c
index 6bfe65e0b038..7db2e6ca4b8f 100644
--- a/fs/ceph/cache.c
+++ b/fs/ceph/cache.c
@@ -68,7 +68,7 @@ int ceph_fscache_register_fs(struct ceph_fs_client* fsc)
68{ 68{
69 fsc->fscache = fscache_acquire_cookie(ceph_cache_netfs.primary_index, 69 fsc->fscache = fscache_acquire_cookie(ceph_cache_netfs.primary_index,
70 &ceph_fscache_fsid_object_def, 70 &ceph_fscache_fsid_object_def,
71 fsc); 71 fsc, true);
72 72
73 if (fsc->fscache == NULL) { 73 if (fsc->fscache == NULL) {
74 pr_err("Unable to resgister fsid: %p fscache cookie", fsc); 74 pr_err("Unable to resgister fsid: %p fscache cookie", fsc);
@@ -204,7 +204,7 @@ void ceph_fscache_register_inode_cookie(struct ceph_fs_client* fsc,
204 204
205 ci->fscache = fscache_acquire_cookie(fsc->fscache, 205 ci->fscache = fscache_acquire_cookie(fsc->fscache,
206 &ceph_fscache_inode_object_def, 206 &ceph_fscache_inode_object_def,
207 ci); 207 ci, true);
208done: 208done:
209 mutex_unlock(&inode->i_mutex); 209 mutex_unlock(&inode->i_mutex);
210 210
diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c
index 2f4bc5a58054..fe2492d2a8fc 100644
--- a/fs/cifs/fscache.c
+++ b/fs/cifs/fscache.c
@@ -27,7 +27,7 @@ void cifs_fscache_get_client_cookie(struct TCP_Server_Info *server)
27{ 27{
28 server->fscache = 28 server->fscache =
29 fscache_acquire_cookie(cifs_fscache_netfs.primary_index, 29 fscache_acquire_cookie(cifs_fscache_netfs.primary_index,
30 &cifs_fscache_server_index_def, server); 30 &cifs_fscache_server_index_def, server, true);
31 cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", 31 cifs_dbg(FYI, "%s: (0x%p/0x%p)\n",
32 __func__, server, server->fscache); 32 __func__, server, server->fscache);
33} 33}
@@ -46,7 +46,7 @@ void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
46 46
47 tcon->fscache = 47 tcon->fscache =
48 fscache_acquire_cookie(server->fscache, 48 fscache_acquire_cookie(server->fscache,
49 &cifs_fscache_super_index_def, tcon); 49 &cifs_fscache_super_index_def, tcon, true);
50 cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", 50 cifs_dbg(FYI, "%s: (0x%p/0x%p)\n",
51 __func__, server->fscache, tcon->fscache); 51 __func__, server->fscache, tcon->fscache);
52} 52}
@@ -69,7 +69,7 @@ static void cifs_fscache_enable_inode_cookie(struct inode *inode)
69 69
70 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE) { 70 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE) {
71 cifsi->fscache = fscache_acquire_cookie(tcon->fscache, 71 cifsi->fscache = fscache_acquire_cookie(tcon->fscache,
72 &cifs_fscache_inode_object_def, cifsi); 72 &cifs_fscache_inode_object_def, cifsi, true);
73 cifs_dbg(FYI, "%s: got FH cookie (0x%p/0x%p)\n", 73 cifs_dbg(FYI, "%s: got FH cookie (0x%p/0x%p)\n",
74 __func__, tcon->fscache, cifsi->fscache); 74 __func__, tcon->fscache, cifsi->fscache);
75 } 75 }
@@ -119,7 +119,7 @@ void cifs_fscache_reset_inode_cookie(struct inode *inode)
119 cifsi->fscache = fscache_acquire_cookie( 119 cifsi->fscache = fscache_acquire_cookie(
120 cifs_sb_master_tcon(cifs_sb)->fscache, 120 cifs_sb_master_tcon(cifs_sb)->fscache,
121 &cifs_fscache_inode_object_def, 121 &cifs_fscache_inode_object_def,
122 cifsi); 122 cifsi, true);
123 cifs_dbg(FYI, "%s: new cookie 0x%p oldcookie 0x%p\n", 123 cifs_dbg(FYI, "%s: new cookie 0x%p oldcookie 0x%p\n",
124 __func__, cifsi->fscache, old); 124 __func__, cifsi->fscache, old);
125 } 125 }
diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c
index d851aa555d28..29d7feb62cf7 100644
--- a/fs/fscache/cookie.c
+++ b/fs/fscache/cookie.c
@@ -58,15 +58,16 @@ void fscache_cookie_init_once(void *_cookie)
58struct fscache_cookie *__fscache_acquire_cookie( 58struct fscache_cookie *__fscache_acquire_cookie(
59 struct fscache_cookie *parent, 59 struct fscache_cookie *parent,
60 const struct fscache_cookie_def *def, 60 const struct fscache_cookie_def *def,
61 void *netfs_data) 61 void *netfs_data,
62 bool enable)
62{ 63{
63 struct fscache_cookie *cookie; 64 struct fscache_cookie *cookie;
64 65
65 BUG_ON(!def); 66 BUG_ON(!def);
66 67
67 _enter("{%s},{%s},%p", 68 _enter("{%s},{%s},%p,%u",
68 parent ? (char *) parent->def->name : "<no-parent>", 69 parent ? (char *) parent->def->name : "<no-parent>",
69 def->name, netfs_data); 70 def->name, netfs_data, enable);
70 71
71 fscache_stat(&fscache_n_acquires); 72 fscache_stat(&fscache_n_acquires);
72 73
@@ -106,7 +107,7 @@ struct fscache_cookie *__fscache_acquire_cookie(
106 cookie->def = def; 107 cookie->def = def;
107 cookie->parent = parent; 108 cookie->parent = parent;
108 cookie->netfs_data = netfs_data; 109 cookie->netfs_data = netfs_data;
109 cookie->flags = 0; 110 cookie->flags = (1 << FSCACHE_COOKIE_NO_DATA_YET);
110 111
111 /* radix tree insertion won't use the preallocation pool unless it's 112 /* radix tree insertion won't use the preallocation pool unless it's
112 * told it may not wait */ 113 * told it may not wait */
@@ -124,16 +125,22 @@ struct fscache_cookie *__fscache_acquire_cookie(
124 break; 125 break;
125 } 126 }
126 127
127 /* if the object is an index then we need do nothing more here - we 128 if (enable) {
128 * create indices on disk when we need them as an index may exist in 129 /* if the object is an index then we need do nothing more here
129 * multiple caches */ 130 * - we create indices on disk when we need them as an index
130 if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) { 131 * may exist in multiple caches */
131 if (fscache_acquire_non_index_cookie(cookie) < 0) { 132 if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) {
132 atomic_dec(&parent->n_children); 133 if (fscache_acquire_non_index_cookie(cookie) == 0) {
133 __fscache_cookie_put(cookie); 134 set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
134 fscache_stat(&fscache_n_acquires_nobufs); 135 } else {
135 _leave(" = NULL"); 136 atomic_dec(&parent->n_children);
136 return NULL; 137 __fscache_cookie_put(cookie);
138 fscache_stat(&fscache_n_acquires_nobufs);
139 _leave(" = NULL");
140 return NULL;
141 }
142 } else {
143 set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
137 } 144 }
138 } 145 }
139 146
@@ -144,6 +151,39 @@ struct fscache_cookie *__fscache_acquire_cookie(
144EXPORT_SYMBOL(__fscache_acquire_cookie); 151EXPORT_SYMBOL(__fscache_acquire_cookie);
145 152
146/* 153/*
154 * Enable a cookie to permit it to accept new operations.
155 */
156void __fscache_enable_cookie(struct fscache_cookie *cookie,
157 bool (*can_enable)(void *data),
158 void *data)
159{
160 _enter("%p", cookie);
161
162 wait_on_bit_lock(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK,
163 fscache_wait_bit, TASK_UNINTERRUPTIBLE);
164
165 if (test_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags))
166 goto out_unlock;
167
168 if (can_enable && !can_enable(data)) {
169 /* The netfs decided it didn't want to enable after all */
170 } else if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) {
171 /* Wait for outstanding disablement to complete */
172 __fscache_wait_on_invalidate(cookie);
173
174 if (fscache_acquire_non_index_cookie(cookie) == 0)
175 set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
176 } else {
177 set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
178 }
179
180out_unlock:
181 clear_bit_unlock(FSCACHE_COOKIE_ENABLEMENT_LOCK, &cookie->flags);
182 wake_up_bit(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK);
183}
184EXPORT_SYMBOL(__fscache_enable_cookie);
185
186/*
147 * acquire a non-index cookie 187 * acquire a non-index cookie
148 * - this must make sure the index chain is instantiated and instantiate the 188 * - this must make sure the index chain is instantiated and instantiate the
149 * object representation too 189 * object representation too
@@ -157,7 +197,7 @@ static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie)
157 197
158 _enter(""); 198 _enter("");
159 199
160 cookie->flags = 1 << FSCACHE_COOKIE_UNAVAILABLE; 200 set_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags);
161 201
162 /* now we need to see whether the backing objects for this cookie yet 202 /* now we need to see whether the backing objects for this cookie yet
163 * exist, if not there'll be nothing to search */ 203 * exist, if not there'll be nothing to search */
@@ -180,9 +220,7 @@ static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie)
180 220
181 _debug("cache %s", cache->tag->name); 221 _debug("cache %s", cache->tag->name);
182 222
183 cookie->flags = 223 set_bit(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags);
184 (1 << FSCACHE_COOKIE_LOOKING_UP) |
185 (1 << FSCACHE_COOKIE_NO_DATA_YET);
186 224
187 /* ask the cache to allocate objects for this cookie and its parent 225 /* ask the cache to allocate objects for this cookie and its parent
188 * chain */ 226 * chain */
@@ -398,7 +436,8 @@ void __fscache_invalidate(struct fscache_cookie *cookie)
398 if (!hlist_empty(&cookie->backing_objects)) { 436 if (!hlist_empty(&cookie->backing_objects)) {
399 spin_lock(&cookie->lock); 437 spin_lock(&cookie->lock);
400 438
401 if (!hlist_empty(&cookie->backing_objects) && 439 if (fscache_cookie_enabled(cookie) &&
440 !hlist_empty(&cookie->backing_objects) &&
402 !test_and_set_bit(FSCACHE_COOKIE_INVALIDATING, 441 !test_and_set_bit(FSCACHE_COOKIE_INVALIDATING,
403 &cookie->flags)) { 442 &cookie->flags)) {
404 object = hlist_entry(cookie->backing_objects.first, 443 object = hlist_entry(cookie->backing_objects.first,
@@ -452,10 +491,14 @@ void __fscache_update_cookie(struct fscache_cookie *cookie)
452 491
453 spin_lock(&cookie->lock); 492 spin_lock(&cookie->lock);
454 493
455 /* update the index entry on disk in each cache backing this cookie */ 494 if (fscache_cookie_enabled(cookie)) {
456 hlist_for_each_entry(object, 495 /* update the index entry on disk in each cache backing this
457 &cookie->backing_objects, cookie_link) { 496 * cookie.
458 fscache_raise_event(object, FSCACHE_OBJECT_EV_UPDATE); 497 */
498 hlist_for_each_entry(object,
499 &cookie->backing_objects, cookie_link) {
500 fscache_raise_event(object, FSCACHE_OBJECT_EV_UPDATE);
501 }
459 } 502 }
460 503
461 spin_unlock(&cookie->lock); 504 spin_unlock(&cookie->lock);
@@ -464,28 +507,14 @@ void __fscache_update_cookie(struct fscache_cookie *cookie)
464EXPORT_SYMBOL(__fscache_update_cookie); 507EXPORT_SYMBOL(__fscache_update_cookie);
465 508
466/* 509/*
467 * release a cookie back to the cache 510 * Disable a cookie to stop it from accepting new requests from the netfs.
468 * - the object will be marked as recyclable on disk if retire is true
469 * - all dependents of this cookie must have already been unregistered
470 * (indices/files/pages)
471 */ 511 */
472void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire) 512void __fscache_disable_cookie(struct fscache_cookie *cookie, bool invalidate)
473{ 513{
474 struct fscache_object *object; 514 struct fscache_object *object;
515 bool awaken = false;
475 516
476 fscache_stat(&fscache_n_relinquishes); 517 _enter("%p,%u", cookie, invalidate);
477 if (retire)
478 fscache_stat(&fscache_n_relinquishes_retire);
479
480 if (!cookie) {
481 fscache_stat(&fscache_n_relinquishes_null);
482 _leave(" [no cookie]");
483 return;
484 }
485
486 _enter("%p{%s,%p,%d},%d",
487 cookie, cookie->def->name, cookie->netfs_data,
488 atomic_read(&cookie->n_active), retire);
489 518
490 ASSERTCMP(atomic_read(&cookie->n_active), >, 0); 519 ASSERTCMP(atomic_read(&cookie->n_active), >, 0);
491 520
@@ -495,24 +524,82 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
495 BUG(); 524 BUG();
496 } 525 }
497 526
498 /* No further netfs-accessing operations on this cookie permitted */ 527 wait_on_bit_lock(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK,
499 set_bit(FSCACHE_COOKIE_RELINQUISHED, &cookie->flags); 528 fscache_wait_bit, TASK_UNINTERRUPTIBLE);
500 if (retire) 529 if (!test_and_clear_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags))
501 set_bit(FSCACHE_COOKIE_RETIRED, &cookie->flags); 530 goto out_unlock_enable;
531
532 /* If the cookie is being invalidated, wait for that to complete first
533 * so that we can reuse the flag.
534 */
535 __fscache_wait_on_invalidate(cookie);
536
537 /* Dispose of the backing objects */
538 set_bit(FSCACHE_COOKIE_INVALIDATING, &cookie->flags);
502 539
503 spin_lock(&cookie->lock); 540 spin_lock(&cookie->lock);
504 hlist_for_each_entry(object, &cookie->backing_objects, cookie_link) { 541 if (!hlist_empty(&cookie->backing_objects)) {
505 fscache_raise_event(object, FSCACHE_OBJECT_EV_KILL); 542 hlist_for_each_entry(object, &cookie->backing_objects, cookie_link) {
543 if (invalidate)
544 set_bit(FSCACHE_OBJECT_RETIRED, &object->flags);
545 fscache_raise_event(object, FSCACHE_OBJECT_EV_KILL);
546 }
547 } else {
548 if (test_and_clear_bit(FSCACHE_COOKIE_INVALIDATING, &cookie->flags))
549 awaken = true;
506 } 550 }
507 spin_unlock(&cookie->lock); 551 spin_unlock(&cookie->lock);
552 if (awaken)
553 wake_up_bit(&cookie->flags, FSCACHE_COOKIE_INVALIDATING);
508 554
509 /* Wait for cessation of activity requiring access to the netfs (when 555 /* Wait for cessation of activity requiring access to the netfs (when
510 * n_active reaches 0). 556 * n_active reaches 0). This makes sure outstanding reads and writes
557 * have completed.
511 */ 558 */
512 if (!atomic_dec_and_test(&cookie->n_active)) 559 if (!atomic_dec_and_test(&cookie->n_active))
513 wait_on_atomic_t(&cookie->n_active, fscache_wait_atomic_t, 560 wait_on_atomic_t(&cookie->n_active, fscache_wait_atomic_t,
514 TASK_UNINTERRUPTIBLE); 561 TASK_UNINTERRUPTIBLE);
515 562
563 /* Reset the cookie state if it wasn't relinquished */
564 if (!test_bit(FSCACHE_COOKIE_RELINQUISHED, &cookie->flags)) {
565 atomic_inc(&cookie->n_active);
566 set_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags);
567 }
568
569out_unlock_enable:
570 clear_bit_unlock(FSCACHE_COOKIE_ENABLEMENT_LOCK, &cookie->flags);
571 wake_up_bit(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK);
572 _leave("");
573}
574EXPORT_SYMBOL(__fscache_disable_cookie);
575
576/*
577 * release a cookie back to the cache
578 * - the object will be marked as recyclable on disk if retire is true
579 * - all dependents of this cookie must have already been unregistered
580 * (indices/files/pages)
581 */
582void __fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire)
583{
584 fscache_stat(&fscache_n_relinquishes);
585 if (retire)
586 fscache_stat(&fscache_n_relinquishes_retire);
587
588 if (!cookie) {
589 fscache_stat(&fscache_n_relinquishes_null);
590 _leave(" [no cookie]");
591 return;
592 }
593
594 _enter("%p{%s,%p,%d},%d",
595 cookie, cookie->def->name, cookie->netfs_data,
596 atomic_read(&cookie->n_active), retire);
597
598 /* No further netfs-accessing operations on this cookie permitted */
599 set_bit(FSCACHE_COOKIE_RELINQUISHED, &cookie->flags);
600
601 __fscache_disable_cookie(cookie, retire);
602
516 /* Clear pointers back to the netfs */ 603 /* Clear pointers back to the netfs */
517 cookie->netfs_data = NULL; 604 cookie->netfs_data = NULL;
518 cookie->def = NULL; 605 cookie->def = NULL;
@@ -592,7 +679,8 @@ int __fscache_check_consistency(struct fscache_cookie *cookie)
592 679
593 spin_lock(&cookie->lock); 680 spin_lock(&cookie->lock);
594 681
595 if (hlist_empty(&cookie->backing_objects)) 682 if (!fscache_cookie_enabled(cookie) ||
683 hlist_empty(&cookie->backing_objects))
596 goto inconsistent; 684 goto inconsistent;
597 object = hlist_entry(cookie->backing_objects.first, 685 object = hlist_entry(cookie->backing_objects.first,
598 struct fscache_object, cookie_link); 686 struct fscache_object, cookie_link);
diff --git a/fs/fscache/fsdef.c b/fs/fscache/fsdef.c
index 10a2ade0bdf8..5a117df2a9ef 100644
--- a/fs/fscache/fsdef.c
+++ b/fs/fscache/fsdef.c
@@ -59,6 +59,7 @@ struct fscache_cookie fscache_fsdef_index = {
59 .lock = __SPIN_LOCK_UNLOCKED(fscache_fsdef_index.lock), 59 .lock = __SPIN_LOCK_UNLOCKED(fscache_fsdef_index.lock),
60 .backing_objects = HLIST_HEAD_INIT, 60 .backing_objects = HLIST_HEAD_INIT,
61 .def = &fscache_fsdef_index_def, 61 .def = &fscache_fsdef_index_def,
62 .flags = 1 << FSCACHE_COOKIE_ENABLED,
62}; 63};
63EXPORT_SYMBOL(fscache_fsdef_index); 64EXPORT_SYMBOL(fscache_fsdef_index);
64 65
diff --git a/fs/fscache/netfs.c b/fs/fscache/netfs.c
index b1bb6117473a..989f39401547 100644
--- a/fs/fscache/netfs.c
+++ b/fs/fscache/netfs.c
@@ -45,6 +45,7 @@ int __fscache_register_netfs(struct fscache_netfs *netfs)
45 netfs->primary_index->def = &fscache_fsdef_netfs_def; 45 netfs->primary_index->def = &fscache_fsdef_netfs_def;
46 netfs->primary_index->parent = &fscache_fsdef_index; 46 netfs->primary_index->parent = &fscache_fsdef_index;
47 netfs->primary_index->netfs_data = netfs; 47 netfs->primary_index->netfs_data = netfs;
48 netfs->primary_index->flags = 1 << FSCACHE_COOKIE_ENABLED;
48 49
49 atomic_inc(&netfs->primary_index->parent->usage); 50 atomic_inc(&netfs->primary_index->parent->usage);
50 atomic_inc(&netfs->primary_index->parent->n_children); 51 atomic_inc(&netfs->primary_index->parent->n_children);
diff --git a/fs/fscache/object.c b/fs/fscache/object.c
index 86d75a60b20c..dcb821617774 100644
--- a/fs/fscache/object.c
+++ b/fs/fscache/object.c
@@ -495,6 +495,7 @@ void fscache_object_lookup_negative(struct fscache_object *object)
495 * returning ENODATA. 495 * returning ENODATA.
496 */ 496 */
497 set_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags); 497 set_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags);
498 clear_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags);
498 499
499 _debug("wake up lookup %p", &cookie->flags); 500 _debug("wake up lookup %p", &cookie->flags);
500 clear_bit_unlock(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags); 501 clear_bit_unlock(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags);
@@ -527,6 +528,7 @@ void fscache_obtained_object(struct fscache_object *object)
527 528
528 /* We do (presumably) have data */ 529 /* We do (presumably) have data */
529 clear_bit_unlock(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags); 530 clear_bit_unlock(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags);
531 clear_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags);
530 532
531 /* Allow write requests to begin stacking up and read requests 533 /* Allow write requests to begin stacking up and read requests
532 * to begin shovelling data. 534 * to begin shovelling data.
@@ -679,7 +681,8 @@ static const struct fscache_state *fscache_drop_object(struct fscache_object *ob
679 */ 681 */
680 spin_lock(&cookie->lock); 682 spin_lock(&cookie->lock);
681 hlist_del_init(&object->cookie_link); 683 hlist_del_init(&object->cookie_link);
682 if (test_and_clear_bit(FSCACHE_COOKIE_INVALIDATING, &cookie->flags)) 684 if (hlist_empty(&cookie->backing_objects) &&
685 test_and_clear_bit(FSCACHE_COOKIE_INVALIDATING, &cookie->flags))
683 awaken = true; 686 awaken = true;
684 spin_unlock(&cookie->lock); 687 spin_unlock(&cookie->lock);
685 688
@@ -927,7 +930,7 @@ static const struct fscache_state *_fscache_invalidate_object(struct fscache_obj
927 */ 930 */
928 if (!fscache_use_cookie(object)) { 931 if (!fscache_use_cookie(object)) {
929 ASSERT(object->cookie->stores.rnode == NULL); 932 ASSERT(object->cookie->stores.rnode == NULL);
930 set_bit(FSCACHE_COOKIE_RETIRED, &cookie->flags); 933 set_bit(FSCACHE_OBJECT_RETIRED, &object->flags);
931 _leave(" [no cookie]"); 934 _leave(" [no cookie]");
932 return transit_to(KILL_OBJECT); 935 return transit_to(KILL_OBJECT);
933 } 936 }
diff --git a/fs/fscache/page.c b/fs/fscache/page.c
index 0fe42a6d0e9c..7f5c658af755 100644
--- a/fs/fscache/page.c
+++ b/fs/fscache/page.c
@@ -204,7 +204,8 @@ int __fscache_attr_changed(struct fscache_cookie *cookie)
204 204
205 spin_lock(&cookie->lock); 205 spin_lock(&cookie->lock);
206 206
207 if (hlist_empty(&cookie->backing_objects)) 207 if (!fscache_cookie_enabled(cookie) ||
208 hlist_empty(&cookie->backing_objects))
208 goto nobufs; 209 goto nobufs;
209 object = hlist_entry(cookie->backing_objects.first, 210 object = hlist_entry(cookie->backing_objects.first,
210 struct fscache_object, cookie_link); 211 struct fscache_object, cookie_link);
@@ -410,7 +411,7 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
410 return -ERESTARTSYS; 411 return -ERESTARTSYS;
411 412
412 op = fscache_alloc_retrieval(cookie, page->mapping, 413 op = fscache_alloc_retrieval(cookie, page->mapping,
413 end_io_func,context); 414 end_io_func, context);
414 if (!op) { 415 if (!op) {
415 _leave(" = -ENOMEM"); 416 _leave(" = -ENOMEM");
416 return -ENOMEM; 417 return -ENOMEM;
@@ -419,7 +420,8 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
419 420
420 spin_lock(&cookie->lock); 421 spin_lock(&cookie->lock);
421 422
422 if (hlist_empty(&cookie->backing_objects)) 423 if (!fscache_cookie_enabled(cookie) ||
424 hlist_empty(&cookie->backing_objects))
423 goto nobufs_unlock; 425 goto nobufs_unlock;
424 object = hlist_entry(cookie->backing_objects.first, 426 object = hlist_entry(cookie->backing_objects.first,
425 struct fscache_object, cookie_link); 427 struct fscache_object, cookie_link);
@@ -551,7 +553,8 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
551 553
552 spin_lock(&cookie->lock); 554 spin_lock(&cookie->lock);
553 555
554 if (hlist_empty(&cookie->backing_objects)) 556 if (!fscache_cookie_enabled(cookie) ||
557 hlist_empty(&cookie->backing_objects))
555 goto nobufs_unlock; 558 goto nobufs_unlock;
556 object = hlist_entry(cookie->backing_objects.first, 559 object = hlist_entry(cookie->backing_objects.first,
557 struct fscache_object, cookie_link); 560 struct fscache_object, cookie_link);
@@ -666,7 +669,8 @@ int __fscache_alloc_page(struct fscache_cookie *cookie,
666 669
667 spin_lock(&cookie->lock); 670 spin_lock(&cookie->lock);
668 671
669 if (hlist_empty(&cookie->backing_objects)) 672 if (!fscache_cookie_enabled(cookie) ||
673 hlist_empty(&cookie->backing_objects))
670 goto nobufs_unlock; 674 goto nobufs_unlock;
671 object = hlist_entry(cookie->backing_objects.first, 675 object = hlist_entry(cookie->backing_objects.first,
672 struct fscache_object, cookie_link); 676 struct fscache_object, cookie_link);
@@ -938,7 +942,8 @@ int __fscache_write_page(struct fscache_cookie *cookie,
938 ret = -ENOBUFS; 942 ret = -ENOBUFS;
939 spin_lock(&cookie->lock); 943 spin_lock(&cookie->lock);
940 944
941 if (hlist_empty(&cookie->backing_objects)) 945 if (!fscache_cookie_enabled(cookie) ||
946 hlist_empty(&cookie->backing_objects))
942 goto nobufs; 947 goto nobufs;
943 object = hlist_entry(cookie->backing_objects.first, 948 object = hlist_entry(cookie->backing_objects.first,
944 struct fscache_object, cookie_link); 949 struct fscache_object, cookie_link);
diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c
index 24d1d1c5fcaf..cd6e7efd4305 100644
--- a/fs/nfs/fscache.c
+++ b/fs/nfs/fscache.c
@@ -39,7 +39,7 @@ void nfs_fscache_get_client_cookie(struct nfs_client *clp)
39 /* create a cache index for looking up filehandles */ 39 /* create a cache index for looking up filehandles */
40 clp->fscache = fscache_acquire_cookie(nfs_fscache_netfs.primary_index, 40 clp->fscache = fscache_acquire_cookie(nfs_fscache_netfs.primary_index,
41 &nfs_fscache_server_index_def, 41 &nfs_fscache_server_index_def,
42 clp); 42 clp, true);
43 dfprintk(FSCACHE, "NFS: get client cookie (0x%p/0x%p)\n", 43 dfprintk(FSCACHE, "NFS: get client cookie (0x%p/0x%p)\n",
44 clp, clp->fscache); 44 clp, clp->fscache);
45} 45}
@@ -139,7 +139,7 @@ void nfs_fscache_get_super_cookie(struct super_block *sb, const char *uniq, int
139 /* create a cache index for looking up filehandles */ 139 /* create a cache index for looking up filehandles */
140 nfss->fscache = fscache_acquire_cookie(nfss->nfs_client->fscache, 140 nfss->fscache = fscache_acquire_cookie(nfss->nfs_client->fscache,
141 &nfs_fscache_super_index_def, 141 &nfs_fscache_super_index_def,
142 nfss); 142 nfss, true);
143 dfprintk(FSCACHE, "NFS: get superblock cookie (0x%p/0x%p)\n", 143 dfprintk(FSCACHE, "NFS: get superblock cookie (0x%p/0x%p)\n",
144 nfss, nfss->fscache); 144 nfss, nfss->fscache);
145 return; 145 return;
@@ -200,7 +200,7 @@ static void nfs_fscache_enable_inode_cookie(struct inode *inode)
200 nfsi->fscache = fscache_acquire_cookie( 200 nfsi->fscache = fscache_acquire_cookie(
201 NFS_SB(sb)->fscache, 201 NFS_SB(sb)->fscache,
202 &nfs_fscache_inode_object_def, 202 &nfs_fscache_inode_object_def,
203 nfsi); 203 nfsi, true);
204 204
205 dfprintk(FSCACHE, "NFS: get FH cookie (0x%p/0x%p/0x%p)\n", 205 dfprintk(FSCACHE, "NFS: get FH cookie (0x%p/0x%p/0x%p)\n",
206 sb, nfsi, nfsi->fscache); 206 sb, nfsi, nfsi->fscache);
@@ -327,7 +327,7 @@ void nfs_fscache_reset_inode_cookie(struct inode *inode)
327 nfsi->fscache = fscache_acquire_cookie( 327 nfsi->fscache = fscache_acquire_cookie(
328 nfss->nfs_client->fscache, 328 nfss->nfs_client->fscache,
329 &nfs_fscache_inode_object_def, 329 &nfs_fscache_inode_object_def,
330 nfsi); 330 nfsi, true);
331 331
332 dfprintk(FSCACHE, 332 dfprintk(FSCACHE,
333 "NFS: revalidation new cookie (0x%p/0x%p/0x%p/0x%p)\n", 333 "NFS: revalidation new cookie (0x%p/0x%p/0x%p/0x%p)\n",
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h
index 96a2b66f5968..771484993ca7 100644
--- a/include/linux/fscache-cache.h
+++ b/include/linux/fscache-cache.h
@@ -308,36 +308,6 @@ struct fscache_cache_ops {
308 void (*dissociate_pages)(struct fscache_cache *cache); 308 void (*dissociate_pages)(struct fscache_cache *cache);
309}; 309};
310 310
311/*
312 * data file or index object cookie
313 * - a file will only appear in one cache
314 * - a request to cache a file may or may not be honoured, subject to
315 * constraints such as disk space
316 * - indices are created on disk just-in-time
317 */
318struct fscache_cookie {
319 atomic_t usage; /* number of users of this cookie */
320 atomic_t n_children; /* number of children of this cookie */
321 atomic_t n_active; /* number of active users of netfs ptrs */
322 spinlock_t lock;
323 spinlock_t stores_lock; /* lock on page store tree */
324 struct hlist_head backing_objects; /* object(s) backing this file/index */
325 const struct fscache_cookie_def *def; /* definition */
326 struct fscache_cookie *parent; /* parent of this entry */
327 void *netfs_data; /* back pointer to netfs */
328 struct radix_tree_root stores; /* pages to be stored on this cookie */
329#define FSCACHE_COOKIE_PENDING_TAG 0 /* pages tag: pending write to cache */
330#define FSCACHE_COOKIE_STORING_TAG 1 /* pages tag: writing to cache */
331
332 unsigned long flags;
333#define FSCACHE_COOKIE_LOOKING_UP 0 /* T if non-index cookie being looked up still */
334#define FSCACHE_COOKIE_NO_DATA_YET 1 /* T if new object with no cached data yet */
335#define FSCACHE_COOKIE_UNAVAILABLE 2 /* T if cookie is unavailable (error, etc) */
336#define FSCACHE_COOKIE_INVALIDATING 3 /* T if cookie is being invalidated */
337#define FSCACHE_COOKIE_RELINQUISHED 4 /* T if cookie has been relinquished */
338#define FSCACHE_COOKIE_RETIRED 5 /* T if cookie was retired */
339};
340
341extern struct fscache_cookie fscache_fsdef_index; 311extern struct fscache_cookie fscache_fsdef_index;
342 312
343/* 313/*
@@ -400,6 +370,7 @@ struct fscache_object {
400#define FSCACHE_OBJECT_IS_LIVE 3 /* T if object is not withdrawn or relinquished */ 370#define FSCACHE_OBJECT_IS_LIVE 3 /* T if object is not withdrawn or relinquished */
401#define FSCACHE_OBJECT_IS_LOOKED_UP 4 /* T if object has been looked up */ 371#define FSCACHE_OBJECT_IS_LOOKED_UP 4 /* T if object has been looked up */
402#define FSCACHE_OBJECT_IS_AVAILABLE 5 /* T if object has become active */ 372#define FSCACHE_OBJECT_IS_AVAILABLE 5 /* T if object has become active */
373#define FSCACHE_OBJECT_RETIRED 6 /* T if object was retired on relinquishment */
403 374
404 struct list_head cache_link; /* link in cache->object_list */ 375 struct list_head cache_link; /* link in cache->object_list */
405 struct hlist_node cookie_link; /* link in cookie->backing_objects */ 376 struct hlist_node cookie_link; /* link in cookie->backing_objects */
diff --git a/include/linux/fscache.h b/include/linux/fscache.h
index 19b46458e4e8..115bb81912cc 100644
--- a/include/linux/fscache.h
+++ b/include/linux/fscache.h
@@ -167,6 +167,42 @@ struct fscache_netfs {
167}; 167};
168 168
169/* 169/*
170 * data file or index object cookie
171 * - a file will only appear in one cache
172 * - a request to cache a file may or may not be honoured, subject to
173 * constraints such as disk space
174 * - indices are created on disk just-in-time
175 */
176struct fscache_cookie {
177 atomic_t usage; /* number of users of this cookie */
178 atomic_t n_children; /* number of children of this cookie */
179 atomic_t n_active; /* number of active users of netfs ptrs */
180 spinlock_t lock;
181 spinlock_t stores_lock; /* lock on page store tree */
182 struct hlist_head backing_objects; /* object(s) backing this file/index */
183 const struct fscache_cookie_def *def; /* definition */
184 struct fscache_cookie *parent; /* parent of this entry */
185 void *netfs_data; /* back pointer to netfs */
186 struct radix_tree_root stores; /* pages to be stored on this cookie */
187#define FSCACHE_COOKIE_PENDING_TAG 0 /* pages tag: pending write to cache */
188#define FSCACHE_COOKIE_STORING_TAG 1 /* pages tag: writing to cache */
189
190 unsigned long flags;
191#define FSCACHE_COOKIE_LOOKING_UP 0 /* T if non-index cookie being looked up still */
192#define FSCACHE_COOKIE_NO_DATA_YET 1 /* T if new object with no cached data yet */
193#define FSCACHE_COOKIE_UNAVAILABLE 2 /* T if cookie is unavailable (error, etc) */
194#define FSCACHE_COOKIE_INVALIDATING 3 /* T if cookie is being invalidated */
195#define FSCACHE_COOKIE_RELINQUISHED 4 /* T if cookie has been relinquished */
196#define FSCACHE_COOKIE_ENABLED 5 /* T if cookie is enabled */
197#define FSCACHE_COOKIE_ENABLEMENT_LOCK 6 /* T if cookie is being en/disabled */
198};
199
200static inline bool fscache_cookie_enabled(struct fscache_cookie *cookie)
201{
202 return test_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
203}
204
205/*
170 * slow-path functions for when there is actually caching available, and the 206 * slow-path functions for when there is actually caching available, and the
171 * netfs does actually have a valid token 207 * netfs does actually have a valid token
172 * - these are not to be called directly 208 * - these are not to be called directly
@@ -181,8 +217,8 @@ extern void __fscache_release_cache_tag(struct fscache_cache_tag *);
181extern struct fscache_cookie *__fscache_acquire_cookie( 217extern struct fscache_cookie *__fscache_acquire_cookie(
182 struct fscache_cookie *, 218 struct fscache_cookie *,
183 const struct fscache_cookie_def *, 219 const struct fscache_cookie_def *,
184 void *); 220 void *, bool);
185extern void __fscache_relinquish_cookie(struct fscache_cookie *, int); 221extern void __fscache_relinquish_cookie(struct fscache_cookie *, bool);
186extern int __fscache_check_consistency(struct fscache_cookie *); 222extern int __fscache_check_consistency(struct fscache_cookie *);
187extern void __fscache_update_cookie(struct fscache_cookie *); 223extern void __fscache_update_cookie(struct fscache_cookie *);
188extern int __fscache_attr_changed(struct fscache_cookie *); 224extern int __fscache_attr_changed(struct fscache_cookie *);
@@ -211,6 +247,9 @@ extern void __fscache_uncache_all_inode_pages(struct fscache_cookie *,
211 struct inode *); 247 struct inode *);
212extern void __fscache_readpages_cancel(struct fscache_cookie *cookie, 248extern void __fscache_readpages_cancel(struct fscache_cookie *cookie,
213 struct list_head *pages); 249 struct list_head *pages);
250extern void __fscache_disable_cookie(struct fscache_cookie *, bool);
251extern void __fscache_enable_cookie(struct fscache_cookie *,
252 bool (*)(void *), void *);
214 253
215/** 254/**
216 * fscache_register_netfs - Register a filesystem as desiring caching services 255 * fscache_register_netfs - Register a filesystem as desiring caching services
@@ -289,6 +328,7 @@ void fscache_release_cache_tag(struct fscache_cache_tag *tag)
289 * @def: A description of the cache object, including callback operations 328 * @def: A description of the cache object, including callback operations
290 * @netfs_data: An arbitrary piece of data to be kept in the cookie to 329 * @netfs_data: An arbitrary piece of data to be kept in the cookie to
291 * represent the cache object to the netfs 330 * represent the cache object to the netfs
331 * @enable: Whether or not to enable a data cookie immediately
292 * 332 *
293 * This function is used to inform FS-Cache about part of an index hierarchy 333 * This function is used to inform FS-Cache about part of an index hierarchy
294 * that can be used to locate files. This is done by requesting a cookie for 334 * that can be used to locate files. This is done by requesting a cookie for
@@ -301,10 +341,12 @@ static inline
301struct fscache_cookie *fscache_acquire_cookie( 341struct fscache_cookie *fscache_acquire_cookie(
302 struct fscache_cookie *parent, 342 struct fscache_cookie *parent,
303 const struct fscache_cookie_def *def, 343 const struct fscache_cookie_def *def,
304 void *netfs_data) 344 void *netfs_data,
345 bool enable)
305{ 346{
306 if (fscache_cookie_valid(parent)) 347 if (fscache_cookie_valid(parent) && fscache_cookie_enabled(parent))
307 return __fscache_acquire_cookie(parent, def, netfs_data); 348 return __fscache_acquire_cookie(parent, def, netfs_data,
349 enable);
308 else 350 else
309 return NULL; 351 return NULL;
310} 352}
@@ -322,7 +364,7 @@ struct fscache_cookie *fscache_acquire_cookie(
322 * description. 364 * description.
323 */ 365 */
324static inline 366static inline
325void fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire) 367void fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire)
326{ 368{
327 if (fscache_cookie_valid(cookie)) 369 if (fscache_cookie_valid(cookie))
328 __fscache_relinquish_cookie(cookie, retire); 370 __fscache_relinquish_cookie(cookie, retire);
@@ -341,7 +383,7 @@ void fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
341static inline 383static inline
342int fscache_check_consistency(struct fscache_cookie *cookie) 384int fscache_check_consistency(struct fscache_cookie *cookie)
343{ 385{
344 if (fscache_cookie_valid(cookie)) 386 if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
345 return __fscache_check_consistency(cookie); 387 return __fscache_check_consistency(cookie);
346 else 388 else
347 return 0; 389 return 0;
@@ -360,7 +402,7 @@ int fscache_check_consistency(struct fscache_cookie *cookie)
360static inline 402static inline
361void fscache_update_cookie(struct fscache_cookie *cookie) 403void fscache_update_cookie(struct fscache_cookie *cookie)
362{ 404{
363 if (fscache_cookie_valid(cookie)) 405 if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
364 __fscache_update_cookie(cookie); 406 __fscache_update_cookie(cookie);
365} 407}
366 408
@@ -407,7 +449,7 @@ void fscache_unpin_cookie(struct fscache_cookie *cookie)
407static inline 449static inline
408int fscache_attr_changed(struct fscache_cookie *cookie) 450int fscache_attr_changed(struct fscache_cookie *cookie)
409{ 451{
410 if (fscache_cookie_valid(cookie)) 452 if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
411 return __fscache_attr_changed(cookie); 453 return __fscache_attr_changed(cookie);
412 else 454 else
413 return -ENOBUFS; 455 return -ENOBUFS;
@@ -429,7 +471,7 @@ int fscache_attr_changed(struct fscache_cookie *cookie)
429static inline 471static inline
430void fscache_invalidate(struct fscache_cookie *cookie) 472void fscache_invalidate(struct fscache_cookie *cookie)
431{ 473{
432 if (fscache_cookie_valid(cookie)) 474 if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
433 __fscache_invalidate(cookie); 475 __fscache_invalidate(cookie);
434} 476}
435 477
@@ -503,7 +545,7 @@ int fscache_read_or_alloc_page(struct fscache_cookie *cookie,
503 void *context, 545 void *context,
504 gfp_t gfp) 546 gfp_t gfp)
505{ 547{
506 if (fscache_cookie_valid(cookie)) 548 if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
507 return __fscache_read_or_alloc_page(cookie, page, end_io_func, 549 return __fscache_read_or_alloc_page(cookie, page, end_io_func,
508 context, gfp); 550 context, gfp);
509 else 551 else
@@ -554,7 +596,7 @@ int fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
554 void *context, 596 void *context,
555 gfp_t gfp) 597 gfp_t gfp)
556{ 598{
557 if (fscache_cookie_valid(cookie)) 599 if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
558 return __fscache_read_or_alloc_pages(cookie, mapping, pages, 600 return __fscache_read_or_alloc_pages(cookie, mapping, pages,
559 nr_pages, end_io_func, 601 nr_pages, end_io_func,
560 context, gfp); 602 context, gfp);
@@ -585,7 +627,7 @@ int fscache_alloc_page(struct fscache_cookie *cookie,
585 struct page *page, 627 struct page *page,
586 gfp_t gfp) 628 gfp_t gfp)
587{ 629{
588 if (fscache_cookie_valid(cookie)) 630 if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
589 return __fscache_alloc_page(cookie, page, gfp); 631 return __fscache_alloc_page(cookie, page, gfp);
590 else 632 else
591 return -ENOBUFS; 633 return -ENOBUFS;
@@ -634,7 +676,7 @@ int fscache_write_page(struct fscache_cookie *cookie,
634 struct page *page, 676 struct page *page,
635 gfp_t gfp) 677 gfp_t gfp)
636{ 678{
637 if (fscache_cookie_valid(cookie)) 679 if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
638 return __fscache_write_page(cookie, page, gfp); 680 return __fscache_write_page(cookie, page, gfp);
639 else 681 else
640 return -ENOBUFS; 682 return -ENOBUFS;
@@ -744,4 +786,47 @@ void fscache_uncache_all_inode_pages(struct fscache_cookie *cookie,
744 __fscache_uncache_all_inode_pages(cookie, inode); 786 __fscache_uncache_all_inode_pages(cookie, inode);
745} 787}
746 788
789/**
790 * fscache_disable_cookie - Disable a cookie
791 * @cookie: The cookie representing the cache object
792 * @invalidate: Invalidate the backing object
793 *
794 * Disable a cookie from accepting further alloc, read, write, invalidate,
795 * update or acquire operations. Outstanding operations can still be waited
796 * upon and pages can still be uncached and the cookie relinquished.
797 *
798 * This will not return until all outstanding operations have completed.
799 *
800 * If @invalidate is set, then the backing object will be invalidated and
801 * detached, otherwise it will just be detached.
802 */
803static inline
804void fscache_disable_cookie(struct fscache_cookie *cookie, bool invalidate)
805{
806 if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
807 __fscache_disable_cookie(cookie, invalidate);
808}
809
810/**
811 * fscache_enable_cookie - Reenable a cookie
812 * @cookie: The cookie representing the cache object
813 * @can_enable: A function to permit enablement once lock is held
814 * @data: Data for can_enable()
815 *
816 * Reenable a previously disabled cookie, allowing it to accept further alloc,
817 * read, write, invalidate, update or acquire operations. An attempt will be
818 * made to immediately reattach the cookie to a backing object.
819 *
820 * The can_enable() function is called (if not NULL) once the enablement lock
821 * is held to rule on whether enablement is still permitted to go ahead.
822 */
823static inline
824void fscache_enable_cookie(struct fscache_cookie *cookie,
825 bool (*can_enable)(void *data),
826 void *data)
827{
828 if (fscache_cookie_valid(cookie) && !fscache_cookie_enabled(cookie))
829 __fscache_enable_cookie(cookie, can_enable, data);
830}
831
747#endif /* _LINUX_FSCACHE_H */ 832#endif /* _LINUX_FSCACHE_H */