Date: Thu, 12 Dec 2019 22:00:10 +0000 (UTC) From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r355674 - in stable/12/sys/fs: nfs nfsserver Message-ID: <201912122200.xBCM0AhI088521@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rmacklem Date: Thu Dec 12 22:00:10 2019 New Revision: 355674 URL: https://svnweb.freebsd.org/changeset/base/355674 Log: MFC: r354989 Fix the pNFS server's reporting of SpaceUsed (va_bytes). The pNFS server currently reports SpaceUsed (va_bytes) for the metadata file. This in not correct, since the metadata file is always empty and, as such, va_bytes is just the allocation for the empty file. This patch adds va_bytes to the list of attributes acquired from the DS for a file, so that it includes the allocated data size and is updated when the file is written. For files created on a pNFS server before this patch is applied, the va_bytes value is estimated by rounding va_size up to a multiple of BLKDEV_IOSIZE. Once the file is written after this patch has been applied to the metadata server, the va_bytes returned for the file will be correct. This patch only affects a pNFS metadata server. Found during testing of the NFSv4.2 pNFS server for the Allocate operation. (Not yet in head/current.) Modified: stable/12/sys/fs/nfs/nfsrvstate.h stable/12/sys/fs/nfsserver/nfs_nfsdport.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/fs/nfs/nfsrvstate.h ============================================================================== --- stable/12/sys/fs/nfs/nfsrvstate.h Thu Dec 12 21:33:00 2019 (r355673) +++ stable/12/sys/fs/nfs/nfsrvstate.h Thu Dec 12 22:00:10 2019 (r355674) @@ -355,14 +355,24 @@ struct nfsdevice { }; /* - * This structure holds the va_size, va_filerev, va_atime and va_mtime for the - * DS file and is stored in the metadata file's extended attribute pnfsd.dsattr. + * This structure holds the va_size, va_filerev, va_atime, va_mtime and + * va_bytes for the DS file and is stored in the metadata file's extended + * attribute pnfsd.dsattr. + * opnfsdsattr was missing the va_bytes field and, as such, it was updated. */ +struct opnfsdsattr { + uint64_t dsa_filerev; + uint64_t dsa_size; + struct timespec dsa_atime; + struct timespec dsa_mtime; +}; + struct pnfsdsattr { uint64_t dsa_filerev; uint64_t dsa_size; struct timespec dsa_atime; struct timespec dsa_mtime; + uint64_t dsa_bytes; }; /* Modified: stable/12/sys/fs/nfsserver/nfs_nfsdport.c ============================================================================== --- stable/12/sys/fs/nfsserver/nfs_nfsdport.c Thu Dec 12 21:33:00 2019 (r355673) +++ stable/12/sys/fs/nfsserver/nfs_nfsdport.c Thu Dec 12 22:00:10 2019 (r355674) @@ -277,7 +277,8 @@ nfsvno_getattr(struct vnode *vp, struct nfsvattr *nvap } /* - * Acquire the Change, Size and TimeModify attributes, as required. + * Acquire the Change, Size, TimeAccess, TimeModify and SpaceUsed + * attributes, as required. * This needs to be done for regular files if: * - non-NFSv4 RPCs or * - when attrbitp == NULL or @@ -292,7 +293,8 @@ nfsvno_getattr(struct vnode *vp, struct nfsvattr *nvap NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_CHANGE) || NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_SIZE) || NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_TIMEACCESS) || - NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_TIMEMODIFY))) { + NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_TIMEMODIFY) || + NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_SPACEUSED))) { error = nfsrv_proxyds(nd, vp, 0, 0, nd->nd_cred, p, NFSPROC_GETATTR, NULL, NULL, NULL, &na, NULL); if (error == 0) @@ -312,6 +314,7 @@ nfsvno_getattr(struct vnode *vp, struct nfsvattr *nvap nvap->na_mtime = na.na_mtime; nvap->na_filerev = na.na_filerev; nvap->na_size = na.na_size; + nvap->na_bytes = na.na_bytes; } NFSD_DEBUG(4, "nfsvno_getattr: gotattr=%d err=%d chg=%ju\n", gotattr, error, (uintmax_t)na.na_filerev); @@ -3880,6 +3883,7 @@ nfsrv_dscreate(struct vnode *dvp, struct vattr *vap, s dsa->dsa_size = va.va_size; dsa->dsa_atime = va.va_atime; dsa->dsa_mtime = va.va_mtime; + dsa->dsa_bytes = va.va_bytes; } } if (error == 0) { @@ -4404,6 +4408,7 @@ nfsrv_proxyds(struct nfsrv_descript *nd, struct vnode struct vnode *dvp[NFSDEV_MAXMIRRORS]; struct nfsdevice *ds; struct pnfsdsattr dsattr; + struct opnfsdsattr odsattr; char *buf; int buflen, error, failpos, i, mirrorcnt, origmircnt, trycnt; @@ -4428,15 +4433,31 @@ nfsrv_proxyds(struct nfsrv_descript *nd, struct vnode error = vn_extattr_get(vp, IO_NODELOCKED, EXTATTR_NAMESPACE_SYSTEM, "pnfsd.dsattr", &buflen, buf, p); - if (error == 0 && buflen != sizeof(dsattr)) - error = ENXIO; if (error == 0) { - NFSBCOPY(buf, &dsattr, buflen); - nap->na_filerev = dsattr.dsa_filerev; - nap->na_size = dsattr.dsa_size; - nap->na_atime = dsattr.dsa_atime; - nap->na_mtime = dsattr.dsa_mtime; - + if (buflen == sizeof(odsattr)) { + NFSBCOPY(buf, &odsattr, buflen); + nap->na_filerev = odsattr.dsa_filerev; + nap->na_size = odsattr.dsa_size; + nap->na_atime = odsattr.dsa_atime; + nap->na_mtime = odsattr.dsa_mtime; + /* + * Fake na_bytes by rounding up na_size. + * Since we don't know the block size, just + * use BLKDEV_IOSIZE. + */ + nap->na_bytes = (odsattr.dsa_size + + BLKDEV_IOSIZE - 1) & ~(BLKDEV_IOSIZE - 1); + } else if (buflen == sizeof(dsattr)) { + NFSBCOPY(buf, &dsattr, buflen); + nap->na_filerev = dsattr.dsa_filerev; + nap->na_size = dsattr.dsa_size; + nap->na_atime = dsattr.dsa_atime; + nap->na_mtime = dsattr.dsa_mtime; + nap->na_bytes = dsattr.dsa_bytes; + } else + error = ENXIO; + } + if (error == 0) { /* * If nfsrv_pnfsgetdsattr is 0 or nfsrv_checkdsattr() * returns 0, just return now. nfsrv_checkdsattr() @@ -4808,6 +4829,7 @@ nfsrv_setextattr(struct vnode *vp, struct nfsvattr *na dsattr.dsa_size = nap->na_size; dsattr.dsa_atime = nap->na_atime; dsattr.dsa_mtime = nap->na_mtime; + dsattr.dsa_bytes = nap->na_bytes; error = vn_extattr_set(vp, IO_NODELOCKED, EXTATTR_NAMESPACE_SYSTEM, "pnfsd.dsattr", sizeof(dsattr), (char *)&dsattr, p); if (error != 0) @@ -4983,12 +5005,13 @@ nfsrv_writedsdorpc(struct nfsmount *nmp, fhandle_t *fh nd->nd_bpos = mtod(m, char *) + m->m_len; NFSD_DEBUG(4, "nfsrv_writedsdorpc: lastmb len=%d\n", m->m_len); - /* Do a Getattr for Size, Change and Modify Time. */ + /* Do a Getattr for the attributes that change upon writing. */ NFSZERO_ATTRBIT(&attrbits); NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_SIZE); NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_CHANGE); NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMEACCESS); NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMEMODIFY); + NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_SPACEUSED); NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); *tl = txdr_unsigned(NFSV4OP_GETATTR); (void) nfsrv_putattrbit(nd, &attrbits); @@ -5167,12 +5190,13 @@ nfsrv_setattrdsdorpc(fhandle_t *fhp, struct ucred *cre nfsm_stateidtom(nd, &st, NFSSTATEID_PUTSTATEID); nfscl_fillsattr(nd, &nap->na_vattr, vp, NFSSATTR_FULL, 0); - /* Do a Getattr for Size, Change, Access Time and Modify Time. */ + /* Do a Getattr for the attributes that change due to writing. */ NFSZERO_ATTRBIT(&attrbits); NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_SIZE); NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_CHANGE); NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMEACCESS); NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMEMODIFY); + NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_SPACEUSED); NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); *tl = txdr_unsigned(NFSV4OP_GETATTR); (void) nfsrv_putattrbit(nd, &attrbits); @@ -5469,7 +5493,7 @@ nfsrv_setacldsrpc(fhandle_t *fhp, struct ucred *cred, } /* - * Getattr call to the DS for the Modify, Size and Change attributes. + * Getattr call to the DS for the attributes that change due to writing. */ static int nfsrv_getattrdsrpc(fhandle_t *fhp, struct ucred *cred, NFSPROC_T *p, @@ -5488,6 +5512,7 @@ nfsrv_getattrdsrpc(fhandle_t *fhp, struct ucred *cred, NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_CHANGE); NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMEACCESS); NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMEMODIFY); + NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_SPACEUSED); (void) nfsrv_putattrbit(nd, &attrbits); error = newnfs_request(nd, nmp, NULL, &nmp->nm_sockreq, NULL, p, cred, NFS_PROG, NFS_VER4, NULL, 1, NULL, NULL);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201912122200.xBCM0AhI088521>