Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/fs/tmpfs Finish and enable whiteout support for tmpfs:
details: https://anonhg.NetBSD.org/src/rev/a9ebba7abcd5
branches: trunk
changeset: 768781:a9ebba7abcd5
user: hannken <hannken%NetBSD.org@localhost>
date: Sat Aug 27 15:32:28 2011 +0000
description:
Finish and enable whiteout support for tmpfs:
- Enable VOP tmpfs_whiteout().
- Support ISWHITEOUT in tmpfs_alloc_file().
- Support DOWHITEOUT in tmpfs_remove() and tmpfs_rmdir().
- Make rmdir on a directory containing whiteouts working.
Should fix PR #35112 (tmpfs doesn't play well with unionfs).
diffstat:
sys/fs/tmpfs/tmpfs_subr.c | 20 +++++++++++++++---
sys/fs/tmpfs/tmpfs_vnops.c | 49 +++++++++++++++++++++++++++++++--------------
2 files changed, 50 insertions(+), 19 deletions(-)
diffs (170 lines):
diff -r b574a3eaba06 -r a9ebba7abcd5 sys/fs/tmpfs/tmpfs_subr.c
--- a/sys/fs/tmpfs/tmpfs_subr.c Sat Aug 27 15:08:58 2011 +0000
+++ b/sys/fs/tmpfs/tmpfs_subr.c Sat Aug 27 15:32:28 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tmpfs_subr.c,v 1.76 2011/06/30 00:37:07 enami Exp $ */
+/* $NetBSD: tmpfs_subr.c,v 1.77 2011/08/27 15:32:28 hannken Exp $ */
/*
* Copyright (c) 2005-2011 The NetBSD Foundation, Inc.
@@ -74,7 +74,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tmpfs_subr.c,v 1.76 2011/06/30 00:37:07 enami Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tmpfs_subr.c,v 1.77 2011/08/27 15:32:28 hannken Exp $");
#include <sys/param.h>
#include <sys/dirent.h>
@@ -343,7 +343,7 @@
{
tmpfs_mount_t *tmp = VFS_TO_TMPFS(dvp->v_mount);
tmpfs_node_t *dnode = VP_TO_TMPFS_DIR(dvp), *node;
- tmpfs_dirent_t *de;
+ tmpfs_dirent_t *de, *wde;
int error;
KASSERT(VOP_ISLOCKED(dvp));
@@ -381,8 +381,20 @@
goto out;
}
+ /* Remove whiteout before adding the new entry. */
+ if (cnp->cn_flags & ISWHITEOUT) {
+ wde = tmpfs_dir_lookup(dnode, cnp);
+ KASSERT(wde != NULL && wde->td_node == TMPFS_NODE_WHITEOUT);
+ tmpfs_dir_detach(dvp, wde);
+ tmpfs_free_dirent(tmp, wde);
+ }
+
/* Associate inode and attach the entry into the directory. */
tmpfs_dir_attach(dvp, de, node);
+
+ /* Make node opaque if requested. */
+ if (cnp->cn_flags & ISWHITEOUT)
+ node->tn_flags |= UF_OPAQUE;
out:
vput(dvp);
return error;
@@ -444,8 +456,8 @@
KASSERT(VOP_ISLOCKED(dvp));
/* Associate directory entry and the inode. */
+ de->td_node = node;
if (node != TMPFS_NODE_WHITEOUT) {
- de->td_node = node;
KASSERT(node->tn_links < LINK_MAX);
node->tn_links++;
diff -r b574a3eaba06 -r a9ebba7abcd5 sys/fs/tmpfs/tmpfs_vnops.c
--- a/sys/fs/tmpfs/tmpfs_vnops.c Sat Aug 27 15:08:58 2011 +0000
+++ b/sys/fs/tmpfs/tmpfs_vnops.c Sat Aug 27 15:32:28 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tmpfs_vnops.c,v 1.89 2011/08/18 21:42:18 riastradh Exp $ */
+/* $NetBSD: tmpfs_vnops.c,v 1.90 2011/08/27 15:32:28 hannken Exp $ */
/*
* Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.89 2011/08/18 21:42:18 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.90 2011/08/27 15:32:28 hannken Exp $");
#include <sys/param.h>
#include <sys/dirent.h>
@@ -103,9 +103,7 @@
{ &vop_bwrite_desc, tmpfs_bwrite },
{ &vop_getpages_desc, tmpfs_getpages },
{ &vop_putpages_desc, tmpfs_putpages },
-#if TMPFS_WHITEOUT
{ &vop_whiteout_desc, tmpfs_whiteout },
-#endif
{ NULL, NULL }
};
@@ -713,11 +711,15 @@
/*
* Remove the entry from the directory (drops the link count) and
- * destroy it. Note: the inode referred by it will not be destroyed
+ * destroy it or replace it with a whiteout.
+ * Note: the inode referred by it will not be destroyed
* until the vnode is reclaimed/recycled.
*/
tmpfs_dir_detach(dvp, de);
- tmpfs_free_dirent(VFS_TO_TMPFS(vp->v_mount), de);
+ if (ap->a_cnp->cn_flags & DOWHITEOUT)
+ tmpfs_dir_attach(dvp, de, TMPFS_NODE_WHITEOUT);
+ else
+ tmpfs_free_dirent(VFS_TO_TMPFS(vp->v_mount), de);
error = 0;
out:
/* Drop the references and unlock the vnodes. */
@@ -2103,12 +2105,19 @@
KASSERT(node->tn_spec.tn_dir.tn_parent == dnode);
/*
- * Directories with more than two entries ('.' and '..') cannot
- * be removed.
+ * Directories with more than two non-whiteout
+ * entries ('.' and '..') cannot be removed.
*/
if (node->tn_size > 0) {
- error = ENOTEMPTY;
- goto out;
+ KASSERT(error == 0);
+ TAILQ_FOREACH(de, &node->tn_spec.tn_dir.tn_dir, td_entries) {
+ if (de->td_node != TMPFS_NODE_WHITEOUT) {
+ error = ENOTEMPTY;
+ break;
+ }
+ }
+ if (error)
+ goto out;
}
/* Lookup the directory entry (check the cached hint first). */
@@ -2136,10 +2145,22 @@
cache_purge(dvp);
/*
- * Destroy the directory entry. Note: the inode referred by it
- * will not be destroyed until the vnode is reclaimed.
+ * Destroy the directory entry or replace it with a whiteout.
+ * Note: the inode referred by it will not be destroyed
+ * until the vnode is reclaimed.
*/
- tmpfs_free_dirent(tmp, de);
+ if (ap->a_cnp->cn_flags & DOWHITEOUT)
+ tmpfs_dir_attach(dvp, de, TMPFS_NODE_WHITEOUT);
+ else
+ tmpfs_free_dirent(tmp, de);
+
+ /* Destroy the whiteout entries from the node. */
+ while ((de = TAILQ_FIRST(&node->tn_spec.tn_dir.tn_dir)) != NULL) {
+ KASSERT(de->td_node == TMPFS_NODE_WHITEOUT);
+ tmpfs_dir_detach(vp, de);
+ tmpfs_free_dirent(tmp, de);
+ }
+
KASSERT(node->tn_links == 0);
out:
/* Release the nodes. */
@@ -2507,7 +2528,6 @@
return error;
}
-#ifdef TMPFS_WHITEOUT
int
tmpfs_whiteout(void *v)
{
@@ -2544,7 +2564,6 @@
}
return 0;
}
-#endif
int
tmpfs_print(void *v)
Home |
Main Index |
Thread Index |
Old Index