Whamcloud - gitweb
Branch HEAD
authorrobert.read <robert.read>
Thu, 19 Jun 2008 22:04:35 +0000 (22:04 +0000)
committerrobert.read <robert.read>
Thu, 19 Jun 2008 22:04:35 +0000 (22:04 +0000)
b=15969
i=isaac
i=adilger

Move libcfs to a module.

123 files changed:
libcfs/.cvsignore [new file with mode: 0644]
libcfs/Kernelenv.in [new file with mode: 0644]
libcfs/Kernelenv.mk [new file with mode: 0644]
libcfs/Makefile.in [new file with mode: 0644]
libcfs/autoMakefile.am [new file with mode: 0644]
libcfs/autoconf/.cvsignore [new file with mode: 0644]
libcfs/autoconf/Makefile.am [new file with mode: 0644]
libcfs/autoconf/lustre-libcfs.m4 [new file with mode: 0644]
libcfs/include/Makefile.am [new file with mode: 0644]
libcfs/include/libcfs/.cvsignore [new file with mode: 0644]
libcfs/include/libcfs/Makefile.am [new file with mode: 0644]
libcfs/include/libcfs/bitmap.h [new file with mode: 0644]
libcfs/include/libcfs/curproc.h [new file with mode: 0644]
libcfs/include/libcfs/darwin/.cvsignore [new file with mode: 0644]
libcfs/include/libcfs/darwin/Makefile.am [new file with mode: 0644]
libcfs/include/libcfs/darwin/darwin-fs.h [new file with mode: 0644]
libcfs/include/libcfs/darwin/darwin-lock.h [new file with mode: 0644]
libcfs/include/libcfs/darwin/darwin-mem.h [new file with mode: 0644]
libcfs/include/libcfs/darwin/darwin-prim.h [new file with mode: 0644]
libcfs/include/libcfs/darwin/darwin-sync.h [new file with mode: 0644]
libcfs/include/libcfs/darwin/darwin-tcpip.h [new file with mode: 0644]
libcfs/include/libcfs/darwin/darwin-time.h [new file with mode: 0644]
libcfs/include/libcfs/darwin/darwin-types.h [new file with mode: 0644]
libcfs/include/libcfs/darwin/darwin-utils.h [new file with mode: 0644]
libcfs/include/libcfs/darwin/kp30.h [new file with mode: 0644]
libcfs/include/libcfs/darwin/libcfs.h [new file with mode: 0644]
libcfs/include/libcfs/darwin/lltrace.h [new file with mode: 0644]
libcfs/include/libcfs/darwin/portals_utils.h [new file with mode: 0644]
libcfs/include/libcfs/kp30.h [new file with mode: 0644]
libcfs/include/libcfs/libcfs.h [new file with mode: 0644]
libcfs/include/libcfs/linux/.cvsignore [new file with mode: 0644]
libcfs/include/libcfs/linux/Makefile.am [new file with mode: 0644]
libcfs/include/libcfs/linux/kp30.h [new file with mode: 0644]
libcfs/include/libcfs/linux/libcfs.h [new file with mode: 0644]
libcfs/include/libcfs/linux/linux-fs.h [new file with mode: 0644]
libcfs/include/libcfs/linux/linux-lock.h [new file with mode: 0644]
libcfs/include/libcfs/linux/linux-mem.h [new file with mode: 0644]
libcfs/include/libcfs/linux/linux-prim.h [new file with mode: 0644]
libcfs/include/libcfs/linux/linux-tcpip.h [new file with mode: 0644]
libcfs/include/libcfs/linux/linux-time.h [new file with mode: 0644]
libcfs/include/libcfs/linux/lltrace.h [new file with mode: 0644]
libcfs/include/libcfs/linux/portals_compat25.h [new file with mode: 0644]
libcfs/include/libcfs/linux/portals_utils.h [new file with mode: 0644]
libcfs/include/libcfs/list.h [new file with mode: 0644]
libcfs/include/libcfs/lltrace.h [new file with mode: 0644]
libcfs/include/libcfs/portals_utils.h [new file with mode: 0644]
libcfs/include/libcfs/types.h [new file with mode: 0644]
libcfs/include/libcfs/user-bitops.h [new file with mode: 0644]
libcfs/include/libcfs/user-lock.h [new file with mode: 0644]
libcfs/include/libcfs/user-prim.h [new file with mode: 0644]
libcfs/include/libcfs/user-tcpip.h [new file with mode: 0644]
libcfs/include/libcfs/user-time.h [new file with mode: 0644]
libcfs/include/libcfs/winnt/kp30.h [new file with mode: 0644]
libcfs/include/libcfs/winnt/libcfs.h [new file with mode: 0644]
libcfs/include/libcfs/winnt/lltrace.h [new file with mode: 0644]
libcfs/include/libcfs/winnt/portals_compat25.h [new file with mode: 0644]
libcfs/include/libcfs/winnt/portals_utils.h [new file with mode: 0644]
libcfs/include/libcfs/winnt/winnt-fs.h [new file with mode: 0644]
libcfs/include/libcfs/winnt/winnt-lock.h [new file with mode: 0644]
libcfs/include/libcfs/winnt/winnt-mem.h [new file with mode: 0644]
libcfs/include/libcfs/winnt/winnt-prim.h [new file with mode: 0644]
libcfs/include/libcfs/winnt/winnt-tcpip.h [new file with mode: 0644]
libcfs/include/libcfs/winnt/winnt-time.h [new file with mode: 0644]
libcfs/include/libcfs/winnt/winnt-types.h [new file with mode: 0644]
libcfs/libcfs/.cvsignore [new file with mode: 0644]
libcfs/libcfs/Info.plist [new file with mode: 0644]
libcfs/libcfs/Makefile.in [new file with mode: 0644]
libcfs/libcfs/autoMakefile.am [new file with mode: 0644]
libcfs/libcfs/darwin/.cvsignore [new file with mode: 0644]
libcfs/libcfs/darwin/Makefile.am [new file with mode: 0644]
libcfs/libcfs/darwin/darwin-curproc.c [new file with mode: 0644]
libcfs/libcfs/darwin/darwin-debug.c [new file with mode: 0644]
libcfs/libcfs/darwin/darwin-fs.c [new file with mode: 0644]
libcfs/libcfs/darwin/darwin-internal.h [new file with mode: 0644]
libcfs/libcfs/darwin/darwin-mem.c [new file with mode: 0644]
libcfs/libcfs/darwin/darwin-module.c [new file with mode: 0644]
libcfs/libcfs/darwin/darwin-prim.c [new file with mode: 0644]
libcfs/libcfs/darwin/darwin-proc.c [new file with mode: 0644]
libcfs/libcfs/darwin/darwin-sync.c [new file with mode: 0644]
libcfs/libcfs/darwin/darwin-tcpip.c [new file with mode: 0644]
libcfs/libcfs/darwin/darwin-tracefile.c [new file with mode: 0644]
libcfs/libcfs/darwin/darwin-utils.c [new file with mode: 0644]
libcfs/libcfs/debug.c [new file with mode: 0644]
libcfs/libcfs/libcfs.xcode/project.pbxproj [new file with mode: 0644]
libcfs/libcfs/linux/.cvsignore [new file with mode: 0644]
libcfs/libcfs/linux/Makefile.am [new file with mode: 0644]
libcfs/libcfs/linux/linux-curproc.c [new file with mode: 0644]
libcfs/libcfs/linux/linux-debug.c [new file with mode: 0644]
libcfs/libcfs/linux/linux-fs.c [new file with mode: 0644]
libcfs/libcfs/linux/linux-lock.c [new file with mode: 0644]
libcfs/libcfs/linux/linux-lwt.c [new file with mode: 0644]
libcfs/libcfs/linux/linux-mem.c [new file with mode: 0644]
libcfs/libcfs/linux/linux-module.c [new file with mode: 0644]
libcfs/libcfs/linux/linux-prim.c [new file with mode: 0644]
libcfs/libcfs/linux/linux-proc.c [new file with mode: 0644]
libcfs/libcfs/linux/linux-sync.c [new file with mode: 0644]
libcfs/libcfs/linux/linux-tcpip.c [new file with mode: 0644]
libcfs/libcfs/linux/linux-tracefile.c [new file with mode: 0644]
libcfs/libcfs/linux/linux-utils.c [new file with mode: 0644]
libcfs/libcfs/lwt.c [new file with mode: 0644]
libcfs/libcfs/module.c [new file with mode: 0644]
libcfs/libcfs/nidstrings.c [new file with mode: 0644]
libcfs/libcfs/tracefile.c [new file with mode: 0644]
libcfs/libcfs/tracefile.h [new file with mode: 0644]
libcfs/libcfs/user-bitops.c [new file with mode: 0644]
libcfs/libcfs/user-lock.c [new file with mode: 0644]
libcfs/libcfs/user-prim.c [new file with mode: 0644]
libcfs/libcfs/user-tcpip.c [new file with mode: 0644]
libcfs/libcfs/watchdog.c [new file with mode: 0644]
libcfs/libcfs/winnt/winnt-curproc.c [new file with mode: 0644]
libcfs/libcfs/winnt/winnt-debug.c [new file with mode: 0644]
libcfs/libcfs/winnt/winnt-fs.c [new file with mode: 0644]
libcfs/libcfs/winnt/winnt-lock.c [new file with mode: 0644]
libcfs/libcfs/winnt/winnt-lwt.c [new file with mode: 0644]
libcfs/libcfs/winnt/winnt-mem.c [new file with mode: 0644]
libcfs/libcfs/winnt/winnt-module.c [new file with mode: 0644]
libcfs/libcfs/winnt/winnt-prim.c [new file with mode: 0644]
libcfs/libcfs/winnt/winnt-proc.c [new file with mode: 0644]
libcfs/libcfs/winnt/winnt-sync.c [new file with mode: 0644]
libcfs/libcfs/winnt/winnt-tcpip.c [new file with mode: 0644]
libcfs/libcfs/winnt/winnt-tracefile.c [new file with mode: 0644]
libcfs/libcfs/winnt/winnt-usr.c [new file with mode: 0644]
libcfs/libcfs/winnt/winnt-utils.c [new file with mode: 0644]

diff --git a/libcfs/.cvsignore b/libcfs/.cvsignore
new file mode 100644 (file)
index 0000000..f30d862
--- /dev/null
@@ -0,0 +1,11 @@
+Kernelenv
+Makefile
+autoMakefile
+autoMakefile.in
+aclocal.m4
+autom4te.cache
+config.log
+config.status
+configure
+.*.cmd
+.depend
diff --git a/libcfs/Kernelenv.in b/libcfs/Kernelenv.in
new file mode 100644 (file)
index 0000000..59eda30
--- /dev/null
@@ -0,0 +1,6 @@
+EXTRA_CFLAGS := -Ifs/lustre/include -Ifs/lustre/lnet/include
+# lnet/utils/debug.c wants <linux/version.h> from userspace.  sigh.
+HOSTCFLAGS := -I@LINUX@/include $(EXTRA_CFLAGS)
+LIBREADLINE := @LIBREADLINE@
+# 2.5's makefiles aren't nice to cross dir libraries in host programs
+PTLCTLOBJS := debug.o l_ioctl.o parser.o portals.o
diff --git a/libcfs/Kernelenv.mk b/libcfs/Kernelenv.mk
new file mode 100644 (file)
index 0000000..d973e5d
--- /dev/null
@@ -0,0 +1,4 @@
+EXTRA_CFLAGS := -Ifs/lustre/include -Ifs/lustre/lnet/include
+HOSTCFLAGS := $(EXTRA_CFLAGS)
+# the kernel doesn't want us to build archives for host binaries :/
+PTLCTLOBJS := debug.o l_ioctl.o parser.o portals.o
diff --git a/libcfs/Makefile.in b/libcfs/Makefile.in
new file mode 100644 (file)
index 0000000..8c58d42
--- /dev/null
@@ -0,0 +1,3 @@
+subdir-m += libcfs
+
+@INCLUDE_RULES@
diff --git a/libcfs/autoMakefile.am b/libcfs/autoMakefile.am
new file mode 100644 (file)
index 0000000..ef90449
--- /dev/null
@@ -0,0 +1,9 @@
+# Copyright (C) 2001  Cluster File Systems, Inc.
+#
+# This code is issued under the GNU General Public License.
+# See the file COPYING in this distribution
+
+SUBDIRS = libcfs include autoconf
+
+sources:
+       $(MAKE) sources -C libcfs
diff --git a/libcfs/autoconf/.cvsignore b/libcfs/autoconf/.cvsignore
new file mode 100644 (file)
index 0000000..282522d
--- /dev/null
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/libcfs/autoconf/Makefile.am b/libcfs/autoconf/Makefile.am
new file mode 100644 (file)
index 0000000..3927b04
--- /dev/null
@@ -0,0 +1 @@
+EXTRA_DIST := lustre-libcfs.m4
diff --git a/libcfs/autoconf/lustre-libcfs.m4 b/libcfs/autoconf/lustre-libcfs.m4
new file mode 100644 (file)
index 0000000..86fe0e6
--- /dev/null
@@ -0,0 +1,517 @@
+#
+# LIBCFS_CONFIG_CDEBUG
+#
+# whether to enable various libcfs debugs (CDEBUG, ENTRY/EXIT, LASSERT, etc.)
+#
+AC_DEFUN([LIBCFS_CONFIG_CDEBUG],
+[
+AC_MSG_CHECKING([whether to enable CDEBUG, CWARN])
+AC_ARG_ENABLE([libcfs_cdebug],
+       AC_HELP_STRING([--disable-libcfs-cdebug],
+                       [disable libcfs CDEBUG, CWARN]),
+       [],[enable_libcfs_cdebug='yes'])
+AC_MSG_RESULT([$enable_libcfs_cdebug])
+if test x$enable_libcfs_cdebug = xyes; then
+   AC_DEFINE(CDEBUG_ENABLED, 1, [enable libcfs CDEBUG, CWARN])
+else
+   AC_DEFINE(CDEBUG_ENABLED, 0, [disable libcfs CDEBUG, CWARN])
+fi
+
+AC_MSG_CHECKING([whether to enable ENTRY/EXIT])
+AC_ARG_ENABLE([libcfs_trace],
+       AC_HELP_STRING([--disable-libcfs-trace],
+                       [disable libcfs ENTRY/EXIT]),
+       [],[enable_libcfs_trace='yes'])
+AC_MSG_RESULT([$enable_libcfs_trace])
+if test x$enable_libcfs_trace = xyes; then
+   AC_DEFINE(CDEBUG_ENTRY_EXIT, 1, [enable libcfs ENTRY/EXIT])
+else
+   AC_DEFINE(CDEBUG_ENTRY_EXIT, 0, [disable libcfs ENTRY/EXIT])
+fi
+
+AC_MSG_CHECKING([whether to enable LASSERT, LASSERTF])
+AC_ARG_ENABLE([libcfs_assert],
+       AC_HELP_STRING([--disable-libcfs-assert],
+                       [disable libcfs LASSERT, LASSERTF]),
+       [],[enable_libcfs_assert='yes'])
+AC_MSG_RESULT([$enable_libcfs_assert])
+if test x$enable_libcfs_assert = xyes; then
+   AC_DEFINE(LIBCFS_DEBUG, 1, [enable libcfs LASSERT, LASSERTF])
+fi
+])
+
+#
+# LIBCFS_CONFIG_PANIC_DUMPLOG
+#
+# check if tunable panic_dumplog is wanted
+#
+AC_DEFUN([LIBCFS_CONFIG_PANIC_DUMPLOG],
+[AC_MSG_CHECKING([for tunable panic_dumplog support])
+AC_ARG_ENABLE([panic_dumplog],
+       AC_HELP_STRING([--enable-panic_dumplog],
+                      [enable panic_dumplog]),
+       [],[enable_panic_dumplog='no'])
+if test x$enable_panic_dumplog = xyes ; then
+       AC_DEFINE(LNET_DUMP_ON_PANIC, 1, [use dumplog on panic])
+       AC_MSG_RESULT([yes (by request)])
+else
+       AC_MSG_RESULT([no])
+fi
+])
+
+#
+# LIBCFS_STRUCT_PAGE_LIST
+#
+# 2.6.4 no longer has page->list
+#
+AC_DEFUN([LIBCFS_STRUCT_PAGE_LIST],
+[AC_MSG_CHECKING([if struct page has a list field])
+LB_LINUX_TRY_COMPILE([
+       #include <linux/mm.h>
+],[
+       struct page page;
+       &page.list;
+],[
+       AC_MSG_RESULT([yes])
+       AC_DEFINE(HAVE_PAGE_LIST, 1, [struct page has a list field])
+],[
+       AC_MSG_RESULT([no])
+])
+])
+
+#
+# LIBCFS_STRUCT_SIGHAND
+#
+# red hat 2.4 adds sighand to struct task_struct
+#
+AC_DEFUN([LIBCFS_STRUCT_SIGHAND],
+[AC_MSG_CHECKING([if task_struct has a sighand field])
+LB_LINUX_TRY_COMPILE([
+       #include <linux/sched.h>
+],[
+       struct task_struct p;
+       p.sighand = NULL;
+],[
+       AC_DEFINE(CONFIG_RH_2_4_20, 1, [this kernel contains Red Hat 2.4.20 patches])
+       AC_MSG_RESULT([yes])
+],[
+       AC_MSG_RESULT([no])
+])
+])
+
+#
+# LIBCFS_FUNC_CPU_ONLINE
+#
+# cpu_online is different in rh 2.4, vanilla 2.4, and 2.6
+#
+AC_DEFUN([LIBCFS_FUNC_CPU_ONLINE],
+[AC_MSG_CHECKING([if kernel defines cpu_online()])
+LB_LINUX_TRY_COMPILE([
+       #include <linux/sched.h>
+],[
+       cpu_online(0);
+],[
+       AC_MSG_RESULT([yes])
+       AC_DEFINE(HAVE_CPU_ONLINE, 1, [cpu_online found])
+],[
+       AC_MSG_RESULT([no])
+])
+])
+
+#
+# LIBCFS_TYPE_GFP_T
+#
+# check if gfp_t is typedef-ed
+#
+AC_DEFUN([LIBCFS_TYPE_GFP_T],
+[AC_MSG_CHECKING([if kernel defines gfp_t])
+LB_LINUX_TRY_COMPILE([
+        #include <linux/gfp.h>
+],[
+       return sizeof(gfp_t);
+],[
+       AC_MSG_RESULT([yes])
+       AC_DEFINE(HAVE_GFP_T, 1, [gfp_t found])
+],[
+       AC_MSG_RESULT([no])
+])
+])
+
+#
+# LIBCFS_TYPE_CPUMASK_T
+#
+# same goes for cpumask_t
+#
+AC_DEFUN([LIBCFS_TYPE_CPUMASK_T],
+[AC_MSG_CHECKING([if kernel defines cpumask_t])
+LB_LINUX_TRY_COMPILE([
+       #include <linux/sched.h>
+],[
+       return sizeof (cpumask_t);
+],[
+       AC_MSG_RESULT([yes])
+       AC_DEFINE(HAVE_CPUMASK_T, 1, [cpumask_t found])
+],[
+       AC_MSG_RESULT([no])
+])
+])
+
+#
+# LIBCFS_FUNC_SHOW_TASK
+#
+# we export show_task(), but not all kernels have it (yet)
+#
+AC_DEFUN([LIBCFS_FUNC_SHOW_TASK],
+[LB_CHECK_SYMBOL_EXPORT([show_task],
+[kernel/ksyms.c kernel/sched.c],[
+AC_DEFINE(HAVE_SHOW_TASK, 1, [show_task is exported])
+],[
+])
+])
+
+# check userland __u64 type
+AC_DEFUN([LIBCFS_U64_LONG_LONG],
+[AC_MSG_CHECKING([u64 is long long type])
+tmp_flags="$CFLAGS"
+CFLAGS="$CFLAGS -Werror"
+AC_COMPILE_IFELSE([
+       #include <linux/types.h>
+       int main(void) {
+               unsigned long long *data1;
+               __u64 *data2;
+               
+               data1 = data2;
+               return 0;
+       }
+],[
+       AC_MSG_RESULT([yes])
+        AC_DEFINE(HAVE_U64_LONG_LONG, 1,
+                  [__u64 is long long type])
+],[
+       AC_MSG_RESULT([no])
+])
+CFLAGS="$tmp_flags"
+])
+
+# check userland size_t type
+AC_DEFUN([LIBCFS_SIZE_T_LONG],
+[AC_MSG_CHECKING([size_t is unsigned long type])
+tmp_flags="$CFLAGS"
+CFLAGS="$CFLAGS -Werror"
+AC_COMPILE_IFELSE([
+       #include <linux/types.h>
+       int main(void) {
+               unsigned long *data1;
+               size_t *data2;
+               
+               data1 = data2;
+               return 0;
+       }
+],[
+       AC_MSG_RESULT([yes])
+        AC_DEFINE(HAVE_SIZE_T_LONG, 1,
+                  [size_t is long type])
+],[
+       AC_MSG_RESULT([no])
+])
+CFLAGS="$tmp_flags"
+])
+
+AC_DEFUN([LIBCFS_SSIZE_T_LONG],
+[AC_MSG_CHECKING([ssize_t is signed long type])
+tmp_flags="$CFLAGS"
+CFLAGS="$CFLAGS -Werror"
+AC_COMPILE_IFELSE([
+       #include <linux/types.h>
+       int main(void) {
+               long *data1;
+               ssize_t *data2;
+               
+               data1 = data2;
+               return 0;
+       }
+],[
+       AC_MSG_RESULT([yes])
+        AC_DEFINE(HAVE_SSIZE_T_LONG, 1,
+                  [ssize_t is long type])
+],[
+       AC_MSG_RESULT([no])
+])
+CFLAGS="$tmp_flags"
+])
+
+
+# LIBCFS_TASKLIST_LOCK
+# 2.6.18 remove tasklist_lock export
+AC_DEFUN([LIBCFS_TASKLIST_LOCK],
+[LB_CHECK_SYMBOL_EXPORT([tasklist_lock],
+[kernel/fork.c],[
+AC_DEFINE(HAVE_TASKLIST_LOCK, 1,
+         [tasklist_lock exported])
+],[
+])
+])
+
+# 2.6.19 API changes
+# kmem_cache_destroy(cachep) return void instead of
+# int
+AC_DEFUN([LIBCFS_KMEM_CACHE_DESTROY_INT],
+[AC_MSG_CHECKING([kmem_cache_destroy(cachep) return int])
+LB_LINUX_TRY_COMPILE([
+        #include <linux/slab.h>
+],[
+       int i = kmem_cache_destroy(NULL);
+],[
+        AC_MSG_RESULT(yes)
+        AC_DEFINE(HAVE_KMEM_CACHE_DESTROY_INT, 1,
+                [kmem_cache_destroy(cachep) return int])
+],[
+        AC_MSG_RESULT(NO)
+])
+])
+
+# 2.6.19 API change
+#panic_notifier_list use atomic_notifier operations
+#
+AC_DEFUN([LIBCFS_ATOMIC_PANIC_NOTIFIER],
+[AC_MSG_CHECKING([panic_notifier_list is atomic])
+LB_LINUX_TRY_COMPILE([
+       #include <linux/notifier.h>
+       #include <linux/kernel.h>
+],[
+       struct atomic_notifier_head panic_notifier_list;
+],[
+        AC_MSG_RESULT(yes)
+       AC_DEFINE(HAVE_ATOMIC_PANIC_NOTIFIER, 1,
+               [panic_notifier_list is atomic_notifier_head])
+],[
+        AC_MSG_RESULT(NO)
+])
+])
+
+# 2.6.20 API change INIT_WORK use 2 args and not
+# store data inside
+AC_DEFUN([LIBCFS_3ARGS_INIT_WORK],
+[AC_MSG_CHECKING([check INIT_WORK want 3 args])
+LB_LINUX_TRY_COMPILE([
+       #include <linux/workqueue.h>
+],[
+       struct work_struct work;
+
+       INIT_WORK(&work, NULL, NULL);
+],[
+        AC_MSG_RESULT(yes)
+        AC_DEFINE(HAVE_3ARGS_INIT_WORK, 1,
+                  [INIT_WORK use 3 args and store data inside])
+],[
+        AC_MSG_RESULT(NO)
+])
+])
+
+# 2.6.21 api change. 'register_sysctl_table' use only one argument,
+# instead of more old which need two.
+AC_DEFUN([LIBCFS_2ARGS_REGISTER_SYSCTL],
+[AC_MSG_CHECKING([check register_sysctl_table want 2 args])
+LB_LINUX_TRY_COMPILE([
+        #include <linux/sysctl.h>
+],[
+       return register_sysctl_table(NULL,0);
+],[
+        AC_MSG_RESULT(yes)
+        AC_DEFINE(HAVE_2ARGS_REGISTER_SYSCTL, 1,
+                  [register_sysctl_table want 2 args])
+],[
+        AC_MSG_RESULT(NO)
+])
+])
+
+# 2.6.21 marks kmem_cache_t deprecated and uses struct kmem_cache
+# instead
+AC_DEFUN([LIBCFS_KMEM_CACHE],
+[AC_MSG_CHECKING([check kernel has struct kmem_cache])
+tmp_flags="$EXTRA_KCFLAGS"
+EXTRA_KCFLAGS="-Werror"
+LB_LINUX_TRY_COMPILE([
+        #include <linux/slab.h>
+        typedef struct kmem_cache cache_t;
+],[
+       cache_t *cachep = NULL;
+
+       kmem_cache_alloc(cachep, 0);
+],[
+        AC_MSG_RESULT(yes)
+        AC_DEFINE(HAVE_KMEM_CACHE, 1,
+                  [kernel has struct kmem_cache])
+],[
+        AC_MSG_RESULT(NO)
+])
+EXTRA_KCFLAGS="$tmp_flags"
+])
+# 2.6.23 lost dtor argument
+AC_DEFUN([LIBCFS_KMEM_CACHE_CREATE_DTOR],
+[AC_MSG_CHECKING([check kmem_cache_create has dtor argument])
+LB_LINUX_TRY_COMPILE([
+        #include <linux/slab.h>
+],[
+       kmem_cache_create(NULL, 0, 0, 0, NULL, NULL);
+],[
+        AC_MSG_RESULT(yes)
+        AC_DEFINE(HAVE_KMEM_CACHE_CREATE_DTOR, 1,
+                  [kmem_cache_create has dtor argument])
+],[
+        AC_MSG_RESULT(NO)
+])
+])
+
+#
+# LIBCFS_PROG_LINUX
+#
+# LNet linux kernel checks
+#
+AC_DEFUN([LIBCFS_PROG_LINUX],
+[
+LIBCFS_FUNC_CPU_ONLINE
+LIBCFS_TYPE_GFP_T
+LIBCFS_TYPE_CPUMASK_T
+LIBCFS_CONFIG_PANIC_DUMPLOG
+
+LIBCFS_STRUCT_PAGE_LIST
+LIBCFS_STRUCT_SIGHAND
+LIBCFS_FUNC_SHOW_TASK
+LIBCFS_U64_LONG_LONG
+LIBCFS_SSIZE_T_LONG
+LIBCFS_SIZE_T_LONG
+# 2.6.18
+LIBCFS_TASKLIST_LOCK
+# 2.6.19
+LIBCFS_KMEM_CACHE_DESTROY_INT
+LIBCFS_ATOMIC_PANIC_NOTIFIER
+# 2.6.20
+LIBCFS_3ARGS_INIT_WORK
+# 2.6.21
+LIBCFS_2ARGS_REGISTER_SYSCTL
+LIBCFS_KMEM_CACHE
+# 2.6.23
+LIBCFS_KMEM_CACHE_CREATE_DTOR
+])
+
+#
+# LIBCFS_PROG_DARWIN
+#
+# Darwin checks
+#
+AC_DEFUN([LIBCFS_PROG_DARWIN],
+[LB_DARWIN_CHECK_FUNCS([get_preemption_level])
+])
+
+#
+# LIBCFS_PATH_DEFAULTS
+#
+# default paths for installed files
+#
+AC_DEFUN([LIBCFS_PATH_DEFAULTS],
+[
+])
+
+#
+# LIBCFS_CONFIGURE
+#
+# other configure checks
+#
+AC_DEFUN([LIBCFS_CONFIGURE],
+[# lnet/utils/portals.c
+AC_CHECK_HEADERS([asm/types.h endian.h sys/ioctl.h])
+
+# lnet/utils/debug.c
+AC_CHECK_HEADERS([linux/version.h])
+
+AC_CHECK_TYPE([spinlock_t],
+       [AC_DEFINE(HAVE_SPINLOCK_T, 1, [spinlock_t is defined])],
+       [],
+       [#include <linux/spinlock.h>])
+
+# lnet/utils/wirecheck.c
+AC_CHECK_FUNCS([strnlen])
+
+# --------  Check for required packages  --------------
+
+
+AC_MSG_CHECKING([if efence debugging support is requested])
+AC_ARG_ENABLE(efence,
+       AC_HELP_STRING([--enable-efence],
+                       [use efence library]),
+       [],[enable_efence='no'])
+AC_MSG_RESULT([$enable_efence])
+if test "$enable_efence" = "yes" ; then
+       LIBEFENCE="-lefence"
+       AC_DEFINE(HAVE_LIBEFENCE, 1, [libefence support is requested])
+else
+       LIBEFENCE=""
+fi
+AC_SUBST(LIBEFENCE)
+
+
+# -------- check for -lpthread support ----
+AC_MSG_CHECKING([whether to use libpthread for libcfs library])
+AC_ARG_ENABLE([libpthread],
+               AC_HELP_STRING([--disable-libpthread],
+                       [disable libpthread]),
+               [],[enable_libpthread=yes])
+if test "$enable_libpthread" = "yes" ; then
+       AC_CHECK_LIB([pthread], [pthread_create],
+               [ENABLE_LIBPTHREAD="yes"],
+               [ENABLE_LIBPTHREAD="no"])
+       if test "$ENABLE_LIBPTHREAD" = "yes" ; then
+               AC_MSG_RESULT([$ENABLE_LIBPTHREAD])
+               PTHREAD_LIBS="-lpthread"
+               AC_DEFINE([HAVE_LIBPTHREAD], 1, [use libpthread])
+       else
+               PTHREAD_LIBS=""
+               AC_MSG_RESULT([no libpthread is found])
+       fi
+       AC_SUBST(PTHREAD_LIBS)
+else
+       AC_MSG_RESULT([no (disabled explicitly)])
+       ENABLE_LIBPTHREAD="no"
+fi
+AC_SUBST(ENABLE_LIBPTHREAD)
+
+
+])
+
+#
+# LIBCFS_CONDITIONALS
+#
+# AM_CONDITOINAL defines for lnet
+#
+AC_DEFUN([LIBCFS_CONDITIONALS],
+[
+])
+
+#
+# LIBCFS_CONFIG_FILES
+#
+# files that should be generated with AC_OUTPUT
+#
+AC_DEFUN([LIBCFS_CONFIG_FILES],
+[AC_CONFIG_FILES([
+libcfs/Kernelenv
+libcfs/Makefile
+libcfs/autoMakefile
+libcfs/autoconf/Makefile
+libcfs/include/Makefile
+libcfs/include/libcfs/Makefile
+libcfs/include/libcfs/linux/Makefile
+libcfs/libcfs/Makefile
+libcfs/libcfs/autoMakefile
+libcfs/libcfs/linux/Makefile
+])
+case $lb_target_os in
+       darwin)
+               AC_CONFIG_FILES([
+libcfs/include/libcfs/darwin/Makefile
+libcfs/libcfs/darwin/Makefile
+])
+               ;;
+esac
+])
diff --git a/libcfs/include/Makefile.am b/libcfs/include/Makefile.am
new file mode 100644 (file)
index 0000000..8289f5f
--- /dev/null
@@ -0,0 +1 @@
+SUBDIRS = libcfs 
diff --git a/libcfs/include/libcfs/.cvsignore b/libcfs/include/libcfs/.cvsignore
new file mode 100644 (file)
index 0000000..3dda729
--- /dev/null
@@ -0,0 +1,2 @@
+Makefile.in
+Makefile
diff --git a/libcfs/include/libcfs/Makefile.am b/libcfs/include/libcfs/Makefile.am
new file mode 100644 (file)
index 0000000..472d0ae
--- /dev/null
@@ -0,0 +1,9 @@
+SUBDIRS := linux
+if DARWIN
+SUBDIRS += darwin
+endif
+DIST_SUBDIRS := $(SUBDIRS)
+
+EXTRA_DIST := curproc.h kp30.h libcfs.h list.h lltrace.h \
+       portals_utils.h types.h user-lock.h user-prim.h user-time.h \
+       user-tcpip.h user-bitops.h bitmap.h
diff --git a/libcfs/include/libcfs/bitmap.h b/libcfs/include/libcfs/bitmap.h
new file mode 100644 (file)
index 0000000..7f6189a
--- /dev/null
@@ -0,0 +1,80 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2007 Cluster File Systems, Inc.
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef _LIBCFS_BITMAP_H_
+#define _LIBCFS_BITMAP_H_
+
+
+typedef struct {
+        int             size;
+        unsigned long   data[0];
+} bitmap_t;
+
+#define CFS_BITMAP_SIZE(nbits) \
+     (((nbits/BITS_PER_LONG)+1)*sizeof(long)+sizeof(bitmap_t))
+
+static inline
+bitmap_t *ALLOCATE_BITMAP(int size)
+{
+        bitmap_t *ptr;
+
+        OBD_ALLOC(ptr, CFS_BITMAP_SIZE(size));
+        if (ptr == NULL)
+                RETURN(ptr);
+
+        ptr->size = size;
+
+        RETURN (ptr);
+}
+
+#define FREE_BITMAP(ptr)        OBD_FREE(ptr, CFS_BITMAP_SIZE(ptr->size))
+
+static inline
+void cfs_bitmap_set(bitmap_t *bitmap, int nbit)
+{
+       set_bit(nbit, bitmap->data);
+}
+
+static inline
+void cfs_bitmap_clear(bitmap_t *bitmap, int nbit)
+{
+        clear_bit(nbit, bitmap->data);
+}
+
+static inline
+int cfs_bitmap_check(bitmap_t *bitmap, int nbit)
+{
+       return test_bit(nbit, bitmap->data);
+}
+
+/* return 0 is bitmap has none set bits */
+static inline
+int cfs_bitmap_check_empty(bitmap_t *bitmap)
+{
+        return find_first_bit(bitmap->data, bitmap->size) == bitmap->size;
+}
+
+#define cfs_foreach_bit(bitmap, pos) \
+       for((pos)=find_first_bit((bitmap)->data, bitmap->size);   \
+            (pos) < (bitmap)->size;                               \
+            (pos) = find_next_bit((bitmap)->data, (bitmap)->size, (pos)))
+
+#endif
diff --git a/libcfs/include/libcfs/curproc.h b/libcfs/include/libcfs/curproc.h
new file mode 100644 (file)
index 0000000..6495c66
--- /dev/null
@@ -0,0 +1,64 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Lustre curproc API declaration
+ *
+ * Copyright (C) 2004 Cluster File Systems, Inc.
+ * Author: Nikita Danilov <nikita@clusterfs.com>
+ *
+ * This file is part of Lustre, http://www.lustre.org.
+ *
+ * Lustre is free software; you can redistribute it and/or modify it under the
+ * terms of version 2 of the GNU General Public License as published by the
+ * Free Software Foundation. Lustre is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+ * Public License for more details. You should have received a copy of the GNU
+ * General Public License along with Lustre; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __LIBCFS_CURPROC_H__
+#define __LIBCFS_CURPROC_H__
+
+#ifdef __KERNEL__
+/*
+ * Portable API to access common characteristics of "current" UNIX process.
+ *
+ * Implemented in portals/include/libcfs/<os>/
+ */
+uid_t  cfs_curproc_uid(void);
+gid_t  cfs_curproc_gid(void);
+uid_t  cfs_curproc_fsuid(void);
+gid_t  cfs_curproc_fsgid(void);
+pid_t  cfs_curproc_pid(void);
+int    cfs_curproc_groups_nr(void);
+int    cfs_curproc_is_in_groups(gid_t group);
+void   cfs_curproc_groups_dump(gid_t *array, int size);
+mode_t cfs_curproc_umask(void);
+char  *cfs_curproc_comm(void);
+
+
+/*
+ * Plus, platform-specific constant
+ *
+ * CFS_CURPROC_COMM_MAX,
+ *
+ * and opaque scalar type
+ *
+ * cfs_kernel_cap_t
+ */
+cfs_kernel_cap_t cfs_curproc_cap_get(void);
+void cfs_curproc_cap_set(cfs_kernel_cap_t cap);
+#endif
+
+/* __LIBCFS_CURPROC_H__ */
+#endif
+/*
+ * Local variables:
+ * c-indentation-style: "K&R"
+ * c-basic-offset: 8
+ * tab-width: 8
+ * fill-column: 80
+ * scroll-step: 1
+ * End:
+ */
diff --git a/libcfs/include/libcfs/darwin/.cvsignore b/libcfs/include/libcfs/darwin/.cvsignore
new file mode 100644 (file)
index 0000000..3dda729
--- /dev/null
@@ -0,0 +1,2 @@
+Makefile.in
+Makefile
diff --git a/libcfs/include/libcfs/darwin/Makefile.am b/libcfs/include/libcfs/darwin/Makefile.am
new file mode 100644 (file)
index 0000000..f2f217a
--- /dev/null
@@ -0,0 +1,3 @@
+EXTRA_DIST := darwin-mem.h darwin-types.h libcfs.h portals_utils.h     \
+       darwin-fs.h darwin-prim.h darwin-utils.h lltrace.h              \
+       darwin-lock.h darwin-sync.h darwin-tcpip.h kp30.h
diff --git a/libcfs/include/libcfs/darwin/darwin-fs.h b/libcfs/include/libcfs/darwin/darwin-fs.h
new file mode 100644 (file)
index 0000000..da613ba
--- /dev/null
@@ -0,0 +1,193 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Implementation of standard file system interfaces for XNU kernel.
+ *
+ *  Copyright (c) 2004 Cluster File Systems, Inc.
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or modify it under
+ *   the terms of version 2 of the GNU General Public License as published by
+ *   the Free Software Foundation. Lustre is distributed in the hope that it
+ *   will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details. You should have received a
+ *   copy of the GNU General Public License along with Lustre; if not, write
+ *   to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ *   USA.
+ */
+#ifndef __LIBCFS_DARWIN_FS_H__
+#define __LIBCFS_DARWIN_FS_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+#ifdef __KERNEL__
+
+#include <sys/types.h>
+#include <sys/systm.h>
+
+#include <sys/kernel.h>
+#include <sys/file.h>
+#include <sys/time.h>
+#include <sys/filedesc.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/ubc.h>
+#include <sys/mbuf.h>
+#include <sys/namei.h>
+#include <sys/fcntl.h>
+#include <sys/lockf.h>
+#include <stdarg.h>
+
+#include <mach/mach_types.h>
+#include <mach/time_value.h>
+#include <kern/clock.h>
+#include <sys/param.h>
+#include <IOKit/system.h>
+
+#include <libcfs/darwin/darwin-types.h>
+#include <libcfs/darwin/darwin-lock.h>
+#include <libcfs/darwin/darwin-mem.h>
+#include <libcfs/list.h>
+
+/*
+ * File operating APIs in kernel
+ */
+#ifdef __DARWIN8__
+/*
+ * Kernel file descriptor
+ */
+typedef struct cfs_kern_file {
+        int             f_flags;
+        vnode_t         f_vp;
+        vfs_context_t   f_ctxt;
+} cfs_file_t;
+
+#else
+
+typedef struct file cfs_file_t;
+
+#endif
+
+int    kern_file_size(cfs_file_t *fp, off_t    *size);
+#define cfs_filp_size(fp)                      \
+       ({                                      \
+               off_t           __size;         \
+               kern_file_size((fp), &__size);  \
+               __size;                         \
+        })
+#define cfs_filp_poff(fp)               (NULL)
+
+cfs_file_t *kern_file_open(const char *name, int flags, int mode, int *err);
+int kern_file_close(cfs_file_t *fp);
+int kern_file_read(cfs_file_t *fp, void *buf, size_t nbytes, off_t *pos);
+int kern_file_write(cfs_file_t *fp, void *buf, size_t nbytes, off_t *pos);
+int kern_file_sync(cfs_file_t *fp);
+
+#define cfs_filp_open(n, f, m, e)      kern_file_open(n, f, m, e)
+#define cfs_filp_close(f)              kern_file_close(f)
+#define cfs_filp_read(f, b, n, p)      kern_file_read(f, b, n, p)
+#define cfs_filp_write(f, b, n, p)     kern_file_write(f, b, n, p)
+#define cfs_filp_fsync(f)              kern_file_sync(f)
+
+int ref_file(cfs_file_t *fp);
+int rele_file(cfs_file_t *fp);
+int file_count(cfs_file_t *fp);
+#define cfs_get_file(f)                        ref_file(f)
+#define cfs_put_file(f)                        rele_file(f)
+#define cfs_file_count(f)              file_count(f)
+
+#define CFS_INT_LIMIT(x)               (~((x)1 << (sizeof(x)*8 - 1)))
+#define CFS_OFFSET_MAX                 CFS_INT_LIMIT(loff_t)
+
+typedef struct flock                   cfs_flock_t;
+#define cfs_flock_type(fl)             ((fl)->l_type)
+#define cfs_flock_set_type(fl, type)   do { (fl)->l_type = (type); } while(0)
+#define cfs_flock_pid(fl)              ((fl)->l_pid)
+#define cfs_flock_set_pid(fl, pid)     do { (fl)->l_pid = (pid); } while(0)
+#define cfs_flock_start(fl)            ((fl)->l_start)
+#define cfs_flock_set_start(fl, start) do { (fl)->l_start = (start); } while(0)
+
+static inline loff_t cfs_flock_end(cfs_flock_t *fl)
+{
+        return (fl->l_len == 0 ? CFS_OFFSET_MAX: (fl->l_start + fl->l_len));
+}
+
+static inline void cfs_flock_set_end(cfs_flock_t *fl, loff_t end)
+{
+        if (end == CFS_OFFSET_MAX)
+                fl->l_len = 0;
+        else
+                fl->l_len = end - fl->l_start;
+}
+
+#define ATTR_MODE       0x0001
+#define ATTR_UID        0x0002
+#define ATTR_GID        0x0004
+#define ATTR_SIZE       0x0008
+#define ATTR_ATIME      0x0010
+#define ATTR_MTIME      0x0020
+#define ATTR_CTIME      0x0040
+#define ATTR_ATIME_SET  0x0080
+#define ATTR_MTIME_SET  0x0100
+#define ATTR_FORCE      0x0200  /* Not a change, but a change it */
+#define ATTR_ATTR_FLAG  0x0400
+#define ATTR_RAW        0x0800  /* file system, not vfs will massage attrs */
+#define ATTR_FROM_OPEN  0x1000  /* called from open path, ie O_TRUNC */
+#define ATTR_CTIME_SET  0x2000
+#define ATTR_BLOCKS     0x4000
+#define ATTR_KILL_SUID  0
+#define ATTR_KILL_SGID  0
+
+#define in_group_p(x)  (0)
+
+struct posix_acl_entry {
+        short                   e_tag;
+        unsigned short          e_perm;
+        unsigned int            e_id;
+};
+
+struct posix_acl {
+        atomic_t                a_refcount;
+        unsigned int            a_count;
+        struct posix_acl_entry  a_entries[0];
+};
+
+struct posix_acl *posix_acl_alloc(int count, int flags);
+static inline struct posix_acl *posix_acl_from_xattr(const void *value, 
+                                                     size_t size)
+{ 
+        return posix_acl_alloc(0, 0);
+}
+static inline void posix_acl_release(struct posix_acl *acl) {};
+static inline int posix_acl_valid(const struct posix_acl *acl) { return 0; }
+static inline struct posix_acl * posix_acl_dup(struct posix_acl *acl) 
+{ 
+        return acl;
+}
+
+#else  /* !__KERNEL__ */
+
+typedef struct file cfs_file_t;
+
+#endif /* END __KERNEL__ */
+
+typedef struct {
+       void    *d;
+} cfs_dentry_t;
+
+#ifndef O_SYNC
+#define O_SYNC                                 0
+#endif
+#ifndef O_DIRECTORY
+#define O_DIRECTORY                            0
+#endif
+#ifndef O_LARGEFILE
+#define O_LARGEFILE                            0
+#endif
+
+#endif
diff --git a/libcfs/include/libcfs/darwin/darwin-lock.h b/libcfs/include/libcfs/darwin/darwin-lock.h
new file mode 100644 (file)
index 0000000..f826fef
--- /dev/null
@@ -0,0 +1,284 @@
+#ifndef __LIBCFS_DARWIN_CFS_LOCK_H__
+#define __LIBCFS_DARWIN_CFS_LOCK_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+#ifdef __KERNEL__
+#include <mach/sync_policy.h>
+#include <mach/task.h>
+#include <mach/semaphore.h>
+#include <kern/assert.h>
+#include <kern/thread.h>
+
+#include <libcfs/darwin/darwin-types.h>
+#include <libcfs/darwin/darwin-sync.h>
+
+/*
+ * spin_lock (use Linux kernel's primitives)
+ * 
+ * - spin_lock_init(x)
+ * - spin_lock(x)
+ * - spin_unlock(x)
+ * - spin_trylock(x)
+ * 
+ * - spin_lock_irqsave(x, f)
+ * - spin_unlock_irqrestore(x, f)
+ */
+struct spin_lock {
+       struct kspin spin;
+};
+
+typedef struct spin_lock spinlock_t;
+
+static inline void spin_lock_init(spinlock_t *lock)
+{
+       kspin_init(&lock->spin);
+}
+
+static inline void spin_lock(spinlock_t *lock)
+{
+       kspin_lock(&lock->spin);
+}
+
+static inline void spin_unlock(spinlock_t *lock)
+{
+       kspin_unlock(&lock->spin);
+}
+
+static inline int spin_trylock(spinlock_t *lock)
+{
+       return kspin_trylock(&lock->spin);
+}
+
+static inline void spin_lock_done(spinlock_t *lock)
+{
+       kspin_done(&lock->spin);
+}
+
+#error "does this lock out timer callbacks?"
+#define spin_lock_bh(x)                spin_lock(x)
+#define spin_unlock_bh(x)      spin_unlock(x)
+#define spin_lock_bh_init(x)   spin_lock_init(x)
+
+extern boolean_t ml_set_interrupts_enabled(boolean_t enable);
+#define __disable_irq()         ml_set_interrupts_enabled(FALSE)
+#define __enable_irq(x)         (void) ml_set_interrupts_enabled(x)
+
+#define spin_lock_irqsave(s, f)                do{                     \
+                                       f = __disable_irq();    \
+                                       spin_lock(s);   }while(0)
+
+#define spin_unlock_irqrestore(s, f)   do{                     \
+                                       spin_unlock(s);         \
+                                       __enable_irq(f);}while(0)
+
+/* 
+ * Semaphore
+ *
+ * - sema_init(x, v)
+ * - __down(x)
+ * - __up(x)
+ */
+struct semaphore {
+       struct ksem sem;
+};
+
+static inline void sema_init(struct semaphore *s, int val)
+{
+       ksem_init(&s->sem, val);
+}
+
+static inline void __down(struct semaphore *s)
+{
+       ksem_down(&s->sem, 1);
+}
+
+static inline void __up(struct semaphore *s)
+{
+       ksem_up(&s->sem, 1);
+}
+
+/*
+ * Mutex:
+ *
+ * - init_mutex(x)
+ * - init_mutex_locked(x)
+ * - mutex_up(x)
+ * - mutex_down(x)
+ */
+
+#define mutex_up(s)                    __up(s)
+#define mutex_down(s)                  __down(s)
+
+#define init_mutex(x)                  sema_init(x, 1)
+#define init_mutex_locked(x)           sema_init(x, 0)
+
+/*
+ * Completion:
+ *
+ * - init_completion(c)
+ * - complete(c)
+ * - wait_for_completion(c)
+ */
+struct completion {
+       /*
+        * Emulate completion by semaphore for now.
+        *
+        * XXX nikita: this is not safe if completion is used to synchronize
+        * exit from kernel daemon thread and kext unloading. In this case
+        * some core function (a la complete_and_exit()) is needed.
+        */
+       struct ksem sem;
+};
+
+static inline void init_completion(struct completion *c)
+{
+       ksem_init(&c->sem, 0);
+}
+
+static inline void complete(struct completion *c)
+{
+       ksem_up(&c->sem, 1);
+}
+
+static inline void wait_for_completion(struct completion *c)
+{
+       ksem_down(&c->sem, 1);
+}
+
+/*
+ * rw_semaphore:
+ *
+ * - DECLARE_RWSEM(x)
+ * - init_rwsem(x)
+ * - down_read(x)
+ * - up_read(x)
+ * - down_write(x)
+ * - up_write(x)
+ */
+struct rw_semaphore {
+       struct krw_sem s;
+};
+
+static inline void init_rwsem(struct rw_semaphore *s)
+{
+       krw_sem_init(&s->s);
+}
+
+static inline void fini_rwsem(struct rw_semaphore *s)
+{
+       krw_sem_done(&s->s);
+}
+
+static inline void down_read(struct rw_semaphore *s)
+{
+       krw_sem_down_r(&s->s);
+}
+
+static inline int down_read_trylock(struct rw_semaphore *s)
+{
+       int ret = krw_sem_down_r_try(&s->s);
+       return ret == 0;
+}
+
+static inline void down_write(struct rw_semaphore *s)
+{
+       krw_sem_down_w(&s->s);
+}
+
+static inline int down_write_trylock(struct rw_semaphore *s)
+{
+       int ret = krw_sem_down_w_try(&s->s);
+       return ret == 0;
+}
+
+static inline void up_read(struct rw_semaphore *s)
+{
+       krw_sem_up_r(&s->s);
+}
+
+static inline void up_write(struct rw_semaphore *s)
+{
+       krw_sem_up_w(&s->s);
+}
+
+/* 
+ * read-write lock : Need to be investigated more!!
+ *
+ * - DECLARE_RWLOCK(l)
+ * - rwlock_init(x)
+ * - read_lock(x)
+ * - read_unlock(x)
+ * - write_lock(x)
+ * - write_unlock(x)
+ */
+typedef struct krw_spin rwlock_t;
+
+#define rwlock_init(pl)                        krw_spin_init(pl)
+
+#define read_lock(l)                   krw_spin_down_r(l)
+#define read_unlock(l)                 krw_spin_up_r(l)
+#define write_lock(l)                  krw_spin_down_w(l)
+#define write_unlock(l)                        krw_spin_up_w(l)
+
+#define write_lock_irqsave(l, f)       do{                     \
+                                       f = __disable_irq();    \
+                                       write_lock(l);  }while(0)
+
+#define write_unlock_irqrestore(l, f)  do{                     \
+                                       write_unlock(l);        \
+                                       __enable_irq(f);}while(0)
+
+#define read_lock_irqsave(l, f)                do{                     \
+                                       f = __disable_irq();    \
+                                       read_lock(l);   }while(0)
+
+#define read_unlock_irqrestore(l, f)   do{                     \
+                                       read_unlock(l);         \
+                                       __enable_irq(f);}while(0)
+/*
+ * Funnel: 
+ *
+ * Safe funnel in/out
+ */
+#ifdef __DARWIN8__
+
+#define CFS_DECL_FUNNEL_DATA
+#define CFS_DECL_CONE_DATA              DECLARE_FUNNEL_DATA
+#define CFS_DECL_NET_DATA               DECLARE_FUNNEL_DATA
+#define CFS_CONE_IN                     do {} while(0)
+#define CFS_CONE_EX                     do {} while(0)
+
+#define CFS_NET_IN                      do {} while(0)
+#define CFS_NET_EX                      do {} while(0)
+
+#else
+
+#define CFS_DECL_FUNNEL_DATA                   \
+        boolean_t    __funnel_state = FALSE;   \
+        funnel_t    *__funnel
+#define CFS_DECL_CONE_DATA             CFS_DECL_FUNNEL_DATA
+#define CFS_DECL_NET_DATA              CFS_DECL_FUNNEL_DATA
+
+void lustre_cone_in(boolean_t *state, funnel_t **cone);
+void lustre_cone_ex(boolean_t state, funnel_t *cone);
+
+#define CFS_CONE_IN lustre_cone_in(&__funnel_state, &__funnel)
+#define CFS_CONE_EX lustre_cone_ex(__funnel_state, __funnel)
+
+void lustre_net_in(boolean_t *state, funnel_t **cone);
+void lustre_net_ex(boolean_t state, funnel_t *cone);
+
+#define CFS_NET_IN  lustre_net_in(&__funnel_state, &__funnel)
+#define CFS_NET_EX  lustre_net_ex(__funnel_state, __funnel)
+
+#endif
+
+#else
+#include <libcfs/user-lock.h>
+#endif /* __KERNEL__ */
+
+/* __XNU_CFS_LOCK_H */
+#endif
diff --git a/libcfs/include/libcfs/darwin/darwin-mem.h b/libcfs/include/libcfs/darwin/darwin-mem.h
new file mode 100644 (file)
index 0000000..5ffcd4e
--- /dev/null
@@ -0,0 +1,232 @@
+#ifndef __LIBCFS_DARWIN_CFS_MEM_H__
+#define __LIBCFS_DARWIN_CFS_MEM_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+#ifdef __KERNEL__
+
+#include <sys/types.h>
+#include <sys/systm.h>
+
+#include <sys/vm.h>
+#include <sys/kernel.h>
+#include <sys/ubc.h>
+#include <sys/uio.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/lockf.h>
+
+#include <mach/mach_types.h>
+#include <mach/vm_types.h>
+#include <vm/pmap.h>
+#include <vm/vm_kern.h>
+#include <mach/machine/vm_param.h>
+#include <kern/thread_call.h>
+#include <sys/param.h>
+#include <sys/vm.h>
+
+#include <libcfs/darwin/darwin-types.h>
+#include <libcfs/darwin/darwin-sync.h>
+#include <libcfs/darwin/darwin-lock.h>
+#include <libcfs/list.h>
+
+/*
+ * Basic xnu_page struct, should be binary compatibility with
+ * all page types in xnu (we have only xnu_raw_page, xll_page now)
+ */
+
+/* Variable sized pages are not supported */
+
+#ifdef PAGE_SHIFT
+#define CFS_PAGE_SHIFT PAGE_SHIFT
+#else
+#define CFS_PAGE_SHIFT 12
+#endif
+
+#define CFS_PAGE_SIZE  (1UL << CFS_PAGE_SHIFT)
+
+#define CFS_PAGE_MASK  (~((__u64)CFS_PAGE_SIZE - 1))
+
+enum {
+       XNU_PAGE_RAW,
+       XNU_PAGE_XLL,
+       XNU_PAGE_NTYPES
+};
+
+typedef __u32 page_off_t;
+
+/*
+ * For XNU we have our own page cache built on top of underlying BSD/MACH
+ * infrastructure. In particular, we have two disjoint types of pages:
+ *
+ *    - "raw" pages (XNU_PAGE_RAW): these are just buffers mapped into KVM,
+ *    based on UPLs, and
+ *
+ *    - "xll" pages (XNU_PAGE_XLL): these are used by file system to cache
+ *    file data, owned by file system objects, hashed, lrued, etc.
+ *
+ * cfs_page_t has to cover both of them, because core Lustre code is based on
+ * the Linux assumption that page is _both_ memory buffer and file system
+ * caching entity.
+ *
+ * To achieve this, all types of pages supported on XNU has to start from
+ * common header that contains only "page type". Common cfs_page_t operations
+ * dispatch through operation vector based on page type.
+ *
+ */
+typedef struct xnu_page {
+       int type;
+} cfs_page_t;
+
+struct xnu_page_ops {
+       void *(*page_map)        (cfs_page_t *);
+       void  (*page_unmap)      (cfs_page_t *);
+       void *(*page_address)    (cfs_page_t *);
+};
+
+void xnu_page_ops_register(int type, struct xnu_page_ops *ops);
+void xnu_page_ops_unregister(int type);
+
+/*
+ * raw page, no cache object, just like buffer
+ */
+struct xnu_raw_page {
+       struct xnu_page  header;
+       void            *virtual;
+       atomic_t         count;
+       struct list_head link;
+};
+
+/*
+ * Public interface to lustre
+ *
+ * - cfs_alloc_page(f)
+ * - cfs_free_page(p)
+ * - cfs_kmap(p)
+ * - cfs_kunmap(p)
+ * - cfs_page_address(p)
+ */
+
+/*
+ * Of all functions above only cfs_kmap(), cfs_kunmap(), and
+ * cfs_page_address() can be called on file system pages. The rest is for raw
+ * pages only.
+ */
+
+cfs_page_t *cfs_alloc_page(u_int32_t flags);
+void cfs_free_page(cfs_page_t *page);
+void cfs_get_page(cfs_page_t *page);
+int cfs_put_page_testzero(cfs_page_t *page);
+int cfs_page_count(cfs_page_t *page);
+#define cfs_page_index(pg)     (0)
+
+void *cfs_page_address(cfs_page_t *pg);
+void *cfs_kmap(cfs_page_t *pg);
+void cfs_kunmap(cfs_page_t *pg);
+
+/*
+ * Memory allocator
+ */
+
+void *cfs_alloc(size_t nr_bytes, u_int32_t flags);
+void  cfs_free(void *addr);
+
+void *cfs_alloc_large(size_t nr_bytes);
+void  cfs_free_large(void *addr);
+
+extern int get_preemption_level(void);
+
+#define CFS_ALLOC_ATOMIC_TRY                                    \
+       (get_preemption_level() != 0 ? CFS_ALLOC_ATOMIC : 0)
+
+/*
+ * Slab:
+ *
+ * No slab in OSX, use zone allocator to simulate slab
+ */
+#define SLAB_HWCACHE_ALIGN             0
+
+#ifdef __DARWIN8__
+/* 
+ * In Darwin8, we cannot use zalloc_noblock(not exported by kernel),
+ * also, direct using of zone allocator is not recommended.
+ */
+#define CFS_INDIVIDUAL_ZONE     (0)
+
+#if !CFS_INDIVIDUAL_ZONE
+#include <libkern/OSMalloc.h>
+typedef        OSMallocTag     mem_cache_t;
+#else
+typedef                void*           zone_t;
+typedef                zone_t          mem_cache_t;
+#endif
+
+#else /* !__DARWIN8__ */
+
+#define CFS_INDIVIDUAL_ZONE     (1)
+
+typedef        zone_t          mem_cache_t;
+
+#endif /* !__DARWIN8__ */
+
+#define MC_NAME_MAX_LEN                64
+
+typedef struct cfs_mem_cache {
+       int                     mc_size;
+       mem_cache_t             mc_cache;
+       struct list_head        mc_link;
+       char                    mc_name [MC_NAME_MAX_LEN];
+} cfs_mem_cache_t;
+
+#define KMEM_CACHE_MAX_COUNT   64
+#define KMEM_MAX_ZONE          8192
+
+cfs_mem_cache_t * cfs_mem_cache_create (const char *, size_t, size_t, unsigned long);
+int cfs_mem_cache_destroy ( cfs_mem_cache_t * );
+void *cfs_mem_cache_alloc ( cfs_mem_cache_t *, int);
+void cfs_mem_cache_free ( cfs_mem_cache_t *, void *);
+
+/*
+ * Misc
+ */
+/* XXX Liang: num_physpages... fix me */
+#define num_physpages                  (64 * 1024)
+
+#define CFS_DECL_MMSPACE               
+#define CFS_MMSPACE_OPEN               do {} while(0)
+#define CFS_MMSPACE_CLOSE              do {} while(0)
+
+#define copy_from_user(kaddr, uaddr, size)     copyin(CAST_USER_ADDR_T(uaddr), (caddr_t)kaddr, size)
+#define copy_to_user(uaddr, kaddr, size)       copyout((caddr_t)kaddr, CAST_USER_ADDR_T(uaddr), size)
+
+#if 0
+static inline int strncpy_from_user(char *kaddr, char *uaddr, int size)
+{
+       size_t count;
+       return copyinstr((const user_addr_t)uaddr, (void *)kaddr, size, &count);
+}
+#endif
+
+#if defined (__ppc__)
+#define mb()  __asm__ __volatile__ ("sync" : : : "memory")
+#define rmb()  __asm__ __volatile__ ("sync" : : : "memory")
+#define wmb()  __asm__ __volatile__ ("eieio" : : : "memory")
+#elif defined (__i386__)
+#define mb()    __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
+#define rmb()   mb()
+#define wmb()   __asm__ __volatile__ ("": : :"memory")
+#else
+#error architecture not supported
+#endif
+
+#else  /* !__KERNEL__ */
+
+#define CFS_CACHE_SHIFT 12
+#define PAGE_CACHE_SIZE (1 << CFS_CACHE_SHIFT)
+#include <libcfs/user-prim.h>
+
+#endif /* __KERNEL__ */
+
+#endif /* __XNU_CFS_MEM_H__ */
diff --git a/libcfs/include/libcfs/darwin/darwin-prim.h b/libcfs/include/libcfs/darwin/darwin-prim.h
new file mode 100644 (file)
index 0000000..0c201c2
--- /dev/null
@@ -0,0 +1,527 @@
+#ifndef __LIBCFS_DARWIN_CFS_PRIM_H__
+#define __LIBCFS_DARWIN_CFS_PRIM_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+#ifdef __KERNEL__
+#include <sys/types.h>
+#include <sys/systm.h>
+
+#ifndef __DARWIN8__
+# ifndef __APPLE_API_PRIVATE
+#  define __APPLE_API_PRIVATE
+#  include <sys/user.h>
+#  undef __APPLE_API_PRIVATE
+# else
+#  include <sys/user.h>
+# endif
+# include <mach/mach_traps.h>
+# include <mach/thread_switch.h>
+# include <machine/cpu_number.h>
+#endif /* !__DARWIN8__ */
+
+#include <sys/kernel.h>
+
+#include <mach/thread_act.h>
+#include <mach/mach_types.h>
+#include <mach/time_value.h>
+#include <kern/sched_prim.h>
+#include <vm/pmap.h>
+#include <vm/vm_kern.h>
+#include <mach/machine/vm_param.h>
+#include <machine/machine_routines.h>
+#include <kern/clock.h>
+#include <kern/thread_call.h>
+#include <sys/param.h>
+#include <sys/vm.h>
+
+#include <libcfs/darwin/darwin-types.h>
+#include <libcfs/darwin/darwin-utils.h>
+#include <libcfs/darwin/darwin-lock.h>
+
+/*
+ * Symbol functions for libcfs
+ *
+ * OSX has no facility for use to register symbol.
+ * So we have to implement it.
+ */
+#define CFS_SYMBOL_LEN     64
+
+struct  cfs_symbol {
+       char    name[CFS_SYMBOL_LEN];
+       void    *value;
+       int     ref;
+       struct  list_head sym_list;
+};
+
+extern kern_return_t            cfs_symbol_register(const char *, const void *);
+extern kern_return_t            cfs_symbol_unregister(const char *);
+extern void *                   cfs_symbol_get(const char *);
+extern kern_return_t            cfs_symbol_put(const char *);
+
+/*
+ * sysctl typedef
+ *
+ * User can register/unregister a list of sysctl_oids
+ * sysctl_oid is data struct of osx's sysctl-entry
+ */
+#define        CONFIG_SYSCTL   1
+
+typedef struct sysctl_oid *     cfs_sysctl_table_t;
+typedef cfs_sysctl_table_t      cfs_sysctl_table_header_t;
+cfs_sysctl_table_header_t      *cfs_register_sysctl_table (cfs_sysctl_table_t *table, int arg);
+void cfs_unregister_sysctl_table (cfs_sysctl_table_header_t *table);
+
+/*
+ * Proc file system APIs, no /proc fs support in OSX
+ */
+typedef struct cfs_proc_dir_entry {
+       void            *data;
+} cfs_proc_dir_entry_t;
+
+cfs_proc_dir_entry_t * cfs_create_proc_entry(char *name, int mod,
+                                         cfs_proc_dir_entry_t *parent);
+void cfs_free_proc_entry(cfs_proc_dir_entry_t *de);
+void cfs_remove_proc_entry(char *name, cfs_proc_dir_entry_t *entry);
+
+typedef int (cfs_read_proc_t)(char *page, char **start, off_t off,
+                         int count, int *eof, void *data);
+typedef int (cfs_write_proc_t)(struct file *file, const char *buffer,
+                          unsigned long count, void *data);
+
+/*
+ * cfs pseudo device
+ *
+ * cfs_psdev_t
+ * cfs_psdev_register:
+ * cfs_psdev_deregister:
+ */
+typedef struct {
+       int             index;
+       void            *handle;
+       const char      *name;
+       struct cdevsw   *devsw;
+       void            *private;
+} cfs_psdev_t;
+
+extern kern_return_t            cfs_psdev_register(cfs_psdev_t *);
+extern kern_return_t            cfs_psdev_deregister(cfs_psdev_t *);
+
+/*
+ * Task struct and ...
+ *
+ * Using BSD current_proc in Darwin
+ */
+extern boolean_t        assert_wait_possible(void);
+extern void             *get_bsdtask_info(task_t);
+
+#ifdef __DARWIN8__
+
+typedef struct {}              cfs_task_t;
+#define cfs_current()          ((cfs_task_t *)current_thread())
+#else  /* !__DARWIN8__ */
+
+typedef struct uthread         cfs_task_t;
+
+#define current_uthread()       ((struct uthread *)get_bsdthread_info(current_act()))
+#define cfs_current()          current_uthread()
+
+#endif /* !__DARWIN8__ */
+
+#define cfs_task_lock(t)       do {;} while (0)
+#define cfs_task_unlock(t)     do {;} while (0)
+
+#define set_current_state(s)   do {;} while (0)
+
+#define CFS_DECL_JOURNAL_DATA  
+#define CFS_PUSH_JOURNAL       do {;} while(0)
+#define CFS_POP_JOURNAL                do {;} while(0)
+
+#define THREAD_NAME(comm, fmt, a...)
+/*
+ * Kernel thread:
+ *
+ * OSX kernel thread can not be created with args,
+ * so we have to implement new APIs to create thread with args
+ */
+
+typedef int (*cfs_thread_t)(void *);
+
+extern task_t  kernel_task;
+
+/*
+ * cloning flags, no use in OSX, just copy them from Linux
+ */
+#define CSIGNAL         0x000000ff      /* signal mask to be sent at exit */
+#define CLONE_VM        0x00000100      /* set if VM shared between processes */
+#define CLONE_FS        0x00000200      /* set if fs info shared between processes */
+#define CLONE_FILES     0x00000400      /* set if open files shared between processes */
+#define CLONE_SIGHAND   0x00000800      /* set if signal handlers and blocked signals shared */
+#define CLONE_PID       0x00001000      /* set if pid shared */
+#define CLONE_PTRACE    0x00002000      /* set if we want to let tracing continue on the child too */
+#define CLONE_VFORK     0x00004000      /* set if the parent wants the child to wake it up on mm_release */
+#define CLONE_PARENT    0x00008000      /* set if we want to have the same parent as the cloner */
+#define CLONE_THREAD    0x00010000      /* Same thread group? */
+#define CLONE_NEWNS     0x00020000      /* New namespace group? */
+
+#define CLONE_SIGNAL    (CLONE_SIGHAND | CLONE_THREAD)
+
+extern int cfs_kernel_thread(cfs_thread_t func, void *arg, int flag);
+
+
+/*
+ * Wait Queue implementation
+ *
+ * Like wait_queue in Linux
+ */
+typedef struct cfs_waitq {
+       struct ksleep_chan wq_ksleep_chan;
+} cfs_waitq_t;
+
+typedef struct cfs_waitlink {
+       struct cfs_waitq   *wl_waitq;
+       struct ksleep_link  wl_ksleep_link;
+} cfs_waitlink_t;
+
+typedef int cfs_task_state_t;
+
+#define CFS_TASK_INTERRUPTIBLE THREAD_ABORTSAFE
+#define CFS_TASK_UNINT         THREAD_UNINT
+
+void cfs_waitq_init(struct cfs_waitq *waitq);
+void cfs_waitlink_init(struct cfs_waitlink *link);
+
+void cfs_waitq_add(struct cfs_waitq *waitq, struct cfs_waitlink *link);
+void cfs_waitq_add_exclusive(struct cfs_waitq *waitq,
+                            struct cfs_waitlink *link);
+void cfs_waitq_forward(struct cfs_waitlink *link, struct cfs_waitq *waitq);
+void cfs_waitq_del(struct cfs_waitq *waitq, struct cfs_waitlink *link);
+int  cfs_waitq_active(struct cfs_waitq *waitq);
+
+void cfs_waitq_signal(struct cfs_waitq *waitq);
+void cfs_waitq_signal_nr(struct cfs_waitq *waitq, int nr);
+void cfs_waitq_broadcast(struct cfs_waitq *waitq);
+
+void cfs_waitq_wait(struct cfs_waitlink *link, cfs_task_state_t state);
+cfs_duration_t cfs_waitq_timedwait(struct cfs_waitlink *link,
+                                  cfs_task_state_t state, 
+                                  cfs_duration_t timeout);
+
+/*
+ * Thread schedule APIs.
+ */
+#define MAX_SCHEDULE_TIMEOUT    ((long)(~0UL>>12))
+extern void thread_set_timer_deadline(__u64 deadline);
+extern void thread_cancel_timer(void);
+
+static inline int cfs_schedule_timeout(int state, int64_t timeout)
+{
+       int          result;
+       
+#ifdef __DARWIN8__
+       result = assert_wait((event_t)current_thread(), state);
+#else
+       result = assert_wait((event_t)current_uthread(), state);
+#endif
+       if (timeout > 0) {
+               __u64 expire;
+               nanoseconds_to_absolutetime(timeout, &expire);
+               clock_absolutetime_interval_to_deadline(expire, &expire);
+               thread_set_timer_deadline(expire);
+       }
+       if (result == THREAD_WAITING)
+               result = thread_block(THREAD_CONTINUE_NULL);
+       if (timeout > 0)
+               thread_cancel_timer();
+       if (result == THREAD_TIMED_OUT)
+               result = 0;
+       else
+               result = 1;
+       return result;
+}
+
+#define cfs_schedule() cfs_schedule_timeout(CFS_TASK_UNINT, CFS_TICK)
+#define cfs_pause(tick)        cfs_schedule_timeout(CFS_TASK_UNINT, tick)
+
+#define __wait_event(wq, condition)                            \
+do {                                                           \
+       struct cfs_waitlink __wait;                             \
+                                                               \
+       cfs_waitlink_init(&__wait);                             \
+       for (;;) {                                              \
+               cfs_waitq_add(&wq, &__wait);                    \
+               if (condition)                                  \
+                       break;                                  \
+               cfs_waitq_wait(&__wait, CFS_TASK_UNINT);        \
+               cfs_waitq_del(&wq, &__wait);                    \
+       }                                                       \
+       cfs_waitq_del(&wq, &__wait);                            \
+} while (0)
+
+#define wait_event(wq, condition)                              \
+do {                                                           \
+       if (condition)                                          \
+               break;                                          \
+       __wait_event(wq, condition);                            \
+} while (0)
+
+#define __wait_event_interruptible(wq, condition, ex, ret)     \
+do {                                                           \
+       struct cfs_waitlink __wait;                             \
+                                                               \
+       cfs_waitlink_init(&__wait);                             \
+       for (;;) {                                              \
+               if (ex == 0)                                    \
+                       cfs_waitq_add(&wq, &__wait);            \
+               else                                            \
+                       cfs_waitq_add_exclusive(&wq, &__wait);  \
+               if (condition)                                  \
+                       break;                                  \
+               if (!cfs_signal_pending()) {                    \
+                       cfs_waitq_wait(&__wait,                 \
+                                      CFS_TASK_INTERRUPTIBLE); \
+                       cfs_waitq_del(&wq, &__wait);            \
+                       continue;                               \
+               }                                               \
+               ret = -ERESTARTSYS;                             \
+               break;                                          \
+       }                                                       \
+       cfs_waitq_del(&wq, &__wait);                            \
+} while (0)
+
+#define wait_event_interruptible(wq, condition)                        \
+({                                                             \
+       int __ret = 0;                                          \
+       if (!condition)                                         \
+               __wait_event_interruptible(wq, condition,       \
+                                          0, __ret);           \
+       __ret;                                                  \
+})
+
+#define wait_event_interruptible_exclusive(wq, condition)      \
+({                                                             \
+       int __ret = 0;                                          \
+       if (!condition)                                         \
+               __wait_event_interruptible(wq, condition,       \
+                                          1, __ret);           \
+       __ret;                                                  \
+})
+
+#ifndef __DARWIN8__
+extern void    wakeup_one __P((void * chan));
+#endif
+/* only used in tests */
+#define wake_up_process(p)                                     \
+       do {                                                    \
+               wakeup_one((caddr_t)p);                         \
+       } while (0)
+       
+/* used in couple of places */
+static inline void sleep_on(cfs_waitq_t *waitq)
+{
+       cfs_waitlink_t link;
+       
+       cfs_waitlink_init(&link);
+       cfs_waitq_add(waitq, &link);
+       cfs_waitq_wait(&link, CFS_TASK_UNINT);
+       cfs_waitq_del(waitq, &link);
+}
+
+/*
+ * Signal
+ */
+typedef sigset_t       cfs_sigset_t;
+
+#define SIGNAL_MASK_ASSERT()
+/*
+ * Timer
+ */
+typedef struct cfs_timer {
+       struct ktimer t;
+} cfs_timer_t;
+
+#define cfs_init_timer(t)      do {} while(0)
+void cfs_timer_init(struct cfs_timer *t, void (*func)(unsigned long), void *arg);
+void cfs_timer_done(struct cfs_timer *t);
+void cfs_timer_arm(struct cfs_timer *t, cfs_time_t deadline);
+void cfs_timer_disarm(struct cfs_timer *t);
+int  cfs_timer_is_armed(struct cfs_timer *t);
+
+cfs_time_t cfs_timer_deadline(struct cfs_timer *t);
+
+/*
+ * Ioctl
+ * We don't need to copy out everything in osx
+ */
+#define cfs_ioctl_data_out(a, d, l)                    \
+       ({                                              \
+               int __size;                             \
+               int __rc = 0;                           \
+               assert((l) >= sizeof(*d));              \
+               __size = (l) - sizeof(*d);              \
+               if (__size > 0)                         \
+                       __rc = copy_to_user((void *)a + __size, \
+                            (void *)d + __size,        \
+                            __size);                   \
+               __rc;                                   \
+       })
+
+/*
+ * CPU
+ */
+/* Run in PowerG5 who is PPC64 */
+#define SMP_CACHE_BYTES                         128
+#define __cacheline_aligned                     __attribute__((__aligned__(SMP_CACHE_BYTES)))
+#define NR_CPUS                                        2
+
+/* 
+ * XXX Liang: patch xnu and export current_processor()?
+ *
+ * #define smp_processor_id()                  current_processor()
+ */
+#define smp_processor_id()                     0
+/* XXX smp_call_function is not supported in xnu */
+#define smp_call_function(f, a, n, w)          do {} while(0)
+int cfs_online_cpus(void);
+#define smp_num_cpus                           cfs_online_cpus()
+
+/*
+ * Misc
+ */
+extern int is_suser(void);
+
+#ifndef likely
+#define likely(exp) (exp)
+#endif
+#ifndef unlikely
+#define unlikely(exp) (exp)
+#endif
+
+#define lock_kernel()                          do {} while(0)
+#define unlock_kernel()                                do {} while(0)
+
+#define CAP_SYS_BOOT                           0
+#define CAP_SYS_ADMIN                           1
+#define capable(a)                             ((a) == CAP_SYS_BOOT ? is_suser(): is_suser1())
+
+#define USERMODEHELPER(path, argv, envp)       (0)
+
+#define cfs_module(name, version, init, fini)                          \
+extern kern_return_t _start(kmod_info_t *ki, void *data);              \
+extern kern_return_t _stop(kmod_info_t *ki, void *data);               \
+__private_extern__ kern_return_t name##_start(kmod_info_t *ki, void *data); \
+__private_extern__ kern_return_t name##_stop(kmod_info_t *ki, void *data); \
+                                                                       \
+kmod_info_t KMOD_INFO_NAME = { 0, KMOD_INFO_VERSION, -1,               \
+                               { "com.clusterfs.lustre." #name }, { version }, \
+                               -1, 0, 0, 0, 0, name##_start, name##_stop }; \
+                                                                       \
+__private_extern__ kmod_start_func_t *_realmain = name##_start;                \
+__private_extern__ kmod_stop_func_t *_antimain = name##_stop;          \
+__private_extern__ int _kext_apple_cc = __APPLE_CC__ ;                 \
+                                                                       \
+kern_return_t name##_start(kmod_info_t *ki, void *d)                   \
+{                                                                      \
+       return init();                                                  \
+}                                                                      \
+                                                                       \
+kern_return_t name##_stop(kmod_info_t *ki, void *d)                    \
+{                                                                      \
+        fini();                                                                \
+        return KERN_SUCCESS;                                           \
+}                                                                      \
+                                                                       \
+/*                                                                     \
+ * to allow semicolon after cfs_module(...)                            \
+ */                                                                    \
+struct __dummy_ ## name ## _struct {}
+
+#define inter_module_get(n)                    cfs_symbol_get(n)
+#define inter_module_put(n)                    cfs_symbol_put(n)
+
+static inline int request_module(char *name)
+{
+       return (-EINVAL);
+}
+
+#ifndef __exit
+#define __exit
+#endif
+#ifndef __init
+#define __init
+#endif
+
+#define EXPORT_SYMBOL(s)
+#define MODULE_AUTHOR(s)
+#define MODULE_DESCRIPTION(s)
+#define MODULE_LICENSE(s)
+#define MODULE_PARM(a, b)
+#define MODULE_PARM_DESC(a, b)
+
+#define KERNEL_VERSION(a,b,c) ((a)*100+(b)*10+c)
+#define LINUX_VERSION_CODE KERNEL_VERSION(2,5,0)
+
+#define NR_IRQS                                512
+#define in_interrupt()                 ml_at_interrupt_context()
+
+#define KERN_EMERG      "<0>"   /* system is unusable                   */
+#define KERN_ALERT      "<1>"   /* action must be taken immediately     */
+#define KERN_CRIT       "<2>"   /* critical conditions                  */
+#define KERN_ERR        "<3>"   /* error conditions                     */
+#define KERN_WARNING    "<4>"   /* warning conditions                   */
+#define KERN_NOTICE     "<5>"   /* normal but significant condition     */
+#define KERN_INFO       "<6>"   /* informational                        */
+#define KERN_DEBUG      "<7>"   /* debug-level messages                 */
+
+static inline long PTR_ERR(const void *ptr)
+{
+       return (long) ptr;
+}
+
+#define ERR_PTR(err)   ((void *)err)
+#define IS_ERR(p)      ((unsigned long)(p) + 1000 < 1000)
+
+#else  /* !__KERNEL__ */
+
+typedef struct cfs_proc_dir_entry {
+       void            *data;
+} cfs_proc_dir_entry_t;
+
+#include <libcfs/user-prim.h>
+#define __WORDSIZE     32
+
+#endif /* END __KERNEL__ */
+/*
+ * Error number
+ */
+#ifndef EPROTO
+#define EPROTO          EPROTOTYPE
+#endif
+#ifndef EBADR
+#define EBADR          EBADRPC
+#endif
+#ifndef ERESTARTSYS
+#define ERESTARTSYS    512
+#endif
+#ifndef EDEADLOCK
+#define EDEADLOCK      EDEADLK
+#endif
+#ifndef ECOMM
+#define ECOMM          EINVAL
+#endif
+#ifndef ENODATA
+#define ENODATA                EINVAL
+#endif
+#ifndef ENOTSUPP
+#define ENOTSUPP       EINVAL
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+# define __BIG_ENDIAN
+#else
+# define __LITTLE_ENDIAN
+#endif
+
+#endif /* __LIBCFS_DARWIN_CFS_PRIM_H__ */
diff --git a/libcfs/include/libcfs/darwin/darwin-sync.h b/libcfs/include/libcfs/darwin/darwin-sync.h
new file mode 100644 (file)
index 0000000..7817b38
--- /dev/null
@@ -0,0 +1,332 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Implementation of standard libcfs synchronization primitives for XNU
+ * kernel.
+ *
+ *  Copyright (c) 2004 Cluster File Systems, Inc.
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or modify it under
+ *   the terms of version 2 of the GNU General Public License as published by
+ *   the Free Software Foundation. Lustre is distributed in the hope that it
+ *   will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details. You should have received a
+ *   copy of the GNU General Public License along with Lustre; if not, write
+ *   to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ *   USA.
+ */
+
+/*
+ * xnu_sync.h
+ *
+ * Created by nikita on Sun Jul 18 2004.
+ *
+ * Prototypes of XNU synchronization primitives.
+ */
+
+#ifndef __LIBCFS_DARWIN_XNU_SYNC_H__
+#define __LIBCFS_DARWIN_XNU_SYNC_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+#define XNU_SYNC_DEBUG (1)
+
+#if XNU_SYNC_DEBUG
+#define ON_SYNC_DEBUG(e) e
+#else
+#define ON_SYNC_DEBUG(e)
+#endif
+
+enum {
+        /* "egrep -i '^(o?x)?[abcdeflo]*$' /usr/dict/words" is your friend */
+       KMUT_MAGIC  = 0x0bac0cab, /* [a, [b, c]] = b (a, c) - c (a, b) */
+       KSEM_MAGIC  = 0x1abe11ed,
+       KCOND_MAGIC = 0xb01dface,
+       KRW_MAGIC   = 0xdabb1edd,
+       KSPIN_MAGIC = 0xca11ab1e,
+        KRW_SPIN_MAGIC    = 0xbabeface,
+       KSLEEP_CHAN_MAGIC = 0x0debac1e,
+       KSLEEP_LINK_MAGIC = 0xacc01ade,
+       KTIMER_MAGIC      = 0xbefadd1e
+};
+
+/* ------------------------- spin lock ------------------------- */
+
+/*
+ * XXX nikita: don't use NCPUS it's hardcoded to (1) in cpus.h
+ */
+#define SMP (1)
+
+#include <libcfs/list.h>
+
+#ifdef __DARWIN8__
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <kern/locks.h>
+
+/*
+ * hw_lock is not available in Darwin8 (hw_lock_* are not exported at all), 
+ * so use lck_spin_t. we can hack out lck_spin_t easily, it's the only 
+ * hacking in Darwin8.x. We did so because it'll take a lot of time to 
+ * add lock_done for all locks, maybe it should be done in the future.
+ * If lock_done for all locks were added, we can:
+ *
+ * typedef lck_spin_t      *xnu_spin_t;
+ */
+#if defined (__ppc__)
+typedef struct {
+        unsigned int    opaque[3];
+} xnu_spin_t;
+#elif defined (__i386__)
+typedef struct {
+        unsigned int    opaque[10];
+} xnu_spin_t;
+#endif
+
+/* 
+ * wait_queue is not available in Darwin8 (wait_queue_* are not exported), 
+ * use assert_wait/wakeup/wake_one (wait_queue in kernel hash).
+ */
+typedef void * xnu_wait_queue_t;
+
+/* DARWIN8 */
+#else
+
+#include <mach/mach_types.h>
+#include <sys/types.h>
+#include <kern/simple_lock.h>
+
+typedef hw_lock_data_t          xnu_spin_t;
+typedef struct wait_queue       xnu_wait_queue_t;
+
+/* DARWIN8 */
+#endif
+
+struct kspin {
+#if SMP
+       xnu_spin_t      lock;
+#endif
+#if XNU_SYNC_DEBUG
+       unsigned        magic;
+       thread_t        owner;
+#endif
+};
+
+void kspin_init(struct kspin *spin);
+void kspin_done(struct kspin *spin);
+void kspin_lock(struct kspin *spin);
+void kspin_unlock(struct kspin *spin);
+int  kspin_trylock(struct kspin *spin);
+
+#if XNU_SYNC_DEBUG
+/*
+ * two functions below are for use in assertions
+ */
+/* true, iff spin-lock is locked by the current thread */
+int kspin_islocked(struct kspin *spin);
+/* true, iff spin-lock is not locked by the current thread */
+int kspin_isnotlocked(struct kspin *spin);
+#else
+#define kspin_islocked(s) (1)
+#define kspin_isnotlocked(s) (1)
+#endif
+
+/* ------------------------- rw spinlock ----------------------- */
+struct krw_spin {
+        struct kspin      guard;
+        int               count;
+#if XNU_SYNC_DEBUG
+        unsigned          magic;
+#endif
+};
+
+void krw_spin_init(struct krw_spin *sem);
+void krw_spin_done(struct krw_spin *sem);
+void krw_spin_down_r(struct krw_spin *sem);
+void krw_spin_down_w(struct krw_spin *sem);
+void krw_spin_up_r(struct krw_spin *sem);
+void krw_spin_up_w(struct krw_spin *sem);
+
+/* ------------------------- semaphore ------------------------- */
+
+struct ksem {
+        struct kspin      guard;
+        xnu_wait_queue_t  q;
+        int               value;
+#if XNU_SYNC_DEBUG
+        unsigned          magic;
+#endif
+};
+
+void ksem_init(struct ksem *sem, int value);
+void ksem_done(struct ksem *sem);
+int  ksem_up  (struct ksem *sem, int value);
+void ksem_down(struct ksem *sem, int value);
+int  ksem_trydown(struct ksem *sem, int value);
+
+/* ------------------------- mutex ------------------------- */
+
+struct kmut {
+       struct ksem s;
+#if XNU_SYNC_DEBUG
+        unsigned    magic;
+        thread_t    owner;
+#endif
+};
+
+void kmut_init(struct kmut *mut);
+void kmut_done(struct kmut *mut);
+
+void kmut_lock   (struct kmut *mut);
+void kmut_unlock (struct kmut *mut);
+int  kmut_trylock(struct kmut *mut);
+
+#if XNU_SYNC_DEBUG
+/*
+ * two functions below are for use in assertions
+ */
+/* true, iff mutex is locked by the current thread */
+int kmut_islocked(struct kmut *mut);
+/* true, iff mutex is not locked by the current thread */
+int kmut_isnotlocked(struct kmut *mut);
+#else
+#define kmut_islocked(m) (1)
+#define kmut_isnotlocked(m) (1)
+#endif
+
+/* ------------------------- condition variable ------------------------- */
+
+struct kcond_link {
+       struct kcond_link *next;
+        struct ksem        sem;
+};
+
+struct kcond {
+        struct kspin       guard;
+        struct kcond_link *waiters;
+#if XNU_SYNC_DEBUG
+        unsigned           magic;
+#endif
+};
+
+void kcond_init(struct kcond *cond);
+void kcond_done(struct kcond *cond);
+void kcond_wait(struct kcond *cond, struct kspin *lock);
+void kcond_signal(struct kcond *cond);
+void kcond_broadcast(struct kcond *cond);
+
+void kcond_wait_guard(struct kcond *cond);
+void kcond_signal_guard(struct kcond *cond);
+void kcond_broadcast_guard(struct kcond *cond);
+
+/* ------------------------- read-write semaphore ------------------------- */
+
+struct krw_sem {
+       int          count;
+       struct kcond cond;
+#if XNU_SYNC_DEBUG
+       unsigned     magic;
+#endif
+};
+
+void krw_sem_init(struct krw_sem *sem);
+void krw_sem_done(struct krw_sem *sem);
+void krw_sem_down_r(struct krw_sem *sem);
+int krw_sem_down_r_try(struct krw_sem *sem);
+void krw_sem_down_w(struct krw_sem *sem);
+int krw_sem_down_w_try(struct krw_sem *sem);
+void krw_sem_up_r(struct krw_sem *sem);
+void krw_sem_up_w(struct krw_sem *sem);
+
+/* ------------------------- sleep-channel ------------------------- */
+
+struct ksleep_chan {
+       struct kspin     guard;
+       struct list_head waiters;
+#if XNU_SYNC_DEBUG
+       unsigned     magic;
+#endif
+};
+
+#define KSLEEP_CHAN_INITIALIZER         {{{0}}}
+
+struct ksleep_link {
+       int                 flags;
+       event_t             event;
+       int                 hits;
+       struct ksleep_chan *forward;
+       struct list_head    linkage;
+#if XNU_SYNC_DEBUG
+       unsigned     magic;
+#endif
+};
+
+enum {
+       KSLEEP_EXCLUSIVE = 1
+};
+
+void ksleep_chan_init(struct ksleep_chan *chan);
+void ksleep_chan_done(struct ksleep_chan *chan);
+
+void ksleep_link_init(struct ksleep_link *link);
+void ksleep_link_done(struct ksleep_link *link);
+
+void ksleep_add(struct ksleep_chan *chan, struct ksleep_link *link);
+void ksleep_del(struct ksleep_chan *chan, struct ksleep_link *link);
+
+void ksleep_wait(struct ksleep_chan *chan, int state);
+int64_t  ksleep_timedwait(struct ksleep_chan *chan, int state, __u64 timeout);
+
+void ksleep_wake(struct ksleep_chan *chan);
+void ksleep_wake_all(struct ksleep_chan *chan);
+void ksleep_wake_nr(struct ksleep_chan *chan, int nr);
+
+#define KSLEEP_LINK_DECLARE(name)               \
+{                                               \
+       .flags   = 0,                           \
+       .event   = 0,                           \
+       .hits    = 0,                           \
+       .linkage = CFS_LIST_HEAD(name.linkage), \
+       .magic   = KSLEEP_LINK_MAGIC            \
+}
+
+/* ------------------------- timer ------------------------- */
+
+struct ktimer {
+       struct kspin   guard;
+       void         (*func)(void *);
+       void          *arg;
+       u_int64_t      deadline; /* timer deadline in absolute nanoseconds */
+       int            armed;
+#if XNU_SYNC_DEBUG
+       unsigned     magic;
+#endif
+};
+
+void ktimer_init(struct ktimer *t, void (*func)(void *), void *arg);
+void ktimer_done(struct ktimer *t);
+void ktimer_arm(struct ktimer *t, u_int64_t deadline);
+void ktimer_disarm(struct ktimer *t);
+int  ktimer_is_armed(struct ktimer *t);
+
+u_int64_t ktimer_deadline(struct ktimer *t);
+
+/* __XNU_SYNC_H__ */
+#endif
+
+/*
+ * Local variables:
+ * c-indentation-style: "K&R"
+ * c-basic-offset: 8
+ * tab-width: 8
+ * fill-column: 80
+ * scroll-step: 1
+ * End:
+ */
diff --git a/libcfs/include/libcfs/darwin/darwin-tcpip.h b/libcfs/include/libcfs/darwin/darwin-tcpip.h
new file mode 100644 (file)
index 0000000..1a73891
--- /dev/null
@@ -0,0 +1,90 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2001 Cluster File Systems, Inc. <braam@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Basic library routines. 
+ *
+ */
+
+#ifndef __LIBCFS_DARWIN_TCPIP_H__
+#define __LIBCFS_DARWIN_TCPIP_H__
+
+#ifdef __KERNEL__
+#include <sys/socket.h>
+
+#ifdef __DARWIN8__
+
+struct socket;
+
+typedef void    (*so_upcall)(socket_t sock, void* arg, int waitf);
+
+#define CFS_SOCK_UPCALL         0x1
+#define CFS_SOCK_DOWN           0x2
+
+#define CFS_SOCK_MAGIC          0xbabeface
+
+typedef struct cfs_socket {
+        socket_t        s_so;
+        int             s_magic;
+        int             s_flags;
+        so_upcall       s_upcall;
+        void           *s_upcallarg;
+} cfs_socket_t;
+
+
+/* cfs_socket_t to bsd socket */
+#define C2B_SOCK(s)             ((s)->s_so)     
+
+static inline int get_sock_intopt(socket_t so, int opt)
+{
+        int     val, len;
+        int     rc;
+
+        /*
+         * sock_getsockopt will take a lock(mutex) for socket,
+         * so it can be blocked. So be careful while using 
+         * them.
+         */
+        len = sizeof(val);
+        rc = sock_getsockopt(so, SOL_SOCKET, opt, &val, &len);
+        assert(rc == 0);
+        return val;
+}
+
+#define SOCK_ERROR(s)           get_sock_intopt(C2B_SOCK(s), SO_ERROR)        
+/* #define SOCK_WMEM_QUEUED(s)     (0) */
+#define SOCK_WMEM_QUEUED(s)     get_sock_intopt(C2B_SOCK(s), SO_NWRITE)
+/* XXX Liang: no reliable way to get it in Darwin8.x */
+#define SOCK_TEST_NOSPACE(s)    (0)
+
+void libcfs_sock_set_cb(cfs_socket_t *sock, so_upcall callback, void *arg);
+void libcfs_sock_reset_cb(cfs_socket_t *sock);
+
+#else /* !__DARWIN8__ */
+
+#define SOCK_WMEM_QUEUED(so)    ((so)->so_snd.sb_cc)
+#define SOCK_ERROR(so)          ((so)->so_error)
+
+#define SOCK_TEST_NOSPACE(so)   (sbspace(&(so)->so_snd) < (so)->so_snd.sb_lowat)
+
+#endif /* !__DARWIN8__ */
+
+#endif /* __KERNEL END */
+
+#endif  /* __XNU_CFS_TYPES_H__ */
diff --git a/libcfs/include/libcfs/darwin/darwin-time.h b/libcfs/include/libcfs/darwin/darwin-time.h
new file mode 100644 (file)
index 0000000..35862a6
--- /dev/null
@@ -0,0 +1,249 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (C) 2004 Cluster File Systems, Inc.
+ * Author: Nikita Danilov <nikita@clusterfs.com>
+ *
+ * This file is part of Lustre, http://www.lustre.org.
+ *
+ * Lustre is free software; you can redistribute it and/or modify it under the
+ * terms of version 2 of the GNU General Public License as published by the
+ * Free Software Foundation.
+ *
+ * Lustre is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Lustre; if not, write to the Free Software Foundation, Inc., 675 Mass
+ * Ave, Cambridge, MA 02139, USA.
+ *
+ * Implementation of portable time API for XNU kernel
+ *
+ */
+
+#ifndef __LIBCFS_DARWIN_DARWIN_TIME_H__
+#define __LIBCFS_DARWIN_DARWIN_TIME_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+/* Portable time API */
+
+/*
+ * Platform provides three opaque data-types:
+ *
+ *  cfs_time_t        represents point in time. This is internal kernel
+ *                    time rather than "wall clock". This time bears no
+ *                    relation to gettimeofday().
+ *
+ *  cfs_duration_t    represents time interval with resolution of internal
+ *                    platform clock
+ *
+ *  cfs_fs_time_t     represents instance in world-visible time. This is
+ *                    used in file-system time-stamps
+ *
+ *  cfs_time_t     cfs_time_current(void);
+ *  cfs_time_t     cfs_time_add    (cfs_time_t, cfs_duration_t);
+ *  cfs_duration_t cfs_time_sub    (cfs_time_t, cfs_time_t);
+ *  int            cfs_time_before (cfs_time_t, cfs_time_t);
+ *  int            cfs_time_beforeq(cfs_time_t, cfs_time_t);
+ *
+ *  cfs_duration_t cfs_duration_build(int64_t);
+ *
+ *  time_t         cfs_duration_sec (cfs_duration_t);
+ *  void           cfs_duration_usec(cfs_duration_t, struct timeval *);
+ *  void           cfs_duration_nsec(cfs_duration_t, struct timespec *);
+ *
+ *  void           cfs_fs_time_current(cfs_fs_time_t *);
+ *  time_t         cfs_fs_time_sec    (cfs_fs_time_t *);
+ *  void           cfs_fs_time_usec   (cfs_fs_time_t *, struct timeval *);
+ *  void           cfs_fs_time_nsec   (cfs_fs_time_t *, struct timespec *);
+ *  int            cfs_fs_time_before (cfs_fs_time_t *, cfs_fs_time_t *);
+ *  int            cfs_fs_time_beforeq(cfs_fs_time_t *, cfs_fs_time_t *);
+ *
+ *  CFS_TIME_FORMAT
+ *  CFS_DURATION_FORMAT
+ *
+ */
+
+#define ONE_BILLION ((u_int64_t)1000000000)
+#define ONE_MILLION 1000000
+
+#ifdef __KERNEL__
+#include <sys/types.h>
+#include <sys/systm.h>
+
+#include <sys/kernel.h>
+
+#include <mach/mach_types.h>
+#include <mach/time_value.h>
+#include <kern/clock.h>
+#include <sys/param.h>
+
+#include <libcfs/darwin/darwin-types.h>
+#include <libcfs/darwin/darwin-utils.h>
+#include <libcfs/darwin/darwin-lock.h>
+
+/*
+ * There are three way to measure time in OS X:
+ * 1. nanoseconds
+ * 2. absolute time (abstime unit equal to the length of one bus cycle),
+ *    schedule of thread/timer are counted by absolute time, but abstime
+ *    in different mac can be different also, so we wouldn't use it.
+ * 3. clock interval (1sec = 100hz). But clock interval only taken by KPI
+ *    like tsleep().
+ *
+ * We use nanoseconds (uptime, not calendar time)
+ *
+ * clock_get_uptime()   :get absolute time since bootup.
+ * nanouptime()         :get nanoseconds since bootup
+ * microuptime()        :get microseonds since bootup
+ * nanotime()           :get nanoseconds since epoch
+ * microtime()          :get microseconds since epoch
+ */
+typedef u_int64_t cfs_time_t; /* nanoseconds */
+typedef int64_t cfs_duration_t;
+
+#define CFS_TIME_T             "%llu"
+#define CFS_DURATION_T         "%lld"
+
+typedef struct timeval cfs_fs_time_t;
+
+static inline cfs_time_t cfs_time_current(void)
+{
+        struct timespec instant;
+
+        nanouptime(&instant);
+        return ((u_int64_t)instant.tv_sec) * NSEC_PER_SEC + instant.tv_nsec;
+}
+
+static inline time_t cfs_time_current_sec(void)
+{
+        struct timespec instant;
+
+        nanouptime(&instant);
+       return instant.tv_sec;
+}
+
+static inline cfs_time_t cfs_time_add(cfs_time_t t, cfs_duration_t d)
+{
+        return t + d;
+}
+
+static inline cfs_duration_t cfs_time_sub(cfs_time_t t1, cfs_time_t t2)
+{
+        return t1 - t2;
+}
+
+static inline int cfs_time_before(cfs_time_t t1, cfs_time_t t2)
+{
+        return (int64_t)t1 - (int64_t)t2 < 0;
+}
+
+static inline int cfs_time_beforeq(cfs_time_t t1, cfs_time_t t2)
+{
+        return (int64_t)t1 - (int64_t)t2 <= 0;
+}
+
+static inline void cfs_fs_time_current(cfs_fs_time_t *t)
+{
+        microtime((struct timeval *)t);
+}
+
+static inline time_t cfs_fs_time_sec(cfs_fs_time_t *t)
+{
+        return t->tv_sec;
+}
+
+static inline void cfs_fs_time_usec(cfs_fs_time_t *t, struct timeval *v)
+{
+        *v = *t;
+}
+
+static inline void cfs_fs_time_nsec(cfs_fs_time_t *t, struct timespec *s)
+{
+        s->tv_sec  = t->tv_sec;
+        s->tv_nsec = t->tv_usec * NSEC_PER_USEC;
+}
+
+static inline cfs_duration_t cfs_time_seconds(int seconds)
+{
+       return (NSEC_PER_SEC * (int64_t)seconds);
+}
+
+/*
+ * internal helper function used by cfs_fs_time_before*()
+ */
+static inline int64_t __cfs_fs_time_flat(cfs_fs_time_t *t)
+{
+        return ((int64_t)t->tv_sec)*NSEC_PER_SEC + t->tv_usec*NSEC_PER_USEC;
+}
+
+static inline int cfs_fs_time_before(cfs_fs_time_t *t1, cfs_fs_time_t *t2)
+{
+        return __cfs_fs_time_flat(t1) - __cfs_fs_time_flat(t2) < 0;
+}
+
+static inline int cfs_fs_time_beforeq(cfs_fs_time_t *t1, cfs_fs_time_t *t2)
+{
+        return __cfs_fs_time_flat(t1) - __cfs_fs_time_flat(t2) <= 0;
+}
+
+static inline time_t cfs_duration_sec(cfs_duration_t d)
+{
+        return d / NSEC_PER_SEC;
+}
+
+static inline void cfs_duration_usec(cfs_duration_t d, struct timeval *s)
+{
+        s->tv_sec = d / NSEC_PER_SEC;
+        s->tv_usec = (d - ((int64_t)s->tv_sec) * NSEC_PER_SEC) / NSEC_PER_USEC;
+}
+
+static inline void cfs_duration_nsec(cfs_duration_t d, struct timespec *s)
+{
+        s->tv_sec = d / NSEC_PER_SEC;
+        s->tv_nsec = d - ((int64_t)s->tv_sec) * NSEC_PER_SEC;
+}
+
+#define cfs_time_current_64 cfs_time_current
+#define cfs_time_add_64     cfs_time_add
+#define cfs_time_shift_64   cfs_time_shift
+#define cfs_time_before_64  cfs_time_before
+#define cfs_time_beforeq_64 cfs_time_beforeq
+
+/* 
+ * One jiffy (in nanoseconds)
+ *
+ * osfmk/kern/sched_prim.c
+ * #define DEFAULT_PREEMPTION_RATE      100
+ */
+#define CFS_TICK               (NSEC_PER_SEC / (u_int64_t)100)
+
+#define LTIME_S(t)             (t)
+
+/* __KERNEL__ */
+#else
+
+/*
+ * User level
+ */
+#include <libcfs/user-time.h>
+
+/* __KERNEL__ */
+#endif
+
+/* __LIBCFS_DARWIN_DARWIN_TIME_H__ */
+#endif
+/*
+ * Local variables:
+ * c-indentation-style: "K&R"
+ * c-basic-offset: 8
+ * tab-width: 8
+ * fill-column: 80
+ * scroll-step: 1
+ * End:
+ */
diff --git a/libcfs/include/libcfs/darwin/darwin-types.h b/libcfs/include/libcfs/darwin/darwin-types.h
new file mode 100644 (file)
index 0000000..3c24724
--- /dev/null
@@ -0,0 +1,95 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2001 Cluster File Systems, Inc. <braam@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Basic library routines. 
+ *
+ */
+
+#ifndef __LIBCFS_DARWIN_XNU_TYPES_H__
+#define __LIBCFS_DARWIN_XNU_TYPES_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+#include <mach/mach_types.h>
+#include <sys/types.h>
+
+#ifndef _BLKID_TYPES_H
+#define _BLKID_TYPES_H
+#endif
+
+typedef u_int8_t        __u8;
+typedef u_int16_t       __u16;
+typedef u_int32_t       __u32;
+typedef u_int64_t       __u64;
+typedef int8_t          __s8;
+typedef int16_t         __s16;
+typedef int32_t         __s32;
+typedef int64_t         __s64;
+
+#ifdef __KERNEL__
+
+#include <kern/kern_types.h>
+
+
+typedef struct { int e; }              event_chan_t;
+typedef dev_t                          kdev_t;
+
+/*
+ * Atmoic define
+ */
+#include <libkern/OSAtomic.h>
+
+typedef struct { volatile uint32_t counter; }  atomic_t;
+
+#define ATOMIC_INIT(i)                 { (i) }
+#define atomic_read(a)                 ((a)->counter)
+#define atomic_set(a, v)               (((a)->counter) = (v))
+#ifdef __DARWIN8__
+/* OS*Atomic return the value before the operation */
+#define atomic_add(v, a)               OSAddAtomic(v, (SInt32 *)&((a)->counter))
+#define atomic_sub(v, a)               OSAddAtomic(-(v), (SInt32 *)&((a)->counter))
+#define atomic_inc(a)                  OSIncrementAtomic((SInt32 *)&((a)->counter))
+#define atomic_dec(a)                  OSDecrementAtomic((SInt32 *)&((a)->counter))
+#else /* !__DARWIN8__ */
+#define atomic_add(v, a)               hw_atomic_add((__u32 *)&((a)->counter), v)
+#define atomic_sub(v, a)               hw_atomic_sub((__u32 *)&((a)->counter), v)
+#define atomic_inc(a)                  atomic_add(1, a)
+#define atomic_dec(a)                  atomic_sub(1, a)
+#endif /* !__DARWIN8__ */
+#define atomic_sub_and_test(v, a)       (atomic_sub(v, a) == (v))
+#define atomic_dec_and_test(a)          (atomic_dec(a) == 1)
+#define atomic_inc_return(a)            (atomic_inc(a) + 1)
+#define atomic_dec_return(a)            (atomic_dec(a) - 1)
+
+#include <libsa/mach/mach.h>
+typedef off_t                          loff_t;
+
+#else  /* !__KERNEL__ */
+
+#include <stdint.h>
+
+typedef off_t                          loff_t;
+
+#endif /* __KERNEL END */
+typedef unsigned short                  umode_t;
+
+#endif  /* __XNU_CFS_TYPES_H__ */
diff --git a/libcfs/include/libcfs/darwin/darwin-utils.h b/libcfs/include/libcfs/darwin/darwin-utils.h
new file mode 100644 (file)
index 0000000..0f808a2
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef __LIBCFS_DARWIN_UTILS_H__
+#define __LIBCFS_DARWIN_UTILS_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+#include <sys/random.h> 
+
+#ifdef __KERNEL__
+inline int isspace(char c);
+char *strpbrk(const char *cs, const char *ct);
+char * strsep(char **s, const char *ct);
+size_t strnlen(const char * s, size_t count);
+char * strstr(const char *in, const char *str);
+char * strrchr(const char *p, int ch);
+char * ul2dstr(unsigned long address, char *buf, int len);
+
+#define simple_strtol(a1, a2, a3)               strtol(a1, a2, a3)
+#define simple_strtoul(a1, a2, a3)              strtoul(a1, a2, a3)
+#define simple_strtoll(a1, a2, a3)              strtoq(a1, a2, a3)
+#define simple_strtoull(a1, a2, a3)             strtouq(a1, a2, a3)
+
+#define test_bit(i, a)                          isset(a, i)
+#define set_bit(i, a)                           setbit(a, i)
+#define clear_bit(i, a)                         clrbit(a, i)
+
+#define get_random_bytes(buf, len)              read_random(buf, len)
+
+#endif  /* __KERNEL__ */
+
+#ifndef min_t
+#define min_t(type,x,y) \
+       ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
+#endif
+#ifndef max_t
+#define max_t(type,x,y) \
+       ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })
+#endif
+
+#define do_div(n,base)                          \
+       ({                                      \
+        __u64 __n = (n);                       \
+        __u32 __base = (base);                 \
+        __u32 __mod;                           \
+                                               \
+        __mod = __n % __base;                  \
+        n = __n / __base;                      \
+        __mod;                                 \
+        })
+
+#define NIPQUAD(addr)                  \
+       ((unsigned char *)&addr)[0],    \
+       ((unsigned char *)&addr)[1],    \
+       ((unsigned char *)&addr)[2],    \
+       ((unsigned char *)&addr)[3]
+
+#define HIPQUAD NIPQUAD
+
+#ifndef LIST_CIRCLE
+#define LIST_CIRCLE(elm, field)                                 \
+       do {                                                    \
+               (elm)->field.le_prev = &(elm)->field.le_next;   \
+       } while (0)
+#endif
+
+#endif /* __XNU_UTILS_H__ */
diff --git a/libcfs/include/libcfs/darwin/kp30.h b/libcfs/include/libcfs/darwin/kp30.h
new file mode 100644 (file)
index 0000000..f9e94b1
--- /dev/null
@@ -0,0 +1,101 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ */
+#ifndef __LIBCFS_DARWIN_KP30__
+#define __LIBCFS_DARWIN_KP30__
+
+#ifndef __LIBCFS_KP30_H__
+#error Do not #include this file directly. #include <libcfs/kp30.h> instead
+#endif
+
+#ifdef __KERNEL__
+
+#include <sys/types.h>
+#include <sys/malloc.h>
+#include <sys/systm.h>
+#include <mach/mach_types.h>
+#include <string.h>
+#include <sys/file.h>
+#include <sys/conf.h>
+#include <miscfs/devfs/devfs.h>
+#include <stdarg.h>
+
+#include <libcfs/darwin/darwin-lock.h>
+#include <libcfs/darwin/darwin-prim.h>
+#include <lnet/lnet.h>
+
+#define our_cond_resched() cfs_schedule_timeout(CFS_TASK_INTERRUPTIBLE, 1)
+
+#ifdef CONFIG_SMP
+#define LASSERT_SPIN_LOCKED(lock) do {} while(0) /* XXX */
+#else
+#define LASSERT_SPIN_LOCKED(lock) do {} while(0)
+#endif
+#define LASSERT_SEM_LOCKED(sem) do {} while(0) /* XXX */
+
+#define LIBCFS_PANIC(msg) panic(msg)
+#error libcfs_register_panic_notifier() missing
+#error libcfs_unregister_panic_notifier() missing
+
+/* --------------------------------------------------------------------- */
+
+#define PORTAL_SYMBOL_REGISTER(x)               cfs_symbol_register(#x, &x)
+#define PORTAL_SYMBOL_UNREGISTER(x)             cfs_symbol_unregister(#x)
+
+#define PORTAL_SYMBOL_GET(x)                    ((typeof(&x))cfs_symbol_get(#x))
+#define PORTAL_SYMBOL_PUT(x)                    cfs_symbol_put(#x)
+
+#define PORTAL_MODULE_USE                       do{int i = 0; i++;}while(0)
+#define PORTAL_MODULE_UNUSE                     do{int i = 0; i--;}while(0)
+
+#define num_online_cpus()                       cfs_online_cpus()
+
+/******************************************************************************/
+/* XXX Liang: There is no module parameter supporting in OSX */
+#define CFS_MODULE_PARM(name, t, type, perm, desc)
+
+#define CFS_SYSFS_MODULE_PARM    0 /* no sysfs access to module parameters */
+/******************************************************************************/
+
+#else  /* !__KERNEL__ */
+# include <stdio.h>
+# include <stdlib.h>
+# include <stdint.h>
+# include <unistd.h>
+# include <time.h>
+# include <machine/limits.h>
+# include <sys/types.h>
+#endif
+
+#define BITS_PER_LONG   LONG_BIT
+/******************************************************************************/
+/* Light-weight trace
+ * Support for temporary event tracing with minimal Heisenberg effect. */
+#define LWT_SUPPORT  0
+
+typedef struct {
+        long long   lwte_when;
+        char       *lwte_where;
+        void       *lwte_task;
+        long        lwte_p1;
+        long        lwte_p2;
+        long        lwte_p3;
+        long        lwte_p4;
+} lwt_event_t;
+
+# define LWT_EVENT(p1,p2,p3,p4)     /* no lwt implementation yet */
+
+/* -------------------------------------------------------------------------- */
+
+#define IOCTL_LIBCFS_TYPE struct libcfs_ioctl_data
+
+#define LPU64 "%llu"
+#define LPD64 "%lld"
+#define LPX64 "%#llx"
+#define LPSZ  "%lu"
+#define LPSSZ "%ld"
+# define LI_POISON ((int)0x5a5a5a5a)
+# define LL_POISON ((long)0x5a5a5a5a)
+# define LP_POISON ((void *)(long)0x5a5a5a5a)
+
+#endif
diff --git a/libcfs/include/libcfs/darwin/libcfs.h b/libcfs/include/libcfs/darwin/libcfs.h
new file mode 100644 (file)
index 0000000..eb4d8f3
--- /dev/null
@@ -0,0 +1,193 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ */
+#ifndef __LIBCFS_DARWIN_LIBCFS_H__
+#define __LIBCFS_DARWIN_LIBCFS_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+#include <mach/mach_types.h>
+#include <sys/errno.h>
+#include <string.h>
+#include <libcfs/darwin/darwin-types.h>
+#include <libcfs/darwin/darwin-time.h>
+#include <libcfs/darwin/darwin-prim.h>
+#include <libcfs/darwin/darwin-mem.h>
+#include <libcfs/darwin/darwin-lock.h>
+#include <libcfs/darwin/darwin-fs.h>
+#include <libcfs/darwin/darwin-tcpip.h>
+
+#ifdef __KERNEL__
+# include <sys/types.h>
+# include <sys/time.h>
+# define do_gettimeofday(tv) microuptime(tv)
+#else
+# include <sys/time.h>
+# define do_gettimeofday(tv) gettimeofday(tv, NULL);
+typedef unsigned long long cycles_t;
+#endif
+
+#define __cpu_to_le64(x)                        OSSwapHostToLittleInt64(x)
+#define __cpu_to_le32(x)                        OSSwapHostToLittleInt32(x)
+#define __cpu_to_le16(x)                        OSSwapHostToLittleInt16(x)
+
+#define __le16_to_cpu(x)                        OSSwapLittleToHostInt16(x)
+#define __le32_to_cpu(x)                        OSSwapLittleToHostInt32(x)
+#define __le64_to_cpu(x)                        OSSwapLittleToHostInt64(x)
+
+#define cpu_to_le64(x)                          __cpu_to_le64(x)
+#define cpu_to_le32(x)                          __cpu_to_le32(x)
+#define cpu_to_le16(x)                          __cpu_to_le16(x)
+
+#define le64_to_cpu(x)                          __le64_to_cpu(x)
+#define le32_to_cpu(x)                          __le32_to_cpu(x)
+#define le16_to_cpu(x)                          __le16_to_cpu(x)
+
+#define __swab16(x)                             OSSwapInt16(x)
+#define __swab32(x)                             OSSwapInt32(x)
+#define __swab64(x)                             OSSwapInt64(x)
+#define __swab16s(x)                            do { *(x) = __swab16(*(x)); } while (0)
+#define __swab32s(x)                            do { *(x) = __swab32(*(x)); } while (0)
+#define __swab64s(x)                            do { *(x) = __swab64(*(x)); } while (0)
+
+struct ptldebug_header {
+        __u32 ph_len;
+        __u32 ph_flags;
+        __u32 ph_subsys;
+        __u32 ph_mask;
+        __u32 ph_cpu_id;
+        __u32 ph_sec;
+        __u64 ph_usec;
+        __u32 ph_stack;
+        __u32 ph_pid;
+        __u32 ph_extern_pid;
+        __u32 ph_line_num;
+} __attribute__((packed));
+
+
+#ifdef __KERNEL__
+# include <sys/systm.h>
+# include <pexpert/pexpert.h>
+/* Fix me */
+# define THREAD_SIZE 8192
+#else
+# define THREAD_SIZE 8192
+#endif
+#define LUSTRE_TRACE_SIZE (THREAD_SIZE >> 5)
+
+#define CHECK_STACK() do { } while(0)
+#define CDEBUG_STACK() (0L)
+
+/* Darwin has defined RETURN, so we have to undef it in lustre */
+#ifdef RETURN
+#undef RETURN
+#endif
+
+/*
+ * When this is enabled debugging messages are indented according to the
+ * current "nesting level". Nesting level in increased when ENTRY macro
+ * is executed, and decreased on EXIT and RETURN.
+ */
+#ifdef __KERNEL__
+#define ENTRY_NESTING_SUPPORT (0)
+#endif
+
+#if ENTRY_NESTING_SUPPORT
+
+/*
+ * Currently ENTRY_NESTING_SUPPORT is only supported for XNU port. Basic
+ * idea is to keep per-thread pointer to small data structure (struct
+ * cfs_debug_data) describing current nesting level. In XNU unused
+ * proc->p_wmegs field in hijacked for this. On Linux
+ * current->journal_info can be used. In user space
+ * pthread_{g,s}etspecific().
+ *
+ * ENTRY macro allocates new cfs_debug_data on stack, and installs it as
+ * a current nesting level, storing old data in cfs_debug_data it just
+ * created.
+ *
+ * EXIT pops old value back.
+ *
+ */
+
+/*
+ * One problem with this approach is that there is a lot of code that
+ * does ENTRY and then escapes scope without doing EXIT/RETURN. In this
+ * case per-thread current nesting level pointer is dangling (it points
+ * to the stack area that is possible already overridden). To detect
+ * such cases, we add two magic fields to the cfs_debug_data and check
+ * them whenever current nesting level pointer is dereferenced. While
+ * looking flaky this works because stack is always consumed
+ * "continously".
+ */
+enum {
+       CDD_MAGIC1 = 0x02128506,
+       CDD_MAGIC2 = 0x42424242
+};
+
+struct cfs_debug_data {
+       unsigned int           magic1;
+       struct cfs_debug_data *parent;
+       int                    nesting_level;
+       unsigned int           magic2;
+};
+
+void __entry_nesting(struct cfs_debug_data *child);
+void __exit_nesting(struct cfs_debug_data *child);
+unsigned int __current_nesting_level(void);
+
+#define ENTRY_NESTING                                          \
+struct cfs_debug_data __cdd = { .magic1        = CDD_MAGIC1,   \
+                               .parent        = NULL,          \
+                                .nesting_level = 0,            \
+                                .magic2        = CDD_MAGIC2 }; \
+__entry_nesting(&__cdd);
+
+#define EXIT_NESTING __exit_nesting(&__cdd)
+
+/* ENTRY_NESTING_SUPPORT */
+#else
+
+#define ENTRY_NESTING   do {;} while (0)
+#define EXIT_NESTING   do {;} while (0)
+#define __current_nesting_level() (0)
+
+/* ENTRY_NESTING_SUPPORT */
+#endif
+
+#define LUSTRE_LNET_PID          12345
+
+#define _XNU_LIBCFS_H
+
+/*
+ * Platform specific declarations for cfs_curproc API (libcfs/curproc.h)
+ *
+ * Implementation is in darwin-curproc.c
+ */
+#define CFS_CURPROC_COMM_MAX    MAXCOMLEN
+/*
+ * XNU has no capabilities
+ */
+typedef int cfs_kernel_cap_t;
+
+#ifdef __KERNEL__
+enum {
+        /* if you change this, update darwin-util.c:cfs_stack_trace_fill() */
+        CFS_STACK_TRACE_DEPTH = 16
+};
+
+struct cfs_stack_trace {
+        void *frame[CFS_STACK_TRACE_DEPTH];
+};
+
+#define printk(format, args...)                 printf(format, ## args)
+
+#ifdef WITH_WATCHDOG
+#undef WITH_WATCHDOG
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* _XNU_LIBCFS_H */
diff --git a/libcfs/include/libcfs/darwin/lltrace.h b/libcfs/include/libcfs/darwin/lltrace.h
new file mode 100644 (file)
index 0000000..31d6e17
--- /dev/null
@@ -0,0 +1,26 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ */
+#ifndef __LIBCFS_DARWIN_LLTRACE_H__
+#define __LIBCFS_DARWIN_LLTRACE_H__
+
+#ifndef __LIBCFS_LLTRACE_H__
+#error Do not #include this file directly. #include <libcfs/lltrace.h> instead
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <lnet/types.h>
+#include <libcfs/kp30.h>
+#include <mach/vm_param.h>
+#include <lnet/lnetctl.h>
+
+#endif
diff --git a/libcfs/include/libcfs/darwin/portals_utils.h b/libcfs/include/libcfs/darwin/portals_utils.h
new file mode 100644 (file)
index 0000000..4907cb1
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef __LIBCFS_DARWIN_PORTALS_UTILS_H__
+#define __LIBCFS_DARWIN_PORTALS_UTILS_H__
+
+#ifndef __LIBCFS_PORTALS_UTILS_H__
+#error Do not #include this file directly. #include <libcfs/portals_utils.h> instead
+#endif
+
+#include <libcfs/list.h>
+#ifdef __KERNEL__
+#include <mach/mach_types.h>
+#include <libcfs/libcfs.h>
+#else /* !__KERNEL__ */
+#include <machine/endian.h>
+#include <netinet/in.h>
+#include <sys/syscall.h>
+#endif /* !__KERNEL__ */
+
+#endif
diff --git a/libcfs/include/libcfs/kp30.h b/libcfs/include/libcfs/kp30.h
new file mode 100644 (file)
index 0000000..0869f67
--- /dev/null
@@ -0,0 +1,610 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ */
+#ifndef __LIBCFS_KP30_H__
+#define __LIBCFS_KP30_H__
+
+/* Controlled via configure key */
+/* #define LIBCFS_DEBUG */
+
+#include <libcfs/libcfs.h>
+#include <lnet/types.h>
+
+#if defined(__linux__)
+#include <libcfs/linux/kp30.h>
+#elif defined(__APPLE__)
+#include <libcfs/darwin/kp30.h>
+#elif defined(__WINNT__)
+#include <libcfs/winnt/kp30.h>
+#else
+#error Unsupported operating system
+#endif
+
+#ifndef DEBUG_SUBSYSTEM
+# define DEBUG_SUBSYSTEM S_UNDEFINED
+#endif
+
+#ifdef __KERNEL__
+
+#ifdef LIBCFS_DEBUG
+
+/*
+ * When this is on, LASSERT macro includes check for assignment used instead
+ * of equality check, but doesn't have unlikely(). Turn this on from time to
+ * time to make test-builds. This shouldn't be on for production release.
+ */
+#define LASSERT_CHECKED (0)
+
+#if LASSERT_CHECKED
+/*
+ * Assertion.
+ *
+ * Strange construction with empty "then" clause is used to trigger compiler
+ * warnings on the assertions of the form LASSERT(a = b);
+ *
+ * "warning: suggest parentheses around assignment used as truth value"
+ *
+ * requires -Wall. Unfortunately this rules out use of likely/unlikely.
+ */
+#define LASSERT(cond)                                           \
+({                                                              \
+        if (cond)                                               \
+                ;                                               \
+        else                                                    \
+                libcfs_assertion_failed( #cond , __FILE__,      \
+                        __FUNCTION__, __LINE__);                \
+})
+
+#define LASSERTF(cond, fmt, a...)                                       \
+({                                                                      \
+         if (cond)                                                      \
+                 ;                                                      \
+         else {                                                         \
+                 libcfs_debug_msg(NULL, DEBUG_SUBSYSTEM, D_EMERG,       \
+                                  __FILE__, __FUNCTION__,__LINE__,      \
+                                  "ASSERTION(" #cond ") failed:" fmt,   \
+                                  ## a);                                \
+                 LBUG();                                                \
+         }                                                              \
+})
+
+/* LASSERT_CHECKED */
+#else
+
+#define LASSERT(cond)                                           \
+({                                                              \
+        if (unlikely(!(cond)))                                  \
+                libcfs_assertion_failed(#cond , __FILE__,       \
+                        __FUNCTION__, __LINE__);                \
+})
+
+#define LASSERTF(cond, fmt, a...)                                       \
+({                                                                      \
+        if (unlikely(!(cond))) {                                        \
+                libcfs_debug_msg(NULL, DEBUG_SUBSYSTEM, D_EMERG,        \
+                                 __FILE__, __FUNCTION__,__LINE__,       \
+                                 "ASSERTION(" #cond ") failed:" fmt,    \
+                                 ## a);                                 \
+                LBUG();                                                 \
+        }                                                               \
+})
+
+/* LASSERT_CHECKED */
+#endif
+
+/* LIBCFS_DEBUG */
+#else
+#define LASSERT(e) ((void)(0))
+#define LASSERTF(cond, fmt...) ((void)(0))
+#endif /* LIBCFS_DEBUG */
+
+#define KLASSERT(e) LASSERT(e)
+
+void lbug_with_loc(char *file, const char *func, const int line)
+        __attribute__((noreturn));
+
+#define LBUG() lbug_with_loc(__FILE__, __FUNCTION__, __LINE__)
+
+extern atomic_t libcfs_kmemory;
+/*
+ * Memory
+ */
+#ifdef LIBCFS_DEBUG
+
+# define libcfs_kmem_inc(ptr, size)             \
+do {                                            \
+        atomic_add(size, &libcfs_kmemory);      \
+} while (0)
+
+# define libcfs_kmem_dec(ptr, size) do {        \
+        atomic_sub(size, &libcfs_kmemory);      \
+} while (0)
+
+#else
+# define libcfs_kmem_inc(ptr, size) do {} while (0)
+# define libcfs_kmem_dec(ptr, size) do {} while (0)
+#endif /* LIBCFS_DEBUG */
+
+#define LIBCFS_VMALLOC_SIZE        16384
+
+#define LIBCFS_ALLOC_GFP(ptr, size, mask)                                 \
+do {                                                                      \
+        LASSERT(!in_interrupt() ||                                        \
+               (size <= LIBCFS_VMALLOC_SIZE && mask == CFS_ALLOC_ATOMIC));\
+        if (unlikely((size) > LIBCFS_VMALLOC_SIZE))                     \
+                (ptr) = cfs_alloc_large(size);                            \
+        else                                                              \
+                (ptr) = cfs_alloc((size), (mask));                        \
+        if (unlikely((ptr) == NULL)) {                                  \
+                CERROR("LNET: out of memory at %s:%d (tried to alloc '"   \
+                       #ptr "' = %d)\n", __FILE__, __LINE__, (int)(size));\
+                CERROR("LNET: %d total bytes allocated by lnet\n",        \
+                       atomic_read(&libcfs_kmemory));                     \
+        } else {                                                          \
+                libcfs_kmem_inc((ptr), (size));                           \
+                if (!((mask) & CFS_ALLOC_ZERO))                           \
+                       memset((ptr), 0, (size));                          \
+        }                                                                 \
+        CDEBUG(D_MALLOC, "kmalloced '" #ptr "': %d at %p (tot %d).\n",    \
+               (int)(size), (ptr), atomic_read (&libcfs_kmemory));        \
+} while (0)
+
+#define LIBCFS_ALLOC(ptr, size) \
+        LIBCFS_ALLOC_GFP(ptr, size, CFS_ALLOC_IO)
+
+#define LIBCFS_ALLOC_ATOMIC(ptr, size) \
+        LIBCFS_ALLOC_GFP(ptr, size, CFS_ALLOC_ATOMIC)
+
+#define LIBCFS_FREE(ptr, size)                                          \
+do {                                                                    \
+        int s = (size);                                                 \
+        if (unlikely((ptr) == NULL)) {                                  \
+                CERROR("LIBCFS: free NULL '" #ptr "' (%d bytes) at "    \
+                       "%s:%d\n", s, __FILE__, __LINE__);               \
+                break;                                                  \
+        }                                                               \
+        if (unlikely(s > LIBCFS_VMALLOC_SIZE))                          \
+                cfs_free_large(ptr);                                    \
+        else                                                            \
+                cfs_free(ptr);                                          \
+        libcfs_kmem_dec((ptr), s);                                      \
+        CDEBUG(D_MALLOC, "kfreed '" #ptr "': %d at %p (tot %d).\n",     \
+               s, (ptr), atomic_read(&libcfs_kmemory));                 \
+} while (0)
+
+/******************************************************************************/
+
+/* htonl hack - either this, or compile with -O2. Stupid byteorder/generic.h */
+#if defined(__GNUC__) && (__GNUC__ >= 2) && !defined(__OPTIMIZE__)
+#define ___htonl(x) __cpu_to_be32(x)
+#define ___htons(x) __cpu_to_be16(x)
+#define ___ntohl(x) __be32_to_cpu(x)
+#define ___ntohs(x) __be16_to_cpu(x)
+#define htonl(x) ___htonl(x)
+#define ntohl(x) ___ntohl(x)
+#define htons(x) ___htons(x)
+#define ntohs(x) ___ntohs(x)
+#endif
+
+void libcfs_debug_dumpstack(cfs_task_t *tsk);
+void libcfs_run_upcall(char **argv);
+void libcfs_run_lbug_upcall(char * file, const char *fn, const int line);
+void libcfs_debug_dumplog(void);
+int libcfs_debug_init(unsigned long bufsize);
+int libcfs_debug_cleanup(void);
+int libcfs_debug_clear_buffer(void);
+int libcfs_debug_mark_buffer(char *text);
+
+void libcfs_debug_set_level(unsigned int debug_level);
+
+#else  /* !__KERNEL__ */
+# ifdef LIBCFS_DEBUG
+#  undef NDEBUG
+#  include <assert.h>
+#  define LASSERT(e)     assert(e)
+#  define LASSERTF(cond, args...)                                              \
+do {                                                                           \
+          if (!(cond))                                                         \
+                CERROR(args);                                                  \
+          assert(cond);                                                        \
+} while (0)
+#  define LBUG()   assert(0)
+# else
+#  define LASSERT(e) ((void)(0))
+#  define LASSERTF(cond, args...) do { } while (0)
+#  define LBUG()   ((void)(0))
+# endif /* LIBCFS_DEBUG */
+# define KLASSERT(e) do { } while (0)
+# define printk(format, args...) printf (format, ## args)
+# ifdef CRAY_XT3                                /* buggy calloc! */
+#  define LIBCFS_ALLOC(ptr, size)               \
+   do {                                         \
+        (ptr) = malloc(size);                   \
+        memset(ptr, 0, size);                   \
+   } while (0)
+# else
+#  define LIBCFS_ALLOC(ptr, size) do { (ptr) = calloc(1,size); } while (0)
+# endif
+# define LIBCFS_FREE(a, b) do { free(a); } while (0)
+
+void libcfs_debug_dumplog(void);
+int libcfs_debug_init(unsigned long bufsize);
+int libcfs_debug_cleanup(void);
+
+/*
+ * Generic compiler-dependent macros required for kernel
+ * build go below this comment. Actual compiler/compiler version
+ * specific implementations come from the above header files
+ */
+
+#define likely(x)      __builtin_expect(!!(x), 1)
+#define unlikely(x)    __builtin_expect(!!(x), 0)
+
+/* !__KERNEL__ */
+#endif
+
+/*
+ * compile-time assertions. @cond has to be constant expression.
+ * ISO C Standard:
+ *
+ *        6.8.4.2  The switch statement
+ *
+ *       ....
+ *
+ *       [#3] The expression of each case label shall be  an  integer
+ *       constant   expression  and  no  two  of  the  case  constant
+ *       expressions in the same switch statement shall have the same
+ *       value  after  conversion...
+ *
+ */
+#define CLASSERT(cond) ({ switch(42) { case (cond): case 0: break; } })
+
+/* support decl needed both by kernel and liblustre */
+int         libcfs_isknown_lnd(int type);
+char       *libcfs_lnd2modname(int type);
+char       *libcfs_lnd2str(int type);
+int         libcfs_str2lnd(const char *str);
+char       *libcfs_net2str(__u32 net);
+char       *libcfs_nid2str(lnet_nid_t nid);
+__u32       libcfs_str2net(const char *str);
+lnet_nid_t  libcfs_str2nid(const char *str);
+int         libcfs_str2anynid(lnet_nid_t *nid, const char *str);
+char       *libcfs_id2str(lnet_process_id_t id);
+void        libcfs_setnet0alias(int type);
+
+/* how an LNET NID encodes net:address */
+#define LNET_NIDADDR(nid)      ((__u32)((nid) & 0xffffffff))
+#define LNET_NIDNET(nid)       ((__u32)(((nid) >> 32)) & 0xffffffff)
+#define LNET_MKNID(net,addr)   ((((__u64)(net))<<32)|((__u64)(addr)))
+/* how net encodes type:number */
+#define LNET_NETNUM(net)       ((net) & 0xffff)
+#define LNET_NETTYP(net)       (((net) >> 16) & 0xffff)
+#define LNET_MKNET(typ,num)    ((((__u32)(typ))<<16)|((__u32)(num)))
+
+/* implication */
+#define ergo(a, b) (!(a) || (b))
+/* logical equivalence */
+#define equi(a, b) (!!(a) == !!(b))
+
+#ifndef CURRENT_TIME
+# define CURRENT_TIME time(0)
+#endif
+
+/* --------------------------------------------------------------------
+ * Light-weight trace
+ * Support for temporary event tracing with minimal Heisenberg effect.
+ * All stuff about lwt are put in arch/kp30.h
+ * -------------------------------------------------------------------- */
+
+struct libcfs_device_userstate
+{
+        int           ldu_memhog_pages;
+        cfs_page_t   *ldu_memhog_root_page;
+};
+
+/* what used to be in portals_lib.h */
+#ifndef MIN
+# define MIN(a,b) (((a)<(b)) ? (a): (b))
+#endif
+#ifndef MAX
+# define MAX(a,b) (((a)>(b)) ? (a): (b))
+#endif
+
+#define MKSTR(ptr) ((ptr))? (ptr) : ""
+
+static inline int size_round4 (int val)
+{
+        return (val + 3) & (~0x3);
+}
+
+static inline int size_round (int val)
+{
+        return (val + 7) & (~0x7);
+}
+
+static inline int size_round16(int val)
+{
+        return (val + 0xf) & (~0xf);
+}
+
+static inline int size_round32(int val)
+{
+        return (val + 0x1f) & (~0x1f);
+}
+
+static inline int size_round0(int val)
+{
+        if (!val)
+                return 0;
+        return (val + 1 + 7) & (~0x7);
+}
+
+static inline size_t round_strlen(char *fset)
+{
+        return (size_t)size_round((int)strlen(fset) + 1);
+}
+
+#define LOGL(var,len,ptr)                                       \
+do {                                                            \
+        if (var)                                                \
+                memcpy((char *)ptr, (const char *)var, len);    \
+        ptr += size_round(len);                                 \
+} while (0)
+
+#define LOGU(var,len,ptr)                                       \
+do {                                                            \
+        if (var)                                                \
+                memcpy((char *)var, (const char *)ptr, len);    \
+        ptr += size_round(len);                                 \
+} while (0)
+
+#define LOGL0(var,len,ptr)                              \
+do {                                                    \
+        if (!len)                                       \
+                break;                                  \
+        memcpy((char *)ptr, (const char *)var, len);    \
+        *((char *)(ptr) + len) = 0;                     \
+        ptr += size_round(len + 1);                     \
+} while (0)
+
+/*
+ * USER LEVEL STUFF BELOW
+ */
+
+#define LIBCFS_IOCTL_VERSION 0x0001000a
+
+struct libcfs_ioctl_data {
+        __u32 ioc_len;
+        __u32 ioc_version;
+
+        __u64 ioc_nid;
+        __u64 ioc_u64[1];
+
+        __u32 ioc_flags;
+        __u32 ioc_count;
+        __u32 ioc_net;
+        __u32 ioc_u32[7];
+
+        __u32 ioc_inllen1;
+        char *ioc_inlbuf1;
+        __u32 ioc_inllen2;
+        char *ioc_inlbuf2;
+
+        __u32 ioc_plen1; /* buffers in userspace */
+        char *ioc_pbuf1;
+        __u32 ioc_plen2; /* buffers in userspace */
+        char *ioc_pbuf2;
+
+        char ioc_bulk[0];
+};
+
+
+struct libcfs_ioctl_hdr {
+        __u32 ioc_len;
+        __u32 ioc_version;
+};
+
+struct libcfs_debug_ioctl_data
+{
+        struct libcfs_ioctl_hdr hdr;
+        unsigned int subs;
+        unsigned int debug;
+};
+
+#define LIBCFS_IOC_INIT(data)                           \
+do {                                                    \
+        memset(&data, 0, sizeof(data));                 \
+        data.ioc_version = LIBCFS_IOCTL_VERSION;        \
+        data.ioc_len = sizeof(data);                    \
+} while (0)
+
+/* FIXME check conflict with lustre_lib.h */
+#define LIBCFS_IOC_DEBUG_MASK             _IOWR('f', 250, long)
+
+static inline int libcfs_ioctl_packlen(struct libcfs_ioctl_data *data)
+{
+        int len = sizeof(*data);
+        len += size_round(data->ioc_inllen1);
+        len += size_round(data->ioc_inllen2);
+        return len;
+}
+
+static inline int libcfs_ioctl_is_invalid(struct libcfs_ioctl_data *data)
+{
+        if (data->ioc_len > (1<<30)) {
+                CERROR ("LIBCFS ioctl: ioc_len larger than 1<<30\n");
+                return 1;
+        }
+        if (data->ioc_inllen1 > (1<<30)) {
+                CERROR ("LIBCFS ioctl: ioc_inllen1 larger than 1<<30\n");
+                return 1;
+        }
+        if (data->ioc_inllen2 > (1<<30)) {
+                CERROR ("LIBCFS ioctl: ioc_inllen2 larger than 1<<30\n");
+                return 1;
+        }
+        if (data->ioc_inlbuf1 && !data->ioc_inllen1) {
+                CERROR ("LIBCFS ioctl: inlbuf1 pointer but 0 length\n");
+                return 1;
+        }
+        if (data->ioc_inlbuf2 && !data->ioc_inllen2) {
+                CERROR ("LIBCFS ioctl: inlbuf2 pointer but 0 length\n");
+                return 1;
+        }
+        if (data->ioc_pbuf1 && !data->ioc_plen1) {
+                CERROR ("LIBCFS ioctl: pbuf1 pointer but 0 length\n");
+                return 1;
+        }
+        if (data->ioc_pbuf2 && !data->ioc_plen2) {
+                CERROR ("LIBCFS ioctl: pbuf2 pointer but 0 length\n");
+                return 1;
+        }
+        if (data->ioc_plen1 && !data->ioc_pbuf1) {
+                CERROR ("LIBCFS ioctl: plen1 nonzero but no pbuf1 pointer\n");
+                return 1;
+        }
+        if (data->ioc_plen2 && !data->ioc_pbuf2) {
+                CERROR ("LIBCFS ioctl: plen2 nonzero but no pbuf2 pointer\n");
+                return 1;
+        }
+        if ((__u32)libcfs_ioctl_packlen(data) != data->ioc_len ) {
+                CERROR ("LIBCFS ioctl: packlen != ioc_len\n");
+                return 1;
+        }
+        if (data->ioc_inllen1 &&
+            data->ioc_bulk[data->ioc_inllen1 - 1] != '\0') {
+                CERROR ("LIBCFS ioctl: inlbuf1 not 0 terminated\n");
+                return 1;
+        }
+        if (data->ioc_inllen2 &&
+            data->ioc_bulk[size_round(data->ioc_inllen1) +
+                           data->ioc_inllen2 - 1] != '\0') {
+                CERROR ("LIBCFS ioctl: inlbuf2 not 0 terminated\n");
+                return 1;
+        }
+        return 0;
+}
+
+#ifndef __KERNEL__
+static inline int libcfs_ioctl_pack(struct libcfs_ioctl_data *data, char **pbuf,
+                                    int max)
+{
+        char *ptr;
+        struct libcfs_ioctl_data *overlay;
+        data->ioc_len = libcfs_ioctl_packlen(data);
+        data->ioc_version = LIBCFS_IOCTL_VERSION;
+
+        if (*pbuf && libcfs_ioctl_packlen(data) > max)
+                return 1;
+        if (*pbuf == NULL) {
+                *pbuf = malloc(data->ioc_len);
+        }
+        if (!*pbuf)
+                return 1;
+        overlay = (struct libcfs_ioctl_data *)*pbuf;
+        memcpy(*pbuf, data, sizeof(*data));
+
+        ptr = overlay->ioc_bulk;
+        if (data->ioc_inlbuf1)
+                LOGL(data->ioc_inlbuf1, data->ioc_inllen1, ptr);
+        if (data->ioc_inlbuf2)
+                LOGL(data->ioc_inlbuf2, data->ioc_inllen2, ptr);
+        if (libcfs_ioctl_is_invalid(overlay))
+                return 1;
+
+        return 0;
+}
+
+#else
+
+extern int libcfs_ioctl_getdata(char *buf, char *end, void *arg);
+extern int libcfs_ioctl_popdata(void *arg, void *buf, int size);
+
+#endif
+
+/* ioctls for manipulating snapshots 30- */
+#define IOC_LIBCFS_TYPE                   'e'
+#define IOC_LIBCFS_MIN_NR                 30
+/* libcfs ioctls */
+#define IOC_LIBCFS_PANIC                   _IOWR('e', 30, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_CLEAR_DEBUG             _IOWR('e', 31, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_MARK_DEBUG              _IOWR('e', 32, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_LWT_CONTROL             _IOWR('e', 33, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_LWT_SNAPSHOT            _IOWR('e', 34, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_LWT_LOOKUP_STRING       _IOWR('e', 35, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_MEMHOG                  _IOWR('e', 36, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_PING_TEST               _IOWR('e', 37, IOCTL_LIBCFS_TYPE)
+/* lnet ioctls */
+#define IOC_LIBCFS_GET_NI                  _IOWR('e', 50, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_FAIL_NID                _IOWR('e', 51, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_ADD_ROUTE               _IOWR('e', 52, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_DEL_ROUTE               _IOWR('e', 53, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_GET_ROUTE               _IOWR('e', 54, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_NOTIFY_ROUTER           _IOWR('e', 55, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_UNCONFIGURE             _IOWR('e', 56, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_PORTALS_COMPATIBILITY   _IOWR('e', 57, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_LNET_DIST               _IOWR('e', 58, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_CONFIGURE               _IOWR('e', 59, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_TESTPROTOCOMPAT         _IOWR('e', 60, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_PING                    _IOWR('e', 61, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_DEBUG_PEER              _IOWR('e', 62, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_LNETST                  _IOWR('e', 63, IOCTL_LIBCFS_TYPE)
+/* lnd ioctls */
+#define IOC_LIBCFS_REGISTER_MYNID          _IOWR('e', 70, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_CLOSE_CONNECTION        _IOWR('e', 71, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_PUSH_CONNECTION         _IOWR('e', 72, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_GET_CONN                _IOWR('e', 73, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_DEL_PEER                _IOWR('e', 74, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_ADD_PEER                _IOWR('e', 75, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_GET_PEER                _IOWR('e', 76, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_GET_TXDESC              _IOWR('e', 77, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_ADD_INTERFACE           _IOWR('e', 78, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_DEL_INTERFACE           _IOWR('e', 79, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_GET_INTERFACE           _IOWR('e', 80, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_GET_GMID                _IOWR('e', 81, IOCTL_LIBCFS_TYPE)
+
+#define IOC_LIBCFS_MAX_NR                             81
+
+
+enum {
+        /* Only add to these values (i.e. don't ever change or redefine them):
+         * network addresses depend on them... */
+        QSWLND    = 1,
+        SOCKLND   = 2,
+        GMLND     = 3,
+        PTLLND    = 4,
+        O2IBLND   = 5,
+        CIBLND    = 6,
+        OPENIBLND = 7,
+        IIBLND    = 8,
+        LOLND     = 9,
+        RALND     = 10,
+        VIBLND    = 11,
+        MXLND     = 12,
+};
+
+enum {
+        DEBUG_DAEMON_START       =  1,
+        DEBUG_DAEMON_STOP        =  2,
+        DEBUG_DAEMON_PAUSE       =  3,
+        DEBUG_DAEMON_CONTINUE    =  4,
+};
+
+
+enum cfg_record_type {
+        PORTALS_CFG_TYPE = 1,
+        LUSTRE_CFG_TYPE = 123,
+};
+
+typedef int (*cfg_record_cb_t)(enum cfg_record_type, int len, void *data);
+
+/* lustre_id output helper macros */
+#define DLID4   "%lu/%lu/%lu/%lu"
+
+#define OLID4(id)                              \
+    (unsigned long)(id)->li_fid.lf_id,         \
+    (unsigned long)(id)->li_fid.lf_group,      \
+    (unsigned long)(id)->li_stc.u.e3s.l3s_ino, \
+    (unsigned long)(id)->li_stc.u.e3s.l3s_gen
+
+#endif
diff --git a/libcfs/include/libcfs/libcfs.h b/libcfs/include/libcfs/libcfs.h
new file mode 100644 (file)
index 0000000..80518b1
--- /dev/null
@@ -0,0 +1,649 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ */
+#ifndef __LIBCFS_LIBCFS_H__
+#define __LIBCFS_LIBCFS_H__
+
+#if !__GNUC__
+#define __attribute__(x)
+#endif
+
+#if defined(__linux__)
+#include <libcfs/linux/libcfs.h>
+#elif defined(__APPLE__)
+#include <libcfs/darwin/libcfs.h>
+#elif defined(__WINNT__)
+#include <libcfs/winnt/libcfs.h>
+#else
+#error Unsupported operating system.
+#endif
+
+#include "curproc.h"
+
+#ifndef __KERNEL__
+#include <stdio.h>
+#endif
+
+/* Controlled via configure key */
+/* #define LIBCFS_DEBUG */
+
+#ifndef offsetof
+# define offsetof(typ,memb)     ((unsigned long)((char *)&(((typ *)0)->memb)))
+#endif
+
+/* cardinality of array */
+#define sizeof_array(a) ((sizeof (a)) / (sizeof ((a)[0])))
+
+#if !defined(container_of)
+/* given a pointer @ptr to the field @member embedded into type (usually
+ * struct) @type, return pointer to the embedding instance of @type. */
+#define container_of(ptr, type, member) \
+        ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
+#endif
+
+#define container_of0(ptr, type, member)                        \
+({                                                              \
+        typeof(ptr) __ptr = (ptr);                              \
+        type       *__res;                                      \
+                                                                \
+        if (unlikely(IS_ERR(__ptr) || __ptr == NULL))           \
+                __res = (type *)__ptr;                          \
+        else                                                    \
+                __res = container_of(__ptr, type, member);      \
+        __res;                                                  \
+})
+
+/*
+ * true iff @i is power-of-2
+ */
+#define IS_PO2(i)                               \
+({                                              \
+        typeof(i) __i;                          \
+                                                \
+        __i = (i);                              \
+        !(__i & (__i - 1));                     \
+})
+
+#define LOWEST_BIT_SET(x)       ((x) & ~((x) - 1))
+
+/*
+ *  Debugging
+ */
+extern unsigned int libcfs_subsystem_debug;
+extern unsigned int libcfs_stack;
+extern unsigned int libcfs_debug;
+extern unsigned int libcfs_printk;
+extern unsigned int libcfs_console_ratelimit;
+extern cfs_duration_t libcfs_console_max_delay;
+extern cfs_duration_t libcfs_console_min_delay;
+extern unsigned int libcfs_console_backoff;
+extern unsigned int libcfs_debug_binary;
+extern char debug_file_path[1024];
+
+int libcfs_debug_mask2str(char *str, int size, int mask, int is_subsys);
+int libcfs_debug_str2mask(int *mask, const char *str, int is_subsys);
+
+/* Has there been an LBUG? */
+extern unsigned int libcfs_catastrophe;
+extern unsigned int libcfs_panic_on_lbug;
+
+/*
+ * struct ptldebug_header is defined in libcfs/<os>/libcfs.h
+ */
+
+#define PH_FLAG_FIRST_RECORD 1
+
+/* Debugging subsystems (32 bits, non-overlapping) */
+/* keep these in sync with lnet/utils/debug.c and lnet/libcfs/debug.c */
+#define S_UNDEFINED   0x00000001
+#define S_MDC         0x00000002
+#define S_MDS         0x00000004
+#define S_OSC         0x00000008
+#define S_OST         0x00000010
+#define S_CLASS       0x00000020
+#define S_LOG         0x00000040
+#define S_LLITE       0x00000080
+#define S_RPC         0x00000100
+#define S_MGMT        0x00000200
+#define S_LNET        0x00000400
+#define S_LND         0x00000800 /* ALL LNDs */
+#define S_PINGER      0x00001000
+#define S_FILTER      0x00002000
+/* unused */
+#define S_ECHO        0x00008000
+#define S_LDLM        0x00010000
+#define S_LOV         0x00020000
+/* unused */
+/* unused */
+/* unused */
+/* unused */
+/* unused */
+#define S_LMV         0x00800000 /* b_new_cmd */
+/* unused */
+#define S_SEC         0x02000000 /* upcall cache */
+#define S_GSS         0x04000000 /* b_new_cmd */
+/* unused */
+#define S_MGC         0x10000000
+#define S_MGS         0x20000000
+#define S_FID         0x40000000 /* b_new_cmd */
+#define S_FLD         0x80000000 /* b_new_cmd */
+/* keep these in sync with lnet/utils/debug.c and lnet/libcfs/debug.c */
+
+/* Debugging masks (32 bits, non-overlapping) */
+/* keep these in sync with lnet/utils/debug.c and lnet/libcfs/debug.c */
+#define D_TRACE       0x00000001 /* ENTRY/EXIT markers */
+#define D_INODE       0x00000002
+#define D_SUPER       0x00000004
+#define D_EXT2        0x00000008 /* anything from ext2_debug */
+#define D_MALLOC      0x00000010 /* print malloc, free information */
+#define D_CACHE       0x00000020 /* cache-related items */
+#define D_INFO        0x00000040 /* general information */
+#define D_IOCTL       0x00000080 /* ioctl related information */
+#define D_NETERROR    0x00000100 /* network errors */
+#define D_NET         0x00000200 /* network communications */
+#define D_WARNING     0x00000400 /* CWARN(...) == CDEBUG (D_WARNING, ...) */
+#define D_BUFFS       0x00000800
+#define D_OTHER       0x00001000
+#define D_DENTRY      0x00002000
+#define D_NETTRACE    0x00004000
+#define D_PAGE        0x00008000 /* bulk page handling */
+#define D_DLMTRACE    0x00010000
+#define D_ERROR       0x00020000 /* CERROR(...) == CDEBUG (D_ERROR, ...) */
+#define D_EMERG       0x00040000 /* CEMERG(...) == CDEBUG (D_EMERG, ...) */
+#define D_HA          0x00080000 /* recovery and failover */
+#define D_RPCTRACE    0x00100000 /* for distributed debugging */
+#define D_VFSTRACE    0x00200000
+#define D_READA       0x00400000 /* read-ahead */
+#define D_MMAP        0x00800000
+#define D_CONFIG      0x01000000
+#define D_CONSOLE     0x02000000
+#define D_QUOTA       0x04000000
+#define D_SEC         0x08000000
+/* keep these in sync with lnet/{utils,libcfs}/debug.c */
+
+#define D_CANTMASK   (D_ERROR | D_EMERG | D_WARNING | D_CONSOLE)
+
+#ifndef DEBUG_SUBSYSTEM
+# define DEBUG_SUBSYSTEM S_UNDEFINED
+#endif
+
+#define CDEBUG_DEFAULT_MAX_DELAY (cfs_time_seconds(600))         /* jiffies */
+#define CDEBUG_DEFAULT_MIN_DELAY ((cfs_time_seconds(1) + 1) / 2) /* jiffies */
+#define CDEBUG_DEFAULT_BACKOFF   2
+typedef struct {
+        cfs_time_t      cdls_next;
+        int             cdls_count;
+        cfs_duration_t  cdls_delay;
+} cfs_debug_limit_state_t;
+
+/* Controlled via configure key */
+/* #define CDEBUG_ENABLED */
+
+#if defined(__KERNEL__) || (defined(__arch_lib__) && !defined(LUSTRE_UTILS))
+
+#ifdef CDEBUG_ENABLED
+#define __CDEBUG(cdls, mask, format, a...)                              \
+do {                                                                    \
+        CHECK_STACK();                                                  \
+                                                                        \
+        if (((mask) & D_CANTMASK) != 0 ||                               \
+            ((libcfs_debug & (mask)) != 0 &&                            \
+             (libcfs_subsystem_debug & DEBUG_SUBSYSTEM) != 0))          \
+                libcfs_debug_msg(cdls, DEBUG_SUBSYSTEM, mask,           \
+                                 __FILE__, __FUNCTION__, __LINE__,      \
+                                 format, ## a);                         \
+} while (0)
+
+#define CDEBUG(mask, format, a...) __CDEBUG(NULL, mask, format, ## a)
+
+#define CDEBUG_LIMIT(mask, format, a...)        \
+do {                                            \
+        static cfs_debug_limit_state_t cdls;    \
+                                                \
+        __CDEBUG(&cdls, mask, format, ## a);    \
+} while (0)
+
+#else /* CDEBUG_ENABLED */
+#define CDEBUG(mask, format, a...) (void)(0)
+#define CDEBUG_LIMIT(mask, format, a...) (void)(0)
+#warning "CDEBUG IS DISABLED. THIS SHOULD NEVER BE DONE FOR PRODUCTION!"
+#endif
+
+#else
+
+#define CDEBUG(mask, format, a...)                                      \
+do {                                                                    \
+        if (((mask) & D_CANTMASK) != 0)                                 \
+                fprintf(stderr, "(%s:%d:%s()) " format,                 \
+                        __FILE__, __LINE__, __FUNCTION__, ## a);        \
+} while (0)
+
+#define CDEBUG_LIMIT CDEBUG
+
+#endif /* !__KERNEL__ */
+
+/*
+ * Lustre Error Checksum: calculates checksum
+ * of Hex number by XORing each bit.
+ */
+#define LERRCHKSUM(hexnum) (((hexnum) & 0xf) ^ ((hexnum) >> 4 & 0xf) ^ \
+                           ((hexnum) >> 8 & 0xf))
+
+#define CWARN(format, a...)          CDEBUG_LIMIT(D_WARNING, format, ## a)
+#define CERROR(format, a...)         CDEBUG_LIMIT(D_ERROR, format, ## a)
+#define CEMERG(format, a...)         CDEBUG_LIMIT(D_EMERG, format, ## a)
+
+#define LCONSOLE(mask, format, a...) CDEBUG(D_CONSOLE | (mask), format, ## a)
+#define LCONSOLE_INFO(format, a...)  CDEBUG_LIMIT(D_CONSOLE, format, ## a)
+#define LCONSOLE_WARN(format, a...)  CDEBUG_LIMIT(D_CONSOLE | D_WARNING, format, ## a)
+#define LCONSOLE_ERROR_MSG(errnum, format, a...) CDEBUG_LIMIT(D_CONSOLE | D_ERROR, \
+                           "%x-%x: " format, errnum, LERRCHKSUM(errnum),  ## a)
+#define LCONSOLE_ERROR(format, a...) LCONSOLE_ERROR_MSG(0x00, format, ## a)
+
+#define LCONSOLE_EMERG(format, a...) CDEBUG(D_CONSOLE | D_EMERG, format, ## a)
+
+#ifdef CDEBUG_ENABLED
+
+#define GOTO(label, rc)                                                 \
+do {                                                                    \
+        long GOTO__ret = (long)(rc);                                    \
+        CDEBUG(D_TRACE,"Process leaving via %s (rc=%lu : %ld : %lx)\n", \
+               #label, (unsigned long)GOTO__ret, (signed long)GOTO__ret,\
+               (signed long)GOTO__ret);                                 \
+        goto label;                                                     \
+} while (0)
+#else
+#define GOTO(label, rc) do { ((void)(rc)); goto label; } while (0)
+#endif
+
+/* Controlled via configure key */
+/* #define CDEBUG_ENTRY_EXIT */
+
+#ifdef CDEBUG_ENTRY_EXIT
+
+/*
+ * if rc == NULL, we need to code as RETURN((void *)NULL), otherwise
+ * there will be a warning in osx.
+ */
+#define RETURN(rc)                                                      \
+do {                                                                    \
+        typeof(rc) RETURN__ret = (rc);                                  \
+        CDEBUG(D_TRACE, "Process leaving (rc=%lu : %ld : %lx)\n",       \
+               (long)RETURN__ret, (long)RETURN__ret, (long)RETURN__ret);\
+        EXIT_NESTING;                                                   \
+        return RETURN__ret;                                             \
+} while (0)
+
+#define ENTRY                                                           \
+ENTRY_NESTING;                                                          \
+do {                                                                    \
+        CDEBUG(D_TRACE, "Process entered\n");                           \
+} while (0)
+
+#define EXIT                                                            \
+do {                                                                    \
+        CDEBUG(D_TRACE, "Process leaving\n");                           \
+        EXIT_NESTING;                                                   \
+} while(0)
+#else /* !CDEBUG_ENTRY_EXIT */
+
+#define RETURN(rc) return (rc)
+#define ENTRY                           do { } while (0)
+#define EXIT                            do { } while (0)
+
+#endif /* !CDEBUG_ENTRY_EXIT */
+
+/*
+ * Some (nomina odiosa sunt) platforms define NULL as naked 0. This confuses
+ * Lustre RETURN(NULL) macro.
+ */
+#if defined(NULL)
+#undef NULL
+#endif
+
+#define NULL ((void *)0)
+
+#define LUSTRE_SRV_LNET_PID      LUSTRE_LNET_PID
+
+#ifdef __KERNEL__
+
+#include <libcfs/list.h>
+
+struct libcfs_ioctl_data;                       /* forward ref */
+
+struct libcfs_ioctl_handler {
+        struct list_head item;
+        int (*handle_ioctl)(unsigned int cmd, struct libcfs_ioctl_data *data);
+};
+
+#define DECLARE_IOCTL_HANDLER(ident, func)                      \
+        struct libcfs_ioctl_handler ident = {                   \
+                /* .item = */ CFS_LIST_HEAD_INIT(ident.item),   \
+                /* .handle_ioctl = */ func                      \
+        }
+
+int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand);
+int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand);
+
+/* libcfs tcpip */
+int libcfs_ipif_query(char *name, int *up, __u32 *ip, __u32 *mask);
+int libcfs_ipif_enumerate(char ***names);
+void libcfs_ipif_free_enumeration(char **names, int n);
+int libcfs_sock_listen(cfs_socket_t **sockp, __u32 ip, int port, int backlog);
+int libcfs_sock_accept(cfs_socket_t **newsockp, cfs_socket_t *sock);
+void libcfs_sock_abort_accept(cfs_socket_t *sock);
+int libcfs_sock_connect(cfs_socket_t **sockp, int *fatal,
+                        __u32 local_ip, int local_port,
+                        __u32 peer_ip, int peer_port);
+int libcfs_sock_setbuf(cfs_socket_t *socket, int txbufsize, int rxbufsize);
+int libcfs_sock_getbuf(cfs_socket_t *socket, int *txbufsize, int *rxbufsize);
+int libcfs_sock_getaddr(cfs_socket_t *socket, int remote, __u32 *ip, int *port);
+int libcfs_sock_write(cfs_socket_t *sock, void *buffer, int nob, int timeout);
+int libcfs_sock_read(cfs_socket_t *sock, void *buffer, int nob, int timeout);
+void libcfs_sock_release(cfs_socket_t *sock);
+
+/* libcfs watchdogs */
+struct lc_watchdog;
+
+/* Add a watchdog which fires after "time" milliseconds of delay.  You have to
+ * touch it once to enable it. */
+struct lc_watchdog *lc_watchdog_add(int time,
+                                    void (*cb)(pid_t pid, void *),
+                                    void *data);
+
+/* Enables a watchdog and resets its timer. */
+void lc_watchdog_touch_ms(struct lc_watchdog *lcw, int timeout_ms);
+void lc_watchdog_touch(struct lc_watchdog *lcw);
+
+/* Disable a watchdog; touch it to restart it. */
+void lc_watchdog_disable(struct lc_watchdog *lcw);
+
+/* Clean up the watchdog */
+void lc_watchdog_delete(struct lc_watchdog *lcw);
+
+/* Dump a debug log */
+void lc_watchdog_dumplog(pid_t pid, void *data);
+
+/* __KERNEL__ */
+#endif
+
+/* need both kernel and user-land acceptor */
+#define LNET_ACCEPTOR_MIN_RESERVED_PORT    512
+#define LNET_ACCEPTOR_MAX_RESERVED_PORT    1023
+
+/*
+ * libcfs pseudo device operations
+ *
+ * struct cfs_psdev_t and
+ * cfs_psdev_register() and
+ * cfs_psdev_deregister() are declared in
+ * libcfs/<os>/cfs_prim.h
+ *
+ * It's just draft now.
+ */
+
+struct cfs_psdev_file {
+        unsigned long   off;
+        void            *private_data;
+        unsigned long   reserved1;
+        unsigned long   reserved2;
+};
+
+struct cfs_psdev_ops {
+        int (*p_open)(unsigned long, void *);
+        int (*p_close)(unsigned long, void *);
+        int (*p_read)(struct cfs_psdev_file *, char *, unsigned long);
+        int (*p_write)(struct cfs_psdev_file *, char *, unsigned long);
+        int (*p_ioctl)(struct cfs_psdev_file *, unsigned long, void *);
+};
+
+/*
+ * generic time manipulation functions.
+ */
+
+static inline int cfs_time_after(cfs_time_t t1, cfs_time_t t2)
+{
+        return cfs_time_before(t2, t1);
+}
+
+static inline int cfs_time_aftereq(cfs_time_t t1, cfs_time_t t2)
+{
+        return cfs_time_beforeq(t2, t1);
+}
+
+/*
+ * return seconds since UNIX epoch
+ */
+static inline time_t cfs_unix_seconds(void)
+{
+        cfs_fs_time_t t;
+
+        cfs_fs_time_current(&t);
+        return (time_t)cfs_fs_time_sec(&t);
+}
+
+static inline cfs_time_t cfs_time_shift(int seconds)
+{
+        return cfs_time_add(cfs_time_current(), cfs_time_seconds(seconds));
+}
+
+static inline long cfs_timeval_sub(struct timeval *large, struct timeval *small,
+                                   struct timeval *result)
+{
+        long r = (long) (
+                (large->tv_sec - small->tv_sec) * ONE_MILLION +
+                (large->tv_usec - small->tv_usec));
+        if (result != NULL) {
+                result->tv_usec = r % ONE_MILLION;
+                result->tv_sec = r / ONE_MILLION;
+        }
+        return r;
+}
+
+#define CFS_RATELIMIT(seconds)                                  \
+({                                                              \
+        /*                                                      \
+         * XXX nikita: non-portable initializer                 \
+         */                                                     \
+        static time_t __next_message = 0;                       \
+        int result;                                             \
+                                                                \
+        if (cfs_time_after(cfs_time_current(), __next_message)) \
+                result = 1;                                     \
+        else {                                                  \
+                __next_message = cfs_time_shift(seconds);       \
+                result = 0;                                     \
+        }                                                       \
+        result;                                                 \
+})
+
+struct libcfs_debug_msg_data {
+        cfs_debug_limit_state_t *msg_cdls;
+        int                      msg_subsys;
+        const char              *msg_file;
+        const char              *msg_fn;
+        int                      msg_line;
+};
+
+#define DEBUG_MSG_DATA_INIT(cdls, subsystem, file, func, ln ) { \
+        .msg_cdls           = (cdls),       \
+        .msg_subsys         = (subsystem),  \
+        .msg_file           = (file),       \
+        .msg_fn             = (func),       \
+        .msg_line           = (ln)          \
+    }
+
+
+extern int libcfs_debug_vmsg2(cfs_debug_limit_state_t *cdls,
+                              int subsys, int mask,
+                              const char *file, const char *fn, const int line,
+                              const char *format1, va_list args,
+                              const char *format2, ...)
+        __attribute__ ((format (printf, 9, 10)));
+
+#define libcfs_debug_vmsg(cdls, subsys, mask, file, fn, line, format, args)   \
+    libcfs_debug_vmsg2(cdls, subsys, mask, file, fn,line,format,args,NULL,NULL)
+
+#define libcfs_debug_msg(cdls, subsys, mask, file, fn, line, format, a...)    \
+    libcfs_debug_vmsg2(cdls, subsys, mask, file, fn,line,NULL,NULL,format, ##a)
+
+#define cdebug_va(cdls, mask, file, func, line, fmt, args)      do {          \
+        CHECK_STACK();                                                        \
+                                                                              \
+        if (((mask) & D_CANTMASK) != 0 ||                                     \
+            ((libcfs_debug & (mask)) != 0 &&                                  \
+             (libcfs_subsystem_debug & DEBUG_SUBSYSTEM) != 0))                \
+                libcfs_debug_vmsg(cdls, DEBUG_SUBSYSTEM, (mask),              \
+                                  (file), (func), (line), fmt, args);         \
+} while(0);
+
+#define cdebug(cdls, mask, file, func, line, fmt, a...) do {                  \
+        CHECK_STACK();                                                        \
+                                                                              \
+        if (((mask) & D_CANTMASK) != 0 ||                                     \
+            ((libcfs_debug & (mask)) != 0 &&                                  \
+             (libcfs_subsystem_debug & DEBUG_SUBSYSTEM) != 0))                \
+                libcfs_debug_msg(cdls, DEBUG_SUBSYSTEM, (mask),               \
+                                 (file), (func), (line), fmt, ## a);          \
+} while(0);
+
+extern void libcfs_assertion_failed(const char *expr, const char *file,
+                                    const char *fn, const int line);
+
+static inline void cfs_slow_warning(cfs_time_t now, int seconds, char *msg)
+{
+        if (cfs_time_after(cfs_time_current(),
+                           cfs_time_add(now, cfs_time_seconds(15))))
+                CERROR("slow %s "CFS_TIME_T" sec\n", msg,
+                       cfs_duration_sec(cfs_time_sub(cfs_time_current(),now)));
+}
+
+/*
+ * helper function similar to do_gettimeofday() of Linux kernel
+ */
+static inline void cfs_fs_timeval(struct timeval *tv)
+{
+        cfs_fs_time_t time;
+
+        cfs_fs_time_current(&time);
+        cfs_fs_time_usec(&time, tv);
+}
+
+/*
+ * return valid time-out based on user supplied one. Currently we only check
+ * that time-out is not shorted than allowed.
+ */
+static inline cfs_duration_t cfs_timeout_cap(cfs_duration_t timeout)
+{
+        if (timeout < CFS_TICK)
+                timeout = CFS_TICK;
+        return timeout;
+}
+
+/*
+ * Universal memory allocator API
+ */
+enum cfs_alloc_flags {
+        /* allocation is not allowed to block */
+        CFS_ALLOC_ATOMIC = 0x1,
+        /* allocation is allowed to block */
+        CFS_ALLOC_WAIT   = 0x2,
+        /* allocation should return zeroed memory */
+        CFS_ALLOC_ZERO   = 0x4,
+        /* allocation is allowed to call file-system code to free/clean
+         * memory */
+        CFS_ALLOC_FS     = 0x8,
+        /* allocation is allowed to do io to free/clean memory */
+        CFS_ALLOC_IO     = 0x10,
+        /* don't report allocation failure to the console */
+        CFS_ALLOC_NOWARN = 0x20,
+        /* standard allocator flag combination */
+        CFS_ALLOC_STD    = CFS_ALLOC_FS | CFS_ALLOC_IO,
+        CFS_ALLOC_USER   = CFS_ALLOC_WAIT | CFS_ALLOC_FS | CFS_ALLOC_IO,
+};
+
+/* flags for cfs_page_alloc() in addition to enum cfs_alloc_flags */
+enum cfs_alloc_page_flags {
+        /* allow to return page beyond KVM. It has to be mapped into KVM by
+         * cfs_page_map(); */
+        CFS_ALLOC_HIGH   = 0x40,
+        CFS_ALLOC_HIGHUSER = CFS_ALLOC_WAIT | CFS_ALLOC_FS | CFS_ALLOC_IO | CFS_ALLOC_HIGH,
+};
+
+/*
+ * Drop into debugger, if possible. Implementation is provided by platform.
+ */
+
+void cfs_enter_debugger(void);
+
+/*
+ * Defined by platform
+ */
+void cfs_daemonize(char *str);
+int cfs_daemonize_ctxt(char *str);
+cfs_sigset_t cfs_get_blocked_sigs(void);
+cfs_sigset_t cfs_block_allsigs(void);
+cfs_sigset_t cfs_block_sigs(cfs_sigset_t bits);
+void cfs_restore_sigs(cfs_sigset_t);
+int cfs_signal_pending(void);
+void cfs_clear_sigpending(void);
+/*
+ * XXX Liang:
+ * these macros should be removed in the future,
+ * we keep them just for keeping libcfs compatible
+ * with other branches.
+ */
+#define libcfs_daemonize(s)     cfs_daemonize(s)
+#define cfs_sigmask_lock(f)     do { f= 0; } while (0)
+#define cfs_sigmask_unlock(f)   do { f= 0; } while (0)
+
+int convert_server_error(__u64 ecode);
+int convert_client_oflag(int cflag, int *result);
+
+/*
+ * Stack-tracing filling.
+ */
+
+/*
+ * Platform-dependent data-type to hold stack frames.
+ */
+struct cfs_stack_trace;
+
+/*
+ * Fill @trace with current back-trace.
+ */
+void cfs_stack_trace_fill(struct cfs_stack_trace *trace);
+
+/*
+ * Return instruction pointer for frame @frame_no. NULL if @frame_no is
+ * invalid.
+ */
+void *cfs_stack_trace_frame(struct cfs_stack_trace *trace, int frame_no);
+
+/*
+ * Universal open flags.
+ */
+#define CFS_O_ACCMODE           0003
+#define CFS_O_CREAT             0100
+#define CFS_O_EXCL              0200
+#define CFS_O_NOCTTY            0400
+#define CFS_O_TRUNC             01000
+#define CFS_O_APPEND            02000
+#define CFS_O_NONBLOCK          04000
+#define CFS_O_NDELAY            CFS_O_NONBLOCK
+#define CFS_O_SYNC              010000
+#define CFS_O_ASYNC             020000
+#define CFS_O_DIRECT            040000
+#define CFS_O_LARGEFILE         0100000
+#define CFS_O_DIRECTORY         0200000
+#define CFS_O_NOFOLLOW          0400000
+#define CFS_O_NOATIME           01000000
+
+/* convert local open flags to universal open flags */
+int cfs_oflags2univ(int flags);
+/* convert universal open flags to local open flags */
+int cfs_univ2oflags(int flags);
+
+#define _LIBCFS_H
+
+#endif /* _LIBCFS_H */
diff --git a/libcfs/include/libcfs/linux/.cvsignore b/libcfs/include/libcfs/linux/.cvsignore
new file mode 100644 (file)
index 0000000..3dda729
--- /dev/null
@@ -0,0 +1,2 @@
+Makefile.in
+Makefile
diff --git a/libcfs/include/libcfs/linux/Makefile.am b/libcfs/include/libcfs/linux/Makefile.am
new file mode 100644 (file)
index 0000000..072a7ad
--- /dev/null
@@ -0,0 +1,3 @@
+EXTRA_DIST := kp30.h libcfs.h linux-fs.h linux-lock.h linux-mem.h      \
+       linux-prim.h linux-time.h linux-tcpip.h lltrace.h               \
+       portals_compat25.h portals_utils.h
diff --git a/libcfs/include/libcfs/linux/kp30.h b/libcfs/include/libcfs/linux/kp30.h
new file mode 100644 (file)
index 0000000..19355ed
--- /dev/null
@@ -0,0 +1,379 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ */
+#ifndef __LIBCFS_LINUX_KP30_H__
+#define __LIBCFS_LINUX_KP30_H__
+
+#ifndef __LIBCFS_KP30_H__
+#error Do not #include this file directly. #include <libcfs/kp30.h> instead
+#endif
+
+#ifdef __KERNEL__
+#ifndef AUTOCONF_INCLUDED
+# include <linux/config.h>
+#endif
+# include <linux/kernel.h>
+# include <linux/mm.h>
+# include <linux/string.h>
+# include <linux/stat.h>
+# include <linux/init.h>
+# include <linux/errno.h>
+# include <linux/unistd.h>
+# include <asm/system.h>
+# include <linux/kmod.h>
+# include <linux/notifier.h>
+# include <linux/fs.h>
+# include <linux/miscdevice.h>
+# include <linux/vmalloc.h>
+# include <linux/time.h>
+# include <linux/slab.h>
+# include <linux/interrupt.h>
+# include <linux/highmem.h>
+# include <linux/module.h>
+# include <linux/version.h>
+# include <lnet/lnet.h>
+# include <linux/smp_lock.h>
+# include <asm/atomic.h>
+# include <asm/uaccess.h>
+# include <linux/rwsem.h>
+# include <linux/proc_fs.h>
+# include <linux/file.h>
+# include <linux/smp.h>
+# include <linux/ctype.h>
+# include <linux/compiler.h>
+# ifdef HAVE_MM_INLINE
+#  include <linux/mm_inline.h>
+# endif
+# if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+#  include <linux/kallsyms.h>
+#  include <linux/moduleparam.h>
+# endif
+
+#include <libcfs/linux/portals_compat25.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#define schedule_work schedule_task
+#define prepare_work(wq,cb,cbdata)                                            \
+do {                                                                          \
+        INIT_TQUEUE((wq), 0, 0);                                              \
+        PREPARE_TQUEUE((wq), (cb), (cbdata));                                 \
+} while (0)
+
+#define PageUptodate Page_Uptodate
+#define our_recalc_sigpending(current) recalc_sigpending(current)
+#define num_online_cpus() smp_num_cpus
+static inline void our_cond_resched(void)
+{
+        if (current->need_resched)
+               schedule ();
+}
+#define work_struct_t                   struct tq_struct
+#define cfs_get_work_data(type,field,data)   (data)
+#else
+
+#ifdef HAVE_3ARGS_INIT_WORK
+
+#define prepare_work(wq,cb,cbdata)                                            \
+do {                                                                          \
+        INIT_WORK((wq), (void *)(cb), (void *)(cbdata));                      \
+} while (0)
+
+#define cfs_get_work_data(type,field,data)   (data)
+
+#else
+
+#define prepare_work(wq,cb,cbdata)                                            \
+do {                                                                          \
+        INIT_WORK((wq), (void *)(cb));                                        \
+} while (0)
+
+#define cfs_get_work_data(type,field,data) container_of(data,type,field)
+
+#endif
+
+#define wait_on_page wait_on_page_locked
+#define our_recalc_sigpending(current) recalc_sigpending()
+#define strtok(a,b) strpbrk(a, b)
+static inline void our_cond_resched(void)
+{
+        cond_resched();
+}
+#define work_struct_t      struct work_struct
+
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) */
+
+#ifdef CONFIG_SMP
+#define LASSERT_SPIN_LOCKED(lock) LASSERT(spin_is_locked(lock))
+#else
+#define LASSERT_SPIN_LOCKED(lock) do {} while(0)
+#endif
+#define LASSERT_SEM_LOCKED(sem) LASSERT(down_trylock(sem) != 0)
+
+#define LIBCFS_PANIC(msg)            panic(msg)
+
+/* ------------------------------------------------------------------- */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+
+#define PORTAL_SYMBOL_REGISTER(x) inter_module_register(#x, THIS_MODULE, &x)
+#define PORTAL_SYMBOL_UNREGISTER(x) inter_module_unregister(#x)
+
+#define PORTAL_SYMBOL_GET(x) ((typeof(&x))inter_module_get(#x))
+#define PORTAL_SYMBOL_PUT(x) inter_module_put(#x)
+
+#define PORTAL_MODULE_USE       MOD_INC_USE_COUNT
+#define PORTAL_MODULE_UNUSE     MOD_DEC_USE_COUNT
+#else
+
+#define PORTAL_SYMBOL_REGISTER(x)
+#define PORTAL_SYMBOL_UNREGISTER(x)
+
+#define PORTAL_SYMBOL_GET(x) symbol_get(x)
+#define PORTAL_SYMBOL_PUT(x) symbol_put(x)
+
+#define PORTAL_MODULE_USE       try_module_get(THIS_MODULE)
+#define PORTAL_MODULE_UNUSE     module_put(THIS_MODULE)
+
+#endif
+
+/******************************************************************************/
+/* Module parameter support */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+# define CFS_MODULE_PARM(name, t, type, perm, desc) \
+        MODULE_PARM(name, t);\
+        MODULE_PARM_DESC(name, desc)
+
+#else
+# define CFS_MODULE_PARM(name, t, type, perm, desc) \
+        module_param(name, type, perm);\
+        MODULE_PARM_DESC(name, desc)
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
+# define CFS_SYSFS_MODULE_PARM  0 /* no sysfs module parameters */
+#else
+# define CFS_SYSFS_MODULE_PARM  1 /* module parameters accessible via sysfs */
+#endif
+/******************************************************************************/
+
+#if (__GNUC__)
+/* Use the special GNU C __attribute__ hack to have the compiler check the
+ * printf style argument string against the actual argument count and
+ * types.
+ */
+#ifdef printf
+# warning printf has been defined as a macro...
+# undef printf
+#endif
+
+#endif /* __GNUC__ */
+
+# define fprintf(a, format, b...) CDEBUG(D_OTHER, format , ## b)
+# define printf(format, b...) CDEBUG(D_OTHER, format , ## b)
+# define time(a) CURRENT_TIME
+
+#ifndef num_possible_cpus
+#define num_possible_cpus() NR_CPUS
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#define i_size_read(a) ((a)->i_size)
+#endif
+
+#else  /* !__KERNEL__ */
+# include <stdio.h>
+# include <stdlib.h>
+#if defined(__CYGWIN__)
+# include <cygwin-ioctl.h>
+#else
+# include <stdint.h>
+#endif
+# include <unistd.h>
+# include <time.h>
+# include <limits.h>
+# include <errno.h>
+# include <sys/ioctl.h>                         /* for _IOWR */
+#ifndef _IOWR
+#include "ioctl.h"
+#endif
+
+# define CFS_MODULE_PARM(name, t, type, perm, desc)
+#define PORTAL_SYMBOL_GET(x) inter_module_get(#x)
+#define PORTAL_SYMBOL_PUT(x) inter_module_put(#x)
+
+#endif /* End of !__KERNEL__ */
+
+/******************************************************************************/
+/* Light-weight trace
+ * Support for temporary event tracing with minimal Heisenberg effect. */
+#define LWT_SUPPORT  0
+
+#define LWT_MEMORY   (16<<20)
+
+#ifndef KLWT_SUPPORT
+# if defined(__KERNEL__)
+#  if !defined(BITS_PER_LONG)
+#   error "BITS_PER_LONG not defined"
+#  endif
+# elif !defined(__WORDSIZE)
+#  error "__WORDSIZE not defined"
+# else
+#  define BITS_PER_LONG __WORDSIZE
+# endif
+
+/* kernel hasn't defined this? */
+typedef struct {
+        long long   lwte_when;
+        char       *lwte_where;
+        void       *lwte_task;
+        long        lwte_p1;
+        long        lwte_p2;
+        long        lwte_p3;
+        long        lwte_p4;
+# if BITS_PER_LONG > 32
+        long        lwte_pad;
+# endif
+} lwt_event_t;
+#endif /* !KLWT_SUPPORT */
+
+#if LWT_SUPPORT
+# ifdef __KERNEL__
+#  if !KLWT_SUPPORT
+
+typedef struct _lwt_page {
+        struct list_head     lwtp_list;
+        struct page         *lwtp_page;
+        lwt_event_t         *lwtp_events;
+} lwt_page_t;
+
+typedef struct {
+        int                lwtc_current_index;
+        lwt_page_t        *lwtc_current_page;
+} lwt_cpu_t;
+
+extern int       lwt_enabled;
+extern lwt_cpu_t lwt_cpus[];
+
+/* Note that we _don't_ define LWT_EVENT at all if LWT_SUPPORT isn't set.
+ * This stuff is meant for finding specific problems; it never stays in
+ * production code... */
+
+#define LWTSTR(n)       #n
+#define LWTWHERE(f,l)   f ":" LWTSTR(l)
+#define LWT_EVENTS_PER_PAGE (CFS_PAGE_SIZE / sizeof (lwt_event_t))
+
+#define LWT_EVENT(p1, p2, p3, p4)                                       \
+do {                                                                    \
+        unsigned long    flags;                                         \
+        lwt_cpu_t       *cpu;                                           \
+        lwt_page_t      *p;                                             \
+        lwt_event_t     *e;                                             \
+                                                                        \
+        if (lwt_enabled) {                                              \
+                local_irq_save (flags);                                 \
+                                                                        \
+                cpu = &lwt_cpus[smp_processor_id()];                    \
+                p = cpu->lwtc_current_page;                             \
+                e = &p->lwtp_events[cpu->lwtc_current_index++];         \
+                                                                        \
+                if (cpu->lwtc_current_index >= LWT_EVENTS_PER_PAGE) {   \
+                        cpu->lwtc_current_page =                        \
+                                list_entry (p->lwtp_list.next,          \
+                                            lwt_page_t, lwtp_list);     \
+                        cpu->lwtc_current_index = 0;                    \
+                }                                                       \
+                                                                        \
+                e->lwte_when  = get_cycles();                           \
+                e->lwte_where = LWTWHERE(__FILE__,__LINE__);            \
+                e->lwte_task  = current;                                \
+                e->lwte_p1    = (long)(p1);                             \
+                e->lwte_p2    = (long)(p2);                             \
+                e->lwte_p3    = (long)(p3);                             \
+                e->lwte_p4    = (long)(p4);                             \
+                                                                        \
+                local_irq_restore (flags);                              \
+        }                                                               \
+} while (0)
+
+#endif /* !KLWT_SUPPORT */
+
+extern int  lwt_init (void);
+extern void lwt_fini (void);
+extern int  lwt_lookup_string (int *size, char *knlptr,
+                               char *usrptr, int usrsize);
+extern int  lwt_control (int enable, int clear);
+extern int  lwt_snapshot (cycles_t *now, int *ncpu, int *total_size,
+                          void *user_ptr, int user_size);
+# else  /* __KERNEL__ */
+#  define LWT_EVENT(p1,p2,p3,p4)     /* no userland implementation yet */
+# endif /* __KERNEL__ */
+#endif /* LWT_SUPPORT */
+
+/* ------------------------------------------------------------------ */
+
+#define IOCTL_LIBCFS_TYPE long
+
+#ifdef __CYGWIN__
+# ifndef BITS_PER_LONG
+#  if (~0UL) == 0xffffffffUL
+#   define BITS_PER_LONG 32
+#  else
+#   define BITS_PER_LONG 64
+#  endif
+# endif
+#endif
+
+#if BITS_PER_LONG > 32
+# define LI_POISON ((int)0x5a5a5a5a5a5a5a5a)
+# define LL_POISON ((long)0x5a5a5a5a5a5a5a5a)
+# define LP_POISON ((void *)(long)0x5a5a5a5a5a5a5a5a)
+#else
+# define LI_POISON ((int)0x5a5a5a5a)
+# define LL_POISON ((long)0x5a5a5a5a)
+# define LP_POISON ((void *)(long)0x5a5a5a5a)
+#endif
+
+/* this is a bit chunky */
+
+#if defined(__KERNEL__)
+ #define _LWORDSIZE BITS_PER_LONG
+#else
+ #define _LWORDSIZE __WORDSIZE
+#endif
+
+#if (defined(__x86_64__) && (defined(__KERNEL__) || defined(CRAY_XT3))) || defined(HAVE_U64_LONG_LONG)
+/* x86_64 defines __u64 as "long" in userspace, but "long long" in the kernel */
+# define LPU64 "%Lu"
+# define LPD64 "%Ld"
+# define LPX64 "%#Lx"
+# define LPF64 "L"
+#elif (_LWORDSIZE == 32)
+# define LPU64 "%Lu"
+# define LPD64 "%Ld"
+# define LPX64 "%#Lx"
+# define LPF64 "L"
+#elif (_LWORDSIZE == 64)
+# define LPU64 "%lu"
+# define LPD64 "%ld"
+# define LPX64 "%#lx"
+# define LPF64 "l"
+#endif
+
+#ifdef HAVE_SIZE_T_LONG
+# define LPSZ  "%lu"
+#else
+# define LPSZ  "%u"
+#endif
+
+#ifdef HAVE_SSIZE_T_LONG
+# define LPSSZ "%ld"
+#else
+# define LPSSZ "%d"
+#endif
+
+#ifndef LPU64
+# error "No word size defined"
+#endif
+
+#undef _LWORDSIZE
+
+#endif
diff --git a/libcfs/include/libcfs/linux/libcfs.h b/libcfs/include/libcfs/linux/libcfs.h
new file mode 100644 (file)
index 0000000..c873c2f
--- /dev/null
@@ -0,0 +1,173 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ */
+#ifndef __LIBCFS_LINUX_LIBCFS_H__
+#define __LIBCFS_LINUX_LIBCFS_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+#ifdef HAVE_ASM_TYPES_H
+#include <asm/types.h>
+#else
+#include <libcfs/types.h>
+#endif
+
+#include <stdarg.h>
+#include <libcfs/linux/linux-time.h>
+#include <libcfs/linux/linux-mem.h>
+#include <libcfs/linux/linux-prim.h>
+#include <libcfs/linux/linux-lock.h>
+#include <libcfs/linux/linux-fs.h>
+#include <libcfs/linux/linux-tcpip.h>
+
+
+#ifdef __KERNEL__
+# include <linux/types.h>
+# include <linux/time.h>
+# include <asm/timex.h>
+#else
+# include <sys/types.h>
+# include <sys/time.h>
+# define do_gettimeofday(tv) gettimeofday(tv, NULL);
+typedef unsigned long long cycles_t;
+#endif
+
+#ifndef __KERNEL__
+/* Userpace byte flipping */
+# include <endian.h>
+# include <byteswap.h>
+# define __swab16(x) bswap_16(x)
+# define __swab32(x) bswap_32(x)
+# define __swab64(x) bswap_64(x)
+# define __swab16s(x) do {*(x) = bswap_16(*(x));} while (0)
+# define __swab32s(x) do {*(x) = bswap_32(*(x));} while (0)
+# define __swab64s(x) do {*(x) = bswap_64(*(x));} while (0)
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+#  define le16_to_cpu(x) (x)
+#  define cpu_to_le16(x) (x)
+#  define le32_to_cpu(x) (x)
+#  define cpu_to_le32(x) (x)
+#  define le64_to_cpu(x) (x)
+#  define cpu_to_le64(x) (x)
+
+#  define be16_to_cpu(x) bswap_16(x)
+#  define cpu_to_be16(x) bswap_16(x)
+#  define be32_to_cpu(x) bswap_32(x)
+#  define cpu_to_be32(x) bswap_32(x)
+#  define be64_to_cpu(x) bswap_64(x)
+#  define cpu_to_be64(x) bswap_64(x)
+
+# else
+#  if __BYTE_ORDER == __BIG_ENDIAN
+#   define le16_to_cpu(x) bswap_16(x)
+#   define cpu_to_le16(x) bswap_16(x)
+#   define le32_to_cpu(x) bswap_32(x)
+#   define cpu_to_le32(x) bswap_32(x)
+#   define le64_to_cpu(x) bswap_64(x)
+#   define cpu_to_le64(x) bswap_64(x)
+
+#   define be16_to_cpu(x) (x)
+#   define cpu_to_be16(x) (x)
+#   define be32_to_cpu(x) (x)
+#   define cpu_to_be32(x) (x)
+#   define be64_to_cpu(x) (x)
+#   define cpu_to_be64(x) (x)
+
+#  else
+#   error "Unknown byte order"
+#  endif /* __BIG_ENDIAN */
+# endif /* __LITTLE_ENDIAN */
+#endif /* ! __KERNEL__ */
+
+struct ptldebug_header {
+        __u32 ph_len;
+        __u32 ph_flags;
+        __u32 ph_subsys;
+        __u32 ph_mask;
+        __u32 ph_cpu_id;
+        __u32 ph_sec;
+        __u64 ph_usec;
+        __u32 ph_stack;
+        __u32 ph_pid;
+        __u32 ph_extern_pid;
+        __u32 ph_line_num;
+} __attribute__((packed));
+
+#ifdef __KERNEL__
+# include <linux/sched.h> /* THREAD_SIZE */
+#else
+# ifndef THREAD_SIZE /* x86_64 has THREAD_SIZE in userspace */
+#  define THREAD_SIZE 8192
+# endif
+#endif
+
+#define LUSTRE_TRACE_SIZE (THREAD_SIZE >> 5)
+
+#if defined(__KERNEL__) && !defined(__x86_64__)
+# ifdef  __ia64__
+#  define CDEBUG_STACK() (THREAD_SIZE -                                 \
+                          ((unsigned long)__builtin_dwarf_cfa() &       \
+                           (THREAD_SIZE - 1)))
+# else
+#  define CDEBUG_STACK() (THREAD_SIZE -                                 \
+                          ((unsigned long)__builtin_frame_address(0) &  \
+                           (THREAD_SIZE - 1)))
+# endif /* __ia64__ */
+
+#define __CHECK_STACK(file, func, line)                                 \
+do {                                                                    \
+        unsigned long _stack = CDEBUG_STACK();                          \
+                                                                        \
+        if (_stack > 3*THREAD_SIZE/4 && _stack > libcfs_stack) {        \
+                libcfs_stack = _stack;                                  \
+                libcfs_debug_msg(NULL, DEBUG_SUBSYSTEM, D_WARNING,      \
+                                 file, func, line,                      \
+                                 "maximum lustre stack %lu\n", _stack); \
+              /*panic("LBUG");*/                                        \
+        }                                                               \
+} while (0)
+#define CHECK_STACK()     __CHECK_STACK(__FILE__, __func__, __LINE__)
+#else /* !__KERNEL__ */
+#define __CHECK_STACK(X, Y, Z) do { } while(0)
+#define CHECK_STACK() do { } while(0)
+#define CDEBUG_STACK() (0L)
+#endif /* __KERNEL__ */
+
+/* initial pid  */
+#define LUSTRE_LNET_PID          12345
+
+#define ENTRY_NESTING_SUPPORT (1)
+#define ENTRY_NESTING   do {;} while (0)
+#define EXIT_NESTING   do {;} while (0)
+#define __current_nesting_level() (0)
+
+/*
+ * Platform specific declarations for cfs_curproc API (libcfs/curproc.h)
+ *
+ * Implementation is in linux-curproc.c
+ */
+#define CFS_CURPROC_COMM_MAX (sizeof ((struct task_struct *)0)->comm)
+
+#if defined(__KERNEL__)
+#include <linux/capability.h>
+typedef kernel_cap_t cfs_kernel_cap_t;
+#else
+typedef __u32 cfs_kernel_cap_t;
+#endif
+
+#if defined(__KERNEL__)
+/*
+ * No stack-back-tracing in Linux for now.
+ */
+struct cfs_stack_trace {
+};
+
+#ifndef WITH_WATCHDOG
+#define WITH_WATCHDOG
+#endif
+
+#endif
+
+#endif /* _LINUX_LIBCFS_H */
diff --git a/libcfs/include/libcfs/linux/linux-fs.h b/libcfs/include/libcfs/linux/linux-fs.h
new file mode 100644 (file)
index 0000000..7573322
--- /dev/null
@@ -0,0 +1,82 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2001 Cluster File Systems, Inc. <braam@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Basic library routines. 
+ *
+ */
+
+#ifndef __LIBCFS_LINUX_CFS_FS_H__
+#define __LIBCFS_LINUX_CFS_FS_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+#ifdef __KERNEL__
+#include <linux/fs.h>
+#include <linux/stat.h>
+#include <linux/mount.h>
+#else /* !__KERNEL__ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/mount.h>
+#include <mntent.h>
+#endif  /* __KERNEL__ */
+
+typedef struct file cfs_file_t;
+typedef struct dentry cfs_dentry_t;
+typedef struct dirent64 cfs_dirent_t;
+
+#ifdef __KERNEL__
+#define cfs_filp_size(f)               (i_size_read((f)->f_dentry->d_inode))
+#define cfs_filp_poff(f)                (&(f)->f_pos)
+
+/* 
+ * XXX Do we need to parse flags and mode in cfs_filp_open? 
+ */
+cfs_file_t *cfs_filp_open (const char *name, int flags, int mode, int *err);
+#define cfs_filp_close(f)                   filp_close(f, NULL)
+#define cfs_filp_read(fp, buf, size, pos)   (fp)->f_op->read((fp), (buf), (size), pos)
+#define cfs_filp_write(fp, buf, size, pos)  (fp)->f_op->write((fp), (buf), (size), pos)
+#define cfs_filp_fsync(fp)                  (fp)->f_op->fsync((fp), (fp)->f_dentry, 1)
+
+#define cfs_get_file(f)                     get_file(f)
+#define cfs_put_file(f)                     fput(f)
+#define cfs_file_count(f)                   file_count(f)
+
+typedef struct file_lock cfs_flock_t;
+#define cfs_flock_type(fl)                  ((fl)->fl_type)
+#define cfs_flock_set_type(fl, type)        do { (fl)->fl_type = (type); } while(0)
+#define cfs_flock_pid(fl)                   ((fl)->fl_pid)
+#define cfs_flock_set_pid(fl, pid)          do { (fl)->fl_pid = (pid); } while(0)
+#define cfs_flock_start(fl)                 ((fl)->fl_start)
+#define cfs_flock_set_start(fl, start)      do { (fl)->fl_start = (start); } while(0)
+#define cfs_flock_end(fl)                   ((fl)->fl_end)
+#define cfs_flock_set_end(fl, end)          do { (fl)->fl_end = (end); } while(0)
+
+ssize_t cfs_user_write (cfs_file_t *filp, const char *buf, size_t count, loff_t *offset);
+
+#endif
+
+#endif
diff --git a/libcfs/include/libcfs/linux/linux-lock.h b/libcfs/include/libcfs/linux/linux-lock.h
new file mode 100644 (file)
index 0000000..4b51d1b
--- /dev/null
@@ -0,0 +1,105 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2001 Cluster File Systems, Inc. <braam@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Basic library routines.
+ *
+ */
+
+#ifndef __LIBCFS_LINUX_CFS_LOCK_H__
+#define __LIBCFS_LINUX_CFS_LOCK_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+#ifdef __KERNEL__
+#include <linux/smp_lock.h>
+
+/*
+ * IMPORTANT !!!!!!!!
+ *
+ * All locks' declaration are not guaranteed to be initialized,
+ * Althought some of they are initialized in Linux. All locks
+ * declared by CFS_DECL_* should be initialized explicitly.
+ */
+
+
+/*
+ * spin_lock (use Linux kernel's primitives)
+ *
+ * - spin_lock_init(x)
+ * - spin_lock(x)
+ * - spin_unlock(x)
+ * - spin_trylock(x)
+ *
+ * - spin_lock_irqsave(x, f)
+ * - spin_unlock_irqrestore(x, f)
+ */
+
+/*
+ * rw_semaphore (use Linux kernel's primitives)
+ *
+ * - init_rwsem(x)
+ * - down_read(x)
+ * - up_read(x)
+ * - down_write(x)
+ * - up_write(x)
+ */
+
+/*
+ * rwlock_t (use Linux kernel's primitives)
+ *
+ * - rwlock_init(x)
+ * - read_lock(x)
+ * - read_unlock(x)
+ * - write_lock(x)
+ * - write_unlock(x)
+ */
+
+/*
+ * mutex:
+ *
+ * - init_mutex(x)
+ * - init_mutex_locked(x)
+ * - mutex_up(x)
+ * - mutex_down(x)
+ */
+#define init_mutex(x)                   init_MUTEX(x)
+#define init_mutex_locked(x)            init_MUTEX_LOCKED(x)
+#define mutex_up(x)                     up(x)
+#define mutex_down(x)                   down(x)
+#define mutex_down_trylock(x)           down_trylock(x)
+
+/*
+ * completion (use Linux kernel's primitives)
+ *
+ * - init_complition(c)
+ * - complete(c)
+ * - wait_for_completion(c)
+ */
+
+/* __KERNEL__ */
+#else
+
+#include "../user-lock.h"
+
+/* __KERNEL__ */
+#endif
+#endif
diff --git a/libcfs/include/libcfs/linux/linux-mem.h b/libcfs/include/libcfs/linux/linux-mem.h
new file mode 100644 (file)
index 0000000..fa4ba3d
--- /dev/null
@@ -0,0 +1,129 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2001 Cluster File Systems, Inc. <braam@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Basic library routines.
+ *
+ */
+
+#ifndef __LIBCFS_LINUX_CFS_MEM_H__
+#define __LIBCFS_LINUX_CFS_MEM_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+#ifdef __KERNEL__
+# include <linux/mm.h>
+# include <linux/vmalloc.h>
+# include <linux/pagemap.h>
+# include <linux/slab.h>
+# ifdef HAVE_MM_INLINE
+#  include <linux/mm_inline.h>
+# endif
+
+typedef struct page                     cfs_page_t;
+#define CFS_PAGE_SIZE                   PAGE_CACHE_SIZE
+#define CFS_PAGE_SHIFT                  PAGE_CACHE_SHIFT
+#define CFS_PAGE_MASK                   (~((__u64)CFS_PAGE_SIZE-1))
+
+static inline void *cfs_page_address(cfs_page_t *page)
+{
+        /*
+         * XXX nikita: do NOT call portals_debug_msg() (CDEBUG/ENTRY/EXIT)
+         * from here: this will lead to infinite recursion.
+         */
+        return page_address(page);
+}
+
+static inline void *cfs_kmap(cfs_page_t *page)
+{
+        return kmap(page);
+}
+
+static inline void cfs_kunmap(cfs_page_t *page)
+{
+        kunmap(page);
+}
+
+static inline void cfs_get_page(cfs_page_t *page)
+{
+        get_page(page);
+}
+
+static inline int cfs_page_count(cfs_page_t *page)
+{
+        return page_count(page);
+}
+
+#define cfs_page_index(p)       ((p)->index)
+
+/*
+ * Memory allocator
+ * XXX Liang: move these declare to public file
+ */
+extern void *cfs_alloc(size_t nr_bytes, u_int32_t flags);
+extern void  cfs_free(void *addr);
+
+extern void *cfs_alloc_large(size_t nr_bytes);
+extern void  cfs_free_large(void *addr);
+
+extern cfs_page_t *cfs_alloc_pages(unsigned int flags, unsigned int order);
+extern void __cfs_free_pages(cfs_page_t *page, unsigned int order);
+
+#define cfs_alloc_page(flags)  cfs_alloc_pages(flags, 0)
+#define __cfs_free_page(page)  __cfs_free_pages(page, 0)
+#define cfs_free_page(p)       __free_pages(p, 0)
+
+/*
+ * In Linux there is no way to determine whether current execution context is
+ * blockable.
+ */
+#define CFS_ALLOC_ATOMIC_TRY   CFS_ALLOC_ATOMIC
+
+/*
+ * SLAB allocator
+ * XXX Liang: move these declare to public file
+ */
+#ifdef HAVE_KMEM_CACHE
+typedef struct kmem_cache cfs_mem_cache_t;
+#else
+typedef kmem_cache_t cfs_mem_cache_t;
+#endif
+extern cfs_mem_cache_t * cfs_mem_cache_create (const char *, size_t, size_t, unsigned long);
+extern int cfs_mem_cache_destroy ( cfs_mem_cache_t * );
+extern void *cfs_mem_cache_alloc ( cfs_mem_cache_t *, int);
+extern void cfs_mem_cache_free ( cfs_mem_cache_t *, void *);
+
+/*
+ */
+#define CFS_DECL_MMSPACE                mm_segment_t __oldfs
+#define CFS_MMSPACE_OPEN                do { __oldfs = get_fs(); set_fs(get_ds());} while(0)
+#define CFS_MMSPACE_CLOSE               set_fs(__oldfs)
+
+#else   /* !__KERNEL__ */
+#ifdef HAVE_ASM_PAGE_H
+#include <asm/page.h>           /* needed for PAGE_SIZE - rread */
+#endif
+
+#include <libcfs/user-prim.h>
+/* __KERNEL__ */
+#endif
+
+#endif /* __LINUX_CFS_MEM_H__ */
diff --git a/libcfs/include/libcfs/linux/linux-prim.h b/libcfs/include/libcfs/linux/linux-prim.h
new file mode 100644 (file)
index 0000000..705499e
--- /dev/null
@@ -0,0 +1,311 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2001 Cluster File Systems, Inc. <braam@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Basic library routines.
+ *
+ */
+
+#ifndef __LIBCFS_LINUX_CFS_PRIM_H__
+#define __LIBCFS_LINUX_CFS_PRIM_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+#ifdef __KERNEL__
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/proc_fs.h>
+#include <linux/mm.h>
+#include <linux/timer.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+
+#include <linux/miscdevice.h>
+#include <libcfs/linux/portals_compat25.h>
+#include <asm/div64.h>
+
+#include <libcfs/linux/linux-time.h>
+
+/*
+ * Pseudo device register
+ */
+typedef struct miscdevice              cfs_psdev_t;
+#define cfs_psdev_register(dev)                misc_register(dev)
+#define cfs_psdev_deregister(dev)      misc_deregister(dev)
+
+/*
+ * Sysctl register
+ */
+typedef struct ctl_table               cfs_sysctl_table_t;
+typedef struct ctl_table_header                cfs_sysctl_table_header_t;
+
+#ifdef HAVE_2ARGS_REGISTER_SYSCTL
+#define cfs_register_sysctl_table(t, a)        register_sysctl_table(t, a)
+#else
+#define cfs_register_sysctl_table(t, a) register_sysctl_table(t)
+#endif
+#define cfs_unregister_sysctl_table(t) unregister_sysctl_table(t)
+
+/*
+ * Symbol register
+ */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#define cfs_symbol_register(s, p)       inter_module_register(s, THIS_MODULE, p)
+#define cfs_symbol_unregister(s)        inter_module_unregister(s)
+#define cfs_symbol_get(s)               inter_module_get(s)
+#define cfs_symbol_put(s)               inter_module_put(s)
+#define cfs_module_get()                MOD_INC_USE_COUNT
+#define cfs_module_put()                MOD_DEC_USE_COUNT
+#else
+#define cfs_symbol_register(s, p)       do {} while(0)
+#define cfs_symbol_unregister(s)        do {} while(0)
+#define cfs_symbol_get(s)               symbol_get(s)
+#define cfs_symbol_put(s)               symbol_put(s)
+#define cfs_module_get()                try_module_get(THIS_MODULE)
+#define cfs_module_put()                module_put(THIS_MODULE)
+#endif
+
+/*
+ * Proc file system APIs
+ */
+typedef read_proc_t                     cfs_read_proc_t;
+typedef write_proc_t                    cfs_write_proc_t;
+typedef struct proc_dir_entry           cfs_proc_dir_entry_t;
+#define cfs_create_proc_entry(n, m, p)  create_proc_entry(n, m, p)
+#define cfs_free_proc_entry(e)          free_proc_entry(e)
+#define cfs_remove_proc_entry(n, e)     remove_proc_entry(n, e)
+
+/*
+ * Wait Queue
+ */
+#define CFS_TASK_INTERRUPTIBLE          TASK_INTERRUPTIBLE
+#define CFS_TASK_UNINT                  TASK_UNINTERRUPTIBLE
+
+typedef wait_queue_t                   cfs_waitlink_t;
+typedef wait_queue_head_t              cfs_waitq_t;
+
+typedef long                            cfs_task_state_t;
+
+#define cfs_waitq_init(w)               init_waitqueue_head(w)
+#define cfs_waitlink_init(l)            init_waitqueue_entry(l, current)
+#define cfs_waitq_add(w, l)             add_wait_queue(w, l)
+#define cfs_waitq_add_exclusive(w, l)   add_wait_queue_exclusive(w, l)
+#define cfs_waitq_forward(l, w)         do {} while(0)
+#define cfs_waitq_del(w, l)             remove_wait_queue(w, l)
+#define cfs_waitq_active(w)             waitqueue_active(w)
+#define cfs_waitq_signal(w)             wake_up(w)
+#define cfs_waitq_signal_nr(w,n)        wake_up_nr(w, n)
+#define cfs_waitq_broadcast(w)          wake_up_all(w)
+#define cfs_waitq_wait(l, s)            schedule()
+#define cfs_waitq_timedwait(l, s, t)    schedule_timeout(t)
+#define cfs_schedule_timeout(s, t)      schedule_timeout(t)
+#define cfs_schedule()                  schedule()
+
+/* Kernel thread */
+typedef int (*cfs_thread_t)(void *);
+
+static inline int cfs_kernel_thread(int (*fn)(void *),
+                                    void *arg, unsigned long flags)
+{
+        void *orig_info = current->journal_info;
+        int rc;
+
+        current->journal_info = NULL;
+        rc = kernel_thread(fn, arg, flags);
+        current->journal_info = orig_info;
+        return rc;
+}
+
+
+/*
+ * Task struct
+ */
+typedef struct task_struct              cfs_task_t;
+#define cfs_current()                   current
+#define cfs_task_lock(t)                task_lock(t)
+#define cfs_task_unlock(t)              task_unlock(t)
+#define CFS_DECL_JOURNAL_DATA           void *journal_info
+#define CFS_PUSH_JOURNAL                do {    \
+        journal_info = current->journal_info;   \
+        current->journal_info = NULL;           \
+        } while(0)
+#define CFS_POP_JOURNAL                 do {    \
+        current->journal_info = journal_info;   \
+        } while(0)
+
+/* Module interfaces */
+#define cfs_module(name, version, init, fini) \
+module_init(init);                            \
+module_exit(fini)
+
+/*
+ * Signal
+ */
+typedef sigset_t                        cfs_sigset_t;
+
+/*
+ * Timer
+ */
+typedef struct timer_list cfs_timer_t;
+typedef  void (*timer_func_t)(unsigned long);
+
+#define cfs_init_timer(t)       init_timer(t)
+
+static inline void cfs_timer_init(cfs_timer_t *t, void (*func)(unsigned long), void *arg)
+{
+        init_timer(t);
+        t->function = (timer_func_t)func;
+        t->data = (unsigned long)arg;
+}
+
+static inline void cfs_timer_done(cfs_timer_t *t)
+{
+        return;
+}
+
+static inline void cfs_timer_arm(cfs_timer_t *t, cfs_time_t deadline)
+{
+        mod_timer(t, deadline);
+}
+
+static inline void cfs_timer_disarm(cfs_timer_t *t)
+{
+        del_timer(t);
+}
+
+static inline int  cfs_timer_is_armed(cfs_timer_t *t)
+{
+        return timer_pending(t);
+}
+
+static inline cfs_time_t cfs_timer_deadline(cfs_timer_t *t)
+{
+        return t->expires;
+}
+
+
+/* deschedule for a bit... */
+static inline void cfs_pause(cfs_duration_t ticks)
+{
+        set_current_state(TASK_UNINTERRUPTIBLE);
+        schedule_timeout(ticks);
+}
+
+#ifndef wait_event_timeout /* Only for RHEL3 2.4.21 kernel */
+#define __wait_event_timeout(wq, condition, timeout, ret)        \
+do {                                                             \
+       int __ret = 0;                                           \
+       if (!(condition)) {                                      \
+               wait_queue_t __wait;                             \
+               unsigned long expire;                            \
+                                                                 \
+               init_waitqueue_entry(&__wait, current);          \
+               expire = timeout + jiffies;                      \
+               add_wait_queue(&wq, &__wait);                    \
+               for (;;) {                                       \
+                       set_current_state(TASK_UNINTERRUPTIBLE); \
+                       if (condition)                           \
+                               break;                           \
+                       if (jiffies > expire) {                  \
+                               ret = jiffies - expire;          \
+                               break;                           \
+                       }                                        \
+                       schedule_timeout(timeout);               \
+               }                                                \
+               current->state = TASK_RUNNING;                   \
+               remove_wait_queue(&wq, &__wait);                 \
+       }                                                        \
+} while (0)
+/*
+   retval == 0; condition met; we're good.
+   retval > 0; timed out.
+*/
+#define cfs_waitq_wait_event_timeout(wq, condition, timeout)         \
+({                                                                   \
+       int __ret = 0;                                               \
+       if (!(condition))                                            \
+               __wait_event_timeout(wq, condition, timeout, __ret); \
+       __ret;                                                       \
+})
+#else
+#define cfs_waitq_wait_event_timeout  wait_event_timeout
+#endif
+
+#ifndef wait_event_interruptible_timeout /* Only for RHEL3 2.4.21 kernel */
+#define __wait_event_interruptible_timeout(wq, condition, timeout, ret)   \
+do {                                                           \
+       int __ret = 0;                                         \
+       if (!(condition)) {                                    \
+               wait_queue_t __wait;                           \
+               unsigned long expire;                          \
+                                                               \
+               init_waitqueue_entry(&__wait, current);        \
+               expire = timeout + jiffies;                    \
+               add_wait_queue(&wq, &__wait);                  \
+               for (;;) {                                     \
+                       set_current_state(TASK_INTERRUPTIBLE); \
+                       if (condition)                         \
+                               break;                         \
+                       if (jiffies > expire) {                \
+                               ret = jiffies - expire;        \
+                               break;                         \
+                       }                                      \
+                       if (!signal_pending(current)) {        \
+                               schedule_timeout(timeout);     \
+                               continue;                      \
+                       }                                      \
+                       ret = -ERESTARTSYS;                    \
+                       break;                                 \
+               }                                              \
+               current->state = TASK_RUNNING;                 \
+               remove_wait_queue(&wq, &__wait);               \
+       }                                                      \
+} while (0)
+
+/*
+   retval == 0; condition met; we're good.
+   retval < 0; interrupted by signal.
+   retval > 0; timed out.
+*/
+#define cfs_waitq_wait_event_interruptible_timeout(wq, condition, timeout) \
+({                                                                \
+       int __ret = 0;                                            \
+       if (!(condition))                                         \
+               __wait_event_interruptible_timeout(wq, condition, \
+                                               timeout, __ret);  \
+       __ret;                                                    \
+})
+#else
+#define cfs_waitq_wait_event_interruptible_timeout wait_event_interruptible_timeout
+#endif
+
+#else   /* !__KERNEL__ */
+
+typedef struct proc_dir_entry           cfs_proc_dir_entry_t;
+#include "../user-prim.h"
+
+#endif /* __KERNEL__ */
+
+#endif
diff --git a/libcfs/include/libcfs/linux/linux-tcpip.h b/libcfs/include/libcfs/linux/linux-tcpip.h
new file mode 100644 (file)
index 0000000..fb2ac93
--- /dev/null
@@ -0,0 +1,66 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2001 Cluster File Systems, Inc. <braam@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Basic library routines. 
+ *
+ */
+
+#ifndef __LIBCFS_LINUX_CFS_TCP_H__
+#define __LIBCFS_LINUX_CFS_TCP_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+#ifdef __KERNEL__
+#include <net/sock.h>
+
+typedef struct socket   cfs_socket_t;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,72))
+# define sk_allocation  allocation
+# define sk_data_ready  data_ready
+# define sk_write_space write_space
+# define sk_user_data   user_data
+# define sk_prot        prot
+# define sk_sndbuf      sndbuf
+# define sk_rcvbuf      rcvbuf
+# define sk_socket      socket
+# define sk_sleep       sleep
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+# define sk_wmem_queued wmem_queued
+# define sk_err         err
+# define sk_route_caps  route_caps
+#endif
+
+#define SOCK_SNDBUF(so)         ((so)->sk->sk_sndbuf)
+#define SOCK_WMEM_QUEUED(so)    ((so)->sk->sk_wmem_queued)
+#define SOCK_ERROR(so)          ((so)->sk->sk_err)
+#define SOCK_TEST_NOSPACE(so)   test_bit(SOCK_NOSPACE, &(so)->flags)
+
+#else   /* !__KERNEL__ */
+
+#include "../user-tcpip.h"
+
+#endif /* __KERNEL__ */
+
+#endif
diff --git a/libcfs/include/libcfs/linux/linux-time.h b/libcfs/include/libcfs/linux/linux-time.h
new file mode 100644 (file)
index 0000000..3d4cdf5
--- /dev/null
@@ -0,0 +1,327 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (C) 2004 Cluster File Systems, Inc.
+ * Author: Nikita Danilov <nikita@clusterfs.com>
+ *
+ * This file is part of Lustre, http://www.lustre.org.
+ *
+ * Lustre is free software; you can redistribute it and/or modify it under the
+ * terms of version 2 of the GNU General Public License as published by the
+ * Free Software Foundation.
+ *
+ * Lustre is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Lustre; if not, write to the Free Software Foundation, Inc., 675 Mass
+ * Ave, Cambridge, MA 02139, USA.
+ *
+ * Implementation of portable time API for Linux (kernel and user-level).
+ *
+ */
+
+#ifndef __LIBCFS_LINUX_LINUX_TIME_H__
+#define __LIBCFS_LINUX_LINUX_TIME_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+/* Portable time API */
+
+/*
+ * Platform provides three opaque data-types:
+ *
+ *  cfs_time_t        represents point in time. This is internal kernel
+ *                    time rather than "wall clock". This time bears no
+ *                    relation to gettimeofday().
+ *
+ *  cfs_duration_t    represents time interval with resolution of internal
+ *                    platform clock
+ *
+ *  cfs_fs_time_t     represents instance in world-visible time. This is
+ *                    used in file-system time-stamps
+ *
+ *  cfs_time_t     cfs_time_current(void);
+ *  cfs_time_t     cfs_time_add    (cfs_time_t, cfs_duration_t);
+ *  cfs_duration_t cfs_time_sub    (cfs_time_t, cfs_time_t);
+ *  int            cfs_time_before (cfs_time_t, cfs_time_t);
+ *  int            cfs_time_beforeq(cfs_time_t, cfs_time_t);
+ *
+ *  cfs_duration_t cfs_duration_build(int64_t);
+ *
+ *  time_t         cfs_duration_sec (cfs_duration_t);
+ *  void           cfs_duration_usec(cfs_duration_t, struct timeval *);
+ *  void           cfs_duration_nsec(cfs_duration_t, struct timespec *);
+ *
+ *  void           cfs_fs_time_current(cfs_fs_time_t *);
+ *  time_t         cfs_fs_time_sec    (cfs_fs_time_t *);
+ *  void           cfs_fs_time_usec   (cfs_fs_time_t *, struct timeval *);
+ *  void           cfs_fs_time_nsec   (cfs_fs_time_t *, struct timespec *);
+ *  int            cfs_fs_time_before (cfs_fs_time_t *, cfs_fs_time_t *);
+ *  int            cfs_fs_time_beforeq(cfs_fs_time_t *, cfs_fs_time_t *);
+ *
+ *  CFS_TIME_FORMAT
+ *  CFS_DURATION_FORMAT
+ *
+ */
+
+#define ONE_BILLION ((u_int64_t)1000000000)
+#define ONE_MILLION 1000000
+
+#ifdef __KERNEL__
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/time.h>
+#include <asm/div64.h>
+
+#include <libcfs/linux/portals_compat25.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+
+/*
+ * old kernels---CURRENT_TIME is struct timeval
+ */
+typedef struct timeval cfs_fs_time_t;
+
+static inline void cfs_fs_time_usec(cfs_fs_time_t *t, struct timeval *v)
+{
+        *v = *t;
+}
+
+static inline void cfs_fs_time_nsec(cfs_fs_time_t *t, struct timespec *s)
+{
+        s->tv_sec  = t->tv_sec;
+        s->tv_nsec = t->tv_usec * 1000;
+}
+
+/*
+ * internal helper function used by cfs_fs_time_before*()
+ */
+static inline unsigned long long __cfs_fs_time_flat(cfs_fs_time_t *t)
+{
+        return (unsigned long long)t->tv_sec * ONE_MILLION + t->tv_usec;
+}
+
+#define CURRENT_KERN_TIME        xtime
+
+#else
+/* (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) */
+
+/*
+ * post 2.5 kernels.
+ */
+
+#include <linux/jiffies.h>
+
+typedef struct timespec cfs_fs_time_t;
+
+static inline void cfs_fs_time_usec(cfs_fs_time_t *t, struct timeval *v)
+{
+        v->tv_sec  = t->tv_sec;
+        v->tv_usec = t->tv_nsec / 1000;
+}
+
+static inline void cfs_fs_time_nsec(cfs_fs_time_t *t, struct timespec *s)
+{
+        *s = *t;
+}
+
+/*
+ * internal helper function used by cfs_fs_time_before*()
+ */
+static inline unsigned long long __cfs_fs_time_flat(cfs_fs_time_t *t)
+{
+        return (unsigned long long)t->tv_sec * ONE_BILLION + t->tv_nsec;
+}
+
+#define CURRENT_KERN_TIME        CURRENT_TIME
+
+/* (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) */
+#endif
+
+/*
+ * Generic kernel stuff
+ */
+
+typedef unsigned long cfs_time_t;      /* jiffies */
+typedef long cfs_duration_t;
+
+
+static inline cfs_time_t cfs_time_current(void)
+{
+        return jiffies;
+}
+
+static inline time_t cfs_time_current_sec(void)
+{
+        return CURRENT_SECONDS;
+}
+
+static inline cfs_time_t cfs_time_add(cfs_time_t t, cfs_duration_t d)
+{
+        return t + d;
+}
+
+static inline cfs_duration_t cfs_time_sub(cfs_time_t t1, cfs_time_t t2)
+{
+        return t1 - t2;
+}
+
+static inline int cfs_time_before(cfs_time_t t1, cfs_time_t t2)
+{
+        return time_before(t1, t2);
+}
+
+static inline int cfs_time_beforeq(cfs_time_t t1, cfs_time_t t2)
+{
+        return time_before_eq(t1, t2);
+}
+
+static inline void cfs_fs_time_current(cfs_fs_time_t *t)
+{
+        *t = CURRENT_KERN_TIME;
+}
+
+static inline time_t cfs_fs_time_sec(cfs_fs_time_t *t)
+{
+        return t->tv_sec;
+}
+
+static inline int cfs_fs_time_before(cfs_fs_time_t *t1, cfs_fs_time_t *t2)
+{
+        return __cfs_fs_time_flat(t1) <  __cfs_fs_time_flat(t2);
+}
+
+static inline int cfs_fs_time_beforeq(cfs_fs_time_t *t1, cfs_fs_time_t *t2)
+{
+        return __cfs_fs_time_flat(t1) <= __cfs_fs_time_flat(t2);
+}
+
+#if 0
+static inline cfs_duration_t cfs_duration_build(int64_t nano)
+{
+#if (BITS_PER_LONG == 32)
+        /* We cannot use do_div(t, ONE_BILLION), do_div can only process
+         * 64 bits n and 32 bits base */
+        int64_t  t = nano * HZ;
+        do_div(t, 1000);
+        do_div(t, 1000000);
+        return (cfs_duration_t)t;
+#else
+        return (nano * HZ / ONE_BILLION);
+#endif
+}
+#endif
+
+static inline cfs_duration_t cfs_time_seconds(int seconds)
+{
+        return ((cfs_duration_t)seconds) * HZ;
+}
+
+static inline time_t cfs_duration_sec(cfs_duration_t d)
+{
+        return d / HZ;
+}
+
+static inline void cfs_duration_usec(cfs_duration_t d, struct timeval *s)
+{
+#if (BITS_PER_LONG == 32) && (HZ > 4096)
+        __u64 t;
+
+        s->tv_sec = d / HZ;
+        t = (d - (cfs_duration_t)s->tv_sec * HZ) * ONE_MILLION;
+        do_div(t, HZ);
+        s->tv_usec = t;
+#else
+        s->tv_sec = d / HZ;
+        s->tv_usec = ((d - (cfs_duration_t)s->tv_sec * HZ) * ONE_MILLION) / HZ;
+#endif
+}
+
+static inline void cfs_duration_nsec(cfs_duration_t d, struct timespec *s)
+{
+#if (BITS_PER_LONG == 32)
+        __u64 t;
+
+        s->tv_sec = d / HZ;
+        t = (d - s->tv_sec * HZ) * ONE_BILLION;
+        do_div(t, HZ);
+        s->tv_nsec = t;
+#else
+        s->tv_sec = d / HZ;
+        s->tv_nsec = ((d - s->tv_sec * HZ) * ONE_BILLION) / HZ;
+#endif
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+
+#define cfs_time_current_64 get_jiffies_64
+
+static inline __u64 cfs_time_add_64(__u64 t, __u64 d)
+{
+        return t + d;
+}
+
+static inline __u64 cfs_time_shift_64(int seconds)
+{
+        return cfs_time_add_64(cfs_time_current_64(),
+                               cfs_time_seconds(seconds));
+}
+
+static inline int cfs_time_before_64(__u64 t1, __u64 t2)
+{
+        return (__s64)t2 - (__s64)t1 > 0;
+}
+
+static inline int cfs_time_beforeq_64(__u64 t1, __u64 t2)
+{
+        return (__s64)t2 - (__s64)t1 >= 0;
+}
+
+#else
+#define cfs_time_current_64 cfs_time_current
+#define cfs_time_add_64     cfs_time_add
+#define cfs_time_shift_64   cfs_time_shift
+#define cfs_time_before_64  cfs_time_before
+#define cfs_time_beforeq_64 cfs_time_beforeq
+#endif
+
+/*
+ * One jiffy
+ */
+#define CFS_TICK                (1)
+
+#define CFS_TIME_T              "%lu"
+#define CFS_DURATION_T          "%ld"
+
+#else   /* !__KERNEL__ */
+
+/*
+ * Liblustre. time(2) based implementation.
+ */
+
+#define CFS_TIME_T              "%lu"
+
+#include <libcfs/user-time.h>
+
+#endif /* __KERNEL__ */
+
+/* __LIBCFS_LINUX_LINUX_TIME_H__ */
+#endif
+/*
+ * Local variables:
+ * c-indentation-style: "K&R"
+ * c-basic-offset: 8
+ * tab-width: 8
+ * fill-column: 80
+ * scroll-step: 1
+ * End:
+ */
diff --git a/libcfs/include/libcfs/linux/lltrace.h b/libcfs/include/libcfs/linux/lltrace.h
new file mode 100644 (file)
index 0000000..1ddd03d
--- /dev/null
@@ -0,0 +1,28 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ */
+#ifndef __LIBCFS_LINUX_LLTRACE_H__
+#define __LIBCFS_LINUX_LLTRACE_H__
+
+#ifndef __LIBCFS_LLTRACE_H__
+#error Do not #include this file directly. #include <libcfs/lltrace.h> instead
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <lnet/types.h>
+#include <libcfs/kp30.h>
+#include <lnet/lnetctl.h>
+#include <linux/limits.h>
+#include <asm/page.h>
+#include <linux/version.h>
+
+#endif
diff --git a/libcfs/include/libcfs/linux/portals_compat25.h b/libcfs/include/libcfs/linux/portals_compat25.h
new file mode 100644 (file)
index 0000000..2d6b782
--- /dev/null
@@ -0,0 +1,125 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ */
+#ifndef __LIBCFS_LINUX_PORTALS_COMPAT_H__
+#define __LIBCFS_LINUX_PORTALS_COMPAT_H__
+
+// XXX BUG 1511 -- remove this stanza and all callers when bug 1511 is resolved
+#if defined(SPINLOCK_DEBUG) && SPINLOCK_DEBUG
+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) || defined(CONFIG_RH_2_4_20)
+#  define SIGNAL_MASK_ASSERT() \
+   LASSERT(current->sighand->siglock.magic == SPINLOCK_MAGIC)
+# else
+#  define SIGNAL_MASK_ASSERT() \
+   LASSERT(current->sigmask_lock.magic == SPINLOCK_MAGIC)
+# endif
+#else
+# define SIGNAL_MASK_ASSERT()
+#endif
+// XXX BUG 1511 -- remove this stanza and all callers when bug 1511 is resolved
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
+
+# define SIGNAL_MASK_LOCK(task, flags)                                  \
+  spin_lock_irqsave(&task->sighand->siglock, flags)
+# define SIGNAL_MASK_UNLOCK(task, flags)                                \
+  spin_unlock_irqrestore(&task->sighand->siglock, flags)
+# define USERMODEHELPER(path, argv, envp)                               \
+  call_usermodehelper(path, argv, envp, 1)
+# define RECALC_SIGPENDING         recalc_sigpending()
+# define CLEAR_SIGPENDING          clear_tsk_thread_flag(current,       \
+                                                         TIF_SIGPENDING)
+# define CURRENT_SECONDS           get_seconds()
+# define smp_num_cpus              num_online_cpus()
+
+
+#elif defined(CONFIG_RH_2_4_20) /* RH 2.4.x */
+
+# define SIGNAL_MASK_LOCK(task, flags)                                  \
+  spin_lock_irqsave(&task->sighand->siglock, flags)
+# define SIGNAL_MASK_UNLOCK(task, flags)                                \
+  spin_unlock_irqrestore(&task->sighand->siglock, flags)
+# define USERMODEHELPER(path, argv, envp)                               \
+  call_usermodehelper(path, argv, envp)
+# define RECALC_SIGPENDING         recalc_sigpending()
+# define CLEAR_SIGPENDING          (current->sigpending = 0)
+# define CURRENT_SECONDS           CURRENT_TIME
+# define wait_event_interruptible_exclusive(wq, condition)              \
+        wait_event_interruptible(wq, condition)
+
+#else /* 2.4.x */
+
+# define SIGNAL_MASK_LOCK(task, flags)                                  \
+  spin_lock_irqsave(&task->sigmask_lock, flags)
+# define SIGNAL_MASK_UNLOCK(task, flags)                                \
+  spin_unlock_irqrestore(&task->sigmask_lock, flags)
+# define USERMODEHELPER(path, argv, envp)                               \
+  call_usermodehelper(path, argv, envp)
+# define RECALC_SIGPENDING         recalc_sigpending(current)
+# define CLEAR_SIGPENDING          (current->sigpending = 0)
+# define CURRENT_SECONDS           CURRENT_TIME
+# define wait_event_interruptible_exclusive(wq, condition)              \
+        wait_event_interruptible(wq, condition)
+
+#endif
+
+#if defined(__arch_um__) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20))
+#define UML_PID(tsk) ((tsk)->thread.extern_pid)
+#elif defined(__arch_um__) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#define UML_PID(tsk) ((tsk)->thread.mode.tt.extern_pid)
+#else
+#define UML_PID(tsk) ((tsk)->pid)
+#endif
+
+#if defined(__arch_um__) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+# define THREAD_NAME(comm, len, fmt, a...)                              \
+        snprintf(comm, len,fmt"|%d", ## a, UML_PID(current))
+#else
+# define THREAD_NAME(comm, len, fmt, a...)                              \
+        snprintf(comm, len, fmt, ## a)
+#endif
+
+#ifdef HAVE_PAGE_LIST
+/* 2.4 alloc_page users can use page->list */
+#define PAGE_LIST_ENTRY list
+#define PAGE_LIST(page) ((page)->list)
+#else
+/* 2.6 alloc_page users can use page->lru */
+#define PAGE_LIST_ENTRY lru
+#define PAGE_LIST(page) ((page)->lru)
+#endif
+
+#ifndef HAVE_CPU_ONLINE
+#define cpu_online(cpu) ((1<<cpu) & (cpu_online_map))
+#endif
+#ifndef HAVE_CPUMASK_T
+typedef unsigned long cpumask_t;
+#define cpu_set(cpu, map) set_bit(cpu, &(map))
+#define cpus_clear(map) memset(&(map), 0, sizeof(cpumask_t))
+#endif
+
+#ifndef __user
+#define __user
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8)
+#define ll_proc_dointvec(table, write, filp, buffer, lenp, ppos)        \
+        proc_dointvec(table, write, filp, buffer, lenp)
+#define ll_proc_dostring(table, write, filp, buffer, lenp, ppos)        \
+        proc_dostring(table, write, filp, buffer, lenp)
+#define LL_PROC_PROTO(name)                                             \
+        name(cfs_sysctl_table_t *table, int write, struct file *filp,   \
+             void __user *buffer, size_t *lenp)
+#define DECLARE_LL_PROC_PPOS_DECL  loff_t *ppos = &filp->f_pos
+#else
+#define ll_proc_dointvec(table, write, filp, buffer, lenp, ppos)        \
+        proc_dointvec(table, write, filp, buffer, lenp, ppos);
+#define ll_proc_dostring(table, write, filp, buffer, lenp, ppos)        \
+        proc_dostring(table, write, filp, buffer, lenp, ppos);
+#define LL_PROC_PROTO(name)                                             \
+        name(cfs_sysctl_table_t *table, int write, struct file *filp,   \
+             void __user *buffer, size_t *lenp, loff_t *ppos)
+#define DECLARE_LL_PROC_PPOS_DECL
+#endif
+
+#endif /* _PORTALS_COMPAT_H */
diff --git a/libcfs/include/libcfs/linux/portals_utils.h b/libcfs/include/libcfs/linux/portals_utils.h
new file mode 100644 (file)
index 0000000..4e76856
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef __LIBCFS_LINUX_PORTALS_UTILS_H__
+#define __LIBCFS_LINUX_PORTALS_UTILS_H__
+
+#ifndef __LIBCFS_PORTALS_UTILS_H__
+#error Do not #include this file directly. #include <libcfs/portals_utils.h> instead
+#endif
+
+#ifdef __KERNEL__
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/smp_lock.h>
+#include <linux/poll.h>
+#include <linux/random.h>
+
+#include <asm/unistd.h>
+#include <asm/semaphore.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+# include <linux/tqueue.h>
+#else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) */
+# include <linux/workqueue.h>
+#endif
+#include <libcfs/linux/linux-mem.h>
+#include <libcfs/linux/linux-prim.h>
+#else /* !__KERNEL__ */
+
+#include <endian.h>
+#include <libcfs/list.h>
+
+#ifdef HAVE_LINUX_VERSION_H
+# include <linux/version.h>
+
+# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#  define BUG()                            /* workaround for module.h includes */
+#  include <linux/module.h>
+# endif
+#endif /* !HAVE_LINUX_VERSION_H */
+
+#ifndef __CYGWIN__
+# include <sys/syscall.h>
+#else /* __CYGWIN__ */
+# include <windows.h>
+# include <windef.h>
+# include <netinet/in.h>
+#endif /* __CYGWIN__ */
+
+#endif /* !__KERNEL__ */
+#endif
diff --git a/libcfs/include/libcfs/list.h b/libcfs/include/libcfs/list.h
new file mode 100644 (file)
index 0000000..ed03bd5
--- /dev/null
@@ -0,0 +1,463 @@
+#ifndef __LIBCFS_LIST_H__
+#define __LIBCFS_LIST_H__
+
+#if defined (__linux__) && defined(__KERNEL__)
+
+#include <linux/list.h>
+
+#define CFS_LIST_HEAD_INIT(n)          LIST_HEAD_INIT(n)
+#define CFS_LIST_HEAD(n)               LIST_HEAD(n)
+#define CFS_INIT_LIST_HEAD(p)          INIT_LIST_HEAD(p)
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+#define CFS_HLIST_HEAD_INIT            HLIST_HEAD_INIT
+#define CFS_HLIST_HEAD(n)              HLIST_HEAD(n)
+#define CFS_INIT_HLIST_HEAD(p)         INIT_HLIST_HEAD(p)
+#define CFS_INIT_HLIST_NODE(p)         INIT_HLIST_NODE(p)
+#endif
+
+#else /* !defined (__linux__) || !defined(__KERNEL__) */
+
+/*
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+
+#ifndef __WINNT__
+#define prefetch(a) ((void)a)
+#else
+#define prefetch(a) ((void *)a)
+#endif
+
+struct list_head {
+       struct list_head *next, *prev;
+};
+
+typedef struct list_head list_t;
+
+#define CFS_LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define CFS_LIST_HEAD(name) \
+       struct list_head name = CFS_LIST_HEAD_INIT(name)
+
+#define CFS_INIT_LIST_HEAD(ptr) do { \
+       (ptr)->next = (ptr); (ptr)->prev = (ptr); \
+} while (0)
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_add(struct list_head * new,
+                             struct list_head * prev,
+                             struct list_head * next)
+{
+       next->prev = new;
+       new->next = next;
+       new->prev = prev;
+       prev->next = new;
+}
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static inline void list_add(struct list_head *new, struct list_head *head)
+{
+       __list_add(new, head, head->next);
+}
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void list_add_tail(struct list_head *new, struct list_head *head)
+{
+       __list_add(new, head->prev, head);
+}
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_del(struct list_head * prev, struct list_head * next)
+{
+       next->prev = prev;
+       prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty on entry does not return true after this, the entry is in an undefined state.
+ */
+static inline void list_del(struct list_head *entry)
+{
+       __list_del(entry->prev, entry->next);
+}
+
+/**
+ * list_del_init - deletes entry from list and reinitialize it.
+ * @entry: the element to delete from the list.
+ */
+static inline void list_del_init(struct list_head *entry)
+{
+       __list_del(entry->prev, entry->next);
+       CFS_INIT_LIST_HEAD(entry);
+}
+
+/**
+ * list_move - delete from one list and add as another's head
+ * @list: the entry to move
+ * @head: the head that will precede our entry
+ *
+ * This is not safe to use if @list is already on the same list as @head.
+ */
+static inline void list_move(struct list_head *list, struct list_head *head)
+{
+       __list_del(list->prev, list->next);
+       list_add(list, head);
+}
+
+/**
+ * list_move_tail - delete from one list and add as another's tail
+ * @list: the entry to move
+ * @head: the head that will follow our entry
+ *
+ * This is not safe to use if @list is already on the same list as @head.
+ */
+static inline void list_move_tail(struct list_head *list,
+                                 struct list_head *head)
+{
+       __list_del(list->prev, list->next);
+       list_add_tail(list, head);
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static inline int list_empty(struct list_head *head)
+{
+       return head->next == head;
+}
+
+static inline void __list_splice(struct list_head *list,
+                                struct list_head *head)
+{
+       struct list_head *first = list->next;
+       struct list_head *last = list->prev;
+       struct list_head *at = head->next;
+
+       first->prev = head;
+       head->next = first;
+
+       last->next = at;
+       at->prev = last;
+}
+
+/**
+ * list_splice - join two lists
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice(struct list_head *list, struct list_head *head)
+{
+       if (!list_empty(list))
+               __list_splice(list, head);
+}
+
+/**
+ * list_splice_init - join two lists and reinitialise the emptied list.
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_init(struct list_head *list,
+                                   struct list_head *head)
+{
+       if (!list_empty(list)) {
+               __list_splice(list, head);
+               CFS_INIT_LIST_HEAD(list);
+       }
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr:       the &struct list_head pointer.
+ * @type:      the type of the struct this is embedded in.
+ * @member:    the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+       ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
+
+/**
+ * list_for_each       -       iterate over a list
+ * @pos:       the &struct list_head to use as a loop counter.
+ * @head:      the head for your list.
+ */
+#define list_for_each(pos, head) \
+       for (pos = (head)->next, prefetch(pos->next); pos != (head); \
+               pos = pos->next, prefetch(pos->next))
+
+/**
+ * list_for_each_safe  -       iterate over a list safe against removal of list entry
+ * @pos:       the &struct list_head to use as a loop counter.
+ * @n:         another &struct list_head to use as temporary storage
+ * @head:      the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+       for (pos = (head)->next, n = pos->next; pos != (head); \
+               pos = n, n = pos->next)
+
+/*
+ * Double linked lists with a single pointer list head.
+ * Mostly useful for hash tables where the two pointer list head is
+ * too wasteful.
+ * You lose the ability to access the tail in O(1).
+ */
+
+struct hlist_head {
+       struct hlist_node *first;
+};
+
+struct hlist_node {
+       struct hlist_node *next, **pprev;
+};
+
+/*
+ * "NULL" might not be defined at this point
+ */
+#ifdef NULL
+#define NULL_P NULL
+#else
+#define NULL_P ((void *)0)
+#endif
+
+#define CFS_HLIST_HEAD_INIT { .first = NULL_P }
+#define CFS_HLIST_HEAD(name) struct hlist_head name = {  .first = NULL_P }
+#define CFS_INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL_P)
+#define CFS_INIT_HLIST_NODE(ptr) ((ptr)->next = NULL_P, (ptr)->pprev = NULL_P)
+
+#define HLIST_HEAD_INIT                CFS_HLIST_HEAD_INIT
+#define HLIST_HEAD(n)          CFS_HLIST_HEAD(n)
+#define INIT_HLIST_HEAD(p)     CFS_INIT_HLIST_HEAD(p)
+#define INIT_HLIST_NODE(p)     CFS_INIT_HLIST_NODE(p)
+
+static inline int hlist_unhashed(const struct hlist_node *h)
+{
+       return !h->pprev;
+}
+
+static inline int hlist_empty(const struct hlist_head *h)
+{
+       return !h->first;
+}
+
+static inline void __hlist_del(struct hlist_node *n)
+{
+       struct hlist_node *next = n->next;
+       struct hlist_node **pprev = n->pprev;
+       *pprev = next;
+       if (next)
+               next->pprev = pprev;
+}
+
+static inline void hlist_del(struct hlist_node *n)
+{
+       __hlist_del(n);
+}
+
+static inline void hlist_del_init(struct hlist_node *n)
+{
+       if (n->pprev)  {
+               __hlist_del(n);
+               INIT_HLIST_NODE(n);
+       }
+}
+
+static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
+{
+       struct hlist_node *first = h->first;
+       n->next = first;
+       if (first)
+               first->pprev = &n->next;
+       h->first = n;
+       n->pprev = &h->first;
+}
+
+/* next must be != NULL */
+static inline void hlist_add_before(struct hlist_node *n,
+                                       struct hlist_node *next)
+{
+       n->pprev = next->pprev;
+       n->next = next;
+       next->pprev = &n->next;
+       *(n->pprev) = n;
+}
+
+static inline void hlist_add_after(struct hlist_node *n,
+                                       struct hlist_node *next)
+{
+       next->next = n->next;
+       n->next = next;
+       next->pprev = &n->next;
+
+       if(next->next)
+               next->next->pprev  = &next->next;
+}
+
+#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
+
+#define hlist_for_each(pos, head) \
+       for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \
+            pos = pos->next)
+
+#define hlist_for_each_safe(pos, n, head) \
+       for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
+            pos = n)
+
+/**
+ * hlist_for_each_entry        - iterate over list of given type
+ * @tpos:      the type * to use as a loop counter.
+ * @pos:       the &struct hlist_node to use as a loop counter.
+ * @head:      the head for your list.
+ * @member:    the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry(tpos, pos, head, member)                   \
+       for (pos = (head)->first;                                        \
+            pos && ({ prefetch(pos->next); 1;}) &&                      \
+               ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
+            pos = pos->next)
+
+/**
+ * hlist_for_each_entry_continue - iterate over a hlist continuing after existing point
+ * @tpos:      the type * to use as a loop counter.
+ * @pos:       the &struct hlist_node to use as a loop counter.
+ * @member:    the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry_continue(tpos, pos, member)                \
+       for (pos = (pos)->next;                                          \
+            pos && ({ prefetch(pos->next); 1;}) &&                      \
+               ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
+            pos = pos->next)
+
+/**
+ * hlist_for_each_entry_from - iterate over a hlist continuing from existing point
+ * @tpos:      the type * to use as a loop counter.
+ * @pos:       the &struct hlist_node to use as a loop counter.
+ * @member:    the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry_from(tpos, pos, member)                    \
+       for (; pos && ({ prefetch(pos->next); 1;}) &&                    \
+               ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
+            pos = pos->next)
+
+/**
+ * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @tpos:      the type * to use as a loop counter.
+ * @pos:       the &struct hlist_node to use as a loop counter.
+ * @n:         another &struct hlist_node to use as temporary storage
+ * @head:      the head for your list.
+ * @member:    the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry_safe(tpos, pos, n, head, member)           \
+       for (pos = (head)->first;                                        \
+            pos && ({ n = pos->next; 1; }) &&                           \
+               ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
+            pos = n)
+
+#endif /* __linux__ && __KERNEL__ */
+
+#ifndef list_for_each_prev
+/**
+ * list_for_each_prev  -       iterate over a list in reverse order
+ * @pos:       the &struct list_head to use as a loop counter.
+ * @head:      the head for your list.
+ */
+#define list_for_each_prev(pos, head) \
+       for (pos = (head)->prev, prefetch(pos->prev); pos != (head); \
+               pos = pos->prev, prefetch(pos->prev))
+
+#endif /* list_for_each_prev */
+
+#ifndef list_for_each_entry
+/**
+ * list_for_each_entry  -       iterate over list of given type
+ * @pos:        the type * to use as a loop counter.
+ * @head:       the head for your list.
+ * @member:     the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, member)                         \
+        for (pos = list_entry((head)->next, typeof(*pos), member),     \
+                    prefetch(pos->member.next);                        \
+            &pos->member != (head);                                    \
+            pos = list_entry(pos->member.next, typeof(*pos), member),  \
+            prefetch(pos->member.next))
+#endif /* list_for_each_entry */
+
+#ifndef list_for_each_entry_reverse
+/**
+ * list_for_each_entry_reverse - iterate backwards over list of given type.
+ * @pos:        the type * to use as a loop counter.
+ * @head:       the head for your list.
+ * @member:     the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_reverse(pos, head, member)                  \
+       for (pos = list_entry((head)->prev, typeof(*pos), member);      \
+            prefetch(pos->member.prev), &pos->member != (head);        \
+            pos = list_entry(pos->member.prev, typeof(*pos), member))
+#endif /* list_for_each_entry_reverse */
+
+#ifndef list_for_each_entry_safe
+/**
+ * list_for_each_entry_safe  -       iterate over list of given type safe against removal of list entry
+ * @pos:        the type * to use as a loop counter.
+ * @n:          another type * to use as temporary storage
+ * @head:       the head for your list.
+ * @member:     the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, member)                 \
+        for (pos = list_entry((head)->next, typeof(*pos), member),     \
+               n = list_entry(pos->member.next, typeof(*pos), member); \
+            &pos->member != (head);                                    \
+            pos = n, n = list_entry(n->member.next, typeof(*n), member))
+#endif /* list_for_each_entry_safe */
+
+#ifndef list_for_each_entry_safe_from
+/**
+ * list_for_each_entry_safe_from
+ * @pos:        the type * to use as a loop cursor.
+ * @n:          another type * to use as temporary storage
+ * @head:       the head for your list.
+ * @member:     the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type from current point, safe against
+ * removal of list entry.
+ */
+#define list_for_each_entry_safe_from(pos, n, head, member)                 \
+        for (n = list_entry(pos->member.next, typeof(*pos), member);        \
+             &pos->member != (head);                                        \
+             pos = n, n = list_entry(n->member.next, typeof(*n), member))
+#endif /* list_for_each_entry_safe_from */
+
+#endif /* __LIBCFS_LUSTRE_LIST_H__ */
diff --git a/libcfs/include/libcfs/lltrace.h b/libcfs/include/libcfs/lltrace.h
new file mode 100644 (file)
index 0000000..dbeae91
--- /dev/null
@@ -0,0 +1,167 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Compile with:
+ * cc -I../../portals/include -o fio fio.c -L../../portals/linux/utils -lptlctl
+ */
+#ifndef __LIBCFS_LLTRACE_H__
+#define __LIBCFS_LLTRACE_H__
+
+#if defined(__linux__)
+#include <libcfs/linux/lltrace.h>
+#elif defined(__APPLE__)
+#include <libcfs/darwin/lltrace.h>
+#elif defined(__WINNT__)
+#include <libcfs/winnt/lltrace.h>
+#else
+#error Unsupported Operating System
+#endif
+
+static inline int ltrace_write_file(char* fname)
+{
+        char* argv[3];
+
+        argv[0] = "debug_kernel";
+        argv[1] = fname;
+        argv[2] = "1";
+
+        fprintf(stderr, "[ptlctl] %s %s %s\n", argv[0], argv[1], argv[2]);
+
+        return jt_dbg_debug_kernel(3, argv);
+}
+
+static inline int ltrace_clear()
+{
+        char* argv[1];
+
+        argv[0] = "clear";
+
+        fprintf(stderr, "[ptlctl] %s\n", argv[0]);
+
+        return jt_dbg_clear_debug_buf(1, argv);
+}
+
+static inline int ltrace_mark(int indent_level, char* text)
+{
+        char* argv[2];
+        char mark_buf[PATH_MAX];
+
+        snprintf(mark_buf, PATH_MAX, "====%d=%s", indent_level, text);
+
+        argv[0] = "mark";
+        argv[1] = mark_buf;
+        return jt_dbg_mark_debug_buf(2, argv);
+}
+
+static inline int ltrace_applymasks()
+{
+        char* argv[2];
+        argv[0] = "list";
+        argv[1] = "applymasks";
+
+        fprintf(stderr, "[ptlctl] %s %s\n", argv[0], argv[1]);
+
+        return jt_dbg_list(2, argv);
+}
+
+
+static inline int ltrace_filter(char* subsys_or_mask)
+{
+        char* argv[2];
+        argv[0] = "filter";
+        argv[1] = subsys_or_mask;
+        return jt_dbg_filter(2, argv);
+}
+
+static inline int ltrace_show(char* subsys_or_mask)
+{
+        char* argv[2];
+        argv[0] = "show";
+        argv[1] = subsys_or_mask;
+        return jt_dbg_show(2, argv);
+}
+
+static inline int ltrace_start()
+{
+        int rc = 0;
+        dbg_initialize(0, NULL);
+#ifdef LNET_DEV_ID
+        rc = register_ioc_dev(LNET_DEV_ID, LNET_DEV_PATH,
+                              LNET_DEV_MAJOR, LNET_DEV_MINOR);
+#endif
+        ltrace_filter("class");
+        ltrace_filter("nal");
+        ltrace_filter("portals");
+
+        ltrace_show("all_types");
+        ltrace_filter("trace");
+        ltrace_filter("malloc");
+        ltrace_filter("net");
+        ltrace_filter("page");
+        ltrace_filter("other");
+        ltrace_filter("info");
+        ltrace_applymasks();
+
+        return rc;
+}
+
+
+static inline void ltrace_stop()
+{
+#ifdef LNET_DEV_ID
+        unregister_ioc_dev(LNET_DEV_ID);
+#endif
+}
+
+static inline int not_uml()
+{
+  /* Return Values:
+   *   0 when run under UML
+   *   1 when run on host
+   *  <0 when lookup failed
+   */
+        struct stat buf;
+        int rc = stat("/dev/ubd", &buf);
+        rc = ((rc<0) && (errno == ENOENT)) ? 1 : rc;
+        if (rc<0) {
+          fprintf(stderr, "Cannot stat /dev/ubd: %s\n", strerror(errno));
+          rc = 1; /* Assume host */
+        }
+        return rc;
+}
+
+#define LTRACE_MAX_NOB   256
+static inline void ltrace_add_processnames(char* fname)
+{
+        char cmdbuf[LTRACE_MAX_NOB];
+        struct timeval tv;
+        struct timezone tz;
+        int nob;
+        int underuml = !not_uml();
+
+        gettimeofday(&tv, &tz);
+
+        nob = snprintf(cmdbuf, LTRACE_MAX_NOB, "ps --no-headers -eo \"");
+
+        /* Careful - these format strings need to match the CDEBUG
+         * formats in portals/linux/debug.c EXACTLY
+         */
+        nob += snprintf(cmdbuf+nob, LTRACE_MAX_NOB, "%02x:%06x:%d:%lu.%06lu ",
+                        S_RPC >> 24, D_VFSTRACE, 0, tv.tv_sec, tv.tv_usec);
+
+        if (underuml && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))) {
+                nob += snprintf (cmdbuf+nob, LTRACE_MAX_NOB,
+                                 "(%s:%d:%s() %d | %d+%lu): ",
+                                 "lltrace.h", __LINE__, __FUNCTION__, 0, 0, 0L);
+        }
+        else {
+                nob += snprintf (cmdbuf+nob, LTRACE_MAX_NOB,
+                                 "(%s:%d:%s() %d+%lu): ",
+                                 "lltrace.h", __LINE__, __FUNCTION__, 0, 0L);
+        }
+
+        nob += snprintf(cmdbuf+nob, LTRACE_MAX_NOB, " %%p %%c\" >> %s", fname);
+        system(cmdbuf);
+}
+
+#endif
diff --git a/libcfs/include/libcfs/portals_utils.h b/libcfs/include/libcfs/portals_utils.h
new file mode 100644 (file)
index 0000000..b79eb7e
--- /dev/null
@@ -0,0 +1,21 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ */
+#ifndef __LIBCFS_PORTALS_UTILS_H__
+#define __LIBCFS_PORTALS_UTILS_H__
+
+/*
+ * portals_utils.h
+ *
+ */
+#if defined(__linux__)
+#include <libcfs/linux/portals_utils.h>
+#elif defined(__APPLE__)
+#include <libcfs/darwin/portals_utils.h>
+#elif defined(__WINNT__)
+#include <libcfs/winnt/portals_utils.h>
+#else
+#error Unsupported Operating System
+#endif
+
+#endif
diff --git a/libcfs/include/libcfs/types.h b/libcfs/include/libcfs/types.h
new file mode 100644 (file)
index 0000000..71dd7fb
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef _LIBCFS_TYPES_H
+#define _LIBCFS_TYPES_H
+
+/*
+ * This file was inttroduced to resolve XT3 (Catamount) build issues.
+ * The orignal idea was to move <lustre/types.h> here however at
+ * the time of this writing
+ * it's unclear what external dependencies are tied
+ * to that file (It's not just some source file #including it)
+ * there is some build/packaging infrastructure that includes it.
+ * Hopefully that will be resolved shortly, that file will
+ * be removed, its contents copied here and this comment can be deleted.
+ */
+
+#include <lustre/types.h>
+
+#endif
diff --git a/libcfs/include/libcfs/user-bitops.h b/libcfs/include/libcfs/user-bitops.h
new file mode 100644 (file)
index 0000000..d2eea0e
--- /dev/null
@@ -0,0 +1,102 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (C) 2004 Cluster File Systems, Inc.
+ * Author: Nikita Danilov <nikita@clusterfs.com>
+ *
+ * This file is part of Lustre, http://www.lustre.org.
+ *
+ * Lustre is free software; you can redistribute it and/or modify it under the
+ * terms of version 2 of the GNU General Public License as published by the
+ * Free Software Foundation.
+ *
+ * Lustre is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Lustre; if not, write to the Free Software Foundation, Inc., 675 Mass
+ * Ave, Cambridge, MA 02139, USA.
+ *
+ * Implementation of portable time API for user-level.
+ *
+ */
+
+#ifndef __LIBCFS_USER_BITOPS_H__
+#define __LIBCFS_USER_BITOPS_H__
+
+/* test if bit nr is set in bitmap addr; returns previous value of bit nr */
+static __inline__ int set_bit(int nr, unsigned long * addr)
+{
+        long    mask;
+
+        addr += nr / BITS_PER_LONG;
+        mask = 1UL << (nr & (BITS_PER_LONG - 1));
+        nr = (mask & *addr) != 0;
+        *addr |= mask;
+        return nr;
+}
+
+/* clear bit nr in bitmap addr; returns previous value of bit nr*/
+static __inline__ int clear_bit(int nr, unsigned long * addr)
+{
+        long    mask;
+
+        addr += nr / BITS_PER_LONG;
+        mask = 1UL << (nr & (BITS_PER_LONG - 1));
+        nr = (mask & *addr) != 0;
+        *addr &= ~mask;
+        return nr;
+}
+
+static __inline__ int test_bit(int nr, const unsigned long * addr)
+{
+        return ((1UL << (nr & (BITS_PER_LONG - 1))) & ((addr)[nr / BITS_PER_LONG])) != 0;
+}
+
+/* using binary seach */
+static __inline__ unsigned long __ffs(long data)
+{
+        int pos = 0;
+
+#if BITS_PER_LONG == 64
+        if ((data & 0xFFFFFFFF) == 0) {
+                pos += 32;
+                data >>= 32;
+        }
+#endif
+        if ((data & 0xFFFF) == 0) {
+                pos += 16;
+                data >>= 16;
+        }
+        if ((data & 0xFF) == 0) {
+                pos += 8;
+                data >>= 8;
+        }
+        if ((data & 0xF) == 0) {
+                pos += 4;
+                data >>= 4;
+        }
+        if ((data & 0x3) == 0) {
+                pos += 2;
+                data >>= 2;
+        }
+        if ((data & 0x1) == 0)
+                pos += 1;
+
+        return pos;
+}
+
+#define __ffz(x)       __ffs(~(x))
+
+unsigned long find_next_bit(unsigned long *addr,
+                            unsigned long size, unsigned long offset);
+
+unsigned long find_next_zero_bit(unsigned long *addr,
+                                 unsigned long size, unsigned long offset);
+
+#define find_first_bit(addr,size)       (find_next_bit((addr),(size),0))
+#define find_first_zero_bit(addr,size)  (find_next_zero_bit((addr),(size),0))
+
+#endif
diff --git a/libcfs/include/libcfs/user-lock.h b/libcfs/include/libcfs/user-lock.h
new file mode 100644 (file)
index 0000000..6b46ce2
--- /dev/null
@@ -0,0 +1,243 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (C) 2004 Cluster File Systems, Inc.
+ * Author: Nikita Danilov <nikita@clusterfs.com>
+ *
+ * This file is part of Lustre, http://www.lustre.org.
+ *
+ * Lustre is free software; you can redistribute it and/or modify it under the
+ * terms of version 2 of the GNU General Public License as published by the
+ * Free Software Foundation.
+ *
+ * Lustre is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Lustre; if not, write to the Free Software Foundation, Inc., 675 Mass
+ * Ave, Cambridge, MA 02139, USA.
+ *
+ * Implementation of portable time API for user-level.
+ *
+ */
+
+#ifndef __LIBCFS_USER_LOCK_H__
+#define __LIBCFS_USER_LOCK_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+/* Implementations of portable synchronization APIs for liblustre */
+
+/*
+ * liblustre is single-threaded, so most "synchronization" APIs are trivial.
+ *
+ * XXX Liang: There are several branches share lnet with b_hd_newconfig,
+ * if we define lock APIs at here, there will be conflict with liblustre
+ * in other branches.
+ */
+
+#ifndef __KERNEL__
+#include <stdio.h>
+#include <stdlib.h>
+
+#if 0
+/*
+ * Optional debugging (magic stamping and checking ownership) can be added.
+ */
+
+/*
+ * spin_lock
+ *
+ * - spin_lock_init(x)
+ * - spin_lock(x)
+ * - spin_unlock(x)
+ * - spin_trylock(x)
+ *
+ * - spin_lock_irqsave(x, f)
+ * - spin_unlock_irqrestore(x, f)
+ *
+ * No-op implementation.
+ */
+struct spin_lock {int foo;};
+
+typedef struct spin_lock spinlock_t;
+
+#define SPIN_LOCK_UNLOCKED (spinlock_t) { }
+#define LASSERT_SPIN_LOCKED(lock) do {} while(0)
+
+void spin_lock_init(spinlock_t *lock);
+void spin_lock(spinlock_t *lock);
+void spin_unlock(spinlock_t *lock);
+int spin_trylock(spinlock_t *lock);
+void spin_lock_bh_init(spinlock_t *lock);
+void spin_lock_bh(spinlock_t *lock);
+void spin_unlock_bh(spinlock_t *lock);
+static inline int spin_is_locked(spinlock_t *l) {return 1;}
+
+static inline void spin_lock_irqsave(spinlock_t *l, unsigned long f){}
+static inline void spin_unlock_irqrestore(spinlock_t *l, unsigned long f){}
+
+/*
+ * Semaphore
+ *
+ * - sema_init(x, v)
+ * - __down(x)
+ * - __up(x)
+ */
+typedef struct semaphore {
+    int foo;
+} mutex_t;
+
+void sema_init(struct semaphore *s, int val);
+void __down(struct semaphore *s);
+void __up(struct semaphore *s);
+
+/*
+ * Mutex:
+ *
+ * - init_mutex(x)
+ * - init_mutex_locked(x)
+ * - mutex_up(x)
+ * - mutex_down(x)
+ */
+#define mutex_up(s)                    __up(s)
+#define mutex_down(s)                  __down(s)
+
+#define init_mutex(x)                  sema_init(x, 1)
+#define init_mutex_locked(x)           sema_init(x, 0)
+
+/*
+ * Completion:
+ *
+ * - init_completion(c)
+ * - complete(c)
+ * - wait_for_completion(c)
+ */
+#if 0
+struct completion {};
+
+void init_completion(struct completion *c);
+void complete(struct completion *c);
+void wait_for_completion(struct completion *c);
+#endif
+
+/*
+ * rw_semaphore:
+ *
+ * - init_rwsem(x)
+ * - down_read(x)
+ * - up_read(x)
+ * - down_write(x)
+ * - up_write(x)
+ */
+struct rw_semaphore {};
+
+void init_rwsem(struct rw_semaphore *s);
+void down_read(struct rw_semaphore *s);
+int down_read_trylock(struct rw_semaphore *s);
+void down_write(struct rw_semaphore *s);
+int down_write_trylock(struct rw_semaphore *s);
+void up_read(struct rw_semaphore *s);
+void up_write(struct rw_semaphore *s);
+
+/*
+ * read-write lock : Need to be investigated more!!
+ * XXX nikita: for now, let rwlock_t to be identical to rw_semaphore
+ *
+ * - DECLARE_RWLOCK(l)
+ * - rwlock_init(x)
+ * - read_lock(x)
+ * - read_unlock(x)
+ * - write_lock(x)
+ * - write_unlock(x)
+ */
+typedef struct rw_semaphore rwlock_t;
+
+#define rwlock_init(pl)                init_rwsem(pl)
+
+#define read_lock(l)           down_read(l)
+#define read_unlock(l)         up_read(l)
+#define write_lock(l)          down_write(l)
+#define write_unlock(l)                up_write(l)
+
+static inline void
+write_lock_irqsave(rwlock_t *l, unsigned long f) { write_lock(l); }
+static inline void
+write_unlock_irqrestore(rwlock_t *l, unsigned long f) { write_unlock(l); }
+
+static inline void 
+read_lock_irqsave(rwlock_t *l, unsigned long f) { read_lock(l); }
+static inline void
+read_unlock_irqrestore(rwlock_t *l, unsigned long f) { read_unlock(l); }
+
+/*
+ * Atomic for user-space
+ * Copied from liblustre
+ */
+typedef struct { volatile int counter; } atomic_t;
+
+#define ATOMIC_INIT(i) { (i) }
+#define atomic_read(a) ((a)->counter)
+#define atomic_set(a,b) do {(a)->counter = b; } while (0)
+#define atomic_dec_and_test(a) ((--((a)->counter)) == 0)
+#define atomic_inc(a)  (((a)->counter)++)
+#define atomic_dec(a)  do { (a)->counter--; } while (0)
+#define atomic_add(b,a)  do {(a)->counter += b;} while (0)
+#define atomic_add_return(n,a) ((a)->counter = n)
+#define atomic_inc_return(a) atomic_add_return(1,a)
+#define atomic_sub(b,a)  do {(a)->counter -= b;} while (0)
+
+#endif
+
+#ifdef HAVE_LIBPTHREAD
+#include <pthread.h>
+
+/*
+ * Completion
+ */
+
+struct cfs_completion {
+        int c_done;
+        pthread_cond_t c_cond;
+        pthread_mutex_t c_mut;
+};
+
+void cfs_init_completion(struct cfs_completion *c);
+void cfs_fini_completion(struct cfs_completion *c);
+void cfs_complete(struct cfs_completion *c);
+void cfs_wait_for_completion(struct cfs_completion *c);
+
+/*
+ * atomic.h
+ */
+
+typedef struct { volatile int counter; } cfs_atomic_t;
+
+int cfs_atomic_read(cfs_atomic_t *a);
+void cfs_atomic_set(cfs_atomic_t *a, int b);
+int cfs_atomic_dec_and_test(cfs_atomic_t *a);
+void cfs_atomic_inc(cfs_atomic_t *a);
+void cfs_atomic_dec(cfs_atomic_t *a);
+void cfs_atomic_add(int b, cfs_atomic_t *a);
+void cfs_atomic_sub(int b, cfs_atomic_t *a);
+
+#endif /* HAVE_LIBPTHREAD */
+
+/* !__KERNEL__ */
+#endif
+
+/* __LIBCFS_USER_LOCK_H__ */
+#endif
+/*
+ * Local variables:
+ * c-indentation-style: "K&R"
+ * c-basic-offset: 8
+ * tab-width: 8
+ * fill-column: 80
+ * scroll-step: 1
+ * End:
+ */
diff --git a/libcfs/include/libcfs/user-prim.h b/libcfs/include/libcfs/user-prim.h
new file mode 100644 (file)
index 0000000..43c1aeb
--- /dev/null
@@ -0,0 +1,328 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (C) 2004 Cluster File Systems, Inc.
+ * Author: Nikita Danilov <nikita@clusterfs.com>
+ *
+ * This file is part of Lustre, http://www.lustre.org.
+ *
+ * Lustre is free software; you can redistribute it and/or modify it under the
+ * terms of version 2 of the GNU General Public License as published by the
+ * Free Software Foundation.
+ *
+ * Lustre is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Lustre; if not, write to the Free Software Foundation, Inc., 675 Mass
+ * Ave, Cambridge, MA 02139, USA.
+ *
+ * Implementation of portable time API for user-level.
+ *
+ */
+
+#ifndef __LIBCFS_USER_PRIM_H__
+#define __LIBCFS_USER_PRIM_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+/* Implementations of portable APIs for liblustre */
+
+/*
+ * liblustre is single-threaded, so most "synchronization" APIs are trivial.
+ */
+
+#ifndef __KERNEL__
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/signal.h>
+#include <sys/mman.h>
+#include <libcfs/list.h>
+#include <libcfs/user-time.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef HAVE_LIBPTHREAD
+#include <pthread.h>
+#endif
+
+
+/*
+ * Wait Queue. No-op implementation.
+ */
+
+typedef struct cfs_waitlink {
+        struct list_head sleeping;
+        void *process;
+} cfs_waitlink_t;
+
+typedef struct cfs_waitq {
+        struct list_head sleepers;
+} cfs_waitq_t;
+
+void cfs_waitq_init(struct cfs_waitq *waitq);
+void cfs_waitlink_init(struct cfs_waitlink *link);
+void cfs_waitq_add(struct cfs_waitq *waitq, struct cfs_waitlink *link);
+void cfs_waitq_add_exclusive(struct cfs_waitq *waitq, 
+                             struct cfs_waitlink *link);
+void cfs_waitq_forward(struct cfs_waitlink *link, struct cfs_waitq *waitq);
+void cfs_waitq_del(struct cfs_waitq *waitq, struct cfs_waitlink *link);
+int  cfs_waitq_active(struct cfs_waitq *waitq);
+void cfs_waitq_signal(struct cfs_waitq *waitq);
+void cfs_waitq_signal_nr(struct cfs_waitq *waitq, int nr);
+void cfs_waitq_broadcast(struct cfs_waitq *waitq);
+void cfs_waitq_wait(struct cfs_waitlink *link, int state);
+int64_t cfs_waitq_timedwait(struct cfs_waitlink *link, int state, int64_t timeout);
+#define cfs_schedule_timeout(s, t)              \
+        do {                                    \
+                cfs_waitlink_t    l;            \
+                cfs_waitq_timedwait(&l, s, t);  \
+        } while (0)
+
+#define CFS_TASK_INTERRUPTIBLE  (0)
+#define CFS_TASK_UNINT          (0)
+
+/* 2.4 defines */
+
+/* XXX
+ * for this moment, liblusre will not rely OST for non-page-aligned write
+ */
+#define LIBLUSTRE_HANDLE_UNALIGNED_PAGE
+
+struct page {
+        void   *addr;
+        unsigned long index;
+        struct list_head list;
+        unsigned long private;
+
+        /* internally used by liblustre file i/o */
+        int     _offset;
+        int     _count;
+#ifdef LIBLUSTRE_HANDLE_UNALIGNED_PAGE
+        int     _managed;
+#endif
+        struct list_head _node;
+};
+
+typedef struct page cfs_page_t;
+
+#ifndef PAGE_SIZE
+
+/* 4K */
+#define CFS_PAGE_SHIFT 12
+#define CFS_PAGE_SIZE (1UL << CFS_PAGE_SHIFT)
+#define CFS_PAGE_MASK (~((__u64)CFS_PAGE_SIZE-1))
+
+#else
+
+#define CFS_PAGE_SIZE                   PAGE_SIZE
+#define CFS_PAGE_SHIFT                  PAGE_SHIFT
+#define CFS_PAGE_MASK                   (~((__u64)CFS_PAGE_SIZE-1))
+
+#endif
+
+cfs_page_t *cfs_alloc_page(unsigned int flags);
+void cfs_free_page(cfs_page_t *pg);
+void *cfs_page_address(cfs_page_t *pg);
+void *cfs_kmap(cfs_page_t *pg);
+void cfs_kunmap(cfs_page_t *pg);
+
+#define cfs_get_page(p)                        __I_should_not_be_called__(at_all)
+#define cfs_page_count(p)              __I_should_not_be_called__(at_all)
+#define cfs_page_index(p)               ((p)->index)
+
+/*
+ * Memory allocator
+ * Inline function, so utils can use them without linking of libcfs
+ */
+#define __ALLOC_ZERO    (1 << 2)
+static inline void *cfs_alloc(size_t nr_bytes, u_int32_t flags)
+{
+        void *result;
+
+        result = malloc(nr_bytes);
+        if (result != NULL && (flags & __ALLOC_ZERO))
+                memset(result, 0, nr_bytes);
+        return result;
+}
+
+#define cfs_free(addr)  free(addr)
+#define cfs_alloc_large(nr_bytes) cfs_alloc(nr_bytes, 0)
+#define cfs_free_large(addr) cfs_free(addr)
+
+#define CFS_ALLOC_ATOMIC_TRY   (0)
+/*
+ * SLAB allocator
+ */
+typedef struct {
+         int size;
+} cfs_mem_cache_t;
+
+#define SLAB_HWCACHE_ALIGN 0
+#define SLAB_KERNEL 0
+#define SLAB_NOFS 0
+
+cfs_mem_cache_t *
+cfs_mem_cache_create(const char *, size_t, size_t, unsigned long);
+int cfs_mem_cache_destroy(cfs_mem_cache_t *c);
+void *cfs_mem_cache_alloc(cfs_mem_cache_t *c, int gfp);
+void cfs_mem_cache_free(cfs_mem_cache_t *c, void *addr);
+
+typedef int (cfs_read_proc_t)(char *page, char **start, off_t off,
+                          int count, int *eof, void *data);
+
+struct file; /* forward ref */
+typedef int (cfs_write_proc_t)(struct file *file, const char *buffer,
+                               unsigned long count, void *data);
+
+/*
+ * Signal
+ */
+typedef sigset_t                        cfs_sigset_t;
+
+/*
+ * Timer
+ */
+#include <sys/time.h>
+
+typedef struct {
+        struct list_head tl_list;
+        void (*function)(unsigned long unused);
+        unsigned long data;
+        long expires;
+} cfs_timer_t;
+
+#define cfs_init_timer(t)       do {} while(0)
+#define cfs_jiffies                             \
+({                                              \
+        unsigned long _ret = 0;                 \
+        struct timeval tv;                      \
+        if (gettimeofday(&tv, NULL) == 0)       \
+                _ret = tv.tv_sec;               \
+        _ret;                                   \
+})
+
+static inline int cfs_timer_init(cfs_timer_t *l, void (* func)(unsigned long), void *arg)
+{
+        CFS_INIT_LIST_HEAD(&l->tl_list);
+        l->function = func;
+        l->data = (unsigned long)arg;
+        return 0;
+}
+
+static inline int cfs_timer_is_armed(cfs_timer_t *l)
+{
+        if (cfs_time_before(cfs_jiffies, l->expires))
+                return 1;
+        else
+                return 0;
+}
+
+static inline void cfs_timer_arm(cfs_timer_t *l, int thetime)
+{
+        l->expires = thetime;
+}
+
+static inline void cfs_timer_disarm(cfs_timer_t *l)
+{
+}
+
+static inline long cfs_timer_deadline(cfs_timer_t *l)
+{
+        return l->expires;
+}
+
+#if 0
+#define cfs_init_timer(t)      do {} while(0)
+void cfs_timer_init(struct cfs_timer *t, void (*func)(unsigned long), void *arg);
+void cfs_timer_done(struct cfs_timer *t);
+void cfs_timer_arm(struct cfs_timer *t, cfs_time_t deadline);
+void cfs_timer_disarm(struct cfs_timer *t);
+int  cfs_timer_is_armed(struct cfs_timer *t);
+
+cfs_time_t cfs_timer_deadline(struct cfs_timer *t);
+#endif
+
+#define in_interrupt()    (0)
+
+static inline void cfs_pause(cfs_duration_t d)
+{
+        struct timespec s;
+        
+        cfs_duration_nsec(d, &s);
+        nanosleep(&s, NULL);
+}
+
+typedef void cfs_psdev_t;
+
+static inline int cfs_psdev_register(cfs_psdev_t *foo)
+{
+        return 0;
+}
+
+static inline int cfs_psdev_deregister(cfs_psdev_t *foo)
+{
+        return 0;
+}
+
+#define cfs_lock_kernel()               do {} while (0)
+#define cfs_sigfillset(l) do {}         while (0)
+#define cfs_recalc_sigpending(l)        do {} while (0)
+#define cfs_kernel_thread(l,m,n)        LBUG()
+
+#ifdef HAVE_LIBPTHREAD
+typedef int (*cfs_thread_t)(void *);
+int cfs_create_thread(cfs_thread_t func, void *arg);
+#else
+#define cfs_create_thread(l,m) LBUG()
+#endif
+
+int cfs_parse_int_tunable(int *value, char *name);
+uid_t cfs_curproc_uid(void);
+
+#define LIBCFS_REALLOC(ptr, size) realloc(ptr, size)
+
+#define cfs_online_cpus() sysconf(_SC_NPROCESSORS_ONLN)
+
+// static inline void local_irq_save(unsigned long flag) {return;}
+// static inline void local_irq_restore(unsigned long flag) {return;}
+
+enum {
+        CFS_STACK_TRACE_DEPTH = 16
+};
+
+struct cfs_stack_trace {
+        void *frame[CFS_STACK_TRACE_DEPTH];
+};
+
+/*
+ * arithmetic
+ */
+#define do_div(a,b)                     \
+        ({                              \
+                unsigned long remainder;\
+                remainder = (a) % (b);  \
+                (a) = (a) / (b);        \
+                (remainder);            \
+        })
+
+/* !__KERNEL__ */
+#endif
+
+/* __LIBCFS_USER_PRIM_H__ */
+#endif
+/*
+ * Local variables:
+ * c-indentation-style: "K&R"
+ * c-basic-offset: 8
+ * tab-width: 8
+ * fill-column: 80
+ * scroll-step: 1
+ * End:
+ */
diff --git a/libcfs/include/libcfs/user-tcpip.h b/libcfs/include/libcfs/user-tcpip.h
new file mode 100644 (file)
index 0000000..342c039
--- /dev/null
@@ -0,0 +1,90 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (C) 2005 Cluster File Systems, Inc.
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __LIBCFS_USER_TCPIP_H__
+#define __LIBCFS_USER_TCPIP_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+#ifndef __KERNEL__
+
+#include <sys/uio.h>
+
+/*
+ * Functions to get network interfaces info
+ */
+
+int libcfs_sock_ioctl(int cmd, unsigned long arg);
+int libcfs_ipif_query (char *name, int *up, __u32 *ip);
+void libcfs_ipif_free_enumeration (char **names, int n);
+int libcfs_ipif_enumerate (char ***namesp);
+
+/*
+ * Network function used by user-land lnet acceptor
+ */
+
+int libcfs_sock_listen (int *sockp, __u32 local_ip, int local_port, int backlog);
+int libcfs_sock_accept (int *newsockp, int sock, __u32 *peer_ip, int *peer_port);
+int libcfs_sock_read (int sock, void *buffer, int nob, int timeout);
+void libcfs_sock_abort_accept(__u16 port);
+
+/*
+ * Network functions of common use
+ */
+
+int libcfs_getpeername(int sock_fd, __u32 *ipaddr_p, __u16 *port_p);
+int libcfs_socketpair(int *fdp);
+int libcfs_fcntl_nonblock(int fd);
+int libcfs_sock_set_nagle(int fd, int nagle);
+int libcfs_sock_set_bufsiz(int fd, int bufsiz);
+int libcfs_sock_create(int *fdp);
+int libcfs_sock_bind_to_port(int fd, __u16 port);
+int libcfs_sock_connect(int fd, __u32 ip, __u16 port);
+int libcfs_sock_writev(int fd, const struct iovec *vector, int count);
+int libcfs_sock_readv(int fd, const struct iovec *vector, int count);
+
+/*
+ * Macros for easy printing IP-adresses
+ */
+
+#define NIPQUAD(addr) \
+        ((unsigned char *)&addr)[0], \
+        ((unsigned char *)&addr)[1], \
+        ((unsigned char *)&addr)[2], \
+        ((unsigned char *)&addr)[3]
+
+#if defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN)
+#define HIPQUAD(addr)                \
+        ((unsigned char *)&addr)[3], \
+        ((unsigned char *)&addr)[2], \
+        ((unsigned char *)&addr)[1], \
+        ((unsigned char *)&addr)[0]
+#elif defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN)
+#define HIPQUAD NIPQUAD
+#else
+#error "Undefined byteorder??"
+#endif /* __LITTLE_ENDIAN */
+
+#endif /* !__KERNEL__ */
+
+#endif
diff --git a/libcfs/include/libcfs/user-time.h b/libcfs/include/libcfs/user-time.h
new file mode 100644 (file)
index 0000000..874b7da
--- /dev/null
@@ -0,0 +1,205 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (C) 2004 Cluster File Systems, Inc.
+ * Author: Nikita Danilov <nikita@clusterfs.com>
+ *
+ * This file is part of Lustre, http://www.lustre.org.
+ *
+ * Lustre is free software; you can redistribute it and/or modify it under the
+ * terms of version 2 of the GNU General Public License as published by the
+ * Free Software Foundation.
+ *
+ * Lustre is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Lustre; if not, write to the Free Software Foundation, Inc., 675 Mass
+ * Ave, Cambridge, MA 02139, USA.
+ *
+ * Implementation of portable time API for user-level.
+ *
+ */
+
+#ifndef __LIBCFS_USER_TIME_H__
+#define __LIBCFS_USER_TIME_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+/* Portable time API */
+
+/*
+ * Platform provides three opaque data-types:
+ *
+ *  cfs_time_t        represents point in time. This is internal kernel
+ *                    time rather than "wall clock". This time bears no
+ *                    relation to gettimeofday().
+ *
+ *  cfs_duration_t    represents time interval with resolution of internal
+ *                    platform clock
+ *
+ *  cfs_fs_time_t     represents instance in world-visible time. This is
+ *                    used in file-system time-stamps
+ *
+ *  cfs_time_t     cfs_time_current(void);
+ *  cfs_time_t     cfs_time_add    (cfs_time_t, cfs_duration_t);
+ *  cfs_duration_t cfs_time_sub    (cfs_time_t, cfs_time_t);
+ *  int            cfs_time_before (cfs_time_t, cfs_time_t);
+ *  int            cfs_time_beforeq(cfs_time_t, cfs_time_t);
+ *
+ *  cfs_duration_t cfs_duration_build(int64_t);
+ *
+ *  time_t         cfs_duration_sec (cfs_duration_t);
+ *  void           cfs_duration_usec(cfs_duration_t, struct timeval *);
+ *  void           cfs_duration_nsec(cfs_duration_t, struct timespec *);
+ *
+ *  void           cfs_fs_time_current(cfs_fs_time_t *);
+ *  time_t         cfs_fs_time_sec    (cfs_fs_time_t *);
+ *  void           cfs_fs_time_usec   (cfs_fs_time_t *, struct timeval *);
+ *  void           cfs_fs_time_nsec   (cfs_fs_time_t *, struct timespec *);
+ *  int            cfs_fs_time_before (cfs_fs_time_t *, cfs_fs_time_t *);
+ *  int            cfs_fs_time_beforeq(cfs_fs_time_t *, cfs_fs_time_t *);
+ *
+ *  CFS_TIME_FORMAT
+ *  CFS_DURATION_FORMAT
+ *
+ */
+
+#ifndef __KERNEL__
+
+#define ONE_BILLION ((u_int64_t)1000000000)
+#define ONE_MILLION 1000000
+
+/*
+ * Liblustre. time(2) based implementation.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+typedef time_t cfs_fs_time_t;
+typedef time_t cfs_time_t;
+typedef long cfs_duration_t;
+
+static inline cfs_time_t cfs_time_current(void)
+{
+        return time(NULL);
+}
+
+static inline cfs_duration_t cfs_time_seconds(int seconds)
+{
+        return seconds;
+}
+
+static inline time_t cfs_time_current_sec(void)
+{
+        return cfs_time_seconds(cfs_time_current());
+}
+
+static inline int cfs_time_before(cfs_time_t t1, cfs_time_t t2)
+{
+        return t1 < t2;
+}
+
+static inline int cfs_time_beforeq(cfs_time_t t1, cfs_time_t t2)
+{
+        return t1 <= t2;
+}
+
+static inline cfs_duration_t cfs_duration_build(int64_t nano)
+{
+        return (cfs_duration_t) (nano / ONE_BILLION);
+}
+
+static inline time_t cfs_duration_sec(cfs_duration_t d)
+{
+        return d;
+}
+
+static inline void cfs_duration_usec(cfs_duration_t d, struct timeval *s)
+{
+        s->tv_sec = d;
+        s->tv_usec = 0;
+}
+
+static inline void cfs_duration_nsec(cfs_duration_t d, struct timespec *s)
+{
+        s->tv_sec = d;
+        s->tv_nsec = 0;
+}
+
+static inline void cfs_fs_time_current(cfs_fs_time_t *t)
+{
+        time(t);
+}
+
+static inline time_t cfs_fs_time_sec(cfs_fs_time_t *t)
+{
+        return *t;
+}
+
+static inline void cfs_fs_time_usec(cfs_fs_time_t *t, struct timeval *v)
+{
+        v->tv_sec = *t;
+        v->tv_usec = 0;
+}
+
+static inline void cfs_fs_time_nsec(cfs_fs_time_t *t, struct timespec *s)
+{
+        s->tv_sec = *t;
+        s->tv_nsec = 0;
+}
+
+static inline int cfs_fs_time_before(cfs_fs_time_t *t1, cfs_fs_time_t *t2)
+{
+        return *t1 < *t2;
+}
+
+static inline int cfs_fs_time_beforeq(cfs_fs_time_t *t1, cfs_fs_time_t *t2)
+{
+        return *t1 <= *t2;
+}
+
+#define CFS_TICK                (1)
+
+static inline cfs_time_t cfs_time_add(cfs_time_t t, cfs_duration_t d)
+{
+        return t + d;
+}
+
+static inline cfs_duration_t cfs_time_sub(cfs_time_t t1, cfs_time_t t2)
+{
+        return t1 - t2;
+}
+
+#define cfs_time_current_64 cfs_time_current
+#define cfs_time_add_64     cfs_time_add
+#define cfs_time_shift_64   cfs_time_shift
+#define cfs_time_before_64  cfs_time_before
+#define cfs_time_beforeq_64 cfs_time_beforeq
+
+#ifndef CFS_TIME_T
+#define CFS_TIME_T              "%u"
+#endif
+
+#define CFS_DURATION_T          "%ld"
+
+/* !__KERNEL__ */
+#endif
+
+/* __LIBCFS_USER_TIME_H__ */
+#endif
+/*
+ * Local variables:
+ * c-indentation-style: "K&R"
+ * c-basic-offset: 8
+ * tab-width: 8
+ * fill-column: 80
+ * scroll-step: 1
+ * End:
+ */
diff --git a/libcfs/include/libcfs/winnt/kp30.h b/libcfs/include/libcfs/winnt/kp30.h
new file mode 100644 (file)
index 0000000..779d8be
--- /dev/null
@@ -0,0 +1,157 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=4:tabstop=4:
+ *
+ * Copyright (C) 2004 Cluster File Systems, Inc.
+ *
+ * This file is part of Lustre, http://www.lustre.org.
+ *
+ * Lustre is free software; you can redistribute it and/or modify it under the
+ * terms of version 2 of the GNU General Public License as published by the
+ * Free Software Foundation.
+ *
+ * Lustre is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Lustre; if not, write to the Free Software Foundation, Inc., 675 Mass
+ * Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __LIBCFS_WINNT_KP30_H__
+#define __LIBCFS_WINNT_KP30_H__
+
+#ifndef __LIBCFS_KP30_H__
+#error Do not #include this file directly. #include <libcfs/kp30.h> instead
+#endif
+
+#include <libcfs/winnt/portals_compat25.h>
+#include <lnet/types.h>
+
+#ifdef __KERNEL__
+
+/* Module parameter support */
+#define CFS_MODULE_PARM(name, t, type, perm, desc)
+
+#define CFS_SYSFS_MODULE_PARM    0 /* no sysfs access to module parameters */
+
+
+static inline void our_cond_resched()
+{
+    schedule_timeout(1i64);
+}
+
+#ifdef CONFIG_SMP
+#define LASSERT_SPIN_LOCKED(lock) do {} while(0) /* XXX */
+#else
+#define LASSERT_SPIN_LOCKED(lock) do {} while(0)
+#endif
+
+#error Need a winnt version of panic()
+#define LIBCFS_PANIC(msg) KeBugCheckEx(msg, (ULONG_PTR)NULL, (ULONG_PTR)NULL, (ULONG_PTR)NULL, (ULONG_PTR)NULL)
+#error libcfs_register_panic_notifier() missing
+#error libcfs_unregister_panic_notifier() missing
+
+#define cfs_work_struct_t WORK_QUEUE_ITEM
+#define cfs_prepare_work(tq, routine, contex)
+#define cfs_schedule_work(tq)
+#define cfs_get_work_data(type,field,data)   (data)
+
+/* ------------------------------------------------------------------- */
+
+#define PORTAL_SYMBOL_REGISTER(x)               cfs_symbol_register(#x, &x)
+#define PORTAL_SYMBOL_UNREGISTER(x)             cfs_symbol_unregister(#x)
+
+#define PORTAL_SYMBOL_GET(x)                    (cfs_symbol_get(#x))
+#define PORTAL_SYMBOL_PUT(x)                    cfs_symbol_put(#x)
+
+#define PORTAL_MODULE_USE                       do{}while(0)
+#define PORTAL_MODULE_UNUSE                     do{}while(0)
+
+#define printk                                  DbgPrint
+#define ptintf                                  DbgPrint
+
+#else  /* !__KERNEL__ */
+
+# include <stdio.h>
+# include <stdlib.h>
+#ifdef __CYGWIN__
+# include <cygwin-ioctl.h>
+#endif
+# include <time.h>
+
+#endif /* End of !__KERNEL__ */
+
+/******************************************************************************/
+/* Light-weight trace
+ * Support for temporary event tracing with minimal Heisenberg effect. */
+#define LWT_SUPPORT  0
+
+/* kernel hasn't defined this? */
+typedef struct {
+        __s64      lwte_when;
+        char       *lwte_where;
+        void       *lwte_task;
+        long_ptr        lwte_p1;
+        long_ptr        lwte_p2;
+        long_ptr        lwte_p3;
+        long_ptr        lwte_p4;
+# if BITS_PER_LONG > 32
+        long_ptr        lwte_pad;
+# endif
+} lwt_event_t;
+
+
+# define LWT_EVENT(p1,p2,p3,p4)
+
+
+/* ------------------------------------------------------------------ */
+
+#define IOCTL_LIBCFS_TYPE long_ptr
+
+#ifdef __CYGWIN__
+# ifndef BITS_PER_LONG
+#  if (~0UL) == 0xffffffffUL
+#   define BITS_PER_LONG 32
+#  else
+#   define BITS_PER_LONG 64
+#  endif
+# endif
+#endif
+
+#if BITS_PER_LONG > 32
+# define LI_POISON ((int)0x5a5a5a5a5a5a5a5a)
+# define LL_POISON ((long_ptr)0x5a5a5a5a5a5a5a5a)
+# define LP_POISON ((char *)(long_ptr)0x5a5a5a5a5a5a5a5a)
+#else
+# define LI_POISON ((int)0x5a5a5a5a)
+# define LL_POISON ((long_ptr)0x5a5a5a5a)
+# define LP_POISON ((char *)(long_ptr)0x5a5a5a5a)
+#endif
+
+#if defined(__x86_64__)
+# define LPU64 "%I64u"
+# define LPD64 "%I64d"
+# define LPX64 "%I64x"
+# define LPSZ  "%lu"
+# define LPSSZ "%ld"
+#elif (BITS_PER_LONG == 32 || __WORDSIZE == 32)
+# define LPU64 "%I64u"
+# define LPD64 "%I64d"
+# define LPX64 "%I64x"
+# define LPSZ  "%u"
+# define LPSSZ "%d"
+#elif (BITS_PER_LONG == 64 || __WORDSIZE == 64)
+# define LPU64 "%I64u"
+# define LPD64 "%I64d"
+# define LPX64 "%I64x"
+# define LPSZ  "%u"
+# define LPSSZ "%d"
+#endif
+#ifndef LPU64
+# error "No word size defined"
+#endif
+
+#endif
diff --git a/libcfs/include/libcfs/winnt/libcfs.h b/libcfs/include/libcfs/winnt/libcfs.h
new file mode 100644 (file)
index 0000000..386eb5f
--- /dev/null
@@ -0,0 +1,126 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=4:tabstop=4:
+ *
+ * Copyright (C) 2004 Cluster File Systems, Inc.
+ *
+ * This file is part of Lustre, http://www.lustre.org.
+ *
+ * Lustre is free software; you can redistribute it and/or modify it under the
+ * terms of version 2 of the GNU General Public License as published by the
+ * Free Software Foundation.
+ *
+ * Lustre is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Lustre; if not, write to the Free Software Foundation, Inc., 675 Mass
+ * Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __LIBCFS_WINNT_LIBCFS_H__
+#define __LIBCFS_WINNT_LIBCFS_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+/* workgroud for VC compiler */
+#ifndef __FUNCTION__
+#define __FUNCTION__ "generic"
+#endif
+
+#include <libcfs/winnt/winnt-types.h>
+#include <libcfs/portals_utils.h>
+#include <libcfs/winnt/winnt-time.h>
+#include <libcfs/winnt/winnt-lock.h>
+#include <libcfs/winnt/winnt-mem.h>
+#include <libcfs/winnt/winnt-prim.h>
+#include <libcfs/winnt/winnt-fs.h>
+#include <libcfs/winnt/winnt-tcpip.h>
+
+struct ptldebug_header {
+        __u32 ph_len;
+        __u32 ph_flags;
+        __u32 ph_subsys;
+        __u32 ph_mask;
+        __u32 ph_cpu_id;
+        __u32 ph_sec;
+        __u64 ph_usec;
+        __u32 ph_stack;
+        __u32 ph_pid;
+        __u32 ph_extern_pid;
+        __u32 ph_line_num;
+} __attribute__((packed));
+
+#ifdef __KERNEL__
+
+enum {
+       /* if you change this, update darwin-util.c:cfs_stack_trace_fill() */
+       CFS_STACK_TRACE_DEPTH = 16
+};
+
+struct cfs_stack_trace {
+       void *frame[CFS_STACK_TRACE_DEPTH];
+};
+
+static inline __u32 query_stack_size()
+{
+    ULONG   LowLimit, HighLimit;
+
+    IoGetStackLimits(&LowLimit, &HighLimit);
+    ASSERT(HighLimit > LowLimit);
+
+    return (__u32) (HighLimit - LowLimit);
+}
+#else
+static inline __u32 query_stack_size()
+{
+   return 4096;
+}
+#endif
+
+
+#ifndef THREAD_SIZE
+# define THREAD_SIZE query_stack_size()
+#endif
+
+#define LUSTRE_TRACE_SIZE (THREAD_SIZE >> 5)
+
+#ifdef __KERNEL__
+# ifdef  __ia64__
+#  define CDEBUG_STACK() (THREAD_SIZE -                         \
+                          ((ulong_ptr)__builtin_dwarf_cfa() &   \
+                           (THREAD_SIZE - 1)))
+# else
+#  define CDEBUG_STACK (IoGetRemainingStackSize())
+#  error "This doesn't seem right; CDEBUG_STACK should grow with the stack"
+# endif /* __ia64__ */
+
+#define CHECK_STACK()                                                   \
+do {                                                                    \
+        unsigned long _stack = CDEBUG_STACK();                          \
+                                                                        \
+        if (_stack > 3*THREAD_SIZE/4 && _stack > libcfs_stack) {        \
+                libcfs_stack = _stack;                                  \
+                libcfs_debug_msg(NULL, DEBUG_SUBSYSTEM, D_WARNING,      \
+                                 __FILE__, NULL, __LINE__,              \
+                                 "maximum lustre stack %lu\n", _stack); \
+        }                                                               \
+} while (0)
+#else /* !__KERNEL__ */
+#define CHECK_STACK() do { } while(0)
+#define CDEBUG_STACK() (0L)
+#endif /* __KERNEL__ */
+
+/* initial pid  */
+#define LUSTRE_LNET_PID          12345
+
+#define ENTRY_NESTING_SUPPORT (0)
+#define ENTRY_NESTING   do {;} while (0)
+#define EXIT_NESTING   do {;} while (0)
+#define __current_nesting_level() (0)
+
+#endif /* _WINNT_LIBCFS_H */
diff --git a/libcfs/include/libcfs/winnt/lltrace.h b/libcfs/include/libcfs/winnt/lltrace.h
new file mode 100644 (file)
index 0000000..9615e94
--- /dev/null
@@ -0,0 +1,33 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=4:tabstop=4:
+ *
+ *  Copyright (C) 2001 Cluster File Systems, Inc. <braam@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Basic library routines.
+ *
+ */
+
+#ifndef __LIBCFS_WINNT_LLTRACE_H__
+#define __LIBCFS_WINNT_LLTRACE_H__
+
+#ifndef __LIBCFS_LLTRACE_H__
+#error Do not #include this file directly. #include <libcfs/lltrace.h> instead
+#endif
+
+
+#endif
diff --git a/libcfs/include/libcfs/winnt/portals_compat25.h b/libcfs/include/libcfs/winnt/portals_compat25.h
new file mode 100644 (file)
index 0000000..579b795
--- /dev/null
@@ -0,0 +1,28 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=4:tabstop=4:
+ *
+ *  Copyright (C) 2001 Cluster File Systems, Inc. <braam@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __LIBCFS_WINNT_PORTALS_COMPAT_H__
+#define __LIBCFS_WINNT_PORTALS_COMPAT_H__
+
+
+
+#endif /* _PORTALS_COMPAT_H */
diff --git a/libcfs/include/libcfs/winnt/portals_utils.h b/libcfs/include/libcfs/winnt/portals_utils.h
new file mode 100644 (file)
index 0000000..ec80692
--- /dev/null
@@ -0,0 +1,168 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=4:tabstop=4:
+ *
+ *  Copyright (C) 2001 Cluster File Systems, Inc. <braam@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Basic library routines.
+ *
+ */
+
+#ifndef __LIBCFS_WINNT_PORTALS_UTILS_H__
+#define __LIBCFS_WINNT_PORTALS_UTILS_H__
+
+#ifndef __LIBCFS_PORTALS_UTILS_H__
+#error Do not #include this file directly. #include <libcfs/portals_utils.h> instead
+#endif
+
+#ifndef cfs_is_flag_set
+#define cfs_is_flag_set(x,f) (((x)&(f))==(f))
+#endif
+
+#ifndef cfs_set_flag
+#define cfs_set_flag(x,f)    ((x) |= (f))
+#endif
+
+#ifndef cfs_clear_flag
+#define cfs_clear_flag(x,f)  ((x) &= ~(f))
+#endif
+
+
+static inline __u32 __do_div(__u32 * n, __u32 b) 
+{
+    __u32   mod;
+
+    mod = *n % b;
+    *n  = *n / b;
+    return mod;
+} 
+
+#define do_div(n,base)  __do_div((__u32 *)&(n), (__u32) (base))
+
+#ifdef __KERNEL__
+
+#include <stdlib.h>
+#include <libcfs/winnt/winnt-types.h>
+
+char * strsep(char **s, const char *ct);
+static inline size_t strnlen(const char * s, size_t count) {
+    size_t len = 0;
+    while(len < count && s[len++]);
+    return len;
+}
+char * ul2dstr(ulong_ptr address, char *buf, int len);
+
+#define simple_strtol(a1, a2, a3)               strtol(a1, a2, a3)
+#define simple_strtoll(a1, a2, a3)              (__s64)strtoull(a1, a2, a3)
+#define simple_strtoull(a1, a2, a3)             strtoull(a1, a2, a3)
+
+unsigned long simple_strtoul(const char *cp,char **endp, unsigned int base);
+
+static inline int test_bit(int nr, void * addr)
+{
+    return ((1UL << (nr & 31)) & (((volatile ULONG *) addr)[nr >> 5])) != 0;
+}
+
+static inline void clear_bit(int nr, void * addr)
+{
+    (((volatile ULONG *) addr)[nr >> 5]) &= (~(1UL << (nr & 31)));
+}
+
+
+static inline void set_bit(int nr, void * addr)
+{
+    (((volatile ULONG *) addr)[nr >> 5]) |= (1UL << (nr & 31));
+}
+
+static inline void read_random(char *buf, int len)
+{
+    ULONG   Seed = (ULONG) buf;
+    Seed = RtlRandom(&Seed);
+    while (len >0) {
+        if (len > sizeof(ULONG)) {
+            memcpy(buf, &Seed, sizeof(ULONG));
+            len -= sizeof(ULONG);
+            buf += sizeof(ULONG);
+        } else {
+            memcpy(buf, &Seed, len);
+            len = 0;
+            break;
+        } 
+    }
+}
+#define get_random_bytes(buf, len)  read_random(buf, len)
+
+/* do NOT use function or expression as parameters ... */
+
+#ifndef min_t
+#define min_t(type,x,y) (type)(x) < (type)(y) ? (x): (y)
+#endif
+
+#ifndef max_t
+#define max_t(type,x,y) (type)(x) < (type)(y) ? (y): (x)
+#endif
+
+
+#define NIPQUAD(addr)                      \
+       ((unsigned char *)&addr)[0],    \
+       ((unsigned char *)&addr)[1],    \
+       ((unsigned char *)&addr)[2],    \
+       ((unsigned char *)&addr)[3]
+
+#define HIPQUAD(addr)                      \
+       ((unsigned char *)&addr)[3],    \
+       ((unsigned char *)&addr)[2],    \
+       ((unsigned char *)&addr)[1],    \
+       ((unsigned char *)&addr)[0]
+
+static int copy_from_user(void *to, void *from, int c) 
+{
+    memcpy(to, from, c);
+    return 0;
+}
+
+static int copy_to_user(void *to, void *from, int c) 
+{
+    memcpy(to, from, c);
+    return 0;
+}
+
+
+#define put_user(x, ptr)        \
+(                               \
+    *(ptr) = x,                 \
+    0                           \
+)
+
+
+#define get_user(x,ptr)         \
+(                               \
+    x = *(ptr),                 \
+    0                           \
+)
+
+#define num_physpages                  (64 * 1024)
+
+#define snprintf  _snprintf
+#define vsnprintf _vsnprintf
+
+
+#endif /* !__KERNEL__ */
+
+int cfs_error_code(NTSTATUS);
+
+#endif
diff --git a/libcfs/include/libcfs/winnt/winnt-fs.h b/libcfs/include/libcfs/winnt/winnt-fs.h
new file mode 100644 (file)
index 0000000..088d0e0
--- /dev/null
@@ -0,0 +1,254 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=4:tabstop=4:
+ *
+ *  Copyright (C) 2001 Cluster File Systems, Inc. <braam@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * File operations & routines.
+ *
+ */
+
+#ifndef __LIBCFS_WINNT_CFS_FS_H__
+#define __LIBCFS_WINNT_CFS_FS_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+
+#define MINORBITS      8
+#define MINORMASK      ((1U << MINORBITS) - 1)
+
+#define MAJOR(dev)     ((unsigned int) ((dev) >> MINORBITS))
+#define MINOR(dev)     ((unsigned int) ((dev) & MINORMASK))
+#define NODEV          0
+#define MKDEV(ma,mi)   (((ma) << MINORBITS) | (mi))
+
+
+#ifdef __KERNEL__
+
+struct file_operations
+{
+    loff_t (*lseek)(struct file * file, loff_t offset, int origin);
+    ssize_t (*read) (struct file * file, char * buf, size_t nbytes, loff_t *ppos);
+    ssize_t (*write)(struct file * file, const char * buffer,
+        size_t count, loff_t *ppos);
+    int (*ioctl) (struct file *, unsigned int, ulong_ptr);
+    int (*open) (struct file *);
+    int (*release) (struct file *);
+};
+
+struct file {
+
+    cfs_handle_t            f_handle;
+    unsigned int            f_flags;
+    mode_t                  f_mode;
+    ulong_ptr           f_count;
+
+    //struct list_head      f_list;
+    //struct dentry *       f_dentry;
+
+    cfs_proc_entry_t *      proc_dentry;
+    cfs_file_operations_t * f_op;
+
+    size_t                  f_size;
+    loff_t                  f_pos;
+    unsigned int            f_uid, f_gid;
+    int                     f_error;
+
+    ulong_ptr           f_version;
+
+    void *                  private_data;
+
+    char                    f_name[1];
+
+};
+
+#define cfs_filp_size(f)               ((f)->f_size)
+#define cfs_filp_poff(f)                (&(f)->f_pos)
+
+cfs_file_t *cfs_filp_open(const char *name, int flags, int mode, int *err);
+int cfs_filp_close(cfs_file_t *fp);
+int cfs_filp_read(cfs_file_t *fp, void *buf, size_t nbytes, loff_t *pos);
+int cfs_filp_write(cfs_file_t *fp, void *buf, size_t nbytes, loff_t *pos);
+int cfs_filp_fsync(cfs_file_t *fp);
+int cfs_get_file(cfs_file_t *fp);
+int cfs_put_file(cfs_file_t *fp);
+int cfs_file_count(cfs_file_t *fp);
+
+
+
+/*
+ * CFS_FLOCK routines
+ */
+
+typedef struct file_lock{
+    int         fl_type;
+    pid_t       fl_pid;
+    size_t      fl_len;
+    off_t       fl_start;
+    off_t       fl_end;
+} cfs_flock_t; 
+
+#define CFS_INT_LIMIT(x)               (~((x)1 << (sizeof(x)*8 - 1)))
+#define CFS_OFFSET_MAX                 CFS_INT_LIMIT(loff_t)
+
+#define cfs_flock_type(fl)                  ((fl)->fl_type)
+#define cfs_flock_set_type(fl, type)        do { (fl)->fl_type = (type); } while(0)
+#define cfs_flock_pid(fl)                   ((fl)->fl_pid)
+#define cfs_flock_set_pid(fl, pid)          do { (fl)->fl_pid = (pid); } while(0)
+#define cfs_flock_start(fl)                 ((fl)->fl_start)
+#define cfs_flock_set_start(fl, start)      do { (fl)->fl_start = (start); } while(0)
+#define cfs_flock_end(fl)                   ((fl)->fl_end)
+#define cfs_flock_set_end(fl, end)          do { (fl)->fl_end = (end); } while(0)
+
+#define ATTR_MODE       0x0001
+#define ATTR_UID        0x0002
+#define ATTR_GID        0x0004
+#define ATTR_SIZE       0x0008
+#define ATTR_ATIME      0x0010
+#define ATTR_MTIME      0x0020
+#define ATTR_CTIME      0x0040
+#define ATTR_ATIME_SET  0x0080
+#define ATTR_MTIME_SET  0x0100
+#define ATTR_FORCE      0x0200  /* Not a change, but a change it */
+#define ATTR_ATTR_FLAG  0x0400
+#define ATTR_RAW        0x0800  /* file system, not vfs will massage attrs */
+#define ATTR_FROM_OPEN  0x1000  /* called from open path, ie O_TRUNC */
+//#define ATTR_CTIME_SET  0x2000
+#define ATTR_BLOCKS     0x4000
+#define ATTR_KILL_SUID  0
+#define ATTR_KILL_SGID  0
+
+#define in_group_p(x)  (0)
+
+/*
+ * proc fs routines
+ */
+
+int proc_init_fs();
+void proc_destroy_fs();
+
+
+/*
+ *  misc
+ */
+
+static inline void *ERR_PTR(long_ptr error)
+{
+       return (void *) error;
+}
+
+static inline long_ptr PTR_ERR(const void *ptr)
+{
+       return (long_ptr) ptr;
+}
+
+static inline long_ptr IS_ERR(const void *ptr)
+{
+       return (ulong_ptr)ptr > (ulong_ptr)-1000L;
+}
+
+#else  /* !__KERNEL__ */
+
+#define CREATE_NEW          1
+#define CREATE_ALWAYS       2
+#define OPEN_EXISTING       3
+#define OPEN_ALWAYS         4
+#define TRUNCATE_EXISTING   5
+
+#define SECTION_QUERY       0x0001
+#define SECTION_MAP_WRITE   0x0002
+#define SECTION_MAP_READ    0x0004
+#define SECTION_MAP_EXECUTE 0x0008
+#define SECTION_EXTEND_SIZE 0x0010
+
+#define FILE_MAP_COPY       SECTION_QUERY
+#define FILE_MAP_WRITE      SECTION_MAP_WRITE
+#define FILE_MAP_READ       SECTION_MAP_READ
+#define FILE_MAP_ALL_ACCESS SECTION_ALL_ACCESS
+
+
+NTSYSAPI
+HANDLE
+NTAPI
+CreateFileA(
+    IN LPCSTR lpFileName,
+    IN DWORD dwDesiredAccess,
+    IN DWORD dwShareMode,
+    IN PVOID lpSecurityAttributes,
+    IN DWORD dwCreationDisposition,
+    IN DWORD dwFlagsAndAttributes,
+    IN HANDLE hTemplateFile
+    );
+
+#define CreateFile  CreateFileA
+
+NTSYSAPI
+BOOL
+NTAPI
+CloseHandle(
+    IN OUT HANDLE hObject
+    );
+
+NTSYSAPI
+HANDLE
+NTAPI
+CreateFileMappingA(
+    IN HANDLE hFile,
+    IN PVOID lpFileMappingAttributes,
+    IN DWORD flProtect,
+    IN DWORD dwMaximumSizeHigh,
+    IN DWORD dwMaximumSizeLow,
+    IN LPCSTR lpName
+    );
+#define CreateFileMapping  CreateFileMappingA
+
+NTSYSAPI
+DWORD
+NTAPI
+GetFileSize(
+    IN HANDLE hFile,
+    OUT DWORD * lpFileSizeHigh
+    );
+
+NTSYSAPI
+PVOID
+NTAPI
+MapViewOfFile(
+    IN HANDLE hFileMappingObject,
+    IN DWORD dwDesiredAccess,
+    IN DWORD dwFileOffsetHigh,
+    IN DWORD dwFileOffsetLow,
+    IN SIZE_T dwNumberOfBytesToMap
+    );
+
+NTSYSAPI
+BOOL
+NTAPI
+UnmapViewOfFile(
+    IN PVOID lpBaseAddress
+    );
+
+#endif /* __KERNEL__ */
+
+typedef struct {
+       void    *d;
+} cfs_dentry_t;
+
+
+#endif /* __LIBCFS_WINNT_CFS_FS_H__*/
diff --git a/libcfs/include/libcfs/winnt/winnt-lock.h b/libcfs/include/libcfs/winnt/winnt-lock.h
new file mode 100644 (file)
index 0000000..e0b9393
--- /dev/null
@@ -0,0 +1,686 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=4:tabstop=4:
+ *
+ *  Copyright (C) 2001 Cluster File Systems, Inc. <braam@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Basic library routines.
+ *
+ */
+
+#ifndef __LIBCFS_WINNT_CFS_LOCK_H__
+#define __LIBCFS_WINNT_CFS_LOCK_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+#ifdef __KERNEL__
+
+
+/*
+ *  nt specific part ...
+ */
+
+
+/* atomic */
+
+typedef struct { volatile int counter; } atomic_t;
+
+#define ATOMIC_INIT(i) { i }
+
+#define atomic_read(v) ((v)->counter)
+#define atomic_set(v,i)                (((v)->counter) = (i))
+
+void FASTCALL atomic_add(int i, atomic_t *v);
+void FASTCALL atomic_sub(int i, atomic_t *v);
+
+int FASTCALL atomic_sub_and_test(int i, atomic_t *v);
+
+void FASTCALL atomic_inc(atomic_t *v);
+void FASTCALL atomic_dec(atomic_t *v);
+
+int FASTCALL atomic_dec_and_test(atomic_t *v);
+int FASTCALL atomic_inc_and_test(atomic_t *v);
+
+
+/* event */
+
+typedef KEVENT          event_t;
+
+/*
+ * cfs_init_event
+ *   To initialize the event object
+ *
+ * Arguments:
+ *   event:  pointer to the event object
+ *   type:   Non Zero: SynchronizationEvent
+ *           Zero: NotificationEvent
+ *   status: the initial stats of the event
+ *           Non Zero: signaled
+ *           Zero: un-signaled
+ *
+ * Return Value:
+ *   N/A
+ *
+ * Notes: 
+ *   N/A
+ */
+static inline void
+    cfs_init_event(event_t *event, int type, int status)
+{
+    KeInitializeEvent(
+            event,
+            (type) ? SynchronizationEvent: NotificationEvent,
+            (status) ? TRUE : FALSE
+            );
+}
+
+/*
+ * cfs_wait_event
+ *   To wait on an event to syncrhonize the process
+ *
+ * Arguments:
+ *   event:  pointer to the event object
+ *   timeout: the timeout for waitting or 0 means infinite time.
+ *
+ * Return Value:
+ *   Zero:   waiting timeouts
+ *   Non Zero: event signaled ...
+ *
+ * Notes: 
+ *   N/A
+ */
+
+static inline int64_t
+cfs_wait_event(event_t * event, int64_t timeout)
+{
+    NTSTATUS        Status;
+    LARGE_INTEGER   TimeOut;
+
+    TimeOut.QuadPart = -1 * (10000000/HZ) * timeout;
+
+    Status = KeWaitForSingleObject(
+                event,
+                Executive,
+                KernelMode,
+                FALSE,
+                (timeout != 0) ? (&TimeOut) : (NULL)
+                );
+
+    if (Status == STATUS_TIMEOUT)  {
+        return 0;
+    }
+
+    return TRUE; // signaled case
+}
+
+/*
+ * cfs_wake_event
+ *   To signal the event object
+ *
+ * Arguments:
+ *   event:  pointer to the event object
+ *
+ * Return Value:
+ *   N/A
+ *
+ * Notes: 
+ *   N/A
+ */
+
+static inline int
+cfs_wake_event(event_t * event)
+{
+    return (KeSetEvent(event, 0, FALSE) != 0);
+}
+
+/*
+ * cfs_clear_event
+ *   To clear/reset the status of the event object
+ *
+ * Arguments:
+ *   event:  pointer to the event object
+ *
+ * Return Value:
+ *   N/A
+ *
+ * Notes: 
+ *   N/A
+ */
+
+static inline void
+cfs_clear_event(event_t * event)
+{
+    KeResetEvent(event);
+}
+
+
+/*
+ * IMPORTANT !!!!!!!!
+ *
+ * All locks' declaration are not guaranteed to be initialized,
+ * Althought some of they are initialized in Linux. All locks
+ * declared by CFS_DECL_* should be initialized explicitly.
+ */
+
+
+/*
+ * spin lock defintions / routines
+ */
+
+/*
+ * Warning:
+ *
+ * for spinlock operations, try to grab nesting acquisition of
+ * spinlock will cause dead-lock in MP system and current irql 
+ * overwritten for UP system. (UP system could allow nesting spin
+ * acqisition, because it's not spin at all just raising the irql.)
+ *
+ */
+
+typedef struct spin_lock {
+
+    KSPIN_LOCK lock;
+    KIRQL      irql;
+
+} spinlock_t;
+
+
+#define CFS_DECL_SPIN(name)  spinlock_t name;
+#define CFS_DECL_SPIN_EXTERN(name)  extern spinlock_t name;
+
+
+static inline void spin_lock_init(spinlock_t *lock)
+{
+    KeInitializeSpinLock(&(lock->lock));
+}
+
+
+static inline void spin_lock(spinlock_t *lock)
+{
+    KeAcquireSpinLock(&(lock->lock), &(lock->irql));
+}
+
+static inline void spin_unlock(spinlock_t *lock)
+{
+    KIRQL       irql = lock->irql;
+    KeReleaseSpinLock(&(lock->lock), irql);
+}
+
+
+#define spin_lock_irqsave(lock, flags)         do {(flags) = 0; spin_lock(lock);} while(0)
+#define spin_unlock_irqrestore(lock, flags)    do {spin_unlock(lock);} while(0)
+
+
+/* There's no  corresponding routine in windows kernel.
+   We must realize a light one of our own.  But there's
+   no way to identify the system is MP build or UP build
+   on the runtime. We just uses a workaround for it. */
+
+extern int MPSystem;
+
+static int spin_trylock(spinlock_t *lock)
+{
+    KIRQL   Irql;
+    int     rc = 0;
+
+    ASSERT(lock != NULL);
+
+    KeRaiseIrql(DISPATCH_LEVEL, &Irql);
+
+    if (MPSystem) {
+        if (0 == (ulong_ptr)lock->lock) {
+#if _X86_
+            __asm {
+                mov  edx, dword ptr [ebp + 8]
+                lock bts dword ptr[edx], 0
+                jb   lock_failed
+                mov  rc, TRUE
+            lock_failed:
+            }
+#else
+        KdBreakPoint();
+#endif
+
+        }
+    } else {
+        rc = TRUE;
+    }
+
+    if (rc) {
+        lock->irql = Irql;
+    } else {
+        KeLowerIrql(Irql);
+    }
+
+    return rc;
+}
+
+/* synchronization between cpus: it will disable all DPCs
+   kernel task scheduler on the CPU */
+#define spin_lock_bh(x)                    spin_lock(x)
+#define spin_unlock_bh(x)          spin_unlock(x)
+#define spin_lock_bh_init(x)   spin_lock_init(x)
+
+/*
+ * rw_semaphore (using ERESOURCE)
+ */
+
+
+typedef struct rw_semaphore {
+    ERESOURCE   rwsem;
+} rw_semaphore_t;
+
+
+#define CFS_DECL_RWSEM(name) rw_semaphore_t name
+#define CFS_DECL_RWSEM_EXTERN(name) extern rw_semaphore_t name
+
+
+/*
+ * init_rwsem
+ *   To initialize the the rw_semaphore_t structure
+ *
+ * Arguments:
+ *   rwsem:  pointer to the rw_semaphore_t structure
+ *
+ * Return Value:
+ *   N/A
+ *
+ * Notes: 
+ *   N/A
+ */
+
+static inline void init_rwsem(rw_semaphore_t *s)
+{
+       ExInitializeResourceLite(&s->rwsem);
+}
+
+
+/*
+ * fini_rwsem
+ *   To finilize/destroy the the rw_semaphore_t structure
+ *
+ * Arguments:
+ *   rwsem:  pointer to the rw_semaphore_t structure
+ *
+ * Return Value:
+ *   N/A
+ *
+ * Notes: 
+ *   For winnt system, we need this routine to delete the ERESOURCE.
+ *   Just define it NULL for other systems.
+ */
+
+static inline void fini_rwsem(rw_semaphore_t *s)
+{
+    ExDeleteResourceLite(&s->rwsem);
+}
+
+/*
+ * down_read
+ *   To acquire read-lock of the rw_semahore
+ *
+ * Arguments:
+ *   rwsem:  pointer to the rw_semaphore_t structure
+ *
+ * Return Value:
+ *   N/A
+ *
+ * Notes: 
+ *   N/A
+ */
+
+static inline void down_read(struct rw_semaphore *s)
+{
+       ExAcquireResourceSharedLite(&s->rwsem, TRUE);
+}
+
+
+/*
+ * down_read_trylock
+ *   To acquire read-lock of the rw_semahore without blocking
+ *
+ * Arguments:
+ *   rwsem:  pointer to the rw_semaphore_t structure
+ *
+ * Return Value:
+ *   Zero: failed to acquire the read lock
+ *   Non-Zero: succeeded to acquire the read lock
+ *
+ * Notes: 
+ *   This routine will return immediately without waiting.
+ */
+
+static inline int down_read_trylock(struct rw_semaphore *s)
+{
+       return ExAcquireResourceSharedLite(&s->rwsem, FALSE);
+}
+
+
+/*
+ * down_write
+ *   To acquire write-lock of the rw_semahore
+ *
+ * Arguments:
+ *   rwsem:  pointer to the rw_semaphore_t structure
+ *
+ * Return Value:
+ *   N/A
+ *
+ * Notes: 
+ *   N/A
+ */
+
+static inline void down_write(struct rw_semaphore *s)
+{
+       ExAcquireResourceExclusiveLite(&(s->rwsem), TRUE);
+}
+
+
+/*
+ * down_write_trylock
+ *   To acquire write-lock of the rw_semahore without blocking
+ *
+ * Arguments:
+ *   rwsem:  pointer to the rw_semaphore_t structure
+ *
+ * Return Value:
+ *   Zero: failed to acquire the write lock
+ *   Non-Zero: succeeded to acquire the read lock
+ *
+ * Notes: 
+ *   This routine will return immediately without waiting.
+ */
+
+static inline int down_write_trylock(struct rw_semaphore *s)
+{
+    return ExAcquireResourceExclusiveLite(&(s->rwsem), FALSE);
+}
+
+
+/*
+ * up_read
+ *   To release read-lock of the rw_semahore
+ *
+ * Arguments:
+ *   rwsem:  pointer to the rw_semaphore_t structure
+ *
+ * Return Value:
+ *   N/A
+ *
+ * Notes: 
+ *   N/A
+ */
+
+static inline void up_read(struct rw_semaphore *s)
+{
+    ExReleaseResourceForThreadLite(
+            &(s->rwsem),
+            ExGetCurrentResourceThread());
+}
+
+
+/*
+ * up_write
+ *   To release write-lock of the rw_semahore
+ *
+ * Arguments:
+ *   rwsem:  pointer to the rw_semaphore_t structure
+ *
+ * Return Value:
+ *   N/A
+ *
+ * Notes: 
+ *   N/A
+ */
+
+static inline void up_write(struct rw_semaphore *s)
+{
+    ExReleaseResourceForThreadLite(
+                &(s->rwsem),
+                ExGetCurrentResourceThread());
+}
+
+/*
+ * rwlock_t (using sempahore)
+ *
+ * - rwlock_init(x)
+ * - read_lock(x)
+ * - read_unlock(x)
+ * - write_lock(x)
+ * - write_unlock(x)
+ */
+
+typedef struct {
+    spinlock_t guard;
+    int        count;
+} rwlock_t;
+
+void rwlock_init(rwlock_t * rwlock);
+void rwlock_fini(rwlock_t * rwlock);
+
+void read_lock(rwlock_t * rwlock);
+void read_unlock(rwlock_t * rwlock);
+void write_lock(rwlock_t * rwlock);
+void write_unlock(rwlock_t * rwlock);
+
+#define write_lock_irqsave(l, f)        do {f = 0; write_lock(l);} while(0)
+#define write_unlock_irqrestore(l, f)   do {write_unlock(l);} while(0)
+#define read_lock_irqsave(l, f)                do {f=0; read_lock(l);} while(0)
+#define read_unlock_irqrestore(l, f)    do {read_unlock(l);} while(0)
+
+
+/*
+ * Semaphore
+ *
+ * - sema_init(x, v)
+ * - __down(x)
+ * - __up(x)
+ */
+
+typedef struct semaphore {
+       KSEMAPHORE sem;
+} mutex_t;
+
+static inline void sema_init(struct semaphore *s, int val)
+{
+       KeInitializeSemaphore(&s->sem, val, val);
+}
+
+static inline void __down(struct semaphore *s)
+{
+   KeWaitForSingleObject( &(s->sem), Executive,
+                          KernelMode, FALSE, NULL );
+
+}
+
+static inline void __up(struct semaphore *s)
+{
+       KeReleaseSemaphore(&s->sem, 0, 1, FALSE);
+}
+
+/*
+ * mutex_t:
+ *
+ * - init_mutex(x)
+ * - init_mutex_locked(x)
+ * - mutex_up(x)
+ * - mutex_down(x)
+ */
+
+
+/*
+ * init_mutex
+ *   To initialize a mutex_t structure
+ *
+ * Arguments:
+ *   mutex:  pointer to the mutex_t structure
+ *
+ * Return Value:
+ *   N/A
+ *
+ * Notes: 
+ *   N/A
+ */
+
+static inline void init_mutex(mutex_t *mutex)
+{
+    sema_init(mutex, 1);
+}
+
+
+/*
+ * mutex_down
+ *   To acquire the mutex lock
+ *
+ * Arguments:
+ *   mutex:  pointer to the mutex_t structure
+ *
+ * Return Value:
+ *   N/A
+ *
+ * Notes: 
+ *   N/A
+ */
+
+static inline void mutex_down(mutex_t *mutex)
+{
+    __down(mutex);
+}
+
+
+/*
+ * mutex_up
+ *   To release the mutex lock (acquired already)
+ *
+ * Arguments:
+ *   mutex:  pointer to the mutex_t structure
+ *
+ * Return Value:
+ *   N/A
+ *
+ * Notes: 
+ *   N/A
+ */
+
+static inline void mutex_up(mutex_t *mutex)
+{
+    __up(mutex);
+}
+
+
+/*
+ * init_mutex_locked
+ *   To initialize the mutex as acquired state
+ *
+ * Arguments:
+ *   mutex:  pointer to the mutex_t structure
+ *
+ * Return Value:
+ *   N/A
+ *
+ * Notes: 
+ *   N/A
+ */
+
+static inline init_mutex_locked(mutex_t *mutex)
+{
+    init_mutex(mutex);
+    mutex_down(mutex);
+}
+
+/*
+ * completion
+ *
+ * - init_complition(c)
+ * - complete(c)
+ * - wait_for_completion(c)
+ */
+
+struct completion {
+       event_t  event;
+};
+
+
+/*
+ * init_completion
+ *   To initialize the completion object
+ *
+ * Arguments:
+ *   c:  pointer to the completion structure
+ *
+ * Return Value:
+ *   N/A
+ *
+ * Notes: 
+ *   N/A
+ */
+
+static inline void init_completion(struct completion *c)
+{
+       cfs_init_event(&(c->event), 1, FALSE);
+}
+
+
+/*
+ * complete
+ *   To complete/signal the completion object
+ *
+ * Arguments:
+ *   c:  pointer to the completion structure
+ *
+ * Return Value:
+ *   N/A
+ *
+ * Notes: 
+ *   N/A
+ */
+
+static inline void complete(struct completion *c)
+{
+       cfs_wake_event(&(c->event));
+}
+
+/*
+ * wait_for_completion
+ *   To wait on the completion object. If the event is signaled,
+ *   this function will return to the call with the event un-singled.
+ *
+ * Arguments:
+ *   c:  pointer to the completion structure
+ *
+ * Return Value:
+ *   N/A
+ *
+ * Notes: 
+ *   N/A
+ */
+
+static inline void wait_for_completion(struct completion *c)
+{
+    cfs_wait_event(&(c->event), 0);
+}
+
+/* __KERNEL__ */
+#else
+
+#include "../user-lock.h"
+
+/* __KERNEL__ */
+#endif
+#endif
diff --git a/libcfs/include/libcfs/winnt/winnt-mem.h b/libcfs/include/libcfs/winnt/winnt-mem.h
new file mode 100644 (file)
index 0000000..b7f00a4
--- /dev/null
@@ -0,0 +1,133 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=4:tabstop=4:
+ *
+ *  Copyright (C) 2001 Cluster File Systems, Inc. <braam@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Basic library routines of memory manipulation routines .
+ *
+ */
+
+#ifndef __LIBCFS_WINNT_CFS_MEM_H__
+#define __LIBCFS_WINNT_CFS_MEM_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
+#endif
+
+#ifdef __KERNEL__
+
+#define CFS_PAGE_SIZE                   PAGE_SIZE
+#define CFS_PAGE_SHIFT                  PAGE_SHIFT
+#define CFS_PAGE_MASK                   (~(PAGE_SIZE - 1))
+
+typedef struct cfs_page {
+    void *      addr;
+    atomic_t    count;
+} cfs_page_t;
+
+
+cfs_page_t *cfs_alloc_page(int flags);
+void cfs_free_page(cfs_page_t *pg);
+
+static inline void *cfs_page_address(cfs_page_t *page)
+{
+    return page->addr;
+}
+
+static inline void *cfs_kmap(cfs_page_t *page)
+{
+    return page->addr;
+}
+
+static inline void cfs_kunmap(cfs_page_t *page)
+{
+    return;
+}
+
+static inline void cfs_get_page(cfs_page_t *page)
+{
+    atomic_inc(&page->count);
+}
+
+static inline void cfs_put_page(cfs_page_t *page)
+{
+    atomic_dec(&page->count);
+}
+
+static inline int cfs_page_count(cfs_page_t *page)
+{
+    return atomic_read(&page->count);
+}
+
+/*
+ * Memory allocator
+ */
+
+#define CFS_ALLOC_ATOMIC_TRY   (0)
+
+extern void *cfs_alloc(size_t nr_bytes, u_int32_t flags);
+extern void  cfs_free(void *addr);
+
+extern void *cfs_alloc_large(size_t nr_bytes);
+extern void  cfs_free_large(void *addr);
+
+/*
+ * SLAB allocator
+ */
+
+#define SLAB_HWCACHE_ALIGN             0
+
+/* The cache name is limited to 20 chars */
+
+typedef struct cfs_mem_cache {
+
+    char                    name[20];
+    ulong_ptr           flags;
+    NPAGED_LOOKASIDE_LIST   npll;
+
+} cfs_mem_cache_t;
+
+
+extern cfs_mem_cache_t * cfs_mem_cache_create (const char *, size_t, size_t, ulong_ptr);
+extern int cfs_mem_cache_destroy ( cfs_mem_cache_t * );
+extern void *cfs_mem_cache_alloc ( cfs_mem_cache_t *, int);
+extern void cfs_mem_cache_free ( cfs_mem_cache_t *, void *);
+
+
+/*
+ * Page allocator slabs 
+ */
+
+extern cfs_mem_cache_t *cfs_page_t_slab;
+extern cfs_mem_cache_t *cfs_page_p_slab;
+
+
+#define CFS_DECL_MMSPACE
+#define CFS_MMSPACE_OPEN    do {} while(0)
+#define CFS_MMSPACE_CLOSE   do {} while(0)
+
+
+#define mb()    do {} while(0)
+#define rmb()   mb()
+#define wmb()   mb()
+
+
+/* __KERNEL__ */
+#endif
+
+#endif /* __WINNT_CFS_MEM_H__ */
diff --git a/libcfs/include/libcfs/winnt/winnt-prim.h b/libcfs/include/libcfs/winnt/winnt-prim.h
new file mode 100644 (file)
index 0000000..3c8560b
--- /dev/null
+++ b