CacheFiles: Implement interface to check cache consistency
authorDavid Howells <dhowells@redhat.com>
Wed, 21 Aug 2013 21:29:21 +0000 (17:29 -0400)
committerDavid Howells <dhowells@redhat.com>
Fri, 6 Sep 2013 08:17:30 +0000 (09:17 +0100)
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>

fs/cachefiles/interface.c
fs/cachefiles/internal.h
fs/cachefiles/xattr.c

index d4c1206af9fca6009a7591a8d36b36684043bf52..43eb5592cdea83c83df854a489edea79d076cfda 100644 (file)
@@ -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,
 };
index 49382519907a28ec7addc1f3a6257871cba9a025..5349473df1b1ff5b900f5eca7a8b1786669b5b0c 100644 (file)
@@ -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,
index 2476e5162609ffc4db6be49549e27999e288f06f..34c88b83e39f1214b0ed7f2c22bc58f5acd00fa4 100644 (file)
@@ -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