summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Irofti <pirofti@cvs.openbsd.org>2012-05-23 11:08:58 +0000
committerPaul Irofti <pirofti@cvs.openbsd.org>2012-05-23 11:08:58 +0000
commit88062ad9da299fa442c20e694806961fe30de003 (patch)
tree0111945b4145b61457d6af46f0ba4d8ae1b405b3
parentbae481b21a8eabc6efce90782fed0aa1339bf9e4 (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.c102
-rw-r--r--sys/compat/linux/linux_types.h26
-rw-r--r--sys/compat/linux/syscalls.master5
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) &ltmp, (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, &ltmp);
+
+ return copyout((caddr_t) &ltmp, (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