linuxolator: proc/filesystems and sysfs function implementations
Divacky Roman
xdivac02 at stud.fit.vutbr.cz
Sun Jan 14 10:52:43 UTC 2007
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,
More information about the freebsd-emulation
mailing list