
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.



---

 cur-root/check.c  |    2 +-
 cur-root/common.c |   22 ++++++++++++++--------
 cur-root/common.h |   12 ++++++++++++
 cur-root/trans.c  |   22 +++++++++++-----------
 cur-root/unix.c   |   16 ++++++++--------
 5 files changed, 46 insertions(+), 28 deletions(-)

diff -puN common.c~split_rw_locks common.c
--- cur/common.c~split_rw_locks	2004-07-10 22:23:17.000000000 -0300
+++ cur-root/common.c	2004-07-10 22:23:17.000000000 -0300
@@ -24,17 +24,23 @@ off_t plockf(int fd, int cmd, off_t offs
 	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 -puN common.h~split_rw_locks common.h
--- cur/common.h~split_rw_locks	2004-07-10 22:23:17.000000000 -0300
+++ cur-root/common.h	2004-07-13 10:49:35.500426136 -0300
@@ -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 -puN check.c~split_rw_locks check.c
--- cur/check.c~split_rw_locks	2004-07-10 22:23:17.000000000 -0300
+++ cur-root/check.c	2004-07-13 10:50:31.195959128 -0300
@@ -174,7 +174,7 @@ int jfsck(const char *name, struct jfsck
 
 		/* 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 -puN trans.c~split_rw_locks trans.c
--- cur/trans.c~split_rw_locks	2004-07-10 22:23:17.000000000 -0300
+++ cur-root/trans.c	2004-07-13 10:50:39.067762432 -0300
@@ -33,7 +33,7 @@ static unsigned int get_tid(struct jfs *
 	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 *
 	}
 
 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, uns
 	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, uns
 	}
 
 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 *na
 	/* 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 -puN unix.c~split_rw_locks unix.c
--- cur/unix.c~split_rw_locks	2004-07-13 10:50:47.057547800 -0300
+++ cur-root/unix.c	2004-07-13 10:49:11.334099976 -0300
@@ -27,9 +27,9 @@ ssize_t jread(struct jfs *fs, void *buf,
 
 	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
 {
 	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 io
 
 	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 leng
 	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;
 }

_
