Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/fs/smbfs When a vnode has an invalid type because the ty...
details: https://anonhg.NetBSD.org/src/rev/2c7abfb58b8e
branches: trunk
changeset: 824224:2c7abfb58b8e
user: hannken <hannken%NetBSD.org@localhost>
date: Sun May 28 16:36:37 2017 +0000
description:
When a vnode has an invalid type because the type changed on the
server replace vgone() with new operation smbfs_uncache() that
removes the vnode from the name cache and changes the vcache key
to an unique and illegal key to prevent further lookups.
diffstat:
sys/fs/smbfs/smbfs_node.c | 56 +++++++++++++++++++++++++++++++++++++++++++--
sys/fs/smbfs/smbfs_node.h | 3 +-
sys/fs/smbfs/smbfs_vnops.c | 7 ++---
3 files changed, 58 insertions(+), 8 deletions(-)
diffs (132 lines):
diff -r 3be3e45ba3a1 -r 2c7abfb58b8e sys/fs/smbfs/smbfs_node.c
--- a/sys/fs/smbfs/smbfs_node.c Sun May 28 16:35:47 2017 +0000
+++ b/sys/fs/smbfs/smbfs_node.c Sun May 28 16:36:37 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: smbfs_node.c,v 1.57 2017/05/26 14:34:20 riastradh Exp $ */
+/* $NetBSD: smbfs_node.c,v 1.58 2017/05/28 16:36:37 hannken Exp $ */
/*
* Copyright (c) 2000-2001 Boris Popov
@@ -35,10 +35,11 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: smbfs_node.c,v 1.57 2017/05/26 14:34:20 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: smbfs_node.c,v 1.58 2017/05/28 16:36:37 hannken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/atomic.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
@@ -191,7 +192,8 @@
if ((vp->v_type == VDIR && (np->n_dosattr & SMB_FA_DIR) == 0) ||
(vp->v_type == VREG && (np->n_dosattr & SMB_FA_DIR) != 0)) {
mutex_exit(&np->n_lock);
- vgone(vp);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ smbfs_uncache(vp);
goto retry;
}
}
@@ -207,6 +209,54 @@
}
/*
+ * Remove vnode that changed its type on the server from
+ * the vnode cache and the name cache.
+ */
+void
+smbfs_uncache(struct vnode *vp)
+{
+ static uint32_t gen = 0;
+ int error __diagused;
+ char newname[10];
+ struct mount *mp = vp->v_mount;
+ struct smbnode *np = VTOSMB(vp);
+ struct smbkey *key = np->n_key, *oldkey, *newkey;
+ int key_len = SMBFS_KEYSIZE(key->k_nmlen), newkey_len;
+
+ /* Setup old key as current key. */
+ oldkey = kmem_alloc(key_len, KM_SLEEP);
+ memcpy(oldkey, key, key_len);
+
+ /* Setup new key as unique and illegal name with colon. */
+ snprintf(newname, sizeof(newname), ":%08x", atomic_inc_uint_nv(&gen));
+ newkey = kmem_alloc(SMBFS_KEYSIZE(strlen(newname)), KM_SLEEP);
+ newkey->k_parent = NULL;
+ newkey->k_nmlen = strlen(newname);
+ memcpy(newkey->k_name, newname, newkey->k_nmlen);
+ newkey_len = SMBFS_KEYSIZE(newkey->k_nmlen);
+
+ /* Release parent and mark as gone. */
+ if (np->n_parent && (np->n_flag & NREFPARENT)) {
+ vrele(np->n_parent);
+ np->n_flag &= ~NREFPARENT;
+ }
+ np->n_flag |= NGONE;
+
+ /* Rekey the node. */
+ error = vcache_rekey_enter(mp, vp, oldkey, key_len, newkey, newkey_len);
+ KASSERT(error == 0);
+ np->n_key = newkey;
+ vcache_rekey_exit(mp, vp, oldkey, key_len, newkey, newkey_len);
+
+ /* Purge from name cache and cleanup. */
+ cache_purge(vp);
+ kmem_free(key, key_len);
+ kmem_free(oldkey, key_len);
+
+ vput(vp);
+}
+
+/*
* Free smbnode, and give vnode back to system
*/
int
diff -r 3be3e45ba3a1 -r 2c7abfb58b8e sys/fs/smbfs/smbfs_node.h
--- a/sys/fs/smbfs/smbfs_node.h Sun May 28 16:35:47 2017 +0000
+++ b/sys/fs/smbfs/smbfs_node.h Sun May 28 16:36:37 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: smbfs_node.h,v 1.15 2015/01/02 09:48:01 martin Exp $ */
+/* $NetBSD: smbfs_node.h,v 1.16 2017/05/28 16:36:37 hannken Exp $ */
/*
* Copyright (c) 2000-2001, Boris Popov
@@ -97,6 +97,7 @@
const void *, size_t, const void **);
int smbfs_nget(struct mount *, struct vnode *, const char *, int,
struct smbfattr *, struct vnode **);
+void smbfs_uncache(struct vnode *);
int smbfs_readvnode(struct vnode *, struct uio *, kauth_cred_t);
int smbfs_writevnode(struct vnode *, struct uio *, kauth_cred_t, int);
diff -r 3be3e45ba3a1 -r 2c7abfb58b8e sys/fs/smbfs/smbfs_vnops.c
--- a/sys/fs/smbfs/smbfs_vnops.c Sun May 28 16:35:47 2017 +0000
+++ b/sys/fs/smbfs/smbfs_vnops.c Sun May 28 16:36:37 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: smbfs_vnops.c,v 1.94 2017/04/26 03:02:48 riastradh Exp $ */
+/* $NetBSD: smbfs_vnops.c,v 1.95 2017/05/28 16:36:37 hannken Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -64,7 +64,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: smbfs_vnops.c,v 1.94 2017/04/26 03:02:48 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: smbfs_vnops.c,v 1.95 2017/05/28 16:36:37 hannken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -1269,8 +1269,7 @@
cache_purge(newvp);
if (newvp != dvp) {
if (killit) {
- VOP_UNLOCK(newvp);
- vgone(newvp);
+ smbfs_uncache(newvp);
} else
vput(newvp);
} else
Home |
Main Index |
Thread Index |
Old Index