commit 5165634a14c51726bced7f4d06c93f3da94c5ffe
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date:   Tue Apr 3 19:04:54 2007 -0400

    preparing for hardlinks

diff --git a/fs/unionfs/commonfops.c b/fs/unionfs/commonfops.c
index 8da5161..7127cb9 100644
--- a/fs/unionfs/commonfops.c
+++ b/fs/unionfs/commonfops.c
@@ -471,7 +471,7 @@ static int __open_dir(struct inode *inode, struct file 
*file)
                unionfs_read_unlock(inode->i_sb);
        }
        
-       odi = odf_ic_dir(file->f_dentry);
+       odi = odf_ic_cache_dentry(file->f_dentry);
        if (IS_ERR(odi))
                return PTR_ERR(odi);
        err = odf_cache_dir(file->f_dentry, odi->dentry, newest);
diff --git a/fs/unionfs/dirfops.c b/fs/unionfs/dirfops.c
index 8991ca3..0eb0538 100644
--- a/fs/unionfs/dirfops.c
+++ b/fs/unionfs/dirfops.c
@@ -39,7 +39,7 @@ static int unionfs_readdir(struct file *file, void *dirent, 
filldir_t filldir)
 
        /* Get the odf/ic file */
        /* FIXME: this should be saved somewhere, also check mtime */
-       odi = odf_ic_dir(file->f_dentry);
+       odi = odf_ic_cache_dentry(file->f_dentry);
        if (IS_ERR(odi)){
                err = PTR_ERR(odi);
                odi = NULL;
diff --git a/fs/unionfs/dirhelper.c b/fs/unionfs/dirhelper.c
index f4cfb0d..7fc8271 100644
--- a/fs/unionfs/dirhelper.c
+++ b/fs/unionfs/dirhelper.c
@@ -142,12 +142,6 @@ static int readdir_util_callback(void *dirent, const char 
*name, int namelen,
        struct filldir_node *found;
        struct odf_dentry_info *odi = NULL;
        
-       /* FIXME: do we want to create(assign inode/nos) on reeddirs?
-        * or do we want to do it on interpose? (if we do it on
-        * interpose lsing a fresh union will not assign inos to dirs
-        */
-       int create_flag = d_type == DT_DIR ? ODF_LOOKUP_DIR : ODF_LOOKUP_FILE;
-
        if (buf->mode == RD_CHECK_EMPTY || buf->mode == RD_CHECK_HD_EMPTY)
                buf->filldir_called = 1;
        else
@@ -157,8 +151,6 @@ static int readdir_util_callback(void *dirent, const char 
*name, int namelen,
                (namelen == 1 || (name[1] == '.' && namelen == 2))){
                if (buf->mode != RD_CACHE_ODF)
                        goto out;
-               else
-                       create_flag = 0;
        }
        
        /* we dont care about odf when checking hidden dirs */
@@ -170,7 +162,7 @@ static int readdir_util_callback(void *dirent, const char 
*name, int namelen,
        /* check odf */
        odi = __odf_lookup(UNIONFS_SB(buf->dir->d_sb)->odf,
                        UNIONFS_D(buf->dir)->odf_info, 
-                       name, namelen, create_flag | ODF_LOOKUP_LOCKED, 0);
+                       name, namelen, ODF_LOOKUP_LOCKED, 0);
        if (IS_ERR(odi)){
                odi = NULL;
                goto out;
diff --git a/fs/unionfs/odf.c b/fs/unionfs/odf.c
index a6176b1..191ae17 100644
--- a/fs/unionfs/odf.c
+++ b/fs/unionfs/odf.c
@@ -394,7 +394,38 @@ out:
  */
 int odf_lookup(struct dentry *parent, struct dentry *dentry, int flags)
 {      
-       int err = 0;
+       struct odf_dentry_info *links = NULL;
+       struct dentry *lower_dentry = NULL;
+       char *name, *uuid;
+       int bstart, err = 0;
+
+       /* this might be called before interpose */
+       for (bstart = 0; bstart <= dbend(dentry); bstart++) {
+               lower_dentry = unionfs_lower_dentry_idx(dentry, bstart);
+               if (lower_dentry)
+                       break;
+       }
+
+       if (lower_dentry && lower_dentry->d_inode &&
+               lower_dentry->d_inode->i_nlink > 1 &&
+               !S_ISDIR(lower_dentry->d_inode->i_mode)) {
+
+               name = kmalloc(UUID_LEN * 2 + 1,GFP_KERNEL);
+               uuid = odf_get_branch_uuid(UNIONFS_SB(dentry->d_sb)->odf, 
bstart);
+               sprintf(name,"%x%x%x%x", *(unsigned int *) uuid,
+                                       *(unsigned int *) uuid + 4,
+                                       *(unsigned int *) uuid + 8,
+                                       *(unsigned int *) uuid + 12);
+               links = odf_ic_dentry(UNIONFS_SB(dentry->d_sb)->odf,
+                               lower_dentry->d_inode->i_ino, name, 
strlen(name));
+               kfree(name);
+               if (IS_ERR(links)) {
+                       err = PTR_ERR(links);
+                       goto out;
+               }
+               odf_put_info(links);
+       }
+
        UNIONFS_D(dentry)->odf_info = __odf_lookup(
                                UNIONFS_SB(dentry->d_sb)->odf,
                                UNIONFS_D(parent)->odf_info,
@@ -406,6 +437,7 @@ int odf_lookup(struct dentry *parent, struct dentry 
*dentry, int flags)
                err = PTR_ERR(UNIONFS_D(dentry)->odf_info);
                UNIONFS_D(dentry)->odf_info = NULL;
        }
+out:
        return err;
 }
 
@@ -530,46 +562,52 @@ out:
  * Returns odf_dentry_info pointing to the location in the odf
  * for the given directory's cached contents
  */
-struct odf_dentry_info *odf_ic_dir(struct dentry *dir)
+struct odf_dentry_info *odf_ic_cache_dentry(struct dentry *dir)
 {
-       struct odf_dentry_info *odi_dir, *odis[4], *odi_ic, *odi_ret = NULL;
-       struct odf_sb_info *osi;
-       u64 ino;
+       struct odf_dentry_info *odi_dir;
+
+       odi_dir = UNIONFS_D(dir)->odf_info;
+       if (!odi_dir)
+               return ERR_PTR(-ENOENT);
+
+       if (!S_ISDIR(dir->d_inode->i_mode))
+               return ERR_PTR(-ENOTDIR);
+
+       return odf_ic_dentry(UNIONFS_SB(dir->d_sb)->odf, 
+               dir->d_inode->i_ino, ODF_CONTENT, ODF_CONTENT_LEN);
+}
+
+/*
+ * Returns odf_dentry_info pointing to the location in odf/ic
+ * for the requested file name
+ */
+struct odf_dentry_info *odf_ic_dentry(struct odf_sb_info *osi, u64 ino, char 
*name, int namelen)
+{
+       struct odf_dentry_info *odis[4], *odi_ic, *odi_ret = NULL;
        int breakdown[4];
-       char name[6];
+       char tmp_name[6];
        int i, err = 0;
 
-       if (!S_ISDIR(dir->d_inode->i_mode)) {
-               err = -ENOTDIR;
-               goto out;
-       }
-       osi = UNIONFS_SB(dir->d_sb)->odf;
        odi_ic = osi->odi_ic;
-       odi_dir = UNIONFS_D(dir)->odf_info;
-       if (!odi_dir) {
-               err = -ENOENT;
-               goto out;
-       }
        
-       ino = odi_dir->inum;
        for (i = 3; i >= 0; i--) {
                breakdown[i] = ino & 0xFFFF;
                ino >>= 16;
                odis[i] = NULL;
        }
 
-       memset(name,0,6);
-       sprintf(name, "%x", breakdown[0]);
-       odis[0] = __odf_lookup(osi, odi_ic, name, strlen(name), ODF_LOOKUP_DIR, 
NULL);
+       memset(tmp_name,0,6);
+       sprintf(tmp_name, "%x", breakdown[0]);
+       odis[0] = __odf_lookup(osi, odi_ic, tmp_name, strlen(tmp_name), 
ODF_LOOKUP_DIR, NULL);
        if (IS_ERR(odis[0])) {
                err = PTR_ERR(odis[0]);
                odis[0] = NULL;
                goto out;
        }
        for (i = 1; i < 4; i++) {
-               memset(name,0,6);
-               sprintf(name, "%x", breakdown[i]);
-               odis[i] = __odf_lookup(osi, odis[i-1], name, strlen(name), 
ODF_LOOKUP_DIR, NULL);
+               memset(tmp_name,0,6);
+               sprintf(tmp_name, "%x", breakdown[i]);
+               odis[i] = __odf_lookup(osi, odis[i-1], tmp_name, 
strlen(tmp_name), ODF_LOOKUP_DIR, NULL);
                if (IS_ERR(odis[i])) {
                        err = PTR_ERR(odis[i]);
                        odis[i] = NULL;
@@ -577,7 +615,7 @@ struct odf_dentry_info *odf_ic_dir(struct dentry *dir)
                }
        }
        
-       odi_ret = __odf_lookup(osi, odis[3], ODF_CONTENT, ODF_CONTENT_LEN, 
ODF_LOOKUP_FILE, NULL);
+       odi_ret = __odf_lookup(osi, odis[3], name, namelen, ODF_LOOKUP_FILE, 
NULL);
        if (IS_ERR(odi_ret)) {
                err = PTR_ERR(odi_ret);
                odi_ret = NULL;
@@ -726,7 +764,7 @@ int odf_purge_dir_cache(struct dentry *dentry)
        //struct iattr attr;
        struct odf_dentry_info *odi = NULL;
 
-       odi = odf_ic_dir(dentry);
+       odi = odf_ic_cache_dentry(dentry);
        if (IS_ERR(odi)){
                err = PTR_ERR(odi);
                odi = NULL;
diff --git a/fs/unionfs/odf.h b/fs/unionfs/odf.h
index 27018a2..5f5044b 100644
--- a/fs/unionfs/odf.h
+++ b/fs/unionfs/odf.h
@@ -26,6 +26,7 @@
 #define ODF_LOOKUP_OPQ 8
 #define ODF_LOOKUP_WH 16
 #define ODF_LOOKUP_LOCKED 32
+#define ODF_LOOKUP_LINK 64
 
 /* Unlink/Remove flags */
 #define ODF_RMV_WH 1
@@ -74,7 +75,8 @@ struct odf_dentry_info *odf_alloc_info(struct odf_sb_info 
*osi, struct dentry *o
 void odf_put_info(struct odf_dentry_info *odi);
 
 /* dirents & dir cache */
-struct odf_dentry_info *odf_ic_dir(struct dentry *dir);
+struct odf_dentry_info *odf_ic_cache_dentry(struct dentry *dir);
+struct odf_dentry_info *odf_ic_dentry(struct odf_sb_info *osi, u64 ino, char 
*name, int namelen);
 int odf_write_dirent(struct file *filp, const char *name, int namelen, u64 
ino, unsigned int d_type);
 int odf_read_dirent(struct file *filp, char **name, int *namelen, u64 *ino, 
unsigned int *d_type);
 int odf_purge_dir_cache(struct dentry *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