dovecot-2.0: fs-sis: Fixed a race condition between comparing fi...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Oct 2 14:33:55 EEST 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/8e511be90b4b
changeset: 12235:8e511be90b4b
user: Timo Sirainen <tss at iki.fi>
date: Thu Jul 22 20:01:55 2010 +0100
description:
fs-sis: Fixed a race condition between comparing files' equality and link()ing
diffstat:
src/lib-fs/fs-sis.c | 18 +++++++++++++++++-
1 files changed, 17 insertions(+), 1 deletions(-)
diffs (35 lines):
diff -r 21ceba48445d -r 8e511be90b4b src/lib-fs/fs-sis.c
--- a/src/lib-fs/fs-sis.c Wed Jul 21 21:08:18 2010 +0100
+++ b/src/lib-fs/fs-sis.c Thu Jul 22 20:01:55 2010 +0100
@@ -168,14 +168,30 @@
static bool fs_sis_try_link(struct sis_fs_file *file)
{
const char *path = fs_file_path(&file->file);
+ const struct stat *st;
+ struct stat st2;
+
+ st = i_stream_stat(file->hash_input, FALSE);
/* we can use the existing file */
if (fs_link(file->super->fs, file->hash_path, path) < 0) {
if (errno != ENOENT && errno != EMLINK)
- i_error("%s", fs_last_error(file->super->fs));
+ i_error("fs-sis: %s", fs_last_error(file->super->fs));
/* failed to use link(), continue as if it hadn't been equal */
return FALSE;
}
+ if (fs_stat(file->super->fs, path, &st2) < 0) {
+ i_error("fs-sis: %s", fs_last_error(file->super->fs));
+ if (fs_unlink(file->super->fs, path) < 0)
+ i_error("fs-sis: %s", fs_last_error(file->super->fs));
+ return FALSE;
+ }
+ if (st->st_ino != st2.st_ino) {
+ /* the hashes/ file was already replaced with something else */
+ if (fs_unlink(file->super->fs, path) < 0)
+ i_error("fs-sis: %s", fs_last_error(file->super->fs));
+ return FALSE;
+ }
return TRUE;
}
More information about the dovecot-cvs
mailing list