vfs: depessimize getfsstat when only the count is requested
This avoids relocking mountlist_mtx for each entry.
This commit is contained in:
parent
8c1f410c19
commit
6c69e69724
@ -441,7 +441,46 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
|
||||
tofree = sfsp = *buf = malloc(maxcount * sizeof(struct statfs),
|
||||
M_STATFS, M_WAITOK);
|
||||
}
|
||||
|
||||
count = 0;
|
||||
|
||||
/*
|
||||
* If there is no target buffer they only want the count.
|
||||
*
|
||||
* This could be TAILQ_FOREACH but it is open-coded to match the original
|
||||
* code below.
|
||||
*/
|
||||
if (sfsp == NULL) {
|
||||
mtx_lock(&mountlist_mtx);
|
||||
for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
|
||||
if (prison_canseemount(td->td_ucred, mp) != 0) {
|
||||
nmp = TAILQ_NEXT(mp, mnt_list);
|
||||
continue;
|
||||
}
|
||||
#ifdef MAC
|
||||
if (mac_mount_check_stat(td->td_ucred, mp) != 0) {
|
||||
nmp = TAILQ_NEXT(mp, mnt_list);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
count++;
|
||||
nmp = TAILQ_NEXT(mp, mnt_list);
|
||||
}
|
||||
mtx_unlock(&mountlist_mtx);
|
||||
*countp = count;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* They want the entire thing.
|
||||
*
|
||||
* Short-circuit the corner case of no room for anything, avoids
|
||||
* relocking below.
|
||||
*/
|
||||
if (maxcount < 1) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
mtx_lock(&mountlist_mtx);
|
||||
for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
|
||||
if (prison_canseemount(td->td_ucred, mp) != 0) {
|
||||
@ -473,7 +512,6 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (sfsp != NULL && count < maxcount) {
|
||||
sp = &mp->mnt_stat;
|
||||
/*
|
||||
* If MNT_NOWAIT is specified, do not refresh
|
||||
@ -509,16 +547,19 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
|
||||
}
|
||||
}
|
||||
sfsp++;
|
||||
}
|
||||
count++;
|
||||
|
||||
if (count == maxcount) {
|
||||
vfs_unbusy(mp);
|
||||
break;
|
||||
}
|
||||
|
||||
mtx_lock(&mountlist_mtx);
|
||||
nmp = TAILQ_NEXT(mp, mnt_list);
|
||||
vfs_unbusy(mp);
|
||||
}
|
||||
mtx_unlock(&mountlist_mtx);
|
||||
if (sfsp != NULL && count > maxcount)
|
||||
*countp = maxcount;
|
||||
else
|
||||
out:
|
||||
*countp = count;
|
||||
return (0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user