vfs: stop always overwriting ->mnt_stat in VFS_STATFS

The struct is already populated on each mount (and remount). Fields are either
constant or not used by filesystem in the first place.

Some infrequently used functions use it to avoid having to allocate a new buffer
and are left alone.

The current code results in an avoidable copying single-threaded and significant
cache line bouncing multithreaded

While here deduplicate initial filling of the struct.

Reviewed by:	kib
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D21317
This commit is contained in:
Mateusz Guzik 2019-08-18 18:40:12 +00:00
parent a9ff79e3bb
commit e7c1709aaf
2 changed files with 10 additions and 33 deletions

View File

@ -1831,12 +1831,15 @@ vfs_copyopt(struct vfsoptlist *opts, const char *name, void *dest, int len)
int
__vfs_statfs(struct mount *mp, struct statfs *sbp)
{
int error;
error = mp->mnt_op->vfs_statfs(mp, &mp->mnt_stat);
if (sbp != &mp->mnt_stat)
*sbp = mp->mnt_stat;
return (error);
/*
* Set these in case the underlying filesystem fails to do so.
*/
sbp->f_version = STATFS_VERSION;
sbp->f_namemax = NAME_MAX;
sbp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
return (mp->mnt_op->vfs_statfs(mp, sbp));
}
void

View File

@ -248,7 +248,6 @@ statfs_scale_blocks(struct statfs *sf, long max_size)
static int
kern_do_statfs(struct thread *td, struct mount *mp, struct statfs *buf)
{
struct statfs *sp;
int error;
if (mp == NULL)
@ -262,17 +261,9 @@ kern_do_statfs(struct thread *td, struct mount *mp, struct statfs *buf)
if (error != 0)
goto out;
#endif
/*
* Set these in case the underlying filesystem fails to do so.
*/
sp = &mp->mnt_stat;
sp->f_version = STATFS_VERSION;
sp->f_namemax = NAME_MAX;
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
error = VFS_STATFS(mp, sp);
error = VFS_STATFS(mp, buf);
if (error != 0)
goto out;
*buf = *sp;
if (priv_check(td, PRIV_VFS_GENERATION)) {
buf->f_fsid.val[0] = buf->f_fsid.val[1] = 0;
prison_enforce_statfs(td->td_ucred, mp, buf);
@ -475,13 +466,6 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
}
if (sfsp != NULL && count < maxcount) {
sp = &mp->mnt_stat;
/*
* Set these in case the underlying filesystem
* fails to do so.
*/
sp->f_version = STATFS_VERSION;
sp->f_namemax = NAME_MAX;
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
/*
* If MNT_NOWAIT is specified, do not refresh
* the fsstat cache.
@ -4545,7 +4529,6 @@ sys_fhstatfs(struct thread *td, struct fhstatfs_args *uap)
int
kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf)
{
struct statfs *sp;
struct mount *mp;
struct vnode *vp;
int error;
@ -4569,16 +4552,7 @@ kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf)
if (error != 0)
goto out;
#endif
/*
* Set these in case the underlying filesystem fails to do so.
*/
sp = &mp->mnt_stat;
sp->f_version = STATFS_VERSION;
sp->f_namemax = NAME_MAX;
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
error = VFS_STATFS(mp, sp);
if (error == 0)
*buf = *sp;
error = VFS_STATFS(mp, buf);
out:
vfs_unbusy(mp);
return (error);