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