commit 3730adac4ea11340a7b83b2db86facd0fff0ac49
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date:   Fri May 25 22:50:15 2007 -0400

    modified odf_lookup functions to return a dentry instead of an
    
    odf_dentry_info

diff --git a/fs/unionfs/commonfops.c b/fs/unionfs/commonfops.c
index 8ad5ed6..b9bc33b 100644
--- a/fs/unionfs/commonfops.c
+++ b/fs/unionfs/commonfops.c
@@ -111,7 +111,6 @@ int unionfs_silly_rename(struct dentry *dentry, struct 
dentry *hidden_dentry)
        struct dentry *tmp_dentry = NULL;
        struct dentry *hidden_old_dir_dentry;
        struct dentry *hidden_new_dir_dentry;
-       struct odf_dentry_info *odi = NULL;
 
        sprintf(name, ".unionfs%*.*lx",
                        i_inosize, i_inosize, hidden_dentry->d_inode->i_ino);
@@ -154,12 +153,13 @@ int unionfs_silly_rename(struct dentry *dentry, struct 
dentry *hidden_dentry)
                goto out;
 
        /* create a whiteout */
-       odi = odf_lookup_name(&UNIONFS_SB(dentry->d_sb)->odf,
-                               UNIONFS_D(dentry->d_parent)->odf_info,
-                               name, strlen(name), ODF_LOOKUP_WH, odi);
-       BUG_ON(IS_ERR(odi) || odi == NULL);
+       tmp_dentry = odf_lookup_name(dentry->d_parent, name,
+                                       strlen(name), ODF_LOOKUP_WH);
+       if (IS_ERR(tmp_dentry))
+               err = PTR_ERR(tmp_dentry);
+       else
+               dput(tmp_dentry);
 out:
-       odf_put_info(odi);
        return err;
 }
 
diff --git a/fs/unionfs/dirhelper.c b/fs/unionfs/dirhelper.c
index 62f71ba..a811945 100644
--- a/fs/unionfs/dirhelper.c
+++ b/fs/unionfs/dirhelper.c
@@ -129,9 +129,9 @@ static int readdir_util_callback(void *dirent, const char 
*name, int namelen,
 
        int err = 0;
        struct unionfs_rdutil_callback *buf = dirent;
-       int whiteout = 0;
+       int whiteout = 0, not_in_odf = 0;
        struct filldir_node *found;
-       struct odf_dentry_info *odi = NULL;
+       struct dentry *odf_dentry = NULL;
 
        if (buf->mode == RD_CHECK_EMPTY || buf->mode == RD_CHECK_HD_EMPTY)
                buf->filldir_called = 1;
@@ -153,20 +153,24 @@ static int readdir_util_callback(void *dirent, const char 
*name, int namelen,
        }
 
        /* check odf */
-       odi = odf_lookup_name(&UNIONFS_SB(buf->dir->d_sb)->odf,
-                       UNIONFS_D(buf->dir)->odf_info,
-                       name, namelen, ODF_LOOKUP_LOCKED, NULL);
-       if (IS_ERR(odi)){
-               odi = NULL;
-               goto out;
+       odf_dentry = odf_lookup_name(buf->dir, name, namelen, 0);
+       if (IS_ERR(odf_dentry)){
+               if (PTR_ERR(odf_dentry) == -ENOENT) {
+                       odf_dentry = NULL;
+                       not_in_odf = 1;
+               }
+               else {
+                       odf_dentry = NULL;
+                       goto out;
+               }
        }
-       if ((odi && !odi->whiteout) || !odi) {
+       if ((odf_dentry || not_in_odf)) {
                if (buf->mode == RD_CHECK_EMPTY) {
                        err = -ENOTEMPTY;
                        goto out;
                }
        }
-       if (odi && odi->whiteout)
+       if (!odf_dentry && !not_in_odf)
                whiteout = 1;
 find:
        found = find_filldir_node(buf->rdstate, name, namelen);
@@ -179,8 +183,8 @@ find:
        if (err || buf->mode != RD_CACHE_ODF || !buf->filp || whiteout)
                goto out;
 
-       if (odi)
-               ino = odi->dentry->d_inode->i_ino;
+       if (odf_dentry)
+               ino = odf_dentry->d_inode->i_ino;
        err = odf_write_dirent(buf->filp, name, namelen, ino, d_type);
 out:
        odf_put_info(odi);
diff --git a/fs/unionfs/odf.c b/fs/unionfs/odf.c
index b8ff210..fdbf681 100644
--- a/fs/unionfs/odf.c
+++ b/fs/unionfs/odf.c
@@ -899,7 +899,7 @@ out:
 int odf_lookup(struct dentry *parent, struct dentry *dentry, int flags)
 {
        struct odf_sb_info *osi = &UNIONFS_SB(dentry->d_sb)->odf;
-       struct dentry *links = NULL;
+       struct dentry *ret, *links = NULL;
        struct dentry *lower_dentry = NULL;
        struct file *link_file = NULL;
        char *name, *uuid;
@@ -960,21 +960,10 @@ int odf_lookup(struct dentry *parent, struct dentry 
*dentry, int flags)
                */
        }
 
-       UNIONFS_D(dentry)->odf_info = __odf_lookup(
-                               &UNIONFS_SB(dentry->d_sb)->odf,
-                               UNIONFS_D(parent)->odf_info,
-                               dentry->d_name.name,
-                               dentry->d_name.len,
-                               flags,
-                               UNIONFS_D(dentry)->odf_info,
-                               NULL);
-       if (IS_ERR(UNIONFS_D(dentry)->odf_info)){
-               err = PTR_ERR(UNIONFS_D(dentry)->odf_info);
-               UNIONFS_D(dentry)->odf_info = NULL;
-               goto out;
-       }
-       else if (UNIONFS_D(dentry)->odf_info == NULL)
-               goto out;
+       ret = __odf_lookup(parent, dentry, dentry->d_name.name,
+                          dentry->d_name.len, flags, NULL);
+       if (IS_ERR(ret))
+               err = PTR_ERR(ret);
 
 out:
        dput(links);
@@ -982,30 +971,41 @@ out:
                filp_close(link_file, NULL);
        return err;
 }
+struct dentry *odf_lookup_name(struct dentry *parent, const char *name, int 
len, int flags)
+{
+        return __odf_lookup(parent, NULL, name, len, flags, NULL);
+}
 
-struct odf_dentry_info *__odf_lookup(struct odf_sb_info *osi,
-                       struct odf_dentry_info *parent,
-                       const char *name, int len, int flags,
-                       struct odf_dentry_info *old_odi,
-                       struct dentry *link)
+struct dentry *__odf_lookup(struct dentry *parent,
+                           struct dentry *target,
+                           const char *name, int len, int flags,
+                           struct dentry *link)
 {
-       struct dentry *odf_dentry;
-       struct odf_dentry_info *odi = old_odi;
-       struct inode *odf_i_dir = parent->dentry->d_inode;
+       struct dentry *odf_dentry, *odf_parent;
+       struct inode *odf_i_dir;
+       struct odf_sb_info *osi = &UNIONFS_SB(parent->d_sb)->odf;
        int opaque, err = 0, cleaned = 0;
        uid_t olduid = current->fsuid;
        gid_t oldgid = current->fsgid;
 
        BUG_ON((flags & ODF_LOOKUP_FILE) && (flags & ODF_LOOKUP_DIR));
        BUG_ON((flags & ODF_LOOKUP_WH) && (flags != ODF_LOOKUP_WH));
-       BUG_ON((flags & ODF_LOOKUP_LINK) && (flags & ODF_LOOKUP_DIR));
+       BUG_ON(link && (flags & ODF_LOOKUP_DIR));
+
+       /* clear the odf_dentry_info of target */
+       if (target) {
+               dput(UNIONFS_D(target)->odf.dentry);
+               UNIONFS_D(target)->odf.dentry = NULL;
+       }
+
+       odf_parent = UNIONFS_D(parent)->odf.dentry;
+       odf_i_dir = odf_parent->d_inode;
 
-       odf_dentry = lookup_one_len(name, parent->dentry, len);
+       /* lookup in the odf */
+       odf_dentry = lookup_one_len(name, odf_parent, len);
 
        if (IS_ERR(odf_dentry)) {
                printk("odf_lookup: failed to lookup %s\n", name);
-               odf_put_info(old_odi);
-               odi = (struct odf_dentry_info *)odf_dentry;
                goto out;
        }
 
@@ -1014,7 +1014,7 @@ struct odf_dentry_info *__odf_lookup(struct odf_sb_info 
*osi,
                if (__odf_is_wh(osi, odf_dentry)){
                        vfs_unlink(odf_i_dir, odf_dentry);
                        dput(odf_dentry);
-                       odf_dentry = lookup_one_len(name, parent->dentry, len);
+                       odf_dentry = lookup_one_len(name, odf_parent, len);
                }
        }
 
@@ -1022,14 +1022,14 @@ struct odf_dentry_info *__odf_lookup(struct odf_sb_info 
*osi,
        if (flags & ODF_LOOKUP_WH)
                BUG_ON(odf_dentry->d_inode && !__odf_is_wh(osi, odf_dentry));
 
-       /* create inode in odf if dont exist */
+       /* create an entry in the odf if dont exist */
        if (!odf_dentry->d_inode) {
 
                if (name[0]=='.')
                        BUG_ON(len==1 || (name[1]=='.'&&len==2));
 retry:
                /* FIXME need to check hardlinks before create */
-               if (link && (flags & (ODF_LOOKUP_FILE | ODF_LOOKUP_LINK))) {
+               if (link && (flags & ODF_LOOKUP_FILE)) {
                        /* link to the given dentry */
                        vfs_link(link, odf_dentry->d_parent->d_inode, 
odf_dentry);
                }
@@ -1050,8 +1050,7 @@ retry:
                }
                else {
                        dput(odf_dentry);
-                       odf_put_info(old_odi);
-                       odi = NULL;
+                       odf_dentry = ERR_PTR(-ENOENT);
                        goto out;
                }
 
@@ -1065,10 +1064,11 @@ retry:
                                wake_up_and_wait_sioa(osi->cleanup);
                                goto retry;
                        }
-                       printk(KERN_WARNING "odf_lookup: could not create odf 
dentry %s, %d\n", name, err);
+                       printk(KERN_WARNING
+                               "odf_lookup: could not create odf dentry %s, 
%d\n",
+                               name, err);
                        dput(odf_dentry);
-                       odf_put_info(old_odi);
-                       odi = ERR_PTR(err);
+                       odf_dentry = ERR_PTR(err);
                        goto out;
                }
 
@@ -1081,10 +1081,26 @@ retry:
                   and if not, link them */
        }
 
-       odi = odf_fill_info(old_odi, osi, odf_dentry);
-       dput(odf_dentry); /* since we dget in fill_info */
+       if (odf_dentry && !IS_ERR(odf_dentry)) {
+               /* fill in the odf_dentry_info struct of target */
+               if (target) {
+                       UNIONFS_D(target)->odf.dentry = odf_dentry;
+                       UNIONFS_D(target)->odf.whiteout =
+                               __odf_is_wh(osi, odf_dentry);
+                       UNIONFS_D(target)->odf.opaque =
+                               __odf_get_opaque(odf_dentry->d_inode);
+               }
+
+               if (__odf_is_wh(osi, odf_dentry)) {
+                       if (!target)
+                               dput(odf_dentry);
+                       odf_dentry = NULL;
+               }
+       }
+       else if (!odf_dentry)
+               odf_dentry = ERR_PTR(-ENOENT);
 out:
-       return odi;
+       return odf_dentry;
 }
 
 /*
@@ -1127,9 +1143,9 @@ struct dentry *odf_ic_dentry(struct odf_sb_info *osi, u64 
ino, char *name, int n
                dirs[i] = NULL;
        }
 
-       current->fsuid = olduid;
-       current->fsgid = oldgid;
-       
+       current->fsuid = 0;
+       current->fsgid = 0;
+
        memset(tmp_name,0,6);
        sprintf(tmp_name, "%x", breakdown[0]);
 
@@ -1176,7 +1192,7 @@ struct dentry *odf_ic_dentry(struct odf_sb_info *osi, u64 
ino, char *name, int n
 out:
        current->fsuid = olduid;
        current->fsgid = oldgid;
-       
+
        for (i = 0; i < 4; i++)
                dput(dirs[i]);
 
diff --git a/fs/unionfs/odf.h b/fs/unionfs/odf.h
index 02bd942..9a3c25d 100644
--- a/fs/unionfs/odf.h
+++ b/fs/unionfs/odf.h
@@ -57,15 +57,9 @@ static inline char *odf_get_branch_uuid(struct odf_sb_info 
*odf, int branch)
 
 /* lookup */
 int odf_lookup(struct dentry *parent, struct dentry *dentry, int flags);
-struct odf_dentry_info *__odf_lookup(struct odf_sb_info *osi, struct 
odf_dentry_info *parent,
-               const char *name, int len, int flags, struct odf_dentry_info 
*old_odi,
-               struct dentry *link);
-static inline struct odf_dentry_info *odf_lookup_name(struct odf_sb_info *osi,
-               struct odf_dentry_info *parent, const char *name, int len,
-               int flags, struct odf_dentry_info *old_odi)
-{
-       return __odf_lookup(osi, parent, name, len, flags, old_odi, NULL);
-}
+struct dentry *__odf_lookup(struct dentry *parent, struct dentry *target,
+                           const char *name, int len, int flags, struct dentry 
*link);
+struct dentry *odf_lookup_name(struct dentry *parent, const char *name, int 
len, int flags);
 struct dentry* odf_getdir(struct dentry *d_odf, const char *name, int len);
 struct odf_dentry_info *odf_fill_info(struct odf_dentry_info *odi,
                struct odf_sb_info *osi, struct dentry *odf_dentry);
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to