Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/fs/tmpfs tmpfs_rename: handle hard-links correctly. Fix...
details: https://anonhg.NetBSD.org/src/rev/854abac05be3
branches: trunk
changeset: 747932:854abac05be3
user: rmind <rmind%NetBSD.org@localhost>
date: Tue Oct 06 00:17:24 2009 +0000
description:
tmpfs_rename: handle hard-links correctly. Fixes PR/41236.
diffstat:
sys/fs/tmpfs/tmpfs_vnops.c | 42 ++++++++++++++++++++++++++----------------
1 files changed, 26 insertions(+), 16 deletions(-)
diffs (98 lines):
diff -r 8f18d0b6b274 -r 854abac05be3 sys/fs/tmpfs/tmpfs_vnops.c
--- a/sys/fs/tmpfs/tmpfs_vnops.c Mon Oct 05 23:59:30 2009 +0000
+++ b/sys/fs/tmpfs/tmpfs_vnops.c Tue Oct 06 00:17:24 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tmpfs_vnops.c,v 1.62 2009/09/03 04:45:28 elad Exp $ */
+/* $NetBSD: tmpfs_vnops.c,v 1.63 2009/10/06 00:17:24 rmind 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.62 2009/09/03 04:45:28 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.63 2009/10/06 00:17:24 rmind Exp $");
#include <sys/param.h>
#include <sys/dirent.h>
@@ -746,9 +746,7 @@
/* Lock vp because we will need to run tmpfs_update over it, which
* needs the vnode to be locked. */
- error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
- if (error != 0)
- goto out1;
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
/* XXX: Why aren't the following two tests done by the caller? */
@@ -795,16 +793,24 @@
out:
VOP_UNLOCK(vp, 0);
-out1:
PNBUF_PUT(cnp->cn_pnbuf);
-
vput(dvp);
return error;
}
-/* --------------------------------------------------------------------- */
-
+/*
+ * tmpfs_rename: rename routine.
+ *
+ * Arguments: fdvp (from-parent vnode), fvp (from-leaf), tdvp (to-parent)
+ * and tvp (to-leaf), if exists (NULL if not).
+ *
+ * => Caller holds a reference on fdvp and fvp, they are unlocked.
+ * Note: fdvp and fvp can refer to the same object (i.e. when it is root).
+ *
+ * => Both tdvp and tvp are referenced and locked. It is our responsibility
+ * to release the references and unlock them (or destroy).
+ */
int
tmpfs_rename(void *v)
{
@@ -857,9 +863,7 @@
/* XXX: this is a potential locking order violation! */
if (fdnode != tdnode) {
- error = vn_lock(fdvp, LK_EXCLUSIVE | LK_RETRY);
- if (error != 0)
- goto out_unlocked;
+ vn_lock(fdvp, LK_EXCLUSIVE | LK_RETRY);
}
/*
@@ -871,10 +875,16 @@
goto out;
}
- /* If source and target are the same file, there is nothing to do. */
+ /* If source and target is the same vnode, remove the source link. */
if (fvp == tvp) {
- error = 0;
- goto out;
+ /*
+ * Detach and free the directory entry. Drops the link
+ * count on the node.
+ */
+ tmpfs_dir_detach(fdvp, de);
+ tmpfs_free_dirent(VFS_TO_TMPFS(fvp->v_mount), de, true);
+ VN_KNOTE(fdvp, NOTE_WRITE);
+ goto out_ok;
}
/* If replacing an existing entry, ensure we can do the operation. */
@@ -986,7 +996,7 @@
fnode->tn_status |= TMPFS_NODE_CHANGED;
tdnode->tn_status |= TMPFS_NODE_MODIFIED;
}
-
+ out_ok:
/* Notify listeners of tdvp about the change in the directory (either
* because a new entry was added or because one was removed) and
* listeners of fvp about the rename. */
Home |
Main Index |
Thread Index |
Old Index