Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/rump/librump/rumpvfs support dotdot lookups
details: https://anonhg.NetBSD.org/src/rev/77da6ce35806
branches: trunk
changeset: 756347:77da6ce35806
user: pooka <pooka%NetBSD.org@localhost>
date: Tue Jul 13 18:08:58 2010 +0000
description:
support dotdot lookups
diffstat:
sys/rump/librump/rumpvfs/rumpfs.c | 51 +++++++++++++++++++++++++-------------
1 files changed, 33 insertions(+), 18 deletions(-)
diffs (139 lines):
diff -r d0a32b30a97e -r 77da6ce35806 sys/rump/librump/rumpvfs/rumpfs.c
--- a/sys/rump/librump/rumpvfs/rumpfs.c Tue Jul 13 17:49:24 2010 +0000
+++ b/sys/rump/librump/rumpvfs/rumpfs.c Tue Jul 13 18:08:58 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rumpfs.c,v 1.61 2010/07/09 08:10:50 hannken Exp $ */
+/* $NetBSD: rumpfs.c,v 1.62 2010/07/13 18:08:58 pooka Exp $ */
/*
* Copyright (c) 2009 Antti Kantee. All Rights Reserved.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rumpfs.c,v 1.61 2010/07/09 08:10:50 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rumpfs.c,v 1.62 2010/07/13 18:08:58 pooka Exp $");
#include <sys/param.h>
#include <sys/atomic.h>
@@ -149,6 +149,7 @@
} reg;
struct { /* VDIR */
LIST_HEAD(, rumpfs_dent) dents;
+ struct rumpfs_node *parent;
int flags;
} dir;
struct {
@@ -161,6 +162,7 @@
#define rn_writefd rn_u.reg.writefd
#define rn_offset rn_u.reg.offset
#define rn_dir rn_u.dir.dents
+#define rn_parent rn_u.dir.parent
#define rn_linktarg rn_u.link.target
#define rn_linklen rn_u.link.len
@@ -579,13 +581,8 @@
struct rumpfs_node *rnd = dvp->v_data, *rn;
struct rumpfs_dent *rd = NULL;
struct etfs *et;
- int rv;
-
- /* we handle only some "non-special" cases */
- if (!(((cnp->cn_flags & ISLASTCN) == 0) || (cnp->cn_nameiop != RENAME)))
- return EOPNOTSUPP;
- if (!((cnp->cn_flags & ISDOTDOT) == 0))
- return EOPNOTSUPP;
+ bool dotdot = (cnp->cn_flags & ISDOTDOT) != 0;
+ int rv = 0;
/* check for dot, return directly if the case */
if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') {
@@ -594,6 +591,10 @@
return 0;
}
+ /* we handle only some "non-special" cases */
+ if (!(((cnp->cn_flags & ISLASTCN) == 0) || (cnp->cn_nameiop != RENAME)))
+ return EOPNOTSUPP;
+
/* check for etfs */
if (dvp == rootvnode && cnp->cn_nameiop == LOOKUP) {
bool found;
@@ -622,6 +623,9 @@
size_t newpathlen;
int hft, error;
+ if (dotdot)
+ return EOPNOTSUPP;
+
newpathlen = strlen(rnd->rn_hostpath) + 1 + cnp->cn_namelen + 1;
newpath = malloc(newpathlen, M_TEMP, M_WAITOK);
@@ -649,11 +653,16 @@
goto getvnode;
} else {
- LIST_FOREACH(rd, &rnd->rn_dir, rd_entries) {
- if (rd->rd_namelen == cnp->cn_namelen &&
- strncmp(rd->rd_name, cnp->cn_nameptr,
- cnp->cn_namelen) == 0)
- break;
+ if (dotdot) {
+ rn = rnd->rn_parent;
+ goto getvnode;
+ } else {
+ LIST_FOREACH(rd, &rnd->rn_dir, rd_entries) {
+ if (rd->rd_namelen == cnp->cn_namelen &&
+ strncmp(rd->rd_name, cnp->cn_nameptr,
+ cnp->cn_namelen) == 0)
+ break;
+ }
}
}
@@ -671,21 +680,25 @@
getvnode:
KASSERT(rn);
+ if (dotdot)
+ VOP_UNLOCK(dvp);
mutex_enter(&reclock);
if ((vp = rn->rn_vp)) {
mutex_enter(&vp->v_interlock);
mutex_exit(&reclock);
- if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK))
+ if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK)) {
+ vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
goto getvnode;
+ }
*vpp = vp;
} else {
mutex_exit(&reclock);
rv = makevnode(dvp->v_mount, rn, vpp);
- if (rv)
- return rv;
}
+ if (dotdot)
+ vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
- return 0;
+ return rv;
}
static int
@@ -718,6 +731,7 @@
int rv = 0;
rn = makeprivate(VDIR, NODEV, DEV_BSIZE);
+ rn->rn_parent = rnd;
rv = makevnode(dvp->v_mount, rn, vpp);
if (rv)
goto out;
@@ -1254,6 +1268,7 @@
rfsmp = kmem_alloc(sizeof(*rfsmp), KM_SLEEP);
rn = makeprivate(VDIR, NODEV, DEV_BSIZE);
+ rn->rn_parent = rn;
error = makevnode(mp, rn, &rfsmp->rfsmp_rvp);
if (error)
panic("could not create root vnode: %d", error);
Home |
Main Index |
Thread Index |
Old Index