X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=include%2Flinux%2Ffscache.h;fp=include%2Flinux%2Ffscache.h;h=867ab9e9d53f968ad1e19904c691b1240a64cc76;hb=f05f9504c50ed069377d37f02f22e7a16b5921de;hp=0000000000000000000000000000000000000000;hpb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;p=linux-2.6.git diff --git a/include/linux/fscache.h b/include/linux/fscache.h new file mode 100644 index 000000000..867ab9e9d --- /dev/null +++ b/include/linux/fscache.h @@ -0,0 +1,495 @@ +/* fscache.h: general filesystem caching interface + * + * Copyright (C) 2004-5 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 +#include +#include +#include + +struct pagevec; +struct fscache_cache_tag; +struct fscache_cookie; +struct fscache_netfs; +struct fscache_netfs_operations; + +typedef void (*fscache_rw_complete_t)(struct page *page, + void *context, + int error); + +/* result of index entry consultation */ +typedef enum { + FSCACHE_CHECKAUX_OKAY, /* entry okay as is */ + FSCACHE_CHECKAUX_NEEDS_UPDATE, /* entry requires update */ + FSCACHE_CHECKAUX_OBSOLETE, /* entry requires deletion */ +} fscache_checkaux_t; + +/*****************************************************************************/ +/* + * 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 + * - 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_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); + + /* get the auxilliary data from netfs data + * - this function can be absent if the index carries no state data + * - should store the auxilliary data in the buffer + * - 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 + * presented, as is the auxilliary data + */ + fscache_checkaux_t (*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); + + /* indicate pages that now have cache metadata retained + * - this function should mark the specified pages as now being cached + */ + void (*mark_pages_cached)(void *cookie_netfs_data, + struct address_space *mapping, + struct pagevec *cached_pvec); + + /* 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); +}; + +/* pattern used to fill dead space in an index entry */ +#define FSCACHE_INDEX_DEADFILL_PATTERN 0x79 + +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) +extern struct fscache_cookie *__fscache_acquire_cookie(struct fscache_cookie *parent, + struct fscache_cookie_def *def, + void *netfs_data); + +extern void __fscache_relinquish_cookie(struct fscache_cookie *cookie, + int retire); + +extern void __fscache_update_cookie(struct fscache_cookie *cookie); +#endif + +static inline +struct fscache_cookie *fscache_acquire_cookie(struct fscache_cookie *parent, + struct fscache_cookie_def *def, + void *netfs_data) +{ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) + if (parent) + return __fscache_acquire_cookie(parent, def, netfs_data); +#endif + return NULL; +} + +static inline +void fscache_relinquish_cookie(struct fscache_cookie *cookie, + int retire) +{ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) + if (cookie) + __fscache_relinquish_cookie(cookie, retire); +#endif +} + +static inline +void fscache_update_cookie(struct fscache_cookie *cookie) +{ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) + if (cookie) + __fscache_update_cookie(cookie); +#endif +} + +/*****************************************************************************/ +/* + * pin or unpin a cookie in a cache + * - only available for data cookies + */ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) +extern int __fscache_pin_cookie(struct fscache_cookie *cookie); +extern void __fscache_unpin_cookie(struct fscache_cookie *cookie); +#endif + +static inline +int fscache_pin_cookie(struct fscache_cookie *cookie) +{ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) + if (cookie) + return __fscache_pin_cookie(cookie); +#endif + return -ENOBUFS; +} + +static inline +void fscache_unpin_cookie(struct fscache_cookie *cookie) +{ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) + if (cookie) + __fscache_unpin_cookie(cookie); +#endif +} + +/*****************************************************************************/ +/* + * 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 fscache_netfs_operations *ops; + struct list_head link; /* internal link */ +}; + +struct fscache_netfs_operations +{ +}; + +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) +extern int __fscache_register_netfs(struct fscache_netfs *netfs); +extern void __fscache_unregister_netfs(struct fscache_netfs *netfs); +#endif + +static inline +int fscache_register_netfs(struct fscache_netfs *netfs) +{ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) + return __fscache_register_netfs(netfs); +#else + return 0; +#endif +} + +static inline +void fscache_unregister_netfs(struct fscache_netfs *netfs) +{ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) + __fscache_unregister_netfs(netfs); +#endif +} + +/*****************************************************************************/ +/* + * look up a cache tag + * - cache tags are used to select specific caches in which to cache indexes + */ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) +extern struct fscache_cache_tag *__fscache_lookup_cache_tag(const char *name); +extern void __fscache_release_cache_tag(struct fscache_cache_tag *tag); +#endif + +static inline +struct fscache_cache_tag *fscache_lookup_cache_tag(const char *name) +{ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) + return __fscache_lookup_cache_tag(name); +#else + return NULL; +#endif +} + +static inline +void fscache_release_cache_tag(struct fscache_cache_tag *tag) +{ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) + __fscache_release_cache_tag(tag); +#endif +} + +/*****************************************************************************/ +/* + * set the data size on a cached object + * - no pages beyond the end of the object will be accessible + * - returns -ENOBUFS if the file is not backed + * - returns -ENOSPC if a pinned file of that size can't be stored + * - returns 0 if okay + */ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) +extern int __fscache_set_i_size(struct fscache_cookie *cookie, loff_t i_size); +#endif + +static inline +int fscache_set_i_size(struct fscache_cookie *cookie, loff_t i_size) +{ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) + if (cookie) + return __fscache_set_i_size(cookie, i_size); +#endif + return -ENOBUFS; +} + +/*****************************************************************************/ +/* + * reserve data space for a cached object + * - returns -ENOBUFS if the file is not backed + * - returns -ENOSPC if there isn't enough space to honour the reservation + * - returns 0 if okay + */ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) +extern int __fscache_reserve_space(struct fscache_cookie *cookie, loff_t size); +#endif + +static inline +int fscache_reserve_space(struct fscache_cookie *cookie, loff_t size) +{ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) + if (cookie) + return __fscache_reserve_space(cookie, size); +#endif + return -ENOBUFS; +} + +/*****************************************************************************/ +/* + * read a page from the cache or allocate a block in which to store it + * - if the page is not backed by a file: + * - -ENOBUFS will be returned and nothing more will be done + * - else if the page is backed by a block in the cache: + * - a read will be started which will call end_io_func on completion + * - else if the page is unbacked: + * - a block will be allocated + * - -ENODATA will be returned + */ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) +extern 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); +#endif + +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) +{ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) + if (cookie) + return __fscache_read_or_alloc_page(cookie, page, end_io_func, + context, gfp); +#endif + return -ENOBUFS; +} + +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) +extern 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); +#endif + +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) +{ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) + if (cookie) + return __fscache_read_or_alloc_pages(cookie, mapping, pages, + nr_pages, end_io_func, + context, gfp); +#endif + return -ENOBUFS; +} + +/* + * allocate a block in which to store a page + * - if the page is not backed by a file: + * - -ENOBUFS will be returned and nothing more will be done + * - else + * - a block will be allocated if there isn't one + * - 0 will be returned + */ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) +extern int __fscache_alloc_page(struct fscache_cookie *cookie, + struct page *page, + gfp_t gfp); +#endif + +static inline +int fscache_alloc_page(struct fscache_cookie *cookie, + struct page *page, + gfp_t gfp) +{ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) + if (cookie) + return __fscache_alloc_page(cookie, page, gfp); +#endif + return -ENOBUFS; +} + +/* + * request a page be stored in the cache + * - this request may be ignored if no cache block is currently allocated, in + * which case it: + * - returns -ENOBUFS + * - if a cache block was already allocated: + * - a BIO will be dispatched to write the page (end_io_func will be called + * from the completion function) + * - returns 0 + */ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) +extern int __fscache_write_page(struct fscache_cookie *cookie, + struct page *page, + fscache_rw_complete_t end_io_func, + void *context, + gfp_t gfp); + +extern int __fscache_write_pages(struct fscache_cookie *cookie, + struct pagevec *pagevec, + fscache_rw_complete_t end_io_func, + void *context, + gfp_t gfp); +#endif + +static inline +int fscache_write_page(struct fscache_cookie *cookie, + struct page *page, + fscache_rw_complete_t end_io_func, + void *context, + gfp_t gfp) +{ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) + if (cookie) + return __fscache_write_page(cookie, page, end_io_func, + context, gfp); +#endif + return -ENOBUFS; +} + +static inline +int fscache_write_pages(struct fscache_cookie *cookie, + struct pagevec *pagevec, + fscache_rw_complete_t end_io_func, + void *context, + gfp_t gfp) +{ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) + if (cookie) + return __fscache_write_pages(cookie, pagevec, end_io_func, + context, gfp); +#endif + return -ENOBUFS; +} + +/* + * indicate that caching is no longer required on a page + * - note: cannot cancel any outstanding BIOs between this page and the cache + */ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) +extern void __fscache_uncache_page(struct fscache_cookie *cookie, + struct page *page); +extern void __fscache_uncache_pages(struct fscache_cookie *cookie, + struct pagevec *pagevec); +#endif + +static inline +void fscache_uncache_page(struct fscache_cookie *cookie, + struct page *page) +{ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) + if (cookie) + __fscache_uncache_page(cookie, page); +#endif +} + +static inline +void fscache_uncache_pagevec(struct fscache_cookie *cookie, + struct pagevec *pagevec) +{ +#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) + if (cookie) + __fscache_uncache_pages(cookie, pagevec); +#endif +} + +#endif /* _LINUX_FSCACHE_H */