Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/fs/smbfs Various fixes for smbfs:
details: https://anonhg.NetBSD.org/src/rev/a61b42acc12f
branches: trunk
changeset: 782951:a61b42acc12f
user: nakayama <nakayama%NetBSD.org@localhost>
date: Wed Nov 28 13:34:24 2012 +0000
description:
Various fixes for smbfs:
- Implement NGONE to fix caching issue described in PR kern/25070.
Mostly taken from FreeBSD r125637.
- Revert revision 1.70 of smbfs_vnops.c to fix setattr to opened
direcotry. In case of SMB_CAP_NT_SMBS, NOPEN is set after
smbfs_smb_ntcreatex() call. If NOPEN is set in front, it will
immediately return by condition at do_open label.
- In smbfs_close(), call smbfs_smb_close() and drop NOPEN bit in
the case of direcotry. Otherwise smbfs_rmdir() fails when the
directory was opened.
diffstat:
sys/fs/smbfs/smbfs_node.c | 22 +++++++++++++++---
sys/fs/smbfs/smbfs_node.h | 3 +-
sys/fs/smbfs/smbfs_vnops.c | 54 ++++++++++++++++++++++++++++++++++++---------
3 files changed, 63 insertions(+), 16 deletions(-)
diffs (205 lines):
diff -r e9f12911d550 -r a61b42acc12f sys/fs/smbfs/smbfs_node.c
--- a/sys/fs/smbfs/smbfs_node.c Wed Nov 28 11:31:27 2012 +0000
+++ b/sys/fs/smbfs/smbfs_node.c Wed Nov 28 13:34:24 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: smbfs_node.c,v 1.47 2011/06/12 03:35:54 rmind Exp $ */
+/* $NetBSD: smbfs_node.c,v 1.48 2012/11/28 13:34:24 nakayama Exp $ */
/*
* Copyright (c) 2000-2001 Boris Popov
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: smbfs_node.c,v 1.47 2011/06/12 03:35:54 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: smbfs_node.c,v 1.48 2012/11/28 13:34:24 nakayama Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -96,6 +96,7 @@
smbfs_node_alloc(struct mount *mp, struct vnode *dvp,
const char *name, int nmlen, struct smbfattr *fap, struct vnode **vpp)
{
+ struct vattr vattr;
struct smbmount *smp = VFSTOSMBFS(mp);
struct smbnode_hashhead *nhpp;
struct smbnode *np, *np2, *dnp;
@@ -139,6 +140,20 @@
mutex_exit(&smp->sm_hashlock);
if (vget(vp, LK_EXCLUSIVE) != 0)
goto retry;
+ /* Force cached attributes to be refreshed if stale. */
+ (void)VOP_GETATTR(vp, &vattr, curlwp->l_cred);
+ /*
+ * If the file type on the server is inconsistent with
+ * what it was when we created the vnode, kill the
+ * bogus vnode now and fall through to the code below
+ * to create a new one with the right type.
+ */
+ if ((vp->v_type == VDIR && (np->n_dosattr & SMB_FA_DIR) == 0) ||
+ (vp->v_type == VREG && (np->n_dosattr & SMB_FA_DIR) != 0)) {
+ vput(vp);
+ vgone(vp);
+ break;
+ }
*vpp = vp;
return (0);
}
@@ -307,10 +322,9 @@
np->n_flag &= ~NOPEN;
smbfs_attr_cacheremove(vp);
}
+ *ap->a_recycle = ((np->n_flag & NGONE) != 0);
VOP_UNLOCK(vp);
- *ap->a_recycle = false; /* XXX: should set the value properly */
-
return (0);
}
/*
diff -r e9f12911d550 -r a61b42acc12f sys/fs/smbfs/smbfs_node.h
--- a/sys/fs/smbfs/smbfs_node.h Wed Nov 28 11:31:27 2012 +0000
+++ b/sys/fs/smbfs/smbfs_node.h Wed Nov 28 13:34:24 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: smbfs_node.h,v 1.12 2006/11/02 17:34:21 jmmv Exp $ */
+/* $NetBSD: smbfs_node.h,v 1.13 2012/11/28 13:34:24 nakayama Exp $ */
/*
* Copyright (c) 2000-2001, Boris Popov
@@ -48,6 +48,7 @@
/*efine NNEW 0x0008*//* smb/vnode has been allocated */
#define NREFPARENT 0x0010 /* node holds parent from recycling */
#define NOPEN 0x2000 /* file is open */
+#define NGONE 0x4000 /* file has been removed/renamed */
#define SMBFS_ATTRTIMO 5 /* Attribute cache timeout in sec */
diff -r e9f12911d550 -r a61b42acc12f sys/fs/smbfs/smbfs_vnops.c
--- a/sys/fs/smbfs/smbfs_vnops.c Wed Nov 28 11:31:27 2012 +0000
+++ b/sys/fs/smbfs/smbfs_vnops.c Wed Nov 28 13:34:24 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: smbfs_vnops.c,v 1.82 2012/11/05 17:27:38 dholland Exp $ */
+/* $NetBSD: smbfs_vnops.c,v 1.83 2012/11/28 13:34:24 nakayama 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.82 2012/11/05 17:27:38 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: smbfs_vnops.c,v 1.83 2012/11/28 13:34:24 nakayama Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -252,9 +252,10 @@
return EACCES;
}
if (vp->v_type == VDIR) {
- np->n_flag |= NOPEN;
- if ((sv_caps & SMB_CAP_NT_SMBS) == 0)
+ if ((sv_caps & SMB_CAP_NT_SMBS) == 0) {
+ np->n_flag |= NOPEN;
return 0;
+ }
goto do_open; /* skip 'modified' check */
}
@@ -339,13 +340,22 @@
* Ideally, the lookup routines should handle such case, and
* the context would be removed only in smbfs_inactive().
*/
- if (vp->v_type == VDIR && (np->n_flag & NOPEN) != 0 &&
- np->n_dirseq != NULL) {
+ if (vp->v_type == VDIR && (np->n_flag & NOPEN) != 0) {
+ struct smb_share *ssp = np->n_mount->sm_share;
struct smb_cred scred;
smb_makescred(&scred, l, ap->a_cred);
- smbfs_findclose(np->n_dirseq, &scred);
- np->n_dirseq = NULL;
+
+ if (np->n_dirseq != NULL) {
+ smbfs_findclose(np->n_dirseq, &scred);
+ np->n_dirseq = NULL;
+ }
+
+ if (SMB_CAPS(SSTOVC(ssp)) & SMB_CAP_NT_SMBS)
+ smbfs_smb_close(ssp, np->n_fid, &np->n_mtime, &scred);
+
+ np->n_flag &= ~NOPEN;
+ smbfs_attr_cacheremove(vp);
}
return (0);
@@ -629,6 +639,8 @@
smb_makescred(&scred, curlwp, cnp->cn_cred);
error = smbfs_smb_delete(np, &scred);
}
+ if (error == 0)
+ np->n_flag |= NGONE;
VN_KNOTE(ap->a_vp, NOTE_DELETE);
VN_KNOTE(ap->a_dvp, NOTE_WRITE);
@@ -706,6 +718,7 @@
error = smbfs_smb_delete(VTOSMB(tvp), &scred);
if (error)
goto out;
+ VTOSMB(tvp)->n_flag |= NGONE;
VN_KNOTE(tdvp, NOTE_WRITE);
VN_KNOTE(tvp, NOTE_DELETE);
cache_purge(tvp);
@@ -831,6 +844,8 @@
smb_makescred(&scred, curlwp, cnp->cn_cred);
error = smbfs_smb_rmdir(np, &scred);
+ if (error == 0)
+ np->n_flag |= NGONE;
dnp->n_flag |= NMODIFIED;
smbfs_attr_cacheremove(dvp);
VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK);
@@ -1208,6 +1223,7 @@
NULL, vpp)) {
struct vattr vattr;
struct vnode *newvp;
+ bool killit = false;
error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred);
if (error != 0) {
@@ -1231,7 +1247,21 @@
}
newvp = *vpp;
- if (!VOP_GETATTR(newvp, &vattr, cnp->cn_cred)
+ error = VOP_GETATTR(newvp, &vattr, cnp->cn_cred);
+ /*
+ * If the file type on the server is inconsistent
+ * with what it was when we created the vnode,
+ * kill the bogus vnode now and fall through to
+ * the code below to create a new one with the
+ * right type.
+ */
+ if (error == 0 &&
+ ((newvp->v_type == VDIR &&
+ (VTOSMB(newvp)->n_dosattr & SMB_FA_DIR) == 0) ||
+ (newvp->v_type == VREG &&
+ (VTOSMB(newvp)->n_dosattr & SMB_FA_DIR) != 0)))
+ killit = true;
+ else if (error == 0
&& vattr.va_ctime.tv_sec == VTOSMB(newvp)->n_ctime)
{
/* nfsstats.lookupcache_hits++; */
@@ -1239,9 +1269,11 @@
}
cache_purge(newvp);
- if (newvp != dvp)
+ if (newvp != dvp) {
vput(newvp);
- else
+ if (killit)
+ vgone(newvp);
+ } else
vrele(newvp);
*vpp = NULLVP;
}
Home |
Main Index |
Thread Index |
Old Index