summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/nfsclient/nfs_vfsops.c34
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);
OpenPOWER on IntegriCloud