sys/vfs/autofs: Change autofs_softc::sc_lock to use mutex(9)
authorTomohiro Kusumi <kusumi.tomohiro@gmail.com>
Tue, 12 Jun 2018 12:25:56 +0000 (05:25 -0700)
committerTomohiro Kusumi <kusumi.tomohiro@gmail.com>
Tue, 12 Jun 2018 12:25:56 +0000 (05:25 -0700)
sys/vfs/autofs/autofs.c
sys/vfs/autofs/autofs.h
sys/vfs/autofs/autofs_vfsops.c
sys/vfs/autofs/autofs_vnops.c

index 43e4242..a5eade2 100644 (file)
@@ -68,6 +68,7 @@
 #include <sys/queue.h>
 #include <sys/signalvar.h>
 #include <sys/refcount.h>
+#include <sys/spinlock2.h>
 #include <sys/kern_syscall.h>
 
 #include "autofs.h"
@@ -197,7 +198,7 @@ autofs_task(void *context, int pending)
 {
        struct autofs_request *ar = context;
 
-       lockmgr(&autofs_softc->sc_lock, LK_EXCLUSIVE);
+       mtx_lock_ex_quick(&autofs_softc->sc_lock);
        AUTOFS_WARN("request %d for %s timed out after %d seconds",
            ar->ar_id, ar->ar_path, autofs_timeout);
 
@@ -206,7 +207,7 @@ autofs_task(void *context, int pending)
        ar->ar_done = true;
        ar->ar_in_progress = false;
        cv_broadcast(&autofs_softc->sc_cv);
-       lockmgr(&autofs_softc->sc_lock, LK_RELEASE);
+       mtx_unlock_ex(&autofs_softc->sc_lock);
 }
 
 bool
@@ -308,7 +309,7 @@ autofs_trigger_one(struct autofs_node *anp,
        int error = 0, request_error;
        bool wildcards;
 
-       KKASSERT(lockstatus(&autofs_softc->sc_lock, curthread) == LK_EXCLUSIVE);
+       KKASSERT(mtx_islocked_ex(&autofs_softc->sc_lock));
 
        if (anp->an_parent == NULL) {
                key = kstrndup(component, componentlen, M_AUTOFS);
@@ -371,16 +372,17 @@ autofs_trigger_one(struct autofs_node *anp,
                if (autofs_interruptible) {
                        sigset_t oldset;
                        autofs_set_sigmask(&oldset);
-                       error = cv_wait_sig(&autofs_softc->sc_cv,
+                       error = cv_mtx_wait_sig(&autofs_softc->sc_cv,
                            &autofs_softc->sc_lock);
                        autofs_restore_sigmask(&oldset);
                        if (error) {
-                               AUTOFS_WARN("cv_wait_sig for %s failed "
+                               AUTOFS_WARN("cv_mtx_wait_sig for %s failed "
                                    "with error %d", ar->ar_path, error);
                                break;
                        }
                } else {
-                       cv_wait(&autofs_softc->sc_cv, &autofs_softc->sc_lock);
+                       cv_mtx_wait(&autofs_softc->sc_cv,
+                           &autofs_softc->sc_lock);
                }
        }
 
@@ -396,11 +398,11 @@ autofs_trigger_one(struct autofs_node *anp,
         */
        if (refcount_release(&ar->ar_refcount)) {
                TAILQ_REMOVE(&autofs_softc->sc_requests, ar, ar_next);
-               lockmgr(&autofs_softc->sc_lock, LK_RELEASE);
+               mtx_unlock_ex(&autofs_softc->sc_lock);
                taskqueue_cancel_timeout(_taskqueue_thread, &ar->ar_task, NULL);
                taskqueue_drain_timeout(_taskqueue_thread, &ar->ar_task);
                objcache_put(autofs_request_objcache, ar);
-               lockmgr(&autofs_softc->sc_lock, LK_EXCLUSIVE);
+               mtx_lock_ex_quick(&autofs_softc->sc_lock);
        }
 
        /*
@@ -452,9 +454,9 @@ autofs_trigger(struct autofs_node *anp,
                AUTOFS_DEBUG("trigger failed with error %d; will retry in "
                    "%d seconds, %d attempts left", error, autofs_retry_delay,
                    autofs_retry_attempts - anp->an_retries);
-               lockmgr(&autofs_softc->sc_lock, LK_RELEASE);
+               mtx_unlock_ex(&autofs_softc->sc_lock);
                tsleep(&dummy, 0, "autofs_retry", autofs_retry_delay * hz);
-               lockmgr(&autofs_softc->sc_lock, LK_EXCLUSIVE);
+               mtx_lock_ex_quick(&autofs_softc->sc_lock);
        }
 }
 
@@ -464,7 +466,7 @@ autofs_ioctl_request(struct autofs_daemon_request *adr)
        struct proc *curp = curproc;
        struct autofs_request *ar;
 
-       lockmgr(&autofs_softc->sc_lock, LK_EXCLUSIVE);
+       mtx_lock_ex_quick(&autofs_softc->sc_lock);
        for (;;) {
                int error;
                TAILQ_FOREACH(ar, &autofs_softc->sc_requests, ar_next) {
@@ -478,10 +480,10 @@ autofs_ioctl_request(struct autofs_daemon_request *adr)
                if (ar != NULL)
                        break;
 
-               error = cv_wait_sig(&autofs_softc->sc_cv,
+               error = cv_mtx_wait_sig(&autofs_softc->sc_cv,
                    &autofs_softc->sc_lock);
                if (error) {
-                       lockmgr(&autofs_softc->sc_lock, LK_RELEASE);
+                       mtx_unlock_ex(&autofs_softc->sc_lock);
                        return (error);
                }
        }
@@ -495,7 +497,7 @@ autofs_ioctl_request(struct autofs_daemon_request *adr)
        strlcpy(adr->adr_key, ar->ar_key, sizeof(adr->adr_key));
        strlcpy(adr->adr_options, ar->ar_options, sizeof(adr->adr_options));
 
-       lockmgr(&autofs_softc->sc_lock, LK_RELEASE);
+       mtx_unlock_ex(&autofs_softc->sc_lock);
 
        lwkt_gettoken(&curp->p_token);
        autofs_softc->sc_dev_sid = proc_pgid(curp);
@@ -509,14 +511,14 @@ autofs_ioctl_done(struct autofs_daemon_done *add)
 {
        struct autofs_request *ar;
 
-       lockmgr(&autofs_softc->sc_lock, LK_EXCLUSIVE);
+       mtx_lock_ex_quick(&autofs_softc->sc_lock);
        TAILQ_FOREACH(ar, &autofs_softc->sc_requests, ar_next) {
                if (ar->ar_id == add->add_id)
                        break;
        }
 
        if (ar == NULL) {
-               lockmgr(&autofs_softc->sc_lock, LK_RELEASE);
+               mtx_unlock_ex(&autofs_softc->sc_lock);
                AUTOFS_DEBUG("id %d not found", add->add_id);
                return (ESRCH);
        }
@@ -527,7 +529,7 @@ autofs_ioctl_done(struct autofs_daemon_done *add)
        ar->ar_in_progress = false;
        cv_broadcast(&autofs_softc->sc_cv);
 
-       lockmgr(&autofs_softc->sc_lock, LK_RELEASE);
+       mtx_unlock_ex(&autofs_softc->sc_lock);
 
        return (0);
 }
@@ -535,7 +537,7 @@ autofs_ioctl_done(struct autofs_daemon_done *add)
 static int
 autofs_open(struct dev_open_args *ap)
 {
-       lockmgr(&autofs_softc->sc_lock, LK_EXCLUSIVE);
+       mtx_lock_ex_quick(&autofs_softc->sc_lock);
        /*
         * We must never block automountd(8) and its descendants, and we use
         * session ID to determine that: we store session id of the process
@@ -545,12 +547,12 @@ autofs_open(struct dev_open_args *ap)
         * it from happening.
         */
        if (autofs_softc->sc_dev_opened) {
-               lockmgr(&autofs_softc->sc_lock, LK_RELEASE);
+               mtx_unlock_ex(&autofs_softc->sc_lock);
                return (EBUSY);
        }
 
        autofs_softc->sc_dev_opened = true;
-       lockmgr(&autofs_softc->sc_lock, LK_RELEASE);
+       mtx_unlock_ex(&autofs_softc->sc_lock);
 
        return (0);
 }
@@ -558,10 +560,10 @@ autofs_open(struct dev_open_args *ap)
 static int
 autofs_close(struct dev_close_args *ap)
 {
-       lockmgr(&autofs_softc->sc_lock, LK_EXCLUSIVE);
+       mtx_lock_ex_quick(&autofs_softc->sc_lock);
        KASSERT(autofs_softc->sc_dev_opened, ("not opened?"));
        autofs_softc->sc_dev_opened = false;
-       lockmgr(&autofs_softc->sc_lock, LK_RELEASE);
+       mtx_unlock_ex(&autofs_softc->sc_lock);
 
        return (0);
 }
@@ -587,3 +589,30 @@ autofs_ioctl(struct dev_ioctl_args *ap)
        }
        return (EINVAL);
 }
+
+int
+_cv_mtx_timedwait(struct cv *c, struct mtx *mtx, int timo, int wakesig)
+{
+       int flags = wakesig ? PCATCH : 0;
+       int error;
+
+       /*
+        * Can interlock without critical section/spinlock as long
+        * as we don't block before calling *sleep().  PINTERLOCKED
+        * must be passed to the *sleep() to use the manual interlock
+        * (else a new one is created which opens a timing race).
+        */
+       tsleep_interlock(c, flags);
+
+       spin_lock(&c->cv_lock);
+       c->cv_waiters++;
+       spin_unlock(&c->cv_lock);
+
+       if (mtx)
+               error = mtxsleep(c, mtx, flags | PINTERLOCKED, c->cv_desc,
+                   timo);
+       else
+               error = tsleep(c, flags | PINTERLOCKED, c->cv_desc, timo);
+
+       return (error);
+}
index a479361..16334f9 100644 (file)
@@ -41,7 +41,6 @@
 #include <sys/malloc.h>
 #include <sys/objcache.h>
 #include <sys/tree.h>
-#include <sys/lock.h>
 #include <sys/mutex2.h>
 #include <sys/condvar.h>
 #include <sys/mount.h>
@@ -143,7 +142,7 @@ struct autofs_softc {
        device_t                        sc_dev;
        struct cdev                     *sc_cdev;
        struct cv                       sc_cv;
-       struct lock                     sc_lock;
+       struct mtx                      sc_lock;
        TAILQ_HEAD(, autofs_request)    sc_requests;
        bool                            sc_dev_opened;
        pid_t                           sc_dev_sid;
@@ -164,6 +163,7 @@ int autofs_node_find(struct autofs_node *parent,
 void   autofs_node_delete(struct autofs_node *anp);
 int    autofs_node_vn(struct autofs_node *anp, struct mount *mp,
            int flags, struct vnode **vpp);
+int    _cv_mtx_timedwait(struct cv *c, struct mtx *mtx, int timo, int wakesig);
 
 static __inline void
 autofs_node_cache(struct autofs_node *anp)
@@ -179,4 +179,7 @@ autofs_node_uncache(struct autofs_node *anp)
 
 RB_PROTOTYPE(autofs_node_tree, autofs_node, an_link, autofs_node_cmp);
 
+#define cv_mtx_wait(cv, mtx)           _cv_mtx_timedwait((cv), (mtx), 0, 0)
+#define cv_mtx_wait_sig(cv, mtx)       _cv_mtx_timedwait((cv), (mtx), 0, 1)
+
 #endif /* !AUTOFS_H */
index 8c25519..de93fe1 100644 (file)
@@ -70,7 +70,7 @@ autofs_init(struct vfsconf *vfsp)
 
        TAILQ_INIT(&autofs_softc->sc_requests);
        cv_init(&autofs_softc->sc_cv, "autofscv");
-       lockinit(&autofs_softc->sc_lock, "autofssclk", 0, 0);
+       mtx_init(&autofs_softc->sc_lock, "autofssclk");
        autofs_softc->sc_dev_opened = false;
 
        autofs_softc->sc_cdev = make_dev(&autofs_ops, 0, UID_ROOT,
@@ -91,9 +91,9 @@ autofs_init(struct vfsconf *vfsp)
 static int
 autofs_uninit(struct vfsconf *vfsp)
 {
-       lockmgr(&autofs_softc->sc_lock, LK_EXCLUSIVE);
+       mtx_lock_ex_quick(&autofs_softc->sc_lock);
        if (autofs_softc->sc_dev_opened) {
-               lockmgr(&autofs_softc->sc_lock, LK_RELEASE);
+               mtx_unlock_ex(&autofs_softc->sc_lock);
                return (EBUSY);
        }
 
@@ -103,7 +103,7 @@ autofs_uninit(struct vfsconf *vfsp)
        objcache_destroy(autofs_request_objcache);
        objcache_destroy(autofs_node_objcache);
 
-       lockmgr(&autofs_softc->sc_lock, LK_RELEASE);
+       mtx_unlock_ex(&autofs_softc->sc_lock);
 
        kfree(autofs_softc, M_AUTOFS);  /* race with open */
        autofs_softc = NULL;
@@ -218,7 +218,7 @@ autofs_unmount(struct mount *mp, int mntflags)
                bool found;
 
                found = false;
-               lockmgr(&autofs_softc->sc_lock, LK_EXCLUSIVE);
+               mtx_lock_ex_quick(&autofs_softc->sc_lock);
                TAILQ_FOREACH(ar, &autofs_softc->sc_requests, ar_next) {
                        if (ar->ar_mount != amp)
                                continue;
@@ -228,12 +228,12 @@ autofs_unmount(struct mount *mp, int mntflags)
                        found = true;
                }
                if (found == false) {
-                       lockmgr(&autofs_softc->sc_lock, LK_RELEASE);
+                       mtx_unlock_ex(&autofs_softc->sc_lock);
                        break;
                }
 
                cv_broadcast(&autofs_softc->sc_cv);
-               lockmgr(&autofs_softc->sc_lock, LK_RELEASE);
+               mtx_unlock_ex(&autofs_softc->sc_lock);
 
                tsleep(&dummy, 0, "autofs_umount", hz);
        }
index 5bb37a0..5082dff 100644 (file)
@@ -169,9 +169,9 @@ autofs_trigger_vn(struct vnode *vp, const char *path, int pathlen,
        if (nlookup_fs_root(anp, &nvp) == 0)
                goto mounted;
 
-       lockmgr(&autofs_softc->sc_lock, LK_EXCLUSIVE);
+       mtx_lock_ex_quick(&autofs_softc->sc_lock);
        error = autofs_trigger(anp, path, pathlen);
-       lockmgr(&autofs_softc->sc_lock, LK_RELEASE);
+       mtx_unlock_ex(&autofs_softc->sc_lock);
 
        if (error)
                return (error);