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