From 72109da06e305f34a3dcc3677bfbefd919a2bc10 Mon Sep 17 00:00:00 2001 From: pjd Date: Thu, 1 Nov 2007 08:58:29 +0000 Subject: [PATCH] - Move crfree() outside MNT_ILOCK()/MNT_IUNLOCK() to eliminate a LOR: 1st 0xc4cea568 struct mount mtx (struct mount mtx) @ /usr/src/sys/modules/zfs/../../compat/opensolaris/kern/opensolaris_vfs.c:209 2nd 0xc3ee9010 sleep mtxpool (sleep mtxpool) @ /usr/src/sys/kern/kern_resource.c:1266 - Move crdup() outside MNT_ILOCK()/MNT_IUNLOCK(), as it can sleep. Reported by: Olli Hauer MFC after: 3 days --- sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c | 8 ++++++-- sys/compat/opensolaris/kern/opensolaris_vfs.c | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c b/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c index 79a4c5bd162e..659870ef007e 100644 --- a/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c @@ -163,6 +163,7 @@ domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath, { struct mount *mp; struct vfsconf *vfsp; + struct ucred *newcr, *oldcr; int error; /* @@ -202,7 +203,9 @@ domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath, /* * Set the mount level flags. + * crdup() can sleep, so do it before acquiring a mutex. */ + newcr = crdup(kcred); MNT_ILOCK(mp); if (fsflags & MNT_RDONLY) mp->mnt_flag |= MNT_RDONLY; @@ -212,10 +215,11 @@ domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath, * Unprivileged user can trigger mounting a snapshot, but we don't want * him to unmount it, so we switch to privileged credentials. */ - crfree(mp->mnt_cred); - mp->mnt_cred = crdup(kcred); + oldcr = mp->mnt_cred; + mp->mnt_cred = newcr; mp->mnt_stat.f_owner = mp->mnt_cred->cr_uid; MNT_IUNLOCK(mp); + crfree(oldcr); /* * Mount the filesystem. * XXX The final recipients of VFS_MOUNT just overwrite the ndp they diff --git a/sys/compat/opensolaris/kern/opensolaris_vfs.c b/sys/compat/opensolaris/kern/opensolaris_vfs.c index 79a4c5bd162e..659870ef007e 100644 --- a/sys/compat/opensolaris/kern/opensolaris_vfs.c +++ b/sys/compat/opensolaris/kern/opensolaris_vfs.c @@ -163,6 +163,7 @@ domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath, { struct mount *mp; struct vfsconf *vfsp; + struct ucred *newcr, *oldcr; int error; /* @@ -202,7 +203,9 @@ domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath, /* * Set the mount level flags. + * crdup() can sleep, so do it before acquiring a mutex. */ + newcr = crdup(kcred); MNT_ILOCK(mp); if (fsflags & MNT_RDONLY) mp->mnt_flag |= MNT_RDONLY; @@ -212,10 +215,11 @@ domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath, * Unprivileged user can trigger mounting a snapshot, but we don't want * him to unmount it, so we switch to privileged credentials. */ - crfree(mp->mnt_cred); - mp->mnt_cred = crdup(kcred); + oldcr = mp->mnt_cred; + mp->mnt_cred = newcr; mp->mnt_stat.f_owner = mp->mnt_cred->cr_uid; MNT_IUNLOCK(mp); + crfree(oldcr); /* * Mount the filesystem. * XXX The final recipients of VFS_MOUNT just overwrite the ndp they