And this is a patch for the third problem.
- store the inode number at copyup.
Applying this patch, you will meet another problem about link(2).
I will post a patch later.
Junjiro Okajima
diff -u -p -r1.1 -r1.2
--- unionfs-20060117-2031/copyup.c 18 Jan 2006 03:02:19 -0000 1.1
+++ unionfs-20060117-2031/copyup.c 18 Jan 2006 08:58:11 -0000 1.2
@@ -200,7 +200,7 @@ int copyup_named_dentry(struct inode *di
int old_bstart;
int old_bend;
int size = len;
- struct dentry *new_hidden_parent_dentry;
+ struct dentry *new_hidden_parent_dentry = NULL;
mm_segment_t oldfs;
char *symbuf = NULL;
uid_t saved_uid = current->fsuid;
@@ -288,7 +288,6 @@ int copyup_named_dentry(struct inode *di
}
current->fsuid = saved_uid;
current->fsgid = saved_gid;
- unlock_dir(new_hidden_parent_dentry);
copyup_readlink_err:
KFREE(symbuf);
if (err) {
@@ -297,9 +296,16 @@ int copyup_named_dentry(struct inode *di
set_dtohd_index(dentry, new_bindex, NULL);
set_dbstart(dentry, old_bstart);
set_dbend(dentry, old_bend);
- goto out;
+ goto out_dir;
}
+ if (stopd(sb)->usi_persistent) {
+ err = write_uin(dentry->d_sb, dentry->d_inode->i_ino,
+ new_bindex, new_hidden_dentry->d_inode->i_ino);
+ if (err)
+ goto out_dir;
+ }
+
/* We actually copyup the file here. */
if (S_ISREG(old_hidden_dentry->d_inode->i_mode)) {
mntget(stohiddenmnt_index(sb, old_bindex));
@@ -310,11 +316,11 @@ int copyup_named_dentry(struct inode *di
stohiddenmnt_index(sb, old_bindex), O_RDONLY);
if (IS_ERR(input_file)) {
err = PTR_ERR(input_file);
- goto out;
+ goto out_dir;
}
if (!input_file->f_op || !input_file->f_op->read) {
err = -EINVAL;
- goto out;
+ goto out_dir;
}
/* copy the new file */
@@ -327,18 +333,18 @@ int copyup_named_dentry(struct inode *di
stohiddenmnt_index(sb, new_bindex), O_WRONLY);
if (IS_ERR(output_file)) {
err = PTR_ERR(output_file);
- goto out;
+ goto out_dir;
}
if (!output_file->f_op || !output_file->f_op->write) {
err = -EINVAL;
- goto out;
+ goto out_dir;
}
/* allocating a buffer */
buf = (char *)KMALLOC(PAGE_SIZE, GFP_KERNEL);
if (!buf) {
err = -ENOMEM;
- goto out;
+ goto out_dir;
}
/* now read PAGE_SIZE bytes from offset 0 in a loop */
@@ -382,15 +388,18 @@ int copyup_named_dentry(struct inode *di
/* Set permissions. */
if ((err =
copyup_permissions(sb, old_hidden_dentry, new_hidden_dentry)))
- goto out;
+ goto out_dir;
/* Selinux uses extended attributes for permissions. */
if ((err = copyup_xattrs(old_hidden_dentry, new_hidden_dentry)))
- goto out;
+ goto out_dir;
/* do not allow files getting deleted to be reinterposed */
if (!d_deleted(dentry))
unionfs_reinterpose(dentry);
+ out_dir:
+ if (new_hidden_parent_dentry)
+ unlock_dir(new_hidden_parent_dentry);
out:
if (input_file && !IS_ERR(input_file)) {
fput(input_file);
@@ -509,6 +518,8 @@ struct dentry *create_parents_named(stru
int old_bend;
struct dentry **path = NULL;
struct dentry **tmp_path;
+ struct super_block *sb;
+ int persistent;
print_entry_location();
@@ -529,7 +540,10 @@ struct dentry *create_parents_named(stru
old_bstart = dbstart(dentry);
old_bend = dbend(dentry);
+ hidden_dentry = ERR_PTR(-ENOMEM);
path = (struct dentry **)KZALLOC(kmalloc_size, GFP_KERNEL);
+ if (!path)
+ goto out;
/* assume the negative dentry of unionfs as the parent dentry */
parent_dentry = dentry;
@@ -575,6 +589,9 @@ struct dentry *create_parents_named(stru
} while (!hidden_parent_dentry);
count--;
+ sb = dentry->d_sb;
+ persistent = stopd(sb)->usi_persistent;
+
/* This is basically while(child_dentry != dentry). This loop is
* horrible to follow and should be replaced with cleaner code. */
while (1) {
@@ -667,20 +684,25 @@ struct dentry *create_parents_named(stru
hidden_dentry, S_IRWXUGO);
current->fsuid = saved_uid;
current->fsgid = saved_gid;
+ if (!err)
+ err =copyup_permissions
+ (dir->i_sb, child_dentry,hidden_dentry);
unlock_dir(hidden_parent_dentry);
- if (err || !hidden_dentry->d_inode) {
- DPUT(hidden_dentry);
- hidden_dentry = ERR_PTR(err);
- goto out;
- }
- err =
- copyup_permissions(dir->i_sb, child_dentry,
- hidden_dentry);
if (err) {
DPUT(hidden_dentry);
hidden_dentry = ERR_PTR(err);
goto out;
}
+ if (persistent) {
+ err = write_uin
+ (sb, child_dentry->d_inode->i_ino,
+ bindex, hidden_dentry->d_inode->i_ino);
+ if (err) {
+ DPUT(hidden_dentry);
+ hidden_dentry = ERR_PTR(err);
+ goto out;
+ }
+ }
set_itohi_index(child_dentry->d_inode, bindex,
igrab(hidden_dentry->d_inode));
if (ibstart(child_dentry->d_inode) > bindex)
_______________________________________________
unionfs mailing list
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs