commit 10de835ec6d9c12780ba56ca37ff896804b11bba
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date: Wed May 30 15:43:20 2007 -0400
lookup only up to opaque branch if looking up an opaque dir
diff --git a/fs/unionfs/lookup.c b/fs/unionfs/lookup.c
index 33d0a7e..718b007 100644
--- a/fs/unionfs/lookup.c
+++ b/fs/unionfs/lookup.c
@@ -34,7 +34,7 @@ struct dentry *unionfs_lookup_backend(struct dentry *dentry,
struct dentry *hidden_dir_dentry = NULL;
struct dentry *parent_dentry = NULL;
struct dentry *d_interposed = NULL;
- int bindex, bstart, bend, bopaque;
+ int bindex, bstart, bend, bopaque = -1;
int dentry_count = 0; /* Number of positive dentries. */
int first_dentry_offset = -1; /* -1 is uninitialized */
struct dentry *first_dentry = NULL;
@@ -85,24 +85,33 @@ struct dentry *unionfs_lookup_backend(struct dentry *dentry,
nd = &new_nd;
}
+ /* Now start the actual lookup procedure. */
+ bstart = dbstart(parent_dentry);
+ bend = dbend(parent_dentry);
+
/* check if whiteout here */
if (dentry && UNIONFS_D(dentry) && UNIONFS_D(dentry->d_parent)){
err = odf_lookup(dentry->d_parent, dentry, 0);
if (err)
goto out;
- /* return negative dentry if a whiteout */
- if (UNIONFS_D(dentry)->odf.dentry &&
- UNIONFS_D(dentry)->odf.whiteout){
- bindex = 0;
- goto out_negative;
+ if (UNIONFS_D(dentry)->odf.dentry) {
+ /* return negative dentry if a whiteout */
+ if (UNIONFS_D(dentry)->odf.whiteout){
+ bindex = 0;
+ goto out_negative;
+ }
+ /* if opaque dir lookup only until opaque branch */
+ else if
(S_ISDIR(UNIONFS_D(dentry)->odf.dentry->d_inode->i_mode)) {
+ bopaque = odf_get_opaque(dentry->d_sb, dentry);
+ if (bopaque != -1)
+ bend = bopaque;
+ }
}
}
- /* Now start the actual lookup procedure. */
- bstart = dbstart(parent_dentry);
- bend = dbend(parent_dentry);
- bopaque = odf_get_opaque(parent_dentry->d_sb, parent_dentry);
+ if (bopaque == -1)
+ bopaque = odf_get_opaque(parent_dentry->d_sb, parent_dentry);
BUG_ON(bstart < 0);
/* It would be ideal if we could convert partial lookups to only have
@@ -298,29 +307,10 @@ out_positive:
if (err)
goto out_drop;
- /* check for whiteout && opaqueness */
- if (UNIONFS_D(dentry)->odf.dentry) {
- if (UNIONFS_D(dentry)->odf.whiteout){
- err = -ENOENT;
- goto out_drop;
- }
-
- /* if the dentry is an opaque dir we must release everything
after the opaqueness branch */
- else if (S_ISDIR(dentry->d_inode->i_mode) &&
- odf_get_opaque(dentry->d_sb, dentry) != -1) {
- for (bindex = dbend(dentry) + 1; bindex <
sbmax(dentry->d_sb); bindex++) {
- if (unionfs_lower_dentry_idx(dentry, bindex))
- dput(unionfs_lower_dentry_idx(dentry,
bindex));
- unionfs_set_lower_dentry_idx(dentry, bindex,
NULL);
- if (unionfs_lower_mnt_idx(dentry, bindex))
- unionfs_mntput(dentry, bindex);
- unionfs_set_lower_mnt_idx(dentry, bindex, NULL);
- if(unionfs_lower_inode_idx(dentry->d_inode,
bindex))
-
iput(unionfs_lower_inode_idx(dentry->d_inode, bindex));
- unionfs_set_lower_inode_idx(dentry->d_inode,
bindex, NULL);
-
- }
- }
+ /* check for whiteout */
+ if (UNIONFS_D(dentry)->odf.dentry && (UNIONFS_D(dentry)->odf.whiteout))
{
+ err = -ENOENT;
+ goto out_drop;
}
goto out;
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs