git » libjio » commit b60413a

Split file locks into read and write locks. This allows multiple readers at the same time, but only one writer. Obviously, it improves paralell reading performance without imposing penalties on the write path.

author Alberto Bertogli
2004-07-13 13:50:55 UTC
committer Alberto Bertogli
2007-07-15 13:09:18 UTC
parent 18a7e4f72ba1992687555d696d78e3efe47cd642

Split file locks into read and write locks. This allows multiple readers at the same time, but only one writer. Obviously, it improves paralell reading performance without imposing penalties on the write path.

Split file locks into read and write locks. This allows multiple readers at
the same time, but only one writer. Obviously, it improves paralell reading
performance without imposing penalties on the write path.

check.c +1 -1
common.c +14 -8
common.h +12 -0
trans.c +11 -11
unix.c +8 -8

diff --git a/check.c b/check.c
index 86c9f46..2626ee5 100644
--- a/check.c
+++ b/check.c
@@ -174,7 +174,7 @@ int jfsck(const char *name, struct jfsck_result *res)
 
 		/* try to lock the transaction file, if it's locked then it is
 		 * currently being used so we skip it */
-		rv = plockf(tfd, F_TLOCK, 0, 0);
+		rv = plockf(tfd, F_TLOCKW, 0, 0);
 		if (rv == -1) {
 			res->in_progress++;
 			goto loop;
diff --git a/common.c b/common.c
index 6e39520..01119ef 100644
--- a/common.c
+++ b/common.c
@@ -24,17 +24,23 @@ off_t plockf(int fd, int cmd, off_t offset, off_t len)
 	struct flock fl;
 	int op;
 
-	if (cmd == F_LOCK) {
+	op = -1;
+	fl.l_type = -1;
+
+	if (cmd & _F_READ) {
+		fl.l_type = F_RDLCK;
+	} else if (cmd & _F_WRITE) {
 		fl.l_type = F_WRLCK;
+	}
+
+	if (cmd & _F_LOCK) {
 		op = F_SETLKW;
-	} else if (cmd == F_ULOCK) {
-		fl.l_type = F_UNLCK;
-		op = F_SETLKW;
-	} else if (cmd == F_TLOCK) {
-		fl.l_type = F_WRLCK;
+	} else if (cmd & _F_TLOCK) {
 		op = F_SETLK;
-	} else
-		return 0;
+	} else if (cmd & F_UNLOCK) {
+		fl.l_type = F_UNLCK;
+		op = F_SETLKW; /* not very relevant */
+	}
 
 	fl.l_whence = SEEK_SET;
 	fl.l_start = offset;
diff --git a/common.h b/common.h
index adcfcfc..3e8f703 100644
--- a/common.h
+++ b/common.h
@@ -9,6 +9,18 @@
 #ifndef _COMMON_H
 #define _COMMON_H
 
+#define _F_READ		0x00001
+#define _F_WRITE	0x00010
+#define _F_LOCK		0x00100
+#define _F_TLOCK	0x01000
+#define _F_ULOCK	0x10000
+
+#define F_LOCKR		(_F_LOCK | _F_READ)
+#define F_LOCKW		(_F_LOCK | _F_WRITE)
+#define F_TLOCKR	(_F_TLOCK | _F_READ)
+#define F_TLOCKW	(_F_TLOCK | _F_WRITE)
+#define F_UNLOCK	(_F_ULOCK)
+
 off_t plockf(int fd, int cmd, off_t offset, off_t len);
 ssize_t spread(int fd, void *buf, size_t count, off_t offset);
 ssize_t spwrite(int fd, const void *buf, size_t count, off_t offset);
diff --git a/trans.c b/trans.c
index f6a2a52..c121bb2 100644
--- a/trans.c
+++ b/trans.c
@@ -33,7 +33,7 @@ static unsigned int get_tid(struct jfs *fs)
 	int r, rv;
 
 	/* lock the whole file */
-	plockf(fs->jfd, F_LOCK, 0, 0);
+	plockf(fs->jfd, F_LOCKW, 0, 0);
 
 	/* read the current max. curid */
 	r = spread(fs->jfd, &curid, sizeof(curid), 0);
@@ -55,7 +55,7 @@ static unsigned int get_tid(struct jfs *fs)
 	}
 
 exit:
-	plockf(fs->jfd, F_ULOCK, 0, 0);
+	plockf(fs->jfd, F_UNLOCK, 0, 0);
 	return rv;
 }
 
@@ -67,7 +67,7 @@ static void free_tid(struct jfs *fs, unsigned int tid)
 	char name[PATH_MAX];
 
 	/* lock the whole file */
-	plockf(fs->jfd, F_LOCK, 0, 0);
+	plockf(fs->jfd, F_LOCKW, 0, 0);
 
 	/* read the current max. curid */
 	r = spread(fs->jfd, &curid, sizeof(curid), 0);
@@ -99,7 +99,7 @@ static void free_tid(struct jfs *fs, unsigned int tid)
 	}
 
 exit:
-	plockf(fs->jfd, F_ULOCK, 0, 0);
+	plockf(fs->jfd, F_UNLOCK, 0, 0);
 	return;
 }
 
@@ -218,7 +218,7 @@ int jtrans_commit(struct jtrans *ts)
 		goto exit;
 
 	/* and lock it */
-	plockf(fd, F_LOCK, 0, 0);
+	plockf(fd, F_LOCKW, 0, 0);
 
 	ts->id = id;
 	ts->name = name;
@@ -255,7 +255,7 @@ int jtrans_commit(struct jtrans *ts)
 	 * break atomicity warantees if we need to rollback */
 	if (!(ts->flags & J_NOLOCK)) {
 		for (op = ts->op; op != NULL; op = op->next) {
-			rv = plockf(ts->fs->fd, F_LOCK, op->offset, op->len);
+			rv = plockf(ts->fs->fd, F_LOCKW, op->offset, op->len);
 			if (rv == -1)
 				/* note it can fail with EDEADLK */
 				goto exit;
@@ -332,7 +332,7 @@ int jtrans_commit(struct jtrans *ts)
 	for (op = ts->op; op != NULL; op = op->next) {
 		rv = spwrite(ts->fs->fd, op->buf, op->len, op->offset);
 
-		plockf(ts->fs->fd, F_ULOCK, op->offset, op->len);
+		plockf(ts->fs->fd, F_UNLOCK, op->offset, op->len);
 		op->locked = 0;
 
 		if (rv != op->len)
@@ -354,7 +354,7 @@ exit:
 	close(fd);
 	for (op = ts->op; op != NULL; op = op->next) {
 		if (op->locked)
-			plockf(ts->fs->fd, F_ULOCK, op->offset, op->len);
+			plockf(ts->fs->fd, F_UNLOCK, op->offset, op->len);
 	}
 
 	pthread_mutex_unlock(&(ts->lock));
@@ -481,17 +481,17 @@ int jopen(struct jfs *fs, const char *name, int flags, int mode, int jflags)
 	/* initialize the lock file by writing the first tid to it, but only
 	 * if its empty, otherwise there is a race if two processes call
 	 * jopen() simultaneously and both initialize the file */
-	plockf(jfd, F_LOCK, 0, 0);
+	plockf(jfd, F_LOCKW, 0, 0);
 	lstat(jlockfile, &sinfo);
 	if (sinfo.st_size == 0) {
 		t = 1;
 		rv = write(jfd, &t, sizeof(t));
 		if (rv != sizeof(t)) {
-			plockf(jfd, F_ULOCK, 0, 0);
+			plockf(jfd, F_UNLOCK, 0, 0);
 			return -1;
 		}
 	}
-	plockf(jfd, F_ULOCK, 0, 0);
+	plockf(jfd, F_UNLOCK, 0, 0);
 
 	fs->jfd = jfd;
 
diff --git a/unix.c b/unix.c
index bce8647..7ae5d0e 100644
--- a/unix.c
+++ b/unix.c
@@ -27,9 +27,9 @@ ssize_t jread(struct jfs *fs, void *buf, size_t count)
 
 	pos = lseek(fs->fd, 0, SEEK_CUR);
 
-	plockf(fs->fd, F_LOCK, pos, count);
+	plockf(fs->fd, F_LOCKR, pos, count);
 	rv = spread(fs->fd, buf, count, pos);
-	plockf(fs->fd, F_ULOCK, pos, count);
+	plockf(fs->fd, F_UNLOCK, pos, count);
 
 	if (rv == count) {
 		/* if success, advance the file pointer */
@@ -46,9 +46,9 @@ ssize_t jpread(struct jfs *fs, void *buf, size_t count, off_t offset)
 {
 	int rv;
 
-	plockf(fs->fd, F_LOCK, offset, count);
+	plockf(fs->fd, F_LOCKR, offset, count);
 	rv = spread(fs->fd, buf, count, offset);
-	plockf(fs->fd, F_ULOCK, offset, count);
+	plockf(fs->fd, F_UNLOCK, offset, count);
 
 	return rv;
 }
@@ -66,9 +66,9 @@ ssize_t jreadv(struct jfs *fs, struct iovec *vector, int count)
 
 	pthread_mutex_lock(&(fs->lock));
 	pos = lseek(fs->fd, 0, SEEK_CUR);
-	plockf(fs->fd, F_LOCK, pos, count);
+	plockf(fs->fd, F_LOCKR, pos, count);
 	rv = readv(fs->fd, vector, count);
-	plockf(fs->fd, F_ULOCK, pos, count);
+	plockf(fs->fd, F_UNLOCK, pos, count);
 	pthread_mutex_unlock(&(fs->lock));
 
 	return rv;
@@ -162,9 +162,9 @@ int jtruncate(struct jfs *fs, off_t length)
 	int rv;
 
 	/* lock from length to the end of file */
-	plockf(fs->fd, F_LOCK, length, 0);
+	plockf(fs->fd, F_LOCKW, length, 0);
 	rv = ftruncate(fs->fd, length);
-	plockf(fs->fd, F_ULOCK, length, 0);
+	plockf(fs->fd, F_UNLOCK, length, 0);
 
 	return rv;
 }