Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-6]: src/sys/fs/smbfs Pull up following revision(s) (requested by ...
details: https://anonhg.NetBSD.org/src/rev/6490b62e98a6
branches: netbsd-6
changeset: 775559:6490b62e98a6
user: riz <riz%NetBSD.org@localhost>
date: Mon Dec 10 21:12:51 2012 +0000
description:
Pull up following revision(s) (requested by nakayama in ticket #731):
sys/fs/smbfs/smbfs_node.h: revision 1.13
sys/fs/smbfs/smbfs_node.c: revision 1.48
sys/fs/smbfs/smbfs_node.c: revision 1.49
sys/fs/smbfs/smbfs_vnops.c: revision 1.83
sys/fs/smbfs/smbfs_vnops.c: revision 1.84
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.
- Remove redundant vput() before vgone().
- Avoid unnecessary mutex_exit() in smbfs_node_alloc().
- Set NGONE bit to from-name vnode to invalidate the smbnode cache.
diffstat:
sys/fs/smbfs/smbfs_node.c | 23 ++++++++++++++---
sys/fs/smbfs/smbfs_node.h | 3 +-
sys/fs/smbfs/smbfs_vnops.c | 59 ++++++++++++++++++++++++++++++++++++---------
3 files changed, 68 insertions(+), 17 deletions(-)
diffs (221 lines):
diff -r 0a8564d74407 -r 6490b62e98a6 sys/fs/smbfs/smbfs_node.c
--- a/sys/fs/smbfs/smbfs_node.c Mon Dec 10 18:27:00 2012 +0000
+++ b/sys/fs/smbfs/smbfs_node.c Mon Dec 10 21:12:51 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.47.8.1 2012/12/10 21:12:51 riz 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.47.8.1 2012/12/10 21:12:51 riz 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,11 +140,26 @@
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)) {
+ VOP_UNLOCK(vp);
+ vgone(vp);
+ goto allocnew;
+ }
*vpp = vp;
return (0);
}
mutex_exit(&smp->sm_hashlock);
+allocnew:
/*
* If we don't have node attributes, then it is an explicit lookup
* for an existing vnode.
@@ -307,10 +323,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 0a8564d74407 -r 6490b62e98a6 sys/fs/smbfs/smbfs_node.h
--- a/sys/fs/smbfs/smbfs_node.h Mon Dec 10 18:27:00 2012 +0000
+++ b/sys/fs/smbfs/smbfs_node.h Mon Dec 10 21:12:51 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.12.94.1 2012/12/10 21:12:51 riz 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 0a8564d74407 -r 6490b62e98a6 sys/fs/smbfs/smbfs_vnops.c
--- a/sys/fs/smbfs/smbfs_vnops.c Mon Dec 10 18:27:00 2012 +0000
+++ b/sys/fs/smbfs/smbfs_vnops.c Mon Dec 10 21:12:51 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: smbfs_vnops.c,v 1.78.2.1 2012/08/12 12:59:51 martin Exp $ */
+/* $NetBSD: smbfs_vnops.c,v 1.78.2.2 2012/12/10 21:12:51 riz 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.78.2.1 2012/08/12 12:59:51 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: smbfs_vnops.c,v 1.78.2.2 2012/12/10 21:12:51 riz Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -250,9 +250,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 */
}
@@ -337,13 +338,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);
@@ -624,6 +634,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);
@@ -701,12 +713,14 @@
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);
}
error = smbfs_smb_rename(VTOSMB(fvp), VTOSMB(tdvp),
tcnp->cn_nameptr, tcnp->cn_namelen, &scred);
+ VTOSMB(fvp)->n_flag |= NGONE;
VN_KNOTE(fdvp, NOTE_WRITE);
VN_KNOTE(fvp, NOTE_RENAME);
}
@@ -826,6 +840,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);
@@ -1202,6 +1218,7 @@
struct vattr vattr;
struct vnode *newvp;
int err2;
+ bool killit = false;
if (error && error != ENOENT) {
*vpp = NULLVP;
@@ -1230,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++; */
@@ -1238,9 +1269,13 @@
}
cache_purge(newvp);
- if (newvp != dvp)
- vput(newvp);
- else
+ if (newvp != dvp) {
+ if (killit) {
+ VOP_UNLOCK(newvp);
+ vgone(newvp);
+ } else
+ vput(newvp);
+ } else
vrele(newvp);
*vpp = NULLVP;
}
Home |
Main Index |
Thread Index |
Old Index