New diff with no magic numbers (suggested by jsing@), more filesystems
support (suggested by ajacoutot@), including the header this time and
fixing a comment (suggested by matthew@).


Index: linux_misc.c
===================================================================
RCS file: /cvs/src/sys/compat/linux/linux_misc.c,v
retrieving revision 1.76
diff -u -p -r1.76 linux_misc.c
--- linux_misc.c        22 Apr 2012 05:43:14 -0000      1.76
+++ linux_misc.c        22 May 2012 17:26:55 -0000
@@ -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;
Index: linux_types.h
===================================================================
RCS file: /cvs/src/sys/compat/linux/linux_types.h,v
retrieving revision 1.10
diff -u -p -r1.10 linux_types.h
--- linux_types.h       5 Apr 2011 22:54:31 -0000       1.10
+++ linux_types.h       22 May 2012 17:26:55 -0000
@@ -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;
@@ -64,6 +75,19 @@ struct linux_statfs {
        linux_fsid_t    l_ffsid;
        long            l_fnamelen;
        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];
 };
 
 /*
Index: syscalls.master
===================================================================
RCS file: /cvs/src/sys/compat/linux/syscalls.master,v
retrieving revision 1.66
diff -u -p -r1.66 syscalls.master
--- syscalls.master     14 Dec 2011 08:33:18 -0000      1.66
+++ syscalls.master     22 May 2012 17:26:56 -0000
@@ -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

Reply via email to