Blame view

include/linux/fscache.h 27.9 KB
2d6fff637   David Howells   FS-Cache: Add the...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
  /* General filesystem caching interface
   *
   * Copyright (C) 2004-2007 Red Hat, Inc. All Rights Reserved.
   * Written by David Howells (dhowells@redhat.com)
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License
   * as published by the Free Software Foundation; either version
   * 2 of the License, or (at your option) any later version.
   *
   * NOTE!!! See:
   *
   *	Documentation/filesystems/caching/netfs-api.txt
   *
   * for a description of the network filesystem interface declared here.
   */
  
  #ifndef _LINUX_FSCACHE_H
  #define _LINUX_FSCACHE_H
  
  #include <linux/fs.h>
  #include <linux/list.h>
  #include <linux/pagemap.h>
  #include <linux/pagevec.h>
  
  #if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
  #define fscache_available() (1)
  #define fscache_cookie_valid(cookie) (cookie)
  #else
  #define fscache_available() (0)
  #define fscache_cookie_valid(cookie) (0)
  #endif
  
  
  /*
   * overload PG_private_2 to give us PG_fscache - this is used to indicate that
   * a page is currently backed by a local disk cache
   */
  #define PageFsCache(page)		PagePrivate2((page))
  #define SetPageFsCache(page)		SetPagePrivate2((page))
  #define ClearPageFsCache(page)		ClearPagePrivate2((page))
  #define TestSetPageFsCache(page)	TestSetPagePrivate2((page))
  #define TestClearPageFsCache(page)	TestClearPagePrivate2((page))
  
  /* pattern used to fill dead space in an index entry */
  #define FSCACHE_INDEX_DEADFILL_PATTERN 0x79
  
  struct pagevec;
  struct fscache_cache_tag;
  struct fscache_cookie;
  struct fscache_netfs;
  
  typedef void (*fscache_rw_complete_t)(struct page *page,
  				      void *context,
  				      int error);
  
  /* result of index entry consultation */
  enum fscache_checkaux {
  	FSCACHE_CHECKAUX_OKAY,		/* entry okay as is */
  	FSCACHE_CHECKAUX_NEEDS_UPDATE,	/* entry requires update */
  	FSCACHE_CHECKAUX_OBSOLETE,	/* entry requires deletion */
  };
  
  /*
   * fscache cookie definition
   */
  struct fscache_cookie_def {
  	/* name of cookie type */
  	char name[16];
  
  	/* cookie type */
  	uint8_t type;
  #define FSCACHE_COOKIE_TYPE_INDEX	0
  #define FSCACHE_COOKIE_TYPE_DATAFILE	1
  
  	/* select the cache into which to insert an entry in this index
  	 * - optional
  	 * - should return a cache identifier or NULL to cause the cache to be
  	 *   inherited from the parent if possible or the first cache picked
  	 *   for a non-index file if not
  	 */
  	struct fscache_cache_tag *(*select_cache)(
  		const void *parent_netfs_data,
  		const void *cookie_netfs_data);
  
  	/* get an index key
  	 * - should store the key data in the buffer
ab0cfb928   Suresh Jayaraman   fscache: fix a tr...
88
  	 * - should return the amount of data stored
2d6fff637   David Howells   FS-Cache: Add the...
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
  	 * - not permitted to return an error
  	 * - the netfs data from the cookie being used as the source is
  	 *   presented
  	 */
  	uint16_t (*get_key)(const void *cookie_netfs_data,
  			    void *buffer,
  			    uint16_t bufmax);
  
  	/* get certain file attributes from the netfs data
  	 * - this function can be absent for an index
  	 * - not permitted to return an error
  	 * - the netfs data from the cookie being used as the source is
  	 *   presented
  	 */
  	void (*get_attr)(const void *cookie_netfs_data, uint64_t *size);
25985edce   Lucas De Marchi   Fix common misspe...
104
  	/* get the auxiliary data from netfs data
2d6fff637   David Howells   FS-Cache: Add the...
105
  	 * - this function can be absent if the index carries no state data
25985edce   Lucas De Marchi   Fix common misspe...
106
  	 * - should store the auxiliary data in the buffer
2d6fff637   David Howells   FS-Cache: Add the...
107
108
109
110
111
112
113
114
115
116
117
118
  	 * - should return the amount of amount stored
  	 * - not permitted to return an error
  	 * - the netfs data from the cookie being used as the source is
  	 *   presented
  	 */
  	uint16_t (*get_aux)(const void *cookie_netfs_data,
  			    void *buffer,
  			    uint16_t bufmax);
  
  	/* consult the netfs about the state of an object
  	 * - this function can be absent if the index carries no state data
  	 * - the netfs data from the cookie being used as the target is
25985edce   Lucas De Marchi   Fix common misspe...
119
  	 *   presented, as is the auxiliary data
2d6fff637   David Howells   FS-Cache: Add the...
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
  	 */
  	enum fscache_checkaux (*check_aux)(void *cookie_netfs_data,
  					   const void *data,
  					   uint16_t datalen);
  
  	/* get an extra reference on a read context
  	 * - this function can be absent if the completion function doesn't
  	 *   require a context
  	 */
  	void (*get_context)(void *cookie_netfs_data, void *context);
  
  	/* release an extra reference on a read context
  	 * - this function can be absent if the completion function doesn't
  	 *   require a context
  	 */
  	void (*put_context)(void *cookie_netfs_data, void *context);
c4d6d8dbf   David Howells   CacheFiles: Fix t...
136
137
138
  	/* indicate page that now have cache metadata retained
  	 * - this function should mark the specified page as now being cached
  	 * - the page will have been marked with PG_fscache before this is
2d6fff637   David Howells   FS-Cache: Add the...
139
140
  	 *   called, so this is optional
  	 */
c4d6d8dbf   David Howells   CacheFiles: Fix t...
141
142
143
  	void (*mark_page_cached)(void *cookie_netfs_data,
  				 struct address_space *mapping,
  				 struct page *page);
2d6fff637   David Howells   FS-Cache: Add the...
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
  
  	/* indicate the cookie is no longer cached
  	 * - this function is called when the backing store currently caching
  	 *   a cookie is removed
  	 * - the netfs should use this to clean up any markers indicating
  	 *   cached pages
  	 * - this is mandatory for any object that may have data
  	 */
  	void (*now_uncached)(void *cookie_netfs_data);
  };
  
  /*
   * fscache cached network filesystem type
   * - name, version and ops must be filled in before registration
   * - all other fields will be set during registration
   */
  struct fscache_netfs {
  	uint32_t			version;	/* indexing version */
  	const char			*name;		/* filesystem name */
  	struct fscache_cookie		*primary_index;
  	struct list_head		link;		/* internal link */
  };
  
  /*
94d30ae90   David Howells   FS-Cache: Provide...
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
   * data file or index object cookie
   * - a file will only appear in one cache
   * - a request to cache a file may or may not be honoured, subject to
   *   constraints such as disk space
   * - indices are created on disk just-in-time
   */
  struct fscache_cookie {
  	atomic_t			usage;		/* number of users of this cookie */
  	atomic_t			n_children;	/* number of children of this cookie */
  	atomic_t			n_active;	/* number of active users of netfs ptrs */
  	spinlock_t			lock;
  	spinlock_t			stores_lock;	/* lock on page store tree */
  	struct hlist_head		backing_objects; /* object(s) backing this file/index */
  	const struct fscache_cookie_def	*def;		/* definition */
  	struct fscache_cookie		*parent;	/* parent of this entry */
  	void				*netfs_data;	/* back pointer to netfs */
  	struct radix_tree_root		stores;		/* pages to be stored on this cookie */
  #define FSCACHE_COOKIE_PENDING_TAG	0		/* pages tag: pending write to cache */
  #define FSCACHE_COOKIE_STORING_TAG	1		/* pages tag: writing to cache */
  
  	unsigned long			flags;
  #define FSCACHE_COOKIE_LOOKING_UP	0	/* T if non-index cookie being looked up still */
  #define FSCACHE_COOKIE_NO_DATA_YET	1	/* T if new object with no cached data yet */
  #define FSCACHE_COOKIE_UNAVAILABLE	2	/* T if cookie is unavailable (error, etc) */
  #define FSCACHE_COOKIE_INVALIDATING	3	/* T if cookie is being invalidated */
  #define FSCACHE_COOKIE_RELINQUISHED	4	/* T if cookie has been relinquished */
  #define FSCACHE_COOKIE_ENABLED		5	/* T if cookie is enabled */
  #define FSCACHE_COOKIE_ENABLEMENT_LOCK	6	/* T if cookie is being en/disabled */
  };
  
  static inline bool fscache_cookie_enabled(struct fscache_cookie *cookie)
  {
  	return test_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
  }
  
  /*
2d6fff637   David Howells   FS-Cache: Add the...
204
205
206
207
208
209
   * slow-path functions for when there is actually caching available, and the
   * netfs does actually have a valid token
   * - these are not to be called directly
   * - these are undefined symbols when FS-Cache is not configured and the
   *   optimiser takes care of not using them
   */
726dd7ff1   David Howells   FS-Cache: Add net...
210
211
  extern int __fscache_register_netfs(struct fscache_netfs *);
  extern void __fscache_unregister_netfs(struct fscache_netfs *);
0e04d4cef   David Howells   FS-Cache: Add cac...
212
213
  extern struct fscache_cache_tag *__fscache_lookup_cache_tag(const char *);
  extern void __fscache_release_cache_tag(struct fscache_cache_tag *);
2d6fff637   David Howells   FS-Cache: Add the...
214

ccc4fc3d1   David Howells   FS-Cache: Impleme...
215
216
217
  extern struct fscache_cookie *__fscache_acquire_cookie(
  	struct fscache_cookie *,
  	const struct fscache_cookie_def *,
94d30ae90   David Howells   FS-Cache: Provide...
218
219
  	void *, bool);
  extern void __fscache_relinquish_cookie(struct fscache_cookie *, bool);
da9803bc8   David Howells   FS-Cache: Add int...
220
  extern int __fscache_check_consistency(struct fscache_cookie *);
ccc4fc3d1   David Howells   FS-Cache: Impleme...
221
  extern void __fscache_update_cookie(struct fscache_cookie *);
b51088228   David Howells   FS-Cache: Impleme...
222
  extern int __fscache_attr_changed(struct fscache_cookie *);
ef778e7ae   David Howells   FS-Cache: Provide...
223
224
  extern void __fscache_invalidate(struct fscache_cookie *);
  extern void __fscache_wait_on_invalidate(struct fscache_cookie *);
b51088228   David Howells   FS-Cache: Impleme...
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
  extern int __fscache_read_or_alloc_page(struct fscache_cookie *,
  					struct page *,
  					fscache_rw_complete_t,
  					void *,
  					gfp_t);
  extern int __fscache_read_or_alloc_pages(struct fscache_cookie *,
  					 struct address_space *,
  					 struct list_head *,
  					 unsigned *,
  					 fscache_rw_complete_t,
  					 void *,
  					 gfp_t);
  extern int __fscache_alloc_page(struct fscache_cookie *, struct page *, gfp_t);
  extern int __fscache_write_page(struct fscache_cookie *, struct page *, gfp_t);
  extern void __fscache_uncache_page(struct fscache_cookie *, struct page *);
  extern bool __fscache_check_page_write(struct fscache_cookie *, struct page *);
  extern void __fscache_wait_on_page_write(struct fscache_cookie *, struct page *);
201a15428   David Howells   FS-Cache: Handle ...
242
243
  extern bool __fscache_maybe_release_page(struct fscache_cookie *, struct page *,
  					 gfp_t);
c902ce1bf   David Howells   FS-Cache: Add a h...
244
245
  extern void __fscache_uncache_all_inode_pages(struct fscache_cookie *,
  					      struct inode *);
5a6f282a2   Milosz Tanski   fscache: Netfs fu...
246
247
  extern void __fscache_readpages_cancel(struct fscache_cookie *cookie,
  				       struct list_head *pages);
94d30ae90   David Howells   FS-Cache: Provide...
248
249
250
  extern void __fscache_disable_cookie(struct fscache_cookie *, bool);
  extern void __fscache_enable_cookie(struct fscache_cookie *,
  				    bool (*)(void *), void *);
ccc4fc3d1   David Howells   FS-Cache: Impleme...
251

2d6fff637   David Howells   FS-Cache: Add the...
252
253
254
255
256
257
258
259
260
261
262
263
  /**
   * fscache_register_netfs - Register a filesystem as desiring caching services
   * @netfs: The description of the filesystem
   *
   * Register a filesystem as desiring caching services if they're available.
   *
   * See Documentation/filesystems/caching/netfs-api.txt for a complete
   * description.
   */
  static inline
  int fscache_register_netfs(struct fscache_netfs *netfs)
  {
726dd7ff1   David Howells   FS-Cache: Add net...
264
265
266
267
  	if (fscache_available())
  		return __fscache_register_netfs(netfs);
  	else
  		return 0;
2d6fff637   David Howells   FS-Cache: Add the...
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
  }
  
  /**
   * fscache_unregister_netfs - Indicate that a filesystem no longer desires
   * caching services
   * @netfs: The description of the filesystem
   *
   * Indicate that a filesystem no longer desires caching services for the
   * moment.
   *
   * See Documentation/filesystems/caching/netfs-api.txt for a complete
   * description.
   */
  static inline
  void fscache_unregister_netfs(struct fscache_netfs *netfs)
  {
726dd7ff1   David Howells   FS-Cache: Add net...
284
285
  	if (fscache_available())
  		__fscache_unregister_netfs(netfs);
2d6fff637   David Howells   FS-Cache: Add the...
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
  }
  
  /**
   * fscache_lookup_cache_tag - Look up a cache tag
   * @name: The name of the tag to search for
   *
   * Acquire a specific cache referral tag that can be used to select a specific
   * cache in which to cache an index.
   *
   * See Documentation/filesystems/caching/netfs-api.txt for a complete
   * description.
   */
  static inline
  struct fscache_cache_tag *fscache_lookup_cache_tag(const char *name)
  {
0e04d4cef   David Howells   FS-Cache: Add cac...
301
302
303
304
  	if (fscache_available())
  		return __fscache_lookup_cache_tag(name);
  	else
  		return NULL;
2d6fff637   David Howells   FS-Cache: Add the...
305
306
307
308
309
310
311
312
313
314
315
316
317
318
  }
  
  /**
   * fscache_release_cache_tag - Release a cache tag
   * @tag: The tag to release
   *
   * Release a reference to a cache referral tag previously looked up.
   *
   * See Documentation/filesystems/caching/netfs-api.txt for a complete
   * description.
   */
  static inline
  void fscache_release_cache_tag(struct fscache_cache_tag *tag)
  {
0e04d4cef   David Howells   FS-Cache: Add cac...
319
320
  	if (fscache_available())
  		__fscache_release_cache_tag(tag);
2d6fff637   David Howells   FS-Cache: Add the...
321
322
323
324
325
326
327
328
  }
  
  /**
   * fscache_acquire_cookie - Acquire a cookie to represent a cache object
   * @parent: The cookie that's to be the parent of this one
   * @def: A description of the cache object, including callback operations
   * @netfs_data: An arbitrary piece of data to be kept in the cookie to
   * represent the cache object to the netfs
94d30ae90   David Howells   FS-Cache: Provide...
329
   * @enable: Whether or not to enable a data cookie immediately
2d6fff637   David Howells   FS-Cache: Add the...
330
331
332
333
334
335
336
337
338
339
340
341
   *
   * This function is used to inform FS-Cache about part of an index hierarchy
   * that can be used to locate files.  This is done by requesting a cookie for
   * each index in the path to the file.
   *
   * See Documentation/filesystems/caching/netfs-api.txt for a complete
   * description.
   */
  static inline
  struct fscache_cookie *fscache_acquire_cookie(
  	struct fscache_cookie *parent,
  	const struct fscache_cookie_def *def,
94d30ae90   David Howells   FS-Cache: Provide...
342
343
  	void *netfs_data,
  	bool enable)
2d6fff637   David Howells   FS-Cache: Add the...
344
  {
94d30ae90   David Howells   FS-Cache: Provide...
345
346
347
  	if (fscache_cookie_valid(parent) && fscache_cookie_enabled(parent))
  		return __fscache_acquire_cookie(parent, def, netfs_data,
  						enable);
ccc4fc3d1   David Howells   FS-Cache: Impleme...
348
349
  	else
  		return NULL;
2d6fff637   David Howells   FS-Cache: Add the...
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
  }
  
  /**
   * fscache_relinquish_cookie - Return the cookie to the cache, maybe discarding
   * it
   * @cookie: The cookie being returned
   * @retire: True if the cache object the cookie represents is to be discarded
   *
   * This function returns a cookie to the cache, forcibly discarding the
   * associated cache object if retire is set to true.
   *
   * See Documentation/filesystems/caching/netfs-api.txt for a complete
   * description.
   */
  static inline
94d30ae90   David Howells   FS-Cache: Provide...
365
  void fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire)
2d6fff637   David Howells   FS-Cache: Add the...
366
  {
ccc4fc3d1   David Howells   FS-Cache: Impleme...
367
368
  	if (fscache_cookie_valid(cookie))
  		__fscache_relinquish_cookie(cookie, retire);
2d6fff637   David Howells   FS-Cache: Add the...
369
370
371
  }
  
  /**
da9803bc8   David Howells   FS-Cache: Add int...
372
373
374
375
376
377
378
379
380
381
382
383
   * fscache_check_consistency - Request that if the cache is updated
   * @cookie: The cookie representing the cache object
   *
   * Request an consistency check from fscache, which passes the request
   * to the backing cache.
   *
   * Returns 0 if consistent and -ESTALE if inconsistent.  May also
   * return -ENOMEM and -ERESTARTSYS.
   */
  static inline
  int fscache_check_consistency(struct fscache_cookie *cookie)
  {
94d30ae90   David Howells   FS-Cache: Provide...
384
  	if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
da9803bc8   David Howells   FS-Cache: Add int...
385
386
387
388
389
390
  		return __fscache_check_consistency(cookie);
  	else
  		return 0;
  }
  
  /**
2d6fff637   David Howells   FS-Cache: Add the...
391
392
393
394
395
396
397
398
399
400
401
402
   * fscache_update_cookie - Request that a cache object be updated
   * @cookie: The cookie representing the cache object
   *
   * Request an update of the index data for the cache object associated with the
   * cookie.
   *
   * See Documentation/filesystems/caching/netfs-api.txt for a complete
   * description.
   */
  static inline
  void fscache_update_cookie(struct fscache_cookie *cookie)
  {
94d30ae90   David Howells   FS-Cache: Provide...
403
  	if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
ccc4fc3d1   David Howells   FS-Cache: Impleme...
404
  		__fscache_update_cookie(cookie);
2d6fff637   David Howells   FS-Cache: Add the...
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
  }
  
  /**
   * fscache_pin_cookie - Pin a data-storage cache object in its cache
   * @cookie: The cookie representing the cache object
   *
   * Permit data-storage cache objects to be pinned in the cache.
   *
   * See Documentation/filesystems/caching/netfs-api.txt for a complete
   * description.
   */
  static inline
  int fscache_pin_cookie(struct fscache_cookie *cookie)
  {
  	return -ENOBUFS;
  }
  
  /**
   * fscache_pin_cookie - Unpin a data-storage cache object in its cache
   * @cookie: The cookie representing the cache object
   *
   * Permit data-storage cache objects to be unpinned from the cache.
   *
   * See Documentation/filesystems/caching/netfs-api.txt for a complete
   * description.
   */
  static inline
  void fscache_unpin_cookie(struct fscache_cookie *cookie)
  {
  }
  
  /**
   * fscache_attr_changed - Notify cache that an object's attributes changed
   * @cookie: The cookie representing the cache object
   *
   * Send a notification to the cache indicating that an object's attributes have
   * changed.  This includes the data size.  These attributes will be obtained
   * through the get_attr() cookie definition op.
   *
   * See Documentation/filesystems/caching/netfs-api.txt for a complete
   * description.
   */
  static inline
  int fscache_attr_changed(struct fscache_cookie *cookie)
  {
94d30ae90   David Howells   FS-Cache: Provide...
450
  	if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
b51088228   David Howells   FS-Cache: Impleme...
451
452
453
  		return __fscache_attr_changed(cookie);
  	else
  		return -ENOBUFS;
2d6fff637   David Howells   FS-Cache: Add the...
454
455
456
  }
  
  /**
ef778e7ae   David Howells   FS-Cache: Provide...
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
   * fscache_invalidate - Notify cache that an object needs invalidation
   * @cookie: The cookie representing the cache object
   *
   * Notify the cache that an object is needs to be invalidated and that it
   * should abort any retrievals or stores it is doing on the cache.  The object
   * is then marked non-caching until such time as the invalidation is complete.
   *
   * This can be called with spinlocks held.
   *
   * See Documentation/filesystems/caching/netfs-api.txt for a complete
   * description.
   */
  static inline
  void fscache_invalidate(struct fscache_cookie *cookie)
  {
94d30ae90   David Howells   FS-Cache: Provide...
472
  	if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
ef778e7ae   David Howells   FS-Cache: Provide...
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
  		__fscache_invalidate(cookie);
  }
  
  /**
   * fscache_wait_on_invalidate - Wait for invalidation to complete
   * @cookie: The cookie representing the cache object
   *
   * Wait for the invalidation of an object to complete.
   *
   * See Documentation/filesystems/caching/netfs-api.txt for a complete
   * description.
   */
  static inline
  void fscache_wait_on_invalidate(struct fscache_cookie *cookie)
  {
  	if (fscache_cookie_valid(cookie))
  		__fscache_wait_on_invalidate(cookie);
  }
  
  /**
2d6fff637   David Howells   FS-Cache: Add the...
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
   * fscache_reserve_space - Reserve data space for a cached object
   * @cookie: The cookie representing the cache object
   * @i_size: The amount of space to be reserved
   *
   * Reserve an amount of space in the cache for the cache object attached to a
   * cookie so that a write to that object within the space can always be
   * honoured.
   *
   * See Documentation/filesystems/caching/netfs-api.txt for a complete
   * description.
   */
  static inline
  int fscache_reserve_space(struct fscache_cookie *cookie, loff_t size)
  {
  	return -ENOBUFS;
  }
  
  /**
   * fscache_read_or_alloc_page - Read a page from the cache or allocate a block
   * in which to store it
   * @cookie: The cookie representing the cache object
   * @page: The netfs page to fill if possible
   * @end_io_func: The callback to invoke when and if the page is filled
   * @context: An arbitrary piece of data to pass on to end_io_func()
   * @gfp: The conditions under which memory allocation should be made
   *
   * Read a page from the cache, or if that's not possible make a potential
   * one-block reservation in the cache into which the page may be stored once
   * fetched from the server.
   *
   * If the page is not backed by the cache object, or if it there's some reason
   * it can't be, -ENOBUFS will be returned and nothing more will be done for
   * that page.
   *
   * Else, if that page is backed by the cache, a read will be initiated directly
   * to the netfs's page and 0 will be returned by this function.  The
   * end_io_func() callback will be invoked when the operation terminates on a
   * completion or failure.  Note that the callback may be invoked before the
   * return.
   *
   * Else, if the page is unbacked, -ENODATA is returned and a block may have
   * been allocated in the cache.
   *
   * See Documentation/filesystems/caching/netfs-api.txt for a complete
   * description.
   */
  static inline
  int fscache_read_or_alloc_page(struct fscache_cookie *cookie,
  			       struct page *page,
  			       fscache_rw_complete_t end_io_func,
  			       void *context,
  			       gfp_t gfp)
  {
94d30ae90   David Howells   FS-Cache: Provide...
546
  	if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
b51088228   David Howells   FS-Cache: Impleme...
547
548
549
550
  		return __fscache_read_or_alloc_page(cookie, page, end_io_func,
  						    context, gfp);
  	else
  		return -ENOBUFS;
2d6fff637   David Howells   FS-Cache: Add the...
551
552
553
554
555
556
557
558
  }
  
  /**
   * fscache_read_or_alloc_pages - Read pages from the cache and/or allocate
   * blocks in which to store them
   * @cookie: The cookie representing the cache object
   * @mapping: The netfs inode mapping to which the pages will be attached
   * @pages: A list of potential netfs pages to be filled
49a3df804   Suresh Jayaraman   fscache: fix miss...
559
   * @nr_pages: Number of pages to be read and/or allocated
2d6fff637   David Howells   FS-Cache: Add the...
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
   * @end_io_func: The callback to invoke when and if each page is filled
   * @context: An arbitrary piece of data to pass on to end_io_func()
   * @gfp: The conditions under which memory allocation should be made
   *
   * Read a set of pages from the cache, or if that's not possible, attempt to
   * make a potential one-block reservation for each page in the cache into which
   * that page may be stored once fetched from the server.
   *
   * If some pages are not backed by the cache object, or if it there's some
   * reason they can't be, -ENOBUFS will be returned and nothing more will be
   * done for that pages.
   *
   * Else, if some of the pages are backed by the cache, a read will be initiated
   * directly to the netfs's page and 0 will be returned by this function.  The
   * end_io_func() callback will be invoked when the operation terminates on a
   * completion or failure.  Note that the callback may be invoked before the
   * return.
   *
   * Else, if a page is unbacked, -ENODATA is returned and a block may have
   * been allocated in the cache.
   *
   * Because the function may want to return all of -ENOBUFS, -ENODATA and 0 in
   * regard to different pages, the return values are prioritised in that order.
   * Any pages submitted for reading are removed from the pages list.
   *
   * See Documentation/filesystems/caching/netfs-api.txt for a complete
   * description.
   */
  static inline
  int fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
  				struct address_space *mapping,
  				struct list_head *pages,
  				unsigned *nr_pages,
  				fscache_rw_complete_t end_io_func,
  				void *context,
  				gfp_t gfp)
  {
94d30ae90   David Howells   FS-Cache: Provide...
597
  	if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
b51088228   David Howells   FS-Cache: Impleme...
598
599
600
601
602
  		return __fscache_read_or_alloc_pages(cookie, mapping, pages,
  						     nr_pages, end_io_func,
  						     context, gfp);
  	else
  		return -ENOBUFS;
2d6fff637   David Howells   FS-Cache: Add the...
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
  }
  
  /**
   * fscache_alloc_page - Allocate a block in which to store a page
   * @cookie: The cookie representing the cache object
   * @page: The netfs page to allocate a page for
   * @gfp: The conditions under which memory allocation should be made
   *
   * Request Allocation a block in the cache in which to store a netfs page
   * without retrieving any contents from the cache.
   *
   * If the page is not backed by a file then -ENOBUFS will be returned and
   * nothing more will be done, and no reservation will be made.
   *
   * Else, a block will be allocated if one wasn't already, and 0 will be
   * returned
   *
   * See Documentation/filesystems/caching/netfs-api.txt for a complete
   * description.
   */
  static inline
  int fscache_alloc_page(struct fscache_cookie *cookie,
  		       struct page *page,
  		       gfp_t gfp)
  {
94d30ae90   David Howells   FS-Cache: Provide...
628
  	if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
b51088228   David Howells   FS-Cache: Impleme...
629
630
631
  		return __fscache_alloc_page(cookie, page, gfp);
  	else
  		return -ENOBUFS;
2d6fff637   David Howells   FS-Cache: Add the...
632
633
634
  }
  
  /**
5a6f282a2   Milosz Tanski   fscache: Netfs fu...
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
   * fscache_readpages_cancel - Cancel read/alloc on pages
   * @cookie: The cookie representing the inode's cache object.
   * @pages: The netfs pages that we canceled write on in readpages()
   *
   * Uncache/unreserve the pages reserved earlier in readpages() via
   * fscache_readpages_or_alloc() and similar.  In most successful caches in
   * readpages() this doesn't do anything.  In cases when the underlying netfs's
   * readahead failed we need to clean up the pagelist (unmark and uncache).
   *
   * This function may sleep as it may have to clean up disk state.
   */
  static inline
  void fscache_readpages_cancel(struct fscache_cookie *cookie,
  			      struct list_head *pages)
  {
  	if (fscache_cookie_valid(cookie))
  		__fscache_readpages_cancel(cookie, pages);
  }
  
  /**
2d6fff637   David Howells   FS-Cache: Add the...
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
   * fscache_write_page - Request storage of a page in the cache
   * @cookie: The cookie representing the cache object
   * @page: The netfs page to store
   * @gfp: The conditions under which memory allocation should be made
   *
   * Request the contents of the netfs page be written into the cache.  This
   * request may be ignored if no cache block is currently allocated, in which
   * case it will return -ENOBUFS.
   *
   * If a cache block was already allocated, a write will be initiated and 0 will
   * be returned.  The PG_fscache_write page bit is set immediately and will then
   * be cleared at the completion of the write to indicate the success or failure
   * of the operation.  Note that the completion may happen before the return.
   *
   * See Documentation/filesystems/caching/netfs-api.txt for a complete
   * description.
   */
  static inline
  int fscache_write_page(struct fscache_cookie *cookie,
  		       struct page *page,
  		       gfp_t gfp)
  {
94d30ae90   David Howells   FS-Cache: Provide...
677
  	if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
b51088228   David Howells   FS-Cache: Impleme...
678
679
680
  		return __fscache_write_page(cookie, page, gfp);
  	else
  		return -ENOBUFS;
2d6fff637   David Howells   FS-Cache: Add the...
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
  }
  
  /**
   * fscache_uncache_page - Indicate that caching is no longer required on a page
   * @cookie: The cookie representing the cache object
   * @page: The netfs page that was being cached.
   *
   * Tell the cache that we no longer want a page to be cached and that it should
   * remove any knowledge of the netfs page it may have.
   *
   * Note that this cannot cancel any outstanding I/O operations between this
   * page and the cache.
   *
   * See Documentation/filesystems/caching/netfs-api.txt for a complete
   * description.
   */
  static inline
  void fscache_uncache_page(struct fscache_cookie *cookie,
  			  struct page *page)
  {
b51088228   David Howells   FS-Cache: Impleme...
701
702
  	if (fscache_cookie_valid(cookie))
  		__fscache_uncache_page(cookie, page);
2d6fff637   David Howells   FS-Cache: Add the...
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
  }
  
  /**
   * fscache_check_page_write - Ask if a page is being writing to the cache
   * @cookie: The cookie representing the cache object
   * @page: The netfs page that is being cached.
   *
   * Ask the cache if a page is being written to the cache.
   *
   * See Documentation/filesystems/caching/netfs-api.txt for a complete
   * description.
   */
  static inline
  bool fscache_check_page_write(struct fscache_cookie *cookie,
  			      struct page *page)
  {
b51088228   David Howells   FS-Cache: Impleme...
719
720
  	if (fscache_cookie_valid(cookie))
  		return __fscache_check_page_write(cookie, page);
2d6fff637   David Howells   FS-Cache: Add the...
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
  	return false;
  }
  
  /**
   * fscache_wait_on_page_write - Wait for a page to complete writing to the cache
   * @cookie: The cookie representing the cache object
   * @page: The netfs page that is being cached.
   *
   * Ask the cache to wake us up when a page is no longer being written to the
   * cache.
   *
   * See Documentation/filesystems/caching/netfs-api.txt for a complete
   * description.
   */
  static inline
  void fscache_wait_on_page_write(struct fscache_cookie *cookie,
  				struct page *page)
  {
b51088228   David Howells   FS-Cache: Impleme...
739
740
  	if (fscache_cookie_valid(cookie))
  		__fscache_wait_on_page_write(cookie, page);
2d6fff637   David Howells   FS-Cache: Add the...
741
  }
201a15428   David Howells   FS-Cache: Handle ...
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
  /**
   * fscache_maybe_release_page - Consider releasing a page, cancelling a store
   * @cookie: The cookie representing the cache object
   * @page: The netfs page that is being cached.
   * @gfp: The gfp flags passed to releasepage()
   *
   * Consider releasing a page for the vmscan algorithm, on behalf of the netfs's
   * releasepage() call.  A storage request on the page may cancelled if it is
   * not currently being processed.
   *
   * The function returns true if the page no longer has a storage request on it,
   * and false if a storage request is left in place.  If true is returned, the
   * page will have been passed to fscache_uncache_page().  If false is returned
   * the page cannot be freed yet.
   */
  static inline
  bool fscache_maybe_release_page(struct fscache_cookie *cookie,
  				struct page *page,
  				gfp_t gfp)
  {
  	if (fscache_cookie_valid(cookie) && PageFsCache(page))
  		return __fscache_maybe_release_page(cookie, page, gfp);
  	return false;
  }
c902ce1bf   David Howells   FS-Cache: Add a h...
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
  /**
   * fscache_uncache_all_inode_pages - Uncache all an inode's pages
   * @cookie: The cookie representing the inode's cache object.
   * @inode: The inode to uncache pages from.
   *
   * Uncache all the pages in an inode that are marked PG_fscache, assuming them
   * to be associated with the given cookie.
   *
   * This function may sleep.  It will wait for pages that are being written out
   * and will wait whilst the PG_fscache mark is removed by the cache.
   */
  static inline
  void fscache_uncache_all_inode_pages(struct fscache_cookie *cookie,
  				     struct inode *inode)
  {
  	if (fscache_cookie_valid(cookie))
  		__fscache_uncache_all_inode_pages(cookie, inode);
  }
94d30ae90   David Howells   FS-Cache: Provide...
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
  /**
   * fscache_disable_cookie - Disable a cookie
   * @cookie: The cookie representing the cache object
   * @invalidate: Invalidate the backing object
   *
   * Disable a cookie from accepting further alloc, read, write, invalidate,
   * update or acquire operations.  Outstanding operations can still be waited
   * upon and pages can still be uncached and the cookie relinquished.
   *
   * This will not return until all outstanding operations have completed.
   *
   * If @invalidate is set, then the backing object will be invalidated and
   * detached, otherwise it will just be detached.
   */
  static inline
  void fscache_disable_cookie(struct fscache_cookie *cookie, bool invalidate)
  {
  	if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie))
  		__fscache_disable_cookie(cookie, invalidate);
  }
  
  /**
   * fscache_enable_cookie - Reenable a cookie
   * @cookie: The cookie representing the cache object
   * @can_enable: A function to permit enablement once lock is held
   * @data: Data for can_enable()
   *
   * Reenable a previously disabled cookie, allowing it to accept further alloc,
   * read, write, invalidate, update or acquire operations.  An attempt will be
   * made to immediately reattach the cookie to a backing object.
   *
   * The can_enable() function is called (if not NULL) once the enablement lock
   * is held to rule on whether enablement is still permitted to go ahead.
   */
  static inline
  void fscache_enable_cookie(struct fscache_cookie *cookie,
  			   bool (*can_enable)(void *data),
  			   void *data)
  {
  	if (fscache_cookie_valid(cookie) && !fscache_cookie_enabled(cookie))
  		__fscache_enable_cookie(cookie, can_enable, data);
  }
2d6fff637   David Howells   FS-Cache: Add the...
826
  #endif /* _LINUX_FSCACHE_H */