CacheFiles: Implement interface to check cache consistency
Implement the FS-Cache interface to check the consistency of a cache object in CacheFiles. Original-author: Hongyi Jia <jiayisuse@gmail.com> Signed-off-by: David Howells <dhowells@redhat.com> cc: Hongyi Jia <jiayisuse@gmail.com> cc: Milosz Tanski <milosz@adfin.com>
This commit is contained in:
parent
da9803bc88
commit
5002d7bef8
3 changed files with 63 additions and 0 deletions
|
@ -377,6 +377,31 @@ static void cachefiles_sync_cache(struct fscache_cache *_cache)
|
|||
ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* check if the backing cache is updated to FS-Cache
|
||||
* - called by FS-Cache when evaluates if need to invalidate the cache
|
||||
*/
|
||||
static bool cachefiles_check_consistency(struct fscache_operation *op)
|
||||
{
|
||||
struct cachefiles_object *object;
|
||||
struct cachefiles_cache *cache;
|
||||
const struct cred *saved_cred;
|
||||
int ret;
|
||||
|
||||
_enter("{OBJ%x}", op->object->debug_id);
|
||||
|
||||
object = container_of(op->object, struct cachefiles_object, fscache);
|
||||
cache = container_of(object->fscache.cache,
|
||||
struct cachefiles_cache, cache);
|
||||
|
||||
cachefiles_begin_secure(cache, &saved_cred);
|
||||
ret = cachefiles_check_auxdata(object);
|
||||
cachefiles_end_secure(cache, saved_cred);
|
||||
|
||||
_leave(" = %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* notification the attributes on an object have changed
|
||||
* - called with reads/writes excluded by FS-Cache
|
||||
|
@ -522,4 +547,5 @@ const struct fscache_cache_ops cachefiles_cache_ops = {
|
|||
.write_page = cachefiles_write_page,
|
||||
.uncache_page = cachefiles_uncache_page,
|
||||
.dissociate_pages = cachefiles_dissociate_pages,
|
||||
.check_consistency = cachefiles_check_consistency,
|
||||
};
|
||||
|
|
|
@ -235,6 +235,7 @@ extern int cachefiles_set_object_xattr(struct cachefiles_object *object,
|
|||
struct cachefiles_xattr *auxdata);
|
||||
extern int cachefiles_update_object_xattr(struct cachefiles_object *object,
|
||||
struct cachefiles_xattr *auxdata);
|
||||
extern int cachefiles_check_auxdata(struct cachefiles_object *object);
|
||||
extern int cachefiles_check_object_xattr(struct cachefiles_object *object,
|
||||
struct cachefiles_xattr *auxdata);
|
||||
extern int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
|
||||
|
|
|
@ -156,6 +156,42 @@ int cachefiles_update_object_xattr(struct cachefiles_object *object,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* check the consistency between the backing cache and the FS-Cache cookie
|
||||
*/
|
||||
int cachefiles_check_auxdata(struct cachefiles_object *object)
|
||||
{
|
||||
struct cachefiles_xattr *auxbuf;
|
||||
struct dentry *dentry = object->dentry;
|
||||
unsigned int dlen;
|
||||
int ret;
|
||||
|
||||
ASSERT(dentry);
|
||||
ASSERT(dentry->d_inode);
|
||||
ASSERT(object->fscache.cookie->def->check_aux);
|
||||
|
||||
auxbuf = kmalloc(sizeof(struct cachefiles_xattr) + 512, GFP_KERNEL);
|
||||
if (!auxbuf)
|
||||
return -ENOMEM;
|
||||
|
||||
auxbuf->len = vfs_getxattr(dentry, cachefiles_xattr_cache,
|
||||
&auxbuf->type, 512 + 1);
|
||||
if (auxbuf->len < 1)
|
||||
return -ESTALE;
|
||||
|
||||
if (auxbuf->type != object->fscache.cookie->def->type)
|
||||
return -ESTALE;
|
||||
|
||||
dlen = auxbuf->len - 1;
|
||||
ret = fscache_check_aux(&object->fscache, &auxbuf->data, dlen);
|
||||
|
||||
kfree(auxbuf);
|
||||
if (ret != FSCACHE_CHECKAUX_OKAY)
|
||||
return -ESTALE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* check the state xattr on a cache file
|
||||
* - return -ESTALE if the object should be deleted
|
||||
|
|
Loading…
Reference in a new issue