diff options
author | Paul Irofti <pirofti@cvs.openbsd.org> | 2012-05-23 11:08:58 +0000 |
---|---|---|
committer | Paul Irofti <pirofti@cvs.openbsd.org> | 2012-05-23 11:08:58 +0000 |
commit | 88062ad9da299fa442c20e694806961fe30de003 (patch) | |
tree | 0111945b4145b61457d6af46f0ba4d8ae1b405b3 | |
parent | bae481b21a8eabc6efce90782fed0aa1339bf9e4 (diff) |
Add support for statfs64.
While at it get rid of some magic numbers and add support for more
filesystem types (like NTFS, AFS etc.).
Suggestions and feedback from ajacoutot@, jsing@ and matthew@.
Okay matthew@.
-rw-r--r-- | sys/compat/linux/linux_misc.c | 102 | ||||
-rw-r--r-- | sys/compat/linux/linux_types.h | 26 | ||||
-rw-r--r-- | sys/compat/linux/syscalls.master | 5 |
3 files changed, 119 insertions, 14 deletions
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index 4977320ae6d..84a3b452136 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: linux_misc.c,v 1.76 2012/04/22 05:43:14 guenther Exp $ */ +/* $OpenBSD: linux_misc.c,v 1.77 2012/05/23 11:08:57 pirofti Exp $ */ /* $NetBSD: linux_misc.c,v 1.27 1996/05/20 01:59:21 fvdl Exp $ */ /*- @@ -364,9 +364,7 @@ linux_sys_time(p, v, retval) * we fake (probably the wrong way). */ static void -bsd_to_linux_statfs(bsp, lsp) - struct statfs *bsp; - struct linux_statfs *lsp; +bsd_to_linux_statfs(struct statfs *bsp, struct linux_statfs *lsp) { /* @@ -376,19 +374,25 @@ bsd_to_linux_statfs(bsp, lsp) */ if (!strcmp(bsp->f_fstypename, MOUNT_FFS) || !strcmp(bsp->f_fstypename, MOUNT_MFS)) - lsp->l_ftype = 0x11954; + lsp->l_ftype = LINUX_FSTYPE_FFS; else if (!strcmp(bsp->f_fstypename, MOUNT_NFS)) - lsp->l_ftype = 0x6969; + lsp->l_ftype = LINUX_FSTYPE_NFS; else if (!strcmp(bsp->f_fstypename, MOUNT_MSDOS)) - lsp->l_ftype = 0x4d44; + lsp->l_ftype = LINUX_FSTYPE_MSDOS; else if (!strcmp(bsp->f_fstypename, MOUNT_PROCFS)) - lsp->l_ftype = 0x9fa0; + lsp->l_ftype = LINUX_FSTYPE_PROCFS; else if (!strcmp(bsp->f_fstypename, MOUNT_EXT2FS)) - lsp->l_ftype = 0xef53; + lsp->l_ftype = LINUX_FSTYPE_EXT2FS; else if (!strcmp(bsp->f_fstypename, MOUNT_CD9660)) - lsp->l_ftype = 0x9660; + lsp->l_ftype = LINUX_FSTYPE_CD9660; else if (!strcmp(bsp->f_fstypename, MOUNT_NCPFS)) - lsp->l_ftype = 0x6969; + lsp->l_ftype = LINUX_FSTYPE_NCPFS; + else if (!strcmp(bsp->f_fstypename, MOUNT_NTFS)) + lsp->l_ftype = LINUX_FSTYPE_NTFS; + else if (!strcmp(bsp->f_fstypename, MOUNT_UDF)) + lsp->l_ftype = LINUX_FSTYPE_UDF; + else if (!strcmp(bsp->f_fstypename, MOUNT_AFS)) + lsp->l_ftype = LINUX_FSTYPE_AFS; else lsp->l_ftype = -1; @@ -441,6 +445,82 @@ linux_sys_statfs(p, v, retval) return copyout((caddr_t) <mp, (caddr_t) SCARG(uap, sp), sizeof ltmp); } +static void +bsd_to_linux_statfs64(struct statfs *bsp, struct linux_statfs64 *lsp) +{ + + /* + * Convert BSD filesystem names to Linux filesystem type numbers + * where possible. Linux statfs uses a value of -1 to indicate + * an unsupported field. + */ + if (!strcmp(bsp->f_fstypename, MOUNT_FFS) || + !strcmp(bsp->f_fstypename, MOUNT_MFS)) + lsp->l_ftype = LINUX_FSTYPE_FFS; + else if (!strcmp(bsp->f_fstypename, MOUNT_NFS)) + lsp->l_ftype = LINUX_FSTYPE_NFS; + else if (!strcmp(bsp->f_fstypename, MOUNT_MSDOS)) + lsp->l_ftype = LINUX_FSTYPE_MSDOS; + else if (!strcmp(bsp->f_fstypename, MOUNT_PROCFS)) + lsp->l_ftype = LINUX_FSTYPE_PROCFS; + else if (!strcmp(bsp->f_fstypename, MOUNT_EXT2FS)) + lsp->l_ftype = LINUX_FSTYPE_EXT2FS; + else if (!strcmp(bsp->f_fstypename, MOUNT_CD9660)) + lsp->l_ftype = LINUX_FSTYPE_CD9660; + else if (!strcmp(bsp->f_fstypename, MOUNT_NCPFS)) + lsp->l_ftype = LINUX_FSTYPE_NCPFS; + else if (!strcmp(bsp->f_fstypename, MOUNT_NTFS)) + lsp->l_ftype = LINUX_FSTYPE_NTFS; + else if (!strcmp(bsp->f_fstypename, MOUNT_UDF)) + lsp->l_ftype = LINUX_FSTYPE_UDF; + else if (!strcmp(bsp->f_fstypename, MOUNT_AFS)) + lsp->l_ftype = LINUX_FSTYPE_AFS; + else + lsp->l_ftype = -1; + + lsp->l_fbsize = bsp->f_bsize; + lsp->l_fblocks = bsp->f_blocks; + lsp->l_fbfree = bsp->f_bfree; + lsp->l_fbavail = bsp->f_bavail; + lsp->l_ffiles = bsp->f_files; + lsp->l_fffree = bsp->f_ffree; + lsp->l_ffsid.val[0] = bsp->f_fsid.val[0]; + lsp->l_ffsid.val[1] = bsp->f_fsid.val[1]; + lsp->l_fnamelen = MAXNAMLEN; /* XXX */ +} + +int +linux_sys_statfs64(struct proc *p, void *v, register_t *retval) +{ + struct linux_sys_statfs64_args /* { + syscallarg(char *) path; + syscallarg(struct linux_statfs64 *) sp; + } */ *uap = v; + struct statfs btmp, *bsp; + struct linux_statfs64 ltmp; + struct sys_statfs_args bsa; + caddr_t sg; + int error; + + sg = stackgap_init(p->p_emul); + bsp = (struct statfs *) stackgap_alloc(&sg, sizeof (struct statfs)); + + LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); + + SCARG(&bsa, path) = SCARG(uap, path); + SCARG(&bsa, buf) = bsp; + + if ((error = sys_statfs(p, &bsa, retval))) + return error; + + if ((error = copyin((caddr_t) bsp, (caddr_t) &btmp, sizeof btmp))) + return error; + + bsd_to_linux_statfs64(&btmp, <mp); + + return copyout((caddr_t) <mp, (caddr_t) SCARG(uap, sp), sizeof ltmp); +} + int linux_sys_fstatfs(p, v, retval) struct proc *p; diff --git a/sys/compat/linux/linux_types.h b/sys/compat/linux/linux_types.h index 880faf07797..340fafe6e63 100644 --- a/sys/compat/linux/linux_types.h +++ b/sys/compat/linux/linux_types.h @@ -1,4 +1,4 @@ -/* $OpenBSD: linux_types.h,v 1.10 2011/04/05 22:54:31 pirofti Exp $ */ +/* $OpenBSD: linux_types.h,v 1.11 2012/05/23 11:08:57 pirofti Exp $ */ /* $NetBSD: linux_types.h,v 1.5 1996/05/20 01:59:28 fvdl Exp $ */ /* @@ -53,6 +53,17 @@ typedef long linux_off_t; typedef u_int64_t linux_loff_t; typedef int linux_pid_t; +#define LINUX_FSTYPE_FFS 0x11954 +#define LINUX_FSTYPE_NFS 0x6969 +#define LINUX_FSTYPE_MSDOS 0x4d44 +#define LINUX_FSTYPE_PROCFS 0x9fa0 +#define LINUX_FSTYPE_EXT2FS 0xef53 +#define LINUX_FSTYPE_CD9660 0x9660 +#define LINUX_FSTYPE_NCPFS 0x6969 +#define LINUX_FSTYPE_NTFS 0x5346544e /* "NTFS" */ +#define LINUX_FSTYPE_UDF 0x15013346 +#define LINUX_FSTYPE_AFS 0x5346414f + struct linux_statfs { long l_ftype; long l_fbsize; @@ -66,6 +77,19 @@ struct linux_statfs { long l_fspare[6]; }; +struct linux_statfs64 { + int l_ftype; + int l_fbsize; + uint64_t l_fblocks; + uint64_t l_fbfree; + uint64_t l_fbavail; + uint64_t l_ffiles; + uint64_t l_fffree; + linux_fsid_t l_ffsid; + int l_fnamelen; + int l_fspare[6]; +}; + /* * Structure for uname(2) */ diff --git a/sys/compat/linux/syscalls.master b/sys/compat/linux/syscalls.master index 78c776f17c0..38945b4e0e7 100644 --- a/sys/compat/linux/syscalls.master +++ b/sys/compat/linux/syscalls.master @@ -1,4 +1,4 @@ - $OpenBSD: syscalls.master,v 1.66 2011/12/14 08:33:18 robert Exp $ + $OpenBSD: syscalls.master,v 1.67 2012/05/23 11:08:57 pirofti Exp $ ; $NetBSD: syscalls.master,v 1.15 1995/12/18 14:35:10 fvdl Exp $ ; @(#)syscalls.master 8.1 (Berkeley) 7/19/93 @@ -416,7 +416,8 @@ 266 STD { int linux_sys_clock_getres(clockid_t which, \ struct l_timespec *tp); } 267 UNIMPL linux_sys_clock_nanosleep -268 UNIMPL linux_sys_statfs64 +268 STD { int linux_sys_statfs64(char *path, \ + struct linux_statfs64 *sp); } 269 UNIMPL linux_sys_fstatfs64 270 UNIMPL linux_sys_tgkill 271 UNIMPL linux_sys_utimes |