commit 1137a0a68f6bf473f3dd15a46c43989c799236e6
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date:   Thu Apr 5 14:08:17 2007 -0400

    moved reading/writting of link odf ino from __odf_lookup to odf_lookup and 
use the ODF_LOOKUP_LINK flag

diff --git a/fs/unionfs/odf.c b/fs/unionfs/odf.c
index c53ed13..01df833 100644
--- a/fs/unionfs/odf.c
+++ b/fs/unionfs/odf.c
@@ -566,6 +566,9 @@ int odf_lookup(struct dentry *parent, struct dentry 
*dentry, int flags)
        struct file *link_file = NULL;
        char *name, *uuid;
        int bstart, err = 0;
+       __le64 le64;
+       u64 ino = 0;
+       mm_segment_t oldfs;
 
        /* this might be called before interpose */
        if (dbstart(dentry) == dbend(dentry) && dbstart(dentry) == 0) {
@@ -582,7 +585,8 @@ int odf_lookup(struct dentry *parent, struct dentry 
*dentry, int flags)
 
        if (lower_dentry && lower_dentry->d_inode &&
                lower_dentry->d_inode->i_nlink > 1 &&
-               !S_ISDIR(lower_dentry->d_inode->i_mode)) {
+               !S_ISDIR(lower_dentry->d_inode->i_mode) &&
+               !(flags & ODF_LOOKUP_WH)) {
 
                /* get/create the link info file for lower fs */
                name = kmalloc(UUID_LEN * 2 + 1,GFP_KERNEL);
@@ -612,8 +616,28 @@ int odf_lookup(struct dentry *parent, struct dentry 
*dentry, int flags)
                        goto out;
                }
        
+               oldfs = get_fs();
+               set_fs(KERNEL_DS);
+               link_file->f_pos = 0;
+               err = link_file->f_op->read(link_file, (char*)&le64,
+                               sizeof(__le64), &link_file->f_pos);
+               set_fs(oldfs);
+               if (err < 0)
+                       goto out;
+               if(err == sizeof(__le64))
+                       ino = le64_to_cpu(le64);
+               else if (err == 0)
+                       ino = 0;
+               else {
+                       err = -EIO;
+                       goto out;
+               }
+               err = 0;
+
                /* check if link was copied up and act appropriately */
-               __check_link_copyup(link_file);
+               if (ino)
+                       __check_link_copyup(link_file);
+               flags |= ODF_LOOKUP_LINK;
        }
 
        UNIONFS_D(dentry)->odf_info = __odf_lookup(
@@ -623,11 +647,28 @@ int odf_lookup(struct dentry *parent, struct dentry 
*dentry, int flags)
                                dentry->d_name.len,
                                flags,
                                UNIONFS_D(dentry)->odf_info,
-                               link_file);
+                               ino);
        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;
+
+       /* if link file did not have the ino, write it */
+       if (link_file && !ino) {
+               oldfs = get_fs();
+               set_fs(KERNEL_DS);
+               link_file->f_pos = 0;
+               le64 = 
cpu_to_le64(UNIONFS_D(dentry)->odf_info->dentry->d_inode->i_ino);
+               err = link_file->f_op->write(link_file, (char*)&le64,
+                       sizeof(__le64), &link_file->f_pos);
+               set_fs(oldfs);  /* XXX check errors, and for -ENOSPC */
+               BUG_ON(err != sizeof(__le64));
+               err = 0;
+       }
+       
 out:
        odf_put_info(links);
        if (link_file)
@@ -638,42 +679,20 @@ out:
 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 file *link_file)
+                       struct odf_dentry_info *old_odi, u64 ino)
 {
        struct inode *i;
        struct dentry *odf_dentry;
        struct odf_dentry_info *odi = old_odi;
        struct inode *odf_i_dir = parent->dentry->d_inode;
        int opaque, whiteout, err = 0, cleaned = 0;
-       __le64 le64;
-       u64 ino = 0;
-       mm_segment_t oldfs;
        uid_t olduid;
        gid_t oldgid;
        
        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));
 
-       /* read the odf ino of the link */
-       if (link_file) {
-               oldfs = get_fs();
-               set_fs(KERNEL_DS);
-               link_file->f_pos = 0;
-               err = link_file->f_op->read(link_file, (char*)&le64,
-                               sizeof(__le64), &link_file->f_pos);
-               set_fs(oldfs);
-               if (err < 0) {
-                       odf_put_info(old_odi);
-                       odi = ERR_PTR(err);
-                       goto out;
-               }
-               if(err != sizeof(__le64))
-                       ino = 0;
-               else
-                       ino = le64_to_cpu(le64);
-               err = 0;
-       }
        odf_dentry = lookup_one_len(name, parent->dentry, len);
        
        if (IS_ERR(odf_dentry)) {
@@ -714,8 +733,7 @@ retry:
                else if (cleaned)
                        odf_lock(osi->odi_ic);
 
-               BUG_ON(link_file && (flags & ODF_LOOKUP_DIR));
-               if (link_file && ino && (flags & ODF_LOOKUP_FILE)) {
+               if (ino && (flags & (ODF_LOOKUP_FILE | ODF_LOOKUP_LINK))) {
                        /* if link ino was set in the file, link to that */
                        i = iget(odf_dentry->d_sb, ino);
                        BUG_ON(i == NULL || IS_ERR(i)); /*XXX: check for these 
*/
@@ -784,7 +802,7 @@ retry:
                 */
 
                /* case 3: unlink odf file and link to given ino */
-               if (link_file && ino && ino != odf_dentry->d_inode->i_ino) {
+               if ((flags & ODF_LOOKUP_LINK) && ino && ino != 
odf_dentry->d_inode->i_ino) {
                        vfs_unlink(odf_dentry->d_parent->d_inode, odf_dentry);
                        i = iget(odf_dentry->d_sb, ino);
                        BUG_ON(i == NULL || IS_ERR(i)); /*XXX: check if i is 
the one */
@@ -793,19 +811,6 @@ retry:
                }
        }
 
-       /* if link file did not have the ino, write it */
-       if (link_file && !ino) {
-               oldfs = get_fs();
-               set_fs(KERNEL_DS);
-               link_file->f_pos = 0;
-               le64 = cpu_to_le64(odf_dentry->d_inode->i_ino);
-               err = link_file->f_op->write(link_file, (char*)&le64,
-                       sizeof(__le64), &link_file->f_pos);
-               set_fs(oldfs);  /* XXX check errors, and for -ENOSPC as above */
-               BUG_ON(err != sizeof(__le64));
-               err = 0;
-       }
-
        odi = odf_fill_info(old_odi, osi, odf_dentry);
        dput(odf_dentry); /* since we dget in fill_info */
 out:
diff --git a/fs/unionfs/odf.h b/fs/unionfs/odf.h
index 51acbb0..ed0bba5 100644
--- a/fs/unionfs/odf.h
+++ b/fs/unionfs/odf.h
@@ -67,13 +67,12 @@ 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 file *link_file);
+               const char *name, int len, int flags, struct odf_dentry_info 
*old_odi, u64 ino);
 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);
+       return __odf_lookup(osi, parent, name, len, flags, old_odi, 0);
 }
 struct odf_dentry_info *odf_getpath(struct dentry *d_odf, struct odf_sb_info 
*osi, const char *name);
 struct odf_dentry_info *odf_fill_info(struct odf_dentry_info *odi,
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to