this patch changes the use of the read/write lock to force serialization
on the branch table.

basically, any entry point that can change it (ioctl for adding/changing
mode/inc) is taken with write, while every other fs entry point (lookup,
read, write....) is taken with read.  basically to force the fs not to
be in use when a branching operation is taking place.

thoughts?

it also does one other thing, makes all (I believe) the
branchget/branchputs follow this model.

1. branchget before open().

2. branchput after fput().
diff -rNu unionfs-20060117-2031/branchman.c unionfs-20060117-2031.lock/branchman.c
--- unionfs-20060117-2031/branchman.c	2006-01-19 13:31:33.000000000 -0500
+++ unionfs-20060117-2031.lock/branchman.c	2006-01-19 13:36:01.000000000 -0500
@@ -158,7 +158,6 @@
 
 	sb = file->f_dentry->d_sb;
 
-	unionfs_write_lock(sb);
 	if ((err = newputmap(sb)))
 		goto out;
 
@@ -169,7 +168,6 @@
 	atomic_set(&itopd(sb->s_root->d_inode)->uii_generation, err);
 
       out:
-	unionfs_write_unlock(sb);
 	print_exit_status(err);
 	return err;
 }
@@ -235,7 +233,6 @@
 		goto out;
 	}
 
-	unionfs_write_lock(inode->i_sb);
 	lock_dentry(inode->i_sb->s_root);
 
 	root = inode->i_sb->s_root;
@@ -380,7 +377,6 @@
 
       out:
 	unlock_dentry(inode->i_sb->s_root);
-	unionfs_write_unlock(inode->i_sb);
 
 	KFREE(new_hidden_mnt);
 	KFREE(new_udi_dentry);
@@ -489,7 +485,6 @@
 
 	print_entry_location();
 
-	unionfs_write_lock(inode->i_sb);
 	lock_dentry(inode->i_sb->s_root);
 
 	if ((err = newputmap(inode->i_sb)))
@@ -526,7 +521,6 @@
 
       out:
 	unlock_dentry(inode->i_sb->s_root);
-	unionfs_write_unlock(inode->i_sb);
 	KFREE(rdwrargs);
 
 	print_exit_status(err);
diff -rNu unionfs-20060117-2031/commonfops.c unionfs-20060117-2031.lock/commonfops.c
--- unionfs-20060117-2031/commonfops.c	2006-01-18 19:14:16.000000000 -0500
+++ unionfs-20060117-2031.lock/commonfops.c	2006-01-19 13:40:35.000000000 -0500
@@ -39,7 +39,6 @@
 	putmap =
 	    stopd(sb)->usi_putmaps[generation - stopd(sb)->usi_firstputmap];
 	BUG_ON(index < 0);
-	BUG_ON(putmap == NULL);
 	BUG_ON(index > putmap->bend);
 	BUG_ON(putmap->map[index] < 0);
 	branchput(sb, putmap->map[index]);
@@ -174,7 +173,6 @@
 	dentry = file->f_dentry;
 	lock_dentry(dentry);
 	sb = dentry->d_sb;
-	unionfs_read_lock(sb);
 	if (!unionfs_d_revalidate(dentry, NULL) && !d_deleted(dentry)) {
 		err = -ESTALE;
 		goto out;
@@ -198,8 +196,8 @@
 		bend = fbend(file);
 		for (bindex = bstart; bindex <= bend; bindex++) {
 			if (ftohf_index(file, bindex)) {
-				branchput_gen(fgen, dentry->d_sb, bindex);
 				fput(ftohf_index(file, bindex));
+				branchput_gen(fgen, dentry->d_sb, bindex);
 			}
 		}
 		if (ftohf_ptr(file)) {
@@ -233,7 +231,6 @@
 
 				DGET(hidden_dentry);
 				mntget(stohiddenmnt_index(sb, bindex));
-				branchget(sb, bindex);
 
 				hidden_file =
 				    DENTRY_OPEN(hidden_dentry,
@@ -245,6 +242,7 @@
 				} else {
 					set_ftohf_index(file, bindex,
 							hidden_file);
+					branchget(sb, bindex);
 				}
 			}
 		} else {
@@ -278,7 +276,6 @@
 
 			DGET(hidden_dentry);
 			mntget(stohiddenmnt_index(sb, bstart));
-			branchget(sb, bstart);
 			hidden_file =
 			    DENTRY_OPEN(hidden_dentry,
 					stohiddenmnt_index(sb, bstart),
@@ -288,6 +285,7 @@
 				goto out;
 			}
 			set_ftohf(file, hidden_file);
+			branchget(sb, bstart);
 			/* Fix up the position. */
 			hidden_file->f_pos = file->f_pos;
 
@@ -333,9 +331,9 @@
 			bend = fbend(file);
 			for (bindex = bstart; bindex <= bend; bindex++) {
 				if (ftohf_index(file, bindex)) {
-					branchput(dentry->d_sb, bindex);
 					fput(ftohf_index(file, bindex));
 					set_ftohf_index(file, bindex, NULL);
+					branchput(dentry->d_sb, bindex);
 				}
 			}
 			fbend(file) = bend;
@@ -345,7 +343,6 @@
       out:
 	fist_print_dentry("file revalidate out", dentry);
 	unlock_dentry(dentry);
-	unionfs_read_unlock(dentry->d_sb);
 	print_exit_status(err);
 	return err;
 }
@@ -361,6 +358,7 @@
 	int locked = 0;
 
 	print_entry_location();
+	unionfs_read_lock(inode->i_sb);
 
 	ftopd_lhs(file) = KZALLOC(sizeof(struct unionfs_file_info), GFP_KERNEL);
 	if (!ftopd(file)) {
@@ -389,7 +387,6 @@
 	dentry = file->f_dentry;
 	fist_dprint(8, "dentry to open is %p\n", dentry);
 	lock_dentry(dentry);
-	unionfs_read_lock(inode->i_sb);
 	locked = 1;
 
 	bstart = fbstart(file) = dbstart(dentry);
@@ -474,18 +471,14 @@
       out:
 	/* freeing the allocated resources, and fput the opened files */
 	if (err < 0 && ftopd(file)) {
-		if (!locked)
-			unionfs_read_lock(file->f_dentry->d_sb);
 		for (bindex = bstart; bindex <= bend; bindex++) {
 			hidden_file = ftohf_index(file, bindex);
 			if (hidden_file) {
-				branchput(file->f_dentry->d_sb, bindex);
 				/* fput calls dput for hidden_dentry */
 				fput(hidden_file);
+				branchput(file->f_dentry->d_sb, bindex);
 			}
 		}
-		if (!locked)
-			unionfs_read_unlock(file->f_dentry->d_sb);
 		KFREE(ftohf_ptr(file));
 		KFREE(ftopd(file));
 	}
@@ -494,8 +487,8 @@
 
 	if (locked) {
 		unlock_dentry(dentry);
-		unionfs_read_unlock(inode->i_sb);
 	}
+	unionfs_read_unlock(inode->i_sb);
 	print_exit_status(err);
 	return err;
 }
@@ -508,6 +501,7 @@
 	int fgen;
 
 	print_entry_location();
+	unionfs_read_lock(file->f_dentry->d_sb);
 
 	fist_checkinode(inode, "unionfs_release");
 
@@ -521,9 +515,7 @@
 
 		if (hidden_file) {
 			fput(hidden_file);
-			unionfs_read_lock(inode->i_sb);
 			branchput_gen(fgen, inode->i_sb, bindex);
-			unionfs_read_unlock(inode->i_sb);
 		}
 	}
 	KFREE(ftohf_ptr(file));
@@ -546,6 +538,8 @@
 
 	fist_checkinode(inode, "post unionfs_release");
 
+	unionfs_read_unlock(file->f_dentry->d_sb);
+
 	print_exit_status(err);
 	return err;
 }
@@ -560,9 +554,22 @@
 	long err = 0;		/* don't fail by default */
 	struct file *hidden_file = NULL;
 	int val;
+	int read_lock = 0;
 
 	print_entry_location();
 
+	switch (cmd) {
+	case FIST_IOCTL_SET_DEBUG_VALUE:
+	case UNIONFS_IOCTL_INCGEN:
+	case UNIONFS_IOCTL_ADDBRANCH:
+	case UNIONFS_IOCTL_RDWRBRANCH:
+		unionfs_write_lock(file->f_dentry->d_sb);
+		break;
+	default:
+		unionfs_read_lock(file->f_dentry->d_sb);
+		read_lock = 1;
+	}
+
 	if ((err = unionfs_file_revalidate(file, 1)))
 		goto out;
 
@@ -661,6 +668,11 @@
 	}			/* end of outer switch statement */
 
       out:
+	if (read_lock)
+		unionfs_read_unlock(file->f_dentry->d_sb);
+	else  {
+		unionfs_write_unlock(file->f_dentry->d_sb);
+	}
 	print_exit_status((int)err);
 	return err;
 }
@@ -673,6 +685,8 @@
 
 	print_entry_location();
 
+	unionfs_read_lock(file->f_dentry->d_sb);
+
 	if ((err = unionfs_file_revalidate(file, 1)))
 		goto out;
 	if (!atomic_dec_and_test
@@ -704,6 +718,7 @@
       out_lock:
 	unlock_dentry(file->f_dentry);
       out:
+	unionfs_read_unlock(file->f_dentry->d_sb);
 	print_exit_status(err);
 	return err;
 }
diff -rNu unionfs-20060117-2031/copyup.c unionfs-20060117-2031.lock/copyup.c
--- unionfs-20060117-2031/copyup.c	2006-01-17 20:31:48.000000000 -0500
+++ unionfs-20060117-2031.lock/copyup.c	2006-01-18 17:07:42.000000000 -0500
@@ -219,8 +219,6 @@
 
 	sb = dir->i_sb;
 
-	unionfs_read_lock(sb);
-
 	if ((err = is_robranch_super(sb, new_bindex)))
 		goto out;
 
@@ -416,8 +414,6 @@
 		}
 	}
 
-	unionfs_read_unlock(sb);
-
 	fist_print_dentry("OUT: copyup_dentry", dentry);
 	fist_print_inode("OUT: copyup_dentry", dentry->d_inode);
 
@@ -442,6 +438,7 @@
 	if (!err) {
 		fbstart(file) = new_bindex;
 		set_ftohf_index(file, new_bindex, output_file);
+		branchget(file->f_dentry->d_sb, new_bindex);
 	}
 
 	print_exit_status(err);
@@ -464,6 +461,7 @@
 	if (!err) {
 		fbstart(file) = new_bindex;
 		set_ftohf_index(file, new_bindex, output_file);
+		branchget(file->f_dentry->d_sb, new_bindex);
 	}
 
 	print_exit_status(err);
diff -rNu unionfs-20060117-2031/dentry.c unionfs-20060117-2031.lock/dentry.c
--- unionfs-20060117-2031/dentry.c	2006-01-17 20:31:48.000000000 -0500
+++ unionfs-20060117-2031.lock/dentry.c	2006-01-18 17:07:42.000000000 -0500
@@ -22,8 +22,10 @@
 #include "unionfs.h"
 
 /* declarations added for "sparse" */
-extern int unionfs_d_revalidate_wrap(struct dentry *dentry,
+extern int unionfs_d_revalidate_lockd(struct dentry *dentry,
 				     struct nameidata *nd);
+extern int unionfs_d_revalidate_wrap(struct dentry *dentry,
+				    struct nameidata *nd);
 extern void unionfs_d_release(struct dentry *dentry);
 extern void unionfs_d_iput(struct dentry *dentry, struct inode *inode);
 
@@ -38,7 +40,6 @@
 	int bindex, bstart, bend;
 	int sbgen, dgen;
 	int positive = 0;
-	int locked = 0;
 	int restart = 0;
 
 	print_util_entry_location();
@@ -66,24 +67,20 @@
 		struct dentry *result;
 		int pdgen;
 
-		unionfs_read_lock(dentry->d_sb);
-		locked = 1;
-
 		/* The root entry should always be valid */
 		BUG_ON(IS_ROOT(dentry));
 
 		/* We can't work correctly if our parent isn't valid. */
 		pdgen = atomic_read(&dtopd(dentry->d_parent)->udi_generation);
 		if (!restart && (pdgen != sbgen)) {
-			unionfs_read_unlock(dentry->d_sb);
-			locked = 0;
 			/* We must be locked before our parent. */
-			if (!
-			    (dentry->d_parent->d_op->
-			     d_revalidate(dentry->d_parent, nd))) {
+			lock_dentry(dentry->d_parent);
+			if (!unionfs_d_revalidate(dentry->d_parent, nd)) {
+				unlock_dentry(dentry->d_parent);
 				invalid = 1;
 				goto out;
 			}
+			unlock_dentry(dentry->d_parent);
 			restart = 1;
 			goto restart;
 		}
@@ -166,8 +163,6 @@
 		fist_copy_attr_all(dentry->d_inode, dtohd(dentry)->d_inode);
 
       out:
-	if (locked)
-		unionfs_read_unlock(dentry->d_sb);
 	if (invalid)
 		err = 0;
 	fist_print_dentry("revalidate out", dentry);
@@ -180,11 +175,13 @@
 	int err;
 
 	print_entry_location();
-	lock_dentry(dentry);
+	unionfs_read_lock(dentry->d_sb);
 
+	lock_dentry(dentry);
 	err = unionfs_d_revalidate(dentry, nd);
-
 	unlock_dentry(dentry);
+
+	unionfs_read_unlock(dentry->d_sb);
 	print_exit_status(err);
 	return err;
 }
diff -rNu unionfs-20060117-2031/dirfops.c unionfs-20060117-2031.lock/dirfops.c
--- unionfs-20060117-2031/dirfops.c	2006-01-17 20:31:48.000000000 -0500
+++ unionfs-20060117-2031.lock/dirfops.c	2006-01-18 17:07:42.000000000 -0500
@@ -106,6 +106,8 @@
 
 	fist_print_file("In unionfs_readdir()", file);
 
+	unionfs_read_lock(file->f_dentry->d_sb);
+
 	if ((err = unionfs_file_revalidate(file, 0)))
 		goto out;
 
@@ -206,6 +208,7 @@
 	}
 
       out:
+	unionfs_read_unlock(file->f_dentry->d_sb);
 	fist_checkinode(inode, "post unionfs_readdir");
 	print_exit_status(err);
 	return err;
@@ -230,6 +233,8 @@
 	print_entry(" file=%p, offset=0x%llx, origin = %d", file, offset,
 		    origin);
 
+	unionfs_read_lock(file->f_dentry->d_sb);
+
 	if ((err = unionfs_file_revalidate(file, 0)))
 		goto out;
 
@@ -294,6 +299,7 @@
 	}
 
       out:
+	unionfs_read_unlock(file->f_dentry->d_sb);
 	print_exit_status((int)err);
 	return err;
 }
diff -rNu unionfs-20060117-2031/dirhelper.c unionfs-20060117-2031.lock/dirhelper.c
--- unionfs-20060117-2031/dirhelper.c	2006-01-17 20:31:48.000000000 -0500
+++ unionfs-20060117-2031.lock/dirhelper.c	2006-01-18 17:07:42.000000000 -0500
@@ -168,8 +168,6 @@
 
 	sb = dentry->d_sb;
 
-	unionfs_read_lock(sb);
-
 	BUG_ON(!S_ISDIR(dentry->d_inode->i_mode));
 
 	if ((err = unionfs_partial_lookup(dentry)))
@@ -206,16 +204,16 @@
 
 		DGET(hidden_dentry);
 		mntget(stohiddenmnt_index(sb, bindex));
-		branchget(sb, bindex);
 		hidden_file =
 		    DENTRY_OPEN(hidden_dentry, stohiddenmnt_index(sb, bindex),
 				O_RDONLY);
 		if (IS_ERR(hidden_file)) {
 			err = PTR_ERR(hidden_file);
 			DPUT(hidden_dentry);
-			branchput(sb, bindex);
 			goto out;
 		}
+		
+		branchget(sb, bindex);
 
 		do {
 			buf->filldir_called = 0;
@@ -243,8 +241,6 @@
 		KFREE(buf);
 	}
 
-	unionfs_read_unlock(sb);
-
 	print_exit_status(err);
 	return err;
 }
diff -rNu unionfs-20060117-2031/file.c unionfs-20060117-2031.lock/file.c
--- unionfs-20060117-2031/file.c	2006-01-17 20:31:48.000000000 -0500
+++ unionfs-20060117-2031.lock/file.c	2006-01-18 17:07:42.000000000 -0500
@@ -40,6 +40,8 @@
 	fist_dprint(6, "unionfs_llseek: file=%p, offset=0x%llx, origin=%d\n",
 		    file, offset, origin);
 
+	unionfs_read_lock(file->f_dentry->d_sb);
+
 	if ((err = unionfs_file_revalidate(file, 0)))
 		goto out;
 
@@ -65,6 +67,7 @@
 		file->f_version++;
 	}
       out:
+	unionfs_read_unlock(file->f_dentry->d_sb);
 	print_exit_status((int)err);
 	return err;
 }
@@ -78,6 +81,8 @@
 
 	print_entry_location();
 
+	unionfs_read_lock(file->f_dentry->d_sb);
+
 	if ((err = unionfs_file_revalidate(file, 0)))
 		goto out;
 
@@ -99,6 +104,7 @@
 	       sizeof(struct file_ra_state));
 
       out:
+	unionfs_read_unlock(file->f_dentry->d_sb);
 	fist_print_file("leaving read()", file);
 	print_exit_status(err);
 	return err;
@@ -113,6 +119,8 @@
 
 	print_entry_location();
 
+	unionfs_read_lock(file->f_dentry->d_sb);
+
 	if ((err = unionfs_file_revalidate(file, 0)))
 		goto out;
 
@@ -126,6 +134,7 @@
 					  target);
 
       out:
+	unionfs_read_unlock(file->f_dentry->d_sb);
 	print_exit_status(err);
 	return err;
 }
@@ -144,6 +153,8 @@
 
 	print_entry_location();
 
+	unionfs_read_lock(file->f_dentry->d_sb);
+
 	if ((err = unionfs_file_revalidate(file, 1)))
 		goto out;
 
@@ -180,6 +191,7 @@
 		inode->i_size = pos;
 
       out:
+	unionfs_read_unlock(file->f_dentry->d_sb);
 	print_exit_status(err);
 	return err;
 }
@@ -200,6 +212,8 @@
 
 	print_entry_location();
 
+	unionfs_read_lock(file->f_dentry->d_sb);
+
 	if (unionfs_file_revalidate(file, 0)) {
 		/* We should pretend an error happend. */
 		mask = POLLERR | POLLIN | POLLOUT;
@@ -214,6 +228,7 @@
 	mask = hidden_file->f_op->poll(hidden_file, wait);
 
       out:
+	unionfs_read_unlock(file->f_dentry->d_sb);
 	print_exit_status(mask);
 	return mask;
 }
@@ -227,6 +242,8 @@
 
 	print_entry_location();
 
+	unionfs_read_lock(file->f_dentry->d_sb);
+
 	/* This might could be deferred to mmap's writepage. */
 	willwrite = ((vma->vm_flags | VM_SHARED | VM_WRITE) == vma->vm_flags);
 	if ((err = unionfs_file_revalidate(file, willwrite)))
@@ -244,6 +261,7 @@
 	fput(file);		/* no need to keep extra ref on ours */
 
       out:
+	unionfs_read_unlock(file->f_dentry->d_sb);
 	print_exit_status(err);
 	return err;
 }
@@ -255,6 +273,8 @@
 
 	print_entry_location();
 
+	unionfs_read_lock(file->f_dentry->d_sb);
+
 	if ((err = unionfs_file_revalidate(file, 1)))
 		goto out;
 
@@ -270,6 +290,7 @@
 	up(&hidden_file->f_dentry->d_inode->i_sem);
 
       out:
+	unionfs_read_unlock(file->f_dentry->d_sb);
 	print_exit_status(err);
 	return err;
 }
@@ -281,6 +302,8 @@
 
 	print_entry_location();
 
+	unionfs_read_lock(file->f_dentry->d_sb);
+
 	if ((err = unionfs_file_revalidate(file, 1)))
 		goto out;
 
@@ -290,6 +313,7 @@
 		err = hidden_file->f_op->fasync(fd, hidden_file, flag);
 
       out:
+	unionfs_read_unlock(file->f_dentry->d_sb);
 	print_exit_status(err);
 	return err;
 }
diff -rNu unionfs-20060117-2031/fistdev.mk unionfs-20060117-2031.lock/fistdev.mk
--- unionfs-20060117-2031/fistdev.mk	1969-12-31 19:00:00.000000000 -0500
+++ unionfs-20060117-2031.lock/fistdev.mk	2006-01-18 17:07:42.000000000 -0500
@@ -0,0 +1 @@
+EXTRACFLAGS=-DUNIONFS_NDEBUG
diff -rNu unionfs-20060117-2031/inode.c unionfs-20060117-2031.lock/inode.c
--- unionfs-20060117-2031/inode.c	2006-01-17 20:31:48.000000000 -0500
+++ unionfs-20060117-2031.lock/inode.c	2006-01-18 17:07:42.000000000 -0500
@@ -45,6 +45,8 @@
 	char *name = NULL;
 
 	print_entry_location();
+	unionfs_read_lock(dentry->d_sb);
+
 	lock_dentry(dentry);
 	fist_print_dentry("IN unionfs_create", dentry);
 
@@ -194,6 +196,7 @@
 
 	fist_print_dentry("OUT unionfs_create :", dentry);
 	unlock_dentry(dentry);
+	unionfs_read_unlock(dentry->d_sb);
 	print_exit_status(err);
 	return err;
 }
@@ -201,8 +204,15 @@
 struct dentry *unionfs_lookup(struct inode *parent, struct dentry *dentry,
 			      struct nameidata *nd)
 {
-	/* The locking is done by unionfs_lookup_backend. */
-	return unionfs_lookup_backend(dentry, INTERPOSE_LOOKUP);
+	struct dentry * ret;
+	unionfs_read_lock(dentry->d_sb);
+	/* The dentry locking is done by unionfs_lookup_backend. */
+
+	ret = unionfs_lookup_backend(dentry, INTERPOSE_LOOKUP);
+
+	unionfs_read_unlock(dentry->d_sb);
+
+	return ret;
 }
 
 static int unionfs_link(struct dentry *old_dentry, struct inode *dir,
@@ -216,6 +226,8 @@
 	char *name = NULL;
 
 	print_entry_location();
+	unionfs_read_lock(new_dentry->d_sb);
+
 	double_lock_dentry(new_dentry, old_dentry);
 
 	hidden_new_dentry = dtohd(new_dentry);
@@ -327,6 +339,8 @@
 	unlock_dentry(new_dentry);
 	unlock_dentry(old_dentry);
 
+	unionfs_read_unlock(new_dentry->d_sb);
+
 	print_exit_status(err);
 	return err;
 }
@@ -343,6 +357,9 @@
 	char *name = NULL;
 
 	print_entry_location();
+
+	unionfs_read_lock(dentry->d_sb);
+
 	lock_dentry(dentry);
 	fist_print_dentry("IN unionfs_symlink", dentry);
 
@@ -453,6 +470,9 @@
 	KFREE(name);
 	fist_print_dentry("OUT unionfs_symlink :", dentry);
 	unlock_dentry(dentry);
+
+	unionfs_read_unlock(dentry->d_sb);
+
 	print_exit_status(err);
 	return err;
 }
@@ -469,6 +489,7 @@
 	gid_t saved_gid = current->fsgid;
 
 	print_entry_location();
+	unionfs_read_lock(dentry->d_sb);
 	lock_dentry(dentry);
 	fist_print_dentry("IN unionfs_mkdir", dentry);
 	bstart = dbstart(dentry);
@@ -605,6 +626,7 @@
 
 	fist_print_dentry("OUT unionfs_mkdir :", dentry);
 	unlock_dentry(dentry);
+	unionfs_read_unlock(dentry->d_sb);
 	print_exit_status(err);
 	return err;
 }
@@ -620,6 +642,7 @@
 	int whiteout_unlinked = 0;
 
 	print_entry_location();
+	unionfs_read_lock(dentry->d_sb);
 	lock_dentry(dentry);
 	fist_print_dentry("IN unionfs_mknod", dentry);
 	bstart = dbstart(dentry);
@@ -718,6 +741,7 @@
 
 	fist_print_dentry("OUT unionfs_mknod :", dentry);
 	unlock_dentry(dentry);
+	unionfs_read_unlock(dentry->d_sb);
 	print_exit_status(err);
 	return err;
 }
@@ -728,6 +752,7 @@
 	struct dentry *hidden_dentry;
 
 	print_entry_location();
+	unionfs_read_lock(dentry->d_sb);
 	lock_dentry(dentry);
 	hidden_dentry = dtohd(dentry);
 	fist_print_dentry("unionfs_readlink IN", dentry);
@@ -745,6 +770,7 @@
 
       out:
 	unlock_dentry(dentry);
+	unionfs_read_unlock(dentry->d_sb);
 	print_exit_status(err);
 	return err;
 }
@@ -762,6 +788,8 @@
 
 	print_entry_location();
 
+	unionfs_read_lock(dentry->d_sb);
+
 	/* This is freed by the put_link method assuming a successful call. */
 	buf = (char *)KMALLOC(len, GFP_KERNEL);
 	if (!buf) {
@@ -784,6 +812,7 @@
 	err = 0;
 
       out:
+	unionfs_read_unlock(dentry->d_sb);
 	print_exit_status(err);
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
 	return err;
@@ -867,6 +896,7 @@
 	int is_file = 0;
 
 	print_entry_location();
+	unionfs_read_lock(inode->i_sb);
 
 	bstart = ibstart(inode);
 	bend = ibend(inode);
@@ -908,6 +938,7 @@
 	}
 
       out:
+	unionfs_read_unlock(inode->i_sb);
 	print_exit_status(err);
 	return err;
 }
@@ -923,6 +954,7 @@
 	int copyup = 0;
 
 	print_entry_location();
+	unionfs_read_lock(dentry->d_sb);
 	lock_dentry(dentry);
 	bstart = dbstart(dentry);
 	bend = dbend(dentry);
@@ -972,6 +1004,7 @@
 
       out:
 	unlock_dentry(dentry);
+	unionfs_read_unlock(dentry->d_sb);
 	fist_checkinode(inode, "post unionfs_setattr");
 	print_exit_status(err);
 	return err;
diff -rNu unionfs-20060117-2031/rename.c unionfs-20060117-2031.lock/rename.c
--- unionfs-20060117-2031/rename.c	2006-01-17 20:31:48.000000000 -0500
+++ unionfs-20060117-2031.lock/rename.c	2006-01-18 17:07:42.000000000 -0500
@@ -757,6 +757,8 @@
 
 	print_entry_location();
 
+	unionfs_read_lock(new_dentry->d_sb);
+
 	double_lock_dentry(old_dentry, new_dentry);
 
 	fist_checkinode(old_dir, "unionfs_rename-old_dir");
@@ -822,6 +824,7 @@
 
 	unlock_dentry(new_dentry);
 	unlock_dentry(old_dentry);
+	unionfs_read_unlock(new_dentry->d_sb);
 	print_exit_status(err);
 	return err;
 }
diff -rNu unionfs-20060117-2031/super.c unionfs-20060117-2031.lock/super.c
--- unionfs-20060117-2031/super.c	2006-01-17 20:31:48.000000000 -0500
+++ unionfs-20060117-2031.lock/super.c	2006-01-18 20:57:31.000000000 -0500
@@ -152,6 +152,7 @@
 	int bindex, bindex1, bstart, bend;
 
 	print_entry_location();
+
 	memset(buf, 0, sizeof(struct kstatfs));
 	buf->f_type = UNIONFS_SUPER_MAGIC;
 
@@ -223,6 +224,7 @@
 
 	memset(&buf->f_fsid, 0, sizeof(__kernel_fsid_t));
 	memset(&buf->f_spare, 0, sizeof(buf->f_spare));
+
 	print_exit_status(err);
 	return err;
 }
@@ -232,6 +234,8 @@
 	unsigned long *uldata = (unsigned long *)data;
 	int err;
 
+	unionfs_write_lock(sb);
+
 	uldata++;
 
 	switch (*uldata) {
@@ -242,6 +246,7 @@
 		err = -ENOTTY;
 	}
 
+	unionfs_write_unlock(sb);
 	return err;
 }
 
@@ -289,7 +294,11 @@
 			hidden_inode = itohi_index(inode, bindex);
 			if (!hidden_inode)
 				continue;
-			iput(hidden_inode);
+			if (hidden_inode->i_sb) {
+				iput(hidden_inode);
+			} else {
+				printk("SHAYA: hidden_inode->i_sb is NULL!\n");
+			}
 		}
 	}
 	// XXX: why this assertion fails?
@@ -317,6 +326,7 @@
 	memset(&c->info, 0, sizeof(c->info));
 
 	c->vfs_inode.i_version = 1;
+
 	print_exit_pointer(&c->vfs_inode);
 	return &c->vfs_inode;
 }
@@ -373,7 +383,11 @@
 /* Called when we have a dirty inode, right here we only throw out
  * parts of our readdir list that are too old.
  */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
 static int unionfs_write_inode(struct inode *inode, int sync)
+#else
+static void unionfs_write_inode(struct inode *inode, int sync)
+#endif
 {
 	struct list_head *pos, *n;
 	struct unionfs_dir_state *rdstate;
@@ -393,7 +407,9 @@
 	spin_unlock(&itopd(inode)->uii_rdlock);
 
 	print_exit_location();
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
 	return 0;
+#endif
 }
 
 /*
diff -rNu unionfs-20060117-2031/unionfs.h unionfs-20060117-2031.lock/unionfs.h
--- unionfs-20060117-2031/unionfs.h	2006-01-17 20:31:48.000000000 -0500
+++ unionfs-20060117-2031.lock/unionfs.h	2006-01-18 17:07:42.000000000 -0500
@@ -44,7 +44,7 @@
 #include <linux/dcache.h>
 #include <linux/poll.h>
 
-#if (!defined(UNIONFS_UNSUPPORTED)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
+#if (!defined(UNIONFS_UNSUPPORTED)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8))
 #warning You are compiling Unionfs on an unsupported kernel version.
 #warning To compile Unionfs, you will need to define UNIONFS_UNSUPPORTED.
 #warning Try adding: EXTRACFLAGS=-DUNIONFS_UNSUPPORTED to fistdev.mk
diff -rNu unionfs-20060117-2031/unlink.c unionfs-20060117-2031.lock/unlink.c
--- unionfs-20060117-2031/unlink.c	2006-01-17 20:31:48.000000000 -0500
+++ unionfs-20060117-2031.lock/unlink.c	2006-01-18 17:07:42.000000000 -0500
@@ -202,6 +202,7 @@
 	int err = 0;
 
 	print_entry_location();
+	unionfs_read_lock(dentry->d_sb);
 	lock_dentry(dentry);
 	fist_print_dentry("IN unionfs_unlink", dentry);
 
@@ -215,6 +216,7 @@
 		d_drop(dentry);
 
 	unlock_dentry(dentry);
+	unionfs_read_unlock(dentry->d_sb);
 	print_exit_status(err);
 	return err;
 }
@@ -342,6 +344,7 @@
 	struct unionfs_dir_state *namelist = NULL;
 
 	print_entry_location();
+	unionfs_read_lock(dentry->d_sb);
 	lock_dentry(dentry);
 	fist_print_dentry("IN unionfs_rmdir: ", dentry);
 
@@ -397,6 +400,7 @@
 		free_rdstate(namelist);
 
 	unlock_dentry(dentry);
+	unionfs_read_unlock(dentry->d_sb);
 	print_exit_status(err);
 	return err;
 }
diff -rNu unionfs-20060117-2031/xattr.c unionfs-20060117-2031.lock/xattr.c
--- unionfs-20060117-2031/xattr.c	2006-01-17 20:31:48.000000000 -0500
+++ unionfs-20060117-2031.lock/xattr.c	2006-01-18 17:07:42.000000000 -0500
@@ -65,6 +65,8 @@
 
 	print_entry_location();
 
+	unionfs_read_lock(dentry->d_sb);
+
 	lock_dentry(dentry);
 
 	hidden_dentry = dtohd(dentry);
@@ -89,6 +91,7 @@
 	}
 
 	unlock_dentry(dentry);
+	unionfs_read_unlock(dentry->d_sb);
 	print_exit_status(err);
 	return err;
 }
@@ -105,6 +108,8 @@
 
 	print_entry_location();
 
+	unionfs_read_lock(dentry->d_sb);
+
 	lock_dentry(dentry);
 	hidden_dentry = dtohd(dentry);
 
@@ -121,6 +126,7 @@
 	}
 
 	unlock_dentry(dentry);
+	unionfs_read_unlock(dentry->d_sb);
 	print_exit_status(err);
 	return err;
 }
@@ -135,6 +141,7 @@
 	char *encoded_name;
 	print_entry_location();
 
+	unionfs_read_lock(dentry->d_sb);
 	lock_dentry(dentry);
 	hidden_dentry = dtohd(dentry);
 
@@ -153,6 +160,7 @@
 	}
 
 	unlock_dentry(dentry);
+	unionfs_read_unlock(dentry->d_sb);
 	print_exit_status(err);
 	return err;
 }
@@ -167,6 +175,7 @@
 	char *encoded_list = NULL;
 
 	print_entry_location();
+	unionfs_read_lock(dentry->d_sb);
 	lock_dentry(dentry);
 
 	hidden_dentry = dtohd(dentry);
@@ -183,6 +192,7 @@
 	}
 
 	unlock_dentry(dentry);
+	unionfs_read_unlock(dentry->d_sb);
 	print_exit_status(err);
 	return err;
 }
_______________________________________________
unionfs mailing list
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs

Reply via email to