Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 13 Mar 2003 14:58:15 -0800 (PST)
From:      John Baldwin <jhb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 26857 for review
Message-ID:  <200303132258.h2DMwFZF003003@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=26857

Change 26857 by jhb@jhb_laptop on 2003/03/13 14:57:34

	IFC @26855.

Affected files ...

.. //depot/projects/smpng/sys/compat/linprocfs/linprocfs.c#24 integrate
.. //depot/projects/smpng/sys/compat/linux/linux_ioctl.c#23 integrate
.. //depot/projects/smpng/sys/compat/linux/linux_mib.c#7 integrate
.. //depot/projects/smpng/sys/compat/linux/linux_mib.h#5 integrate
.. //depot/projects/smpng/sys/compat/linux/linux_misc.c#34 integrate

Differences ...

==== //depot/projects/smpng/sys/compat/linprocfs/linprocfs.c#24 (text+ko) ====

@@ -38,7 +38,7 @@
  *
  *	@(#)procfs_status.c	8.4 (Berkeley) 6/15/94
  *
- * $FreeBSD: src/sys/compat/linprocfs/linprocfs.c,v 1.61 2003/02/16 14:11:51 phk Exp $
+ * $FreeBSD: src/sys/compat/linprocfs/linprocfs.c,v 1.62 2003/03/13 22:45:43 jhb Exp $
  */
 
 #include <sys/param.h>
@@ -449,8 +449,8 @@
 	char osname[LINUX_MAX_UTSNAME];
 	char osrelease[LINUX_MAX_UTSNAME];
 
-	linux_get_osname(td->td_proc, osname);
-	linux_get_osrelease(td->td_proc, osrelease);
+	linux_get_osname(td, osname);
+	linux_get_osrelease(td, osrelease);
 
 	sbuf_printf(sb,
 	    "%s version %s (des@freebsd.org) (gcc version " __VERSION__ ")"

==== //depot/projects/smpng/sys/compat/linux/linux_ioctl.c#23 (text+ko) ====

@@ -25,7 +25,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/compat/linux/linux_ioctl.c,v 1.102 2003/03/03 09:14:25 des Exp $
+ * $FreeBSD: src/sys/compat/linux/linux_ioctl.c,v 1.103 2003/03/13 22:45:43 jhb Exp $
  */
 
 #include <sys/param.h>
@@ -1596,7 +1596,7 @@
 		return (ioctl(td, (struct ioctl_args *)args));
 
 	case LINUX_OSS_GETVERSION: {
-		int version = linux_get_oss_version(td->td_proc);
+		int version = linux_get_oss_version(td);
 		return (copyout(&version, (void *)args->arg, sizeof(int)));
 	}
 

==== //depot/projects/smpng/sys/compat/linux/linux_mib.c#7 (text+ko) ====

@@ -25,7 +25,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/compat/linux/linux_mib.c,v 1.18 2003/02/19 05:46:58 imp Exp $
+ * $FreeBSD: src/sys/compat/linux/linux_mib.c,v 1.19 2003/03/13 22:45:43 jhb Exp $
  */
 
 #include <sys/param.h>
@@ -50,6 +50,9 @@
 SYSCTL_NODE(_compat, OID_AUTO, linux, CTLFLAG_RW, 0,
 	    "Linux mode");
 
+static struct mtx osname_lock;
+MTX_SYSINIT(linux_osname, &osname_lock, "linux osname", MTX_DEF);
+
 static char	linux_osname[LINUX_MAX_UTSNAME] = "Linux";
 
 static int
@@ -58,11 +61,11 @@
 	char osname[LINUX_MAX_UTSNAME];
 	int error;
 
-	linux_get_osname(req->td->td_proc, osname);
+	linux_get_osname(req->td, osname);
 	error = sysctl_handle_string(oidp, osname, LINUX_MAX_UTSNAME, req);
 	if (error || req->newptr == NULL)
 		return (error);
-	error = linux_set_osname(req->td->td_proc, osname);
+	error = linux_set_osname(req->td, osname);
 	return (error);
 }
 
@@ -79,11 +82,11 @@
 	char osrelease[LINUX_MAX_UTSNAME];
 	int error;
 
-	linux_get_osrelease(req->td->td_proc, osrelease);
+	linux_get_osrelease(req->td, osrelease);
 	error = sysctl_handle_string(oidp, osrelease, LINUX_MAX_UTSNAME, req);
 	if (error || req->newptr == NULL)
 		return (error);
-	error = linux_set_osrelease(req->td->td_proc, osrelease);
+	error = linux_set_osrelease(req->td, osrelease);
 	return (error);
 }
 
@@ -100,11 +103,11 @@
 	int oss_version;
 	int error;
 
-	oss_version = linux_get_oss_version(req->td->td_proc);
+	oss_version = linux_get_oss_version(req->td);
 	error = sysctl_handle_int(oidp, &oss_version, 0, req);
 	if (error || req->newptr == NULL)
 		return (error);
-	error = linux_set_oss_version(req->td->td_proc, oss_version);
+	error = linux_set_oss_version(req->td, oss_version);
 	return (error);
 }
 
@@ -116,177 +119,168 @@
 /*
  * Returns holding the prison mutex if return non-NULL.
  */
-static struct linux_prison *
-linux_get_prison(struct proc *p)
+static struct prison *
+linux_get_prison(struct thread *td)
 {
 	register struct prison *pr;
 	register struct linux_prison *lpr;
 
-	if (!jailed(p->p_ucred))
+	KASSERT(td == curthread, ("linux_get_prison() called on !curthread"));
+	if (!jailed(td->td_ucred))
 		return (NULL);
-
-	pr = p->p_ucred->cr_prison;
-
-	/*
-	 * Rather than hold the prison mutex during allocation, check to
-	 * see if we need to allocate while holding the mutex, release it,
-	 * allocate, then once we've allocated the memory, check again to
-	 * see if it's still needed, and set if appropriate.  If it's not,
-	 * we release the mutex again to FREE(), and grab it again so as
-	 * to release holding the lock.
-	 */
+	pr = td->td_ucred->cr_prison;
 	mtx_lock(&pr->pr_mtx);
 	if (pr->pr_linux == NULL) {
+		/*
+		 * If we don't have a linux prison structure yet, allocate
+		 * one.  We have to handle the race where another thread
+		 * could be adding a linux prison to this process already.
+		 */
 		mtx_unlock(&pr->pr_mtx);
-		MALLOC(lpr, struct linux_prison *, sizeof *lpr,
-		    M_PRISON, M_WAITOK|M_ZERO);
+		lpr = malloc(sizeof(struct linux_prison), M_PRISON,
+		    M_WAITOK | M_ZERO);
 		mtx_lock(&pr->pr_mtx);
-		if (pr->pr_linux == NULL) {
+		if (pr->pr_linux == NULL)
 			pr->pr_linux = lpr;
-		} else {
-			mtx_unlock(&pr->pr_mtx);
-			FREE(lpr, M_PRISON);
-			mtx_lock(&pr->pr_mtx);
-		}
+		else
+			free(lpr, M_PRISON);
 	}
-
-	return (pr->pr_linux);
+	return (pr);
 }
 
 void
-linux_get_osname(p, dst)
-	struct proc *p;
-	char *dst;
+linux_get_osname(struct thread *td, char *dst)
 {
 	register struct prison *pr;
 	register struct linux_prison *lpr;
 
-	if (p->p_ucred->cr_prison == NULL) {
-		bcopy(linux_osname, dst, LINUX_MAX_UTSNAME);
-		return;
+	pr = td->td_ucred->cr_prison;
+	if (pr != NULL) {
+		mtx_lock(&pr->pr_mtx);
+		if (pr->pr_linux != NULL) {
+			lpr = (struct linux_prison *)pr->pr_linux;
+			if (lpr->pr_osname[0]) {
+				bcopy(lpr->pr_osname, dst, LINUX_MAX_UTSNAME);
+				mtx_unlock(&pr->pr_mtx);
+				return;
+			}
+		}
+		mtx_unlock(&pr->pr_mtx);
 	}
 
-	pr = p->p_ucred->cr_prison;
-
-	mtx_lock(&pr->pr_mtx);
-	if (pr->pr_linux != NULL) {
-		lpr = (struct linux_prison *)pr->pr_linux;
-		if (lpr->pr_osname[0]) {
-			bcopy(lpr->pr_osname, dst, LINUX_MAX_UTSNAME);
-			mtx_unlock(&pr->pr_mtx);
-			return;
-		}
-	}
-	mtx_unlock(&pr->pr_mtx);
+	mtx_lock(&osname_lock);
 	bcopy(linux_osname, dst, LINUX_MAX_UTSNAME);
+	mtx_unlock(&osname_lock);
 }
 
 int
-linux_set_osname(p, osname)
-	struct proc *p;
-	char *osname;
+linux_set_osname(struct thread *td, char *osname)
 {
-	register struct linux_prison *lpr;
+	struct prison *pr;
+	struct linux_prison *lpr;
 
-	lpr = linux_get_prison(p);
-	if (lpr != NULL) {
+	pr = linux_get_prison(td);
+	if (pr != NULL) {
+		lpr = (struct linux_prison *)pr->pr_linux;
 		strcpy(lpr->pr_osname, osname);
-		mtx_unlock(&p->p_ucred->cr_prison->pr_mtx);
+		mtx_unlock(&pr->pr_mtx);
 	} else {
+		mtx_lock(&osname_lock);
 		strcpy(linux_osname, osname);
+		mtx_unlock(&osname_lock);
 	}
 
 	return (0);
 }
 
 void
-linux_get_osrelease(p, dst)
-	struct proc *p;
-	char *dst;
+linux_get_osrelease(struct thread *td, char *dst)
 {
 	register struct prison *pr;
 	struct linux_prison *lpr;
 
-	if (p->p_ucred->cr_prison == NULL) {
-		bcopy(linux_osrelease, dst, LINUX_MAX_UTSNAME);
-		return;
+	pr = td->td_ucred->cr_prison;
+	if (pr != NULL) {
+		mtx_lock(&pr->pr_mtx);
+		if (pr->pr_linux != NULL) {
+			lpr = (struct linux_prison *)pr->pr_linux;
+			if (lpr->pr_osrelease[0]) {
+				bcopy(lpr->pr_osrelease, dst,
+				    LINUX_MAX_UTSNAME);
+				mtx_unlock(&pr->pr_mtx);
+				return;
+			}
+		}
+		mtx_unlock(&pr->pr_mtx);
 	}
 
-	pr = p->p_ucred->cr_prison;
-
-	mtx_lock(&pr->pr_mtx);
-	if (pr->pr_linux != NULL) {
-		lpr = (struct linux_prison *) pr->pr_linux;
-		if (lpr->pr_osrelease[0]) {
-			bcopy(lpr->pr_osrelease, dst, LINUX_MAX_UTSNAME);
-			mtx_unlock(&pr->pr_mtx);
-			return;
-		}
-	}
-	mtx_unlock(&pr->pr_mtx);
+	mtx_lock(&osname_lock);
 	bcopy(linux_osrelease, dst, LINUX_MAX_UTSNAME);
+	mtx_unlock(&osname_lock);
 }
 
 int
-linux_set_osrelease(p, osrelease)
-	struct proc *p;
-	char *osrelease;
+linux_set_osrelease(struct thread *td, char *osrelease)
 {
-	register struct linux_prison *lpr;
+	struct prison *pr;
+	struct linux_prison *lpr;
 
-	lpr = linux_get_prison(p);
-	if (lpr != NULL) {
+	pr = linux_get_prison(td);
+	if (pr != NULL) {
+		lpr = (struct linux_prison *)pr->pr_linux;
 		strcpy(lpr->pr_osrelease, osrelease);
-		mtx_unlock(&p->p_ucred->cr_prison->pr_mtx);
+		mtx_unlock(&pr->pr_mtx);
 	} else {
+		mtx_lock(&osname_lock);
 		strcpy(linux_osrelease, osrelease);
+		mtx_unlock(&osname_lock);
 	}
 
 	return (0);
 }
 
 int
-linux_get_oss_version(p)
-	struct proc *p;
+linux_get_oss_version(struct thread *td)
 {
 	register struct prison *pr;
 	register struct linux_prison *lpr;
 	int version;
 
-	if (p->p_ucred->cr_prison == NULL)
-		return (linux_oss_version);
-
-	pr = p->p_ucred->cr_prison;
-
-	mtx_lock(&pr->pr_mtx);
-	if (pr->pr_linux != NULL) {
-		lpr = (struct linux_prison *) pr->pr_linux;
-		if (lpr->pr_oss_version) {
-			version = lpr->pr_oss_version;
-		} else {
-			version = linux_oss_version;
+	pr = td->td_ucred->cr_prison;
+	if (pr != NULL) {
+		mtx_lock(&pr->pr_mtx);
+		if (pr->pr_linux != NULL) {
+			lpr = (struct linux_prison *)pr->pr_linux;
+			if (lpr->pr_oss_version) {
+				version = lpr->pr_oss_version;
+				mtx_unlock(&pr->pr_mtx);
+				return (version);
+			}
 		}
-	} else {
-		version = linux_oss_version;
+		mtx_unlock(&pr->pr_mtx);
 	}
-	mtx_unlock(&pr->pr_mtx);
 
+	mtx_lock(&osname_lock);
+	version = linux_oss_version;
+	mtx_unlock(&osname_lock);
 	return (version);
 }
 
 int
-linux_set_oss_version(p, oss_version)
-	struct proc *p;
-	int oss_version;
+linux_set_oss_version(struct thread *td, int oss_version)
 {
-	register struct linux_prison *lpr;
+	struct prison *pr;
+	struct linux_prison *lpr;
 
-	lpr = linux_get_prison(p);
-	if (lpr != NULL) {
+	pr = linux_get_prison(td);
+	if (pr != NULL) {
+		lpr = (struct linux_prison *)pr->pr_linux;
 		lpr->pr_oss_version = oss_version;
-		mtx_unlock(&p->p_ucred->cr_prison->pr_mtx);
+		mtx_unlock(&pr->pr_mtx);
 	} else {
+		mtx_lock(&osname_lock);
 		linux_oss_version = oss_version;
+		mtx_unlock(&osname_lock);
 	}
 
 	return (0);

==== //depot/projects/smpng/sys/compat/linux/linux_mib.h#5 (text+ko) ====

@@ -25,19 +25,19 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/compat/linux/linux_mib.h,v 1.6 2002/03/24 04:04:50 bde Exp $
+ * $FreeBSD: src/sys/compat/linux/linux_mib.h,v 1.7 2003/03/13 22:45:43 jhb Exp $
  */
 
 #ifndef _LINUX_MIB_H_
 #define _LINUX_MIB_H_
 
-void	linux_get_osname(struct proc *p, char *dst);
-int	linux_set_osname(struct proc *p, char *osname);
+void	linux_get_osname(struct thread *td, char *dst);
+int	linux_set_osname(struct thread *td, char *osname);
 
-void	linux_get_osrelease(struct proc *p, char *dst);
-int	linux_set_osrelease(struct proc *p, char *osrelease);
+void	linux_get_osrelease(struct thread *td, char *dst);
+int	linux_set_osrelease(struct thread *td, char *osrelease);
 
-int	linux_get_oss_version(struct proc *p);
-int	linux_set_oss_version(struct proc *p, int oss_version);
+int	linux_get_oss_version(struct thread *td);
+int	linux_set_oss_version(struct thread *td, int oss_version);
 
 #endif /* _LINUX_MIB_H_ */

==== //depot/projects/smpng/sys/compat/linux/linux_misc.c#34 (text+ko) ====

@@ -25,7 +25,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/compat/linux/linux_misc.c,v 1.138 2003/03/03 09:17:12 des Exp $
+ * $FreeBSD: src/sys/compat/linux/linux_misc.c,v 1.139 2003/03/13 22:45:43 jhb Exp $
  */
 
 #include "opt_mac.h"
@@ -697,8 +697,8 @@
 		printf(ARGS(newuname, "*"));
 #endif
 
-	linux_get_osname(td->td_proc, osname);
-	linux_get_osrelease(td->td_proc, osrelease);
+	linux_get_osname(td, osname);
+	linux_get_osrelease(td, osrelease);
 
 	bzero(&utsname, sizeof(utsname));
 	strlcpy(utsname.sysname, osname, LINUX_MAX_UTSNAME);

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe p4-projects" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200303132258.h2DMwFZF003003>