linuxolator: proc/filesystems and sysfs function implementations

Scot Hetzel swhetzel at gmail.com
Sun Jan 14 20:54:30 UTC 2007


On 1/14/07, Divacky Roman <xdivac02 at stud.fit.vutbr.cz> wrote:
> a few notes..
>
> +       switch (args->option) {
> +               /*
> +                * Translate the filesystem identifier string into a
> +                * filesystem type index.
> +                */
> +               case 1:
>
> I'd use #define BAH 1. I know linux code uses 1,2,3 but we are not linux :)
>
Ok, I'll change them to GETFSIND, GETFSTYP, and GETNFSTYP, found them
defined in a couple of other online man pages (sgi, HP-UX, ..) for
sysfs.

http://www.docs.hp.com/en/B9106-90009/sysfs.2.html

> +                       if (error) {
> +                               LFREEPATH(name);
>
> use free() here. the LFREEPATH is meant to be used with the LCONVPATH...
> macros.
>
Wasn't sure, if I should use free or LFREEPATH, it's simple enough to change.

> +                       if (!vfsp)
> +                               return EINVAL;
>
> style - return (EINVAL);
>

Missed that one, will make the change.

> +                       buf = (char *)(uintptr_t)args->arg2;
:
> +                       bsd_to_linux_fs(vfsp->vfc_name, &fs);
> +                       len = strlen(fs.name) + 1;
> +                       error = copyout(fs.name, buf, len);
>
> no need to check if it fits in the userspace buffer? also you
> dont check return value
>

According to the linux man page, there isn't a way to check the size
of buf, as we are only passed the value of the pointer in args->arg2.
Should I replace buf with  (char *)(uintptr_t)args->arg2 in the
copyout, since it is only used there.

http://www.die.net/doc/linux/man/man2/sysfs.2.html

I didn't check the return value, as error is going to be set to either
0 or EFAULT by the copyout function.  Since it's the end of the case,
it falls thru to the return statement at the bottom of the function.

> +                       break;
> +
> +               /*
> +                * Return the total number of file system types currently present
> +                * in the kernel.
> +                */
> +               case 3:
> +                       TAILQ_FOREACH(vfsp, &vfsconf, vfc_list)
> +                               index++;
> +                       td->td_retval[0] = index;
>
> does this make sense? shouldnt we return just the number of filesystems
> that we share with linux?
>

There are only 7 filesystems that are freebsd specific (devfs,
fdescfs, mfs, nullfs, portalfs, procfs (bsd), unionfs).  If we exclude
these filesystems, then we would need to ensure that we skip them in
the other two options.

The way that it is currently emulated, is that all freebsd filesystems
(kldloaded filesystems) are available to the linuxolator.

> +                       break;
> +               default:
> +                       error = EINVAL;
> +       }
> +       return (error);
> +}

> Index: compat/linux/linux_util.c
> ===================================================================
> RCS file: /home/ncvs/src/sys/compat/linux/linux_util.c,v
> retrieving revision 1.31
> diff -u -r1.31 linux_util.c
> --- compat/linux/linux_util.c   15 Aug 2006 12:54:29 -0000      1.31
> +++ compat/linux/linux_util.c   14 Jan 2007 02:11:08 -0000
> @@ -224,3 +224,82 @@
>
>        return (EINVAL);
>  }
> +
> +void
> +bsd_to_linux_fs(char *name, struct linux_file_system_type *fs)
> +{
> +#define L_NODEV(fname) \
> +       if (strcmp(fname, name) == 0) \
> +           fs->fs_flags = 0;
> +#define F2L_NAME(fname, lname) \
> +       if (strcmp(fname, name) == 0) \
> +          strcpy(fs->name, lname);
> +
> +       L_NODEV("9p")
> +       else L_NODEV("afs")
> +       else L_NODEV("autofs")
> +       else L_NODEV("cifs")
> +       else L_NODEV("coda")
> +       else L_NODEV("configfs")
> +       else L_NODEV("debugfs")
> +       else L_NODEV("devfs")
> +       else L_NODEV("devpts")
> +       else L_NODEV("fdescfs")
> +       else L_NODEV("fuse")
> +       else L_NODEV("hostfs")
> +       else L_NODEV("hppfs")
> +       else L_NODEV("hugetlbfs")
> +       else L_NODEV("jffs2")
> +       else L_NODEV("mfs")
> +       else L_NODEV("ncpfs")
> +       else L_NODEV("nfs")
> +       else L_NODEV("nfs4")
> +       else L_NODEV("nfsd")
> +       else L_NODEV("nullfs")
> +       else L_NODEV("openpromfs")
> +       else L_NODEV("portalfs")
> +       else L_NODEV("procfs")
> +       else L_NODEV("linprocfs")
> +       else L_NODEV("ramfs")
> +       else L_NODEV("rootfs")
> +       else L_NODEV("smbfs")
> +       else L_NODEV("linsysfs")
> +       else L_NODEV("unionfs")
> +       else
> +               fs->fs_flags = 1;       /* FS_REQUIRES_DEV */
> +
> +       F2L_NAME("ext2fs", "ext2")
> +       else F2L_NAME("cd9660", "iso9660")
> +       else F2L_NAME("msdosfs", "msdos")
> +       else F2L_NAME("procfs", "bsdprocfs")
> +       else F2L_NAME("linprocfs", "proc")
> +       else F2L_NAME("linsysfs", "sysfs")
> +       else F2L_NAME("ffs", "ufs")
> +       else
> +               strcpy(fs->name, name);
> +#undef L_NODEV
> +#undef F2L_NAME
>
> man, this is ugly :) cant you come up with some translation table or something?
>
I had created a table (see attached linux.fs), but wasn't sure how to
parse it, or how to keep it up todate as more filesystems are added.

> also... you strcpy string to another string, are you sure it always fits? how do you
> asure that?
>

name can't be larger than MFSNAMELEN, and sizeof(fs->name) == MFSNAMELEN.

> RCS file: /home/ncvs/src/sys/compat/linux/linux_util.h,v
> retrieving revision 1.28
> diff -u -r1.28 linux_util.h
> --- compat/linux/linux_util.h   27 Jun 2006 18:30:49 -0000      1.28
> +++ compat/linux/linux_util.h   14 Jan 2007 02:08:42 -0000
> @@ -101,4 +101,12 @@
>  char   *linux_get_char_devices(void);
>  void   linux_free_get_char_devices(char *string);
>
> +struct linux_file_system_type {
> +       char    name[16];
> +       int     fs_flags;
> +};
>
> 16? why 16? please comment or something
>
16 is the value of MFSNAMELEN and used by the vfsconf struct to define
the max size of vfc_name.  I kept name (in the linux_file_system_type
struct) the same size, so that we didn't have to worry about the size
when using strcpy.

I also wasn't sure if I should add:

#include <sys/mount.h>

in linux_util.h so that MFSNAMELEN could be used to define the size of
name in the struct (it may also affect other files, that include
linux_util.h).

Scot
-- 
DISCLAIMER:
No electrons were mamed while sending this message. Only slightly bruised.
-------------- next part --------------

l_name		f_name		k_module,	flags			description
"9p",		NULL,		NULL,		NULL,			"Plan 9 Filesystem",
"adfs",		NULL,		NULL,		FS_REQUIRES_DEV,	"",
"affs",		NULL,		NULL,		FS_REQUIRES_DEV,	"Amiga Filesystem",
"afs",		NULL,		NULL,		FS_BINARY_MOUNTDATA,	"AFS Client Filesystem",
"autofs",	NULL,		NULL,		NULL,			"Auto Filesystem",
"befs",		NULL,		NULL,		FS_REQUIRES_DEV,	"BeOS Filesystem (BeFS)",
"bfs",		NULL,		NULL,		FS_REQUIRES_DEV,	"SCO UnixWare BFS Filesystem",
"cifs"		NULL,		NULL,		NULL,			"SNIA CIFS Filesystem",
"coda",		NULL,		NULL,		FS_BINARY_MOUNTDATA,	"",
"configfs"	NULL,		NULL,		NULL,			"Simple RAM Filesystem for user driven kernel subsystem configuration.",
"cramfs",	NULL,		NULL,		FS_REQUIRES_DEV,	"Compressed ROM Filesystem",
"debugfs",	NULL,		NULL,		NULL,			"",
NULL,		"devfs",	"devfs",	NULL,			"FreeBSD Device Filesystem",
"devpts",	NULL,		NULL		NULL,,			"",
"efs",		NULL,		NULL,		FS_REQUIRES_DEV,	"",
"ext2",		"ext2fs",	"ext2fs",	FS_REQUIRES_DEV,	"Second Extended Filesystem",
"ext3",		"ext2fs",	"ext2fs",	FS_REQUIRES_DEV,	"Second Extended Filesystem with Journaling",
NULL,		"fdescfs",	"fdescfs",	NULL,			"FreeBSD File Descriptor Filesystem",
"fuse"		NULL,		NULL,		NULL,			"Filesystem in Userspace",
"hfs",		NULL,		NULL,		FS_REQUIRES_DEV,	"Macintosh Filesystem",
"hfsplus"	NULL,		NULL,		FS_REQUIRES_DEV,	"Extended Macintosh Filesystem",
"hostfs"	NULL,		NULL,		NULL,			"",
"hpfs",		NULL,		NULL,		FS_REQUIRES_DEV,	"",
"hppfs",	NULL,		NULL,		NULL,			"",
"hugetlbfs",	NULL,		NULL,		NULL,			"",
"iso9660",	"cd9660",	"cd9660",	FS_REQUIRES_DEV,	"",
"jffs",		NULL,		NULL,		FS_REQUIRES_DEV,	"Journalling Flash Filesystem",
"jffs2",	NULL,		NULL,		NULL,			"The Journalling Flash Filesystem, v2",
"jfs",		NULL,		NULL,		FS_REQUIRES_DEV,	"The Journaled Filesystem (JFS)",
NULL,		"mfs"		"g_md",		NULL,			"FreeBSD Memory Filesystem",
"minix",	NULL,		NULL,		FS_REQUIRES_DEV,	"",
"msdos",	"msdosfs",	"msdosfs",	FS_REQUIRES_DEV,	"MS-DOS filesystem support",
"ncpfs",	NULL,		NULL,		NULL,			"",
"nfs",		"nfs",		"nfs",		FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,	"",
"nfs4",		"nfs4",		"nfs4",		FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,	"",
"nfsd",		NULL,		NULL,		NULL,			"",
"ntfs"		"ntfs",		"ntfs",		FS_REQUIRES_DEV,	"NTFS 1.2/3.x driver - Copyright (c) 2001-2006 Anton Altaparmakov",
NULL,		"nullfs",	"nullfs"	NULL,			"FreeBSD Null Filesystem",
"ocfs2"		NULL,		NULL,		FS_REQUIRES_DEV,	"OCFS2 1.3.3",
"openpromfs",	NULL,		NULL,		NULL,			"",
NULL,		"portalfs",	"portalfs",	NULL,			"FreeBSD Portal Filesystem",
NULL,		"procfs",	"procfs",	NULL,			"FreeBSD Process Filesystem",
"proc",		"linprocfs",	"linprocfs",	NULL,			"Linux Process Filesystem",
"qnx4",		NULL,		NULL,		FS_REQUIRES_DEV,	"QNX4 file system",
"ramfs",	NULL,		NULL,		NULL,			"Resizable simple RAM Filesystem",
"rootfs",	NULL,		NULL,		NULL,			"",
"reiserfs",	"reiserfs",	"reiserfs",	FS_REQUIRES_DEV,	"ReiserFS Journaled Filesystem",
"romfs"		NULL,		NULL,		FS_REQUIRES_DEV,	"ROMFS Filesystem",
"smbfs",	"smbfs",	"smbfs",	FS_BINARY_MOUNTDATA,	"",
"sysfs",	"linsysfs",	"linsysfs",	NULL,			"Linux System Filesystem",
"sysv",		NULL,		NULL,		FS_REQUIRES_DEV,	"",
"v7",		NULL,		NULL,		FS_REQUIRES_DEV,	"",
"udf"		"udf",		"udf",		FS_REQUIRES_DEV,	"Universal Disk Format Filesystem",
NULL,		"ffs",		"ufs",		FS_REQUIRES_DEV,	"Berkeley Fast Filesystem",
"ufs",		"ufs",		"ufs",		FS_REQUIRES_DEV,	"Berkeley Fast Filesystem",
NULL,		"unionfs",	"unionfs"	NULL,			"FreeBSD Union Filesystem",
"vfat",		"msdosfs",	"msdosfs",	FS_REQUIRES_DEV,	"VFAT Filesystem",
"vxfs",		NULL,		NULL,		FS_REQUIRES_DEV,	"Veritas Filesystem (VxFS) driver",
"xfs",		"xfs",		"xfs",		FS_REQUIRES_DEV,	"SGI XFS",
NULL,		"zfs"		"zfs"		FS_REQUIRES_DEV,	"Solaris Zettabyte File System"


More information about the freebsd-emulation mailing list