commit 3f58874e04b60828c8139ad16c5f4bee662c1d26
Merge: 754cd36... 4d167eb...
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date:   Mon May 28 23:24:51 2007 -0400

    Merge branch 'master' of story:/home/git/unionfs-odf into odf

diff --git a/Documentation/filesystems/unionfs/odf.txt 
b/Documentation/filesystems/unionfs/odf.txt
index 
a46cc7fd89c86a3e858f0c8075285d77f1c17739..4ee898553be88808e8b065affd6c16012d52e6d8
 100644
--- a/Documentation/filesystems/unionfs/odf.txt
+++ b/Documentation/filesystems/unionfs/odf.txt
@@ -1,6 +1,6 @@
                    ODF: On Disk Format for Unionfs 2.x
 
-                         (Updated April 13, 2007)
+                          (Updated May 25, 2007)
 
                      http://unionfs.filesystems.org/
 
diff --git a/fs/unionfs/copyup.c b/fs/unionfs/copyup.c
index 
373679b71c4837ada9e5cd5993bb8559405edc71..18eacad641efbed7471f417aa64876f7756e7c56
 100644
--- a/fs/unionfs/copyup.c
+++ b/fs/unionfs/copyup.c
@@ -184,6 +184,7 @@ static int __copyup_reg_data(struct dent
        struct super_block *sb = dentry->d_sb;
        struct file *input_file;
        struct file *output_file;
+       struct vfsmount *output_mnt;
        mm_segment_t old_fs;
        char *buf = NULL;
        ssize_t read_bytes, write_bytes;
@@ -211,12 +212,11 @@ static int __copyup_reg_data(struct dent
 
        /* open new file */
        dget(new_hidden_dentry);
-       unionfs_mntget(dentry, new_bindex);
+       output_mnt = unionfs_mntget(sb->s_root, new_bindex);
        unionfs_read_lock(sb);
        branchget(sb, new_bindex);
        unionfs_read_unlock(sb);
-       output_file = dentry_open(new_hidden_dentry,
-                                 unionfs_lower_mnt_idx(dentry, new_bindex),
+       output_file = dentry_open(new_hidden_dentry, output_mnt,
                                  O_WRONLY | O_LARGEFILE);
        if (IS_ERR(output_file)) {
                err = PTR_ERR(output_file);
diff --git a/fs/unionfs/dentry.c b/fs/unionfs/dentry.c
index 
1653267c1d5a5fa94861e633237f1954bcfecae8..c9ff88676db211d7daaf2819349400a67b020a20
 100644
--- a/fs/unionfs/dentry.c
+++ b/fs/unionfs/dentry.c
@@ -325,9 +325,11 @@ static void unionfs_d_release(struct den
        bend = dbend(dentry);
        for (bindex = bstart; bindex <= bend; bindex++) {
                dput(unionfs_lower_dentry_idx(dentry, bindex));
-               unionfs_mntput(dentry, bindex);
-
                unionfs_set_lower_dentry_idx(dentry, bindex, NULL);
+               /* NULL lower mnt is ok if this is a negative dentry */
+               if (!dentry->d_inode && !unionfs_lower_mnt_idx(dentry,bindex))
+                       continue;
+               unionfs_mntput(dentry, bindex);
                unionfs_set_lower_mnt_idx(dentry, bindex, NULL);
        }
        /* free private data (unionfs_dentry_info) here */
diff --git a/fs/unionfs/inode.c b/fs/unionfs/inode.c
index 
4ddf9b862dc521f8b9fcfae93423b423483dfd4c..0ce143d4278fe96a99ad772c1268c1500d847c83
 100644
--- a/fs/unionfs/inode.c
+++ b/fs/unionfs/inode.c
@@ -147,7 +147,6 @@ static struct dentry *unionfs_lookup(str
        if (!IS_ERR(ret)) {
                if (ret)
                        dentry = ret;
-               unionfs_inherit_mnt(dentry);
        }
 
        unionfs_check_inode(parent);
diff --git a/fs/unionfs/lookup.c b/fs/unionfs/lookup.c
index 
f8e4eb09f1b94b26aeb0ffdf80c2d5e47f64ae41..c42778011a0e8a86e7b0481cb5f9ca0551b10259
 100644
--- a/fs/unionfs/lookup.c
+++ b/fs/unionfs/lookup.c
@@ -19,8 +19,15 @@
 #include "union.h"
 
 /* The rest of these are utility functions for lookup. */
-struct dentry *unionfs_lookup_backend(struct dentry *dentry, struct nameidata 
*nd,
-                                     int lookupmode)
+
+/*
+ * Main (and complex) driver function for Unionfs's lookup
+ *
+ * Returns: NULL (ok), ERR_PTR if an error occurred, or a non-null non-error
+ * PTR if d_splice returned a different dentry.
+ */
+struct dentry *unionfs_lookup_backend(struct dentry *dentry,
+                                     struct nameidata *nd, int lookupmode)
 {
        int err = 0;
        struct dentry *hidden_dentry = NULL;
@@ -230,7 +237,7 @@ out_negative:
                 * mount-point crossing
                 */
                first_dentry = dentry;
-               first_hidden_mnt = unionfs_mntget(dentry, bindex);
+               first_hidden_mnt = unionfs_mntget(dentry->d_sb->s_root, bindex);
        }
        unionfs_set_lower_dentry_idx(dentry, first_dentry_offset,
                                     first_hidden_dentry);
@@ -352,32 +359,40 @@ out:
        return ERR_PTR(err);
 }
 
-/* This is a utility function that fills in a unionfs dentry */
+/*
+ * This is a utility function that fills in a unionfs dentry.
+ *
+ * Returns: 0 (ok), or -ERRNO if an error occurred.
+ */
 int unionfs_partial_lookup(struct dentry *dentry)
 {
        struct dentry *tmp;
        struct nameidata nd = { .flags = 0 };
+       int err = -ENOSYS;
 
        tmp = unionfs_lookup_backend(dentry, &nd, INTERPOSE_PARTIAL);
-       if (!tmp) {
-               int err = 0;
-               if (UNIONFS_D(dentry) && !UNIONFS_D(dentry)->odf.dentry) {
-                       tmp = unionfs_lower_dentry_idx(dentry, 0);
-                       if (dentry->d_inode || (tmp && tmp->d_inode)) {
-                               err = odf_lookup(dentry->d_parent, dentry, 0);
-                               if (err)
-                                       return  err;
-                               BUG_ON(!UNIONFS_D(dentry)->odf.dentry);
-                       }
+       if (IS_ERR(tmp)) {
+               err = PTR_ERR(tmp);
+               goto out;
+       }
+       if (tmp)
+               goto out;
 
+       if (UNIONFS_D(dentry) && !UNIONFS_D(dentry)->odf.dentry) {
+               tmp = unionfs_lower_dentry_idx(dentry, 0);
+               if (dentry->d_inode || (tmp && tmp->d_inode)) {
+                       err = odf_lookup(dentry->d_parent, dentry, 0);
+                       if (err)
+                               goto out;
+                       BUG_ON(!UNIONFS_D(dentry)->odf.dentry);
                }
-               return 0;
        }
-       if (IS_ERR(tmp))
-               return PTR_ERR(tmp);
+       err = 0;
+
+out:
        /* need to change the interface */
        BUG_ON(tmp != dentry);
-       return -ENOSYS;
+       return err;
 }
 
 /* The dentry cache is just so we have properly sized dentries. */
diff --git a/fs/unionfs/union.h b/fs/unionfs/union.h
index 
614d23332f4a0ab3ffeb06b83fa545fb96b30712..8daa7e4da53f8993590da1172a6e534a110bd1e6
 100644
--- a/fs/unionfs/union.h
+++ b/fs/unionfs/union.h
@@ -497,9 +497,19 @@ #endif /* UNIONFS_DEBUG */
                        return;
                if (!mnt && bindex >= 0) {
 #ifdef UNIONFS_DEBUG
-                       printk(KERN_DEBUG
-                              "unionfs_mntput: mnt=%p bindex=%d\n",
-                              mnt, bindex);
+                       /*
+                        * Directories can have NULL lower objects in
+                        * between start/end, but NOT if at the start/end
+                        * range.  We cannot verify that this dentry is a
+                        * type=DIR, because it may already be a negative
+                        * dentry.  But if dbstart is greater than dbend, we
+                        * know that this couldn't have been a regular file:
+                        * it had to have been a directory.
+                        */
+                       if (!(bindex > dbstart(dentry) && bindex < 
dbend(dentry)))
+                               printk(KERN_WARNING
+                                      "unionfs_mntput: mnt=%p bindex=%d\n",
+                                      mnt, bindex);
 #endif /* UNIONFS_DEBUG */
                        return;
                }
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to