commit 97aea0acdd17e5fabdc49c0374b6f54bf65ba6e3
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date: Fri May 25 15:53:32 2007 -0400
modified odf_ic_cache_dentry not to use odf_lookup and to return a dentry
instead of
an odf_dentry_info
diff --git a/fs/unionfs/commonfops.c b/fs/unionfs/commonfops.c
index b460525..d560fe6 100644
--- a/fs/unionfs/commonfops.c
+++ b/fs/unionfs/commonfops.c
@@ -487,7 +487,7 @@ static int __open_dir(struct inode *inode, struct file
*file)
struct dentry *hidden_dentry;
struct file *hidden_file;
int bindex, bstart, bend;
- struct odf_dentry_info *odi;
+ struct dentry *odf_cache;
struct timespec *newest;
int err;
bstart = fbstart(file) = dbstart(file->f_dentry);
@@ -523,12 +523,12 @@ static int __open_dir(struct inode *inode, struct file
*file)
unionfs_read_unlock(inode->i_sb);
}
- 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);
+ odf_cache = odf_ic_cache_dentry(file->f_dentry);
+ if (IS_ERR(odf_cache))
+ return PTR_ERR(odf_cache);
+ err = odf_cache_dir(file->f_dentry, odf_cache, newest);
/* FIXME: store the dentry somewhere */
- odf_put_info(odi);
+ dput(odf_cache);
return err;
}
diff --git a/fs/unionfs/dirfops.c b/fs/unionfs/dirfops.c
index ba6c619..d39e1c3 100644
--- a/fs/unionfs/dirfops.c
+++ b/fs/unionfs/dirfops.c
@@ -23,7 +23,7 @@ static int unionfs_readdir(struct file *file, void *dirent,
filldir_t filldir)
int err = 0;
struct file *odf_file = NULL;
struct inode *inode = NULL;
- struct odf_dentry_info *odi = NULL;
+ struct dentry *odf_cache = NULL;
loff_t size, pos;
int overflow = 0;
/* dirent */
@@ -40,19 +40,19 @@ 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_cache_dentry(file->f_dentry);
- if (IS_ERR(odi)){
- err = PTR_ERR(odi);
- odi = NULL;
+ odf_cache = odf_ic_cache_dentry(file->f_dentry);
+ if (IS_ERR(odf_cache)){
+ err = PTR_ERR(odf_cache);
+ odf_cache = NULL;
goto out;
}
/* check if cached dir does not exist */
- if (!odi->dentry->d_inode || !odi->dentry->d_inode->i_size) {
+ if (!odf_cache->d_inode || !odf_cache->d_inode->i_size) {
/* odf cache dir calls partial lookup wich expects a locked
dentry */
unionfs_lock_dentry(file->f_dentry);
- err = odf_cache_dir(file->f_dentry, odi->dentry,
&file->f_dentry->d_inode->i_mtime);
+ err = odf_cache_dir(file->f_dentry, odf_cache,
&file->f_dentry->d_inode->i_mtime);
unionfs_unlock_dentry(file->f_dentry);
if (err)
goto out;
@@ -65,15 +65,15 @@ static int unionfs_readdir(struct file *file, void *dirent,
filldir_t filldir)
file->f_pos = 0;
}
- dget(odi->dentry);
+ dget(odf_cache);
mntget(UNIONFS_SB(file->f_dentry->d_sb)->odf.mnt);
- odf_file = dentry_open(odi->dentry,
- UNIONFS_SB(file->f_dentry->d_sb)->odf.mnt,
- O_RDONLY);
+ odf_file = dentry_open(odf_cache,
+ UNIONFS_SB(file->f_dentry->d_sb)->odf.mnt,
+ O_RDONLY);
if (IS_ERR(odf_file)){
err = PTR_ERR(odf_file);
mntput(UNIONFS_SB(file->f_dentry->d_sb)->odf.mnt);
- dput(odi->dentry);
+ dput(odf_cache);
odf_file = NULL;
goto out;
}
@@ -84,7 +84,7 @@ static int unionfs_readdir(struct file *file, void *dirent,
filldir_t filldir)
odf_file->f_pos = file->f_pos;
- size = odi->dentry->d_inode->i_size;
+ size = odf_cache->d_inode->i_size;
while (odf_file->f_pos < size && !overflow) {
pos = odf_file->f_pos;
@@ -100,7 +100,7 @@ static int unionfs_readdir(struct file *file, void *dirent,
filldir_t filldir)
}
/* Copy the atime. */
- fsstack_copy_attr_atime(inode, odi->dentry->d_inode);
+ fsstack_copy_attr_atime(inode, odf_cache->d_inode);
/* save the file position */
file->f_pos = odf_file->f_pos;
@@ -117,7 +117,7 @@ out:
kfree(name);
if (odf_file)
filp_close(odf_file, NULL);
- odf_put_info(odi);
+ dput(odf_cache);
unionfs_read_unlock(file->f_dentry->d_sb);
return err;
}
diff --git a/fs/unionfs/export.c b/fs/unionfs/export.c
index 9846c6b..828622e 100644
--- a/fs/unionfs/export.c
+++ b/fs/unionfs/export.c
@@ -165,7 +165,7 @@ static int unionfs_get_name(struct dentry *dentry, char
*name, struct dentry *ch
{
int err;
struct inode *dir = dentry->d_inode;
- struct odf_dentry_info *odi = NULL;
+ struct dentry *odf_cache = NULL;
struct file *file = NULL;
/* dirent */
u64 ino;
@@ -184,29 +184,29 @@ static int unionfs_get_name(struct dentry *dentry, char
*name, struct dentry *ch
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;
+ odf_cache = odf_ic_cache_dentry(dentry);
+ if (IS_ERR(odf_cache)){
+ err = PTR_ERR(odf_cache);
+ odf_cache = NULL;
goto out;
}
/* reconstruct the cached dir if necessary */
- if (!odi->dentry->d_inode || !odi->dentry->d_inode->i_size) {
+ if (!odf_cache->d_inode || !odf_cache->d_inode->i_size) {
unionfs_lock_dentry(dentry);
- err = odf_cache_dir(dentry, odi->dentry,
&dentry->d_inode->i_mtime);
+ err = odf_cache_dir(dentry, odf_cache,
&dentry->d_inode->i_mtime);
unionfs_unlock_dentry(dentry);
if (err)
goto out;
}
- dget(odi->dentry);
+ dget(odf_cache);
mntget(UNIONFS_SB(dentry->d_sb)->odf.mnt);
- file = dentry_open(odi->dentry, UNIONFS_SB(dentry->d_sb)->odf.mnt,
O_RDONLY);
+ file = dentry_open(odf_cache, 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);
+ dput(odf_cache);
file = NULL;
goto out;
}
@@ -236,7 +236,7 @@ out:
tmp_name = NULL;
if (file)
filp_close(file, NULL);
- odf_put_info(odi);
+ dput(odf_cache);
return err;
}
diff --git a/fs/unionfs/odf.c b/fs/unionfs/odf.c
index 6957173..0882f3a 100644
--- a/fs/unionfs/odf.c
+++ b/fs/unionfs/odf.c
@@ -650,7 +650,7 @@ int odf_copyup_link(struct super_block *sb, struct dentry
*old_dentry, struct de
int old_branch, int new_branch)
{
char *name, *uuid;
- struct odf_dentry_info *links = NULL;
+ struct dentry *links = NULL;
struct odf_sb_info *osi = &UNIONFS_SB(sb)->odf;
struct file *link_file = NULL;
mm_segment_t oldfs;
@@ -683,13 +683,13 @@ int odf_copyup_link(struct super_block *sb, struct dentry
*old_dentry, struct de
}
/* open the file */
- dget(links->dentry);
+ dget(links);
mntget(osi->mnt);
- link_file = dentry_open(links->dentry, osi->mnt, O_RDWR);
+ link_file = dentry_open(links, osi->mnt, O_RDWR);
if (IS_ERR(link_file)) {
err = PTR_ERR(link_file);
link_file = NULL;
- dput(links->dentry);
+ dput(links);
mntput(osi->mnt);
goto out;
}
@@ -722,7 +722,7 @@ int odf_copyup_link(struct super_block *sb, struct dentry
*old_dentry, struct de
set_fs(oldfs);
err = 0;
- odf_put_info(links);
+ dput(links);
links = NULL;
filp_close(link_file, NULL);
link_file = NULL;
@@ -734,7 +734,7 @@ int odf_copyup_link(struct super_block *sb, struct dentry
*old_dentry, struct de
out:
if (link_file)
filp_close(link_file, NULL);
- odf_put_info(links);
+ dput(links);
kfree(name);
return err;
}
@@ -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 odf_dentry_info *links = NULL;
+ struct dentry *links = NULL;
struct dentry *lower_dentry = NULL;
struct file *link_file = NULL;
char *name, *uuid;
@@ -940,13 +940,13 @@ int odf_lookup(struct dentry *parent, struct dentry
*dentry, int flags)
}
/* open the file */
- dget(links->dentry);
+ dget(links);
mntget(osi->mnt);
- link_file = dentry_open(links->dentry, osi->mnt, O_RDWR);
+ link_file = dentry_open(links, osi->mnt, O_RDWR);
if (IS_ERR(link_file)) {
err = PTR_ERR(link_file);
link_file = NULL;
- dput(links->dentry);
+ dput(links);
mntput(osi->mnt);
goto out;
}
@@ -977,7 +977,7 @@ int odf_lookup(struct dentry *parent, struct dentry
*dentry, int flags)
goto out;
out:
- odf_put_info(links);
+ dput(links);
if (link_file)
filp_close(link_file, NULL);
return err;
@@ -1091,7 +1091,7 @@ 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_cache_dentry(struct dentry *dir)
+struct dentry *odf_ic_cache_dentry(struct dentry *dir)
{
struct odf_dentry_info *odi_dir;
@@ -1110,55 +1110,81 @@ struct odf_dentry_info *odf_ic_cache_dentry(struct
dentry *dir)
* 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 dentry *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;
+ struct dentry *dirs[4], *ic, *ret = NULL;
int breakdown[4];
char tmp_name[6];
int i, err = 0;
+ uid_t olduid = current->fsuid;
+ gid_t oldgid = current->fsgid;
- odi_ic = odf_fill_info(NULL, osi, osi->ic);
+ ic = osi->ic;
for (i = 3; i >= 0; i--) {
breakdown[i] = ino & 0xFFFF;
ino >>= 16;
- odis[i] = NULL;
+ dirs[i] = NULL;
}
+ current->fsuid = olduid;
+ current->fsgid = oldgid;
+
memset(tmp_name,0,6);
sprintf(tmp_name, "%x", breakdown[0]);
- odis[0] = odf_lookup_name(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;
+
+ /* look for/create the ##/##/##/## hiearachy */
+ dirs[0] = lookup_one_len(tmp_name, ic, strlen(tmp_name));
+ if (IS_ERR(dirs[0])) {
+ err = PTR_ERR(dirs[0]);
+ dirs[0] = NULL;
goto out;
}
+ if (!dirs[0]->d_inode) {
+ err = vfs_mkdir(ic->d_inode, dirs[0], S_IRWXUGO);
+ if (err)
+ goto out;
+ }
for (i = 1; i < 4; i++) {
memset(tmp_name,0,6);
sprintf(tmp_name, "%x", breakdown[i]);
- odis[i] = odf_lookup_name(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;
+ dirs[i] = lookup_one_len(tmp_name, dirs[i-1], strlen(tmp_name));
+ if (IS_ERR(dirs[i])) {
+ err = PTR_ERR(dirs[i]);
+ dirs[i] = NULL;
goto out;
}
+ if (!dirs[i]->d_inode) {
+ err = vfs_mkdir(dirs[i-1]->d_inode, dirs[i], S_IRWXUGO);
+ if (err)
+ goto out;
+ }
}
- odi_ret = odf_lookup_name(osi, odis[3], name, namelen, ODF_LOOKUP_FILE,
NULL);
- if (IS_ERR(odi_ret)) {
- err = PTR_ERR(odi_ret);
- odi_ret = NULL;
+ /* now we can look for our target */
+ ret = lookup_one_len(name, dirs[3], namelen);
+ if (IS_ERR(ret)) {
+ err = PTR_ERR(ret);
goto out;
}
+ if (!dirs[i]->d_inode) {
+ err = vfs_create(dirs[3]->d_inode, ret, S_IRWXUGO, 0 );
+ if (err)
+ dput(ret);
+ }
+
out:
+ current->fsuid = olduid;
+ current->fsgid = oldgid;
+
for (i = 0; i < 4; i++)
- odf_put_info(odis[i]);
- odf_put_info(odi_ic);
+ dput(dirs[i]);
+ dput(ic);
if (err)
return ERR_PTR(err);
- return odi_ret;
+ return ret;
}
/*
* Write a dirent to the given file
@@ -1302,24 +1328,24 @@ out:
int odf_purge_dir_cache(struct dentry *dentry)
{
int err = 0;
- struct odf_dentry_info *odi = NULL;
+ struct dentry *odf_cache = NULL;
uid_t olduid = current->fsuid;
gid_t oldgid = current->fsgid;
- odi = odf_ic_cache_dentry(dentry);
- if (IS_ERR(odi)){
- err = PTR_ERR(odi);
- odi = NULL;
+ odf_cache = odf_ic_cache_dentry(dentry);
+ if (IS_ERR(odf_cache)){
+ err = PTR_ERR(odf_cache);
+ odf_cache = NULL;
goto out;
}
current->fsuid = 0;
current->fsgid = 0;
- err = vfs_unlink(odi->dentry->d_parent->d_inode, odi->dentry);
+ err = vfs_unlink(odf_cache->d_parent->d_inode, odf_cache);
current->fsuid = olduid;
current->fsgid = oldgid;
out:
- odf_put_info(odi);
+ dput(odf_cache);
return err;
}
diff --git a/fs/unionfs/odf.h b/fs/unionfs/odf.h
index 934094e..02bd942 100644
--- a/fs/unionfs/odf.h
+++ b/fs/unionfs/odf.h
@@ -73,8 +73,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_cache_dentry(struct dentry *dir);
-struct odf_dentry_info *odf_ic_dentry(struct odf_sb_info *osi, u64 ino, char
*name, int namelen);
+struct dentry *odf_ic_cache_dentry(struct dentry *dir);
+struct dentry *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