Here is a patch for branchman.c bug.
This is minor since the bug will be the problem when an error occurs.
And I want you to check around RECORD_PATH_XXX().

This patch also checks the persistent ino is used or not.

Junjiro Okajima

--- branchman.c 5 Feb 2006 06:21:15 -0000       1.1
+++ branchman.c 6 Feb 2006 09:43:25 -0000
@@ -197,8 +197,12 @@ int unionfs_ioctl_addbranch(struct inode
        struct dentry *root = NULL;
        struct dentry *hidden_root = NULL;
 
        print_entry_location();
 
+       err = -EBUSY;
+       if (stopd(inode->i_sb)->usi_persistent)
+               goto out;
+
        err = -ENOMEM;
        addargs = KMALLOC(sizeof(struct unionfs_addbranch_args), GFP_KERNEL);
        if (!addargs)
@@ -208,35 +213,31 @@ int unionfs_ioctl_addbranch(struct inode
        if (copy_from_user
            (addargs, (const void __user *)arg,
             sizeof(struct unionfs_addbranch_args)))
-               goto out;
+               goto out_addargs;
 
        err = -EINVAL;
        if (addargs->ab_perms & ~(MAY_READ | MAY_WRITE | MAY_NFSRO))
-               goto out;
+               goto out_addargs;
        if (!(addargs->ab_perms & MAY_READ))
-               goto out;
+               goto out_addargs;
 
        err = -E2BIG;
        if (sbend(inode->i_sb) > FD_SETSIZE)
-               goto out;
+               goto out_addargs;
 
        err = -ENOMEM;
        if (!(path = getname((const char __user *)addargs->ab_path)))
-               goto out;
+               goto out_path;
 
        err = path_lookup(path, LOOKUP_FOLLOW, &nd);
-
-       RECORD_PATH_LOOKUP(&nd);
        if (err)
-               goto out;
-       if ((err = check_branch(&nd))) {
-               path_release(&nd);
-               RECORD_PATH_RELEASE(&nd);
-               goto out;
-       }
+               goto out_path;
+       if ((err = check_branch(&nd)))
+               goto out_nd;
+       RECORD_PATH_LOOKUP(&nd);
 
        unionfs_write_lock(inode->i_sb);
        lock_dentry(inode->i_sb->s_root);
 
        root = inode->i_sb->s_root;
        for (i = dbstart(inode->i_sb->s_root); i <= dbend(inode->i_sb->s_root);
@@ -244,17 +263,17 @@ int unionfs_ioctl_addbranch(struct inode
                hidden_root = dtohd_index(root, i);
                if (is_branch_overlap(hidden_root, nd.dentry)) {
                        err = -EINVAL;
-                       goto out;
+                       goto out_unlock;
                }
        }
 
        err = -EINVAL;
        if (addargs->ab_branch < 0
            || (addargs->ab_branch > (sbend(inode->i_sb) + 1)))
-               goto out;
+               goto out_unlock;
 
        if ((err = newputmap(inode->i_sb)))
-               goto out;
+               goto out_unlock;
 
        stopd(inode->i_sb)->b_end++;
        dtopd(inode->i_sb->s_root)->udi_bcount++;
@@ -281,7 +300,7 @@ int unionfs_ioctl_addbranch(struct inode
                if (!new_hidden_mnt || !new_udi_dentry || !new_uii_inode
                    || !new_counts || !new_usi_sb || !new_branchperms) {
                        err = -ENOMEM;
-                       goto out;
+                       goto out_free;
                }
        }
 
@@ -378,21 +397,27 @@ int unionfs_ioctl_addbranch(struct inode
 
        fixputmaps(inode->i_sb);
 
-      out:
-       unlock_dentry(inode->i_sb->s_root);
-       unionfs_write_unlock(inode->i_sb);
-
+      out_free:
        KFREE(new_hidden_mnt);
        KFREE(new_udi_dentry);
        KFREE(new_uii_inode);
        KFREE(new_usi_sb);
        KFREE(new_counts);
        KFREE(new_branchperms);
+      out_unlock:
+       unlock_dentry(inode->i_sb->s_root);
+       unionfs_write_unlock(inode->i_sb);
+      out_nd:
+       if (err) {
+               path_release(&nd);
+               RECORD_PATH_RELEASE(&nd);
+       }
+      out_path:
+       putname(path);
+      out_addargs:
        KFREE(addargs);
-       if (path)
-               putname(path);
-
+      out:
        print_exit_status(err);
 
        return err;
 }
_______________________________________________
unionfs mailing list
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs

Reply via email to