Use rwlock for fmi_shared_lock and fmi_lazy_lock.

Ok: Andrew Doran <ad@netbsd.org>
This commit is contained in:
hannken 2007-05-16 16:11:56 +00:00
parent 724513abed
commit 0453160a52
1 changed files with 29 additions and 29 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: vfs_trans.c,v 1.7 2007/03/12 21:33:08 ad Exp $ */ /* $NetBSD: vfs_trans.c,v 1.8 2007/05/16 16:11:56 hannken Exp $ */
/*- /*-
* Copyright (c) 2007 The NetBSD Foundation, Inc. * Copyright (c) 2007 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vfs_trans.c,v 1.7 2007/03/12 21:33:08 ad Exp $"); __KERNEL_RCSID(0, "$NetBSD: vfs_trans.c,v 1.8 2007/05/16 16:11:56 hannken Exp $");
/* /*
* File system transaction operations. * File system transaction operations.
@ -53,6 +53,7 @@ __KERNEL_RCSID(0, "$NetBSD: vfs_trans.c,v 1.7 2007/03/12 21:33:08 ad Exp $");
#include <sys/systm.h> #include <sys/systm.h>
#include <sys/malloc.h> #include <sys/malloc.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/rwlock.h>
#include <sys/vnode.h> #include <sys/vnode.h>
#define _FSTRANS_API_PRIVATE #define _FSTRANS_API_PRIVATE
#include <sys/fstrans.h> #include <sys/fstrans.h>
@ -67,8 +68,8 @@ struct fstrans_lwp_info {
}; };
struct fstrans_mount_info { struct fstrans_mount_info {
enum fstrans_state fmi_state; enum fstrans_state fmi_state;
struct lock fmi_shared_lock; krwlock_t fmi_shared_lock;
struct lock fmi_lazy_lock; krwlock_t fmi_lazy_lock;
}; };
static specificdata_key_t lwp_data_key; static specificdata_key_t lwp_data_key;
@ -125,8 +126,8 @@ fstrans_mount_dtor(void *arg)
struct fstrans_mount_info *fmi = arg; struct fstrans_mount_info *fmi = arg;
KASSERT(fmi->fmi_state == FSTRANS_NORMAL); KASSERT(fmi->fmi_state == FSTRANS_NORMAL);
lockmgr(&fmi->fmi_lazy_lock, LK_DRAIN, NULL); rw_destroy(&fmi->fmi_lazy_lock);
lockmgr(&fmi->fmi_shared_lock, LK_DRAIN, NULL); rw_destroy(&fmi->fmi_shared_lock);
free(fmi, M_MOUNT); free(fmi, M_MOUNT);
} }
@ -147,8 +148,8 @@ fstrans_mount_init(struct mount *mp)
new = malloc(sizeof(*new), M_MOUNT, M_WAITOK); new = malloc(sizeof(*new), M_MOUNT, M_WAITOK);
new->fmi_state = FSTRANS_NORMAL; new->fmi_state = FSTRANS_NORMAL;
lockinit(&new->fmi_lazy_lock, PVFS, "suspfs", 0, 0); rw_init(&new->fmi_lazy_lock);
lockinit(&new->fmi_shared_lock, PVFS, "suspfs", 0, 0); rw_init(&new->fmi_shared_lock);
mount_setspecific(mp, mount_data_key, new); mount_setspecific(mp, mount_data_key, new);
mutex_exit(&fstrans_init_lock); mutex_exit(&fstrans_init_lock);
@ -166,16 +167,13 @@ fstrans_mount_init(struct mount *mp)
int int
_fstrans_start(struct mount *mp, enum fstrans_lock_type lock_type, int wait) _fstrans_start(struct mount *mp, enum fstrans_lock_type lock_type, int wait)
{ {
int error, lkflags; krwlock_t *lock_p;
krw_t lock_op;
struct fstrans_lwp_info *fli, *new_fli; struct fstrans_lwp_info *fli, *new_fli;
struct fstrans_mount_info *fmi; struct fstrans_mount_info *fmi;
ASSERT_SLEEPABLE(NULL, __func__); ASSERT_SLEEPABLE(NULL, __func__);
lkflags = (lock_type == FSTRANS_EXCL ? LK_EXCLUSIVE : LK_SHARED);
if (!wait)
lkflags |= LK_NOWAIT;
if (mp == NULL || (mp->mnt_iflag & IMNT_HAS_TRANS) == 0) if (mp == NULL || (mp->mnt_iflag & IMNT_HAS_TRANS) == 0)
return 0; return 0;
@ -208,11 +206,15 @@ _fstrans_start(struct mount *mp, enum fstrans_lock_type lock_type, int wait)
fmi = fstrans_mount_init(mp); fmi = fstrans_mount_init(mp);
if (lock_type == FSTRANS_LAZY) if (lock_type == FSTRANS_LAZY)
error = lockmgr(&fmi->fmi_lazy_lock, lkflags, NULL); lock_p = &fmi->fmi_lazy_lock;
else else
error = lockmgr(&fmi->fmi_shared_lock, lkflags, NULL); lock_p = &fmi->fmi_shared_lock;
if (error) lock_op = (lock_type == FSTRANS_EXCL ? RW_WRITER : RW_READER);
return error;
if (wait)
rw_enter(lock_p, lock_op);
else if (rw_tryenter(lock_p, lock_op) == 0)
return EBUSY;
new_fli->fli_mount = mp; new_fli->fli_mount = mp;
new_fli->fli_count = 1; new_fli->fli_count = 1;
@ -249,9 +251,9 @@ fstrans_done(struct mount *mp)
fmi = mount_getspecific(mp, mount_data_key); fmi = mount_getspecific(mp, mount_data_key);
KASSERT(fmi != NULL); KASSERT(fmi != NULL);
if (fli->fli_lock_type == FSTRANS_LAZY) if (fli->fli_lock_type == FSTRANS_LAZY)
lockmgr(&fmi->fmi_lazy_lock, LK_RELEASE, NULL); rw_exit(&fmi->fmi_lazy_lock);
else else
lockmgr(&fmi->fmi_shared_lock, LK_RELEASE, NULL); rw_exit(&fmi->fmi_shared_lock);
} }
/* /*
@ -307,9 +309,7 @@ fstrans_setstate(struct mount *mp, enum fstrans_state new_state)
if (fmi->fmi_state == FSTRANS_NORMAL && if (fmi->fmi_state == FSTRANS_NORMAL &&
(error = fstrans_start(mp, FSTRANS_EXCL)) != 0) (error = fstrans_start(mp, FSTRANS_EXCL)) != 0)
return error; return error;
if ((error = lockmgr(&fmi->fmi_lazy_lock, LK_EXCLUSIVE, NULL)) rw_enter(&fmi->fmi_lazy_lock, RW_WRITER);
!= 0)
return error;
fmi->fmi_state = FSTRANS_SUSPENDED; fmi->fmi_state = FSTRANS_SUSPENDED;
break; break;
@ -317,7 +317,7 @@ fstrans_setstate(struct mount *mp, enum fstrans_state new_state)
KASSERT(fmi->fmi_state == FSTRANS_NORMAL || KASSERT(fmi->fmi_state == FSTRANS_NORMAL ||
fstrans_is_owner(mp)); fstrans_is_owner(mp));
if (fmi->fmi_state == FSTRANS_SUSPENDED) if (fmi->fmi_state == FSTRANS_SUSPENDED)
lockmgr(&fmi->fmi_lazy_lock, LK_RELEASE, NULL); rw_exit(&fmi->fmi_lazy_lock);
if (fmi->fmi_state == FSTRANS_SUSPENDING || if (fmi->fmi_state == FSTRANS_SUSPENDING ||
fmi->fmi_state == FSTRANS_SUSPENDED) { fmi->fmi_state == FSTRANS_SUSPENDED) {
fmi->fmi_state = FSTRANS_NORMAL; fmi->fmi_state = FSTRANS_NORMAL;
@ -461,12 +461,12 @@ fstrans_print_mount(struct mount *mp, int verbose)
printf("state %#x\n", fmi->fmi_state); printf("state %#x\n", fmi->fmi_state);
break; break;
} }
printf("%16s", "lock_lazy:"); printf("%16s r=%d w=%d\n", "lock_lazy:",
lockmgr_printinfo(&fmi->fmi_lazy_lock); rw_read_held(&fmi->fmi_lazy_lock),
printf("\n"); rw_write_held(&fmi->fmi_lazy_lock));
printf("%16s", "lock_shared:"); printf("%16s r=%d w=%d\n", "lock_shared:",
lockmgr_printinfo(&fmi->fmi_shared_lock); rw_read_held(&fmi->fmi_shared_lock),
printf("\n"); rw_write_held(&fmi->fmi_shared_lock));
} }
void void