commit 2223996ab85c41c90c029e5f67a9826f18eca1e2
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date: Sat Mar 17 22:19:19 2007 -0400
odf_cache_dir wakes up cleanup thread if it fails to write a dirent with
ENOSPC
diff --git a/fs/unionfs/dirhelper.c b/fs/unionfs/dirhelper.c
index dce4b3e..60cf8f4 100644
--- a/fs/unionfs/dirhelper.c
+++ b/fs/unionfs/dirhelper.c
@@ -116,12 +116,9 @@ 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,
UNIONFS_SB(buf->dir->d_sb)->odf,
- name, namelen, create_flag, 0);
- odf_lock(UNIONFS_D(buf->dir)->odf_info);
+ name, namelen, create_flag | ODF_LOOKUP_LOCKED, 0);
if (IS_ERR(odi)){
odi = NULL;
goto out;
@@ -260,11 +257,13 @@ int odf_cache_dir(struct dentry *d_upper, struct dentry
*d_odf, struct timespec
struct file *hidden_file, *odf_file = NULL;
struct unionfs_rdutil_callback *buf = NULL;
int bindex, bstart, bend, bopaque;
+ int cleaned = 0;
struct iattr attr;
sb = d_upper->d_sb;
-
+retry:
unionfs_read_lock(sb);
+ odf_lock(UNIONFS_SB(sb)->odf->odi_ic);
BUG_ON(!S_ISDIR(d_upper->d_inode->i_mode));
@@ -379,8 +378,15 @@ out:
if (odf_file)
filp_close(odf_file, NULL);
+ odf_unlock(UNIONFS_SB(sb)->odf->odi_ic);
unionfs_read_unlock(sb);
+ if (err == -ENOSPC && !cleaned) {
+ cleaned = 1;
+ wake_up_sioa(UNIONFS_SB(sb)->odf->cleanup);
+ schedule();
+ goto retry;
+ }
return err;
}
diff --git a/fs/unionfs/odf.c b/fs/unionfs/odf.c
index c55c6a2..c186c21 100644
--- a/fs/unionfs/odf.c
+++ b/fs/unionfs/odf.c
@@ -363,6 +363,7 @@ out:
* (useful for create where we want to rmv wh's)
* - ODF_LOOKUP_OPQ: if a dir is created, set it opaque (branch 0)
* - ODF_LOOKUP_WH: create a whiteout
+ * - ODF_LOOKUP_LOCKED: dont lock parent and ic (already locked from
caller)
*/
int odf_lookup(struct dentry *parent, struct dentry *dentry, int flags)
{
@@ -426,9 +427,11 @@ retry:
oldgid = current->fsgid;
/* FIXME need to check hardlinks before create */
- if (osi->odi_ic != parent)
- odf_lock(osi->odi_ic);
- odf_lock(parent); /* lock parent */
+ if (!(flags & ODF_LOOKUP_LOCKED)){
+ if (osi->odi_ic != parent)
+ odf_lock(osi->odi_ic);
+ odf_lock(parent); /* lock parent */
+ }
if (flags & ODF_LOOKUP_FILE || flags & ODF_LOOKUP_WH) {
current->fsuid = 0;
@@ -442,16 +445,20 @@ retry:
}
else {
dput(odf_dentry);
- odf_unlock(parent);
- if (osi->odi_ic != parent)
- odf_unlock(osi->odi_ic);
+ if (!(flags & ODF_LOOKUP_LOCKED)){
+ odf_unlock(parent);
+ if (osi->odi_ic != parent)
+ odf_unlock(osi->odi_ic);
+ }
odf_put_info(old_odi);
odi = NULL;
goto out;
}
- odf_unlock(parent);
- if (osi->odi_ic != parent)
- odf_unlock(osi->odi_ic);
+ if (!(flags & ODF_LOOKUP_LOCKED)){
+ odf_unlock(parent);
+ if (osi->odi_ic != parent)
+ odf_unlock(osi->odi_ic);
+ }
current->fsuid = oldgid;
current->fsgid = olduid;
diff --git a/fs/unionfs/odf.h b/fs/unionfs/odf.h
index d83519b..f994a7d 100644
--- a/fs/unionfs/odf.h
+++ b/fs/unionfs/odf.h
@@ -25,6 +25,7 @@
#define ODF_LOOKUP_RMV_WH 4
#define ODF_LOOKUP_OPQ 8
#define ODF_LOOKUP_WH 16
+#define ODF_LOOKUP_LOCKED 32
/* Unlink/Remove flags */
#define ODF_RMV_WH 1
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs