Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern Add an owner field to fstrans mount info and use it...



details:   https://anonhg.NetBSD.org/src/rev/790c044e20a3
branches:  trunk
changeset: 452052:790c044e20a3
user:      hannken <hannken%NetBSD.org@localhost>
date:      Mon Jun 17 08:07:27 2019 +0000

description:
Add an owner field to fstrans mount info and use it to hold
the thread currently suspending this mount.

Remove now unneeded state FSTRANS_EXCL.

It is now possible to suspend a file system from a thread
already holding fstrans locks.  Use with care ...

diffstat:

 sys/kern/vfs_trans.c |  59 ++++++++++++++++++++++++++++-----------------------
 1 files changed, 32 insertions(+), 27 deletions(-)

diffs (182 lines):

diff -r 651c4b4df583 -r 790c044e20a3 sys/kern/vfs_trans.c
--- a/sys/kern/vfs_trans.c      Mon Jun 17 06:38:29 2019 +0000
+++ b/sys/kern/vfs_trans.c      Mon Jun 17 08:07:27 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vfs_trans.c,v 1.60 2019/05/13 08:16:56 hannken Exp $   */
+/*     $NetBSD: vfs_trans.c,v 1.61 2019/06/17 08:07:27 hannken Exp $   */
 
 /*-
  * Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_trans.c,v 1.60 2019/05/13 08:16:56 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_trans.c,v 1.61 2019/06/17 08:07:27 hannken Exp $");
 
 /*
  * File system transaction operations.
@@ -55,8 +55,7 @@
 
 enum fstrans_lock_type {
        FSTRANS_LAZY,                   /* Granted while not suspended */
-       FSTRANS_SHARED,                 /* Granted while not suspending */
-       FSTRANS_EXCL                    /* Internal: exclusive lock */
+       FSTRANS_SHARED                  /* Granted while not suspending */
 };
 
 struct fscow_handler {
@@ -83,6 +82,7 @@
        bool fmi_cow_change;
        LIST_HEAD(, fscow_handler) fmi_cow_handler;
        struct mount *fmi_mount;
+       struct lwp *fmi_owner;
 };
 
 static kmutex_t vfs_suspend_lock;      /* Serialize suspensions. */
@@ -101,7 +101,8 @@
     fstrans_get_lwp_info(struct mount *, bool);
 static struct fstrans_lwp_info *fstrans_alloc_lwp_info(struct mount *);
 static inline int _fstrans_start(struct mount *, enum fstrans_lock_type, int);
-static bool grant_lock(const enum fstrans_state, const enum fstrans_lock_type);
+static bool grant_lock(const struct fstrans_mount_info *,
+    const enum fstrans_lock_type);
 static bool state_change_done(const struct fstrans_mount_info *);
 static bool cow_state_change_done(const struct fstrans_mount_info *);
 static void cow_change_enter(struct fstrans_mount_info *);
@@ -233,6 +234,7 @@
 
        KASSERT(fmi->fmi_state == FSTRANS_NORMAL);
        KASSERT(LIST_FIRST(&fmi->fmi_cow_handler) == NULL);
+       KASSERT(fmi->fmi_owner == NULL);
 
        KASSERT(fstrans_gone_count > 0);
        fstrans_gone_count -= 1;
@@ -258,6 +260,7 @@
        LIST_INIT(&newfmi->fmi_cow_handler);
        newfmi->fmi_cow_change = false;
        newfmi->fmi_mount = mp;
+       newfmi->fmi_owner = NULL;
 
        mutex_enter(&fstrans_mount_lock);
        mp->mnt_transinfo = newfmi;
@@ -433,14 +436,15 @@
  * Check if this lock type is granted at this state.
  */
 static bool
-grant_lock(const enum fstrans_state state, const enum fstrans_lock_type type)
+grant_lock(const struct fstrans_mount_info *fmi,
+    const enum fstrans_lock_type type)
 {
 
-       if (__predict_true(state == FSTRANS_NORMAL))
+       if (__predict_true(fmi->fmi_state == FSTRANS_NORMAL))
                return true;
-       if (type == FSTRANS_EXCL)
+       if (fmi->fmi_owner == curlwp)
                return true;
-       if  (state == FSTRANS_SUSPENDING && type == FSTRANS_LAZY)
+       if  (fmi->fmi_state == FSTRANS_SUSPENDING && type == FSTRANS_LAZY)
                return true;
 
        return false;
@@ -468,14 +472,13 @@
        fmi = fli->fli_mountinfo;
 
        if (fli->fli_trans_cnt > 0) {
-               KASSERT(lock_type != FSTRANS_EXCL);
                fli->fli_trans_cnt += 1;
 
                return 0;
        }
 
        s = pserialize_read_enter();
-       if (__predict_true(grant_lock(fmi->fmi_state, lock_type))) {
+       if (__predict_true(grant_lock(fmi, lock_type))) {
                fli->fli_trans_cnt = 1;
                fli->fli_lock_type = lock_type;
                pserialize_read_exit(s);
@@ -488,7 +491,7 @@
                return EBUSY;
 
        mutex_enter(&fstrans_lock);
-       while (! grant_lock(fmi->fmi_state, lock_type))
+       while (! grant_lock(fmi, lock_type))
                cv_wait(&fstrans_state_cv, &fstrans_lock);
        fli->fli_trans_cnt = 1;
        fli->fli_lock_type = lock_type;
@@ -572,15 +575,14 @@
 fstrans_is_owner(struct mount *mp)
 {
        struct fstrans_lwp_info *fli;
+       struct fstrans_mount_info *fmi;
 
        KASSERT(mp != dead_rootmount);
 
        fli = fstrans_get_lwp_info(mp, true);
+       fmi = fli->fli_mountinfo;
 
-       if (fli->fli_trans_cnt == 0)
-               return 0;
-
-       return (fli->fli_lock_type == FSTRANS_EXCL);
+       return (fmi->fmi_owner == curlwp);
 }
 
 /*
@@ -598,7 +600,9 @@
                        continue;
                if (fli->fli_trans_cnt == 0)
                        continue;
-               if (grant_lock(fmi->fmi_state, fli->fli_lock_type))
+               if (fli->fli_self == curlwp)
+                       continue;
+               if (grant_lock(fmi, fli->fli_lock_type))
                        continue;
 
                return false;
@@ -642,16 +646,19 @@
                        break;
                }
        }
+       if (old_state != new_state) {
+               if (old_state == FSTRANS_NORMAL) {
+                       KASSERT(fmi->fmi_owner == NULL);
+                       fmi->fmi_owner = curlwp;
+               }
+               if (new_state == FSTRANS_NORMAL) {
+                       KASSERT(fmi->fmi_owner == curlwp);
+                       fmi->fmi_owner = NULL;
+               }
+       }
        cv_broadcast(&fstrans_state_cv);
        mutex_exit(&fstrans_lock);
 
-       if (old_state != new_state) {
-               if (old_state == FSTRANS_NORMAL)
-                       _fstrans_start(mp, FSTRANS_EXCL, 1);
-               if (new_state == FSTRANS_NORMAL)
-                       fstrans_done(mp);
-       }
-
        return error;
 }
 
@@ -976,9 +983,6 @@
                        case FSTRANS_SHARED:
                                printf(" shared");
                                break;
-                       case FSTRANS_EXCL:
-                               printf(" excl");
-                               break;
                        default:
                                printf(" %#x", fli->fli_lock_type);
                                break;
@@ -1004,6 +1008,7 @@
                printf("(null)\n");
                return;
        }
+       printf("owner %p ", fmi->fmi_owner);
        switch (fmi->fmi_state) {
        case FSTRANS_NORMAL:
                printf("state normal\n");



Home | Main Index | Thread Index | Old Index