Remove the WinNT "support" code. It's not maintained or used.
Signed-off-by: John L. Hammond <john.hammond@intel.com>
Change-Id: I361bfce148a040db60d68d3c34a399415f2dd628
Reviewed-on: http://review.whamcloud.com/11385
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Dmitry Eremin <dmitry.eremin@intel.com>
Reviewed-by: Bob Glossman <bob.glossman@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
libcfs_heap.h \
libcfs_ioctl.h \
libcfs_kernelcomm.h \
- libcfs_pack.h \
libcfs_prim.h \
libcfs_private.h \
libcfs_string.h \
libcfs_time.h \
- libcfs_unpack.h \
libcfs_workitem.h \
libcfsutil.h \
list.h \
#include <libcfs/types.h>
-#if !defined(__WINNT__) && !defined(__KERNEL__)
+#if !defined(__KERNEL__)
#include <libcfs/posix/libcfs.h>
#elif 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
} while (0)
#endif /* BITS_PER_LONG > 32 */
-#elif defined(_MSC_VER)
-#define RETURN(rc) \
-do { \
- CDEBUG(D_TRACE, "Process leaving.\n"); \
- EXIT_NESTING; \
- return (rc); \
-} while (0)
#else
# error "Unkown compiler"
#endif /* __GNUC__ */
extern int cfs_trace_copyout_string(char *usr_buffer, int usr_buffer_nob,
const char *knl_buffer, char *append);
-#if defined(__WINNT__)
-#define LIBCFS_DEBUG_FILE_PATH_DEFAULT "\\SystemRoot\\temp\\lustre-log"
-#else
#define LIBCFS_DEBUG_FILE_PATH_DEFAULT "/tmp/lustre-log"
-#endif
#endif /* __LIBCFS_DEBUG_H__ */
+++ /dev/null
-#if !defined(__GNUC__) && defined(_MSC_VER)
-#pragma warning(disable:4103)
-#pragma pack(push, 1)
-#endif
-
+++ /dev/null
-#if !defined(__GNUC__) && defined(_MSC_VER)
-#pragma warning(disable:4103)
-#pragma pack(pop)
-#endif
#define get_random_bytes(val, size) (*val) = 0
/* utility libcfs init/fini entries */
-#ifdef __WINNT__
-extern int libcfs_arch_init(void);
-extern void libcfs_arch_cleanup(void);
-#else /* !__WINNT__ */
static inline int libcfs_arch_init(void) {
return 0;
}
static inline void libcfs_arch_cleanup(void) {
}
-/* __WINNT__ */
-#endif
-
-/* proc interface wrappers for non-win OS */
-#ifndef __WINNT__
-#define cfs_proc_open open
-#define cfs_proc_mknod mknod
-#define cfs_proc_ioctl ioctl
-#define cfs_proc_close close
-#define cfs_proc_read read
-#define cfs_proc_write write
-#define cfs_proc_fopen fopen
-#define cfs_proc_fclose fclose
-#define cfs_proc_fgets fgets
-/* !__WINNT__ */
-#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:
- */
+#endif /* __LIBCFS_USER_PRIM_H__ */
#include <errno.h>
#include <string.h>
#if HAVE_LIBPTHREAD
-#ifndef __WINNT__
#include <sys/ipc.h>
#include <sys/shm.h>
-#endif
#include <pthread.h>
typedef pthread_mutex_t l_mutex_t;
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#ifndef __LIBCFS_WINNT_KP30_H__
-#define __LIBCFS_WINNT_KP30_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 */
-
-
-/* winnt panic */
-void libcfs_panic(char *msg);
-#define panic(msg) libcfs_panic(msg)
-void libcfs_register_panic_notifier();
-void libcfs_unregister_panic_notifier();
-
-
-#define cfs_work_struct_t WORK_QUEUE_ITEM
-#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 symbol_get(x) (cfs_symbol_get(#x))
-#define symbol_put(x) cfs_symbol_put(#x)
-
-#define try_module_get(THIS_MODULE) do{}while(0)
-#define module_put(THIS_MODULE) do{}while(0)
-
-#define printk DbgPrint
-#define ptintf DbgPrint
-#define printk_ratelimit() (FALSE)
-#define vprintk(f, a) vDbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, f, a)
- /* vDbgPrintEx only available on xp and later OS */
-#define cfs_assert ASSERT
-
-#else /* !__KERNEL__ */
-
-# include <stdio.h>
-# include <stdlib.h>
-#ifdef __CYGWIN__
-# include <cygwin-ioctl.h>
-#endif
-# include <time.h>
-#include <crtdbg.h>
-
-#define cfs_assert _ASSERT
-
-#ifndef get_cpu
-#define get_cpu() smp_processor_id()
-#define put_cpu() do { } while (0)
-#else
-#endif
-
-#endif /* End of !__KERNEL__ */
-
-#define IOCTL_LIBCFS_TYPE long_ptr_t
-
-#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_t)0x5a5a5a5a5a5a5a5a)
-# define LP_POISON ((char *)(long_ptr_t)0x5a5a5a5a5a5a5a5a)
-#else
-# define LI_POISON ((int)0x5a5a5a5a)
-# define LL_POISON ((long_ptr_t)0x5a5a5a5a)
-# define LP_POISON ((char *)(long_ptr_t)0x5a5a5a5a)
-#endif
-
-#define LPF64 "%I64d"
-#define LPU64 "%I64u"
-#define LPD64 "%I64d"
-#define LPX64 "%#I64x"
-#define LPO64 "%#I64o"
-
-/*
- * long_ptr_t & ulong_ptr_t, same to "long" for linux
- */
-#if _x86_
-# define LPLU "%u"
-# define LPLD "%d"
-# define LPLX "%#x"
-# define LPPID "%d"
-#else
-# define LPLU "%Ii64u"
-# define LPLD "%I64d"
-# define LPLX "%#I64x"
-# define LPPID "%d"
-#endif
-
-#endif
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#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 */
-#if _MSC_VER <= 1300
-#define __FUNCTION__ ("generic")
-#endif
-
-#include <config.h>
-#include <libcfs/winnt/winnt-types.h>
-#include <libcfs/list.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>
-#include <libcfs/winnt/kp30.h>
-
-#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((PULONG_PTR)&LowLimit, (PULONG_PTR)&HighLimit);
- ASSERT(HighLimit > LowLimit);
-
- return (__u32) (HighLimit - LowLimit);
-}
-
-/* disable watchdog */
-#undef WITH_WATCHDOG
-
-#else /* !__KERNEL__*/
-
-#include <libcfs/user-bitops.h>
-
-static inline __u32 query_stack_size()
-{
- return PAGE_SIZE; /* using one page in default */
-}
-
-#endif /* __KERNEL__*/
-
-#ifndef THREAD_SIZE
-# define THREAD_SIZE query_stack_size()
-#endif
-
-#ifdef __KERNEL__
-#define CDEBUG_STACK() (THREAD_SIZE - (__u32)IoGetRemainingStackSize())
-#define CFS_CHECK_STACK(msgdata, mask, cdls) do {} while(0)
-#else /* !__KERNEL__ */
-#define CFS_CHECK_STACK(msgdata, mask, cdls) 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)
-
-/*
- * Portable API to access common characteristics of "current" UNIX process.
- */
-uid_t current_uid(void);
-gid_t current_gid(void);
-uid_t current_euid(void);
-gid_t current_egid(void);
-uid_t current_fsuid(void);
-gid_t current_fsgid(void);
-pid_t current_pid(void);
-int in_group_p(gid_t group);
-mode_t current_umask(void);
-char *current_comm(void);
-
-/* check if task is running in compat mode.*/
-int current_is_32bit(void);
-
-#endif /* _WINNT_LIBCFS_H */
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#ifndef __LIBCFS_WINNT_PORTALS_COMPAT_H__
-#define __LIBCFS_WINNT_PORTALS_COMPAT_H__
-#ifdef __KERNEL__
-/*
- * Signal
- */
-
-#define SIGNAL_MASK_LOCK(task, flags) do {} while(0)
-#define SIGNAL_MASK_UNLOCK(task, flags) do {} while(0)
-#define call_usermodehelper(path, argv, envp, 1) do {} while(0)
-#define recalc_sigpending() do {} while(0)
-#define clear_tsk_thread_flag(current, TIF_SIGPENDING) do {} while(0)
-#endif
-
-#define LL_PROC_PROTO(name) \
- name(struct ctl_table *table, int write, struct file *filp, \
- void __user *buffer, size_t *lenp)
-
-#endif /* _PORTALS_COMPAT_H */
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * libcfs/include/libcfs/winnt/portals_utils.h
- *
- * Basic library routines.
- */
-
-#ifndef __LIBCFS_WINNT_PORTALS_UTILS_H__
-#define __LIBCFS_WINNT_PORTALS_UTILS_H__
-
-#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_div64(__u64 * n, __u64 b)
-{
- __u64 mod;
-
- mod = *n % b;
- *n = *n / b;
- return (__u32)mod;
-}
-
-#define do_div(n, b) do_div64(&(n), (__u64)b)
-#ifdef __KERNEL__
-
-#include <stdlib.h>
-#include <libcfs/winnt/winnt-types.h>
-
-char * strsep(char **s, const char *ct);
-char * ul2dstr(ulong_ptr_t 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 set_bit(int nr, void * addr)
-{
- (((volatile ULONG *) addr)[nr >> 5]) |= (1UL << (nr & 31));
- return *((int *) addr);
-}
-
-static inline int test_bit(int nr, void * addr)
-{
- return (int)(((1UL << (nr & 31)) & (((volatile ULONG *) addr)[nr >> 5])) != 0);
-}
-
-static inline int clear_bit(int nr, void * addr)
-{
- (((volatile ULONG *) addr)[nr >> 5]) &= (~(1UL << (nr & 31)));
- return *((int *) addr);
-}
-
-static inline int test_and_set_bit(int nr, volatile void *addr)
-{
- int rc;
- unsigned char mask;
- volatile unsigned char *ADDR = addr;
-
- ADDR += nr >> 3;
- mask = 1 << (nr & 0x07);
- rc = ((mask & *ADDR) != 0);
- *ADDR |= mask;
-
- return rc;
-}
-
-#define ext2_set_bit(nr, addr) (set_bit(nr, addr), 0)
-#define ext2_clear_bit(nr, addr) (clear_bit(nr, addr), 0)
-#define ext2_test_bit(nr, addr) test_bit(nr, addr)
-
-static inline int ffs(int x)
-{
- int r = 1;
-
- if (!x)
- return 0;
- if (!(x & 0xffff)) {
- x >>= 16;
- r += 16;
- }
- if (!(x & 0xff)) {
- x >>= 8;
- r += 8;
- }
- if (!(x & 0xf)) {
- x >>= 4;
- r += 4;
- }
- if (!(x & 3)) {
- x >>= 2;
- r += 2;
- }
- if (!(x & 1)) {
- x >>= 1;
- r += 1;
- }
- return r;
-}
-
-static inline unsigned long __cfs_ffs(unsigned long word)
-{
- int num = 0;
-
-#if BITS_PER_LONG == 64
- if ((word & 0xffffffff) == 0) {
- num += 32;
- word >>= 32;
- }
-#endif
- if ((word & 0xffff) == 0) {
- num += 16;
- word >>= 16;
- }
- if ((word & 0xff) == 0) {
- num += 8;
- word >>= 8;
- }
- if ((word & 0xf) == 0) {
- num += 4;
- word >>= 4;
- }
- if ((word & 0x3) == 0) {
- num += 2;
- word >>= 2;
- }
- if ((word & 0x1) == 0)
- num += 1;
- return num;
-}
-
-/**
- * fls - find last (most-significant) bit set
- * @x: the word to search
- *
- * This is defined the same way as ffs.
- * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
- */
-static inline
-int fls(int x)
-{
- int r = 32;
-
- if (!x)
- return 0;
- if (!(x & 0xffff0000u)) {
- x <<= 16;
- r -= 16;
- }
- if (!(x & 0xff000000u)) {
- x <<= 8;
- r -= 8;
- }
- if (!(x & 0xf0000000u)) {
- x <<= 4;
- r -= 4;
- }
- if (!(x & 0xc0000000u)) {
- x <<= 2;
- r -= 2;
- }
- if (!(x & 0x80000000u)) {
- x <<= 1;
- r -= 1;
- }
- return r;
-}
-
-static inline unsigned find_first_bit(const unsigned long *addr,
- unsigned size)
-{
- unsigned x = 0;
-
- while (x < size) {
- unsigned long val = *addr++;
- if (val)
- return __cfs_ffs(val) + x;
- x += (sizeof(*addr)<<3);
- }
- return x;
-}
-
-static inline void read_random(char *buf, int len)
-{
- ULONG Seed = (ULONG)(ULONG_PTR) 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, const void *from, int c)
-{
- memcpy(to, from, c);
- return 0;
-}
-
-static unsigned long
-clear_user(void __user *to, unsigned long n)
-{
- memset(to, 0, n);
- return n;
-}
-
-#define put_user(x, ptr) \
-( \
- *(ptr) = x, \
- 0 \
-)
-
-
-#define get_user(x,ptr) \
-( \
- x = *(ptr), \
- 0 \
-)
-
-#define totalram_pages (64 * 1024)
-#define NUM_CACHEPAGES totalram_pages
-
-#else
-
-#define unlink _unlink
-#define close _close
-#define open _open
-#define fdopen _fdopen
-#define strdup _strdup
-#define fileno _fileno
-#define isattry _isattry
-#define stat _stat
-
-#endif /* !__KERNEL__ */
-
-int cfs_error_code(NTSTATUS);
-
-static inline int vsnprintf(char *buf, size_t cnt,
- const char *fmt, va_list va)
-{
- int rc;
-
-#ifdef TRUE /* using msvcrt from windkk 3790 */
- rc = _vsnprintf(buf, cnt, fmt, va);
-#else
- rc = _vsnprintf_s(buf, cnt, cnt, fmt, va);
-#endif
- if (rc == -1)
- return cnt;
- return rc;
-}
-
-static inline int snprintf(char *buf, size_t cnt,
- const char *fmt, ...)
-{
- int rc;
- va_list va;
-
- va_start(va, fmt);
- rc = vsnprintf(buf, cnt, fmt, va);
- va_end(va);
- return rc;
-}
-
-#endif
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * libcfs/include/libcfs/winnt/winnt-fs.h
- *
- * 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))
-
-#define PATH_MAX (260)
-
-#ifdef __KERNEL__
-
-/* linux/fs.h */
-
-#define MAY_EXEC 1
-#define MAY_WRITE 2
-#define MAY_READ 4
-#define MAY_APPEND 8
-
-#define FMODE_READ 1
-#define FMODE_WRITE 2
-
-/* Internal kernel extensions */
-#define FMODE_LSEEK 4
-#define FMODE_PREAD 8
-#define FMODE_PWRITE FMODE_PREAD /* These go hand in hand */
-
-/* File is being opened for execution. Primary users of this flag are
- distributed filesystems that can use it to achieve correct ETXTBUSY
- behavior for cross-node execution/opening_for_writing of files */
-#define FMODE_EXEC 16
-
-#define RW_MASK 1
-#define RWA_MASK 2
-#define READ 0
-#define WRITE 1
-#define READA 2 /* read-ahead - don't block if no resources */
-#define SWRITE 3 /* for ll_rw_block() - wait for buffer lock */
-#define SPECIAL 4 /* For non-blockdevice requests in request queue */
-#define READ_SYNC (READ | (1 << BIO_RW_SYNC))
-#define WRITE_SYNC (WRITE | (1 << BIO_RW_SYNC))
-#define WRITE_BARRIER ((1 << BIO_RW) | (1 << BIO_RW_BARRIER))
-
-struct file_operations
-{
- struct module *owner;
- loff_t (*llseek)(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_t);
- int (*open) (struct inode*, struct file *);
- int (*release) (struct inode*, struct file *);
-};
-
-struct file {
-
- cfs_handle_t f_handle;
- unsigned int f_flags;
- mode_t f_mode;
- __u32 f_count;
-
- size_t f_size;
- loff_t f_pos;
- unsigned int f_uid, f_gid;
- int f_error;
-
- __u32 f_version;
-
- //struct list_head f_list;
- struct dentry * f_dentry;
-
- cfs_proc_entry_t * proc_dentry;
- cfs_file_operations_t * f_op;
-
- void * private_data;
- struct inode * f_inode;
- char f_name[1];
-
-};
-
-#define filp_size(f) ((f)->f_size)
-#define filp_poff(f) (&(f)->f_pos)
-
-struct file *filp_open(const char *name, int flags, int mode);
-int filp_close(struct file *fp, void *id);
-int filp_read(struct file *fp, void *buf, size_t nbytes, loff_t *pos);
-int filp_write(struct file *fp, void *buf, size_t nbytes, loff_t *pos);
-int filp_fsync(struct file *fp);
-int get_file(struct file *fp);
-int fput(struct file *fp);
-int file_count(struct file *fp);
-#define cfs_filp_unlink(x, y) (KdBreakPoint(), 0)
-/*
- * CFS_FLOCK routines
- */
-
-struct file_lock {
- int fl_type;
- pid_t fl_pid;
- size_t fl_len;
- off_t fl_start;
- off_t fl_end;
-};
-
-#define INT_LIMIT(x) (~((x)1 << (sizeof(x)*8 - 1)))
-#define OFFSET_MAX INT_LIMIT(loff_t)
-
-#define flock_type(fl) ((fl)->fl_type)
-#define flock_set_type(fl, type) do { (fl)->fl_type = (type); } while (0)
-#define flock_pid(fl) ((fl)->fl_pid)
-#define flock_set_pid(fl, pid) do { (fl)->fl_pid = (pid); } while (0)
-#define flock_start(fl) ((fl)->fl_start)
-#define flock_set_start(fl, st) do { (fl)->fl_start = (st); } while (0)
-#define flock_end(fl) ((fl)->fl_end)
-#define 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
-
-/*
- * set ATTR_BLOCKS to a high value to avoid any risk of collision with other
- * ATTR_* attributes (see bug 13828): lustre/include/winnt/lustre_compat25.h
- */
-/* #define ATTR_BLOCKS 0x4000 */
-#define ATTR_BLOCKS (1 << 27)
-
-#define ATTR_KILL_SUID 0
-#define ATTR_KILL_SGID 0
-
-
-
-#define in_group_p(x) (0)
-
-
-/* VFS structures for windows */
-
-/*
- * inode formats
- */
-
-#define S_IFMT 00170000
-#define S_IFSOCK 0140000
-#define S_IFLNK 0120000
-#define S_IFREG 0100000
-#define S_IFBLK 0060000
-#define S_IFDIR 0040000
-#define S_IFCHR 0020000
-#define S_IFIFO 0010000
-#define S_ISUID 0004000
-#define S_ISGID 0002000
-#define S_ISVTX 0001000
-
-/* Inode flags - they have nothing to superblock flags now */
-
-#define S_SYNC 1 /* Writes are synced at once */
-#define S_NOATIME 2 /* Do not update access times */
-#define S_APPEND 4 /* Append-only file */
-#define S_IMMUTABLE 8 /* Immutable file */
-#define S_DEAD 16 /* removed, but still open directory */
-#define S_NOQUOTA 32 /* Inode is not counted to quota */
-#define S_DIRSYNC 64 /* Directory modifications are synchronous */
-#define S_NOCMTIME 128 /* Do not update file c/mtime */
-#define S_SWAPFILE 256 /* Do not truncate: swapon got its bmaps */
-#define S_PRIVATE 512 /* Inode is fs-internal */
-
-
-struct inode {
- __u32 i_mode;
- __u64 i_size;
- __u64 i_blocks;
- struct timespec i_atime;
- struct timespec i_ctime;
- struct timespec i_mtime;
- struct timespec i_dtime;
- __u32 i_ino;
- __u32 i_generation;
- __u32 i_state;
- __u32 i_blkbits;
- int i_uid;
- int i_gid;
- __u32 i_flags;
- struct mutex i_sem;
- void * i_priv;
-};
-
-#define I_FREEING 0x0001
-
-struct dentry {
- atomic_t d_count;
- struct {
- int len;
- char * name;
- } d_name;
- struct inode * d_inode;
- struct dentry* d_parent;
-};
-
-extern struct dentry *dget(struct dentry *de);
-extern void dput(struct dentry *de);
-static __inline struct dentry *lookup_one_len(const char *name, struct dentry *de, int len)
-{
- cfs_enter_debugger();
- return NULL;
-}
-
-static inline loff_t i_size_read(const struct inode *inode)
-{
- cfs_enter_debugger();
- return inode->i_size;
-}
-
-static inline void i_size_write(struct inode *inode, loff_t i_size)
-{
- cfs_enter_debugger();
- inode->i_size = i_size;
-}
-
-struct kstatfs {
- u64 f_type;
- long f_bsize;
- u64 f_blocks;
- u64 f_bfree;
- u64 f_bavail;
- u64 f_files;
- u64 f_ffree;
- __u32 f_fsid;
- long f_namelen;
- long f_frsize;
- long f_spare[5];
-};
-
-struct super_block {
- void * s_fs_info;
-};
-
-struct vfsmount {
- struct dentry * pwd;
- struct dentry * mnt_root;
- struct super_block *mnt_sb;
-};
-
-
-/*
- * quota definitions (linux/quota.h)
- */
-
-#define MAXQUOTAS 2
-#define USRQUOTA 0 /* element used for user quotas */
-#define GRPQUOTA 1 /* element used for group quotas */
-
-
-/*
- * proc fs routines
- */
-
-typedef int (read_proc_t)(char *page, char **start, off_t off,
- int count, int *eof, void *data);
-
-struct file; /* forward ref */
-typedef int (write_proc_t)(struct file *file, const char *buffer,
- unsigned long count, void *data);
-
-void proc_destory_subtree(cfs_proc_entry_t *entry);
-
-int proc_init_fs();
-void proc_destroy_fs();
-
-/*
- * thread affinity
- */
-
-HANDLE cfs_open_current_thread();
-void cfs_close_thread_handle(HANDLE handle);
-KAFFINITY cfs_query_thread_affinity();
-int cfs_set_thread_affinity(KAFFINITY affinity);
-int cfs_tie_thread_to_cpu(int cpu);
-typedef PVOID mm_segment_t;
-
-/*
- * thread priority
- */
-int cfs_set_thread_priority(KPRIORITY priority);
-
-#define MAKE_MM_SEG(s) ((mm_segment_t)(ulong_ptr_t)(s))
-#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFFUL)
-#define USER_DS MAKE_MM_SEG(PAGE_OFFSET)
-
-#define get_ds() (KERNEL_DS)
-#define set_fs(x) do {} while(0)
-#define get_fs() (NULL)
-
-/*
- * radix tree (linux/radix_tree.h)
- */
-
-/* radix tree root structure */
-struct radix_tree_root {
- RTL_GENERIC_TABLE table;
-};
-
-/* #define RADIX_TREE_INIT(mask) {0}
-
-#define RADIX_TREE(name, mask) \
- struct radix_tree_root name RADIX_TREE_INIT(mask) */
-
-VOID RadixInitTable(IN PRTL_GENERIC_TABLE Table);
-#define INIT_RADIX_TREE(root, mask) RadixInitTable(&((root)->table))
-
-/* all radix tree routines should be protected by external locks */
-unsigned int
-radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
- unsigned long first_index, unsigned int max_items);
-void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index);
-int radix_tree_insert(struct radix_tree_root *root, unsigned long index,
- void *item);
-void *radix_tree_delete(struct radix_tree_root *root, unsigned long index);
-
-#else /* !__KERNEL__ */
-
-#if !defined(_WINDOWS_)
-
-#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
-DWORD
-NTAPI
-GetLastError(
- VOID
- );
-
-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
-
-#endif /* __KERNEL__ */
-
-struct dentry {
- void *d;
-};
-
-/*
- * misc
- */
-
-#endif /* __LIBCFS_WINNT_CFS_FS_H__*/
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * libcfs/include/libcfs/winnt/winnt-lock.h
- *
- * 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__
-
-
-/*
- * 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.
- */
-
-/*
- * spinlock & event definitions
- */
-
-typedef struct spin_lock spinlock_t;
-
-/* 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);
-
-int FASTCALL atomic_add_return(int i, atomic_t *v);
-int FASTCALL atomic_sub_return(int i, atomic_t *v);
-
-#define atomic_inc_return(v) atomic_add_return(1, v)
-#define atomic_dec_return(v) atomic_sub_return(1, v)
-
-int FASTCALL atomic_dec_and_lock(atomic_t *v, spinlock_t *lock);
-
-/* 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_internal
- * 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_internal(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);
-}
-
-/*
- * 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.)
- *
- */
-
-struct spin_lock {
- KSPIN_LOCK lock;
- KIRQL irql;
-};
-
-#define CFS_DECL_SPIN(name) spinlock_t name;
-#define CFS_DECL_SPIN_EXTERN(name) extern spinlock_t name;
-
-#define DEFINE_SPINLOCK {0}
-
-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_lock_nested(spinlock_t *lock, unsigned subclass)
-{
- 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 libcfs_mp_system;
-
-static int spin_trylock(spinlock_t *lock)
-{
- KIRQL Irql;
- int rc = 0;
-
- ASSERT(lock != NULL);
-
- KeRaiseIrql(DISPATCH_LEVEL, &Irql);
-
- if (libcfs_mp_system) {
- if (0 == (ulong_ptr_t)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;
-}
-
-static int assert_spin_locked(spinlock_t *lock)
-{
-#if _WIN32_WINNT >= 0x502
- /* KeTestSpinLock only avalilable on 2k3 server or later */
- return !KeTestSpinLock(&lock->lock);
-#else
- return (int) (lock->lock);
-#endif
-}
-
-/* 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)
- */
-
-
-struct rw_semaphore {
- ERESOURCE rwsem;
-};
-
-
-#define DECLARE_RWSEM(name) struct rw_semaphore name
-#define CFS_DECLARE_RWSEM_EXTERN(name) extern struct rw_semaphore name
-
-/*
- * init_rwsem
- * To initialize the the rw_semaphore structure
- *
- * Arguments:
- * rwsem: pointer to the rw_semaphore structure
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-static inline void init_rwsem(struct rw_semaphore *s)
-{
- ExInitializeResourceLite(&s->rwsem);
-}
-#define rwsem_init init_rwsem
-
-/*
- * fini_rwsem
- * To finilize/destroy the the rw_semaphore structure
- *
- * Arguments:
- * rwsem: pointer to the rw_semaphore 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(struct rw_semaphore *s)
-{
- ExDeleteResourceLite(&s->rwsem);
-}
-
-/*
- * down_read
- * To acquire read-lock of the rw_semaphore
- *
- * Arguments:
- * rwsem: pointer to the struct rw_semaphore
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-static inline void down_read(struct rw_semaphore *s)
-{
- ExAcquireResourceSharedLite(&s->rwsem, TRUE);
-}
-#define down_read_nested down_read
-
-
-/*
- * down_read_trylock
- * To acquire read-lock of the rw_semaphore without blocking
- *
- * Arguments:
- * rwsem: pointer to the struct rw_semaphore
- *
- * 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 struct rw_semaphore
- *
- * Arguments:
- * rwsem: pointer to the struct rw_semaphore
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-static inline void down_write(struct rw_semaphore *s)
-{
- ExAcquireResourceExclusiveLite(&(s->rwsem), TRUE);
-}
-#define down_write_nested down_write
-
-/*
- * down_write_trylock
- * To acquire write-lock of the rw_semaphore without blocking
- *
- * Arguments:
- * rwsem: pointer to the struct rw_semaphore
- *
- * 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_semaphore
- *
- * Arguments:
- * rwsem: pointer to the struct rw_semaphore
- *
- * 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_semaphore
- *
- * Arguments:
- * rwsem: pointer to the struct rw_semaphore
- *
- * 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 cfs_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)
-
-#define write_lock_bh write_lock
-#define write_unlock_bh write_unlock
-
-struct lock_class_key {
- int foo;
-};
-
-#define lockdep_set_class(lock, class) do {} while (0)
-
-static inline void lockdep_off(void)
-{
-}
-
-static inline void lockdep_on(void)
-{
-}
-
-/*
- * Semaphore
- *
- * - sema_init(x, v)
- * - __down(x)
- * - __up(x)
- */
-
-struct semaphore {
- KSEMAPHORE sem;
-};
-
-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);
-}
-
-static inline int down_trylock(struct semaphore *s)
-{
- LARGE_INTEGER timeout = {0};
- NTSTATUS status = KeWaitForSingleObject(&(s->sem), Executive,
- KernelMode, FALSE, &timeout);
-
- if (status == STATUS_SUCCESS)
- return 0;
-
- return 1;
-}
-
-/*
- * mutex_t:
- *
- * - init_mutex(x)
- * - init_mutex_locked(x)
- * - mutex_unlock(x)
- * - mutex_lock(x)
- */
-
-#define mutex semaphore
-
-#define CFS_DECLARE_MUTEX(x) struct mutex x
-
-/*
- * init_mutex
- * To initialize a mutex_t structure
- *
- * Arguments:
- * mutex: pointer to the mutex_t structure
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-#define mutex_init cfs_init_mutex
-static inline void cfs_init_mutex(struct mutex *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 cfs_mutex_down(struct mutex *mutex)
-{
- __down(mutex);
-}
-
-static inline int cfs_mutex_down_interruptible(struct mutex *mutex)
-{
- __down(mutex);
- return 0;
-}
-
-#define mutex_lock(m) cfs_mutex_down(m)
-#define mutex_trylock(s) down_trylock(s)
-#define mutex_lock_nested(m) cfs_mutex_down(m)
-#define down(m) cfs_mutex_down(m)
-#define down_interruptible(m) cfs_mutex_down_interruptible(m)
-
-/*
- * 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 cfs_mutex_up(struct mutex *mutex)
-{
- __up(mutex);
-}
-
-#define mutex_unlock(m) cfs_mutex_up(m)
-#define up(m) cfs_mutex_up(m)
-
-/*
- * 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 void cfs_init_mutex_locked(struct mutex *mutex)
-{
- cfs_init_mutex(mutex);
- cfs_mutex_down(mutex);
-}
-
-static inline void mutex_destroy(struct mutex *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_internal(&(c->event), 0);
-}
-
-static inline int wait_for_completion_interruptible(struct completion *c)
-{
- cfs_wait_event_internal(&(c->event), 0);
- return 0;
-}
-
-#endif /* !__KERNEL__ */
-#endif
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * libcfs/include/libcfs/winnt/winnt-mem.h
- *
- * 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
-
-#include <libcfs/winnt/portals_utils.h>
-
-#ifdef __KERNEL__
-
-/*
- * page definitions
- */
-
-#define PAGE_CACHE_SIZE PAGE_SIZE
-#define PAGE_CACHE_SHIFT PAGE_SHIFT
-#define CFS_PAGE_MASK (~(PAGE_SIZE - 1))
-
-#define memory_pressure_get() (0)
-#define memory_pressure_set() do {} while (0)
-#define memory_pressure_clr() do {} while (0)
-
-struct page {
- void * addr;
- atomic_t count;
- void * private;
- void * mapping;
- __u32 index;
- __u32 flags;
-};
-
-#define page cfs_page
-
-#ifndef page_private
-#define page_private(page) ((page)->private)
-#define set_page_private(page, v) ((page)->private = (v))
-#endif
-
-#define page_count(page) (0)
-
-#define PG_locked 0 /* Page is locked. Don't touch. */
-#define PG_error 1
-#define PG_referenced 2
-#define PG_uptodate 3
-
-#define PG_dirty 4
-#define PG_lru 5
-#define PG_active 6
-#define PG_slab 7 /* slab debug (Suparna wants this) */
-
-#define PG_owner_priv_1 8 /* Owner use. If pagecache, fs may use*/
-#define PG_arch_1 9
-#define PG_reserved 10
-#define PG_private 11 /* If pagecache, has fs-private data */
-
-#define PG_writeback 12 /* Page is under writeback */
-#define PG_compound 14 /* Part of a compound page */
-#define PG_swapcache 15 /* Swap page: swp_entry_t in private */
-
-#define PG_mappedtodisk 16 /* Has blocks allocated on-disk */
-#define PG_reclaim 17 /* To be reclaimed asap */
-#define PG_buddy 19 /* Page is free, on buddy lists */
-
-#define PG_virt 31 /* addr is not */
-
-#ifndef arch_set_page_uptodate
-#define arch_set_page_uptodate(page)
-#endif
-
-/* Make it prettier to test the above... */
-#define UnlockPage(page) unlock_page(page)
-#define Page_Uptodate(page) test_bit(PG_uptodate, &(page)->flags)
-#define SetPageUptodate(page) \
- do { \
- arch_set_page_uptodate(page); \
- set_bit(PG_uptodate, &(page)->flags); \
- } while (0)
-#define ClearPageUptodate(page) clear_bit(PG_uptodate, &(page)->flags)
-#define PageDirty(page) test_bit(PG_dirty, &(page)->flags)
-#define SetPageDirty(page) set_bit(PG_dirty, &(page)->flags)
-#define ClearPageDirty(page) clear_bit(PG_dirty, &(page)->flags)
-#define PageLocked(page) test_bit(PG_locked, &(page)->flags)
-#define LockPage(page) set_bit(PG_locked, &(page)->flags)
-#define TryLockPage(page) test_and_set_bit(PG_locked, &(page)->flags)
-#define PageChecked(page) test_bit(PG_checked, &(page)->flags)
-#define SetPageChecked(page) set_bit(PG_checked, &(page)->flags)
-#define ClearPageChecked(page) clear_bit(PG_checked, &(page)->flags)
-#define PageLaunder(page) test_bit(PG_launder, &(page)->flags)
-#define SetPageLaunder(page) set_bit(PG_launder, &(page)->flags)
-#define ClearPageLaunder(page) clear_bit(PG_launder, &(page)->flags)
-#define ClearPageArch1(page) clear_bit(PG_arch_1, &(page)->flags)
-
-#define PageError(page) test_bit(PG_error, &(page)->flags)
-#define SetPageError(page) set_bit(PG_error, &(page)->flags)
-#define ClearPageError(page) clear_bit(PG_error, &(page)->flags)
-#define PageReferenced(page) test_bit(PG_referenced, &(page)->flags)
-#define SetPageReferenced(page) set_bit(PG_referenced, &(page)->flags)
-#define ClearPageReferenced(page) clear_bit(PG_referenced, &(page)->flags)
-
-#define PageActive(page) test_bit(PG_active, &(page)->flags)
-#define SetPageActive(page) set_bit(PG_active, &(page)->flags)
-#define ClearPageActive(page) clear_bit(PG_active, &(page)->flags)
-
-#define PageWriteback(page) test_bit(PG_writeback, &(page)->flags)
-#define TestSetPageWriteback(page) test_and_set_bit(PG_writeback, \
- &(page)->flags)
-#define TestClearPageWriteback(page) test_and_clear_bit(PG_writeback, \
- &(page)->flags)
-
-/*
- * Universal memory allocator API
- */
-enum cfs_alloc_flags {
- /* allocation is not allowed to block */
- GFP_ATOMIC = 0x1,
- /* allocation is allowed to block */
- __GFP_WAIT = 0x2,
- /* allocation should return zeroed memory */
- __GFP_ZERO = 0x4,
- /* allocation is allowed to call file-system code to free/clean
- * memory */
- __GFP_FS = 0x8,
- /* allocation is allowed to do io to free/clean memory */
- __GFP_IO = 0x10,
- /* don't report allocation failure to the console */
- __GFP_NOWARN = 0x20,
- /* standard allocator flag combination */
- GFP_IOFS = __GFP_FS | __GFP_IO,
- GFP_USER = __GFP_WAIT | __GFP_FS | __GFP_IO,
- GFP_NOFS = __GFP_WAIT | __GFP_IO,
- GFP_KERNEL = __GFP_WAIT | __GFP_IO | __GFP_FS,
-};
-
-/* 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
- * kmap() and unmapped with kunmap(). */
- __GFP_HIGHMEM = 0x40,
- GFP_HIGHUSER = __GFP_WAIT | __GFP_FS | __GFP_IO |
- __GFP_HIGHMEM,
-};
-
-struct page *alloc_page(int flags);
-void __free_page(struct page *pg);
-void cfs_release_page(struct page *pg);
-struct page *virt_to_page(void *addr);
-
-#define page_cache_get(a) do {} while (0)
-#define page_cache_release(a) do {} while (0)
-
-static inline void *page_address(struct page *page)
-{
- return page->addr;
-}
-
-static inline void *kmap(struct page *page)
-{
- return page->addr;
-}
-
-static inline void kunmap(struct page *page)
-{
- return;
-}
-
-static inline void get_page(struct page *page)
-{
- atomic_inc(&page->count);
-}
-
-static inline void cfs_put_page(struct page *page)
-{
- atomic_dec(&page->count);
-}
-
-static inline int page_count(struct page *page)
-{
- return atomic_read(&page->count);
-}
-
-#define page_index(p) ((p)->index)
-
-/*
- * Memory allocator
- */
-
-#define ALLOC_ATOMIC_TRY (0)
-extern void *kmalloc(size_t nr_bytes, u_int32_t flags);
-extern void kfree(void *addr);
-extern void *vmalloc(size_t nr_bytes);
-extern void vfree(void *addr);
-
-/*
- * SLAB allocator
- */
-
-#define SLAB_HWCACHE_ALIGN 0
-
-/* The cache name is limited to 20 chars */
-
-struct kmem_cache {
- char name[20];
- ulong_ptr_t flags;
- NPAGED_LOOKASIDE_LIST npll;
-};
-
-
-extern struct kmem_cache *kmem_cache_create(const char *, size_t, size_t,
- unsigned long, void *);
-extern kmem_cache_destroy(struct kmem_cache *);
-extern void *kmem_cache_alloc(struct kmem_cache *, int);
-extern void kmem_cache_free(struct kmem_cache *, void *);
-
-/*
- * shrinker
- */
-typedef int (*shrink_callback)(int nr_to_scan, gfp_t gfp_mask);
-struct shrinker {
- shrink_callback cb;
- int seeks; /* seeks to recreate an obj */
-
- /* These are for internal use */
- struct list_head list;
- long nr; /* objs pending delete */
-};
-
-struct shrinker *set_shrinker(int seeks, shrink_callback cb);
-void remove_shrinker(struct shrinker *s);
-
-int start_shrinker_timer();
-void stop_shrinker_timer();
-
-/*
- * Page allocator slabs
- */
-
-extern struct kmem_cache *cfs_page_t_slab;
-extern struct kmem_cache *cfs_page_p_slab;
-
-
-#define DECL_MMSPACE
-#define MMSPACE_OPEN do {} while (0)
-#define MMSPACE_CLOSE do {} while (0)
-
-
-#define smp_mb() do {} while(0)
-#define rmb() smp_mb()
-#define wmb() smp_mb()
-
-/*
- * MM defintions from (linux/mm.h)
- */
-
-#define DEFAULT_SEEKS 2 /* shrink seek */
-
-#else /* !__KERNEL__ */
-
-#include "../user-mem.h"
-
-/* page alignmed buffer allocation */
-void* pgalloc(size_t factor);
-void pgfree(void * page);
-
-#endif /* __KERNEL__ */
-
-#endif /* __WINNT_CFS_MEM_H__ */
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * libcfs/include/libcfs/winnt/winnt-prim.h
- *
- * Basic library routines.
- */
-
-#ifndef __LIBCFS_WINNT_CFS_PRIM_H__
-#define __LIBCFS_WINNT_CFS_PRIM_H__
-
-#ifndef __LIBCFS_LIBCFS_H__
-#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
-#endif
-
-#ifndef EXPORT_SYMBOL
-# define EXPORT_SYMBOL(s)
-#endif
-
-/*
- * libcfs proc device object
- */
-
-
-#define LUSTRE_PROC_DEVICE L"\\Device\\LNetProcFS" /* proc fs emulator device object */
-#define LUSTRE_PROC_SYMLNK L"\\DosDevices\\LNetProcFS" /* proc fs user-visible device */
-
-
-/*
- * Device IO Control Code Definitions
- */
-
-#define FILE_DEVICE_LIBCFS ('LC')
-
-#define FUNC_LIBCFS_VERSION 0x101 // get version of current libcfs
-#define FUNC_LIBCFS_IOCTL 0x102 // Device i/o control to proc fs
-
-
-#define IOCTL_LIBCFS_VERSION \
- CTL_CODE (FILE_DEVICE_LIBCFS, FUNC_LIBCFS_VERSION, METHOD_BUFFERED, FILE_ANY_ACCESS)
-#define IOCTL_LIBCFS_ENTRY \
- CTL_CODE(FILE_DEVICE_LIBCFS, FUNC_LIBCFS_IOCTL, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-#pragma pack(4)
-typedef struct _CFS_PROC_IOCTL {
-
- ULONG cmd; // ioctl command identifier
- ULONG len; // length of data
- int rc; // return code
- ULONG usused; // unused
-
- // UCHAR data[]; // content of the real ioctl
-
-} CFS_PROC_IOCTL, *PCFS_PROC_IOCTL;
-#pragma pack()
-
-#ifdef __KERNEL__
-
-void cfs_enter_debugger(void);
-#define __builtin_return_address(x) (0)
-
-/*
- * 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 int cfs_symbol_register(const char *, const void *);
-extern void cfs_symbol_unregister(const char *);
-extern void * cfs_symbol_get(const char *);
-extern void cfs_symbol_put(const char *);
-extern void cfs_symbol_clean();
-
-typedef struct file_operations cfs_file_operations_t;
-
-/*
- * Pseudo device register
- */
-
-typedef struct miscdevice{
- int minor;
- const char * name;
- cfs_file_operations_t * fops;
-};
-
-int misc_register(struct miscdevice *psdev);
-int misc_deregister(struct miscdevice *psdev);
-
-
-/*
- * Proc emulator file system APIs
- */
-
-typedef int read_proc_t(char *page, char **start, off_t off,
- int count, int *eof, void *data);
-typedef int write_proc_t(struct file *file, const char *buffer,
- unsigned long count, void *data);
-
-#define CFS_PROC_ENTRY_MAGIC 'CPEM'
-
-#define CFS_PROC_FLAG_DIRECTORY 0x00000001 // directory node
-#define CFS_PROC_FLAG_ATTACHED 0x00000002 // node is attached to proc
-#define CFS_PROC_FLAG_MISCDEV 0x00000004 // miscellaneous device
-
-typedef struct cfs_proc_entry
-{
- ULONG magic; // Magic
- ULONG flags; // Flags
-
- struct _dir_entry { // proc directory entry
- PRTL_SPLAY_LINKS root;
- };
-
- struct cfs_proc_entry *parent;
-
- struct _file_entry { // proc file / leaf entry
- read_proc_t * read_proc;
- write_proc_t * write_proc;
- };
-
- mode_t mode;
- unsigned short nlink;
- BOOLEAN deleted;
-
-
- struct file_operations *proc_fops;
- void *data;
-
- // proc_dir_entry ended.
-
- RTL_SPLAY_LINKS s_link; // splay link
-
- //
- // Maximum length of proc entry name is 0x20
- //
-
- char name[0x20];
-
-} cfs_proc_entry_t, cfs_proc_dir_entry_t;
-
-typedef cfs_proc_entry_t cfs_proc_dir_entry_t;
-#define proc_dir_entry cfs_proc_entry
-
-#define PROC_BLOCK_SIZE PAGE_SIZE
-
-struct proc_dir_entry *PDE(const struct inode *inode);
-
-
-/*
- * Sysctl register
- */
-typedef int ctl_handler(struct ctl_table *table,
- int *name, int nlen,
- void *oldval, size_t *oldlenp,
- void *newval, size_t newlen,
- void **context);
-
-typedef int proc_handler (struct ctl_table *ctl,
- int write, struct file *filp,
- void *buffer, size_t *lenp);
-
-
-int proc_dointvec(struct ctl_table *table, int write, struct file *filp,
- void *buffer, size_t *lenp);
-
-int proc_dostring(struct ctl_table *table, int write, struct file *filp,
- void *buffer, size_t *lenp);
-
-int sysctl_string(struct ctl_table *table, int *name, int nlen,
- void *oldval, size_t *oldlenp,
- void *newval, size_t newlen, void **context);
-
-/*
- * System io control definitions
- */
-
-#define CTL_MAXNAME 10
-
-#define CTL_ANY -1 /* Matches any name */
-#define CTL_NONE 0
-
-enum
-{
- CTL_KERN=1, /* General kernel info and control */
- CTL_VM=2, /* VM management */
- CTL_NET=3, /* Networking */
- CTL_PROC=4, /* Process info */
- CTL_FS=5, /* Filesystems */
- CTL_DEBUG=6, /* Debugging */
- CTL_DEV=7, /* Devices */
- CTL_BUS=8, /* Busses */
- CTL_ABI=9, /* Binary emulation */
- CTL_CPU=10 /* CPU stuff (speed scaling, etc) */
-};
-
-/* sysctl table definitons */
-struct ctl_table
-{
- int ctl_name;
- char *procname;
- void *data;
- int maxlen;
- mode_t mode;
- struct ctl_table *child;
- proc_handler *proc_handler; /* text formatting callback */
- ctl_handler *strategy; /* read / write callback functions */
- cfs_proc_entry_t *de; /* proc entry block */
- void *extra1;
- void *extra2;
-};
-
-
-/* the mantaner of the cfs_sysctl_table trees */
-struct ctl_table_header
-{
- struct ctl_table *ctl_table;
- struct list_head ctl_entry;
-};
-
-/* proc root entries, support routines */
-extern cfs_proc_entry_t * cfs_proc_root; /* / */
-extern cfs_proc_entry_t * cfs_proc_proc; /* /proc */
-extern cfs_proc_entry_t * cfs_proc_fs; /* /proc/fs */
-extern cfs_proc_entry_t * cfs_proc_sys; /* /proc/sys */
-extern cfs_proc_entry_t * cfs_proc_dev; /* /dev */
-
-cfs_proc_entry_t * create_proc_entry(const char *name, mode_t mod,
- cfs_proc_entry_t *parent);
-void proc_free_entry(cfs_proc_entry_t *de);
-void remove_proc_entry(const char *name, cfs_proc_entry_t *entry);
-cfs_proc_entry_t * search_proc_entry(const char * name,
- cfs_proc_entry_t * root );
-cfs_proc_entry_t *proc_symlink(const char *name,
- cfs_proc_entry_t *parent,
- const char *dest);
-cfs_proc_entry_t *proc_mkdir(const char *name,
- cfs_proc_entry_t *parent);
-
-#define cfs_create_proc_entry create_proc_entry
-#define cfs_free_proc_entry proc_free_entry
-#define cfs_remove_proc_entry remove_proc_entry
-
-struct ctl_table_header *register_sysctl_table(struct ctl_table *table);
-void unregister_sysctl_table(struct ctl_table_header *header);
-
-/*
- * seq device (linux/seq_file.h)
- */
-
-
-/*
- * seq file definitions
- */
-
-struct dentry;
-struct vfsmount;
-
-struct path {
- struct vfsmount *mnt;
- struct dentry *dentry;
-};
-
-struct seq_operations;
-struct file;
-struct inode;
-
-struct seq_file {
- char *buf;
- size_t size;
- size_t from;
- size_t count;
- loff_t index;
- u32 version;
- struct mutex lock;
- const struct seq_operations *op;
- void *private;
-};
-
-struct seq_operations {
- void * (*start) (struct seq_file *m, loff_t *pos);
- void (*stop) (struct seq_file *m, void *v);
- void * (*next) (struct seq_file *m, void *v, loff_t *pos);
- int (*show) (struct seq_file *m, void *v);
-};
-
-int seq_open(struct file *, const struct seq_operations *);
-ssize_t seq_read(struct file *, char __user *, size_t, loff_t *);
-loff_t seq_lseek(struct file *, loff_t, int);
-int seq_release(struct inode *, struct file *);
-int seq_escape(struct seq_file *, const char *, const char *);
-int seq_putc(struct seq_file *m, char c);
-int seq_puts(struct seq_file *m, const char *s);
-
-int seq_path(struct seq_file *, struct path *, char *);
-
-int single_open(struct file *, int (*)(struct seq_file *, void *), void *);
-int single_release(struct inode *, struct file *);
-void *__seq_open_private(struct file *, const struct seq_operations *, int);
-int seq_open_private(struct file *, const struct seq_operations *, int);
-int seq_release_private(struct inode *, struct file *);
-
-#define SEQ_START_TOKEN ((void *)1)
-
-/*
- * Helpers for iteration over list_head-s in seq_files
- */
-
-extern struct list_head *seq_list_start(struct list_head *head, loff_t pos);
-extern struct list_head *seq_list_start_head(struct list_head *head, loff_t pos);
-extern struct list_head *seq_list_next(void *v, struct list_head *head, loff_t *ppos);
-
-/*
- * declaration of proc kernel process routines
- */
-
-struct file *lustre_open_file(char *filename);
-
-int lustre_close_file(struct file *fh);
-
-int lustre_do_ioctl(struct file *fh, unsigned long cmd, ulong_ptr_t arg);
-
-int lustre_ioctl_file(struct file *fh, PCFS_PROC_IOCTL devctl);
-
-size_t lustre_read_file(struct file *fh, loff_t offl, size_t size, char *buf);
-
-size_t lustre_write_file(struct file *fh, loff_t off, size_t size, char *buf);
-
-/*
- * Wait Queue
- */
-
-
-#define TASK_INTERRUPTIBLE 0x00000001
-#define TASK_UNINTERRUPTIBLE 0x00000002
-#define TASK_RUNNING 0x00000003
-#define CFS_TASK_UNINTERRUPTIBLE TASK_UNINTERRUPTIBLE
-
-#define CFS_WAITQ_MAGIC 'CWQM'
-#define CFS_WAITLINK_MAGIC 'CWLM'
-
-typedef struct cfs_waitq {
- unsigned int magic;
- unsigned int flags;
-
- spinlock_t guard;
- struct list_head waiters;
-} wait_queue_head_t;
-
-
-typedef struct cfs_waitlink wait_queue_t;
-
-#define CFS_WAITQ_CHANNELS (2)
-
-#define CFS_WAITQ_CHAN_NORMAL (0)
-#define CFS_WAITQ_CHAN_FORWARD (1)
-
-typedef struct cfs_waitlink_channel {
- struct list_head link;
- wait_queue_head_t *waitq;
- wait_queue_t *waitl;
-} cfs_waitlink_channel_t;
-
-struct cfs_waitlink {
-
- unsigned int magic;
- int flags;
- event_t * event;
- atomic_t * hits;
-
- cfs_waitlink_channel_t waitq[CFS_WAITQ_CHANNELS];
-};
-
-enum {
- CFS_WAITQ_EXCLUSIVE = 1
-};
-
-#define CFS_DECL_WAITQ(name) wait_queue_head_t name
-
-/* Kernel thread */
-
-typedef int (*cfs_thread_t) (void *arg);
-
-typedef struct _cfs_thread_context {
- cfs_thread_t func;
- void * arg;
-} cfs_thread_context_t;
-
-/*
- * thread creation flags from Linux, not used in winnt
- */
-#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)
-
-/*
- * group_info: linux/sched.h
- */
-#define NGROUPS_SMALL 32
-#define NGROUPS_PER_BLOCK ((int)(PAGE_SIZE / sizeof(gid_t)))
-struct group_info {
- int ngroups;
- atomic_t usage;
- gid_t small_block[NGROUPS_SMALL];
- int nblocks;
- gid_t *blocks[0];
-};
-
-#define get_group_info(group_info) do { \
- atomic_inc(&(group_info)->usage); \
-} while (0)
-
-#define put_group_info(group_info) do { \
- if (atomic_dec_and_test(&(group_info)->usage)) \
- groups_free(group_info); \
-} while (0)
-
-static __inline struct group_info *groups_alloc(int gidsetsize)
-{
- struct group_info * groupinfo;
- KdPrint(("%s(%d): %s NOT implemented.\n", __FILE__, __LINE__, __FUNCTION__));
- groupinfo = kmalloc(sizeof(struct group_info), 0);
-
- if (groupinfo) {
- memset(groupinfo, 0, sizeof(struct group_info));
- }
- return groupinfo;
-}
-
-static __inline void groups_free(struct group_info *group_info)
-{
- KdPrint(("%s(%d): %s NOT implemented.\n", __FILE__, __LINE__,
- __FUNCTION__));
- kfree(group_info);
-}
-
-static __inline int
-set_current_groups(struct group_info *group_info)
-{
- KdPrint(("%s(%d): %s NOT implemented.\n", __FILE__, __LINE__,
- __FUNCTION__));
- return 0;
-}
-
-static __inline int groups_search(struct group_info *group_info,
- gid_t grp) {
- KdPrint(("%s(%d): %s NOT implemented.\n", __FILE__, __LINE__,
- __FUNCTION__));
- return 0;
-}
-
-/*
- * capability issue (linux/capability.h)
- */
-
-/* Override resource limits. Set resource limits. */
-/* Override quota limits. */
-/* Override reserved space on ext2 filesystem */
-/* Modify data journaling mode on ext3 filesystem (uses journaling
- resources) */
-/* NOTE: ext2 honors fsuid when checking for resource overrides, so
- you can override using fsuid too */
-/* Override size restrictions on IPC message queues */
-/* Allow more than 64hz interrupts from the real-time clock */
-/* Override max number of consoles on console allocation */
-/* Override max number of keymaps */
-
-#define CAP_SYS_RESOURCE 24
-
-/*
- * capabilities support
- */
-
-typedef __u32 kernel_cap_t;
-
-#define cap_raise(c, flag) do {} while(0)
-#define cap_lower(c, flag) do {} while(0)
-#define cap_raised(c, flag) do {} while(0)
-
-
-/*
- * Task struct
- */
-
-#define MAX_SCHEDULE_TIMEOUT ((long_ptr_t)(~0UL>>12))
-#define schedule_timeout(t) schedule_timeout_and_set_state(0, t)
-
-struct vfsmount;
-
-#define NGROUPS 1
-#define CFS_CURPROC_COMM_MAX (16)
-struct task_struct{
- mode_t umask;
- sigset_t blocked;
-
- pid_t pid;
- pid_t pgrp;
-
- uid_t uid,euid,suid,fsuid;
- gid_t gid,egid,sgid,fsgid;
-
- int ngroups;
- int cgroups;
- gid_t groups[NGROUPS];
- struct group_info *group_info;
- kernel_cap_t cap_effective,
- cap_inheritable,
- cap_permitted;
-
- char comm[CFS_CURPROC_COMM_MAX];
- void *journal_info;
- struct vfsmount *fs;
-};
-
-static inline void task_lock(struct task_struct *t)
-{
-}
-
-static inline void task_unlock(struct task_struct *t)
-{
-}
-
-/*
- * linux task struct emulator ...
- */
-
-#define TASKMAN_MAGIC 'TMAN' /* Task Manager */
-#define TASKSLT_MAGIC 'TSLT' /* Task Slot */
-
-typedef struct _TASK_MAN {
- ULONG Magic; /* Magic and Flags */
- ULONG Flags;
-
- spinlock_t Lock; /* Protection lock */
-
- struct kmem_cache *slab; /* Memory slab for task slot */
-
- ULONG NumOfTasks; /* Total tasks (threads) */
- LIST_ENTRY TaskList; /* List of task slots */
-} TASK_MAN, *PTASK_MAN;
-
-typedef struct _TASK_SLOT {
-
- ULONG Magic; /* Magic and Flags */
- ULONG Flags;
-
- LIST_ENTRY Link; /* To be linked to TaskMan */
-
- event_t Event; /* Schedule event */
-
- HANDLE Pid; /* Process id */
- HANDLE Tid; /* Thread id */
- PETHREAD Tet; /* Pointer to ethread */
-
- atomic_t count; /* refer count */
- atomic_t hits; /* times of waken event singaled */
-
- KIRQL irql; /* irql for rwlock ... */
-
- struct task_struct task; /* linux task part */
-
-} TASK_SLOT, *PTASK_SLOT;
-
-
-#define set_current_state(s) do {;} while (0)
-
-#define wait_event(wq, condition) \
-do { \
- wait_queue_t __wait; \
- \
- init_waitqueue_entry_current(&__wait); \
- while (TRUE) { \
- add_wait_queue(&wq, &__wait); \
- if (condition) { \
- break; \
- } \
- waitq_wait(&__wait, TASK_INTERRUPTIBLE); \
- remove_wait_queue(&wq, &__wait); \
- } \
- remove_wait_queue(&wq, &__wait); \
-} while(0)
-
-#define wait_event_interruptible(wq, condition) \
-{ \
- wait_queue_t __wait; \
- \
- __ret = 0; \
- init_waitqueue_entry_current(&__wait); \
- while (TRUE) { \
- add_wait_queue(&wq, &__wait); \
- if (condition) { \
- break; \
- } \
- waitq_wait(&__wait, TASK_INTERRUPTIBLE);\
- remove_wait_queue(&wq, &__wait); \
- } \
- remove_wait_queue(&wq, &__wait); \
- __ret; \
-}
-
-# define wait_event_interruptible_exclusive(wq, condition) \
- wait_event_interruptible(wq, condition)
-
-/*
- retval == 0; condition met; we're good.
- retval < 0; interrupted by signal.
- retval > 0; timed out.
-*/
-
-#define wait_event_interruptible_timeout(wq, condition, timeout)\
-do { \
- wait_queue_t __wait; \
- \
- init_waitqueue_entry_current(&__wait); \
- while (TRUE) { \
- add_wait_queue(&wq, &__wait); \
- if (condition) { \
- break; \
- } \
- if (waitq_timedwait(&__wait, \
- TASK_INTERRUPTIBLE, timeout) == 0) { \
- break; \
- } \
- remove_wait_queue(&wq, &__wait); \
- } \
- remove_wait_queue(&wq, &__wait); \
-} while(0)
-
-int init_task_manager();
-void cleanup_task_manager();
-struct task_struct * current;
-int wake_up_process(struct task_struct * task);
-void sleep_on(wait_queue_head_t *waitq);
-#define might_sleep() do {} while(0)
-#define DECL_JOURNAL_DATA
-#define PUSH_JOURNAL do {;} while(0)
-#define POP_JOURNAL do {;} while(0)
-
-
-/* module related definitions */
-
-#ifndef __exit
-#define __exit
-#endif
-#ifndef __init
-#define __init
-#endif
-
-struct module{
- const char *name;
-};
-
-extern struct module libcfs_global_module;
-#define THIS_MODULE &libcfs_global_module
-
-#define request_module(x, y) (0)
-#define MODULE_AUTHOR(s)
-#define MODULE_DESCRIPTION(s)
-#define MODULE_LICENSE(s)
-#define MODULE_PARM(a, b)
-#define MODULE_PARM_DESC(a, b)
-
-#define module_init(X) int __init module_##X() {return X();}
-#define module_exit(X) void __exit module_##X() {X();}
-
-#define DECLARE_INIT(X) extern int __init module_##X(void)
-#define DECLARE_EXIT(X) extern void __exit module_##X(void)
-
-#define MODULE_INIT(X) do { int rc = module_##X(); \
- if (rc) goto errorout; \
- } while(0)
-
-#define MODULE_EXIT(X) do { module_##X(); } while(0)
-
-
-/* Module interfaces */
-#define cfs_module(name, version, init, fini) \
- module_init(init); \
- module_exit(fini)
-#define module_refcount(x) (1)
-
-/*
- * typecheck
- */
-
-#define typecheck(a, b) do {} while(0)
-
-/*
- * linux/crypto.h
- */
-
-#define CRYPTO_MAX_ALG_NAME 64
-
-#define CRYPTO_TFM_MODE_ECB 0x00000001
-#define CRYPTO_TFM_MODE_CBC 0x00000002
-#define CRYPTO_TFM_MODE_CFB 0x00000004
-#define CRYPTO_TFM_MODE_CTR 0x00000008
-#define CRYPTO_TFM_MODE_EME 0x00000010
-
-/*
- * hash
- */
-/* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */
-#define GOLDEN_RATIO_PRIME_32 0x9e370001UL
-
-#if 0 /* defined in libcfs/libcfs_hash.h */
-static inline u32 hash_long(u32 val, unsigned int bits)
-{
- /* On some cpus multiply is faster, on others gcc will do shifts */
- u32 hash = val * GOLDEN_RATIO_PRIME_32;
-
- /* High bits are more random, so use them. */
- return hash >> (32 - bits);
-}
-#endif
-
-/*
- * Timer
- */
-
-#define CFS_TIMER_FLAG_INITED 0x00000001 // Initialized already
-#define CFS_TIMER_FLAG_TIMERED 0x00000002 // KeSetTimer is called
-
-struct timer_list {
-
- KSPIN_LOCK Lock;
-
- ULONG Flags;
-
- KDPC Dpc;
- KTIMER Timer;
-
- cfs_time_t deadline;
-
- void (*proc)(ulong_ptr_t);
- void * arg;
-
-};
-
-/*
- * libcfs globals initialization/cleanup
- */
-
-int
-libcfs_arch_init(void);
-
-void
-libcfs_arch_cleanup(void);
-
-/*
- * cache alignment size
- */
-
-#define L1_CACHE_ALIGN(x) (x)
-
-#define __cacheline_aligned
-
-/*
- * SMP ...
- */
-
-
-#define SMP_CACHE_BYTES 128
-#define NR_CPUS (32)
-#define smp_num_cpus ((CCHAR)KeNumberProcessors)
-#define num_possible_cpus() smp_num_cpus
-#define num_online_cpus() smp_num_cpus
-#define smp_processor_id() ((USHORT)KeGetCurrentProcessorNumber())
-#define smp_call_function(f, a, n, w) do {} while(0)
-#define smp_rmb() do {} while(0)
-
-/*
- * Irp related
- */
-
-#define NR_IRQS 512
-#define in_interrupt() (0)
-
-/*
- * printk flags
- */
-
-#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 */
-
-/*
- * Misc
- */
-
-#define inter_module_get(n) cfs_symbol_get(n)
-#define inter_module_put(n) cfs_symbol_put(n)
-
-#ifndef likely
-#define likely(exp) (exp)
-#endif
-#ifndef unlikely
-#define unlikely(exp) (exp)
-#endif
-
-#define local_irq_save(x)
-#define local_irq_restore(x)
-
-#define va_copy(_d, _s) (_d = _s)
-
-char *strnchr(const char *s, size_t count, int c);
-
-#define adler32(a,b,l) zlib_adler32(a,b,l)
-ULONG zlib_adler32(ULONG adler, const BYTE *buf, UINT len);
-
-typedef ssize_t (*read_actor_t)();
-
-#if DBG
-/*
- * winnt debug routines
- */
-
-VOID
-KsPrintf(
- LONG DebugPrintLevel,
- PCHAR DebugMessage,
- ...
- );
-
-PUCHAR
-KsNtStatusToString (IN NTSTATUS Status);
-#endif
-
-#else /* !__KERNEL__ */
-
-void cfs_enter_debugger();
-
-/*
- * PAGE_SIZE ...
- */
-
-#ifndef PAGE_SIZE
-#define PAGE_SIZE (4096)
-#endif
-
-#define getpagesize() (4096)
-
-#define PAGE_CACHE_SIZE PAGE_SIZE
-#define PAGE_CACHE_MASK PAGE_MASK
-
-#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) -1)
-#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t) -2)
-#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t) -3)
-
-struct file {
- int foo;
-};
-
-#include "../user-prim.h"
-#include "../user-lock.h"
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#define strcasecmp strcmp
-#define strncasecmp strncmp
-#define getpid() (0)
-
-#define getuid() (0)
-#define getgrgid(x) (NULL)
-
-struct passwd {
- uid_t pw_uid;
- char pw_name[64];
-};
-struct passwd * getpwuid(uid_t uid);
-
-int cfs_proc_mknod(const char *path, mode_t mode, dev_t dev);
-
-int gethostname(char * name, int namelen);
-
-#define setlinebuf(x) do {} while(0)
-
-
-/* Maximum EA Information Length */
-#define EA_MAX_LENGTH (sizeof(FILE_FULL_EA_INFORMATION) + 15)
-
-/*
- * proc user mode routines
- */
-
-int cfs_proc_open (char * filename, int oflag);
-int cfs_proc_close(int fd);
-int cfs_proc_read(int fd, void *buffer, unsigned int count);
-int cfs_proc_write(int fd, void *buffer, unsigned int count);
-int cfs_proc_ioctl(int fd, int cmd, void *buffer);
-FILE *cfs_proc_fopen(char *path, char * mode);
-char *cfs_proc_fgets(char * buf, int len, FILE *fp);
-int cfs_proc_fclose(FILE *fp);
-
-/* Bits set in the FLAGS argument to `glob'. */
-#define GLOB_ERR (1 << 0)/* Return on read errors. */
-#define GLOB_MARK (1 << 1)/* Append a slash to each name. */
-#define GLOB_NOSORT (1 << 2)/* Don't sort the names. */
-#define GLOB_DOOFFS (1 << 3)/* Insert PGLOB->gl_offs NULLs. */
-#define GLOB_NOCHECK (1 << 4)/* If nothing matches, return the pattern. */
-#define GLOB_APPEND (1 << 5)/* Append to results of a previous call. */
-#define GLOB_NOESCAPE (1 << 6)/* Backslashes don't quote metacharacters. */
-#define GLOB_PERIOD (1 << 7)/* Leading `.' can be matched by metachars. */
-
-#if !defined __USE_POSIX2 || defined __USE_BSD || defined __USE_GNU
-# define GLOB_MAGCHAR (1 << 8)/* Set in gl_flags if any metachars seen. */
-# define GLOB_ALTDIRFUNC (1 << 9)/* Use gl_opendir et al functions. */
-# define GLOB_BRACE (1 << 10)/* Expand "{a,b}" to "a" "b". */
-# define GLOB_NOMAGIC (1 << 11)/* If no magic chars, return the pattern. */
-# define GLOB_TILDE (1 << 12)/* Expand ~user and ~ to home directories. */
-# define GLOB_ONLYDIR (1 << 13)/* Match only directories. */
-# define GLOB_TILDE_CHECK (1 << 14)/* Like GLOB_TILDE but return an error
- if the user name is not available. */
-# define __GLOB_FLAGS (GLOB_ERR|GLOB_MARK|GLOB_NOSORT|GLOB_DOOFFS| \
- GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_APPEND| \
- GLOB_PERIOD|GLOB_ALTDIRFUNC|GLOB_BRACE| \
- GLOB_NOMAGIC|GLOB_TILDE|GLOB_ONLYDIR|GLOB_TILDE_CHECK)
-#else
-# define __GLOB_FLAGS (GLOB_ERR|GLOB_MARK|GLOB_NOSORT|GLOB_DOOFFS| \
- GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_APPEND| \
- GLOB_PERIOD)
-#endif
-
-/* Error returns from `glob'. */
-#define GLOB_NOSPACE 1 /* Ran out of memory. */
-#define GLOB_ABORTED 2 /* Read error. */
-#define GLOB_NOMATCH 3 /* No matches found. */
-#define GLOB_NOSYS 4 /* Not implemented. */
-#ifdef __USE_GNU
-/* Previous versions of this file defined GLOB_ABEND instead of
- GLOB_ABORTED. Provide a compatibility definition here. */
-# define GLOB_ABEND GLOB_ABORTED
-#endif
-
-/* Structure describing a globbing run. */
-#ifdef __USE_GNU
-struct stat;
-#endif
-typedef struct
- {
- size_t gl_pathc; /* Count of paths matched by the pattern. */
- char **gl_pathv; /* List of matched pathnames. */
- size_t gl_offs; /* Slots to reserve in `gl_pathv'. */
- int gl_flags; /* Set to FLAGS, maybe | GLOB_MAGCHAR. */
-
- /* If the GLOB_ALTDIRFUNC flag is set, the following functions
- are used instead of the normal file access functions. */
- void (*gl_closedir) (void *);
-#ifdef __USE_GNU
- struct dirent *(*gl_readdir) (void *);
-#else
- void *(*gl_readdir) (void *);
-#endif
- void *(*gl_opendir) (const char *);
-#ifdef __USE_GNU
- int (*gl_lstat) (const char *__restrict, struct stat *__restrict);
- int (*gl_stat) (const char *__restrict, struct stat *__restrict);
-#else
- int (*gl_lstat) (const char *__restrict, void *__restrict);
- int (*gl_stat) (const char *__restrict, void *__restrict);
-#endif
- } glob_t;
-
-#ifdef __USE_LARGEFILE64
-# ifdef __USE_GNU
-struct stat64;
-# endif
-typedef struct
- {
- __size_t gl_pathc;
- char **gl_pathv;
- __size_t gl_offs;
- int gl_flags;
-
- /* If the GLOB_ALTDIRFUNC flag is set, the following functions
- are used instead of the normal file access functions. */
- void (*gl_closedir) (void *);
-# ifdef __USE_GNU
- struct dirent64 *(*gl_readdir) (void *);
-# else
- void *(*gl_readdir) (void *);
-# endif
- void *(*gl_opendir) (__const char *);
-# ifdef __USE_GNU
- int (*gl_lstat) (__const char *__restrict, struct stat64 *__restrict);
- int (*gl_stat) (__const char *__restrict, struct stat64 *__restrict);
-# else
- int (*gl_lstat) (__const char *__restrict, void *__restrict);
- int (*gl_stat) (__const char *__restrict, void *__restrict);
-# endif
- } glob64_t;
-#endif
-
-int glob (const char * __pattern, int __flags,
- int (*__errfunc) (const char *, int),
- glob_t * __pglob);
-void globfree(glob_t *__pglog);
-
-#endif /* !__KERNEL__ */
-
-/*
- * module routines
- */
-
-static inline void __module_get(struct module *module)
-{
-}
-
-static inline int try_module_get(struct module *module)
-{
- return 1;
-}
-
-static inline void module_put(struct module *module)
-{
-}
-
-/*
- * sigset_t routines
- */
-
-#define sigaddset(what,sig) (*(what) |= (1<<(sig)), 0)
-#define sigdelset(what,sig) (*(what) &= ~(1<<(sig)), 0)
-#define sigemptyset(what) (*(what) = 0, 0)
-#define sigfillset(what) (*(what) = ~(0), 0)
-#define sigismember(what,sig) (((*(what)) & (1<<(sig))) != 0)
-
-static __inline int
-sigprocmask(int sig, sigset_t *w1, sigset_t *w2) {
- return 0;
-}
-static __inline int
-sigpending(sigset_t *what) {
- return 0;
-}
-
-/*
- * common inode flags (user & kernel)
- */
-
-#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
-#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
-#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
-#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
-#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
-#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
-
-#define S_IRWXU 00700
-#define S_IRUSR 00400
-#define S_IWUSR 00200
-#define S_IXUSR 00100
-
-#define S_IRWXG 00070
-#define S_IRGRP 00040
-#define S_IWGRP 00020
-#define S_IXGRP 00010
-
-#define S_IRWXO 00007
-#define S_IROTH 00004
-#define S_IWOTH 00002
-#define S_IXOTH 00001
-
-#define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO)
-#define S_IALLUGO (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
-#define S_IRUGO (S_IRUSR|S_IRGRP|S_IROTH)
-#define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH)
-#define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH)
-
-
-/*
- * linux ioctl coding definitions
- */
-
-#define _IOC_NRBITS 8
-#define _IOC_TYPEBITS 8
-#define _IOC_SIZEBITS 14
-#define _IOC_DIRBITS 2
-
-#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT 0
-#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS)
-
-/*
- * Direction bits.
- */
-#define _IOC_NONE 0U
-#define _IOC_WRITE 1U
-#define _IOC_READ 2U
-
-#define _IOC(dir,type,nr,size) \
- (((dir) << _IOC_DIRSHIFT) | \
- ((type) << _IOC_TYPESHIFT) | \
- ((nr) << _IOC_NRSHIFT) | \
- ((size) << _IOC_SIZESHIFT))
-
-/* used to create numbers */
-#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
-#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
-#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
-#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-
-/* used to decode ioctl numbers.. */
-#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
-#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* i/o vector sgructure ... */
-struct iovec {
- void *iov_base;
- size_t iov_len;
-};
-
-/* idr support routines */
-struct idr_context *cfs_idr_init();
-int cfs_idr_remove(struct idr_context *idp, int id);
-int cfs_idr_get_new(struct idr_context *idp, void *ptr);
-int cfs_idr_get_new_above(struct idr_context *idp, void *ptr, int starting_id);
-void *cfs_idr_find(struct idr_context *idp, int id);
-void cfs_idr_exit(struct idr_context *idp);
-
-/* runtime time routines for both kenrel and user mode */
-extern int cfs_isalpha(int);
-extern int cfs_isspace(int);
-extern int cfs_isupper(int);
-extern int cfs_isdigit(int);
-extern int cfs_isxdigit(int);
-
-#define ULONG_LONG_MAX ((__u64)(0xFFFFFFFFFFFFFFFF))
-/*
- * Convert a string to an unsigned long long integer.
- *
- * Ignores `locale' stuff. Assumes that the upper and lower case
- * alphabets and digits are each contiguous.
- */
-__u64 strtoull(char *nptr, char **endptr,int base);
-
-/*
- * getopt routines
- */
-
-/* For communication from `getopt' to the caller.
- When `getopt' finds an option that takes an argument,
- the argument value is returned here.
- Also, when `ordering' is RETURN_IN_ORDER,
- each non-option ARGV-element is returned here. */
-
-extern char *optarg;
-
-/* Index in ARGV of the next element to be scanned.
- This is used for communication to and from the caller
- and for communication between successive calls to `getopt'.
-
- On entry to `getopt', zero means this is the first call; initialize.
-
- When `getopt' returns -1, this is the index of the first of the
- non-option elements that the caller should itself scan.
-
- Otherwise, `optind' communicates from one call to the next
- how much of ARGV has been scanned so far. */
-
-extern int optind;
-
-/* Callers store zero here to inhibit the error message `getopt' prints
- for unrecognized options. */
-
-extern int opterr;
-
-/* Set to an option character which was unrecognized. */
-
-extern int optopt;
-
-
-struct option
-{
- const char *name;
- /* has_arg can't be an enum because some compilers complain about
- type mismatches in all the code that assumes it is an int. */
- int has_arg;
- int *flag;
- int val;
-};
-
-/* Names for the values of the `has_arg' field of `struct option'. */
-# define no_argument 0
-# define required_argument 1
-# define optional_argument 2
-
-extern int getopt(int ___argc, char *const *___argv, const char *__shortopts);
-extern int getopt_long (int ___argc, char *const *___argv,
- const char *__shortopts,
- const struct option *__longopts, int *__longind);
-extern int getopt_long_only (int ___argc, char *const *___argv,
- const char *__shortopts,
- const struct option *__longopts, int *__longind);
-
-extern char *strcasestr (const char *phaystack, const char *pneedle);
-
-/*
- * global environment runtime routine
- */
-
-static __inline char * __cdecl cfs_getenv(const char *ENV) {return NULL;}
-static __inline void __cdecl set_getenv(const char *ENV, const char *value, int overwrite) {}
-
-int setenv(const char *envname, const char *envval, int overwrite);
-
-typedef struct utsname {
- char sysname[64];
- char nodename[64];
- char release[128];
- char version[128];
- char machine[64];
-};
-
-int uname(struct utsname *uts);
-
-#endif
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#ifndef __LIBCFS_WINNT_TCPIP_H__
-#define __LIBCFS_WINNT_TCPIP_H__
-
-#ifndef __LIBCFS_LIBCFS_H__
-#error Do not #include this file directly. #include <libcfs/libcfs.h> instead
-#endif
-
-
-#ifdef __KERNEL__
-
-//
-// ks definitions
-//
-
-// iovec is defined in libcfs: winnt_prim.h
-// lnetkiov_t is defined in lnet/types.h
-
-typedef struct socket ks_tconn_t, cfs_socket_t;
-
-// completion notification callback routine
-
-typedef VOID (*ks_schedule_cb)(struct socket*, int);
-
-#define SOCK_TEST_NOSPACE(s) (1)
-
-//
-// tdinal definitions
-//
-
-
-#if DBG
-#define KsPrint(X) KsPrintf X
-#else
-#define KsPrint(X)
-#endif
-
-
-//
-// Socket Addresses Related ...
-//
-
-#define INADDR_ANY (ULONG)0x00000000
-#define INADDR_LOOPBACK (ULONG)0x7f000001
-#define INADDR_BROADCAST (ULONG)0xffffffff
-#define INADDR_NONE (ULONG)0xffffffff
-
-/*
- * TCP / IP options
- */
-
-#define SOL_TCP 6
-#define SOL_UD 17
-
-
-#define TL_INSTANCE 0
-
-#define TCP_SOCKET_NODELAY 1 // disabling "Nagle"
-#define TCP_SOCKET_KEEPALIVE 2
-#define TCP_SOCKET_OOBINLINE 3
-#define TCP_SOCKET_BSDURGENT 4
-#define TCP_SOCKET_ATMARK 5
-#define TCP_SOCKET_WINDOW 6
-
-
-/* Flags we can use with send/ and recv.
- Added those for 1003.1g not all are supported yet
- */
-
-#define MSG_OOB 1
-#define MSG_PEEK 2
-#define MSG_DONTROUTE 4
-#define MSG_TRYHARD 4 /* Synonym for MSG_DONTROUTE for DECnet */
-#define MSG_CTRUNC 8
-#define MSG_PROBE 0x10 /* Do not send. Only probe path f.e. for MTU */
-#define MSG_TRUNC 0x20
-#define MSG_DONTWAIT 0x40 /* Nonblocking io */
-#define MSG_EOR 0x80 /* End of record */
-#define MSG_WAITALL 0x100 /* Wait for a full request */
-#define MSG_FIN 0x200
-#define MSG_SYN 0x400
-#define MSG_CONFIRM 0x800 /* Confirm path validity */
-#define MSG_RST 0x1000
-#define MSG_ERRQUEUE 0x2000 /* Fetch message from error queue */
-#define MSG_NOSIGNAL 0x4000 /* Do not generate SIGPIPE */
-#define MSG_MORE 0x8000 /* Sender will send more */
-
-#define MSG_EOF MSG_FIN
-
-
-//
-// Maximum TRANSPORT_ADDRESS Length
-//
-// it must >= FIELD_OFFSET(TRANSPORT_ADDRESS, Address->Address)
-// + TDI_ADDRESS_LENGTH_IP
-//
-// I define it a little large and 16 bytes aligned to avoid possible overflow.
-//
-
-#define MAX_ADDRESS_LENGTH (0x30)
-
-
-//
-// Maximum Listers Children Sockets
-//
-
-#define MAX_CHILD_LISTENERS (4)
-
-//
-// Maximum EA Information Length
-//
-
-#define EA_MAX_LENGTH ( sizeof(FILE_FULL_EA_INFORMATION) - 1 + \
- TDI_TRANSPORT_ADDRESS_LENGTH + 1 + \
- MAX_ADDRESS_LENGTH )
-
-
-#define UDP_DEVICE_NAME L"\\Device\\Udp"
-#define TCP_DEVICE_NAME L"\\Device\\Tcp"
-
-
-/*
- * TSDU definitions
- */
-
-#define TDINAL_TSDU_DEFAULT_SIZE (0x10000)
-
-#define KS_TSDU_MAGIC 'KSTD'
-
-#define KS_TSDU_ATTACHED 0x00000001 // Attached to the socket receive tsdu list
-
-typedef struct _KS_TSDU {
-
- ULONG Magic; /* magic */
- ULONG Flags; /* flags */
-
- struct list_head Link; /* link list */
-
- ULONG TotalLength; /* total size of KS_TSDU */
- ULONG StartOffset; /* offset of the first Tsdu unit */
- ULONG LastOffset; /* end offset of the last Tsdu unit */
-
-/*
- union {
- KS_TSDU_DAT[];
- KS_TSDU_BUF[];
- KS_TSDU_MDL[];
- }
-*/
-
-} KS_TSDU, *PKS_TSDU;
-
-#define TSDU_TYPE_BUF ((USHORT)0x5401)
-#define TSDU_TYPE_DAT ((USHORT)0x5402)
-#define TSDU_TYPE_MDL ((USHORT)0x5403)
-
-#define KS_TSDU_COMM_PARTIAL 0x0001
-
-typedef struct _KS_TSDU_BUF {
-
- USHORT TsduType;
- USHORT TsduFlags;
-
- ULONG DataLength;
- ULONG StartOffset;
-
- PVOID UserBuffer;
- PMDL Mdl; /* mdl */
-} KS_TSDU_BUF, *PKS_TSDU_BUF;
-
-typedef struct _KS_TSDU_DAT {
-
- USHORT TsduType;
- USHORT TsduFlags;
-
- ULONG DataLength;
- ULONG StartOffset;
-
- ULONG TotalLength;
- PMDL Mdl; /* mdl */
-
- UCHAR Data[0];
-
-} KS_TSDU_DAT, *PKS_TSDU_DAT;
-
-#define KS_QWORD_ALIGN(x) (((x) + 0x07) & 0xFFFFFFF8)
-#define KS_TSDU_STRU_SIZE(Len) (KS_QWORD_ALIGN((Len) + FIELD_OFFSET(KS_TSDU_DAT, Data[0])))
-
-typedef struct _KS_TSDU_MDL {
- USHORT TsduType; /* TSDU_TYPE_MDL */
- USHORT TsduFlags; /* */
-
- ULONG DataLength; /* total valid data length */
- ULONG BaseOffset; /* payload offset in Tsdu */
- ULONG StartOffset; /* offset in payload */
-
- PVOID Descriptor; /* tdi descriptor for receiving */
- PMDL Mdl;
-} KS_TSDU_MDL, *PKS_TSDU_MDL;
-
-typedef struct ks_engine_mgr {
- spinlock_t lock;
- int stop;
- event_t exit;
- event_t start;
- struct list_head list;
-} ks_engine_mgr_t;
-
-typedef struct ks_engine_slot {
- ks_tconn_t *tconn;
- void *tsdumgr;
- struct list_head link;
- int queued;
- ks_engine_mgr_t *emgr;
-} ks_engine_slot_t;
-
-typedef struct _KS_TSDUMGR {
- struct list_head TsduList;
- ULONG NumOfTsdu;
- ULONG TotalBytes;
- KEVENT Event;
- spinlock_t Lock;
- ks_engine_slot_t Slot;
- ULONG Payload;
- int Busy:1;
- int OOB:1;
-} KS_TSDUMGR, *PKS_TSDUMGR;
-
-#define ks_lock_tsdumgr(mgr) spin_lock(&((mgr)->Lock))
-#define ks_unlock_tsdumgr(mgr) spin_unlock(&((mgr)->Lock))
-
-typedef struct _KS_CHAIN {
- KS_TSDUMGR Normal; /* normal queue */
- KS_TSDUMGR Expedited; /* OOB/expedited queue */
-} KS_CHAIN, *PKS_CHAIN;
-
-
-#define KS_CAN_SCHED(TM) ((TM)->TotalBytes >= ((TM)->Payload >> 2))
-
-//
-// Handler Settings Indictor
-//
-
-#define TDI_EVENT_MAXIMUM_HANDLER (TDI_EVENT_ERROR_EX + 1)
-
-
-typedef struct _KS_EVENT_HANDLERS {
- BOOLEAN IsActive[TDI_EVENT_MAXIMUM_HANDLER];
- PVOID Handler [TDI_EVENT_MAXIMUM_HANDLER];
-} KS_EVENT_HANDLERS, *PKS_EVENT_HANDLERS;
-
-#define SetEventHandler(ha, ht, hr) do { \
- ha.IsActive[ht] = TRUE; \
- ha.Handler[ht] = (PVOID) (hr); \
- } while(0)
-
-//
-// KSock Internal Structures
-//
-
-typedef struct _KS_ADDRESS {
-
- union {
- TRANSPORT_ADDRESS Tdi;
- UCHAR Pading[MAX_ADDRESS_LENGTH];
- };
-
- HANDLE Handle;
- PFILE_OBJECT FileObject;
-
-} KS_ADDRESS, *PKS_ADDRESS;
-
-//
-// Structures for Disconnect Workitem
-//
-
-typedef struct _KS_DISCONNECT_WORKITEM {
-
- WORK_QUEUE_ITEM WorkItem; // Workitem to perform disconnection
- ks_tconn_t * tconn; // tdi connecton
- ULONG Flags; // connection broken/discnnection flags
- KEVENT Event; // sync event
-
-} KS_DISCONNECT_WORKITEM, *PKS_DISCONNECT_WORKITEM;
-
-
-typedef struct _KS_CONNECTION {
-
- HANDLE Handle; // Handle of the tdi connection
- PFILE_OBJECT FileObject; // FileObject if the conn object
-
- PTRANSPORT_ADDRESS Remote; // the ConnectionInfo of this connection
- PTDI_CONNECTION_INFORMATION ConnectionInfo;
-
- ULONG nagle; // Tcp options
-
-} KS_CONNECTION, *PKS_CONNECTION;
-
-
-//
-// type definitions
-//
-
-typedef MDL ks_mdl_t;
-typedef UNICODE_STRING ks_unicode_name_t;
-typedef WORK_QUEUE_ITEM ks_workitem_t;
-
-
-typedef KS_CHAIN ks_chain_t;
-typedef KS_ADDRESS ks_tdi_addr_t;
-typedef KS_CONNECTION ks_tconn_info_t;
-typedef KS_DISCONNECT_WORKITEM ks_disconnect_t;
-
-
-//
-// Structures for transmission done Workitem
-//
-
-typedef struct ks_backlogs {
- struct list_head list; /* list to link the backlog connections */
- int num; /* number of backlogs in the list */
-} ks_backlogs_t;
-
-
-typedef struct ks_daemon {
- ks_tconn_t *tconn; /* the listener connection object */
- unsigned short nbacklogs; /* number of listening backlog conns */
- unsigned short port; /* listening port number */
- int shutdown; /* daemon threads is to exit */
- struct list_head list; /* to be attached into ks_nal_data_t */
-
-} ks_daemon_t;
-
-typedef enum {
-
- kstt_sender = 0, // normal sending connection type, it's active connection, while
- // child tconn is for passive connection.
-
- kstt_listener, // listener daemon type, it just acts as a daemon, and it does
- // not have real connection. It manages children tcons to accept
- // or refuse the connecting request from remote peers.
-
- kstt_child, // accepted child connection type, it's parent must be Listener
-
- kstt_lasttype
-
-} ks_tconn_type_t;
-
-typedef enum {
-
- ksts_uninited = 0, // tconn is just allocated (zero values), not initialized yet
-
- ksts_inited, // tconn structure initialized: so it now can be identified as
- // a sender, listener or a child
-
- ksts_bind, // tconn is bound: the local address object (ip/port) is created.
- // after being bound, we must call ksocknal_put_tconn to release
- // the tconn objects, it's not safe just to free the memory of tconn.
-
- ksts_associated, // the connection object is created and associated with the address
- // object. so it's ready for connection. only for child and sender.
-
- ksts_connecting, // only used by child tconn: in the ConnectEvent handler routine,
- // it indicts the child tconn is busy to be connected to the peer.
-
- ksts_connected, // the connection is built already: for sender and child
-
- ksts_listening, // listener daemon is working, only for listener tconn
-
- ksts_disconnected, // disconnected by user
- ksts_aborted, // un-exptected broken status
-
- ksts_last // total number of tconn statuses
-
-} ks_tconn_state_t;
-
-#define KS_TCONN_MAGIC 'KSTM'
-
-#define KS_TCONN_HANDLERS_SET 0x00000001 // Conection handlers are set.
-#define KS_TCONN_DISCONNECT_BUSY 0x00010000 // Disconnect Workitem is queued ...
-#define KS_TCONN_DESTROY_BUSY 0x00020000 // Destory Workitem is queued ...
-
-#define KS_TCONN_DAEMON_STARTED 0x00100000 // indict the daemon is started,
- // only valid for listener
-struct socket {
-
- ulong kstc_magic; /* Magic & Flags */
- ulong kstc_flags;
-
- spinlock_t kstc_lock; /* serialise lock*/
- void * kstc_conn; /* ks_conn_t */
-
- ks_tconn_type_t kstc_type; /* tdi connection Type */
- ks_tconn_state_t kstc_state; /* tdi connection state flag */
-
- ks_unicode_name_t kstc_dev; /* tcp transport device name */
-
- ks_tdi_addr_t kstc_addr; /* local address handlers / Objects */
-
- atomic_t kstc_refcount; /* reference count of ks_tconn_t */
-
- struct list_head kstc_list; /* linked to global ksocknal_data */
-
- union {
-
- struct {
- int nbacklog; /* total number of backlog tdi connections */
- ks_backlogs_t kstc_listening; /* listeing backlog child connections */
- ks_backlogs_t kstc_accepted; /* connected backlog child connections */
- event_t kstc_accept_event; /* Signaled by AcceptedHander,
- ksocknal_wait_accpeted_conns waits on */
- event_t kstc_destroy_event; /* Signaled when accepted child is released */
- } listener;
-
- struct {
- ks_tconn_info_t kstc_info; /* Connection Info if Connected */
- ks_chain_t kstc_recv; /* tsdu engine for data receiving */
- ks_chain_t kstc_send; /* tsdu engine for data sending */
-
- int kstc_queued; /* Attached to Parent->ChildList ... */
- int kstc_queueno; /* 0: Attached to Listening list
- 1: Attached to Accepted list */
-
- int kstc_busy; /* referred by ConnectEventCallback ? */
- int kstc_accepted; /* the connection is built ready ? */
-
- struct list_head kstc_link; /* linked to parent tdi connection */
- ks_tconn_t *kstc_parent; /* pointers to it's listener parent */
- } child;
-
- struct {
- ks_tconn_info_t kstc_info; /* Connection Info if Connected */
- ks_chain_t kstc_recv; /* tsdu engine for data receiving */
- ks_chain_t kstc_send; /* tsdu engine for data sending */
- } sender;
- };
-
- ulong kstc_snd_wnd; /* Sending window size */
- ulong kstc_rcv_wnd; /* Recving window size */
-
- ks_workitem_t kstc_destroy; /* tconn destruction workitem */
- ks_disconnect_t kstc_disconnect; /* connection disconnect workitem */
-
- ks_schedule_cb kstc_sched_cb; /* notification callback routine of completion */
-};
-
-static inline int
-libcfs_sock_error(struct socket *sock)
-{
- return (sock->kstc_state >= ksts_disconnected) ? ECONNRESET : 0;
-}
-
-
-static inline int
-libcfs_sock_wmem_queued(struct socket *sock)
-{
- return 0;
-}
-
-#define TDINAL_WINDOW_DEFAULT_SIZE (0x100000)
-#define TDINAL_MAX_TSDU_QUEUE_SIZE (0x200000)
-
-struct _KS_UDP_COMPLETION_CONTEXT;
-struct _KS_TCP_COMPLETION_CONTEXT;
-
-
-typedef
-NTSTATUS
-(*PKS_UDP_COMPLETION_ROUTINE) (
- IN PIRP Irp,
- IN struct _KS_UDP_COMPLETION_CONTEXT
- *UdpContext
- );
-
-
-typedef
-NTSTATUS
-(*PKS_TCP_COMPLETION_ROUTINE) (
- IN PIRP Irp,
- IN struct _KS_TCP_COMPLETION_CONTEXT
- *TcpContext
- );
-
-//
-// Udp Irp Completion Context
-//
-
-typedef struct _KS_UDP_COMPLETION_CONTEXT {
-
- PKEVENT Event;
- union {
- PFILE_OBJECT AddressObject;
- ks_tconn_t * tconn;
- };
-
- PKS_UDP_COMPLETION_ROUTINE CompletionRoutine;
- PVOID CompletionContext;
-
-} KS_UDP_COMPLETION_CONTEXT, *PKS_UDP_COMPLETION_CONTEXT;
-
-
-//
-// Tcp Irp Completion Context (used by tcp data recv/send)
-//
-
-#define KS_TCP_CONTEXT_MAGIC 'CCTK'
-
-typedef struct _KS_TCP_COMPLETION_CONTEXT {
- PKEVENT Event; // Event to be waited on by Irp caller ...
- ks_tconn_t * tconn; // the tdi connection
- PKS_TCP_COMPLETION_ROUTINE CompletionRoutine;
- PVOID CompletionContext;
- PKS_TSDUMGR TsduMgr; // Tsdu buffer manager
- ULONG Length; // Payload length in KsTsdu queue
- PCHAR Buffer; // User allocated buffer
- ULONG Magic; // Magic key
-} KS_TCP_COMPLETION_CONTEXT, *PKS_TCP_COMPLETION_CONTEXT;
-
-typedef KS_TCP_COMPLETION_CONTEXT ks_tdi_tx_t, ks_tdi_rx_t;
-
-
-/*
- * tdi extensions
- */
-
-#define IOCTL_TCP_QUERY_INFORMATION_EX \
- CTL_CODE(FILE_DEVICE_NETWORK, 0, METHOD_NEITHER, FILE_ANY_ACCESS)
-#define IOCTL_TCP_SET_INFORMATION_EX \
- CTL_CODE(FILE_DEVICE_NETWORK, 1, METHOD_BUFFERED, FILE_WRITE_ACCESS)
-
-
-#define TcpBuildSetInformationEx(Irp, DevObj, FileObj, CompRoutine, Contxt, Buffer, BufferLen)\
- { \
- PIO_STACK_LOCATION _IRPSP; \
- if ( CompRoutine != NULL) { \
- IoSetCompletionRoutine( Irp, CompRoutine, Contxt, TRUE, TRUE, TRUE);\
- } else { \
- IoSetCompletionRoutine( Irp, NULL, NULL, FALSE, FALSE, FALSE); \
- } \
- _IRPSP = IoGetNextIrpStackLocation (Irp); \
- _IRPSP->MajorFunction = IRP_MJ_DEVICE_CONTROL; \
- _IRPSP->DeviceObject = DevObj; \
- _IRPSP->FileObject = FileObj; \
- _IRPSP->Parameters.DeviceIoControl.OutputBufferLength = 0; \
- _IRPSP->Parameters.DeviceIoControl.InputBufferLength = BufferLen; \
- _IRPSP->Parameters.DeviceIoControl.IoControlCode = IOCTL_TCP_SET_INFORMATION_EX; \
- Irp->AssociatedIrp.SystemBuffer = Buffer; \
- }
-
-
-#define TcpBuildQueryInformationEx(Irp, DevObj, FileObj, CompRoutine, Contxt, InBuffer, InLength, OutBuffer, OutLength)\
- { \
- PIO_STACK_LOCATION _IRPSP; \
- if ( CompRoutine != NULL) { \
- IoSetCompletionRoutine( Irp, CompRoutine, Contxt, TRUE, TRUE, TRUE);\
- } else { \
- IoSetCompletionRoutine( Irp, NULL, NULL, FALSE, FALSE, FALSE); \
- } \
- _IRPSP = IoGetNextIrpStackLocation (Irp); \
- _IRPSP->MajorFunction = IRP_MJ_DEVICE_CONTROL; \
- _IRPSP->DeviceObject = DevObj; \
- _IRPSP->FileObject = FileObj; \
- _IRPSP->Parameters.DeviceIoControl.OutputBufferLength = OutLength; \
- _IRPSP->Parameters.DeviceIoControl.InputBufferLength = InLength; \
- _IRPSP->Parameters.DeviceIoControl.IoControlCode = IOCTL_TCP_QUERY_INFORMATION_EX; \
- _IRPSP->Parameters.DeviceIoControl.Type3InputBuffer = InBuffer; \
- Irp->UserBuffer = OutBuffer; \
- }
-
-typedef struct ks_addr_slot {
- LIST_ENTRY link;
- int up;
- char iface[40];
- __u32 ip_addr;
- __u32 netmask;
- UNICODE_STRING devname;
- WCHAR buffer[1];
-} ks_addr_slot_t;
-
-typedef struct {
- /*
- * Tdi client information
- */
-
- UNICODE_STRING ksnd_client_name; /* tdi client module name */
- HANDLE ksnd_pnp_handle; /* the handle for pnp changes */
-
- spinlock_t ksnd_addrs_lock; /* serialize ip address list */
- LIST_ENTRY ksnd_addrs_list; /* list of the ip addresses */
- int ksnd_naddrs; /* number of the ip addresses */
-
- /*
- * Tdilnd internal defintions
- */
- int ksnd_init; /* initialisation state */
-
- TDI_PROVIDER_INFO ksnd_provider; /* tdi tcp/ip provider's information */
-
- spinlock_t ksnd_tconn_lock; /* tdi connections access lock*/
-
- int ksnd_ntconns; /* number of tconns in list */
- struct list_head ksnd_tconns; /* tdi connections list */
- struct kmem_cache *ksnd_tconn_slab; /* ks_tconn_t allocation slabs*/
- event_t ksnd_tconn_exit; /* event signal by last tconn */
-
- spinlock_t ksnd_tsdu_lock; /* tsdu access serialise */
-
- int ksnd_ntsdus; /* number of tsdu buffers allocated */
- ulong ksnd_tsdu_size; /* the size of a signel tsdu buffer */
- struct kmem_cache *ksnd_tsdu_slab; /* slab cache for tsdu buffer allocation */
-
- int ksnd_nfreetsdus; /* number of tsdu buffers in the freed list */
- struct list_head ksnd_freetsdus; /* List of the freed Tsdu buffer. */
-
- int ksnd_engine_nums; /* number of tcp sending engine threads */
- ks_engine_mgr_t *ksnd_engine_mgr; /* tcp sending engine structure */
-} ks_tdi_data_t;
-
-int
-ks_init_tdi_data();
-
-void
-ks_fini_tdi_data();
-
-
-int
-ks_query_local_ipaddr(
- ks_tconn_t * tconn
- );
-
-void
-ks_get_tconn(
- ks_tconn_t * tconn
- );
-
-void
-ks_put_tconn(
- ks_tconn_t * tconn
- );
-
-void
-ks_abort_tconn(
- ks_tconn_t * tconn
- );
-int
-ks_disconnect_tconn(
- ks_tconn_t * tconn,
- ulong flags
- );
-
-void
-ks_destroy_tconn(
- ks_tconn_t * tconn
- );
-
-NTSTATUS
-KsLockUserBuffer (
- IN PVOID UserBuffer,
- IN BOOLEAN bPaged,
- IN ULONG Length,
- IN LOCK_OPERATION Operation,
- OUT PMDL * pMdl
- );
-
-VOID
-KsReleaseMdl (IN PMDL Mdl,
- IN int Paged );
-
-void
-KsQueueTdiEngine(ks_tconn_t * tconn, PKS_TSDUMGR);
-
-void
-KsRemoveTdiEngine(PKS_TSDUMGR);
-
-NTSTATUS
-ks_set_tcp_option (
- ks_tconn_t * tconn,
- ULONG ID,
- PVOID OptionValue,
- ULONG Length
- );
-
-int
-ks_get_tcp_option (
- ks_tconn_t * tconn,
- ULONG ID,
- PVOID OptionValue,
- PULONG Length
- );
-
-#endif /* __KERNEL__ */
-#endif /* __LIBCFS_WINNT_TCPIP_H__ */
-
-/*
- * Local variables:
- * c-indentation-style: "K&R"
- * c-basic-offset: 8
- * tab-width: 8
- * fill-column: 80
- * scroll-step: 1
- * End:
- */
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * libcfs/include/libcfs/winnt/winnt-time.h
- *
- * Implementation of portable time API for Winnt (kernel and user-level).
- */
-
-#ifndef __LIBCFS_WINNT_LINUX_TIME_H__
-#define __LIBCFS_WINNT_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
- *
- */
-
-struct timeval {
- time_t tv_sec; /* seconds */
- suseconds_t tv_usec; /* microseconds */
-};
-
-typedef time_t cfs_time_t;
-typedef time_t cfs_duration_t;
-
-#ifdef __KERNEL__
-
-#include <libcfs/winnt/portals_compat25.h>
-
-#define HZ (100)
-
-struct timespec {
- __u32 tv_sec;
- __u32 tv_nsec;
-};
-typedef struct timeval cfs_fs_time_t;
-
-
-#define ONE_BILLION ((u_int64_t)1000000000)
-#define ONE_MILLION ((u_int64_t) 1000000)
-
-/*
- * Generic kernel stuff
- */
-
-#define jiffies (ULONG_PTR)JIFFIES()
-#define cfs_jiffies (ULONG_PTR)JIFFIES()
-
-static inline void do_gettimeofday(struct timeval *tv)
-{
- LARGE_INTEGER Time;
-
- KeQuerySystemTime(&Time);
-
- tv->tv_sec = (time_t) (Time.QuadPart / 10000000);
- tv->tv_usec = (suseconds_t) (Time.QuadPart % 10000000) / 10;
-}
-
-static inline LONGLONG JIFFIES()
-{
- LARGE_INTEGER Tick;
- LARGE_INTEGER Elapse;
-
- KeQueryTickCount(&Tick);
-
- Elapse.QuadPart = Tick.QuadPart * KeQueryTimeIncrement();
- Elapse.QuadPart /= (10000000 / HZ);
-
- return Elapse.QuadPart;
-}
-
-static inline cfs_time_t cfs_time_current(void)
-{
- return (cfs_time_t)JIFFIES();
-}
-
-static inline time_t cfs_time_current_sec(void)
-{
- return (time_t)(JIFFIES() / HZ);
-}
-
-#define cfs_time_before(t1, t2) (((signed)(t1) - (signed)(t2)) < 0)
-#define cfs_time_beforeq(t1, t2) (((signed)(t1) - (signed)(t2)) <= 0)
-
-static inline void cfs_fs_time_current(cfs_fs_time_t *t)
-{
- ULONG Linux;
- LARGE_INTEGER Sys;
-
- KeQuerySystemTime(&Sys);
-
- RtlTimeToSecondsSince1970(&Sys, &Linux);
-
- t->tv_sec = Linux;
- t->tv_usec = (Sys.LowPart % 10000000) / 10;
-}
-
-static inline unsigned long get_seconds(void)
-{
- cfs_fs_time_t t;
- cfs_fs_time_current(&t);
- return (unsigned long) t.tv_sec;
-}
-
-static inline cfs_time_t cfs_fs_time_sec(cfs_fs_time_t *t)
-{
- return (cfs_time_t)t->tv_sec;
-}
-
-static inline unsigned long __cfs_fs_time_flat(cfs_fs_time_t *t)
-{
- return (unsigned long)(t->tv_sec) * ONE_MILLION + t->tv_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));
-}
-
-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));
-}
-
-static inline cfs_duration_t cfs_time_seconds(cfs_duration_t seconds)
-{
- return (cfs_duration_t)(seconds * HZ);
-}
-
-static inline time_t cfs_duration_sec(cfs_duration_t d)
-{
- return (time_t)(d / HZ);
-}
-
-static inline void cfs_duration_usec(cfs_duration_t d, struct timeval *s)
-{
- s->tv_sec = (__u32)(d / HZ);
- s->tv_usec = (__u32)((d - (cfs_duration_t)s->tv_sec * HZ) *
- ONE_MILLION / HZ);
-}
-
-static inline void cfs_duration_nsec(cfs_duration_t d, struct timespec *s)
-{
- s->tv_sec = (__u32) (d / HZ);
- s->tv_nsec = (__u32)((d - (cfs_duration_t)s->tv_sec * HZ) *
- ONE_BILLION / HZ);
-}
-
-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 = (__u32) t->tv_sec;
- s->tv_nsec = (__u32) t->tv_usec * 1000;
-}
-
-
-#define cfs_time_current_64 JIFFIES
-
-static inline __u64 cfs_time_add_64(__u64 t, __u64 d)
-{
- return t + d;
-}
-
-static inline __u64 cfs_time_shift_64(cfs_duration_t 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;
-}
-
-/*
- * One jiffy
- */
-#define CFS_TICK (1)
-#define LTIME_S(t) *((__u64 *)&(t))
-
-#define CFS_TIME_T "%u"
-#define CFS_DURATION_T "%d"
-
-#else /* !__KERNEL__ */
-
-#include <time.h>
-#ifdef HAVE_LIBPTHREAD
-#include <pthread.h>
-#else
-struct timespec {
- unsigned long tv_sec;
- unsigned long tv_nsec;
-};
-#endif /* HAVE_LIBPTHREAD */
-
-#include "../user-time.h"
-
-/* liblustre. time(2) based implementation. */
-int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
-void sleep(int time);
-void do_gettimeofday(struct timeval *tv);
-int gettimeofday(struct timeval *tv, void * tz);
-
-#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:
- */
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * libcfs/include/libcfs/winnt/winnt-types.h
- *
- * Basic types definitions
- */
-
-#ifndef _WINNT_TYPE_H
-#define _WINNT_TYPE_H
-
-#ifdef __KERNEL__
-
-#include <ntifs.h>
-#include <basetsd.h>
-#include <windef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <tdi.h>
-#include <tdikrnl.h>
-#include <tdiinfo.h>
-
-#else
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <ntddk.h>
-#include <stdarg.h>
-#include <io.h>
-#include <time.h>
-#include <string.h>
-#include <assert.h>
-#endif
-
-
-#define __LITTLE_ENDIAN
-#define __user
-
-#define inline __inline
-#define __inline__ __inline
-
-typedef unsigned __int8 __u8;
-typedef signed __int8 __s8;
-
-typedef signed __int16 __s16;
-typedef unsigned __int16 __u16;
-
-typedef signed __int32 __s32;
-typedef unsigned __int32 __u32;
-
-typedef signed __int64 __s64;
-typedef unsigned __int64 __u64;
-
-typedef unsigned long ULONG;
-
-/* bsd */
-typedef unsigned char u_char;
-typedef unsigned short u_short;
-typedef unsigned int u_int;
-typedef unsigned long u_long;
-
-/* sysv */
-typedef unsigned char unchar;
-typedef unsigned short ushort;
-typedef unsigned int uint;
-typedef unsigned long ulong;
-
-#ifndef __BIT_TYPES_DEFINED__
-#define __BIT_TYPES_DEFINED__
-
-typedef __u8 u_int8_t;
-typedef __s8 int8_t;
-typedef __u16 u_int16_t;
-typedef __s16 int16_t;
-typedef __u32 u_int32_t;
-typedef __s32 int32_t;
-
-#define u8 __u8
-#define u16 __u16
-#define u32 __u32
-#define u64 __u64
-
-#endif /* !(__BIT_TYPES_DEFINED__) */
-
-typedef __u8 uint8_t;
-typedef __u16 uint16_t;
-typedef __u32 uint32_t;
-
-typedef __u64 uint64_t;
-typedef __u64 u_int64_t;
-typedef __s64 int64_t;
-
-typedef long ssize_t;
-
-typedef __u32 suseconds_t;
-
-typedef __u16 uid_t, gid_t;
-
-typedef __u16 mode_t;
-typedef __u16 umode_t;
-
-typedef __u32 sigset_t;
-
-typedef int64_t loff_t;
-typedef void * cfs_handle_t;
-typedef uint64_t cfs_cycles_t;
-
-#ifndef INVALID_HANDLE_VALUE
-#define INVALID_HANDLE_VALUE ((HANDLE)-1)
-#endif
-
-# define BITS_PER_LONG (32)
-
-#if defined(_WIN64)
-typedef __int64 long_ptr_t;
-typedef unsigned __int64 ulong_ptr_t;
-#else
-typedef long long_ptr_t;
-typedef unsigned long ulong_ptr_t;
-#endif
-
-#ifdef __KERNEL__ /* kernel */
-
-typedef __u32 off_t;
-
-typedef __u32 pid_t;
-typedef __u32 tid_t;
-
-typedef __u32 ino_t;
-
-#define dma_addr_t PVOID
-#define gfp_t __u32
-
-/*
- * Bytes order
- */
-
-//
-// Byte order swapping routines
-//
-
-#if 0 && NTDDI_VERSION < 0x06000000
-
-USHORT
-FASTCALL
-RtlUshortByteSwap(
- IN USHORT Source
- );
-
-ULONG
-FASTCALL
-RtlUlongByteSwap(
- IN ULONG Source
- );
-
-ULONGLONG
-FASTCALL
-RtlUlonglongByteSwap(
- IN ULONGLONG Source
- );
-#endif
-
-#else /* !__KERNEL__ */
-
-typedef int BOOL;
-
-#ifndef _WINDOWS_
-typedef __u8 BYTE;
-typedef __u16 WORD;
-typedef __u32 DWORD;
-#endif
-
-#define __WORDSIZE 32
-typedef long off_t;
-
-#endif /* __KERNEL__ */
-
-/*
- * Conastants suffix
- */
-
-#define ULL i64
-#define ull i64
-
-#define ___swab16(x) RtlUshortByteSwap(x)
-#define ___swab32(x) RtlUlongByteSwap(x)
-#define ___swab64(x) RtlUlonglongByteSwap(x)
-
-#define ___constant_swab16(x) \
- ((__u16)( \
- (((__u16)(x) & (__u16)0x00ffU) << 8) | \
- (((__u16)(x) & (__u16)0xff00U) >> 8) ))
-
-#define ___constant_swab32(x) \
- ((__u32)( \
- (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \
- (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \
- (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \
- (((__u32)(x) & (__u32)0xff000000UL) >> 24) ))
-
-#define ___constant_swab64(x) \
- ((__u64)( \
- (__u64)(((__u64)(x) & (__u64)0x00000000000000ffUi64) << 56) | \
- (__u64)(((__u64)(x) & (__u64)0x000000000000ff00Ui64) << 40) | \
- (__u64)(((__u64)(x) & (__u64)0x0000000000ff0000Ui64) << 24) | \
- (__u64)(((__u64)(x) & (__u64)0x00000000ff000000Ui64) << 8) | \
- (__u64)(((__u64)(x) & (__u64)0x000000ff00000000Ui64) >> 8) | \
- (__u64)(((__u64)(x) & (__u64)0x0000ff0000000000Ui64) >> 24) | \
- (__u64)(((__u64)(x) & (__u64)0x00ff000000000000Ui64) >> 40) | \
- (__u64)(((__u64)(x) & (__u64)0xff00000000000000Ui64) >> 56) ))
-
-
-#define __swab16(x) ___constant_swab16(x)
-#define __swab32(x) ___constant_swab32(x)
-#define __swab64(x) ___constant_swab64(x)
-
-#define __swab16s(x) do { *(x) = __swab16((USHORT)(*(x)));} while(0)
-#define __swab32s(x) do { *(x) = __swab32((ULONG)(*(x)));} while(0)
-#define __swab64s(x) do { *(x) = __swab64((ULONGLONG)(*(x)));} while(0)
-
-#define __constant_htonl(x) ___constant_swab32((x))
-#define __constant_ntohl(x) ___constant_swab32((x))
-#define __constant_htons(x) ___constant_swab16((x))
-#define __constant_ntohs(x) ___constant_swab16((x))
-#define __constant_cpu_to_le64(x) ((__u64)(x))
-#define __constant_le64_to_cpu(x) ((__u64)(x))
-#define __constant_cpu_to_le32(x) ((__u32)(x))
-#define __constant_le32_to_cpu(x) ((__u32)(x))
-#define __constant_cpu_to_le16(x) ((__u16)(x))
-#define __constant_le16_to_cpu(x) ((__u16)(x))
-#define __constant_cpu_to_be64(x) ___constant_swab64((x))
-#define __constant_be64_to_cpu(x) ___constant_swab64((x))
-#define __constant_cpu_to_be32(x) ___constant_swab32((x))
-#define __constant_be32_to_cpu(x) ___constant_swab32((x))
-#define __constant_cpu_to_be16(x) ___constant_swab16((x))
-#define __constant_be16_to_cpu(x) ___constant_swab16((x))
-#define __cpu_to_le64(x) ((__u64)(x))
-#define __le64_to_cpu(x) ((__u64)(x))
-#define __cpu_to_le32(x) ((__u32)(x))
-#define __le32_to_cpu(x) ((__u32)(x))
-#define __cpu_to_le16(x) ((__u16)(x))
-#define __le16_to_cpu(x) ((__u16)(x))
-#define __cpu_to_be64(x) __swab64((x))
-#define __be64_to_cpu(x) __swab64((x))
-#define __cpu_to_be32(x) __swab32((x))
-#define __be32_to_cpu(x) __swab32((x))
-#define __cpu_to_be16(x) __swab16((x))
-#define __be16_to_cpu(x) __swab16((x))
-#define __cpu_to_le64p(x) (*(__u64*)(x))
-#define __le64_to_cpup(x) (*(__u64*)(x))
-#define __cpu_to_le32p(x) (*(__u32*)(x))
-#define __le32_to_cpup(x) (*(__u32*)(x))
-#define __cpu_to_le16p(x) (*(__u16*)(x))
-#define __le16_to_cpup(x) (*(__u16*)(x))
-#define __cpu_to_be64p(x) __swab64p((x))
-#define __be64_to_cpup(x) __swab64p((x))
-#define __cpu_to_be32p(x) __swab32p((x))
-#define __be32_to_cpup(x) __swab32p((x))
-#define __cpu_to_be16p(x) __swab16p((x))
-#define __be16_to_cpup(x) __swab16p((x))
-#define __cpu_to_le64s(x) do {} while (0)
-#define __le64_to_cpus(x) do {} while (0)
-#define __cpu_to_le32s(x) do {} while (0)
-#define __le32_to_cpus(x) do {} while (0)
-#define __cpu_to_le16s(x) do {} while (0)
-#define __le16_to_cpus(x) do {} while (0)
-#define __cpu_to_be64s(x) __swab64s((x))
-#define __be64_to_cpus(x) __swab64s((x))
-#define __cpu_to_be32s(x) __swab32s((x))
-#define __be32_to_cpus(x) __swab32s((x))
-#define __cpu_to_be16s(x) __swab16s((x))
-#define __be16_to_cpus(x) __swab16s((x))
-
-#ifndef cpu_to_le64
-#define cpu_to_le64 __cpu_to_le64
-#define le64_to_cpu __le64_to_cpu
-#define cpu_to_le32 __cpu_to_le32
-#define le32_to_cpu __le32_to_cpu
-#define cpu_to_le16 __cpu_to_le16
-#define le16_to_cpu __le16_to_cpu
-#endif
-
-#define cpu_to_be64 __cpu_to_be64
-#define be64_to_cpu __be64_to_cpu
-#define cpu_to_be32 __cpu_to_be32
-#define be32_to_cpu __be32_to_cpu
-#define cpu_to_be16 __cpu_to_be16
-#define be16_to_cpu __be16_to_cpu
-#define cpu_to_le64p __cpu_to_le64p
-#define le64_to_cpup __le64_to_cpup
-#define cpu_to_le32p __cpu_to_le32p
-#define le32_to_cpup __le32_to_cpup
-#define cpu_to_le16p __cpu_to_le16p
-#define le16_to_cpup __le16_to_cpup
-#define cpu_to_be64p __cpu_to_be64p
-#define be64_to_cpup __be64_to_cpup
-#define cpu_to_be32p __cpu_to_be32p
-#define be32_to_cpup __be32_to_cpup
-#define cpu_to_be16p __cpu_to_be16p
-#define be16_to_cpup __be16_to_cpup
-#define cpu_to_le64s __cpu_to_le64s
-#define le64_to_cpus __le64_to_cpus
-#define cpu_to_le32s __cpu_to_le32s
-#define le32_to_cpus __le32_to_cpus
-#define cpu_to_le16s __cpu_to_le16s
-#define le16_to_cpus __le16_to_cpus
-#define cpu_to_be64s __cpu_to_be64s
-#define be64_to_cpus __be64_to_cpus
-#define cpu_to_be32s __cpu_to_be32s
-#define be32_to_cpus __be32_to_cpus
-#define cpu_to_be16s __cpu_to_be16s
-#define be16_to_cpus __be16_to_cpus
-
-
-//
-// Network to host byte swap functions
-//
-
-#define ntohl(x) ( ( ( ( x ) & 0x000000ff ) << 24 ) | \
- ( ( ( x ) & 0x0000ff00 ) << 8 ) | \
- ( ( ( x ) & 0x00ff0000 ) >> 8 ) | \
- ( ( ( x ) & 0xff000000 ) >> 24 ) )
-
-#define ntohs(x) ( ( ( ( x ) & 0xff00 ) >> 8 ) | \
- ( ( ( x ) & 0x00ff ) << 8 ) )
-
-
-#define htonl(x) ntohl(x)
-#define htons(x) ntohs(x)
-
-
-/*
- * array must be used for array not pointer
- */
-#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
-
-#endif /* _WINNT_TYPES_H */
-
-#ifndef _I386_ERRNO_H
-#define _I386_ERRNO_H
-
-#include <errno.h>
-
-#define EPERM 1 /* Operation not permitted */
-#define ENOENT 2 /* No such file or directory */
-#define ESRCH 3 /* No such process */
-#define EINTR 4 /* Interrupted system call */
-#define EIO 5 /* I/O error */
-#define ENXIO 6 /* No such device or address */
-#define E2BIG 7 /* Arg list too long */
-#define ENOEXEC 8 /* Exec format error */
-#define EBADF 9 /* Bad file number */
-#define ECHILD 10 /* No child processes */
-#define EAGAIN 11 /* Try again */
-#define ENOMEM 12 /* Out of memory */
-#define EACCES 13 /* Permission denied */
-#define EFAULT 14 /* Bad address */
-#define ENOTBLK 15 /* Block device required */
-#define EBUSY 16 /* Device or resource busy */
-#define EEXIST 17 /* File exists */
-#define EXDEV 18 /* Cross-device link */
-#define ENODEV 19 /* No such device */
-#define ENOTDIR 20 /* Not a directory */
-#define EISDIR 21 /* Is a directory */
-#define EINVAL 22 /* Invalid argument */
-#define ENFILE 23 /* File table overflow */
-#define EMFILE 24 /* Too many open files */
-#define ENOTTY 25 /* Not a typewriter */
-#define ETXTBSY 26 /* Text file busy */
-#define EFBIG 27 /* File too large */
-#define ENOSPC 28 /* No space left on device */
-#define ESPIPE 29 /* Illegal seek */
-#define EROFS 30 /* Read-only file system */
-#define EMLINK 31 /* Too many links */
-#define EPIPE 32 /* Broken pipe */
-#define EDOM 33 /* Math argument out of domain of func */
-#define ERANGE 34 /* Math result not representable */
-#define ELOOP 40 /* Too many symbolic links encountered */
-#define EWOULDBLOCK EAGAIN /* Operation would block */
-#define ENOMSG 42 /* No message of desired type */
-#define EIDRM 43 /* Identifier removed */
-#define ECHRNG 44 /* Channel number out of range */
-#define EL2NSYNC 45 /* Level 2 not synchronized */
-#define EL3HLT 46 /* Level 3 halted */
-#define EL3RST 47 /* Level 3 reset */
-#define ELNRNG 48 /* Link number out of range */
-#define EUNATCH 49 /* Protocol driver not attached */
-#define ENOCSI 50 /* No CSI structure available */
-#define EL2HLT 51 /* Level 2 halted */
-#define EBADE 52 /* Invalid exchange */
-#define EBADR 53 /* Invalid request descriptor */
-#define EXFULL 54 /* Exchange full */
-#define ENOANO 55 /* No anode */
-#define EBADRQC 56 /* Invalid request code */
-#define EBADSLT 57 /* Invalid slot */
-
-#define EDEADLOCK EDEADLK
-
-#define EBFONT 59 /* Bad font file format */
-#define ENOSTR 60 /* Device not a stream */
-#define ENODATA 61 /* No data available */
-#define ETIME 62 /* Timer expired */
-#define ENOSR 63 /* Out of streams resources */
-#define ENONET 64 /* Machine is not on the network */
-#define ENOPKG 65 /* Package not installed */
-#define EREMOTE 66 /* Object is remote */
-#define ENOLINK 67 /* Link has been severed */
-#define EADV 68 /* Advertise error */
-#define ESRMNT 69 /* Srmount error */
-#define ECOMM 70 /* Communication error on send */
-#define EPROTO 71 /* Protocol error */
-#define EMULTIHOP 72 /* Multihop attempted */
-#define EDOTDOT 73 /* RFS specific error */
-#define EBADMSG 74 /* Not a data message */
-#define EOVERFLOW 75 /* Value too large for defined data type */
-#define ENOTUNIQ 76 /* Name not unique on network */
-#define EBADFD 77 /* File descriptor in bad state */
-#define EREMCHG 78 /* Remote address changed */
-#define ELIBACC 79 /* Can not access a needed shared library */
-#define ELIBBAD 80 /* Accessing a corrupted shared library */
-#define ELIBSCN 81 /* .lib section in a.out corrupted */
-#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
-#define ELIBEXEC 83 /* Cannot exec a shared library directly */
-#define ERESTART 85 /* Interrupted system call should be restarted */
-#define ESTRPIPE 86 /* Streams pipe error */
-#define EUSERS 87 /* Too many users */
-#define ENOTSOCK 88 /* Socket operation on non-socket */
-#define EDESTADDRREQ 89 /* Destination address required */
-#define EMSGSIZE 90 /* Message too long */
-#define EPROTOTYPE 91 /* Protocol wrong type for socket */
-#define ENOPROTOOPT 92 /* Protocol not available */
-#define EPROTONOSUPPORT 93 /* Protocol not supported */
-#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
-#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
-#define EPFNOSUPPORT 96 /* Protocol family not supported */
-#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
-#define EADDRINUSE 98 /* Address already in use */
-#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
-#define ENETDOWN 100 /* Network is down */
-#define ENETUNREACH 101 /* Network is unreachable */
-#define ENETRESET 102 /* Network dropped connection because of reset */
-#define ECONNABORTED 103 /* Software caused connection abort */
-#define ECONNRESET 104 /* Connection reset by peer */
-#define ENOBUFS 105 /* No buffer space available */
-#define EISCONN 106 /* Transport endpoint is already connected */
-#define ENOTCONN 107 /* Transport endpoint is not connected */
-#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
-#define ETOOMANYREFS 109 /* Too many references: cannot splice */
-#define ETIMEDOUT 110 /* Connection timed out */
-#define ECONNREFUSED 111 /* Connection refused */
-#define EHOSTDOWN 112 /* Host is down */
-#define EHOSTUNREACH 113 /* No route to host */
-#define EALREADY 114 /* Operation already in progress */
-#define EINPROGRESS 115 /* Operation now in progress */
-#define ESTALE 116 /* Stale NFS file handle */
-#define EUCLEAN 117 /* Structure needs cleaning */
-#define ENOTNAM 118 /* Not a XENIX named type file */
-#define ENAVAIL 119 /* No XENIX semaphores available */
-#define EISNAM 120 /* Is a named type file */
-#define EREMOTEIO 121 /* Remote I/O error */
-#define EDQUOT 122 /* Quota exceeded */
-
-#define ENOMEDIUM 123 /* No medium found */
-#define EMEDIUMTYPE 124 /* Wrong medium type */
-
-/* Should never be seen by user programs */
-#define ERESTARTSYS 512
-#define ERESTARTNOINTR 513
-#define ERESTARTNOHAND 514 /* restart if no handler.. */
-#define ENOIOCTLCMD 515 /* No ioctl command */
-
-/* Defined for the NFSv3 protocol */
-#define EBADHANDLE 521 /* Illegal NFS file handle */
-#define ENOTSYNC 522 /* Update synchronization mismatch */
-#define EBADCOOKIE 523 /* Cookie is stale */
-#define ENOTSUPP 524 /* Operation is not supported */
-#define ETOOSMALL 525 /* Buffer or request is too small */
-#define ESERVERFAULT 526 /* An untranslatable error occurred */
-#define EBADTYPE 527 /* Type not supported by server */
-#define EJUKEBOX 528 /* Request initiated, but will not complete before timeout */
-
-/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
- located on an ext2 file system */
-#define O_ACCMODE 0003
-#define O_RDONLY 00
-#define O_WRONLY 01
-#define O_RDWR 02
-#define O_CREAT 0100 /* not fcntl */
-#define O_EXCL 0200 /* not fcntl */
-#define O_NOCTTY 0400 /* not fcntl */
-#define O_TRUNC 01000 /* not fcntl */
-#define O_APPEND 02000
-#define O_NONBLOCK 04000
-#define O_NDELAY O_NONBLOCK
-#define O_SYNC 010000
-#define FASYNC 020000 /* fcntl, for BSD compatibility */
-#define O_DIRECT 040000 /* direct disk access hint */
-#define O_LARGEFILE 0100000
-#define O_DIRECTORY 0200000 /* must be a directory */
-#define O_NOFOLLOW 0400000 /* don't follow links */
-
-#define F_DUPFD 0 /* dup */
-#define F_GETFD 1 /* get close_on_exec */
-#define F_SETFD 2 /* set/clear close_on_exec */
-#define F_GETFL 3 /* get file->f_flags */
-#define F_SETFL 4 /* set file->f_flags */
-#define F_GETLK 5
-#define F_SETLK 6
-#define F_SETLKW 7
-
-#define F_SETOWN 8 /* for sockets. */
-#define F_GETOWN 9 /* for sockets. */
-#define F_SETSIG 10 /* for sockets. */
-#define F_GETSIG 11 /* for sockets. */
-
-#define F_GETLK64 12 /* using 'struct flock64' */
-#define F_SETLK64 13
-#define F_SETLKW64 14
-
-/* for F_[GET|SET]FL */
-#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
-
-/* for posix fcntl() and lockf() */
-#define F_RDLCK 0
-#define F_WRLCK 1
-#define F_UNLCK 2
-
-/* for old implementation of bsd flock () */
-#define F_EXLCK 4 /* or 3 */
-#define F_SHLCK 8 /* or 4 */
-
-/* for leases */
-#define F_INPROGRESS 16
-
-/* operations for bsd flock(), also used by the kernel implementation */
-#define LOCK_SH 1 /* shared lock */
-#define LOCK_EX 2 /* exclusive lock */
-#define LOCK_NB 4 /* or'd with one of the above to prevent
- blocking */
-#define LOCK_UN 8 /* remove lock */
-
-#define LOCK_MAND 32 /* This is a mandatory flock */
-#define LOCK_READ 64 /* ... Which allows concurrent read operations */
-#define LOCK_WRITE 128 /* ... Which allows concurrent write operations */
-#define LOCK_RW 192 /* ... Which allows concurrent read & write ops */
-
-#endif
-
-
-#ifndef LIBCFS_SIGNAL_H
-#define LIBCFS_SIGNAL_H
-
-/*
- * signal values ...
- */
-
-#ifdef __KERNEL__
-#define SIGHUP 1
-#define SIGINT 2
-#define SIGQUIT 3
-#define SIGILL 4
-#define SIGTRAP 5
-#define SIGABRT 6
-#define SIGIOT 6
-#define SIGBUS 7
-#define SIGFPE 8
-#define SIGKILL 9
-#define SIGUSR1 10
-#define SIGSEGV 11
-#define SIGUSR2 12
-#define SIGPIPE 13
-#define SIGALRM 14
-#define SIGTERM 15
-#define SIGSTKFLT 16
-#define SIGCHLD 17
-#define SIGCONT 18
-#define SIGSTOP 19
-#define SIGTSTP 20
-#define SIGTTIN 21
-#define SIGTTOU 22
-#define SIGURG 23
-#define SIGXCPU 24
-#define SIGXFSZ 25
-#define SIGVTALRM 26
-#define SIGPROF 27
-#define SIGWINCH 28
-#define SIGIO 29
-#define SIGPOLL SIGIO
-/*
-#define SIGLOST 29
-*/
-#define SIGPWR 30
-#define SIGSYS 31
-#define SIGUNUSED 31
-
-/* These should not be considered constants from userland. */
-#define SIGRTMIN 32
-#define SIGRTMAX (_NSIG-1)
-
-#endif
-
-/*
- * SA_FLAGS values:
- *
- * SA_ONSTACK indicates that a registered stack_t will be used.
- * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
- * SA_RESETHAND clears the handler when the signal is delivered.
- * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
- * SA_NODEFER prevents the current signal from being masked in the handler.
- *
- * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
- * Unix names RESETHAND and NODEFER respectively.
- */
-#define SA_NOCLDSTOP 0x00000001
-#define SA_NOCLDWAIT 0x00000002 /* not supported yet */
-#define SA_SIGINFO 0x00000004
-#define SA_ONSTACK 0x08000000
-#define SA_RESTART 0x10000000
-#define SA_NODEFER 0x40000000
-#define SA_RESETHAND 0x80000000
-
-#define SA_NOMASK SA_NODEFER
-#define SA_ONESHOT SA_RESETHAND
-#define SA_INTERRUPT 0x20000000 /* dummy -- ignored */
-
-#define SA_RESTORER 0x04000000
-
-/*
- * sigaltstack controls
- */
-#define SS_ONSTACK 1
-#define SS_DISABLE 2
-
-#define MINSIGSTKSZ 2048
-#define SIGSTKSZ 8192
-
-
-#define sigmask(sig) ((__u32)1 << ((sig) - 1))
-
-#endif // LIBCFS_SIGNAL_H
if (rc != 0)
goto out;
-#if !defined(__WINNT__)
if (str[0] != '/') {
rc = -EINVAL;
goto out;
}
-#endif
rc = cfs_tracefile_dump_all_pages(str);
out:
cfs_trace_free_string_buffer(str, usr_str_nob + 1);
} else if (strlen(str) >= sizeof(cfs_tracefile)) {
rc = -ENAMETOOLONG;
-#ifndef __WINNT__
} else if (str[0] != '/') {
rc = -EINVAL;
-#endif
} else {
strcpy(cfs_tracefile, str);
#ifdef __KERNEL__
#if defined(__linux__)
#include "linux/linux-tracefile.h"
-#elif defined(__WINNT__)
-#include "winnt/winnt-tracefile.h"
#else
#error Unsupported operating system.
#endif
#if defined (__DARWIN__)
pg->addr = valloc(PAGE_CACHE_SIZE);
-#elif defined (__WINNT__)
- pg->addr = pgalloc(0);
#else
rc = posix_memalign(&pg->addr, PAGE_CACHE_SIZE, PAGE_CACHE_SIZE);
#endif
void __free_page(struct page *pg)
{
-#if defined (__WINNT__)
- pgfree(pg->addr);
-#else
free(pg->addr);
-#endif
free(pg);
}
#if defined(__sun__) || defined(__sun)
#include <sys/sockio.h>
#endif
-#ifndef __CYGWIN__
#include <sys/syscall.h>
-#endif
/*
* Functions to get network interfaces info
}
if (ioc_dev_list[dev_id].dev_fd < 0) {
- int fd = cfs_proc_open((char *)dev_name, O_RDWR);
-
- /* Make the /dev/ node if we need to */
- if (fd < 0 && errno == ENOENT) {
- if (cfs_proc_mknod(dev_name,
- S_IFCHR|S_IWUSR|S_IRUSR,
- MKDEV(ioc_dev_list[dev_id].dev_major,
- ioc_dev_list[dev_id].dev_minor)) == 0)
- fd = cfs_proc_open((char *)dev_name, O_RDWR);
+ int fd = open(dev_name, O_RDWR);
+
+ /* Make the /dev/ node if we need to */
+ if (fd < 0 && errno == ENOENT) {
+ if (mknod(dev_name, S_IFCHR|S_IWUSR|S_IRUSR,
+ MKDEV(ioc_dev_list[dev_id].dev_major,
+ ioc_dev_list[dev_id].dev_minor)) == 0)
+ fd = open(dev_name, O_RDWR);
else
fprintf(stderr, "mknod %s failed: %s\n",
dev_name, strerror(errno));
if (fd < 0)
return fd;
- rc = cfs_proc_ioctl(fd, opc, buf);
- return rc;
-
+ rc = ioctl(fd, opc, buf);
+
+ return rc;
}
static FILE *
void
unregister_ioc_dev(int dev_id)
{
+ if (dev_id < 0 ||
+ dev_id >= sizeof(ioc_dev_list) / sizeof(ioc_dev_list[0]))
+ return;
- if (dev_id < 0 ||
- dev_id >= sizeof(ioc_dev_list) / sizeof(ioc_dev_list[0]))
- return;
- if (ioc_dev_list[dev_id].dev_name != NULL &&
- ioc_dev_list[dev_id].dev_fd >= 0)
- cfs_proc_close(ioc_dev_list[dev_id].dev_fd);
+ if (ioc_dev_list[dev_id].dev_name != NULL &&
+ ioc_dev_list[dev_id].dev_fd >= 0)
+ close(ioc_dev_list[dev_id].dev_fd);
- ioc_dev_list[dev_id].dev_name = NULL;
- ioc_dev_list[dev_id].dev_fd = -1;
+ ioc_dev_list[dev_id].dev_name = NULL;
+ ioc_dev_list[dev_id].dev_fd = -1;
}
/* If this file is set, then all ioctl buffers will be
{
int line =0;
char *start, *buf, *end;
-
-#if defined(__CYGWIN__) || defined(__WINNT__)
-
- HANDLE fd, hmap;
- DWORD size;
-
- fd = CreateFile(dump_file, GENERIC_READ, FILE_SHARE_READ, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (fd == INVALID_HANDLE_VALUE) {
- fprintf(stderr, "couldn't open %s (error code: %u)\n",
- dump_file, GetLastError());
- exit(1);
- }
- size = GetFileSize(fd, NULL);
- if (size < 1 || size == 0xFFFFFFFF) {
- fprintf(stderr, "KML is empty\n");
- CloseHandle(fd);
- exit(1);
- }
-
- hmap = CreateFileMapping(fd, NULL, PAGE_READONLY, 0,0, NULL);
- if (hmap == NULL) {
- fprintf(stderr, "can't create file mapping\n");
- CloseHandle(fd);
- exit(1);
- }
- start = buf = MapViewOfFile(hmap, FILE_MAP_READ, 0, 0, 0);
- if (start == NULL) {
- fprintf(stderr, "can't map file content\n");
- CloseHandle(hmap);
- CloseHandle(fd);
- exit(1);
- }
- end = buf + size;
- CloseHandle(fd);
- if (start == NULL) {
- fprintf(stderr, "can't create file mapping\n");
- UnmapViewOfFile(start);
- CloseHandle(hmap);
- exit(1);
- }
-#else
-
struct stat st;
int fd;
fprintf(stderr, "can't create file mapping\n");
exit(1);
}
-#endif
while (buf < end) {
struct dump_hdr *dump_hdr = (struct dump_hdr *) buf;
buf += data->ioc_len + sizeof(*dump_hdr);
}
-#if defined(__CYGWIN__) || defined(__WINNT__)
- UnmapViewOfFile(start);
- CloseHandle(hmap);
-#else
- munmap(start, end - start);
-#endif
+ munmap(start, end - start);
- return 0;
+ return 0;
}
int
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * libcfs/libcfs/winnt/winnt-curproc.c
- *
- * Impletion of winnt curproc routines.
- */
-
-#define DEBUG_SUBSYSTEM S_LNET
-
-#include <libcfs/libcfs.h>
-
-/*
- * Implementation of cfs_curproc API (see portals/include/libcfs/curproc.h)
- * for Linux kernel.
- */
-
-struct task_struct this_task =
- { /* umask */ 0,/* blocked*/0, /* pid */ 0, /* pgrp */ 0,
- /* uid,euid,suid,fsuid */ 0, 0, 0, 0,
- /* gid_t gid,egid,sgid,fsgid */ 0, 0, 0, 0,
- /* ngroups*/ 1, /*cgroups*/ 0, /*groups*/ 0,
- /* group_info */ NULL,
- /* cap_effective, cap_inheritable, cap_permitted */ 0, 0, 0,
- /* comm */"sysetm\0",
- /* journal_info */ NULL
- };
-
-struct user_namespace init_user_ns __read_mostly;
-EXPORT_SYMBOL(init_user_ns);
-
-uid_t current_uid(void)
-{
- return this_task.uid;
-}
-
-gid_t current_gid(void)
-{
- return this_task.gid;
-}
-
-uid_t current_fsuid(void)
-{
- return this_task.fsuid;
-}
-
-gid_t current_fsgid(void)
-{
- return this_task.fsgid;
-}
-
-pid_t current_pid(void)
-{
- return current->pid;
-}
-
-mode_t current_umask(void)
-{
- return this_task.umask;
-}
-
-char *current_comm(void)
-{
- return this_task.comm;
-}
-
-void cfs_cap_raise(cfs_cap_t cap)
-{
- this_task.cap_effective |= (1 << cap);
-}
-
-void cfs_cap_lower(cfs_cap_t cap)
-{
- this_task.cap_effective &= ~(1 << cap);
-}
-
-int cfs_cap_raised(cfs_cap_t cap)
-{
- return this_task.cap_effective & (1 << cap);
-}
-
-cfs_cap_t cfs_curproc_cap_pack(void) {
- return this_task.cap_effective;
-}
-
-void cfs_curproc_cap_unpack(cfs_cap_t cap) {
- this_task.cap_effective = cap;
-}
-
-int cfs_capable(cfs_cap_t cap)
-{
- return TRUE;
-}
-
-/*
- * Implementation of linux task management routines
- */
-
-
-/* global of the task manager structure */
-
-TASK_MAN cfs_win_task_manger;
-
-/* global idr context */
-struct idr_context * cfs_win_task_slot_idp = NULL;
-
-/*
- * task slot routiens
- */
-
-PTASK_SLOT alloc_task_slot()
-{
- if (cfs_win_task_manger.slab)
- return kmem_cache_alloc(cfs_win_task_manger.slab, 0);
- else
- return kmalloc(sizeof(TASK_SLOT), 0);
-}
-
-void
-init_task_slot(PTASK_SLOT task)
-{
- memset(task, 0, sizeof(TASK_SLOT));
- task->Magic = TASKSLT_MAGIC;
- task->task = this_task;
- cfs_init_event(&task->Event, TRUE, FALSE);
-}
-
-void cleanup_task_slot(PTASK_SLOT task)
-{
- if (task->task.pid)
- cfs_idr_remove(cfs_win_task_slot_idp, task->task.pid);
-
- if (cfs_win_task_manger.slab)
- kmem_cache_free(cfs_win_task_manger.slab, task);
- else
- kfree(task);
-}
-
-/*
- * task manager related routines
- */
-
-VOID
-task_manager_notify(
- IN HANDLE ProcessId,
- IN HANDLE ThreadId,
- IN BOOLEAN Create
- )
-{
- PLIST_ENTRY ListEntry = NULL;
- PTASK_SLOT TaskSlot = NULL;
-
- spin_lock(&(cfs_win_task_manger.Lock));
-
- ListEntry = cfs_win_task_manger.TaskList.Flink;
- while (ListEntry != (&(cfs_win_task_manger.TaskList))) {
-
- TaskSlot = CONTAINING_RECORD(ListEntry, TASK_SLOT, Link);
-
- if (TaskSlot->Pid == ProcessId && TaskSlot->Tid == ThreadId) {
-
- if (!Create) {
- /* remove the taskslot */
- RemoveEntryList(&(TaskSlot->Link));
- cfs_win_task_manger.NumOfTasks--;
-
- /* now free the task slot */
- cleanup_task_slot(TaskSlot);
- }
- }
-
- ListEntry = ListEntry->Flink;
- }
-
- spin_unlock(&(cfs_win_task_manger.Lock));
-}
-
-int
-init_task_manager()
-{
- NTSTATUS status;
-
- /* initialize the content and magic */
- memset(&cfs_win_task_manger, 0, sizeof(TASK_MAN));
- cfs_win_task_manger.Magic = TASKMAN_MAGIC;
-
- /* initialize the spinlock protection */
- spin_lock_init(&cfs_win_task_manger.Lock);
-
- /* create slab memory cache */
- cfs_win_task_manger.slab = kmem_cache_create("TSLT", sizeof(TASK_SLOT),
- 0, 0, NULL);
-
- /* intialize the list header */
- InitializeListHead(&(cfs_win_task_manger.TaskList));
-
- cfs_win_task_slot_idp = cfs_idr_init();
- if (!cfs_win_task_slot_idp) {
- return -ENOMEM;
- }
-
- /* set the thread creation/destruction notify routine */
- status = PsSetCreateThreadNotifyRoutine(task_manager_notify);
-
- if (!NT_SUCCESS(status)) {
- cfs_enter_debugger();
- /* remove idr context */
- if (cfs_win_task_slot_idp) {
- cfs_idr_exit(cfs_win_task_slot_idp);
- cfs_win_task_slot_idp = NULL;
- }
- return cfs_error_code(status);
- }
-
- return 0;
-}
-
-void
-cleanup_task_manager()
-{
- PLIST_ENTRY ListEntry = NULL;
- PTASK_SLOT TaskSlot = NULL;
-
- /* remove ThreadNotifyRoutine: task_manager_notify */
- PsRemoveCreateThreadNotifyRoutine(task_manager_notify);
-
- /* remove idr context */
- if (cfs_win_task_slot_idp) {
- cfs_idr_exit(cfs_win_task_slot_idp);
- cfs_win_task_slot_idp = NULL;
- }
-
- /* cleanup all the taskslots attached to the list */
- spin_lock(&(cfs_win_task_manger.Lock));
-
- while (!IsListEmpty(&(cfs_win_task_manger.TaskList))) {
-
- ListEntry = cfs_win_task_manger.TaskList.Flink;
- TaskSlot = CONTAINING_RECORD(ListEntry, TASK_SLOT, Link);
-
- RemoveEntryList(ListEntry);
- cleanup_task_slot(TaskSlot);
- }
-
- spin_unlock(&cfs_win_task_manger.Lock);
-
- /* destroy the taskslot cache slab */
- kmem_cache_destroy(cfs_win_task_manger.slab);
- memset(&cfs_win_task_manger, 0, sizeof(TASK_MAN));
-}
-
-
-/*
- * schedule routines (task slot list)
- */
-
-
-struct task_struct *
-current
-{
- HANDLE Pid = PsGetCurrentProcessId();
- HANDLE Tid = PsGetCurrentThreadId();
- PETHREAD Tet = PsGetCurrentThread();
-
- PLIST_ENTRY ListEntry = NULL;
- PTASK_SLOT TaskSlot = NULL;
-
- spin_lock(&(cfs_win_task_manger.Lock));
-
- ListEntry = cfs_win_task_manger.TaskList.Flink;
- while (ListEntry != (&(cfs_win_task_manger.TaskList))) {
-
- TaskSlot = CONTAINING_RECORD(ListEntry, TASK_SLOT, Link);
- if (TaskSlot->Pid == Pid && TaskSlot->Tid == Tid) {
- if (TaskSlot->Tet != Tet) {
-
- //
- // The old thread was already exit. This must be a
- // new thread which get the same Tid to the previous.
- //
-
- TaskSlot->Tet = Tet;
- }
- break;
-
- } else {
-
- if (TaskSlot->Pid > Pid) {
- TaskSlot = NULL;
- break;
- } else if (TaskSlot->Pid == Pid) {
- if (TaskSlot->Tid > Tid) {
- TaskSlot = NULL;
- break;
- }
- }
- TaskSlot = NULL;
- }
-
- ListEntry = ListEntry->Flink;
- }
-
- if (!TaskSlot) {
-
- /* allocate new task slot */
- TaskSlot = alloc_task_slot();
- if (!TaskSlot) {
- cfs_enter_debugger();
- goto errorout;
- }
-
- /* set task slot IDs */
- init_task_slot(TaskSlot);
- TaskSlot->Pid = Pid;
- TaskSlot->Tid = Tid;
- TaskSlot->Tet = Tet;
- TaskSlot->task.pid = (pid_t)cfs_idr_get_new(cfs_win_task_slot_idp, Tet);
-
- if (ListEntry == (&(cfs_win_task_manger.TaskList))) {
- //
- // Empty case or the biggest case, put it to the tail.
- //
- InsertTailList(&(cfs_win_task_manger.TaskList), &(TaskSlot->Link));
- } else {
- //
- // Get a slot and smaller than it's tid, put it just before.
- //
- InsertHeadList(ListEntry->Blink, &(TaskSlot->Link));
- }
-
- cfs_win_task_manger.NumOfTasks++;
- }
-
- //
- // To Check whether he task structures are arranged in the expected order ?
- //
-
- {
- PTASK_SLOT Prev = NULL, Curr = NULL;
-
- ListEntry = cfs_win_task_manger.TaskList.Flink;
-
- while (ListEntry != (&(cfs_win_task_manger.TaskList))) {
-
- Curr = CONTAINING_RECORD(ListEntry, TASK_SLOT, Link);
- ListEntry = ListEntry->Flink;
-
- if (Prev) {
- if (Prev->Pid > Curr->Pid) {
- cfs_enter_debugger();
- } else if (Prev->Pid == Curr->Pid) {
- if (Prev->Tid > Curr->Tid) {
- cfs_enter_debugger();
- }
- }
- }
-
- Prev = Curr;
- }
- }
-
-errorout:
-
- spin_unlock(&(cfs_win_task_manger.Lock));
-
- if (!TaskSlot) {
- cfs_enter_debugger();
- return NULL;
- }
-
- return (&(TaskSlot->task));
-}
-
-/* deschedule for a bit... */
-void
-cfs_pause(cfs_duration_t ticks)
-{
- schedule_timeout_and_set_state(CFS_TASK_UNINTERRUPTIBLE, ticks);
-}
-
-void
-schedule_timeout_and_set_state(long state, int64_t time)
-{
- struct task_struct * task = current;
- PTASK_SLOT slot = NULL;
-
- if (!task) {
- cfs_enter_debugger();
- return;
- }
-
- slot = CONTAINING_RECORD(task, TASK_SLOT, task);
- cfs_assert(slot->Magic == TASKSLT_MAGIC);
-
- if (time == MAX_SCHEDULE_TIMEOUT) {
- time = 0;
- }
-
- cfs_wait_event_internal(&(slot->Event), time);
-}
-
-void
-schedule()
-{
- schedule_timeout_and_set_state(CFS_TASK_UNINTERRUPTIBLE, 0);
-}
-
-int
-wake_up_process(
- struct task_struct * task
- )
-{
- PTASK_SLOT slot = NULL;
-
- if (!task) {
- cfs_enter_debugger();
- return 0;
- }
-
- slot = CONTAINING_RECORD(task, TASK_SLOT, task);
- cfs_assert(slot->Magic == TASKSLT_MAGIC);
-
- cfs_wake_event(&(slot->Event));
-
- return TRUE;
-}
-
-void
-sleep_on(wait_queue_head_t *waitq)
-{
- wait_queue_t link;
-
- init_waitqueue_entry_current(&link);
- add_wait_queue(waitq, &link);
- waitq_wait(&link, TASK_INTERRUPTIBLE);
- remove_wait_queue(waitq, &link);
-}
-
-EXPORT_SYMBOL(current_uid);
-EXPORT_SYMBOL(current_pid);
-EXPORT_SYMBOL(current_gid);
-EXPORT_SYMBOL(current_fsuid);
-EXPORT_SYMBOL(current_fsgid);
-EXPORT_SYMBOL(current_umask);
-EXPORT_SYMBOL(current_comm);
-EXPORT_SYMBOL(cfs_cap_raise);
-EXPORT_SYMBOL(cfs_cap_lower);
-EXPORT_SYMBOL(cfs_cap_raised);
-EXPORT_SYMBOL(cfs_curproc_cap_pack);
-EXPORT_SYMBOL(cfs_curproc_cap_unpack);
-EXPORT_SYMBOL(cfs_capable);
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-# define DEBUG_SUBSYSTEM S_LNET
-
-#include <libcfs/libcfs.h>
-#include "tracefile.h"
-
-void libcfs_debug_dumpstack(struct task_struct *tsk)
-{
- return;
-}
-
-void libcfs_run_debug_log_upcall(char *file)
-{
-}
-
-struct task_struct *libcfs_current(void)
-{
- return current;
-}
-
-void libcfs_run_lbug_upcall(struct libcfs_debug_msg_data *msgdata)
-{
-}
-
-void lbug_with_loc(struct libcfs_debug_msg_data *msgdata)
-{
- libcfs_catastrophe = 1;
- CEMERG("LBUG: pid: %u thread: %#x\n",
- current_pid(), PsGetCurrentThread());
- cfs_enter_debugger();
- libcfs_debug_dumplog();
- libcfs_run_lbug_upcall(msgdata);
-}
-
-void cfs_enter_debugger(void)
-{
-# if _X86_
- __asm int 3;
-# else
- KdBreakPoint();
-# endif
-}
-
-#if DBG
-
-/*
- * Definitions
- */
-
-LONG KsDebugLevel = 1;
-
-
-/*
- * Routines
- */
-
-
-/*
- * KsNtStatusToString
- * Get the error message for a specified nt status
- *
- * Arguments:
- * Status - nt status code
- *
- * Return Value:
- * PUCHAR - message string for the status code
- *
- * NOTES:
- * N/A
- */
-
-PUCHAR
-KsNtStatusToString (IN NTSTATUS Status)
-{
- switch (Status) {
-
- case 0x00000000: return "STATUS_SUCCESS";
- case 0x00000001: return "STATUS_WAIT_1";
- case 0x00000002: return "STATUS_WAIT_2";
- case 0x00000003: return "STATUS_WAIT_3";
- case 0x0000003F: return "STATUS_WAIT_63";
- case 0x00000080: return "STATUS_ABANDONED_WAIT_0";
- case 0x000000BF: return "STATUS_ABANDONED_WAIT_63";
- case 0x000000C0: return "STATUS_USER_APC";
- case 0x00000100: return "STATUS_KERNEL_APC";
- case 0x00000101: return "STATUS_ALERTED";
- case 0x00000102: return "STATUS_TIMEOUT";
- case 0x00000103: return "STATUS_PENDING";
- case 0x00000104: return "STATUS_REPARSE";
- case 0x00000105: return "STATUS_MORE_ENTRIES";
- case 0x00000106: return "STATUS_NOT_ALL_ASSIGNED";
- case 0x00000107: return "STATUS_SOME_NOT_MAPPED";
- case 0x00000108: return "STATUS_OPLOCK_BREAK_IN_PROGRESS";
- case 0x00000109: return "STATUS_VOLUME_MOUNTED";
- case 0x0000010A: return "STATUS_RXACT_COMMITTED";
- case 0x0000010B: return "STATUS_NOTIFY_CLEANUP";
- case 0x0000010C: return "STATUS_NOTIFY_ENUM_DIR";
- case 0x0000010D: return "STATUS_NO_QUOTAS_FOR_ACCOUNT";
- case 0x0000010E: return "STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED";
- case 0x00000110: return "STATUS_PAGE_FAULT_TRANSITION";
- case 0x00000111: return "STATUS_PAGE_FAULT_DEMAND_ZERO";
- case 0x00000112: return "STATUS_PAGE_FAULT_COPY_ON_WRITE";
- case 0x00000113: return "STATUS_PAGE_FAULT_GUARD_PAGE";
- case 0x00000114: return "STATUS_PAGE_FAULT_PAGING_FILE";
- case 0x00000115: return "STATUS_CACHE_PAGE_LOCKED";
- case 0x00000116: return "STATUS_CRASH_DUMP";
- case 0x00000117: return "STATUS_BUFFER_ALL_ZEROS";
- case 0x00000118: return "STATUS_REPARSE_OBJECT";
- case 0x00000119: return "STATUS_RESOURCE_REQUIREMENTS_CHANGED";
- case 0x00000120: return "STATUS_TRANSLATION_COMPLETE";
- case 0x00000121: return "STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY";
- case 0x00010001: return "DBG_EXCEPTION_HANDLED";
- case 0x00010002: return "DBG_CONTINUE";
- case 0x40000000: return "STATUS_OBJECT_NAME_EXISTS";
- case 0x40000001: return "STATUS_THREAD_WAS_SUSPENDED";
- case 0x40000002: return "STATUS_WORKING_SET_LIMIT_RANGE";
- case 0x40000003: return "STATUS_IMAGE_NOT_AT_BASE";
- case 0x40000004: return "STATUS_RXACT_STATE_CREATED";
- case 0x40000005: return "STATUS_SEGMENT_NOTIFICATION";
- case 0x40000006: return "STATUS_LOCAL_USER_SESSION_KEY";
- case 0x40000007: return "STATUS_BAD_CURRENT_DIRECTORY";
- case 0x40000008: return "STATUS_SERIAL_MORE_WRITES";
- case 0x40000009: return "STATUS_REGISTRY_RECOVERED";
- case 0x4000000A: return "STATUS_FT_READ_RECOVERY_FROM_BACKUP";
- case 0x4000000B: return "STATUS_FT_WRITE_RECOVERY";
- case 0x4000000C: return "STATUS_SERIAL_COUNTER_TIMEOUT";
- case 0x4000000D: return "STATUS_NULL_LM_PASSWORD";
- case 0x4000000E: return "STATUS_IMAGE_MACHINE_TYPE_MISMATCH";
- case 0x4000000F: return "STATUS_RECEIVE_PARTIAL";
- case 0x40000010: return "STATUS_RECEIVE_EXPEDITED";
- case 0x40000011: return "STATUS_RECEIVE_PARTIAL_EXPEDITED";
- case 0x40000012: return "STATUS_EVENT_DONE";
- case 0x40000013: return "STATUS_EVENT_PENDING";
- case 0x40000014: return "STATUS_CHECKING_FILE_SYSTEM";
- case 0x40000015: return "STATUS_FATAL_APP_EXIT";
- case 0x40000016: return "STATUS_PREDEFINED_HANDLE";
- case 0x40000017: return "STATUS_WAS_UNLOCKED";
- case 0x40000018: return "STATUS_SERVICE_NOTIFICATION";
- case 0x40000019: return "STATUS_WAS_LOCKED";
- case 0x4000001A: return "STATUS_LOG_HARD_ERROR";
- case 0x4000001B: return "STATUS_ALREADY_WIN32";
- case 0x4000001C: return "STATUS_WX86_UNSIMULATE";
- case 0x4000001D: return "STATUS_WX86_CONTINUE";
- case 0x4000001E: return "STATUS_WX86_SINGLE_STEP";
- case 0x4000001F: return "STATUS_WX86_BREAKPOINT";
- case 0x40000020: return "STATUS_WX86_EXCEPTION_CONTINUE";
- case 0x40000021: return "STATUS_WX86_EXCEPTION_LASTCHANCE";
- case 0x40000022: return "STATUS_WX86_EXCEPTION_CHAIN";
- case 0x40000023: return "STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE";
- case 0x40000024: return "STATUS_NO_YIELD_PERFORMED";
- case 0x40000025: return "STATUS_TIMER_RESUME_IGNORED";
- case 0x40000026: return "STATUS_ARBITRATION_UNHANDLED";
- case 0x40000027: return "STATUS_CARDBUS_NOT_SUPPORTED";
- case 0x40000028: return "STATUS_WX86_CREATEWX86TIB";
- case 0x40000029: return "STATUS_MP_PROCESSOR_MISMATCH";
- case 0x40010001: return "DBG_REPLY_LATER";
- case 0x40010002: return "DBG_UNABLE_TO_PROVIDE_HANDLE";
- case 0x40010003: return "DBG_TERMINATE_THREAD";
- case 0x40010004: return "DBG_TERMINATE_PROCESS";
- case 0x40010005: return "DBG_CONTROL_C";
- case 0x40010006: return "DBG_PRINTEXCEPTION_C";
- case 0x40010007: return "DBG_RIPEXCEPTION";
- case 0x40010008: return "DBG_CONTROL_BREAK";
- case 0x80000001: return "STATUS_GUARD_PAGE_VIOLATION";
- case 0x80000002: return "STATUS_DATATYPE_MISALIGNMENT";
- case 0x80000003: return "STATUS_BREAKPOINT";
- case 0x80000004: return "STATUS_SINGLE_STEP";
- case 0x80000005: return "STATUS_BUFFER_OVERFLOW";
- case 0x80000006: return "STATUS_NO_MORE_FILES";
- case 0x80000007: return "STATUS_WAKE_SYSTEM_DEBUGGER";
- case 0x8000000A: return "STATUS_HANDLES_CLOSED";
- case 0x8000000B: return "STATUS_NO_INHERITANCE";
- case 0x8000000C: return "STATUS_GUID_SUBSTITUTION_MADE";
- case 0x8000000D: return "STATUS_PARTIAL_COPY";
- case 0x8000000E: return "STATUS_DEVICE_PAPER_EMPTY";
- case 0x8000000F: return "STATUS_DEVICE_POWERED_OFF";
- case 0x80000010: return "STATUS_DEVICE_OFF_LINE";
- case 0x80000011: return "STATUS_DEVICE_BUSY";
- case 0x80000012: return "STATUS_NO_MORE_EAS";
- case 0x80000013: return "STATUS_INVALID_EA_NAME";
- case 0x80000014: return "STATUS_EA_LIST_INCONSISTENT";
- case 0x80000015: return "STATUS_INVALID_EA_FLAG";
- case 0x80000016: return "STATUS_VERIFY_REQUIRED";
- case 0x80000017: return "STATUS_EXTRANEOUS_INFORMATION";
- case 0x80000018: return "STATUS_RXACT_COMMIT_NECESSARY";
- case 0x8000001A: return "STATUS_NO_MORE_ENTRIES";
- case 0x8000001B: return "STATUS_FILEMARK_DETECTED";
- case 0x8000001C: return "STATUS_MEDIA_CHANGED";
- case 0x8000001D: return "STATUS_BUS_RESET";
- case 0x8000001E: return "STATUS_END_OF_MEDIA";
- case 0x8000001F: return "STATUS_BEGINNING_OF_MEDIA";
- case 0x80000020: return "STATUS_MEDIA_CHECK";
- case 0x80000021: return "STATUS_SETMARK_DETECTED";
- case 0x80000022: return "STATUS_NO_DATA_DETECTED";
- case 0x80000023: return "STATUS_REDIRECTOR_HAS_OPEN_HANDLES";
- case 0x80000024: return "STATUS_SERVER_HAS_OPEN_HANDLES";
- case 0x80000025: return "STATUS_ALREADY_DISCONNECTED";
- case 0x80000026: return "STATUS_LONGJUMP";
- case 0x80010001: return "DBG_EXCEPTION_NOT_HANDLED";
- case 0xC0000001: return "STATUS_UNSUCCESSFUL";
- case 0xC0000002: return "STATUS_NOT_IMPLEMENTED";
- case 0xC0000003: return "STATUS_INVALID_INFO_CLASS";
- case 0xC0000004: return "STATUS_INFO_LENGTH_MISMATCH";
- case 0xC0000005: return "STATUS_ACCESS_VIOLATION";
- case 0xC0000006: return "STATUS_IN_PAGE_ERROR";
- case 0xC0000007: return "STATUS_PAGEFILE_QUOTA";
- case 0xC0000008: return "STATUS_INVALID_HANDLE";
- case 0xC0000009: return "STATUS_BAD_INITIAL_STACK";
- case 0xC000000A: return "STATUS_BAD_INITIAL_PC";
- case 0xC000000B: return "STATUS_INVALID_CID";
- case 0xC000000C: return "STATUS_TIMER_NOT_CANCELED";
- case 0xC000000D: return "STATUS_INVALID_PARAMETER";
- case 0xC000000E: return "STATUS_NO_SUCH_DEVICE";
- case 0xC000000F: return "STATUS_NO_SUCH_FILE";
- case 0xC0000010: return "STATUS_INVALID_DEVICE_REQUEST";
- case 0xC0000011: return "STATUS_END_OF_FILE";
- case 0xC0000012: return "STATUS_WRONG_VOLUME";
- case 0xC0000013: return "STATUS_NO_MEDIA_IN_DEVICE";
- case 0xC0000014: return "STATUS_UNRECOGNIZED_MEDIA";
- case 0xC0000015: return "STATUS_NONEXISTENT_SECTOR";
- case 0xC0000016: return "STATUS_MORE_PROCESSING_REQUIRED";
- case 0xC0000017: return "STATUS_NO_MEMORY";
- case 0xC0000018: return "STATUS_CONFLICTING_ADDRESSES";
- case 0xC0000019: return "STATUS_NOT_MAPPED_VIEW";
- case 0xC000001A: return "STATUS_UNABLE_TO_FREE_VM";
- case 0xC000001B: return "STATUS_UNABLE_TO_DELETE_SECTION";
- case 0xC000001C: return "STATUS_INVALID_SYSTEM_SERVICE";
- case 0xC000001D: return "STATUS_ILLEGAL_INSTRUCTION";
- case 0xC000001E: return "STATUS_INVALID_LOCK_SEQUENCE";
- case 0xC000001F: return "STATUS_INVALID_VIEW_SIZE";
- case 0xC0000020: return "STATUS_INVALID_FILE_FOR_SECTION";
- case 0xC0000021: return "STATUS_ALREADY_COMMITTED";
- case 0xC0000022: return "STATUS_ACCESS_DENIED";
- case 0xC0000023: return "STATUS_BUFFER_TOO_SMALL";
- case 0xC0000024: return "STATUS_OBJECT_TYPE_MISMATCH";
- case 0xC0000025: return "STATUS_NONCONTINUABLE_EXCEPTION";
- case 0xC0000026: return "STATUS_INVALID_DISPOSITION";
- case 0xC0000027: return "STATUS_UNWIND";
- case 0xC0000028: return "STATUS_BAD_STACK";
- case 0xC0000029: return "STATUS_INVALID_UNWIND_TARGET";
- case 0xC000002A: return "STATUS_NOT_LOCKED";
- case 0xC000002B: return "STATUS_PARITY_ERROR";
- case 0xC000002C: return "STATUS_UNABLE_TO_DECOMMIT_VM";
- case 0xC000002D: return "STATUS_NOT_COMMITTED";
- case 0xC000002E: return "STATUS_INVALID_PORT_ATTRIBUTES";
- case 0xC000002F: return "STATUS_PORT_MESSAGE_TOO_LONG";
- case 0xC0000030: return "STATUS_INVALID_PARAMETER_MIX";
- case 0xC0000031: return "STATUS_INVALID_QUOTA_LOWER";
- case 0xC0000032: return "STATUS_DISK_CORRUPT_ERROR";
- case 0xC0000033: return "STATUS_OBJECT_NAME_INVALID";
- case 0xC0000034: return "STATUS_OBJECT_NAME_NOT_FOUND";
- case 0xC0000035: return "STATUS_OBJECT_NAME_COLLISION";
- case 0xC0000037: return "STATUS_PORT_DISCONNECTED";
- case 0xC0000038: return "STATUS_DEVICE_ALREADY_ATTACHED";
- case 0xC0000039: return "STATUS_OBJECT_PATH_INVALID";
- case 0xC000003A: return "STATUS_OBJECT_PATH_NOT_FOUND";
- case 0xC000003B: return "STATUS_OBJECT_PATH_SYNTAX_BAD";
- case 0xC000003C: return "STATUS_DATA_OVERRUN";
- case 0xC000003D: return "STATUS_DATA_LATE_ERROR";
- case 0xC000003E: return "STATUS_DATA_ERROR";
- case 0xC000003F: return "STATUS_CRC_ERROR";
- case 0xC0000040: return "STATUS_SECTION_TOO_BIG";
- case 0xC0000041: return "STATUS_PORT_CONNECTION_REFUSED";
- case 0xC0000042: return "STATUS_INVALID_PORT_HANDLE";
- case 0xC0000043: return "STATUS_SHARING_VIOLATION";
- case 0xC0000044: return "STATUS_QUOTA_EXCEEDED";
- case 0xC0000045: return "STATUS_INVALID_PAGE_PROTECTION";
- case 0xC0000046: return "STATUS_MUTANT_NOT_OWNED";
- case 0xC0000047: return "STATUS_SEMAPHORE_LIMIT_EXCEEDED";
- case 0xC0000048: return "STATUS_PORT_ALREADY_SET";
- case 0xC0000049: return "STATUS_SECTION_NOT_IMAGE";
- case 0xC000004A: return "STATUS_SUSPEND_COUNT_EXCEEDED";
- case 0xC000004B: return "STATUS_THREAD_IS_TERMINATING";
- case 0xC000004C: return "STATUS_BAD_WORKING_SET_LIMIT";
- case 0xC000004D: return "STATUS_INCOMPATIBLE_FILE_MAP";
- case 0xC000004E: return "STATUS_SECTION_PROTECTION";
- case 0xC000004F: return "STATUS_EAS_NOT_SUPPORTED";
- case 0xC0000050: return "STATUS_EA_TOO_LARGE";
- case 0xC0000051: return "STATUS_NONEXISTENT_EA_ENTRY";
- case 0xC0000052: return "STATUS_NO_EAS_ON_FILE";
- case 0xC0000053: return "STATUS_EA_CORRUPT_ERROR";
- case 0xC0000054: return "STATUS_FILE_LOCK_CONFLICT";
- case 0xC0000055: return "STATUS_LOCK_NOT_GRANTED";
- case 0xC0000056: return "STATUS_DELETE_PENDING";
- case 0xC0000057: return "STATUS_CTL_FILE_NOT_SUPPORTED";
- case 0xC0000058: return "STATUS_UNKNOWN_REVISION";
- case 0xC0000059: return "STATUS_REVISION_MISMATCH";
- case 0xC000005A: return "STATUS_INVALID_OWNER";
- case 0xC000005B: return "STATUS_INVALID_PRIMARY_GROUP";
- case 0xC000005C: return "STATUS_NO_IMPERSONATION_TOKEN";
- case 0xC000005D: return "STATUS_CANT_DISABLE_MANDATORY";
- case 0xC000005E: return "STATUS_NO_LOGON_SERVERS";
- case 0xC000005F: return "STATUS_NO_SUCH_LOGON_SESSION";
- case 0xC0000060: return "STATUS_NO_SUCH_PRIVILEGE";
- case 0xC0000061: return "STATUS_PRIVILEGE_NOT_HELD";
- case 0xC0000062: return "STATUS_INVALID_ACCOUNT_NAME";
- case 0xC0000063: return "STATUS_USER_EXISTS";
- case 0xC0000064: return "STATUS_NO_SUCH_USER";
- case 0xC0000065: return "STATUS_GROUP_EXISTS";
- case 0xC0000066: return "STATUS_NO_SUCH_GROUP";
- case 0xC0000067: return "STATUS_MEMBER_IN_GROUP";
- case 0xC0000068: return "STATUS_MEMBER_NOT_IN_GROUP";
- case 0xC0000069: return "STATUS_LAST_ADMIN";
- case 0xC000006A: return "STATUS_WRONG_PASSWORD";
- case 0xC000006B: return "STATUS_ILL_FORMED_PASSWORD";
- case 0xC000006C: return "STATUS_PASSWORD_RESTRICTION";
- case 0xC000006D: return "STATUS_LOGON_FAILURE";
- case 0xC000006E: return "STATUS_ACCOUNT_RESTRICTION";
- case 0xC000006F: return "STATUS_INVALID_LOGON_HOURS";
- case 0xC0000070: return "STATUS_INVALID_WORKSTATION";
- case 0xC0000071: return "STATUS_PASSWORD_EXPIRED";
- case 0xC0000072: return "STATUS_ACCOUNT_DISABLED";
- case 0xC0000073: return "STATUS_NONE_MAPPED";
- case 0xC0000074: return "STATUS_TOO_MANY_LUIDS_REQUESTED";
- case 0xC0000075: return "STATUS_LUIDS_EXHAUSTED";
- case 0xC0000076: return "STATUS_INVALID_SUB_AUTHORITY";
- case 0xC0000077: return "STATUS_INVALID_ACL";
- case 0xC0000078: return "STATUS_INVALID_SID";
- case 0xC0000079: return "STATUS_INVALID_SECURITY_DESCR";
- case 0xC000007A: return "STATUS_PROCEDURE_NOT_FOUND";
- case 0xC000007B: return "STATUS_INVALID_IMAGE_FORMAT";
- case 0xC000007C: return "STATUS_NO_TOKEN";
- case 0xC000007D: return "STATUS_BAD_INHERITANCE_ACL";
- case 0xC000007E: return "STATUS_RANGE_NOT_LOCKED";
- case 0xC000007F: return "STATUS_DISK_FULL";
- case 0xC0000080: return "STATUS_SERVER_DISABLED";
- case 0xC0000081: return "STATUS_SERVER_NOT_DISABLED";
- case 0xC0000082: return "STATUS_TOO_MANY_GUIDS_REQUESTED";
- case 0xC0000083: return "STATUS_GUIDS_EXHAUSTED";
- case 0xC0000084: return "STATUS_INVALID_ID_AUTHORITY";
- case 0xC0000085: return "STATUS_AGENTS_EXHAUSTED";
- case 0xC0000086: return "STATUS_INVALID_VOLUME_LABEL";
- case 0xC0000087: return "STATUS_SECTION_NOT_EXTENDED";
- case 0xC0000088: return "STATUS_NOT_MAPPED_DATA";
- case 0xC0000089: return "STATUS_RESOURCE_DATA_NOT_FOUND";
- case 0xC000008A: return "STATUS_RESOURCE_TYPE_NOT_FOUND";
- case 0xC000008B: return "STATUS_RESOURCE_NAME_NOT_FOUND";
- case 0xC000008C: return "STATUS_ARRAY_BOUNDS_EXCEEDED";
- case 0xC000008D: return "STATUS_FLOAT_DENORMAL_OPERAND";
- case 0xC000008E: return "STATUS_FLOAT_DIVIDE_BY_ZERO";
- case 0xC000008F: return "STATUS_FLOAT_INEXACT_RESULT";
- case 0xC0000090: return "STATUS_FLOAT_INVALID_OPERATION";
- case 0xC0000091: return "STATUS_FLOAT_OVERFLOW";
- case 0xC0000092: return "STATUS_FLOAT_STACK_CHECK";
- case 0xC0000093: return "STATUS_FLOAT_UNDERFLOW";
- case 0xC0000094: return "STATUS_INTEGER_DIVIDE_BY_ZERO";
- case 0xC0000095: return "STATUS_INTEGER_OVERFLOW";
- case 0xC0000096: return "STATUS_PRIVILEGED_INSTRUCTION";
- case 0xC0000097: return "STATUS_TOO_MANY_PAGING_FILES";
- case 0xC0000098: return "STATUS_FILE_INVALID";
- case 0xC0000099: return "STATUS_ALLOTTED_SPACE_EXCEEDED";
- case 0xC000009A: return "STATUS_INSUFFICIENT_RESOURCES";
- case 0xC000009B: return "STATUS_DFS_EXIT_PATH_FOUND";
- case 0xC000009C: return "STATUS_DEVICE_DATA_ERROR";
- case 0xC000009D: return "STATUS_DEVICE_NOT_CONNECTED";
- case 0xC000009E: return "STATUS_DEVICE_POWER_FAILURE";
- case 0xC000009F: return "STATUS_FREE_VM_NOT_AT_BASE";
- case 0xC00000A0: return "STATUS_MEMORY_NOT_ALLOCATED";
- case 0xC00000A1: return "STATUS_WORKING_SET_QUOTA";
- case 0xC00000A2: return "STATUS_MEDIA_WRITE_PROTECTED";
- case 0xC00000A3: return "STATUS_DEVICE_NOT_READY";
- case 0xC00000A4: return "STATUS_INVALID_GROUP_ATTRIBUTES";
- case 0xC00000A5: return "STATUS_BAD_IMPERSONATION_LEVEL";
- case 0xC00000A6: return "STATUS_CANT_OPEN_ANONYMOUS";
- case 0xC00000A7: return "STATUS_BAD_VALIDATION_CLASS";
- case 0xC00000A8: return "STATUS_BAD_TOKEN_TYPE";
- case 0xC00000A9: return "STATUS_BAD_MASTER_BOOT_RECORD";
- case 0xC00000AA: return "STATUS_INSTRUCTION_MISALIGNMENT";
- case 0xC00000AB: return "STATUS_INSTANCE_NOT_AVAILABLE";
- case 0xC00000AC: return "STATUS_PIPE_NOT_AVAILABLE";
- case 0xC00000AD: return "STATUS_INVALID_PIPE_STATE";
- case 0xC00000AE: return "STATUS_PIPE_BUSY";
- case 0xC00000AF: return "STATUS_ILLEGAL_FUNCTION";
- case 0xC00000B0: return "STATUS_PIPE_DISCONNECTED";
- case 0xC00000B1: return "STATUS_PIPE_CLOSING";
- case 0xC00000B2: return "STATUS_PIPE_CONNECTED";
- case 0xC00000B3: return "STATUS_PIPE_LISTENING";
- case 0xC00000B4: return "STATUS_INVALID_READ_MODE";
- case 0xC00000B5: return "STATUS_IO_TIMEOUT";
- case 0xC00000B6: return "STATUS_FILE_FORCED_CLOSED";
- case 0xC00000B7: return "STATUS_PROFILING_NOT_STARTED";
- case 0xC00000B8: return "STATUS_PROFILING_NOT_STOPPED";
- case 0xC00000B9: return "STATUS_COULD_NOT_INTERPRET";
- case 0xC00000BA: return "STATUS_FILE_IS_A_DIRECTORY";
- case 0xC00000BB: return "STATUS_NOT_SUPPORTED";
- case 0xC00000BC: return "STATUS_REMOTE_NOT_LISTENING";
- case 0xC00000BD: return "STATUS_DUPLICATE_NAME";
- case 0xC00000BE: return "STATUS_BAD_NETWORK_PATH";
- case 0xC00000BF: return "STATUS_NETWORK_BUSY";
- case 0xC00000C0: return "STATUS_DEVICE_DOES_NOT_EXIST";
- case 0xC00000C1: return "STATUS_TOO_MANY_COMMANDS";
- case 0xC00000C2: return "STATUS_ADAPTER_HARDWARE_ERROR";
- case 0xC00000C3: return "STATUS_INVALID_NETWORK_RESPONSE";
- case 0xC00000C4: return "STATUS_UNEXPECTED_NETWORK_ERROR";
- case 0xC00000C5: return "STATUS_BAD_REMOTE_ADAPTER";
- case 0xC00000C6: return "STATUS_PRINT_QUEUE_FULL";
- case 0xC00000C7: return "STATUS_NO_SPOOL_SPACE";
- case 0xC00000C8: return "STATUS_PRINT_CANCELLED";
- case 0xC00000C9: return "STATUS_NETWORK_NAME_DELETED";
- case 0xC00000CA: return "STATUS_NETWORK_ACCESS_DENIED";
- case 0xC00000CB: return "STATUS_BAD_DEVICE_TYPE";
- case 0xC00000CC: return "STATUS_BAD_NETWORK_NAME";
- case 0xC00000CD: return "STATUS_TOO_MANY_NAMES";
- case 0xC00000CE: return "STATUS_TOO_MANY_SESSIONS";
- case 0xC00000CF: return "STATUS_SHARING_PAUSED";
- case 0xC00000D0: return "STATUS_REQUEST_NOT_ACCEPTED";
- case 0xC00000D1: return "STATUS_REDIRECTOR_PAUSED";
- case 0xC00000D2: return "STATUS_NET_WRITE_FAULT";
- case 0xC00000D3: return "STATUS_PROFILING_AT_LIMIT";
- case 0xC00000D4: return "STATUS_NOT_SAME_DEVICE";
- case 0xC00000D5: return "STATUS_FILE_RENAMED";
- case 0xC00000D6: return "STATUS_VIRTUAL_CIRCUIT_CLOSED";
- case 0xC00000D7: return "STATUS_NO_SECURITY_ON_OBJECT";
- case 0xC00000D8: return "STATUS_CANT_WAIT";
- case 0xC00000D9: return "STATUS_PIPE_EMPTY";
- case 0xC00000DA: return "STATUS_CANT_ACCESS_DOMAIN_INFO";
- case 0xC00000DB: return "STATUS_CANT_TERMINATE_SELF";
- case 0xC00000DC: return "STATUS_INVALID_SERVER_STATE";
- case 0xC00000DD: return "STATUS_INVALID_DOMAIN_STATE";
- case 0xC00000DE: return "STATUS_INVALID_DOMAIN_ROLE";
- case 0xC00000DF: return "STATUS_NO_SUCH_DOMAIN";
- case 0xC00000E0: return "STATUS_DOMAIN_EXISTS";
- case 0xC00000E1: return "STATUS_DOMAIN_LIMIT_EXCEEDED";
- case 0xC00000E2: return "STATUS_OPLOCK_NOT_GRANTED";
- case 0xC00000E3: return "STATUS_INVALID_OPLOCK_PROTOCOL";
- case 0xC00000E4: return "STATUS_INTERNAL_DB_CORRUPTION";
- case 0xC00000E5: return "STATUS_INTERNAL_ERROR";
- case 0xC00000E6: return "STATUS_GENERIC_NOT_MAPPED";
- case 0xC00000E7: return "STATUS_BAD_DESCRIPTOR_FORMAT";
- case 0xC00000E8: return "STATUS_INVALID_USER_BUFFER";
- case 0xC00000E9: return "STATUS_UNEXPECTED_IO_ERROR";
- case 0xC00000EA: return "STATUS_UNEXPECTED_MM_CREATE_ERR";
- case 0xC00000EB: return "STATUS_UNEXPECTED_MM_MAP_ERROR";
- case 0xC00000EC: return "STATUS_UNEXPECTED_MM_EXTEND_ERR";
- case 0xC00000ED: return "STATUS_NOT_LOGON_PROCESS";
- case 0xC00000EE: return "STATUS_LOGON_SESSION_EXISTS";
- case 0xC00000EF: return "STATUS_INVALID_PARAMETER_1";
- case 0xC00000F0: return "STATUS_INVALID_PARAMETER_2";
- case 0xC00000F1: return "STATUS_INVALID_PARAMETER_3";
- case 0xC00000F2: return "STATUS_INVALID_PARAMETER_4";
- case 0xC00000F3: return "STATUS_INVALID_PARAMETER_5";
- case 0xC00000F4: return "STATUS_INVALID_PARAMETER_6";
- case 0xC00000F5: return "STATUS_INVALID_PARAMETER_7";
- case 0xC00000F6: return "STATUS_INVALID_PARAMETER_8";
- case 0xC00000F7: return "STATUS_INVALID_PARAMETER_9";
- case 0xC00000F8: return "STATUS_INVALID_PARAMETER_10";
- case 0xC00000F9: return "STATUS_INVALID_PARAMETER_11";
- case 0xC00000FA: return "STATUS_INVALID_PARAMETER_12";
- case 0xC00000FB: return "STATUS_REDIRECTOR_NOT_STARTED";
- case 0xC00000FC: return "STATUS_REDIRECTOR_STARTED";
- case 0xC00000FD: return "STATUS_STACK_OVERFLOW";
- case 0xC00000FE: return "STATUS_NO_SUCH_PACKAGE";
- case 0xC00000FF: return "STATUS_BAD_FUNCTION_TABLE";
- case 0xC0000100: return "STATUS_VARIABLE_NOT_FOUND";
- case 0xC0000101: return "STATUS_DIRECTORY_NOT_EMPTY";
- case 0xC0000102: return "STATUS_FILE_CORRUPT_ERROR";
- case 0xC0000103: return "STATUS_NOT_A_DIRECTORY";
- case 0xC0000104: return "STATUS_BAD_LOGON_SESSION_STATE";
- case 0xC0000105: return "STATUS_LOGON_SESSION_COLLISION";
- case 0xC0000106: return "STATUS_NAME_TOO_LONG";
- case 0xC0000107: return "STATUS_FILES_OPEN";
- case 0xC0000108: return "STATUS_CONNECTION_IN_USE";
- case 0xC0000109: return "STATUS_MESSAGE_NOT_FOUND";
- case 0xC000010A: return "STATUS_PROCESS_IS_TERMINATING";
- case 0xC000010B: return "STATUS_INVALID_LOGON_TYPE";
- case 0xC000010C: return "STATUS_NO_GUID_TRANSLATION";
- case 0xC000010D: return "STATUS_CANNOT_IMPERSONATE";
- case 0xC000010E: return "STATUS_IMAGE_ALREADY_LOADED";
- case 0xC000010F: return "STATUS_ABIOS_NOT_PRESENT";
- case 0xC0000110: return "STATUS_ABIOS_LID_NOT_EXIST";
- case 0xC0000111: return "STATUS_ABIOS_LID_ALREADY_OWNED";
- case 0xC0000112: return "STATUS_ABIOS_NOT_LID_OWNER";
- case 0xC0000113: return "STATUS_ABIOS_INVALID_COMMAND";
- case 0xC0000114: return "STATUS_ABIOS_INVALID_LID";
- case 0xC0000115: return "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE";
- case 0xC0000116: return "STATUS_ABIOS_INVALID_SELECTOR";
- case 0xC0000117: return "STATUS_NO_LDT";
- case 0xC0000118: return "STATUS_INVALID_LDT_SIZE";
- case 0xC0000119: return "STATUS_INVALID_LDT_OFFSET";
- case 0xC000011A: return "STATUS_INVALID_LDT_DESCRIPTOR";
- case 0xC000011B: return "STATUS_INVALID_IMAGE_NE_FORMAT";
- case 0xC000011C: return "STATUS_RXACT_INVALID_STATE";
- case 0xC000011D: return "STATUS_RXACT_COMMIT_FAILURE";
- case 0xC000011E: return "STATUS_MAPPED_FILE_SIZE_ZERO";
- case 0xC000011F: return "STATUS_TOO_MANY_OPENED_FILES";
- case 0xC0000120: return "STATUS_CANCELLED";
- case 0xC0000121: return "STATUS_CANNOT_DELETE";
- case 0xC0000122: return "STATUS_INVALID_COMPUTER_NAME";
- case 0xC0000123: return "STATUS_FILE_DELETED";
- case 0xC0000124: return "STATUS_SPECIAL_ACCOUNT";
- case 0xC0000125: return "STATUS_SPECIAL_GROUP";
- case 0xC0000126: return "STATUS_SPECIAL_USER";
- case 0xC0000127: return "STATUS_MEMBERS_PRIMARY_GROUP";
- case 0xC0000128: return "STATUS_FILE_CLOSED";
- case 0xC0000129: return "STATUS_TOO_MANY_THREADS";
- case 0xC000012A: return "STATUS_THREAD_NOT_IN_PROCESS";
- case 0xC000012B: return "STATUS_TOKEN_ALREADY_IN_USE";
- case 0xC000012C: return "STATUS_PAGEFILE_QUOTA_EXCEEDED";
- case 0xC000012D: return "STATUS_COMMITMENT_LIMIT";
- case 0xC000012E: return "STATUS_INVALID_IMAGE_LE_FORMAT";
- case 0xC000012F: return "STATUS_INVALID_IMAGE_NOT_MZ";
- case 0xC0000130: return "STATUS_INVALID_IMAGE_PROTECT";
- case 0xC0000131: return "STATUS_INVALID_IMAGE_WIN_16";
- case 0xC0000132: return "STATUS_LOGON_SERVER_CONFLICT";
- case 0xC0000133: return "STATUS_TIME_DIFFERENCE_AT_DC";
- case 0xC0000134: return "STATUS_SYNCHRONIZATION_REQUIRED";
- case 0xC0000135: return "STATUS_DLL_NOT_FOUND";
- case 0xC0000136: return "STATUS_OPEN_FAILED";
- case 0xC0000137: return "STATUS_IO_PRIVILEGE_FAILED";
- case 0xC0000138: return "STATUS_ORDINAL_NOT_FOUND";
- case 0xC0000139: return "STATUS_ENTRYPOINT_NOT_FOUND";
- case 0xC000013A: return "STATUS_CONTROL_C_EXIT";
- case 0xC000013B: return "STATUS_LOCAL_DISCONNECT";
- case 0xC000013C: return "STATUS_REMOTE_DISCONNECT";
- case 0xC000013D: return "STATUS_REMOTE_RESOURCES";
- case 0xC000013E: return "STATUS_LINK_FAILED";
- case 0xC000013F: return "STATUS_LINK_TIMEOUT";
- case 0xC0000140: return "STATUS_INVALID_CONNECTION";
- case 0xC0000141: return "STATUS_INVALID_ADDRESS";
- case 0xC0000142: return "STATUS_DLL_INIT_FAILED";
- case 0xC0000143: return "STATUS_MISSING_SYSTEMFILE";
- case 0xC0000144: return "STATUS_UNHANDLED_EXCEPTION";
- case 0xC0000145: return "STATUS_APP_INIT_FAILURE";
- case 0xC0000146: return "STATUS_PAGEFILE_CREATE_FAILED";
- case 0xC0000147: return "STATUS_NO_PAGEFILE";
- case 0xC0000148: return "STATUS_INVALID_LEVEL";
- case 0xC0000149: return "STATUS_WRONG_PASSWORD_CORE";
- case 0xC000014A: return "STATUS_ILLEGAL_FLOAT_CONTEXT";
- case 0xC000014B: return "STATUS_PIPE_BROKEN";
- case 0xC000014C: return "STATUS_REGISTRY_CORRUPT";
- case 0xC000014D: return "STATUS_REGISTRY_IO_FAILED";
- case 0xC000014E: return "STATUS_NO_EVENT_PAIR";
- case 0xC000014F: return "STATUS_UNRECOGNIZED_VOLUME";
- case 0xC0000150: return "STATUS_SERIAL_NO_DEVICE_INITED";
- case 0xC0000151: return "STATUS_NO_SUCH_ALIAS";
- case 0xC0000152: return "STATUS_MEMBER_NOT_IN_ALIAS";
- case 0xC0000153: return "STATUS_MEMBER_IN_ALIAS";
- case 0xC0000154: return "STATUS_ALIAS_EXISTS";
- case 0xC0000155: return "STATUS_LOGON_NOT_GRANTED";
- case 0xC0000156: return "STATUS_TOO_MANY_SECRETS";
- case 0xC0000157: return "STATUS_SECRET_TOO_LONG";
- case 0xC0000158: return "STATUS_INTERNAL_DB_ERROR";
- case 0xC0000159: return "STATUS_FULLSCREEN_MODE";
- case 0xC000015A: return "STATUS_TOO_MANY_CONTEXT_IDS";
- case 0xC000015B: return "STATUS_LOGON_TYPE_NOT_GRANTED";
- case 0xC000015C: return "STATUS_NOT_REGISTRY_FILE";
- case 0xC000015D: return "STATUS_NT_CROSS_ENCRYPTION_REQUIRED";
- case 0xC000015E: return "STATUS_DOMAIN_CTRLR_CONFIG_ERROR";
- case 0xC000015F: return "STATUS_FT_MISSING_MEMBER";
- case 0xC0000160: return "STATUS_ILL_FORMED_SERVICE_ENTRY";
- case 0xC0000161: return "STATUS_ILLEGAL_CHARACTER";
- case 0xC0000162: return "STATUS_UNMAPPABLE_CHARACTER";
- case 0xC0000163: return "STATUS_UNDEFINED_CHARACTER";
- case 0xC0000164: return "STATUS_FLOPPY_VOLUME";
- case 0xC0000165: return "STATUS_FLOPPY_ID_MARK_NOT_FOUND";
- case 0xC0000166: return "STATUS_FLOPPY_WRONG_CYLINDER";
- case 0xC0000167: return "STATUS_FLOPPY_UNKNOWN_ERROR";
- case 0xC0000168: return "STATUS_FLOPPY_BAD_REGISTERS";
- case 0xC0000169: return "STATUS_DISK_RECALIBRATE_FAILED";
- case 0xC000016A: return "STATUS_DISK_OPERATION_FAILED";
- case 0xC000016B: return "STATUS_DISK_RESET_FAILED";
- case 0xC000016C: return "STATUS_SHARED_IRQ_BUSY";
- case 0xC000016D: return "STATUS_FT_ORPHANING";
- case 0xC000016E: return "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT";
- case 0xC0000172: return "STATUS_PARTITION_FAILURE";
- case 0xC0000173: return "STATUS_INVALID_BLOCK_LENGTH";
- case 0xC0000174: return "STATUS_DEVICE_NOT_PARTITIONED";
- case 0xC0000175: return "STATUS_UNABLE_TO_LOCK_MEDIA";
- case 0xC0000176: return "STATUS_UNABLE_TO_UNLOAD_MEDIA";
- case 0xC0000177: return "STATUS_EOM_OVERFLOW";
- case 0xC0000178: return "STATUS_NO_MEDIA";
- case 0xC000017A: return "STATUS_NO_SUCH_MEMBER";
- case 0xC000017B: return "STATUS_INVALID_MEMBER";
- case 0xC000017C: return "STATUS_KEY_DELETED";
- case 0xC000017D: return "STATUS_NO_LOG_SPACE";
- case 0xC000017E: return "STATUS_TOO_MANY_SIDS";
- case 0xC000017F: return "STATUS_LM_CROSS_ENCRYPTION_REQUIRED";
- case 0xC0000180: return "STATUS_KEY_HAS_CHILDREN";
- case 0xC0000181: return "STATUS_CHILD_MUST_BE_VOLATILE";
- case 0xC0000182: return "STATUS_DEVICE_CONFIGURATION_ERROR";
- case 0xC0000183: return "STATUS_DRIVER_INTERNAL_ERROR";
- case 0xC0000184: return "STATUS_INVALID_DEVICE_STATE";
- case 0xC0000185: return "STATUS_IO_DEVICE_ERROR";
- case 0xC0000186: return "STATUS_DEVICE_PROTOCOL_ERROR";
- case 0xC0000187: return "STATUS_BACKUP_CONTROLLER";
- case 0xC0000188: return "STATUS_LOG_FILE_FULL";
- case 0xC0000189: return "STATUS_TOO_LATE";
- case 0xC000018A: return "STATUS_NO_TRUST_LSA_SECRET";
- case 0xC000018B: return "STATUS_NO_TRUST_SAM_ACCOUNT";
- case 0xC000018C: return "STATUS_TRUSTED_DOMAIN_FAILURE";
- case 0xC000018D: return "STATUS_TRUSTED_RELATIONSHIP_FAILURE";
- case 0xC000018E: return "STATUS_EVENTLOG_FILE_CORRUPT";
- case 0xC000018F: return "STATUS_EVENTLOG_CANT_START";
- case 0xC0000190: return "STATUS_TRUST_FAILURE";
- case 0xC0000191: return "STATUS_MUTANT_LIMIT_EXCEEDED";
- case 0xC0000192: return "STATUS_NETLOGON_NOT_STARTED";
- case 0xC0000193: return "STATUS_ACCOUNT_EXPIRED";
- case 0xC0000194: return "STATUS_POSSIBLE_DEADLOCK";
- case 0xC0000195: return "STATUS_NETWORK_CREDENTIAL_CONFLICT";
- case 0xC0000196: return "STATUS_REMOTE_SESSION_LIMIT";
- case 0xC0000197: return "STATUS_EVENTLOG_FILE_CHANGED";
- case 0xC0000198: return "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT";
- case 0xC0000199: return "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT";
- case 0xC000019A: return "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT";
- case 0xC000019B: return "STATUS_DOMAIN_TRUST_INCONSISTENT";
- case 0xC000019C: return "STATUS_FS_DRIVER_REQUIRED";
- case 0xC0000202: return "STATUS_NO_USER_SESSION_KEY";
- case 0xC0000203: return "STATUS_USER_SESSION_DELETED";
- case 0xC0000204: return "STATUS_RESOURCE_LANG_NOT_FOUND";
- case 0xC0000205: return "STATUS_INSUFF_SERVER_RESOURCES";
- case 0xC0000206: return "STATUS_INVALID_BUFFER_SIZE";
- case 0xC0000207: return "STATUS_INVALID_ADDRESS_COMPONENT";
- case 0xC0000208: return "STATUS_INVALID_ADDRESS_WILDCARD";
- case 0xC0000209: return "STATUS_TOO_MANY_ADDRESSES";
- case 0xC000020A: return "STATUS_ADDRESS_ALREADY_EXISTS";
- case 0xC000020B: return "STATUS_ADDRESS_CLOSED";
- case 0xC000020C: return "STATUS_CONNECTION_DISCONNECTED";
- case 0xC000020D: return "STATUS_CONNECTION_RESET";
- case 0xC000020E: return "STATUS_TOO_MANY_NODES";
- case 0xC000020F: return "STATUS_TRANSACTION_ABORTED";
- case 0xC0000210: return "STATUS_TRANSACTION_TIMED_OUT";
- case 0xC0000211: return "STATUS_TRANSACTION_NO_RELEASE";
- case 0xC0000212: return "STATUS_TRANSACTION_NO_MATCH";
- case 0xC0000213: return "STATUS_TRANSACTION_RESPONDED";
- case 0xC0000214: return "STATUS_TRANSACTION_INVALID_ID";
- case 0xC0000215: return "STATUS_TRANSACTION_INVALID_TYPE";
- case 0xC0000216: return "STATUS_NOT_SERVER_SESSION";
- case 0xC0000217: return "STATUS_NOT_CLIENT_SESSION";
- case 0xC0000218: return "STATUS_CANNOT_LOAD_REGISTRY_FILE";
- case 0xC0000219: return "STATUS_DEBUG_ATTACH_FAILED";
- case 0xC000021A: return "STATUS_SYSTEM_PROCESS_TERMINATED";
- case 0xC000021B: return "STATUS_DATA_NOT_ACCEPTED";
- case 0xC000021C: return "STATUS_NO_BROWSER_SERVERS_FOUND";
- case 0xC000021D: return "STATUS_VDM_HARD_ERROR";
- case 0xC000021E: return "STATUS_DRIVER_CANCEL_TIMEOUT";
- case 0xC000021F: return "STATUS_REPLY_MESSAGE_MISMATCH";
- case 0xC0000220: return "STATUS_MAPPED_ALIGNMENT";
- case 0xC0000221: return "STATUS_IMAGE_CHECKSUM_MISMATCH";
- case 0xC0000222: return "STATUS_LOST_WRITEBEHIND_DATA";
- case 0xC0000223: return "STATUS_CLIENT_SERVER_PARAMETERS_INVALID";
- case 0xC0000224: return "STATUS_PASSWORD_MUST_CHANGE";
- case 0xC0000225: return "STATUS_NOT_FOUND";
- case 0xC0000226: return "STATUS_NOT_TINY_STREAM";
- case 0xC0000227: return "STATUS_RECOVERY_FAILURE";
- case 0xC0000228: return "STATUS_STACK_OVERFLOW_READ";
- case 0xC0000229: return "STATUS_FAIL_CHECK";
- case 0xC000022A: return "STATUS_DUPLICATE_OBJECTID";
- case 0xC000022B: return "STATUS_OBJECTID_EXISTS";
- case 0xC000022C: return "STATUS_CONVERT_TO_LARGE";
- case 0xC000022D: return "STATUS_RETRY";
- case 0xC000022E: return "STATUS_FOUND_OUT_OF_SCOPE";
- case 0xC000022F: return "STATUS_ALLOCATE_BUCKET";
- case 0xC0000230: return "STATUS_PROPSET_NOT_FOUND";
- case 0xC0000231: return "STATUS_MARSHALL_OVERFLOW";
- case 0xC0000232: return "STATUS_INVALID_VARIANT";
- case 0xC0000233: return "STATUS_DOMAIN_CONTROLLER_NOT_FOUND";
- case 0xC0000234: return "STATUS_ACCOUNT_LOCKED_OUT";
- case 0xC0000235: return "STATUS_HANDLE_NOT_CLOSABLE";
- case 0xC0000236: return "STATUS_CONNECTION_REFUSED";
- case 0xC0000237: return "STATUS_GRACEFUL_DISCONNECT";
- case 0xC0000238: return "STATUS_ADDRESS_ALREADY_ASSOCIATED";
- case 0xC0000239: return "STATUS_ADDRESS_NOT_ASSOCIATED";
- case 0xC000023A: return "STATUS_CONNECTION_INVALID";
- case 0xC000023B: return "STATUS_CONNECTION_ACTIVE";
- case 0xC000023C: return "STATUS_NETWORK_UNREACHABLE";
- case 0xC000023D: return "STATUS_HOST_UNREACHABLE";
- case 0xC000023E: return "STATUS_PROTOCOL_UNREACHABLE";
- case 0xC000023F: return "STATUS_PORT_UNREACHABLE";
- case 0xC0000240: return "STATUS_REQUEST_ABORTED";
- case 0xC0000241: return "STATUS_CONNECTION_ABORTED";
- case 0xC0000242: return "STATUS_BAD_COMPRESSION_BUFFER";
- case 0xC0000243: return "STATUS_USER_MAPPED_FILE";
- case 0xC0000244: return "STATUS_AUDIT_FAILED";
- case 0xC0000245: return "STATUS_TIMER_RESOLUTION_NOT_SET";
- case 0xC0000246: return "STATUS_CONNECTION_COUNT_LIMIT";
- case 0xC0000247: return "STATUS_LOGIN_TIME_RESTRICTION";
- case 0xC0000248: return "STATUS_LOGIN_WKSTA_RESTRICTION";
- case 0xC0000249: return "STATUS_IMAGE_MP_UP_MISMATCH";
- case 0xC0000250: return "STATUS_INSUFFICIENT_LOGON_INFO";
- case 0xC0000251: return "STATUS_BAD_DLL_ENTRYPOINT";
- case 0xC0000252: return "STATUS_BAD_SERVICE_ENTRYPOINT";
- case 0xC0000253: return "STATUS_LPC_REPLY_LOST";
- case 0xC0000254: return "STATUS_IP_ADDRESS_CONFLICT1";
- case 0xC0000255: return "STATUS_IP_ADDRESS_CONFLICT2";
- case 0xC0000256: return "STATUS_REGISTRY_QUOTA_LIMIT";
- case 0xC0000257: return "STATUS_PATH_NOT_COVERED";
- case 0xC0000258: return "STATUS_NO_CALLBACK_ACTIVE";
- case 0xC0000259: return "STATUS_LICENSE_QUOTA_EXCEEDED";
- case 0xC000025A: return "STATUS_PWD_TOO_SHORT";
- case 0xC000025B: return "STATUS_PWD_TOO_RECENT";
- case 0xC000025C: return "STATUS_PWD_HISTORY_CONFLICT";
- case 0xC000025E: return "STATUS_PLUGPLAY_NO_DEVICE";
- case 0xC000025F: return "STATUS_UNSUPPORTED_COMPRESSION";
- case 0xC0000260: return "STATUS_INVALID_HW_PROFILE";
- case 0xC0000261: return "STATUS_INVALID_PLUGPLAY_DEVICE_PATH";
- case 0xC0000262: return "STATUS_DRIVER_ORDINAL_NOT_FOUND";
- case 0xC0000263: return "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND";
- case 0xC0000264: return "STATUS_RESOURCE_NOT_OWNED";
- case 0xC0000265: return "STATUS_TOO_MANY_LINKS";
- case 0xC0000266: return "STATUS_QUOTA_LIST_INCONSISTENT";
- case 0xC0000267: return "STATUS_FILE_IS_OFFLINE";
- case 0xC0000268: return "STATUS_EVALUATION_EXPIRATION";
- case 0xC0000269: return "STATUS_ILLEGAL_DLL_RELOCATION";
- case 0xC000026A: return "STATUS_LICENSE_VIOLATION";
- case 0xC000026B: return "STATUS_DLL_INIT_FAILED_LOGOFF";
- case 0xC000026C: return "STATUS_DRIVER_UNABLE_TO_LOAD";
- case 0xC000026D: return "STATUS_DFS_UNAVAILABLE";
- case 0xC000026E: return "STATUS_VOLUME_DISMOUNTED";
- case 0xC000026F: return "STATUS_WX86_INTERNAL_ERROR";
- case 0xC0000270: return "STATUS_WX86_FLOAT_STACK_CHECK";
- case 0xC0000271: return "STATUS_VALIDATE_CONTINUE";
- case 0xC0000272: return "STATUS_NO_MATCH";
- case 0xC0000273: return "STATUS_NO_MORE_MATCHES";
- case 0xC0000275: return "STATUS_NOT_A_REPARSE_POINT";
- case 0xC0000276: return "STATUS_IO_REPARSE_TAG_INVALID";
- case 0xC0000277: return "STATUS_IO_REPARSE_TAG_MISMATCH";
- case 0xC0000278: return "STATUS_IO_REPARSE_DATA_INVALID";
- case 0xC0000279: return "STATUS_IO_REPARSE_TAG_NOT_HANDLED";
- case 0xC0000280: return "STATUS_REPARSE_POINT_NOT_RESOLVED";
- case 0xC0000281: return "STATUS_DIRECTORY_IS_A_REPARSE_POINT";
- case 0xC0000282: return "STATUS_RANGE_LIST_CONFLICT";
- case 0xC0000283: return "STATUS_SOURCE_ELEMENT_EMPTY";
- case 0xC0000284: return "STATUS_DESTINATION_ELEMENT_FULL";
- case 0xC0000285: return "STATUS_ILLEGAL_ELEMENT_ADDRESS";
- case 0xC0000286: return "STATUS_MAGAZINE_NOT_PRESENT";
- case 0xC0000287: return "STATUS_REINITIALIZATION_NEEDED";
- case 0x80000288: return "STATUS_DEVICE_REQUIRES_CLEANING";
- case 0x80000289: return "STATUS_DEVICE_DOOR_OPEN";
- case 0xC000028A: return "STATUS_ENCRYPTION_FAILED";
- case 0xC000028B: return "STATUS_DECRYPTION_FAILED";
- case 0xC000028C: return "STATUS_RANGE_NOT_FOUND";
- case 0xC000028D: return "STATUS_NO_RECOVERY_POLICY";
- case 0xC000028E: return "STATUS_NO_EFS";
- case 0xC000028F: return "STATUS_WRONG_EFS";
- case 0xC0000290: return "STATUS_NO_USER_KEYS";
- case 0xC0000291: return "STATUS_FILE_NOT_ENCRYPTED";
- case 0xC0000292: return "STATUS_NOT_EXPORT_FORMAT";
- case 0xC0000293: return "STATUS_FILE_ENCRYPTED";
- case 0x40000294: return "STATUS_WAKE_SYSTEM";
- case 0xC0000295: return "STATUS_WMI_GUID_NOT_FOUND";
- case 0xC0000296: return "STATUS_WMI_INSTANCE_NOT_FOUND";
- case 0xC0000297: return "STATUS_WMI_ITEMID_NOT_FOUND";
- case 0xC0000298: return "STATUS_WMI_TRY_AGAIN";
- case 0xC0000299: return "STATUS_SHARED_POLICY";
- case 0xC000029A: return "STATUS_POLICY_OBJECT_NOT_FOUND";
- case 0xC000029B: return "STATUS_POLICY_ONLY_IN_DS";
- case 0xC000029C: return "STATUS_VOLUME_NOT_UPGRADED";
- case 0xC000029D: return "STATUS_REMOTE_STORAGE_NOT_ACTIVE";
- case 0xC000029E: return "STATUS_REMOTE_STORAGE_MEDIA_ERROR";
- case 0xC000029F: return "STATUS_NO_TRACKING_SERVICE";
- case 0xC00002A0: return "STATUS_SERVER_SID_MISMATCH";
- case 0xC00002A1: return "STATUS_DS_NO_ATTRIBUTE_OR_VALUE";
- case 0xC00002A2: return "STATUS_DS_INVALID_ATTRIBUTE_SYNTAX";
- case 0xC00002A3: return "STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED";
- case 0xC00002A4: return "STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS";
- case 0xC00002A5: return "STATUS_DS_BUSY";
- case 0xC00002A6: return "STATUS_DS_UNAVAILABLE";
- case 0xC00002A7: return "STATUS_DS_NO_RIDS_ALLOCATED";
- case 0xC00002A8: return "STATUS_DS_NO_MORE_RIDS";
- case 0xC00002A9: return "STATUS_DS_INCORRECT_ROLE_OWNER";
- case 0xC00002AA: return "STATUS_DS_RIDMGR_INIT_ERROR";
- case 0xC00002AB: return "STATUS_DS_OBJ_CLASS_VIOLATION";
- case 0xC00002AC: return "STATUS_DS_CANT_ON_NON_LEAF";
- case 0xC00002AD: return "STATUS_DS_CANT_ON_RDN";
- case 0xC00002AE: return "STATUS_DS_CANT_MOD_OBJ_CLASS";
- case 0xC00002AF: return "STATUS_DS_CROSS_DOM_MOVE_FAILED";
- case 0xC00002B0: return "STATUS_DS_GC_NOT_AVAILABLE";
- case 0xC00002B1: return "STATUS_DIRECTORY_SERVICE_REQUIRED";
- case 0xC00002B2: return "STATUS_REPARSE_ATTRIBUTE_CONFLICT";
- case 0xC00002B3: return "STATUS_CANT_ENABLE_DENY_ONLY";
- case 0xC00002B4: return "STATUS_FLOAT_MULTIPLE_FAULTS";
- case 0xC00002B5: return "STATUS_FLOAT_MULTIPLE_TRAPS";
- case 0xC00002B6: return "STATUS_DEVICE_REMOVED";
- case 0xC00002B7: return "STATUS_JOURNAL_DELETE_IN_PROGRESS";
- case 0xC00002B8: return "STATUS_JOURNAL_NOT_ACTIVE";
- case 0xC00002B9: return "STATUS_NOINTERFACE";
- case 0xC00002C1: return "STATUS_DS_ADMIN_LIMIT_EXCEEDED";
- case 0xC00002C2: return "STATUS_DRIVER_FAILED_SLEEP";
- case 0xC00002C3: return "STATUS_MUTUAL_AUTHENTICATION_FAILED";
- case 0xC00002C4: return "STATUS_CORRUPT_SYSTEM_FILE";
- case 0xC00002C5: return "STATUS_DATATYPE_MISALIGNMENT_ERROR";
- case 0xC00002C6: return "STATUS_WMI_READ_ONLY";
- case 0xC00002C7: return "STATUS_WMI_SET_FAILURE";
- case 0xC00002C8: return "STATUS_COMMITMENT_MINIMUM";
- case 0xC00002C9: return "STATUS_REG_NAT_CONSUMPTION";
- case 0xC00002CA: return "STATUS_TRANSPORT_FULL";
- case 0xC00002CB: return "STATUS_DS_SAM_INIT_FAILURE";
- case 0xC00002CC: return "STATUS_ONLY_IF_CONNECTED";
- case 0xC00002CD: return "STATUS_DS_SENSITIVE_GROUP_VIOLATION";
- case 0xC00002CE: return "STATUS_PNP_RESTART_ENUMERATION";
- case 0xC00002CF: return "STATUS_JOURNAL_ENTRY_DELETED";
- case 0xC00002D0: return "STATUS_DS_CANT_MOD_PRIMARYGROUPID";
- case 0xC00002D1: return "STATUS_SYSTEM_IMAGE_BAD_SIGNATURE";
- case 0xC00002D2: return "STATUS_PNP_REBOOT_REQUIRED";
- case 0xC00002D3: return "STATUS_POWER_STATE_INVALID";
- case 0xC00002D4: return "STATUS_DS_INVALID_GROUP_TYPE";
- case 0xC00002D5: return "STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN";
- case 0xC00002D6: return "STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN";
- case 0xC00002D7: return "STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER";
- case 0xC00002D8: return "STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER";
- case 0xC00002D9: return "STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER";
- case 0xC00002DA: return "STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER";
- case 0xC00002DB: return "STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER";
- case 0xC00002DC: return "STATUS_DS_HAVE_PRIMARY_MEMBERS";
- case 0xC00002DD: return "STATUS_WMI_NOT_SUPPORTED";
- case 0xC00002DE: return "STATUS_INSUFFICIENT_POWER";
- case 0xC00002DF: return "STATUS_SAM_NEED_BOOTKEY_PASSWORD";
- case 0xC00002E0: return "STATUS_SAM_NEED_BOOTKEY_FLOPPY";
- case 0xC00002E1: return "STATUS_DS_CANT_START";
- case 0xC00002E2: return "STATUS_DS_INIT_FAILURE";
- case 0xC00002E3: return "STATUS_SAM_INIT_FAILURE";
- case 0xC00002E4: return "STATUS_DS_GC_REQUIRED";
- case 0xC00002E5: return "STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY";
- case 0xC00002E6: return "STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS";
- case 0xC00002E7: return "STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED";
- case 0xC00002E8: return "STATUS_MULTIPLE_FAULT_VIOLATION";
- case 0xC0000300: return "STATUS_NOT_SUPPORTED_ON_SBS";
- case 0xC0009898: return "STATUS_WOW_ASSERTION";
- case 0xC0010001: return "DBG_NO_STATE_CHANGE";
- case 0xC0010002: return "DBG_APP_NOT_IDLE";
- case 0xC0020001: return "RPC_NT_INVALID_STRING_BINDING";
- case 0xC0020002: return "RPC_NT_WRONG_KIND_OF_BINDING";
- case 0xC0020003: return "RPC_NT_INVALID_BINDING";
- case 0xC0020004: return "RPC_NT_PROTSEQ_NOT_SUPPORTED";
- case 0xC0020005: return "RPC_NT_INVALID_RPC_PROTSEQ";
- case 0xC0020006: return "RPC_NT_INVALID_STRING_UUID";
- case 0xC0020007: return "RPC_NT_INVALID_ENDPOINT_FORMAT";
- case 0xC0020008: return "RPC_NT_INVALID_NET_ADDR";
- case 0xC0020009: return "RPC_NT_NO_ENDPOINT_FOUND";
- case 0xC002000A: return "RPC_NT_INVALID_TIMEOUT";
- case 0xC002000B: return "RPC_NT_OBJECT_NOT_FOUND";
- case 0xC002000C: return "RPC_NT_ALREADY_REGISTERED";
- case 0xC002000D: return "RPC_NT_TYPE_ALREADY_REGISTERED";
- case 0xC002000E: return "RPC_NT_ALREADY_LISTENING";
- case 0xC002000F: return "RPC_NT_NO_PROTSEQS_REGISTERED";
- case 0xC0020010: return "RPC_NT_NOT_LISTENING";
- case 0xC0020011: return "RPC_NT_UNKNOWN_MGR_TYPE";
- case 0xC0020012: return "RPC_NT_UNKNOWN_IF";
- case 0xC0020013: return "RPC_NT_NO_BINDINGS";
- case 0xC0020014: return "RPC_NT_NO_PROTSEQS";
- case 0xC0020015: return "RPC_NT_CANT_CREATE_ENDPOINT";
- case 0xC0020016: return "RPC_NT_OUT_OF_RESOURCES";
- case 0xC0020017: return "RPC_NT_SERVER_UNAVAILABLE";
- case 0xC0020018: return "RPC_NT_SERVER_TOO_BUSY";
- case 0xC0020019: return "RPC_NT_INVALID_NETWORK_OPTIONS";
- case 0xC002001A: return "RPC_NT_NO_CALL_ACTIVE";
- case 0xC002001B: return "RPC_NT_CALL_FAILED";
- case 0xC002001C: return "RPC_NT_CALL_FAILED_DNE";
- case 0xC002001D: return "RPC_NT_PROTOCOL_ERROR";
- case 0xC002001F: return "RPC_NT_UNSUPPORTED_TRANS_SYN";
- case 0xC0020021: return "RPC_NT_UNSUPPORTED_TYPE";
- case 0xC0020022: return "RPC_NT_INVALID_TAG";
- case 0xC0020023: return "RPC_NT_INVALID_BOUND";
- case 0xC0020024: return "RPC_NT_NO_ENTRY_NAME";
- case 0xC0020025: return "RPC_NT_INVALID_NAME_SYNTAX";
- case 0xC0020026: return "RPC_NT_UNSUPPORTED_NAME_SYNTAX";
- case 0xC0020028: return "RPC_NT_UUID_NO_ADDRESS";
- case 0xC0020029: return "RPC_NT_DUPLICATE_ENDPOINT";
- case 0xC002002A: return "RPC_NT_UNKNOWN_AUTHN_TYPE";
- case 0xC002002B: return "RPC_NT_MAX_CALLS_TOO_SMALL";
- case 0xC002002C: return "RPC_NT_STRING_TOO_LONG";
- case 0xC002002D: return "RPC_NT_PROTSEQ_NOT_FOUND";
- case 0xC002002E: return "RPC_NT_PROCNUM_OUT_OF_RANGE";
- case 0xC002002F: return "RPC_NT_BINDING_HAS_NO_AUTH";
- case 0xC0020030: return "RPC_NT_UNKNOWN_AUTHN_SERVICE";
- case 0xC0020031: return "RPC_NT_UNKNOWN_AUTHN_LEVEL";
- case 0xC0020032: return "RPC_NT_INVALID_AUTH_IDENTITY";
- case 0xC0020033: return "RPC_NT_UNKNOWN_AUTHZ_SERVICE";
- case 0xC0020034: return "EPT_NT_INVALID_ENTRY";
- case 0xC0020035: return "EPT_NT_CANT_PERFORM_OP";
- case 0xC0020036: return "EPT_NT_NOT_REGISTERED";
- case 0xC0020037: return "RPC_NT_NOTHING_TO_EXPORT";
- case 0xC0020038: return "RPC_NT_INCOMPLETE_NAME";
- case 0xC0020039: return "RPC_NT_INVALID_VERS_OPTION";
- case 0xC002003A: return "RPC_NT_NO_MORE_MEMBERS";
- case 0xC002003B: return "RPC_NT_NOT_ALL_OBJS_UNEXPORTED";
- case 0xC002003C: return "RPC_NT_INTERFACE_NOT_FOUND";
- case 0xC002003D: return "RPC_NT_ENTRY_ALREADY_EXISTS";
- case 0xC002003E: return "RPC_NT_ENTRY_NOT_FOUND";
- case 0xC002003F: return "RPC_NT_NAME_SERVICE_UNAVAILABLE";
- case 0xC0020040: return "RPC_NT_INVALID_NAF_ID";
- case 0xC0020041: return "RPC_NT_CANNOT_SUPPORT";
- case 0xC0020042: return "RPC_NT_NO_CONTEXT_AVAILABLE";
- case 0xC0020043: return "RPC_NT_INTERNAL_ERROR";
- case 0xC0020044: return "RPC_NT_ZERO_DIVIDE";
- case 0xC0020045: return "RPC_NT_ADDRESS_ERROR";
- case 0xC0020046: return "RPC_NT_FP_DIV_ZERO";
- case 0xC0020047: return "RPC_NT_FP_UNDERFLOW";
- case 0xC0020048: return "RPC_NT_FP_OVERFLOW";
- case 0xC0030001: return "RPC_NT_NO_MORE_ENTRIES";
- case 0xC0030002: return "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL";
- case 0xC0030003: return "RPC_NT_SS_CHAR_TRANS_SHORT_FILE";
- case 0xC0030004: return "RPC_NT_SS_IN_NULL_CONTEXT";
- case 0xC0030005: return "RPC_NT_SS_CONTEXT_MISMATCH";
- case 0xC0030006: return "RPC_NT_SS_CONTEXT_DAMAGED";
- case 0xC0030007: return "RPC_NT_SS_HANDLES_MISMATCH";
- case 0xC0030008: return "RPC_NT_SS_CANNOT_GET_CALL_HANDLE";
- case 0xC0030009: return "RPC_NT_NULL_REF_POINTER";
- case 0xC003000A: return "RPC_NT_ENUM_VALUE_OUT_OF_RANGE";
- case 0xC003000B: return "RPC_NT_BYTE_COUNT_TOO_SMALL";
- case 0xC003000C: return "RPC_NT_BAD_STUB_DATA";
- case 0xC0020049: return "RPC_NT_CALL_IN_PROGRESS";
- case 0xC002004A: return "RPC_NT_NO_MORE_BINDINGS";
- case 0xC002004B: return "RPC_NT_GROUP_MEMBER_NOT_FOUND";
- case 0xC002004C: return "EPT_NT_CANT_CREATE";
- case 0xC002004D: return "RPC_NT_INVALID_OBJECT";
- case 0xC002004F: return "RPC_NT_NO_INTERFACES";
- case 0xC0020050: return "RPC_NT_CALL_CANCELLED";
- case 0xC0020051: return "RPC_NT_BINDING_INCOMPLETE";
- case 0xC0020052: return "RPC_NT_COMM_FAILURE";
- case 0xC0020053: return "RPC_NT_UNSUPPORTED_AUTHN_LEVEL";
- case 0xC0020054: return "RPC_NT_NO_PRINC_NAME";
- case 0xC0020055: return "RPC_NT_NOT_RPC_ERROR";
- case 0x40020056: return "RPC_NT_UUID_LOCAL_ONLY";
- case 0xC0020057: return "RPC_NT_SEC_PKG_ERROR";
- case 0xC0020058: return "RPC_NT_NOT_CANCELLED";
- case 0xC0030059: return "RPC_NT_INVALID_ES_ACTION";
- case 0xC003005A: return "RPC_NT_WRONG_ES_VERSION";
- case 0xC003005B: return "RPC_NT_WRONG_STUB_VERSION";
- case 0xC003005C: return "RPC_NT_INVALID_PIPE_OBJECT";
- case 0xC003005D: return "RPC_NT_INVALID_PIPE_OPERATION";
- case 0xC003005E: return "RPC_NT_WRONG_PIPE_VERSION";
- case 0xC003005F: return "RPC_NT_PIPE_CLOSED";
- case 0xC0030060: return "RPC_NT_PIPE_DISCIPLINE_ERROR";
- case 0xC0030061: return "RPC_NT_PIPE_EMPTY";
- case 0xC0020062: return "RPC_NT_INVALID_ASYNC_HANDLE";
- case 0xC0020063: return "RPC_NT_INVALID_ASYNC_CALL";
- case 0x400200AF: return "RPC_NT_SEND_INCOMPLETE";
- case 0xC0140001: return "STATUS_ACPI_INVALID_OPCODE";
- case 0xC0140002: return "STATUS_ACPI_STACK_OVERFLOW";
- case 0xC0140003: return "STATUS_ACPI_ASSERT_FAILED";
- case 0xC0140004: return "STATUS_ACPI_INVALID_INDEX";
- case 0xC0140005: return "STATUS_ACPI_INVALID_ARGUMENT";
- case 0xC0140006: return "STATUS_ACPI_FATAL";
- case 0xC0140007: return "STATUS_ACPI_INVALID_SUPERNAME";
- case 0xC0140008: return "STATUS_ACPI_INVALID_ARGTYPE";
- case 0xC0140009: return "STATUS_ACPI_INVALID_OBJTYPE";
- case 0xC014000A: return "STATUS_ACPI_INVALID_TARGETTYPE";
- case 0xC014000B: return "STATUS_ACPI_INCORRECT_ARGUMENT_COUNT";
- case 0xC014000C: return "STATUS_ACPI_ADDRESS_NOT_MAPPED";
- case 0xC014000D: return "STATUS_ACPI_INVALID_EVENTTYPE";
- case 0xC014000E: return "STATUS_ACPI_HANDLER_COLLISION";
- case 0xC014000F: return "STATUS_ACPI_INVALID_DATA";
- case 0xC0140010: return "STATUS_ACPI_INVALID_REGION";
- case 0xC0140011: return "STATUS_ACPI_INVALID_ACCESS_SIZE";
- case 0xC0140012: return "STATUS_ACPI_ACQUIRE_GLOBAL_LOCK";
- case 0xC0140013: return "STATUS_ACPI_ALREADY_INITIALIZED";
- case 0xC0140014: return "STATUS_ACPI_NOT_INITIALIZED";
- case 0xC0140015: return "STATUS_ACPI_INVALID_MUTEX_LEVEL";
- case 0xC0140016: return "STATUS_ACPI_MUTEX_NOT_OWNED";
- case 0xC0140017: return "STATUS_ACPI_MUTEX_NOT_OWNER";
- case 0xC0140018: return "STATUS_ACPI_RS_ACCESS";
- case 0xC0140019: return "STATUS_ACPI_INVALID_TABLE";
- case 0xC0140020: return "STATUS_ACPI_REG_HANDLER_FAILED";
- case 0xC0140021: return "STATUS_ACPI_POWER_REQUEST_FAILED";
- case 0xC00A0001: return "STATUS_CTX_WINSTATION_NAME_INVALID";
- case 0xC00A0002: return "STATUS_CTX_INVALID_PD";
- case 0xC00A0003: return "STATUS_CTX_PD_NOT_FOUND";
- case 0x400A0004: return "STATUS_CTX_CDM_CONNECT";
- case 0x400A0005: return "STATUS_CTX_CDM_DISCONNECT";
- case 0xC00A0006: return "STATUS_CTX_CLOSE_PENDING";
- case 0xC00A0007: return "STATUS_CTX_NO_OUTBUF";
- case 0xC00A0008: return "STATUS_CTX_MODEM_INF_NOT_FOUND";
- case 0xC00A0009: return "STATUS_CTX_INVALID_MODEMNAME";
- case 0xC00A000A: return "STATUS_CTX_RESPONSE_ERROR";
- case 0xC00A000B: return "STATUS_CTX_MODEM_RESPONSE_TIMEOUT";
- case 0xC00A000C: return "STATUS_CTX_MODEM_RESPONSE_NO_CARRIER";
- case 0xC00A000D: return "STATUS_CTX_MODEM_RESPONSE_NO_DIALTONE";
- case 0xC00A000E: return "STATUS_CTX_MODEM_RESPONSE_BUSY";
- case 0xC00A000F: return "STATUS_CTX_MODEM_RESPONSE_VOICE";
- case 0xC00A0010: return "STATUS_CTX_TD_ERROR";
- case 0xC00A0012: return "STATUS_CTX_LICENSE_CLIENT_INVALID";
- case 0xC00A0013: return "STATUS_CTX_LICENSE_NOT_AVAILABLE";
- case 0xC00A0014: return "STATUS_CTX_LICENSE_EXPIRED";
- case 0xC00A0015: return "STATUS_CTX_WINSTATION_NOT_FOUND";
- case 0xC00A0016: return "STATUS_CTX_WINSTATION_NAME_COLLISION";
- case 0xC00A0017: return "STATUS_CTX_WINSTATION_BUSY";
- case 0xC00A0018: return "STATUS_CTX_BAD_VIDEO_MODE";
- case 0xC00A0022: return "STATUS_CTX_GRAPHICS_INVALID";
- case 0xC00A0024: return "STATUS_CTX_NOT_CONSOLE";
- case 0xC00A0026: return "STATUS_CTX_CLIENT_QUERY_TIMEOUT";
- case 0xC00A0027: return "STATUS_CTX_CONSOLE_DISCONNECT";
- case 0xC00A0028: return "STATUS_CTX_CONSOLE_CONNECT";
- case 0xC00A002A: return "STATUS_CTX_SHADOW_DENIED";
- case 0xC00A002B: return "STATUS_CTX_WINSTATION_ACCESS_DENIED";
- case 0xC00A002E: return "STATUS_CTX_INVALID_WD";
- case 0xC00A002F: return "STATUS_CTX_WD_NOT_FOUND";
- case 0xC00A0030: return "STATUS_CTX_SHADOW_INVALID";
- case 0xC00A0031: return "STATUS_CTX_SHADOW_DISABLED";
- case 0xC00A0032: return "STATUS_RDP_PROTOCOL_ERROR";
- case 0xC00A0033: return "STATUS_CTX_CLIENT_LICENSE_NOT_SET";
- case 0xC00A0034: return "STATUS_CTX_CLIENT_LICENSE_IN_USE";
- case 0xC0040035: return "STATUS_PNP_BAD_MPS_TABLE";
- case 0xC0040036: return "STATUS_PNP_TRANSLATION_FAILED";
- case 0xC0040037: return "STATUS_PNP_IRQ_TRANSLATION_FAILED";
- default: return "STATUS_UNKNOWN";
- }
-}
-
-
-/*
- * KsPrintf
- * This function is variable-argument, level-sensitive debug print routine.
- * If the specified debug level for the print statement is lower or equal
- * to the current debug level, the message will be printed.
- *
- * Arguments:
- * DebugPrintLevel - Specifies at which debugging level the string should
- * be printed
- * DebugMessage - Variable argument ascii c string
- *
- * Return Value:
- * N/A
- *
- * NOTES:
- * N/A
- */
-
-VOID
-KsPrintf(
- LONG DebugPrintLevel,
- PCHAR DebugMessage,
- ...
- )
-{
- LARGE_INTEGER tick;
- va_list ap;
-
- va_start(ap, DebugMessage);
- if (DebugPrintLevel <= KsDebugLevel) {
- CHAR buffer[0x200];
- KeQueryTickCount(&tick);
- vsprintf(buffer, DebugMessage, ap);
- KdPrint(("%8.8X cpu:%d:%d tid:%p %s",
- tick.LowPart,
- KeGetCurrentProcessorNumber(),
- KeGetCurrentIrql(),
- PsGetCurrentThread(), buffer));
- }
- va_end(ap);
-
-} // KsPrint()
-
-#endif
-
-
-void libcfs_panic(char *msg)
-{
- DbgPrint("%s", msg);
- cfs_enter_debugger();
-}
-
-/* BUGCHECK callback record */
-static int libcfs_bugcheck_inited = 0;
-KBUGCHECK_CALLBACK_RECORD libcfs_bugcheck_record;
-
-void
-libcfs_bugcheck_callback(
- IN PVOID Buffer,
- IN ULONG Length
- )
-{
- cfs_enter_debugger();
-}
-
-
-void libcfs_register_panic_notifier(void)
-{
- if (libcfs_bugcheck_inited) {
- return;
- }
-
- KeInitializeCallbackRecord(&libcfs_bugcheck_record);
- KeRegisterBugCheckCallback(&libcfs_bugcheck_record,
- libcfs_bugcheck_callback,
- &libcfs_bugcheck_record,
- sizeof(KBUGCHECK_CALLBACK_RECORD),
- "Lustre");
-}
-
-void libcfs_unregister_panic_notifier(void)
-{
- if (!libcfs_bugcheck_inited) {
- return;
- }
-
- KeDeregisterBugCheckCallback(&libcfs_bugcheck_record);
-}
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-# define DEBUG_SUBSYSTEM S_LNET
-
-#include <libcfs/libcfs.h>
-
-const CHAR *dos_file_prefix[] = {
- "\\??\\", "\\DosDevices\\",
- "\\SystemRoot\\", NULL};
-
-/*
- * filp_open
- * To open or create a file in kernel mode
- *
- * Arguments:
- * name: name of the file to be opened or created, no dos path prefix
- * flags: open/creation attribute options
- * mode: access mode/permission to open or create
- * err: error code
- *
- * Return Value:
- * the pointer to the struct file or NULL if it fails
- *
- * Notes:
- * N/A
- */
-
-#define is_drv_letter_valid(x) (((x) >= 0 && (x) <= 9) || \
- ( ((x)|0x20) <= 'z' && ((x)|0x20) >= 'a'))
-
-struct file *filp_open(const char *name, int flags, int mode, int *err)
-{
- struct file *fp = NULL;
-
- NTSTATUS Status;
-
- OBJECT_ATTRIBUTES ObjectAttributes;
- HANDLE FileHandle;
- IO_STATUS_BLOCK IoStatus;
- ACCESS_MASK DesiredAccess;
- ULONG CreateDisposition;
- ULONG ShareAccess;
- ULONG CreateOptions;
-
- USHORT NameLength = 0;
- USHORT PrefixLength = 0;
-
- UNICODE_STRING UnicodeName;
- PWCHAR UnicodeString = NULL;
-
- ANSI_STRING AnsiName;
- PUCHAR AnsiString = NULL;
-
- /* Analyze the flags settings */
- if (cfs_is_flag_set(flags, O_WRONLY)) {
- DesiredAccess = (GENERIC_WRITE | SYNCHRONIZE);
- ShareAccess = 0;
- } else if (cfs_is_flag_set(flags, O_RDWR)) {
- DesiredAccess = (GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE);
- ShareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE;
- } else {
- DesiredAccess = (GENERIC_READ | SYNCHRONIZE);
- ShareAccess = FILE_SHARE_READ;
- }
-
- if (cfs_is_flag_set(flags, O_CREAT)) {
- if (cfs_is_flag_set(flags, O_EXCL)) {
- CreateDisposition = FILE_CREATE;
- } else {
- CreateDisposition = FILE_OPEN_IF;
- }
- } else {
- CreateDisposition = FILE_OPEN;
- }
-
- if (cfs_is_flag_set(flags, O_TRUNC)) {
- if (cfs_is_flag_set(flags, O_EXCL)) {
- CreateDisposition = FILE_OVERWRITE;
- } else {
- CreateDisposition = FILE_OVERWRITE_IF;
- }
- }
-
- CreateOptions = 0;
-
- if (cfs_is_flag_set(flags, O_DIRECTORY)) {
- cfs_set_flag(CreateOptions, FILE_DIRECTORY_FILE);
- }
-
- if (cfs_is_flag_set(flags, O_SYNC)) {
- cfs_set_flag(CreateOptions, FILE_WRITE_THROUGH);
- }
-
- if (cfs_is_flag_set(flags, O_DIRECT)) {
- cfs_set_flag(CreateOptions, FILE_NO_INTERMEDIATE_BUFFERING);
- }
-
- /* Initialize the unicode path name for the specified file */
- NameLength = (USHORT)strlen(name);
-
- /* Check file & path name */
- if (name[0] != '\\') {
- if (NameLength < 1 || name[1] != ':' ||
- !is_drv_letter_valid(name[0])) {
- /* invalid file path name */
- return ERR_PTR(-EINVAL);
- }
- PrefixLength = (USHORT)strlen(dos_file_prefix[0]);
- } else {
- int i, j;
- for (i = 0; i < 3 && dos_file_prefix[i] != NULL; i++) {
- j = strlen(dos_file_prefix[i]);
- if (NameLength > j &&
- _strnicmp(dos_file_prefix[i], name, j) == 0)
- break;
- }
- if (i >= 3)
- return ERR_PTR(-EINVAL);
- }
-
- AnsiString = kmalloc(sizeof(CHAR) * (NameLength + PrefixLength + 1),
- __GFP_ZERO);
- if (NULL == AnsiString)
- return ERR_PTR(-ENOMEM);
-
- UnicodeString =
- kmalloc(sizeof(WCHAR) * (NameLength + PrefixLength + 1),
- __GFP_ZERO);
- if (NULL == UnicodeString) {
- kfree(AnsiString);
- return ERR_PTR(-ENOMEM);
- }
-
- if (PrefixLength) {
- RtlCopyMemory(&AnsiString[0], dos_file_prefix[0], PrefixLength);
- }
-
- RtlCopyMemory(&AnsiString[PrefixLength], name, NameLength);
- NameLength += PrefixLength;
-
- AnsiName.MaximumLength = NameLength + 1;
- AnsiName.Length = NameLength;
- AnsiName.Buffer = AnsiString;
-
- UnicodeName.MaximumLength = (NameLength + 1) * sizeof(WCHAR);
- UnicodeName.Length = 0;
- UnicodeName.Buffer = (PWSTR)UnicodeString;
-
- RtlAnsiStringToUnicodeString(&UnicodeName, &AnsiName, FALSE);
-
- /* Setup the object attributes structure for the file. */
- InitializeObjectAttributes(
- &ObjectAttributes,
- &UnicodeName,
- OBJ_CASE_INSENSITIVE |
- OBJ_KERNEL_HANDLE,
- NULL,
- NULL );
-
- /* Now to open or create the file now */
- Status = ZwCreateFile(
- &FileHandle,
- DesiredAccess,
- &ObjectAttributes,
- &IoStatus,
- 0,
- FILE_ATTRIBUTE_NORMAL,
- ShareAccess,
- CreateDisposition,
- CreateOptions,
- NULL,
- 0 );
-
- /* Check the returned status of IoStatus... */
- if (!NT_SUCCESS(IoStatus.Status)) {
- kfree(UnicodeString);
- kfree(AnsiString);
- return ERR_PTR(cfs_error_code(IoStatus.Status));
- }
-
- /* Allocate the file_t: libcfs file object */
- fp = kmalloc(sizeof(*fp) + NameLength, __GFP_ZERO);
-
- if (NULL == fp) {
- Status = ZwClose(FileHandle);
- ASSERT(NT_SUCCESS(Status));
- kfree(UnicodeString);
- kfree(AnsiString);
- return ERR_PTR(-ENOMEM);
- }
-
- fp->f_handle = FileHandle;
- strcpy(fp->f_name, name);
- fp->f_flags = flags;
- fp->f_mode = (mode_t)mode;
- fp->f_count = 1;
-
- /* free the memory of temporary name strings */
- kfree(UnicodeString);
- kfree(AnsiString);
-
- return fp;
-}
-
-
-/*
- * filp_close
- * To close the opened file and release the filp structure
- *
- * Arguments:
- * fp: the pointer of the file structure
- *
- * Return Value:
- * ZERO: on success
- * Non-Zero: on failure
- *
- * Notes:
- * N/A
- */
-
-int filp_close(file_t *fp, void *id)
-{
- NTSTATUS Status;
-
- ASSERT(fp != NULL);
- ASSERT(fp->f_handle != NULL);
-
- /* release the file handle */
- Status = ZwClose(fp->f_handle);
- ASSERT(NT_SUCCESS(Status));
-
- /* free the file flip structure */
- kfree(fp);
- return 0;
-}
-
-
-NTSTATUS CompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
-{
- /* copy the IoStatus result */
- if (Irp->UserIosb)
- *Irp->UserIosb = Irp->IoStatus;
-
- /* singal the event we set */
- KeSetEvent((PKEVENT) Context, 0, FALSE);
-
- /* free the Irp we allocated */
- IoFreeIrp(Irp);
-
- return STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-
-NTSTATUS cfs_nt_filp_io(HANDLE Handle, BOOLEAN Writing, PLARGE_INTEGER Offset,
- ULONG Length, PUCHAR Buffer, PULONG Bytes)
-{
- NTSTATUS status;
- IO_STATUS_BLOCK iosb;
-
- PIRP irp = NULL;
- PIO_STACK_LOCATION irpSp = NULL;
-
- PFILE_OBJECT fileObject = NULL;
- PDEVICE_OBJECT deviceObject;
-
- KEVENT event;
-
- KeInitializeEvent(&event, SynchronizationEvent, FALSE);
-
- status = ObReferenceObjectByHandle( Handle,
- Writing ? FILE_WRITE_DATA :
- FILE_READ_DATA,
- *IoFileObjectType,
- KernelMode,
- (PVOID *) &fileObject,
- NULL );
- if (!NT_SUCCESS(status)) {
- goto errorout;
- }
-
- /* query the DeviceObject in case no input */
- deviceObject = IoGetBaseFileSystemDeviceObject(fileObject);
-
-
- /* allocate our own irp */
- irp = IoAllocateIrp(deviceObject->StackSize, FALSE);
- if (NULL == irp) {
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto errorout;
- }
-
- irp->Tail.Overlay.OriginalFileObject = fileObject;
- irp->Tail.Overlay.Thread = PsGetCurrentThread();
- irp->Tail.Overlay.AuxiliaryBuffer = (PVOID) NULL;
- irp->PendingReturned = FALSE;
- irp->Cancel = FALSE;
- irp->CancelRoutine = (PDRIVER_CANCEL) NULL;
- irp->RequestorMode = KernelMode;
- irp->UserIosb = &iosb;
-
- /* set up the next I/O stack location. */
- irpSp = (PIO_STACK_LOCATION)IoGetNextIrpStackLocation(irp);
- irpSp->MajorFunction = Writing ? IRP_MJ_WRITE : IRP_MJ_READ;
- irpSp->FileObject = fileObject;
- irpSp->DeviceObject = deviceObject;
-
- if (deviceObject->Flags & DO_BUFFERED_IO) {
- irp->AssociatedIrp.SystemBuffer = Buffer;
- irp->UserBuffer = Buffer;
- irp->Flags |= (ULONG) (IRP_BUFFERED_IO |
- IRP_INPUT_OPERATION);
- } else if (deviceObject->Flags & DO_DIRECT_IO) {
-
- PMDL mdl = NULL;
-
- mdl = IoAllocateMdl(Buffer, Length, FALSE, TRUE, irp);
- if (mdl == NULL) {
- KsPrint((0, "cfs_nt_filp_io: failed to allocate MDL for %wZ .\n",
- &fileObject->FileName));
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto errorout;
- }
-
- __try {
- MmProbeAndLockPages(mdl, KernelMode, Writing ? IoReadAccess : IoWriteAccess );
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- KsPrint((0, "cfs_nt_filp_io: failed to lock buffer %p for %wZ .\n",
- Buffer, &fileObject->FileName));
- IoFreeMdl(irp->MdlAddress);
- irp->MdlAddress = NULL;
- status = STATUS_INSUFFICIENT_RESOURCES;
- }
- } else {
- irp->UserBuffer = Buffer;
- irp->Flags = 0;
- }
-
- if (Writing) {
- irp->Flags |= IRP_WRITE_OPERATION | IRP_DEFER_IO_COMPLETION;
- irpSp->Parameters.Write.Length = Length;
- irpSp->Parameters.Write.ByteOffset = *Offset;
- } else {
- irp->Flags |= IRP_READ_OPERATION | IRP_DEFER_IO_COMPLETION;
- irpSp->Parameters.Read.Length = Length;
- irpSp->Parameters.Read.ByteOffset = *Offset;
- }
-
- /* set the Irp completion routine */
- IoSetCompletionRoutine( irp, CompletionRoutine,
- &event, TRUE, TRUE, TRUE);
-
-
- /* issue the irp to the lower layer device */
- status = IoCallDriver(deviceObject, irp);
-
- /* Irp is to be cleaned up in the compleiton routine */
- irp = NULL;
-
- if (status == STATUS_PENDING) {
-
- /* we need wait until operation is completed, then we can
- get the returned status and information length */
-
- status = KeWaitForSingleObject(
- &event,
- Executive,
- KernelMode,
- FALSE,
- NULL
- );
- if (NT_SUCCESS(status)) {
- status = iosb.Status;
- }
- }
-
- if (NT_SUCCESS(status)) {
- *Bytes = (ULONG)iosb.Information;
- } else {
- *Bytes = 0;
- }
-
-errorout:
-
- if (fileObject) {
- ObDereferenceObject(fileObject);
- }
-
- /* free the Irp in error case */
- if (irp) {
- IoFreeIrp(irp);
- }
-
- return status;
-}
-
-/*
- * filp_read
- * To read data from the opened file
- *
- * Arguments:
- * fp: the pointer of the file strcture
- * buf: pointer to the buffer to contain the data
- * nbytes: size in bytes to be read from the file
- * pos: offset in file where reading starts, if pos
- * NULL, then read from current file offset
- *
- * Return Value:
- * Actual size read into the buffer in success case
- * Error code in failure case
- *
- * Notes:
- * N/A
- */
-int filp_read(struct file *fp, void *buf, size_t nbytes, loff_t *pos)
-{
- LARGE_INTEGER offset;
- NTSTATUS status;
- int rc = 0;
-
- /* Read data from the file into the specified buffer */
- if (pos != NULL) {
- offset.QuadPart = *pos;
- } else {
- offset.QuadPart = fp->f_pos;
- }
-
- status = cfs_nt_filp_io(fp->f_handle, 0, &offset,
- nbytes, buf, &rc);
-
- if (!NT_SUCCESS(status)) {
- rc = cfs_error_code(status);
- }
-
- if (rc > 0) {
- fp->f_pos = offset.QuadPart + rc;
- if (pos != NULL)
- *pos = fp->f_pos;
- }
-
- return rc;
-}
-
-/*
- * cfs_filp_wrtie
- * To write specified data to the opened file
- *
- * Arguments:
- * fp: the pointer of the file strcture
- * buf: pointer to the buffer containing the data
- * nbytes: size in bytes to be written to the file
- * pos: offset in file where writing starts, if pos
- * NULL, then write to current file offset
- *
- * Return Value:
- * Actual size written into the buffer in success case
- * Error code in failure case
- *
- * Notes:
- * N/A
- */
-
-int filp_write(struct file *fp, void *buf, size_t nbytes, loff_t *pos)
-{
- LARGE_INTEGER offset;
- NTSTATUS status;
- int rc = 0;
-
- /* Read data from the file into the specified buffer */
- if (pos != NULL) {
- offset.QuadPart = *pos;
- } else {
- offset.QuadPart = fp->f_pos;
- }
-
- status = cfs_nt_filp_io(fp->f_handle, 1, &offset,
- nbytes, buf, &rc);
-
- if (!NT_SUCCESS(status)) {
- rc = cfs_error_code(status);
- }
-
- if (rc > 0) {
- fp->f_pos = offset.QuadPart + rc;
- if (pos != NULL)
- *pos = fp->f_pos;
- }
-
- return rc;
-}
-
-/*
- * filp_fsync
- * To sync the dirty data of the file to disk
- *
- * Arguments:
- * fp: the pointer of the file strcture
- *
- * Return Value:
- * Zero: in success case
- * Error code: in failure case
- *
- * Notes:
- * Nt kernel doesn't export such a routine to flush a file,
- * we must allocate our own Irp and issue it to the file
- * system driver.
- */
-int filp_fsync(struct file *fp, loff_t start, loff_t end)
-{
- PFILE_OBJECT FileObject;
- PDEVICE_OBJECT DeviceObject;
-
- NTSTATUS Status;
- PIRP Irp;
- KEVENT Event;
- IO_STATUS_BLOCK IoSb;
- PIO_STACK_LOCATION IrpSp;
-
- /* get the FileObject and the DeviceObject */
- Status = ObReferenceObjectByHandle(
- fp->f_handle,
- FILE_WRITE_DATA,
- NULL,
- KernelMode,
- (PVOID*)&FileObject,
- NULL );
-
- if (!NT_SUCCESS(Status)) {
- return cfs_error_code(Status);
- }
-
- DeviceObject = IoGetRelatedDeviceObject(FileObject);
-
- /* allocate a new Irp */
- Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
- if (!Irp) {
- ObDereferenceObject(FileObject);
- return -ENOMEM;
- }
-
- /* intialize the event */
- KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
-
- /* setup the Irp */
- Irp->UserIosb = &IoSb;
- Irp->RequestorMode = KernelMode;
-
- Irp->Tail.Overlay.Thread = PsGetCurrentThread();
- Irp->Tail.Overlay.OriginalFileObject = FileObject;
-
- /* setup the Irp stack location */
- IrpSp = IoGetNextIrpStackLocation(Irp);
-
- IrpSp->MajorFunction = IRP_MJ_FLUSH_BUFFERS;
- IrpSp->DeviceObject = DeviceObject;
- IrpSp->FileObject = FileObject;
-
- IoSetCompletionRoutine( Irp, CompletionRoutine,
- &Event, TRUE, TRUE, TRUE);
-
-
- /* issue the Irp to the underlying file system driver */
- IoCallDriver(DeviceObject, Irp);
-
- /* wait until it is finished */
- KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0);
-
- /* cleanup our reference on it */
- ObDereferenceObject(FileObject);
-
- Status = IoSb.Status;
-
- return cfs_error_code(Status);
-}
-
-/*
- * get_file
- * To increase the reference of the file object
- *
- * Arguments:
- * fp: the pointer of the file strcture
- *
- * Return Value:
- * Zero: in success case
- * Non-Zero: in failure case
- *
- * Notes:
- * N/A
- */
-
-int get_file(struct file *fp)
-{
- InterlockedIncrement(&(fp->f_count));
- return 0;
-}
-
-
-/*
- * fput
- * To decrease the reference of the file object
- *
- * Arguments:
- * fp: the pointer of the file strcture
- *
- * Return Value:
- * Zero: in success case
- * Non-Zero: in failure case
- *
- * Notes:
- * N/A
- */
-
-int fput(struct file *fp)
-{
- if (InterlockedDecrement(&(fp->f_count)) == 0)
- filp_close(fp, NULL);
-
- return 0;
-}
-
-
-/*
- * file_count
- * To query the reference count of the file object
- *
- * Arguments:
- * fp: the pointer of the file strcture
- *
- * Return Value:
- * the reference count of the file object
- *
- * Notes:
- * N/A
- */
-
-int file_count(struct file *fp)
-{
- return (int)(fp->f_count);
-}
-
-struct dentry *dget(struct dentry *de)
-{
- if (de) {
- atomic_inc(&de->d_count);
- }
- return de;
-}
-
-void dput(struct dentry *de)
-{
- if (!de || atomic_read(&de->d_count) == 0) {
- return;
- }
- if (atomic_dec_and_test(&de->d_count)) {
- kfree(de);
- }
-}
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-
-# define DEBUG_SUBSYSTEM S_LNET
-
-#include <libcfs/libcfs.h>
-
-
-#if defined(_X86_)
-
-void __declspec (naked) FASTCALL
-atomic_add(
- int i,
- atomic_t *v
- )
-{
- // ECX = i
- // EDX = v ; [EDX][0] = v->counter
-
- __asm {
- lock add dword ptr [edx][0], ecx
- ret
- }
-}
-
-void __declspec (naked) FASTCALL
-atomic_sub(
- int i,
- atomic_t *v
- )
-{
- // ECX = i
- // EDX = v ; [EDX][0] = v->counter
-
- __asm {
- lock sub dword ptr [edx][0], ecx
- ret
- }
-}
-
-void __declspec (naked) FASTCALL
-atomic_inc(
- atomic_t *v
- )
-{
- //InterlockedIncrement((PULONG)(&((v)->counter)));
-
- //` ECX = v ; [ECX][0] = v->counter
-
- __asm {
- lock inc dword ptr [ecx][0]
- ret
- }
-}
-
-void __declspec (naked) FASTCALL
-atomic_dec(
- atomic_t *v
- )
-{
- // ECX = v ; [ECX][0] = v->counter
-
- __asm {
- lock dec dword ptr [ecx][0]
- ret
- }
-}
-
-int __declspec (naked) FASTCALL
-atomic_sub_and_test(
- int i,
- atomic_t *v
- )
-{
-
- // ECX = i
- // EDX = v ; [EDX][0] = v->counter
-
- __asm {
- xor eax, eax
- lock sub dword ptr [edx][0], ecx
- sete al
- ret
- }
-}
-
-int __declspec (naked) FASTCALL
-atomic_inc_and_test(
- atomic_t *v
- )
-{
- // ECX = v ; [ECX][0] = v->counter
-
- __asm {
- xor eax, eax
- lock inc dword ptr [ecx][0]
- sete al
- ret
- }
-}
-
-int __declspec (naked) FASTCALL
-atomic_dec_and_test(
- atomic_t *v
- )
-{
- // ECX = v ; [ECX][0] = v->counter
-
- __asm {
- xor eax, eax
- lock dec dword ptr [ecx][0]
- sete al
- ret
- }
-}
-
-#elif defined(_AMD64_)
-
-void FASTCALL
-atomic_add(
- int i,
- atomic_t *v
- )
-{
- InterlockedExchangeAdd( (PULONG)(&((v)->counter)) , (LONG) (i));
-}
-
-void FASTCALL
-atomic_sub(
- int i,
- atomic_t *v
- )
-{
- InterlockedExchangeAdd( (PULONG)(&((v)->counter)) , (LONG) (-1*i));
-}
-
-void FASTCALL
-atomic_inc(
- atomic_t *v
- )
-{
- InterlockedIncrement((PULONG)(&((v)->counter)));
-}
-
-void FASTCALL
-atomic_dec(
- atomic_t *v
- )
-{
- InterlockedDecrement((PULONG)(&((v)->counter)));
-}
-
-int FASTCALL
-atomic_sub_and_test(
- int i,
- atomic_t *v
- )
-{
- int counter, result;
-
- do {
-
- counter = v->counter;
- result = counter - i;
-
- } while ( InterlockedCompareExchange(
- &(v->counter),
- result,
- counter) != counter);
-
- return (result == 0);
-}
-
-int FASTCALL
-atomic_inc_and_test(
- atomic_t *v
- )
-{
- int counter, result;
-
- do {
-
- counter = v->counter;
- result = counter + 1;
-
- } while ( InterlockedCompareExchange(
- &(v->counter),
- result,
- counter) != counter);
-
- return (result == 0);
-}
-
-int FASTCALL
-atomic_dec_and_test(
- atomic_t *v
- )
-{
- int counter, result;
-
- do {
-
- counter = v->counter;
- result = counter - 1;
-
- } while ( InterlockedCompareExchange(
- &(v->counter),
- result,
- counter) != counter);
-
- return (result == 0);
-}
-
-#else
-
-#error CPU arch type isn't specified.
-
-#endif
-
-/**
- * atomic_add_return - add integer and return
- * \param v pointer of type atomic_t
- * \param i integer value to add
- *
- * Atomically adds \a i to \a v and returns \a i + \a v
- */
-int FASTCALL atomic_add_return(int i, atomic_t *v)
-{
- int counter, result;
-
- do {
-
- counter = v->counter;
- result = counter + i;
-
- } while ( InterlockedCompareExchange(
- &(v->counter),
- result,
- counter) != counter);
-
- return result;
-
-}
-
-/**
- * atomic_sub_return - subtract integer and return
- * \param v pointer of type atomic_t
- * \param i integer value to subtract
- *
- * Atomically subtracts \a i from \a v and returns \a v - \a i
- */
-int FASTCALL atomic_sub_return(int i, atomic_t *v)
-{
- return atomic_add_return(-i, v);
-}
-
-int FASTCALL atomic_dec_and_lock(atomic_t *v, spinlock_t *lock)
-{
- if (atomic_read(v) != 1)
- return 0;
-
- spin_lock(lock);
- if (atomic_dec_and_test(v))
- return 1;
- spin_unlock(lock);
- return 0;
-}
-
-
-/*
- * rw spinlock
- */
-
-
-void
-rwlock_init(rwlock_t *rwlock)
-{
- spin_lock_init(&rwlock->guard);
- rwlock->count = 0;
-}
-
-void
-cfs_rwlock_fini(rwlock_t *rwlock)
-{
-}
-
-void
-read_lock(rwlock_t *rwlock)
-{
- struct task_struct * task = current;
- PTASK_SLOT slot = NULL;
-
- if (!task) {
- /* should bugchk here */
- cfs_enter_debugger();
- return;
- }
-
- slot = CONTAINING_RECORD(task, TASK_SLOT, task);
- ASSERT(slot->Magic == TASKSLT_MAGIC);
-
- slot->irql = KeRaiseIrqlToDpcLevel();
-
- while (TRUE) {
- spin_lock(&rwlock->guard);
- if (rwlock->count >= 0)
- break;
- spin_unlock(&rwlock->guard);
- }
-
- rwlock->count++;
- spin_unlock(&rwlock->guard);
-}
-
-void
-read_unlock(rwlock_t *rwlock)
-{
- struct task_struct * task = current;
- PTASK_SLOT slot = NULL;
-
- if (!task) {
- /* should bugchk here */
- cfs_enter_debugger();
- return;
- }
-
- slot = CONTAINING_RECORD(task, TASK_SLOT, task);
- ASSERT(slot->Magic == TASKSLT_MAGIC);
-
- spin_lock(&rwlock->guard);
- ASSERT(rwlock->count > 0);
- rwlock->count--;
- if (rwlock < 0)
- cfs_enter_debugger();
- spin_unlock(&rwlock->guard);
-
- KeLowerIrql(slot->irql);
-}
-
-void
-write_lock(rwlock_t *rwlock)
-{
- struct task_struct * task = current;
- PTASK_SLOT slot = NULL;
-
- if (!task) {
- /* should bugchk here */
- cfs_enter_debugger();
- return;
- }
-
- slot = CONTAINING_RECORD(task, TASK_SLOT, task);
- ASSERT(slot->Magic == TASKSLT_MAGIC);
-
- slot->irql = KeRaiseIrqlToDpcLevel();
-
- while (TRUE) {
- spin_lock(&rwlock->guard);
- if (rwlock->count == 0)
- break;
- spin_unlock(&rwlock->guard);
- }
-
- rwlock->count = -1;
- spin_unlock(&rwlock->guard);
-}
-
-void
-write_unlock(rwlock_t *rwlock)
-{
- struct task_struct * task = current;
- PTASK_SLOT slot = NULL;
-
- if (!task) {
- /* should bugchk here */
- cfs_enter_debugger();
- return;
- }
-
- slot = CONTAINING_RECORD(task, TASK_SLOT, task);
- ASSERT(slot->Magic == TASKSLT_MAGIC);
-
- spin_lock(&rwlock->guard);
- ASSERT(rwlock->count == -1);
- rwlock->count = 0;
- spin_unlock(&rwlock->guard);
-
- KeLowerIrql(slot->irql);
-}
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-# define DEBUG_SUBSYSTEM S_LNET
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#define DEBUG_SUBSYSTEM S_LNET
-
-#include <libcfs/libcfs.h>
-
-
-struct kmem_cache *cfs_page_t_slab;
-struct kmem_cache *cfs_page_p_slab;
-
-struct page *virt_to_page(void *addr)
-{
- struct page *pg;
- pg = kmem_cache_alloc(cfs_page_t_slab, 0);
-
- if (NULL == pg) {
- cfs_enter_debugger();
- return NULL;
- }
-
- memset(pg, 0, sizeof(struct page));
- pg->addr = (void *)((__u64)addr & (~((__u64)PAGE_SIZE-1)));
- pg->mapping = addr;
- atomic_set(&pg->count, 1);
- set_bit(PG_virt, &(pg->flags));
- cfs_enter_debugger();
- return pg;
-}
-
-/*
- * alloc_page
- * To allocate the struct page and also 1 page of memory
- *
- * Arguments:
- * flags: the allocation options
- *
- * Return Value:
- * pointer to the struct page strcture in success or
- * NULL in failure case
- *
- * Notes:
- * N/A
- */
-
-atomic_t libcfs_total_pages;
-
-struct page *alloc_page(int flags)
-{
- struct page *pg;
- pg = kmem_cache_alloc(cfs_page_t_slab, 0);
-
- if (NULL == pg) {
- cfs_enter_debugger();
- return NULL;
- }
-
- memset(pg, 0, sizeof(struct page));
- pg->addr = kmem_cache_alloc(cfs_page_p_slab, 0);
- atomic_set(&pg->count, 1);
-
- if (pg->addr) {
- if (cfs_is_flag_set(flags, __GFP_ZERO))
- memset(pg->addr, 0, PAGE_CACHE_SIZE);
- atomic_inc(&libcfs_total_pages);
- } else {
- cfs_enter_debugger();
- kmem_cache_free(cfs_page_t_slab, pg);
- pg = NULL;
- }
-
- return pg;
-}
-
-/*
- * __free_page
- * To free the struct page including the page
- *
- * Arguments:
- * pg: pointer to the struct page strcture
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-void __free_page(struct page *pg)
-{
- ASSERT(pg != NULL);
- ASSERT(pg->addr != NULL);
- ASSERT(atomic_read(&pg->count) <= 1);
-
- if (!test_bit(PG_virt, &pg->flags)) {
- kmem_cache_free(cfs_page_p_slab, pg->addr);
- atomic_dec(&libcfs_total_pages);
- } else {
- cfs_enter_debugger();
- }
- kmem_cache_free(cfs_page_t_slab, pg);
-}
-
-int kmem_is_in_cache(const void *addr, const struct kmem_cache *kmem)
-{
- KdPrint(("kmem_is_in_cache: not implemented. (should maintain a"
- "chain to keep all allocations traced.)\n"));
- return 1;
-}
-
-/*
- * kmalloc
- * To allocate memory from system pool
- *
- * Arguments:
- * nr_bytes: length in bytes of the requested buffer
- * flags: flags indiction
- *
- * Return Value:
- * NULL: if there's no enough memory space in system
- * the address of the allocated memory in success.
- *
- * Notes:
- * This operation can be treated as atomic.
- */
-
-void *
-kmalloc(size_t nr_bytes, u_int32_t flags)
-{
- void *ptr;
-
- /* Ignore the flags: always allcoate from NonPagedPool */
- ptr = ExAllocatePoolWithTag(NonPagedPool, nr_bytes, 'Lufs');
- if (ptr != NULL && (flags & __GFP_ZERO))
- memset(ptr, 0, nr_bytes);
-
- if (!ptr)
- cfs_enter_debugger();
-
- return ptr;
-}
-
-/*
- * kfree
- * To free the sepcified memory to system pool
- *
- * Arguments:
- * addr: pointer to the buffer to be freed
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * This operation can be treated as atomic.
- */
-
-void
-kfree(void *addr)
-{
- ExFreePool(addr);
-}
-
-/*
- * vmalloc
- * To allocate large block of memory from system pool
- *
- * Arguments:
- * nr_bytes: length in bytes of the requested buffer
- *
- * Return Value:
- * NULL: if there's no enough memory space in system
- * the address of the allocated memory in success.
- *
- * Notes:
- * N/A
- */
-
-void *
-vmalloc(size_t nr_bytes)
-{
- return kmalloc(nr_bytes, 0);
-}
-
-/*
- * vfree
- * To free the sepcified memory to system pool
- *
- * Arguments:
- * addr: pointer to the buffer to be freed
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void vfree(void *addr)
-{
- kfree(addr);
-}
-
-
-/*
- * kmem_cache_create
- * To create a SLAB cache
- *
- * Arguments:
- * name: name string of the SLAB cache to be created
- * size: size in bytes of SLAB entry buffer
- * offset: offset in the page
- * flags: SLAB creation flags
-*
- * Return Value:
- * The poitner of cfs_memory_cache structure in success.
- * NULL pointer in failure case.
- *
- * Notes:
- * 1, offset won't be used here.
- * 2, it could be better to induce a lock to protect the access of the
- * SLAB structure on SMP if there's not outside lock protection.
- * 3, parameters C/D are removed.
- */
-
-struct kmem_cache *kmem_cache_create(const char *name, size_t size,
- size_t offset, unsigned long flags,
- void *ctor)
-{
- struct kmem_cache *kmc = NULL;
-
- /* The name of the SLAB could not exceed 20 chars */
-
- if (name && strlen(name) >= 20)
- goto errorout;
-
- /* Allocate and initialize the SLAB strcture */
-
- kmc = kmalloc(sizeof(struct kmem_cache), 0);
-
- if (NULL == kmc)
- goto errorout;
-
- memset(kmc, 0, sizeof(struct kmem_cache));
- kmc->flags = flags;
-
- if (name) {
- strcpy(&kmc->name[0], name);
- }
-
- /* Initialize the corresponding LookAside list */
-
- ExInitializeNPagedLookasideList(
- &(kmc->npll),
- NULL,
- NULL,
- 0,
- size,
- 'pnmk',
- 0);
-
-errorout:
-
- return kmc;
-}
-
-/*
- *kmem_cache_destroy
- * To destroy the unused SLAB cache
- *
- * Arguments:
- * kmc: the SLAB cache to be destroied.
- *
- * Return Value:
- * 0: in success case.
- * 1: in failure case.
- *
- * Notes:
- * N/A
- */
-
-kmem_cache_destroy(struct kmem_cache *kmc)
-{
- ASSERT(kmc != NULL);
-
- ExDeleteNPagedLookasideList(&(kmc->npll));
-
- kfree(kmc);
-
- return 0;
-}
-
-/*
- * kmem_cache_alloc
- * To allocate an object (LookAside entry) from the SLAB
- *
- * Arguments:
- * kmc: the SLAB cache to be allocated from.
- * flags: flags for allocation options
- *
- * Return Value:
- * object buffer address: in success case.
- * NULL: in failure case.
- *
- * Notes:
- * N/A
- */
-
-void *kmem_cache_alloc(struct kmem_cache *kmc, int flags)
-{
- void *buf = NULL;
-
- buf = ExAllocateFromNPagedLookasideList(&(kmc->npll));
-
- return buf;
-}
-
-/*
- * kmem_cache_free
- * To free an object (LookAside entry) to the SLAB cache
- *
- * Arguments:
- * kmc: the SLAB cache to be freed to.
- * buf: the pointer to the object to be freed.
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void kmem_cache_free(struct kmem_cache *kmc, void *buf)
-{
- ExFreeToNPagedLookasideList(&(kmc->npll), buf);
-}
-
-spinlock_t shrinker_guard = {0};
-struct list_head shrinker_hdr = LIST_HEAD_INIT(shrinker_hdr);
-struct timer_list shrinker_timer = {0};
-
-struct shrinker *set_shrinker(int seeks, shrink_callback cb)
-{
- struct shrinker *s = (struct shrinker *)
- kmalloc(sizeof(struct shrinker), __GFP_ZERO);
- if (s) {
- s->cb = cb;
- s->seeks = seeks;
- s->nr = 2;
- spin_lock(&shrinker_guard);
- list_add(&s->list, &shrinker_hdr);
- spin_unlock(&shrinker_guard);
- }
-
- return s;
-}
-
-void remove_shrinker(struct shrinker *s)
-{
- struct shrinker *tmp;
- spin_lock(&shrinker_guard);
-#if TRUE
- list_for_each_entry(tmp, &shrinker_hdr, list) {
- if (tmp == s) {
- list_del(&tmp->list);
- break;
- }
- }
-#else
- list_del(&s->list);
-#endif
- spin_unlock(&shrinker_guard);
- kfree(s);
-}
-
-/* time ut test proc */
-void shrinker_timer_proc(ulong_ptr_t arg)
-{
- struct shrinker *s;
- spin_lock(&shrinker_guard);
-
- list_for_each_entry(s, &shrinker_hdr, list) {
- s->cb(s->nr, __GFP_FS);
- }
- spin_unlock(&shrinker_guard);
- cfs_timer_arm(&shrinker_timer, 300);
-}
-
-int start_shrinker_timer()
-{
- /* initialize shriner timer */
- cfs_timer_init(&shrinker_timer, shrinker_timer_proc, NULL);
-
- /* start the timer to trigger in 5 minutes */
- cfs_timer_arm(&shrinker_timer, 300);
-
- return 0;
-}
-
-void stop_shrinker_timer()
-{
- /* cancel the timer */
- cfs_timer_disarm(&shrinker_timer);
- cfs_timer_done(&shrinker_timer);
-}
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-
-#define DEBUG_SUBSYSTEM S_LNET
-
-#include <libcfs/libcfs.h>
-
-#define LIBCFS_MINOR 240
-
-int libcfs_ioctl_getdata(char *buf, char *end, void *arg)
-{
- struct libcfs_ioctl_hdr *hdr;
- struct libcfs_ioctl_data *data;
- int err;
- ENTRY;
-
- hdr = (struct libcfs_ioctl_hdr *)buf;
- data = (struct libcfs_ioctl_data *)buf;
-
- err = copy_from_user(buf, (void *)arg, sizeof(*hdr));
- if (err)
- RETURN(err);
-
- if (hdr->ioc_version != LIBCFS_IOCTL_VERSION) {
- CERROR("LIBCFS: version mismatch kernel vs application\n");
- RETURN(-EINVAL);
- }
-
- if (hdr->ioc_len + buf >= end) {
- CERROR("LIBCFS: user buffer exceeds kernel buffer\n");
- RETURN(-EINVAL);
- }
-
- if (hdr->ioc_len < sizeof(struct libcfs_ioctl_data)) {
- CERROR("LIBCFS: user buffer too small for ioctl\n");
- RETURN(-EINVAL);
- }
-
- err = copy_from_user(buf, (void *)arg, hdr->ioc_len);
- if (err)
- RETURN(err);
-
- if (libcfs_ioctl_is_invalid(data)) {
- CERROR("LIBCFS: ioctl not correctly formatted\n");
- RETURN(-EINVAL);
- }
-
- if (data->ioc_inllen1)
- data->ioc_inlbuf1 = &data->ioc_bulk[0];
-
- if (data->ioc_inllen2)
- data->ioc_inlbuf2 = &data->ioc_bulk[0] +
- cfs_size_round(data->ioc_inllen1);
-
- RETURN(0);
-}
-
-int libcfs_ioctl_popdata(void *arg, void *data, int size)
-{
- if (copy_to_user((char *)arg, data, size))
- return -EFAULT;
- return 0;
-}
-
-extern struct cfs_psdev_ops libcfs_psdev_ops;
-
-static int
-libcfs_psdev_open(struct inode *in, struct file *file)
-{
- struct libcfs_device_userstate **pdu = NULL;
- int rc = 0;
-
- pdu = (struct libcfs_device_userstate **)&file->private_data;
- if (libcfs_psdev_ops.p_open != NULL)
- rc = libcfs_psdev_ops.p_open(0, (void *)pdu);
- else
- return (-EPERM);
- return rc;
-}
-
-/* called when closing /dev/device */
-static int
-libcfs_psdev_release(struct inode *in, struct file *file)
-{
- struct libcfss_device_userstate *pdu;
- int rc = 0;
-
- pdu = file->private_data;
- if (libcfs_psdev_ops.p_close != NULL)
- rc = libcfs_psdev_ops.p_close(0, (void *)pdu);
- else
- rc = -EPERM;
- return rc;
-}
-
-static int
-libcfs_ioctl(struct file *file, unsigned int cmd, ulong_ptr_t arg)
-{
- struct cfs_psdev_file pfile;
- int rc = 0;
-
- if ( _IOC_TYPE(cmd) != IOC_LIBCFS_TYPE ||
- _IOC_NR(cmd) < IOC_LIBCFS_MIN_NR ||
- _IOC_NR(cmd) > IOC_LIBCFS_MAX_NR ) {
- CDEBUG(D_IOCTL, "invalid ioctl ( type %d, nr %d, size %d )\n",
- _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
- return (-EINVAL);
- }
-
- /* Handle platform-dependent IOC requests */
- switch (cmd) {
- case IOC_LIBCFS_PANIC:
- if (!cfs_capable(CFS_CAP_SYS_BOOT))
- return (-EPERM);
- CERROR("debugctl-invoked panic");
- KeBugCheckEx('LUFS', (ULONG_PTR)libcfs_ioctl, (ULONG_PTR)NULL, (ULONG_PTR)NULL, (ULONG_PTR)NULL);
-
- return (0);
- case IOC_LIBCFS_MEMHOG:
-
- if (!cfs_capable(CFS_CAP_SYS_ADMIN))
- return -EPERM;
- break;
- }
-
- pfile.off = 0;
- pfile.private_data = file->private_data;
- if (libcfs_psdev_ops.p_ioctl != NULL)
- rc = libcfs_psdev_ops.p_ioctl(&pfile, cmd, (void *)arg);
- else
- rc = -EPERM;
- return (rc);
-}
-
-static struct file_operations libcfs_fops = {
- /* owner */ THIS_MODULE,
- /* lseek: */ NULL,
- /* read: */ NULL,
- /* write: */ NULL,
- /* ioctl: */ libcfs_ioctl,
- /* open: */ libcfs_psdev_open,
- /* release:*/ libcfs_psdev_release
-};
-
-struct miscdevice libcfs_dev = {
- LIBCFS_MINOR,
- "lnet",
- &libcfs_fops
-};
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-# define DEBUG_SUBSYSTEM S_LNET
-
-#ifndef __KERNEL__
-
-#include <ntddk.h>
-#include <libcfs/libcfs.h>
-#include <libcfs/user-bitops.h>
-#include <lustre_lib.h>
-
-/*
- * Native API definitions
- */
-
-//
-// Disk I/O Routines
-//
-
-NTSYSAPI
-NTSTATUS
-NTAPI
-NtReadFile(HANDLE FileHandle,
- HANDLE Event OPTIONAL,
- PIO_APC_ROUTINE ApcRoutine OPTIONAL,
- PVOID ApcContext OPTIONAL,
- PIO_STATUS_BLOCK IoStatusBlock,
- PVOID Buffer,
- ULONG Length,
- PLARGE_INTEGER ByteOffset OPTIONAL,
- PULONG Key OPTIONAL);
-
-NTSYSAPI
-NTSTATUS
-NTAPI
-NtWriteFile(HANDLE FileHandle,
- HANDLE Event OPTIONAL,
- PIO_APC_ROUTINE ApcRoutine OPTIONAL,
- PVOID ApcContext OPTIONAL,
- PIO_STATUS_BLOCK IoStatusBlock,
- PVOID Buffer,
- ULONG Length,
- PLARGE_INTEGER ByteOffset OPTIONAL,
- PULONG Key OPTIONAL);
-
-NTSYSAPI
-NTSTATUS
-NTAPI
-NtClose(HANDLE Handle);
-
-NTSYSAPI
-NTSTATUS
-NTAPI
-NtCreateFile(PHANDLE FileHandle,
- ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes,
- PIO_STATUS_BLOCK IoStatusBlock,
- PLARGE_INTEGER AllocationSize OPTIONAL,
- ULONG FileAttributes,
- ULONG ShareAccess,
- ULONG CreateDisposition,
- ULONG CreateOptions,
- PVOID EaBuffer OPTIONAL,
- ULONG EaLength);
-
-
-NTSYSAPI
-NTSTATUS
-NTAPI
-NtDeviceIoControlFile(
- IN HANDLE FileHandle,
- IN HANDLE Event,
- IN PIO_APC_ROUTINE ApcRoutine,
- IN PVOID ApcContext,
- OUT PIO_STATUS_BLOCK IoStatusBlock,
- IN ULONG IoControlCode,
- IN PVOID InputBuffer,
- IN ULONG InputBufferLength,
- OUT PVOID OutputBuffer,
- OUT ULONG OutputBufferLength
- );
-
-NTSYSAPI
-NTSTATUS
-NTAPI
-NtFsControlFile(
- IN HANDLE FileHandle,
- IN HANDLE Event OPTIONAL,
- IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
- IN PVOID ApcContext OPTIONAL,
- OUT PIO_STATUS_BLOCK IoStatusBlock,
- IN ULONG FsControlCode,
- IN PVOID InputBuffer OPTIONAL,
- IN ULONG InputBufferLength,
- OUT PVOID OutputBuffer OPTIONAL,
- IN ULONG OutputBufferLength
-);
-
-
-NTSYSAPI
-NTSTATUS
-NTAPI
-NtQueryInformationFile(
- IN HANDLE FileHandle,
- OUT PIO_STATUS_BLOCK IoStatusBlock,
- OUT PVOID FileInformation,
- IN ULONG Length,
- IN FILE_INFORMATION_CLASS FileInformationClass
- );
-
-//
-// Random routines ...
-//
-
-NTSYSAPI
-ULONG
-NTAPI
-RtlRandom(
- IN OUT PULONG Seed
- );
-
-/*
- * Time routines ...
- */
-
-NTSYSAPI
-CCHAR
-NTAPI
-NtQuerySystemTime(
- OUT PLARGE_INTEGER CurrentTime
- );
-
-
-NTSYSAPI
-BOOLEAN
-NTAPI
-RtlTimeToSecondsSince1970(
- IN PLARGE_INTEGER Time,
- OUT PULONG ElapsedSeconds
- );
-
-
-NTSYSAPI
-VOID
-NTAPI
-RtlSecondsSince1970ToTime(
- IN ULONG ElapsedSeconds,
- OUT PLARGE_INTEGER Time
- );
-
-NTSYSAPI
-NTSTATUS
-NTAPI
-ZwDelayExecution(
- IN BOOLEAN Alertable,
- IN PLARGE_INTEGER Interval
-);
-
-
-int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
-{
- NTSTATUS status;
- LARGE_INTEGER Interval;
- Interval.QuadPart = rqtp->tv_sec * 10000000 + rqtp->tv_nsec / 100;
- status = ZwDelayExecution(TRUE, &Interval);
- if (rmtp) {
- rmtp->tv_sec = 0;
- rmtp->tv_nsec = 0;
- }
- if (status == STATUS_ALERTED || status == STATUS_USER_APC) {
- return -1;
- }
- return 0;
-}
-
-
-void do_gettimeofday(struct timeval *tv)
-{
- LARGE_INTEGER Time;
-
- NtQuerySystemTime(&Time);
-
- tv->tv_sec = (long_ptr_t) (Time.QuadPart / 10000000);
- tv->tv_usec = (suseconds_t) (Time.QuadPart % 10000000) / 10;
-}
-
-int gettimeofday(struct timeval *tv, void * tz)
-{
- do_gettimeofday(tv);
- return 0;
-}
-
-/*
- * proc process routines of user space
- */
-
-struct idr_context *cfs_proc_idp = NULL;
-
-int cfs_proc_open (char * filename, int oflag)
-{
- NTSTATUS status;
- IO_STATUS_BLOCK iosb;
- int rc = 0;
-
- HANDLE Handle = INVALID_HANDLE_VALUE;
- OBJECT_ATTRIBUTES ObjectAttributes;
- ACCESS_MASK DesiredAccess;
- ULONG CreateDisposition;
- ULONG ShareAccess;
- ULONG CreateOptions;
- UNICODE_STRING UnicodeName;
- USHORT NameLength;
-
- PFILE_FULL_EA_INFORMATION Ea = NULL;
- ULONG EaLength;
- PUCHAR EaBuffer = NULL;
-
- /* Check the filename: should start with "/proc" or "/dev" */
- NameLength = (USHORT)strlen(filename);
- if (NameLength > 0x05) {
- if (_strnicmp(filename, "/proc/", 6) == 0) {
- if (NameLength <= 6) {
- rc = -EINVAL;
- goto errorout;
- }
- } else if (_strnicmp(filename, "/dev/", 5) == 0) {
- } else {
- rc = -EINVAL;
- goto errorout;
- }
- } else {
- rc = -EINVAL;
- goto errorout;
- }
-
- /* Analyze the flags settings */
-
- if (cfs_is_flag_set(oflag, O_WRONLY)) {
- DesiredAccess = (GENERIC_WRITE | SYNCHRONIZE);
- ShareAccess = 0;
- } else if (cfs_is_flag_set(oflag, O_RDWR)) {
- DesiredAccess = (GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE);
- ShareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE;
- } else {
- DesiredAccess = (GENERIC_READ | SYNCHRONIZE);
- ShareAccess = FILE_SHARE_READ;
- }
-
- if (cfs_is_flag_set(oflag, O_CREAT)) {
- if (cfs_is_flag_set(oflag, O_EXCL)) {
- CreateDisposition = FILE_CREATE;
- rc = -EINVAL;
- goto errorout;
- } else {
- CreateDisposition = FILE_OPEN_IF;
- }
- } else {
- CreateDisposition = FILE_OPEN;
- }
-
- if (cfs_is_flag_set(oflag, O_TRUNC)) {
- if (cfs_is_flag_set(oflag, O_EXCL)) {
- CreateDisposition = FILE_OVERWRITE;
- } else {
- CreateDisposition = FILE_OVERWRITE_IF;
- }
- }
-
- CreateOptions = 0;
-
- if (cfs_is_flag_set(oflag, O_DIRECTORY)) {
- cfs_set_flag(CreateOptions, FILE_DIRECTORY_FILE);
- }
-
- if (cfs_is_flag_set(oflag, O_SYNC)) {
- cfs_set_flag(CreateOptions, FILE_WRITE_THROUGH);
- }
-
- if (cfs_is_flag_set(oflag, O_DIRECT)) {
- cfs_set_flag(CreateOptions, FILE_NO_INTERMEDIATE_BUFFERING);
- }
-
- /* Initialize the unicode path name for the specified file */
- RtlInitUnicodeString(&UnicodeName, LUSTRE_PROC_SYMLNK);
-
- /* Setup the object attributes structure for the file. */
- InitializeObjectAttributes(
- &ObjectAttributes,
- &UnicodeName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL );
-
- /* building EA for the proc entry ... */
- EaBuffer = malloc(NameLength + sizeof(FILE_FULL_EA_INFORMATION));
- if (!EaBuffer) {
- rc = -ENOMEM;
- goto errorout;
- }
- memset(EaBuffer, 0, NameLength + sizeof(FILE_FULL_EA_INFORMATION));
- Ea = (PFILE_FULL_EA_INFORMATION)EaBuffer;
- Ea->NextEntryOffset = 0;
- Ea->Flags = 0;
- Ea->EaNameLength = (UCHAR)NameLength;
- Ea->EaValueLength = 0;
- RtlCopyMemory(
- &(Ea->EaName),
- filename,
- NameLength + 1
- );
- EaLength = sizeof(FILE_FULL_EA_INFORMATION) - 1 +
- Ea->EaNameLength + 1;
-
- /* Now to open or create the file now */
- status = NtCreateFile(
- &Handle,
- DesiredAccess,
- &ObjectAttributes,
- &iosb,
- 0,
- FILE_ATTRIBUTE_NORMAL,
- ShareAccess,
- CreateDisposition,
- CreateOptions,
- Ea,
- EaLength );
-
- /* Check the returned status of Iosb ... */
-
- if (!NT_SUCCESS(status)) {
- rc = cfs_error_code(status);
- goto errorout;
- }
-
-errorout:
-
- if (Handle) {
- rc = cfs_idr_get_new(cfs_proc_idp, Handle);
- if (rc < 0) {
- NtClose(Handle);
- }
- }
-
- if (EaBuffer) {
- free(EaBuffer);
- }
-
- return rc;
-}
-
-int cfs_proc_close(int fd)
-{
- HANDLE handle = cfs_idr_find(cfs_proc_idp, fd);
-
- if (handle) {
- NtClose(handle);
- }
-
- cfs_idr_remove(cfs_proc_idp, fd);
-
- return 0;
-}
-
-int cfs_proc_read_internal(
- int fd, void *buffer,
- unsigned int count,
- unsigned int offlow,
- unsigned int offhigh
- )
-{
- NTSTATUS status;
- IO_STATUS_BLOCK iosb;
- LARGE_INTEGER offset;
-
- HANDLE handle = cfs_idr_find(cfs_proc_idp, fd);
- offset.HighPart = offhigh;
- offset.LowPart = offlow;
-
- /* read file data */
- status = NtReadFile(
- handle,
- 0,
- NULL,
- NULL,
- &iosb,
- buffer,
- count,
- &offset,
- NULL);
-
- /* check the return status */
- if (!NT_SUCCESS(status)) {
- printf("NtReadFile request failed with status: 0x%0x\n", status);
- goto errorout;
- }
-
-errorout:
-
- if (NT_SUCCESS(status)) {
- return (int)(iosb.Information);
- }
-
- return cfs_error_code(status);
-}
-
-int cfs_proc_read(
- int fd, void *buffer,
- unsigned int count
- )
-{
- return cfs_proc_read_internal(fd, buffer, count, 0, 0);
-}
-
-int cfs_proc_write_internal(
- int fd, void *buffer,
- unsigned int count,
- unsigned int offlow,
- unsigned int offhigh
- )
-{
- NTSTATUS status;
- IO_STATUS_BLOCK iosb;
- LARGE_INTEGER offset;
-
- HANDLE handle = cfs_idr_find(cfs_proc_idp, fd);
- offset.HighPart = offhigh;
- offset.LowPart = offlow;
-
- /* write buffer to the opened file */
- status = NtWriteFile(
- handle,
- 0,
- NULL,
- NULL,
- &iosb,
- buffer,
- count,
- &offset,
- NULL);
-
- /* check the return status */
- if (!NT_SUCCESS(status)) {
- printf("NtWriteFile request failed 0x%0x\n", status);
- goto errorout;
- }
-
-errorout:
-
- if (NT_SUCCESS(status)) {
- return (int)(iosb.Information);
- }
-
- return cfs_error_code(status);
-}
-
-int cfs_proc_write(
- int fd, void *buffer,
- unsigned int count
- )
-{
- return cfs_proc_write_internal(fd, buffer, count, 0, 0);
-}
-
-int cfs_proc_ioctl(int fd, int cmd, void *buffer)
-{
- PUCHAR procdat = NULL;
- CFS_PROC_IOCTL procctl;
- ULONG length = 0;
- ULONG extra = 0;
- int rc = 0;
-
- NTSTATUS status = STATUS_UNSUCCESSFUL;
- IO_STATUS_BLOCK iosb;
-
- struct libcfs_ioctl_data * portal = buffer;
- struct obd_ioctl_data * obd = buffer;
- struct obd_ioctl_data * data;
-
- HANDLE handle = cfs_idr_find(cfs_proc_idp, fd);
-#if defined(_X86_)
- CLASSERT(sizeof(struct obd_ioctl_data) == 528);
-#else
- CLASSERT(sizeof(struct obd_ioctl_data) == 576);
-#endif
- memset(&procctl, 0, sizeof(CFS_PROC_IOCTL));
- procctl.cmd = cmd;
-
- if(_IOC_TYPE(cmd) == IOC_LIBCFS_TYPE) {
- length = portal->ioc_len;
- } else if (_IOC_TYPE(cmd) == 'f') {
- length = obd->ioc_len;
- extra = cfs_size_round(obd->ioc_plen1) + cfs_size_round(obd->ioc_plen2);
- } else if(_IOC_TYPE(cmd) == 'u') {
- length = 4;
- extra = 0;
- } else if(_IOC_TYPE(cmd) == 'i') {
- length = obd->ioc_len;
- extra = 0;
- } else {
- printf("cfs_proc_ioctl: un-supported ioctl type ...\n");
- cfs_enter_debugger();
- status = STATUS_INVALID_PARAMETER;
- goto errorout;
- }
-
- procctl.len = length + extra;
- procdat = malloc(length + extra + sizeof(CFS_PROC_IOCTL));
-
- if (NULL == procdat) {
- printf("user:winnt-proc:cfs_proc_ioctl: no enough memory ...\n");
- status = STATUS_INSUFFICIENT_RESOURCES;
- cfs_enter_debugger();
- goto errorout;
- }
- memset(procdat, 0, length + extra + sizeof(CFS_PROC_IOCTL));
- memcpy(procdat, &procctl, sizeof(CFS_PROC_IOCTL));
- memcpy(&procdat[sizeof(CFS_PROC_IOCTL)], buffer, length);
- length += sizeof(CFS_PROC_IOCTL);
-
- if (_IOC_TYPE(cmd) == 'f') {
-
- data = (struct obd_ioctl_data *) (procdat + sizeof(CFS_PROC_IOCTL));
- if ( cmd != (ULONG)OBD_IOC_BRW_WRITE &&
- cmd != (ULONG)OBD_IOC_BRW_READ ) {
-
- if (obd->ioc_pbuf1 && data->ioc_plen1) {
- data->ioc_pbuf1 = &procdat[length];
- memcpy(data->ioc_pbuf1, obd->ioc_pbuf1, obd->ioc_plen1);
- length += cfs_size_round(obd->ioc_plen1);
- } else {
- data->ioc_plen1 = 0;
- data->ioc_pbuf1 = NULL;
- }
-
- if (obd->ioc_pbuf2 && obd->ioc_plen2) {
- data->ioc_pbuf2 = &procdat[length];
- memcpy(data->ioc_pbuf2, obd->ioc_pbuf2, obd->ioc_plen2);
- length += cfs_size_round(obd->ioc_plen2);
- } else {
- data->ioc_plen2 = 0;
- data->ioc_pbuf2 = NULL;
- }
- } else {
- extra = 0;
- }
-
- ASSERT(length == extra + sizeof(CFS_PROC_IOCTL) + data->ioc_len);
- if (obd_ioctl_is_invalid(obd)) {
- cfs_enter_debugger();
- }
- }
-
- status = NtDeviceIoControlFile(
- handle, NULL, NULL,
- NULL, &iosb,
- IOCTL_LIBCFS_ENTRY,
- procdat, length,
- procdat, length );
-
-
- if (_IOC_TYPE(cmd) == 'f') {
-
- length = sizeof(CFS_PROC_IOCTL);
- ASSERT(data == (struct obd_ioctl_data *) (procdat + sizeof(CFS_PROC_IOCTL)));
- if ( cmd != (ULONG)OBD_IOC_BRW_WRITE &&
- cmd != (ULONG)OBD_IOC_BRW_READ ) {
-
- if (obd->ioc_pbuf1) {
- ASSERT(obd->ioc_plen1 == data->ioc_plen1);
- data->ioc_pbuf1 = &procdat[length];
- memcpy(obd->ioc_pbuf1, data->ioc_pbuf1, obd->ioc_plen1);
- length += cfs_size_round(obd->ioc_plen1);
- }
- if (obd->ioc_pbuf2) {
- ASSERT(obd->ioc_plen2 == data->ioc_plen2);
- data->ioc_pbuf2 = &procdat[length];
- memcpy(obd->ioc_pbuf2, data->ioc_pbuf2, obd->ioc_plen2);
- length += cfs_size_round(obd->ioc_plen2);
- }
- }
- data->ioc_inlbuf1 = obd->ioc_inlbuf1;
- data->ioc_inlbuf2 = obd->ioc_inlbuf2;
- data->ioc_inlbuf3 = obd->ioc_inlbuf3;
- data->ioc_inlbuf4 = obd->ioc_inlbuf4;
- data->ioc_pbuf1 = obd->ioc_pbuf1;
- data->ioc_pbuf2 = obd->ioc_pbuf2;
- memcpy(obd, data, obd->ioc_len);
-
- } else {
-
- memcpy(buffer, &procdat[sizeof(CFS_PROC_IOCTL)], procctl.len);
- }
-
-errorout:
-
- if (STATUS_SUCCESS == status) {
- rc = ((CFS_PROC_IOCTL *)procdat)->rc;
- } else {
- rc = cfs_error_code(status);
- }
-
- if (procdat) {
- free(procdat);
- }
-
- return rc;
-}
-
-
-int cfs_proc_mknod(const char *path, mode_t mode, dev_t dev)
-{
- return 0;
-}
-
-FILE *cfs_proc_fopen(char *path, char * mode)
-{
- int fp = cfs_proc_open(path, O_RDWR);
- if (fp > 0) {
- return (FILE *)(LONG_PTR)fp;
- }
-
- return NULL;
-}
-
-char *cfs_proc_fgets(char * buf, int len, FILE *fp)
-{
- int rc = 0;
-
- if (fp == NULL) {
- return NULL;
- }
-
- rc = cfs_proc_read_internal((int)(LONG_PTR)fp,
- buf, len, -1, 1);
- if (rc <= 0) {
- return NULL;
- }
-
- return buf;
-}
-
-int cfs_proc_fclose(FILE *fp)
-{
- if (fp == NULL) {
- return -1;
- }
-
- return cfs_proc_close((int)(LONG_PTR)fp);
-}
-
-void cfs_libc_init();
-
-int
-libcfs_arch_init(void)
-{
- cfs_libc_init();
- cfs_proc_idp = cfs_idr_init();
-
- if (cfs_proc_idp) {
- return 0;
- }
-
- return -ENOMEM;
-}
-
-void
-libcfs_arch_cleanup(void)
-{
- if (cfs_proc_idp) {
- cfs_idr_exit(cfs_proc_idp);
- cfs_proc_idp = NULL;
- }
-}
-
-#endif /* __KERNEL__ */
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2011, 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#define DEBUG_SUBSYSTEM S_LNET
-
-#include <libcfs/libcfs.h>
-
-
-/*
- * Thread routines
- */
-
-/*
- * cfs_thread_proc
- * Lustre thread procedure wrapper routine (It's an internal routine)
- *
- * Arguments:
- * context: a structure of cfs_thread_context_t, containing
- * all the necessary parameters
- *
- * Return Value:
- * void: N/A
- *
- * Notes:
- * N/A
- */
-
-void
-cfs_thread_proc(void *context)
-{
- cfs_thread_context_t * thread_context =
- (cfs_thread_context_t *) context;
-
- /* Execute the specified function ... */
-
- if (thread_context->func) {
- (thread_context->func)(thread_context->arg);
- }
-
- /* Free the context memory */
-
- kfree(context);
-
- /* Terminate this system thread */
-
- PsTerminateSystemThread(STATUS_SUCCESS);
-}
-
-/*
- * kthread_run
- * Create a system thread to execute the routine specified
- *
- * Arguments:
- * func: function to be executed in the thread
- * arg: argument transferred to func function
- * name: thread name to create
- *
- * Return Value:
- * struct task_struct: 0 on success or error codes
- *
- * Notes:
- * N/A
- */
-
-struct task_struct kthread_run(int (*func)(void *), void *arg, char *name)
-{
- cfs_handle_t thread = NULL;
- NTSTATUS status;
- cfs_thread_context_t *context = NULL;
-
- /* Allocate the context to be transferred to system thread */
-
- context = kmalloc(sizeof(cfs_thread_context_t), __GFP_ZERO);
-
- if (!context) {
- return ERR_PTR(-ENOMEM);
- }
-
- context->func = func;
- context->arg = arg;
-
- /* Create system thread with the cfs_thread_proc wrapper */
-
- status = PsCreateSystemThread(
- &thread,
- (ACCESS_MASK)0L,
- 0, 0, 0,
- cfs_thread_proc,
- context);
-
- if (!NT_SUCCESS(status)) {
-
-
- kfree(context);
-
- /* We need translate the nt status to linux error code */
-
- return ERR_PTR(cfs_error_code(status));
- }
-
- //
- // Query the thread id of the newly created thread
- //
-
- ZwClose(thread);
-
- return (struct task_struct)0;
-}
-
-
-/*
- * Symbols routines
- */
-
-
-static DECLARE_RWSEM(cfs_symbol_lock);
-struct list_head cfs_symbol_list = LIST_HEAD_INIT(cfs_symbol_list);
-
-int libcfs_is_mp_system = FALSE;
-
-/*
- * cfs_symbol_get
- * To query the specified symbol form the symbol table
- *
- * Arguments:
- * name: the symbol name to be queried
- *
- * Return Value:
- * If the symbol is in the table, return the address of it.
- * If not, return NULL.
- *
- * Notes:
- * N/A
- */
-
-void *
-cfs_symbol_get(const char *name)
-{
- struct list_head *walker;
- struct cfs_symbol *sym = NULL;
-
- down_read(&cfs_symbol_lock);
- list_for_each(walker, &cfs_symbol_list) {
- sym = list_entry (walker, struct cfs_symbol, sym_list);
- if (!strcmp(sym->name, name)) {
- sym->ref ++;
- break;
- }
- }
- up_read(&cfs_symbol_lock);
-
- if (sym != NULL)
- return sym->value;
-
- return NULL;
-}
-
-/*
- * cfs_symbol_put
- * To decrease the reference of the specified symbol
- *
- * Arguments:
- * name: the symbol name to be dereferred
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void
-cfs_symbol_put(const char *name)
-{
- struct list_head *walker;
- struct cfs_symbol *sym = NULL;
-
- down_read(&cfs_symbol_lock);
- list_for_each(walker, &cfs_symbol_list) {
- sym = list_entry (walker, struct cfs_symbol, sym_list);
- if (!strcmp(sym->name, name)) {
- LASSERT(sym->ref > 0);
- sym->ref--;
- break;
- }
- }
- up_read(&cfs_symbol_lock);
-
- LASSERT(sym != NULL);
-}
-
-
-/*
- * cfs_symbol_register
- * To register the specified symbol infromation
- *
- * Arguments:
- * name: the symbol name to be dereferred
- * value: the value that the symbol stands for
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * Zero: Succeed to register
- * Non-Zero: Fail to register the symbol
- */
-
-int
-cfs_symbol_register(const char *name, const void *value)
-{
- struct list_head *walker;
- struct cfs_symbol *sym = NULL;
- struct cfs_symbol *new = NULL;
-
- new = kmalloc(sizeof(struct cfs_symbol), __GFP_ZERO);
- if (!new)
- return -ENOMEM;
-
- strncpy(new->name, name, CFS_SYMBOL_LEN);
- new->value = (void *)value;
- new->ref = 0;
- INIT_LIST_HEAD(&new->sym_list);
-
- down_write(&cfs_symbol_lock);
- list_for_each(walker, &cfs_symbol_list) {
- sym = list_entry (walker, struct cfs_symbol, sym_list);
- if (!strcmp(sym->name, name)) {
- up_write(&cfs_symbol_lock);
- kfree(new);
- return 0; /* alreay registerred */
- }
- }
- list_add_tail(&new->sym_list, &cfs_symbol_list);
- up_write(&cfs_symbol_lock);
-
- return 0;
-}
-
-/*
- * cfs_symbol_unregister
- * To unregister/remove the specified symbol
- *
- * Arguments:
- * name: the symbol name to be dereferred
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void
-cfs_symbol_unregister(const char *name)
-{
- struct list_head *walker;
- struct list_head *nxt;
- struct cfs_symbol *sym = NULL;
-
- down_write(&cfs_symbol_lock);
- list_for_each_safe(walker, nxt, &cfs_symbol_list) {
- sym = list_entry (walker, struct cfs_symbol, sym_list);
- if (!strcmp(sym->name, name)) {
- LASSERT(sym->ref == 0);
- list_del (&sym->sym_list);
- kfree(sym);
- break;
- }
- }
- up_write(&cfs_symbol_lock);
-}
-
-/*
- * cfs_symbol_clean
- * To clean all the symbols
- *
- * Arguments:
- * N/A
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void
-cfs_symbol_clean()
-{
- struct list_head *walker;
- struct cfs_symbol *sym = NULL;
-
- down_write(&cfs_symbol_lock);
- list_for_each(walker, &cfs_symbol_list) {
- sym = list_entry (walker, struct cfs_symbol, sym_list);
- LASSERT(sym->ref == 0);
- list_del (&sym->sym_list);
- kfree(sym);
- }
- up_write(&cfs_symbol_lock);
- return;
-}
-
-
-
-/*
- * Timer routines
- */
-
-
-/* Timer dpc procedure */
-
-static void
-cfs_timer_dpc_proc (
- IN PKDPC Dpc,
- IN PVOID DeferredContext,
- IN PVOID SystemArgument1,
- IN PVOID SystemArgument2)
-{
- struct timer_list * timer;
- KIRQL Irql;
-
- timer = (struct timer_list *) DeferredContext;
-
- /* clear the flag */
- KeAcquireSpinLock(&(timer->Lock), &Irql);
- cfs_clear_flag(timer->Flags, CFS_TIMER_FLAG_TIMERED);
- KeReleaseSpinLock(&(timer->Lock), Irql);
-
- /* call the user specified timer procedure */
- timer->proc((long_ptr_t)timer->arg);
-}
-
-void cfs_init_timer(struct timer_list *timer)
-{
- memset(timer, 0, sizeof(struct timer_list));
-}
-
-/*
- * cfs_timer_init
- * To initialize the struct timer_list
- *
- * Arguments:
- * timer: the cfs_timer to be initialized
- * func: the timer callback procedure
- * arg: argument for the callback proc
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void cfs_timer_init(struct timer_list *timer, void (*func)(ulong_ptr_t), void *arg)
-{
- memset(timer, 0, sizeof(struct timer_list));
-
- timer->proc = func;
- timer->arg = arg;
-
- KeInitializeSpinLock(&(timer->Lock));
- KeInitializeTimer(&timer->Timer);
- KeInitializeDpc (&timer->Dpc, cfs_timer_dpc_proc, timer);
-
- cfs_set_flag(timer->Flags, CFS_TIMER_FLAG_INITED);
-}
-
-/*
- * cfs_timer_done
- * To finialize the struct timer_list (unused)
- *
- * Arguments:
- * timer: the cfs_timer to be cleaned up
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void cfs_timer_done(struct timer_list *timer)
-{
- return;
-}
-
-/*
- * cfs_timer_arm
- * To schedule the timer while touching @deadline
- *
- * Arguments:
- * timer: the cfs_timer to be freed
- * dealine: timeout value to wake up the timer
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void cfs_timer_arm(struct timer_list *timer, cfs_time_t deadline)
-{
- LARGE_INTEGER timeout;
- KIRQL Irql;
-
- KeAcquireSpinLock(&(timer->Lock), &Irql);
- if (!cfs_is_flag_set(timer->Flags, CFS_TIMER_FLAG_TIMERED)){
-
- timeout.QuadPart = (LONGLONG)-1*1000*1000*10/HZ*deadline;
-
- if (KeSetTimer(&timer->Timer, timeout, &timer->Dpc)) {
- cfs_set_flag(timer->Flags, CFS_TIMER_FLAG_TIMERED);
- }
-
- timer->deadline = deadline;
- }
-
- KeReleaseSpinLock(&(timer->Lock), Irql);
-}
-
-/*
- * cfs_timer_disarm
- * To discard the timer to be scheduled
- *
- * Arguments:
- * timer: the cfs_timer to be discarded
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void cfs_timer_disarm(struct timer_list *timer)
-{
- KIRQL Irql;
-
- KeAcquireSpinLock(&(timer->Lock), &Irql);
- KeCancelTimer(&(timer->Timer));
- cfs_clear_flag(timer->Flags, CFS_TIMER_FLAG_TIMERED);
- KeReleaseSpinLock(&(timer->Lock), Irql);
-}
-
-
-/*
- * cfs_timer_is_armed
- * To check the timer is scheduled or not
- *
- * Arguments:
- * timer: the cfs_timer to be checked
- *
- * Return Value:
- * 1: if it's armed.
- * 0: if it's not.
- *
- * Notes:
- * N/A
- */
-
-int cfs_timer_is_armed(struct timer_list *timer)
-{
- int rc = 0;
- KIRQL Irql;
-
- KeAcquireSpinLock(&(timer->Lock), &Irql);
- if (cfs_is_flag_set(timer->Flags, CFS_TIMER_FLAG_TIMERED)) {
- rc = 1;
- }
- KeReleaseSpinLock(&(timer->Lock), Irql);
-
- return rc;
-}
-
-/*
- * cfs_timer_deadline
- * To query the deadline of the timer
- *
- * Arguments:
- * timer: the cfs_timer to be queried
- *
- * Return Value:
- * the deadline value
- *
- * Notes:
- * N/A
- */
-
-cfs_time_t cfs_timer_deadline(struct timer_list * timer)
-{
- return timer->deadline;
-}
-
-int unshare_fs_struct()
-{
- return 0;
-}
-
-/*
- * routine related with sigals
- */
-
-sigset_t cfs_block_allsigs()
-{
- return 0;
-}
-
-sigset_t cfs_block_sigs(sigset_t bit)
-{
- return 0;
-}
-
-/* Block all signals except for the @sigs. It's only used in
- * Linux kernel, just a dummy here. */
-sigset_t cfs_block_sigsinv(unsigned long sigs)
-{
- return 0;
-}
-
-void cfs_restore_sigs(sigset_t old)
-{
-}
-
-int cfs_signal_pending(void)
-{
- return 0;
-}
-
-void cfs_clear_sigpending(void)
-{
- return;
-}
-
-/*
- * thread cpu affinity routines
- */
-
-typedef struct _THREAD_BASIC_INFORMATION {
- NTSTATUS ExitStatus;
- PVOID TebBaseAddress;
- CLIENT_ID ClientId;
- ULONG_PTR AffinityMask;
- KPRIORITY Priority;
- LONG BasePriority;
-} THREAD_BASIC_INFORMATION;
-
-typedef THREAD_BASIC_INFORMATION *PTHREAD_BASIC_INFORMATION;
-
-#define THREAD_QUERY_INFORMATION (0x0040)
-
-NTSYSAPI
-NTSTATUS
-NTAPI
-ZwOpenThread (
- __out PHANDLE ThreadHandle,
- __in ACCESS_MASK DesiredAccess,
- __in POBJECT_ATTRIBUTES ObjectAttributes,
- __in_opt PCLIENT_ID ClientId
- );
-
-NTSYSAPI
-NTSTATUS
-NTAPI
-ZwQueryInformationThread (
- __in HANDLE ThreadHandle,
- __in THREADINFOCLASS ThreadInformationClass,
- __out_bcount(ThreadInformationLength) PVOID ThreadInformation,
- __in ULONG ThreadInformationLength,
- __out_opt PULONG ReturnLength
- );
-
-NTSYSAPI
-NTSTATUS
-NTAPI
-ZwSetInformationThread (
- __in HANDLE ThreadHandle,
- __in THREADINFOCLASS ThreadInformationClass,
- __in_bcount(ThreadInformationLength) PVOID ThreadInformation,
- __in ULONG ThreadInformationLength
- );
-
-HANDLE
-cfs_open_current_thread()
-{
- NTSTATUS status;
- HANDLE handle = NULL;
- OBJECT_ATTRIBUTES oa;
- CLIENT_ID cid;
-
- /* initialize object attributes */
- InitializeObjectAttributes( &oa, NULL, OBJ_KERNEL_HANDLE |
- OBJ_CASE_INSENSITIVE, NULL, NULL);
-
- /* initialize client id */
- cid.UniqueProcess = PsGetCurrentProcessId();
- cid.UniqueThread = PsGetCurrentThreadId();
-
- /* get thread handle */
- status = ZwOpenThread( &handle, THREAD_QUERY_INFORMATION |
- THREAD_SET_INFORMATION, &oa, &cid);
- if (!NT_SUCCESS(status)) {
- handle = NULL;
- }
-
- return handle;
-}
-
-void
-cfs_close_thread_handle(HANDLE handle)
-{
- if (handle)
- ZwClose(handle);
-}
-
-KAFFINITY
-cfs_query_thread_affinity()
-{
- NTSTATUS status;
- HANDLE handle = NULL;
- DWORD size;
- THREAD_BASIC_INFORMATION TBI = {0};
-
- /* open current thread */
- handle = cfs_open_current_thread();
- if (!handle) {
- goto errorout;
- }
-
- /* query thread cpu affinity */
- status = ZwQueryInformationThread(handle, ThreadBasicInformation,
- &TBI, sizeof(THREAD_BASIC_INFORMATION), &size);
- if (!NT_SUCCESS(status)) {
- goto errorout;
- }
-
-errorout:
-
- cfs_close_thread_handle(handle);
- return TBI.AffinityMask;
-}
-
-int
-cfs_set_thread_affinity(KAFFINITY affinity)
-{
- NTSTATUS status;
- HANDLE handle = NULL;
-
- /* open current thread */
- handle = cfs_open_current_thread();
- if (!handle) {
- goto errorout;
- }
-
- /* set thread cpu affinity */
- status = ZwSetInformationThread(handle, ThreadAffinityMask,
- &affinity, sizeof(KAFFINITY));
- if (!NT_SUCCESS(status)) {
- goto errorout;
- }
-
-errorout:
-
- cfs_close_thread_handle(handle);
- return NT_SUCCESS(status);
-}
-
-int
-cfs_tie_thread_to_cpu(int cpu)
-{
- return cfs_set_thread_affinity((KAFFINITY) (1 << cpu));
-}
-
-int
-cfs_set_thread_priority(KPRIORITY priority)
-{
- NTSTATUS status;
- HANDLE handle = NULL;
-
- /* open current thread */
- handle = cfs_open_current_thread();
- if (!handle) {
- goto errorout;
- }
-
- /* set thread cpu affinity */
- status = ZwSetInformationThread(handle, ThreadPriority,
- &priority, sizeof(KPRIORITY));
- if (!NT_SUCCESS(status)) {
- KdPrint(("set_thread_priority failed: %xh\n", status));
- goto errorout;
- }
-
-errorout:
-
- cfs_close_thread_handle(handle);
- return NT_SUCCESS(status);
-}
-
-int need_resched(void)
-{
- return 0;
-}
-
-void cond_resched(void)
-{
-}
-
-/**
- ** Initialize routines
- **/
-
-void cfs_libc_init();
-
-int
-libcfs_arch_init(void)
-{
- int rc;
- spinlock_t lock;
-
- /* Workground to check the system is MP build or UP build */
- spin_lock_init(&lock);
- spin_lock(&lock);
- libcfs_is_mp_system = (int)lock.lock;
- /* MP build system: it's a real spin, for UP build system, it
- * only raises the IRQL to DISPATCH_LEVEL */
- spin_unlock(&lock);
-
- /* initialize libc routines (confliction between libcnptr.lib
- and kernel ntoskrnl.lib) */
- cfs_libc_init();
-
- /* create slab memory caches for page alloctors */
- cfs_page_t_slab = kmem_cache_create("CPGT", sizeof(struct page),
- 0, 0, NULL);
-
- cfs_page_p_slab = kmem_cache_create("CPGP", PAGE_CACHE_SIZE,
- 0, 0, NULL);
-
- if ( cfs_page_t_slab == NULL ||
- cfs_page_p_slab == NULL ){
- rc = -ENOMEM;
- goto errorout;
- }
-
- rc = init_task_manager();
- if (rc != 0) {
- cfs_enter_debugger();
- KdPrint(("winnt-prim.c:libcfs_arch_init: error initializing task manager ...\n"));
- goto errorout;
- }
-
- /* initialize the proc file system */
- rc = proc_init_fs();
- if (rc != 0) {
- cfs_enter_debugger();
- KdPrint(("winnt-prim.c:libcfs_arch_init: error initializing proc fs ...\n"));
- cleanup_task_manager();
- goto errorout;
- }
-
- /* initialize the tdi data */
- rc = ks_init_tdi_data();
- if (rc != 0) {
- cfs_enter_debugger();
- KdPrint(("winnt-prim.c:libcfs_arch_init: failed to initialize tdi.\n"));
- proc_destroy_fs();
- cleanup_task_manager();
- goto errorout;
- }
-
- rc = start_shrinker_timer();
-
-errorout:
-
- if (rc != 0) {
- /* destroy the taskslot cache slab */
- if (cfs_page_t_slab)
- kmem_cache_destroy(cfs_page_t_slab);
- if (cfs_page_p_slab)
- kmem_cache_destroy(cfs_page_p_slab);
- }
-
- return rc;
-}
-
-void
-libcfs_arch_cleanup(void)
-{
- /* stop shrinker timer */
- stop_shrinker_timer();
-
- /* finialize the tdi data */
- ks_fini_tdi_data();
-
- /* detroy the whole proc fs tree and nodes */
- proc_destroy_fs();
-
- /* cleanup context of task manager */
- cleanup_task_manager();
-
- /* destroy the taskslot cache slab */
- if (cfs_page_t_slab) {
-kmem_cache_destroy(cfs_page_t_slab);
- }
-
- if (cfs_page_p_slab) {
-kmem_cache_destroy(cfs_page_p_slab);
- }
-
- return;
-}
-
-EXPORT_SYMBOL(libcfs_arch_init);
-EXPORT_SYMBOL(libcfs_arch_cleanup);
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-# define DEBUG_SUBSYSTEM S_LNET
-
-#include <libcfs/libcfs.h>
-#include "tracefile.h"
-#include <lustre_lib.h>
-
-#ifdef __KERNEL__
-
-
-/*
- * /proc emulator routines ...
- */
-
-/* The root node of the proc fs emulation: / */
-cfs_proc_entry_t * cfs_proc_root = NULL;
-
-/* The root node of the proc fs emulation: /proc */
-cfs_proc_entry_t * cfs_proc_proc = NULL;
-
-/* The fs sys directory: /proc/fs */
-cfs_proc_entry_t * cfs_proc_fs = NULL;
-
-/* The sys root: /proc/sys */
-cfs_proc_entry_t * cfs_proc_sys = NULL;
-
-/* The sys root: /proc/dev | to implement misc device */
-cfs_proc_entry_t * cfs_proc_dev = NULL;
-
-
-/* SLAB object for cfs_proc_entry_t allocation */
-struct kmem_cache *proc_entry_cache;
-
-/* root node for sysctl table */
-struct ctl_table_header root_table_header;
-
-/* The global lock to protect all the access */
-
-#if LIBCFS_PROCFS_SPINLOCK
-spinlock_t proc_fs_lock;
-
-#define INIT_PROCFS_LOCK() spin_lock_init(&proc_fs_lock)
-#define LOCK_PROCFS() spin_lock(&proc_fs_lock)
-#define UNLOCK_PROCFS() spin_unlock(&proc_fs_lock)
-
-#else
-
-struct mutex proc_fs_lock;
-
-#define INIT_PROCFS_LOCK() cfs_init_mutex(&proc_fs_lock)
-#define LOCK_PROCFS() mutex_lock(&proc_fs_lock)
-#define UNLOCK_PROCFS() mutex_unlock(&proc_fs_lock)
-
-#endif
-
-static ssize_t
-proc_file_read(struct file * file, const char * buf, size_t nbytes, loff_t *ppos)
-{
- char *page;
- ssize_t retval=0;
- int eof=0;
- ssize_t n, count;
- char *start;
- cfs_proc_entry_t * dp;
-
- dp = (cfs_proc_entry_t *) file->f_inode->i_priv;
- page = (char *) kmalloc(PAGE_CACHE_SIZE, 0);
- if (page == NULL)
- return -ENOMEM;
-
- while ((nbytes > 0) && !eof) {
-
- count = min_t(size_t, PROC_BLOCK_SIZE, nbytes);
-
- start = NULL;
- if (dp->read_proc) {
- n = dp->read_proc( page, &start, (long)*ppos,
- count, &eof, dp->data);
- } else
- break;
-
- if (!start) {
- /*
- * For proc files that are less than 4k
- */
- start = page + *ppos;
- n -= (ssize_t)(*ppos);
- if (n <= 0)
- break;
- if (n > count)
- n = count;
- }
- if (n == 0)
- break; /* End of file */
- if (n < 0) {
- if (retval == 0)
- retval = n;
- break;
- }
-
- n -= copy_to_user((void *)buf, start, n);
- if (n == 0) {
- if (retval == 0)
- retval = -EFAULT;
- break;
- }
-
- *ppos += n;
- nbytes -= n;
- buf += n;
- retval += n;
- }
- kfree(page);
-
- return retval;
-}
-
-static ssize_t
-proc_file_write(struct file * file, const char * buffer,
- size_t count, loff_t *ppos)
-{
- cfs_proc_entry_t * dp;
-
- dp = (cfs_proc_entry_t *) file->f_inode->i_priv;
-
- if (!dp->write_proc)
- return -EIO;
-
- /* FIXME: does this routine need ppos? probably... */
- return dp->write_proc(file, buffer, count, dp->data);
-}
-
-struct file_operations proc_file_operations = {
- /*owner*/ THIS_MODULE,
- /*lseek:*/ NULL, //proc_file_lseek,
- /*read:*/ proc_file_read,
- /*write:*/ proc_file_write,
- /*ioctl:*/ NULL,
- /*open:*/ NULL,
- /*release:*/ NULL
-};
-
-/* allocate proc entry block */
-
-cfs_proc_entry_t *
-proc_alloc_entry()
-{
- cfs_proc_entry_t * entry = NULL;
-
- entry = kmem_cache_alloc(proc_entry_cache, 0);
- if (!entry)
- return NULL;
-
- memset(entry, 0, sizeof(cfs_proc_entry_t));
-
- entry->magic = CFS_PROC_ENTRY_MAGIC;
- RtlInitializeSplayLinks(&(entry->s_link));
- entry->proc_fops = &proc_file_operations;
-
- return entry;
-}
-
-/* free the proc entry block */
-
-void
-proc_free_entry(cfs_proc_entry_t * entry)
-{
- ASSERT(entry->magic == CFS_PROC_ENTRY_MAGIC);
- kmem_cache_free(proc_entry_cache, entry);
-}
-
-/* dissect the path string for a given full proc path */
-
-void
-proc_dissect_name(
- const char *path,
- char **first,
- int *first_len,
- char **remain
- )
-{
- int i = 0, j = 0, len = 0;
-
- *first = *remain = NULL;
- *first_len = 0;
-
- len = strlen(path);
-
- while (i < len && (path[i] == '/')) i++;
-
- if (i < len) {
-
- *first = (char *)path + i;
- while (i < len && (path[i] != '/')) i++;
- *first_len = (int)(path + i - *first);
-
- if (i + 1 < len) {
- *remain = (char *)path + i + 1;
- }
- }
-}
-
-/* search the children entries of the parent entry */
-
-cfs_proc_entry_t *
-proc_search_splay (
- cfs_proc_entry_t * parent,
- char * name
- )
-{
- cfs_proc_entry_t * node;
- PRTL_SPLAY_LINKS link;
-
- ASSERT(parent->magic == CFS_PROC_ENTRY_MAGIC);
- ASSERT(cfs_is_flag_set(parent->flags, CFS_PROC_FLAG_DIRECTORY));
-
- link = parent->root;
-
- while (link) {
-
- ANSI_STRING ename,nname;
- long result;
-
- node = CONTAINING_RECORD(link, cfs_proc_entry_t, s_link);
-
- ASSERT(node->magic == CFS_PROC_ENTRY_MAGIC);
-
- /* Compare the prefix in the tree with the full name */
-
- RtlInitAnsiString(&ename, name);
- RtlInitAnsiString(&nname, node->name);
-
- result = RtlCompareString(&nname, &ename,TRUE);
-
- if (result > 0) {
-
- /* The prefix is greater than the full name
- so we go down the left child */
-
- link = RtlLeftChild(link);
-
- } else if (result < 0) {
-
- /* The prefix is less than the full name
- so we go down the right child */
-
- link = RtlRightChild(link);
-
- } else {
-
- /* We got the entry in the splay tree and
- make it root node instead */
-
- parent->root = RtlSplay(link);
-
- return node;
- }
-
- /* we need continue searching down the tree ... */
- }
-
- /* There's no the exptected entry in the splay tree */
-
- return NULL;
-}
-
-int
-proc_insert_splay (
- cfs_proc_entry_t * parent,
- cfs_proc_entry_t * child
- )
-{
- cfs_proc_entry_t * entry;
-
- ASSERT(parent != NULL && child != NULL);
- ASSERT(parent->magic == CFS_PROC_ENTRY_MAGIC);
- ASSERT(child->magic == CFS_PROC_ENTRY_MAGIC);
- ASSERT(cfs_is_flag_set(parent->flags, CFS_PROC_FLAG_DIRECTORY));
-
- if (!parent->root) {
- parent->root = &(child->s_link);
- } else {
- entry = CONTAINING_RECORD(parent->root, cfs_proc_entry_t, s_link);
- while (TRUE) {
- long result;
- ANSI_STRING ename, cname;
-
- ASSERT(entry->magic == CFS_PROC_ENTRY_MAGIC);
-
- RtlInitAnsiString(&ename, entry->name);
- RtlInitAnsiString(&cname, child->name);
-
- result = RtlCompareString(&ename, &cname,TRUE);
-
- if (result == 0) {
- cfs_enter_debugger();
- if (entry == child) {
- break;
- }
- return FALSE;
- }
-
- if (result > 0) {
- if (RtlLeftChild(&entry->s_link) == NULL) {
- RtlInsertAsLeftChild(&entry->s_link, &child->s_link);
- break;
- } else {
- entry = CONTAINING_RECORD( RtlLeftChild(&entry->s_link),
- cfs_proc_entry_t, s_link);
- }
- } else {
- if (RtlRightChild(&entry->s_link) == NULL) {
- RtlInsertAsRightChild(&entry->s_link, &child->s_link);
- break;
- } else {
- entry = CONTAINING_RECORD( RtlRightChild(&entry->s_link),
- cfs_proc_entry_t, s_link );
- }
- }
- }
- }
-
- cfs_set_flag(child->flags, CFS_PROC_FLAG_ATTACHED);
- parent->nlink++;
- child->parent = parent;
-
- return TRUE;
-}
-
-
-/* remove a child entry from the splay tree */
-int
-proc_remove_splay (
- cfs_proc_entry_t * parent,
- cfs_proc_entry_t * child
- )
-{
- cfs_proc_entry_t * entry = NULL;
-
- ASSERT(parent != NULL && child != NULL);
- ASSERT(parent->magic == CFS_PROC_ENTRY_MAGIC);
- ASSERT(child->magic == CFS_PROC_ENTRY_MAGIC);
- ASSERT(cfs_is_flag_set(parent->flags, CFS_PROC_FLAG_DIRECTORY));
- ASSERT(cfs_is_flag_set(child->flags, CFS_PROC_FLAG_ATTACHED));
- ASSERT(child->parent == parent);
-
- entry = proc_search_splay(parent, child->name);
-
- if (entry) {
- ASSERT(entry == child);
- parent->root = RtlDelete(&(entry->s_link));
- parent->nlink--;
- } else {
- cfs_enter_debugger();
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-/* search a node inside the proc fs tree */
-
-cfs_proc_entry_t *
-proc_search_entry(
- const char * name,
- cfs_proc_entry_t * root
- )
-{
- cfs_proc_entry_t * entry;
- cfs_proc_entry_t * parent;
- char *first, *remain;
- int flen;
- char *ename = NULL;
-
- parent = root;
- entry = NULL;
-
- ename = kmalloc(0x21, __GFP_ZERO);
-
- if (ename == NULL)
- goto errorout;
-
-again:
-
- /* dissect the file name string */
- proc_dissect_name(name, &first, &flen, &remain);
-
- if (first) {
-
- if (flen >= 0x20) {
- cfs_enter_debugger();
- entry = NULL;
- goto errorout;
- }
-
- memset(ename, 0, 0x20);
- memcpy(ename, first, flen);
-
- entry = proc_search_splay(parent, ename);
-
- if (!entry) {
- goto errorout;
- }
-
- if (remain) {
- name = remain;
- parent = entry;
-
- goto again;
- }
- }
-
-errorout:
-
- if (ename) {
- kfree(ename);
- }
-
- return entry;
-}
-
-/* insert the path nodes to the proc fs tree */
-
-cfs_proc_entry_t *
-proc_insert_entry(
- const char * name,
- cfs_proc_entry_t * root
- )
-{
- cfs_proc_entry_t *entry;
- cfs_proc_entry_t *parent;
- char *first, *remain;
- int flen;
- char ename[0x20];
-
- parent = root;
- entry = NULL;
-
-again:
-
- proc_dissect_name(name, &first, &flen, &remain);
-
- if (first) {
-
- if (flen >= 0x20) {
- return NULL;
- }
-
- memset(ename, 0, 0x20);
- memcpy(ename, first, flen);
-
- entry = proc_search_splay(parent, ename);
-
- if (!entry) {
- entry = proc_alloc_entry();
- memcpy(entry->name, ename, flen);
-
- if (entry && !proc_insert_splay(parent, entry)) {
- proc_free_entry(entry);
- entry = NULL;
- }
- }
-
- if (!entry) {
- return NULL;
- }
-
- if (remain) {
- entry->mode |= S_IFDIR | S_IRUGO | S_IXUGO;
- cfs_set_flag(entry->flags, CFS_PROC_FLAG_DIRECTORY);
- name = remain;
- parent = entry;
- goto again;
- }
- }
-
- return entry;
-}
-
-/* remove the path nodes from the proc fs tree */
-
-void
-proc_remove_entry(
- const char * name,
- cfs_proc_entry_t * root
- )
-{
- cfs_proc_entry_t *entry;
- char *first, *remain;
- int flen;
- char ename[0x20];
-
- entry = NULL;
-
- proc_dissect_name(name, &first, &flen, &remain);
-
- if (first) {
-
- memset(ename, 0, 0x20);
- memcpy(ename, first, flen);
-
- entry = proc_search_splay(root, ename);
-
- if (entry) {
-
- if (remain) {
- ASSERT(S_ISDIR(entry->mode));
- proc_remove_entry(remain, entry);
- }
-
- if (!entry->nlink) {
- proc_remove_splay(root, entry);
- proc_free_entry(entry);
- }
- }
- } else {
- cfs_enter_debugger();
- }
-}
-
-/* create proc entry and insert it into the proc fs */
-
-cfs_proc_entry_t *
-create_proc_entry (
- const char * name,
- mode_t mode,
- cfs_proc_entry_t * parent
- )
-{
- cfs_proc_entry_t *entry = NULL;
-
- if (S_ISDIR(mode)) {
- if ((mode & S_IALLUGO) == 0)
- mode |= S_IRUGO | S_IXUGO;
- } else {
- if ((mode & S_IFMT) == 0)
- mode |= S_IFREG;
- if ((mode & S_IALLUGO) == 0)
- mode |= S_IRUGO;
- }
-
- LOCK_PROCFS();
- ASSERT(NULL != cfs_proc_root);
-
- if (!parent) {
- if (name[0] == '/') {
- parent = cfs_proc_root;
- } else {
- ASSERT(NULL != cfs_proc_proc);
- parent = cfs_proc_proc;
- }
- }
-
- entry = proc_search_entry(name, parent);
-
- if (!entry) {
- entry = proc_insert_entry(name, parent);
- if (!entry) {
- /* Failed to create/insert the splay node ... */
- cfs_enter_debugger();
- goto errorout;
- }
- /* Initializing entry ... */
- entry->mode = mode;
-
- if (S_ISDIR(mode)) {
- cfs_set_flag(entry->flags, CFS_PROC_FLAG_DIRECTORY);
- }
- }
-
-errorout:
-
- UNLOCK_PROCFS();
-
- return entry;
-}
-
-
-/* search the specified entry form the proc fs */
-
-cfs_proc_entry_t *
-search_proc_entry(
- const char * name,
- cfs_proc_entry_t * root
- )
-{
- cfs_proc_entry_t * entry;
-
- LOCK_PROCFS();
- ASSERT(cfs_proc_root != NULL);
- if (root == NULL) {
- if (name[0] == '/') {
- root = cfs_proc_root;
- } else {
- ASSERT(cfs_proc_proc != NULL);
- root = cfs_proc_proc;
- }
- }
- entry = proc_search_entry(name, root);
- UNLOCK_PROCFS();
-
- return entry;
-}
-
-/* remove the entry from the proc fs */
-
-void
-remove_proc_entry(
- const char * name,
- cfs_proc_entry_t * parent
- )
-{
- LOCK_PROCFS();
- ASSERT(cfs_proc_root != NULL);
- if (parent == NULL) {
- if (name[0] == '/') {
- parent = cfs_proc_root;
- } else {
- ASSERT(cfs_proc_proc != NULL);
- parent = cfs_proc_proc;
- }
- }
- proc_remove_entry(name, parent);
- UNLOCK_PROCFS();
-}
-
-
-void proc_destroy_splay(cfs_proc_entry_t * entry)
-{
- cfs_proc_entry_t * node;
-
- if (S_ISDIR(entry->mode)) {
-
- while (entry->root) {
- node = CONTAINING_RECORD(entry->root, cfs_proc_entry_t, s_link);
- entry->root = RtlDelete(&(node->s_link));
- proc_destroy_splay(node);
- }
- }
-
- proc_free_entry(entry);
-}
-
-cfs_proc_entry_t *proc_symlink(
- const char *name,
- cfs_proc_entry_t *parent,
- const char *dest
- )
-{
- cfs_enter_debugger();
- return NULL;
-}
-
-cfs_proc_entry_t *proc_mkdir(
- const char *name,
- cfs_proc_entry_t *parent)
-{
- return create_proc_entry((char *)name, S_IFDIR, parent);
-}
-
-void proc_destory_subtree(cfs_proc_entry_t *entry)
-{
- LOCK_PROCFS();
- entry->root = NULL;
- proc_destroy_splay(entry);
- UNLOCK_PROCFS();
-}
-
-/* destory the whole proc fs tree */
-
-void proc_destroy_fs()
-{
- LOCK_PROCFS();
-
- if (cfs_proc_root)
- proc_destroy_splay(cfs_proc_root);
-
- if (proc_entry_cache)
- kmem_cache_destroy(proc_entry_cache);
-
- UNLOCK_PROCFS();
-}
-
-static char proc_item_path[512];
-
-
-void proc_show_tree(cfs_proc_entry_t * node);
-void proc_print_node(cfs_proc_entry_t * node)
-{
- if (node != cfs_proc_root) {
- if (S_ISDIR(node->mode)) {
- printk("%s/%s/\n", proc_item_path, node->name);
- } else {
- printk("%s/%s\n", proc_item_path, node->name);
- }
- } else {
- printk("%s\n", node->name);
- }
-
- if (S_ISDIR(node->mode)) {
- proc_show_tree(node);
- }
-}
-
-void proc_show_child(PRTL_SPLAY_LINKS link)
-{
- cfs_proc_entry_t * entry = NULL;
-
- if (!link) {
- return;
- }
-
- proc_show_child(link->LeftChild);
- entry = CONTAINING_RECORD(link, cfs_proc_entry_t, s_link);
- proc_print_node(entry);
- proc_show_child(link->RightChild);
-}
-
-void proc_show_tree(cfs_proc_entry_t * node)
-{
- PRTL_SPLAY_LINKS link = NULL;
- cfs_proc_entry_t * entry = NULL;
- int i;
-
- link = node->root;
- i = strlen(proc_item_path);
- ASSERT(S_ISDIR(node->mode));
- if (node != cfs_proc_root) {
- strcat(proc_item_path, "/");
- strcat(proc_item_path, node->name);
- }
- proc_show_child(link);
- proc_item_path[i] = 0;
-}
-
-void proc_print_splay()
-{
- printk("=================================================\n");
- printk("Lustre virtual proc entries:\n");
- printk("-------------------------------------------------\n");
- LOCK_PROCFS();
- proc_show_tree(cfs_proc_root);
- UNLOCK_PROCFS();
- printk("=================================================\n");
-}
-
-
-/* initilaize / build the proc fs tree */
-int proc_init_fs()
-{
- cfs_proc_entry_t * root = NULL;
-
- memset(&(root_table_header), 0, sizeof(struct ctl_table_header));
- INIT_LIST_HEAD(&(root_table_header.ctl_entry));
-
- INIT_PROCFS_LOCK();
- proc_entry_cache = kmem_cache_create(NULL, sizeof(cfs_proc_entry_t),
- 0, 0, NULL);
-
- if (!proc_entry_cache) {
- return (-ENOMEM);
- }
-
- root = proc_alloc_entry();
- if (!root) {
- proc_destroy_fs();
- return (-ENOMEM);
- }
- root->magic = CFS_PROC_ENTRY_MAGIC;
- root->flags = CFS_PROC_FLAG_DIRECTORY;
- root->mode = S_IFDIR | S_IRUGO | S_IXUGO;
- root->nlink = 3; // root should never be deleted.
- root->name[0]='/';
- root->name[1]= 0;
- cfs_proc_root = root;
-
- cfs_proc_dev = create_proc_entry("dev", S_IFDIR, root);
- if (!cfs_proc_dev) {
- goto errorout;
- }
- cfs_proc_dev->nlink = 1;
-
- cfs_proc_proc = create_proc_entry("proc", S_IFDIR, root);
- if (!cfs_proc_proc) {
- goto errorout;
- }
- cfs_proc_proc->nlink = 1;
-
- cfs_proc_fs = create_proc_entry("fs", S_IFDIR, cfs_proc_proc);
- if (!cfs_proc_fs) {
- goto errorout;
- }
- cfs_proc_fs->nlink = 1;
-
- cfs_proc_sys = create_proc_entry("sys", S_IFDIR, cfs_proc_proc);
- if (!cfs_proc_sys) {
- goto errorout;
- }
- cfs_proc_sys->nlink = 1;
-
-
- return 0;
-
-errorout:
-
- proc_destroy_fs();
- return (-ENOMEM);
-}
-
-
-static ssize_t do_rw_proc(int write, struct file * file, char * buf,
- size_t count, loff_t *ppos)
-{
- int op;
- cfs_proc_entry_t *de;
- struct ctl_table *table;
- size_t res;
- ssize_t error;
-
- de = (cfs_proc_entry_t *) file->proc_dentry;
-
- if (!de || !de->data)
- return -ENOTDIR;
- table = (struct ctl_table *) de->data;
- if (!table || !table->proc_handler)
- return -ENOTDIR;
- op = (write ? 002 : 004);
-
- res = count;
-
- /*
- * FIXME: we need to pass on ppos to the handler.
- */
-
- error = (*table->proc_handler) (table, write, file, buf, &res);
- if (error)
- return error;
- return res;
-}
-
-static ssize_t proc_readsys(struct file * file, char * buf,
- size_t count, loff_t *ppos)
-{
- return do_rw_proc(0, file, buf, count, ppos);
-}
-
-static ssize_t proc_writesys(struct file * file, const char * buf,
- size_t count, loff_t *ppos)
-{
- return do_rw_proc(1, file, (char *) buf, count, ppos);
-}
-
-
-struct file_operations proc_sys_file_operations = {
- /*owner*/ THIS_MODULE,
- /*lseek:*/ NULL,
- /*read:*/ proc_readsys,
- /*write:*/ proc_writesys,
- /*ioctl:*/ NULL,
- /*open:*/ NULL,
- /*release:*/ NULL
-};
-
-
-/* Scan the sysctl entries in table and add them all into /proc */
-void register_proc_table(struct ctl_table * table, cfs_proc_entry_t * root)
-{
- cfs_proc_entry_t * de;
- int len;
- mode_t mode;
-
- for (; table->ctl_name; table++) {
- /* Can't do anything without a proc name. */
- if (!table->procname)
- continue;
- /* Maybe we can't do anything with it... */
- if (!table->proc_handler && !table->child) {
- printk(KERN_WARNING "SYSCTL: Can't register %s\n",
- table->procname);
- continue;
- }
-
- len = strlen(table->procname);
- mode = table->mode;
-
- de = NULL;
- if (table->proc_handler)
- mode |= S_IFREG;
- else {
- de = search_proc_entry(table->procname, root);
- if (de) {
- break;
- }
- /* If the subdir exists already, de is non-NULL */
- }
-
- if (!de) {
-
- de = create_proc_entry((char *)table->procname, mode, root);
- if (!de)
- continue;
- de->data = (void *) table;
- if (table->proc_handler) {
- de->proc_fops = &proc_sys_file_operations;
- }
- }
- table->de = de;
- if (de->mode & S_IFDIR)
- register_proc_table(table->child, de);
- }
-}
-
-
-/*
- * Unregister a /proc sysctl table and any subdirectories.
- */
-void unregister_proc_table(struct ctl_table * table, cfs_proc_entry_t *root)
-{
- cfs_proc_entry_t *de;
- for (; table->ctl_name; table++) {
- if (!(de = table->de))
- continue;
- if (de->mode & S_IFDIR) {
- if (!table->child) {
- printk (KERN_ALERT "Help- malformed sysctl tree on free\n");
- continue;
- }
- unregister_proc_table(table->child, de);
-
- /* Don't unregister directories which still have entries.. */
- if (de->nlink)
- continue;
- }
-
- /* Don't unregister proc entries that are still being used.. */
- if (de->nlink)
- continue;
-
- table->de = NULL;
- remove_proc_entry((char *)table->procname, root);
- }
-}
-
-/* The generic string strategy routine: */
-int sysctl_string(struct ctl_table *table, int *name, int nlen,
- void *oldval, size_t *oldlenp,
- void *newval, size_t newlen, void **context)
-{
- int l, len;
-
- if (!table->data || !table->maxlen)
- return -ENOTDIR;
-
- if (oldval && oldlenp) {
- if (get_user(len, oldlenp))
- return -EFAULT;
- if (len) {
- l = strlen(table->data);
- if (len > l)
- len = l;
- if (len >= table->maxlen)
- len = table->maxlen;
- if (copy_to_user(oldval, table->data, len))
- return -EFAULT;
- if (put_user(0, ((char *) oldval) + len))
- return -EFAULT;
- if (put_user(len, oldlenp))
- return -EFAULT;
- }
- }
- if (newval && newlen) {
- len = newlen;
- if (len > table->maxlen)
- len = table->maxlen;
- if (copy_from_user(table->data, newval, len))
- return -EFAULT;
- if (len == table->maxlen)
- len--;
- ((char *) table->data)[len] = 0;
- }
- return 0;
-}
-
-/**
- * simple_strtoul - convert a string to an unsigned long
- * @cp: The start of the string
- * @endp: A pointer to the end of the parsed string will be placed here
- * @base: The number base to use
- */
-unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
-{
- unsigned long result = 0, value;
-
- if (!base) {
- base = 10;
- if (*cp == '0') {
- base = 8;
- cp++;
- if ((*cp == 'x') && cfs_isxdigit(cp[1])) {
- cp++;
- base = 16;
- }
- }
- }
- while (cfs_isxdigit(*cp) &&
- (value = cfs_isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
- result = result*base + value;
- cp++;
- }
- if (endp)
- *endp = (char *)cp;
- return result;
-}
-
-#define OP_SET 0
-#define OP_AND 1
-#define OP_OR 2
-#define OP_MAX 3
-#define OP_MIN 4
-
-
-static int do_proc_dointvec(struct ctl_table *table, int write,
- void *buffer, size_t *lenp, int conv, int op)
-{
- int *i, vleft, first=1, neg, val;
- size_t left, len;
-
- #define TMPBUFLEN 20
- char buf[TMPBUFLEN], *p;
-
- if (!table->data || !table->maxlen || !*lenp)
- {
- *lenp = 0;
- return 0;
- }
-
- i = (int *) table->data;
- vleft = table->maxlen / sizeof(int);
- left = *lenp;
-
- for (; left && vleft--; i++, first=0) {
- if (write) {
- while (left) {
- char c;
- if (get_user(c, (char *)buffer))
- return -EFAULT;
- if (!isspace(c))
- break;
- left--;
- ((char *)buffer)++;
- }
- if (!left)
- break;
- neg = 0;
- len = left;
- if (len > TMPBUFLEN-1)
- len = TMPBUFLEN-1;
- if (copy_from_user(buf, buffer, len))
- return -EFAULT;
- buf[len] = 0;
- p = buf;
- if (*p == '-' && left > 1) {
- neg = 1;
- left--, p++;
- }
- if (*p < '0' || *p > '9')
- break;
- val = simple_strtoul(p, &p, 0) * conv;
- len = p-buf;
- if ((len < left) && *p && !isspace(*p))
- break;
- if (neg)
- val = -val;
- (char *)buffer += len;
- left -= len;
- switch(op) {
- case OP_SET:
- *i = val;
- break;
- case OP_AND:
- *i &= val;
- break;
- case OP_OR:
- *i |= val;
- break;
- case OP_MAX:
- if (*i < val)
- *i = val;
- break;
- case OP_MIN:
- if (*i > val)
- *i = val;
- break;
- }
- } else {
- p = buf;
- if (!first)
- *p++ = '\t';
- sprintf(p, "%d", (*i) / conv);
- len = strlen(buf);
- if (len > left)
- len = left;
- if (copy_to_user(buffer, buf, len))
- return -EFAULT;
- left -= len;
- (char *)buffer += len;
- }
- }
-
- if (!write && !first && left) {
- if (put_user('\n', (char *) buffer))
- return -EFAULT;
- left--, ((char *)buffer)++;
- }
- if (write) {
- p = (char *) buffer;
- while (left) {
- char c;
- if (get_user(c, p++))
- return -EFAULT;
- if (!isspace(c))
- break;
- left--;
- }
- }
- if (write && first)
- return -EINVAL;
- *lenp -= left;
- return 0;
-}
-
-/**
- * proc_dointvec - read a vector of integers
- * @table: the sysctl table
- * @write: %TRUE if this is a write to the sysctl file
- * @buffer: the user buffer
- * @lenp: the size of the user buffer
- *
- * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
- * values from/to the user buffer, treated as an ASCII string.
- *
- * Returns 0 on success.
- */
-int proc_dointvec(struct ctl_table *table, int write,
- void *buffer, size_t *lenp)
-{
- return do_proc_dointvec(table,write,buffer,lenp,1,OP_SET);
-}
-
-
-/**
- * proc_dostring - read a string sysctl
- * @table: the sysctl table
- * @write: %TRUE if this is a write to the sysctl file
- * @buffer: the user buffer
- * @lenp: the size of the user buffer
- *
- * Reads/writes a string from/to the user buffer. If the kernel
- * buffer provided is not large enough to hold the string, the
- * string is truncated. The copied string is %NULL-terminated.
- * If the string is being read by the user process, it is copied
- * and a newline '\n' is added. It is truncated if the buffer is
- * not large enough.
- *
- * Returns 0 on success.
- */
-int proc_dostring(struct ctl_table *table, int write,
- void *buffer, size_t *lenp)
-{
- size_t len;
- char *p, c;
-
- if (!table->data || !table->maxlen || !*lenp ||
- (!write)) {
- *lenp = 0;
- return 0;
- }
-
- if (write) {
- len = 0;
- p = buffer;
- while (len < *lenp) {
- if (get_user(c, p++))
- return -EFAULT;
- if (c == 0 || c == '\n')
- break;
- len++;
- }
- if (len >= (size_t)table->maxlen)
- len = (size_t)table->maxlen-1;
- if (copy_from_user(table->data, buffer, len))
- return -EFAULT;
- ((char *) table->data)[len] = 0;
- } else {
- len = (size_t)strlen(table->data);
- if (len > (size_t)table->maxlen)
- len = (size_t)table->maxlen;
- if (len > *lenp)
- len = *lenp;
- if (len)
- if (copy_to_user(buffer, table->data, len))
- return -EFAULT;
- if (len < *lenp) {
- if (put_user('\n', ((char *) buffer) + len))
- return -EFAULT;
- len++;
- }
- *lenp = len;
- }
- return 0;
-}
-
-/* Perform the actual read/write of a sysctl table entry. */
-int do_sysctl_strategy(struct ctl_table *table, int *name, int nlen,
- void *oldval, size_t *oldlenp, void *newval,
- size_t newlen, void **context)
-{
- int op = 0, rc;
- size_t len;
-
- if (oldval)
- op |= 004;
- if (newval)
- op |= 002;
-
- if (table->strategy) {
- rc = table->strategy(table, name, nlen, oldval, oldlenp,
- newval, newlen, context);
- if (rc < 0)
- return rc;
- if (rc > 0)
- return 0;
- }
-
- /* If there is no strategy routine, or if the strategy returns
- * zero, proceed with automatic r/w */
- if (table->data && table->maxlen) {
- if (oldval && oldlenp) {
- get_user(len, oldlenp);
- if (len) {
- if (len > (size_t)table->maxlen)
- len = (size_t)table->maxlen;
- if (copy_to_user(oldval, table->data, len))
- return -EFAULT;
- if (put_user(len, oldlenp))
- return -EFAULT;
- }
- }
- if (newval && newlen) {
- len = newlen;
- if (len > (size_t)table->maxlen)
- len = (size_t)table->maxlen;
- if (copy_from_user(table->data, newval, len))
- return -EFAULT;
- }
- }
- return 0;
-}
-
-static int parse_table(int *name, int nlen,
- void *oldval, size_t *oldlenp,
- void *newval, size_t newlen,
- struct ctl_table *table, void **context)
-{
- int n;
-
-repeat:
-
- if (!nlen)
- return -ENOTDIR;
- if (get_user(n, name))
- return -EFAULT;
- for ( ; table->ctl_name; table++) {
- if (n == table->ctl_name || table->ctl_name == CTL_ANY) {
- int error;
- if (table->child) {
-/*
- if (ctl_perm(table, 001))
- return -EPERM;
-*/
- if (table->strategy) {
- error = table->strategy(
- table, name, nlen,
- oldval, oldlenp,
- newval, newlen, context);
- if (error)
- return error;
- }
- name++;
- nlen--;
- table = table->child;
- goto repeat;
- }
- error = do_sysctl_strategy(table, name, nlen,
- oldval, oldlenp,
- newval, newlen, context);
- return error;
- }
- }
- return -ENOTDIR;
-}
-
-int do_sysctl(int *name, int nlen, void *oldval, size_t *oldlenp,
- void *newval, size_t newlen)
-{
- struct list_head *tmp;
-
- if (nlen <= 0 || nlen >= CTL_MAXNAME)
- return -ENOTDIR;
- if (oldval) {
- int old_len;
- if (!oldlenp || get_user(old_len, oldlenp))
- return -EFAULT;
- }
- tmp = &root_table_header.ctl_entry;
- do {
- struct ctl_table_header *head =
- list_entry(tmp, struct ctl_table_header, ctl_entry);
- void *context = NULL;
- int error = parse_table(name, nlen, oldval, oldlenp,
- newval, newlen, head->ctl_table,
- &context);
- if (context)
- kfree(context);
- if (error != -ENOTDIR)
- return error;
- tmp = tmp->next;
- } while (tmp != &root_table_header.ctl_entry);
- return -ENOTDIR;
-}
-
-/**
- * register_sysctl_table - register a sysctl heirarchy
- * @table: the top-level table structure
- * @insert_at_head: whether the entry should be inserted in front or at the end
- *
- * Register a sysctl table heirarchy. @table should be a filled in ctl_table
- * array. An entry with a ctl_name of 0 terminates the table.
- *
- * The members of the &ctl_table structure are used as follows:
- *
- * ctl_name - This is the numeric sysctl value used by sysctl(2). The number
- * must be unique within that level of sysctl
- *
- * procname - the name of the sysctl file under /proc/sys. Set to %NULL to not
- * enter a sysctl file
- *
- * data - a pointer to data for use by proc_handler
- *
- * maxlen - the maximum size in bytes of the data
- *
- * mode - the file permissions for the /proc/sys file, and for sysctl(2)
- *
- * child - a pointer to the child sysctl table if this entry is a directory, or
- * %NULL.
- *
- * proc_handler - the text handler routine (described below)
- *
- * strategy - the strategy routine (described below)
- *
- * de - for internal use by the sysctl routines
- *
- * extra1, extra2 - extra pointers usable by the proc handler routines
- *
- * Leaf nodes in the sysctl tree will be represented by a single file
- * under /proc; non-leaf nodes will be represented by directories.
- *
- * sysctl(2) can automatically manage read and write requests through
- * the sysctl table. The data and maxlen fields of the ctl_table
- * struct enable minimal validation of the values being written to be
- * performed, and the mode field allows minimal authentication.
- *
- * More sophisticated management can be enabled by the provision of a
- * strategy routine with the table entry. This will be called before
- * any automatic read or write of the data is performed.
- *
- * The strategy routine may return
- *
- * < 0 - Error occurred (error is passed to user process)
- *
- * 0 - OK - proceed with automatic read or write.
- *
- * > 0 - OK - read or write has been done by the strategy routine, so
- * return immediately.
- *
- * There must be a proc_handler routine for any terminal nodes
- * mirrored under /proc/sys (non-terminals are handled by a built-in
- * directory handler). Several default handlers are available to
- * cover common cases -
- *
- * proc_dostring(), proc_dointvec(), proc_dointvec_jiffies(),
- * proc_dointvec_minmax(), proc_doulongvec_ms_jiffies_minmax(),
- * proc_doulongvec_minmax()
- *
- * It is the handler's job to read the input buffer from user memory
- * and process it. The handler should return 0 on success.
- *
- * This routine returns %NULL on a failure to register, and a pointer
- * to the table header on success.
- */
-struct ctl_table_header *
-register_sysctl_table(struct ctl_table *table)
-{
- struct ctl_table_header *tmp;
- tmp = kmalloc(sizeof(struct ctl_table_header), 0);
- if (!tmp)
- return NULL;
- tmp->ctl_table = table;
-
- INIT_LIST_HEAD(&tmp->ctl_entry);
- list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry);
-#ifdef CONFIG_PROC_FS
- register_proc_table(table, cfs_proc_sys);
-#endif
- return tmp;
-}
-
-/**
- * unregister_sysctl_table - unregister a sysctl table heirarchy
- * @header: the header returned from register_sysctl_table
- *
- * Unregisters the sysctl table and all children. proc entries may not
- * actually be removed until they are no longer used by anyone.
- */
-void unregister_sysctl_table(struct ctl_table_header * header)
-{
- list_del(&header->ctl_entry);
-#ifdef CONFIG_PROC_FS
- unregister_proc_table(header->ctl_table, cfs_proc_sys);
-#endif
- kfree(header);
-}
-
-
-int misc_register(struct miscdevice * psdev)
-{
- cfs_proc_entry_t * entry;
-
- entry = create_proc_entry (
- (char *)psdev->name,
- S_IFREG,
- cfs_proc_dev
- );
-
- if (!entry) {
- return -ENOMEM;
- }
-
- entry->flags |= CFS_PROC_FLAG_MISCDEV;
-
- entry->proc_fops = psdev->fops;
- entry->data = (void *)psdev;
-
- return 0;
-}
-
-int misc_deregister(struct miscdevice * psdev)
-{
- cfs_proc_entry_t * entry;
-
- entry = search_proc_entry (
- (char *)psdev->name,
- cfs_proc_dev
- );
-
- if (entry) {
-
- ASSERT(entry->data == (void *)psdev);
- ASSERT(entry->flags & CFS_PROC_FLAG_MISCDEV);
-
- remove_proc_entry(
- (char *)psdev->name,
- cfs_proc_dev
- );
- }
-
- return 0;
-}
-
-#define PSDEV_LNET (0x100)
-enum {
- PSDEV_DEBUG = 1, /* control debugging */
- PSDEV_SUBSYSTEM_DEBUG, /* control debugging */
- PSDEV_PRINTK, /* force all messages to console */
- PSDEV_CONSOLE_RATELIMIT, /* rate limit console messages */
- PSDEV_DEBUG_PATH, /* crashdump log location */
- PSDEV_DEBUG_DUMP_PATH, /* crashdump tracelog location */
- PSDEV_LIBCFS_MEMUSED, /* bytes currently PORTAL_ALLOCated */
-};
-
-static struct ctl_table lnet_table[] = {
- {PSDEV_DEBUG, "debug", &libcfs_debug, sizeof(int), 0644, NULL,
- &proc_dointvec},
- {PSDEV_SUBSYSTEM_DEBUG, "subsystem_debug", &libcfs_subsystem_debug,
- sizeof(int), 0644, NULL, &proc_dointvec},
- {PSDEV_PRINTK, "printk", &libcfs_printk, sizeof(int), 0644, NULL,
- &proc_dointvec},
- {PSDEV_CONSOLE_RATELIMIT, "console_ratelimit", &libcfs_console_ratelimit,
- sizeof(int), 0644, NULL, &proc_dointvec},
-/*
- {PSDEV_PORTALS_UPCALL, "upcall", portals_upcall,
- sizeof(portals_upcall), 0644, NULL, &proc_dostring,
- &sysctl_string},
-*/
- {PSDEV_LIBCFS_MEMUSED, "memused", (int *)&libcfs_kmemory.counter,
- sizeof(int), 0644, NULL, &proc_dointvec},
- {0}
-};
-
-static struct ctl_table top_table[2] = {
- {PSDEV_LNET, "lnet", NULL, 0, 0555, lnet_table},
- {0}
-};
-
-
-int trace_write_dump_kernel(struct file *file, const char *buffer,
- unsigned long count, void *data)
-{
- int rc = cfs_trace_dump_debug_buffer_usrstr((void *)buffer, count);
-
- return (rc < 0) ? rc : count;
-}
-
-int trace_write_daemon_file(struct file *file, const char *buffer,
- unsigned long count, void *data)
-{
- int rc = cfs_trace_daemon_command_usrstr((void *)buffer, count);
-
- return (rc < 0) ? rc : count;
-}
-
-int trace_read_daemon_file(char *page, char **start, off_t off, int count,
- int *eof, void *data)
-{
- int rc;
- cfs_tracefile_read_lock();
- rc = cfs_trace_copyout_string(page, count, cfs_tracefile, "\n");
- cfs_tracefile_read_unlock();
- return rc;
-}
-
-int trace_write_debug_mb(struct file *file, const char *buffer,
- unsigned long count, void *data)
-{
- int rc = 0; /*trace_set_debug_mb_userstr((void *)buffer, count);*/
-
- return (rc < 0) ? rc : count;
-}
-
-int trace_read_debug_mb(char *page, char **start, off_t off, int count,
- int *eof, void *data)
-{
- char str[32];
-
- snprintf(str, sizeof(str), "%d\n", cfs_trace_get_debug_mb());
-
- return cfs_trace_copyout_string(page, count, str, NULL);
-}
-
-int insert_proc(void)
-{
- cfs_proc_entry_t *ent;
-
- ent = create_proc_entry("sys/lnet/dump_kernel", 0, NULL);
- if (ent == NULL) {
- CERROR("couldn't register dump_kernel\n");
- return -1;
- }
- ent->write_proc = trace_write_dump_kernel;
-
- ent = create_proc_entry("sys/lnet/daemon_file", 0, NULL);
- if (ent == NULL) {
- CERROR("couldn't register daemon_file\n");
- return -1;
- }
- ent->write_proc = trace_write_daemon_file;
- ent->read_proc = trace_read_daemon_file;
-
- ent = create_proc_entry("sys/lnet/debug_mb", 0, NULL);
- if (ent == NULL) {
- CERROR("couldn't register debug_mb\n");
- return -1;
- }
- ent->write_proc = trace_write_debug_mb;
- ent->read_proc = trace_read_debug_mb;
-
- return 0;
-}
-
-void remove_proc(void)
-{
- remove_proc_entry("sys/lnet/dump_kernel", NULL);
- remove_proc_entry("sys/lnet/daemon_file", NULL);
- remove_proc_entry("sys/lnet/debug_mb", NULL);
-}
-
-
-/*
- * proc process routines of kernel space
- */
-
-struct file *
-lustre_open_file(char *filename)
-{
- int rc = 0;
- struct file *fh = NULL;
- cfs_proc_entry_t *fp = NULL;
-
- fp = search_proc_entry(filename, cfs_proc_root);
- if (fp == NULL)
- return NULL;
-
- fh = kmalloc(sizeof(*fh), __GFP_ZERO);
- if (fh == NULL)
- return NULL;
-
- fh->f_inode = kmalloc(sizeof(struct inode), __GFP_ZERO);
- if (!fh->f_inode) {
- kfree(fh);
- return NULL;
- }
-
- fh->f_inode->i_priv = (void *)fp;
- fh->f_op = fp->proc_fops;
-
- if (fh->f_op->open) {
- rc = (fh->f_op->open)(fh->f_inode, fh);
- } else {
- fp->nlink++;
- }
-
- if (0 != rc) {
- kfree(fh->f_inode);
- kfree(fh);
- return NULL;
- }
-
- return fh;
-}
-
-int
-lustre_close_file(struct file *fh)
-{
- int rc = 0;
- cfs_proc_entry_t *fp = NULL;
-
- fp = (cfs_proc_entry_t *) fh->f_inode->i_priv;
- if (fh->f_op->release) {
- rc = (fh->f_op->release)(fh->f_inode, fh);
- } else {
- fp->nlink--;
- }
-
- kfree(fh->f_inode);
- kfree(fh);
-
- return rc;
-}
-
-int
-lustre_do_ioctl(struct file *fh, unsigned long cmd, ulong_ptr_t arg)
-{
- int rc = 0;
-
- if (fh->f_op->ioctl)
- rc = (fh->f_op->ioctl)(fh, cmd, arg);
-
- return rc;
-}
-
-int
-lustre_ioctl_file(struct file *fh, PCFS_PROC_IOCTL devctl)
-{
- int rc = 0;
- ulong_ptr_t data;
-
- data = (ulong_ptr_t)devctl + sizeof(CFS_PROC_IOCTL);
-#if defined(_X86_)
- CLASSERT(sizeof(struct obd_ioctl_data) == 528);
-#else
- CLASSERT(sizeof(struct obd_ioctl_data) == 576);
-#endif
-
- /* obd ioctl code */
- if (_IOC_TYPE(devctl->cmd) == 'f') {
-
- struct obd_ioctl_data * obd = (struct obd_ioctl_data *) data;
-
- if ( devctl->cmd != (ULONG)OBD_IOC_BRW_WRITE &&
- devctl->cmd != (ULONG)OBD_IOC_BRW_READ ) {
-
- unsigned long off = obd->ioc_len;
-
- if (obd->ioc_plen1) {
- obd->ioc_pbuf1 = (char *)(data + off);
- off += cfs_size_round(obd->ioc_plen1);
- } else {
- obd->ioc_pbuf1 = NULL;
- }
-
- if (obd->ioc_plen2) {
- obd->ioc_pbuf2 = (char *)(data + off);
- off += cfs_size_round(obd->ioc_plen2);
- } else {
- obd->ioc_pbuf2 = NULL;
- }
- }
- }
-
- rc = lustre_do_ioctl(fh, devctl->cmd, data);
-
- return rc;
-}
-
-size_t
-lustre_read_file(struct file *fh, loff_t off, size_t size, char *buf)
-{
- size_t rc = 0;
- off_t low, high;
-
- low = (off_t) size;
- high = (off_t)(off >> 32);
-
- if (fh->f_op->read) {
- rc = (fh->f_op->read) (fh, buf, size, &off);
- }
-
- if (rc) {
- fh->f_pos = off + rc;
- }
-
- return rc;
-}
-
-size_t
-lustre_write_file(struct file *fh, loff_t off, size_t size, char *buf)
-{
- size_t rc = 0;
-
- off = 0;
- if (fh->f_op->write)
- rc = (fh->f_op->write)(fh, buf, size, &off);
-
- return rc;
-}
-
-
-/*
- * seq file routines
- */
-
-/**
- * seq_open - initialize sequential file
- * @file: file we initialize
- * @op: method table describing the sequence
- *
- * seq_open() sets @file, associating it with a sequence described
- * by @op. @op->start() sets the iterator up and returns the first
- * element of sequence. @op->stop() shuts it down. @op->next()
- * returns the next element of sequence. @op->show() prints element
- * into the buffer. In case of error ->start() and ->next() return
- * ERR_PTR(error). In the end of sequence they return %NULL. ->show()
- * returns 0 in case of success and negative number in case of error.
- */
-int seq_open(struct file *file, const struct seq_operations *op)
-{
- struct seq_file *p = file->private_data;
-
- if (!p) {
- p = kmalloc(sizeof(*p), GFP_KERNEL);
- if (!p)
- return -ENOMEM;
- file->private_data = p;
- }
- memset(p, 0, sizeof(*p));
- mutex_init(&p->lock);
- p->op = op;
-
- /*
- * Wrappers around seq_open(e.g. swaps_open) need to be
- * aware of this. If they set f_version themselves, they
- * should call seq_open first and then set f_version.
- */
- file->f_version = 0;
-
- /* SEQ files support lseek, but not pread/pwrite */
- file->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
- return 0;
-}
-EXPORT_SYMBOL(seq_open);
-
-/**
- * seq_read - ->read() method for sequential files.
- * @file: the file to read from
- * @buf: the buffer to read to
- * @size: the maximum number of bytes to read
- * @ppos: the current position in the file
- *
- * Ready-made ->f_op->read()
- */
-ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
-{
- struct seq_file *m = (struct seq_file *)file->private_data;
- size_t copied = 0;
- loff_t pos;
- size_t n;
- void *p;
- int err = 0;
-
- mutex_lock(&m->lock);
- /*
- * seq_file->op->..m_start/m_stop/m_next may do special actions
- * or optimisations based on the file->f_version, so we want to
- * pass the file->f_version to those methods.
- *
- * seq_file->version is just copy of f_version, and seq_file
- * methods can treat it simply as file version.
- * It is copied in first and copied out after all operations.
- * It is convenient to have it as part of structure to avoid the
- * need of passing another argument to all the seq_file methods.
- */
- m->version = file->f_version;
- /* grab buffer if we didn't have one */
- if (!m->buf) {
- m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
- if (!m->buf)
- goto Enomem;
- }
- /* if not empty - flush it first */
- if (m->count) {
- n = min(m->count, size);
- err = copy_to_user(buf, m->buf + m->from, n);
- if (err)
- goto Efault;
- m->count -= n;
- m->from += n;
- size -= n;
- buf += n;
- copied += n;
- if (!m->count)
- m->index++;
- if (!size)
- goto Done;
- }
- /* we need at least one record in buffer */
- while (1) {
- pos = m->index;
- p = m->op->start(m, &pos);
- err = PTR_ERR(p);
- if (!p || IS_ERR(p))
- break;
- err = m->op->show(m, p);
- if (err)
- break;
- if (m->count < m->size)
- goto Fill;
- m->op->stop(m, p);
- kfree(m->buf);
- m->buf = kmalloc(m->size <<= 1, GFP_KERNEL);
- if (!m->buf)
- goto Enomem;
- m->count = 0;
- m->version = 0;
- }
- m->op->stop(m, p);
- m->count = 0;
- goto Done;
-Fill:
- /* they want more? let's try to get some more */
- while (m->count < size) {
- size_t offs = m->count;
- loff_t next = pos;
- p = m->op->next(m, p, &next);
- if (!p || IS_ERR(p)) {
- err = PTR_ERR(p);
- break;
- }
- err = m->op->show(m, p);
- if (err || m->count == m->size) {
- m->count = offs;
- break;
- }
- pos = next;
- }
- m->op->stop(m, p);
- n = min(m->count, size);
- err = copy_to_user(buf, m->buf, n);
- if (err)
- goto Efault;
- copied += n;
- m->count -= n;
- if (m->count)
- m->from = n;
- else
- pos++;
- m->index = pos;
-Done:
- if (!copied)
- copied = err;
- else
- *ppos += copied;
- file->f_version = m->version;
- mutex_unlock(&m->lock);
- return copied;
-Enomem:
- err = -ENOMEM;
- goto Done;
-Efault:
- err = -EFAULT;
- goto Done;
-}
-EXPORT_SYMBOL(seq_read);
-
-static int traverse(struct seq_file *m, loff_t offset)
-{
- loff_t pos = 0, index;
- int error = 0;
- void *p;
-
- m->version = 0;
- index = 0;
- m->count = m->from = 0;
- if (!offset) {
- m->index = index;
- return 0;
- }
- if (!m->buf) {
- m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
- if (!m->buf)
- return -ENOMEM;
- }
- p = m->op->start(m, &index);
- while (p) {
- error = PTR_ERR(p);
- if (IS_ERR(p))
- break;
- error = m->op->show(m, p);
- if (error)
- break;
- if (m->count == m->size)
- goto Eoverflow;
- if (pos + (loff_t)(m->count) > offset) {
- m->from = (size_t)(offset - pos);
- m->count -= m->from;
- m->index = index;
- break;
- }
- pos += m->count;
- m->count = 0;
- if (pos == offset) {
- index++;
- m->index = index;
- break;
- }
- p = m->op->next(m, p, &index);
- }
- m->op->stop(m, p);
- return error;
-
-Eoverflow:
- m->op->stop(m, p);
- kfree(m->buf);
- m->buf = kmalloc(m->size <<= 1, GFP_KERNEL | __GFP_ZERO);
- return !m->buf ? -ENOMEM : -EAGAIN;
-}
-
-/**
- * seq_lseek - ->llseek() method for sequential files.
- * @file: the file in question
- * @offset: new position
- * @origin: 0 for absolute, 1 for relative position
- *
- * Ready-made ->f_op->llseek()
- */
-loff_t seq_lseek(struct file *file, loff_t offset, int origin)
-{
- struct seq_file *m = (struct seq_file *)file->private_data;
- long long retval = -EINVAL;
-
- mutex_lock(&m->lock);
- m->version = file->f_version;
- switch (origin) {
- case 1:
- offset += file->f_pos;
- case 0:
- if (offset < 0)
- break;
- retval = offset;
- if (offset != file->f_pos) {
- while ((retval=traverse(m, offset)) == -EAGAIN)
- ;
- if (retval) {
- /* with extreme prejudice... */
- file->f_pos = 0;
- m->version = 0;
- m->index = 0;
- m->count = 0;
- } else {
- retval = file->f_pos = offset;
- }
- }
- }
- file->f_version = m->version;
- mutex_unlock(&m->lock);
- return retval;
-}
-EXPORT_SYMBOL(seq_lseek);
-
-/**
- * seq_release - free the structures associated with sequential file.
- * @file: file in question
- * @inode: file->f_path.dentry->d_inode
- *
- * Frees the structures associated with sequential file; can be used
- * as ->f_op->release() if you don't have private data to destroy.
- */
-int seq_release(struct inode *inode, struct file *file)
-{
- struct seq_file *m = (struct seq_file *)file->private_data;
- if (m) {
- if (m->buf)
- kfree(m->buf);
- kfree(m);
- }
- return 0;
-}
-EXPORT_SYMBOL(seq_release);
-
-/**
- * seq_escape - print string into buffer, escaping some characters
- * @m: target buffer
- * @s: string
- * @esc: set of characters that need escaping
- *
- * Puts string into buffer, replacing each occurrence of character from
- * @esc with usual octal escape. Returns 0 in case of success, -1 - in
- * case of overflow.
- */
-int seq_escape(struct seq_file *m, const char *s, const char *esc)
-{
- char *end = m->buf + m->size;
- char *p;
- char c;
-
- for (p = m->buf + m->count; (c = *s) != '\0' && p < end; s++) {
- if (!strchr(esc, c)) {
- *p++ = c;
- continue;
- }
- if (p + 3 < end) {
- *p++ = '\\';
- *p++ = '0' + ((c & 0300) >> 6);
- *p++ = '0' + ((c & 070) >> 3);
- *p++ = '0' + (c & 07);
- continue;
- }
- m->count = m->size;
- return -1;
- }
- m->count = p - m->buf;
- return 0;
-}
-EXPORT_SYMBOL(seq_escape);
-
-int seq_printf(struct seq_file *m, const char *f, ...)
-{
- va_list args;
- int len;
-
- if (m->count < m->size) {
- va_start(args, f);
- len = vsnprintf(m->buf + m->count, m->size - m->count, f, args);
- va_end(args);
- if (m->count + len < m->size) {
- m->count += len;
- return 0;
- }
- }
- m->count = m->size;
- return -1;
-}
-EXPORT_SYMBOL(seq_printf);
-
-char *d_path(struct path *p, char *buffer, int buflen)
-{
- cfs_enter_debugger();
- return ERR_PTR(-ENAMETOOLONG);
-}
-
-int seq_path(struct seq_file *m, struct path *path, char *esc)
-{
- if (m->count < m->size) {
- char *s = m->buf + m->count;
- char *p = d_path(path, s, m->size - m->count);
- if (!IS_ERR(p)) {
- while (s <= p) {
- char c = *p++;
- if (!c) {
- p = m->buf + m->count;
- m->count = s - m->buf;
- return (int)(s - p);
- } else if (!strchr(esc, c)) {
- *s++ = c;
- } else if (s + 4 > p) {
- break;
- } else {
- *s++ = '\\';
- *s++ = '0' + ((c & 0300) >> 6);
- *s++ = '0' + ((c & 070) >> 3);
- *s++ = '0' + (c & 07);
- }
- }
- }
- }
- m->count = m->size;
- return -1;
-}
-EXPORT_SYMBOL(seq_path);
-
-static void *single_start(struct seq_file *p, loff_t *pos)
-{
- return (void *) (INT_PTR) (*pos == 0);
-}
-
-static void *single_next(struct seq_file *p, void *v, loff_t *pos)
-{
- ++*pos;
- return NULL;
-}
-
-static void single_stop(struct seq_file *p, void *v)
-{
-}
-
-int single_open(struct file *file, int (*show)(struct seq_file *, void *),
- void *data)
-{
- struct seq_operations *op = kmalloc(sizeof(*op), GFP_KERNEL);
- int res = -ENOMEM;
-
- if (op) {
- op->start = single_start;
- op->next = single_next;
- op->stop = single_stop;
- op->show = show;
- res = seq_open(file, op);
- if (!res)
- ((struct seq_file *)file->private_data)->private = data;
- else
- kfree(op);
- }
- return res;
-}
-EXPORT_SYMBOL(single_open);
-
-int single_release(struct inode *inode, struct file *file)
-{
- const struct seq_operations *op = ((struct seq_file *)file->private_data)->op;
- int res = seq_release(inode, file);
- kfree((void *)op);
- return res;
-}
-EXPORT_SYMBOL(single_release);
-
-int seq_release_private(struct inode *inode, struct file *file)
-{
- struct seq_file *seq = file->private_data;
-
- kfree(seq->private);
- seq->private = NULL;
- return seq_release(inode, file);
-}
-EXPORT_SYMBOL(seq_release_private);
-
-void *__seq_open_private(struct file *f, const struct seq_operations *ops,
- int psize)
-{
- int rc;
- void *private;
- struct seq_file *seq;
-
- private = kmalloc(psize, GFP_KERNEL | __GFP_ZERO);
- if (private == NULL)
- goto out;
-
- rc = seq_open(f, ops);
- if (rc < 0)
- goto out_free;
-
- seq = f->private_data;
- seq->private = private;
- return private;
-
-out_free:
- kfree(private);
-out:
- return NULL;
-}
-EXPORT_SYMBOL(__seq_open_private);
-
-int seq_open_private(struct file *filp, const struct seq_operations *ops,
- int psize)
-{
- return __seq_open_private(filp, ops, psize) ? 0 : -ENOMEM;
-}
-EXPORT_SYMBOL(seq_open_private);
-
-int seq_putc(struct seq_file *m, char c)
-{
- if (m->count < m->size) {
- m->buf[m->count++] = c;
- return 0;
- }
- return -1;
-}
-EXPORT_SYMBOL(seq_putc);
-
-int seq_puts(struct seq_file *m, const char *s)
-{
- int len = strlen(s);
- if (m->count + len < m->size) {
- memcpy(m->buf + m->count, s, len);
- m->count += len;
- return 0;
- }
- m->count = m->size;
- return -1;
-}
-EXPORT_SYMBOL(seq_puts);
-
-struct list_head *seq_list_start(struct list_head *head, loff_t pos)
-{
- struct list_head *lh;
-
- list_for_each(lh, head)
- if (pos-- == 0)
- return lh;
-
- return NULL;
-}
-
-EXPORT_SYMBOL(seq_list_start);
-
-struct list_head *seq_list_start_head(struct list_head *head,
- loff_t pos)
-{
- if (!pos)
- return head;
-
- return seq_list_start(head, pos - 1);
-}
-
-EXPORT_SYMBOL(seq_list_start_head);
-
-struct list_head *seq_list_next(void *v, struct list_head *head,
- loff_t *ppos)
-{
- struct list_head *lh;
-
- lh = ((struct list_head *)v)->next;
- ++*ppos;
- return lh == head ? NULL : lh;
-}
-
-EXPORT_SYMBOL(seq_list_next);
-
-struct proc_dir_entry *PDE(const struct inode *inode)
-{
- return (struct proc_dir_entry *)inode->i_priv;
-}
-
-
-#endif /* __KERNEL__ */
+++ /dev/null
-/*
- * 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.
- *
- */
-
-# define DEBUG_SUBSYSTEM S_LNET
-
-#include <libcfs/libcfs.h>
-
-/*
- * Windows generic table support routines
- */
-
-#define TAG_RADIX_TABLE 'XIDR'
-typedef struct _RADIX_TABLE_ELEMENT {
- ULONG Key;
- PVOID Value;
-} RADIX_TABLE_ELEMENT, *PRADIX_TABLE_ELEMENT;
-
-
-RTL_GENERIC_COMPARE_RESULTS
-RadixCompareElement (
- IN PRTL_GENERIC_TABLE Table,
- IN PVOID Index1,
- IN PVOID Index2
- )
-{
- ULONG Key1, Key2;
-
- Key1 = *((ULONG UNALIGNED *) Index1);
- Key2 = *((ULONG UNALIGNED *) Index2);
-
- if (Key1 < Key2) {
- return GenericLessThan;
- } else if (Key1 > Key2) {
- return GenericGreaterThan;
- }
-
- return GenericEqual;
-}
-
-PVOID
-RadixAllocateElement (
- IN PRTL_GENERIC_TABLE Table,
- IN CLONG Size
- )
-{
- return FsRtlAllocatePoolWithTag(NonPagedPool,Size, TAG_RADIX_TABLE);
-}
-
-VOID
-RadixDestroyElement (
- IN PRTL_GENERIC_TABLE Table,
- IN PVOID Buffer
- )
-{
- ExFreePoolWithTag(Buffer, TAG_RADIX_TABLE);
-}
-
-
-PVOID
-RadixInsertElement(
- IN PRTL_GENERIC_TABLE Table,
- IN ULONG Key,
- IN PVOID Value
- )
-{
- RADIX_TABLE_ELEMENT element;
- element.Key = Key;
- element.Value = Value;
- return RtlInsertElementGenericTable( Table, &element,
- sizeof(RADIX_TABLE_ELEMENT), NULL );
-}
-
-BOOLEAN
-RadixDeleteElement(
- IN PRTL_GENERIC_TABLE Table,
- IN ULONG Key
- )
-{
- RADIX_TABLE_ELEMENT element;
- element.Key = Key;
- return RtlDeleteElementGenericTable(Table, &element);
-}
-
-
-PRADIX_TABLE_ELEMENT
-RadixLookupElement (
- IN PRTL_GENERIC_TABLE Table,
- IN ULONG Key
- )
-{
- RADIX_TABLE_ELEMENT element;
-
- element.Key = Key;
- return (PRADIX_TABLE_ELEMENT)
- RtlLookupElementGenericTable(Table, &element);
-}
-
-PRADIX_TABLE_ELEMENT
-RadixGetNextElement (
- IN PRTL_GENERIC_TABLE Table,
- IN PVOID * Restart
- )
-{
- return (PRADIX_TABLE_ELEMENT)
- RtlEnumerateGenericTableWithoutSplaying(Table, Restart);
-}
-
-
-
-VOID
-RadixInitTable(
- IN PRTL_GENERIC_TABLE Table
- )
-{
-
- /* initialize rafix generic table. */
-
- RtlInitializeGenericTable(
- Table,
- RadixCompareElement,
- RadixAllocateElement,
- RadixDestroyElement,
- NULL
- );
-}
-
-VOID
-RadixDestroyTable(
- IN PRTL_GENERIC_TABLE Table
- )
-{
- PRADIX_TABLE_ELEMENT element;
- PVOID restart = NULL;
-
-Again:
- element = (PRADIX_TABLE_ELEMENT) RadixGetNextElement(Table, &restart);
- if (element) {
- RadixDeleteElement(Table, element->Key);
- goto Again;
- }
-}
-
-/*
- * Radix Tree Suppoert Rotuines
- *
- */
-
-/**
- * radix_tree_gang_lookup - perform multiple lookup on a radix tree
- * \param root radix tree root
- * \param results where the results of the lookup are placed
- * \param first_index start the lookup from this key
- * \param max_items place up to this many items at *results
- *
- * Performs an index-ascending scan of the tree for present items. Places
- * them at * \a results and returns the number of items which were placed at
- * *\a results.
- *
- */
-unsigned int
-radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
- unsigned long first_index, unsigned int max_items)
-{
- PRADIX_TABLE_ELEMENT element;
- PVOID restart = NULL;
- unsigned int i = 0;
-
- element = RadixLookupElement(&root->table, first_index);
- restart = element;
- while (element && i < max_items) {
- results[i++] = element->Value;
- element = RadixGetNextElement(&root->table, &restart);
- }
-
- return i;
-}
-
-
-/**
- * radix_tree_lookup - perform lookup operation on a radix tree
- * \param root radix tree root
- * \param index index key
- *
- * Lookup the item at the position \a index in the radix tree \a root.
- *
- */
-void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index)
-{
- PRADIX_TABLE_ELEMENT element;
- int i = 0;
-
- element = RadixLookupElement(&root->table, index);
- if (element) {
- return element->Value;
- }
-
- return NULL;
-}
-
-/**
- * radix_tree_insert - insert into a radix tree
- * \param root radix tree root
- * \param index index key
- * \param item item to insert
- *
- * Insert an item into the radix tree at position \a index.
- */
-int radix_tree_insert(struct radix_tree_root *root,
- unsigned long index, void *item)
-{
- if (RadixInsertElement(&root->table, index, item)) {
- return 0;
- }
-
- return -ENOMEM;
-}
-
-/**
- * radix_tree_delete - delete an item from a radix tree
- * \param root radix tree root
- * \param index index key
- *
- * Remove the item at \a index from the radix tree rooted at \a root.
- *
- * Returns the address of the deleted item, or NULL if it was not present.
- */
-void *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
-{
- RadixDeleteElement(&root->table, index);
- return NULL;
-}
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#define DEBUG_SUBSYSTEM S_LNET
-
-#include <libcfs/libcfs.h>
-
-
-/*
- * Wait queue routines
- */
-
-/*
- * init_waitqueue_head
- * To initialize the wait queue
- *
- * Arguments:
- * waitq: pointer to the wait_queue_head_t structure
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void init_waitqueue_head(wait_queue_head_t *waitq)
-{
- waitq->magic = CFS_WAITQ_MAGIC;
- waitq->flags = 0;
- INIT_LIST_HEAD(&(waitq->waiters));
- spin_lock_init(&(waitq->guard));
-}
-
-/*
- * init_waitqueue_entry_current
- * To initialize the wake link node
- *
- * Arguments:
- * link: pointer to the wait_queue_t structure
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void init_waitqueue_entry_current(wait_queue_t *link)
-{
- struct task_struct * task = current;
- PTASK_SLOT slot = NULL;
-
- if (!task) {
- /* should bugchk here */
- cfs_enter_debugger();
- return;
- }
-
- slot = CONTAINING_RECORD(task, TASK_SLOT, task);
- cfs_assert(slot->Magic == TASKSLT_MAGIC);
-
- memset(link, 0, sizeof(wait_queue_t));
-
- link->magic = CFS_WAITLINK_MAGIC;
- link->flags = 0;
-
- link->event = &(slot->Event);
- link->hits = &(slot->hits);
-
- atomic_inc(&slot->count);
-
- INIT_LIST_HEAD(&(link->waitq[0].link));
- INIT_LIST_HEAD(&(link->waitq[1].link));
-
- link->waitq[0].waitl = link->waitq[1].waitl = link;
-}
-
-
-/*
- * cfs_waitlink_fini
- * To finilize the wake link node
- *
- * Arguments:
- * link: pointer to the wait_queue_t structure
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void cfs_waitlink_fini(wait_queue_t *link)
-{
- struct task_struct * task = current;
- PTASK_SLOT slot = NULL;
-
- if (!task) {
- /* should bugchk here */
- cfs_enter_debugger();
- return;
- }
-
- slot = CONTAINING_RECORD(task, TASK_SLOT, task);
- cfs_assert(slot->Magic == TASKSLT_MAGIC);
- cfs_assert(link->magic == CFS_WAITLINK_MAGIC);
- cfs_assert(link->waitq[0].waitq == NULL);
- cfs_assert(link->waitq[1].waitq == NULL);
-
- atomic_dec(&slot->count);
-}
-
-
-/*
- * cfs_waitq_add_internal
- * To queue the wait link node to the wait queue
- *
- * Arguments:
- * waitq: pointer to the wait_queue_head_t structure
- * link: pointer to the wait_queue_t structure
- * int: queue no (Normal or Forward waitq)
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void cfs_waitq_add_internal(wait_queue_head_t *waitq,
- wait_queue_t *link,
- __u32 waitqid )
-{
- LASSERT(waitq != NULL);
- LASSERT(link != NULL);
- LASSERT(waitq->magic == CFS_WAITQ_MAGIC);
- LASSERT(link->magic == CFS_WAITLINK_MAGIC);
- LASSERT(waitqid < CFS_WAITQ_CHANNELS);
-
- spin_lock(&(waitq->guard));
- LASSERT(link->waitq[waitqid].waitq == NULL);
- link->waitq[waitqid].waitq = waitq;
- if (link->flags & CFS_WAITQ_EXCLUSIVE) {
- list_add_tail(&link->waitq[waitqid].link, &waitq->waiters);
- } else {
- list_add(&link->waitq[waitqid].link, &waitq->waiters);
- }
- spin_unlock(&(waitq->guard));
-}
-/*
- * add_wait_queue
- * To queue the wait link node to the wait queue
- *
- * Arguments:
- * waitq: pointer to the wait_queue_head_t structure
- * link: pointer to the wait_queue_t structure
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void add_wait_queue(wait_queue_head_t *waitq,
- wait_queue_t *link)
-{
- cfs_waitq_add_internal(waitq, link, CFS_WAITQ_CHAN_NORMAL);
-}
-
-/*
- * add_wait_queue_exclusive
- * To set the wait link node to exclusive mode
- * and queue it to the wait queue
- *
- * Arguments:
- * waitq: pointer to the wait_queue_head_t structure
- * link: pointer to the cfs_wait_link structure
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void add_wait_queue_exclusive( wait_queue_head_t *waitq,
- wait_queue_t *link)
-{
- LASSERT(waitq != NULL);
- LASSERT(link != NULL);
- LASSERT(waitq->magic == CFS_WAITQ_MAGIC);
- LASSERT(link->magic == CFS_WAITLINK_MAGIC);
-
- link->flags |= CFS_WAITQ_EXCLUSIVE;
- add_wait_queue(waitq, link);
-}
-
-/*
- * remove_wait_queue
- * To remove the wait link node from the waitq
- *
- * Arguments:
- * waitq: pointer to the cfs_ waitq_t structure
- * link: pointer to the wait_queue_t structure
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void remove_wait_queue( wait_queue_head_t *waitq,
- wait_queue_t *link)
-{
- int i = 0;
-
- LASSERT(waitq != NULL);
- LASSERT(link != NULL);
-
- LASSERT(waitq->magic == CFS_WAITQ_MAGIC);
- LASSERT(link->magic == CFS_WAITLINK_MAGIC);
-
- spin_lock(&(waitq->guard));
-
- for (i=0; i < CFS_WAITQ_CHANNELS; i++) {
- if (link->waitq[i].waitq == waitq)
- break;
- }
-
- if (i < CFS_WAITQ_CHANNELS) {
- link->waitq[i].waitq = NULL;
- list_del_init(&link->waitq[i].link);
- } else {
- cfs_enter_debugger();
- }
-
- spin_unlock(&(waitq->guard));
-}
-
-/*
- * waitqueue_active
- * Is the waitq active (not empty) ?
- *
- * Arguments:
- * waitq: pointer to the cfs_ waitq_t structure
- *
- * Return Value:
- * Zero: the waitq is empty
- * Non-Zero: the waitq is active
- *
- * Notes:
- * We always returns TRUE here, the same to Darwin.
- */
-
-int waitqueue_active(wait_queue_head_t *waitq)
-{
- LASSERT(waitq != NULL);
- LASSERT(waitq->magic == CFS_WAITQ_MAGIC);
-
- return (1);
-}
-
-/*
- * wake_up_nr
- * To wake up all the non-exclusive tasks plus nr exclusive
- * ones in the waitq
- *
- * Arguments:
- * waitq: pointer to the wait_queue_head_t structure
- * nr: number of exclusive tasks to be woken up
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-
-void wake_up_nr(wait_queue_head_t *waitq, int nr)
-{
- int result;
- cfs_waitlink_channel_t * scan;
-
- LASSERT(waitq != NULL);
- LASSERT(waitq->magic == CFS_WAITQ_MAGIC);
-
- spin_lock(&waitq->guard);
- list_for_each_entry(scan, &waitq->waiters,
- link) {
-
- wait_queue_t *waitl = scan->waitl;
-
- result = cfs_wake_event(waitl->event);
- LASSERT( result == FALSE || result == TRUE );
-
- if (result) {
- atomic_inc(waitl->hits);
- }
-
- if ((waitl->flags & CFS_WAITQ_EXCLUSIVE) && --nr == 0)
- break;
- }
-
- spin_unlock(&waitq->guard);
- return;
-}
-
-/*
- * wake_up
- * To wake up all the non-exclusive tasks and 1 exclusive
- *
- * Arguments:
- * waitq: pointer to the wait_queue_head_t structure
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void wake_up(wait_queue_head_t *waitq)
-{
- wake_up_nr(waitq, 1);
-}
-
-
-/*
- * wake_up_all
- * To wake up all the tasks in the waitq
- *
- * Arguments:
- * waitq: pointer to the wait_queue_head_t structure
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void wake_up_all(wait_queue_head_t *waitq)
-{
- LASSERT(waitq != NULL);
- LASSERT(waitq->magic ==CFS_WAITQ_MAGIC);
-
- wake_up_nr(waitq, 0);
-}
-
-/*
- * waitq_wait
- * To wait on the link node until it is signaled.
- *
- * Arguments:
- * link: pointer to the wait_queue_t structure
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void waitq_wait(wait_queue_t *link, long state)
-{
- LASSERT(link != NULL);
- LASSERT(link->magic == CFS_WAITLINK_MAGIC);
-
- if (atomic_read(link->hits) > 0) {
- atomic_dec(link->hits);
- LASSERT((__u32)atomic_read(link->hits) < (__u32)0xFFFFFF00);
- } else {
- cfs_wait_event_internal(link->event, 0);
- }
-}
-
-/*
- * waitq_timedwait
- * To wait the link node to be signaled with a timeout limit
- *
- * Arguments:
- * link: pointer to the wait_queue_t structure
- * timeout: the timeout limitation
- *
- * Return Value:
- * Woken up: return the difference of the current time and
- * the timeout
- * Timeout: return 0
- *
- * Notes:
- * What if it happens to be woken up at the just timeout time !?
- */
-
-int64_t waitq_timedwait( wait_queue_t *link,
- long state,
- int64_t timeout)
-{
-
- if (atomic_read(link->hits) > 0) {
- atomic_dec(link->hits);
- LASSERT((__u32)atomic_read(link->hits) < (__u32)0xFFFFFF00);
- return (int64_t)TRUE;
- }
-
- return (int64_t)cfs_wait_event_internal(link->event, timeout);
-}
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#define DEBUG_SUBSYSTEM S_LNET
-
-#include <libcfs/libcfs.h>
-#include <lnet/lnet.h>
-
-#define TDILND_MODULE_NAME L"tdilnd"
-
-ks_tdi_data_t ks_data;
-
-VOID
-KsDumpPrint(PCHAR buffer, ULONG length)
-{
- ULONG i;
- for (i=0; i < length; i++) {
- if (((i+1) % 31) == 0)
- printk("\n");
- printk("%2.2x ", (UCHAR)buffer[i]);
- }
- printk("\n");
-}
-
-PVOID
-KsMapMdlBuffer (PMDL Mdl);
-
-VOID
-KsDumpMdlChain(PMDL Mdl, ULONG length)
-{
- PMDL mdl = Mdl;
- PCHAR buffer = NULL;
- ULONG len = 0;
- int i = 0;
-
- while (mdl) {
- printk("mdl %d:\n", i);
- buffer = KsMapMdlBuffer(mdl);
- KsDumpPrint(buffer, mdl->ByteCount);
- len += mdl->ByteCount;
- mdl = mdl->Next;
- }
- ASSERT(len == length);
-}
-
-/*
- * KsLockUserBuffer
- * Allocate MDL for the buffer and lock the pages into
- * nonpaged pool
- *
- * Arguments:
- * UserBuffer: the user buffer to be locked
- * Length: length in bytes of the buffer
- * Operation: read or write access
- * pMdl: the result of the created mdl
- *
- * Return Value:
- * NTSTATUS: kernel status code (STATUS_SUCCESS
- * or other error code)
- *
- * NOTES:
- * N/A
- */
-
-NTSTATUS
-KsLockUserBuffer (
- IN PVOID UserBuffer,
- IN BOOLEAN bPaged,
- IN ULONG Length,
- IN LOCK_OPERATION Operation,
- OUT PMDL * pMdl
- )
-{
- NTSTATUS Status;
- PMDL Mdl = NULL;
-
- LASSERT(UserBuffer != NULL);
-
- *pMdl = NULL;
-
- Mdl = IoAllocateMdl(
- UserBuffer,
- Length,
- FALSE,
- FALSE,
- NULL
- );
-
- if (Mdl == NULL) {
-
- Status = STATUS_INSUFFICIENT_RESOURCES;
-
- } else {
-
- __try {
-
- if (bPaged) {
- MmProbeAndLockPages(
- Mdl,
- KernelMode,
- Operation
- );
- } else {
- MmBuildMdlForNonPagedPool(
- Mdl
- );
- }
-
- Status = STATUS_SUCCESS;
-
- *pMdl = Mdl;
-
- } __except (EXCEPTION_EXECUTE_HANDLER) {
-
- IoFreeMdl(Mdl);
-
- Mdl = NULL;
-
- cfs_enter_debugger();
-
- Status = STATUS_INVALID_USER_BUFFER;
- }
- }
-
- return Status;
-}
-
-/*
- * KsMapMdlBuffer
- * Map the mdl into a buffer in kernel space
- *
- * Arguments:
- * Mdl: the mdl to be mapped
- *
- * Return Value:
- * PVOID: the buffer mapped or NULL in failure
- *
- * NOTES:
- * N/A
- */
-
-PVOID
-KsMapMdlBuffer (PMDL Mdl)
-{
- LASSERT(Mdl != NULL);
-
- return MmGetSystemAddressForMdlSafe(
- Mdl,
- NormalPagePriority
- );
-}
-
-
-/*
- * KsReleaseMdl
- * Unlock all the pages in the mdl
- *
- * Arguments:
- * Mdl: memory description list to be released
- *
- * Return Value:
- * N/A
- *
- * NOTES:
- * N/A
- */
-
-VOID
-KsReleaseMdl (IN PMDL Mdl,
- IN int Paged )
-{
- LASSERT(Mdl != NULL);
-
- while (Mdl) {
-
- PMDL Next;
-
- Next = Mdl->Next;
-
- if (Paged) {
- MmUnlockPages(Mdl);
- }
-
- IoFreeMdl(Mdl);
-
- Mdl = Next;
- }
-}
-
-/*
- * KsQueryMdlsSize
- * Query the whole size of a MDL (may be chained)
- *
- * Arguments:
- * Mdl: the Mdl to be queried
- *
- * Return Value:
- * ULONG: the total size of the mdl
- *
- * NOTES:
- * N/A
- */
-
-ULONG
-KsQueryMdlsSize (PMDL Mdl)
-{
- PMDL Next = Mdl;
- ULONG Length = 0;
-
-
- //
- // Walking the MDL Chain ...
- //
-
- while (Next) {
- Length += MmGetMdlByteCount(Next);
- Next = Next->Next;
- }
-
- return (Length);
-}
-
-/*
- * KsCopyMdlToBuffer
- * Copy payload from Mdl to buffer
- *
- * Arguments:
- * SourceMdl: the source mdl
- * SourceOffset: start offset of the source
- * DestinationBuffer: the dst buffer
- * DestinationOffset: the offset where data are to be copied.
- * BytesTobecopied: the expteced bytes to be copied
- *
- * Return Value:
- * Length of data copied from MDL to user buffer
- *
- * NOTES:
- * N/A
- */
-
-ULONG
-KsCopyMdlToBuffer(
- IN PMDL SourceMdl,
- IN ULONG SourceOffset,
- IN PVOID DestinationBuffer,
- IN ULONG DestinationOffset,
- IN ULONG BytesTobeCopied
- )
-{
- PUCHAR SourceBuffer = NULL;
- PUCHAR TargetBuffer = DestinationBuffer;
- ULONG BytesCopied = 0;
-
- if (MmGetMdlByteCount(SourceMdl) <= SourceOffset) {
- return 0;
- }
-
- BytesCopied = MmGetMdlByteCount(SourceMdl) - SourceOffset;
- if (BytesCopied > BytesTobeCopied) {
- BytesCopied = BytesTobeCopied;
- }
-
- SourceBuffer = (PUCHAR)KsMapMdlBuffer(SourceMdl);
-
- RtlMoveMemory(TargetBuffer + DestinationOffset,
- SourceBuffer + SourceOffset, BytesCopied);
-
- return BytesCopied;
-}
-
-/*
- * KsInitializeKsTsdu
- * Initialize the Tsdu buffer header
- *
- * Arguments:
- * KsTsdu: the Tsdu to be initialized
- * Length: the total length of the Tsdu
- *
- * Return Value:
- * VOID
- *
- * NOTES:
- * N/A
- */
-
-VOID
-KsInitializeKsTsdu(
- PKS_TSDU KsTsdu,
- ULONG Length
- )
-{
- KsTsdu->Magic = KS_TSDU_MAGIC;
- KsTsdu->TotalLength = Length;
- KsTsdu->StartOffset = KsTsdu->LastOffset =
- KS_QWORD_ALIGN(sizeof(KS_TSDU));
-}
-
-/*
- * KsAllocateKsTsdu
- * Reuse a Tsdu from the freelist or allocate a new Tsdu
- * from the LookAsideList table or the NonPagedPool
- *
- * Arguments:
- * N/A
- *
- * Return Value:
- * PKS_Tsdu: the new Tsdu or NULL if it fails
- *
- * Notes:
- * N/A
- */
-
-PKS_TSDU
-KsAllocateKsTsdu()
-{
- PKS_TSDU KsTsdu = NULL;
-
- spin_lock(&(ks_data.ksnd_tsdu_lock));
-
- if (!list_empty (&(ks_data.ksnd_freetsdus))) {
-
- LASSERT(ks_data.ksnd_nfreetsdus > 0);
-
- KsTsdu = list_entry(ks_data.ksnd_freetsdus.next, KS_TSDU, Link);
- list_del(&(KsTsdu->Link));
- ks_data.ksnd_nfreetsdus--;
-
- } else {
-
- KsTsdu = (PKS_TSDU) kmem_cache_alloc(
- ks_data.ksnd_tsdu_slab, 0);
- }
-
- spin_unlock(&(ks_data.ksnd_tsdu_lock));
-
- if (NULL != KsTsdu) {
- RtlZeroMemory(KsTsdu, ks_data.ksnd_tsdu_size);
- KsInitializeKsTsdu(KsTsdu, (ULONG)ks_data.ksnd_tsdu_size);
- }
-
- return (KsTsdu);
-}
-
-/*
- * KsFreeKsTsdu
- * Release a Tsdu: uninitialize then free it.
- *
- * Arguments:
- * KsTsdu: Tsdu to be freed.
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-VOID
-KsFreeKsTsdu(
- PKS_TSDU KsTsdu
- )
-{
- kmem_cache_free(
- ks_data.ksnd_tsdu_slab,
- KsTsdu );
-}
-
-/*
- * KsPutKsTsdu
- * Move the Tsdu to the free tsdu list in ks_data.
- *
- * Arguments:
- * KsTsdu: Tsdu to be moved.
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-VOID
-KsPutKsTsdu(
- PKS_TSDU KsTsdu
- )
-{
- spin_lock(&(ks_data.ksnd_tsdu_lock));
- if (ks_data.ksnd_nfreetsdus > 128) {
- KsFreeKsTsdu(KsTsdu);
- } else {
- list_add_tail( &(KsTsdu->Link), &(ks_data.ksnd_freetsdus));
- ks_data.ksnd_nfreetsdus++;
- }
- spin_unlock(&(ks_data.ksnd_tsdu_lock));
-}
-
-/* with tconn lock acquired */
-ks_mdl_t *
-KsLockTsdus(
- ks_tconn_t * tconn,
- PKS_TSDUMGR TsduMgr,
- PULONG Flags,
- PULONG Length
- )
-{
-
- ks_mdl_t * mdl = NULL;
- ks_mdl_t * tail = NULL;
-
- PKS_TSDU KsTsdu;
- PKS_TSDU_DAT KsTsduDat;
- PKS_TSDU_BUF KsTsduBuf;
- PKS_TSDU_MDL KsTsduMdl;
-
- *Length = 0;
-
- list_for_each_entry(KsTsdu, &TsduMgr->TsduList, Link) {
-
- ULONG start = 0;
-
- LASSERT(KsTsdu->Magic == KS_TSDU_MAGIC);
- start = KsTsdu->StartOffset;
-
- while (start < KsTsdu->LastOffset) {
-
- ks_mdl_t * iov = NULL;
-
- KsTsduDat = (PKS_TSDU_DAT)((PUCHAR)KsTsdu + start);
- KsTsduBuf = (PKS_TSDU_BUF)((PUCHAR)KsTsdu + start);
- KsTsduMdl = (PKS_TSDU_MDL)((PUCHAR)KsTsdu + start);
- LASSERT(KsTsduDat->TsduType == TSDU_TYPE_DAT ||
- KsTsduBuf->TsduType == TSDU_TYPE_BUF ||
- KsTsduMdl->TsduType == TSDU_TYPE_MDL);
-
- if (TSDU_TYPE_DAT == KsTsduDat->TsduType) {
-
- ASSERT(KsTsdu->LastOffset >= start + KsTsduDat->TotalLength);
- if (KsTsduDat->Mdl) {
- iov = KsTsduDat->Mdl;
- } else {
- KsLockUserBuffer(
- &KsTsduDat->Data[KsTsduDat->StartOffset],
- FALSE,
- KsTsduDat->DataLength,
- IoReadAccess,
- &iov );
- KsTsduDat->Mdl = iov;
- }
-/*
- printk("KsLockTsdus: %u\n", KsTsduDat->DataLength);
- KsDumpPrint(
- &KsTsduDat->Data[KsTsduDat->StartOffset],
- KsTsduDat->DataLength);
-*/
- *Length += KsTsduDat->DataLength;
- start += KsTsduDat->TotalLength;
-
- } else if (TSDU_TYPE_BUF == KsTsduBuf->TsduType) {
-
- ASSERT(KsTsdu->LastOffset >= start + sizeof(KS_TSDU_BUF));
- if (KsTsduBuf->Mdl) {
- iov = KsTsduBuf->Mdl;
- } else {
- KsLockUserBuffer(
- (PUCHAR)KsTsduBuf->UserBuffer +
- KsTsduBuf->StartOffset,
- FALSE,
- KsTsduBuf->DataLength,
- IoReadAccess,
- &iov );
- KsTsduBuf->Mdl = iov;
- }
-
- *Length += KsTsduBuf->DataLength;
- start += sizeof(KS_TSDU_BUF);
-
- } else {
-
- LASSERT(TSDU_TYPE_MDL == KsTsduMdl->TsduType);
- ASSERT(KsTsdu->LastOffset >= start + sizeof(KS_TSDU_MDL));
- iov = KsTsduMdl->Mdl;
- *Length += KsTsduMdl->DataLength;
- start += sizeof(KS_TSDU_MDL);
- }
-
- if (!iov) {
- cfs_enter_debugger();
- goto cleanup;
- }
-
- if (tail) {
- tail->Next = iov;
- } else {
- mdl = iov;
- }
- tail = iov;
- tail->Next = NULL;
-/*
- printk("KsLockTsdus: mdl %d\n", tail->ByteCount);
- KsDumpMdlChain(tail, tail->ByteCount);
-*/
- }
- }
-#if 0
- if (Flags) {
- *Flags = TsduFlags;
- }
-#endif
- return mdl;
-
-cleanup:
-
- *Length = 0;
- return NULL;
-}
-
-ks_mdl_t *
-KsSplitMdl(
- IN ks_mdl_t * master,
- IN ULONG offset,
- IN ULONG length
- )
-{
- ks_mdl_t * mdl = NULL;
- char * ptr = NULL;
-
- /* calculate the start virtual address */
- ptr = (char *)KsMapMdlBuffer(master) + offset;
-
- /* allocate new mdl for new memory range */
- mdl = IoAllocateMdl(ptr, length, FALSE, FALSE, NULL);
-
- if (!mdl) {
- return NULL;
- }
-
- /* initialize the mdl */
- IoBuildPartialMdl(master, mdl, (PVOID)ptr, length);
-
- return mdl;
-}
-
-/* with tconn lock acquired */
-VOID
-KsReleaseTsdus(
- ks_tconn_t * tconn,
- PKS_TSDUMGR TsduMgr,
- ULONG length
- )
-{
- PKS_TSDU KsTsdu;
- PKS_TSDU_DAT KsTsduDat;
- PKS_TSDU_BUF KsTsduBuf;
- PKS_TSDU_MDL KsTsduMdl;
-#if DBG
- ULONG total = TsduMgr->TotalBytes;
- ULONG size = length;
-#endif
-
- LASSERT(TsduMgr->TotalBytes >= length);
-
- while (!list_empty(&TsduMgr->TsduList)) {
-
- ULONG start = 0;
-
- KsTsdu = list_entry(TsduMgr->TsduList.next, KS_TSDU, Link);
- LASSERT(KsTsdu->Magic == KS_TSDU_MAGIC);
- start = KsTsdu->StartOffset;
-
- while (length > 0 && start < KsTsdu->LastOffset) {
-
- ULONG size = 0;
- ks_mdl_t * mdl = NULL;
-
- KsTsduDat = (PKS_TSDU_DAT)((PUCHAR)KsTsdu + start);
- KsTsduBuf = (PKS_TSDU_BUF)((PUCHAR)KsTsdu + start);
- KsTsduMdl = (PKS_TSDU_MDL)((PUCHAR)KsTsdu + start);
- LASSERT(KsTsduDat->TsduType == TSDU_TYPE_DAT ||
- KsTsduBuf->TsduType == TSDU_TYPE_BUF ||
- KsTsduMdl->TsduType == TSDU_TYPE_MDL);
-
- if (TSDU_TYPE_DAT == KsTsduDat->TsduType) {
-
- ASSERT(KsTsdu->LastOffset >= start + KsTsduDat->DataLength);
- if (length >= KsTsduDat->DataLength) {
- /* whole tsdu is sent out */
- size = KsTsduDat->DataLength;
- start += KsTsduDat->TotalLength;
- } else {
- size = length;
- KsTsduDat->StartOffset += size;
- }
-
- if (KsTsduDat->Mdl) {
- mdl = KsTsduDat->Mdl;
- KsTsduDat->Mdl = NULL;
- }
-
- KsTsduDat->DataLength -= size;
-
- } else if (TSDU_TYPE_BUF == KsTsduBuf->TsduType) {
-
- ASSERT(KsTsdu->LastOffset >= start + sizeof(KS_TSDU_BUF));
- if (length >= KsTsduBuf->DataLength) {
- /* whole tsdu is sent out */
- size = KsTsduBuf->DataLength;
- start += sizeof(KS_TSDU_BUF);
- LASSERT(KsTsduBuf->UserBuffer);
- ExFreePool(KsTsduBuf->UserBuffer);
- KsTsduBuf->UserBuffer = NULL;
- } else {
- KsTsduBuf->StartOffset += length;
- size = length;
- }
-
- if (KsTsduBuf->Mdl) {
- mdl = KsTsduBuf->Mdl;
- KsTsduBuf->Mdl = NULL;
- }
-
- KsTsduBuf->DataLength -= size;
-
- } else {
-
- LASSERT(TSDU_TYPE_MDL == KsTsduMdl->TsduType);
- ASSERT(KsTsdu->LastOffset >= start + sizeof(KS_TSDU_MDL));
- mdl = KsTsduMdl->Mdl;
- if (length >= KsTsduMdl->DataLength) {
- /* whole mdl is sent out */
- size = KsTsduMdl->DataLength;
- start += sizeof(KS_TSDU_MDL);
- KsTsduMdl->Mdl = NULL;
- } else {
- /* now split the remained data out */
- ks_mdl_t * mdl1 = KsSplitMdl(mdl, length,
- KsTsduMdl->DataLength - length);
- if (NULL == mdl1) {
- mdl->ByteOffset += length;
- mdl = NULL;
- } else {
- KsTsduMdl->Mdl = mdl1;
- }
- size = length;
- KsTsduMdl->StartOffset += size;
- }
-
- KsTsduMdl->DataLength -= size;
- }
-
- length -= size;
- TsduMgr->TotalBytes -= size;
-
- if (mdl) {
- mdl->Next = NULL;
- KsReleaseMdl(mdl, FALSE);
- }
-
- KsTsdu->StartOffset = start;
- }
-
- if (KsTsdu->StartOffset >= KsTsdu->LastOffset) {
-
- /* remove KsTsdu from list */
- list_del(&KsTsdu->Link);
- TsduMgr->NumOfTsdu--;
- KsPutKsTsdu(KsTsdu);
- }
-
- if (length == 0) {
- break;
- }
- }
-
- LASSERT(length == 0);
-#if DBG
- LASSERT(total - size == TsduMgr->TotalBytes);
- KsPrint((4, "KsReleaseTsdus: TsduMgr=%p Remained=%xh (%xh)\n",
- TsduMgr, TsduMgr->TotalBytes, size ));
-#endif
-}
-
-PKS_TSDUMGR
-KsQueryTsduMgr(
- ks_tconn_t * tconn,
- BOOLEAN expedited,
- BOOLEAN sending
- )
-{
-
- PKS_CHAIN KsChain;
- PKS_TSDUMGR TsduMgr;
-
- /* get the latest Tsdu buffer form TsduMgr list.
- just set NULL if the list is empty. */
-
- if (sending) {
- if (tconn->kstc_type == kstt_sender) {
- KsChain = &(tconn->sender.kstc_send);
- } else {
- LASSERT(tconn->kstc_type == kstt_child);
- KsChain = &(tconn->child.kstc_send);
- }
- } else {
- if (tconn->kstc_type == kstt_sender) {
- KsChain = &(tconn->sender.kstc_recv);
- } else {
- LASSERT(tconn->kstc_type == kstt_child);
- KsChain = &(tconn->child.kstc_recv);
- }
- }
-
- if (expedited) {
- TsduMgr = &(KsChain->Expedited);
- } else {
- TsduMgr = &(KsChain->Normal);
- }
-
- return TsduMgr;
-}
-
-PKS_TSDU
-KsGetTsdu(PKS_TSDUMGR TsduMgr, ULONG Length)
-{
- PKS_TSDU KsTsdu = NULL;
-
- /* retrieve the latest Tsdu buffer form TsduMgr
- list if the list is not empty. */
-
- if (list_empty(&(TsduMgr->TsduList))) {
-
- LASSERT(TsduMgr->NumOfTsdu == 0);
- KsTsdu = NULL;
-
- } else {
-
- LASSERT(TsduMgr->NumOfTsdu > 0);
- KsTsdu = list_entry(TsduMgr->TsduList.prev, KS_TSDU, Link);
-
- /* if this Tsdu does not contain enough space, we need
- allocate a new Tsdu queue. */
-
- if (KsTsdu->LastOffset + Length > KsTsdu->TotalLength) {
- KsTsdu = NULL;
- }
- }
-
- /* allocate a new Tsdu in case we are not statisfied. */
- if (NULL == KsTsdu) {
- KsTsdu = KsAllocateKsTsdu();
- if (NULL != KsTsdu) {
- list_add_tail(&(KsTsdu->Link), &(TsduMgr->TsduList));
- TsduMgr->NumOfTsdu++;
- }
- }
-
- return KsTsdu;
-}
-
-ULONG
-KsWriteTsduDat(
- PKS_TSDUMGR TsduMgr,
- PCHAR buffer,
- ULONG length,
- ULONG flags
- )
-{
- PKS_TSDU KsTsdu;
- PKS_TSDU_DAT KsTsduDat;
- PKS_TSDU_BUF KsTsduBuf;
-
- BOOLEAN bNewBuff = FALSE;
- PCHAR Buffer = NULL;
-
-/*
- printk("KsWriteTsduDat: %u\n", length);
- KsDumpPrint(buffer, length);
-*/
- /* if the Tsdu is even larger than the biggest Tsdu, we have
- to allocate new buffer and use TSDU_TYPE_BUF to store it */
-
- if ( KS_TSDU_STRU_SIZE(length) > ks_data.ksnd_tsdu_size -
- KS_QWORD_ALIGN(sizeof(KS_TSDU))) {
- bNewBuff = TRUE;
- }
-
- /* allocating the buffer for TSDU_TYPE_BUF */
- if (bNewBuff) {
- Buffer = ExAllocatePool(NonPagedPool, length);
- if (NULL == Buffer) {
- /* there's no enough memory for us. We just try to
- receive maximum bytes with a new Tsdu */
- bNewBuff = FALSE;
- length = ks_data.ksnd_tsdu_size - KS_TSDU_STRU_SIZE(0) -
- KS_QWORD_ALIGN(sizeof(KS_TSDU));
- }
- }
-
- /* get empty Tsdu from TsduMgr */
- KsTsdu = KsGetTsdu(TsduMgr, bNewBuff ? sizeof(KS_TSDU_BUF) :
- KS_TSDU_STRU_SIZE(length) );
-
- /* allocate a new Tsdu in case we are not statisfied. */
- if (NULL == KsTsdu) {
- goto errorout;
- }
-
- KsTsduBuf = (PKS_TSDU_BUF)((PUCHAR)KsTsdu + KsTsdu->LastOffset);
- KsTsduDat = (PKS_TSDU_DAT)((PUCHAR)KsTsdu + KsTsdu->LastOffset);
-
- if (bNewBuff) {
-
- /* setup up the KS_TSDU_BUF record */
- KsTsduBuf->TsduType = TSDU_TYPE_BUF;
- KsTsduBuf->TsduFlags = 0;
- KsTsduBuf->StartOffset = 0;
- KsTsduBuf->UserBuffer = Buffer;
- KsTsduBuf->DataLength = length;
- KsTsduBuf->Mdl = NULL;
- if (cfs_is_flag_set(flags, TDI_SEND_PARTIAL)) {
- KsTsduBuf->TsduFlags |= KS_TSDU_COMM_PARTIAL;
- }
-
- KsTsdu->LastOffset += sizeof(KS_TSDU_BUF);
-
- } else {
-
- /* setup the KS_TSDU_DATA to contain all the messages */
-
- KsTsduDat->TsduType = TSDU_TYPE_DAT;
- KsTsduDat->TsduFlags = 0;
-
- if ( KsTsdu->TotalLength - KsTsdu->LastOffset <
- KS_TSDU_STRU_SIZE(length) ) {
- length = KsTsdu->TotalLength - KsTsdu->LastOffset -
- FIELD_OFFSET(KS_TSDU_DAT, Data);
- }
- KsTsduDat->DataLength = length;
- KsTsduDat->TotalLength = KS_TSDU_STRU_SIZE(length);
- KsTsduDat->StartOffset = 0;
- KsTsduDat->Mdl = NULL;
- if (cfs_is_flag_set(flags, TDI_SEND_PARTIAL)) {
- KsTsduDat->TsduFlags |= KS_TSDU_COMM_PARTIAL;
- }
-
- Buffer = &KsTsduDat->Data[0];
- KsTsdu->LastOffset += KsTsduDat->TotalLength;
- }
-
- RtlMoveMemory(Buffer, buffer, length);
- TsduMgr->TotalBytes += length;
-
- KsPrint((4, "KsWriteTsduDat: TsduMgr=%p bytes in queue:%xh (%xh)\n",
- TsduMgr, TsduMgr->TotalBytes, length));
- return length;
-
-errorout:
-
- return 0;
-}
-
-ULONG
-KsWriteTsduBuf(
- PKS_TSDUMGR TsduMgr,
- PCHAR buffer,
- ULONG length,
- ULONG flags
- )
-{
- PKS_TSDU KsTsdu;
- PKS_TSDU_BUF KsTsduBuf;
-
- /* get empty Tsdu from TsduMgr */
- KsTsdu = KsGetTsdu(TsduMgr, sizeof(KS_TSDU_BUF));
-
- /* allocate a new Tsdu in case we are not statisfied. */
- if (NULL == KsTsdu) {
- goto errorout;
- }
-
- /* setup up the KS_TSDU_BUF record */
- KsTsduBuf = (PKS_TSDU_BUF)((PUCHAR)KsTsdu + KsTsdu->LastOffset);
- KsTsduBuf->TsduType = TSDU_TYPE_BUF;
- KsTsduBuf->TsduFlags = 0;
- KsTsduBuf->StartOffset = 0;
- KsTsduBuf->UserBuffer = buffer;
- KsTsduBuf->DataLength = length;
- KsTsduBuf->Mdl = NULL;
- KsTsdu->LastOffset += sizeof(KS_TSDU_BUF);
- if (cfs_is_flag_set(flags, TDI_SEND_PARTIAL)) {
- KsTsduBuf->TsduFlags |= KS_TSDU_COMM_PARTIAL;
- }
-
- TsduMgr->TotalBytes += length;
- KsPrint((4, "KsWriteTsduBuf: TsduMgr=%p bytes in queue:%xh (%xh)\n",
- TsduMgr, TsduMgr->TotalBytes, length));
-
- return length;
-
-errorout:
- return 0;
-}
-
-ULONG
-KsWriteTsduMdl(
- PKS_TSDUMGR TsduMgr,
- ks_mdl_t * mdl,
- PVOID desc,
- ULONG offset,
- ULONG length,
- ULONG flags
- )
-{
- PKS_TSDU KsTsdu;
- PKS_TSDU_MDL KsTsduMdl;
-
- /* get empty Tsdu from TsduMgr */
- KsTsdu = KsGetTsdu(TsduMgr, sizeof(KS_TSDU_MDL));
-
- /* allocate a new Tsdu in case we are not statisfied. */
- if (NULL == KsTsdu) {
- goto errorout;
- }
-
- /* setup up the KS_TSDU_MDL record */
- KsTsduMdl = (PKS_TSDU_MDL)((PUCHAR)KsTsdu + KsTsdu->LastOffset);
- KsTsduMdl->TsduType = TSDU_TYPE_MDL;
- KsTsduMdl->TsduFlags = 0;
- KsTsduMdl->StartOffset = 0;
- KsTsduMdl->BaseOffset = offset;
- KsTsduMdl->DataLength = length;
- KsTsduMdl->Mdl = mdl;
- KsTsduMdl->Descriptor = desc;
- KsTsdu->LastOffset += sizeof(KS_TSDU_MDL);
- if (cfs_is_flag_set(flags, TDI_SEND_PARTIAL)) {
- KsTsduMdl->TsduFlags |= KS_TSDU_COMM_PARTIAL;
- }
-
- TsduMgr->TotalBytes += length;
- KsPrint((4, "KsWriteTsduMdl: TsduMgr=%p bytes in queue:%xh (%xh)\n",
- TsduMgr, TsduMgr->TotalBytes, length));
-
- return length;
-
-errorout:
- return 0;
-}
-
-ULONG
-KsReadTsdu (
- PKS_TSDUMGR TsduMgr,
- PCHAR buffer,
- ULONG length,
- ULONG flags
- )
-{
- PKS_TSDU KsTsdu;
- PKS_TSDU_DAT KsTsduDat;
- PKS_TSDU_BUF KsTsduBuf;
- PKS_TSDU_MDL KsTsduMdl;
-
- PUCHAR Buffer;
- ULONG BytesRecved = 0;
-#if DBG
- ULONG TotalBytes = TsduMgr->TotalBytes;
-#endif
-
- KsPrint((4, "KsReadTsdu: TsduMgr=%p request=%xh total=%xh\n",
- TsduMgr, length, TsduMgr->TotalBytes ));
-NextTsdu:
-
- if (TsduMgr->TotalBytes == 0) {
-
- /* It's a notification event. We need reset it to
- un-signaled state in case there no any tsdus. */
-
- KeResetEvent(&(TsduMgr->Event));
-
- } else {
-
- KsTsdu = list_entry(TsduMgr->TsduList.next, KS_TSDU, Link);
- LASSERT(KsTsdu->Magic == KS_TSDU_MAGIC);
-
- /* remove the KsTsdu from TsduMgr list to release the lock */
- list_del(&(KsTsdu->Link));
- TsduMgr->NumOfTsdu--;
-
- while (length > BytesRecved) {
-
- ULONG BytesToCopy = 0;
- ULONG StartOffset = 0;
- ULONG BytesCopied = 0;
-
- if (KsTsdu->StartOffset >= KsTsdu->LastOffset) {
- /* KsTsdu is empty now, we need free it ... */
- KsPutKsTsdu(KsTsdu);
- KsTsdu = NULL;
- break;
- }
-
- KsTsduDat = (PKS_TSDU_DAT)((PUCHAR)KsTsdu + KsTsdu->StartOffset);
- KsTsduBuf = (PKS_TSDU_BUF)((PUCHAR)KsTsdu + KsTsdu->StartOffset);
- KsTsduMdl = (PKS_TSDU_MDL)((PUCHAR)KsTsdu + KsTsdu->StartOffset);
-
- if ( TSDU_TYPE_DAT == KsTsduDat->TsduType ||
- TSDU_TYPE_BUF == KsTsduBuf->TsduType ) {
-
- if (TSDU_TYPE_DAT == KsTsduDat->TsduType) {
-
- /* Data Tsdu Unit ... */
- Buffer = &KsTsduDat->Data[0];
- StartOffset = KsTsduDat->StartOffset;
- if (KsTsduDat->DataLength - KsTsduDat->StartOffset > length - BytesRecved) {
- /* Recvmsg requst could be statisfied ... */
- BytesToCopy = length - BytesRecved;
- } else {
- BytesToCopy = KsTsduDat->DataLength - KsTsduDat->StartOffset;
- }
-
- } else {
-
- /* Buffer Tsdu Unit */
- ASSERT(TSDU_TYPE_BUF == KsTsduBuf->TsduType);
- Buffer = KsTsduBuf->UserBuffer;
- StartOffset = KsTsduBuf->StartOffset;
-
- if (KsTsduBuf->DataLength - KsTsduBuf->StartOffset > length - BytesRecved) {
- /* Recvmsg requst could be statisfied ... */
- BytesToCopy = length - BytesRecved;
- } else {
- BytesToCopy = KsTsduBuf->DataLength - KsTsduBuf->StartOffset;
- }
- }
-
- if (BytesToCopy > 0) {
- RtlMoveMemory(buffer + BytesRecved, Buffer + StartOffset, BytesToCopy);
- }
- BytesCopied = BytesToCopy;
- BytesRecved += BytesCopied;
- LASSERT(TsduMgr->TotalBytes >= BytesCopied);
- TsduMgr->TotalBytes -= BytesCopied;
- KsPrint((4, "KsReadTsdu: TsduMgr=%p copied=%xh recved=%xh\n",
- TsduMgr, BytesCopied, BytesRecved ));
-
- if (TSDU_TYPE_DAT == KsTsduDat->TsduType) {
-
- KsTsduDat->StartOffset += BytesCopied;
- if (KsTsduDat->StartOffset == KsTsduDat->DataLength) {
- if (KsTsduDat->Mdl) {
- KsTsduDat->Mdl->Next = NULL;
- KsReleaseMdl(KsTsduDat->Mdl, FALSE);
- }
- KsTsdu->StartOffset += KsTsduDat->TotalLength;
- }
-
- } else {
-
- ASSERT(TSDU_TYPE_BUF == KsTsduBuf->TsduType);
- KsTsduBuf->StartOffset += BytesCopied;
- if (KsTsduBuf->StartOffset == KsTsduBuf->DataLength) {
- KsTsdu->StartOffset += sizeof(KS_TSDU_BUF);
- /* now we need release the buf to system pool */
- if (KsTsduBuf->Mdl) {
- KsTsduBuf->Mdl->Next = NULL;
- KsReleaseMdl(KsTsduBuf->Mdl, FALSE);
- }
- ExFreePool(KsTsduBuf->UserBuffer);
- }
- }
-
- } else if (TSDU_TYPE_MDL == KsTsduMdl->TsduType) {
-
- /* MDL Tsdu Unit ... */
- if (KsTsduMdl->DataLength > length - BytesRecved) {
- /* Recvmsg requst could be statisfied ... */
- BytesToCopy = length - BytesRecved;
- } else {
- BytesToCopy = KsTsduMdl->DataLength;
- }
-
- BytesCopied =
- KsCopyMdlToBuffer(
- KsTsduMdl->Mdl,
- KsTsduMdl->StartOffset +
- KsTsduMdl->BaseOffset,
- buffer,
- BytesRecved,
- BytesToCopy
- );
- KsPrint((4, "KsReadTsdu: TsduMgr=%p mdl=%p dec=%p copied=%xh "
- "recved=%xh\n",
- TsduMgr, KsTsduMdl->Mdl, KsTsduMdl->Descriptor,
- BytesCopied, BytesRecved + BytesCopied));
- if (BytesCopied == 0) {
- cfs_enter_debugger();
- break;
- }
-
- KsTsduMdl->StartOffset += BytesCopied;
- KsTsduMdl->DataLength -= BytesCopied;
- BytesRecved += BytesCopied;
- LASSERT(TsduMgr->TotalBytes >= BytesCopied);
- TsduMgr->TotalBytes -= BytesCopied;
-
- if (0 == KsTsduMdl->DataLength) {
-
- /* Call TdiReturnChainedReceives to release the Tsdu memory */
- LASSERT(KsTsduMdl->Descriptor != NULL);
- if (KsTsduMdl->Descriptor) {
- TdiReturnChainedReceives(
- &(KsTsduMdl->Descriptor),
- 1 );
- }
-
- KsTsdu->StartOffset += sizeof(KS_TSDU_MDL);
- }
-
- } else {
- KsPrint((1, "KsReadTsdu: unknown tsdu slot: slot = %x type = %x Start= %x Length=%x\n",
- KsTsduDat, KsTsduDat->TsduType, KsTsduDat->StartOffset, KsTsduDat->DataLength));
- KsPrint((1, " Tsdu = %x Magic=%x: Start = %x Last = %x Length = %x\n",
- KsTsdu, KsTsdu->Magic, KsTsdu->StartOffset, KsTsdu->LastOffset, KsTsdu->TotalLength));
- cfs_enter_debugger();
- }
- }
-
- /* we need attach the KsTsdu to the list header */
- if (KsTsdu) {
- if (KsTsdu->StartOffset >= KsTsdu->LastOffset) {
- KsPutKsTsdu(KsTsdu);
- KsTsdu = NULL;
- } else {
- TsduMgr->NumOfTsdu++;
- list_add(&(KsTsdu->Link), &(TsduMgr->TsduList));
- }
- }
-
- if (length > BytesRecved) {
- goto NextTsdu;
- }
- }
-
-#if DBG
- LASSERT(TotalBytes == TsduMgr->TotalBytes + BytesRecved);
-#endif
- KsPrint((4, "KsReadTsdu: TsduMgr=%p recved=%xh (%xh) remained=%xh\n",
- TsduMgr, BytesRecved, length, TsduMgr->TotalBytes ));
-
- return BytesRecved;
-}
-
-
-ULONG
-KsTdiSendFlags(int SockFlags)
-{
- ULONG TdiFlags = 0;
-
- if (cfs_is_flag_set(SockFlags, MSG_OOB)) {
- cfs_set_flag(TdiFlags, TDI_SEND_EXPEDITED);
- }
-
- if (cfs_is_flag_set(SockFlags, MSG_MORE)) {
- cfs_set_flag(TdiFlags, TDI_SEND_PARTIAL);
- }
-
- if (cfs_is_flag_set(SockFlags, MSG_DONTWAIT)) {
- cfs_set_flag(TdiFlags, TDI_SEND_NON_BLOCKING);
- }
-
- return TdiFlags;
-}
-
-ULONG
-KsTdiRecvFlags(int SockFlags)
-{
- ULONG TdiFlags = 0;
-
- if (cfs_is_flag_set(SockFlags, MSG_OOB)) {
- cfs_set_flag(TdiFlags, TDI_RECEIVE_EXPEDITED);
- }
-
- if (cfs_is_flag_set(SockFlags, MSG_MORE)) {
- cfs_set_flag(TdiFlags, TDI_RECEIVE_PARTIAL);
- }
-
- if (cfs_is_flag_set(SockFlags, MSG_DONTWAIT)) {
- cfs_set_flag(TdiFlags, TDI_SEND_NON_BLOCKING);
- }
-
- return TdiFlags;
-}
-
-int
-KsWriteTsdus(PKS_TSDUMGR TsduMgr, char * buffer, int length, int flags)
-{
- int rc = 0;
-
- if (TsduMgr->TotalBytes <= TDINAL_MAX_TSDU_QUEUE_SIZE) {
- rc = KsWriteTsduDat(TsduMgr, buffer, length, flags);
- }
-
- if (rc > 0) {
- return rc;
- }
-
- return -EAGAIN;
-}
-
-int
-KsReadTsdus(PKS_TSDUMGR TsduMgr, char * buffer, int length, int flags)
-{
- int rc = KsReadTsdu(TsduMgr, buffer, length, flags);
-
- if (rc > 0) {
- return rc;
- }
-
- return -EAGAIN;
-}
-
-/*
- * KsInitializeKsTsduMgr
- * Initialize the management structure of
- * Tsdu buffers
- *
- * Arguments:
- * TsduMgr: the TsduMgr to be initialized
- *
- * Return Value:
- * VOID
- *
- * NOTES:
- * N/A
- */
-
-VOID
-KsInitializeKsTsduMgr(
- PKS_TSDUMGR TsduMgr
- )
-{
- KeInitializeEvent(
- &(TsduMgr->Event),
- NotificationEvent,
- FALSE
- );
-
- INIT_LIST_HEAD(
- &(TsduMgr->TsduList)
- );
-
- TsduMgr->NumOfTsdu = 0;
- TsduMgr->TotalBytes = 0;
-
- spin_lock_init(&TsduMgr->Lock);
-}
-
-
-/*
- * KsInitializeKsChain
- * Initialize the China structure for receiving
- * or transmitting
- *
- * Arguments:
- * KsChain: the KsChain to be initialized
- *
- * Return Value:
- * VOID
- *
- * NOTES:
- * N/A
- */
-
-VOID
-KsInitializeKsChain(
- PKS_CHAIN KsChain
- )
-{
- KsInitializeKsTsduMgr(&(KsChain->Normal));
- KsInitializeKsTsduMgr(&(KsChain->Expedited));
- KsChain->Expedited.OOB = TRUE;
-}
-
-
-/*
- * KsCleanupTsduMgr
- * Clean up all the Tsdus in the TsduMgr list
- *
- * Arguments:
- * TsduMgr: the Tsdu list manager
- *
- * Return Value:
- * NTSTATUS: nt status code
- *
- * NOTES:
- * N/A
- */
-
-NTSTATUS
-KsCleanupTsduMgr(
- PKS_TSDUMGR TsduMgr
- )
-{
- PKS_TSDU KsTsdu;
- PKS_TSDU_DAT KsTsduDat;
- PKS_TSDU_BUF KsTsduBuf;
- PKS_TSDU_MDL KsTsduMdl;
-
- LASSERT(NULL != TsduMgr);
-
- KsRemoveTdiEngine(TsduMgr);
- KeSetEvent(&(TsduMgr->Event), 0, FALSE);
-
- while (!list_empty(&TsduMgr->TsduList)) {
-
- KsTsdu = list_entry(TsduMgr->TsduList.next, KS_TSDU, Link);
- LASSERT(KsTsdu->Magic == KS_TSDU_MAGIC);
-
- if (KsTsdu->StartOffset == KsTsdu->LastOffset) {
-
- //
- // KsTsdu is empty now, we need free it ...
- //
-
- list_del(&(KsTsdu->Link));
- TsduMgr->NumOfTsdu--;
-
- KsFreeKsTsdu(KsTsdu);
-
- } else {
-
- KsTsduDat = (PKS_TSDU_DAT)((PUCHAR)KsTsdu + KsTsdu->StartOffset);
- KsTsduBuf = (PKS_TSDU_BUF)((PUCHAR)KsTsdu + KsTsdu->StartOffset);
- KsTsduMdl = (PKS_TSDU_MDL)((PUCHAR)KsTsdu + KsTsdu->StartOffset);
-
- if (TSDU_TYPE_DAT == KsTsduDat->TsduType) {
-
- KsTsdu->StartOffset += KsTsduDat->TotalLength;
-
- } else if (TSDU_TYPE_BUF == KsTsduBuf->TsduType) {
-
- ASSERT(KsTsduBuf->UserBuffer != NULL);
-
- if (KsTsduBuf->DataLength > KsTsduBuf->StartOffset) {
- if (KsTsduBuf->Mdl) {
- KsTsduBuf->Mdl->Next = NULL;
- KsReleaseMdl(KsTsduBuf->Mdl, FALSE);
- }
- ExFreePool(KsTsduBuf->UserBuffer);
- } else {
- cfs_enter_debugger();
- }
-
- KsTsdu->StartOffset += sizeof(KS_TSDU_BUF);
-
- } else if (TSDU_TYPE_MDL == KsTsduMdl->TsduType) {
-
- //
- // MDL Tsdu Unit ...
- //
- if (KsTsduMdl->Descriptor) {
- TdiReturnChainedReceives(
- &(KsTsduMdl->Descriptor),
- 1 );
- } else if (KsTsduMdl->Mdl) {
- KsTsduMdl->Mdl->Next = NULL;
- KsReleaseMdl(KsTsduMdl->Mdl, FALSE);
- }
-
- KsTsdu->StartOffset += sizeof(KS_TSDU_MDL);
- }
- }
- }
-
- return STATUS_SUCCESS;
-}
-
-
-/*
- * KsCleanupKsChain
- * Clean up the TsduMgrs of the KsChain
- *
- * Arguments:
- * KsChain: the chain managing TsduMgr
- *
- * Return Value:
- * NTSTATUS: nt status code
- *
- * NOTES:
- * N/A
- */
-
-NTSTATUS
-KsCleanupKsChain(
- PKS_CHAIN KsChain
- )
-{
- NTSTATUS Status;
-
- LASSERT(NULL != KsChain);
-
- Status = KsCleanupTsduMgr(
- &(KsChain->Normal)
- );
-
- if (!NT_SUCCESS(Status)) {
- cfs_enter_debugger();
- goto errorout;
- }
-
- Status = KsCleanupTsduMgr(
- &(KsChain->Expedited)
- );
-
- if (!NT_SUCCESS(Status)) {
- cfs_enter_debugger();
- goto errorout;
- }
-
-errorout:
-
- return Status;
-}
-
-
-/*
- * KsCleanupTsdu
- * Clean up all the Tsdus of a tdi connected object
- *
- * Arguments:
- * tconn: the tdi connection which is connected already.
- *
- * Return Value:
- * Nt status code
- *
- * NOTES:
- * N/A
- */
-
-NTSTATUS
-KsCleanupTsdu(
- ks_tconn_t * tconn
- )
-{
- NTSTATUS Status = STATUS_SUCCESS;
-
-
- if (tconn->kstc_type != kstt_sender &&
- tconn->kstc_type != kstt_child ) {
-
- goto errorout;
- }
-
- if (tconn->kstc_type == kstt_sender) {
-
- Status = KsCleanupKsChain(
- &(tconn->sender.kstc_recv)
- );
-
- if (!NT_SUCCESS(Status)) {
- cfs_enter_debugger();
- goto errorout;
- }
-
- Status = KsCleanupKsChain(
- &(tconn->sender.kstc_send)
- );
-
- if (!NT_SUCCESS(Status)) {
- cfs_enter_debugger();
- goto errorout;
- }
-
- } else {
-
- Status = KsCleanupKsChain(
- &(tconn->child.kstc_recv)
- );
-
- if (!NT_SUCCESS(Status)) {
- cfs_enter_debugger();
- goto errorout;
- }
-
- Status = KsCleanupKsChain(
- &(tconn->child.kstc_send)
- );
-
- if (!NT_SUCCESS(Status)) {
- cfs_enter_debugger();
- goto errorout;
- }
-
- }
-
-errorout:
-
- return (Status);
-}
-
-NTSTATUS
-KsIrpCompletionRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- )
-{
- if (NULL != Context) {
- KeSetEvent((PKEVENT)Context, IO_NETWORK_INCREMENT, FALSE);
- }
-
- return STATUS_MORE_PROCESSING_REQUIRED;
-
- UNREFERENCED_PARAMETER(DeviceObject);
- UNREFERENCED_PARAMETER(Irp);
-}
-
-
-/*
- * KsBuildTdiIrp
- * Allocate a new IRP and initialize it to be issued to tdi
- *
- * Arguments:
- * DeviceObject: device object created by the underlying
- * TDI transport driver
- *
- * Return Value:
- * PRIP: the allocated Irp in success or NULL in failure.
- *
- * NOTES:
- * N/A
- */
-
-PIRP
-KsBuildTdiIrp(
- IN PDEVICE_OBJECT DeviceObject
- )
-{
- PIRP Irp;
- PIO_STACK_LOCATION IrpSp;
-
- //
- // Allocating the IRP ...
- //
-
- Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
-
- if (NULL != Irp) {
-
- //
- // Getting the Next Stack Location ...
- //
-
- IrpSp = IoGetNextIrpStackLocation(Irp);
-
- //
- // Initializing Irp ...
- //
-
- IrpSp->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
- IrpSp->Parameters.DeviceIoControl.IoControlCode = 0;
- }
-
- return Irp;
-}
-
-/*
- * KsSubmitTdiIrp
- * Issue the Irp to the underlying tdi driver
- *
- * Arguments:
- * DeviceObject: the device object created by TDI driver
- * Irp: the I/O request packet to be processed
- * bSynchronous: synchronous or not. If true, we need wait
- * until the process is finished.
- * Information: returned info
- *
- * Return Value:
- * NTSTATUS: kernel status code
- *
- * NOTES:
- * N/A
- */
-
-NTSTATUS
-KsSubmitTdiIrp(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN BOOLEAN bSynchronous,
- OUT PULONG Information
- )
-{
- NTSTATUS Status;
- KEVENT Event;
-
- if (bSynchronous) {
-
- KeInitializeEvent(
- &Event,
- SynchronizationEvent,
- FALSE
- );
-
-
- IoSetCompletionRoutine(
- Irp,
- KsIrpCompletionRoutine,
- &Event,
- TRUE,
- TRUE,
- TRUE
- );
- }
-
- Status = IoCallDriver(DeviceObject, Irp);
-
- if (bSynchronous) {
-
- if (STATUS_PENDING == Status) {
-
- Status = KeWaitForSingleObject(
- &Event,
- Executive,
- KernelMode,
- FALSE,
- NULL
- );
- }
-
- Status = Irp->IoStatus.Status;
-
- if (Information) {
- *Information = (ULONG)(Irp->IoStatus.Information);
- }
-
- IoFreeIrp(Irp);
- }
-
- if (!NT_SUCCESS(Status)) {
-
- KsPrint((1, "KsSubmitTdiIrp: Error when submitting the Irp: "
- "Status = %xh (%s)\n", Status, KsNtStatusToString(Status)));
- }
-
- return (Status);
-}
-
-
-
-/*
- * KsOpenControl
- * Open the Control Channel Object ...
- *
- * Arguments:
- * DeviceName: the device name to be opened
- * Handle: opened handle in success case
- * FileObject: the fileobject of the device
- *
- * Return Value:
- * NTSTATUS: kernel status code (STATUS_SUCCESS
- * or other error code)
- *
- * Notes:
- * N/A
- */
-
-NTSTATUS
-KsOpenControl(
- IN PUNICODE_STRING DeviceName,
- OUT HANDLE * Handle,
- OUT PFILE_OBJECT * FileObject
- )
-{
- NTSTATUS Status = STATUS_SUCCESS;
-
- OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK IoStatus;
-
-
- LASSERT( KeGetCurrentIrql() < DISPATCH_LEVEL );
-
- //
- // Initializing ...
- //
-
- InitializeObjectAttributes(
- &ObjectAttributes,
- DeviceName,
- OBJ_CASE_INSENSITIVE |
- OBJ_KERNEL_HANDLE,
- NULL,
- NULL
- );
-
- LASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL );
-
- //
- // Creating the Transport Address Object ...
- //
-
- Status = ZwCreateFile(
- Handle,
- FILE_READ_DATA | FILE_WRITE_DATA,
- &ObjectAttributes,
- &IoStatus,
- 0,
- FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- FILE_OPEN,
- 0,
- NULL,
- 0
- );
-
-
- if (NT_SUCCESS(Status)) {
-
- //
- // Now Obtaining the FileObject of the Transport Address ...
- //
-
- Status = ObReferenceObjectByHandle(
- *Handle,
- FILE_ANY_ACCESS,
- NULL,
- KernelMode,
- FileObject,
- NULL
- );
-
- if (!NT_SUCCESS(Status)) {
-
- cfs_enter_debugger();
- ZwClose(*Handle);
- }
-
- } else {
-
- cfs_enter_debugger();
- }
-
- return (Status);
-}
-
-
-/*
- * KsCloseControl
- * Release the Control Channel Handle and FileObject
- *
- * Arguments:
- * Handle: the channel handle to be released
- * FileObject: the fileobject to be released
- *
- * Return Value:
- * NTSTATUS: kernel status code (STATUS_SUCCESS
- * or other error code)
- *
- * Notes:
- * N/A
- */
-
-NTSTATUS
-KsCloseControl(
- IN HANDLE Handle,
- IN PFILE_OBJECT FileObject
- )
-{
- NTSTATUS Status = STATUS_SUCCESS;
-
- LASSERT( KeGetCurrentIrql() < DISPATCH_LEVEL );
-
- if (FileObject) {
-
- ObDereferenceObject(FileObject);
- }
-
- if (Handle) {
-
- Status = ZwClose(Handle);
- }
-
- ASSERT(NT_SUCCESS(Status));
-
- return (Status);
-}
-
-
-/*
- * KsOpenAddress
- * Open the tdi address object
- *
- * Arguments:
- * DeviceName: device name of the address object
- * pAddress: tdi address of the address object
- * AddressLength: length in bytes of the tdi address
- * Handle: the newly opened handle
- * FileObject: the newly opened fileobject
- *
- * Return Value:
- * NTSTATUS: kernel status code (STATUS_SUCCESS
- * or other error code)
- *
- * Notes:
- * N/A
- */
-
-NTSTATUS
-KsOpenAddress(
- IN PUNICODE_STRING DeviceName,
- IN PTRANSPORT_ADDRESS pAddress,
- IN ULONG AddressLength,
- OUT HANDLE * Handle,
- OUT PFILE_OBJECT * FileObject
- )
-{
- NTSTATUS Status = STATUS_SUCCESS;
-
- PFILE_FULL_EA_INFORMATION Ea = NULL;
- ULONG EaLength;
- UCHAR EaBuffer[EA_MAX_LENGTH];
-
- OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK IoStatus;
-
- //
- // Building EA for the Address Object to be Opened ...
- //
-
- Ea = (PFILE_FULL_EA_INFORMATION)EaBuffer;
- Ea->NextEntryOffset = 0;
- Ea->Flags = 0;
- Ea->EaNameLength = TDI_TRANSPORT_ADDRESS_LENGTH;
- Ea->EaValueLength = (USHORT)AddressLength;
- RtlCopyMemory(
- &(Ea->EaName),
- TdiTransportAddress,
- Ea->EaNameLength + 1
- );
- RtlMoveMemory(
- &(Ea->EaName[Ea->EaNameLength + 1]),
- pAddress,
- AddressLength
- );
- EaLength = sizeof(FILE_FULL_EA_INFORMATION) +
- Ea->EaNameLength + AddressLength;
-
- LASSERT( KeGetCurrentIrql() < DISPATCH_LEVEL );
-
-
- //
- // Initializing ...
- //
-
- InitializeObjectAttributes(
- &ObjectAttributes,
- DeviceName,
- OBJ_CASE_INSENSITIVE |
- OBJ_KERNEL_HANDLE,
- NULL,
- NULL
- );
-
- LASSERT( KeGetCurrentIrql() < DISPATCH_LEVEL );
-
- //
- // Creating the Transport Address Object ...
- //
-
- Status = ZwCreateFile(
- Handle,
- FILE_READ_DATA | FILE_WRITE_DATA,
- &ObjectAttributes,
- &IoStatus,
- 0,
- FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ | FILE_SHARE_WRITE, /* 0: DON'T REUSE */
- FILE_OPEN,
- 0,
- Ea,
- EaLength
- );
-
-
- if (NT_SUCCESS(Status)) {
-
- //
- // Now Obtaining the FileObject of the Transport Address ...
- //
-
- Status = ObReferenceObjectByHandle(
- *Handle,
- FILE_ANY_ACCESS,
- NULL,
- KernelMode,
- FileObject,
- NULL
- );
-
- if (!NT_SUCCESS(Status)) {
-
- cfs_enter_debugger();
- ZwClose(*Handle);
- }
-
- } else {
-
- cfs_enter_debugger();
- }
-
- return (Status);
-}
-
-/*
- * KsCloseAddress
- * Release the Hanlde and FileObject of an opened tdi
- * address object
- *
- * Arguments:
- * Handle: the handle to be released
- * FileObject: the fileobject to be released
- *
- * Return Value:
- * NTSTATUS: kernel status code (STATUS_SUCCESS
- * or other error code)
- *
- * Notes:
- * N/A
- */
-
-NTSTATUS
-KsCloseAddress(
- IN HANDLE Handle,
- IN PFILE_OBJECT FileObject
-)
-{
- NTSTATUS Status = STATUS_SUCCESS;
-
- if (FileObject) {
-
- ObDereferenceObject(FileObject);
- }
-
- if (Handle) {
-
- Status = ZwClose(Handle);
- }
-
- ASSERT(NT_SUCCESS(Status));
-
- return (Status);
-}
-
-
-/*
- * KsOpenConnection
- * Open a tdi connection object
- *
- * Arguments:
- * DeviceName: device name of the connection object
- * ConnectionContext: the connection context
- * Handle: the newly opened handle
- * FileObject: the newly opened fileobject
- *
- * Return Value:
- * NTSTATUS: kernel status code (STATUS_SUCCESS
- * or other error code)
- *
- * Notes:
- * N/A
- */
-
-NTSTATUS
-KsOpenConnection(
- IN PUNICODE_STRING DeviceName,
- IN CONNECTION_CONTEXT ConnectionContext,
- OUT HANDLE * Handle,
- OUT PFILE_OBJECT * FileObject
- )
-{
- NTSTATUS Status = STATUS_SUCCESS;
-
- PFILE_FULL_EA_INFORMATION Ea = NULL;
- ULONG EaLength;
- UCHAR EaBuffer[EA_MAX_LENGTH];
-
- OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK IoStatus;
-
- //
- // Building EA for the Address Object to be Opened ...
- //
-
- Ea = (PFILE_FULL_EA_INFORMATION)EaBuffer;
- Ea->NextEntryOffset = 0;
- Ea->Flags = 0;
- Ea->EaNameLength = TDI_CONNECTION_CONTEXT_LENGTH;
- Ea->EaValueLength = (USHORT)sizeof(CONNECTION_CONTEXT);
- RtlCopyMemory(
- &(Ea->EaName),
- TdiConnectionContext,
- Ea->EaNameLength + 1
- );
- RtlMoveMemory(
- &(Ea->EaName[Ea->EaNameLength + 1]),
- &ConnectionContext,
- sizeof(CONNECTION_CONTEXT)
- );
- EaLength = sizeof(FILE_FULL_EA_INFORMATION) - 1 +
- Ea->EaNameLength + 1 + sizeof(CONNECTION_CONTEXT);
-
- LASSERT( KeGetCurrentIrql() < DISPATCH_LEVEL );
-
-
- //
- // Initializing ...
- //
-
- InitializeObjectAttributes(
- &ObjectAttributes,
- DeviceName,
- OBJ_CASE_INSENSITIVE |
- OBJ_KERNEL_HANDLE,
- NULL,
- NULL
- );
-
- LASSERT( KeGetCurrentIrql() < DISPATCH_LEVEL );
-
- //
- // Creating the Connection Object ...
- //
-
- Status = ZwCreateFile(
- Handle,
- FILE_READ_DATA | FILE_WRITE_DATA,
- &ObjectAttributes,
- &IoStatus,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- FILE_OPEN,
- 0,
- Ea,
- EaLength
- );
-
-
- if (NT_SUCCESS(Status)) {
-
- //
- // Now Obtaining the FileObject of the Transport Address ...
- //
-
- Status = ObReferenceObjectByHandle(
- *Handle,
- FILE_ANY_ACCESS,
- NULL,
- KernelMode,
- FileObject,
- NULL
- );
-
- if (!NT_SUCCESS(Status)) {
-
- cfs_enter_debugger();
- ZwClose(*Handle);
- }
-
- } else {
-
- cfs_enter_debugger();
- }
-
- return (Status);
-}
-
-/*
- * KsCloseConnection
- * Release the Hanlde and FileObject of an opened tdi
- * connection object
- *
- * Arguments:
- * Handle: the handle to be released
- * FileObject: the fileobject to be released
- *
- * Return Value:
- * NTSTATUS: kernel status code (STATUS_SUCCESS
- * or other error code)
- *
- * Notes:
- * N/A
- */
-
-NTSTATUS
-KsCloseConnection(
- IN HANDLE Handle,
- IN PFILE_OBJECT FileObject
- )
-{
- NTSTATUS Status = STATUS_SUCCESS;
-
- if (FileObject) {
-
- ObDereferenceObject(FileObject);
- }
-
- if (Handle) {
-
- Status = ZwClose(Handle);
- }
-
- ASSERT(NT_SUCCESS(Status));
-
- return (Status);
-}
-
-
-/*
- * KsAssociateAddress
- * Associate an address object with a connection object
- *
- * Arguments:
- * AddressHandle: the handle of the address object
- * ConnectionObject: the FileObject of the connection
- *
- * Return Value:
- * NTSTATUS: kernel status code (STATUS_SUCCESS
- * or other error code)
- *
- * Notes:
- * N/A
- */
-
-NTSTATUS
-KsAssociateAddress(
- IN HANDLE AddressHandle,
- IN PFILE_OBJECT ConnectionObject
- )
-{
- NTSTATUS Status;
- PDEVICE_OBJECT DeviceObject;
- PIRP Irp;
-
- //
- // Getting the DeviceObject from Connection FileObject
- //
-
- DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
-
- //
- // Building Tdi Internal Irp ...
- //
-
- Irp = KsBuildTdiIrp(DeviceObject);
-
- if (NULL == Irp) {
-
- Status = STATUS_INSUFFICIENT_RESOURCES;
-
- } else {
-
- //
- // Assocating the Address Object with the Connection Object
- //
-
- TdiBuildAssociateAddress(
- Irp,
- DeviceObject,
- ConnectionObject,
- NULL,
- NULL,
- AddressHandle
- );
-
- //
- // Calling the Transprot Driver with the Prepared Irp
- //
-
- Status = KsSubmitTdiIrp(DeviceObject, Irp, TRUE, NULL);
- }
-
- return (Status);
-}
-
-
-/*
- * KsDisassociateAddress
- * Disassociate the connection object (the relationship will
- * the corresponding address object will be dismissed. )
- *
- * Arguments:
- * ConnectionObject: the FileObject of the connection
- *
- * Return Value:
- * NTSTATUS: kernel status code (STATUS_SUCCESS
- * or other error code)
- *
- * Notes:
- * N/A
- */
-
-NTSTATUS
-KsDisassociateAddress(
- IN PFILE_OBJECT ConnectionObject
- )
-{
- NTSTATUS Status;
- PDEVICE_OBJECT DeviceObject;
- PIRP Irp;
-
- //
- // Getting the DeviceObject from Connection FileObject
- //
-
- DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
-
- //
- // Building Tdi Internal Irp ...
- //
-
- Irp = KsBuildTdiIrp(DeviceObject);
-
- if (NULL == Irp) {
-
- Status = STATUS_INSUFFICIENT_RESOURCES;
-
- } else {
-
- //
- // Disassocating the Address Object with the Connection Object
- //
-
- TdiBuildDisassociateAddress(
- Irp,
- DeviceObject,
- ConnectionObject,
- NULL,
- NULL
- );
-
- //
- // Calling the Transprot Driver with the Prepared Irp
- //
-
- Status = KsSubmitTdiIrp(DeviceObject, Irp, TRUE, NULL);
- }
-
- return (Status);
-}
-
-
-/*
-
-//
-// Connection Control Event Callbacks
-//
-
-TDI_EVENT_CONNECT
-TDI_EVENT_DISCONNECT
-TDI_EVENT_ERROR
-
-//
-// Tcp Event Callbacks
-//
-
-TDI_EVENT_RECEIVE
-TDI_EVENT_RECEIVE_EXPEDITED
-TDI_EVENT_CHAINED_RECEIVE
-TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
-
-//
-// Udp Event Callbacks
-//
-
-TDI_EVENT_RECEIVE_DATAGRAM
-TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
-
-*/
-
-
-/*
- * KsSetEventHandlers
- * Set the tdi event callbacks with an address object
- *
- * Arguments:
- * AddressObject: the FileObject of the address object
- * EventContext: the parameter for the callbacks
- * Handlers: the handlers indictor array
- *
- * Return Value:
- * NTSTATUS: kernel status code (STATUS_SUCCESS
- * or other error code)
- *
- * NOTES:
- * N/A
- */
-
-NTSTATUS
-KsSetEventHandlers(
- IN PFILE_OBJECT AddressObject, // Address File Object
- IN PVOID EventContext, // Context for Handlers
- IN PKS_EVENT_HANDLERS Handlers // Handlers Indictor
- )
-{
- NTSTATUS Status = STATUS_SUCCESS;
- PDEVICE_OBJECT DeviceObject;
- USHORT i = 0;
-
- DeviceObject = IoGetRelatedDeviceObject(AddressObject);
-
- for (i=0; i < TDI_EVENT_MAXIMUM_HANDLER; i++) {
-
- //
- // Setup the tdi event callback handler if requested.
- //
-
- if (Handlers->IsActive[i]) {
-
- PIRP Irp;
-
- //
- // Building Tdi Internal Irp ...
- //
-
- Irp = KsBuildTdiIrp(DeviceObject);
-
- if (NULL == Irp) {
-
- Status = STATUS_INSUFFICIENT_RESOURCES;
-
- } else {
-
- //
- // Building the Irp to set the Event Handler ...
- //
-
- TdiBuildSetEventHandler(
- Irp,
- DeviceObject,
- AddressObject,
- NULL,
- NULL,
- i, /* tdi event type */
- Handlers->Handler[i], /* tdi event handler */
- EventContext /* context for the handler */
- );
-
- //
- // Calling the Transprot Driver with the Prepared Irp
- //
-
- Status = KsSubmitTdiIrp(DeviceObject, Irp, TRUE, NULL);
-
- //
- // tcp/ip tdi does not support these two event callbacks
- //
-
- if ((!NT_SUCCESS(Status)) && ( i == TDI_EVENT_SEND_POSSIBLE ||
- i == TDI_EVENT_CHAINED_RECEIVE_EXPEDITED )) {
- cfs_enter_debugger();
- Status = STATUS_SUCCESS;
- }
- }
-
- if (!NT_SUCCESS(Status)) {
- cfs_enter_debugger();
- goto errorout;
- }
- }
- }
-
-
-errorout:
-
- if (!NT_SUCCESS(Status)) {
-
- KsPrint((1, "KsSetEventHandlers: Error Status = %xh (%s)\n",
- Status, KsNtStatusToString(Status) ));
- }
-
- return (Status);
-}
-
-
-
-/*
- * KsQueryAddressInfo
- * Query the address of the FileObject specified
- *
- * Arguments:
- * FileObject: the FileObject to be queried
- * AddressInfo: buffer to contain the address info
- * AddressSize: length of the AddressInfo buffer
- *
- * Return Value:
- * NTSTATUS: kernel status code (STATUS_SUCCESS
- * or other error code)
- *
- * Notes:
- * N/A
- */
-
-NTSTATUS
-KsQueryAddressInfo(
- PFILE_OBJECT FileObject,
- PTDI_ADDRESS_INFO AddressInfo,
- PULONG AddressSize
- )
-{
- NTSTATUS Status = STATUS_UNSUCCESSFUL;
- PIRP Irp = NULL;
- PMDL Mdl;
- PDEVICE_OBJECT DeviceObject;
-
- LASSERT( KeGetCurrentIrql() < DISPATCH_LEVEL );
-
- DeviceObject = IoGetRelatedDeviceObject(FileObject);
-
- RtlZeroMemory(AddressInfo, *(AddressSize));
-
- //
- // Allocating the Tdi Setting Irp ...
- //
-
- Irp = KsBuildTdiIrp(DeviceObject);
-
- if (NULL == Irp) {
-
- Status = STATUS_INSUFFICIENT_RESOURCES;
-
- } else {
-
- //
- // Locking the User Buffer / Allocating a MDL for it
- //
-
- Status = KsLockUserBuffer(
- AddressInfo,
- FALSE,
- *(AddressSize),
- IoModifyAccess,
- &Mdl
- );
-
- if (!NT_SUCCESS(Status)) {
-
- IoFreeIrp(Irp);
- Irp = NULL;
- }
- }
-
- if (Irp) {
-
- LASSERT(NT_SUCCESS(Status));
-
- TdiBuildQueryInformation(
- Irp,
- DeviceObject,
- FileObject,
- NULL,
- NULL,
- TDI_QUERY_ADDRESS_INFO,
- Mdl
- );
-
- Status = KsSubmitTdiIrp(
- DeviceObject,
- Irp,
- TRUE,
- AddressSize
- );
-
- KsReleaseMdl(Mdl, FALSE);
- }
-
- if (!NT_SUCCESS(Status)) {
-
- cfs_enter_debugger();
- //TDI_BUFFER_OVERFLOW
- }
-
- return (Status);
-}
-
-/*
- * KsQueryProviderInfo
- * Query the underlying transport device's information
- *
- * Arguments:
- * TdiDeviceName: the transport device's name string
- * ProviderInfo: TDI_PROVIDER_INFO struncture
- *
- * Return Value:
- * NTSTATUS: Nt system status code
- *
- * NOTES:
- * N/A
- */
-
-NTSTATUS
-KsQueryProviderInfo(
- PWSTR TdiDeviceName,
- PTDI_PROVIDER_INFO ProviderInfo
- )
-{
- NTSTATUS Status = STATUS_SUCCESS;
-
- PIRP Irp = NULL;
- PMDL Mdl = NULL;
-
- UNICODE_STRING ControlName;
-
- HANDLE Handle;
- PFILE_OBJECT FileObject;
- PDEVICE_OBJECT DeviceObject;
-
- ULONG ProviderSize = 0;
-
- RtlInitUnicodeString(&ControlName, TdiDeviceName);
-
- //
- // Open the Tdi Control Channel
- //
-
- Status = KsOpenControl(
- &ControlName,
- &Handle,
- &FileObject
- );
-
- if (!NT_SUCCESS(Status)) {
-
- KsPrint((1, "KsQueryProviderInfo: Fail to open the tdi control channel.\n"));
- return (Status);
- }
-
- //
- // Obtain The Related Device Object
- //
-
- DeviceObject = IoGetRelatedDeviceObject(FileObject);
-
- ProviderSize = sizeof(TDI_PROVIDER_INFO);
- RtlZeroMemory(ProviderInfo, ProviderSize);
-
- //
- // Allocating the Tdi Setting Irp ...
- //
-
- Irp = KsBuildTdiIrp(DeviceObject);
-
- if (NULL == Irp) {
-
- Status = STATUS_INSUFFICIENT_RESOURCES;
-
- } else {
-
- //
- // Locking the User Buffer / Allocating a MDL for it
- //
-
- Status = KsLockUserBuffer(
- ProviderInfo,
- FALSE,
- ProviderSize,
- IoModifyAccess,
- &Mdl
- );
-
- if (!NT_SUCCESS(Status)) {
-
- IoFreeIrp(Irp);
- Irp = NULL;
- }
- }
-
- if (Irp) {
-
- LASSERT(NT_SUCCESS(Status));
-
- TdiBuildQueryInformation(
- Irp,
- DeviceObject,
- FileObject,
- NULL,
- NULL,
- TDI_QUERY_PROVIDER_INFO,
- Mdl
- );
-
- Status = KsSubmitTdiIrp(
- DeviceObject,
- Irp,
- TRUE,
- &ProviderSize
- );
-
- KsReleaseMdl(Mdl, FALSE);
- }
-
- if (!NT_SUCCESS(Status)) {
-
- cfs_enter_debugger();
- //TDI_BUFFER_OVERFLOW
- }
-
- KsCloseControl(Handle, FileObject);
-
- return (Status);
-}
-
-/*
- * KsQueryConnectionInfo
- * Query the connection info of the FileObject specified
- * (some statics data of the traffic)
- *
- * Arguments:
- * FileObject: the FileObject to be queried
- * ConnectionInfo: buffer to contain the connection info
- * ConnectionSize: length of the ConnectionInfo buffer
- *
- * Return Value:
- * NTSTATUS: kernel status code (STATUS_SUCCESS
- * or other error code)
- *
- * NOTES:
- * N/A
- */
-
-NTSTATUS
-KsQueryConnectionInfo(
- PFILE_OBJECT ConnectionObject,
- PTDI_CONNECTION_INFO ConnectionInfo,
- PULONG ConnectionSize
- )
-{
- NTSTATUS Status = STATUS_UNSUCCESSFUL;
- PIRP Irp = NULL;
- PMDL Mdl;
- PDEVICE_OBJECT DeviceObject;
-
- LASSERT( KeGetCurrentIrql() < DISPATCH_LEVEL );
-
- DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
-
- RtlZeroMemory(ConnectionInfo, *(ConnectionSize));
-
- //
- // Allocating the Tdi Query Irp ...
- //
-
- Irp = KsBuildTdiIrp(DeviceObject);
-
- if (NULL == Irp) {
-
- Status = STATUS_INSUFFICIENT_RESOURCES;
-
- } else {
-
- //
- // Locking the User Buffer / Allocating a MDL for it
- //
-
- Status = KsLockUserBuffer(
- ConnectionInfo,
- FALSE,
- *(ConnectionSize),
- IoModifyAccess,
- &Mdl
- );
-
- if (NT_SUCCESS(Status)) {
-
- IoFreeIrp(Irp);
- Irp = NULL;
- }
- }
-
- if (Irp) {
-
- LASSERT(NT_SUCCESS(Status));
-
- TdiBuildQueryInformation(
- Irp,
- DeviceObject,
- ConnectionObject,
- NULL,
- NULL,
- TDI_QUERY_CONNECTION_INFO,
- Mdl
- );
-
- Status = KsSubmitTdiIrp(
- DeviceObject,
- Irp,
- TRUE,
- ConnectionSize
- );
-
- KsReleaseMdl(Mdl, FALSE);
- }
-
- return (Status);
-}
-
-
-/*
- * KsInitializeTdiAddress
- * Initialize the tdi addresss
- *
- * Arguments:
- * pTransportAddress: tdi address to be initialized
- * IpAddress: the ip address of object
- * IpPort: the ip port of the object
- *
- * Return Value:
- * ULONG: the total size of the tdi address
- *
- * NOTES:
- * N/A
- */
-
-ULONG
-KsInitializeTdiAddress(
- IN OUT PTA_IP_ADDRESS pTransportAddress,
- IN ULONG IpAddress,
- IN USHORT IpPort
- )
-{
- pTransportAddress->TAAddressCount = 1;
- pTransportAddress->Address[ 0 ].AddressLength = TDI_ADDRESS_LENGTH_IP;
- pTransportAddress->Address[ 0 ].AddressType = TDI_ADDRESS_TYPE_IP;
- pTransportAddress->Address[ 0 ].Address[ 0 ].sin_port = IpPort;
- pTransportAddress->Address[ 0 ].Address[ 0 ].in_addr = IpAddress;
-
- return (FIELD_OFFSET(TRANSPORT_ADDRESS, Address->Address) + TDI_ADDRESS_LENGTH_IP);
-}
-
-/*
- * KsQueryTdiAddressLength
- * Query the total size of the tdi address
- *
- * Arguments:
- * pTransportAddress: tdi address to be queried
- *
- * Return Value:
- * ULONG: the total size of the tdi address
- *
- * NOTES:
- * N/A
- */
-
-ULONG
-KsQueryTdiAddressLength(
- PTRANSPORT_ADDRESS pTransportAddress
- )
-{
- ULONG TotalLength = 0;
- LONG i;
-
- PTA_ADDRESS pTaAddress = NULL;
-
- ASSERT (NULL != pTransportAddress);
-
- TotalLength = FIELD_OFFSET(TRANSPORT_ADDRESS, Address) +
- FIELD_OFFSET(TA_ADDRESS, Address) * pTransportAddress->TAAddressCount;
-
- pTaAddress = (PTA_ADDRESS)pTransportAddress->Address;
-
- for (i = 0; i < pTransportAddress->TAAddressCount; i++)
- {
- TotalLength += pTaAddress->AddressLength;
- pTaAddress = (PTA_ADDRESS)((PCHAR)pTaAddress +
- FIELD_OFFSET(TA_ADDRESS,Address) +
- pTaAddress->AddressLength );
- }
-
- return (TotalLength);
-}
-
-
-/*
- * KsQueryIpAddress
- * Query the ip address of the tdi object
- *
- * Arguments:
- * FileObject: tdi object to be queried
- * TdiAddress: TdiAddress buffer, to store the queried
- * tdi ip address
- * AddressLength: buffer length of the TdiAddress
- *
- * Return Value:
- * ULONG: the total size of the tdi ip address
- *
- * NOTES:
- * N/A
- */
-
-NTSTATUS
-KsQueryIpAddress(
- PFILE_OBJECT FileObject,
- PVOID TdiAddress,
- ULONG* AddressLength
- )
-{
- NTSTATUS Status;
-
- PTDI_ADDRESS_INFO TdiAddressInfo;
- ULONG Length;
-
-
- //
- // Maximum length of TDI_ADDRESSS_INFO with one TRANSPORT_ADDRESS
- //
-
- Length = MAX_ADDRESS_LENGTH;
-
- TdiAddressInfo = (PTDI_ADDRESS_INFO)
- ExAllocatePoolWithTag(
- NonPagedPool,
- Length,
- 'KSAI' );
-
- if (NULL == TdiAddressInfo) {
-
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto errorout;
- }
-
-
- Status = KsQueryAddressInfo(
- FileObject,
- TdiAddressInfo,
- &Length
- );
-
-errorout:
-
- if (NT_SUCCESS(Status)) {
-
- if (*AddressLength < Length) {
- Status = STATUS_BUFFER_TOO_SMALL;
- } else {
- *AddressLength = Length;
- RtlCopyMemory(
- TdiAddress,
- &(TdiAddressInfo->Address),
- Length
- );
- Status = STATUS_SUCCESS;
- }
- }
-
- if (NULL != TdiAddressInfo) {
- ExFreePool(TdiAddressInfo);
- }
-
- return Status;
-}
-
-
-/*
- * KsErrorEventHandler
- * the common error event handler callback
- *
- * Arguments:
- * TdiEventContext: should be the socket
- * Status: the error code
- *
- * Return Value:
- * Status: STATS_SUCCESS
- *
- * NOTES:
- * We need not do anything in such a severe
- * error case. System will process it for us.
- */
-
-NTSTATUS
-KsErrorEventHandler(
- IN PVOID TdiEventContext,
- IN NTSTATUS Status
- )
-{
- KsPrint((1, "KsErrorEventHandler called at Irql = %xh ...\n",
- KeGetCurrentIrql()));
-
- cfs_enter_debugger();
-
- return (STATUS_SUCCESS);
-}
-
-/*
- * KsAcceptCompletionRoutine
- * Irp completion routine for TdiBuildAccept (KsConnectEventHandler)
- *
- * Here system gives us a chance to check the conneciton is built
- * ready or not.
- *
- * Arguments:
- * DeviceObject: the device object of the transport driver
- * Irp: the Irp is being completed.
- * Context: the context we specified when issuing the Irp
- *
- * Return Value:
- * Nt status code
- *
- * Notes:
- * N/A
- */
-
-NTSTATUS
-KsAcceptCompletionRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- )
-{
- ks_tconn_t * child = (ks_tconn_t *) Context;
- ks_tconn_t * parent = child->child.kstc_parent;
-
- KsPrint((2, "KsAcceptCompletionRoutine at Irql: %xh child: %p status: %p\n",
- KeGetCurrentIrql(), child, Irp->IoStatus.Status));
-
- LASSERT(child->kstc_type == kstt_child);
-
- spin_lock(&(child->kstc_lock));
-
- LASSERT(parent->kstc_state == ksts_listening);
- LASSERT(child->kstc_state == ksts_connecting);
-
- if (NT_SUCCESS(Irp->IoStatus.Status)) {
-
- child->child.kstc_accepted = TRUE;
-
- child->kstc_state = ksts_connected;
-
- /* wake up the daemon thread which waits on this event */
- KeSetEvent(
- &(parent->listener.kstc_accept_event),
- 0,
- FALSE
- );
-
- spin_unlock(&(child->kstc_lock));
-
- KsPrint((2, "KsAcceptCompletionRoutine: singal parent: %p (child: %p)\n",
- parent, child));
-
- } else {
-
- /* re-use this child connecton */
- child->child.kstc_accepted = FALSE;
- child->child.kstc_busy = FALSE;
- child->kstc_state = ksts_associated;
-
- spin_unlock(&(child->kstc_lock));
- }
-
- /* now free the Irp */
- IoFreeIrp(Irp);
-
- /* drop the refer count of the child */
- ks_put_tconn(child);
-
- return (STATUS_MORE_PROCESSING_REQUIRED);
-}
-
-ks_addr_slot_t *
-KsSearchIpAddress(PUNICODE_STRING DeviceName)
-{
- ks_addr_slot_t * slot = NULL;
- PLIST_ENTRY list = NULL;
-
- spin_lock(&ks_data.ksnd_addrs_lock);
-
- list = ks_data.ksnd_addrs_list.Flink;
- while (list != &ks_data.ksnd_addrs_list) {
- slot = CONTAINING_RECORD(list, ks_addr_slot_t, link);
- if (RtlCompareUnicodeString(
- DeviceName,
- &slot->devname,
- TRUE) == 0) {
- break;
- }
- list = list->Flink;
- slot = NULL;
- }
-
- spin_unlock(&ks_data.ksnd_addrs_lock);
-
- return slot;
-}
-
-void
-KsCleanupIpAddresses()
-{
- spin_lock(&ks_data.ksnd_addrs_lock);
-
- while (!IsListEmpty(&ks_data.ksnd_addrs_list)) {
-
- ks_addr_slot_t * slot = NULL;
- PLIST_ENTRY list = NULL;
-
- list = RemoveHeadList(&ks_data.ksnd_addrs_list);
- slot = CONTAINING_RECORD(list, ks_addr_slot_t, link);
- kfree(slot);
- ks_data.ksnd_naddrs--;
- }
-
- cfs_assert(ks_data.ksnd_naddrs == 0);
- spin_unlock(&ks_data.ksnd_addrs_lock);
-}
-
-VOID
-KsAddAddressHandler(
- IN PTA_ADDRESS Address,
- IN PUNICODE_STRING DeviceName,
- IN PTDI_PNP_CONTEXT Context
- )
-{
- PTDI_ADDRESS_IP IpAddress = NULL;
-
- if ( Address->AddressType == TDI_ADDRESS_TYPE_IP &&
- Address->AddressLength == TDI_ADDRESS_LENGTH_IP ) {
-
- ks_addr_slot_t * slot = NULL;
-
- IpAddress = (PTDI_ADDRESS_IP) &Address->Address[0];
- KsPrint((2, "KsAddAddressHandle: Device=%wZ Context=%xh "
- "IpAddress=%xh(%d.%d.%d.%d)\n",
- DeviceName, Context, IpAddress->in_addr,
- (IpAddress->in_addr & 0x000000FF) >> 0,
- (IpAddress->in_addr & 0x0000FF00) >> 8,
- (IpAddress->in_addr & 0x00FF0000) >> 16,
- (IpAddress->in_addr & 0xFF000000) >> 24
- ));
-
- slot = KsSearchIpAddress(DeviceName);
-
- if (slot != NULL) {
- slot->up = TRUE;
- slot->ip_addr = ntohl(IpAddress->in_addr);
- } else {
-
- /* Matt: only add 192.168.10/5/92.xxx for temporary test */
- if ((IpAddress->in_addr & 0x00FFFFFF) != 0x000aa8c0 &&
- (IpAddress->in_addr & 0x00FFFFFF) != 0x0092a8c0 &&
- (IpAddress->in_addr & 0x00FFFFFF) != 0x0005a8c0 ) {
- return;
- }
-
- slot = kmalloc(sizeof(ks_addr_slot_t) + DeviceName->Length, __GFP_ZERO);
- if (slot != NULL) {
- spin_lock(&ks_data.ksnd_addrs_lock);
- InsertTailList(&ks_data.ksnd_addrs_list, &slot->link);
- sprintf(slot->iface, "eth%d", ks_data.ksnd_naddrs++);
- slot->ip_addr = ntohl(IpAddress->in_addr);
- slot->netmask = 0x00FFFFFF; /* Matt: hardcode*/
- slot->up = TRUE;
- RtlMoveMemory(&slot->buffer[0], DeviceName->Buffer, DeviceName->Length);
- slot->devname.Length = DeviceName->Length;
- slot->devname.MaximumLength = DeviceName->Length + sizeof(WCHAR);
- slot->devname.Buffer = slot->buffer;
- spin_unlock(&ks_data.ksnd_addrs_lock);
-
- KsPrint((0, "KsAddAddressHandle: %s added: ip=%xh(%d.%d.%d.%d)\n",
- slot->iface, IpAddress->in_addr,
- (IpAddress->in_addr & 0x000000FF) >> 0,
- (IpAddress->in_addr & 0x0000FF00) >> 8,
- (IpAddress->in_addr & 0x00FF0000) >> 16,
- (IpAddress->in_addr & 0xFF000000) >> 24
- ));
- }
- }
- }
-}
-
-VOID
-KsDelAddressHandler(
- IN PTA_ADDRESS Address,
- IN PUNICODE_STRING DeviceName,
- IN PTDI_PNP_CONTEXT Context
- )
-{
- PTDI_ADDRESS_IP IpAddress = NULL;
-
- if ( Address->AddressType == TDI_ADDRESS_TYPE_IP &&
- Address->AddressLength == TDI_ADDRESS_LENGTH_IP ) {
-
- ks_addr_slot_t * slot = NULL;
-
- slot = KsSearchIpAddress(DeviceName);
-
- if (slot != NULL) {
- slot->up = FALSE;
- }
-
- IpAddress = (PTDI_ADDRESS_IP) &Address->Address[0];
- KsPrint((2, "KsDelAddressHandle: Device=%wZ Context=%xh IpAddress=%xh(%d.%d.%d.%d)\n",
- DeviceName, Context, IpAddress->in_addr,
- (IpAddress->in_addr & 0xFF000000) >> 24,
- (IpAddress->in_addr & 0x00FF0000) >> 16,
- (IpAddress->in_addr & 0x0000FF00) >> 8,
- (IpAddress->in_addr & 0x000000FF) >> 0 ));
- }
-}
-
-NTSTATUS
-KsRegisterPnpHandlers()
-{
- TDI20_CLIENT_INTERFACE_INFO ClientInfo;
-
- /* initialize the global ks_data members */
- RtlInitUnicodeString(&ks_data.ksnd_client_name, TDILND_MODULE_NAME);
- spin_lock_init(&ks_data.ksnd_addrs_lock);
- InitializeListHead(&ks_data.ksnd_addrs_list);
-
- /* register the pnp handlers */
- RtlZeroMemory(&ClientInfo, sizeof(ClientInfo));
- ClientInfo.TdiVersion = TDI_CURRENT_VERSION;
-
- ClientInfo.ClientName = &ks_data.ksnd_client_name;
- ClientInfo.AddAddressHandlerV2 = KsAddAddressHandler;
- ClientInfo.DelAddressHandlerV2 = KsDelAddressHandler;
-
- return TdiRegisterPnPHandlers(&ClientInfo, sizeof(ClientInfo),
- &ks_data.ksnd_pnp_handle);
-}
-
-VOID
-KsDeregisterPnpHandlers()
-{
- if (ks_data.ksnd_pnp_handle) {
-
- /* De-register the pnp handlers */
-
- TdiDeregisterPnPHandlers(ks_data.ksnd_pnp_handle);
- ks_data.ksnd_pnp_handle = NULL;
-
- /* cleanup all the ip address slots */
- KsCleanupIpAddresses();
- }
-}
-
-
-/*
- * KsGetVacancyBacklog
- * Get a vacancy listeing child from the backlog list
- *
- * Arguments:
- * parent: the listener daemon connection
- *
- * Return Value:
- * the child listening connection or NULL in failure
- *
- * Notes
- * Parent's lock should be acquired before calling.
- */
-
-ks_tconn_t *
-KsGetVacancyBacklog(
- ks_tconn_t * parent
- )
-{
- ks_tconn_t * child;
-
- LASSERT(parent->kstc_type == kstt_listener);
- LASSERT(parent->kstc_state == ksts_listening);
-
- if (list_empty(&(parent->listener.kstc_listening.list))) {
-
- child = NULL;
-
- } else {
-
- struct list_head * tmp;
-
- /* check the listening queue and try to get a free connecton */
-
- list_for_each(tmp, &(parent->listener.kstc_listening.list)) {
- child = list_entry (tmp, ks_tconn_t, child.kstc_link);
- spin_lock(&(child->kstc_lock));
-
- if (!child->child.kstc_busy) {
- LASSERT(child->kstc_state == ksts_associated);
- child->child.kstc_busy = TRUE;
- spin_unlock(&(child->kstc_lock));
- break;
- } else {
- spin_unlock(&(child->kstc_lock));
- child = NULL;
- }
- }
- }
-
- return child;
-}
-
-/*
- * KsConnectEventHandler
- * Connect event handler event handler, called by the underlying TDI
- * transport in response to an incoming request to the listening daemon.
- *
- * it will grab a vacancy backlog from the children tconn list, and
- * build an acception Irp with it, then transfer the Irp to TDI driver.
- *
- * Arguments:
- * TdiEventContext: the tdi connnection object of the listening daemon
- * ......
- *
- * Return Value:
- * Nt kernel status code
- *
- * Notes:
- * N/A
- */
-
-NTSTATUS
-KsConnectEventHandler(
- IN PVOID TdiEventContext,
- IN LONG RemoteAddressLength,
- IN PVOID RemoteAddress,
- IN LONG UserDataLength,
- IN PVOID UserData,
- IN LONG OptionsLength,
- IN PVOID Options,
- OUT CONNECTION_CONTEXT * ConnectionContext,
- OUT PIRP * AcceptIrp
- )
-{
- ks_tconn_t * parent;
- ks_tconn_t * child;
-
- PFILE_OBJECT FileObject;
- PDEVICE_OBJECT DeviceObject;
- NTSTATUS Status;
-
- PIRP Irp = NULL;
- PTDI_CONNECTION_INFORMATION ConnectionInfo = NULL;
-
- KsPrint((2,"KsConnectEventHandler: call at Irql: %u\n", KeGetCurrentIrql()));
- parent = (ks_tconn_t *) TdiEventContext;
-
- LASSERT(parent->kstc_type == kstt_listener);
-
- spin_lock(&(parent->kstc_lock));
-
- if (parent->kstc_state == ksts_listening) {
-
- /* allocate a new ConnectionInfo to backup the peer's info */
-
- ConnectionInfo = (PTDI_CONNECTION_INFORMATION)ExAllocatePoolWithTag(
- NonPagedPool, sizeof(TDI_CONNECTION_INFORMATION) +
- RemoteAddressLength, 'iCsK' );
-
- if (NULL == ConnectionInfo) {
-
- Status = STATUS_INSUFFICIENT_RESOURCES;
- cfs_enter_debugger();
- goto errorout;
- }
-
- /* initializing ConnectionInfo structure ... */
-
- ConnectionInfo->UserDataLength = UserDataLength;
- ConnectionInfo->UserData = UserData;
- ConnectionInfo->OptionsLength = OptionsLength;
- ConnectionInfo->Options = Options;
- ConnectionInfo->RemoteAddressLength = RemoteAddressLength;
- ConnectionInfo->RemoteAddress = ConnectionInfo + 1;
-
- RtlCopyMemory(
- ConnectionInfo->RemoteAddress,
- RemoteAddress,
- RemoteAddressLength
- );
-
- /* get the vacancy listening child tdi connections */
-
- child = KsGetVacancyBacklog(parent);
-
- if (child) {
-
- spin_lock(&(child->kstc_lock));
- child->child.kstc_info.ConnectionInfo = ConnectionInfo;
- child->child.kstc_info.Remote = ConnectionInfo->RemoteAddress;
- child->kstc_state = ksts_connecting;
- spin_unlock(&(child->kstc_lock));
-
- } else {
-
- KsPrint((1, "KsConnectEventHandler: No enough backlogs: Refsued the connectio: %xh\n", parent));
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto errorout;
- }
-
- FileObject = child->child.kstc_info.FileObject;
- DeviceObject = IoGetRelatedDeviceObject (FileObject);
-
- Irp = KsBuildTdiIrp(DeviceObject);
-
- TdiBuildAccept(
- Irp,
- DeviceObject,
- FileObject,
- KsAcceptCompletionRoutine,
- child,
- NULL,
- NULL
- );
-
- IoSetNextIrpStackLocation(Irp);
-
- /* grap the refer of the child tdi connection */
- ks_get_tconn(child);
-
- Status = STATUS_MORE_PROCESSING_REQUIRED;
- *AcceptIrp = Irp;
- *ConnectionContext = child;
-
- } else {
-
- Status = STATUS_CONNECTION_REFUSED;
- goto errorout;
- }
-
- spin_unlock(&(parent->kstc_lock));
-
- return Status;
-
-errorout:
-
- spin_unlock(&(parent->kstc_lock));
-
- *AcceptIrp = NULL;
- *ConnectionContext = NULL;
-
- if (ConnectionInfo) {
- ExFreePool(ConnectionInfo);
- }
-
- if (Irp) {
- IoFreeIrp (Irp);
- }
-
- return Status;
-}
-
-/*
- * KsDisconnectCompletionRoutine
- * the Irp completion routine for TdiBuildDisconect
- *
- * We just signal the event and return MORE_PRO... to
- * let the caller take the responsibility of the Irp.
- *
- * Arguments:
- * DeviceObject: the device object of the transport
- * Irp: the Irp is being completed.
- * Context: the event specified by the caller
- *
- * Return Value:
- * Nt status code
- *
- * Notes:
- * N/A
- */
-
-NTSTATUS
-KsDisconectCompletionRoutine (
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- )
-{
-
- KeSetEvent((PKEVENT) Context, 0, FALSE);
-
- return STATUS_MORE_PROCESSING_REQUIRED;
-
- UNREFERENCED_PARAMETER(DeviceObject);
-}
-
-
-/*
- * KsDisconnectHelper
- * the routine to be executed in the WorkItem procedure
- * this routine is to disconnect a tdi connection
- *
- * Arguments:
- * Workitem: the context transferred to the workitem
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * tconn is already referred in abort_connecton ...
- */
-
-VOID
-KsDisconnectHelper(PKS_DISCONNECT_WORKITEM WorkItem)
-{
- ks_tconn_t * tconn = WorkItem->tconn;
-
- KsPrint((1, "KsDisconnectHelper: disconnecting tconn=%p\n", tconn));
- ks_disconnect_tconn(tconn, WorkItem->Flags);
-
- KeSetEvent(&(WorkItem->Event), 0, FALSE);
-
- spin_lock(&(tconn->kstc_lock));
- cfs_clear_flag(tconn->kstc_flags, KS_TCONN_DISCONNECT_BUSY);
- spin_unlock(&(tconn->kstc_lock));
- ks_put_tconn(tconn);
-}
-
-
-/*
- * KsDisconnectEventHandler
- * Disconnect event handler event handler, called by the underlying TDI transport
- * in response to an incoming disconnection notification from a remote node.
- *
- * Arguments:
- * ConnectionContext: tdi connnection object
- * DisconnectFlags: specifies the nature of the disconnection
- * ......
- *
- * Return Value:
- * Nt kernel status code
- *
- * Notes:
- * N/A
- */
-
-
-NTSTATUS
-KsDisconnectEventHandler(
- IN PVOID TdiEventContext,
- IN CONNECTION_CONTEXT ConnectionContext,
- IN LONG DisconnectDataLength,
- IN PVOID DisconnectData,
- IN LONG DisconnectInformationLength,
- IN PVOID DisconnectInformation,
- IN ULONG DisconnectFlags
- )
-{
- ks_tconn_t * tconn;
- NTSTATUS Status;
- PKS_DISCONNECT_WORKITEM WorkItem;
-
- tconn = (ks_tconn_t *)ConnectionContext;
-
- KsPrint((2, "KsTcpDisconnectEventHandler: called at Irql: %xh\n",
- KeGetCurrentIrql() ));
-
- KsPrint((2, "tconn = %x DisconnectFlags= %xh\n",
- tconn, DisconnectFlags));
-
- ks_get_tconn(tconn);
- spin_lock(&(tconn->kstc_lock));
-
- WorkItem = &(tconn->kstc_disconnect);
-
- if (tconn->kstc_state != ksts_connected) {
-
- Status = STATUS_SUCCESS;
-
- } else {
-
- if (cfs_is_flag_set(DisconnectFlags, TDI_DISCONNECT_ABORT)) {
-
- Status = STATUS_REMOTE_DISCONNECT;
-
- } else if (cfs_is_flag_set(DisconnectFlags, TDI_DISCONNECT_RELEASE)) {
-
- Status = STATUS_GRACEFUL_DISCONNECT;
- }
-
- if (!cfs_is_flag_set(tconn->kstc_flags, KS_TCONN_DISCONNECT_BUSY)) {
-
- ks_get_tconn(tconn);
-
- WorkItem->Flags = DisconnectFlags;
- WorkItem->tconn = tconn;
-
- cfs_set_flag(tconn->kstc_flags, KS_TCONN_DISCONNECT_BUSY);
-
- /* queue the workitem to call */
- ExQueueWorkItem(&(WorkItem->WorkItem), DelayedWorkQueue);
- }
- }
-
- spin_unlock(&(tconn->kstc_lock));
- ks_put_tconn(tconn);
-
- return (Status);
-}
-
-NTSTATUS
-KsTcpReceiveCompletionRoutine(
- IN PIRP Irp,
- IN PKS_TCP_COMPLETION_CONTEXT Context
- )
-{
- ks_tconn_t *tconn = Context->tconn;
- NTSTATUS status = Irp->IoStatus.Status;
- ULONG length = (ULONG)Irp->IoStatus.Information;
-
- LASSERT(Context != NULL);
-
- if (NT_SUCCESS(status)) {
-
- PKS_TSDUMGR TsduMgr = Context->TsduMgr;
- PCHAR Buffer = Context->Buffer;
-
- KsPrint((4, "KsTcpReceiveCompletionRoutine: Total %xh bytes.\n",
- TsduMgr->TotalBytes ));
-
- ks_lock_tsdumgr(TsduMgr);
- KsWriteTsduBuf(TsduMgr, Context->Buffer, length, 0);
- /* signal TsduMgr event */
- KeSetEvent(&(Context->TsduMgr->Event), 0, FALSE);
- ks_unlock_tsdumgr(TsduMgr);
-
- /* re-active the ks connection and wake up the scheduler */
- if (KS_CAN_SCHED(TsduMgr)) {
- if (tconn->kstc_conn && tconn->kstc_sched_cb) {
- tconn->kstc_sched_cb(tconn, FALSE);
- }
- }
-
- ks_put_tconn(tconn);
-
- } else {
-
- /* un-expected errors occur, we must abort the connection */
- ks_put_tconn(tconn);
- ks_abort_tconn(tconn);
- }
-
-
- if (Context) {
-
- /* free the Context structure... */
- ASSERT(Context->Magic == KS_TCP_CONTEXT_MAGIC);
- Context->Magic = 'CDAB';
- kfree(Context);
- }
-
- /* free the Irp */
- if (Irp) {
-
- /* release mdl chain */
- if (Irp->MdlAddress) {
- KsReleaseMdl(Irp->MdlAddress, FALSE);
- }
-
- /* free irp packet */
- IoFreeIrp(Irp);
- }
-
- return (status);
-}
-
-
-/*
- * KsTcpCompletionRoutine
- * the Irp completion routine for TdiBuildSend and TdiBuildReceive ...
- * We need call the use's own CompletionRoutine if specified. Or
- * it's a synchronous case, we need signal the event.
- *
- * Arguments:
- * DeviceObject: the device object of the transport
- * Irp: the Irp is being completed.
- * Context: the context we specified when issuing the Irp
- *
- * Return Value:
- * Nt status code
- *
- * Notes:
- * N/A
- */
-
-NTSTATUS
-KsTcpCompletionRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- )
-{
- if (Context) {
-
- PKS_TCP_COMPLETION_CONTEXT context = NULL;
- ks_tconn_t * tconn = NULL;
-
- context = (PKS_TCP_COMPLETION_CONTEXT) Context;
- ASSERT(context->Magic == KS_TCP_CONTEXT_MAGIC);
- tconn = context->tconn;
-
- if (context->CompletionRoutine) {
-
- //
- // Giving control to user specified CompletionRoutine ...
- //
-
- context->CompletionRoutine(Irp, context);
-
- } else {
-
- //
- // Signaling the Event ...
- //
- LASSERT(NULL != context->Event);
- KeSetEvent(context->Event, 0, FALSE);
-
- /* drop the reference count of the tconn object */
- ks_put_tconn(tconn);
- }
-
- } else {
-
- /* cfs_enter_debugger(); */
- }
-
- return STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-/*
- * KsTcpSendCompletionRoutine
- * the user specified Irp completion routine for asynchronous
- * data transmission requests.
- *
- * It will do th cleanup job of the ks_tx_t and wake up the
- * ks scheduler thread
- *
- * Arguments:
- * Irp: the Irp is being completed.
- * Context: the context we specified when issuing the Irp
- *
- * Return Value:
- * Nt status code
- *
- * Notes:
- * N/A
- */
-
-NTSTATUS
-KsTcpSendCompletionRoutine(
- IN PIRP Irp,
- IN PKS_TCP_COMPLETION_CONTEXT context
- )
-{
- NTSTATUS status = Irp->IoStatus.Status;
- ULONG rc = (ULONG)(ULONG_PTR)Irp->IoStatus.Information;
- ks_tconn_t * tconn = context->tconn;
-
- PKS_TSDUMGR TsduMgr = context->TsduMgr;
- PKEVENT Event = context->Event;
-
- LASSERT(tconn != NULL && tconn->kstc_magic == KS_TCONN_MAGIC);
- LASSERT(context && context->Magic == KS_TCP_CONTEXT_MAGIC);
-
- KsPrint((4, "KsTcpSendCompltionRoutine: tconn = %p TsduMgr = %p "
- "status = %xh bytes = %xh/%x\n", tconn, TsduMgr, status,
- Irp->IoStatus.Information, TsduMgr->TotalBytes));
-
- ks_lock_tsdumgr(TsduMgr);
-
- if (NT_SUCCESS(status)) {
-
- /* cleanup processed TsduMgr queue */
- KsReleaseTsdus(tconn, TsduMgr, rc);
-
- /* queue to delivery engine if there's still remained data */
- TsduMgr->Busy = FALSE;
- if (TsduMgr->TotalBytes > 0) {
- KsQueueTdiEngine(tconn, TsduMgr);
- }
- /* signal TsduMgr event */
- KeSetEvent(&(TsduMgr->Event), 0, FALSE);
- ks_unlock_tsdumgr(TsduMgr);
-
- /*
- * now it's time to re-queue the conns into the
- * scheduler queue and wake the scheduler thread.
- */
-
- if (tconn->kstc_conn && tconn->kstc_sched_cb) {
- tconn->kstc_sched_cb(tconn, TRUE);
- }
-
- } else {
-
- ks_unlock_tsdumgr(TsduMgr);
-
- KsPrint((1, "KsTcpSendCompltionRoutine: failed tconn: %p "
- "TsduMgr: %p status: %xh\n", tconn, TsduMgr, status));
-
- /* cfs_enter_debugger(); */
-
- /*
- * for the case that the transmission is unsuccessful,
- * we need abort the tdi connection, but not destroy it.
- * the socknal conn will drop the refer count, then the
- * tdi connection will be freed.
- */
-
- ks_abort_tconn(tconn);
- }
-
- /* drop tconn reference */
- ks_put_tconn(tconn);
-
- /* freeing the context structure */
- if (context) {
- ASSERT(context->Magic == KS_TCP_CONTEXT_MAGIC);
- context->Magic = 'CDAB';
- kfree(context);
- }
-
- /* free the Irp structure */
- if (Irp) {
- /* mdl chain was released by KsReleaseTsdus*/
- Irp->MdlAddress = NULL;
- IoFreeIrp(Irp);
- Irp = NULL;
- }
-
- return status;
-}
-
-/*
- * Normal receive event handler
- *
- * It will move data from system Tsdu to our TsduList
- */
-
-NTSTATUS
-KsTcpReceiveEventHandler(
- IN PVOID TdiEventContext,
- IN CONNECTION_CONTEXT ConnectionContext,
- IN ULONG ReceiveFlags,
- IN ULONG BytesIndicated,
- IN ULONG BytesAvailable,
- OUT ULONG * BytesTaken,
- IN PVOID Tsdu,
- OUT PIRP * IoRequestPacket
- )
-{
- NTSTATUS status;
-
- ks_tconn_t * tconn;
-
- BOOLEAN bIsExpedited;
- BOOLEAN bIsCompleteTsdu;
-
- PCHAR Buffer = NULL;
- PIRP Irp = NULL;
- PMDL Mdl = NULL;
- PFILE_OBJECT FileObject;
- PDEVICE_OBJECT DeviceObject;
- PKS_TSDUMGR TsduMgr;
-
- PKS_TCP_COMPLETION_CONTEXT context = NULL;
-
- tconn = (ks_tconn_t *) ConnectionContext;
- ks_get_tconn(tconn);
-
- /* check expedited flag */
- bIsExpedited = cfs_is_flag_set(ReceiveFlags, TDI_RECEIVE_EXPEDITED);
-
- /* check whether the whole body of payload is received or not */
- if ( (cfs_is_flag_set(ReceiveFlags, TDI_RECEIVE_ENTIRE_MESSAGE)) &&
- (BytesIndicated == BytesAvailable) ) {
- bIsCompleteTsdu = TRUE;
- } else {
- bIsCompleteTsdu = FALSE;
- }
-
- KsPrint((4, "KsTcpReceiveEventHandler BytesIndicated = %d BytesAvailable = %d ...\n",
- BytesIndicated, BytesAvailable));
- KsPrint((4, "bIsCompleteTsdu = %d bIsExpedited = %d\n", bIsCompleteTsdu, bIsExpedited ));
-
- /* check whether we are conntected or not listener */
- if ( !((tconn->kstc_state == ksts_connected) &&
- (tconn->kstc_type == kstt_sender ||
- tconn->kstc_type == kstt_child))) {
-
- *BytesTaken = BytesIndicated;
- ks_put_tconn(tconn);
- return (STATUS_SUCCESS);
- }
-
- /* query tsdu mgr */
- TsduMgr = KsQueryTsduMgr(tconn, bIsExpedited, FALSE);
-
- ks_lock_tsdumgr(TsduMgr);
- if (bIsCompleteTsdu) {
-
- *BytesTaken = KsWriteTsduDat(TsduMgr, Tsdu, BytesAvailable, 0);
- status = STATUS_SUCCESS;
-
- /* signal TsduMgr event */
- KeSetEvent(&(TsduMgr->Event), 0, FALSE);
- ks_unlock_tsdumgr(TsduMgr);
-
- /* re-active the ks connection and wake up the scheduler */
- if (KS_CAN_SCHED(TsduMgr)) {
- if (tconn->kstc_conn && tconn->kstc_sched_cb) {
- tconn->kstc_sched_cb(tconn, FALSE);
- }
- }
-
- } else {
-
- ks_unlock_tsdumgr(TsduMgr);
-
- /* allocate buffer for further data in tsdu queue */
- Buffer = ExAllocatePool(NonPagedPool, BytesAvailable);
- if (NULL == Buffer) {
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto errorout;
- }
-
- /* there's still data in tdi internal queue, we need issue a new
- Irp to receive all of them. first allocate the tcp context */
- context = kmalloc(sizeof(KS_TCP_COMPLETION_CONTEXT), 0);
- if (!context) {
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto errorout;
- }
-
- /* setup the context */
- RtlZeroMemory(context, sizeof(KS_TCP_COMPLETION_CONTEXT));
- context->Magic = KS_TCP_CONTEXT_MAGIC;
- context->tconn = tconn;
- context->CompletionRoutine = KsTcpReceiveCompletionRoutine;
- context->CompletionContext = Buffer;
- context->TsduMgr = TsduMgr;
- context->Buffer = Buffer;
- context->Event = &(TsduMgr->Event);
-
- if (tconn->kstc_type == kstt_sender) {
- FileObject = tconn->sender.kstc_info.FileObject;
- } else {
- FileObject = tconn->child.kstc_info.FileObject;
- }
- DeviceObject = IoGetRelatedDeviceObject(FileObject);
-
- /* build new tdi Irp and setup it. */
- Irp = KsBuildTdiIrp(DeviceObject);
- if (NULL == Irp) {
- goto errorout;
- }
-
- status = KsLockUserBuffer(
- Buffer,
- FALSE,
- BytesAvailable,
- IoModifyAccess,
- &Mdl
- );
-
- if (!NT_SUCCESS(status)) {
- goto errorout;
- }
-
- TdiBuildReceive(
- Irp,
- DeviceObject,
- FileObject,
- KsTcpCompletionRoutine,
- context,
- Mdl,
- ReceiveFlags & (TDI_RECEIVE_NORMAL | TDI_RECEIVE_EXPEDITED),
- BytesAvailable
- );
-
- IoSetNextIrpStackLocation(Irp);
-
- /* return the newly built Irp to transport driver,
- it will process it to receive all the data */
-
- *IoRequestPacket = Irp;
- *BytesTaken = 0;
-
- ks_get_tconn(tconn);
- status = STATUS_MORE_PROCESSING_REQUIRED;
- }
-
- ks_put_tconn(tconn);
-
- return (status);
-
-errorout:
-
- if (Mdl) {
- KsReleaseMdl(Mdl, FALSE);
- }
-
- if (Buffer) {
- ExFreePool(Buffer);
- }
-
- if (Irp) {
- IoFreeIrp(Irp);
- }
-
- if (context) {
- ASSERT(context->Magic == KS_TCP_CONTEXT_MAGIC);
- context->Magic = 'CDAB';
- kfree(context);
- }
-
- ks_abort_tconn(tconn);
- ks_put_tconn(tconn);
-
- *BytesTaken = BytesAvailable;
-
- return STATUS_SUCCESS;
-}
-
-/*
- * Expedited receive event handler
- */
-
-NTSTATUS
-KsTcpReceiveExpeditedEventHandler(
- IN PVOID TdiEventContext,
- IN CONNECTION_CONTEXT ConnectionContext,
- IN ULONG ReceiveFlags,
- IN ULONG BytesIndicated,
- IN ULONG BytesAvailable,
- OUT ULONG * BytesTaken,
- IN PVOID Tsdu,
- OUT PIRP * IoRequestPacket
- )
-{
- return KsTcpReceiveEventHandler(
- TdiEventContext,
- ConnectionContext,
- ReceiveFlags | TDI_RECEIVE_EXPEDITED,
- BytesIndicated,
- BytesAvailable,
- BytesTaken,
- Tsdu,
- IoRequestPacket
- );
-}
-
-/*
- * Bulk receive event handler
- *
- * It will queue all the system Tsdus to our TsduList.
- * Then later ks_recv_mdl will release them.
- */
-
-NTSTATUS
-KsTcpChainedReceiveEventHandler (
- IN PVOID TdiEventContext, // the event context
- IN CONNECTION_CONTEXT ConnectionContext,
- IN ULONG ReceiveFlags,
- IN ULONG ReceiveLength,
- IN ULONG StartingOffset, // offset of start of client data in TSDU
- IN PMDL Tsdu, // TSDU data chain
- IN PVOID TsduDescriptor // for call to TdiReturnChainedReceives
- )
-{
-
- NTSTATUS status;
- ks_tconn_t * tconn;
-
- PKS_TSDUMGR TsduMgr;
-
- BOOLEAN expedited;
-
- tconn = (ks_tconn_t *) ConnectionContext;
- expedited = cfs_is_flag_set(ReceiveFlags, TDI_RECEIVE_EXPEDITED);
-
- KsPrint((4, "KsTcpChainedReceive: sock: %p conn: %p ReceiveLength: %xh "
- "bIsExpedited: %d Tsdu=%p TsduDesc=%p data=%xh\n",
- tconn, tconn->kstc_conn, ReceiveLength, expedited,
- Tsdu, TsduDescriptor, *((PULONG)KsMapMdlBuffer(Tsdu))));
-
- ks_get_tconn(tconn);
-
- /* check whether we are conntected or not listener */
- if ( !((tconn->kstc_state == ksts_connected) &&
- (tconn->kstc_type == kstt_sender ||
- tconn->kstc_type == kstt_child))) {
-
- ks_put_tconn(tconn);
- return (STATUS_SUCCESS);
- }
-
- if (Tsdu) {
-
- TsduMgr = KsQueryTsduMgr(tconn, expedited, FALSE);
- ks_lock_tsdumgr(TsduMgr);
-#if FALSE
- KsWriteTsduMdl(TsduMgr, Tsdu, TsduDescriptor,
- StartingOffset, ReceiveLength, 0);
- status = STATUS_PENDING;
-#else
- KsWriteTsduDat(TsduMgr, (PCHAR)KsMapMdlBuffer(Tsdu) +
- StartingOffset, ReceiveLength, 0);
- status = STATUS_SUCCESS;
-#endif
- KeSetEvent(&(TsduMgr->Event), 0, FALSE);
- ks_unlock_tsdumgr(TsduMgr);
-
- /* re-active the ks connection and wake up the scheduler */
- if (KS_CAN_SCHED(TsduMgr)) {
- if (tconn->kstc_conn && tconn->kstc_sched_cb) {
- tconn->kstc_sched_cb(tconn, FALSE);
- }
- }
-
- } else {
-
- ks_abort_tconn(tconn);
- status = STATUS_CONNECTION_ABORTED;
- }
-
- ks_put_tconn(tconn);
-
- /* Return STATUS_PENDING to system because we are still
- owning the MDL resources. ks_recv_mdl is expected
- to free the MDL resources. */
-
- return (status);
-}
-
-
-/*
- * Expedited & Bulk receive event handler
- */
-
-NTSTATUS
-KsTcpChainedReceiveExpeditedEventHandler (
- IN PVOID TdiEventContext, // the event context
- IN CONNECTION_CONTEXT ConnectionContext,
- IN ULONG ReceiveFlags,
- IN ULONG ReceiveLength,
- IN ULONG StartingOffset, // offset of start of client data in TSDU
- IN PMDL Tsdu, // TSDU data chain
- IN PVOID TsduDescriptor // for call to TdiReturnChainedReceives
- )
-{
- return KsTcpChainedReceiveEventHandler(
- TdiEventContext,
- ConnectionContext,
- ReceiveFlags | TDI_RECEIVE_EXPEDITED,
- ReceiveLength,
- StartingOffset,
- Tsdu,
- TsduDescriptor );
-}
-
-
-/*
- * KsSetHandlers
- * setup all the event handler callbacks
- *
- * Arguments:
- * tconn: the tdi connecton object
- *
- * Return Value:
- * int: ks error code
- *
- * NOTES:
- * N/A
- */
-
-int
-KsSetHandlers(
- ks_tconn_t * tconn
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- KS_EVENT_HANDLERS handlers;
-
- /* to make sure the address object is opened already */
- if (tconn->kstc_addr.FileObject == NULL) {
- goto errorout;
- }
-
- /* initialize the handlers indictor array. for sender and listenr,
- there are different set of callbacks. for child, we just return. */
-
- memset(&handlers, 0, sizeof(KS_EVENT_HANDLERS));
-
- SetEventHandler(handlers, TDI_EVENT_ERROR, KsErrorEventHandler);
- SetEventHandler(handlers, TDI_EVENT_DISCONNECT, KsDisconnectEventHandler);
- SetEventHandler(handlers, TDI_EVENT_RECEIVE, KsTcpReceiveEventHandler);
- SetEventHandler(handlers, TDI_EVENT_RECEIVE_EXPEDITED, KsTcpReceiveExpeditedEventHandler);
- SetEventHandler(handlers, TDI_EVENT_CHAINED_RECEIVE, KsTcpChainedReceiveEventHandler);
-
- // SetEventHandler(handlers, TDI_EVENT_CHAINED_RECEIVE_EXPEDITED, KsTcpChainedReceiveExpeditedEventHandler);
-
- if (tconn->kstc_type == kstt_listener) {
- SetEventHandler(handlers, TDI_EVENT_CONNECT, KsConnectEventHandler);
- } else if (tconn->kstc_type == kstt_child) {
- goto errorout;
- }
-
- /* set all the event callbacks */
- status = KsSetEventHandlers(
- tconn->kstc_addr.FileObject, /* Address File Object */
- tconn, /* Event Context */
- &handlers /* Event callback handlers */
- );
-
-errorout:
-
- return cfs_error_code(status);
-}
-
-
-/*
- * KsResetHandlers
- * disable all the event handler callbacks (set to NULL)
- *
- * Arguments:
- * tconn: the tdi connecton object
- *
- * Return Value:
- * int: ks error code
- *
- * NOTES:
- * N/A
- */
-
-int
-KsResetHandlers(
- ks_tconn_t * tconn
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- KS_EVENT_HANDLERS handlers;
-
- /* to make sure the address object is opened already */
- if (tconn->kstc_addr.FileObject == NULL) {
- goto errorout;
- }
-
- /* initialize the handlers indictor array. for sender and listenr,
- there are different set of callbacks. for child, we just return. */
-
- memset(&handlers, 0, sizeof(KS_EVENT_HANDLERS));
-
- SetEventHandler(handlers, TDI_EVENT_ERROR, NULL);
- SetEventHandler(handlers, TDI_EVENT_DISCONNECT, NULL);
- SetEventHandler(handlers, TDI_EVENT_RECEIVE, NULL);
- SetEventHandler(handlers, TDI_EVENT_RECEIVE_EXPEDITED, NULL);
- SetEventHandler(handlers, TDI_EVENT_CHAINED_RECEIVE, NULL);
- // SetEventHandler(handlers, TDI_EVENT_CHAINED_RECEIVE_EXPEDITED, NULL);
-
- if (tconn->kstc_type == kstt_listener) {
- SetEventHandler(handlers, TDI_EVENT_CONNECT, NULL);
- } else if (tconn->kstc_type == kstt_child) {
- goto errorout;
- }
-
- /* set all the event callbacks */
- status = KsSetEventHandlers(
- tconn->kstc_addr.FileObject, /* Address File Object */
- tconn, /* Event Context */
- &handlers /* Event callback handlers */
- );
-
-errorout:
-
- return cfs_error_code(status);
-}
-
-VOID
-KsPrintProviderInfo(
- PWSTR DeviceName,
- PTDI_PROVIDER_INFO ProviderInfo
- )
-{
- KsPrint((2, "%ws ProviderInfo:\n", DeviceName));
-
- KsPrint((2, " Version : 0x%4.4X\n", ProviderInfo->Version ));
- KsPrint((2, " MaxSendSize : %d\n", ProviderInfo->MaxSendSize ));
- KsPrint((2, " MaxConnectionUserData: %d\n", ProviderInfo->MaxConnectionUserData ));
- KsPrint((2, " MaxDatagramSize : %d\n", ProviderInfo->MaxDatagramSize ));
- KsPrint((2, " ServiceFlags : 0x%8.8X\n", ProviderInfo->ServiceFlags ));
-
- if (ProviderInfo->ServiceFlags & TDI_SERVICE_CONNECTION_MODE) {
- KsPrint((2, " CONNECTION_MODE\n"));
- }
-
- if (ProviderInfo->ServiceFlags & TDI_SERVICE_ORDERLY_RELEASE) {
- KsPrint((2, " ORDERLY_RELEASE\n"));
- }
-
- if (ProviderInfo->ServiceFlags & TDI_SERVICE_CONNECTIONLESS_MODE) {
- KsPrint((2, " CONNECTIONLESS_MODE\n"));
- }
-
- if (ProviderInfo->ServiceFlags & TDI_SERVICE_ERROR_FREE_DELIVERY) {
- KsPrint((2, " ERROR_FREE_DELIVERY\n"));
- }
-
- if( ProviderInfo->ServiceFlags & TDI_SERVICE_SECURITY_LEVEL ) {
- KsPrint((2, " SECURITY_LEVEL\n"));
- }
-
- if (ProviderInfo->ServiceFlags & TDI_SERVICE_BROADCAST_SUPPORTED) {
- KsPrint((2, " BROADCAST_SUPPORTED\n"));
- }
-
- if (ProviderInfo->ServiceFlags & TDI_SERVICE_MULTICAST_SUPPORTED) {
- KsPrint((2, " MULTICAST_SUPPORTED\n"));
- }
-
- if (ProviderInfo->ServiceFlags & TDI_SERVICE_DELAYED_ACCEPTANCE) {
- KsPrint((2, " DELAYED_ACCEPTANCE\n"));
- }
-
- if (ProviderInfo->ServiceFlags & TDI_SERVICE_EXPEDITED_DATA) {
- KsPrint((2, " EXPEDITED_DATA\n"));
- }
-
- if( ProviderInfo->ServiceFlags & TDI_SERVICE_INTERNAL_BUFFERING) {
- KsPrint((2, " INTERNAL_BUFFERING\n"));
- }
-
- if (ProviderInfo->ServiceFlags & TDI_SERVICE_ROUTE_DIRECTED) {
- KsPrint((2, " ROUTE_DIRECTED\n"));
- }
-
- if (ProviderInfo->ServiceFlags & TDI_SERVICE_NO_ZERO_LENGTH) {
- KsPrint((2, " NO_ZERO_LENGTH\n"));
- }
-
- if (ProviderInfo->ServiceFlags & TDI_SERVICE_POINT_TO_POINT) {
- KsPrint((2, " POINT_TO_POINT\n"));
- }
-
- if (ProviderInfo->ServiceFlags & TDI_SERVICE_MESSAGE_MODE) {
- KsPrint((2, " MESSAGE_MODE\n"));
- }
-
- if (ProviderInfo->ServiceFlags & TDI_SERVICE_HALF_DUPLEX) {
- KsPrint((2, " HALF_DUPLEX\n"));
- }
-
- KsPrint((2, " MinimumLookaheadData : %d\n", ProviderInfo->MinimumLookaheadData ));
- KsPrint((2, " MaximumLookaheadData : %d\n", ProviderInfo->MaximumLookaheadData ));
- KsPrint((2, " NumberOfResources : %d\n", ProviderInfo->NumberOfResources ));
-}
-
-
-/*
- * ks_create_tconn
- * allocate a new tconn structure from the SLAB cache or
- * NonPaged sysetm pool
- *
- * Arguments:
- * N/A
- *
- * Return Value:
- * ks_tconn_t *: the address of tconn or NULL if it fails
- *
- * NOTES:
- * N/A
- */
-
-ks_tconn_t *
-ks_create_tconn()
-{
- ks_tconn_t * tconn = NULL;
-
- /* allocate ksoc_tconn_t from the slab cache memory */
- tconn = (ks_tconn_t *)kmem_cache_alloc(
- ks_data.ksnd_tconn_slab, __GFP_ZERO);
-
- if (tconn) {
-
- /* zero tconn elements */
- memset(tconn, 0, sizeof(ks_tconn_t));
-
- /* initialize the tconn ... */
- tconn->kstc_magic = KS_TCONN_MAGIC;
-
- ExInitializeWorkItem(
- &(tconn->kstc_disconnect.WorkItem),
- KsDisconnectHelper,
- &(tconn->kstc_disconnect)
- );
-
- KeInitializeEvent(
- &(tconn->kstc_disconnect.Event),
- SynchronizationEvent,
- FALSE );
-
- ExInitializeWorkItem(
- &(tconn->kstc_destroy),
- ks_destroy_tconn,
- tconn
- );
-
- spin_lock_init(&(tconn->kstc_lock));
-
- ks_get_tconn(tconn);
- spin_lock(&(ks_data.ksnd_tconn_lock));
-
- /* attach it into global list in ks_data */
-
- list_add(&(tconn->kstc_list), &(ks_data.ksnd_tconns));
- ks_data.ksnd_ntconns++;
- spin_unlock(&(ks_data.ksnd_tconn_lock));
-
- tconn->kstc_rcv_wnd = tconn->kstc_snd_wnd = 0x10000;
- }
- KsPrint((3, "ks_create_tconn: new connection: %p\n", tconn));
- return (tconn);
-}
-
-/*
- * ks_free_tconn
- * free the tconn structure to the SLAB cache or NonPaged
- * sysetm pool
- *
- * Arguments:
- * tconn: the tcon is to be freed
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void
-ks_free_tconn(ks_tconn_t * tconn)
-{
- LASSERT(atomic_read(&(tconn->kstc_refcount)) == 0);
-
- spin_lock(&(ks_data.ksnd_tconn_lock));
-
- /* remove it from the global list */
- list_del(&tconn->kstc_list);
- ks_data.ksnd_ntconns--;
-
- /* if this is the last tconn, it would be safe for
- ks_tdi_fini_data to quit ... */
- if (ks_data.ksnd_ntconns == 0) {
- cfs_wake_event(&ks_data.ksnd_tconn_exit);
- }
- spin_unlock(&(ks_data.ksnd_tconn_lock));
-
- /* free the structure memory */
- kmem_cache_free(ks_data.ksnd_tconn_slab, tconn);
-
- KsPrint((3, "ks_free_tconn: tconn %p is freed.\n", tconn));
-}
-
-
-/*
- * ks_init_listener
- * Initialize the tconn as a listener (daemon)
- *
- * Arguments:
- * tconn: the listener tconn
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void
-ks_init_listener(
- ks_tconn_t * tconn
- )
-{
- /* preparation: intialize the tconn members */
-
- tconn->kstc_type = kstt_listener;
-
- RtlInitUnicodeString(&(tconn->kstc_dev), TCP_DEVICE_NAME);
-
- INIT_LIST_HEAD(&(tconn->listener.kstc_listening.list));
- INIT_LIST_HEAD(&(tconn->listener.kstc_accepted.list));
-
- cfs_init_event( &(tconn->listener.kstc_accept_event),
- TRUE,
- FALSE );
-
- cfs_init_event( &(tconn->listener.kstc_destroy_event),
- TRUE,
- FALSE );
-
- tconn->kstc_state = ksts_inited;
-}
-
-
-/*
- * ks_init_sender
- * Initialize the tconn as a sender
- *
- * Arguments:
- * tconn: the sender tconn
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void
-ks_init_sender(
- ks_tconn_t * tconn
- )
-{
- tconn->kstc_type = kstt_sender;
- RtlInitUnicodeString(&(tconn->kstc_dev), TCP_DEVICE_NAME);
-
- KsInitializeKsChain(&(tconn->sender.kstc_recv));
- KsInitializeKsChain(&(tconn->sender.kstc_send));
-
- tconn->kstc_snd_wnd = TDINAL_WINDOW_DEFAULT_SIZE;
- tconn->kstc_rcv_wnd = TDINAL_WINDOW_DEFAULT_SIZE;
-
- tconn->kstc_state = ksts_inited;
-}
-
-/*
- * ks_init_child
- * Initialize the tconn as a child
- *
- * Arguments:
- * tconn: the child tconn
- *
- * Return Value:
- * N/A
- *
- * NOTES:
- * N/A
- */
-
-void
-ks_init_child(
- ks_tconn_t * tconn
- )
-{
- tconn->kstc_type = kstt_child;
- RtlInitUnicodeString(&(tconn->kstc_dev), TCP_DEVICE_NAME);
-
- KsInitializeKsChain(&(tconn->child.kstc_recv));
- KsInitializeKsChain(&(tconn->child.kstc_send));
-
- tconn->kstc_snd_wnd = TDINAL_WINDOW_DEFAULT_SIZE;
- tconn->kstc_rcv_wnd = TDINAL_WINDOW_DEFAULT_SIZE;
-
- tconn->kstc_state = ksts_inited;
-}
-
-/*
- * ks_get_tconn
- * increase the reference count of the tconn with 1
- *
- * Arguments:
- * tconn: the tdi connection to be referred
- *
- * Return Value:
- * N/A
- *
- * NOTES:
- * N/A
- */
-
-void
-ks_get_tconn(
- ks_tconn_t * tconn
- )
-{
- atomic_inc(&(tconn->kstc_refcount));
-}
-
-/*
- * ks_put_tconn
- * decrease the reference count of the tconn and destroy
- * it if the refercount becomes 0.
- *
- * Arguments:
- * tconn: the tdi connection to be dereferred
- *
- * Return Value:
- * N/A
- *
- * NOTES:
- * N/A
- */
-
-void
-ks_put_tconn(
- ks_tconn_t *tconn
- )
-{
- if (atomic_dec_and_test(&(tconn->kstc_refcount))) {
-
- spin_lock(&(tconn->kstc_lock));
-
- if ( ( tconn->kstc_type == kstt_child ||
- tconn->kstc_type == kstt_sender ) &&
- ( tconn->kstc_state == ksts_connected ) ) {
-
- spin_unlock(&(tconn->kstc_lock));
-
- ks_abort_tconn(tconn);
-
- } else {
-
- if (cfs_is_flag_set(tconn->kstc_flags, KS_TCONN_DESTROY_BUSY)) {
- cfs_enter_debugger();
- } else {
- ExQueueWorkItem(
- &(tconn->kstc_destroy),
- DelayedWorkQueue
- );
-
- cfs_set_flag(tconn->kstc_flags, KS_TCONN_DESTROY_BUSY);
- }
-
- spin_unlock(&(tconn->kstc_lock));
- }
- }
-}
-
-/*
- * ks_destroy_tconn
- * cleanup the tdi connection and free it
- *
- * Arguments:
- * tconn: the tdi connection to be cleaned.
- *
- * Return Value:
- * N/A
- *
- * NOTES:
- * N/A
- */
-
-void
-ks_destroy_tconn(
- ks_tconn_t * tconn
- )
-{
- LASSERT(tconn->kstc_refcount.counter == 0);
-
- if (tconn->kstc_type == kstt_listener) {
-
- KsResetHandlers(tconn);
-
- /* for listener, we just need to close the address object */
- KsCloseAddress(
- tconn->kstc_addr.Handle,
- tconn->kstc_addr.FileObject
- );
-
- tconn->kstc_state = ksts_inited;
-
- } else if (tconn->kstc_type == kstt_child) {
-
- /* for child tdi conections */
-
- /* disassociate the relation between it's connection object
- and the address object */
-
- if (tconn->kstc_state == ksts_associated) {
- KsDisassociateAddress(
- tconn->child.kstc_info.FileObject
- );
- }
-
- /* release the connection object */
-
- KsCloseConnection(
- tconn->child.kstc_info.Handle,
- tconn->child.kstc_info.FileObject
- );
-
- /* release it's refer of it's parent's address object */
- KsCloseAddress(
- NULL,
- tconn->kstc_addr.FileObject
- );
-
- spin_lock(&tconn->child.kstc_parent->kstc_lock);
- spin_lock(&tconn->kstc_lock);
-
- tconn->kstc_state = ksts_inited;
-
- /* remove it frome it's parent's queues */
-
- if (tconn->child.kstc_queued) {
-
- list_del(&(tconn->child.kstc_link));
-
- if (tconn->child.kstc_queueno) {
-
- LASSERT(tconn->child.kstc_parent->listener.kstc_accepted.num > 0);
- tconn->child.kstc_parent->listener.kstc_accepted.num -= 1;
-
- } else {
-
- LASSERT(tconn->child.kstc_parent->listener.kstc_listening.num > 0);
- tconn->child.kstc_parent->listener.kstc_listening.num -= 1;
- }
-
- tconn->child.kstc_queued = FALSE;
- }
-
- spin_unlock(&tconn->kstc_lock);
- spin_unlock(&tconn->child.kstc_parent->kstc_lock);
-
- /* drop the reference of the parent tconn */
- ks_put_tconn(tconn->child.kstc_parent);
-
- } else if (tconn->kstc_type == kstt_sender) {
-
- KsResetHandlers(tconn);
-
- /* release the connection object */
-
- KsCloseConnection(
- tconn->sender.kstc_info.Handle,
- tconn->sender.kstc_info.FileObject
- );
-
- /* release it's refer of it's parent's address object */
- KsCloseAddress(
- tconn->kstc_addr.Handle,
- tconn->kstc_addr.FileObject
- );
-
- tconn->kstc_state = ksts_inited;
-
- } else {
- cfs_enter_debugger();
- }
-
- /* free the tconn structure ... */
-
- ks_free_tconn(tconn);
-}
-
-/*
- * ks_get_tcp_option
- * Query the the options of the tcp stream connnection
- *
- * Arguments:
- * tconn: the tdi connection
- * ID: option id
- * OptionValue: buffer to store the option value
- * Length: the length of the value, to be returned
- *
- * Return Value:
- * int: ks return code
- *
- * NOTES:
- * N/A
- */
-
-int
-ks_get_tcp_option (
- ks_tconn_t * tconn,
- ULONG ID,
- PVOID OptionValue,
- PULONG Length
- )
-{
- NTSTATUS Status = STATUS_SUCCESS;
-
- IO_STATUS_BLOCK IoStatus;
-
- TCP_REQUEST_QUERY_INFORMATION_EX QueryInfoEx;
-
- PFILE_OBJECT ConnectionObject;
- PDEVICE_OBJECT DeviceObject = NULL;
-
- PIRP Irp = NULL;
- PIO_STACK_LOCATION IrpSp = NULL;
-
- KEVENT Event;
-
- /* make sure the tdi connection is connected ? */
-
- ks_get_tconn(tconn);
-
- if (tconn->kstc_state != ksts_connected) {
- Status = STATUS_INVALID_PARAMETER;
- goto errorout;
- }
-
- LASSERT(tconn->kstc_type == kstt_sender ||
- tconn->kstc_type == kstt_child);
-
- if (tconn->kstc_type == kstt_sender) {
- ConnectionObject = tconn->sender.kstc_info.FileObject;
- } else {
- ConnectionObject = tconn->child.kstc_info.FileObject;
- }
-
- QueryInfoEx.ID.toi_id = ID;
- QueryInfoEx.ID.toi_type = INFO_TYPE_CONNECTION;
- QueryInfoEx.ID.toi_class = INFO_CLASS_PROTOCOL;
- QueryInfoEx.ID.toi_entity.tei_entity = CO_TL_ENTITY;
- QueryInfoEx.ID.toi_entity.tei_instance = 0;
-
- RtlZeroMemory(&(QueryInfoEx.Context), CONTEXT_SIZE);
-
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
- DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
-
- Irp = IoBuildDeviceIoControlRequest(
- IOCTL_TCP_QUERY_INFORMATION_EX,
- DeviceObject,
- &QueryInfoEx,
- sizeof(TCP_REQUEST_QUERY_INFORMATION_EX),
- OptionValue,
- *Length,
- FALSE,
- &Event,
- &IoStatus
- );
-
- if (Irp == NULL) {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto errorout;
- }
-
- IrpSp = IoGetNextIrpStackLocation(Irp);
-
- if (IrpSp == NULL) {
-
- IoFreeIrp(Irp);
- Irp = NULL;
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto errorout;
- }
-
- IrpSp->FileObject = ConnectionObject;
- IrpSp->DeviceObject = DeviceObject;
-
- Status = IoCallDriver(DeviceObject, Irp);
-
- if (Status == STATUS_PENDING) {
-
- KeWaitForSingleObject(
- &Event,
- Executive,
- KernelMode,
- FALSE,
- NULL
- );
-
- Status = IoStatus.Status;
- }
-
-
- if (NT_SUCCESS(Status)) {
- *Length = (ULONG)(ULONG_PTR)IoStatus.Information;
- } else {
- cfs_enter_debugger();
- memset(OptionValue, 0, *Length);
- Status = STATUS_SUCCESS;
- }
-
-errorout:
-
- ks_put_tconn(tconn);
-
- return cfs_error_code(Status);
-}
-
-/*
- * ks_set_tcp_option
- * Set the the options for the tcp stream connnection
- *
- * Arguments:
- * tconn: the tdi connection
- * ID: option id
- * OptionValue: buffer containing the new option value
- * Length: the length of the value
- *
- * Return Value:
- * int: ks return code
- *
- * NOTES:
- * N/A
- */
-
-NTSTATUS
-ks_set_tcp_option (
- ks_tconn_t * tconn,
- ULONG ID,
- PVOID OptionValue,
- ULONG Length
- )
-{
- NTSTATUS Status = STATUS_SUCCESS;
-
- IO_STATUS_BLOCK IoStatus;
-
- ULONG SetInfoExLength;
- PTCP_REQUEST_SET_INFORMATION_EX SetInfoEx = NULL;
-
- PFILE_OBJECT ConnectionObject;
- PDEVICE_OBJECT DeviceObject = NULL;
-
- PIRP Irp = NULL;
- PIO_STACK_LOCATION IrpSp = NULL;
-
- PKEVENT Event;
-
- /* make sure the tdi connection is connected ? */
-
- ks_get_tconn(tconn);
-
- if (tconn->kstc_state != ksts_connected) {
- Status = STATUS_INVALID_PARAMETER;
- goto errorout;
- }
-
- LASSERT(tconn->kstc_type == kstt_sender ||
- tconn->kstc_type == kstt_child);
-
- if (tconn->kstc_type == kstt_sender) {
- ConnectionObject = tconn->sender.kstc_info.FileObject;
- } else {
- ConnectionObject = tconn->child.kstc_info.FileObject;
- }
-
- SetInfoExLength = sizeof(TCP_REQUEST_SET_INFORMATION_EX) - 1 + Length + sizeof(KEVENT);
-
- SetInfoEx = ExAllocatePoolWithTag(
- NonPagedPool,
- SetInfoExLength,
- 'TSSK'
- );
-
- if (SetInfoEx == NULL) {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto errorout;
- }
-
- SetInfoEx->ID.toi_id = ID;
-
- SetInfoEx->ID.toi_type = INFO_TYPE_CONNECTION;
- SetInfoEx->ID.toi_class = INFO_CLASS_PROTOCOL;
- SetInfoEx->ID.toi_entity.tei_entity = CO_TL_ENTITY;
- SetInfoEx->ID.toi_entity.tei_instance = TL_INSTANCE;
-
- SetInfoEx->BufferSize = Length;
- RtlCopyMemory(&(SetInfoEx->Buffer[0]), OptionValue, Length);
-
- Event = (PKEVENT)(&(SetInfoEx->Buffer[Length]));
- KeInitializeEvent(Event, NotificationEvent, FALSE);
-
- DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
-
- Irp = IoBuildDeviceIoControlRequest(
- IOCTL_TCP_SET_INFORMATION_EX,
- DeviceObject,
- SetInfoEx,
- SetInfoExLength,
- NULL,
- 0,
- FALSE,
- Event,
- &IoStatus
- );
-
- if (Irp == NULL) {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto errorout;
- }
-
- IrpSp = IoGetNextIrpStackLocation(Irp);
-
- if (IrpSp == NULL) {
- IoFreeIrp(Irp);
- Irp = NULL;
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto errorout;
- }
-
- IrpSp->FileObject = ConnectionObject;
- IrpSp->DeviceObject = DeviceObject;
-
- Status = IoCallDriver(DeviceObject, Irp);
-
- if (Status == STATUS_PENDING) {
-
- KeWaitForSingleObject(
- Event,
- Executive,
- KernelMode,
- FALSE,
- NULL
- );
-
- Status = IoStatus.Status;
- }
-
-errorout:
-
- if (SetInfoEx) {
- ExFreePool(SetInfoEx);
- }
-
- if (!NT_SUCCESS(Status)) {
- KsPrint((0, "ks_set_tcp_option: error setup tcp option: "
- "ID (%d) Status = %xh\n", ID, Status));
- Status = STATUS_SUCCESS;
- }
-
- ks_put_tconn(tconn);
-
- return cfs_error_code(Status);
-}
-
-/*
- * ks_bind_tconn
- * bind the tdi connection object with an address
- *
- * Arguments:
- * tconn: tconn to be bound
- * parent: the parent tconn object
- * ipaddr: the ip address
- * port: the port number
- *
- * Return Value:
- * int: 0 for success or ks error codes.
- *
- * NOTES:
- * N/A
- */
-
-int
-ks_bind_tconn (
- ks_tconn_t * tconn,
- ks_tconn_t * parent,
- ulong addr,
- unsigned short port
- )
-{
- NTSTATUS status;
- int rc = 0;
-
- ks_tdi_addr_t taddr;
-
- memset(&taddr, 0, sizeof(ks_tdi_addr_t));
-
- if (tconn->kstc_state != ksts_inited) {
-
- status = STATUS_INVALID_PARAMETER;
- rc = cfs_error_code(status);
- goto errorout;
-
- } else if (tconn->kstc_type == kstt_child) {
-
- if (NULL == parent) {
- status = STATUS_INVALID_PARAMETER;
- rc = cfs_error_code(status);
-
- goto errorout;
- }
-
- /* refer it's parent's address object */
-
- taddr = parent->kstc_addr;
- ObReferenceObject(taddr.FileObject);
-
- ks_get_tconn(parent);
-
- } else {
-
- PTRANSPORT_ADDRESS TdiAddress = &(taddr.Tdi);
- ULONG AddrLen = 0;
-
- /* intialize the tdi address*/
-
- TdiAddress->TAAddressCount = 1;
- TdiAddress->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
- TdiAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
-
- ((PTDI_ADDRESS_IP)&(TdiAddress->Address[0].Address))->sin_port = htons(port);
- ((PTDI_ADDRESS_IP)&(TdiAddress->Address[0].Address))->in_addr = (ULONG)htonl(addr);
-
- memset(&(((PTDI_ADDRESS_IP)&(TdiAddress->Address[0].Address))->sin_zero[0]),0,8);
-
-
- /* open the transport address object */
-
- AddrLen = FIELD_OFFSET(TRANSPORT_ADDRESS, Address->Address) +
- TDI_ADDRESS_LENGTH_IP;
-
- status = KsOpenAddress(
- &(tconn->kstc_dev),
- &(taddr.Tdi),
- AddrLen,
- &(taddr.Handle),
- &(taddr.FileObject)
- );
-
- if (!NT_SUCCESS(status)) {
-
- KsPrint((1, "ks_bind_tconn: failed to open ip addr object (%x:%d), status = %xh\n",
- addr, port, status ));
- rc = cfs_error_code(status);
- goto errorout;
- }
- }
-
- if (tconn->kstc_type == kstt_child) {
- tconn->child.kstc_parent = parent;
- }
-
- tconn->kstc_state = ksts_bind;
- tconn->kstc_addr = taddr;
-
-errorout:
-
- return (rc);
-}
-
-/*
- * ks_build_tconn
- * build tcp/streaming connection to remote peer
- *
- * Arguments:
- * tconn: tconn to be connected to the peer
- * addr: the peer's ip address
- * port: the peer's port number
- *
- * Return Value:
- * int: 0 for success or ks error codes.
- *
- * Notes:
- * N/A
- */
-
-int
-ks_build_tconn(
- ks_tconn_t * tconn,
- ulong addr,
- unsigned short port
- )
-{
- int rc = 0;
- NTSTATUS status = STATUS_SUCCESS;
-
-
- PFILE_OBJECT ConnectionObject = NULL;
- PDEVICE_OBJECT DeviceObject = NULL;
-
- PTDI_CONNECTION_INFORMATION ConnectionInfo = NULL;
- ULONG AddrLength;
-
- PIRP Irp = NULL;
-
- LASSERT(tconn->kstc_type == kstt_sender);
- LASSERT(tconn->kstc_state == ksts_bind);
-
- ks_get_tconn(tconn);
-
- {
- /* set the event callbacks */
- rc = KsSetHandlers(tconn);
-
- if (rc < 0) {
- cfs_enter_debugger();
- goto errorout;
- }
- }
-
- /* create the connection file handle / object */
- status = KsOpenConnection(
- &(tconn->kstc_dev),
- (CONNECTION_CONTEXT)tconn,
- &(tconn->sender.kstc_info.Handle),
- &(tconn->sender.kstc_info.FileObject)
- );
-
- if (!NT_SUCCESS(status)) {
- rc = cfs_error_code(status);
- cfs_enter_debugger();
- goto errorout;
- }
-
- /* associdate the the connection with the adress object of the tconn */
-
- status = KsAssociateAddress(
- tconn->kstc_addr.Handle,
- tconn->sender.kstc_info.FileObject
- );
-
- if (!NT_SUCCESS(status)) {
- rc = cfs_error_code(status);
- cfs_enter_debugger();
- goto errorout;
- }
-
- tconn->kstc_state = ksts_associated;
-
- /* Allocating Connection Info Together with the Address */
- AddrLength = FIELD_OFFSET(TRANSPORT_ADDRESS, Address->Address)
- + TDI_ADDRESS_LENGTH_IP;
-
- ConnectionInfo = (PTDI_CONNECTION_INFORMATION)ExAllocatePoolWithTag(
- NonPagedPool, sizeof(TDI_CONNECTION_INFORMATION) + AddrLength, 'iCsK');
-
- if (NULL == ConnectionInfo) {
-
- status = STATUS_INSUFFICIENT_RESOURCES;
- rc = cfs_error_code(status);
- cfs_enter_debugger();
- goto errorout;
- }
-
- /* Initializing ConnectionInfo ... */
- {
- PTRANSPORT_ADDRESS TdiAddress;
-
- /* ConnectionInfo settings */
-
- ConnectionInfo->UserDataLength = 0;
- ConnectionInfo->UserData = NULL;
- ConnectionInfo->OptionsLength = 0;
- ConnectionInfo->Options = NULL;
- ConnectionInfo->RemoteAddressLength = AddrLength;
- ConnectionInfo->RemoteAddress = ConnectionInfo + 1;
-
-
- /* intialize the tdi address*/
-
- TdiAddress = ConnectionInfo->RemoteAddress;
-
- TdiAddress->TAAddressCount = 1;
- TdiAddress->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
- TdiAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
-
- ((PTDI_ADDRESS_IP)&(TdiAddress->Address[0].Address))->sin_port = htons(port);
- ((PTDI_ADDRESS_IP)&(TdiAddress->Address[0].Address))->in_addr = (ULONG)htonl(addr);
-
- memset(&(((PTDI_ADDRESS_IP)&(TdiAddress->Address[0].Address))->sin_zero[0]),0,8);
- }
-
- /* Now prepare to connect the remote peer ... */
-
- ConnectionObject = tconn->sender.kstc_info.FileObject;
- DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
-
- /* allocate a new Irp */
-
- Irp = KsBuildTdiIrp(DeviceObject);
-
- if (NULL == Irp) {
-
- status = STATUS_INSUFFICIENT_RESOURCES;
- rc = cfs_error_code(status);
- cfs_enter_debugger();
- goto errorout;
- }
-
- /* setup the Irp */
-
- TdiBuildConnect(
- Irp,
- DeviceObject,
- ConnectionObject,
- NULL,
- NULL,
- NULL,
- ConnectionInfo,
- NULL
- );
-
-
- /* sumbit the Irp to the underlying transport driver */
- status = KsSubmitTdiIrp(
- DeviceObject,
- Irp,
- TRUE,
- NULL
- );
-
- spin_lock(&(tconn->kstc_lock));
-
- if (NT_SUCCESS(status)) {
-
- /* Connected! the conneciton is built successfully. */
-
- tconn->kstc_state = ksts_connected;
-
- tconn->sender.kstc_info.ConnectionInfo = ConnectionInfo;
- tconn->sender.kstc_info.Remote = ConnectionInfo->RemoteAddress;
-
- spin_unlock(&(tconn->kstc_lock));
-
- } else {
-
- /* Not connected! Abort it ... */
-
- if (rc != 0) {
- cfs_enter_debugger();
- }
-
- Irp = NULL;
- rc = cfs_error_code(status);
-
- tconn->kstc_state = ksts_associated;
- spin_unlock(&(tconn->kstc_lock));
-
- /* disassocidate the connection and the address object,
- after cleanup, it's safe to set the state to abort ... */
-
- if ( NT_SUCCESS(KsDisassociateAddress(
- tconn->sender.kstc_info.FileObject))) {
- tconn->kstc_state = ksts_aborted;
- }
-
- /* reset the event callbacks */
- rc = KsResetHandlers(tconn);
-
- goto errorout;
- }
-
-errorout:
-
- if (NT_SUCCESS(status)) {
-
- ks_query_local_ipaddr(tconn);
-
- } else {
-
- if (ConnectionInfo) {
- ExFreePool(ConnectionInfo);
- }
- if (Irp) {
- IoFreeIrp(Irp);
- }
- }
-
- ks_put_tconn(tconn);
-
- return (rc);
-}
-
-
-/*
- * ks_disconnect_tconn
- * disconnect the tconn from a connection
- *
- * Arguments:
- * tconn: the tdi connecton object connected already
- * flags: flags & options for disconnecting
- *
- * Return Value:
- * int: ks error code
- *
- * Notes:
- * N/A
- */
-
-int
-ks_disconnect_tconn(
- ks_tconn_t * tconn,
- ulong flags
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
-
- ks_tconn_info_t * info;
-
- PFILE_OBJECT ConnectionObject;
- PDEVICE_OBJECT DeviceObject = NULL;
-
- PIRP Irp = NULL;
-
- KEVENT Event;
-
- ks_get_tconn(tconn);
-
- /* make sure tt's connected already and it
- must be a sender or a child ... */
-
- LASSERT(tconn->kstc_state == ksts_connected);
- LASSERT( tconn->kstc_type == kstt_sender ||
- tconn->kstc_type == kstt_child);
-
- /* reset all the event handlers to NULL */
-
- if (tconn->kstc_type != kstt_child) {
- KsResetHandlers (tconn);
- }
-
- /* Disconnecting to the remote peer ... */
-
- if (tconn->kstc_type == kstt_sender) {
- info = &(tconn->sender.kstc_info);
- } else {
- info = &(tconn->child.kstc_info);
- }
-
- ConnectionObject = info->FileObject;
- DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
-
- /* allocate an Irp and setup it */
-
- Irp = KsBuildTdiIrp(DeviceObject);
-
- if (NULL == Irp) {
-
- status = STATUS_INSUFFICIENT_RESOURCES;
- cfs_enter_debugger();
- goto errorout;
- }
-
- KeInitializeEvent(
- &Event,
- SynchronizationEvent,
- FALSE
- );
-
- TdiBuildDisconnect(
- Irp,
- DeviceObject,
- ConnectionObject,
- KsDisconectCompletionRoutine,
- &Event,
- NULL,
- flags,
- NULL,
- NULL
- );
-
- /* issue the Irp to the underlying transport
- driver to disconnect the connection */
-
- status = IoCallDriver(DeviceObject, Irp);
-
- if (STATUS_PENDING == status) {
-
- status = KeWaitForSingleObject(
- &Event,
- Executive,
- KernelMode,
- FALSE,
- NULL
- );
-
- status = Irp->IoStatus.Status;
- }
-
- KsPrint((2, "KsDisconnect: Disconnection is done with Status = %xh (%s) ...\n",
- status, KsNtStatusToString(status)));
-
- IoFreeIrp(Irp);
-
- if (info->ConnectionInfo) {
-
- /* disassociate the association between connection/address objects */
-
- status = KsDisassociateAddress(ConnectionObject);
-
- if (!NT_SUCCESS(status)) {
- cfs_enter_debugger();
- }
-
- spin_lock(&(tconn->kstc_lock));
-
- /* cleanup the tsdumgr Lists */
- KsCleanupTsdu (tconn);
-
- /* set the state of the tconn */
- if (NT_SUCCESS(status)) {
- tconn->kstc_state = ksts_disconnected;
- } else {
- tconn->kstc_state = ksts_associated;
- }
-
- /* free the connection info to system pool*/
- ExFreePool(info->ConnectionInfo);
- info->ConnectionInfo = NULL;
- info->Remote = NULL;
-
- spin_unlock(&(tconn->kstc_lock));
- }
-
- status = STATUS_SUCCESS;
-
-errorout:
-
- ks_put_tconn(tconn);
-
- return cfs_error_code(status);
-}
-
-
-/*
- * ks_abort_tconn
- * The connection is broken un-expectedly. We need do
- * some cleanup.
- *
- * Arguments:
- * tconn: the tdi connection
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void
-ks_abort_tconn(
- ks_tconn_t * tconn
- )
-{
- PKS_DISCONNECT_WORKITEM WorkItem = NULL;
-
- WorkItem = &(tconn->kstc_disconnect);
-
- ks_get_tconn(tconn);
- spin_lock(&(tconn->kstc_lock));
-
- if (tconn->kstc_state != ksts_connected) {
- ks_put_tconn(tconn);
- } else {
-
- if (!cfs_is_flag_set(tconn->kstc_flags, KS_TCONN_DISCONNECT_BUSY)) {
-
- WorkItem->Flags = TDI_DISCONNECT_ABORT;
- WorkItem->tconn = tconn;
-
- cfs_set_flag(tconn->kstc_flags, KS_TCONN_DISCONNECT_BUSY);
-
- ExQueueWorkItem(
- &(WorkItem->WorkItem),
- DelayedWorkQueue
- );
- }
- }
-
- spin_unlock(&(tconn->kstc_lock));
-}
-
-
-/*
- * ks_query_local_ipaddr
- * query the local connection ip address
- *
- * Arguments:
- * tconn: the tconn which is connected
- *
- * Return Value:
- * int: ks error code
- *
- * Notes:
- * N/A
- */
-
-int
-ks_query_local_ipaddr(
- ks_tconn_t * tconn
- )
-{
- PFILE_OBJECT FileObject = NULL;
- NTSTATUS status;
-
- PTRANSPORT_ADDRESS TdiAddress;
- ULONG AddressLength;
-
- if (tconn->kstc_type == kstt_sender) {
- FileObject = tconn->sender.kstc_info.FileObject;
- } else if (tconn->kstc_type == kstt_child) {
- FileObject = tconn->child.kstc_info.FileObject;
- } else {
- status = STATUS_INVALID_PARAMETER;
- goto errorout;
- }
-
- TdiAddress = &(tconn->kstc_addr.Tdi);
- AddressLength = MAX_ADDRESS_LENGTH;
-
- status = KsQueryIpAddress(FileObject, TdiAddress, &AddressLength);
-
- if (NT_SUCCESS(status)) {
- KsPrint((2, "ks_query_local_ipaddr: Local ip address = %xh port = %xh\n",
- ((PTDI_ADDRESS_IP)(&(TdiAddress->Address[0].Address)))->in_addr,
- ((PTDI_ADDRESS_IP)(&(TdiAddress->Address[0].Address)))->sin_port ));
- } else {
- KsPrint((2, "ks_query_local_ipaddr: Failed to query the connection local ip address.\n"));
- }
-
-errorout:
-
- return cfs_error_code(status);
-}
-
-int
-KsCalcWhichEngine(ks_tconn_t * tconn)
-{
- PTRANSPORT_ADDRESS TdiAddress = &(tconn->kstc_addr.Tdi);
- ULONG addr = ((PTDI_ADDRESS_IP)(&(TdiAddress->Address[0].Address)))->in_addr;
- ULONG sum = (addr & 0xFF) + ((addr & 0xFF00) >> 8) + ((addr & 0xFF0000) >> 16);
-
- return (int)(sum % ks_data.ksnd_engine_nums);
-}
-
-void
-KsQueueTdiEngine(ks_tconn_t * tconn, PKS_TSDUMGR TsduMgr)
-{
- ks_engine_mgr_t * engm;
- ks_engine_slot_t * engs;
-
- engm = &ks_data.ksnd_engine_mgr[KsCalcWhichEngine(tconn)];
- engs = &TsduMgr->Slot;
-
- if (!engs->queued) {
- spin_lock(&engm->lock);
- if (!engs->queued) {
- list_add_tail(&engs->link, &engm->list);
- engs->queued = TRUE;
- engs->tconn = tconn;
- engs->emgr = engm;
- engs->tsdumgr = TsduMgr;
- KeSetEvent(&(engm->start),0, FALSE);
- }
- spin_unlock(&engm->lock);
- KsPrint((4, "KsQueueTdiEngine: TsduMgr=%p is queued to engine %p\n",
- TsduMgr, engm));
- }
- KeSetEvent(&(engm->start),0, FALSE);
-}
-
-void
-KsRemoveTdiEngine(PKS_TSDUMGR TsduMgr)
-{
- ks_engine_mgr_t * engm;
- ks_engine_slot_t * engs;
-
- engs = &TsduMgr->Slot;
- if (engs->queued) {
- engm = engs->emgr;
- LASSERT(engm != NULL);
- spin_lock(&engm->lock);
- if (engs->queued) {
- list_del(&engs->link);
- engs->queued = FALSE;
- engs->tconn = NULL;
- engs->emgr = NULL;
- engs->tsdumgr = NULL;
- }
- spin_unlock(&engm->lock);
- KsPrint((4, "KsQueueTdiEngine: TsduMgr %p is removed from engine %p\n",
- TsduMgr, engm));
- }
-}
-
-int
-KsDeliveryIrp(ks_tconn_t * tconn, PIRP irp)
-{
- PFILE_OBJECT connobj;
- PDEVICE_OBJECT devobj;
- NTSTATUS status;
- int rc = 0;
-
- /* construct Irp */
- if (tconn->kstc_type == kstt_sender) {
- connobj = tconn->sender.kstc_info.FileObject;
- } else {
- LASSERT(tconn->kstc_type == kstt_child);
- connobj = tconn->child.kstc_info.FileObject;
- }
- devobj = IoGetRelatedDeviceObject(connobj);
-
- /* send irp to transport layer */
- status = IoCallDriver(devobj, irp);
-
- /* convert status to linux error code */
- if (!NT_SUCCESS(status)) {
- rc = cfs_error_code(status);
- }
-
- KsPrint((4, "KsDeliveryIrp: tconn=%p irp=%p status=%xh rc=%d.\n",
- tconn, irp, status, rc));
- return rc;
-}
-
-PIRP
-KsBuildSend(ks_tconn_t * tconn, PKS_TSDUMGR TsduMgr,
- ks_mdl_t * mdl, ulong flags )
-{
- ks_tdi_tx_t * context;
- PIRP irp = NULL;
- PFILE_OBJECT connobj;
- PDEVICE_OBJECT devobj;
- NTSTATUS status;
- ULONG length;
-
- int rc = 0;
-
- /* query mdl chain total length */
- length = KsQueryMdlsSize(mdl);
-
- /* we need allocate the ks_tx_t structure from memory pool. */
- context = kmalloc(sizeof(ks_tdi_tx_t), 0);
- if (!context) {
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto errorout;
- }
-
- /* intialize the TcpContext */
- memset(context,0, sizeof(ks_tdi_tx_t));
- context->Magic = KS_TCP_CONTEXT_MAGIC;
- context->tconn = tconn;
- context->CompletionRoutine = KsTcpSendCompletionRoutine;
- context->TsduMgr = TsduMgr;
- context->Length = length;
-
- /* construct Irp */
- if (tconn->kstc_type == kstt_sender) {
- connobj = tconn->sender.kstc_info.FileObject;
- } else {
- LASSERT(tconn->kstc_type == kstt_child);
- connobj = tconn->child.kstc_info.FileObject;
- }
- devobj = IoGetRelatedDeviceObject(connobj);
- irp = KsBuildTdiIrp(devobj);
- if (NULL == irp) {
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto errorout;
- }
-
- /* grab tconn reference */
- ks_get_tconn(tconn);
-
- /* delivery the sending request */
- TdiBuildSend(
- irp,
- devobj,
- connobj,
- KsTcpCompletionRoutine,
- context,
- mdl,
- flags,
- length
- );
-
- return irp;
-
-errorout:
-
- /* free the context if is not used at all */
- if (context) {
- ASSERT(context->Magic == KS_TCP_CONTEXT_MAGIC);
- context->Magic = 'CDAB';
- kfree(context);
- }
-
- /* here need free the Irp. */
- if (irp) {
- IoFreeIrp(irp);
- irp = NULL;
- }
-
- return NULL;
-}
-
-int
-KsDeliveryTsdus(ks_tconn_t * tconn, PKS_TSDUMGR TsduMgr)
-{
- int rc = 0;
- ulong length = 0;
- ulong tflags = 0;
- ks_mdl_t * mdl = NULL;
- PIRP irp = NULL;
- BOOLEAN expedited;
-
- LASSERT(tconn->kstc_magic == KS_TCONN_MAGIC);
-
- ks_get_tconn(tconn);
- ks_lock_tsdumgr(TsduMgr);
-
- if ( tconn->kstc_type != kstt_sender &&
- tconn->kstc_type != kstt_child) {
- rc = -EINVAL;
- ks_unlock_tsdumgr(TsduMgr);
- goto errorout;
- }
-
- if (tconn->kstc_state != ksts_connected) {
- rc = -ENOTCONN;
- ks_unlock_tsdumgr(TsduMgr);
- goto errorout;
- }
-
- if (TsduMgr->OOB) {
- tflags = TDI_SEND_NON_BLOCKING | TDI_SEND_EXPEDITED;
- } else {
- tflags = TDI_SEND_NON_BLOCKING;
- }
-
- if (list_empty(&TsduMgr->TsduList)) {
- LASSERT(TsduMgr->TotalBytes == 0);
- ks_unlock_tsdumgr(TsduMgr);
- goto errorout;
- }
-
- /* check whether there's outstanding sending requests */
- if (TsduMgr->Busy) {
- rc = -EAGAIN;
- ks_unlock_tsdumgr(TsduMgr);
- goto errorout;
- }
-
- /* probe all Tsdus and merge buffers together */
- mdl = KsLockTsdus(tconn, TsduMgr, &tflags, &length);
- if (NULL == mdl) {
- if (length == 0) {
- LASSERT(TsduMgr->TotalBytes == 0);
- rc = -EAGAIN;
- } else {
- rc = -ENOMEM;
- }
- ks_unlock_tsdumgr(TsduMgr);
- goto errorout;
- }
-
- KsPrint((4, "KsDeliveryTsdus: tconn=%p TsudMgr=%p, length=%xh/%xh\n",
- tconn, TsduMgr, length, TsduMgr->TotalBytes));
-
- /* build send irp request */
- irp = KsBuildSend(tconn, TsduMgr, mdl, tflags);
- if (NULL == irp) {
- rc = -ENOMEM;
- ks_unlock_tsdumgr(TsduMgr);
- goto errorout;
- }
- TsduMgr->Busy = TRUE;
- ks_unlock_tsdumgr(TsduMgr);
-
- /* delivery mdl chain */
- LASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
- rc = KsDeliveryIrp(tconn, irp);
- if (rc < 0) {
- goto errorout;
- }
-
-errorout:
-
- LASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
- ks_put_tconn(tconn);
- return rc;
-}
-
-int
-KsDeliveryEngineThread(void * context)
-{
- ks_engine_mgr_t * engm = context;
- ks_engine_slot_t * engs;
- struct list_head * list;
- ks_tconn_t * tconn;
-
- cfs_set_thread_priority(31);
-
- while (!engm->stop) {
-
- cfs_wait_event_internal(&engm->start, 0);
-
- spin_lock(&engm->lock);
- if (list_empty(&engm->list)) {
- spin_unlock(&engm->lock);
- continue;
- }
-
- list = engm->list.next;
- list_del(list);
- engs = list_entry(list, ks_engine_slot_t, link);
- LASSERT(engs->emgr == engm);
- LASSERT(engs->queued);
- engs->emgr = NULL;
- engs->queued = FALSE;
- spin_unlock(&engm->lock);
-
- tconn = engs->tconn;
- LASSERT(tconn->kstc_magic == KS_TCONN_MAGIC);
-
- KsPrint((4, "KsDeliveryEngineThread: %p active: tconn=%p "
- "TsduMgr=%p\n", engm, tconn, engs->tsdumgr));
- KsDeliveryTsdus(tconn, engs->tsdumgr);
-
- LASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
- }
-
- KeSetEvent(&engm->exit, 0, FALSE);
-
- return 0;
-}
-
-/*
- * ks_init_tdi_data
- * initialize the global data in ksockal_data
- *
- * Arguments:
- * N/A
- *
- * Return Value:
- * int: ks error code
- *
- * Notes:
- * N/A
- */
-
-int
-ks_init_tdi_data()
-{
- int rc = 0, i;
-
- /* initialize tconn related globals */
- RtlZeroMemory(&ks_data, sizeof(ks_tdi_data_t));
-
- spin_lock_init(&ks_data.ksnd_tconn_lock);
- INIT_LIST_HEAD(&ks_data.ksnd_tconns);
- cfs_init_event(&ks_data.ksnd_tconn_exit, TRUE, FALSE);
-
- ks_data.ksnd_tconn_slab = kmem_cache_create("tcon", sizeof(ks_tconn_t),
- 0, 0, NULL);
-
- if (!ks_data.ksnd_tconn_slab) {
- rc = -ENOMEM;
- goto errorout;
- }
-
- /* initialize tsdu related globals */
- spin_lock_init(&ks_data.ksnd_tsdu_lock);
- INIT_LIST_HEAD(&ks_data.ksnd_freetsdus);
- ks_data.ksnd_tsdu_size = TDINAL_TSDU_DEFAULT_SIZE; /* 64k */
- ks_data.ksnd_tsdu_slab = kmem_cache_create("tsdu", ks_data.ksnd_tsdu_size,
- 0, 0, NULL);
-
- if (!ks_data.ksnd_tsdu_slab) {
- rc = -ENOMEM;
- goto errorout;
- }
-
- /* initialize engine threads list */
- ks_data.ksnd_engine_nums = num_online_cpus();
- if (ks_data.ksnd_engine_nums < 4) {
- ks_data.ksnd_engine_nums = 4;
- }
- ks_data.ksnd_engine_mgr = kmalloc(sizeof(ks_engine_mgr_t) *
- ks_data.ksnd_engine_nums, __GFP_ZERO);
- if (ks_data.ksnd_engine_mgr == NULL) {
- rc = -ENOMEM;
- goto errorout;
- }
- for (i = 0; i < ks_data.ksnd_engine_nums; i++) {
- spin_lock_init(&ks_data.ksnd_engine_mgr[i].lock);
- cfs_init_event(&ks_data.ksnd_engine_mgr[i].start, TRUE, FALSE);
- cfs_init_event(&ks_data.ksnd_engine_mgr[i].exit, TRUE, FALSE);
- INIT_LIST_HEAD(&ks_data.ksnd_engine_mgr[i].list);
- kthread_run(KsDeliveryEngineThread, &ks_data.ksnd_engine_mgr[i], "");
- }
-
- /* register pnp handlers to watch network condition */
- KsRegisterPnpHandlers();
-
-errorout:
-
- /* do cleanup in case we get failures */
- if (rc < 0) {
- if (ks_data.ksnd_tconn_slab) {
-kmem_cache_destroy(ks_data.ksnd_tconn_slab);
- ks_data.ksnd_tconn_slab = NULL;
- }
- }
-
- return rc;
-}
-
-
-/*
- * ks_fini_tdi_data
- * finalize the global data in ksockal_data
- *
- * Arguments:
- * N/A
- *
- * Return Value:
- * int: ks error code
- *
- * Notes:
- * N/A
- */
-
-void
-ks_fini_tdi_data()
-{
- PKS_TSDU KsTsdu = NULL;
- struct list_head * list = NULL;
- int i;
-
- /* clean up the pnp handler and address slots */
- KsDeregisterPnpHandlers();
-
- /* stop all tcp sending engines */
- for (i = 0; i < ks_data.ksnd_engine_nums; i++) {
- ks_data.ksnd_engine_mgr[i].stop = TRUE;
- KeSetEvent(&ks_data.ksnd_engine_mgr[i].start, 0, FALSE);
- }
-
- for (i = 0; i < ks_data.ksnd_engine_nums; i++) {
- cfs_wait_event_internal(&ks_data.ksnd_engine_mgr[i].exit, 0);
- }
-
- /* we need wait until all the tconn are freed */
- spin_lock(&(ks_data.ksnd_tconn_lock));
-
- if (list_empty(&(ks_data.ksnd_tconns))) {
- cfs_wake_event(&ks_data.ksnd_tconn_exit);
- }
- spin_unlock(&(ks_data.ksnd_tconn_lock));
-
- /* now wait on the tconn exit event */
- cfs_wait_event_internal(&ks_data.ksnd_tconn_exit, 0);
-
- /* it's safe to delete the tconn slab ... */
-kmem_cache_destroy(ks_data.ksnd_tconn_slab);
- ks_data.ksnd_tconn_slab = NULL;
-
- /* clean up all the tsud buffers in the free list */
- spin_lock(&(ks_data.ksnd_tsdu_lock));
- list_for_each (list, &ks_data.ksnd_freetsdus) {
- KsTsdu = list_entry (list, KS_TSDU, Link);
-
- kmem_cache_free(
- ks_data.ksnd_tsdu_slab,
- KsTsdu );
- }
- spin_unlock(&(ks_data.ksnd_tsdu_lock));
-
- /* it's safe to delete the tsdu slab ... */
-kmem_cache_destroy(ks_data.ksnd_tsdu_slab);
- ks_data.ksnd_tsdu_slab = NULL;
-
- /* good! it's smooth to do the cleaning up...*/
-}
-
-/*
- * ks_create_child_tconn
- * Create the backlog child connection for a listener
- *
- * Arguments:
- * parent: the listener daemon connection
- *
- * Return Value:
- * the child connection or NULL in failure
- *
- * Notes:
- * N/A
- */
-
-ks_tconn_t *
-ks_create_child_tconn(
- ks_tconn_t * parent
- )
-{
- NTSTATUS status;
- ks_tconn_t * backlog;
-
- /* allocate the tdi connecton object */
- backlog = ks_create_tconn();
-
- if (!backlog) {
- goto errorout;
- }
-
- /* initialize the tconn as a child */
- ks_init_child(backlog);
-
-
- /* now bind it */
- if (ks_bind_tconn(backlog, parent, 0, 0) < 0) {
- ks_free_tconn(backlog);
- backlog = NULL;
- goto errorout;
- }
-
- /* open the connection object */
- status = KsOpenConnection(
- &(backlog->kstc_dev),
- (PVOID)backlog,
- &(backlog->child.kstc_info.Handle),
- &(backlog->child.kstc_info.FileObject)
- );
-
- if (!NT_SUCCESS(status)) {
-
- ks_put_tconn(backlog);
- backlog = NULL;
- cfs_enter_debugger();
- goto errorout;
- }
-
- /* associate it now ... */
- status = KsAssociateAddress(
- backlog->kstc_addr.Handle,
- backlog->child.kstc_info.FileObject
- );
-
- if (!NT_SUCCESS(status)) {
-
- ks_put_tconn(backlog);
- backlog = NULL;
- cfs_enter_debugger();
- goto errorout;
- }
-
- backlog->kstc_state = ksts_associated;
-
-errorout:
-
- return backlog;
-}
-
-/*
- * ks_replenish_backlogs(
- * to replenish the backlogs listening...
- *
- * Arguments:
- * tconn: the parent listen tdi connect
- * nbacklog: number fo child connections in queue
- *
- * Return Value:
- * N/A
- *
- * Notes:
- * N/A
- */
-
-void
-ks_replenish_backlogs(
- ks_tconn_t * parent,
- int nbacklog
- )
-{
- ks_tconn_t * backlog;
- int n = 0;
-
- /* calculate how many backlogs needed */
- if ( ( parent->listener.kstc_listening.num +
- parent->listener.kstc_accepted.num ) < nbacklog ) {
- n = nbacklog - ( parent->listener.kstc_listening.num +
- parent->listener.kstc_accepted.num );
- } else {
- n = 0;
- }
-
- while (n--) {
-
- /* create the backlog child tconn */
- backlog = ks_create_child_tconn(parent);
-
- spin_lock(&(parent->kstc_lock));
-
- if (backlog) {
- spin_lock(&backlog->kstc_lock);
- /* attch it into the listing list of daemon */
- list_add( &backlog->child.kstc_link,
- &parent->listener.kstc_listening.list );
- parent->listener.kstc_listening.num++;
-
- backlog->child.kstc_queued = TRUE;
- spin_unlock(&backlog->kstc_lock);
- } else {
- cfs_enter_debugger();
- }
-
- spin_unlock(&(parent->kstc_lock));
- }
-}
-
-/*
- * ks_start_listen
- * setup the listener tdi connection and make it listen
- * on the user specified ip address and port.
- *
- * Arguments:
- * tconn: the parent listen tdi connect
- * nbacklog: number fo child connections in queue
- *
- * Return Value:
- * ks error code >=: success; otherwise error.
- *
- * Notes:
- * N/A
- */
-
-int
-ks_start_listen(ks_tconn_t *tconn, int nbacklog)
-{
- int rc = 0;
-
- /* now replenish the backlogs */
- ks_replenish_backlogs(tconn, nbacklog);
-
- /* set the event callback handlers */
- rc = KsSetHandlers(tconn);
-
- if (rc < 0) {
- return rc;
- }
-
- spin_lock(&(tconn->kstc_lock));
- tconn->listener.nbacklog = nbacklog;
- tconn->kstc_state = ksts_listening;
- cfs_set_flag(tconn->kstc_flags, KS_TCONN_DAEMON_STARTED);
- spin_unlock(&(tconn->kstc_lock));
-
- return rc;
-}
-
-void
-ks_stop_listen(ks_tconn_t *tconn)
-{
- struct list_head * list;
- ks_tconn_t * backlog;
-
- /* reset all tdi event callbacks to NULL */
- KsResetHandlers (tconn);
-
- spin_lock(&tconn->kstc_lock);
-
- cfs_clear_flag(tconn->kstc_flags, KS_TCONN_DAEMON_STARTED);
-
- /* cleanup all the listening backlog child connections */
- list_for_each (list, &(tconn->listener.kstc_listening.list)) {
- backlog = list_entry(list, ks_tconn_t, child.kstc_link);
-
- /* destory and free it */
- ks_put_tconn(backlog);
- }
-
- spin_unlock(&tconn->kstc_lock);
-
- /* wake up it from the waiting on new incoming connections */
- KeSetEvent(&tconn->listener.kstc_accept_event, 0, FALSE);
-
- /* free the listening daemon tconn */
- ks_put_tconn(tconn);
-}
-
-
-/*
- * ks_wait_child_tconn
- * accept a child connection from peer
- *
- * Arguments:
- * parent: the daemon tdi connection listening
- * child: to contain the accepted connection
- *
- * Return Value:
- * ks error code;
- *
- * Notes:
- * N/A
- */
-
-int
-ks_wait_child_tconn(
- ks_tconn_t * parent,
- ks_tconn_t ** child
- )
-{
- struct list_head * tmp;
- ks_tconn_t * backlog = NULL;
-
- ks_replenish_backlogs(parent, parent->listener.nbacklog);
-
- spin_lock(&(parent->kstc_lock));
-
- if (parent->listener.kstc_listening.num <= 0) {
- spin_unlock(&(parent->kstc_lock));
- return -1;
- }
-
-again:
-
- /* check the listening queue and try to search the accepted connecton */
-
- list_for_each(tmp, &(parent->listener.kstc_listening.list)) {
- backlog = list_entry (tmp, ks_tconn_t, child.kstc_link);
-
- spin_lock(&(backlog->kstc_lock));
-
- if (backlog->child.kstc_accepted) {
-
- LASSERT(backlog->kstc_state == ksts_connected);
- LASSERT(backlog->child.kstc_busy);
-
- list_del(&(backlog->child.kstc_link));
- list_add(&(backlog->child.kstc_link),
- &(parent->listener.kstc_accepted.list));
- parent->listener.kstc_accepted.num++;
- parent->listener.kstc_listening.num--;
- backlog->child.kstc_queueno = 1;
-
- spin_unlock(&(backlog->kstc_lock));
-
- break;
- } else {
- spin_unlock(&(backlog->kstc_lock));
- backlog = NULL;
- }
- }
-
- spin_unlock(&(parent->kstc_lock));
-
- /* we need wait until new incoming connections are requested
- or the case of shuting down the listenig daemon thread */
- if (backlog == NULL) {
-
- NTSTATUS Status;
-
- Status = KeWaitForSingleObject(
- &(parent->listener.kstc_accept_event),
- Executive,
- KernelMode,
- FALSE,
- NULL
- );
-
- spin_lock(&(parent->kstc_lock));
-
- /* check whether it's exptected to exit ? */
- if (!cfs_is_flag_set(parent->kstc_flags, KS_TCONN_DAEMON_STARTED)) {
- spin_unlock(&(parent->kstc_lock));
- } else {
- goto again;
- }
- }
-
- KsPrint((2, "ks_wait_child_tconn: connection %p accepted.\n", backlog));
-
- if (backlog) {
- /* query the local ip address of the connection */
- ks_query_local_ipaddr(backlog);
- } else {
- return -EINTR;
- }
- *child = backlog;
-
- return 0;
-}
-
-int
-ks_query_iovs_length(struct iovec *iov, int niov)
-{
- int i;
- int total = 0;
-
- LASSERT(iov != NULL);
- LASSERT(niov > 0);
-
- for (i=0; i < niov; i++) {
- total += iov[i].iov_len;
- }
-
- return total;
-}
-
-int
-ks_query_kiovs_length(lnet_kiov_t *kiov, int nkiov)
-{
- int i;
- int total = 0;
-
- LASSERT(kiov != NULL);
- LASSERT(nkiov > 0);
-
- for (i=0; i < nkiov; i++) {
- total += kiov[i].kiov_len;
- }
-
- return total;
-}
-
-int
-ks_sock_buf_cb(void *tsdu, int ns, int off, char **buf)
-{
- int rc = 0;
-
- if (off < ns) {
- *buf = (char *)tsdu + off;
- rc = ns - off;
- }
- return rc;
-}
-
-int
-ks_sock_iov_cb(void *tsdu, int ns, int off, char **buf)
-{
- int rc = 0, i;
- struct iovec *iov = tsdu;
-
- for (i=0; i < ns; i++) {
- if ((size_t)off >= iov[i].iov_len) {
- off -= iov[i].iov_len;
- } else {
- *buf = (char *)iov[i].iov_base + off;
- rc = iov[i].iov_len - off;
- break;
- }
- }
- return rc;
-}
-
-int
-ks_sock_kiov_cb(void *tsdu, int ns, int off, char **buf)
-{
- int rc = 0, i;
- lnet_kiov_t *kiov = tsdu;
-
- for (i=0; i < ns; i++) {
- if ((size_t)off >= kiov[i].kiov_len) {
- off -= kiov[i].kiov_len;
- } else {
- *buf = (char *)kiov[i].kiov_page->addr +
- kiov[i].kiov_offset + off;
- rc = kiov[i].kiov_len - off;
- break;
- }
- }
- return rc;
-}
-
-typedef int (*ks_tsdu_cb_t)(void *tsdu, int ns, int off, char **buf);
-
-int
-ks_sock_io(ks_tconn_t *tconn, void *tsdu, int ns, int reqlen,
- int flags, int timeout, int out, ks_tsdu_cb_t callback)
-{
- ULONG tflags;
- BOOLEAN expedited;
- PKS_TSDUMGR TsduMgr;
-
- int rc;
- int length;
- int total = 0;
- int64_t remained;
- PCHAR buffer;
- BOOLEAN async;
-
- LASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
- remained = (int64_t)cfs_time_seconds(timeout);
-
- /* query tsdu manager */
- expedited = cfs_is_flag_set(flags, MSG_OOB);
- TsduMgr = KsQueryTsduMgr(tconn, expedited, (BOOLEAN)out);
-
- /* check whether equest is nonblocking */
- if (async = cfs_is_flag_set(flags, MSG_DONTWAIT)) {
- timeout = 0;
- }
-
- ks_get_tconn(tconn);
- ks_lock_tsdumgr(TsduMgr);
- if ( tconn->kstc_type != kstt_sender &&
- tconn->kstc_type != kstt_child) {
- rc = -EINVAL;
- goto errorout;
- }
-
- while (length = callback(tsdu, ns, total, &buffer)) {
-
- /* check whether socket is stil valid */
- if (tconn->kstc_state != ksts_connected) {
- rc = -ENOTCONN;
- goto errorout;
- }
-
- if (out) {
- tflags = KsTdiSendFlags(flags);
- rc = KsWriteTsdus(TsduMgr, buffer, length, tflags);
- } else {
- tflags = KsTdiRecvFlags(flags);
- rc = KsReadTsdus(TsduMgr, buffer, length, tflags);
- }
-
- if (rc > 0) {
- total += rc;
- } else if (!async && rc == -EAGAIN) {
- if (timeout) {
- if (remained) {
- ks_unlock_tsdumgr(TsduMgr);
- remained = cfs_wait_event_internal(
- &TsduMgr->Event,
- remained );
- } else {
- goto errorout;
- }
- } else {
- ks_unlock_tsdumgr(TsduMgr);
- cfs_wait_event_internal(&TsduMgr->Event, 0);
- }
- ks_lock_tsdumgr(TsduMgr);
- } else {
- break;
- }
- }
-
-errorout:
-
- if (!out) {
- TsduMgr->Payload = reqlen - total;
- }
- ks_unlock_tsdumgr(TsduMgr);
-
- KsPrint((4, "ks_sock_io: tconn=%p tsdumgr=%p %c total=%xh/%xh rc=%d\n",
- tconn, TsduMgr, out?'W':'R', total, TsduMgr->TotalBytes, rc));
-
- if (total) {
- if (out) {
- /* signal Tdi sending engine */
- KsQueueTdiEngine(tconn, TsduMgr);
- }
- rc = total;
- }
-
- ks_put_tconn(tconn);
-
- LASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
- return rc;
-}
-
-int ks_send_buf(ks_tconn_t * tconn, char *buf,
- int len, int flags, int timeout)
-{
- return ks_sock_io(tconn, buf, len, len, flags,
- timeout, 1, ks_sock_buf_cb);
-}
-
-int ks_recv_buf(ks_tconn_t * tconn, char *buf,
- int len, int flags, int timeout)
-{
- return ks_sock_io(tconn, buf, len, len, flags,
- timeout, 0, ks_sock_buf_cb);
-}
-
-int ks_send_iovs(ks_tconn_t * tconn, struct iovec *iov,
- int niov, int flags, int timeout)
-{
- int reqlen = ks_query_iovs_length(iov, niov);
- return ks_sock_io(tconn, iov, niov, reqlen, flags,
- timeout, TRUE, ks_sock_iov_cb);
-}
-
-int ks_recv_iovs(ks_tconn_t * tconn, struct iovec *iov,
- int niov, int flags, int timeout)
-{
- int reqlen = ks_query_iovs_length(iov, niov);
- return ks_sock_io(tconn, iov, niov, reqlen, flags,
- timeout, FALSE, ks_sock_iov_cb);
-}
-
-int ks_send_kiovs(ks_tconn_t * tconn, lnet_kiov_t *kiov,
- int nkiov, int flags, int timeout)
-{
- int reqlen = ks_query_kiovs_length(kiov, nkiov);
- return ks_sock_io(tconn, kiov, nkiov, reqlen, flags,
- timeout, TRUE, ks_sock_kiov_cb);
-}
-
-int ks_recv_kiovs(ks_tconn_t * tconn, lnet_kiov_t *kiov,
- int nkiov, int flags, int timeout)
-{
- int reqlen = ks_query_kiovs_length(kiov, nkiov);
- return ks_sock_io(tconn, kiov, nkiov, reqlen, flags,
- timeout, FALSE, ks_sock_kiov_cb);
-}
-
-int libcfs_ipif_query(char *name, int *up, __u32 *ip, __u32 *mask)
-{
- ks_addr_slot_t * slot = NULL;
- PLIST_ENTRY list = NULL;
-
- spin_lock(&ks_data.ksnd_addrs_lock);
-
- list = ks_data.ksnd_addrs_list.Flink;
- while (list != &ks_data.ksnd_addrs_list) {
- slot = CONTAINING_RECORD(list, ks_addr_slot_t, link);
- if (_stricmp(name, &slot->iface[0]) == 0) {
- *up = slot->up;
- *ip = slot->ip_addr;
- *mask = slot->netmask;
- break;
- }
- list = list->Flink;
- slot = NULL;
- }
-
- spin_unlock(&ks_data.ksnd_addrs_lock);
-
- return (int)(slot == NULL);
-}
-
-int libcfs_ipif_enumerate(char ***names)
-{
- ks_addr_slot_t * slot = NULL;
- PLIST_ENTRY list = NULL;
- int nips = 0;
-
- spin_lock(&ks_data.ksnd_addrs_lock);
-
- *names = kmalloc(sizeof(char *) * ks_data.ksnd_naddrs, __GFP_ZERO);
- if (*names == NULL) {
- goto errorout;
- }
-
- list = ks_data.ksnd_addrs_list.Flink;
- while (list != &ks_data.ksnd_addrs_list) {
- slot = CONTAINING_RECORD(list, ks_addr_slot_t, link);
- list = list->Flink;
- (*names)[nips++] = slot->iface;
- cfs_assert(nips <= ks_data.ksnd_naddrs);
- }
-
- cfs_assert(nips == ks_data.ksnd_naddrs);
-
-errorout:
-
- spin_unlock(&ks_data.ksnd_addrs_lock);
- return nips;
-}
-
-void libcfs_ipif_free_enumeration(char **names, int n)
-{
- if (names) {
- kfree(names);
- }
-}
-
-int libcfs_sock_listen(struct socket **sockp, __u32 ip, int port, int backlog)
-{
- int rc = 0;
- ks_tconn_t * parent;
-
- parent = ks_create_tconn();
- if (!parent) {
- rc = -ENOMEM;
- goto errorout;
- }
-
- /* initialize the tconn as a listener */
- ks_init_listener(parent);
-
- /* bind the daemon->tconn */
- rc = ks_bind_tconn(parent, NULL, ip, (unsigned short)port);
-
- if (rc < 0) {
- ks_free_tconn(parent);
- goto errorout;
- }
-
- /* create listening children and make it to listen state*/
- rc = ks_start_listen(parent, backlog);
- if (rc < 0) {
- ks_stop_listen(parent);
- goto errorout;
- }
-
- *sockp = parent;
-
-errorout:
-
- return rc;
-}
-
-int libcfs_sock_accept(struct socket **newsockp, struct socket *sock)
-{
- /* wait for incoming connecitons */
- return ks_wait_child_tconn(sock, newsockp);
-}
-
-void libcfs_sock_abort_accept(struct socket *sock)
-{
- LASSERT(sock->kstc_type == kstt_listener);
-
- spin_lock(&(sock->kstc_lock));
-
- /* clear the daemon flag */
- cfs_clear_flag(sock->kstc_flags, KS_TCONN_DAEMON_STARTED);
-
- /* wake up it from the waiting on new incoming connections */
- KeSetEvent(&sock->listener.kstc_accept_event, 0, FALSE);
-
- spin_unlock(&(sock->kstc_lock));
-}
-
-/*
- * libcfs_sock_connect
- * build a conntion between local ip/port and the peer ip/port.
- *
- * Arguments:
- * laddr: local ip address
- * lport: local port number
- * paddr: peer's ip address
- * pport: peer's port number
- *
- * Return Value:
- * int: return code ...
- *
- * Notes:
- * N/A
- */
-
-
-int libcfs_sock_connect(struct socket **sockp, int *fatal,
- __u32 local_ip, int local_port,
- __u32 peer_ip, int peer_port)
-{
- ks_tconn_t * tconn = NULL;
- int rc = 0;
-
- *sockp = NULL;
- if (fatal) *fatal = 0;
-
- KsPrint((2, "libcfs_sock_connect: connecting to %x:%d with %x:%d...\n",
- peer_ip, peer_port, local_ip, local_port ));
-
- /* create the tdi connecion structure */
- tconn = ks_create_tconn();
- if (!tconn) {
- rc = -ENOMEM;
- goto errorout;
- }
-
- /* initialize the tdi sender connection */
- ks_init_sender(tconn);
-
- /* bind the local ip address with the tconn */
- rc = ks_bind_tconn(tconn, NULL, local_ip, (unsigned short)local_port);
- if (rc < 0) {
- KsPrint((1, "libcfs_sock_connect: failed to bind address %x:%d...\n",
- local_ip, local_port ));
- ks_free_tconn(tconn);
- goto errorout;
- }
-
- /* connect to the remote peer */
- rc = ks_build_tconn(tconn, peer_ip, (unsigned short)peer_port);
- if (rc < 0) {
- KsPrint((1, "libcfs_sock_connect: failed to connect %x:%d ...\n",
- peer_ip, peer_port ));
-
- ks_put_tconn(tconn);
- goto errorout;
- }
-
- *sockp = tconn;
-
-errorout:
-
- return rc;
-}
-
-int libcfs_sock_setbuf(struct socket *socket, int txbufsize, int rxbufsize)
-{
- return 0;
-}
-
-int libcfs_sock_getbuf(struct socket *socket, int *txbufsize, int *rxbufsize)
-{
- return 0;
-}
-
-int libcfs_sock_getaddr(struct socket *socket, int remote, __u32 *ip, int *port)
-{
- PTRANSPORT_ADDRESS taddr = NULL;
-
- spin_lock(&socket->kstc_lock);
- if (remote) {
- if (socket->kstc_type == kstt_sender) {
- taddr = socket->sender.kstc_info.Remote;
- } else if (socket->kstc_type == kstt_child) {
- taddr = socket->child.kstc_info.Remote;
- }
- } else {
- taddr = &(socket->kstc_addr.Tdi);
- }
-
- if (taddr) {
- PTDI_ADDRESS_IP addr = (PTDI_ADDRESS_IP)(&(taddr->Address[0].Address));
- if (ip != NULL)
- *ip = ntohl (addr->in_addr);
- if (port != NULL)
- *port = ntohs (addr->sin_port);
- } else {
- spin_unlock(&socket->kstc_lock);
- return -ENOTCONN;
- }
-
- spin_unlock(&socket->kstc_lock);
- return 0;
-}
-
-int libcfs_sock_write(struct socket *sock, void *buffer, int nob, int timeout)
-{
- int rc;
- int offset = 0;
-
- while (nob > offset) {
-
- rc = ks_send_buf(sock, (char *)buffer + offset, nob - offset, 0, timeout);
-
- if (rc <= 0) {
- goto errorout;
- } else {
- offset += rc;
- rc = 0;
- }
- }
-
-errorout:
-
- KsPrint((4, "libcfs_sock_write: sock: %p %d bytes rc: %d\n", sock, offset, rc));
- return rc;
-}
-
-int libcfs_sock_read(struct socket *sock, void *buffer, int nob, int timeout)
-{
- int rc = 0;
- int offset = 0;
-
- while (nob > offset) {
-
- rc = ks_recv_buf(sock, (char *)buffer + offset, nob - offset, 0, timeout);
-
- if (rc <= 0) {
- goto errorout;
- } else {
- offset += rc;
- rc = 0;
- }
- }
-
-errorout:
-
- KsPrint((4, "libcfs_sock_read: sock: %p %d bytes rc: %d\n", sock, offset, rc));
- return rc;
-}
-
-void libcfs_sock_release(struct socket *sock)
-{
- if (sock->kstc_type == kstt_listener &&
- sock->kstc_state == ksts_listening) {
- ks_stop_listen(sock);
- } else {
- ks_put_tconn(sock);
- }
-}
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#define DEBUG_SUBSYSTEM S_LNET
-#define LUSTRE_TRACEFILE_PRIVATE
-
-#include <libcfs/libcfs.h>
-#include "tracefile.h"
-
-/* percents to share the total debug memory for each type */
-static unsigned int pages_factor[CFS_TCD_TYPE_MAX] = {
- 90, /* 90% pages for CFS_TCD_TYPE_PASSIVE */
- 10 /* 10% pages for CFS_TCD_TYPE_DISPATCH */
-};
-
-char *cfs_trace_console_buffers[NR_CPUS][CFS_TCD_TYPE_MAX];
-
-struct rw_semaphore cfs_tracefile_sem;
-
-int cfs_tracefile_init_arch()
-{
- int i;
- int j;
- struct cfs_trace_cpu_data *tcd;
-
- init_rwsem(&cfs_tracefile_sem);
-
- /* initialize trace_data */
- memset(cfs_trace_data, 0, sizeof(cfs_trace_data));
- for (i = 0; i < CFS_TCD_TYPE_MAX; i++) {
- cfs_trace_data[i] =
- kmalloc(sizeof(union cfs_trace_data_union) * \
- NR_CPUS, GFP_KERNEL);
- if (cfs_trace_data[i] == NULL)
- goto out;
- }
-
- /* arch related info initialized */
- cfs_tcd_for_each(tcd, i, j) {
- tcd->tcd_pages_factor = (USHORT) pages_factor[i];
- tcd->tcd_type = (USHORT) i;
- tcd->tcd_cpu = (USHORT)j;
- }
-
- for (i = 0; i < num_possible_cpus(); i++)
- for (j = 0; j < CFS_TCD_TYPE_MAX; j++) {
- cfs_trace_console_buffers[i][j] =
- kmalloc(CFS_TRACE_CONSOLE_BUFFER_SIZE,
- GFP_KERNEL);
-
- if (cfs_trace_console_buffers[i][j] == NULL)
- goto out;
- }
-
- return 0;
-
-out:
- cfs_tracefile_fini_arch();
- printk(KERN_ERR "lnet: Not enough memory\n");
- return -ENOMEM;
-
-}
-
-void cfs_tracefile_fini_arch()
-{
- int i;
- int j;
-
- for (i = 0; i < num_possible_cpus(); i++) {
- for (j = 0; j < CFS_TCD_TYPE_MAX; j++) {
- if (cfs_trace_console_buffers[i][j] != NULL) {
- kfree(cfs_trace_console_buffers[i][j]);
- cfs_trace_console_buffers[i][j] = NULL;
- }
- }
- }
-
- for (i = 0; cfs_trace_data[i] != NULL; i++) {
- kfree(cfs_trace_data[i]);
- cfs_trace_data[i] = NULL;
- }
-
- fini_rwsem(&cfs_tracefile_sem);
-}
-
-void cfs_tracefile_read_lock()
-{
- down_read(&cfs_tracefile_sem);
-}
-
-void cfs_tracefile_read_unlock()
-{
- up_read(&cfs_tracefile_sem);
-}
-
-void cfs_tracefile_write_lock()
-{
- down_write(&cfs_tracefile_sem);
-}
-
-void cfs_tracefile_write_unlock()
-{
- up_write(&cfs_tracefile_sem);
-}
-
-cfs_trace_buf_type_t cfs_trace_buf_idx_get()
-{
- if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
- return CFS_TCD_TYPE_DISPATCH;
- else
- return CFS_TCD_TYPE_PASSIVE;
-}
-
-int cfs_trace_lock_tcd(struct cfs_trace_cpu_data *tcd, int walking)
-{
- __LASSERT(tcd->tcd_type < CFS_TCD_TYPE_MAX);
- return 1;
-}
-
-void cfs_trace_unlock_tcd(struct cfs_trace_cpu_data *tcd, int walking)
-{
- __LASSERT(tcd->tcd_type < CFS_TCD_TYPE_MAX);
-}
-
-int cfs_tcd_owns_tage(struct cfs_trace_cpu_data *tcd,
- struct cfs_trace_page *tage)
-{
- /*
- * XXX nikita: do NOT call portals_debug_msg() (CDEBUG/ENTRY/EXIT)
- * from here: this will lead to infinite recursion.
- */
- return tcd->tcd_cpu == tage->cpu;
-}
-
-void
-cfs_set_ptldebug_header(struct ptldebug_header *header, int subsys, int mask,
- const int line, unsigned long stack)
-{
- struct timeval tv;
-
- do_gettimeofday(&tv);
-
- header->ph_subsys = subsys;
- header->ph_mask = mask;
- header->ph_cpu_id = smp_processor_id();
- header->ph_type = cfs_trace_buf_idx_get();
- header->ph_sec = (__u32)tv.tv_sec;
- header->ph_usec = tv.tv_usec;
- header->ph_stack = stack;
- header->ph_pid = (__u32)(ULONG_PTR)current->pid;
- header->ph_line_num = line;
- header->ph_extern_pid = 0;
- return;
-}
-
-void cfs_print_to_console(struct ptldebug_header *hdr, int mask,
- const char *buf, int len, const char *file,
- const char *fn)
-{
- char *prefix = "Lustre", *ptype = NULL;
-
- if ((mask & D_EMERG) != 0) {
- prefix = "LustreError";
- ptype = KERN_EMERG;
- } else if ((mask & D_ERROR) != 0) {
- prefix = "LustreError";
- ptype = KERN_ERR;
- } else if ((mask & D_WARNING) != 0) {
- prefix = "Lustre";
- ptype = KERN_WARNING;
- } else if ((mask & (D_CONSOLE | libcfs_printk)) != 0) {
- prefix = "Lustre";
- ptype = KERN_INFO;
- }
-
- if ((mask & D_CONSOLE) != 0) {
- printk("%s%s: %.*s", ptype, prefix, len, buf);
- } else {
- printk("%s%s: %d:%d:(%s:%d:%s()) %.*s", ptype, prefix, hdr->ph_pid,
- hdr->ph_extern_pid, file, hdr->ph_line_num, fn, len, buf);
- }
- return;
-}
-
-int cfs_trace_max_debug_mb(void)
-{
- int total_mb = (totalram_pages >> (20 - PAGE_CACHE_SHIFT));
-
- return MAX(512, (total_mb * 80)/100);
-}
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#ifndef __LIBCFS_WINNT_TRACEFILE_H__
-#define __LIBCFS_WINNT_TRACEFILE_H__
-
-/**
- * only define one trace_data type for windows
- */
-typedef enum {
- CFS_TCD_TYPE_PASSIVE = 0,
- CFS_TCD_TYPE_DISPATCH,
- CFS_TCD_TYPE_MAX
-} cfs_trace_buf_type_t;
-
-#endif
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#ifndef __KERNEL__
-
-#define _NTDDK_
-#include <windows.h>
-#include <libcfs/libcfs.h>
-
-void sleep(int time)
-{
- DWORD Time = 1000 * time;
- Sleep(Time);
-}
-
-void print_last_error(char* Prefix)
-{
- LPVOID lpMsgBuf;
-
- FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- GetLastError(),
- 0,
- (LPTSTR) &lpMsgBuf,
- 0,
- NULL
- );
-
- printf("%s %s", Prefix, (LPTSTR) lpMsgBuf);
-
- LocalFree(lpMsgBuf);
-}
-
-
-int gethostname(char * name, int namelen)
-{
- return 0;
-}
-
-int ioctl (
- int handle,
- int cmd,
- void *buffer
- )
-{
- printf("hello, world\n");
- return 0;
-}
-
-
-/*
- * getopt structures & routines
- */
-
-
-/* Data type for reentrant functions. */
-struct _getopt_data
-{
- /* These have exactly the same meaning as the corresponding global
- variables, except that they are used for the reentrant
- versions of getopt. */
- int optind;
- int opterr;
- int optopt;
- char *optarg;
-
- /* Internal members. */
-
- /* True if the internal members have been initialized. */
- int __initialized;
-
- /* The next char to be scanned in the option-element
- in which the last option character we returned was found.
- This allows us to pick up the scan where we left off.
-
- If this is zero, or a null string, it means resume the scan
- by advancing to the next ARGV-element. */
- char *__nextchar;
-
- /* Describe how to deal with options that follow non-option ARGV-elements.
-
- If the caller did not specify anything,
- the default is REQUIRE_ORDER if the environment variable
- POSIXLY_CORRECT is defined, PERMUTE otherwise.
-
- REQUIRE_ORDER means don't recognize them as options;
- stop option processing when the first non-option is seen.
- This is what Unix does.
- This mode of operation is selected by either setting the environment
- variable POSIXLY_CORRECT, or using `+' as the first character
- of the list of option characters.
-
- PERMUTE is the default. We permute the contents of ARGV as we
- scan, so that eventually all the non-options are at the end.
- This allows options to be given in any order, even with programs
- that were not written to expect this.
-
- RETURN_IN_ORDER is an option available to programs that were
- written to expect options and other ARGV-elements in any order
- and that care about the ordering of the two. We describe each
- non-option ARGV-element as if it were the argument of an option
- with character code 1. Using `-' as the first character of the
- list of option characters selects this mode of operation.
-
- The special argument `--' forces an end of option-scanning regardless
- of the value of `ordering'. In the case of RETURN_IN_ORDER, only
- `--' can cause `getopt' to return -1 with `optind' != ARGC. */
-
- enum
- {
- REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
- } __ordering;
-
- /* If the POSIXLY_CORRECT environment variable is set. */
- int __posixly_correct;
-
-
- /* Handle permutation of arguments. */
-
- /* Describe the part of ARGV that contains non-options that have
- been skipped. `first_nonopt' is the index in ARGV of the first
- of them; `last_nonopt' is the index after the last of them. */
-
- int __first_nonopt;
- int __last_nonopt;
-};
-
-/* For communication from `getopt' to the caller.
- When `getopt' finds an option that takes an argument,
- the argument value is returned here.
- Also, when `ordering' is RETURN_IN_ORDER,
- each non-option ARGV-element is returned here. */
-
-char *optarg;
-
-/* Index in ARGV of the next element to be scanned.
- This is used for communication to and from the caller
- and for communication between successive calls to `getopt'.
-
- On entry to `getopt', zero means this is the first call; initialize.
-
- When `getopt' returns -1, this is the index of the first of the
- non-option elements that the caller should itself scan.
-
- Otherwise, `optind' communicates from one call to the next
- how much of ARGV has been scanned so far. */
-
-/* 1003.2 says this must be 1 before any call. */
-int optind = 1;
-
-/* Callers store zero here to inhibit the error message
- for unrecognized options. */
-
-int opterr = 1;
-
-/* Set to an option character which was unrecognized.
- This must be initialized on some systems to avoid linking in the
- system's own getopt implementation. */
-
-int optopt = '?';
-
-/* Keep a global copy of all internal members of getopt_data. */
-
-static struct _getopt_data getopt_data;
-
-
-/* Initialize the internal data when the first call is made. */
-
-static const char *
-_getopt_initialize (int argc, char *const *argv, const char *optstring,
- struct _getopt_data *d)
-{
- /* Start processing options with ARGV-element 1 (since ARGV-element 0
- is the program name); the sequence of previously skipped
- non-option ARGV-elements is empty. */
-
- d->__first_nonopt = d->__last_nonopt = d->optind;
-
- d->__nextchar = NULL;
-
- d->__posixly_correct = 0;
-
- /* Determine how to handle the ordering of options and nonoptions. */
-
- if (optstring[0] == '-')
- {
- d->__ordering = RETURN_IN_ORDER;
- ++optstring;
- }
- else if (optstring[0] == '+')
- {
- d->__ordering = REQUIRE_ORDER;
- ++optstring;
- }
- else if (d->__posixly_correct)
- d->__ordering = REQUIRE_ORDER;
- else
- d->__ordering = PERMUTE;
-
- return optstring;
-}
-
-/* Scan elements of ARGV (whose length is ARGC) for option characters
- given in OPTSTRING.
-
- If an element of ARGV starts with '-', and is not exactly "-" or "--",
- then it is an option element. The characters of this element
- (aside from the initial '-') are option characters. If `getopt'
- is called repeatedly, it returns successively each of the option characters
- from each of the option elements.
-
- If `getopt' finds another option character, it returns that character,
- updating `optind' and `nextchar' so that the next call to `getopt' can
- resume the scan with the following option character or ARGV-element.
-
- If there are no more option characters, `getopt' returns -1.
- Then `optind' is the index in ARGV of the first ARGV-element
- that is not an option. (The ARGV-elements have been permuted
- so that those that are not options now come last.)
-
- OPTSTRING is a string containing the legitimate option characters.
- If an option character is seen that is not listed in OPTSTRING,
- return '?' after printing an error message. If you set `opterr' to
- zero, the error message is suppressed but we still return '?'.
-
- If a char in OPTSTRING is followed by a colon, that means it wants an arg,
- so the following text in the same ARGV-element, or the text of the following
- ARGV-element, is returned in `optarg'. Two colons mean an option that
- wants an optional arg; if there is text in the current ARGV-element,
- it is returned in `optarg', otherwise `optarg' is set to zero.
-
- If OPTSTRING starts with `-' or `+', it requests different methods of
- handling the non-option ARGV-elements.
- See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
-
- Long-named options begin with `--' instead of `-'.
- Their names may be abbreviated as long as the abbreviation is unique
- or is an exact match for some defined option. If they have an
- argument, it follows the option name in the same ARGV-element, separated
- from the option name by a `=', or else the in next ARGV-element.
- When `getopt' finds a long-named option, it returns 0 if that option's
- `flag' field is nonzero, the value of the option's `val' field
- if the `flag' field is zero.
-
- The elements of ARGV aren't really const, because we permute them.
- But we pretend they're const in the prototype to be compatible
- with other systems.
-
- LONGOPTS is a vector of `struct option' terminated by an
- element containing a name which is zero.
-
- LONGIND returns the index in LONGOPT of the long-named option found.
- It is only valid when a long-named option has been found by the most
- recent call.
-
- If LONG_ONLY is nonzero, '-' as well as '--' can introduce
- long-named options. */
-
-/* Exchange two adjacent subsequences of ARGV.
- One subsequence is elements [first_nonopt,last_nonopt)
- which contains all the non-options that have been skipped so far.
- The other is elements [last_nonopt,optind), which contains all
- the options processed since those non-options were skipped.
-
- `first_nonopt' and `last_nonopt' are relocated so that they describe
- the new indices of the non-options in ARGV after they are moved. */
-
-#define SWAP_FLAGS(ch1, ch2)
-
-static void
-exchange (char **argv, struct _getopt_data *d)
-{
- int bottom = d->__first_nonopt;
- int middle = d->__last_nonopt;
- int top = d->optind;
- char *tem;
-
- /* Exchange the shorter segment with the far end of the longer segment.
- That puts the shorter segment into the right place.
- It leaves the longer segment in the right place overall,
- but it consists of two parts that need to be swapped next. */
-
- while (top > middle && middle > bottom)
- {
- if (top - middle > middle - bottom)
- {
- /* Bottom segment is the short one. */
- int len = middle - bottom;
- register int i;
-
- /* Swap it with the top part of the top segment. */
- for (i = 0; i < len; i++)
- {
- tem = argv[bottom + i];
- argv[bottom + i] = argv[top - (middle - bottom) + i];
- argv[top - (middle - bottom) + i] = tem;
- SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
- }
- /* Exclude the moved bottom segment from further swapping. */
- top -= len;
- }
- else
- {
- /* Top segment is the short one. */
- int len = top - middle;
- register int i;
-
- /* Swap it with the bottom part of the bottom segment. */
- for (i = 0; i < len; i++)
- {
- tem = argv[bottom + i];
- argv[bottom + i] = argv[middle + i];
- argv[middle + i] = tem;
- SWAP_FLAGS (bottom + i, middle + i);
- }
- /* Exclude the moved top segment from further swapping. */
- bottom += len;
- }
- }
-
- /* Update records for the slots the non-options now occupy. */
-
- d->__first_nonopt += (d->optind - d->__last_nonopt);
- d->__last_nonopt = d->optind;
-}
-
-int
-_getopt_internal_r (int argc, char *const *argv, const char *optstring,
- const struct option *longopts, int *longind,
- int long_only, struct _getopt_data *d)
-{
- int print_errors = d->opterr;
- if (optstring[0] == ':')
- print_errors = 0;
-
- if (argc < 1)
- return -1;
-
- d->optarg = NULL;
-
- if (d->optind == 0 || !d->__initialized)
- {
- if (d->optind == 0)
- d->optind = 1; /* Don't scan ARGV[0], the program name. */
- optstring = _getopt_initialize (argc, argv, optstring, d);
- d->__initialized = 1;
- }
-
- /* Test whether ARGV[optind] points to a non-option argument.
- Either it does not have option syntax, or there is an environment flag
- from the shell indicating it is not an option. The later information
- is only used when the used in the GNU libc. */
-
-# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')
-
- if (d->__nextchar == NULL || *d->__nextchar == '\0')
- {
- /* Advance to the next ARGV-element. */
-
- /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
- moved back by the user (who may also have changed the arguments). */
- if (d->__last_nonopt > d->optind)
- d->__last_nonopt = d->optind;
- if (d->__first_nonopt > d->optind)
- d->__first_nonopt = d->optind;
-
- if (d->__ordering == PERMUTE)
- {
- /* If we have just processed some options following some non-options,
- exchange them so that the options come first. */
-
- if (d->__first_nonopt != d->__last_nonopt
- && d->__last_nonopt != d->optind)
- exchange ((char **) argv, d);
- else if (d->__last_nonopt != d->optind)
- d->__first_nonopt = d->optind;
-
- /* Skip any additional non-options
- and extend the range of non-options previously skipped. */
-
- while (d->optind < argc && NONOPTION_P)
- d->optind++;
- d->__last_nonopt = d->optind;
- }
-
- /* The special ARGV-element `--' means premature end of options.
- Skip it like a null option,
- then exchange with previous non-options as if it were an option,
- then skip everything else like a non-option. */
-
- if (d->optind != argc && !strcmp (argv[d->optind], "--"))
- {
- d->optind++;
-
- if (d->__first_nonopt != d->__last_nonopt
- && d->__last_nonopt != d->optind)
- exchange ((char **) argv, d);
- else if (d->__first_nonopt == d->__last_nonopt)
- d->__first_nonopt = d->optind;
- d->__last_nonopt = argc;
-
- d->optind = argc;
- }
-
- /* If we have done all the ARGV-elements, stop the scan
- and back over any non-options that we skipped and permuted. */
-
- if (d->optind == argc)
- {
- /* Set the next-arg-index to point at the non-options
- that we previously skipped, so the caller will digest them. */
- if (d->__first_nonopt != d->__last_nonopt)
- d->optind = d->__first_nonopt;
- return -1;
- }
-
- /* If we have come to a non-option and did not permute it,
- either stop the scan or describe it to the caller and pass it by. */
-
- if (NONOPTION_P)
- {
- if (d->__ordering == REQUIRE_ORDER)
- return -1;
- d->optarg = argv[d->optind++];
- return 1;
- }
-
- /* We have found another option-ARGV-element.
- Skip the initial punctuation. */
-
- d->__nextchar = (argv[d->optind] + 1
- + (longopts != NULL && argv[d->optind][1] == '-'));
- }
-
- /* Decode the current option-ARGV-element. */
-
- /* Check whether the ARGV-element is a long option.
-
- If long_only and the ARGV-element has the form "-f", where f is
- a valid short option, don't consider it an abbreviated form of
- a long option that starts with f. Otherwise there would be no
- way to give the -f short option.
-
- On the other hand, if there's a long option "fubar" and
- the ARGV-element is "-fu", do consider that an abbreviation of
- the long option, just like "--fu", and not "-f" with arg "u".
-
- This distinction seems to be the most useful approach. */
-
- if (longopts != NULL
- && (argv[d->optind][1] == '-'
- || (long_only && (argv[d->optind][2]
- || !strchr (optstring, argv[d->optind][1])))))
- {
- char *nameend;
- const struct option *p;
- const struct option *pfound = NULL;
- int exact = 0;
- int ambig = 0;
- int indfound = -1;
- int option_index;
-
- for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++)
- /* Do nothing. */ ;
-
- /* Test all long options for either exact match
- or abbreviated matches. */
- for (p = longopts, option_index = 0; p->name; p++, option_index++)
- if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
- {
- if ((unsigned int) (nameend - d->__nextchar)
- == (unsigned int) strlen (p->name))
- {
- /* Exact match found. */
- pfound = p;
- indfound = option_index;
- exact = 1;
- break;
- }
- else if (pfound == NULL)
- {
- /* First nonexact match found. */
- pfound = p;
- indfound = option_index;
- }
- else if (long_only
- || pfound->has_arg != p->has_arg
- || pfound->flag != p->flag
- || pfound->val != p->val)
- /* Second or later nonexact match found. */
- ambig = 1;
- }
-
- if (ambig && !exact)
- {
- if (print_errors)
- {
- fprintf (stderr, "%s: option '%s' is ambiguous\n",
- argv[0], argv[d->optind]);
- }
- d->__nextchar += strlen (d->__nextchar);
- d->optind++;
- d->optopt = 0;
- return '?';
- }
-
- if (pfound != NULL)
- {
- option_index = indfound;
- d->optind++;
- if (*nameend)
- {
- /* Don't test has_arg with >, because some C compilers don't
- allow it to be used on enums. */
- if (pfound->has_arg)
- d->optarg = nameend + 1;
- else
- {
- if (print_errors)
- {
-
- if (argv[d->optind - 1][1] == '-')
- {
- /* --option */
- fprintf (stderr, "%s: option '--%s' doesn't allow an argument\n",
- argv[0], pfound->name);
- }
- else
- {
- /* +option or -option */
- fprintf (stderr, "%s: option '%c%s' doesn't allow an argument\n",
- argv[0], argv[d->optind - 1][0],
- pfound->name);
- }
-
- }
-
- d->__nextchar += strlen (d->__nextchar);
-
- d->optopt = pfound->val;
- return '?';
- }
- }
- else if (pfound->has_arg == 1)
- {
- if (d->optind < argc)
- d->optarg = argv[d->optind++];
- else
- {
- if (print_errors)
- {
- fprintf (stderr,
- "%s: option '%s' requires an argument\n",
- argv[0], argv[d->optind - 1]);
- }
- d->__nextchar += strlen (d->__nextchar);
- d->optopt = pfound->val;
- return optstring[0] == ':' ? ':' : '?';
- }
- }
- d->__nextchar += strlen (d->__nextchar);
- if (longind != NULL)
- *longind = option_index;
- if (pfound->flag)
- {
- *(pfound->flag) = pfound->val;
- return 0;
- }
- return pfound->val;
- }
-
- /* Can't find it as a long option. If this is not getopt_long_only,
- or the option starts with '--' or is not a valid short
- option, then it's an error.
- Otherwise interpret it as a short option. */
- if (!long_only || argv[d->optind][1] == '-'
- || strchr (optstring, *d->__nextchar) == NULL)
- {
- if (print_errors)
- {
- if (argv[d->optind][1] == '-')
- {
- /* --option */
-
- fprintf (stderr, "%s: unrecognized option '--%s'\n",
- argv[0], d->__nextchar);
- }
- else
- {
- /* +option or -option */
- fprintf (stderr, "%s: unrecognized option '%c%s'\n",
- argv[0], argv[d->optind][0], d->__nextchar);
- }
-
-
- }
- d->__nextchar = (char *) "";
- d->optind++;
- d->optopt = 0;
- return '?';
- }
- }
-
- /* Look at and handle the next short option-character. */
-
- {
- char c = *d->__nextchar++;
- char *temp = strchr (optstring, c);
-
- /* Increment `optind' when we start to process its last character. */
- if (*d->__nextchar == '\0')
- ++d->optind;
-
- if (temp == NULL || c == ':')
- {
- if (print_errors)
- {
- fprintf (stderr, "%s: invalid option -- '%c'\n", argv[0], c);
- }
- d->optopt = c;
- return '?';
- }
- /* Convenience. Treat POSIX -W foo same as long option --foo */
- if (temp[0] == 'W' && temp[1] == ';')
- {
- char *nameend;
- const struct option *p;
- const struct option *pfound = NULL;
- int exact = 0;
- int ambig = 0;
- int indfound = 0;
- int option_index;
-
- /* This is an option that requires an argument. */
- if (*d->__nextchar != '\0')
- {
- d->optarg = d->__nextchar;
- /* If we end this ARGV-element by taking the rest as an arg,
- we must advance to the next element now. */
- d->optind++;
- }
- else if (d->optind == argc)
- {
- if (print_errors)
- {
- fprintf (stderr,
- "%s: option requires an argument -- '%c'\n",
- argv[0], c);
- }
- d->optopt = c;
- if (optstring[0] == ':')
- c = ':';
- else
- c = '?';
- return c;
- }
- else
- /* We already incremented `d->optind' once;
- increment it again when taking next ARGV-elt as argument. */
- d->optarg = argv[d->optind++];
-
- /* optarg is now the argument, see if it's in the
- table of longopts. */
-
- for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '=';
- nameend++)
- /* Do nothing. */ ;
-
- /* Test all long options for either exact match
- or abbreviated matches. */
- for (p = longopts, option_index = 0; p->name; p++, option_index++)
- if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
- {
- if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name))
- {
- /* Exact match found. */
- pfound = p;
- indfound = option_index;
- exact = 1;
- break;
- }
- else if (pfound == NULL)
- {
- /* First nonexact match found. */
- pfound = p;
- indfound = option_index;
- }
- else
- /* Second or later nonexact match found. */
- ambig = 1;
- }
- if (ambig && !exact)
- {
- if (print_errors)
- {
- fprintf (stderr, "%s: option '-W %s' is ambiguous\n",
- argv[0], argv[d->optind]);
- }
- d->__nextchar += strlen (d->__nextchar);
- d->optind++;
- return '?';
- }
- if (pfound != NULL)
- {
- option_index = indfound;
- if (*nameend)
- {
- /* Don't test has_arg with >, because some C compilers don't
- allow it to be used on enums. */
- if (pfound->has_arg)
- d->optarg = nameend + 1;
- else
- {
- if (print_errors)
- {
- fprintf (stderr, "\
-%s: option '-W %s' doesn't allow an argument\n",
- argv[0], pfound->name);
- }
-
- d->__nextchar += strlen (d->__nextchar);
- return '?';
- }
- }
- else if (pfound->has_arg == 1)
- {
- if (d->optind < argc)
- d->optarg = argv[d->optind++];
- else
- {
- if (print_errors)
- {
-
- fprintf (stderr,
- "%s: option '%s' requires an argument\n",
- argv[0], argv[d->optind - 1]);
- }
- d->__nextchar += strlen (d->__nextchar);
- return optstring[0] == ':' ? ':' : '?';
- }
- }
- d->__nextchar += strlen (d->__nextchar);
- if (longind != NULL)
- *longind = option_index;
- if (pfound->flag)
- {
- *(pfound->flag) = pfound->val;
- return 0;
- }
- return pfound->val;
- }
- d->__nextchar = NULL;
- return 'W'; /* Let the application handle it. */
- }
- if (temp[1] == ':')
- {
- if (temp[2] == ':')
- {
- /* This is an option that accepts an argument optionally. */
- if (*d->__nextchar != '\0')
- {
- d->optarg = d->__nextchar;
- d->optind++;
- }
- else
- d->optarg = NULL;
- d->__nextchar = NULL;
- }
- else
- {
- /* This is an option that requires an argument. */
- if (*d->__nextchar != '\0')
- {
- d->optarg = d->__nextchar;
- /* If we end this ARGV-element by taking the rest as an arg,
- we must advance to the next element now. */
- d->optind++;
- }
- else if (d->optind == argc)
- {
- if (print_errors)
- {
- fprintf (stderr,
- "%s: option requires an argument -- '%c'\n",
- argv[0], c);
- }
- d->optopt = c;
- if (optstring[0] == ':')
- c = ':';
- else
- c = '?';
- }
- else
- /* We already incremented `optind' once;
- increment it again when taking next ARGV-elt as argument. */
- d->optarg = argv[d->optind++];
- d->__nextchar = NULL;
- }
- }
- return c;
- }
-}
-
-int
-_getopt_internal (int argc, char *const *argv, const char *optstring,
- const struct option *longopts, int *longind, int long_only)
-{
- int result;
-
- getopt_data.optind = optind;
- getopt_data.opterr = opterr;
-
- result = _getopt_internal_r (argc, argv, optstring, longopts,
- longind, long_only, &getopt_data);
-
- optind = getopt_data.optind;
- optarg = getopt_data.optarg;
- optopt = getopt_data.optopt;
-
- return result;
-}
-
-int
-getopt_long (int argc, char *const *argv, const char *options,
- const struct option *long_options, int *opt_index)
-{
- return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
-}
-
-#define TOLOWER(c) tolower(c)
-typedef unsigned chartype;
-
-char *
-strcasestr (phaystack, pneedle)
- const char *phaystack;
- const char *pneedle;
-{
- register const unsigned char *haystack, *needle;
- register chartype b, c;
-
-
- haystack = (const unsigned char *) phaystack;
- needle = (const unsigned char *) pneedle;
-
- b = TOLOWER (*needle);
- if (b != '\0')
- {
- haystack--; /* possible ANSI violation */
- do
- {
- c = *++haystack;
- if (c == '\0')
- goto ret0;
- }
- while (TOLOWER (c) != (int) b);
-
- c = TOLOWER (*++needle);
- if (c == '\0')
- goto foundneedle;
- ++needle;
- goto jin;
-
- for (;;)
- {
- register chartype a;
- register const unsigned char *rhaystack, *rneedle;
-
- do
- {
- a = *++haystack;
- if (a == '\0')
- goto ret0;
- if (TOLOWER (a) == (int) b)
- break;
- a = *++haystack;
- if (a == '\0')
- goto ret0;
-shloop:
- ;
- }
- while (TOLOWER (a) != (int) b);
-
-jin: a = *++haystack;
- if (a == '\0')
- goto ret0;
-
- if (TOLOWER (a) != (int) c)
- goto shloop;
-
- rhaystack = haystack-- + 1;
- rneedle = needle;
- a = TOLOWER (*rneedle);
-
- if (TOLOWER (*rhaystack) == (int) a)
- do
- {
- if (a == '\0')
- goto foundneedle;
- ++rhaystack;
- a = TOLOWER (*++needle);
- if (TOLOWER (*rhaystack) != (int) a)
- break;
- if (a == '\0')
- goto foundneedle;
- ++rhaystack;
- a = TOLOWER (*++needle);
- }
- while (TOLOWER (*rhaystack) == (int) a);
-
- needle = rneedle; /* took the register-poor approach */
-
- if (a == '\0')
- break;
- }
- }
-foundneedle:
- return (char*) haystack;
-ret0:
- return 0;
-}
-
-int glob (const char * __pattern, int __flags,
- int (*__errfunc) (const char *, int),
- glob_t * __pglob) {
-
- cfs_enter_debugger();
- return 0;
-}
-
-void globfree(glob_t *__pglog)
-{
-}
-
-int setenv(const char *envname, const char *envval, int overwrite)
-{
- int rc = 0;
-
- if (GetEnvironmentVariable(envname, NULL, 0) == 0) {
- overwrite = TRUE;
- }
-
- if (overwrite) {
- rc = SetEnvironmentVariable(envname, envval);
- rc = rc > 0 ? 0 : -1;
- } else {
- rc = -1;
- }
- return rc;
-}
-
-int uname(struct utsname *uts)
-{
- OSVERSIONINFO OsVerInfo;
-
- /* query computer name */
- memset(uts, 0, sizeof(struct utsname));
- strcpy(uts->sysname, "winnt");
- strcpy(uts->release, "winnt");
-
- /* query system version */
- OsVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx(&OsVerInfo);
-
- if (OsVerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
- if (OsVerInfo.dwMajorVersion == 6 &&
- OsVerInfo.dwBuildNumber > 3790) {
- strcpy(uts->release, "Vista");
- }
- } else {
- /* we got errors */
- return -1;
- }
-
- sprintf(uts->version, "%d.%d", OsVerInfo.dwMajorVersion,
- OsVerInfo.dwMinorVersion);
- return 0;
-}
-
-struct passwd * getpwuid(uid_t uid)
-{
- static struct passwd generic_passwd = {0, "root"};
- return &generic_passwd;
-}
-
-void* pgalloc(size_t factor)
-{
- LPVOID page;
-
- page = VirtualAlloc(NULL, PAGE_CACHE_SIZE << factor,
- MEM_COMMIT, PAGE_READWRITE);
- return page;
-}
-
-void pgfree(void * page)
-{
- _ASSERT(page != NULL);
- VirtualFree(page, 0, MEM_RELEASE);
-}
-
-#endif /* !__KERNEL__ */
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-
-/*
- * miscellaneous libcfs stuff
- */
-#define DEBUG_SUBSYSTEM S_LNET
-#include <libcfs/libcfs.h>
-#include <errno.h>
-
-/*
- * IDR support routines
- *
- * local global id <-> handle context
- */
-
-/* idr definitions */
-
-#define IDR_BITS 7
-#define IDR_FULL 0xffffffff
-#define IDR_SIZE (1 << IDR_BITS)
-#define IDR_MASK ((1 << IDR_BITS)-1)
-#define MAX_ID_SHIFT (sizeof(int)*8 - 1)
-#define MAX_ID_BIT (1U << MAX_ID_SHIFT)
-#define MAX_ID_MASK (MAX_ID_BIT - 1)
-#define MAX_LEVEL (MAX_ID_SHIFT + IDR_BITS - 1) / IDR_BITS
-#define IDR_FREE_MAX MAX_LEVEL + MAX_LEVEL
-
-#define idr_set_bit(bit, v) (v) |= (1<<(bit))
-#define idr_clear_bit(bit, v) (v) &= ~(1<<(bit))
-#define idr_test_bit(bit, v) ((v) & (1<<(bit)))
-
-struct idr_layer {
- uint32_t bitmap;
- struct idr_layer *ary[IDR_SIZE];
- int count;
-};
-
-struct idr_context {
- struct idr_layer *top;
- struct idr_layer *id_free;
- int layers;
- int id_free_cnt;
-};
-
-
-/*
- * id (fd) <-> pointer (HANDLE)
- */
-
-/**********************************************************
- private structures and routines for id implementation
-***********************************************************/
-
-static struct idr_layer *alloc_layer(struct idr_context *idp)
-{
- struct idr_layer *p;
-
- if (!(p = idp->id_free))
- return NULL;
- idp->id_free = p->ary[0];
- idp->id_free_cnt--;
- p->ary[0] = NULL;
- return p;
-}
-
-static int find_next_idrbit(uint32_t bm, int maxid, int n)
-{
- while (n<maxid && !idr_test_bit(n, bm)) n++;
- return n;
-}
-
-static void free_layer(struct idr_context *idp, struct idr_layer *p)
-{
- p->ary[0] = idp->id_free;
- idp->id_free = p;
- idp->id_free_cnt++;
-}
-
-static int idr_pre_get(struct idr_context *idp)
-{
- while (idp->id_free_cnt < IDR_FREE_MAX) {
- struct idr_layer *new;
-
- new = kmalloc(sizeof(struct idr_layer), __GFP_ZERO);
- if(new == NULL)
- return (0);
- free_layer(idp, new);
- }
- return 1;
-}
-
-static int sub_alloc(struct idr_context *idp, void *ptr, int *starting_id)
-{
- int n, m, sh;
- struct idr_layer *p, *new;
- struct idr_layer *pa[MAX_LEVEL];
- int l, id;
- uint32_t bm;
-
- memset(pa, 0, sizeof(pa));
-
- id = *starting_id;
- p = idp->top;
- l = idp->layers;
- pa[l--] = NULL;
- while (1) {
- /*
- * We run around this while until we reach the leaf node...
- */
- n = (id >> (IDR_BITS*l)) & IDR_MASK;
- bm = ~p->bitmap;
- m = find_next_idrbit(bm, IDR_SIZE, n);
- if (m == IDR_SIZE) {
- /* no space available go back to previous layer. */
- l++;
- id = (id | ((1 << (IDR_BITS*l))-1)) + 1;
- if (!(p = pa[l])) {
- *starting_id = id;
- return -2;
- }
- continue;
- }
- if (m != n) {
- sh = IDR_BITS*l;
- id = ((id >> sh) ^ n ^ m) << sh;
- }
- if ((id >= MAX_ID_BIT) || (id < 0))
- return -1;
- if (l == 0)
- break;
- /*
- * Create the layer below if it is missing.
- */
- if (!p->ary[m]) {
- if (!(new = alloc_layer(idp)))
- return -1;
- p->ary[m] = new;
- p->count++;
- }
- pa[l--] = p;
- p = p->ary[m];
- }
- /*
- * We have reached the leaf node, plant the
- * users pointer and return the raw id.
- */
- p->ary[m] = (struct idr_layer *)ptr;
- idr_set_bit(m, p->bitmap);
- p->count++;
- /*
- * If this layer is full mark the bit in the layer above
- * to show that this part of the radix tree is full.
- * This may complete the layer above and require walking
- * up the radix tree.
- */
- n = id;
- while (p->bitmap == IDR_FULL) {
- if (!(p = pa[++l]))
- break;
- n = n >> IDR_BITS;
- idr_set_bit((n & IDR_MASK), p->bitmap);
- }
- return(id);
-}
-
-static int idr_get_new_above_int(struct idr_context *idp, void *ptr, int starting_id)
-{
- struct idr_layer *p, *new;
- int layers, v, id;
-
- idr_pre_get(idp);
-
- id = starting_id;
-build_up:
- p = idp->top;
- layers = idp->layers;
- if (!p) {
- if (!(p = alloc_layer(idp)))
- return -1;
- layers = 1;
- }
- /*
- * Add a new layer to the top of the tree if the requested
- * id is larger than the currently allocated space.
- */
- while ((layers < MAX_LEVEL) && (id >= (1 << (layers*IDR_BITS)))) {
- layers++;
- if (!p->count)
- continue;
- if (!(new = alloc_layer(idp))) {
- /*
- * The allocation failed. If we built part of
- * the structure tear it down.
- */
- for (new = p; p && p != idp->top; new = p) {
- p = p->ary[0];
- new->ary[0] = NULL;
- new->bitmap = new->count = 0;
- free_layer(idp, new);
- }
- return -1;
- }
- new->ary[0] = p;
- new->count = 1;
- if (p->bitmap == IDR_FULL)
- idr_set_bit(0, new->bitmap);
- p = new;
- }
- idp->top = p;
- idp->layers = layers;
- v = sub_alloc(idp, ptr, &id);
- if (v == -2)
- goto build_up;
- return(v);
-}
-
-static int sub_remove(struct idr_context *idp, int shift, int id)
-{
- struct idr_layer *p = idp->top;
- struct idr_layer **pa[MAX_LEVEL];
- struct idr_layer ***paa = &pa[0];
- int n;
-
- *paa = NULL;
- *++paa = &idp->top;
-
- while ((shift > 0) && p) {
- n = (id >> shift) & IDR_MASK;
- idr_clear_bit(n, p->bitmap);
- *++paa = &p->ary[n];
- p = p->ary[n];
- shift -= IDR_BITS;
- }
- n = id & IDR_MASK;
- if (p != NULL && idr_test_bit(n, p->bitmap)) {
- idr_clear_bit(n, p->bitmap);
- p->ary[n] = NULL;
- while(*paa && ! --((**paa)->count)){
- free_layer(idp, **paa);
- **paa-- = NULL;
- }
- if ( ! *paa )
- idp->layers = 0;
- return 0;
- }
- return -1;
-}
-
-static void *_idr_find(struct idr_context *idp, int id)
-{
- int n;
- struct idr_layer *p;
-
- n = idp->layers * IDR_BITS;
- p = idp->top;
- /*
- * This tests to see if bits outside the current tree are
- * present. If so, tain't one of ours!
- */
- if ((id & ~(~0 << MAX_ID_SHIFT)) >> (n + IDR_BITS))
- return NULL;
-
- /* Mask off upper bits we don't use for the search. */
- id &= MAX_ID_MASK;
-
- while (n >= IDR_BITS && p) {
- n -= IDR_BITS;
- p = p->ary[(id >> n) & IDR_MASK];
- }
- return((void *)p);
-}
-
-static int _idr_remove(struct idr_context *idp, int id)
-{
- struct idr_layer *p;
-
- /* Mask off upper bits we don't use for the search. */
- id &= MAX_ID_MASK;
-
- if (sub_remove(idp, (idp->layers - 1) * IDR_BITS, id) == -1) {
- return -1;
- }
-
- if ( idp->top && idp->top->count == 1 &&
- (idp->layers > 1) &&
- idp->top->ary[0]) {
- /* We can drop a layer */
- p = idp->top->ary[0];
- idp->top->bitmap = idp->top->count = 0;
- free_layer(idp, idp->top);
- idp->top = p;
- --idp->layers;
- }
- while (idp->id_free_cnt >= IDR_FREE_MAX) {
- p = alloc_layer(idp);
- kfree(p);
- }
- return 0;
-}
-
-/**********************************************************
- publick interfaces of id vs handle conversion
-***********************************************************/
-
-/**
- initialise a idr tree.
- */
-struct idr_context *cfs_idr_init()
-{
- struct idr_context * idp = NULL;
- idp = kmalloc(sizeof(struct idr_context), 0);
- if (idp) {
- memset(idp, 0, sizeof(struct idr_context));
- }
-
- return idp;
-}
-
-/**
- remove an id from the idr tree
-*/
-int cfs_idr_remove(struct idr_context *idp, int id)
-{
- int ret;
- ret = _idr_remove((struct idr_context *)idp, id);
- if (ret != 0) {
- CWARN("WARNING: attempt to remove unset id %d in idtree\n", id);
- }
- return ret;
-}
-
-/**
- allocate the next available id, and assign 'ptr' into its slot.
- you can retrieve later this pointer using idr_find()
-*/
-int cfs_idr_get_new(struct idr_context *idp, void *ptr)
-{
- int ret = idr_get_new_above_int(idp, ptr, 0);
- if (ret > MAX_ID_MASK) {
- cfs_idr_remove(idp, ret);
- return -1;
- }
- return ret;
-}
-
-/**
- allocate a new id, giving the first available value greater than or
- equal to the given starting id
-*/
-int cfs_idr_get_new_above(struct idr_context *idp, void *ptr, int starting_id)
-{
- int ret = idr_get_new_above_int(idp, ptr, starting_id);
- if (ret > MAX_ID_MASK) {
- cfs_idr_remove(idp, ret);
- return -1;
- }
- return ret;
-}
-
-/**
- find a pointer value previously set with idr_get_new given an id
-*/
-void *cfs_idr_find(struct idr_context *idp, int id)
-{
- return _idr_find(idp, id);
-}
-
-/**
- destroy a idr tree.
- */
-void cfs_idr_exit(struct idr_context *idp)
-{
- if (idp) {
- kfree(idp);
- }
-}
-
-/*
- * convert <fcntl.h> flag from client to server.
- *
- * nt kernel uses several members to describe the open flags
- * such as DesiredAccess/ShareAccess/CreateDisposition/CreateOptions
- * so it's better to convert when using, not here.
- */
-
-int convert_client_oflag(int cflag, int *result)
-{
- *result = 0;
- return 0;
-}
-
-int cfs_error_code(NTSTATUS Status)
-{
- switch (Status) {
-
- case STATUS_ACCESS_DENIED:
- return (-EACCES);
-
- case STATUS_ACCESS_VIOLATION:
- return (-EFAULT);
-
- case STATUS_BUFFER_TOO_SMALL:
- return (-ETOOSMALL);
-
- case STATUS_INVALID_PARAMETER:
- return (-EINVAL);
-
- case STATUS_NOT_IMPLEMENTED:
- case STATUS_NOT_SUPPORTED:
- return (-EOPNOTSUPP);
-
- case STATUS_INVALID_ADDRESS:
- case STATUS_INVALID_ADDRESS_COMPONENT:
- return (-EADDRNOTAVAIL);
-
- case STATUS_NO_SUCH_DEVICE:
- case STATUS_NO_SUCH_FILE:
- case STATUS_OBJECT_NAME_NOT_FOUND:
- case STATUS_OBJECT_PATH_NOT_FOUND:
- case STATUS_NETWORK_BUSY:
- case STATUS_INVALID_NETWORK_RESPONSE:
- case STATUS_UNEXPECTED_NETWORK_ERROR:
- return (-ENETDOWN);
-
- case STATUS_BAD_NETWORK_PATH:
- case STATUS_NETWORK_UNREACHABLE:
- case STATUS_PROTOCOL_UNREACHABLE:
- return (-ENETUNREACH);
-
- case STATUS_LOCAL_DISCONNECT:
- case STATUS_TRANSACTION_ABORTED:
- case STATUS_CONNECTION_ABORTED:
- return (-ECONNABORTED);
-
- case STATUS_REMOTE_DISCONNECT:
- case STATUS_LINK_FAILED:
- case STATUS_CONNECTION_DISCONNECTED:
- case STATUS_CONNECTION_RESET:
- case STATUS_PORT_UNREACHABLE:
- return (-ECONNRESET);
-
- case STATUS_INSUFFICIENT_RESOURCES:
- return (-ENOMEM);
-
- case STATUS_PAGEFILE_QUOTA:
- case STATUS_NO_MEMORY:
- case STATUS_CONFLICTING_ADDRESSES:
- case STATUS_QUOTA_EXCEEDED:
- case STATUS_TOO_MANY_PAGING_FILES:
- case STATUS_WORKING_SET_QUOTA:
- case STATUS_COMMITMENT_LIMIT:
- case STATUS_TOO_MANY_ADDRESSES:
- case STATUS_REMOTE_RESOURCES:
- return (-ENOBUFS);
-
- case STATUS_INVALID_CONNECTION:
- return (-ENOTCONN);
-
- case STATUS_PIPE_DISCONNECTED:
- return (-ESHUTDOWN);
-
- case STATUS_TIMEOUT:
- case STATUS_IO_TIMEOUT:
- case STATUS_LINK_TIMEOUT:
- return (-ETIMEDOUT);
-
- case STATUS_REMOTE_NOT_LISTENING:
- case STATUS_CONNECTION_REFUSED:
- return (-ECONNREFUSED);
-
- case STATUS_HOST_UNREACHABLE:
- return (-EHOSTUNREACH);
-
- case STATUS_PENDING:
- case STATUS_DEVICE_NOT_READY:
- return (-EAGAIN);
-
- case STATUS_CANCELLED:
- case STATUS_REQUEST_ABORTED:
- return (-EINTR);
-
- case STATUS_BUFFER_OVERFLOW:
- case STATUS_INVALID_BUFFER_SIZE:
- return (-EMSGSIZE);
-
- case STATUS_ADDRESS_ALREADY_EXISTS:
- return (-EADDRINUSE);
- }
-
- if (NT_SUCCESS(Status))
- return 0;
-
- return (-EINVAL);
-}
-
-/*
- * Convert server error code to client format. Error codes are from
- * Linux errno.h, so for Linux client---identity.
- */
-int convert_server_error(__u64 ecode)
-{
- return cfs_error_code((NTSTATUS)ecode);
-}
-
-char * strsep(char **strp, const char *delim)
-{
- char *begin, *end;
-
- begin = *strp;
- if (begin == NULL) {
- return NULL;
- }
-
- if (delim[0] == '\0' || delim[1] == '\0') {
- char ch = delim[0];
- if (ch == '\0') {
- end = NULL;
- } else {
- if (*begin == ch) {
- end = begin;
- } else if (*begin == '\0') {
- end = NULL;
- } else {
- end = strchr (begin + 1, ch);
- }
- }
- } else {
- end = strpbrk (begin, delim);
- }
-
- if (end) {
- *end++ = '\0';
- *strp = end;
- } else {
- *strp = NULL;
- }
-
- return begin;
-}
-
-/*
- * strnchr - Find a character in a length limited string
- * @s: The string to be searched
- * @count: The number of characters to be searched
- * @c: The character to search for
- */
-
-char *strnchr(const char *s, size_t count, int c)
-{
- for (; count-- && *s != '\0'; ++s)
- if (*s == (char) c)
- return (char *) s;
- return NULL;
-}
-
-__u64 strtoull(char *nptr, char **endptr,int base)
-{
- char *s = nptr;
- __u64 acc, cutoff;
- int c, neg = 0, any, cutlim;
-
- /*
- * See strtol for comments as to the logic used.
- */
- do {
- c = *s++;
- } while (cfs_isspace(c));
- if (c == '-') {
- neg = 1;
- c = *s++;
- } else if (c == '+')
- c = *s++;
- if ((base == 0 || base == 16) &&
- c == '0' && (*s == 'x' || *s == 'X')) {
- c = s[1];
- s += 2;
- base = 16;
- }
- if (base == 0)
- base = c == '0' ? 8 : 10;
- cutoff = (__u64)ULONG_LONG_MAX / (__u64)base;
- cutlim = (int)((__u64)ULONG_LONG_MAX % (__u64)base);
- for (acc = 0, any = 0;; c = *s++) {
- if (cfs_isdigit(c))
- c -= '0';
- else if (cfs_isalpha(c))
- c -= cfs_isupper(c) ? 'A' - 10 : 'a' - 10;
- else
- break;
- if (c >= base)
- break;
- if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
- any = -1;
- else {
- any = 1;
- acc *= base;
- acc += c;
- }
- }
- if (any < 0) {
- acc = ULONG_LONG_MAX;
- } else if (neg)
- acc = 0 - acc;
- if (endptr != 0)
- *endptr = (char *) (any ? s - 1 : nptr);
- return (acc);
-}
-
-#if __KERNEL__
-
-#define BASE 65521L /* largest prime smaller than 65536 */
-#define NMAX 5552
-/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-
-#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
-#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
-#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
-#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
-#define DO16(buf) DO8(buf,0); DO8(buf,8);
-
-/* ========================================================================= */
-/*
- Update a running Adler-32 checksum with the bytes buf[0..len-1] and
- return the updated checksum. If buf is NULL, this function returns
- the required initial value for the checksum.
- An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
- much faster. Usage example:
-
- uLong adler = adler32(0L, NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- adler = adler32(adler, buffer, length);
- }
- if (adler != original_adler) error();
-*/
-
-ULONG zlib_adler32(ULONG adler,
- const BYTE *buf,
- UINT len)
-{
- unsigned long s1 = adler & 0xffff;
- unsigned long s2 = (adler >> 16) & 0xffff;
- int k;
-
- if (buf == NULL) return 1L;
-
- while (len > 0) {
- k = len < NMAX ? len : NMAX;
- len -= k;
- while (k >= 16) {
- DO16(buf);
- buf += 16;
- k -= 16;
- }
- if (k != 0) do {
- s1 += *buf++;
- s2 += s1;
- } while (--k);
- s1 %= BASE;
- s2 %= BASE;
- }
- return (s2 << 16) | s1;
-}
-
-#if !defined(NTDDI_VERSION) || NTDDI_VERSION < 0x06000000
-_CRTIMP size_t __cdecl strnlen(const char * _Str, size_t _MaxCount)
-{
- size_t len = 0;
- while(len < _MaxCount && _Str[len++]);
- return len;
-}
-#endif
-
-int (__cdecl *_cfs_isalpha)(int);
-int (__cdecl *_cfs_isspace)(int);
-int (__cdecl *_cfs_isupper)(int);
-int (__cdecl *_cfs_isdigit)(int);
-int (__cdecl *_cfs_isxdigit)(int);
-
-int cfs_isalpha(int c)
-{
- if (_cfs_isalpha) {
- return _cfs_isalpha(c);
- } else {
- return ((c >= 'a' && c <= 'z') ||
- (c >= 'A' && c <= 'Z'));
- }
-}
-
-int cfs_isspace(int c)
-{
- if (_cfs_isspace) {
- return _cfs_isspace(c);
- } else {
- return ((c >= 0x09 && c <= 0x0d) ||
- (c == 0x20));
- }
-}
-
-int cfs_isupper(int c)
-{
- if (_cfs_isupper) {
- return _cfs_isupper(c);
- } else {
- return (c >= 'A' && c <= 'Z');
- }
-}
-
-int cfs_isdigit(int c)
-{
- if (_cfs_isdigit) {
- return _cfs_isdigit(c);
- } else {
- return (c >= '0' && c <= '9');
- }
-}
-
-int cfs_isxdigit(int c)
-{
- if (_cfs_isxdigit) {
- return _cfs_isxdigit(c);
- } else {
- return ((c >= '0' && c <= '9') ||
- (c >= 'A' && c <= 'F') ||
- (c >= 'a' && c <= 'F'));
- }
-}
-
-void cfs_libc_init()
-{
- UNICODE_STRING fn;
- int i;
-
- struct {WCHAR * name; PVOID * addr;} funcs[] = {
- { L"isspace", (PVOID *)&_cfs_isspace},
- { L"isalpha", (PVOID *)&_cfs_isalpha},
- { L"isupper", (PVOID *)&_cfs_isupper},
- { L"isdigit", (PVOID *)&_cfs_isdigit},
- { L"isxdigit",(PVOID *)&_cfs_isxdigit},
- { NULL, NULL },
- };
-
- for (i=0; funcs[i].name != NULL; i++) {
- RtlInitUnicodeString(&fn, funcs[i].name);
- *(funcs[i].addr) = MmGetSystemRoutineAddress(&fn);
- }
-
-#if DBG
- ASSERT(cfs_isspace(0x20) && cfs_isspace(0x09) &&
- cfs_isspace(0x0a) && cfs_isspace(0x0d) &&
- !cfs_isspace('a') && !cfs_isspace('0'));
- ASSERT(cfs_isalpha('a') && cfs_isalpha('Z') &&
- !cfs_isalpha('0') && !cfs_isalpha('='));
- ASSERT(cfs_isupper('A') && cfs_isupper('Z') &&
- !cfs_isupper('a') && !cfs_isupper('='));
- ASSERT(cfs_isdigit('0') && cfs_isdigit('9') &&
- !cfs_isdigit('a') && !cfs_isdigit('#'));
- ASSERT(cfs_isxdigit('0') && cfs_isxdigit('9') &&
- cfs_isxdigit('a') && cfs_isxdigit('A') &&
- cfs_isxdigit('F') && cfs_isxdigit('f') &&
- !cfs_isxdigit('G') && !cfs_isxdigit('z'));
-#endif
-}
-
-#else
-
-unsigned int libcfs_subsystem_debug = ~0;
-
-int cfs_isalpha(int c)
-{
- return isalpha(c);
-}
-
-int cfs_isspace(int c)
-{
- return isspace(c);
-}
-
-int cfs_isupper(int c)
-{
- return isupper(c);
-}
-
-int cfs_isdigit(int c)
-{
- return isdigit(c);
-}
-
-int cfs_isxdigit(int c)
-{
- return isxdigit(c);
-}
-
-void cfs_libc_init()
-{
-}
-
-
-#endif
SUBDIRS = lnet
-
-EXTRA_DIST = cygwin-ioctl.h
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * lnet/include/cygwin-ioctl.h
- *
- * linux/ioctl.h for Linux by H.H. Bergman.
- */
-
-#ifndef _ASMI386_IOCTL_H
-#define _ASMI386_IOCTL_H
-
-/* ioctl command encoding: 32 bits total, command in lower 16 bits,
- * size of the parameter structure in the lower 14 bits of the
- * upper 16 bits.
- * Encoding the size of the parameter structure in the ioctl request
- * is useful for catching programs compiled with old versions
- * and to avoid overwriting user space outside the user buffer area.
- * The highest 2 bits are reserved for indicating the ``access mode''.
- * NOTE: This limits the max parameter size to 16kB -1 !
- */
-
-/*
- * The following is for compatibility across the various Linux
- * platforms. The i386 ioctl numbering scheme doesn't really enforce
- * a type field. De facto, however, the top 8 bits of the lower 16
- * bits are indeed used as a type field, so we might just as well make
- * this explicit here. Please be sure to use the decoding macros
- * below from now on.
- */
-#undef _IO
-#undef _IOR
-#undef _IOW
-#undef _IOC
-#undef IOC_IN
-#undef IOC_OUT
-
-#define _IOC_NRBITS 8
-#define _IOC_TYPEBITS 8
-#define _IOC_SIZEBITS 14
-#define _IOC_DIRBITS 2
-
-#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT 0
-#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS)
-
-/*
- * Direction bits.
- */
-#define _IOC_NONE 0U
-#define _IOC_WRITE 1U
-#define _IOC_READ 2U
-
-#define _IOC(dir,type,nr,size) \
- (((dir) << _IOC_DIRSHIFT) | \
- ((type) << _IOC_TYPESHIFT) | \
- ((nr) << _IOC_NRSHIFT) | \
- ((size) << _IOC_SIZESHIFT))
-
-/* used to create numbers */
-#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
-#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
-#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
-#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-
-/* used to decode ioctl numbers.. */
-#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
-#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the drivers/sound files... */
-
-#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT)
-#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT)
-#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT)
-#define IOCSIZE_SHIFT (_IOC_SIZESHIFT)
-
-#endif /* _ASMI386_IOCTL_H */
#include <lnet/linux/api-support.h>
#elif defined(__APPLE__)
#include <lnet/darwin/api-support.h>
-#elif defined(__WINNT__)
-#include <lnet/winnt/api-support.h>
#else
#error Unsupported Operating System
#endif
#include <lnet/linux/lib-lnet.h>
#elif defined(__APPLE__)
#include <lnet/darwin/lib-lnet.h>
-#elif defined(__WINNT__)
-#include <lnet/winnt/lib-lnet.h>
#else
#error Unsupported Operating System
#endif
#include <lnet/linux/lib-types.h>
#elif defined(__APPLE__)
#include <lnet/darwin/lib-types.h>
-#elif defined(__WINNT__)
-#include <lnet/winnt/lib-types.h>
-#include <libcfs/libcfs_pack.h>
-#include <libcfs/libcfs_unpack.h>
#else
#error Unsupported Operating System
#endif
#include <lnet/linux/lnet.h>
#elif defined(__APPLE__)
#include <lnet/darwin/lnet.h>
-#elif defined(__WINNT__)
-#include <lnet/winnt/lnet.h>
#else
#error Unsupported Operating System
#endif
int png_flags; /* reserved flags */
} lst_test_ping_param_t;
-/* more tests */
-#ifdef __WINNT__
-#include <libcfs/libcfs_pack.h>
-#include <libcfs/libcfs_unpack.h>
-#endif
typedef struct {
__u32 errors;
__u32 rpcs_sent;
#define SOCKLND_CONN_ACK SOCKLND_CONN_BULK_IN
-#ifdef __WINNT__
-#include <libcfs/libcfs_pack.h>
-#include <libcfs/libcfs_unpack.h>
-#endif
typedef struct {
__u32 kshm_magic; /* magic number of socklnd message */
__u32 kshm_version; /* version of socklnd message */
typedef unsigned LNET_SEQ_BASETYPE lnet_seq_t;
#define LNET_SEQ_GT(a,b) (((signed LNET_SEQ_BASETYPE)((a) - (b))) > 0)
-/* XXX
- * cygwin need the pragma line, not clear if it's needed in other places.
- * checking!!!
- */
-#ifdef __CYGWIN__
-#pragma pack(push, 4)
-#endif
-
/**
* Information about an event on a MD.
*/
*/
volatile lnet_seq_t sequence;
} lnet_event_t;
-#ifdef __CYGWIN__
-#pragma pop
-#endif
/**
* Event queue handler function type.
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#ifndef __WINNT_API_SUPPORT_H__
-#define __WINNT_API_SUPPORT_H__
-
-#ifndef __LNET_API_SUPPORT_H__
-#error Do not #include this file directly. #include <lnet/api-support.h> instead
-#endif
-
-
-#endif
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#ifndef __LNET_WINNT_LIB_LNET_H__
-#define __LNET_WINNT_LIB_LNET_H__
-
-#ifndef __LNET_LIB_LNET_H__
-#error Do not #include this file directly. #include <lnet/lib-lnet.h> instead
-#endif
-
-#ifdef __KERNEL__
-# include <libcfs/libcfs.h>
-
-static inline __u64
-lnet_page2phys (struct page *p)
-{
- return 0;
-}
-
-#else /* __KERNEL__ */
-
-#endif
-
-#endif /* __LNET_WINNT_LIB_LNET_H__ */
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#ifndef __LNET_WINNT_LIB_TYPES_H__
-#define __LNET_WINNT_LIB_TYPES_H__
-
-#ifndef __LNET_LIB_TYPES_H__
-#error Do not #include this file directly. #include <lnet/lib-types.h> instead
-#endif
-
-#endif
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#ifndef __LNET_LINUX_LNET_H__
-#define __LNET_LINUX_LNET_H__
-
-#ifndef __LNET_H__
-#error Do not #include this file directly. #include <lnet/lnet.h> instead
-#endif
-
-#ifdef __KERNEL__
-#include <lnet/types.h>
-
-int
-ks_query_iovs_length(struct iovec *iov, int niov);
-
-int
-ks_query_kiovs_length(lnet_kiov_t *kiov, int nkiov);
-
-int
-ks_send_buf(ks_tconn_t *, char *, int, int, int);
-
-int
-ks_recv_buf(ks_tconn_t *, char *, int, int, int);
-
-int
-ks_send_iovs(ks_tconn_t *, struct iovec *, int, int, int);
-
-int
-ks_recv_iovs(ks_tconn_t *, struct iovec *, int, int, int);
-
-int
-ks_send_kiovs(ks_tconn_t *, lnet_kiov_t *, int, int, int);
-
-int
-ks_recv_kiovs(ks_tconn_t *, lnet_kiov_t *, int, int, int);
-
-#endif /* __KERNEL__ */
-#endif
#include "socklnd_lib-linux.h"
#elif defined(__APPLE__)
#include "socklnd_lib-darwin.h"
-#elif defined(__WINNT__)
-#include "socklnd_lib-winnt.h"
#else
#error Unsupported Operating System
#endif
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * lnet/klnds/socklnd/socklnd_lib-winnt.c
- *
- * windows socknal library
- */
-
-#include "socklnd.h"
-
-# if defined(CONFIG_SYSCTL) && !CFS_SYSFS_MODULE_PARM
-static struct ctl_table ksocknal_ctl_table[21];
-
-struct ctl_table ksocknal_top_ctl_table[] = {
- {
- /* ctl_name */ 200,
- /* procname */ "socknal",
- /* data */ NULL,
- /* maxlen */ 0,
- /* mode */ 0555,
- /* child */ ksocknal_ctl_table
- },
- { 0 }
-};
-
-int
-ksocknal_lib_tunables_init ()
-{
- int i = 0;
- int j = 1;
-
- ksocknal_ctl_table[i].ctl_name = j++;
- ksocknal_ctl_table[i].procname = "timeout";
- ksocknal_ctl_table[i].data = ksocknal_tunables.ksnd_timeout;
- ksocknal_ctl_table[i].maxlen = sizeof (int);
- ksocknal_ctl_table[i].mode = 0644;
- ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
- i++;
-
- ksocknal_ctl_table[i].ctl_name = j++;
- ksocknal_ctl_table[i].procname = "credits";
- ksocknal_ctl_table[i].data = ksocknal_tunables.ksnd_credits;
- ksocknal_ctl_table[i].maxlen = sizeof (int);
- ksocknal_ctl_table[i].mode = 0444;
- ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
- i++;
-
- ksocknal_ctl_table[i].ctl_name = j++;
- ksocknal_ctl_table[i].procname = "peer_credits";
- ksocknal_ctl_table[i].data = ksocknal_tunables.ksnd_peertxcredits;
- ksocknal_ctl_table[i].maxlen = sizeof (int);
- ksocknal_ctl_table[i].mode = 0444;
- ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
- i++;
-
- ksocknal_ctl_table[i].ctl_name = j++;
- ksocknal_ctl_table[i].procname = "peer_buffer_credits";
- ksocknal_ctl_table[i].data = ksocknal_tunables.ksnd_peerrtrcredits;
- ksocknal_ctl_table[i].maxlen = sizeof (int);
- ksocknal_ctl_table[i].mode = 0444;
- ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
- i++;
-
- ksocknal_ctl_table[i].ctl_name = j++;
- ksocknal_ctl_table[i].procname = "nconnds";
- ksocknal_ctl_table[i].data = ksocknal_tunables.ksnd_nconnds;
- ksocknal_ctl_table[i].maxlen = sizeof (int);
- ksocknal_ctl_table[i].mode = 0444;
- ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
- i++;
-
-
- ksocknal_ctl_table[i].ctl_name = j++;
- ksocknal_ctl_table[i].procname = "min_reconnectms";
- ksocknal_ctl_table[i].data = ksocknal_tunables.ksnd_min_reconnectms;
- ksocknal_ctl_table[i].maxlen = sizeof (int);
- ksocknal_ctl_table[i].mode = 0444;
- ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
- i++;
-
- ksocknal_ctl_table[i].ctl_name = j++;
- ksocknal_ctl_table[i].procname = "max_reconnectms";
- ksocknal_ctl_table[i].data = ksocknal_tunables.ksnd_max_reconnectms;
- ksocknal_ctl_table[i].maxlen = sizeof (int);
- ksocknal_ctl_table[i].mode = 0444;
- ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
- i++;
-
- ksocknal_ctl_table[i].ctl_name = j++;
- ksocknal_ctl_table[i].procname = "eager_ack";
- ksocknal_ctl_table[i].data = ksocknal_tunables.ksnd_eager_ack;
- ksocknal_ctl_table[i].maxlen = sizeof (int);
- ksocknal_ctl_table[i].mode = 0644;
- ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
- i++;
-
- ksocknal_ctl_table[i].ctl_name = j++;
- ksocknal_ctl_table[i].procname = "zero_copy";
- ksocknal_ctl_table[i].data = ksocknal_tunables.ksnd_zc_min_payload;
- ksocknal_ctl_table[i].maxlen = sizeof (int);
- ksocknal_ctl_table[i].mode = 0644;
- ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
- i++;
-
- ksocknal_ctl_table[i].ctl_name = j++;
- ksocknal_ctl_table[i].procname = "typed";
- ksocknal_ctl_table[i].data = ksocknal_tunables.ksnd_typed_conns;
- ksocknal_ctl_table[i].maxlen = sizeof (int);
- ksocknal_ctl_table[i].mode = 0444;
- ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
- i++;
-
- ksocknal_ctl_table[i].ctl_name = j++;
- ksocknal_ctl_table[i].procname = "min_bulk";
- ksocknal_ctl_table[i].data = ksocknal_tunables.ksnd_min_bulk;
- ksocknal_ctl_table[i].maxlen = sizeof (int);
- ksocknal_ctl_table[i].mode = 0644;
- ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
- i++;
-
- ksocknal_ctl_table[i].ctl_name = j++;
- ksocknal_ctl_table[i].procname = "rx_buffer_size";
- ksocknal_ctl_table[i].data = ksocknal_tunables.ksnd_rx_buffer_size;
- ksocknal_ctl_table[i].maxlen = sizeof(int);
- ksocknal_ctl_table[i].mode = 0644;
- ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
- i++;
-
- ksocknal_ctl_table[i].ctl_name = j++;
- ksocknal_ctl_table[i].procname = "tx_buffer_size";
- ksocknal_ctl_table[i].data = ksocknal_tunables.ksnd_tx_buffer_size;
- ksocknal_ctl_table[i].maxlen = sizeof(int);
- ksocknal_ctl_table[i].mode = 0644;
- ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
- i++;
-
- ksocknal_ctl_table[i].ctl_name = j++;
- ksocknal_ctl_table[i].procname = "nagle";
- ksocknal_ctl_table[i].data = ksocknal_tunables.ksnd_nagle;
- ksocknal_ctl_table[i].maxlen = sizeof(int);
- ksocknal_ctl_table[i].mode = 0644;
- ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
- i++;
-
- ksocknal_ctl_table[i].ctl_name = j++;
- ksocknal_ctl_table[i].procname = "round_robin";
- ksocknal_ctl_table[i].data = ksocknal_tunables.ksnd_round_robin;
- ksocknal_ctl_table[i].maxlen = sizeof(int);
- ksocknal_ctl_table[i].mode = 0644;
- ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
- i++;
-
-#ifdef CPU_AFFINITY
- ksocknal_ctl_table[i].ctl_name = j++;
- ksocknal_ctl_table[i].procname = "irq_affinity";
- ksocknal_ctl_table[i].data = ksocknal_tunables.ksnd_irq_affinity;
- ksocknal_ctl_table[i].maxlen = sizeof(int);
- ksocknal_ctl_table[i].mode = 0644;
- ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
- i++;
-#endif
-
- ksocknal_ctl_table[i].ctl_name = j++;
- ksocknal_ctl_table[i].procname = "keepalive_idle";
- ksocknal_ctl_table[i].data = ksocknal_tunables.ksnd_keepalive_idle;
- ksocknal_ctl_table[i].maxlen = sizeof(int);
- ksocknal_ctl_table[i].mode = 0644;
- ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
- i++;
-
- ksocknal_ctl_table[i].ctl_name = j++;
- ksocknal_ctl_table[i].procname = "keepalive_count";
- ksocknal_ctl_table[i].data = ksocknal_tunables.ksnd_keepalive_count;
- ksocknal_ctl_table[i].maxlen = sizeof(int);
- ksocknal_ctl_table[i].mode = 0644;
- ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
- i++;
-
- ksocknal_ctl_table[i].ctl_name = j++;
- ksocknal_ctl_table[i].procname = "keepalive_intvl";
- ksocknal_ctl_table[i].data = ksocknal_tunables.ksnd_keepalive_intvl;
- ksocknal_ctl_table[i].maxlen = sizeof(int);
- ksocknal_ctl_table[i].mode = 0644;
- ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
- i++;
-
-#ifdef SOCKNAL_BACKOFF
- ksocknal_ctl_table[i].ctl_name = j++;
- ksocknal_ctl_table[i].procname = "backoff_init";
- ksocknal_ctl_table[i].data = ksocknal_tunables.ksnd_backoff_init;
- ksocknal_ctl_table[i].maxlen = sizeof(int);
- ksocknal_ctl_table[i].mode = 0644;
- ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
- i++;
-
- ksocknal_ctl_table[i].ctl_name = j++;
- ksocknal_ctl_table[i].procname = "backoff_max";
- ksocknal_ctl_table[i].data = ksocknal_tunables.ksnd_backoff_max;
- ksocknal_ctl_table[i].maxlen = sizeof(int);
- ksocknal_ctl_table[i].mode = 0644;
- ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
- i++;
-#endif
-
-#if SOCKNAL_VERSION_DEBUG
- ksocknal_ctl_table[i].ctl_name = j++;
- ksocknal_ctl_table[i].procname = "protocol";
- ksocknal_ctl_table[i].data = ksocknal_tunables.ksnd_protocol;
- ksocknal_ctl_table[i].maxlen = sizeof(int);
- ksocknal_ctl_table[i].mode = 0644;
- ksocknal_ctl_table[i].proc_handler = &proc_dointvec;
- i++;
-#endif
-
- LASSERT (j == i + 1);
- LASSERT (i <= sizeof(ksocknal_ctl_table)/sizeof(ksocknal_ctl_table[0]));
-
- ksocknal_tunables.ksnd_sysctl =
- register_sysctl_table(ksocknal_top_ctl_table);
-
- if (ksocknal_tunables.ksnd_sysctl == NULL)
- CWARN("Can't setup /proc tunables\n");
-
- return 0;
-}
-
-void
-ksocknal_lib_tunables_fini ()
-{
- if (ksocknal_tunables.ksnd_sysctl != NULL)
- unregister_sysctl_table(ksocknal_tunables.ksnd_sysctl);
-}
-#else
-int
-ksocknal_lib_tunables_init ()
-{
- return 0;
-}
-
-void
-ksocknal_lib_tunables_fini ()
-{
-}
-#endif /* # if CONFIG_SYSCTL && !CFS_SYSFS_MODULE_PARM */
-
-void
-ksocknal_lib_bind_irq (unsigned int irq)
-{
-}
-
-int
-ksocknal_lib_get_conn_addrs (ksock_conn_t *conn)
-{
- int rc = libcfs_sock_getaddr(conn->ksnc_sock, 1,
- &conn->ksnc_ipaddr,
- &conn->ksnc_port);
-
- /* Didn't need the {get,put}connsock dance to deref ksnc_sock... */
- LASSERT (!conn->ksnc_closing);
-
- if (rc != 0) {
- CERROR ("Error %d getting sock peer IP\n", rc);
- return rc;
- }
-
- rc = libcfs_sock_getaddr(conn->ksnc_sock, 0,
- &conn->ksnc_myipaddr, NULL);
- if (rc != 0) {
- CERROR ("Error %d getting sock local IP\n", rc);
- return rc;
- }
-
- return 0;
-}
-
-unsigned int
-ksocknal_lib_sock_irq (struct socket *sock)
-{
- return 0;
-}
-
-int
-ksocknal_lib_send_iov (ksock_conn_t *conn, ksock_tx_t *tx)
-{
- struct socket *sock = conn->ksnc_sock;
-
- int nob;
- int rc;
- int flags;
-
-
- if (*ksocknal_tunables.ksnd_enable_csum && /* checksum enabled */
- conn->ksnc_proto == &ksocknal_protocol_v2x && /* V2.x connection */
- tx->tx_nob == tx->tx_resid && /* frist sending */
- tx->tx_msg.ksm_csum == 0) /* not checksummed */
- ksocknal_lib_csum_tx(tx);
-
- nob = ks_query_iovs_length(tx->tx_iov, tx->tx_niov);
- flags = (!list_empty(&conn->ksnc_tx_queue) || nob < tx->tx_resid) ?
- (MSG_DONTWAIT | MSG_MORE) : MSG_DONTWAIT;
- rc = ks_send_iovs(sock, tx->tx_iov, tx->tx_niov, flags, 0);
-
- KsPrint((4, "ksocknal_lib_send_iov: conn %p sock %p rc %d\n",
- conn, sock, rc));
- return rc;
-}
-
-int
-ksocknal_lib_send_kiov (ksock_conn_t *conn, ksock_tx_t *tx)
-{
- struct socket *sock = conn->ksnc_sock;
- lnet_kiov_t *kiov = tx->tx_kiov;
- int rc;
- int nob;
- int nkiov;
- int flags;
-
- nkiov = tx->tx_nkiov;
- nob = ks_query_kiovs_length(tx->tx_kiov, nkiov);
- flags = (!list_empty(&conn->ksnc_tx_queue) || nob < tx->tx_resid) ?
- (MSG_DONTWAIT | MSG_MORE) : MSG_DONTWAIT;
- rc = ks_send_kiovs(sock, tx->tx_kiov, nkiov, flags, 0);
-
- KsPrint((4, "ksocknal_lib_send_kiov: conn %p sock %p rc %d\n",
- conn, sock, rc));
- return rc;
-}
-
-int
-ksocknal_lib_recv_iov (ksock_conn_t *conn)
-{
- struct iovec *iov = conn->ksnc_rx_iov;
- int rc;
- int size;
-
- /* receive payload from tsdu queue */
- rc = ks_recv_iovs (conn->ksnc_sock, iov, conn->ksnc_rx_niov,
- MSG_DONTWAIT, 0);
-
- /* calcuate package checksum */
- if (rc > 0) {
-
- int i;
- int fragnob;
- int sum;
- __u32 saved_csum = 0;
-
- if (conn->ksnc_proto == &ksocknal_protocol_v2x) {
- saved_csum = conn->ksnc_msg.ksm_csum;
- conn->ksnc_msg.ksm_csum = 0;
- }
-
- if (saved_csum != 0) {
-
- /* accumulate checksum */
- for (i = 0, sum = rc; sum > 0; i++, sum -= fragnob) {
- LASSERT (i < conn->ksnc_rx_niov);
-
- fragnob = iov[i].iov_len;
- if (fragnob > sum)
- fragnob = sum;
-
- conn->ksnc_rx_csum = ksocknal_csum(conn->ksnc_rx_csum,
- iov[i].iov_base, fragnob);
- }
- conn->ksnc_msg.ksm_csum = saved_csum;
- }
- }
-
- KsPrint((4, "ksocknal_lib_recv_iov: conn %p sock %p rc %d.\n",
- conn, conn->ksnc_sock, rc));
- return rc;
-}
-
-int
-ksocknal_lib_recv_kiov (ksock_conn_t *conn)
-{
- lnet_kiov_t *kiov = conn->ksnc_rx_kiov;
- int rc;
-
- /* NB we can't trust socket ops to either consume our iovs
- * or leave them alone, so we only receive 1 frag at a time. */
- LASSERT (conn->ksnc_rx_nkiov > 0);
-
- /* receive payload from tsdu queue */
- rc = ks_recv_kiovs (conn->ksnc_sock, kiov, conn->ksnc_rx_nkiov,
- MSG_DONTWAIT, 0);
-
- if (rc > 0 && conn->ksnc_msg.ksm_csum != 0) {
-
- int i;
- char *base;
- int sum;
- int fragnob;
-
- for (i = 0, sum = rc; sum > 0; i++, sum -= fragnob) {
-
- LASSERT (i < conn->ksnc_rx_nkiov);
-
- base = (char *)(kiov[i].kiov_page->addr) + kiov[i].kiov_offset;
- fragnob = kiov[i].kiov_len;
- if (fragnob > sum)
- fragnob = sum;
-
- conn->ksnc_rx_csum = ksocknal_csum(conn->ksnc_rx_csum,
- base, fragnob);
- }
- }
-
- KsPrint((4, "ksocknal_lib_recv_kiov: conn %p sock %p rc %d.\n",
- conn, conn->ksnc_sock, rc));
- return rc;
-}
-
-void
-ksocknal_lib_eager_ack (ksock_conn_t *conn)
-{
- __u32 option = 1;
- int rc = 0;
-
- rc = ks_set_tcp_option(
- conn->ksnc_sock, TCP_SOCKET_NODELAY,
- &option, sizeof(option) );
- if (rc != 0) {
- CERROR("Can't disable nagle: %d\n", rc);
- }
-}
-
-int
-ksocknal_lib_get_conn_tunables (ksock_conn_t *conn, int *txmem, int *rxmem, int *nagle)
-{
- ks_tconn_t * tconn = conn->ksnc_sock;
- int len;
- int rc;
-
- ks_get_tconn (tconn);
- *txmem = *rxmem = 0;
- len = sizeof(*nagle);
- rc = ks_get_tcp_option(tconn, TCP_SOCKET_NODELAY, (__u32 *)nagle, &len);
- ks_put_tconn (tconn);
-
- KsPrint((2, "ksocknal_get_conn_tunables: nodelay = %d rc = %d\n", *nagle, rc));
-
- if (rc == 0)
- *nagle = !*nagle;
- else
- *txmem = *rxmem = *nagle = 0;
-
- return (rc);
-}
-
-int
-ksocknal_lib_setup_sock (struct socket *sock)
-{
- int rc;
-
- int keep_idle;
- int keep_count;
- int keep_intvl;
- int keep_alive;
-
- __u32 option;
-
-#if 0
- /* set the window size */
- tconn->kstc_snd_wnd = ksocknal_tunables.ksnd_buffer_size;
- tconn->kstc_rcv_wnd = ksocknal_tunables.ksnd_buffer_size;
-#endif
-
- /* disable nagle */
- if (!ksocknal_tunables.ksnd_nagle) {
- option = 1;
-
- rc = ks_set_tcp_option(
- sock, TCP_SOCKET_NODELAY,
- &option, sizeof (option));
- if (rc != 0) {
- CERROR ("Can't disable nagle: %d\n", rc);
- return (rc);
- }
- }
-
- /* snapshot tunables */
- keep_idle = *ksocknal_tunables.ksnd_keepalive_idle;
- keep_count = *ksocknal_tunables.ksnd_keepalive_count;
- keep_intvl = *ksocknal_tunables.ksnd_keepalive_intvl;
-
- keep_alive = (keep_idle > 0 && keep_count > 0 && keep_intvl > 0);
-
- option = (__u32)(keep_alive ? 1 : 0);
-
- rc = ks_set_tcp_option(
- sock, TCP_SOCKET_KEEPALIVE,
- &option, sizeof (option));
- if (rc != 0) {
- CERROR ("Can't disable nagle: %d\n", rc);
- return (rc);
- }
-
- return (0);
-}
-
-void
-ksocknal_lib_push_conn (ksock_conn_t *conn)
-{
- ks_tconn_t * tconn;
- __u32 nagle;
- __u32 val = 1;
- int rc;
-
- tconn = conn->ksnc_sock;
-
- ks_get_tconn(tconn);
-
- spin_lock(&tconn->kstc_lock);
- if (tconn->kstc_type == kstt_sender) {
- nagle = tconn->sender.kstc_info.nagle;
- tconn->sender.kstc_info.nagle = 0;
- } else {
- LASSERT(tconn->kstc_type == kstt_child);
- nagle = tconn->child.kstc_info.nagle;
- tconn->child.kstc_info.nagle = 0;
- }
-
- spin_unlock(&tconn->kstc_lock);
-
- val = 1;
- rc = ks_set_tcp_option(
- tconn,
- TCP_SOCKET_NODELAY,
- &(val),
- sizeof(__u32)
- );
-
- LASSERT (rc == 0);
- spin_lock(&tconn->kstc_lock);
-
- if (tconn->kstc_type == kstt_sender) {
- tconn->sender.kstc_info.nagle = nagle;
- } else {
- LASSERT(tconn->kstc_type == kstt_child);
- tconn->child.kstc_info.nagle = nagle;
- }
- spin_unlock(&tconn->kstc_lock);
- ks_put_tconn(tconn);
-}
-
-void
-ksocknal_lib_csum_tx(ksock_tx_t *tx)
-{
- int i;
- __u32 csum;
- void *base;
-
- LASSERT(tx->tx_iov[0].iov_base == (void *)&tx->tx_msg);
- LASSERT(tx->tx_conn != NULL);
- LASSERT(tx->tx_conn->ksnc_proto == &ksocknal_protocol_v2x);
-
- tx->tx_msg.ksm_csum = 0;
-
- csum = ksocknal_csum(~0, (void *)tx->tx_iov[0].iov_base,
- tx->tx_iov[0].iov_len);
-
- if (tx->tx_kiov != NULL) {
- for (i = 0; i < tx->tx_nkiov; i++) {
- base = (PUCHAR)(tx->tx_kiov[i].kiov_page->addr) +
- tx->tx_kiov[i].kiov_offset;
-
- csum = ksocknal_csum(csum, base, tx->tx_kiov[i].kiov_len);
- }
- } else {
- for (i = 1; i < tx->tx_niov; i++)
- csum = ksocknal_csum(csum, tx->tx_iov[i].iov_base,
- tx->tx_iov[i].iov_len);
- }
-
- if (*ksocknal_tunables.ksnd_inject_csum_error) {
- csum++;
- *ksocknal_tunables.ksnd_inject_csum_error = 0;
- }
-
- tx->tx_msg.ksm_csum = csum;
-}
-
-void ksocknal_schedule_callback(struct socket*sock, int mode)
-{
- ksock_conn_t * conn = (ksock_conn_t *) sock->kstc_conn;
-
- read_lock(&ksocknal_data.ksnd_global_lock);
- if (mode) {
- ksocknal_write_callback(conn);
- } else {
- ksocknal_read_callback(conn);
- }
- read_unlock(&ksocknal_data.ksnd_global_lock);
-}
-
-void
-ksocknal_tx_fini_callback(ksock_conn_t * conn, ksock_tx_t * tx)
-{
- /* remove tx/conn from conn's outgoing queue */
- spin_lock_bh(&conn->ksnc_scheduler->kss_lock);
- list_del(&tx->tx_list);
- if (list_empty(&conn->ksnc_tx_queue))
- list_del(&conn->ksnc_tx_list);
-
- spin_unlock_bh(&conn->ksnc_scheduler->kss_lock);
-
- /* complete send; tx -ref */
- ksocknal_tx_decref(tx);
-}
-
-void
-ksocknal_lib_save_callback(struct socket *sock, ksock_conn_t *conn)
-{
-}
-
-void
-ksocknal_lib_set_callback(struct socket *sock, ksock_conn_t *conn)
-{
- sock->kstc_conn = conn;
- sock->kstc_sched_cb = ksocknal_schedule_callback;
-}
-
-void
-ksocknal_lib_reset_callback(struct socket *sock, ksock_conn_t *conn)
-{
- sock->kstc_conn = NULL;
- sock->kstc_sched_cb = NULL;
-}
-
-int
-ksocknal_lib_zc_capable(ksock_conn_t *conn)
-{
- return 0;
-}
-
-int
-ksocknal_lib_memory_pressure(ksock_conn_t *conn)
-{
- return 0;
-}
-
-int
-ksocknal_lib_bind_thread_to_cpu(int id)
-{
- return 0;
-}
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#define DEBUG_PORTAL_ALLOC
-#ifndef __WINNT_TDILND_LIB_H__
-#define __WINNT_TDILND_LIB_H__
-
-#include <libcfs/libcfs.h>
-
-#ifndef CONFIG_SMP
-
-static inline
-int ksocknal_nsched(void)
-{
- return 1;
-}
-
-#else
-
-static inline int
-ksocknal_nsched(void)
-{
- return num_online_cpus();
-}
-
-static inline int
-ksocknal_sched2cpu(int i)
-{
- return i;
-}
-
-static inline int
-ksocknal_irqsched2cpu(int i)
-{
- return i;
-}
-
-#endif
-
-static inline __u32 ksocknal_csum(__u32 crc, unsigned char const *p, size_t len)
-{
- while (len-- > 0)
- crc = ((crc + 0x100) & ~0xff) | ((crc + *p++) & 0xff) ;
- return crc;
-}
-
-
-#endif
SRPC_MSG_JOIN_REPLY = 17,
} srpc_msg_type_t;
-#ifdef __WINNT__
-#include <libcfs/libcfs_pack.h>
-#include <libcfs/libcfs_unpack.h>
-#endif
-
/* CAVEAT EMPTOR:
* All srpc_*_reqst_t's 1st field must be matchbits of reply buffer,
* and 2nd field matchbits of bulk buffer if any.
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * winnt selftest driver framework
- *
- */
-
-#define DEBUG_SUBSYSTEM S_LNET
-
-/*
- * Included Headers
- */
-
-
-#include <libcfs/libcfs.h>
-
-
-/* libcfs module init/exit routines */
-DECLARE_INIT(init_libcfs_module);
-DECLARE_EXIT(exit_libcfs_module);
-
-/* portal module init/exit routines */
-DECLARE_INIT(init_lnet);
-DECLARE_EXIT(fini_lnet);
-
-/* tdinal module init/exit routines */
-DECLARE_INIT(ksocknal_module_init);
-DECLARE_EXIT(ksocknal_module_fini);
-
-/* selftest module init/exit routines */
-DECLARE_INIT(lnet_selftest_init);
-DECLARE_EXIT(lnet_selftest_fini);
-
-/*
- * module info
- */
-
-struct module libcfs_global_module = {"selftest"};
-
-/*
- * structure definitions
- */
-
-#define LNET_SELFTEST_VERSION 0x00010001 /* LNET selftest module version */
-
-#define LNET_SELFTEST_DEVICE L"\\Device\\Selftest" /* device object name */
-#define LNET_SELFTEST_SYMLNK L"\\DosDevices\\Selftest" /* user-visible name for the device*/
-
-typedef struct _DEVICE_EXTENSION {
- BOOLEAN bProcFS;
-} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
-
-/*
- * global definitions
- */
-
-PDEVICE_OBJECT SelfObject = NULL; /* lnet selftest object */
-PDEVICE_OBJECT ProcObject = NULL; /* procfs emulator device */
-
-
-/*
- * common routines
- */
-
-
-//
-// complete Irp request ...
-//
-
-NTSTATUS
-LstCompleteIrp(
- PIRP Irp,
- NTSTATUS Status,
- ULONG Info
- )
-{
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = Info;
- IoCompleteRequest(Irp,IO_NO_INCREMENT);
-
- return Status;
-}
-
-//
-// Open/Create Device ...
-//
-
-NTSTATUS
-LstCreate(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-{
- KdPrint(("LstCreate: DeviceCreate ...\n"));
-
- return LstCompleteIrp(Irp,STATUS_SUCCESS,0);
-}
-
-//
-// Close Devcie ...
-//
-
-NTSTATUS
-LstClose(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- KdPrint(("LstClose: Device Closed.\n"));
-
- return LstCompleteIrp(Irp, STATUS_SUCCESS, 0);
-
- UNREFERENCED_PARAMETER(DeviceObject);
-}
-
-
-//
-// computer is being shut down
-//
-
-NTSTATUS
-LstShutdown(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-{
- KdPrint(("LstShutdown: ...\n"));
-
- return LstCompleteIrp(Irp, STATUS_SUCCESS, 0);
-
- UNREFERENCED_PARAMETER(DeviceObject);
-}
-
-//
-// device io control
-//
-
-
-NTSTATUS
-LstDeviceControl(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-{
- NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST;
- PIO_STACK_LOCATION IrpSp;
-
- ULONG ControlCode;
- ULONG InputLength;
- ULONG OutputLength;
-
- PVOID lpvInBuffer;
-
- Irp->IoStatus.Information = 0;
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
-
- ControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
- InputLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
- OutputLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
- lpvInBuffer = Irp->AssociatedIrp.SystemBuffer;
-
- ASSERT (IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL);
-
- switch (ControlCode)
- {
- case IOCTL_LIBCFS_VERSION:
-
- *((ULONG *)lpvInBuffer) = (ULONG)(LNET_SELFTEST_VERSION);
- Irp->IoStatus.Information = sizeof(ULONG);
- Status = STATUS_SUCCESS;
- break;
-
- default:
- break;
- }
-
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return Status;
-}
-
-NTSTATUS
-ProcCreate(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-{
- NTSTATUS Status;
- PIO_STACK_LOCATION IrpSp;
-
- FILE_FULL_EA_INFORMATION *ea;
- struct file *fp;
-
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
- ea = (PFILE_FULL_EA_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
-
- if (!ea) {
- Status = STATUS_INVALID_PARAMETER;
- } else {
- fp = lustre_open_file(&ea->EaName[0]);
- if (!fp) {
- Status = STATUS_OBJECT_NAME_NOT_FOUND;
- } else {
- IrpSp->FileObject->FsContext = fp;
- IrpSp->FileObject->FsContext2 = fp->private_data;
- Status = STATUS_SUCCESS;
- }
- }
-
- return LstCompleteIrp(Irp, Status, 0);
-}
-
-//
-// Close Devcie ...
-//
-
-NTSTATUS
-ProcClose(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- PIO_STACK_LOCATION IrpSp;
-
- struct file *fp;
-
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
- fp = (file_t *) IrpSp->FileObject->FsContext;
- ASSERT(fp != NULL);
- ASSERT(IrpSp->FileObject->FsContext2 == fp->private_data);
-
- lustre_close_file(fp);
-
- return LstCompleteIrp(Irp, STATUS_SUCCESS, 0);
-
- UNREFERENCED_PARAMETER(DeviceObject);
-}
-
-/*
- * proc frame routines
- */
-
-NTSTATUS
-ProcDeviceControl(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-{
- NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST;
- PIO_STACK_LOCATION IrpSp;
-
- ULONG ControlCode;
- ULONG InputLength;
- ULONG OutputLength;
-
- PVOID lpvInBuffer;
-
- Irp->IoStatus.Information = 0;
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
-
- ControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
- InputLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
- OutputLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
- lpvInBuffer = Irp->AssociatedIrp.SystemBuffer;
-
- ASSERT (IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL);
-
- switch (ControlCode)
- {
- case IOCTL_LIBCFS_VERSION:
-
- *((ULONG *)lpvInBuffer) = (ULONG)(LNET_SELFTEST_VERSION);
- Irp->IoStatus.Information = sizeof(ULONG);
-
- Status = STATUS_SUCCESS;
-
- break;
-
- case IOCTL_LIBCFS_ENTRY:
- {
- int rc = 0;
- struct file *fp;
-
- fp = (struct file *)IrpSp->FileObject->FsContext;
-
- if (!fp) {
- rc = -EINVAL;
- } else {
- rc = lustre_ioctl_file(fp, (PCFS_PROC_IOCTL) lpvInBuffer);
- }
-
- ((PCFS_PROC_IOCTL) lpvInBuffer)->rc = rc;
- Irp->IoStatus.Information = InputLength;
- Status = STATUS_SUCCESS;
- }
- }
-
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return Status;
-}
-
-
-NTSTATUS
-ProcReadWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp)
-{
- PIO_STACK_LOCATION IrpSp;
- NTSTATUS Status;
-
- struct file *fp;
- int rc;
- PCHAR buf;
-
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
- if (Irp->MdlAddress) {
- buf = MmGetSystemAddressForMdlSafe(
- Irp->MdlAddress,
- NormalPagePriority);
- } else {
- buf = Irp->AssociatedIrp.SystemBuffer;
- }
-
- if (buf == NULL) {
- Status = STATUS_SUCCESS;
- rc = 0;
- } else {
- fp = (struct file *)IrpSp->FileObject->FsContext;
-
- if (!fp) {
- Status = STATUS_INVALID_PARAMETER;
- goto errorout;
- }
-
- if (IrpSp->MajorFunction == IRP_MJ_READ) {
- rc = lustre_read_file(
- fp, IrpSp->Parameters.Read.ByteOffset.LowPart,
- IrpSp->Parameters.Read.Length, buf);
- } else {
- rc = lustre_write_file(
- fp, IrpSp->Parameters.Write.ByteOffset.LowPart,
- IrpSp->Parameters.Write.Length, buf);
- }
- if (rc < 0) {
- cfs_enter_debugger();
- Status = STATUS_UNSUCCESSFUL;
- } else {
- Status = STATUS_SUCCESS;
- }
- }
-
-
-errorout:
- return LstCompleteIrp(Irp, Status, rc);
-}
-
-
-//
-// common dispatch routines
-//
-
-NTSTATUS
-LstDispatchRequest(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-{
- NTSTATUS Status;
- PIO_STACK_LOCATION IrpSp;
-
- Status = STATUS_INVALID_DEVICE_REQUEST;
-
- __try {
-
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
-
- switch (IrpSp->MajorFunction) {
-
- case IRP_MJ_CREATE:
- if (DeviceObject == SelfObject) {
- Status = LstCreate(DeviceObject, Irp);
- } else if (DeviceObject == ProcObject) {
- Status = ProcCreate(DeviceObject, Irp);
- }
- break;
-
- case IRP_MJ_CLOSE:
- if (DeviceObject == SelfObject) {
- Status = LstClose(DeviceObject, Irp);
- } else if (DeviceObject == ProcObject) {
- Status = ProcClose(DeviceObject, Irp);
- }
- break;
-
- case IRP_MJ_READ:
- case IRP_MJ_WRITE:
- if (DeviceObject == ProcObject) {
- Status = ProcReadWrite(DeviceObject, Irp);
- }
- break;
-
- case IRP_MJ_DEVICE_CONTROL:
- if (DeviceObject == SelfObject) {
- Status = LstDeviceControl(DeviceObject, Irp);
- } else if (DeviceObject == ProcObject) {
- Status = ProcDeviceControl(DeviceObject, Irp);
- }
- break;
-
- case IRP_MJ_SHUTDOWN:
- Status = LstShutdown(DeviceObject, Irp);
- break;
-
- default:
-
- KdPrint(("LstDispatchRequest: Major Function: %xh is not supported.\n",
- IrpSp->MajorFunction));
- LstCompleteIrp(Irp, Status, 0);
- break;
- }
- }
-
- __finally {
- }
-
- return Status;
-}
-
-//
-// create a device object and a dosdevice symbol link
-//
-
-PDEVICE_OBJECT
-LstCreateDevice(
- IN PDRIVER_OBJECT DriverObject,
- IN PWCHAR DeviceName,
- IN PWCHAR SymlnkName,
- IN BOOLEAN bProcFS
- )
-{
- NTSTATUS Status;
-
- UNICODE_STRING NtDevName;
- UNICODE_STRING Win32DevName;
-
- PDEVICE_EXTENSION DeviceExtension;
- PDEVICE_OBJECT DeviceObject;
-
- /* create the device object with the specified name */
-
- RtlInitUnicodeString(&NtDevName, DeviceName);
-
- Status = IoCreateDevice(
- DriverObject,
- sizeof(DEVICE_EXTENSION),
- &NtDevName,
- FILE_DEVICE_UNKNOWN,
- 0,
- FALSE,
- &DeviceObject );
-
- if (!NT_SUCCESS(Status)) {
-
- cfs_enter_debugger();
- return NULL;
- }
-
- /* create the symlink to make the device visible to user */
-
- RtlInitUnicodeString(&Win32DevName, SymlnkName);
- Status = IoCreateSymbolicLink(&Win32DevName, &NtDevName);
-
- if (!NT_SUCCESS(Status)) {
-
- IoDeleteDevice(DeviceObject);
- return NULL;
- }
-
- DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceObjectExtension;
- DeviceExtension->bProcFS = bProcFS;
-
- DeviceObject->AlignmentRequirement = 0;
- DeviceObject->SectorSize = 0;
- DeviceObject->Flags |= DO_BUFFERED_IO;
- DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
-
- return DeviceObject;
-}
-
-//
-// DriverEntry
-//
-
-NTSTATUS DriverEntry(
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath
- )
-{
- KdPrint(("LNet selftest: Build Time: " __DATE__ " " __TIME__ "\n"));
- KdPrint(("LNet selftest: DriverEntry ... \n"));
-
- /* initialize libcfs module */
- if (module_init_libcfs_module() != 0) {
- KdPrint(("selftest: failed to initialize module: libcfs ...\n"));
- goto errorout;
- }
-
- /* initialize portals module */
- if (module_init_lnet() != 0) {
- KdPrint(("selftest: failed to initialize module: lnet ...\n"));
- module_exit_libcfs_module();
- goto errorout;
- }
-
- /* initialize tdinal module */
- if (module_ksocknal_module_init() != 0) {
- KdPrint(("selftest: failed to initialize module: socklnd ...\n"));
- module_fini_lnet();
- module_exit_libcfs_module();
- goto errorout;
- }
-
- /* initialize lnet selttest module */
- if (module_lnet_selftest_init() != 0) {
- KdPrint(("selftest: failed to initialize module: selftest ...\n"));
- module_ksocknal_module_fini();
- module_fini_lnet();
- module_exit_libcfs_module();
- goto errorout;
- }
-
- /* create lnet selftest device object */
- SelfObject = LstCreateDevice(
- DriverObject,
- LNET_SELFTEST_DEVICE,
- LNET_SELFTEST_SYMLNK,
- FALSE );
- if (!SelfObject) {
- KdPrint(("selftest: failed to allocate DeviceObject ...\n"));
- module_lnet_selftest_fini();
- module_ksocknal_module_fini();
- module_fini_lnet();
- module_exit_libcfs_module();
-
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* create the libcfs proc fs emultor device object */
- ProcObject = LstCreateDevice(
- DriverObject,
- LUSTRE_PROC_DEVICE,
- LUSTRE_PROC_SYMLNK,
- TRUE );
- if (!ProcObject) {
-
- KdPrint(("selftest: failed to allocate proc DeviceObject ...\n"));
- /* remove Selftest DeviceObject */
- IoDeleteDevice(SelfObject);
- module_lnet_selftest_fini();
- module_ksocknal_module_fini();
- module_fini_lnet();
- module_exit_libcfs_module();
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* initialize the driver callback routines */
-
- DriverObject->MajorFunction[IRP_MJ_CREATE] = LstDispatchRequest;
- DriverObject->MajorFunction[IRP_MJ_CLOSE] = LstDispatchRequest;
- DriverObject->MajorFunction[IRP_MJ_READ] = LstDispatchRequest;
- DriverObject->MajorFunction[IRP_MJ_WRITE] = LstDispatchRequest;
- DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = LstDispatchRequest;
- DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = LstDispatchRequest;
-
- return STATUS_SUCCESS;
-
-errorout:
-
- cfs_enter_debugger();
-
- return STATUS_UNSUCCESSFUL;
-}
return (rc == 0 ? 0: 1);
}
-#elif defined(__WINNT__)
-
-#define DAEMON_CTL_NAME "/proc/sys/lnet/daemon_file"
-#define SUBSYS_DEBUG_CTL_NAME "/proc/sys/lnet/subsystem_debug"
-#define DEBUG_CTL_NAME "/proc/sys/lnet/debug"
-#define DUMP_KERNEL_CTL_NAME "/proc/sys/lnet/dump_kernel"
-
-static int
-dbg_open_ctlhandle(const char *str)
-{
- int fd;
- fd = cfs_proc_open((char *)str, (int)O_WRONLY);
- if (fd < 0) {
- fprintf(stderr, "open %s failed: %s\n", str,
- strerror(errno));
- return -1;
- }
- return fd;
-}
-
-static void
-dbg_close_ctlhandle(int fd)
-{
- cfs_proc_close(fd);
-}
-
-static int
-dbg_write_cmd(int fd, char *str, int len)
-{
- int rc = cfs_proc_write(fd, str, len);
-
- return (rc == len ? 0 : 1);
-}
-
#else
#error - Unknown sysctl convention.
#endif
#include <linux/lprocfs_status.h>
#elif defined(__APPLE__)
#include <darwin/lprocfs_status.h>
-#elif defined(__WINNT__)
-#include <winnt/lprocfs_status.h>
#else
#error Unsupported operating system.
#endif
#include <linux/lustre_user.h>
#elif defined(__APPLE__)
#include <darwin/lustre_user.h>
-#elif defined(__WINNT__)
-#include <winnt/lustre_user.h>
#else
#error Unsupported operating system.
#endif
#include <linux/lustre_acl.h>
#elif defined(__APPLE__)
#include <darwin/lustre_acl.h>
-#elif defined(__WINNT__)
-#include <winnt/lustre_acl.h>
-#error Unsupported operating system.
#endif
#endif
#include <linux/lustre_debug.h>
#elif defined(__APPLE__)
#include <darwin/lustre_debug.h>
-#elif defined(__WINNT__)
-#include <winnt/lustre_debug.h>
#else
#error Unsupported operating system.
#endif
#include <linux/lustre_dlm.h>
#elif defined(__APPLE__)
#include <darwin/lustre_dlm.h>
-#elif defined(__WINNT__)
-#include <winnt/lustre_dlm.h>
#else
#error Unsupported operating system.
#endif
#include <linux/lustre_handles.h>
#elif defined(__APPLE__)
#include <darwin/lustre_handles.h>
-#elif defined(__WINNT__)
-#include <winnt/lustre_handles.h>
#else
#error Unsupported operating system.
#endif
#include <linux/lustre_lib.h>
#elif defined(__APPLE__)
#include <darwin/lustre_lib.h>
-#elif defined(__WINNT__)
-#include <winnt/lustre_lib.h>
#else
#error Unsupported operating system.
#endif
#include <linux/lustre_lite.h>
#elif defined(__APPLE__)
#include <darwin/lustre_lite.h>
-#elif defined(__WINNT__)
-#include <winnt/lustre_lite.h>
#else
#error Unsupported operating system.
#endif
#include <linux/lustre_log.h>
#elif defined(__APPLE__)
#include <darwin/lustre_log.h>
-#elif defined(__WINNT__)
-#include <winnt/lustre_log.h>
#else
#error Unsupported operating system.
#endif
#include <linux/lustre_net.h>
#elif defined(__APPLE__)
#include <darwin/lustre_net.h>
-#elif defined(__WINNT__)
-#include <winnt/lustre_net.h>
#else
#error Unsupported operating system.
#endif
#include <linux/lustre_quota.h>
#elif defined(__APPLE__)
#include <darwin/lustre_quota.h>
-#elif defined(__WINNT__)
-#include <winnt/lustre_quota.h>
-#error Unsupported operating system.
#endif
#include <dt_object.h>
#include <linux/lvfs.h>
#elif defined(__APPLE__)
#include <darwin/lvfs.h>
-#elif defined(__WINNT__)
-#include <winnt/lvfs.h>
#else
#error Unsupported operating system.
#endif
#include <linux/obd.h>
#elif defined(__APPLE__)
#include <darwin/obd.h>
-#elif defined(__WINNT__)
-#include <winnt/obd.h>
#else
#error Unsupported operating system.
#endif
#include <linux/obd_class.h>
#elif defined(__APPLE__)
#include <darwin/obd_class.h>
-#elif defined(__WINNT__)
-#include <winnt/obd_class.h>
#else
#error Unsupported operating system.
#endif
#include <linux/obd_support.h>
#elif defined(__APPLE__)
#include <darwin/obd_support.h>
-#elif defined(__WINNT__)
-#include <winnt/obd_support.h>
#else
#error Unsupported operating system.
#endif
#include <lustre_net.h>
#include <lustre/lustre_user.h>
#include <obd_cksum.h>
-
-#ifdef __CYGWIN__
-# include <ctype.h>
-#endif
-
#include <lustre_ha.h>
#include <lprocfs_status.h>
#include <lustre_ioctl.h>