diff options
-rw-r--r-- | sys/nfsclient/nfs_vfsops.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c index cee1ec8..acef9ea 100644 --- a/sys/nfsclient/nfs_vfsops.c +++ b/sys/nfsclient/nfs_vfsops.c @@ -74,6 +74,8 @@ __FBSDID("$FreeBSD$"); #include <nfsclient/nfsm_subs.h> #include <nfsclient/nfsdiskless.h> +#include <machine/limits.h> + MALLOC_DEFINE(M_NFSREQ, "NFS req", "NFS request header"); MALLOC_DEFINE(M_NFSBIGFH, "NFSV3 bigfh", "NFS version 3 file handle"); MALLOC_DEFINE(M_NFSDIROFF, "NFSV3 diroff", "NFS directory offset data"); @@ -245,6 +247,7 @@ 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; @@ -272,17 +275,26 @@ 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) { - sbp->f_bsize = NFS_FABLKSIZE; - tquad = fxdr_hyper(&sfp->sf_tbytes); - sbp->f_blocks = (long)(tquad / ((u_quad_t)NFS_FABLKSIZE)); - tquad = fxdr_hyper(&sfp->sf_fbytes); - sbp->f_bfree = (long)(tquad / ((u_quad_t)NFS_FABLKSIZE)); - tquad = fxdr_hyper(&sfp->sf_abytes); - sbp->f_bavail = (long)(tquad / ((u_quad_t)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); + for (bsize = NFS_FABLKSIZE; ; bsize *= 2) { + sbp->f_bsize = bsize; + tquad = fxdr_hyper(&sfp->sf_tbytes); + if ((tquad / bsize) > LONG_MAX) + continue; + sbp->f_blocks = tquad / bsize; + tquad = fxdr_hyper(&sfp->sf_fbytes); + if ((tquad / bsize) > LONG_MAX) + continue; + sbp->f_bfree = tquad / bsize; + tquad = fxdr_hyper(&sfp->sf_abytes); + if ((tquad / bsize) > LONG_MAX) + 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; + } } else { sbp->f_bsize = fxdr_unsigned(int32_t, sfp->sf_bsize); sbp->f_blocks = fxdr_unsigned(int32_t, sfp->sf_blocks); |