commit 462071d4477739dd7c343002fc61814ecb17a009
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date: Sat Mar 17 20:40:58 2007 -0400
cleanup thread to always cleanup odf/ic whenever it wakes up.
odf_lookup wakes up cleanup thread when out of space
added an odf_sb_info field to odf_dentry_info (for locking whole odf)
diff --git a/fs/unionfs/dirhelper.c b/fs/unionfs/dirhelper.c
index 988f703..2abb6f3 100644
--- a/fs/unionfs/dirhelper.c
+++ b/fs/unionfs/dirhelper.c
@@ -60,6 +60,8 @@ struct unionfs_rmdir_callback {
int filldir_called;
struct dentry *dir;
struct vfsmount *mnt;
+ int isleaf;
+ int mode;
};
static int rmdir_util_callback(void *dirent, const char *name, int namelen,
loff_t offset, u64 ino, unsigned int d_type)
@@ -837,12 +839,15 @@ out:
}
/* This function recursively rermoves all the entries of a lower directory
- * at a specific branch and then the directory itself if rm_parent is set. It
- * does not cross branches, and does nothing visible to the union. It should
- * only be used when both a whiteout and a dir at top branch exists
- * and we need to create a new dentry or in the odf
+ * at a specific branch and then the directory itself. It does not cross
+ * branches, and does nothing visible to the union. It should only be used
+ * when both a whiteout and a dir at top branch exists and we need to create
+ * create a new dentry or in the odf for cleanup
+ * Flags: RMV_ALL : removes all entries
+ * RMV_LEAF : removes dirs only if they are leaves (dont have
subdirs)
+ * RMV_NOTPARENT : can be set with both flags above, does not rmv
base dir
*/
-int unionfs_force_rmdir(struct vfsmount *mnt, struct dentry *hidden_dentry,
int rm_parent)
+int unionfs_force_rmdir(struct vfsmount *mnt, struct dentry *hidden_dentry,
int flags)
{
int err = 0;
struct file *hidden_file;
@@ -856,6 +861,11 @@ int unionfs_force_rmdir(struct vfsmount *mnt, struct
dentry *hidden_dentry, int
buf->err = 0;
buf->dir = hidden_dentry;
buf->mnt = mnt;
+ buf->isleaf = 1;
+ if (flags & FRMV_LEAF)
+ buf->mode = RM_LEAF;
+ else
+ buf->mode = RM_ALL;
if (!hidden_dentry->d_inode)
goto out;
@@ -877,15 +887,16 @@ int unionfs_force_rmdir(struct vfsmount *mnt, struct
dentry *hidden_dentry, int
if (buf->err)
err = buf->err;
} while ((err >= 0) && buf->filldir_called);
-
+
/* fput calls dput for hidden_dentry */
fput(hidden_file);
if (err < 0)
goto out;
- if (rm_parent)
- err = vfs_rmdir(hidden_dentry->d_parent->d_inode,
hidden_dentry);
+ if ((flags & FRMV_NOTPARENT) || ((flags & FRMV_LEAF) && !buf->isleaf))
+ goto out;
+ err = vfs_rmdir(hidden_dentry->d_parent->d_inode, hidden_dentry);
out:
kfree(buf);
diff --git a/fs/unionfs/odf.c b/fs/unionfs/odf.c
index 8ab7d3b..e0dadd1 100644
--- a/fs/unionfs/odf.c
+++ b/fs/unionfs/odf.c
@@ -1369,6 +1369,7 @@ out:
struct odf_dentry_info *odf_ic_dir(struct dentry *dir)
{
struct odf_dentry_info *odi_dir, *odis[4], *odi_ic, *odi_ret = NULL;
+ struct odf_sb_info *osi;
u64 ino;
int breakdown[4];
char name[6];
@@ -1378,7 +1379,8 @@ struct odf_dentry_info *odf_ic_dir(struct dentry *dir)
err = -ENOTDIR;
goto out;
}
- odi_ic = UNIONFS_SB(dir->d_sb)->odf->odi_ic;
+ osi = UNIONFS_SB(dir->d_sb)->odf;
+ odi_ic = osi->odi_ic;
odi_dir = UNIONFS_D(dir)->odf_info;
if (!odi_dir) {
err = -ENOENT;
@@ -1394,7 +1396,7 @@ struct odf_dentry_info *odf_ic_dir(struct dentry *dir)
memset(name,0,6);
sprintf(name, "%x", breakdown[0]);
- odis[0] = __odf_lookup(odi_ic, name, strlen(name), ODF_LOOKUP_DIR,
NULL);
+ odis[0] = __odf_lookup(odi_ic, osi, name, strlen(name), ODF_LOOKUP_DIR,
NULL);
if (IS_ERR(odis[0])) {
err = PTR_ERR(odis[0]);
odis[0] = NULL;
@@ -1403,7 +1405,7 @@ struct odf_dentry_info *odf_ic_dir(struct dentry *dir)
for (i = 1; i < 4; i++) {
memset(name,0,6);
sprintf(name, "%x", breakdown[i]);
- odis[i] = __odf_lookup(odis[i-1], name, strlen(name),
ODF_LOOKUP_DIR, NULL);
+ odis[i] = __odf_lookup(odis[i-1], osi, name, strlen(name),
ODF_LOOKUP_DIR, NULL);
if (IS_ERR(odis[i])) {
err = PTR_ERR(odis[i]);
odis[i] = NULL;
@@ -1411,7 +1413,7 @@ struct odf_dentry_info *odf_ic_dir(struct dentry *dir)
}
}
- odi_ret = __odf_lookup(odis[3], "content", 7, ODF_LOOKUP_FILE, NULL);
+ odi_ret = __odf_lookup(odis[3], osi, "content", 7, ODF_LOOKUP_FILE,
NULL);
if (IS_ERR(odi_ret)) {
err = PTR_ERR(odi_ret);
odi_ret = NULL;
diff --git a/fs/unionfs/odf.h b/fs/unionfs/odf.h
index 699f745..8e75657 100644
--- a/fs/unionfs/odf.h
+++ b/fs/unionfs/odf.h
@@ -159,8 +159,8 @@ static inline void odf_unlock(struct odf_dentry_info *odi)
extern void generate_random_uuid(unsigned char uuid_out[16]);
/* cleanup thread functions */
-extern void __odf_reclaim_w(void *args);
-extern int __odf_reclaim_d(void *args);
+extern void __odf_cleanup_w(void *args);
+extern int __odf_cleanup_d(void *args);
/* Macros for locking an odf dentry info. */
static inline void odf_lock(struct odf_dentry_info *odi)
diff --git a/fs/unionfs/sioq.h b/fs/unionfs/sioq.h
index f97b594..91109a3 100644
--- a/fs/unionfs/sioq.h
+++ b/fs/unionfs/sioq.h
@@ -63,7 +63,7 @@ struct sioa_args {
int (*done) (void*);
union {
- struct reclaim_args reclaim;
+ struct cleanup_args cleanup;
};
};
diff --git a/fs/unionfs/union.h b/fs/unionfs/union.h
index 78cdb22..d819f56 100644
--- a/fs/unionfs/union.h
+++ b/fs/unionfs/union.h
@@ -122,7 +122,7 @@ struct odf_sb_info {
struct odf_dentry_info *odi_sb;
struct odf_dentry_info *odi_rc;
struct odf_dentry_info *odi_ic;
- struct sioa_args *sioa;
+ struct sioa_args *cleanup;
};
/* unionfs inode data in memory */
@@ -331,6 +331,11 @@ int __unionfs_d_revalidate_chain(struct dentry *dentry,
struct nameidata *nd);
int unionfs_force_rm(struct dentry *dentry, struct dentry **hidden_dentry, int
bindex);
int unionfs_silly_rename(struct dentry *dentry, struct dentry *hidden_dentry);
+/* Force rmv flags */
+#define FRMV_ALL 0
+#define FRMV_NOTPARENT 1
+#define FRMV_LEAF 2
+
/* The values for unionfs_interpose's flag. */
#define INTERPOSE_DEFAULT 0
#define INTERPOSE_LOOKUP 1
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs