svn commit: r354989 - in head/sys/fs: nfs nfsserver
Rick Macklem
rmacklem at FreeBSD.org
Fri Nov 22 00:22:56 UTC 2019
Author: rmacklem
Date: Fri Nov 22 00:22:55 2019
New Revision: 354989
URL: https://svnweb.freebsd.org/changeset/base/354989
Log:
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.)
MFC after: 2 weeks
Modified:
head/sys/fs/nfs/nfsrvstate.h
head/sys/fs/nfsserver/nfs_nfsdport.c
Modified: head/sys/fs/nfs/nfsrvstate.h
==============================================================================
--- head/sys/fs/nfs/nfsrvstate.h Thu Nov 21 23:55:43 2019 (r354988)
+++ head/sys/fs/nfs/nfsrvstate.h Fri Nov 22 00:22:55 2019 (r354989)
@@ -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: head/sys/fs/nfsserver/nfs_nfsdport.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdport.c Thu Nov 21 23:55:43 2019 (r354988)
+++ head/sys/fs/nfsserver/nfs_nfsdport.c Fri Nov 22 00:22:55 2019 (r354989)
@@ -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(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);
@@ -3881,6 +3884,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) {
@@ -4405,6 +4409,7 @@ nfsrv_proxyds(struct vnode *vp, off_t off, int cnt, st
struct vnode *dvp[NFSDEV_MAXMIRRORS];
struct nfsdevice *ds;
struct pnfsdsattr dsattr;
+ struct opnfsdsattr odsattr;
char *buf;
int buflen, error, failpos, i, mirrorcnt, origmircnt, trycnt;
@@ -4429,15 +4434,31 @@ nfsrv_proxyds(struct vnode *vp, off_t off, int cnt, st
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()
@@ -4809,6 +4830,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)
@@ -4984,12 +5006,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);
@@ -5168,12 +5191,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);
@@ -5470,7 +5494,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,
@@ -5489,6 +5513,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);
More information about the svn-src-all
mailing list