diff options
author | kib <kib@FreeBSD.org> | 2008-06-09 10:31:38 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2008-06-09 10:31:38 +0000 |
commit | 926d12d0ea65c1b10638efb17de093ecc2fe4063 (patch) | |
tree | ab9745925fe55b9a4f33ea4af659d8d13f96cc4f /sys | |
parent | 98ec5e76a88638596bb55271c5e91a26f266703d (diff) | |
download | FreeBSD-src-926d12d0ea65c1b10638efb17de093ecc2fe4063.zip FreeBSD-src-926d12d0ea65c1b10638efb17de093ecc2fe4063.tar.gz |
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.
Reported by: kris, pho, many
Based on the submission by: mohan
Tested by: pho
MFC after: 2 weeks
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/vfs_export.c | 4 | ||||
-rw-r--r-- | sys/kern/vfs_mount.c | 2 | ||||
-rw-r--r-- | sys/sys/mount.h | 1 |
3 files changed, 7 insertions, 0 deletions
diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c index 7afe991..439e84f 100644 --- a/sys/kern/vfs_export.c +++ b/sys/kern/vfs_export.c @@ -255,6 +255,7 @@ vfs_export(struct mount *mp, struct export_args *argp) nep = mp->mnt_export; error = 0; + lockmgr(&mp->mnt_explock, LK_EXCLUSIVE, NULL); if (argp->ex_flags & MNT_DELEXPORT) { if (nep == NULL) { error = ENOENT; @@ -294,6 +295,7 @@ vfs_export(struct mount *mp, struct export_args *argp) } out: + lockmgr(&mp->mnt_explock, LK_RELEASE, NULL); /* * Once we have executed the vfs_export() command, we do * not want to keep the "export" option around in the @@ -443,7 +445,9 @@ vfs_stdcheckexp(struct mount *mp, struct sockaddr *nam, int *extflagsp, { struct netcred *np; + lockmgr(&mp->mnt_explock, LK_SHARED, NULL); np = vfs_export_lookup(mp, nam); + lockmgr(&mp->mnt_explock, LK_RELEASE, NULL); if (np == NULL) return (EACCES); *extflagsp = np->netc_exflags; diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 0b2bee6..ade918a 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -452,6 +452,7 @@ mount_init(void *mem, int size, int flags) 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); } @@ -461,6 +462,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); } diff --git a/sys/sys/mount.h b/sys/sys/mount.h index b5625c7..f74ccba 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -182,6 +182,7 @@ struct mount { int mnt_secondary_accwrites;/* (i) secondary wr. starts */ #define mnt_endzero mnt_gjprovider char *mnt_gjprovider; /* gjournal provider name */ + struct lock mnt_explock; /* vfs_export walkers lock */ }; struct vnode *__mnt_vnode_next(struct vnode **mvp, struct mount *mp); |