The contents of read-only objects are immutable. We can cache their sha1 digests as extended attributes for the next sha1 calculation. With this patch, I can complete 'collie vdi check' of a 4 GB snapshot volume in 0.2 seconds.
Signed-off-by: MORITA Kazutaka <[email protected]> --- v3: - remove redundant old_is_readonly() check v2: - remove xattr check - move read-only check into default_get_hash() - rename get/set_sha1_cache to get/set_object_sha1 - add check of the return value of setxattr sheep/plain_store.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/sheep/plain_store.c b/sheep/plain_store.c index 3b71467..5428dbe 100644 --- a/sheep/plain_store.c +++ b/sheep/plain_store.c @@ -12,6 +12,7 @@ #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> +#include <sys/xattr.h> #include <unistd.h> #include <libgen.h> @@ -476,6 +477,42 @@ int default_remove_object(uint64_t oid) return SD_RES_SUCCESS; } +#define SHA1NAME "user.obj.sha1" + +static int get_object_sha1(uint64_t oid, uint32_t epoch, uint8_t *sha1) +{ + char path[PATH_MAX]; + + if (default_exist(oid)) + get_obj_path(oid, path); + else + get_stale_obj_path(oid, epoch, path); + + if (getxattr(path, SHA1NAME, sha1, SHA1_LEN) != SHA1_LEN) { + sd_eprintf("fail to get sha1, %s", path); + return -1; + } + + return 0; +} + +static int set_object_sha1(uint64_t oid, uint32_t epoch, const uint8_t *sha1) +{ + char path[PATH_MAX]; + int ret; + + if (default_exist(oid)) + get_obj_path(oid, path); + else + get_stale_obj_path(oid, epoch, path); + + ret = setxattr(path, SHA1NAME, sha1, SHA1_LEN, 0); + if (ret < 0) + sd_eprintf("fail to set sha1, %s", path); + + return ret; +} + int default_get_hash(uint64_t oid, uint32_t epoch, uint8_t *sha1) { int ret; @@ -484,6 +521,15 @@ int default_get_hash(uint64_t oid, uint32_t epoch, uint8_t *sha1) struct sha1_ctx c; uint64_t offset = 0; uint32_t length; + bool is_readonly_obj = oid_is_readonly(oid); + + if (is_readonly_obj) { + if (get_object_sha1(oid, epoch, sha1) == 0) { + sd_dprintf("use cached sha1 digest %s", + sha1_to_hex(sha1)); + return SD_RES_SUCCESS; + } + } length = get_objsize(oid); buf = malloc(length); @@ -512,6 +558,9 @@ int default_get_hash(uint64_t oid, uint32_t epoch, uint8_t *sha1) sd_dprintf("the message digest of %"PRIx64" at epoch %d is %s", oid, epoch, sha1_to_hex(sha1)); + if (is_readonly_obj) + set_object_sha1(oid, epoch, sha1); + return ret; } -- 1.8.1.3.566.gaa39828 -- sheepdog mailing list [email protected] http://lists.wpkg.org/mailman/listinfo/sheepdog
