diff options
author | pjd <pjd@FreeBSD.org> | 2007-11-01 08:58:29 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2007-11-01 08:58:29 +0000 |
commit | 72109da06e305f34a3dcc3677bfbefd919a2bc10 (patch) | |
tree | cd4e94d194f5ae44ed127b5724e059d2eddbf1a0 /sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c | |
parent | 45e2b52e41bb441553f783ccbfb5bb7693a64c45 (diff) | |
download | FreeBSD-src-72109da06e305f34a3dcc3677bfbefd919a2bc10.zip FreeBSD-src-72109da06e305f34a3dcc3677bfbefd919a2bc10.tar.gz |
- 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 <ohauer@gmx.de>
MFC after: 3 days
Diffstat (limited to 'sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c')
-rw-r--r-- | sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c b/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c index 79a4c5b..659870e 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 |