Whamcloud - gitweb
LU-4748 test: get one single qos_threshold_rr number
[fs/lustre-release.git] / libcfs / libcfs / winnt / winnt-proc.c
index dd1e0d2..3d7e7bb 100644 (file)
@@ -1,6 +1,4 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
  * GPL HEADER START
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  * GPL HEADER END
  */
 /*
- * Copyright  2008 Sun Microsystems, Inc. All rights reserved
+ * 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 EXPORT_SYMTAB
-# define EXPORT_SYMTAB
-#endif
-
 # 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 *              proc_fs_root = NULL;
+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 *              proc_sys_root = NULL;
-
+cfs_proc_entry_t *              cfs_proc_sys = NULL;
 
 /* The sys root: /proc/dev | to implement misc device */
-
-cfs_proc_entry_t *              proc_dev_root = NULL;
+cfs_proc_entry_t *              cfs_proc_dev = NULL;
 
 
 /* SLAB object for cfs_proc_entry_t allocation */
-
-cfs_mem_cache_t *               proc_entry_cache = NULL;
+struct kmem_cache *proc_entry_cache;
 
 /* root node for sysctl table */
-
-cfs_sysctl_table_header_t       root_table_header;
+struct ctl_table_header       root_table_header;
 
 /* The global lock to protect all the access */
 
 #if LIBCFS_PROCFS_SPINLOCK
-spinlock_t                      proc_fs_lock;
+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)
+#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
 
-mutex_t                         proc_fs_lock;
+struct mutex                           proc_fs_lock;
 
-#define INIT_PROCFS_LOCK()      init_mutex(&proc_fs_lock)
-#define LOCK_PROCFS()           mutex_down(&proc_fs_lock)
-#define UNLOCK_PROCFS()         mutex_up(&proc_fs_lock)
+#define INIT_PROCFS_LOCK()      cfs_init_mutex(&proc_fs_lock)
+#define LOCK_PROCFS()           cfs_mutex_down(&proc_fs_lock)
+#define UNLOCK_PROCFS()         cfs_mutex_up(&proc_fs_lock)
 
 #endif
 
@@ -101,9 +98,10 @@ proc_file_read(struct file * file, const char * buf, size_t nbytes, loff_t *ppos
     char    *start;
     cfs_proc_entry_t * dp;
 
-    dp = (cfs_proc_entry_t  *) file->private_data;
-    if (!(page = (char*) cfs_alloc(CFS_PAGE_SIZE, 0)))
-        return -ENOMEM;
+       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) {
 
@@ -135,7 +133,7 @@ proc_file_read(struct file * file, const char * buf, size_t nbytes, loff_t *ppos
             break;
         }
         
-        n -= copy_to_user((void *)buf, start, n);
+       n -= copy_to_user((void *)buf, start, n);
         if (n == 0) {
             if (retval == 0)
                 retval = -EFAULT;
@@ -147,9 +145,9 @@ proc_file_read(struct file * file, const char * buf, size_t nbytes, loff_t *ppos
         buf += n;
         retval += n;
     }
-    cfs_free(page);
+       kfree(page);
 
-    return retval;
+       return retval;
 }
 
 static ssize_t
@@ -158,7 +156,7 @@ proc_file_write(struct file * file, const char * buffer,
 {
     cfs_proc_entry_t  * dp;
     
-    dp = (cfs_proc_entry_t *) file->private_data;
+    dp = (cfs_proc_entry_t *) file->f_inode->i_priv;
 
     if (!dp->write_proc)
         return -EIO;
@@ -168,6 +166,7 @@ proc_file_write(struct file * file, const char * buffer,
 }
 
 struct file_operations proc_file_operations = {
+    /*owner*/       THIS_MODULE,
     /*lseek:*/      NULL, //proc_file_lseek,
     /*read:*/       proc_file_read,
     /*write:*/      proc_file_write,
@@ -183,10 +182,9 @@ proc_alloc_entry()
 {
     cfs_proc_entry_t * entry = NULL;
 
-    entry = cfs_mem_cache_alloc(proc_entry_cache, 0);
-    if (!entry) {
-        return NULL;
-    }
+       entry = kmem_cache_alloc(proc_entry_cache, 0);
+       if (!entry)
+               return NULL;
 
     memset(entry, 0, sizeof(cfs_proc_entry_t));
 
@@ -201,18 +199,16 @@ proc_alloc_entry()
 
 void
 proc_free_entry(cfs_proc_entry_t * entry)
-
 {
-    ASSERT(entry->magic == CFS_PROC_ENTRY_MAGIC);
-
-    cfs_mem_cache_free(proc_entry_cache, 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(
-    char *path,
+    const char *path,
     char **first,
     int  *first_len,
     char **remain
@@ -229,12 +225,12 @@ proc_dissect_name(
 
     if (i < len) {
 
-        *first = path + i;
+        *first = (char *)path + i;
         while (i < len && (path[i] != '/')) i++;
-        *first_len = (path + i - *first);
+        *first_len = (int)(path + i - *first);
 
         if (i + 1 < len) {
-            *remain = path + i + 1;
+            *remain = (char *)path + i + 1;
         }
     }
 }
@@ -282,7 +278,6 @@ proc_search_splay (
 
             /*  The prefix is less than the full name
                 so we go down the right child      */
-            //
 
             link = RtlRightChild(link);
 
@@ -362,6 +357,7 @@ proc_insert_splay (
 
     cfs_set_flag(child->flags, CFS_PROC_FLAG_ATTACHED);
     parent->nlink++;
+    child->parent = parent;
 
     return TRUE;
 }
@@ -381,6 +377,7 @@ proc_remove_splay (
     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);
 
@@ -401,7 +398,7 @@ proc_remove_splay (
 
 cfs_proc_entry_t *
 proc_search_entry(
-    char *              name,
+    const char *        name,
     cfs_proc_entry_t *  root
     )
 {
@@ -414,11 +411,10 @@ proc_search_entry(
     parent = root;
     entry = NULL;
 
-    ename = cfs_alloc(0x21, CFS_ALLOC_ZERO);
+       ename = kmalloc(0x21, __GFP_ZERO);
 
-    if (ename == NULL) {
-        goto errorout;
-    }
+       if (ename == NULL)
+               goto errorout;
 
 again:
 
@@ -453,7 +449,7 @@ again:
 errorout:
 
     if (ename) {
-        cfs_free(ename);
+       kfree(ename);
     }
 
     return entry;   
@@ -463,7 +459,7 @@ errorout:
 
 cfs_proc_entry_t *
 proc_insert_entry(
-    char *              name,
+    const char *        name,
     cfs_proc_entry_t *  root
     )
 {
@@ -495,12 +491,10 @@ again:
             entry = proc_alloc_entry();
             memcpy(entry->name, ename, flen);
 
-            if (entry) {
-                if(!proc_insert_splay(parent, entry)) {
-                    proc_free_entry(entry);
-                    entry = NULL;
-                }
-            }
+               if (entry && !proc_insert_splay(parent, entry)) {
+                       proc_free_entry(entry);
+                       entry = NULL;
+               }
         }
 
         if (!entry) {
@@ -523,7 +517,7 @@ again:
 
 void
 proc_remove_entry(
-    char *              name,
+    const char *        name,
     cfs_proc_entry_t *  root
     )
 {
@@ -564,12 +558,11 @@ proc_remove_entry(
 
 cfs_proc_entry_t *
 create_proc_entry (
-    char *              name,
+    const char *        name,
     mode_t              mode,
-    cfs_proc_entry_t *  root
+    cfs_proc_entry_t *  parent
     )
 {
-    cfs_proc_entry_t *parent = root;
     cfs_proc_entry_t *entry  = NULL;
 
     if (S_ISDIR(mode)) {
@@ -583,11 +576,15 @@ create_proc_entry (
     }
 
     LOCK_PROCFS();
-
-    ASSERT(NULL != proc_fs_root);
+    ASSERT(NULL != cfs_proc_root);
 
     if (!parent) {
-        parent = proc_fs_root;
+        if (name[0] == '/') {
+            parent = cfs_proc_root;
+        } else {
+            ASSERT(NULL != cfs_proc_proc);
+            parent = cfs_proc_proc;
+        }
     }
 
     entry = proc_search_entry(name, parent);
@@ -619,15 +616,21 @@ errorout:
 
 cfs_proc_entry_t *
 search_proc_entry(
-    char *              name,
+    const char *        name,
     cfs_proc_entry_t *  root
     )
 {
     cfs_proc_entry_t * entry;
 
     LOCK_PROCFS();
+    ASSERT(cfs_proc_root != NULL);
     if (root == NULL) {
-        root = proc_fs_root;
+        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();
@@ -639,13 +642,19 @@ search_proc_entry(
 
 void
 remove_proc_entry(
-    char *              name,
+    const char *        name,
     cfs_proc_entry_t *  parent
     )
 {
     LOCK_PROCFS();
+    ASSERT(cfs_proc_root != NULL);
     if (parent == NULL) {
-        parent = proc_fs_root;
+        if (name[0] == '/') {
+            parent = cfs_proc_root;
+        } else {
+            ASSERT(cfs_proc_proc != NULL);
+            parent = cfs_proc_proc;
+        }
     }
     proc_remove_entry(name, parent);
     UNLOCK_PROCFS();
@@ -668,26 +677,111 @@ void proc_destroy_splay(cfs_proc_entry_t * entry)
     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();
+       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 (proc_fs_root) {
-        proc_destroy_splay(proc_fs_root);
+    if (S_ISDIR(node->mode)) {
+        proc_show_tree(node);
     }
+}
+
+void proc_show_child(PRTL_SPLAY_LINKS link)
+{
+    cfs_proc_entry_t * entry  = NULL;
 
-    if (proc_entry_cache) {
-        cfs_mem_cache_destroy(proc_entry_cache);
+    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 */
 
+/* initilaize / build the proc fs tree */
 int proc_init_fs()
 {
     cfs_proc_entry_t * root = NULL;
@@ -696,61 +790,57 @@ int proc_init_fs()
     INIT_LIST_HEAD(&(root_table_header.ctl_entry));
 
     INIT_PROCFS_LOCK();
-    proc_entry_cache = cfs_mem_cache_create(
-                            NULL,
-                            sizeof(cfs_proc_entry_t),
-                            0,
-                            0
-                            );
+    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;
 
-    root->name[0]='p';
-    root->name[1]='r';
-    root->name[2]='o';
-    root->name[3]='c';
-
-    proc_fs_root = root;
-
-    proc_sys_root = create_proc_entry("sys", S_IFDIR, root);
-
-    if (!proc_sys_root) {
-        proc_free_entry(root);
-        proc_fs_root = NULL;
-        proc_destroy_fs();
-        return (-ENOMEM);
+    cfs_proc_dev = create_proc_entry("dev", S_IFDIR, root);
+    if (!cfs_proc_dev) {
+        goto errorout;
     }
+    cfs_proc_dev->nlink = 1;
 
-    proc_sys_root->nlink = 1;
+    cfs_proc_proc  = create_proc_entry("proc", S_IFDIR, root);
+    if (!cfs_proc_proc) {
+        goto errorout;
+    }
+    cfs_proc_proc->nlink = 1;
 
-    proc_dev_root = create_proc_entry("dev", S_IFDIR, root);
+    cfs_proc_fs = create_proc_entry("fs",  S_IFDIR, cfs_proc_proc);
+    if (!cfs_proc_fs) {
+        goto errorout;
+    }
+    cfs_proc_fs->nlink = 1;
 
-    if (!proc_dev_root) {
-        proc_free_entry(proc_sys_root);
-        proc_sys_root = NULL;
-        proc_free_entry(proc_fs_root);
-        proc_fs_root = NULL;
-        proc_destroy_fs();
-        return (-ENOMEM);
+    cfs_proc_sys = create_proc_entry("sys",  S_IFDIR, cfs_proc_proc);
+    if (!cfs_proc_sys) {
+        goto errorout;
     }
+    cfs_proc_sys->nlink = 1;
 
-    proc_dev_root->nlink = 1;
-   
+  
     return 0;
+
+errorout:
+
+    proc_destroy_fs();
+    return (-ENOMEM);
 }
 
 
@@ -772,9 +862,6 @@ static ssize_t do_rw_proc(int write, struct file * file, char * buf,
         return -ENOTDIR;
     op = (write ? 002 : 004);
 
-//  if (ctl_perm(table, op))
-//      return -EPERM;
-    
     res = count;
 
     /*
@@ -801,6 +888,7 @@ static ssize_t proc_writesys(struct file * file, const char * buf,
 
 
 struct file_operations proc_sys_file_operations = {
+    /*owner*/       THIS_MODULE,
     /*lseek:*/      NULL,
     /*read:*/       proc_readsys,
     /*write:*/      proc_writesys,
@@ -811,7 +899,7 @@ struct file_operations proc_sys_file_operations = {
 
 
 /* Scan the sysctl entries in table and add them all into /proc */
-void register_proc_table(cfs_sysctl_table_t * table, cfs_proc_entry_t * root)
+void register_proc_table(struct ctl_table * table, cfs_proc_entry_t * root)
 {
     cfs_proc_entry_t * de;
     int len;
@@ -821,12 +909,12 @@ void register_proc_table(cfs_sysctl_table_t * table, cfs_proc_entry_t * root)
         /* 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;
-        }
+       /* 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;
@@ -862,17 +950,17 @@ void register_proc_table(cfs_sysctl_table_t * table, cfs_proc_entry_t * root)
 /*
  * Unregister a /proc sysctl table and any subdirectories.
  */
-void unregister_proc_table(cfs_sysctl_table_t * table, cfs_proc_entry_t *root)
+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;
-            }
+           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.. */
@@ -890,7 +978,7 @@ void unregister_proc_table(cfs_sysctl_table_t * table, cfs_proc_entry_t *root)
 }
 
 /* The generic string strategy routine: */
-int sysctl_string(cfs_sysctl_table_t *table, int *name, int nlen,
+int sysctl_string(struct ctl_table *table, int *name, int nlen,
           void *oldval, size_t *oldlenp,
           void *newval, size_t newlen, void **context)
 {
@@ -900,26 +988,27 @@ int sysctl_string(cfs_sysctl_table_t *table, int *name, int nlen,
         return -ENOTDIR;
     
     if (oldval && oldlenp) {
-        if(get_user(len, 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 (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))
+       if (copy_from_user(table->data, newval, len))
             return -EFAULT;
         if (len == table->maxlen)
             len--;
@@ -943,14 +1032,14 @@ unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
         if (*cp == '0') {
             base = 8;
             cp++;
-            if ((*cp == 'x') && isxdigit(cp[1])) {
+            if ((*cp == 'x') && cfs_isxdigit(cp[1])) {
                 cp++;
                 base = 16;
             }
         }
     }
-    while (isxdigit(*cp) &&
-           (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
+    while (cfs_isxdigit(*cp) &&
+           (value = cfs_isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
         result = result*base + value;
         cp++;
     }
@@ -966,7 +1055,7 @@ unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
 #define OP_MIN  4
 
 
-static int do_proc_dointvec(cfs_sysctl_table_t *table, int write, struct file *filp,
+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;
@@ -989,12 +1078,12 @@ static int do_proc_dointvec(cfs_sysctl_table_t *table, int write, struct file *f
         if (write) {
             while (left) {
                 char c;
-                if(get_user(c,(char *) buffer))
-                    return -EFAULT;
+               if (get_user(c, (char *)buffer))
+                       return -EFAULT;
                 if (!isspace(c))
-                    break;
+                       break;
                 left--;
-                ((char *) buffer)++;
+               ((char *)buffer)++;
             }
             if (!left)
                 break;
@@ -1002,7 +1091,7 @@ static int do_proc_dointvec(cfs_sysctl_table_t *table, int write, struct file *f
             len = left;
             if (len > TMPBUFLEN-1)
                 len = TMPBUFLEN-1;
-            if(copy_from_user(buf, buffer, len))
+           if (copy_from_user(buf, buffer, len))
                 return -EFAULT;
             buf[len] = 0;
             p = buf;
@@ -1020,17 +1109,25 @@ static int do_proc_dointvec(cfs_sysctl_table_t *table, int write, struct file *f
                 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;
-            }
+               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)
@@ -1039,7 +1136,7 @@ static int do_proc_dointvec(cfs_sysctl_table_t *table, int write, struct file *f
             len = strlen(buf);
             if (len > left)
                 len = left;
-            if(copy_to_user(buffer, buf, len))
+           if (copy_to_user(buffer, buf, len))
                 return -EFAULT;
             left -= len;
             (char *)buffer += len;
@@ -1047,7 +1144,7 @@ static int do_proc_dointvec(cfs_sysctl_table_t *table, int write, struct file *f
     }
 
     if (!write && !first && left) {
-        if(put_user('\n', (char *) buffer))
+       if (put_user('\n', (char *) buffer))
             return -EFAULT;
         left--, ((char *)buffer)++;
     }
@@ -1055,7 +1152,7 @@ static int do_proc_dointvec(cfs_sysctl_table_t *table, int write, struct file *f
         p = (char *) buffer;
         while (left) {
             char c;
-            if(get_user(c, p++))
+           if (get_user(c, p++))
                 return -EFAULT;
             if (!isspace(c))
                 break;
@@ -1065,8 +1162,6 @@ static int do_proc_dointvec(cfs_sysctl_table_t *table, int write, struct file *f
     if (write && first)
         return -EINVAL;
     *lenp -= left;
-    memset(&(filp->f_pos) , 0, sizeof(loff_t));
-    filp->f_pos += (loff_t)(*lenp);
     return 0;
 }
 
@@ -1074,7 +1169,6 @@ static int do_proc_dointvec(cfs_sysctl_table_t *table, int write, struct file *f
  * proc_dointvec - read a vector of integers
  * @table: the sysctl table
  * @write: %TRUE if this is a write to the sysctl file
- * @filp: the file structure
  * @buffer: the user buffer
  * @lenp: the size of the user buffer
  *
@@ -1083,10 +1177,10 @@ static int do_proc_dointvec(cfs_sysctl_table_t *table, int write, struct file *f
  *
  * Returns 0 on success.
  */
-int proc_dointvec(cfs_sysctl_table_t *table, int write, struct file *filp,
+int proc_dointvec(struct ctl_table *table, int write,
              void *buffer, size_t *lenp)
 {
-    return do_proc_dointvec(table,write,filp,buffer,lenp,1,OP_SET);
+    return do_proc_dointvec(table,write,buffer,lenp,1,OP_SET);
 }
 
 
@@ -1094,7 +1188,6 @@ int proc_dointvec(cfs_sysctl_table_t *table, int write, struct file *filp,
  * proc_dostring - read a string sysctl
  * @table: the sysctl table
  * @write: %TRUE if this is a write to the sysctl file
- * @filp: the file structure
  * @buffer: the user buffer
  * @lenp: the size of the user buffer
  *
@@ -1107,14 +1200,14 @@ int proc_dointvec(cfs_sysctl_table_t *table, int write, struct file *filp,
  *
  * Returns 0 on success.
  */
-int proc_dostring(cfs_sysctl_table_t *table, int write, struct file *filp,
+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 ||
-        (filp->f_pos && !write)) {
+       (!write)) {
         *lenp = 0;
         return 0;
     }
@@ -1123,7 +1216,7 @@ int proc_dostring(cfs_sysctl_table_t *table, int write, struct file *filp,
         len = 0;
         p = buffer;
         while (len < *lenp) {
-            if(get_user(c, p++))
+           if (get_user(c, p++))
                 return -EFAULT;
             if (c == 0 || c == '\n')
                 break;
@@ -1131,10 +1224,9 @@ int proc_dostring(cfs_sysctl_table_t *table, int write, struct file *filp,
         }
         if (len >= (size_t)table->maxlen)
             len = (size_t)table->maxlen-1;
-        if(copy_from_user(table->data, buffer, len))
+       if (copy_from_user(table->data, buffer, len))
             return -EFAULT;
         ((char *) table->data)[len] = 0;
-        filp->f_pos += *lenp;
     } else {
         len = (size_t)strlen(table->data);
         if (len > (size_t)table->maxlen)
@@ -1142,24 +1234,22 @@ int proc_dostring(cfs_sysctl_table_t *table, int write, struct file *filp,
         if (len > *lenp)
             len = *lenp;
         if (len)
-            if(copy_to_user(buffer, table->data, len))
+           if (copy_to_user(buffer, table->data, len))
                 return -EFAULT;
         if (len < *lenp) {
-            if(put_user('\n', ((char *) buffer) + len))
+           if (put_user('\n', ((char *) buffer) + len))
                 return -EFAULT;
             len++;
         }
         *lenp = len;
-        filp->f_pos += len;
     }
     return 0;
 }
 
 /* Perform the actual read/write of a sysctl table entry. */
-int do_sysctl_strategy (cfs_sysctl_table_t *table, 
-            int *name, int nlen,
-            void *oldval, size_t *oldlenp,
-            void *newval, size_t newlen, void **context)
+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;
@@ -1186,9 +1276,9 @@ int do_sysctl_strategy (cfs_sysctl_table_t *table,
             if (len) {
                 if (len > (size_t)table->maxlen)
                     len = (size_t)table->maxlen;
-                if(copy_to_user(oldval, table->data, len))
+               if (copy_to_user(oldval, table->data, len))
                     return -EFAULT;
-                if(put_user(len, oldlenp))
+               if (put_user(len, oldlenp))
                     return -EFAULT;
             }
         }
@@ -1196,7 +1286,7 @@ int do_sysctl_strategy (cfs_sysctl_table_t *table,
             len = newlen;
             if (len > (size_t)table->maxlen)
                 len = (size_t)table->maxlen;
-            if(copy_from_user(table->data, newval, len))
+           if (copy_from_user(table->data, newval, len))
                 return -EFAULT;
         }
     }
@@ -1204,9 +1294,9 @@ int do_sysctl_strategy (cfs_sysctl_table_t *table,
 }
 
 static int parse_table(int *name, int nlen,
-               void *oldval, size_t *oldlenp,
-               void *newval, size_t newlen,
-               cfs_sysctl_table_t *table, void **context)
+              void *oldval, size_t *oldlenp,
+              void *newval, size_t newlen,
+              struct ctl_table *table, void **context)
 {
     int n;
 
@@ -1261,13 +1351,13 @@ int do_sysctl(int *name, int nlen, void *oldval, size_t *oldlenp,
     tmp = &root_table_header.ctl_entry;
     do {
         struct ctl_table_header *head =
-            list_entry(tmp, struct ctl_table_header, ctl_entry);
+           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)
-            cfs_free(context);
+           kfree(context);
         if (error != -ENOTDIR)
             return error;
         tmp = tmp->next;
@@ -1344,24 +1434,21 @@ int do_sysctl(int *name, int nlen, void *oldval, size_t *oldlenp,
  * 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(cfs_sysctl_table_t * table, 
-                           int insert_at_head)
+struct ctl_table_header *
+register_sysctl_table(struct ctl_table *table)
 {
-    struct ctl_table_header *tmp;
-    tmp = cfs_alloc(sizeof(struct ctl_table_header), 0);
-    if (!tmp)
-        return NULL;
-    tmp->ctl_table = table;
-
-    INIT_LIST_HEAD(&tmp->ctl_entry);
-    if (insert_at_head)
-        list_add(&tmp->ctl_entry, &root_table_header.ctl_entry);
-    else
-        list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry);
+       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, proc_sys_root);
+       register_proc_table(table, cfs_proc_sys);
 #endif
-    return tmp;
+       return tmp;
 }
 
 /**
@@ -1375,20 +1462,20 @@ void unregister_sysctl_table(struct ctl_table_header * header)
 {
     list_del(&header->ctl_entry);
 #ifdef CONFIG_PROC_FS
-    unregister_proc_table(header->ctl_table, proc_sys_root);
+    unregister_proc_table(header->ctl_table, cfs_proc_sys);
 #endif
-    cfs_free(header);
+    kfree(header);
 }
 
 
-int cfs_psdev_register(cfs_psdev_t * psdev)
+int misc_register(struct miscdevice * psdev)
 {
     cfs_proc_entry_t *  entry;
 
     entry = create_proc_entry (
                 (char *)psdev->name,
                 S_IFREG,
-                proc_dev_root
+                cfs_proc_dev
             );
 
     if (!entry) {
@@ -1403,13 +1490,13 @@ int cfs_psdev_register(cfs_psdev_t * psdev)
     return 0;
 }
 
-int cfs_psdev_deregister(cfs_psdev_t * psdev)
+int misc_deregister(struct miscdevice * psdev)
 {
     cfs_proc_entry_t *  entry;
 
     entry = search_proc_entry (
                 (char *)psdev->name,
-                proc_dev_root
+                cfs_proc_dev
             );
 
     if (entry) {
@@ -1419,15 +1506,13 @@ int cfs_psdev_deregister(cfs_psdev_t * psdev)
 
         remove_proc_entry(
             (char *)psdev->name,
-            proc_dev_root
+            cfs_proc_dev
             );
     }
 
     return 0;
 }
 
-extern char debug_file_path[1024];
-
 #define PSDEV_LNET  (0x100)
 enum {
         PSDEV_DEBUG = 1,          /* control debugging */
@@ -1446,10 +1531,8 @@ static struct ctl_table lnet_table[] = {
          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, 
+        {PSDEV_CONSOLE_RATELIMIT, "console_ratelimit", &libcfs_console_ratelimit,
          sizeof(int), 0644, NULL, &proc_dointvec},
-        {PSDEV_DEBUG_PATH, "debug_path", debug_file_path,
-         sizeof(debug_file_path), 0644, NULL, &proc_dostring, &sysctl_string},
 /*
         {PSDEV_PORTALS_UPCALL, "upcall", portals_upcall,
          sizeof(portals_upcall), 0644, NULL, &proc_dostring,
@@ -1469,7 +1552,7 @@ static struct ctl_table top_table[2] = {
 int trace_write_dump_kernel(struct file *file, const char *buffer,
                              unsigned long count, void *data)
 {
-        int rc = trace_dump_debug_buffer_usrstr(buffer, count);
+        int rc = cfs_trace_dump_debug_buffer_usrstr((void *)buffer, count);
         
         return (rc < 0) ? rc : count;
 }
@@ -1477,7 +1560,7 @@ int trace_write_dump_kernel(struct file *file, const char *buffer,
 int trace_write_daemon_file(struct file *file, const char *buffer,
                             unsigned long count, void *data)
 {
-        int rc = trace_daemon_command_usrstr(buffer, count);
+        int rc = cfs_trace_daemon_command_usrstr((void *)buffer, count);
 
         return (rc < 0) ? rc : count;
 }
@@ -1485,21 +1568,17 @@ int trace_write_daemon_file(struct file *file, const char *buffer,
 int trace_read_daemon_file(char *page, char **start, off_t off, int count,
                            int *eof, void *data)
 {
-       int rc;
-
-       tracefile_read_lock();
-
-        rc = trace_copyout_string(page, count, tracefile, "\n");
-
-        tracefile_read_unlock();
-
-       return rc;
+        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 = trace_set_debug_mb_userstr(buffer, count);
+        int rc = 0; /*trace_set_debug_mb_userstr((void *)buffer, count);*/
         
         return (rc < 0) ? rc : count;
 }
@@ -1509,9 +1588,9 @@ int trace_read_debug_mb(char *page, char **start, off_t off, int count,
 {
         char   str[32];
 
-        snprintf(str, sizeof(str), "%d\n", trace_get_debug_mb());
+        snprintf(str, sizeof(str), "%d\n", cfs_trace_get_debug_mb());
 
-        return trace_copyout_string(page, count, str, NULL);
+        return cfs_trace_copyout_string(page, count, str, NULL);
 }
 
 int insert_proc(void)
@@ -1520,14 +1599,14 @@ int insert_proc(void)
 
         ent = create_proc_entry("sys/lnet/dump_kernel", 0, NULL);
         if (ent == NULL) {
-                CERROR(("couldn't register dump_kernel\n"));
+                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"));
+                CERROR("couldn't register daemon_file\n");
                 return -1;
         }
         ent->write_proc = trace_write_daemon_file;
@@ -1535,7 +1614,7 @@ int insert_proc(void)
 
         ent = create_proc_entry("sys/lnet/debug_mb", 0, NULL);
         if (ent == NULL) {
-                CERROR(("couldn't register debug_mb\n"));
+                CERROR("couldn't register debug_mb\n");
                 return -1;
         }
         ent->write_proc = trace_write_debug_mb;
@@ -1546,15 +1625,9 @@ int insert_proc(void)
 
 void remove_proc(void)
 {
-        remove_proc_entry("sys/portals/dump_kernel", NULL);
-        remove_proc_entry("sys/portals/daemon_file", NULL);
-        remove_proc_entry("sys/portals/debug_mb", NULL);
-
-#ifdef CONFIG_SYSCTL
-        if (portals_table_header)
-                unregister_sysctl_table(portals_table_header);
-        portals_table_header = NULL;
-#endif
+        remove_proc_entry("sys/lnet/dump_kernel", NULL);
+        remove_proc_entry("sys/lnet/daemon_file", NULL);
+        remove_proc_entry("sys/lnet/debug_mb", NULL);
 }
 
 
@@ -1562,38 +1635,39 @@ void remove_proc(void)
  *  proc process routines of kernel space
  */
 
-cfs_file_t *
-lustre_open_file(char * filename)
+struct file *
+lustre_open_file(char *filename)
 {
-    int rc = 0;
-    cfs_file_t * fh = NULL;
-    cfs_proc_entry_t * fp = NULL;
+       int rc = 0;
+       struct file *fh = NULL;
+       cfs_proc_entry_t *fp = NULL;
 
-    fp = search_proc_entry(filename, proc_fs_root);
-
-    if (!fp) {
-        rc =  -ENOENT;
-        return NULL;
-    }
+       fp = search_proc_entry(filename, cfs_proc_root);
+       if (fp == NULL)
+               return NULL;
 
-    fh = cfs_alloc(sizeof(cfs_file_t), CFS_ALLOC_ZERO);
+       fh = kmalloc(sizeof(*fh), __GFP_ZERO);
+       if (fh == NULL)
+               return NULL;
 
-    if (!fh) {
-        rc =  -ENOMEM;
+    fh->f_inode = kmalloc(sizeof(struct inode), __GFP_ZERO);
+    if (!fh->f_inode) {
+       kfree(fh);
         return NULL;
     }
 
-    fh->private_data = (void *)fp;
+    fh->f_inode->i_priv = (void *)fp;
     fh->f_op = fp->proc_fops;
 
     if (fh->f_op->open) {
-        rc = (fh->f_op->open)(fh);
+        rc = (fh->f_op->open)(fh->f_inode, fh);
     } else {
         fp->nlink++;
     }
 
     if (0 != rc) {
-        cfs_free(fh);
+       kfree(fh->f_inode);
+       kfree(fh);
         return NULL;
     }
 
@@ -1601,54 +1675,51 @@ lustre_open_file(char * filename)
 }
 
 int
-lustre_close_file(cfs_file_t * fh)
+lustre_close_file(struct file *fh)
 {
-    int rc = 0;
-    cfs_proc_entry_t * fp = NULL;
-
-    fp = (cfs_proc_entry_t *) fh->private_data;
+       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);
+        rc = (fh->f_op->release)(fh->f_inode, fh);
     } else {
         fp->nlink--;
     }
 
-    cfs_free(fh);
+    kfree(fh->f_inode);
+    kfree(fh);
 
     return rc;
 }
 
 int
-lustre_do_ioctl( cfs_file_t * fh,
-                 unsigned long cmd,
-                 ulong_ptr arg )
+lustre_do_ioctl(struct file *fh, unsigned long cmd, ulong_ptr_t arg)
 {
-    int rc = 0;
+       int rc = 0;
 
-    if (fh->f_op->ioctl) {
-        rc = (fh->f_op->ioctl)(fh, cmd, arg);
-    }
-
-    if (rc != 0) {
-        printk("lustre_do_ioctl: fialed: cmd = %xh arg = %xh rc = %d\n",
-                cmd, arg, rc);
-    }
+       if (fh->f_op->ioctl)
+               rc = (fh->f_op->ioctl)(fh, cmd, arg);
 
-    return rc;
+       return rc;
 }
-    
+
 int
-lustre_ioctl_file(cfs_file_t * fh, PCFS_PROC_IOCTL devctl)
+lustre_ioctl_file(struct file *fh, PCFS_PROC_IOCTL devctl)
 {
     int         rc = 0;
-    ulong_ptr   data;
+    ulong_ptr_t data;
 
-    data = (ulong_ptr)devctl + sizeof(CFS_PROC_IOCTL);
+    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') {
-#if 0
+
         struct obd_ioctl_data * obd = (struct obd_ioctl_data *) data;
 
         if ( devctl->cmd != (ULONG)OBD_IOC_BRW_WRITE  &&
@@ -1656,400 +1727,583 @@ lustre_ioctl_file(cfs_file_t * fh, PCFS_PROC_IOCTL devctl)
 
             unsigned long off = obd->ioc_len;
 
-            if (obd->ioc_pbuf1) {
+            if (obd->ioc_plen1) {
                 obd->ioc_pbuf1 = (char *)(data + off);
-                off += size_round(obd->ioc_plen1);
+                off += cfs_size_round(obd->ioc_plen1);
+            } else {
+                obd->ioc_pbuf1 = NULL;
             }
 
-            if (obd->ioc_pbuf2) {
+            if (obd->ioc_plen2) {
                 obd->ioc_pbuf2 = (char *)(data + off);
+                off += cfs_size_round(obd->ioc_plen2);
+            } else {
+                obd->ioc_pbuf2 = NULL;
             }
         }
- #endif
-   }
+    }
 
     rc = lustre_do_ioctl(fh, devctl->cmd, data);
 
     return rc;
-} 
-
+}
 
 size_t
-lustre_read_file(
-    cfs_file_t *    fh,
-    loff_t          off,
-    size_t          size,
-    char *          buf
-    )
+lustre_read_file(struct file *fh, loff_t off, size_t size, char *buf)
 {
-    size_t rc = 0;
+    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(
-    cfs_file_t *    fh,
-    loff_t          off,
-    size_t          size,
-    char *          buf
-    )
+lustre_write_file(struct file *fh, loff_t off, size_t size, char *buf)
 {
-    size_t rc = 0;
+       size_t rc = 0;
 
-    if (fh->f_op->write) {
-        rc = (fh->f_op->write)(fh, buf, size, &off);
-    }
-
-    return rc;
-}  
+       off = 0;
+       if (fh->f_op->write)
+               rc = (fh->f_op->write)(fh, buf, size, &off);
 
-#else /* !__KERNEL__ */
+       return rc;
+}
 
-#include <lnet/api-support.h>
-#include <liblustre.h>
-#include <lustre_lib.h>
 
 /*
- * proc process routines of user space
+ *  seq file routines
  */
 
-HANDLE cfs_proc_open (char * filename, int oflag)
-{
-    NTSTATUS            status;
-    IO_STATUS_BLOCK     iosb;
-    int                 rc;
-
-    HANDLE              FileHandle = 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;
-    UCHAR               EaBuffer[EA_MAX_LENGTH];
-
-    /* Check the filename: should start with "/proc" or "/dev" */
-    NameLength = (USHORT)strlen(filename);
-    if (NameLength > 0x05) {
-        if (_strnicmp(filename, "/proc/", 6) == 0) {
-            filename += 6;
-            NameLength -=6;
-            if (NameLength <= 0) {
-                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 ...  */
-    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 = ZwCreateFile(
-                &FileHandle,
-                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:
-
-    return FileHandle;
+/**
+ *     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);
 
-int cfs_proc_close(HANDLE handle)
+/**
+ *     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)
 {
-    if (handle) {
-        NtClose((HANDLE)handle);
-    }
-
-    return 0;
+       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);
 
-int cfs_proc_read(HANDLE handle, void *buffer, unsigned int count)
+static int traverse(struct seq_file *m, loff_t offset)
 {
-    NTSTATUS            status;
-    IO_STATUS_BLOCK     iosb;
-    LARGE_INTEGER       offset;
-
-
-    offset.QuadPart = 0;
+       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;
+}
 
-    /* read file data */
-    status = NtReadFile(
-                (HANDLE)handle,
-                0,
-                NULL,
-                NULL,
-                &iosb,
-                buffer,
-                count,
-                &offset,
-                NULL);                     
+/**
+ *     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);
 
-    /* check the return status */
-    if (!NT_SUCCESS(status)) {
-        printf("NtReadFile request failed 0x%0x\n", status);
-        goto errorout;
+/**
+ *     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);
 
-errorout:
+/**
+ *     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);
 
-    if (NT_SUCCESS(status)) {
-        return iosb.Information;
-    }
+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);
 
-    return cfs_error_code(status);
+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);
 
-int cfs_proc_write(HANDLE handle, void *buffer, unsigned int count)
+static void *single_start(struct seq_file *p, loff_t *pos)
 {
-    NTSTATUS            status;
-    IO_STATUS_BLOCK     iosb;
-    LARGE_INTEGER       offset;
+       return (void *) (INT_PTR) (*pos == 0);
+}
 
-    offset.QuadPart = -1;
+static void *single_next(struct seq_file *p, void *v, loff_t *pos)
+{
+       ++*pos;
+       return NULL;
+}
 
-    /* write buffer to the opened file */
-    status = NtWriteFile(
-                (HANDLE)handle,
-                0,
-                NULL,
-                NULL,
-                &iosb,
-                buffer,
-                count,
-                &offset,
-                NULL);                     
+static void single_stop(struct seq_file *p, void *v)
+{
+}
 
-    /* check the return status */
-    if (!NT_SUCCESS(status)) {
-        printf("NtWriteFile request failed 0x%0x\n", status);
-        goto errorout;
-    }
+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);
 
-errorout:
+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);
 
-    if (NT_SUCCESS(status)) {
-        return iosb.Information;
-    }
+int seq_release_private(struct inode *inode, struct file *file)
+{
+       struct seq_file *seq = file->private_data;
 
-    return cfs_error_code(status);
+       kfree(seq->private);
+       seq->private = NULL;
+       return seq_release(inode, file);
 }
+EXPORT_SYMBOL(seq_release_private);
 
-int cfs_proc_ioctl(HANDLE handle, int cmd, void *buffer)
+void *__seq_open_private(struct file *f, const struct seq_operations *ops,
+               int psize)
 {
-    PUCHAR          procdat = NULL;
-    CFS_PROC_IOCTL  procctl;
-    ULONG           length = 0;
-    ULONG           extra = 0;
+       int rc;
+       void *private;
+       struct seq_file *seq;
 
-    NTSTATUS        status;
-    IO_STATUS_BLOCK iosb;
+       private = kmalloc(psize, GFP_KERNEL | __GFP_ZERO);
+       if (private == NULL)
+               goto out;
 
-    procctl.cmd = cmd;
+       rc = seq_open(f, ops);
+       if (rc < 0)
+               goto out_free;
 
-    if(_IOC_TYPE(cmd) == IOC_LIBCFS_TYPE) {
-        struct libcfs_ioctl_data * portal;
-        portal = (struct libcfs_ioctl_data *) buffer;
-        length = portal->ioc_len;
-    } else if (_IOC_TYPE(cmd) == 'f') {
-        struct obd_ioctl_data * obd;
-        obd = (struct obd_ioctl_data *) buffer;
-        length = obd->ioc_len;
-        extra = size_round(obd->ioc_plen1) + size_round(obd->ioc_plen2);
-    } else if(_IOC_TYPE(cmd) == 'u') {
-        length = 4;
-        extra  = 0;
-    } else {
-        printf("user:winnt-proc:cfs_proc_ioctl: un-supported ioctl type ...\n");
-        cfs_enter_debugger();
-        status = STATUS_INVALID_PARAMETER;
-        goto errorout;
-    }
+       seq = f->private_data;
+       seq->private = private;
+       return private;
 
-    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);
+out_free:
+       kfree(private);
+out:
+       return NULL;
+}
+EXPORT_SYMBOL(__seq_open_private);
 
-    if (_IOC_TYPE(cmd) == 'f') {
+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);
 
-        char *ptr;
-        struct obd_ioctl_data * data;
-        struct obd_ioctl_data * obd;
+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);
 
-        data = (struct obd_ioctl_data *) buffer;
-        obd  = (struct obd_ioctl_data *) (procdat + sizeof(CFS_PROC_IOCTL));
-        ptr = obd->ioc_bulk;
+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);
 
-        if (data->ioc_inlbuf1) {
-                obd->ioc_inlbuf1 = ptr;
-                LOGL(data->ioc_inlbuf1, data->ioc_inllen1, ptr);
-        }
+struct list_head *seq_list_start(struct list_head *head, loff_t pos)
+{
+       struct list_head *lh;
 
-        if (data->ioc_inlbuf2) {
-                obd->ioc_inlbuf2 = ptr;
-                LOGL(data->ioc_inlbuf2, data->ioc_inllen2, ptr);
-        }
-        if (data->ioc_inlbuf3) {
-                obd->ioc_inlbuf3 = ptr;
-                LOGL(data->ioc_inlbuf3, data->ioc_inllen3, ptr);
-        }
-        if (data->ioc_inlbuf4) {
-                obd->ioc_inlbuf4 = ptr;
-                LOGL(data->ioc_inlbuf4, data->ioc_inllen4, ptr);
-        }
-    
-        if ( cmd != (ULONG)OBD_IOC_BRW_WRITE  &&
-             cmd != (ULONG)OBD_IOC_BRW_READ ) {
+       list_for_each(lh, head)
+               if (pos-- == 0)
+                       return lh;
 
-            if (data->ioc_pbuf1 && data->ioc_plen1) {
-                obd->ioc_pbuf1 = &procdat[length];
-                memcpy(obd->ioc_pbuf1, data->ioc_pbuf1, data->ioc_plen1); 
-                length += size_round(data->ioc_plen1);
-            }
+       return NULL;
+}
 
-            if (data->ioc_pbuf2 && data->ioc_plen2) {
-                obd->ioc_pbuf2 = &procdat[length];
-                memcpy(obd->ioc_pbuf2, data->ioc_pbuf2, data->ioc_plen2);
-                length += size_round(data->ioc_plen2);
-            }
-        }
+EXPORT_SYMBOL(seq_list_start);
 
-        if (obd_ioctl_is_invalid(obd)) {
-            cfs_enter_debugger();
-        }
-    }
+struct list_head *seq_list_start_head(struct list_head *head,
+                                loff_t pos)
+{
+       if (!pos)
+               return head;
 
-    status = NtDeviceIoControlFile(
-                (HANDLE)handle,
-                NULL, NULL, NULL, &iosb,
-                IOCTL_LIBCFS_ENTRY,
-                procdat, length,
-                procdat, length );
+       return seq_list_start(head, pos - 1);
+}
 
+EXPORT_SYMBOL(seq_list_start_head);
 
-    if (NT_SUCCESS(status)) {
-        memcpy(buffer, &procdat[sizeof(CFS_PROC_IOCTL)], procctl.len); 
-    }
+struct list_head *seq_list_next(void *v, struct list_head *head,
+                          loff_t *ppos)
+{
+       struct list_head *lh;
 
-errorout:
+       lh = ((struct list_head *)v)->next;
+       ++*ppos;
+       return lh == head ? NULL : lh;
+}
 
-    if (procdat) {
-        free(procdat);
-    }
+EXPORT_SYMBOL(seq_list_next);
 
-    return cfs_error_code(status);
+struct proc_dir_entry *PDE(const struct inode *inode)
+{
+       return (struct proc_dir_entry *)inode->i_priv;
 }
 
+
 #endif /* __KERNEL__ */