svn commit: r334411 - in projects/pnfs-planb-server/sys/fs: nfs nfsclient nfsserver
Rick Macklem
rmacklem at FreeBSD.org
Thu May 31 02:25:48 UTC 2018
Author: rmacklem
Date: Thu May 31 02:25:46 2018
New Revision: 334411
URL: https://svnweb.freebsd.org/changeset/base/334411
Log:
Fix the handling of statfs so that the pNFS service reports the sum of
the blocks for the DSs to the NFS clients instead of the block counts
for the MDS file system.
Reported by: james.rose at framestore.com
Modified:
projects/pnfs-planb-server/sys/fs/nfs/nfs_commonsubs.c
projects/pnfs-planb-server/sys/fs/nfs/nfs_var.h
projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clport.c
projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clrpcops.c
projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clstate.c
projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdport.c
Modified: projects/pnfs-planb-server/sys/fs/nfs/nfs_commonsubs.c
==============================================================================
--- projects/pnfs-planb-server/sys/fs/nfs/nfs_commonsubs.c Thu May 31 02:22:40 2018 (r334410)
+++ projects/pnfs-planb-server/sys/fs/nfs/nfs_commonsubs.c Thu May 31 02:25:46 2018 (r334411)
@@ -2068,7 +2068,8 @@ APPLESTATIC int
nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
NFSACL_T *saclp, struct vattr *vap, fhandle_t *fhp, int rderror,
nfsattrbit_t *attrbitp, struct ucred *cred, NFSPROC_T *p, int isdgram,
- int reterr, int supports_nfsv4acls, int at_root, uint64_t mounted_on_fileno)
+ int reterr, int supports_nfsv4acls, int at_root, uint64_t mounted_on_fileno,
+ struct statfs *pnfssf)
{
int bitpos, retnum = 0;
u_int32_t *tl;
@@ -2470,25 +2471,45 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount
break;
case NFSATTRBIT_SPACEAVAIL:
NFSM_BUILD(tl, u_int32_t *, NFSX_HYPER);
- if (priv_check_cred(cred, PRIV_VFS_BLOCKRESERVE, 0))
- uquad = (u_int64_t)fs->f_bfree;
+ if (priv_check_cred(cred, PRIV_VFS_BLOCKRESERVE, 0)) {
+ if (pnfssf != NULL)
+ uquad = (u_int64_t)pnfssf->f_bfree;
+ else
+ uquad = (u_int64_t)fs->f_bfree;
+ } else {
+ if (pnfssf != NULL)
+ uquad = (u_int64_t)pnfssf->f_bavail;
+ else
+ uquad = (u_int64_t)fs->f_bavail;
+ }
+ if (pnfssf != NULL)
+ uquad *= pnfssf->f_bsize;
else
- uquad = (u_int64_t)fs->f_bavail;
- uquad *= fs->f_bsize;
+ uquad *= fs->f_bsize;
txdr_hyper(uquad, tl);
retnum += NFSX_HYPER;
break;
case NFSATTRBIT_SPACEFREE:
NFSM_BUILD(tl, u_int32_t *, NFSX_HYPER);
- uquad = (u_int64_t)fs->f_bfree;
- uquad *= fs->f_bsize;
+ if (pnfssf != NULL) {
+ uquad = (u_int64_t)pnfssf->f_bfree;
+ uquad *= pnfssf->f_bsize;
+ } else {
+ uquad = (u_int64_t)fs->f_bfree;
+ uquad *= fs->f_bsize;
+ }
txdr_hyper(uquad, tl);
retnum += NFSX_HYPER;
break;
case NFSATTRBIT_SPACETOTAL:
NFSM_BUILD(tl, u_int32_t *, NFSX_HYPER);
- uquad = (u_int64_t)fs->f_blocks;
- uquad *= fs->f_bsize;
+ if (pnfssf != NULL) {
+ uquad = (u_int64_t)pnfssf->f_blocks;
+ uquad *= pnfssf->f_bsize;
+ } else {
+ uquad = (u_int64_t)fs->f_blocks;
+ uquad *= fs->f_bsize;
+ }
txdr_hyper(uquad, tl);
retnum += NFSX_HYPER;
break;
Modified: projects/pnfs-planb-server/sys/fs/nfs/nfs_var.h
==============================================================================
--- projects/pnfs-planb-server/sys/fs/nfs/nfs_var.h Thu May 31 02:22:40 2018 (r334410)
+++ projects/pnfs-planb-server/sys/fs/nfs/nfs_var.h Thu May 31 02:25:46 2018 (r334411)
@@ -372,7 +372,7 @@ void nfsrv_wcc(struct nfsrv_descript *, int, struct nf
struct nfsvattr *);
int nfsv4_fillattr(struct nfsrv_descript *, struct mount *, vnode_t, NFSACL_T *,
struct vattr *, fhandle_t *, int, nfsattrbit_t *,
- struct ucred *, NFSPROC_T *, int, int, int, int, uint64_t);
+ struct ucred *, NFSPROC_T *, int, int, int, int, uint64_t, struct statfs *);
void nfsrv_fillattr(struct nfsrv_descript *, struct nfsvattr *);
void nfsrv_adj(mbuf_t, int, int);
void nfsrv_postopattr(struct nfsrv_descript *, int, struct nfsvattr *);
Modified: projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clport.c
==============================================================================
--- projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clport.c Thu May 31 02:22:40 2018 (r334410)
+++ projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clport.c Thu May 31 02:25:46 2018 (r334411)
@@ -931,7 +931,7 @@ nfscl_fillsattr(struct nfsrv_descript *nd, struct vatt
if (vap->va_mtime.tv_sec != VNOVAL)
NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMEMODIFYSET);
(void) nfsv4_fillattr(nd, vp->v_mount, vp, NULL, vap, NULL, 0,
- &attrbits, NULL, NULL, 0, 0, 0, 0, (uint64_t)0);
+ &attrbits, NULL, NULL, 0, 0, 0, 0, (uint64_t)0, NULL);
break;
}
}
Modified: projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clrpcops.c
==============================================================================
--- projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clrpcops.c Thu May 31 02:22:40 2018 (r334410)
+++ projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clrpcops.c Thu May 31 02:25:46 2018 (r334411)
@@ -4619,7 +4619,7 @@ nfsrpc_setaclrpc(vnode_t vp, struct ucred *cred, NFSPR
NFSZERO_ATTRBIT(&attrbits);
NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_ACL);
(void) nfsv4_fillattr(nd, vnode_mount(vp), vp, aclp, NULL, NULL, 0,
- &attrbits, NULL, NULL, 0, 0, 0, 0, (uint64_t)0);
+ &attrbits, NULL, NULL, 0, 0, 0, 0, (uint64_t)0, NULL);
error = nfscl_request(nd, vp, p, cred, stuff);
if (error)
return (error);
Modified: projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clstate.c
==============================================================================
--- projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clstate.c Thu May 31 02:22:40 2018 (r334410)
+++ projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clstate.c Thu May 31 02:25:46 2018 (r334411)
@@ -3374,7 +3374,7 @@ nfscl_docb(struct nfsrv_descript *nd, NFSPROC_T *p)
if (!error)
(void) nfsv4_fillattr(nd, NULL, NULL, NULL, &va,
NULL, 0, &rattrbits, NULL, p, 0, 0, 0, 0,
- (uint64_t)0);
+ (uint64_t)0, NULL);
break;
case NFSV4OP_CBRECALL:
NFSCL_DEBUG(4, "cbrecall\n");
Modified: projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdport.c
==============================================================================
--- projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdport.c Thu May 31 02:22:40 2018 (r334410)
+++ projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdport.c Thu May 31 02:25:46 2018 (r334411)
@@ -131,6 +131,7 @@ static int nfsrv_pnfslookupds(struct vnode *, struct v
static void nfsrv_pnfssetfh(struct vnode *, struct pnfsdsfile *,
struct vnode *, NFSPROC_T *);
static int nfsrv_dsremove(struct vnode *, char *, struct ucred *, NFSPROC_T *);
+static int nfsrv_pnfsstatfs(struct statfs *);
int nfs_pnfsio(task_fn_t *, void *);
@@ -1567,10 +1568,27 @@ nfsvno_fsync(struct vnode *vp, u_int64_t off, int cnt,
int
nfsvno_statfs(struct vnode *vp, struct statfs *sf)
{
+ struct statfs *tsf;
int error;
+ tsf = NULL;
+ if (nfsrv_devidcnt > 0) {
+ /* For a pNFS service, get the DS numbers. */
+ tsf = malloc(sizeof(*tsf), M_TEMP, M_WAITOK | M_ZERO);
+ error = nfsrv_pnfsstatfs(tsf);
+ if (error != 0) {
+ free(tsf, M_TEMP);
+ tsf = NULL;
+ }
+ }
error = VFS_STATFS(vp->v_mount, sf);
if (error == 0) {
+ if (tsf != NULL) {
+ sf->f_blocks = tsf->f_blocks;
+ sf->f_bavail = tsf->f_bavail;
+ sf->f_bfree = tsf->f_bfree;
+ sf->f_bsize = tsf->f_bsize;
+ }
/*
* Since NFS handles these values as unsigned on the
* wire, there is no way to represent negative values,
@@ -1583,6 +1601,7 @@ nfsvno_statfs(struct vnode *vp, struct statfs *sf)
if (sf->f_ffree < 0)
sf->f_ffree = 0;
}
+ free(tsf, M_TEMP);
NFSEXITCODE(error);
return (error);
}
@@ -1728,11 +1747,25 @@ nfsvno_fillattr(struct nfsrv_descript *nd, struct moun
struct ucred *cred, struct thread *p, int isdgram, int reterr,
int supports_nfsv4acls, int at_root, uint64_t mounted_on_fileno)
{
+ struct statfs *sf;
int error;
+ sf = NULL;
+ if (nfsrv_devidcnt > 0 &&
+ (NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_SPACEAVAIL) ||
+ NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_SPACEFREE) ||
+ NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_SPACETOTAL))) {
+ sf = malloc(sizeof(*sf), M_TEMP, M_WAITOK | M_ZERO);
+ error = nfsrv_pnfsstatfs(sf);
+ if (error != 0) {
+ free(sf, M_TEMP);
+ sf = NULL;
+ }
+ }
error = nfsv4_fillattr(nd, mp, vp, NULL, &nvap->na_vattr, fhp, rderror,
attrbitp, cred, p, isdgram, reterr, supports_nfsv4acls, at_root,
- mounted_on_fileno);
+ mounted_on_fileno, sf);
+ free(sf, M_TEMP);
NFSEXITCODE2(0, nd);
return (error);
}
@@ -5168,7 +5201,7 @@ nfsrv_setacldsdorpc(fhandle_t *fhp, struct ucred *cred
* the same type (VREG).
*/
nfsv4_fillattr(nd, NULL, vp, aclp, NULL, NULL, 0, &attrbits, NULL,
- NULL, 0, 0, 0, 0, 0);
+ NULL, 0, 0, 0, 0, 0, NULL);
error = newnfs_request(nd, nmp, NULL, &nmp->nm_sockreq, NULL, p, cred,
NFS_PROG, NFS_VER4, NULL, 1, NULL, NULL);
if (error != 0) {
@@ -5436,6 +5469,78 @@ nfsrv_killrpcs(struct nfsmount *nmp)
* called.
*/
newnfs_nmcancelreqs(nmp);
+}
+
+/*
+ * Sum up the statfs info for each of the DSs, so that the client will
+ * receive the total for all DSs.
+ */
+static int
+nfsrv_pnfsstatfs(struct statfs *sf)
+{
+ struct statfs *tsf;
+ struct nfsdevice *ds;
+ struct vnode **dvpp, **tdvpp, *dvp;
+ uint64_t tot;
+ int cnt, error = 0, i;
+
+ if (nfsrv_devidcnt <= 0)
+ return (ENXIO);
+ dvpp = mallocarray(nfsrv_devidcnt, sizeof(*dvpp), M_TEMP, M_WAITOK);
+ tsf = malloc(sizeof(*tsf), M_TEMP, M_WAITOK);
+
+ /* Get an array of the dvps for the DSs. */
+ tdvpp = dvpp;
+ i = 0;
+ NFSDDSLOCK();
+ TAILQ_FOREACH(ds, &nfsrv_devidhead, nfsdev_list) {
+ if (ds->nfsdev_nmp != NULL) {
+ if (++i > nfsrv_devidcnt)
+ break;
+ *tdvpp++ = ds->nfsdev_dvp;
+ }
+ }
+ NFSDDSUNLOCK();
+ cnt = i;
+
+ /* Do a VFS_STATFS() for each of the DSs and sum them up. */
+ tdvpp = dvpp;
+ for (i = 0; i < cnt && error == 0; i++) {
+ dvp = *tdvpp++;
+ error = VFS_STATFS(dvp->v_mount, tsf);
+ if (error == 0) {
+ if (sf->f_bsize == 0) {
+ if (tsf->f_bsize > 0)
+ sf->f_bsize = tsf->f_bsize;
+ else
+ sf->f_bsize = 8192;
+ }
+ if (tsf->f_blocks > 0) {
+ if (sf->f_bsize != tsf->f_bsize) {
+ tot = tsf->f_blocks * tsf->f_bsize;
+ sf->f_blocks += (tot / sf->f_bsize);
+ } else
+ sf->f_blocks += tsf->f_blocks;
+ }
+ if (tsf->f_bfree > 0) {
+ if (sf->f_bsize != tsf->f_bsize) {
+ tot = tsf->f_bfree * tsf->f_bsize;
+ sf->f_bfree += (tot / sf->f_bsize);
+ } else
+ sf->f_bfree += tsf->f_bfree;
+ }
+ if (tsf->f_bavail > 0) {
+ if (sf->f_bsize != tsf->f_bsize) {
+ tot = tsf->f_bavail * tsf->f_bsize;
+ sf->f_bavail += (tot / sf->f_bsize);
+ } else
+ sf->f_bavail += tsf->f_bavail;
+ }
+ }
+ }
+ free(tsf, M_TEMP);
+ free(dvpp, M_TEMP);
+ return (error);
}
extern int (*nfsd_call_nfsd)(struct thread *, struct nfssvc_args *);
More information about the svn-src-projects
mailing list