implement support for Linux statfs64() syscall - 64bit variant of statfs()

This commit is contained in:
jdolecek 2004-09-20 18:41:07 +00:00
parent 845beacce3
commit 110cc1cc61
8 changed files with 190 additions and 28 deletions

View File

@ -1,4 +1,4 @@
$NetBSD: syscalls.master,v 1.18 2004/09/08 19:45:22 jdolecek Exp $
$NetBSD: syscalls.master,v 1.19 2004/09/20 18:41:07 jdolecek Exp $
; Derived from sys/compat/linux/arch/*/syscalls.master
; and from Linux 2.4.12 arch/arm/kernel/calls.S
@ -420,8 +420,10 @@
263 UNIMPL clock_gettime
264 UNIMPL clock_getres
265 UNIMPL clock_nanosleep
266 UNIMPL statfs64
267 UNIMPL fstatfs64
266 STD { int linux_sys_statfs64(const char *path, \
size_t sz, struct linux_statfs64 *sp); }
267 STD { int linux_sys_fstatfs64(int fd, \
size_t sz, struct linux_statfs64 *sp); }
268 UNIMPL tgkill
269 UNIMPL utimes
270 UNIMPL fadvise64_64

View File

@ -1,4 +1,4 @@
$NetBSD: syscalls.master,v 1.70 2004/09/08 19:45:22 jdolecek Exp $
$NetBSD: syscalls.master,v 1.71 2004/09/20 18:41:07 jdolecek Exp $
; @(#)syscalls.master 8.1 (Berkeley) 7/19/93
@ -416,8 +416,10 @@
265 UNIMPL clock_gettime
266 UNIMPL clock_getres
267 UNIMPL clock_nanosleep
268 UNIMPL statfs64
269 UNIMPL fstatfs64
268 STD { int linux_sys_statfs64(const char *path, \
size_t sz, struct linux_statfs64 *sp); }
269 STD { int linux_sys_fstatfs64(int fd, \
size_t sz, struct linux_statfs64 *sp); }
270 UNIMPL tgkill
271 UNIMPL utimes
272 UNIMPL fadvise64_64

View File

@ -1,4 +1,4 @@
$NetBSD: syscalls.master,v 1.15 2004/09/08 19:45:22 jdolecek Exp $
$NetBSD: syscalls.master,v 1.16 2004/09/20 18:41:07 jdolecek Exp $
; @(#)syscalls.master 8.1 (Berkeley) 7/19/93
@ -420,8 +420,10 @@
252 UNIMPL set_tid_address
253 UNIMPL restart_syscall
254 UNIMPL fadvise64
255 UNIMPL statfs64
256 UNIMPL fstatfs64
255 STD { int linux_sys_statfs64(const char *path, \
size_t sz, struct linux_statfs64 *sp); }
256 STD { int linux_sys_fstatfs64(int fd, \
size_t sz, struct linux_statfs64 *sp); }
257 UNIMPL timer_create
258 UNIMPL timer_settime
259 UNIMPL timer_gettime

View File

@ -1,4 +1,4 @@
$NetBSD: syscalls.master,v 1.19 2004/09/08 19:45:22 jdolecek Exp $
$NetBSD: syscalls.master,v 1.20 2004/09/20 18:41:07 jdolecek Exp $
; @(#)syscalls.master 8.1 (Berkeley) 7/19/93
@ -421,8 +421,10 @@
249 UNIMPL swapcontext
250 UNIMPL tgkill
251 UNIMPL utimes
252 UNIMPL statfs64
253 UNIMPL fstatfs64
252 STD { int linux_sys_statfs64(const char *path, \
size_t sz, struct linux_statfs64 *sp); }
253 STD { int linux_sys_fstatfs64(int fd, \
size_t sz, struct linux_statfs64 *sp); }
254 UNIMPL fadvise64_64
255 UNIMPL rtas
256 UNIMPL /* reserved for sys_debug_setcontext */

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_misc.c,v 1.131 2004/09/19 16:50:11 jdolecek Exp $ */
/* $NetBSD: linux_misc.c,v 1.132 2004/09/20 18:41:07 jdolecek Exp $ */
/*-
* Copyright (c) 1995, 1998, 1999 The NetBSD Foundation, Inc.
@ -64,7 +64,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: linux_misc.c,v 1.131 2004/09/19 16:50:11 jdolecek Exp $");
__KERNEL_RCSID(0, "$NetBSD: linux_misc.c,v 1.132 2004/09/20 18:41:07 jdolecek Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -132,10 +132,7 @@ const int linux_ptrace_request_map[] = {
-1
};
static const struct mnttypes {
char *bsd;
int linux;
} fstypes[] = {
const struct linux_mnttypes linux_fstypes[] = {
{ MOUNT_FFS, LINUX_DEFAULT_SUPER_MAGIC },
{ MOUNT_NFS, LINUX_NFS_SUPER_MAGIC },
{ MOUNT_MFS, LINUX_DEFAULT_SUPER_MAGIC },
@ -159,7 +156,7 @@ static const struct mnttypes {
{ MOUNT_NTFS, LINUX_DEFAULT_SUPER_MAGIC },
{ MOUNT_SMBFS, LINUX_SMB_SUPER_MAGIC }
};
#define FSTYPESSIZE (sizeof(fstypes) / sizeof(fstypes[0]))
const int linux_fstypes_cnt = sizeof(linux_fstypes) / sizeof(linux_fstypes[0]);
#ifdef DEBUG_LINUX
#define DPRINTF(a) uprintf a
@ -307,16 +304,17 @@ bsd_to_linux_statfs(bsp, lsp)
{
int i;
for (i = 0; i < FSTYPESSIZE; i++)
if (strcmp(bsp->f_fstypename, fstypes[i].bsd) == 0)
for (i = 0; i < linux_fstypes_cnt; i++) {
if (strcmp(bsp->f_fstypename, linux_fstypes[i].bsd) == 0) {
lsp->l_ftype = linux_fstypes[i].linux;
break;
}
}
if (i == FSTYPESSIZE) {
if (i == linux_fstypes_cnt) {
DPRINTF(("unhandled fstype in linux emulation: %s\n",
bsp->f_fstypename));
lsp->l_ftype = LINUX_DEFAULT_SUPER_MAGIC;
} else {
lsp->l_ftype = fstypes[i].linux;
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_misc.h,v 1.8 2003/01/18 08:02:53 thorpej Exp $ */
/* $NetBSD: linux_misc.h,v 1.9 2004/09/20 18:41:07 jdolecek Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -109,6 +109,13 @@ struct linux_sysinfo {
#define LINUX_USBDEVICE_SUPER_MAGIC 0x00009fa2
#define LINUX_XENIX_SUPER_MAGIC (LINUX_SYSV_MAGIC_BASE + 1)
struct linux_mnttypes {
const char *bsd;
int linux;
};
extern const struct linux_mnttypes linux_fstypes[];
extern const int linux_fstypes_cnt;
#ifdef _KERNEL
__BEGIN_DECLS
void bsd_to_linux_wstat __P((int *));

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_misc_notalpha.c,v 1.69 2003/06/29 22:29:31 fvdl Exp $ */
/* $NetBSD: linux_misc_notalpha.c,v 1.70 2004/09/20 18:41:07 jdolecek Exp $ */
/*-
* Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: linux_misc_notalpha.c,v 1.69 2003/06/29 22:29:31 fvdl Exp $");
__KERNEL_RCSID(0, "$NetBSD: linux_misc_notalpha.c,v 1.70 2004/09/20 18:41:07 jdolecek Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -75,6 +75,15 @@ __KERNEL_RCSID(0, "$NetBSD: linux_misc_notalpha.c,v 1.69 2003/06/29 22:29:31 fvd
/* Used on: arm, i386, m68k, mips, ppc, sparc, sparc64 */
/* Not used on: alpha */
#ifdef DEBUG_LINUX
#define DPRINTF(a) uprintf a
#else
#define DPRINTF(a)
#endif
static void bsd_to_linux_statfs64(const struct statvfs *,
struct linux_statfs64 *);
/*
* Alarm. This is a libc call which uses setitimer(2) in NetBSD.
* Fiddle with the timers to make it work.
@ -417,3 +426,129 @@ linux_sys_stime(l, v, retval)
return 0;
}
#ifndef __m68k__
/*
* Convert NetBSD statvfs structure to Linux statfs64 structure.
* See comments in bsd_to_linux_statfs() for further background.
* We can safely pass correct bsize and frsize here, since Linux glibc
* statvfs() doesn't use statfs64().
*/
static void
bsd_to_linux_statfs64(bsp, lsp)
const struct statvfs *bsp;
struct linux_statfs64 *lsp;
{
int i, div;
for (i = 0; i < linux_fstypes_cnt; i++) {
if (strcmp(bsp->f_fstypename, linux_fstypes[i].bsd) == 0) {
lsp->l_ftype = linux_fstypes[i].linux;
break;
}
}
if (i == linux_fstypes_cnt) {
DPRINTF(("unhandled fstype in linux emulation: %s\n",
bsp->f_fstypename));
lsp->l_ftype = LINUX_DEFAULT_SUPER_MAGIC;
}
div = bsp->f_bsize / bsp->f_frsize;
lsp->l_fbsize = bsp->f_bsize;
lsp->l_ffrsize = bsp->f_frsize;
lsp->l_fblocks = bsp->f_blocks / div;
lsp->l_fbfree = bsp->f_bfree / div;
lsp->l_fbavail = bsp->f_bavail / div;
lsp->l_ffiles = bsp->f_files;
lsp->l_fffree = bsp->f_ffree / div;
/* Linux sets the fsid to 0..., we don't */
lsp->l_ffsid.val[0] = bsp->f_fsidx.__fsid_val[0];
lsp->l_ffsid.val[1] = bsp->f_fsidx.__fsid_val[1];
lsp->l_fnamelen = bsp->f_namemax;
(void)memset(lsp->l_fspare, 0, sizeof(lsp->l_fspare));
}
/*
* Implement the fs stat functions. Straightforward.
*/
int
linux_sys_statfs64(l, v, retval)
struct lwp *l;
void *v;
register_t *retval;
{
struct linux_sys_statfs64_args /* {
syscallarg(const char *) path;
syscallarg(size_t) sz;
syscallarg(struct linux_statfs64 *) sp;
} */ *uap = v;
struct proc *p = l->l_proc;
struct statvfs btmp, *bsp;
struct linux_statfs64 ltmp;
struct sys_statvfs1_args bsa;
caddr_t sg;
int error;
if (SCARG(uap, sz) != sizeof ltmp)
return (EINVAL);
sg = stackgap_init(p, 0);
bsp = (struct statvfs *) stackgap_alloc(p, &sg, sizeof (struct statvfs));
CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
SCARG(&bsa, path) = SCARG(uap, path);
SCARG(&bsa, buf) = bsp;
SCARG(&bsa, flags) = ST_WAIT;
if ((error = sys_statvfs1(l, &bsa, retval)))
return error;
if ((error = copyin((caddr_t) bsp, (caddr_t) &btmp, sizeof btmp)))
return error;
bsd_to_linux_statfs64(&btmp, &ltmp);
return copyout((caddr_t) &ltmp, (caddr_t) SCARG(uap, sp), sizeof ltmp);
}
int
linux_sys_fstatfs64(l, v, retval)
struct lwp *l;
void *v;
register_t *retval;
{
struct linux_sys_fstatfs64_args /* {
syscallarg(int) fd;
syscallarg(size_t) sz;
syscallarg(struct linux_statfs64 *) sp;
} */ *uap = v;
struct proc *p = l->l_proc;
struct statvfs btmp, *bsp;
struct linux_statfs64 ltmp;
struct sys_fstatvfs1_args bsa;
caddr_t sg;
int error;
if (SCARG(uap, sz) != sizeof ltmp)
return (EINVAL);
sg = stackgap_init(p, 0);
bsp = (struct statvfs *) stackgap_alloc(p, &sg, sizeof (struct statvfs));
SCARG(&bsa, fd) = SCARG(uap, fd);
SCARG(&bsa, buf) = bsp;
SCARG(&bsa, flags) = ST_WAIT;
if ((error = sys_fstatvfs1(l, &bsa, retval)))
return error;
if ((error = copyin((caddr_t) bsp, (caddr_t) &btmp, sizeof btmp)))
return error;
bsd_to_linux_statfs64(&btmp, &ltmp);
return copyout((caddr_t) &ltmp, (caddr_t) SCARG(uap, sp), sizeof ltmp);
}
#endif /* !__m68k__ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_types.h,v 1.18 2004/09/20 03:21:40 christos Exp $ */
/* $NetBSD: linux_types.h,v 1.19 2004/09/20 18:41:08 jdolecek Exp $ */
/*-
* Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
@ -118,6 +118,20 @@ struct linux_statfs {
u_int32_t l_ffrsize;
u_int32_t l_fspare[5];
};
struct linux_statfs64 {
u_int32_t l_ftype;
u_int32_t l_fbsize;
u_int64_t l_fblocks;
u_int64_t l_fbfree;
u_int64_t l_fbavail;
u_int64_t l_ffiles;
u_int64_t l_fffree;
linux_fsid_t l_ffsid;
u_int32_t l_fnamelen;
u_int32_t l_ffrsize;
u_int32_t l_fspare[5];
};
#endif /* !__sparc64__ */
#endif /* !_LINUX_TYPES_H */