Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 14 Jan 2007 11:52:39 +0100
From:      Divacky Roman <xdivac02@stud.fit.vutbr.cz>
To:        Scot Hetzel <swhetzel@gmail.com>
Cc:        Alexander Leidinger <Alexander@leidinger.net>, freebsd-emulation@freebsd.org
Subject:   Re: linuxolator: proc/filesystems and sysfs function implementations
Message-ID:  <20070114105239.GA6955@stud.fit.vutbr.cz>
In-Reply-To: <790a9fff0701132017g6c081567la4a759cea4618535@mail.gmail.com>
References:  <790a9fff0701060012x40063f48pc842510b082df5a5@mail.gmail.com> <20070106130830.3c2e6d98@Magellan.Leidinger.net> <790a9fff0701132017g6c081567la4a759cea4618535@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
a few notes..

===================================================================
RCS file: /home/ncvs/src/sys/compat/linux/linux_misc.c,v
retrieving revision 1.205
diff -u -r1.205 linux_misc.c
--- compat/linux/linux_misc.c	7 Jan 2007 19:30:19 -0000	1.205
+++ compat/linux/linux_misc.c	14 Jan 2007 01:56:41 -0000
@@ -1711,3 +1724,83 @@
 
 	return (error);
 }
 
 int
 linux_chroot(struct thread *td, struct linux_chroot_args *args)
 {
 	return (chroot(td, (struct chroot_args *)args));
}
+
+int
+linux_sysfs(struct thread *td, struct linux_sysfs_args *args)
+{
+	int error=0;
+	unsigned int index = 0;
+	size_t len;
+	char *buf;
+	char *name;
+	struct linux_file_system_type fs;
+	struct vfsconf *vfsp;
+
+	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 :)

+			/* is args->arg1 is valid, if not valid return EFAULT */
+			name = (char *) malloc(MFSNAMELEN, M_TEMP, M_WAITOK);
+			error = copyinstr((char *)(uintptr_t)args->arg1, name,
+					  MFSNAMELEN, &len);
+			if (error) {
+				LFREEPATH(name);

use free() here. the LFREEPATH is meant to be used with the LCONVPATH...
macros.

+				return (error);
+ 			}
+
+			error = EINVAL;
+
+			linux_to_bsd_fs(name, &fs);
+			TAILQ_FOREACH(vfsp, &vfsconf, vfc_list)
+				if (strcmp(vfsp->vfc_name, fs.name) == 0) {
+					td->td_retval[0] = index;
+					error = 0;
+					break;
+				} else
+					index++;
+			LFREEPATH(name);
+			break;
+
+		/*
+		 * Translate the file-system type index into a null-terminated
+		 * filesystem identifier string.
+		 */
+		case 2:
+			index = args->arg1;
+			buf = (char *)(uintptr_t)args->arg2;
+
+			TAILQ_FOREACH(vfsp, &vfsconf, vfc_list)
+				if (index-- <= 0)
+					break;
+			if (!vfsp)
+				return EINVAL;

style - return (EINVAL);

+			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

+			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?

+			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?

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

+}
+
+void
+linux_to_bsd_fs(char *name, struct linux_file_system_type *fs)
+{
+
+#define L2F_NAME(lname, fname) \
+	if (strcmp(lname, name) == 0) \
+	   strcpy(fs->name, fname);
+
+	L2F_NAME("ext2", "ext2fs")
+	else L2F_NAME("ext3", "ext2fs")
+	else L2F_NAME("iso9660", "cd9660")
+	else L2F_NAME("msdos", "msdosfs")
+	else L2F_NAME("bsdprocfs", "procfs")
+	else L2F_NAME("proc", "linprocfs")
+	else L2F_NAME("sysfs", "linsysfs")
+	else L2F_NAME("ufs", "ffs")
+	else L2F_NAME("vfat", "msdosfs")
+	else
+		strcpy(fs->name, name);

ditto as for bsd_to_linux_fs

+#undef L2F_NAME
+}
Index: compat/linux/linux_util.h
===================================================================
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

+void	bsd_to_linux_fs(char *name, struct linux_file_system_type *fs);
+void	linux_to_bsd_fs(char *name, struct linux_file_system_type *fs);
+
 #endif /* !_LINUX_UTIL_H_ */
Index: compat/linprocfs/linprocfs.c
===================================================================
RCS file: /home/ncvs/src/sys/compat/linprocfs/linprocfs.c,v
retrieving revision 1.101
diff -u -r1.101 linprocfs.c
--- compat/linprocfs/linprocfs.c	27 Nov 2006 21:10:55 -0000	1.101
+++ compat/linprocfs/linprocfs.c	14 Jan 2007 00:07:28 -0000
@@ -1031,6 +1031,24 @@
 }
 
 /*
+ * Filler function for proc/filesystems
+ */
+static int
+linprocfs_dofilesystems(PFS_FILL_ARGS)
+{
+	struct vfsconf *vfsp;
+	struct linux_file_system_type fs;
+
+	TAILQ_FOREACH(vfsp, &vfsconf, vfc_list) {
+		bsd_to_linux_fs(vfsp->vfc_name, &fs);
+		sbuf_printf(sb, "%s\t%s\n", \
+		    fs.fs_flags ? "" : "nodev", fs.name);
+	}
+
+	return (0);
+}
+
+/*
  * Filler function for proc/cmdline
  */
 static int
@@ -1076,6 +1094,8 @@
 	    NULL, NULL, PFS_RD);
 	pfs_create_file(root, "devices", &linprocfs_dodevices,
 	    NULL, NULL, PFS_RD);
+	pfs_create_file(root, "filesystems", &linprocfs_dofilesystems,
+	    NULL, NULL, PFS_RD);
 	pfs_create_file(root, "loadavg", &linprocfs_doloadavg,
 	    NULL, NULL, PFS_RD);
 	pfs_create_file(root, "meminfo", &linprocfs_domeminfo,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070114105239.GA6955>