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