commit 7ff4ab8788e4edff82993bbd55fddd21f0bd32b9
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date: Mon Feb 12 17:08:58 2007 -0500
only cache dir if mtime changed
some other minor fixes
diff --git a/fs/unionfs/dirhelper.c b/fs/unionfs/dirhelper.c
index 191c9e7..76cafab 100644
--- a/fs/unionfs/dirhelper.c
+++ b/fs/unionfs/dirhelper.c
@@ -692,11 +692,13 @@ int odf_cache_dir(struct dentry *d_upper, struct dentry
*d_odf)
{
int err = 0;
struct dentry *hidden_dentry = NULL;
+ struct inode *i_odf;
struct super_block *sb;
struct file *hidden_file, *odf_file = NULL;
struct unionfs_rdutil_callback *buf = NULL;
int bindex, bstart, bend, bopaque;
-
+ struct iattr attr;
+
sb = d_upper->d_sb;
unionfs_read_lock(sb);
@@ -705,9 +707,27 @@ int odf_cache_dir(struct dentry *d_upper, struct dentry
*d_odf)
if ((err = unionfs_partial_lookup(d_upper)))
goto out;
+
+ i_odf = d_odf->d_inode;
+
+ /* compare mtimes, do not proceed if equal */
+ if (i_odf && timespec_equal(&i_odf->i_mtime,
+ &d_upper->d_inode->i_mtime))
+ goto out;
dget(d_odf);
mntget(UNIONFS_SB(sb)->odf->mnt);
+
+ /* force truncate if file exists */
+ if (i_odf) {
+ truncate_inode_pages(i_odf->i_mapping, 0);
+ attr.ia_size = 0;
+ attr.ia_valid = ATTR_SIZE | ATTR_FORCE;
+ err = notify_change(d_odf, &attr);
+ if (err)
+ goto out;
+
+ }
odf_file = dentry_open(d_odf,
UNIONFS_SB(sb)->odf->mnt,
O_TRUNC|O_CREAT|O_WRONLY);
@@ -778,6 +798,11 @@ int odf_cache_dir(struct dentry *d_upper, struct dentry
*d_odf)
goto out;
}
+ /* set mtime of odf file to that of higher file */
+ attr.ia_mtime = d_upper->d_inode->i_mtime;
+ attr.ia_valid = ATTR_MTIME | ATTR_MTIME_SET | ATTR_FORCE;
+ err = notify_change(d_odf, &attr);
+
out:
if (buf && buf->rdstate)
free_rdstate(buf->rdstate);
diff --git a/fs/unionfs/odf.c b/fs/unionfs/odf.c
index 1c499de..41bbd9a 100644
--- a/fs/unionfs/odf.c
+++ b/fs/unionfs/odf.c
@@ -837,7 +837,12 @@ int odf_rename(struct dentry *old_dentry, struct dentry
*new_dentry)
int err = 0;
err = odf_lookup(old_dentry->d_parent, old_dentry, 0);
+ if (err)
+ goto out;
+
err = odf_lookup(new_dentry->d_parent, new_dentry, 0);
+ if (err)
+ goto out;
/* if new exists, remove it */
if (UNIONFS_D(new_dentry)->odf_info)
diff --git a/fs/unionfs/unlink.c b/fs/unionfs/unlink.c
index 3e03165..0803e53 100644
--- a/fs/unionfs/unlink.c
+++ b/fs/unionfs/unlink.c
@@ -126,6 +126,16 @@ static int unionfs_do_unlink(struct inode *dir, struct
dentry *dentry)
"unionfs_unlink: IO error unlinking from branch
%d\n",
bindex);
err = odf_create_wh(dentry);
+ if (err)
+ goto out;
+ /* we want to update mtime here, since if the file to
+ * be removed was only on a rd only branch, then since
+ * the mtime of that branch has not changed, so the
+ * mtime of the upper file is not updated
+ */
+ attr.ia_mtime = current_kernel_time();
+ attr.ia_valid = ATTR_MTIME | ATTR_MTIME_SET | ATTR_FORCE;
+ err = notify_change(dentry->d_parent, &attr);
}
out:
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs