[dovecot-cvs] dovecot/src/lib file-dotlock.c, 1.30,
1.31 file-dotlock.h, 1.11, 1.12
cras at dovecot.org
cras at dovecot.org
Sun Feb 5 14:46:09 EET 2006
Update of /var/lib/cvs/dovecot/src/lib
In directory talvi:/tmp/cvs-serv27670/lib
Modified Files:
file-dotlock.c file-dotlock.h
Log Message:
Removed immediate_stale_timeout and changed the stale_timeout behavior to
check both dotlock and the file it protects, and overwrite the lock file
whenever neither of them have been modified for stale_timeout seconds (ie.
also immediately if their timestamps are old enough).
Index: file-dotlock.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/file-dotlock.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- file-dotlock.c 13 Jan 2006 20:26:01 -0000 1.30
+++ file-dotlock.c 5 Feb 2006 12:46:07 -0000 1.31
@@ -32,22 +32,24 @@
time_t lock_time;
};
-struct lock_info {
- const struct dotlock_settings *set;
- const char *path, *lock_path, *temp_path;
- int fd;
-
+struct file_change_info {
dev_t dev;
ino_t ino;
off_t size;
time_t ctime, mtime;
+};
- off_t last_size;
- time_t last_ctime, last_mtime;
- time_t last_change;
+struct lock_info {
+ const struct dotlock_settings *set;
+ const char *path, *lock_path, *temp_path;
+ int fd;
+
+ struct file_change_info lock_info;
+ struct file_change_info file_info;
bool have_pid;
time_t last_pid_check;
+ time_t last_change;
};
static struct dotlock *
@@ -100,10 +102,33 @@
return (pid_t)strtoul(buf, NULL, 0);
}
+static bool
+update_change_info(const struct stat *st, struct file_change_info *change,
+ time_t *last_change_r, time_t now)
+{
+ if (change->ino != st->st_ino || !CMP_DEV_T(change->dev, st->st_dev) ||
+ change->ctime != st->st_ctime || change->mtime != st->st_mtime ||
+ change->size != st->st_size) {
+ time_t change_time = now;
+
+ if (change->ctime == 0) {
+ /* first check, set last_change to file's change time */
+ change_time = I_MAX(st->st_ctime, st->st_mtime);
+ }
+ if (*last_change_r < change_time)
+ *last_change_r = change_time;
+ change->ino = st->st_ino;
+ change->dev = st->st_dev;
+ change->ctime = st->st_ctime;
+ change->mtime = st->st_mtime;
+ change->size = st->st_size;
+ return TRUE;
+ }
+ return FALSE;
+}
+
static int check_lock(time_t now, struct lock_info *lock_info)
{
- time_t immediate_stale_timeout =
- lock_info->set->immediate_stale_timeout;
time_t stale_timeout = lock_info->set->stale_timeout;
struct stat st;
pid_t pid;
@@ -116,32 +141,11 @@
return 1;
}
- if (lock_info->set->immediate_stale_timeout != 0 &&
- now > st.st_mtime + immediate_stale_timeout &&
- now > st.st_ctime + immediate_stale_timeout) {
- /* old lock file */
- if (unlink(lock_info->lock_path) < 0 && errno != ENOENT) {
- i_error("unlink(%s) failed: %m", lock_info->lock_path);
- return -1;
- }
- return 1;
- }
-
- if (lock_info->ino != st.st_ino ||
- !CMP_DEV_T(lock_info->dev, st.st_dev) ||
- lock_info->ctime != st.st_ctime ||
- lock_info->mtime != st.st_mtime ||
- lock_info->size != st.st_size) {
+ if (update_change_info(&st, &lock_info->lock_info,
+ &lock_info->last_change, now)) {
/* either our first check or someone else got the lock file. */
- lock_info->dev = st.st_dev;
- lock_info->ino = st.st_ino;
- lock_info->ctime = st.st_ctime;
- lock_info->mtime = st.st_mtime;
- lock_info->size = st.st_size;
-
pid = read_local_pid(lock_info->lock_path);
lock_info->have_pid = pid != -1;
- lock_info->last_change = now;
} else if (!lock_info->have_pid) {
/* no pid checking */
pid = -1;
@@ -181,7 +185,9 @@
return 0;
}
- if (lock_info->last_change != now) {
+ if (now > lock_info->last_change + stale_timeout) {
+ /* possibly stale lock file. check also the timestamp of the
+ file we're protecting. */
if (stat(lock_info->path, &st) < 0) {
if (errno == ENOENT) {
/* file doesn't exist. treat it as if
@@ -190,13 +196,9 @@
i_error("stat(%s) failed: %m", lock_info->path);
return -1;
}
- } else if (lock_info->last_size != st.st_size ||
- lock_info->last_ctime != st.st_ctime ||
- lock_info->last_mtime != st.st_mtime) {
- lock_info->last_change = now;
- lock_info->last_size = st.st_size;
- lock_info->last_ctime = st.st_ctime;
- lock_info->last_mtime = st.st_mtime;
+ } else {
+ (void)update_change_info(&st, &lock_info->file_info,
+ &lock_info->last_change, now);
}
}
@@ -368,7 +370,6 @@
lock_info.path = path;
lock_info.set = set;
lock_info.lock_path = lock_path;
- lock_info.last_change = now;
lock_info.fd = -1;
last_notify = 0; do_wait = FALSE;
Index: file-dotlock.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/file-dotlock.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- file-dotlock.h 13 Jan 2006 20:26:01 -0000 1.11
+++ file-dotlock.h 5 Feb 2006 12:46:07 -0000 1.12
@@ -17,11 +17,9 @@
/* Abort after this many seconds. */
unsigned int timeout;
- /* If file specified in path doesn't change in stale_timeout seconds
- and it's still locked, override the lock file. */
+ /* Override the lock file when it and the file we're protecting is
+ older than stale_timeout. */
unsigned int stale_timeout;
- /* If file is older than this, override the lock immediately. */
- unsigned int immediate_stale_timeout;
/* Callback is called once in a while. stale is set to TRUE if stale
lock is detected and will be overridden in secs_left. If callback
More information about the dovecot-cvs
mailing list