summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/alpha/osf1/osf1_mount.c70
-rw-r--r--sys/compat/freebsd32/freebsd32_misc.c41
-rw-r--r--sys/kern/vfs_extattr.c123
-rw-r--r--sys/kern/vfs_syscalls.c123
-rw-r--r--sys/sys/syscallsubr.h2
5 files changed, 139 insertions, 220 deletions
diff --git a/sys/alpha/osf1/osf1_mount.c b/sys/alpha/osf1/osf1_mount.c
index 1d0ac2a..ca25854 100644
--- a/sys/alpha/osf1/osf1_mount.c
+++ b/sys/alpha/osf1/osf1_mount.c
@@ -47,7 +47,6 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/proc.h>
-#include <sys/jail.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
@@ -156,56 +155,39 @@ osf1_getfsstat(td, uap)
struct thread *td;
register struct osf1_getfsstat_args *uap;
{
- long count, error, maxcount;
- caddr_t osf_sfsp;
- struct mount *mp, *nmp;
- struct statfs *sp, sb;
+ struct statfs *buf, *sp;
struct osf1_statfs osfs;
+ size_t count, size;
+ int error, flags;
if (uap->flags & ~OSF1_GETFSSTAT_FLAGS)
return (EINVAL);
-
- maxcount = uap->bufsize / sizeof(struct osf1_statfs);
- osf_sfsp = (caddr_t)uap->buf;
- for (count = 0, mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
- nmp = TAILQ_NEXT(mp, mnt_list);
- if (osf_sfsp && count < maxcount) {
- if (!prison_check_mount(td->td_ucred, mp))
- continue;
-#ifdef MAC
- if (mac_check_mount_stat(td->td_ucred, mp) != 0)
- continue;
-#endif
- sp = &mp->mnt_stat;
- /*
- * If OSF1_MNT_NOWAIT is specified, do not refresh the
- * fsstat cache. OSF1_MNT_WAIT overrides
- * OSF1_MNT_NOWAIT.
- */
- if (((uap->flags & OSF1_MNT_NOWAIT) == 0 ||
- (uap->flags & OSF1_MNT_WAIT)) &&
- (error = VFS_STATFS(mp, sp, 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;
- }
+ flags = 0;
+ if (uap->flags & OSF1_MNT_WAIT)
+ flags |= MNT_WAIT;
+ if (uap->flags & OSF1_MNT_NOWAIT)
+ flags |= MNT_NOWAIT;
+
+ 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, flags);
+ if (buf != NULL) {
+ count = td->td_retval[0];
+ sp = buf;
+ while (count > 0 && error == 0) {
bsd2osf_statfs(sp, &osfs);
- if ((error = copyout(&osfs, osf_sfsp,
- sizeof (struct osf1_statfs))))
- return (error);
- osf_sfsp += sizeof (struct osf1_statfs);
+ error = copyout(&osfs, uap->buf, sizeof(osfs));
+ sp++;
+ uap->buf++;
+ count--;
}
- count++;
+ free(buf, M_TEMP);
}
- if (osf_sfsp && count > maxcount)
- td->td_retval[0] = maxcount;
- else
- td->td_retval[0] = count;
-
- return (0);
+ return (error);
}
int
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index 1469c3e..1c003a0 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -156,32 +156,29 @@ copy_statfs(struct statfs *in, struct statfs32 *out)
int
freebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap)
{
+ struct statfs *buf, *sp;
+ struct statfs32 stat32;
+ size_t count, size;
int error;
- caddr_t sg;
- struct statfs32 *sp32, stat32;
- struct statfs *sp = NULL, stat;
- int maxcount, count, i;
-
- sp32 = uap->buf;
- maxcount = uap->bufsize / sizeof(struct statfs32);
- if (sp32) {
- sg = stackgap_init();
- sp = stackgap_alloc(&sg, sizeof(struct statfs) * maxcount);
- uap->buf = (struct statfs32 *)sp;
- }
- error = getfsstat(td, (struct getfsstat_args *) uap);
- if (sp32 && !error) {
+ count = uap->bufsize / sizeof(struct statfs32);
+ 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];
- for (i = 0; i < count; i++) {
- error = copyin(&sp[i], &stat, sizeof(stat));
- if (error)
- return (error);
- copy_statfs(&stat, &stat32);
- error = copyout(&stat32, &sp32[i], sizeof(stat32));
- if (error)
- return (error);
+ sp = buf;
+ while (count > 0 && error == 0) {
+ copy_statfs(sp, &stat32);
+ error = copyout(&stat32, uap->buf, sizeof(stat32));
+ sp++;
+ uap->buf++;
+ count--;
}
+ free(buf, M_TEMP);
}
return (error);
}
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);
}
/*
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index bf92a6e..16975cc 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.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);
}
/*
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
index c8f11e7..c09288e 100644
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -69,6 +69,8 @@ int kern_fstat(struct thread *td, int fd, struct stat *sbp);
int kern_fstatfs(struct thread *td, int fd, struct statfs *buf);
int kern_futimes(struct thread *td, int fd, struct timeval *tptr,
enum uio_seg tptrseg);
+int kern_getfsstat(struct thread *td, struct statfs *buf, size_t bufsize,
+ enum uio_seg bufseg, int flags);
int kern_getitimer(struct thread *, u_int, struct itimerval *);
int kern_getrusage(struct thread *td, int who, struct rusage *rup);
int kern_getsockopt(struct thread *td, int s, int level, int name,
OpenPOWER on IntegriCloud