commit 86f96153ceefd53e926dcc6a7e9a355b86003b1c
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date: Tue May 22 17:51:30 2007 -0400
when an inode is dropped, check if it has an entry in /odf/sr and move it
to /odf/reclaim
diff --git a/fs/unionfs/odf.c b/fs/unionfs/odf.c
index dd33968..1ed3329 100644
--- a/fs/unionfs/odf.c
+++ b/fs/unionfs/odf.c
@@ -358,6 +358,60 @@ out:
return err;
}
+/* Check if the given inode has an entry in /odf/sr and move this
+ * to /odf/rc so it can be cleaned by the cleanup thread
+ */
+int odf_release_sr(struct inode *inode)
+{
+ struct dentry *old_dentry = NULL, *new_dentry = NULL;
+ struct odf_dentry_info *odi_sr, *odi_rc;
+ char name[ODF_INAME_LEN];
+ int err = 0;
+
+ odi_sr = UNIONFS_SB(inode->i_sb)->odf->odi_sr;
+ odi_rc = UNIONFS_SB(inode->i_sb)->odf->odi_rc;
+ memset(name, 0, ODF_INAME_LEN);
+ if (!name){
+ err = -ENOMEM;
+ goto out;
+ }
+ sprintf(name, "%lu", inode->i_ino);
+
+ odf_lock(odi_sr);
+ odf_lock(odi_rc);
+
+ /* check for an entry in /odf/sr */
+ old_dentry = lookup_one_len(name, odi_sr->dentry, strlen(name));
+ if (IS_ERR(old_dentry)) {
+ err = PTR_ERR(old_dentry);
+ old_dentry = NULL;
+ goto out_unlock;
+ }
+ if (!old_dentry->d_inode)
+ goto out_unlock;
+
+ /* move it to /odf/rc with the same name */
+ new_dentry = lookup_one_len(name, odi_rc->dentry, strlen(name));
+ if (IS_ERR(new_dentry)) {
+ err = PTR_ERR(new_dentry);
+ new_dentry = NULL;
+ goto out_unlock;
+ }
+
+ lock_rename(old_dentry->d_parent, new_dentry->d_parent);
+ err = vfs_rename(old_dentry->d_parent->d_inode, old_dentry,
+ new_dentry->d_parent->d_inode, new_dentry);
+ unlock_rename(old_dentry->d_parent, new_dentry->d_parent);
+
+out_unlock:
+ odf_unlock(odi_rc);
+ odf_unlock(odi_sr);
+ dput(old_dentry);
+ dput(new_dentry);
+out:
+ return err;
+}
+
/*
* Rename in odf, expects UnionFS dentries.
* If the new_dentry exists (either as a file or wh)
diff --git a/fs/unionfs/odf.h b/fs/unionfs/odf.h
index 54b25b0..bef6865 100644
--- a/fs/unionfs/odf.h
+++ b/fs/unionfs/odf.h
@@ -82,13 +82,7 @@ int odf_write_dirent(struct file *filp, const char *name,
int namelen, u64 ino,
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);
int odf_cache_dir(struct dentry *d_upper, struct dentry *d_odf, struct
timespec *mtime);
-
-/* dirents & dir cache */
-struct odf_dentry_info *odf_ic_dir(struct dentry *dir);
-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);
-int odf_cache_dir(struct dentry *d_upper, struct dentry *d_odf, struct
timespec *mtime);
+int odf_release_sr(struct inode *inode);
int odf_rename(struct dentry *old_dentry, struct dentry *new_dentry);
int odf_link(struct dentry *old_dentry, struct dentry *new_dentry);
diff --git a/fs/unionfs/super.c b/fs/unionfs/super.c
index dd7a949..e663752 100644
--- a/fs/unionfs/super.c
+++ b/fs/unionfs/super.c
@@ -75,6 +75,11 @@ static void unionfs_delete_inode(struct inode *inode)
clear_inode(inode);
}
+static void unionfs_drop_inode(struct inode *inode)
+{
+ odf_release_sr(inode);
+ return generic_drop_inode(inode);
+}
/* final actions when unmounting a file system */
static void unionfs_put_super(struct super_block *sb)
@@ -955,6 +960,7 @@ out:
struct super_operations unionfs_sops = {
.read_inode = unionfs_read_inode,
.delete_inode = unionfs_delete_inode,
+ .drop_inode = unionfs_drop_inode,
.put_super = unionfs_put_super,
.statfs = unionfs_statfs,
.remount_fs = unionfs_remount_fs,
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs