Subject: kern/7074: df(1) prints wrong value on NFS v3 filesystem
To: None <gnats-bugs@gnats.netbsd.org>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: netbsd-bugs
Date: 03/03/1999 03:16:13
>Number:         7074
>Category:       kern
>Synopsis:       df(1) prints wrong value on NFS v3 filesystem
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Mar  2 10:20:01 1999
>Last-Modified:
>Originator:     Izumi Tsutsui
>Organization:
Izumi Tsutsui	Himeji City, Japan
>Release:        <NetBSD-current supped on 19990301
>Environment:
System:	NetBSD  1.3J NetBSD 1.3J (LANCER) #435: Wed Mar  3 02:32:59 JST 1999 \
    tsutsui@lancer:/usr/src/sys/arch/macppc/compile/LANCER macppc

>Description:
When a kernel is compiled with `gcc -O2' on powerpc, mips and sparc,
df(1) prints wrong values on NFS v3 filesystems.

>How-To-Repeat:
Make kernel with `gcc -O2' on powerpc, mips or sparc,
mount NFS v3 filesystem, and type `df'.
Following is the result on my macppc:

# mount -t nfs 192.168.20.1:/home /home
# df
Filesystem         1K-blocks     Used    Avail Capacity  Mounted on
/dev/wd0a              38983    20121    16912    54%    /
/dev/wd0g             949979   404925   497555    44%    /usr
192.168.20.1:/home         0 -1022892   789251    99%    /home
# umount /home
# mount -t nfs -o -2 192.168.20.1:/home /home
# df
Filesystem         1K-blocks     Used    Avail Capacity  Mounted on
/dev/wd0a              38983    20121    16912    54%    /
/dev/wd0g             949979   404925   497555    44%    /usr
192.168.20.1:/home   1022892   233641   738106    24%    /home
# 

>Fix:
This problem occurs when nfs_vfsops.c is compiled with `-O2'.
If nfs_vfsops.c is compiled with `-O2 -fno-schedule-insns',
df(1) shows correct values.

I guess egcs have some problems around reorder instruction
optimization on some architectures, but I don't know how to fix it.

Anyway, attached patch prevents incorrect instruction reordering
and solves this problem.

--- sys/nfs/xdr_subs.h.orig	Mon Mar  1 22:43:36 1999
+++ sys/nfs/xdr_subs.h	Mon Mar  1 22:43:16 1999
@@ -97,13 +97,13 @@
 	((struct nfsv3_time *)(t))->nfsv3_nsec = htonl((f)->tv_nsec); \
 }
 
-#define	fxdr_hyper(f, t) { \
+#define	fxdr_hyper(f, t) do { \
 	((int32_t *)(t))[_QUAD_HIGHWORD] = ntohl(((int32_t *)(f))[0]); \
 	((int32_t *)(t))[_QUAD_LOWWORD] = ntohl(((int32_t *)(f))[1]); \
-}
-#define	txdr_hyper(f, t) { \
+}while(0)
+#define	txdr_hyper(f, t) do { \
 	((int32_t *)(t))[0] = htonl(((int32_t *)(f))[_QUAD_HIGHWORD]); \
 	((int32_t *)(t))[1] = htonl(((int32_t *)(f))[_QUAD_LOWWORD]); \
-}
+}while(0)
 
 #endif
---
>Audit-Trail:
>Unformatted: