[Unionfs] Can't mount NFS-exported union anymore in unionfs-1.4

hooanon05 at yahoo.co.jp hooanon05 at yahoo.co.jp
Fri Nov 24 22:59:04 EST 2006


Wilhelm Meier:
> As I said before the two branches are on the same fs, so I get:
> 
> gs tftproot # unionimap -c gbf.map
> gs tftproot # unionimap -a gbf.map gbro.map /tftproot/gentoo_A
> gs tftproot # unionimap -a gbf.map gbrw.map /tftproot/gentoo_Bdiff
> Specified fs already exists in the forward map

I think it is a bug of unionfs, and here is a patch.
It allows unionfs to share the reverse maps.
I hope this fix your oops at mount time, but I am not sure it can fix
all of your problem.

And I want people whoever want to export unionfs via NFS to read these
mails.
http://www.fsl.cs.sunysb.edu/pipermail/unionfs/2006-June/004603.html
http://www.fsl.cs.sunysb.edu/pipermail/unionfs/2006-August/004741.html
http://www.fsl.cs.sunysb.edu/pipermail/unionfs/2006-August/004748.html
http://www.fsl.cs.sunysb.edu/pipermail/unionfs/2006-August/004749.html
http://www.fsl.cs.sunysb.edu/pipermail/unionfs/2006-August/004755.html
http://www.fsl.cs.sunysb.edu/pipermail/unionfs/2006-August/004756.html


Junjiro Okajima


Index: branchman.c
===================================================================
RCS file: /home/cvs/unionfs/unionfs/branchman.c,v
retrieving revision 1.66
diff -u -p -r1.66 branchman.c
--- branchman.c	31 Oct 2006 00:05:22 -0000	1.66
+++ branchman.c	25 Nov 2006 03:50:10 -0000
@@ -214,7 +214,7 @@ int unionfs_ioctl_addbranch(struct inode
 	print_entry_location();
 
 #ifdef UNIONFS_IMAP
-	if (stopd(sb)->usi_persistent) {
+	if (stopd(inode->i_sb)->usi_persistent) {
 		printk(KERN_ERR "Cannot manipulate branches if imap is used\n");
 		err = -EPERM;
 		goto out;
Index: main.c
===================================================================
RCS file: /home/cvs/unionfs/unionfs/main.c,v
retrieving revision 1.176
diff -u -p -r1.176 main.c
--- main.c	10 Oct 2006 07:28:13 -0000	1.176
+++ main.c	25 Nov 2006 03:50:10 -0000
@@ -581,6 +581,13 @@ static struct unionfs_dentry_info *union
 		err = -EINVAL;
 		goto out_error;
 	}
+#ifdef UNIONFS_IMAP
+	else if (stopd(sb)->usi_persistent) {
+		err = share_imap(stopd(sb), hidden_root_info);
+		if (err)
+			goto out_error;
+	}
+#endif
 	goto out;
 
       out_error:
Index: persistent_inode.c
===================================================================
RCS file: /home/cvs/unionfs/unionfs/persistent_inode.c,v
retrieving revision 1.36
diff -u -p -r1.36 persistent_inode.c
--- persistent_inode.c	8 Jul 2006 17:58:31 -0000	1.36
+++ persistent_inode.c	25 Nov 2006 03:50:10 -0000
@@ -211,7 +211,7 @@ static int verify_reversemap(struct supe
 
 			d = hidden_root_info->udi_dentry[bindex];
 
-			err = d->d_sb->s_op->statfs(d->d_sb, &st);
+			err = d->d_sb->s_op->statfs(d, &st);
 			if (err)
 				goto out;
 
@@ -439,6 +439,38 @@ int parse_imap_option(struct super_block
 	return err;
 }
 
+/*
+ * When several branches are on same superblock, unionfs shares reverse maps for them.
+ */
+int share_imap(struct unionfs_sb_info *sbi, struct unionfs_dentry_info *hidden_root_info)
+{
+	int bindex, bend, i;
+	struct super_block *hidden_sb;
+
+	bend = hidden_root_info->udi_bend;
+	for (bindex = 0; bindex <= bend; bindex++) {
+		if (sbi->usi_reversemaps[bindex])
+			continue;
+		hidden_sb = hidden_root_info->udi_dentry[bindex]->d_sb;
+		for (i = 0; i < bend; i++) {
+			if (i == bindex
+			    || !sbi->usi_reversemaps[i]
+			    || hidden_sb != hidden_root_info->udi_dentry[i]->d_sb)
+				continue;
+			sbi->usi_reversemaps[bindex] = sbi->usi_reversemaps[i];
+			get_file(sbi->usi_reversemaps[bindex]);
+			break;
+		}
+		if (!sbi->usi_reversemaps[bindex]) {
+			printk(KERN_WARNING "no reverse map for branch %d\n",
+			       bindex);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
  /*
   * get @ino from @hidden_ino.
   */
@@ -540,6 +572,9 @@ int read_uin(struct super_block *sb, uin
 	spd = stopd(sb);
 	BUG_ON(!spd);
 
+	/* read/write lock per file is necessary */
+	mutex_lock(&sb->s_lock);
+
 	/* Find appropriate reverse map and then read from the required position */
 	/* get it from the array. */
 	err = __read_uin(spd, inode_number, branchnum, uino);
@@ -553,13 +588,12 @@ int read_uin(struct super_block *sb, uin
 	/* If we haven't found an entry and we have the O_CREAT flag set we want to
 	 * create a new entry write it out to the file and return its index
 	 */
-	mutex_lock(&sb->s_lock);
 	*uino = spd->usi_next_avail++;
 	err = __write_uin(spd, *uino, branchnum, inode_number);
 	if (err)
 		spd->usi_next_avail--;
-	mutex_unlock(&sb->s_lock);
       out:
+	mutex_unlock(&sb->s_lock);
 	print_exit_status(err);
 	return err;
 }
Index: unionfs_imap.h
===================================================================
RCS file: /home/cvs/unionfs/unionfs/unionfs_imap.h,v
retrieving revision 1.1
diff -u -p -r1.1 unionfs_imap.h
--- unionfs_imap.h	30 May 2006 21:38:45 -0000	1.1
+++ unionfs_imap.h	25 Nov 2006 03:50:10 -0000
@@ -72,6 +72,8 @@ extern int parse_imap_option(struct supe
 			     struct unionfs_dentry_info *hidden_root_info,
 			     char *options);
 extern void cleanup_imap_data(struct super_block *sb);
+extern int share_imap(struct unionfs_sb_info *sbi,
+		      struct unionfs_dentry_info *hidden_root_info);
 
 #endif				/*#ifdef UNIONFS_IMAP */
 



More information about the unionfs mailing list