257 строки
6.3 KiB
C
257 строки
6.3 KiB
C
|
/* AFS caching stuff
|
||
|
*
|
||
|
* Copyright (C) 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.
|
||
|
*/
|
||
|
|
||
|
#ifdef AFS_CACHING_SUPPORT
|
||
|
static cachefs_match_val_t afs_cell_cache_match(void *target,
|
||
|
const void *entry);
|
||
|
static void afs_cell_cache_update(void *source, void *entry);
|
||
|
|
||
|
struct cachefs_index_def afs_cache_cell_index_def = {
|
||
|
.name = "cell_ix",
|
||
|
.data_size = sizeof(struct afs_cache_cell),
|
||
|
.keys[0] = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 },
|
||
|
.match = afs_cell_cache_match,
|
||
|
.update = afs_cell_cache_update,
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* match a cell record obtained from the cache
|
||
|
*/
|
||
|
#ifdef AFS_CACHING_SUPPORT
|
||
|
static cachefs_match_val_t afs_cell_cache_match(void *target,
|
||
|
const void *entry)
|
||
|
{
|
||
|
const struct afs_cache_cell *ccell = entry;
|
||
|
struct afs_cell *cell = target;
|
||
|
|
||
|
_enter("{%s},{%s}", ccell->name, cell->name);
|
||
|
|
||
|
if (strncmp(ccell->name, cell->name, sizeof(ccell->name)) == 0) {
|
||
|
_leave(" = SUCCESS");
|
||
|
return CACHEFS_MATCH_SUCCESS;
|
||
|
}
|
||
|
|
||
|
_leave(" = FAILED");
|
||
|
return CACHEFS_MATCH_FAILED;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* update a cell record in the cache
|
||
|
*/
|
||
|
#ifdef AFS_CACHING_SUPPORT
|
||
|
static void afs_cell_cache_update(void *source, void *entry)
|
||
|
{
|
||
|
struct afs_cache_cell *ccell = entry;
|
||
|
struct afs_cell *cell = source;
|
||
|
|
||
|
_enter("%p,%p", source, entry);
|
||
|
|
||
|
strncpy(ccell->name, cell->name, sizeof(ccell->name));
|
||
|
|
||
|
memcpy(ccell->vl_servers,
|
||
|
cell->vl_addrs,
|
||
|
min(sizeof(ccell->vl_servers), sizeof(cell->vl_addrs)));
|
||
|
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifdef AFS_CACHING_SUPPORT
|
||
|
static cachefs_match_val_t afs_vlocation_cache_match(void *target,
|
||
|
const void *entry);
|
||
|
static void afs_vlocation_cache_update(void *source, void *entry);
|
||
|
|
||
|
struct cachefs_index_def afs_vlocation_cache_index_def = {
|
||
|
.name = "vldb",
|
||
|
.data_size = sizeof(struct afs_cache_vlocation),
|
||
|
.keys[0] = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 },
|
||
|
.match = afs_vlocation_cache_match,
|
||
|
.update = afs_vlocation_cache_update,
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* match a VLDB record stored in the cache
|
||
|
* - may also load target from entry
|
||
|
*/
|
||
|
#ifdef AFS_CACHING_SUPPORT
|
||
|
static cachefs_match_val_t afs_vlocation_cache_match(void *target,
|
||
|
const void *entry)
|
||
|
{
|
||
|
const struct afs_cache_vlocation *vldb = entry;
|
||
|
struct afs_vlocation *vlocation = target;
|
||
|
|
||
|
_enter("{%s},{%s}", vlocation->vldb.name, vldb->name);
|
||
|
|
||
|
if (strncmp(vlocation->vldb.name, vldb->name, sizeof(vldb->name)) == 0
|
||
|
) {
|
||
|
if (!vlocation->valid ||
|
||
|
vlocation->vldb.rtime == vldb->rtime
|
||
|
) {
|
||
|
vlocation->vldb = *vldb;
|
||
|
vlocation->valid = 1;
|
||
|
_leave(" = SUCCESS [c->m]");
|
||
|
return CACHEFS_MATCH_SUCCESS;
|
||
|
} else if (memcmp(&vlocation->vldb, vldb, sizeof(*vldb)) != 0) {
|
||
|
/* delete if VIDs for this name differ */
|
||
|
if (memcmp(&vlocation->vldb.vid,
|
||
|
&vldb->vid,
|
||
|
sizeof(vldb->vid)) != 0) {
|
||
|
_leave(" = DELETE");
|
||
|
return CACHEFS_MATCH_SUCCESS_DELETE;
|
||
|
}
|
||
|
|
||
|
_leave(" = UPDATE");
|
||
|
return CACHEFS_MATCH_SUCCESS_UPDATE;
|
||
|
} else {
|
||
|
_leave(" = SUCCESS");
|
||
|
return CACHEFS_MATCH_SUCCESS;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
_leave(" = FAILED");
|
||
|
return CACHEFS_MATCH_FAILED;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* update a VLDB record stored in the cache
|
||
|
*/
|
||
|
#ifdef AFS_CACHING_SUPPORT
|
||
|
static void afs_vlocation_cache_update(void *source, void *entry)
|
||
|
{
|
||
|
struct afs_cache_vlocation *vldb = entry;
|
||
|
struct afs_vlocation *vlocation = source;
|
||
|
|
||
|
_enter("");
|
||
|
|
||
|
*vldb = vlocation->vldb;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifdef AFS_CACHING_SUPPORT
|
||
|
static cachefs_match_val_t afs_volume_cache_match(void *target,
|
||
|
const void *entry);
|
||
|
static void afs_volume_cache_update(void *source, void *entry);
|
||
|
|
||
|
struct cachefs_index_def afs_volume_cache_index_def = {
|
||
|
.name = "volume",
|
||
|
.data_size = sizeof(struct afs_cache_vhash),
|
||
|
.keys[0] = { CACHEFS_INDEX_KEYS_BIN, 1 },
|
||
|
.keys[1] = { CACHEFS_INDEX_KEYS_BIN, 1 },
|
||
|
.match = afs_volume_cache_match,
|
||
|
.update = afs_volume_cache_update,
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* match a volume hash record stored in the cache
|
||
|
*/
|
||
|
#ifdef AFS_CACHING_SUPPORT
|
||
|
static cachefs_match_val_t afs_volume_cache_match(void *target,
|
||
|
const void *entry)
|
||
|
{
|
||
|
const struct afs_cache_vhash *vhash = entry;
|
||
|
struct afs_volume *volume = target;
|
||
|
|
||
|
_enter("{%u},{%u}", volume->type, vhash->vtype);
|
||
|
|
||
|
if (volume->type == vhash->vtype) {
|
||
|
_leave(" = SUCCESS");
|
||
|
return CACHEFS_MATCH_SUCCESS;
|
||
|
}
|
||
|
|
||
|
_leave(" = FAILED");
|
||
|
return CACHEFS_MATCH_FAILED;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* update a volume hash record stored in the cache
|
||
|
*/
|
||
|
#ifdef AFS_CACHING_SUPPORT
|
||
|
static void afs_volume_cache_update(void *source, void *entry)
|
||
|
{
|
||
|
struct afs_cache_vhash *vhash = entry;
|
||
|
struct afs_volume *volume = source;
|
||
|
|
||
|
_enter("");
|
||
|
|
||
|
vhash->vtype = volume->type;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifdef AFS_CACHING_SUPPORT
|
||
|
static cachefs_match_val_t afs_vnode_cache_match(void *target,
|
||
|
const void *entry);
|
||
|
static void afs_vnode_cache_update(void *source, void *entry);
|
||
|
|
||
|
struct cachefs_index_def afs_vnode_cache_index_def = {
|
||
|
.name = "vnode",
|
||
|
.data_size = sizeof(struct afs_cache_vnode),
|
||
|
.keys[0] = { CACHEFS_INDEX_KEYS_BIN, 4 },
|
||
|
.match = afs_vnode_cache_match,
|
||
|
.update = afs_vnode_cache_update,
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* match a vnode record stored in the cache
|
||
|
*/
|
||
|
#ifdef AFS_CACHING_SUPPORT
|
||
|
static cachefs_match_val_t afs_vnode_cache_match(void *target,
|
||
|
const void *entry)
|
||
|
{
|
||
|
const struct afs_cache_vnode *cvnode = entry;
|
||
|
struct afs_vnode *vnode = target;
|
||
|
|
||
|
_enter("{%x,%x,%Lx},{%x,%x,%Lx}",
|
||
|
vnode->fid.vnode,
|
||
|
vnode->fid.unique,
|
||
|
vnode->status.version,
|
||
|
cvnode->vnode_id,
|
||
|
cvnode->vnode_unique,
|
||
|
cvnode->data_version);
|
||
|
|
||
|
if (vnode->fid.vnode != cvnode->vnode_id) {
|
||
|
_leave(" = FAILED");
|
||
|
return CACHEFS_MATCH_FAILED;
|
||
|
}
|
||
|
|
||
|
if (vnode->fid.unique != cvnode->vnode_unique ||
|
||
|
vnode->status.version != cvnode->data_version) {
|
||
|
_leave(" = DELETE");
|
||
|
return CACHEFS_MATCH_SUCCESS_DELETE;
|
||
|
}
|
||
|
|
||
|
_leave(" = SUCCESS");
|
||
|
return CACHEFS_MATCH_SUCCESS;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* update a vnode record stored in the cache
|
||
|
*/
|
||
|
#ifdef AFS_CACHING_SUPPORT
|
||
|
static void afs_vnode_cache_update(void *source, void *entry)
|
||
|
{
|
||
|
struct afs_cache_vnode *cvnode = entry;
|
||
|
struct afs_vnode *vnode = source;
|
||
|
|
||
|
_enter("");
|
||
|
|
||
|
cvnode->vnode_id = vnode->fid.vnode;
|
||
|
cvnode->vnode_unique = vnode->fid.unique;
|
||
|
cvnode->data_version = vnode->status.version;
|
||
|
}
|
||
|
#endif
|