Module Name:    src
Committed By:   dsl
Date:           Sun Jun  3 11:37:45 UTC 2012

Modified Files:
        src/sys/kern: vfs_bio.c

Log Message:
Fix processing of vm.bufmem_lowater and vm.bufmem_hiwater on 64bit systems.
The values are 'u_long' so copying them into an 'int' temporary
(to avoid writing an out of range value into the actual variable)
doesn't work too well at all.
Shows up on amd64 now that the sysctl values are marked as 64bit.
sparc64 must have been badly broken for ages.


To generate a diff of this commit:
cvs rdiff -u -r1.237 -r1.238 src/sys/kern/vfs_bio.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/vfs_bio.c
diff -u src/sys/kern/vfs_bio.c:1.237 src/sys/kern/vfs_bio.c:1.238
--- src/sys/kern/vfs_bio.c:1.237	Sat Jun  2 21:36:46 2012
+++ src/sys/kern/vfs_bio.c	Sun Jun  3 11:37:44 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_bio.c,v 1.237 2012/06/02 21:36:46 dsl Exp $	*/
+/*	$NetBSD: vfs_bio.c,v 1.238 2012/06/03 11:37:44 dsl Exp $	*/
 
 /*-
  * Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -123,7 +123,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_bio.c,v 1.237 2012/06/02 21:36:46 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_bio.c,v 1.238 2012/06/03 11:37:44 dsl Exp $");
 
 #include "opt_bufcache.h"
 
@@ -1730,39 +1730,41 @@ sysctl_dobuf(SYSCTLFN_ARGS)
 static int
 sysctl_bufvm_update(SYSCTLFN_ARGS)
 {
-	int t, error, rv;
+	int error, rv;
 	struct sysctlnode node;
+	union u_int_long { unsigned int i; unsigned long l; } t;
 
+	/* Take a copy of the supplied node and its data */
 	node = *rnode;
 	node.sysctl_data = &t;
-	t = *(int *)rnode->sysctl_data;
+	t = *(union u_int_long *)rnode->sysctl_data;
+
+	/* Update the copy */
 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
 	if (error || newp == NULL)
 		return (error);
 
-	if (t < 0)
-		return EINVAL;
 	if (rnode->sysctl_data == &bufcache) {
-		if (t > 100)
+		if (t.i > 100)
 			return (EINVAL);
-		bufcache = t;
+		bufcache = t.i;
 		buf_setwm();
 	} else if (rnode->sysctl_data == &bufmem_lowater) {
-		if (bufmem_hiwater - t < 16)
+		if (bufmem_hiwater - t.l < 16)
 			return (EINVAL);
-		bufmem_lowater = t;
+		bufmem_lowater = t.l;
 	} else if (rnode->sysctl_data == &bufmem_hiwater) {
-		if (t - bufmem_lowater < 16)
+		if (t.l - bufmem_lowater < 16)
 			return (EINVAL);
-		bufmem_hiwater = t;
+		bufmem_hiwater = t.l;
 	} else
 		return (EINVAL);
 
 	/* Drain until below new high water mark */
 	sysctl_unlock();
 	mutex_enter(&bufcache_lock);
-	while ((t = bufmem - bufmem_hiwater) >= 0) {
-		rv = buf_drain(t / (2 * 1024));
+	while (bufmem > bufmem_hiwater) {
+		rv = buf_drain((bufmem - bufmem_hiwater) / (2 * 1024));
 		if (rv <= 0)
 			break;
 	}

Reply via email to