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/14e8287e5009
branches: trunk
changeset: 457226:14e8287e5009
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 5dfb7c640211 -r 14e8287e5009 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