Split the statvfs functions so that the 'work' is done to a kernel buffer
which can either be copied directly to userspace, or converted then copied. Saves replicating a lot of code in the compat functions (esp. for getvfsstat) at a cast of an extra function call in the non-emulated case - which is unlikely to be measurable given the other costs of the actions involved (even on vax). Remove dofhstat() and dofhstatvfs() (and the last caller). Remove some redundant stackgap_init() calls.
This commit is contained in:
parent
815c7faa9e
commit
0df00dcf55
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: vfs_syscalls_30.c,v 1.22 2007/04/22 08:29:55 dsl Exp $ */
|
||||
/* $NetBSD: vfs_syscalls_30.c,v 1.23 2007/04/30 08:32:15 dsl Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005 The NetBSD Foundation, Inc.
|
||||
|
@ -36,7 +36,7 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls_30.c,v 1.22 2007/04/22 08:29:55 dsl Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls_30.c,v 1.23 2007/04/30 08:32:15 dsl Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -405,10 +405,14 @@ compat_30_sys___fhstat30(struct lwp *l, void *v, register_t *retval)
|
|||
struct compat_30_sys___fhstat30_args /* {
|
||||
syscallarg(const fhandle_t *) fhp;
|
||||
syscallarg(struct stat *) sb;
|
||||
} */ *uap = v;
|
||||
} */ *uap_30 = v;
|
||||
struct sys___fhstat40_args uap;
|
||||
|
||||
return dofhstat(l, SCARG(uap, fhp), FHANDLE_SIZE_COMPAT,
|
||||
SCARG(uap, sb), retval);
|
||||
SCARG(&uap, fhp) = SCARG(uap_30, fhp);
|
||||
SCARG(&uap, fh_size) = FHANDLE_SIZE_COMPAT;
|
||||
SCARG(&uap, sb) = SCARG(uap_30, sb);
|
||||
|
||||
return sys___fhstat40(l, &uap, retval);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
|
@ -419,8 +423,13 @@ compat_30_sys_fhstatvfs1(struct lwp *l, void *v, register_t *retval)
|
|||
syscallarg(const fhandle_t *) fhp;
|
||||
syscallarg(struct statvfs *) buf;
|
||||
syscallarg(int) flags;
|
||||
} */ *uap = v;
|
||||
} */ *uap_30 = v;
|
||||
struct sys___fhstatvfs140_args uap;
|
||||
|
||||
return dofhstatvfs(l, SCARG(uap, fhp), FHANDLE_SIZE_COMPAT,
|
||||
SCARG(uap, buf), SCARG(uap, flags), retval);
|
||||
SCARG(&uap, fhp) = SCARG(uap_30, fhp);
|
||||
SCARG(&uap, fh_size) = FHANDLE_SIZE_COMPAT;
|
||||
SCARG(&uap, buf) = SCARG(uap_30, buf);
|
||||
SCARG(&uap, flags) = SCARG(uap_30, flags);
|
||||
|
||||
return sys___fhstatvfs140(l, &uap, retval);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: netbsd32_compat_30.c,v 1.20 2007/04/22 08:29:58 dsl Exp $ */
|
||||
/* $NetBSD: netbsd32_compat_30.c,v 1.21 2007/04/30 08:32:15 dsl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998, 2001 Matthew R. Green
|
||||
|
@ -29,7 +29,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: netbsd32_compat_30.c,v 1.20 2007/04/22 08:29:58 dsl Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: netbsd32_compat_30.c,v 1.21 2007/04/30 08:32:15 dsl Exp $");
|
||||
|
||||
#include "opt_nfsserver.h"
|
||||
|
||||
|
@ -112,12 +112,9 @@ compat_30_netbsd32___stat13(l, v, retval)
|
|||
struct netbsd32_stat13 sb32;
|
||||
struct stat sb;
|
||||
int error;
|
||||
void *sg;
|
||||
const char *path;
|
||||
struct proc *p = l->l_proc;
|
||||
|
||||
path = SCARG_P32(uap, path);
|
||||
sg = stackgap_init(p, 0);
|
||||
|
||||
error = do_sys_stat(l, path, FOLLOW, &sb);
|
||||
if (error)
|
||||
|
@ -172,12 +169,9 @@ compat_30_netbsd32___lstat13(l, v, retval)
|
|||
struct netbsd32_stat13 sb32;
|
||||
struct stat sb;
|
||||
int error;
|
||||
void *sg;
|
||||
const char *path;
|
||||
struct proc *p = l->l_proc;
|
||||
|
||||
path = SCARG_P32(uap, path);
|
||||
sg = stackgap_init(p, 0);
|
||||
|
||||
error = do_sys_stat(l, path, NOFOLLOW, &sb);
|
||||
if (error)
|
||||
|
@ -242,41 +236,20 @@ compat_30_netbsd32_fhstatvfs1(l, v, retval)
|
|||
} */ *uap = v;
|
||||
struct statvfs *sbuf;
|
||||
struct netbsd32_statvfs *s32;
|
||||
fhandle_t *fh;
|
||||
struct vnode *vp;
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Must be super user
|
||||
*/
|
||||
if ((error = kauth_authorize_system(l->l_cred,
|
||||
KAUTH_SYSTEM_FILEHANDLE, 0, NULL, NULL, NULL)) != 0)
|
||||
return error;
|
||||
sbuf = STATVFSBUF_GET();
|
||||
error = do_fhstatvfs(l, SCARG_P32(uap, fhp), FHANDLE_SIZE_COMPAT, sbuf,
|
||||
SCARG(uap, flags));
|
||||
|
||||
if ((error = vfs_copyinfh_alloc(SCARG_P32(uap, fhp),
|
||||
FHANDLE_SIZE_COMPAT, &fh)) != 0)
|
||||
goto bad;
|
||||
if ((error = vfs_fhtovp(fh, &vp)) != 0)
|
||||
goto bad;
|
||||
if (error != 0) {
|
||||
s32 = malloc(sizeof *s32, M_TEMP, M_WAITOK);
|
||||
netbsd32_from_statvfs(sbuf, s32);
|
||||
error = copyout(s32, SCARG_P32(uap, buf), sizeof *s32);
|
||||
free(s32, M_TEMP);
|
||||
}
|
||||
STATVFSBUF_PUT(sbuf);
|
||||
|
||||
sbuf = (struct statvfs *)malloc(sizeof(struct statvfs), M_TEMP,
|
||||
M_WAITOK);
|
||||
error = dostatvfs(vp->v_mount, sbuf, l, SCARG(uap, flags), 1);
|
||||
vput(vp);
|
||||
if (error != 0)
|
||||
goto out;
|
||||
|
||||
s32 = (struct netbsd32_statvfs *)
|
||||
malloc(sizeof(struct netbsd32_statvfs), M_TEMP, M_WAITOK);
|
||||
netbsd32_from_statvfs(sbuf, s32);
|
||||
error = copyout(s32, SCARG_P32(uap, buf),
|
||||
sizeof(struct netbsd32_statvfs));
|
||||
free(s32, M_TEMP);
|
||||
|
||||
out:
|
||||
free(sbuf, M_TEMP);
|
||||
bad:
|
||||
vfs_copyinfh_free(fh);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -330,31 +303,13 @@ int compat_30_netbsd32_sys___fhstat30(l, v, retval)
|
|||
struct stat sb;
|
||||
struct netbsd32_stat sb32;
|
||||
int error;
|
||||
fhandle_t *fh;
|
||||
struct vnode *vp;
|
||||
|
||||
/*
|
||||
* Must be super user
|
||||
*/
|
||||
if ((error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FILEHANDLE,
|
||||
0, NULL, NULL, NULL)))
|
||||
error = do_fhstat(l, SCARG_P32(uap, fhp), FHANDLE_SIZE_COMPAT, &sb);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if ((error = vfs_copyinfh_alloc(SCARG_P32(uap, fhp),
|
||||
FHANDLE_SIZE_COMPAT, &fh)) != 0)
|
||||
goto bad;
|
||||
|
||||
if ((error = vfs_fhtovp(fh, &vp)) != 0)
|
||||
goto bad;
|
||||
|
||||
error = vn_stat(vp, &sb, l);
|
||||
vput(vp);
|
||||
if (error)
|
||||
goto bad;
|
||||
netbsd32_from___stat30(&sb, &sb32);
|
||||
error = copyout(&sb32, SCARG_P32(uap, sb), sizeof(sb));
|
||||
bad:
|
||||
vfs_copyinfh_free(fh);
|
||||
error = copyout(&sb32, SCARG_P32(uap, sb), sizeof(sb32));
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: netbsd32_fs.c,v 1.41 2007/04/22 10:54:43 dsl Exp $ */
|
||||
/* $NetBSD: netbsd32_fs.c,v 1.42 2007/04/30 08:32:15 dsl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998, 2001 Matthew R. Green
|
||||
|
@ -29,7 +29,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: netbsd32_fs.c,v 1.41 2007/04/22 10:54:43 dsl Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: netbsd32_fs.c,v 1.42 2007/04/30 08:32:15 dsl Exp $");
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_ktrace.h"
|
||||
|
@ -376,6 +376,20 @@ change_utimes32(vp, tptr, l)
|
|||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
netbds32_copyout_statvfs(const void *kp, void *up, size_t len)
|
||||
{
|
||||
struct netbsd32_statvfs *sbuf_32;
|
||||
int error;
|
||||
|
||||
sbuf_32 = malloc(sizeof *sbuf_32, M_TEMP, M_WAITOK);
|
||||
netbsd32_from_statvfs(kp, sbuf_32);
|
||||
error = copyout(sbuf_32, up, sizeof(*sbuf_32));
|
||||
free(sbuf_32, M_TEMP);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
netbsd32_statvfs1(l, v, retval)
|
||||
struct lwp *l;
|
||||
|
@ -387,31 +401,15 @@ netbsd32_statvfs1(l, v, retval)
|
|||
syscallarg(netbsd32_statvfsp_t) buf;
|
||||
syscallarg(int) flags;
|
||||
} */ *uap = v;
|
||||
struct mount *mp;
|
||||
struct statvfs *sbuf;
|
||||
struct netbsd32_statvfs *s32;
|
||||
struct nameidata nd;
|
||||
struct statvfs *sb;
|
||||
int error;
|
||||
|
||||
NDINIT(&nd, LOOKUP, FOLLOW | TRYEMULROOT, UIO_USERSPACE, SCARG_P32(uap, path), l);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
/* Allocating on the stack would blow it up */
|
||||
sbuf = (struct statvfs *)malloc(sizeof(struct statvfs), M_TEMP,
|
||||
M_WAITOK);
|
||||
mp = nd.ni_vp->v_mount;
|
||||
vrele(nd.ni_vp);
|
||||
if ((error = dostatvfs(mp, sbuf, l, SCARG(uap, flags), 1)) != 0)
|
||||
goto out;
|
||||
s32 = (struct netbsd32_statvfs *)
|
||||
malloc(sizeof(struct netbsd32_statvfs), M_TEMP, M_WAITOK);
|
||||
netbsd32_from_statvfs(sbuf, s32);
|
||||
error = copyout(s32, SCARG_P32(uap, buf),
|
||||
sizeof(struct netbsd32_statvfs));
|
||||
free(s32, M_TEMP);
|
||||
out:
|
||||
free(sbuf, M_TEMP);
|
||||
return (error);
|
||||
sb = STATVFSBUF_GET();
|
||||
error = do_sys_pstatvfs(l, SCARG_P32(uap, path), SCARG(uap, flags), sb);
|
||||
if (error == 0)
|
||||
error = netbds32_copyout_statvfs(sb, SCARG_P32(uap, buf), 0);
|
||||
STATVFSBUF_PUT(sb);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -425,30 +423,14 @@ netbsd32_fstatvfs1(l, v, retval)
|
|||
syscallarg(netbsd32_statvfsp_t) buf;
|
||||
syscallarg(int) flags;
|
||||
} */ *uap = v;
|
||||
struct proc *p = l->l_proc;
|
||||
struct file *fp;
|
||||
struct mount *mp;
|
||||
struct statvfs *sbuf;
|
||||
struct netbsd32_statvfs *s32;
|
||||
struct statvfs *sb;
|
||||
int error;
|
||||
|
||||
/* getvnode() will use the descriptor for us */
|
||||
if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
|
||||
return (error);
|
||||
mp = ((struct vnode *)fp->f_data)->v_mount;
|
||||
sbuf = (struct statvfs *)malloc(sizeof(struct statvfs), M_TEMP,
|
||||
M_WAITOK);
|
||||
if ((error = dostatvfs(mp, sbuf, l, SCARG(uap, flags), 1)) != 0)
|
||||
goto out;
|
||||
s32 = (struct netbsd32_statvfs *)
|
||||
malloc(sizeof(struct netbsd32_statvfs), M_TEMP, M_WAITOK);
|
||||
netbsd32_from_statvfs(sbuf, s32);
|
||||
error = copyout(s32, SCARG_P32(uap, buf),
|
||||
sizeof(struct netbsd32_statvfs));
|
||||
free(s32, M_TEMP);
|
||||
out:
|
||||
free(sbuf, M_TEMP);
|
||||
FILE_UNUSE(fp, l);
|
||||
sb = STATVFSBUF_GET();
|
||||
error = do_sys_fstatvfs(l, SCARG(uap, fd), SCARG(uap, flags), sb);
|
||||
if (error == 0)
|
||||
error = netbds32_copyout_statvfs(sb, SCARG_P32(uap, buf), 0);
|
||||
STATVFSBUF_PUT(sb);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -463,74 +445,10 @@ netbsd32_getvfsstat(l, v, retval)
|
|||
syscallarg(netbsd32_size_t) bufsize;
|
||||
syscallarg(int) flags;
|
||||
} */ *uap = v;
|
||||
int root = 0;
|
||||
struct proc *p = l->l_proc;
|
||||
struct mount *mp, *nmp;
|
||||
struct statvfs *sbuf;
|
||||
struct netbsd32_statvfs *sfsp;
|
||||
struct netbsd32_statvfs *s32;
|
||||
size_t count, maxcount;
|
||||
int error = 0;
|
||||
|
||||
maxcount = SCARG(uap, bufsize) / sizeof(struct netbsd32_statvfs);
|
||||
sfsp = SCARG_P32(uap, buf);
|
||||
sbuf = (struct statvfs *)malloc(sizeof(struct statvfs), M_TEMP,
|
||||
M_WAITOK);
|
||||
s32 = (struct netbsd32_statvfs *)
|
||||
malloc(sizeof(struct netbsd32_statvfs), M_TEMP, M_WAITOK);
|
||||
simple_lock(&mountlist_slock);
|
||||
count = 0;
|
||||
for (mp = CIRCLEQ_FIRST(&mountlist); mp != (void *)&mountlist;
|
||||
mp = nmp) {
|
||||
if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock)) {
|
||||
nmp = CIRCLEQ_NEXT(mp, mnt_list);
|
||||
continue;
|
||||
}
|
||||
if (sfsp && count < maxcount) {
|
||||
error = dostatvfs(mp, sbuf, l, SCARG(uap, flags), 0);
|
||||
if (error) {
|
||||
simple_lock(&mountlist_slock);
|
||||
nmp = CIRCLEQ_NEXT(mp, mnt_list);
|
||||
vfs_unbusy(mp);
|
||||
continue;
|
||||
}
|
||||
netbsd32_from_statvfs(sbuf, s32);
|
||||
error = copyout(s32, sfsp, sizeof(*sfsp));
|
||||
if (error) {
|
||||
vfs_unbusy(mp);
|
||||
goto out;
|
||||
}
|
||||
sfsp++;
|
||||
root |= strcmp(sbuf->f_mntonname, "/") == 0;
|
||||
}
|
||||
count++;
|
||||
simple_lock(&mountlist_slock);
|
||||
nmp = CIRCLEQ_NEXT(mp, mnt_list);
|
||||
vfs_unbusy(mp);
|
||||
}
|
||||
simple_unlock(&mountlist_slock);
|
||||
if (root == 0 && p->p_cwdi->cwdi_rdir) {
|
||||
/*
|
||||
* fake a root entry
|
||||
*/
|
||||
if ((error = dostatvfs(p->p_cwdi->cwdi_rdir->v_mount, sbuf, l,
|
||||
SCARG(uap, flags), 1)) != 0)
|
||||
goto out;
|
||||
if (sfsp) {
|
||||
netbsd32_from_statvfs(sbuf, s32);
|
||||
error = copyout(s32, sfsp, sizeof(*sfsp));
|
||||
}
|
||||
count++;
|
||||
}
|
||||
if (sfsp && count > maxcount)
|
||||
*retval = maxcount;
|
||||
else
|
||||
*retval = count;
|
||||
|
||||
out:
|
||||
free(s32, M_TEMP);
|
||||
free(sbuf, M_TEMP);
|
||||
return (error);
|
||||
return do_sys_getvfsstat(l, SCARG_P32(uap, buf), SCARG(uap, bufsize),
|
||||
SCARG(uap, flags), netbds32_copyout_statvfs,
|
||||
sizeof (struct netbsd32_statvfs), retval);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -545,44 +463,18 @@ netbsd32___fhstatvfs140(l, v, retval)
|
|||
syscallarg(netbsd32_statvfsp_t) buf;
|
||||
syscallarg(int) flags;
|
||||
} */ *uap = v;
|
||||
struct statvfs *sbuf;
|
||||
struct netbsd32_statvfs *s32;
|
||||
fhandle_t *fh;
|
||||
struct vnode *vp;
|
||||
struct statvfs *sb;
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Must be super user
|
||||
*/
|
||||
if ((error = kauth_authorize_system(l->l_cred,
|
||||
KAUTH_SYSTEM_FILEHANDLE, 0, NULL, NULL, NULL)) != 0)
|
||||
return error;
|
||||
sb = STATVFSBUF_GET();
|
||||
error = do_fhstatvfs(l, SCARG_P32(uap, fhp), SCARG(uap, fh_size), sb,
|
||||
SCARG(uap, flags));
|
||||
|
||||
if ((error = vfs_copyinfh_alloc(SCARG_P32(uap, fhp),
|
||||
SCARG(uap, fh_size), &fh)) != 0)
|
||||
goto bad;
|
||||
if ((error = vfs_fhtovp(fh, &vp)) != 0)
|
||||
goto bad;
|
||||
if (error == 0)
|
||||
error = netbds32_copyout_statvfs(sb, SCARG_P32(uap, buf), 0);
|
||||
STATVFSBUF_PUT(sb);
|
||||
|
||||
sbuf = (struct statvfs *)malloc(sizeof(struct statvfs), M_TEMP,
|
||||
M_WAITOK);
|
||||
error = dostatvfs(vp->v_mount, sbuf, l, SCARG(uap, flags), 1);
|
||||
vput(vp);
|
||||
if (error != 0)
|
||||
goto out;
|
||||
|
||||
s32 = (struct netbsd32_statvfs *)
|
||||
malloc(sizeof(struct netbsd32_statvfs), M_TEMP, M_WAITOK);
|
||||
netbsd32_from_statvfs(sbuf, s32);
|
||||
error = copyout(s32, SCARG_P32(uap, buf),
|
||||
sizeof(struct netbsd32_statvfs));
|
||||
free(s32, M_TEMP);
|
||||
|
||||
out:
|
||||
free(sbuf, M_TEMP);
|
||||
bad:
|
||||
vfs_copyinfh_free(fh);
|
||||
return (error);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -732,12 +624,9 @@ netbsd32_sys___lstat30(l, v, retval)
|
|||
struct netbsd32_stat sb32;
|
||||
struct stat sb;
|
||||
int error;
|
||||
void *sg;
|
||||
const char *path;
|
||||
struct proc *p = l->l_proc;
|
||||
|
||||
path = SCARG_P32(uap, path);
|
||||
sg = stackgap_init(p, 0);
|
||||
|
||||
error = do_sys_stat(l, path, NOFOLLOW, &sb);
|
||||
if (error)
|
||||
|
@ -760,31 +649,12 @@ int netbsd32___fhstat40(l, v, retval)
|
|||
struct stat sb;
|
||||
struct netbsd32_stat sb32;
|
||||
int error;
|
||||
fhandle_t *fh;
|
||||
struct vnode *vp;
|
||||
|
||||
/*
|
||||
* Must be super user
|
||||
*/
|
||||
if ((error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FILEHANDLE,
|
||||
0, NULL, NULL, NULL)))
|
||||
return error;
|
||||
|
||||
if ((error = vfs_copyinfh_alloc(SCARG_P32(uap, fhp),
|
||||
SCARG(uap, fh_size), &fh)) != 0)
|
||||
goto bad;
|
||||
|
||||
if ((error = vfs_fhtovp(fh, &vp)) != 0)
|
||||
goto bad;
|
||||
|
||||
error = vn_stat(vp, &sb, l);
|
||||
vput(vp);
|
||||
if (error)
|
||||
goto bad;
|
||||
netbsd32_from___stat30(&sb, &sb32);
|
||||
error = copyout(&sb32, SCARG_P32(uap, sb), sizeof(sb));
|
||||
bad:
|
||||
vfs_copyinfh_free(fh);
|
||||
error = do_fhstat(l, SCARG_P32(uap, fhp), SCARG(uap, fh_size), &sb);
|
||||
if (error != 0) {
|
||||
netbsd32_from___stat30(&sb, &sb32);
|
||||
error = copyout(&sb32, SCARG_P32(uap, sb), sizeof(sb));
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: vfs_syscalls.c,v 1.310 2007/04/22 08:30:01 dsl Exp $ */
|
||||
/* $NetBSD: vfs_syscalls.c,v 1.311 2007/04/30 08:32:14 dsl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
|
@ -37,7 +37,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.310 2007/04/22 08:30:01 dsl Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.311 2007/04/30 08:32:14 dsl Exp $");
|
||||
|
||||
#include "opt_compat_netbsd.h"
|
||||
#include "opt_compat_43.h"
|
||||
|
@ -823,8 +823,24 @@ done:
|
|||
}
|
||||
|
||||
/*
|
||||
* Get filesystem statistics.
|
||||
* Get filesystem statistics by path.
|
||||
*/
|
||||
int
|
||||
do_sys_pstatvfs(struct lwp *l, const char *path, int flags, struct statvfs *sb)
|
||||
{
|
||||
struct mount *mp;
|
||||
int error;
|
||||
struct nameidata nd;
|
||||
|
||||
NDINIT(&nd, LOOKUP, FOLLOW | TRYEMULROOT, UIO_USERSPACE, path, l);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return error;
|
||||
mp = nd.ni_vp->v_mount;
|
||||
error = dostatvfs(mp, sb, l, flags, 1);
|
||||
vrele(nd.ni_vp);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
sys_statvfs1(struct lwp *l, void *v, register_t *retval)
|
||||
|
@ -834,28 +850,37 @@ sys_statvfs1(struct lwp *l, void *v, register_t *retval)
|
|||
syscallarg(struct statvfs *) buf;
|
||||
syscallarg(int) flags;
|
||||
} */ *uap = v;
|
||||
struct mount *mp;
|
||||
struct statvfs *sb;
|
||||
int error;
|
||||
struct nameidata nd;
|
||||
|
||||
NDINIT(&nd, LOOKUP, FOLLOW | TRYEMULROOT, UIO_USERSPACE, SCARG(uap, path), l);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return error;
|
||||
mp = nd.ni_vp->v_mount;
|
||||
vrele(nd.ni_vp);
|
||||
sb = STATVFSBUF_GET();
|
||||
error = dostatvfs(mp, sb, l, SCARG(uap, flags), 1);
|
||||
if (error == 0) {
|
||||
error = do_sys_pstatvfs(l, SCARG(uap, path), SCARG(uap, flags), sb);
|
||||
if (error == 0)
|
||||
error = copyout(sb, SCARG(uap, buf), sizeof(*sb));
|
||||
}
|
||||
STATVFSBUF_PUT(sb);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get filesystem statistics.
|
||||
* Get filesystem statistics by fd.
|
||||
*/
|
||||
int
|
||||
do_sys_fstatvfs(struct lwp *l, int fd, int flags, struct statvfs *sb)
|
||||
{
|
||||
struct proc *p = l->l_proc;
|
||||
struct file *fp;
|
||||
struct mount *mp;
|
||||
int error;
|
||||
|
||||
/* getvnode() will use the descriptor for us */
|
||||
if ((error = getvnode(p->p_fd, fd, &fp)) != 0)
|
||||
return (error);
|
||||
mp = ((struct vnode *)fp->f_data)->v_mount;
|
||||
error = dostatvfs(mp, sb, l, flags, 1);
|
||||
FILE_UNUSE(fp, l);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
sys_fstatvfs1(struct lwp *l, void *v, register_t *retval)
|
||||
|
@ -865,22 +890,13 @@ sys_fstatvfs1(struct lwp *l, void *v, register_t *retval)
|
|||
syscallarg(struct statvfs *) buf;
|
||||
syscallarg(int) flags;
|
||||
} */ *uap = v;
|
||||
struct proc *p = l->l_proc;
|
||||
struct file *fp;
|
||||
struct mount *mp;
|
||||
struct statvfs *sb;
|
||||
int error;
|
||||
|
||||
/* getvnode() will use the descriptor for us */
|
||||
if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
|
||||
return (error);
|
||||
mp = ((struct vnode *)fp->f_data)->v_mount;
|
||||
sb = STATVFSBUF_GET();
|
||||
if ((error = dostatvfs(mp, sb, l, SCARG(uap, flags), 1)) != 0)
|
||||
goto out;
|
||||
error = copyout(sb, SCARG(uap, buf), sizeof(*sb));
|
||||
out:
|
||||
FILE_UNUSE(fp, l);
|
||||
error = do_sys_fstatvfs(l, SCARG(uap, fd), SCARG(uap, flags), sb);
|
||||
if (error != 0)
|
||||
error = copyout(sb, SCARG(uap, buf), sizeof(*sb));
|
||||
STATVFSBUF_PUT(sb);
|
||||
return error;
|
||||
}
|
||||
|
@ -890,24 +906,19 @@ sys_fstatvfs1(struct lwp *l, void *v, register_t *retval)
|
|||
* Get statistics on all filesystems.
|
||||
*/
|
||||
int
|
||||
sys_getvfsstat(struct lwp *l, void *v, register_t *retval)
|
||||
do_sys_getvfsstat(struct lwp *l, void *sfsp, size_t bufsize, int flags,
|
||||
int (*copyfn)(const void *, void *, size_t), size_t entry_sz,
|
||||
register_t *retval)
|
||||
{
|
||||
struct sys_getvfsstat_args /* {
|
||||
syscallarg(struct statvfs *) buf;
|
||||
syscallarg(size_t) bufsize;
|
||||
syscallarg(int) flags;
|
||||
} */ *uap = v;
|
||||
int root = 0;
|
||||
struct proc *p = l->l_proc;
|
||||
struct mount *mp, *nmp;
|
||||
struct statvfs *sb;
|
||||
struct statvfs *sfsp;
|
||||
size_t count, maxcount;
|
||||
int error = 0;
|
||||
|
||||
sb = STATVFSBUF_GET();
|
||||
maxcount = SCARG(uap, bufsize) / sizeof(struct statvfs);
|
||||
sfsp = SCARG(uap, buf);
|
||||
maxcount = bufsize / entry_sz;
|
||||
simple_lock(&mountlist_slock);
|
||||
count = 0;
|
||||
for (mp = CIRCLEQ_FIRST(&mountlist); mp != (void *)&mountlist;
|
||||
|
@ -917,19 +928,19 @@ sys_getvfsstat(struct lwp *l, void *v, register_t *retval)
|
|||
continue;
|
||||
}
|
||||
if (sfsp && count < maxcount) {
|
||||
error = dostatvfs(mp, sb, l, SCARG(uap, flags), 0);
|
||||
error = dostatvfs(mp, sb, l, flags, 0);
|
||||
if (error) {
|
||||
simple_lock(&mountlist_slock);
|
||||
nmp = CIRCLEQ_NEXT(mp, mnt_list);
|
||||
vfs_unbusy(mp);
|
||||
continue;
|
||||
}
|
||||
error = copyout(sb, sfsp, sizeof(*sfsp));
|
||||
error = copyfn(sb, sfsp, entry_sz);
|
||||
if (error) {
|
||||
vfs_unbusy(mp);
|
||||
goto out;
|
||||
}
|
||||
sfsp++;
|
||||
sfsp = (char *)sfsp + entry_sz;
|
||||
root |= strcmp(sb->f_mntonname, "/") == 0;
|
||||
}
|
||||
count++;
|
||||
|
@ -942,11 +953,11 @@ sys_getvfsstat(struct lwp *l, void *v, register_t *retval)
|
|||
/*
|
||||
* fake a root entry
|
||||
*/
|
||||
if ((error = dostatvfs(p->p_cwdi->cwdi_rdir->v_mount, sb, l,
|
||||
SCARG(uap, flags), 1)) != 0)
|
||||
error = dostatvfs(p->p_cwdi->cwdi_rdir->v_mount, sb, l, flags, 1);
|
||||
if (error != 0)
|
||||
goto out;
|
||||
if (sfsp)
|
||||
error = copyout(sb, sfsp, sizeof(*sfsp));
|
||||
error = copyfn(sb, sfsp, entry_sz);
|
||||
count++;
|
||||
}
|
||||
if (sfsp && count > maxcount)
|
||||
|
@ -958,6 +969,19 @@ out:
|
|||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
sys_getvfsstat(struct lwp *l, void *v, register_t *retval)
|
||||
{
|
||||
struct sys_getvfsstat_args /* {
|
||||
syscallarg(struct statvfs *) buf;
|
||||
syscallarg(size_t) bufsize;
|
||||
syscallarg(int) flags;
|
||||
} */ *uap = v;
|
||||
|
||||
return do_sys_getvfsstat(l, SCARG(uap, buf), SCARG(uap, bufsize),
|
||||
SCARG(uap, flags), copyout, sizeof (struct statvfs), retval);
|
||||
}
|
||||
|
||||
/*
|
||||
* Change current working directory to a given file descriptor.
|
||||
*/
|
||||
|
@ -1624,20 +1648,6 @@ sys___fhopen40(struct lwp *l, void *v, register_t *retval)
|
|||
SCARG(uap, flags), retval);
|
||||
}
|
||||
|
||||
/* XXX: temp (mar '07) for LKM compat */
|
||||
int
|
||||
dofhstat(struct lwp *l, const void *ufhp, size_t fhsize, struct stat *sbp,
|
||||
register_t *retval)
|
||||
{
|
||||
int error;
|
||||
struct stat sb;
|
||||
|
||||
error = do_fhstat(l, ufhp, fhsize, &sb);
|
||||
if (error == 0)
|
||||
error = copyout(&sb, sbp, sizeof(sb));
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
do_fhstat(struct lwp *l, const void *ufhp, size_t fhsize, struct stat *sb)
|
||||
{
|
||||
|
@ -1685,21 +1695,6 @@ sys___fhstat40(struct lwp *l, void *v, register_t *retval)
|
|||
return copyout(&sb, SCARG(uap, sb), sizeof(sb));
|
||||
}
|
||||
|
||||
/* XXX: temp (mar '07) for LKM compat */
|
||||
int
|
||||
dofhstatvfs(struct lwp *l, const void *ufhp, size_t fhsize, struct statvfs *buf,
|
||||
int flags, register_t *retval)
|
||||
{
|
||||
struct statvfs *sb = STATVFSBUF_GET();
|
||||
int error;
|
||||
|
||||
error = do_fhstatvfs(l, ufhp, fhsize, sb, flags);
|
||||
if (error == 0)
|
||||
error = copyout(sb, buf, sizeof(*sb));
|
||||
STATVFSBUF_PUT(sb);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
do_fhstatvfs(struct lwp *l, const void *ufhp, size_t fhsize, struct statvfs *sb,
|
||||
int flags)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: vfs_syscalls.h,v 1.2 2007/03/11 19:34:55 dsl Exp $ */
|
||||
/* $NetBSD: vfs_syscalls.h,v 1.3 2007/04/30 08:32:14 dsl Exp $ */
|
||||
|
||||
#ifndef _SYS_VFS_SYSCALLS_H_
|
||||
#define _SYS_VFS_SYSCALLS_H_
|
||||
|
@ -15,13 +15,15 @@ int do_sys_stat(struct lwp *, const char *, unsigned int, struct stat *);
|
|||
int do_fhstat(struct lwp *, const void *, size_t, struct stat *);
|
||||
int do_fhstatvfs(struct lwp *, const void *, size_t, struct statvfs *, int);
|
||||
|
||||
/* VFS status functions to kernel buffers */
|
||||
int do_sys_pstatvfs(struct lwp *, const char *, int, struct statvfs *);
|
||||
int do_sys_fstatvfs(struct lwp *, int, int, struct statvfs *);
|
||||
/* VFS status - call copyfn() for each entry */
|
||||
int do_sys_getvfsstat(struct lwp *, void *, size_t, int, int (*)(const void *, void *, size_t), size_t, register_t *);
|
||||
|
||||
int vfs_copyinfh_alloc(const void *, size_t, fhandle_t **);
|
||||
void vfs_copyinfh_free(fhandle_t *);
|
||||
|
||||
int dofhopen(struct lwp *, const void *, size_t, int, register_t *);
|
||||
/* These 2 have user-space stat buffer pointer and must be killed */
|
||||
int dofhstat(struct lwp *, const void *, size_t, struct stat *, register_t *);
|
||||
int dofhstatvfs(struct lwp *, const void *, size_t, struct statvfs *, int,
|
||||
register_t *);
|
||||
|
||||
#endif /* _SYS_VFS_SYSCALLS_H_ */
|
||||
|
|
Loading…
Reference in New Issue