From: Timo Sirainen Date: Wed, 4 Mar 2020 13:40:46 +0000 (+0200) Subject: lib-fs: Add fs_lookup_loaded_metadata() X-Git-Tag: 2.3.10~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4f4a9bbfaacfd5d577a240a22a4d5ca41a502a03;p=thirdparty%2Fdovecot%2Fcore.git lib-fs: Add fs_lookup_loaded_metadata() --- diff --git a/src/lib-fs/fs-api-private.h b/src/lib-fs/fs-api-private.h index 3037d0ee48..4861b4f4b8 100644 --- a/src/lib-fs/fs-api-private.h +++ b/src/lib-fs/fs-api-private.h @@ -12,7 +12,7 @@ #define FS_EVENT_FIELD_ITER "lib-fs#iter" enum fs_get_metadata_flags { - FS_GET_METADATA_FLAG_DUMMY, + FS_GET_METADATA_FLAG_LOADED_ONLY = BIT(0), }; struct fs_api_module_register { diff --git a/src/lib-fs/fs-api.c b/src/lib-fs/fs-api.c index 619c01e041..26d8690311 100644 --- a/src/lib-fs/fs-api.c +++ b/src/lib-fs/fs-api.c @@ -504,8 +504,10 @@ int fs_get_metadata_full(struct fs_file *file, } if (!file->read_or_prefetch_counted && !file->lookup_metadata_counted) { - file->lookup_metadata_counted = TRUE; - file->fs->stats.lookup_metadata_count++; + if ((flags & FS_GET_METADATA_FLAG_LOADED_ONLY) == 0) { + file->lookup_metadata_counted = TRUE; + file->fs->stats.lookup_metadata_count++; + } fs_file_timing_start(file, FS_OP_METADATA); } T_BEGIN { @@ -533,6 +535,15 @@ int fs_lookup_metadata(struct fs_file *file, const char *key, return *value_r != NULL ? 1 : 0; } +const char *fs_lookup_loaded_metadata(struct fs_file *file, const char *key) +{ + const ARRAY_TYPE(fs_metadata) *metadata; + + if (fs_get_metadata_full(file, FS_GET_METADATA_FLAG_LOADED_ONLY, &metadata) < 0) + i_panic("FS_GET_METADATA_FLAG_LOADED_ONLY lookup can't fail"); + return fs_metadata_find(metadata, key); +} + const char *fs_file_path(struct fs_file *file) { return file->fs->v.get_path == NULL ? file->path : diff --git a/src/lib-fs/fs-api.h b/src/lib-fs/fs-api.h index e5067d895d..588a3f5e9f 100644 --- a/src/lib-fs/fs-api.h +++ b/src/lib-fs/fs-api.h @@ -250,6 +250,12 @@ int fs_get_metadata(struct fs_file *file, is set, 0 if key wasn't found, -1 if error. */ int fs_lookup_metadata(struct fs_file *file, const char *key, const char **value_r); +/* Try to find key from the currently set metadata (without refreshing it). + This is typically used e.g. after writing or copying a file to find some + extra metadata they may have set. It can also be used after + fs_get_metadata() or fs_lookup_metadata() to search within the looked up + metadata. */ +const char *fs_lookup_loaded_metadata(struct fs_file *file, const char *key); /* Returns the path given to fs_open(). If file was opened with FS_OPEN_MODE_CREATE_UNIQUE_128 and the write has already finished, diff --git a/src/lib-fs/fs-metawrap.c b/src/lib-fs/fs-metawrap.c index aac904ffcd..b718f26ff9 100644 --- a/src/lib-fs/fs-metawrap.c +++ b/src/lib-fs/fs-metawrap.c @@ -176,6 +176,8 @@ fs_metawrap_get_metadata(struct fs_file *_file, if (file->metadata_read) { /* we have the metadata */ + } else if ((flags & FS_GET_METADATA_FLAG_LOADED_ONLY) != 0) { + /* use the existing metadata only */ } else if (file->input == NULL) { if (fs_read(_file, &c, 1) < 0) return -1; diff --git a/src/lib-fs/fs-test.c b/src/lib-fs/fs-test.c index a6c21d06b9..46881508ae 100644 --- a/src/lib-fs/fs-test.c +++ b/src/lib-fs/fs-test.c @@ -111,11 +111,16 @@ fs_test_set_metadata(struct fs_file *_file, const char *key, static int fs_test_get_metadata(struct fs_file *_file, - enum fs_get_metadata_flags flags ATTR_UNUSED, + enum fs_get_metadata_flags flags, const ARRAY_TYPE(fs_metadata) **metadata_r) { struct test_fs_file *file = (struct test_fs_file *)_file; + if ((flags & FS_GET_METADATA_FLAG_LOADED_ONLY) != 0) { + *metadata_r = &_file->metadata; + return 0; + } + if (file->wait_async) { fs_file_set_error_async(_file); return -1;