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