Mostly back out rev 1.33 from quite some time ago, and the followup fixes

and tweaks.  The code was actually quite broken because it discarded the
upper bits of the 64 bit division.  We only had a 50% chance of scaling up
the blocksize for large NFS client mounts when it was needed.  For 5.x and
beyond, this was harmless because we could represent the result in either
case.  For 4.x this was a big problem though.  (4.x also has a df(1) bug to
compound the problem)
This commit is contained in:
Peter Wemm 2005-01-18 21:59:44 +00:00
parent 324cfdb7e8
commit bcbfb8bc3d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=140460

View File

@ -41,7 +41,6 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
@ -243,7 +242,6 @@ nfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td)
struct mbuf *mreq, *mrep, *md, *mb;
struct nfsnode *np;
u_quad_t tquad;
int bsize;
#ifndef nolint
sfp = NULL;
@ -271,29 +269,17 @@ nfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td)
sbp->f_flags = nmp->nm_flag;
sbp->f_iosize = nfs_iosize(nmp);
if (v3) {
for (bsize = NFS_FABLKSIZE; ; bsize *= 2) {
sbp->f_bsize = bsize;
tquad = fxdr_hyper(&sfp->sf_tbytes);
if (((unsigned long)(tquad / bsize) > LONG_MAX) ||
((long)(tquad / bsize) < LONG_MIN))
continue;
sbp->f_blocks = tquad / bsize;
tquad = fxdr_hyper(&sfp->sf_fbytes);
if (((unsigned long)(tquad / bsize) > LONG_MAX) ||
((long)(tquad / bsize) < LONG_MIN))
continue;
sbp->f_bfree = tquad / bsize;
tquad = fxdr_hyper(&sfp->sf_abytes);
if (((unsigned long)(tquad / bsize) > LONG_MAX) ||
((long)(tquad / bsize) < LONG_MIN))
continue;
sbp->f_bavail = tquad / bsize;
sbp->f_files = (fxdr_unsigned(int32_t,
sfp->sf_tfiles.nfsuquad[1]) & 0x7fffffff);
sbp->f_ffree = (fxdr_unsigned(int32_t,
sfp->sf_ffiles.nfsuquad[1]) & 0x7fffffff);
break;
}
sbp->f_bsize = NFS_FABLKSIZE;
tquad = fxdr_hyper(&sfp->sf_tbytes);
sbp->f_blocks = tquad / NFS_FABLKSIZE;
tquad = fxdr_hyper(&sfp->sf_fbytes);
sbp->f_bfree = tquad / NFS_FABLKSIZE;
tquad = fxdr_hyper(&sfp->sf_abytes);
sbp->f_bavail = tquad / NFS_FABLKSIZE;
sbp->f_files = (fxdr_unsigned(int32_t,
sfp->sf_tfiles.nfsuquad[1]) & 0x7fffffff);
sbp->f_ffree = (fxdr_unsigned(int32_t,
sfp->sf_ffiles.nfsuquad[1]) & 0x7fffffff);
} else {
sbp->f_bsize = fxdr_unsigned(int32_t, sfp->sf_bsize);
sbp->f_blocks = fxdr_unsigned(int32_t, sfp->sf_blocks);