Mercurial > dovecot > core-2.2
changeset 20548:5f6962a5be0f
lib-fs: Added fs_get_nlinks()
Although fs_stat() could return this, its caller can't indicate whether
it actually wants the link count. Usually fs_stat() is used only to get
the file's size. In some backends it's not cheap to get the link count,
so adding this function allows the caller to explicitly ask for it.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Sat, 23 Jul 2016 12:02:29 -0400 |
parents | 879b2a660a95 |
children | c83ca52a7f65 |
files | src/lib-fs/fs-api-private.h src/lib-fs/fs-api.c src/lib-fs/fs-api.h src/lib-fs/fs-dict.c src/lib-fs/fs-metawrap.c src/lib-fs/fs-posix.c src/lib-fs/fs-randomfail.c src/lib-fs/fs-sis-queue.c src/lib-fs/fs-sis.c src/lib-fs/fs-test.c src/lib-fs/fs-wrapper.c src/lib-fs/fs-wrapper.h src/plugins/fs-compress/fs-compress.c |
diffstat | 13 files changed, 64 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-fs/fs-api-private.h Mon Jul 25 17:41:36 2016 -0400 +++ b/src/lib-fs/fs-api-private.h Sat Jul 23 12:02:29 2016 -0400 @@ -69,6 +69,7 @@ int (*iter_deinit)(struct fs_iter *iter); bool (*switch_ioloop)(struct fs *fs); + int (*get_nlinks)(struct fs_file *file, nlink_t *nlinks_r); }; struct fs {
--- a/src/lib-fs/fs-api.c Mon Jul 25 17:41:36 2016 -0400 +++ b/src/lib-fs/fs-api.c Sat Jul 23 12:02:29 2016 -0400 @@ -839,6 +839,33 @@ return ret; } +int fs_get_nlinks(struct fs_file *file, nlink_t *nlinks_r) +{ + int ret; + + if (file->fs->v.get_nlinks == NULL) { + struct stat st; + + if (fs_stat(file, &st) < 0) + return -1; + *nlinks_r = st.st_nlink; + return 0; + } + + if (!file->read_or_prefetch_counted && + !file->lookup_metadata_counted && !file->stat_counted) { + file->stat_counted = TRUE; + file->fs->stats.stat_count++; + fs_file_timing_start(file, FS_OP_STAT); + } + T_BEGIN { + ret = file->fs->v.get_nlinks(file, nlinks_r); + } T_END; + if (!(ret < 0 && errno == EAGAIN)) + fs_file_timing_end(file, FS_OP_STAT); + return ret; +} + int fs_default_copy(struct fs_file *src, struct fs_file *dest) { /* we're going to be counting this as read+write, so remove the
--- a/src/lib-fs/fs-api.h Mon Jul 25 17:41:36 2016 -0400 +++ b/src/lib-fs/fs-api.h Sat Jul 23 12:02:29 2016 -0400 @@ -304,6 +304,10 @@ /* Returns 0 if ok, -1 if error occurred (e.g. errno=ENOENT). All fs backends may not support all stat fields. */ int fs_stat(struct fs_file *file, struct stat *st_r); +/* Get number of links to the file. This is the same as using fs_stat()'s + st_nlinks field, except not all backends support returning it via fs_stat(). + Returns 0 if ok, -1 if error occurred. */ +int fs_get_nlinks(struct fs_file *file, nlink_t *nlinks_r); /* Copy an object with possibly updated metadata. Destination parent directories are created automatically. Returns 0 if ok, -1 if error occurred. */
--- a/src/lib-fs/fs-dict.c Mon Jul 25 17:41:36 2016 -0400 +++ b/src/lib-fs/fs-dict.c Sat Jul 23 12:02:29 2016 -0400 @@ -319,6 +319,7 @@ fs_dict_iter_init, fs_dict_iter_next, fs_dict_iter_deinit, + NULL, NULL } };
--- a/src/lib-fs/fs-metawrap.c Mon Jul 25 17:41:36 2016 -0400 +++ b/src/lib-fs/fs-metawrap.c Sat Jul 23 12:02:29 2016 -0400 @@ -512,6 +512,7 @@ fs_wrapper_iter_init, fs_wrapper_iter_next, fs_wrapper_iter_deinit, - NULL + NULL, + fs_wrapper_get_nlinks, } };
--- a/src/lib-fs/fs-posix.c Mon Jul 25 17:41:36 2016 -0400 +++ b/src/lib-fs/fs-posix.c Sat Jul 23 12:02:29 2016 -0400 @@ -888,6 +888,7 @@ fs_posix_iter_init, fs_posix_iter_next, fs_posix_iter_deinit, - NULL + NULL, + NULL, } };
--- a/src/lib-fs/fs-randomfail.c Mon Jul 25 17:41:36 2016 -0400 +++ b/src/lib-fs/fs-randomfail.c Sat Jul 23 12:02:29 2016 -0400 @@ -448,6 +448,17 @@ return fs_file_random_fail_end(file, ret, FS_OP_STAT); } +static int fs_randomfail_get_nlinks(struct fs_file *_file, nlink_t *nlinks_r) +{ + struct randomfail_fs_file *file = (struct randomfail_fs_file *)_file; + int ret; + + if (fs_file_random_fail_begin(file, FS_OP_STAT)) + return -1; + ret = fs_get_nlinks(file->super, nlinks_r); + return fs_file_random_fail_end(file, ret, FS_OP_STAT); +} + static int fs_randomfail_copy(struct fs_file *_src, struct fs_file *_dest) { struct randomfail_fs_file *src = (struct randomfail_fs_file *)_src; @@ -568,6 +579,7 @@ fs_randomfail_iter_init, fs_randomfail_iter_next, fs_randomfail_iter_deinit, - NULL + NULL, + fs_randomfail_get_nlinks, } };
--- a/src/lib-fs/fs-sis-queue.c Mon Jul 25 17:41:36 2016 -0400 +++ b/src/lib-fs/fs-sis-queue.c Sat Jul 23 12:02:29 2016 -0400 @@ -200,6 +200,7 @@ fs_wrapper_iter_init, NULL, NULL, - NULL + NULL, + fs_wrapper_get_nlinks, } };
--- a/src/lib-fs/fs-sis.c Mon Jul 25 17:41:36 2016 -0400 +++ b/src/lib-fs/fs-sis.c Sat Jul 23 12:02:29 2016 -0400 @@ -351,6 +351,7 @@ fs_wrapper_iter_init, NULL, NULL, - NULL + NULL, + fs_wrapper_get_nlinks, } };
--- a/src/lib-fs/fs-test.c Mon Jul 25 17:41:36 2016 -0400 +++ b/src/lib-fs/fs-test.c Sat Jul 23 12:02:29 2016 -0400 @@ -418,6 +418,7 @@ fs_test_iter_init, fs_test_iter_next, fs_test_iter_deinit, - NULL + NULL, + NULL, } };
--- a/src/lib-fs/fs-wrapper.c Mon Jul 25 17:41:36 2016 -0400 +++ b/src/lib-fs/fs-wrapper.c Sat Jul 23 12:02:29 2016 -0400 @@ -108,6 +108,11 @@ return fs_stat(file->parent, st_r); } +int fs_wrapper_get_nlinks(struct fs_file *file, nlink_t *nlinks_r) +{ + return fs_get_nlinks(file->parent, nlinks_r); +} + int fs_wrapper_copy(struct fs_file *src, struct fs_file *dest) { if (src != NULL)
--- a/src/lib-fs/fs-wrapper.h Mon Jul 25 17:41:36 2016 -0400 +++ b/src/lib-fs/fs-wrapper.h Sat Jul 23 12:02:29 2016 -0400 @@ -24,6 +24,7 @@ void fs_wrapper_unlock(struct fs_lock *_lock); int fs_wrapper_exists(struct fs_file *file); int fs_wrapper_stat(struct fs_file *file, struct stat *st_r); +int fs_wrapper_get_nlinks(struct fs_file *file, nlink_t *nlinks_r); int fs_wrapper_copy(struct fs_file *src, struct fs_file *dest); int fs_wrapper_rename(struct fs_file *src, struct fs_file *dest); int fs_wrapper_delete(struct fs_file *file);