[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[lvm-devel] [PATCH] DRAFT! write lock priority



Hi,

I am attaching a draft version of the write lock priority patch. Other than
running the testsuite, it is completely untested. I am running away for about
an hour now, I'll read it through again when I'm back and see what can be done
about testing, too.

Yours,
   Petr.

diff -rN -u -p old-upstream/lib/config/defaults.h new-upstream/lib/config/defaults.h
--- old-upstream/lib/config/defaults.h	2009-08-12 09:37:36.000000000 +0200
+++ new-upstream/lib/config/defaults.h	2009-08-12 09:37:36.000000000 +0200
@@ -42,6 +42,7 @@
 #define DEFAULT_FALLBACK_TO_LOCAL_LOCKING 1
 #define DEFAULT_FALLBACK_TO_CLUSTERED_LOCKING 1
 #define DEFAULT_WAIT_FOR_LOCKS 1
+#define DEFAULT_WRITE_LOCK_PRIORITY 1
 
 #define DEFAULT_MIRRORLOG "disk"
 #define DEFAULT_MIRROR_LOG_FAULT_POLICY "allocate"
diff -rN -u -p old-upstream/lib/locking/file_locking.c new-upstream/lib/locking/file_locking.c
--- old-upstream/lib/locking/file_locking.c	2009-08-12 09:37:36.000000000 +0200
+++ new-upstream/lib/locking/file_locking.c	2009-08-12 09:37:36.000000000 +0200
@@ -38,18 +38,33 @@ struct lock_list {
 
 static struct dm_list _lock_list;
 static char _lock_dir[NAME_LEN];
+static int _write_priority;
 
 static sig_t _oldhandler;
 static sigset_t _fullsigset, _intsigset;
 static volatile sig_atomic_t _handler_installed;
 
+static void _unflock(const char *file, int fd)
+{
+	struct stat buf1, buf2;
+
+	if (!flock(fd, LOCK_NB | LOCK_EX) &&
+	    !stat(file, &buf1) &&
+	    !fstat(fd, &buf2) &&
+	    is_same_inode(buf1, buf2))
+		if (unlink(file))
+			log_sys_error("unlink", file);
+
+	if (close(fd) < 0)
+		log_sys_error("close", file);
+}
+
+
 static int _release_lock(const char *file, int unlock)
 {
 	struct lock_list *ll;
 	struct dm_list *llh, *llt;
 
-	struct stat buf1, buf2;
-
 	dm_list_iterate_safe(llh, llt, &_lock_list) {
 		ll = dm_list_item(llh, struct lock_list);
 
@@ -61,16 +76,7 @@ static int _release_lock(const char *fil
 					log_sys_error("flock", ll->res);
 			}
 
-			if (!flock(ll->lf, LOCK_NB | LOCK_EX) &&
-			    !stat(ll->res, &buf1) &&
-			    !fstat(ll->lf, &buf2) &&
-			    is_same_inode(buf1, buf2))
-				if (unlink(ll->res))
-					log_sys_error("unlink", ll->res);
-
-			if (close(ll->lf) < 0)
-				log_sys_error("close", ll->res);
-
+			_unflock(ll->res, ll->lf);
 			dm_free(ll->res);
 			dm_free(llh);
 
@@ -124,15 +130,62 @@ static void _install_ctrl_c_handler()
 	siginterrupt(SIGINT, 1);
 }
 
-static int _lock_file(const char *file, uint32_t flags)
+static int _flock(const char *file, int *fd, int operation, int nonblock)
 {
-	int operation;
 	int r = 1;
 	int old_errno;
+	struct stat buf1, buf2;
+
+	do {
+		if ((*fd > -1) && close(*fd))
+			log_sys_error("close", file);
+
+		if ((*fd = open(file, O_CREAT | O_APPEND | O_RDWR, 0777)) < 0) {
+			log_sys_error("open", file);
+			return 0;
+		}
+
+		if (nonblock)
+			operation |= LOCK_NB;
+		else
+			_install_ctrl_c_handler();
+
+		r = flock(*fd, operation);
+		old_errno = errno;
+		if (!nonblock)
+			_remove_ctrl_c_handler();
+
+		if (r) {
+			errno = old_errno;
+			log_sys_error("flock", file);
+			close(*fd);
+			return 0;
+		}
+
+		if (!stat(file, &buf1) && !fstat(*fd, &buf2) &&
+		    is_same_inode(buf1, buf2))
+			return 1;
+	} while (!nonblock);
+
+	return 0;
+}
+
+static int _lock_file(const char *file, uint32_t flags)
+{
+	int operation;
+	int fd_aux = -1;
+	int nonblock = flags & LCK_NONBLOCK;
+	int success;
 
 	struct lock_list *ll;
-	struct stat buf1, buf2;
 	char state;
+	char *file_aux = alloca(strlen(file) + 5);
+
+	strcpy(file_aux, file);
+	/* There is always a slash before the basename part of the filename. */
+	*(strrchr(file_aux, '/') + 1) = 0;
+	strcat(file_aux, "aux_");
+	strcat(file_aux, strrchr(file, '/') + 1);
 
 	switch (flags & LCK_TYPE_MASK) {
 	case LCK_READ:
@@ -162,45 +215,30 @@ static int _lock_file(const char *file, 
 
 	log_very_verbose("Locking %s %c%c", ll->res, state,
 			 flags & LCK_NONBLOCK ? ' ' : 'B');
-	do {
-		if ((ll->lf > -1) && close(ll->lf))
-			log_sys_error("close", file);
-
-		if ((ll->lf = open(file, O_CREAT | O_APPEND | O_RDWR, 0777))
-		    < 0) {
-			log_sys_error("open", file);
-			goto err;
-		}
-
-		if ((flags & LCK_NONBLOCK))
-			operation |= LOCK_NB;
-		else
-			_install_ctrl_c_handler();
 
-		r = flock(ll->lf, operation);
-		old_errno = errno;
-		if (!(flags & LCK_NONBLOCK))
-			_remove_ctrl_c_handler();
-
-		if (r) {
-			errno = old_errno;
-			log_sys_error("flock", ll->res);
-			close(ll->lf);
-			goto err;
+	if (_write_priority) {
+		if (flags & LCK_WRITE) {
+			if ((success = _flock(file_aux, &fd_aux, LOCK_EX, nonblock))) {
+				success = _flock(file, &ll->lf, operation, nonblock);
+				_unflock(file_aux, fd_aux);
+			}
+		} else {
+			if ((success = _flock(file_aux, &fd_aux, LOCK_EX, nonblock))) {
+				_unflock(file_aux, fd_aux);
+				success = _flock(file, &ll->lf, operation, nonblock);
+			}
 		}
+	} else {
+		success = _flock(file, &ll->lf, operation, nonblock);
+	}
 
-		if (!stat(ll->res, &buf1) && !fstat(ll->lf, &buf2) &&
-		    is_same_inode(buf1, buf2))
-			break;
-	} while (!(flags & LCK_NONBLOCK));
-
-	dm_list_add(&_lock_list, &ll->list);
-	return 1;
-
-      err:
-	dm_free(ll->res);
-	dm_free(ll);
-	return 0;
+	if (success)
+		dm_list_add(&_lock_list, &ll->list);
+	else {
+		dm_free(ll->res);
+		dm_free(ll);
+	}
+	return success;
 }
 
 static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
@@ -283,6 +321,9 @@ int init_file_locking(struct locking_typ
 						DEFAULT_LOCK_DIR),
 		sizeof(_lock_dir));
 
+	_write_priority = find_config_tree_bool(cmd, "global/write_lock_priority",
+						DEFAULT_WRITE_LOCK_PRIORITY);
+
 	if (!dm_create_dir(_lock_dir))
 		return 0;
 

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]