You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
FS-Cache: Make kAFS use FS-Cache
The attached patch makes the kAFS filesystem in fs/afs/ use FS-Cache, and through it any attached caches. The kAFS filesystem will use caching automatically if it's available. Signed-off-by: David Howells <dhowells@redhat.com> Acked-by: Steve Dickson <steved@redhat.com> Acked-by: Trond Myklebust <Trond.Myklebust@netapp.com> Acked-by: Al Viro <viro@zeniv.linux.org.uk> Tested-by: Daire Byrne <Daire.Byrne@framestore.com>
This commit is contained in:
@@ -19,3 +19,11 @@ config AFS_DEBUG
|
||||
See <file:Documentation/filesystems/afs.txt> for more information.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config AFS_FSCACHE
|
||||
bool "Provide AFS client caching support (EXPERIMENTAL)"
|
||||
depends on EXPERIMENTAL
|
||||
depends on AFS_FS=m && FSCACHE || AFS_FS=y && FSCACHE=y
|
||||
help
|
||||
Say Y here if you want AFS data to be cached locally on disk through
|
||||
the generic filesystem cache manager
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
# Makefile for Red Hat Linux AFS client.
|
||||
#
|
||||
|
||||
afs-cache-$(CONFIG_AFS_FSCACHE) := cache.o
|
||||
|
||||
kafs-objs := \
|
||||
$(afs-cache-y) \
|
||||
callback.o \
|
||||
cell.o \
|
||||
cmservice.o \
|
||||
|
||||
+348
-201
File diff suppressed because it is too large
Load Diff
+2
-13
@@ -1,6 +1,6 @@
|
||||
/* AFS local cache management interface
|
||||
*
|
||||
* Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
|
||||
* Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
|
||||
* Written by David Howells (dhowells@redhat.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -9,15 +9,4 @@
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef AFS_CACHE_H
|
||||
#define AFS_CACHE_H
|
||||
|
||||
#undef AFS_CACHING_SUPPORT
|
||||
|
||||
#include <linux/mm.h>
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
#include <linux/cachefs.h>
|
||||
#endif
|
||||
#include "types.h"
|
||||
|
||||
#endif /* AFS_CACHE_H */
|
||||
#include <linux/fscache.h>
|
||||
|
||||
+7
-9
@@ -147,12 +147,11 @@ struct afs_cell *afs_cell_create(const char *name, char *vllist)
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
/* put it up for caching */
|
||||
cachefs_acquire_cookie(afs_cache_netfs.primary_index,
|
||||
&afs_vlocation_cache_index_def,
|
||||
cell,
|
||||
&cell->cache);
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
/* put it up for caching (this never returns an error) */
|
||||
cell->cache = fscache_acquire_cookie(afs_cache_netfs.primary_index,
|
||||
&afs_cell_cache_index_def,
|
||||
cell);
|
||||
#endif
|
||||
|
||||
/* add to the cell lists */
|
||||
@@ -362,10 +361,9 @@ static void afs_cell_destroy(struct afs_cell *cell)
|
||||
list_del_init(&cell->proc_link);
|
||||
up_write(&afs_proc_cells_sem);
|
||||
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
cachefs_relinquish_cookie(cell->cache, 0);
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
fscache_relinquish_cookie(cell->cache, 0);
|
||||
#endif
|
||||
|
||||
key_put(cell->anonymous_key);
|
||||
kfree(cell);
|
||||
|
||||
|
||||
+144
-78
@@ -23,6 +23,9 @@ static void afs_invalidatepage(struct page *page, unsigned long offset);
|
||||
static int afs_releasepage(struct page *page, gfp_t gfp_flags);
|
||||
static int afs_launder_page(struct page *page);
|
||||
|
||||
static int afs_readpages(struct file *filp, struct address_space *mapping,
|
||||
struct list_head *pages, unsigned nr_pages);
|
||||
|
||||
const struct file_operations afs_file_operations = {
|
||||
.open = afs_open,
|
||||
.release = afs_release,
|
||||
@@ -46,6 +49,7 @@ const struct inode_operations afs_file_inode_operations = {
|
||||
|
||||
const struct address_space_operations afs_fs_aops = {
|
||||
.readpage = afs_readpage,
|
||||
.readpages = afs_readpages,
|
||||
.set_page_dirty = afs_set_page_dirty,
|
||||
.launder_page = afs_launder_page,
|
||||
.releasepage = afs_releasepage,
|
||||
@@ -101,37 +105,18 @@ int afs_release(struct inode *inode, struct file *file)
|
||||
/*
|
||||
* deal with notification that a page was read from the cache
|
||||
*/
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
static void afs_readpage_read_complete(void *cookie_data,
|
||||
struct page *page,
|
||||
void *data,
|
||||
int error)
|
||||
static void afs_file_readpage_read_complete(struct page *page,
|
||||
void *data,
|
||||
int error)
|
||||
{
|
||||
_enter("%p,%p,%p,%d", cookie_data, page, data, error);
|
||||
_enter("%p,%p,%d", page, data, error);
|
||||
|
||||
if (error)
|
||||
SetPageError(page);
|
||||
else
|
||||
/* if the read completes with an error, we just unlock the page and let
|
||||
* the VM reissue the readpage */
|
||||
if (!error)
|
||||
SetPageUptodate(page);
|
||||
unlock_page(page);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* deal with notification that a page was written to the cache
|
||||
*/
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
static void afs_readpage_write_complete(void *cookie_data,
|
||||
struct page *page,
|
||||
void *data,
|
||||
int error)
|
||||
{
|
||||
_enter("%p,%p,%p,%d", cookie_data, page, data, error);
|
||||
|
||||
unlock_page(page);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AFS read page from file, directory or symlink
|
||||
@@ -161,9 +146,9 @@ static int afs_readpage(struct file *file, struct page *page)
|
||||
if (test_bit(AFS_VNODE_DELETED, &vnode->flags))
|
||||
goto error;
|
||||
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
/* is it cached? */
|
||||
ret = cachefs_read_or_alloc_page(vnode->cache,
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
ret = fscache_read_or_alloc_page(vnode->cache,
|
||||
page,
|
||||
afs_file_readpage_read_complete,
|
||||
NULL,
|
||||
@@ -171,20 +156,21 @@ static int afs_readpage(struct file *file, struct page *page)
|
||||
#else
|
||||
ret = -ENOBUFS;
|
||||
#endif
|
||||
|
||||
switch (ret) {
|
||||
/* read BIO submitted and wb-journal entry found */
|
||||
case 1:
|
||||
BUG(); // TODO - handle wb-journal match
|
||||
|
||||
/* read BIO submitted (page in cache) */
|
||||
case 0:
|
||||
break;
|
||||
|
||||
/* no page available in cache */
|
||||
case -ENOBUFS:
|
||||
/* page not yet cached */
|
||||
case -ENODATA:
|
||||
_debug("cache said ENODATA");
|
||||
goto go_on;
|
||||
|
||||
/* page will not be cached */
|
||||
case -ENOBUFS:
|
||||
_debug("cache said ENOBUFS");
|
||||
default:
|
||||
go_on:
|
||||
offset = page->index << PAGE_CACHE_SHIFT;
|
||||
len = min_t(size_t, i_size_read(inode) - offset, PAGE_SIZE);
|
||||
|
||||
@@ -198,27 +184,25 @@ static int afs_readpage(struct file *file, struct page *page)
|
||||
set_bit(AFS_VNODE_DELETED, &vnode->flags);
|
||||
ret = -ESTALE;
|
||||
}
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
cachefs_uncache_page(vnode->cache, page);
|
||||
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
fscache_uncache_page(vnode->cache, page);
|
||||
#endif
|
||||
BUG_ON(PageFsCache(page));
|
||||
goto error;
|
||||
}
|
||||
|
||||
SetPageUptodate(page);
|
||||
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
if (cachefs_write_page(vnode->cache,
|
||||
page,
|
||||
afs_file_readpage_write_complete,
|
||||
NULL,
|
||||
GFP_KERNEL) != 0
|
||||
) {
|
||||
cachefs_uncache_page(vnode->cache, page);
|
||||
unlock_page(page);
|
||||
/* send the page to the cache */
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
if (PageFsCache(page) &&
|
||||
fscache_write_page(vnode->cache, page, GFP_KERNEL) != 0) {
|
||||
fscache_uncache_page(vnode->cache, page);
|
||||
BUG_ON(PageFsCache(page));
|
||||
}
|
||||
#else
|
||||
unlock_page(page);
|
||||
#endif
|
||||
unlock_page(page);
|
||||
}
|
||||
|
||||
_leave(" = 0");
|
||||
@@ -232,34 +216,59 @@ error:
|
||||
}
|
||||
|
||||
/*
|
||||
* invalidate part or all of a page
|
||||
* read a set of pages
|
||||
*/
|
||||
static void afs_invalidatepage(struct page *page, unsigned long offset)
|
||||
static int afs_readpages(struct file *file, struct address_space *mapping,
|
||||
struct list_head *pages, unsigned nr_pages)
|
||||
{
|
||||
int ret = 1;
|
||||
struct afs_vnode *vnode;
|
||||
int ret = 0;
|
||||
|
||||
_enter("{%lu},%lu", page->index, offset);
|
||||
_enter(",{%lu},,%d", mapping->host->i_ino, nr_pages);
|
||||
|
||||
BUG_ON(!PageLocked(page));
|
||||
|
||||
if (PagePrivate(page)) {
|
||||
/* We release buffers only if the entire page is being
|
||||
* invalidated.
|
||||
* The get_block cached value has been unconditionally
|
||||
* invalidated, so real IO is not possible anymore.
|
||||
*/
|
||||
if (offset == 0) {
|
||||
BUG_ON(!PageLocked(page));
|
||||
|
||||
ret = 0;
|
||||
if (!PageWriteback(page))
|
||||
ret = page->mapping->a_ops->releasepage(page,
|
||||
0);
|
||||
/* possibly should BUG_ON(!ret); - neilb */
|
||||
}
|
||||
vnode = AFS_FS_I(mapping->host);
|
||||
if (vnode->flags & AFS_VNODE_DELETED) {
|
||||
_leave(" = -ESTALE");
|
||||
return -ESTALE;
|
||||
}
|
||||
|
||||
_leave(" = %d", ret);
|
||||
/* attempt to read as many of the pages as possible */
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
ret = fscache_read_or_alloc_pages(vnode->cache,
|
||||
mapping,
|
||||
pages,
|
||||
&nr_pages,
|
||||
afs_file_readpage_read_complete,
|
||||
NULL,
|
||||
mapping_gfp_mask(mapping));
|
||||
#else
|
||||
ret = -ENOBUFS;
|
||||
#endif
|
||||
|
||||
switch (ret) {
|
||||
/* all pages are being read from the cache */
|
||||
case 0:
|
||||
BUG_ON(!list_empty(pages));
|
||||
BUG_ON(nr_pages != 0);
|
||||
_leave(" = 0 [reading all]");
|
||||
return 0;
|
||||
|
||||
/* there were pages that couldn't be read from the cache */
|
||||
case -ENODATA:
|
||||
case -ENOBUFS:
|
||||
break;
|
||||
|
||||
/* other error */
|
||||
default:
|
||||
_leave(" = %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* load the missing pages from the network */
|
||||
ret = read_cache_pages(mapping, pages, (void *) afs_readpage, file);
|
||||
|
||||
_leave(" = %d [netting]", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -273,25 +282,82 @@ static int afs_launder_page(struct page *page)
|
||||
}
|
||||
|
||||
/*
|
||||
* release a page and cleanup its private data
|
||||
* invalidate part or all of a page
|
||||
* - release a page and clean up its private data if offset is 0 (indicating
|
||||
* the entire page)
|
||||
*/
|
||||
static void afs_invalidatepage(struct page *page, unsigned long offset)
|
||||
{
|
||||
struct afs_writeback *wb = (struct afs_writeback *) page_private(page);
|
||||
|
||||
_enter("{%lu},%lu", page->index, offset);
|
||||
|
||||
BUG_ON(!PageLocked(page));
|
||||
|
||||
/* we clean up only if the entire page is being invalidated */
|
||||
if (offset == 0) {
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
if (PageFsCache(page)) {
|
||||
struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
|
||||
fscache_wait_on_page_write(vnode->cache, page);
|
||||
fscache_uncache_page(vnode->cache, page);
|
||||
ClearPageFsCache(page);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (PagePrivate(page)) {
|
||||
if (wb && !PageWriteback(page)) {
|
||||
set_page_private(page, 0);
|
||||
afs_put_writeback(wb);
|
||||
}
|
||||
|
||||
if (!page_private(page))
|
||||
ClearPagePrivate(page);
|
||||
}
|
||||
}
|
||||
|
||||
_leave("");
|
||||
}
|
||||
|
||||
/*
|
||||
* release a page and clean up its private state if it's not busy
|
||||
* - return true if the page can now be released, false if not
|
||||
*/
|
||||
static int afs_releasepage(struct page *page, gfp_t gfp_flags)
|
||||
{
|
||||
struct afs_writeback *wb = (struct afs_writeback *) page_private(page);
|
||||
struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
|
||||
struct afs_writeback *wb;
|
||||
|
||||
_enter("{{%x:%u}[%lu],%lx},%x",
|
||||
vnode->fid.vid, vnode->fid.vnode, page->index, page->flags,
|
||||
gfp_flags);
|
||||
|
||||
/* deny if page is being written to the cache and the caller hasn't
|
||||
* elected to wait */
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
if (PageFsCache(page)) {
|
||||
if (fscache_check_page_write(vnode->cache, page)) {
|
||||
if (!(gfp_flags & __GFP_WAIT)) {
|
||||
_leave(" = F [cache busy]");
|
||||
return 0;
|
||||
}
|
||||
fscache_wait_on_page_write(vnode->cache, page);
|
||||
}
|
||||
|
||||
fscache_uncache_page(vnode->cache, page);
|
||||
ClearPageFsCache(page);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (PagePrivate(page)) {
|
||||
wb = (struct afs_writeback *) page_private(page);
|
||||
ASSERT(wb != NULL);
|
||||
set_page_private(page, 0);
|
||||
if (wb) {
|
||||
set_page_private(page, 0);
|
||||
afs_put_writeback(wb);
|
||||
}
|
||||
ClearPagePrivate(page);
|
||||
afs_put_writeback(wb);
|
||||
}
|
||||
|
||||
_leave(" = 0");
|
||||
return 0;
|
||||
/* indicate that the page can be released */
|
||||
_leave(" = T");
|
||||
return 1;
|
||||
}
|
||||
|
||||
+20
-11
@@ -61,6 +61,11 @@ static int afs_inode_map_status(struct afs_vnode *vnode, struct key *key)
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
if (vnode->status.size != inode->i_size)
|
||||
fscache_attr_changed(vnode->cache);
|
||||
#endif
|
||||
|
||||
inode->i_nlink = vnode->status.nlink;
|
||||
inode->i_uid = vnode->status.owner;
|
||||
inode->i_gid = 0;
|
||||
@@ -149,15 +154,6 @@ struct inode *afs_iget(struct super_block *sb, struct key *key,
|
||||
return inode;
|
||||
}
|
||||
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
/* set up caching before reading the status, as fetch-status reads the
|
||||
* first page of symlinks to see if they're really mntpts */
|
||||
cachefs_acquire_cookie(vnode->volume->cache,
|
||||
NULL,
|
||||
vnode,
|
||||
&vnode->cache);
|
||||
#endif
|
||||
|
||||
if (!status) {
|
||||
/* it's a remotely extant inode */
|
||||
set_bit(AFS_VNODE_CB_BROKEN, &vnode->flags);
|
||||
@@ -183,6 +179,15 @@ struct inode *afs_iget(struct super_block *sb, struct key *key,
|
||||
}
|
||||
}
|
||||
|
||||
/* set up caching before mapping the status, as map-status reads the
|
||||
* first page of symlinks to see if they're really mountpoints */
|
||||
inode->i_size = vnode->status.size;
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
vnode->cache = fscache_acquire_cookie(vnode->volume->cache,
|
||||
&afs_vnode_cache_index_def,
|
||||
vnode);
|
||||
#endif
|
||||
|
||||
ret = afs_inode_map_status(vnode, key);
|
||||
if (ret < 0)
|
||||
goto bad_inode;
|
||||
@@ -196,6 +201,10 @@ struct inode *afs_iget(struct super_block *sb, struct key *key,
|
||||
|
||||
/* failure */
|
||||
bad_inode:
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
fscache_relinquish_cookie(vnode->cache, 0);
|
||||
vnode->cache = NULL;
|
||||
#endif
|
||||
iget_failed(inode);
|
||||
_leave(" = %d [bad]", ret);
|
||||
return ERR_PTR(ret);
|
||||
@@ -340,8 +349,8 @@ void afs_clear_inode(struct inode *inode)
|
||||
ASSERT(list_empty(&vnode->writebacks));
|
||||
ASSERT(!vnode->cb_promised);
|
||||
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
cachefs_relinquish_cookie(vnode->cache, 0);
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
fscache_relinquish_cookie(vnode->cache, 0);
|
||||
vnode->cache = NULL;
|
||||
#endif
|
||||
|
||||
|
||||
+25
-28
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "afs.h"
|
||||
#include "afs_vl.h"
|
||||
#include "cache.h"
|
||||
|
||||
#define AFS_CELL_MAX_ADDRS 15
|
||||
|
||||
@@ -193,8 +194,8 @@ struct afs_cell {
|
||||
struct key *anonymous_key; /* anonymous user key for this cell */
|
||||
struct list_head proc_link; /* /proc cell list link */
|
||||
struct proc_dir_entry *proc_dir; /* /proc dir for this cell */
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
struct cachefs_cookie *cache; /* caching cookie */
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
struct fscache_cookie *cache; /* caching cookie */
|
||||
#endif
|
||||
|
||||
/* server record management */
|
||||
@@ -249,8 +250,8 @@ struct afs_vlocation {
|
||||
struct list_head grave; /* link in master graveyard list */
|
||||
struct list_head update; /* link in master update list */
|
||||
struct afs_cell *cell; /* cell to which volume belongs */
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
struct cachefs_cookie *cache; /* caching cookie */
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
struct fscache_cookie *cache; /* caching cookie */
|
||||
#endif
|
||||
struct afs_cache_vlocation vldb; /* volume information DB record */
|
||||
struct afs_volume *vols[3]; /* volume access record pointer (index by type) */
|
||||
@@ -302,8 +303,8 @@ struct afs_volume {
|
||||
atomic_t usage;
|
||||
struct afs_cell *cell; /* cell to which belongs (unrefd ptr) */
|
||||
struct afs_vlocation *vlocation; /* volume location */
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
struct cachefs_cookie *cache; /* caching cookie */
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
struct fscache_cookie *cache; /* caching cookie */
|
||||
#endif
|
||||
afs_volid_t vid; /* volume ID */
|
||||
afs_voltype_t type; /* type of volume */
|
||||
@@ -333,8 +334,8 @@ struct afs_vnode {
|
||||
struct afs_server *server; /* server currently supplying this file */
|
||||
struct afs_fid fid; /* the file identifier for this inode */
|
||||
struct afs_file_status status; /* AFS status info for this file */
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
struct cachefs_cookie *cache; /* caching cookie */
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
struct fscache_cookie *cache; /* caching cookie */
|
||||
#endif
|
||||
struct afs_permits *permits; /* cache of permits so far obtained */
|
||||
struct mutex permits_lock; /* lock for altering permits list */
|
||||
@@ -427,6 +428,22 @@ struct afs_uuid {
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
* cache.c
|
||||
*/
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
extern struct fscache_netfs afs_cache_netfs;
|
||||
extern struct fscache_cookie_def afs_cell_cache_index_def;
|
||||
extern struct fscache_cookie_def afs_vlocation_cache_index_def;
|
||||
extern struct fscache_cookie_def afs_volume_cache_index_def;
|
||||
extern struct fscache_cookie_def afs_vnode_cache_index_def;
|
||||
#else
|
||||
#define afs_cell_cache_index_def (*(struct fscache_cookie_def *) NULL)
|
||||
#define afs_vlocation_cache_index_def (*(struct fscache_cookie_def *) NULL)
|
||||
#define afs_volume_cache_index_def (*(struct fscache_cookie_def *) NULL)
|
||||
#define afs_vnode_cache_index_def (*(struct fscache_cookie_def *) NULL)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* callback.c
|
||||
*/
|
||||
@@ -446,9 +463,6 @@ extern void afs_callback_update_kill(void);
|
||||
*/
|
||||
extern struct rw_semaphore afs_proc_cells_sem;
|
||||
extern struct list_head afs_proc_cells;
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
extern struct cachefs_index_def afs_cache_cell_index_def;
|
||||
#endif
|
||||
|
||||
#define afs_get_cell(C) do { atomic_inc(&(C)->usage); } while(0)
|
||||
extern int afs_cell_init(char *);
|
||||
@@ -554,9 +568,6 @@ extern void afs_clear_inode(struct inode *);
|
||||
* main.c
|
||||
*/
|
||||
extern struct afs_uuid afs_uuid;
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
extern struct cachefs_netfs afs_cache_netfs;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* misc.c
|
||||
@@ -637,10 +648,6 @@ extern int afs_get_MAC_address(u8 *, size_t);
|
||||
/*
|
||||
* vlclient.c
|
||||
*/
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
extern struct cachefs_index_def afs_vlocation_cache_index_def;
|
||||
#endif
|
||||
|
||||
extern int afs_vl_get_entry_by_name(struct in_addr *, struct key *,
|
||||
const char *, struct afs_cache_vlocation *,
|
||||
const struct afs_wait_mode *);
|
||||
@@ -664,12 +671,6 @@ extern void afs_vlocation_purge(void);
|
||||
/*
|
||||
* vnode.c
|
||||
*/
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
extern struct cachefs_index_def afs_vnode_cache_index_def;
|
||||
#endif
|
||||
|
||||
extern struct afs_timer_ops afs_vnode_cb_timed_out_ops;
|
||||
|
||||
static inline struct afs_vnode *AFS_FS_I(struct inode *inode)
|
||||
{
|
||||
return container_of(inode, struct afs_vnode, vfs_inode);
|
||||
@@ -711,10 +712,6 @@ extern int afs_vnode_release_lock(struct afs_vnode *, struct key *);
|
||||
/*
|
||||
* volume.c
|
||||
*/
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
extern struct cachefs_index_def afs_volume_cache_index_def;
|
||||
#endif
|
||||
|
||||
#define afs_get_volume(V) do { atomic_inc(&(V)->usage); } while(0)
|
||||
|
||||
extern void afs_put_volume(struct afs_volume *);
|
||||
|
||||
+7
-20
@@ -1,6 +1,6 @@
|
||||
/* AFS client file system
|
||||
*
|
||||
* Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
|
||||
* Copyright (C) 2002,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
|
||||
@@ -29,18 +29,6 @@ static char *rootcell;
|
||||
module_param(rootcell, charp, 0);
|
||||
MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list");
|
||||
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
static struct cachefs_netfs_operations afs_cache_ops = {
|
||||
.get_page_cookie = afs_cache_get_page_cookie,
|
||||
};
|
||||
|
||||
struct cachefs_netfs afs_cache_netfs = {
|
||||
.name = "afs",
|
||||
.version = 0,
|
||||
.ops = &afs_cache_ops,
|
||||
};
|
||||
#endif
|
||||
|
||||
struct afs_uuid afs_uuid;
|
||||
|
||||
/*
|
||||
@@ -104,10 +92,9 @@ static int __init afs_init(void)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
/* we want to be able to cache */
|
||||
ret = cachefs_register_netfs(&afs_cache_netfs,
|
||||
&afs_cache_cell_index_def);
|
||||
ret = fscache_register_netfs(&afs_cache_netfs);
|
||||
if (ret < 0)
|
||||
goto error_cache;
|
||||
#endif
|
||||
@@ -142,8 +129,8 @@ error_fs:
|
||||
error_open_socket:
|
||||
error_vl_update_init:
|
||||
error_cell_init:
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
cachefs_unregister_netfs(&afs_cache_netfs);
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
fscache_unregister_netfs(&afs_cache_netfs);
|
||||
error_cache:
|
||||
#endif
|
||||
afs_callback_update_kill();
|
||||
@@ -175,8 +162,8 @@ static void __exit afs_exit(void)
|
||||
afs_vlocation_purge();
|
||||
flush_scheduled_work();
|
||||
afs_cell_purge();
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
cachefs_unregister_netfs(&afs_cache_netfs);
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
fscache_unregister_netfs(&afs_cache_netfs);
|
||||
#endif
|
||||
afs_proc_cleanup();
|
||||
rcu_barrier();
|
||||
|
||||
+2
-2
@@ -173,9 +173,9 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
|
||||
if (PageError(page))
|
||||
goto error;
|
||||
|
||||
buf = kmap(page);
|
||||
buf = kmap_atomic(page, KM_USER0);
|
||||
memcpy(devname, buf, size);
|
||||
kunmap(page);
|
||||
kunmap_atomic(buf, KM_USER0);
|
||||
page_cache_release(page);
|
||||
page = NULL;
|
||||
|
||||
|
||||
+13
-12
@@ -281,9 +281,8 @@ static void afs_vlocation_apply_update(struct afs_vlocation *vl,
|
||||
|
||||
vl->vldb = *vldb;
|
||||
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
/* update volume entry in local cache */
|
||||
cachefs_update_cookie(vl->cache);
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
fscache_update_cookie(vl->cache);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -304,11 +303,9 @@ static int afs_vlocation_fill_in_record(struct afs_vlocation *vl,
|
||||
memset(&vldb, 0, sizeof(vldb));
|
||||
|
||||
/* see if we have an in-cache copy (will set vl->valid if there is) */
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
cachefs_acquire_cookie(cell->cache,
|
||||
&afs_volume_cache_index_def,
|
||||
vlocation,
|
||||
&vl->cache);
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
vl->cache = fscache_acquire_cookie(vl->cell->cache,
|
||||
&afs_vlocation_cache_index_def, vl);
|
||||
#endif
|
||||
|
||||
if (vl->valid) {
|
||||
@@ -420,6 +417,11 @@ fill_in_record:
|
||||
spin_unlock(&vl->lock);
|
||||
wake_up(&vl->waitq);
|
||||
|
||||
/* update volume entry in local cache */
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
fscache_update_cookie(vl->cache);
|
||||
#endif
|
||||
|
||||
/* schedule for regular updates */
|
||||
afs_vlocation_queue_for_updates(vl);
|
||||
goto success;
|
||||
@@ -465,7 +467,7 @@ found_in_memory:
|
||||
spin_unlock(&vl->lock);
|
||||
|
||||
success:
|
||||
_leave(" = %p",vl);
|
||||
_leave(" = %p", vl);
|
||||
return vl;
|
||||
|
||||
error_abandon:
|
||||
@@ -523,10 +525,9 @@ static void afs_vlocation_destroy(struct afs_vlocation *vl)
|
||||
{
|
||||
_enter("%p", vl);
|
||||
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
cachefs_relinquish_cookie(vl->cache, 0);
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
fscache_relinquish_cookie(vl->cache, 0);
|
||||
#endif
|
||||
|
||||
afs_put_cell(vl->cell);
|
||||
kfree(vl);
|
||||
}
|
||||
|
||||
+6
-8
@@ -124,13 +124,11 @@ struct afs_volume *afs_volume_lookup(struct afs_mount_params *params)
|
||||
}
|
||||
|
||||
/* attach the cache and volume location */
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
cachefs_acquire_cookie(vlocation->cache,
|
||||
&afs_vnode_cache_index_def,
|
||||
volume,
|
||||
&volume->cache);
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
volume->cache = fscache_acquire_cookie(vlocation->cache,
|
||||
&afs_volume_cache_index_def,
|
||||
volume);
|
||||
#endif
|
||||
|
||||
afs_get_vlocation(vlocation);
|
||||
volume->vlocation = vlocation;
|
||||
|
||||
@@ -194,8 +192,8 @@ void afs_put_volume(struct afs_volume *volume)
|
||||
up_write(&vlocation->cell->vl_sem);
|
||||
|
||||
/* finish cleaning up the volume */
|
||||
#ifdef AFS_CACHING_SUPPORT
|
||||
cachefs_relinquish_cookie(volume->cache, 0);
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
fscache_relinquish_cookie(volume->cache, 0);
|
||||
#endif
|
||||
afs_put_vlocation(vlocation);
|
||||
|
||||
|
||||
@@ -780,3 +780,24 @@ int afs_fsync(struct file *file, struct dentry *dentry, int datasync)
|
||||
_leave(" = %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* notification that a previously read-only page is about to become writable
|
||||
* - if it returns an error, the caller will deliver a bus error signal
|
||||
*/
|
||||
int afs_page_mkwrite(struct vm_area_struct *vma, struct page *page)
|
||||
{
|
||||
struct afs_vnode *vnode = AFS_FS_I(vma->vm_file->f_mapping->host);
|
||||
|
||||
_enter("{{%x:%u}},{%lx}",
|
||||
vnode->fid.vid, vnode->fid.vnode, page->index);
|
||||
|
||||
/* wait for the page to be written to the cache before we allow it to
|
||||
* be modified */
|
||||
#ifdef CONFIG_AFS_FSCACHE
|
||||
fscache_wait_on_page_write(vnode->cache, page);
|
||||
#endif
|
||||
|
||||
_leave(" = 0");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user