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