summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_extattr.c
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2005-06-09 17:44:46 +0000
committerpjd <pjd@FreeBSD.org>2005-06-09 17:44:46 +0000
commit3af857a21ae29e6bd992143c332930401686617d (patch)
tree11a9edf30c5981a81932d35c358f4a0ab56990f8 /sys/kern/vfs_extattr.c
parentcd5038ab36b62fd0d3378b0486ebd1c1a0b27b65 (diff)
downloadFreeBSD-src-3af857a21ae29e6bd992143c332930401686617d.zip
FreeBSD-src-3af857a21ae29e6bd992143c332930401686617d.tar.gz
Avoid code duplication in serval places by introducing universal
kern_getfsstat() function. Obtained from: jhb
Diffstat (limited to 'sys/kern/vfs_extattr.c')
-rw-r--r--sys/kern/vfs_extattr.c123
1 files changed, 46 insertions, 77 deletions
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
index bf92a6e..16975cc 100644
--- a/sys/kern/vfs_extattr.c
+++ b/sys/kern/vfs_extattr.c
@@ -373,13 +373,22 @@ getfsstat(td, uap)
int flags;
} */ *uap;
{
+
+ return (kern_getfsstat(td, uap->buf, uap->bufsize, UIO_USERSPACE,
+ uap->flags));
+}
+
+int
+kern_getfsstat(struct thread *td, struct statfs *buf, size_t bufsize,
+ enum uio_seg bufseg, int flags)
+{
struct mount *mp, *nmp;
- struct statfs *sp, sb;
- caddr_t sfsp;
- long count, maxcount, error;
+ struct statfs *sfsp, *sp, sb;
+ size_t count, maxcount;
+ int error;
- maxcount = uap->bufsize / sizeof(struct statfs);
- sfsp = (caddr_t)uap->buf;
+ maxcount = bufsize / sizeof(struct statfs);
+ sfsp = buf;
count = 0;
mtx_lock(&Giant);
mtx_lock(&mountlist_mtx);
@@ -412,8 +421,8 @@ getfsstat(td, uap)
* refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY
* overrides MNT_WAIT.
*/
- if (((uap->flags & (MNT_LAZY|MNT_NOWAIT)) == 0 ||
- (uap->flags & MNT_WAIT)) &&
+ if (((flags & (MNT_LAZY|MNT_NOWAIT)) == 0 ||
+ (flags & MNT_WAIT)) &&
(error = VFS_STATFS(mp, sp, td))) {
mtx_lock(&mountlist_mtx);
nmp = TAILQ_NEXT(mp, mnt_list);
@@ -425,13 +434,16 @@ getfsstat(td, uap)
sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
sp = &sb;
}
- error = copyout(sp, sfsp, sizeof(*sp));
- if (error) {
- vfs_unbusy(mp, td);
- mtx_unlock(&Giant);
- return (error);
- }
- sfsp += sizeof(*sp);
+ if (bufseg == UIO_USERSPACE) {
+ error = copyout(sp, sfsp, sizeof(*sp));
+ if (error) {
+ vfs_unbusy(mp, td);
+ mtx_unlock(&Giant);
+ return (error);
+ }
+ } else
+ bcopy(sp, sfsp, sizeof(*sp));
+ sfsp++;
}
count++;
mtx_lock(&mountlist_mtx);
@@ -525,74 +537,31 @@ freebsd4_getfsstat(td, uap)
int flags;
} */ *uap;
{
- struct mount *mp, *nmp;
- struct statfs *sp, sb;
+ struct statfs *buf, *sp;
struct ostatfs osb;
- caddr_t sfsp;
- long count, maxcount, error;
+ size_t count, size;
+ int error;
- maxcount = uap->bufsize / sizeof(struct ostatfs);
- sfsp = (caddr_t)uap->buf;
- count = 0;
- mtx_lock(&Giant);
- mtx_lock(&mountlist_mtx);
- for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
- if (!prison_check_mount(td->td_ucred, mp)) {
- nmp = TAILQ_NEXT(mp, mnt_list);
- continue;
- }
-#ifdef MAC
- if (mac_check_mount_stat(td->td_ucred, mp) != 0) {
- nmp = TAILQ_NEXT(mp, mnt_list);
- continue;
- }
-#endif
- if (vfs_busy(mp, LK_NOWAIT, &mountlist_mtx, td)) {
- nmp = TAILQ_NEXT(mp, mnt_list);
- continue;
- }
- if (sfsp && count < maxcount) {
- sp = &mp->mnt_stat;
- /*
- * If MNT_NOWAIT or MNT_LAZY is specified, do not
- * refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY
- * overrides MNT_WAIT.
- */
- if (((uap->flags & (MNT_LAZY|MNT_NOWAIT)) == 0 ||
- (uap->flags & MNT_WAIT)) &&
- (error = VFS_STATFS(mp, sp, td))) {
- mtx_lock(&mountlist_mtx);
- nmp = TAILQ_NEXT(mp, mnt_list);
- vfs_unbusy(mp, td);
- continue;
- }
- sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
- if (suser(td)) {
- bcopy(sp, &sb, sizeof(sb));
- sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
- sp = &sb;
- }
+ count = uap->bufsize / sizeof(struct ostatfs);
+ size = count * sizeof(struct statfs);
+ if (size > 0)
+ buf = malloc(size, M_TEMP, M_WAITOK);
+ else
+ buf = NULL;
+ error = kern_getfsstat(td, buf, size, UIO_SYSSPACE, uap->flags);
+ if (buf != NULL) {
+ count = td->td_retval[0];
+ sp = buf;
+ while (count > 0 && error == 0) {
cvtstatfs(sp, &osb);
- error = copyout(&osb, sfsp, sizeof(osb));
- if (error) {
- vfs_unbusy(mp, td);
- mtx_unlock(&Giant);
- return (error);
- }
- sfsp += sizeof(osb);
+ error = copyout(&osb, uap->buf, sizeof(osb));
+ sp++;
+ uap->buf++;
+ count--;
}
- count++;
- mtx_lock(&mountlist_mtx);
- nmp = TAILQ_NEXT(mp, mnt_list);
- vfs_unbusy(mp, td);
+ free(buf, M_TEMP);
}
- mtx_unlock(&mountlist_mtx);
- mtx_unlock(&Giant);
- if (sfsp && count > maxcount)
- td->td_retval[0] = maxcount;
- else
- td->td_retval[0] = count;
- return (0);
+ return (error);
}
/*
OpenPOWER on IntegriCloud