commit 3730adac4ea11340a7b83b2db86facd0fff0ac49
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date: Fri May 25 22:50:15 2007 -0400
modified odf_lookup functions to return a dentry instead of an
odf_dentry_info
diff --git a/fs/unionfs/commonfops.c b/fs/unionfs/commonfops.c
index 8ad5ed6..b9bc33b 100644
--- a/fs/unionfs/commonfops.c
+++ b/fs/unionfs/commonfops.c
@@ -111,7 +111,6 @@ int unionfs_silly_rename(struct dentry *dentry, struct
dentry *hidden_dentry)
struct dentry *tmp_dentry = NULL;
struct dentry *hidden_old_dir_dentry;
struct dentry *hidden_new_dir_dentry;
- struct odf_dentry_info *odi = NULL;
sprintf(name, ".unionfs%*.*lx",
i_inosize, i_inosize, hidden_dentry->d_inode->i_ino);
@@ -154,12 +153,13 @@ int unionfs_silly_rename(struct dentry *dentry, struct
dentry *hidden_dentry)
goto out;
/* create a whiteout */
- odi = odf_lookup_name(&UNIONFS_SB(dentry->d_sb)->odf,
- UNIONFS_D(dentry->d_parent)->odf_info,
- name, strlen(name), ODF_LOOKUP_WH, odi);
- BUG_ON(IS_ERR(odi) || odi == NULL);
+ tmp_dentry = odf_lookup_name(dentry->d_parent, name,
+ strlen(name), ODF_LOOKUP_WH);
+ if (IS_ERR(tmp_dentry))
+ err = PTR_ERR(tmp_dentry);
+ else
+ dput(tmp_dentry);
out:
- odf_put_info(odi);
return err;
}
diff --git a/fs/unionfs/dirhelper.c b/fs/unionfs/dirhelper.c
index 62f71ba..a811945 100644
--- a/fs/unionfs/dirhelper.c
+++ b/fs/unionfs/dirhelper.c
@@ -129,9 +129,9 @@ static int readdir_util_callback(void *dirent, const char
*name, int namelen,
int err = 0;
struct unionfs_rdutil_callback *buf = dirent;
- int whiteout = 0;
+ int whiteout = 0, not_in_odf = 0;
struct filldir_node *found;
- struct odf_dentry_info *odi = NULL;
+ struct dentry *odf_dentry = NULL;
if (buf->mode == RD_CHECK_EMPTY || buf->mode == RD_CHECK_HD_EMPTY)
buf->filldir_called = 1;
@@ -153,20 +153,24 @@ static int readdir_util_callback(void *dirent, const char
*name, int namelen,
}
/* check odf */
- odi = odf_lookup_name(&UNIONFS_SB(buf->dir->d_sb)->odf,
- UNIONFS_D(buf->dir)->odf_info,
- name, namelen, ODF_LOOKUP_LOCKED, NULL);
- if (IS_ERR(odi)){
- odi = NULL;
- goto out;
+ odf_dentry = odf_lookup_name(buf->dir, name, namelen, 0);
+ if (IS_ERR(odf_dentry)){
+ if (PTR_ERR(odf_dentry) == -ENOENT) {
+ odf_dentry = NULL;
+ not_in_odf = 1;
+ }
+ else {
+ odf_dentry = NULL;
+ goto out;
+ }
}
- if ((odi && !odi->whiteout) || !odi) {
+ if ((odf_dentry || not_in_odf)) {
if (buf->mode == RD_CHECK_EMPTY) {
err = -ENOTEMPTY;
goto out;
}
}
- if (odi && odi->whiteout)
+ if (!odf_dentry && !not_in_odf)
whiteout = 1;
find:
found = find_filldir_node(buf->rdstate, name, namelen);
@@ -179,8 +183,8 @@ find:
if (err || buf->mode != RD_CACHE_ODF || !buf->filp || whiteout)
goto out;
- if (odi)
- ino = odi->dentry->d_inode->i_ino;
+ if (odf_dentry)
+ ino = odf_dentry->d_inode->i_ino;
err = odf_write_dirent(buf->filp, name, namelen, ino, d_type);
out:
odf_put_info(odi);
diff --git a/fs/unionfs/odf.c b/fs/unionfs/odf.c
index b8ff210..fdbf681 100644
--- a/fs/unionfs/odf.c
+++ b/fs/unionfs/odf.c
@@ -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 dentry *links = NULL;
+ struct dentry *ret, *links = NULL;
struct dentry *lower_dentry = NULL;
struct file *link_file = NULL;
char *name, *uuid;
@@ -960,21 +960,10 @@ int odf_lookup(struct dentry *parent, struct dentry
*dentry, int flags)
*/
}
- UNIONFS_D(dentry)->odf_info = __odf_lookup(
- &UNIONFS_SB(dentry->d_sb)->odf,
- UNIONFS_D(parent)->odf_info,
- dentry->d_name.name,
- dentry->d_name.len,
- flags,
- UNIONFS_D(dentry)->odf_info,
- NULL);
- 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;
+ ret = __odf_lookup(parent, dentry, dentry->d_name.name,
+ dentry->d_name.len, flags, NULL);
+ if (IS_ERR(ret))
+ err = PTR_ERR(ret);
out:
dput(links);
@@ -982,30 +971,41 @@ out:
filp_close(link_file, NULL);
return err;
}
+struct dentry *odf_lookup_name(struct dentry *parent, const char *name, int
len, int flags)
+{
+ return __odf_lookup(parent, NULL, name, len, flags, NULL);
+}
-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 dentry *link)
+struct dentry *__odf_lookup(struct dentry *parent,
+ struct dentry *target,
+ const char *name, int len, int flags,
+ struct dentry *link)
{
- struct dentry *odf_dentry;
- struct odf_dentry_info *odi = old_odi;
- struct inode *odf_i_dir = parent->dentry->d_inode;
+ struct dentry *odf_dentry, *odf_parent;
+ struct inode *odf_i_dir;
+ struct odf_sb_info *osi = &UNIONFS_SB(parent->d_sb)->odf;
int opaque, err = 0, cleaned = 0;
uid_t olduid = current->fsuid;
gid_t oldgid = current->fsgid;
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));
+ BUG_ON(link && (flags & ODF_LOOKUP_DIR));
+
+ /* clear the odf_dentry_info of target */
+ if (target) {
+ dput(UNIONFS_D(target)->odf.dentry);
+ UNIONFS_D(target)->odf.dentry = NULL;
+ }
+
+ odf_parent = UNIONFS_D(parent)->odf.dentry;
+ odf_i_dir = odf_parent->d_inode;
- odf_dentry = lookup_one_len(name, parent->dentry, len);
+ /* lookup in the odf */
+ odf_dentry = lookup_one_len(name, odf_parent, len);
if (IS_ERR(odf_dentry)) {
printk("odf_lookup: failed to lookup %s\n", name);
- odf_put_info(old_odi);
- odi = (struct odf_dentry_info *)odf_dentry;
goto out;
}
@@ -1014,7 +1014,7 @@ struct odf_dentry_info *__odf_lookup(struct odf_sb_info
*osi,
if (__odf_is_wh(osi, odf_dentry)){
vfs_unlink(odf_i_dir, odf_dentry);
dput(odf_dentry);
- odf_dentry = lookup_one_len(name, parent->dentry, len);
+ odf_dentry = lookup_one_len(name, odf_parent, len);
}
}
@@ -1022,14 +1022,14 @@ struct odf_dentry_info *__odf_lookup(struct odf_sb_info
*osi,
if (flags & ODF_LOOKUP_WH)
BUG_ON(odf_dentry->d_inode && !__odf_is_wh(osi, odf_dentry));
- /* create inode in odf if dont exist */
+ /* create an entry in the odf if dont exist */
if (!odf_dentry->d_inode) {
if (name[0]=='.')
BUG_ON(len==1 || (name[1]=='.'&&len==2));
retry:
/* FIXME need to check hardlinks before create */
- if (link && (flags & (ODF_LOOKUP_FILE | ODF_LOOKUP_LINK))) {
+ if (link && (flags & ODF_LOOKUP_FILE)) {
/* link to the given dentry */
vfs_link(link, odf_dentry->d_parent->d_inode,
odf_dentry);
}
@@ -1050,8 +1050,7 @@ retry:
}
else {
dput(odf_dentry);
- odf_put_info(old_odi);
- odi = NULL;
+ odf_dentry = ERR_PTR(-ENOENT);
goto out;
}
@@ -1065,10 +1064,11 @@ retry:
wake_up_and_wait_sioa(osi->cleanup);
goto retry;
}
- printk(KERN_WARNING "odf_lookup: could not create odf
dentry %s, %d\n", name, err);
+ printk(KERN_WARNING
+ "odf_lookup: could not create odf dentry %s,
%d\n",
+ name, err);
dput(odf_dentry);
- odf_put_info(old_odi);
- odi = ERR_PTR(err);
+ odf_dentry = ERR_PTR(err);
goto out;
}
@@ -1081,10 +1081,26 @@ retry:
and if not, link them */
}
- odi = odf_fill_info(old_odi, osi, odf_dentry);
- dput(odf_dentry); /* since we dget in fill_info */
+ if (odf_dentry && !IS_ERR(odf_dentry)) {
+ /* fill in the odf_dentry_info struct of target */
+ if (target) {
+ UNIONFS_D(target)->odf.dentry = odf_dentry;
+ UNIONFS_D(target)->odf.whiteout =
+ __odf_is_wh(osi, odf_dentry);
+ UNIONFS_D(target)->odf.opaque =
+ __odf_get_opaque(odf_dentry->d_inode);
+ }
+
+ if (__odf_is_wh(osi, odf_dentry)) {
+ if (!target)
+ dput(odf_dentry);
+ odf_dentry = NULL;
+ }
+ }
+ else if (!odf_dentry)
+ odf_dentry = ERR_PTR(-ENOENT);
out:
- return odi;
+ return odf_dentry;
}
/*
@@ -1127,9 +1143,9 @@ struct dentry *odf_ic_dentry(struct odf_sb_info *osi, u64
ino, char *name, int n
dirs[i] = NULL;
}
- current->fsuid = olduid;
- current->fsgid = oldgid;
-
+ current->fsuid = 0;
+ current->fsgid = 0;
+
memset(tmp_name,0,6);
sprintf(tmp_name, "%x", breakdown[0]);
@@ -1176,7 +1192,7 @@ struct dentry *odf_ic_dentry(struct odf_sb_info *osi, u64
ino, char *name, int n
out:
current->fsuid = olduid;
current->fsgid = oldgid;
-
+
for (i = 0; i < 4; i++)
dput(dirs[i]);
diff --git a/fs/unionfs/odf.h b/fs/unionfs/odf.h
index 02bd942..9a3c25d 100644
--- a/fs/unionfs/odf.h
+++ b/fs/unionfs/odf.h
@@ -57,15 +57,9 @@ 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 dentry *link);
-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);
-}
+struct dentry *__odf_lookup(struct dentry *parent, struct dentry *target,
+ const char *name, int len, int flags, struct dentry
*link);
+struct dentry *odf_lookup_name(struct dentry *parent, const char *name, int
len, int flags);
struct dentry* odf_getdir(struct dentry *d_odf, const char *name, int len);
struct odf_dentry_info *odf_fill_info(struct odf_dentry_info *odi,
struct odf_sb_info *osi, struct dentry *odf_dentry);
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs