commit 8cc9b17852d150dcacc6f1573588c9ebf398b9d8
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date:   Sat Feb 24 17:04:00 2007 -0500

    locking

diff --git a/fs/unionfs/dirhelper.c b/fs/unionfs/dirhelper.c
index 3d81dfb..76df000 100644
--- a/fs/unionfs/dirhelper.c
+++ b/fs/unionfs/dirhelper.c
@@ -61,7 +61,10 @@ static int readdir_util_callback(void *dirent, const char 
*name, int namelen,
        }
                
        /* check odf */
+       /* XXX: lookup might require to lock it, so unlock for now */
+       odf_unlock(UNIONFS_D(buf->dir)->odf_info);
        odi = __odf_lookup(UNIONFS_D(buf->dir)->odf_info, name, namelen, 
create_flag, 0);
+       odf_lock(UNIONFS_D(buf->dir)->odf_info);
        if (IS_ERR(odi)){
                odi = NULL;
                goto out;
@@ -259,6 +262,8 @@ int odf_cache_dir(struct dentry *d_upper, struct dentry 
*d_odf, struct timespec
                goto out;
        }
 
+       /* lock to prevent concurrent writes */
+       odf_lock(UNIONFS_D(d_upper)->odf_info);
        /* Process the hidden directories with rdutil_callback as a filldir. */
        for (bindex = bstart; bindex <= bend; bindex++) {
                hidden_dentry = unionfs_lower_dentry_idx(d_upper, bindex);
@@ -268,7 +273,6 @@ int odf_cache_dir(struct dentry *d_upper, struct dentry 
*d_odf, struct timespec
                        continue;
                if (!S_ISDIR(hidden_dentry->d_inode->i_mode))
                        continue;
-
                dget(hidden_dentry);
                mntget(unionfs_lower_mnt_idx(d_upper, bindex));
                branchget(sb, bindex);
@@ -279,7 +283,7 @@ int odf_cache_dir(struct dentry *d_upper, struct dentry 
*d_odf, struct timespec
                        err = PTR_ERR(hidden_file);
                        dput(hidden_dentry);
                        branchput(sb, bindex);
-                       goto out;
+                       goto out_unlock;
                }
 
                do {
@@ -298,13 +302,18 @@ int odf_cache_dir(struct dentry *d_upper, struct dentry 
*d_odf, struct timespec
                branchput(sb, bindex);
 
                if (err < 0)
-                       goto out;
+                       goto out_unlock;
        }
+       odf_unlock(UNIONFS_D(d_upper)->odf_info);
 
        /* set mtime of odf file to that of higher file */
        attr.ia_mtime = *mtime;//d_upper->d_inode->i_mtime;
        attr.ia_valid = ATTR_MTIME | ATTR_MTIME_SET | ATTR_FORCE;
        err = notify_change(d_odf, &attr);
+       goto out;
+
+out_unlock:
+       odf_unlock(UNIONFS_D(d_upper)->odf_info);
 
 out:
        if (buf && buf->rdstate)
diff --git a/fs/unionfs/odf.c b/fs/unionfs/odf.c
index 5c84f68..5442c78 100644
--- a/fs/unionfs/odf.c
+++ b/fs/unionfs/odf.c
@@ -249,6 +249,9 @@ int odf_rename(struct dentry *old_dentry, struct dentry 
*new_dentry)
        if (UNIONFS_D(new_dentry)->odf_info)
                err = odf_remove(new_dentry, ODF_RMV_ANY);
 
+       odf_lock(UNIONFS_D(old_dentry)->odf_info);
+       odf_lock(UNIONFS_D(new_dentry->d_parent)->odf_info);
+
        old_odfdentry = UNIONFS_D(old_dentry)->odf_info->dentry;
        old_dir = old_odfdentry->d_parent;
        new_dir = (UNIONFS_D(new_dentry->d_parent))->odf_info->dentry;
@@ -258,7 +261,7 @@ int odf_rename(struct dentry *old_dentry, struct dentry 
*new_dentry)
                                new_dentry->d_name.len);
        if (IS_ERR(new_odfdentry)) { 
                err = PTR_ERR(new_odfdentry);
-               goto out;
+               goto out_unlock;
        }
        
        /* this should never happen */
@@ -271,6 +274,9 @@ int odf_rename(struct dentry *old_dentry, struct dentry 
*new_dentry)
        unlock_rename(old_dir, new_dir);
        dput(new_odfdentry);
 
+out_unlock:
+       odf_unlock(UNIONFS_D(old_dentry)->odf_info);
+       odf_unlock(UNIONFS_D(new_dentry->d_parent)->odf_info);
 out:
        return err;
 }
@@ -443,12 +449,13 @@ struct odf_dentry_info *odf_ic_dir(struct dentry *dir)
                odi_ret = NULL;
                goto out;
        }
-
 out:
        for (i = 0; i < 4; i++)
                odf_put_info(odis[i]);
+
        if (err) 
                return ERR_PTR(err);
+
        return odi_ret;
 }
 /*
@@ -591,13 +598,16 @@ int odf_purge_dir_cache(struct dentry *dentry)
                odi = NULL;
                goto out;
        }
-
+       
        /* truncate */
+/*
        if (dentry->d_inode) {
                attr.ia_size = 0;
                attr.ia_valid = ATTR_SIZE | ATTR_FORCE;
                err = notify_change(odi->dentry, &attr);
        }
+*/
+       err = vfs_unlink(odi->dentry->d_parent->d_inode, odi->dentry);
 out:
        odf_put_info(odi);
        return err;
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to