Author: emaste
Date: Tue Jun 16 13:05:34 2009
New Revision: 194289
URL: http://svn.freebsd.org/changeset/base/194289

Log:
  MFC part of r166182 and 179670.
  
    Provide the mutual exclusion between the nfs export list modifications
    and nfs requests processing. Lockmgr lock provides the shared locking for
    nfs requests, while exclusive mode is used for modifications. The writer
    starvation is handled by lockmgr too.
  
  Submitted by: kib

Modified:
  stable/6/sys/kern/vfs_export.c
  stable/6/sys/kern/vfs_mount.c
  stable/6/sys/sys/mount.h

Modified: stable/6/sys/kern/vfs_export.c
==============================================================================
--- stable/6/sys/kern/vfs_export.c      Tue Jun 16 12:33:38 2009        
(r194288)
+++ stable/6/sys/kern/vfs_export.c      Tue Jun 16 13:05:34 2009        
(r194289)
@@ -179,6 +179,7 @@ vfs_hang_addrlist(mp, nep, argp)
            sizeof(np->netc_anon.cr_groups));
        refcount_init(&np->netc_anon.cr_ref, 1);
        return (0);
+
 out:
        free(np, M_NETADDR);
        return (error);
@@ -232,10 +233,14 @@ vfs_export(mp, argp)
        struct netexport *nep;
        int error;
 
+       error = 0;
+       lockmgr(&mp->mnt_explock, LK_EXCLUSIVE, NULL, curthread);
        nep = mp->mnt_export;
        if (argp->ex_flags & MNT_DELEXPORT) {
-               if (nep == NULL)
-                       return (ENOENT);
+               if (nep == NULL) {
+                       error = ENOENT;
+                       goto out;
+               }
                if (mp->mnt_flag & MNT_EXPUBLIC) {
                        vfs_setpublicfs(NULL, NULL, NULL);
                        MNT_ILOCK(mp);
@@ -257,18 +262,20 @@ vfs_export(mp, argp)
                }
                if (argp->ex_flags & MNT_EXPUBLIC) {
                        if ((error = vfs_setpublicfs(mp, nep, argp)) != 0)
-                               return (error);
+                               goto out;
                        MNT_ILOCK(mp);
                        mp->mnt_flag |= MNT_EXPUBLIC;
                        MNT_IUNLOCK(mp);
                }
                if ((error = vfs_hang_addrlist(mp, nep, argp)))
-                       return (error);
+                       goto out;
                MNT_ILOCK(mp);
                mp->mnt_flag |= MNT_EXPORTED;
                MNT_IUNLOCK(mp);
        }
-       return (0);
+out:
+       lockmgr(&mp->mnt_explock, LK_RELEASE, NULL, curthread);
+       return (error);
 }
 
 /*
@@ -412,7 +419,9 @@ vfs_stdcheckexp(mp, nam, extflagsp, cred
 {
        struct netcred *np;
 
+       lockmgr(&mp->mnt_explock, LK_SHARED, NULL, curthread);
        np = vfs_export_lookup(mp, nam);
+       lockmgr(&mp->mnt_explock, LK_RELEASE, NULL, curthread);
        if (np == NULL)
                return (EACCES);
        *extflagsp = np->netc_exflags;

Modified: stable/6/sys/kern/vfs_mount.c
==============================================================================
--- stable/6/sys/kern/vfs_mount.c       Tue Jun 16 12:33:38 2009        
(r194288)
+++ stable/6/sys/kern/vfs_mount.c       Tue Jun 16 13:05:34 2009        
(r194289)
@@ -448,6 +448,7 @@ mount_init(void *mem, int size, int flag
        mp = (struct mount *)mem;
        mtx_init(&mp->mnt_mtx, "struct mount mtx", NULL, MTX_DEF);
        lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, 0);
+       lockinit(&mp->mnt_explock, PVFS, "explock", 0, 0);
        return (0);
 }
 
@@ -457,6 +458,7 @@ mount_fini(void *mem, int size)
        struct mount *mp;
 
        mp = (struct mount *)mem;
+       lockdestroy(&mp->mnt_explock);
        lockdestroy(&mp->mnt_lock);
        mtx_destroy(&mp->mnt_mtx);
 }

Modified: stable/6/sys/sys/mount.h
==============================================================================
--- stable/6/sys/sys/mount.h    Tue Jun 16 12:33:38 2009        (r194288)
+++ stable/6/sys/sys/mount.h    Tue Jun 16 13:05:34 2009        (r194289)
@@ -178,6 +178,7 @@ struct mount {
        int             mnt_secondary_accwrites;/* (i) secondary wr. starts */
        int             mnt_ref;                /* (i) Reference count */
        int             mnt_gen;                /* struct mount generation */
+       struct lock     mnt_explock;            /* vfs_export walkers lock */
 };
 
 struct vnode *__mnt_vnode_next(struct vnode **mvp, struct mount *mp);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to