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

Reply via email to