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:
parent
a9ff79e3bb
commit
e7c1709aaf
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user