commit 242ef215a82846792a8eb3c5678abda850d9d30a
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date:   Sat May 12 22:03:31 2007 -0400

    export: get_name export op

diff --git a/fs/unionfs/export.c b/fs/unionfs/export.c
index c3abd36..f37c6c9 100644
--- a/fs/unionfs/export.c
+++ b/fs/unionfs/export.c
@@ -5,7 +5,6 @@ static struct dentry *__get_parent(struct super_block *sb, 
struct dentry *odf_de
        struct dentry *odf_root = UNIONFS_SB(sb)->odf->odi_ns->dentry;
        struct dentry *d, *parent, *child = NULL;
        struct dentry_stack stack;
-       int count = 0;
 
        if (odf_root == odf_dentry)
                return sb->s_root;
@@ -27,6 +26,7 @@ static struct dentry *__get_parent(struct super_block *sb, 
struct dentry *odf_de
                child = lookup_one_len(d->d_name.name, parent, d->d_name.len);
                if (IS_ERR(child))
                        break;
+               dput(parent);
                parent = child;
        }
 
@@ -39,7 +39,7 @@ static struct dentry *unionfs_get_parent(struct dentry *child)
        struct odf_sb_info *odf;
        struct super_block *odf_sb;
        struct inode *odf_i;
-       struct dentry *odf_child, *odf_parent, *res ;
+       struct dentry *odf_child, *odf_parent, *res;
 
        res = ERR_PTR(-EACCES);
        odf = UNIONFS_SB(child->d_sb)->odf;
@@ -72,6 +72,95 @@ out:
        return res;
 }
 
+/**
+ * @dentry: the directory in which to find a name
+ * @name:   a pointer to a %NAME_MAX+1 char buffer to store the name
+ * @child:  the dentry for the child directory.
+ *
+ * searches the cached dir in odf to find a dirent with
+ * the same inode number as the child, and returns that.
+ */
+static int unionfs_get_name(struct dentry *dentry, char *name, struct dentry 
*child)
+{
+       int err;
+       struct inode *dir = dentry->d_inode;
+       struct odf_dentry_info *odi = NULL;
+       struct file *file = NULL;
+        /* dirent */
+        u64 ino;
+        char *tmp_name = NULL;
+        int namelen;
+        unsigned int d_type;
+
+       err = -ENOTDIR;
+       if (!dir || !S_ISDIR(dir->i_mode))
+               goto out;
+
+       err = -EINVAL;
+       if (!dir->i_fop)
+               goto out;
+
+       if (!UNIONFS_D(dentry) || !UNIONFS_D(dentry)->odf_info)
+               goto out;
+
+        odi = odf_ic_cache_dentry(dentry);
+        if (IS_ERR(odi)){
+                err = PTR_ERR(odi);
+                odi = NULL;
+                goto out;
+        }
+
+       /* reconstruct the cached dir if necessary */
+        if (!odi->dentry->d_inode || !odi->dentry->d_inode->i_size) {
+                unionfs_lock_dentry(dentry);
+                err = odf_cache_dir(dentry, odi->dentry, 
&dentry->d_inode->i_mtime);
+                unionfs_unlock_dentry(dentry);
+                if (err)
+                        goto out;
+        }
+
+       dget(odi->dentry);
+       mntget(UNIONFS_SB(dentry->d_sb)->odf->mnt);
+       file = dentry_open(odi->dentry, UNIONFS_SB(dentry->d_sb)->odf->mnt, 
O_RDONLY);
+        if (IS_ERR(file)){
+                err = PTR_ERR(file);
+                mntput(UNIONFS_SB(dentry->d_sb)->odf->mnt);
+                dput(odi->dentry);
+                file = NULL;
+                goto out;
+        }
+
+       /* search for the inode in the dir */
+       file->f_pos = 0;
+       while (file->f_pos < file->f_dentry->d_inode->i_size) {
+               err = odf_read_dirent(file, &tmp_name, &namelen, &ino, &d_type);
+               if (err)
+                       break;
+               if (ino == child->d_inode->i_ino) {
+                       if (namelen >= NAME_MAX)
+                               namelen =  NAME_MAX;
+                       strncpy(name, tmp_name, namelen);
+                       name[namelen] = 0;
+                       err = 0;
+                       
+                       break;
+               }
+               
+               err = -ENOENT;
+               kfree(tmp_name);
+               tmp_name = NULL;
+       }
+
+out:
+       kfree(tmp_name);
+       tmp_name = NULL;
+       if (file)
+                filp_close(file, NULL);
+        odf_put_info(odi);
+       return err;
+}
+
 struct export_operations unionfs_export_ops = {
-       .get_parent = unionfs_get_parent
+       .get_parent = unionfs_get_parent,
+       .get_name = unionfs_get_name
 };
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to