Whamcloud - gitweb
LU-1346 libcfs: replace libcfs wrappers with kernel API
[fs/lustre-release.git] / libcfs / include / libcfs / winnt / winnt-prim.h
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  */
30 /*
31  * This file is part of Lustre, http://www.lustre.org/
32  * Lustre is a trademark of Sun Microsystems, Inc.
33  *
34  * libcfs/include/libcfs/winnt/winnt-prim.h
35  *
36  * Basic library routines.
37  */
38
39 #ifndef __LIBCFS_WINNT_CFS_PRIM_H__
40 #define __LIBCFS_WINNT_CFS_PRIM_H__
41
42 #ifndef __LIBCFS_LIBCFS_H__
43 #error Do not #include this file directly. #include <libcfs/libcfs.h> instead
44 #endif
45
46 /*
47  * libcfs proc device object
48  */
49
50
51 #define LUSTRE_PROC_DEVICE  L"\\Device\\LNetProcFS"      /* proc fs emulator device object */
52 #define LUSTRE_PROC_SYMLNK  L"\\DosDevices\\LNetProcFS"  /* proc fs user-visible device */
53
54
55 /*
56  * Device IO Control Code Definitions
57  */
58
59 #define FILE_DEVICE_LIBCFS      ('LC')
60
61 #define FUNC_LIBCFS_VERSION     0x101  // get version of current libcfs
62 #define FUNC_LIBCFS_IOCTL       0x102  // Device i/o control to proc fs
63
64
65 #define IOCTL_LIBCFS_VERSION \
66      CTL_CODE (FILE_DEVICE_LIBCFS, FUNC_LIBCFS_VERSION, METHOD_BUFFERED, FILE_ANY_ACCESS)
67 #define IOCTL_LIBCFS_ENTRY   \
68      CTL_CODE(FILE_DEVICE_LIBCFS, FUNC_LIBCFS_IOCTL,   METHOD_BUFFERED, FILE_ANY_ACCESS)
69
70 #pragma pack(4)
71 typedef struct _CFS_PROC_IOCTL {
72
73     ULONG           cmd;    // ioctl command identifier
74     ULONG           len;    // length of data
75     int             rc;     // return code
76     ULONG           usused; // unused 
77
78     // UCHAR        data[]; // content of the real ioctl
79
80 } CFS_PROC_IOCTL, *PCFS_PROC_IOCTL;
81 #pragma pack()
82
83 #ifdef __KERNEL__
84
85 void cfs_enter_debugger(void);
86 #define __builtin_return_address(x) (0)
87
88 /*
89  * Symbol functions for libcfs
90  *
91  * OSX has no facility for use to register symbol.
92  * So we have to implement it.
93  */
94 #define CFS_SYMBOL_LEN     64
95
96 struct  cfs_symbol {
97         char       name[CFS_SYMBOL_LEN];
98         void      *value;
99         int        ref;
100         cfs_list_t sym_list;
101 };
102
103 extern int      cfs_symbol_register(const char *, const void *);
104 extern void     cfs_symbol_unregister(const char *);
105 extern void *   cfs_symbol_get(const char *);
106 extern void     cfs_symbol_put(const char *);
107 extern void     cfs_symbol_clean();
108
109 typedef struct file_operations cfs_file_operations_t;
110 typedef struct file cfs_file_t;
111
112 /*
113  * Pseudo device register
114  */
115
116 typedef struct
117 {
118     int                     minor;
119     const char *            name;
120     cfs_file_operations_t * fops;
121 } cfs_psdev_t;
122
123 int cfs_psdev_register(cfs_psdev_t * psdev);
124 int cfs_psdev_deregister(cfs_psdev_t * psdev);
125
126
127 /*
128  * Proc emulator file system APIs
129  */
130
131 typedef int cfs_read_proc_t(char *page, char **start, off_t off,
132                             int count, int *eof, void *data);
133 typedef int cfs_write_proc_t(struct file *file, const char *buffer,
134                              unsigned long count, void *data);
135
136 #define CFS_PROC_ENTRY_MAGIC 'CPEM'
137
138 #define CFS_PROC_FLAG_DIRECTORY    0x00000001 // directory node
139 #define CFS_PROC_FLAG_ATTACHED     0x00000002 // node is attached to proc
140 #define CFS_PROC_FLAG_MISCDEV      0x00000004 // miscellaneous device
141
142 typedef struct cfs_proc_entry
143 {
144     ULONG                   magic;      // Magic
145     ULONG                   flags;      // Flags
146
147     struct _dir_entry {                 // proc directory entry
148         PRTL_SPLAY_LINKS    root;
149     };
150
151     struct cfs_proc_entry  *parent;
152
153     struct _file_entry {                // proc file / leaf entry
154             cfs_read_proc_t  *  read_proc;
155             cfs_write_proc_t *  write_proc;
156     };
157
158     mode_t                  mode;
159     unsigned short          nlink;
160     BOOLEAN                 deleted;
161
162         
163     struct file_operations *proc_fops;
164     void                   *data;
165
166     // proc_dir_entry ended.
167
168     RTL_SPLAY_LINKS         s_link;       // splay link
169
170     //
171     // Maximum length of proc entry name is 0x20
172     //
173
174     char                    name[0x20];
175
176 } cfs_proc_entry_t, cfs_proc_dir_entry_t;
177
178 typedef cfs_proc_entry_t cfs_proc_dir_entry_t;
179 #define proc_dir_entry cfs_proc_entry
180
181 #define PROC_BLOCK_SIZE    PAGE_SIZE
182
183 struct proc_dir_entry *PDE(const struct inode *inode);
184
185
186 /*
187  * Sysctl register
188  */
189
190 typedef struct ctl_table                cfs_sysctl_table_t;
191 typedef struct ctl_table_header         cfs_sysctl_table_header_t;
192
193
194 typedef int ctl_handler (
195             cfs_sysctl_table_t *table,
196             int *name,  int nlen,
197             void *oldval, size_t *oldlenp,
198             void *newval, size_t newlen, 
199             void **context );
200
201 typedef int proc_handler (
202             cfs_sysctl_table_t *ctl,
203             int write, struct file * filp,
204             void *buffer, size_t *lenp );
205
206
207 int proc_dointvec(cfs_sysctl_table_t *table, int write, struct file *filp,
208                      void *buffer, size_t *lenp);
209
210 int proc_dostring(cfs_sysctl_table_t *table, int write, struct file *filp,
211                   void *buffer, size_t *lenp);
212
213 int sysctl_string(cfs_sysctl_table_t *table, int *name, int nlen,
214                   void *oldval, size_t *oldlenp,
215                   void *newval, size_t newlen, void **context);
216
217 /*
218  *  System io control definitions
219  */
220
221 #define CTL_MAXNAME 10
222
223 #define CTL_ANY     -1  /* Matches any name */
224 #define CTL_NONE    0
225
226 enum
227 {
228     CTL_KERN=1,     /* General kernel info and control */
229     CTL_VM=2,       /* VM management */
230     CTL_NET=3,      /* Networking */
231     CTL_PROC=4,     /* Process info */
232     CTL_FS=5,       /* Filesystems */
233     CTL_DEBUG=6,        /* Debugging */
234     CTL_DEV=7,      /* Devices */
235     CTL_BUS=8,      /* Busses */
236     CTL_ABI=9,      /* Binary emulation */
237     CTL_CPU=10      /* CPU stuff (speed scaling, etc) */
238 };
239
240 /* sysctl table definitons */
241 struct ctl_table 
242 {
243         int ctl_name;
244         char *procname;
245         void *data;
246         int maxlen;
247         mode_t mode;
248         cfs_sysctl_table_t *child;
249         proc_handler *proc_handler;     /* text formatting callback */
250         ctl_handler *strategy;          /* read / write callback functions */
251         cfs_proc_entry_t *de;   /* proc entry block */
252         void *extra1;
253         void *extra2;
254 };
255
256
257 /* the mantaner of the cfs_sysctl_table trees */
258 struct ctl_table_header
259 {
260         cfs_sysctl_table_t *    ctl_table;
261         cfs_list_t              ctl_entry;
262 };
263
264 /* proc root entries, support routines */
265 extern cfs_proc_entry_t *  cfs_proc_root;   /* / */
266 extern cfs_proc_entry_t *  cfs_proc_proc;   /* /proc */
267 extern cfs_proc_entry_t *  cfs_proc_fs;     /* /proc/fs */
268 extern cfs_proc_entry_t *  cfs_proc_sys;    /* /proc/sys */
269 extern cfs_proc_entry_t *  cfs_proc_dev;    /* /dev */
270
271 cfs_proc_entry_t * create_proc_entry(const char *name, mode_t mod,
272                                           cfs_proc_entry_t *parent);
273 void proc_free_entry(cfs_proc_entry_t *de);
274 void remove_proc_entry(const char *name, cfs_proc_entry_t *entry);
275 cfs_proc_entry_t * search_proc_entry(const char * name,
276                         cfs_proc_entry_t *  root );
277 cfs_proc_entry_t *proc_symlink(const char *name,
278                                        cfs_proc_entry_t *parent,
279                                const char *dest);
280 cfs_proc_entry_t *proc_mkdir(const char *name,
281                                      cfs_proc_entry_t *parent);
282
283 #define cfs_create_proc_entry create_proc_entry
284 #define cfs_free_proc_entry   proc_free_entry
285 #define cfs_remove_proc_entry remove_proc_entry
286
287 struct ctl_table_header *register_sysctl_table(cfs_sysctl_table_t * table,
288                                                int insert_at_head);
289 void unregister_sysctl_table(struct ctl_table_header * header);
290
291 #define cfs_register_sysctl_table(t, a)   register_sysctl_table(t, a)
292 #define cfs_unregister_sysctl_table(t)    unregister_sysctl_table(t)
293
294 /*
295  * seq device (linux/seq_file.h)
296  */
297
298
299 /*
300  * seq file definitions
301  */
302
303 struct dentry;
304 struct vfsmount;
305
306 struct path {
307         struct vfsmount *mnt;
308         struct dentry *dentry;
309 };
310
311 struct seq_operations;
312 struct file;
313 struct inode;
314
315 struct seq_file {
316         char *buf;
317         size_t size;
318         size_t from;
319         size_t count;
320         loff_t index;
321         u32    version;
322         struct mutex            lock;
323         const struct seq_operations *op;
324         void *private;
325 };
326
327 struct seq_operations {
328         void * (*start) (struct seq_file *m, loff_t *pos);
329         void (*stop) (struct seq_file *m, void *v);
330         void * (*next) (struct seq_file *m, void *v, loff_t *pos);
331         int (*show) (struct seq_file *m, void *v);
332 };
333
334 int seq_open(struct file *, const struct seq_operations *);
335 ssize_t seq_read(struct file *, char __user *, size_t, loff_t *);
336 loff_t seq_lseek(struct file *, loff_t, int);
337 int seq_release(struct inode *, struct file *);
338 int seq_escape(struct seq_file *, const char *, const char *);
339 int seq_putc(struct seq_file *m, char c);
340 int seq_puts(struct seq_file *m, const char *s);
341
342 int seq_printf(struct seq_file *, const char *, ...)
343         __attribute__ ((format (printf,2,3)));
344
345 int seq_path(struct seq_file *, struct path *, char *);
346
347 int single_open(struct file *, int (*)(struct seq_file *, void *), void *);
348 int single_release(struct inode *, struct file *);
349 void *__seq_open_private(struct file *, const struct seq_operations *, int);
350 int seq_open_private(struct file *, const struct seq_operations *, int);
351 int seq_release_private(struct inode *, struct file *);
352
353 #define SEQ_START_TOKEN ((void *)1)
354
355 /*
356  * Helpers for iteration over list_head-s in seq_files
357  */
358
359 extern cfs_list_t *seq_list_start(cfs_list_t *head, loff_t pos);
360 extern cfs_list_t *seq_list_start_head(cfs_list_t *head, loff_t pos);
361 extern cfs_list_t *seq_list_next(void *v, cfs_list_t *head, loff_t *ppos);
362
363 /*
364  *  declaration of proc kernel process routines
365  */
366
367 cfs_file_t *
368 lustre_open_file(char * filename);
369
370 int
371 lustre_close_file(cfs_file_t * fh);
372
373 int
374 lustre_do_ioctl( cfs_file_t * fh,
375                  unsigned long cmd,
376                  ulong_ptr_t arg );
377
378 int
379 lustre_ioctl_file( cfs_file_t * fh,
380                    PCFS_PROC_IOCTL devctl);
381
382 size_t
383 lustre_read_file( cfs_file_t *    fh,
384                   loff_t          offl,
385                   size_t          size,
386                   char *          buf
387                   );
388
389 size_t
390 lustre_write_file( cfs_file_t *    fh,
391                    loff_t          off,
392                    size_t          size,
393                    char *          buf
394                    );
395
396 /*
397  * Wait Queue
398  */
399
400
401 typedef int cfs_task_state_t;
402
403 #define CFS_TASK_INTERRUPTIBLE   0x00000001
404 #define CFS_TASK_UNINT           0x00000002
405 #define CFS_TASK_RUNNING         0x00000003
406 #define CFS_TASK_UNINTERRUPTIBLE CFS_TASK_UNINT
407
408 #define CFS_WAITQ_MAGIC     'CWQM'
409 #define CFS_WAITLINK_MAGIC  'CWLM'
410
411 typedef struct cfs_waitq {
412         unsigned int            magic;
413         unsigned int            flags;
414
415         spinlock_t              guard;
416         cfs_list_t              waiters;
417
418 } cfs_waitq_t;
419
420
421 typedef struct cfs_waitlink cfs_waitlink_t;
422
423 #define CFS_WAITQ_CHANNELS     (2)
424
425 #define CFS_WAITQ_CHAN_NORMAL  (0)
426 #define CFS_WAITQ_CHAN_FORWARD (1)
427
428
429
430 typedef struct cfs_waitlink_channel {
431     cfs_list_t              link;
432     cfs_waitq_t *           waitq;
433     cfs_waitlink_t *        waitl;
434 } cfs_waitlink_channel_t;
435
436 struct cfs_waitlink {
437
438     unsigned int            magic;
439     int                     flags;
440     event_t  *              event;
441     cfs_atomic_t *          hits;
442
443     cfs_waitlink_channel_t  waitq[CFS_WAITQ_CHANNELS];
444 };
445
446 enum {
447         CFS_WAITQ_EXCLUSIVE = 1
448 };
449
450 #define CFS_DECL_WAITQ(name) cfs_waitq_t name
451
452 /* Kernel thread */
453
454 typedef int (*cfs_thread_t) (void *arg);
455
456 typedef struct _cfs_thread_context {
457     cfs_thread_t        func;
458     void *              arg;
459 } cfs_thread_context_t;
460
461 int cfs_create_thread(int (*func)(void *), void *arg, unsigned long flag);
462
463 /*
464  * thread creation flags from Linux, not used in winnt
465  */
466 #define CSIGNAL         0x000000ff      /* signal mask to be sent at exit */
467 #define CLONE_VM        0x00000100      /* set if VM shared between processes */
468 #define CLONE_FS        0x00000200      /* set if fs info shared between processes */
469 #define CLONE_FILES     0x00000400      /* set if open files shared between processes */
470 #define CLONE_SIGHAND   0x00000800      /* set if signal handlers and blocked signals shared */
471 #define CLONE_PID       0x00001000      /* set if pid shared */
472 #define CLONE_PTRACE    0x00002000      /* set if we want to let tracing continue on the child too */
473 #define CLONE_VFORK     0x00004000      /* set if the parent wants the child to wake it up on mm_release */
474 #define CLONE_PARENT    0x00008000      /* set if we want to have the same parent as the cloner */
475 #define CLONE_THREAD    0x00010000      /* Same thread group? */
476 #define CLONE_NEWNS     0x00020000      /* New namespace group? */
477
478 #define CLONE_SIGNAL    (CLONE_SIGHAND | CLONE_THREAD)
479
480 #define CFS_DAEMON_FLAGS (CLONE_VM|CLONE_FILES)
481
482 /*
483  * group_info: linux/sched.h
484  */
485 #define NGROUPS_SMALL           32
486 #define NGROUPS_PER_BLOCK       ((int)(PAGE_SIZE / sizeof(gid_t)))
487 typedef struct cfs_group_info {
488         int ngroups;
489         cfs_atomic_t usage;
490         gid_t small_block[NGROUPS_SMALL];
491         int nblocks;
492         gid_t *blocks[0];
493 } cfs_group_info_t;
494
495 #define cfs_get_group_info(group_info) do { \
496         cfs_atomic_inc(&(group_info)->usage); \
497 } while (0)
498
499 #define cfs_put_group_info(group_info) do { \
500         if (cfs_atomic_dec_and_test(&(group_info)->usage)) \
501                 cfs_groups_free(group_info); \
502 } while (0)
503
504 static __inline cfs_group_info_t *cfs_groups_alloc(int gidsetsize)
505 {
506     cfs_group_info_t * groupinfo;
507     KdPrint(("%s(%d): %s NOT implemented.\n", __FILE__, __LINE__, __FUNCTION__));
508     groupinfo =
509         (cfs_group_info_t *)cfs_alloc(sizeof(cfs_group_info_t), 0);
510
511     if (groupinfo) {
512         memset(groupinfo, 0, sizeof(cfs_group_info_t));
513     }
514     return groupinfo;
515 }
516 static __inline void cfs_groups_free(cfs_group_info_t *group_info)
517 {
518     KdPrint(("%s(%d): %s NOT implemented.\n", __FILE__, __LINE__,
519             __FUNCTION__));
520     cfs_free(group_info);
521 }
522 static __inline int
523 cfs_set_current_groups(cfs_group_info_t *group_info)
524 {
525     KdPrint(("%s(%d): %s NOT implemented.\n", __FILE__, __LINE__,
526              __FUNCTION__));
527     return 0;
528 }
529 static __inline int groups_search(cfs_group_info_t *group_info,
530                                   gid_t grp) {
531     KdPrint(("%s(%d): %s NOT implemented.\n", __FILE__, __LINE__,
532             __FUNCTION__));
533     return 0;
534 }
535
536 /*
537  *   capability issue (linux/capability.h)
538  */
539
540 /* Override resource limits. Set resource limits. */
541 /* Override quota limits. */
542 /* Override reserved space on ext2 filesystem */
543 /* Modify data journaling mode on ext3 filesystem (uses journaling
544    resources) */
545 /* NOTE: ext2 honors fsuid when checking for resource overrides, so
546    you can override using fsuid too */
547 /* Override size restrictions on IPC message queues */
548 /* Allow more than 64hz interrupts from the real-time clock */
549 /* Override max number of consoles on console allocation */
550 /* Override max number of keymaps */
551
552 #define CAP_SYS_RESOURCE     24
553
554 /*
555  *  capabilities support 
556  */
557
558 typedef __u32 cfs_kernel_cap_t;
559
560 #define cap_raise(c, flag)  do {} while(0)
561 #define cap_lower(c, flag)  do {} while(0)
562 #define cap_raised(c, flag) do {} while(0)
563
564
565 /*
566  * Task struct
567  */
568
569 #define CFS_MAX_SCHEDULE_TIMEOUT     ((long_ptr_t)(~0UL>>12))
570 #define cfs_schedule_timeout(t)      cfs_schedule_timeout_and_set_state(0, t)
571
572 struct vfsmount;
573
574 #define NGROUPS 1
575 #define CFS_CURPROC_COMM_MAX (16)
576 typedef struct task_sruct{
577     mode_t                umask;
578     sigset_t              blocked;
579
580     pid_t                 pid;
581     pid_t                 pgrp;
582
583     uid_t                 uid,euid,suid,fsuid;
584     gid_t                 gid,egid,sgid,fsgid;
585
586     int                   ngroups;
587     int                   cgroups;
588     gid_t                 groups[NGROUPS];
589     cfs_group_info_t     *group_info;
590     cfs_kernel_cap_t      cap_effective,
591                           cap_inheritable,
592                           cap_permitted;
593
594     char                  comm[CFS_CURPROC_COMM_MAX];
595     void                 *journal_info;
596     struct vfsmount      *fs;
597 }  cfs_task_t;
598
599 static inline void task_lock(cfs_task_t *t)
600 {
601 }
602
603 static inline void task_unlock(cfs_task_t *t)
604 {
605 }
606
607 /*
608  *  linux task struct emulator ...
609  */
610
611 #define TASKMAN_MAGIC  'TMAN'   /* Task Manager */
612 #define TASKSLT_MAGIC  'TSLT'   /* Task Slot */
613
614 typedef struct _TASK_MAN {
615         ULONG           Magic;          /* Magic and Flags */
616         ULONG           Flags;
617
618         spinlock_t      Lock;           /* Protection lock */
619
620         cfs_mem_cache_t *slab;          /* Memory slab for task slot */
621
622         ULONG           NumOfTasks;     /* Total tasks (threads) */
623         LIST_ENTRY      TaskList;       /* List of task slots */
624 } TASK_MAN, *PTASK_MAN;
625
626 typedef struct _TASK_SLOT {
627
628     ULONG           Magic;      /* Magic and Flags */
629     ULONG           Flags;
630
631     LIST_ENTRY      Link;       /* To be linked to TaskMan */
632
633     event_t         Event;      /* Schedule event */
634
635     HANDLE          Pid;        /* Process id */
636     HANDLE          Tid;        /* Thread id */
637     PETHREAD        Tet;        /* Pointer to ethread */
638
639     cfs_atomic_t    count;      /* refer count */
640     cfs_atomic_t    hits;       /* times of waken event singaled */
641
642     KIRQL           irql;       /* irql for rwlock ... */
643
644     cfs_task_t      task;       /* linux task part */
645
646 } TASK_SLOT, *PTASK_SLOT;
647
648
649 #define current                      cfs_current()
650 #define cfs_set_current_state(s)     do {;} while (0)
651 #define cfs_set_current_state(state) cfs_set_current_state(state)
652
653 #define cfs_wait_event(wq, condition)                           \
654 do {                                                            \
655         cfs_waitlink_t __wait;                                  \
656                                                                 \
657         cfs_waitlink_init(&__wait);                             \
658         while (TRUE) {                                          \
659             cfs_waitq_add(&wq, &__wait);                        \
660             if (condition) {                                    \
661                 break;                                          \
662             }                                                   \
663             cfs_waitq_wait(&__wait, CFS_TASK_INTERRUPTIBLE);    \
664             cfs_waitq_del(&wq, &__wait);                        \
665         }                                                       \
666         cfs_waitq_del(&wq, &__wait);                            \
667 } while(0)
668
669 #define cfs_wait_event_interruptible(wq, condition, __ret)      \
670 do {                                                            \
671         cfs_waitlink_t __wait;                                  \
672                                                                 \
673         __ret = 0;                                              \
674         cfs_waitlink_init(&__wait);                             \
675         while (TRUE) {                                          \
676             cfs_waitq_add(&wq, &__wait);                        \
677             if (condition) {                                    \
678                 break;                                          \
679             }                                                   \
680             cfs_waitq_wait(&__wait, CFS_TASK_INTERRUPTIBLE);    \
681             cfs_waitq_del(&wq, &__wait);                        \
682         }                                                       \
683         cfs_waitq_del(&wq, &__wait);                            \
684 } while(0)
685
686 # define cfs_wait_event_interruptible_exclusive(wq, condition, rc)  \
687          cfs_wait_event_interruptible(wq, condition, rc)
688
689 /*
690    retval == 0; condition met; we're good.
691    retval < 0; interrupted by signal.
692    retval > 0; timed out.
693 */
694
695 #define cfs_waitq_wait_event_interruptible_timeout(             \
696                         wq, condition, timeout, rc)             \
697 do {                                                            \
698         cfs_waitlink_t __wait;                                  \
699                                                                 \
700         rc = 0;                                                 \
701         cfs_waitlink_init(&__wait);                             \
702         while (TRUE) {                                          \
703             cfs_waitq_add(&wq, &__wait);                        \
704             if (condition) {                                    \
705                 break;                                          \
706             }                                                   \
707             if (cfs_waitq_timedwait(&__wait,                    \
708                 CFS_TASK_INTERRUPTIBLE, timeout) == 0) {        \
709                 rc = TRUE;                                      \
710                 break;                                          \
711             }                                                   \
712             cfs_waitq_del(&wq, &__wait);                        \
713         }                                                       \
714         cfs_waitq_del(&wq, &__wait);                            \
715 } while(0)
716
717
718 #define cfs_waitq_wait_event_timeout                            \
719         cfs_waitq_wait_event_interruptible_timeout
720
721 int     init_task_manager();
722 void    cleanup_task_manager();
723 cfs_task_t * cfs_current();
724 int     wake_up_process(cfs_task_t * task);
725 void sleep_on(cfs_waitq_t *waitq);
726 #define cfs_might_sleep() do {} while(0)
727 #define CFS_DECL_JOURNAL_DATA   
728 #define CFS_PUSH_JOURNAL            do {;} while(0)
729 #define CFS_POP_JOURNAL             do {;} while(0)
730
731
732 /* module related definitions */
733
734 #ifndef __exit
735 #define __exit
736 #endif
737 #ifndef __init
738 #define __init
739 #endif
740
741 typedef struct cfs_module {
742     const char *name;
743 } cfs_module_t;
744
745 extern cfs_module_t libcfs_global_module;
746 #define THIS_MODULE  &libcfs_global_module
747
748 #define cfs_request_module(x, y) (0)
749 #define EXPORT_SYMBOL(s)
750 #define MODULE_AUTHOR(s)
751 #define MODULE_DESCRIPTION(s)
752 #define MODULE_LICENSE(s)
753 #define MODULE_PARM(a, b)
754 #define MODULE_PARM_DESC(a, b)
755
756 #define module_init(X) int  __init module_##X() {return X();}
757 #define module_exit(X) void __exit module_##X() {X();}
758
759 #define DECLARE_INIT(X) extern int  __init  module_##X(void)
760 #define DECLARE_EXIT(X) extern void __exit  module_##X(void)
761
762 #define MODULE_INIT(X) do { int rc = module_##X(); \
763                             if (rc) goto errorout; \
764                           } while(0)
765
766 #define MODULE_EXIT(X) do { module_##X(); } while(0)
767
768
769 /* Module interfaces */
770 #define cfs_module(name, version, init, fini) \
771         module_init(init);                    \
772         module_exit(fini)
773 #define cfs_module_refcount(x) (1)
774
775 /*
776  * typecheck
777  */
778
779 #define typecheck(a, b) do {} while(0)
780
781 /*
782  * linux/crypto.h
783  */
784
785 #define CRYPTO_MAX_ALG_NAME             64
786
787 #define CRYPTO_TFM_MODE_ECB             0x00000001
788 #define CRYPTO_TFM_MODE_CBC             0x00000002
789 #define CRYPTO_TFM_MODE_CFB             0x00000004
790 #define CRYPTO_TFM_MODE_CTR             0x00000008
791 #define CRYPTO_TFM_MODE_EME             0x00000010
792
793 /*
794  * hash
795  */
796 /* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */
797 #define GOLDEN_RATIO_PRIME_32 0x9e370001UL
798
799 #if 0 /* defined in libcfs/libcfs_hash.h */
800 static inline u32 cfs_hash_long(u32 val, unsigned int bits)
801 {
802         /* On some cpus multiply is faster, on others gcc will do shifts */
803         u32 hash = val * GOLDEN_RATIO_PRIME_32;
804
805         /* High bits are more random, so use them. */
806         return hash >> (32 - bits);
807 }
808 #endif
809
810 /*
811  * Timer
812  */
813
814 #define CFS_TIMER_FLAG_INITED   0x00000001  // Initialized already
815 #define CFS_TIMER_FLAG_TIMERED  0x00000002  // KeSetTimer is called
816
817 typedef struct cfs_timer {
818
819     KSPIN_LOCK      Lock;
820
821     ULONG           Flags;
822
823     KDPC            Dpc;
824     KTIMER          Timer;
825
826     cfs_time_t      deadline;
827
828     void (*proc)(ulong_ptr_t);
829     void *          arg;
830
831 } cfs_timer_t;
832
833 /*
834  *  libcfs globals initialization/cleanup
835  */
836
837 int
838 libcfs_arch_init(void);
839
840 void
841 libcfs_arch_cleanup(void);
842
843 /*
844  *  cache alignment size
845  */
846
847 #define CFS_L1_CACHE_ALIGN(x) (x)
848
849 #define __cacheline_aligned
850
851 /*
852  * SMP ...
853  */
854
855
856 #define SMP_CACHE_BYTES             128
857 #define CFS_NR_CPUS                 (32)
858 #define smp_num_cpus                ((CCHAR)KeNumberProcessors)
859 #define cfs_num_possible_cpus()     smp_num_cpus
860 #define cfs_num_present_cpus()      smp_num_cpus
861 #define cfs_num_online_cpus()       smp_num_cpus
862 #define cfs_smp_processor_id()      ((USHORT)KeGetCurrentProcessorNumber())
863 #define smp_call_function(f, a, n, w)           do {} while(0)
864 #define smp_rmb()                   do {} while(0)
865
866 /*
867  *  Irp related
868  */
869
870 #define CFS_NR_IRQS                 512
871 #define cfs_in_interrupt()          (0)
872
873 /*
874  *  printk flags
875  */
876
877 #define CFS_KERN_EMERG      "<0>"   /* system is unusable                   */
878 #define CFS_KERN_ALERT      "<1>"   /* action must be taken immediately     */
879 #define CFS_KERN_CRIT       "<2>"   /* critical conditions                  */
880 #define CFS_KERN_ERR        "<3>"   /* error conditions                     */
881 #define CFS_KERN_WARNING    "<4>"   /* warning conditions                   */
882 #define CFS_KERN_NOTICE     "<5>"   /* normal but significant condition     */
883 #define CFS_KERN_INFO       "<6>"   /* informational                        */
884 #define CFS_KERN_DEBUG      "<7>"   /* debug-level messages                 */
885
886 /*
887  * Misc
888  */
889
890 #define inter_module_get(n)                     cfs_symbol_get(n)
891 #define inter_module_put(n)                     cfs_symbol_put(n)
892
893 #ifndef likely
894 #define likely(exp) (exp)
895 #endif
896 #ifndef unlikely
897 #define unlikely(exp) (exp)
898 #endif
899
900 #define local_irq_save(x)
901 #define local_irq_restore(x)
902
903 #define THREAD_NAME
904
905 #define va_copy(_d, _s)                 (_d = _s)
906
907 char *strnchr(const char *s, size_t count, int c);
908
909 #define adler32(a,b,l) zlib_adler32(a,b,l)
910 ULONG zlib_adler32(ULONG adler, const BYTE *buf, UINT len);
911
912 typedef ssize_t (*read_actor_t)();
913
914 #if DBG
915 /*
916  *  winnt debug routines
917  */
918
919 VOID
920 KsPrintf(
921     LONG  DebugPrintLevel,
922     PCHAR DebugMessage,
923     ...
924     );
925
926 PUCHAR
927 KsNtStatusToString (IN NTSTATUS Status);
928 #endif
929
930 #else   /* !__KERNEL__ */
931
932 void cfs_enter_debugger();
933
934 /*
935  *  PAGE_SIZE ...
936  */
937
938 #ifndef PAGE_SIZE
939 #define PAGE_SIZE       (4096)
940 #endif
941
942 #define getpagesize()   (4096)
943
944 #define PAGE_CACHE_SIZE PAGE_SIZE
945 #define PAGE_CACHE_MASK PAGE_MASK
946
947 #define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) -1)
948 #define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t) -2)
949 #define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t) -3)
950
951 typedef struct file {
952     int foo;
953 } cfs_file_t;
954
955 #include "../user-prim.h"
956 #include "../user-lock.h"
957 #include <sys/stat.h>
958 #include <sys/types.h>
959
960 #define strcasecmp  strcmp
961 #define strncasecmp strncmp
962 #define getpid()   (0)
963
964 #define getuid()    (0)
965 #define getgrgid(x) (NULL)
966
967 struct passwd {
968         uid_t pw_uid;
969         char  pw_name[64];
970 };
971 struct passwd * getpwuid(uid_t uid);
972
973 int cfs_proc_mknod(const char *path, mode_t mode, dev_t dev);
974
975 int gethostname(char * name, int namelen);
976
977 #define setlinebuf(x) do {} while(0)
978
979
980 /* Maximum EA Information Length */
981 #define EA_MAX_LENGTH  (sizeof(FILE_FULL_EA_INFORMATION) + 15)
982
983 /*
984  *  proc user mode routines
985  */
986
987 int cfs_proc_open (char * filename, int oflag);
988 int cfs_proc_close(int fd);
989 int cfs_proc_read(int fd, void *buffer, unsigned int count);
990 int cfs_proc_write(int fd, void *buffer, unsigned int count);
991 int cfs_proc_ioctl(int fd, int cmd, void *buffer);
992 FILE *cfs_proc_fopen(char *path, char * mode);
993 char *cfs_proc_fgets(char * buf, int len, FILE *fp);
994 int cfs_proc_fclose(FILE *fp);
995
996 /* Bits set in the FLAGS argument to `glob'.  */
997 #define GLOB_ERR        (1 << 0)/* Return on read errors.  */
998 #define GLOB_MARK       (1 << 1)/* Append a slash to each name.  */
999 #define GLOB_NOSORT     (1 << 2)/* Don't sort the names.  */
1000 #define GLOB_DOOFFS     (1 << 3)/* Insert PGLOB->gl_offs NULLs.  */
1001 #define GLOB_NOCHECK    (1 << 4)/* If nothing matches, return the pattern.  */
1002 #define GLOB_APPEND     (1 << 5)/* Append to results of a previous call.  */
1003 #define GLOB_NOESCAPE   (1 << 6)/* Backslashes don't quote metacharacters.  */
1004 #define GLOB_PERIOD     (1 << 7)/* Leading `.' can be matched by metachars.  */
1005
1006 #if !defined __USE_POSIX2 || defined __USE_BSD || defined __USE_GNU
1007 # define GLOB_MAGCHAR    (1 << 8)/* Set in gl_flags if any metachars seen.  */
1008 # define GLOB_ALTDIRFUNC (1 << 9)/* Use gl_opendir et al functions.  */
1009 # define GLOB_BRACE      (1 << 10)/* Expand "{a,b}" to "a" "b".  */
1010 # define GLOB_NOMAGIC    (1 << 11)/* If no magic chars, return the pattern.  */
1011 # define GLOB_TILDE      (1 << 12)/* Expand ~user and ~ to home directories. */
1012 # define GLOB_ONLYDIR    (1 << 13)/* Match only directories.  */
1013 # define GLOB_TILDE_CHECK (1 << 14)/* Like GLOB_TILDE but return an error
1014                                       if the user name is not available.  */
1015 # define __GLOB_FLAGS   (GLOB_ERR|GLOB_MARK|GLOB_NOSORT|GLOB_DOOFFS| \
1016                          GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_APPEND|     \
1017                          GLOB_PERIOD|GLOB_ALTDIRFUNC|GLOB_BRACE|     \
1018                          GLOB_NOMAGIC|GLOB_TILDE|GLOB_ONLYDIR|GLOB_TILDE_CHECK)
1019 #else
1020 # define __GLOB_FLAGS   (GLOB_ERR|GLOB_MARK|GLOB_NOSORT|GLOB_DOOFFS| \
1021                          GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_APPEND|     \
1022                          GLOB_PERIOD)
1023 #endif
1024
1025 /* Error returns from `glob'.  */
1026 #define GLOB_NOSPACE    1       /* Ran out of memory.  */
1027 #define GLOB_ABORTED    2       /* Read error.  */
1028 #define GLOB_NOMATCH    3       /* No matches found.  */
1029 #define GLOB_NOSYS      4       /* Not implemented.  */
1030 #ifdef __USE_GNU
1031 /* Previous versions of this file defined GLOB_ABEND instead of
1032    GLOB_ABORTED.  Provide a compatibility definition here.  */
1033 # define GLOB_ABEND GLOB_ABORTED
1034 #endif
1035
1036 /* Structure describing a globbing run.  */
1037 #ifdef __USE_GNU
1038 struct stat;
1039 #endif
1040 typedef struct
1041   {
1042     size_t gl_pathc;            /* Count of paths matched by the pattern.  */
1043     char **gl_pathv;            /* List of matched pathnames.  */
1044     size_t gl_offs;             /* Slots to reserve in `gl_pathv'.  */
1045     int gl_flags;               /* Set to FLAGS, maybe | GLOB_MAGCHAR.  */
1046
1047     /* If the GLOB_ALTDIRFUNC flag is set, the following functions
1048        are used instead of the normal file access functions.  */
1049     void (*gl_closedir) (void *);
1050 #ifdef __USE_GNU
1051     struct dirent *(*gl_readdir) (void *);
1052 #else
1053     void *(*gl_readdir) (void *);
1054 #endif
1055     void *(*gl_opendir) (const char *);
1056 #ifdef __USE_GNU
1057     int (*gl_lstat) (const char *__restrict, struct stat *__restrict);
1058     int (*gl_stat) (const char *__restrict, struct stat *__restrict);
1059 #else
1060     int (*gl_lstat) (const char *__restrict, void *__restrict);
1061     int (*gl_stat) (const char *__restrict, void *__restrict);
1062 #endif
1063   } glob_t;
1064
1065 #ifdef __USE_LARGEFILE64
1066 # ifdef __USE_GNU
1067 struct stat64;
1068 # endif
1069 typedef struct
1070   {
1071     __size_t gl_pathc;
1072     char **gl_pathv;
1073     __size_t gl_offs;
1074     int gl_flags;
1075
1076     /* If the GLOB_ALTDIRFUNC flag is set, the following functions
1077        are used instead of the normal file access functions.  */
1078     void (*gl_closedir) (void *);
1079 # ifdef __USE_GNU
1080     struct dirent64 *(*gl_readdir) (void *);
1081 # else
1082     void *(*gl_readdir) (void *);
1083 # endif
1084     void *(*gl_opendir) (__const char *);
1085 # ifdef __USE_GNU
1086     int (*gl_lstat) (__const char *__restrict, struct stat64 *__restrict);
1087     int (*gl_stat) (__const char *__restrict, struct stat64 *__restrict);
1088 # else
1089     int (*gl_lstat) (__const char *__restrict, void *__restrict);
1090     int (*gl_stat) (__const char *__restrict, void *__restrict);
1091 # endif
1092   } glob64_t;
1093 #endif
1094
1095 int glob (const char * __pattern, int __flags,
1096                  int (*__errfunc) (const char *, int),
1097                  glob_t * __pglob);
1098 void globfree(glob_t *__pglog);
1099
1100 #endif /* !__KERNEL__ */
1101
1102 /*
1103  *  module routines
1104  */
1105
1106 static inline void __cfs_module_get(cfs_module_t *module)
1107 {
1108 }
1109
1110 static inline int cfs_try_module_get(cfs_module_t *module)
1111 {
1112     return 1;
1113 }
1114
1115 static inline void cfs_module_put(cfs_module_t *module)
1116 {
1117 }
1118
1119 /*
1120  *  sigset_t routines 
1121  */
1122
1123 typedef sigset_t cfs_sigset_t;
1124 #define sigaddset(what,sig) (*(what) |= (1<<(sig)), 0)
1125 #define sigdelset(what,sig) (*(what) &= ~(1<<(sig)), 0)
1126 #define sigemptyset(what)   (*(what) = 0, 0)
1127 #define sigfillset(what)    (*(what) = ~(0), 0)
1128 #define sigismember(what,sig) (((*(what)) & (1<<(sig))) != 0)
1129
1130 static __inline int
1131 sigprocmask(int sig, cfs_sigset_t *w1, cfs_sigset_t *w2) {
1132     return 0;
1133 }
1134 static __inline int
1135 sigpending(cfs_sigset_t *what) {
1136     return 0;
1137 }
1138
1139 /*
1140  * common inode flags (user & kernel)
1141  */
1142
1143 #define S_ISLNK(m)      (((m) & S_IFMT) == S_IFLNK)
1144 #define S_ISREG(m)      (((m) & S_IFMT) == S_IFREG)
1145 #define S_ISDIR(m)      (((m) & S_IFMT) == S_IFDIR)
1146 #define S_ISCHR(m)      (((m) & S_IFMT) == S_IFCHR)
1147 #define S_ISBLK(m)      (((m) & S_IFMT) == S_IFBLK)
1148 #define S_ISFIFO(m)     (((m) & S_IFMT) == S_IFIFO)
1149 #define S_ISSOCK(m)     (((m) & S_IFMT) == S_IFSOCK)
1150
1151 #define S_IRWXU 00700
1152 #define S_IRUSR 00400
1153 #define S_IWUSR 00200
1154 #define S_IXUSR 00100
1155
1156 #define S_IRWXG 00070
1157 #define S_IRGRP 00040
1158 #define S_IWGRP 00020
1159 #define S_IXGRP 00010
1160
1161 #define S_IRWXO 00007
1162 #define S_IROTH 00004
1163 #define S_IWOTH 00002
1164 #define S_IXOTH 00001
1165
1166 #define S_IRWXUGO   (S_IRWXU|S_IRWXG|S_IRWXO)
1167 #define S_IALLUGO   (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
1168 #define S_IRUGO     (S_IRUSR|S_IRGRP|S_IROTH)
1169 #define S_IWUGO     (S_IWUSR|S_IWGRP|S_IWOTH)
1170 #define S_IXUGO     (S_IXUSR|S_IXGRP|S_IXOTH)
1171
1172
1173 /*
1174  *  linux ioctl coding definitions
1175  */
1176  
1177 #define _IOC_NRBITS 8
1178 #define _IOC_TYPEBITS   8
1179 #define _IOC_SIZEBITS   14
1180 #define _IOC_DIRBITS    2
1181
1182 #define _IOC_NRMASK     ((1 << _IOC_NRBITS)-1)
1183 #define _IOC_TYPEMASK   ((1 << _IOC_TYPEBITS)-1)
1184 #define _IOC_SIZEMASK   ((1 << _IOC_SIZEBITS)-1)
1185 #define _IOC_DIRMASK    ((1 << _IOC_DIRBITS)-1)
1186
1187 #define _IOC_NRSHIFT    0
1188 #define _IOC_TYPESHIFT  (_IOC_NRSHIFT+_IOC_NRBITS)
1189 #define _IOC_SIZESHIFT  (_IOC_TYPESHIFT+_IOC_TYPEBITS)
1190 #define _IOC_DIRSHIFT   (_IOC_SIZESHIFT+_IOC_SIZEBITS)
1191
1192 /*
1193  * Direction bits.
1194  */
1195 #define _IOC_NONE   0U
1196 #define _IOC_WRITE  1U
1197 #define _IOC_READ   2U
1198
1199 #define _IOC(dir,type,nr,size) \
1200     (((dir)  << _IOC_DIRSHIFT) | \
1201      ((type) << _IOC_TYPESHIFT) | \
1202      ((nr)   << _IOC_NRSHIFT) | \
1203      ((size) << _IOC_SIZESHIFT))
1204
1205 /* used to create numbers */
1206 #define _IO(type,nr)      _IOC(_IOC_NONE,(type),(nr),0)
1207 #define _IOR(type,nr,size)    _IOC(_IOC_READ,(type),(nr),sizeof(size))
1208 #define _IOW(type,nr,size)    _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
1209 #define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
1210
1211 /* used to decode ioctl numbers.. */
1212 #define _IOC_DIR(nr)        (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
1213 #define _IOC_TYPE(nr)       (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
1214 #define _IOC_NR(nr)         (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
1215 #define _IOC_SIZE(nr)       (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
1216
1217 /* i/o vector sgructure ... */
1218 struct iovec {
1219     void *iov_base;
1220     size_t iov_len;
1221 };
1222
1223 /* idr support routines */
1224 struct idr_context *cfs_idr_init();
1225 int cfs_idr_remove(struct idr_context *idp, int id);
1226 int cfs_idr_get_new(struct idr_context *idp, void *ptr);
1227 int cfs_idr_get_new_above(struct idr_context *idp, void *ptr, int starting_id);
1228 void *cfs_idr_find(struct idr_context *idp, int id);
1229 void cfs_idr_exit(struct idr_context *idp);
1230
1231 /* runtime time routines for both kenrel and user mode */
1232 extern int cfs_isalpha(int);
1233 extern int cfs_isspace(int);
1234 extern int cfs_isupper(int);
1235 extern int cfs_isdigit(int);
1236 extern int cfs_isxdigit(int);
1237
1238 #define ULONG_LONG_MAX ((__u64)(0xFFFFFFFFFFFFFFFF))
1239 /*
1240  * Convert a string to an unsigned long long integer.
1241  *
1242  * Ignores `locale' stuff.  Assumes that the upper and lower case
1243  * alphabets and digits are each contiguous.
1244  */
1245 __u64 strtoull(char *nptr, char **endptr,int base);
1246
1247 /*
1248  *  getopt routines
1249  */
1250
1251 /* For communication from `getopt' to the caller.
1252    When `getopt' finds an option that takes an argument,
1253    the argument value is returned here.
1254    Also, when `ordering' is RETURN_IN_ORDER,
1255    each non-option ARGV-element is returned here.  */
1256
1257 extern char *optarg;
1258
1259 /* Index in ARGV of the next element to be scanned.
1260    This is used for communication to and from the caller
1261    and for communication between successive calls to `getopt'.
1262
1263    On entry to `getopt', zero means this is the first call; initialize.
1264
1265    When `getopt' returns -1, this is the index of the first of the
1266    non-option elements that the caller should itself scan.
1267
1268    Otherwise, `optind' communicates from one call to the next
1269    how much of ARGV has been scanned so far.  */
1270
1271 extern int optind;
1272
1273 /* Callers store zero here to inhibit the error message `getopt' prints
1274    for unrecognized options.  */
1275
1276 extern int opterr;
1277
1278 /* Set to an option character which was unrecognized.  */
1279
1280 extern int optopt;
1281
1282
1283 struct option
1284 {
1285   const char *name;
1286   /* has_arg can't be an enum because some compilers complain about
1287      type mismatches in all the code that assumes it is an int.  */
1288   int has_arg;
1289   int *flag;
1290   int val;
1291 };
1292
1293 /* Names for the values of the `has_arg' field of `struct option'.  */
1294 # define no_argument            0
1295 # define required_argument      1
1296 # define optional_argument      2
1297
1298 extern int getopt(int ___argc, char *const *___argv, const char *__shortopts);
1299 extern int getopt_long (int ___argc, char *const *___argv,
1300                         const char *__shortopts,
1301                         const struct option *__longopts, int *__longind);
1302 extern int getopt_long_only (int ___argc, char *const *___argv,
1303                              const char *__shortopts,
1304                              const struct option *__longopts, int *__longind);
1305
1306 extern char *strcasestr (const char *phaystack, const char *pneedle);
1307
1308 /*
1309  * global environment runtime routine
1310  */
1311
1312 static __inline char * __cdecl cfs_getenv(const char *ENV) {return NULL;}
1313 static __inline void   __cdecl set_getenv(const char *ENV, const char *value, int overwrite) {}
1314
1315 int setenv(const char *envname, const char *envval, int overwrite);
1316
1317 typedef struct utsname {
1318          char sysname[64];
1319          char nodename[64];
1320          char release[128];
1321          char version[128];
1322          char machine[64];
1323 };
1324
1325 int uname(struct utsname *uts);
1326
1327 #endif