Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 16 Sep 2009 09:42:22 -0500
From:      Scot Hetzel <swhetzel@gmail.com>
To:        freebsd-emulation@freebsd.org
Subject:   Fwd: linuxolator: proc/filesystems and sysfs function implementations
Message-ID:  <790a9fff0909160742p1043e643i69febf5a7e88a97e@mail.gmail.com>
In-Reply-To: <790a9fff0701261550n5982c0chea94dbfa208439da@mail.gmail.com>
References:  <790a9fff0701060012x40063f48pc842510b082df5a5@mail.gmail.com> <20070106130830.3c2e6d98@Magellan.Leidinger.net> <790a9fff0701132017g6c081567la4a759cea4618535@mail.gmail.com> <20070114105239.GA6955@stud.fit.vutbr.cz> <790a9fff0701141254s2c92b10ag6b042a019bc283c@mail.gmail.com> <20070115105921.wbv2yrd4bkgokcko@webmail.leidinger.net> <790a9fff0701252321x2c7bea62od928766849e32c68@mail.gmail.com> <790a9fff0701261550n5982c0chea94dbfa208439da@mail.gmail.com>

index | next in thread | previous in thread | raw e-mail

[-- Attachment #1 --]
I see that Alexander Best had added sysfs to the linux-kernel wiki.

Attached is the sysfs implementation that I had created back in 2007,
and was reviewed on this list.

Could someone commit this implentation to P4 or at least put it up
some where so others can improve on it.

Thanks,

Scot

[-- Attachment #2 --]
Index: compat/linprocfs/linprocfs.c
===================================================================
RCS file: /home/ncvs/src/sys/compat/linprocfs/linprocfs.c,v
retrieving revision 1.105
diff -u -r1.105 linprocfs.c
--- compat/linprocfs/linprocfs.c	21 Jan 2007 13:18:52 -0000	1.105
+++ compat/linprocfs/linprocfs.c	26 Jan 2006 01:57:08 -0000
@@ -1041,6 +1133,51 @@
 }
 
 /*
+ * Filler function for proc/filesystems
+ */
+static int
+linprocfs_dofilesystems(PFS_FILL_ARGS)
+{
+	int i, fs_flags;
+	char fs_name[MFSNAMELEN];
+	struct vfsconf *vfsp;
+	static char *linux_nodevfs[] = {
+		/* Filesystems included with FreeBSD */
+		"coda", "devfs", "fdescfs", "mfs", "nfs",
+		"nfs4", "nullfs", "portalfs", "procfs",
+		"linprocfs", "smbfs", "linsysfs", "unionfs",
+
+		/* Filesystems included with Linux */
+		"9p", "afs", "autofs", "cifs", "configfs",
+		"debugfs", "devpts", "fuse", "hostfs",
+		"hppfs", "hugetlbfs", "jffs2", "ncpfs",
+		"nfsd", "openpromfs", "ramfs", "rootfs",
+
+		NULL
+	};
+
+	TAILQ_FOREACH(vfsp, &vfsconf, vfc_list) {
+
+		/* Does the filesystem require a dev entry? */
+		fs_flags = 1;	/* FS_REQUIRES_DEV */
+		for (i = 0; linux_nodevfs[i] != NULL; i++) {
+			if (strcmp(linux_nodevfs[i], vfsp->vfc_name) == 0) {
+			    fs_flags = 0;
+			    break;
+			}
+		}
+
+		strlcpy(fs_name, vfsp->vfc_name, sizeof(fs_name));
+		bsd2linux_fsname(fs_name, sizeof(fs_name));
+
+		sbuf_printf(sb, "%s\t%s\n", \
+		    fs_flags ? "" : "nodev", fs_name);
+	}
+
+	return (0);
+}
+
+/*
  * Filler function for proc/cmdline
  */
 static int
@@ -1086,6 +1223,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,
Index: compat/linux/linux_misc.h
===================================================================
RCS file: /home/ncvs/src/sys/compat/linux/linux_misc.h,v
retrieving revision 1.2
diff -u -r1.2 linux_misc.h
--- compat/linux/linux_misc.h	31 Dec 2006 11:56:16 -0000	1.2
+++ compat/linux/linux_misc.h	26 Jan 2006 02:12:30 -0000
@@ -42,4 +42,9 @@
 
 #define	LINUX_MAX_COMM_LEN	16	/* Maximum length of the process name. */
 
+/* defines for sysfs */
+#define LINUX_GETFSIND		1	/* Translate filesystem name to index */
+#define LINUX_GETFSTYP		2	/* Translate index to filesystem name */
+#define LINUX_GETNFSTYP		3	/* Return total number of filesystems */
+
 #endif	/* _LINUX_MISC_H_ */
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	26 Jan 2006 02:01:34 -0000
@@ -101,4 +103,7 @@
 char	*linux_get_char_devices(void);
 void	linux_free_get_char_devices(char *string);
 
+/* used by sysfs and linprocfs_dofilesystems functions */
+void	bsd2linux_fsname(char *name, int size);
+
 #endif /* !_LINUX_UTIL_H_ */
Index: amd64/linux32/linux32_dummy.c
===================================================================
RCS file: /home/ncvs/src/sys/amd64/linux32/linux32_dummy.c,v
retrieving revision 1.7
diff -u -r1.7 linux32_dummy.c
--- amd64/linux32/linux32_dummy.c	31 Dec 2006 13:16:00 -0000	1.7
+++ amd64/linux32/linux32_dummy.c	16 Jan 2007 02:42:03 -0000
@@ -50,6 +50,5 @@
 DUMMY(get_kernel_syms);
 DUMMY(quotactl);
 DUMMY(bdflush);
-DUMMY(sysfs);
 DUMMY(query_module);
 DUMMY(nfsservctl);
Index: i386/linux/linux_dummy.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/linux/linux_dummy.c,v
retrieving revision 1.45
diff -u -r1.45 linux_dummy.c
--- i386/linux/linux_dummy.c	31 Dec 2006 13:16:00 -0000	1.45
+++ i386/linux/linux_dummy.c	16 Jan 2007 03:02:56 -0000
@@ -52,6 +52,5 @@
 DUMMY(get_kernel_syms);
 DUMMY(quotactl);
 DUMMY(bdflush);
-DUMMY(sysfs);
 DUMMY(vm86);
 DUMMY(query_module);
Index: compat/linux/linux_misc.c
===================================================================
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	26 Jan 2006 04:56:52 -0000
@@ -1716,3 +1729,114 @@
 {
 	return (chroot(td, (struct chroot_args *)args));
 }
+
+/* table used to derive linux filesystem names to/from freebsd filesystem names */
+static struct {const char *l_name; const char *b_name;} l2bfs_tbl[] = {
+	{ "ext2", "ext2fs" },
+	{ "ext3", "ext2fs"},
+	{ "iso9660", "cd9660"},
+	{ "msdos", "msdosfs"},
+	{ "bsdprocfs", "procfs"},
+	{ "proc", "linprocfs"},
+	{ "sysfs", "linsysfs"},
+	{ "ufs", "ffs"},
+	{ "vfat", "msdosfs"},
+	{ NULL, NULL }
+};
+
+/* 
+ * Translate bsd filesystem name to linux filesystem name
+ * used by linprocfs_dofilesystems and sysfs LINUX_GETFSTYP
+ */
+void
+bsd2linux_fsname(char *name, int size)
+{
+	int i;
+
+	for ( i = 0; l2bfs_tbl[i].b_name != NULL; i++) {
+		if (strcmp(l2bfs_tbl[i].b_name, name) == 0) {
+			strlcpy(name, l2bfs_tbl[i].l_name, size);
+			break;
+		}
+	}
+}
+
+int
+linux_sysfs(struct thread *td, struct linux_sysfs_args *args)
+{
+	int i, error=0;
+	unsigned int index = 0;
+	char fs_name[MFSNAMELEN];
+	struct vfsconf *vfsp;
+
+	switch (args->option) {
+		/*
+		 * Translate the filesystem identifier string into a
+		 * filesystem type index.
+		 */
+		case LINUX_GETFSIND:
+			/* Is args->arg1 valid, if not valid return EFAULT */
+			error = copyinstr((void *)(register_t)args->arg1, fs_name,
+					  MFSNAMELEN, NULL);
+			if (error) {
+				return (error);
+ 			}
+
+			for ( i = 0; l2bfs_tbl[i].l_name != NULL; i++) {
+				if (strcmp(l2bfs_tbl[i].l_name, fs_name) == 0) {
+					strlcpy(fs_name, l2bfs_tbl[i].b_name,
+						sizeof(fs_name));
+					break;
+				}
+			}
+
+			TAILQ_FOREACH(vfsp, &vfsconf, vfc_list)
+				if (strcmp(vfsp->vfc_name, fs_name) == 0) {
+					td->td_retval[0] = index;
+					break;
+				} else
+					index++;
+			if (!vfsp)
+				return (EINVAL);
+			break;
+
+		/*
+		 * Translate the file-system type index into a
+		 * null-terminated filesystem identifier string.
+		 */
+		case LINUX_GETFSTYP:
+			index = args->arg1;
+
+			TAILQ_FOREACH(vfsp, &vfsconf, vfc_list)
+				if (index-- <= 0)
+					break;
+			if (!vfsp)
+				return (EINVAL);
+
+			strlcpy(fs_name, vfsp->vfc_name, sizeof(fs_name));
+			bsd2linux_fsname(fs_name);
+
+			/*
+			 * We assume that the buffer pointed to by
+			 * (void *)(register_t)args->arg2 is greater than MFSNAMELEN
+			 */
+			error = copyout(fs_name, (void *)(register_t)args->arg2,
+					MFSNAMELEN);
+			break;
+
+		/*
+		 * Return the total number of file system types
+		 * currently present in the kernel.
+		 */
+		case LINUX_GETNFSTYP:
+			TAILQ_FOREACH(vfsp, &vfsconf, vfc_list)
+				index++;
+			td->td_retval[0] = index;
+			break;
+
+		/* Invalid option passed */
+		default:
+			error = EINVAL;
+	}
+	return (error);
+}
help

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