Whamcloud - gitweb
landing b_open onto b_devel:
authorpschwan <pschwan>
Sun, 18 May 2003 16:39:34 +0000 (16:39 +0000)
committerpschwan <pschwan>
Sun, 18 May 2003 16:39:34 +0000 (16:39 +0000)
 - kernel patches for bug 1203
 - fixes directory open()s
 - re-enables metadata caching on the MDS
 - fixes bug in ext3_noread kernel patch
 - fixes some symbol export problems in other kernels
 - fixes compilation problems when running on Red Hat 2.4.20 kernels

If you update past this merge, you will require kernel version 18

17 files changed:
lustre/kernel_patches/patches/dsp.patch [new file with mode: 0644]
lustre/kernel_patches/patches/ext3-delete_thread-2.4.20.patch
lustre/kernel_patches/patches/ext3-noread-2.4.20.patch
lustre/kernel_patches/patches/ext3_orphan_lock-2.4.20-rh.patch [new file with mode: 0644]
lustre/kernel_patches/patches/iopen-chaos-2.4.18.patch [new file with mode: 0644]
lustre/kernel_patches/patches/iopen.patch [new file with mode: 0644]
lustre/kernel_patches/patches/kmem_cache_validate_2.4.20.patch [new file with mode: 0644]
lustre/kernel_patches/patches/mcore-2.4.20-8.patch [new file with mode: 0644]
lustre/kernel_patches/patches/uml-patch-2.4.20-4.patch
lustre/kernel_patches/pc/dsp.pc [new file with mode: 0644]
lustre/kernel_patches/pc/ext3_orphan_lock-2.4.20-rh.pc [new file with mode: 0644]
lustre/kernel_patches/pc/iopen-chaos-2.4.18.pc [new file with mode: 0644]
lustre/kernel_patches/pc/iopen.pc [new file with mode: 0644]
lustre/kernel_patches/pc/kmem_cache_validate_2.4.20.pc [new file with mode: 0644]
lustre/kernel_patches/pc/mcore-2.4.20-8.pc [new file with mode: 0644]
lustre/kernel_patches/pc/uml-patch-2.4.20-4.pc
lustre/tests/fchdir_test.c [new file with mode: 0644]

diff --git a/lustre/kernel_patches/patches/dsp.patch b/lustre/kernel_patches/patches/dsp.patch
new file mode 100644 (file)
index 0000000..f2e5b93
--- /dev/null
@@ -0,0 +1,130 @@
+ arch/i386/kernel/crash.c |   24 +++++++++++++++++-------
+ arch/i386/kernel/nmi.c   |    2 +-
+ include/asm-i386/apic.h  |    1 +
+ include/linux/crash.h    |    2 +-
+ kernel/bootimg.c         |   13 ++++++++++++-
+ kernel/bootimg_pic.c     |    6 ++++--
+ 6 files changed, 36 insertions(+), 12 deletions(-)
+
+--- linux-rh-2.4.20-8/kernel/bootimg.c~dsp     2003-05-07 19:30:47.000000000 +0800
++++ linux-rh-2.4.20-8-root/kernel/bootimg.c    2003-05-07 19:31:12.000000000 +0800
+@@ -238,9 +238,20 @@ int boot_image()
+       int error = -ENOMEM;
+       if (bootimg_checksum(__va(bootimg_dsc.page_dir),bootimg_dsc.pages) 
+-              != bootimg_dsc.csum)
++              != bootimg_dsc.csum) {
+               printk("Checksum of kernel image failed.  Rebooting via BIOS\n");
++              /* Before calling machine_restart(), make sure it will not
++               * simply call this function recursively.
++               */
++              bootimg_dsc.page_dir = NULL;
++              machine_restart(NULL);
++
++              /* We should never get here, but just in case... */
++              for (; ; )
++                      __asm__ __volatile__ ("hlt");
++      }
++
+       code_page = get_identity_mapped_page();
+       if (!code_page) goto out3;
+       code = (relocate_and_jump_t) virt_to_phys((void *) code_page);
+--- linux-rh-2.4.20-8/kernel/bootimg_pic.c~dsp 2003-05-07 19:30:47.000000000 +0800
++++ linux-rh-2.4.20-8-root/kernel/bootimg_pic.c        2003-05-07 19:31:12.000000000 +0800
+@@ -69,7 +69,8 @@ void __bootimg relocate_and_jump(void)
+                       for (j = i+1; j < dsc.pages; j++) {
+                               table = dsc.page_dir+FROM_TABLE(j);
+                               if (((unsigned long) *table) == to) {
+-                                      copy_and_swap(*table,dsc.scratch);
++                                      copy_and_swap((unsigned long) (*table),
++                                                    dsc.scratch);
+                                       break;
+                               }
+                               if ((*table)[PAGE_NR(j)] == to) {
+@@ -79,7 +80,8 @@ void __bootimg relocate_and_jump(void)
+                               }
+                               table = dsc.page_dir+TO_TABLE(j);
+                               if (((unsigned long) *table) == to) {
+-                                      copy_and_swap(*table,dsc.scratch);
++                                      copy_and_swap((unsigned long) (*table),
++                                                    dsc.scratch);
+                                       break;
+                               }
+                       }
+--- linux-rh-2.4.20-8/include/asm-i386/apic.h~dsp      2003-05-07 17:00:16.000000000 +0800
++++ linux-rh-2.4.20-8-root/include/asm-i386/apic.h     2003-05-07 19:31:12.000000000 +0800
+@@ -86,6 +86,7 @@ extern struct pm_dev *apic_pm_register(p
+ extern void apic_pm_unregister(struct pm_dev*);
+ extern int check_nmi_watchdog (void);
++extern void disable_apic_nmi_watchdog(void);
+ extern unsigned int nmi_watchdog;
+ #define NMI_NONE      0
+--- linux-rh-2.4.20-8/include/linux/crash.h~dsp        2003-05-07 19:30:47.000000000 +0800
++++ linux-rh-2.4.20-8-root/include/linux/crash.h       2003-05-07 19:31:12.000000000 +0800
+@@ -71,7 +71,7 @@ extern void stop_this_cpu(void *);
+ #define CRASH_ZALLOC_PAGES 16*5*2     /* 2 to handle crash in crash */
+ #define CRASH_LOW_WATER_PAGES 100
+-#define CRASH_CPU_TIMEOUT 5000        /* 5 sec wait for other cpus to stop */
++#define CRASH_CPU_TIMEOUT 15000       /* 15 sec wait for other cpus to stop */
+ #define CRASH_MARK_RESERVED(addr) (set_bit(PG_reserved,&mem_map[MAP_NR(addr)].flags))
+ #define CRASH_CLEAR_RESERVED(addr) (clear_bit(PG_reserved,&mem_map[MAP_NR(addr)].flags))
+--- linux-rh-2.4.20-8/arch/i386/kernel/crash.c~dsp     2003-05-07 19:30:47.000000000 +0800
++++ linux-rh-2.4.20-8-root/arch/i386/kernel/crash.c    2003-05-07 19:31:39.000000000 +0800
+@@ -9,6 +9,8 @@
+ #include <linux/crash.h>
+ #include <linux/reboot.h>
+ #include <linux/bootimg.h>
++#include <asm/fixmap.h>
++#include <asm/apic.h>
+ inline void crash_save_regs(void) {
+       static unsigned long regs[8];
+@@ -30,15 +32,23 @@ inline void crash_save_regs(void) {
+  */
+ void crash_save_current_state(struct task_struct *tp)
+ {
++      if (tp != NULL) {
++              /*
++               *  Here we save ebp instead of esp just in case the compiler
++               *  decides to put an extra push in before we execute this
++               *  instruction (thus invalidating our frame pointer).
++               */
++              asm volatile("movl %%ebp,%0":"=m" (*(u_long *)&tp->thread.esp));
++              tp->thread.eip = (u_long)crash_save_current_state;
++              panic_ksp[smp_processor_id()] = tp->thread.esp;
++              mb();
++      }
++
+       /*
+-       *  Here we save ebp instead of esp just in case the compiler
+-       *  decides to put an extra push in before we execute this
+-       *  instruction (thus invalidating our frame pointer).
++       * Just to be safe, disable the NMI watchdog on the calling CPU so it
++       * doesn't get in the way while we are trying to save a dump.
+        */
+-      asm volatile("movl %%ebp,%0":"=m" (*(u_long *)&tp->thread.esp));
+-      tp->thread.eip = (u_long)crash_save_current_state;
+-      panic_ksp[smp_processor_id()] = tp->thread.esp;
+-      mb();
++      disable_apic_nmi_watchdog();
+       save_core();
+--- linux-rh-2.4.20-8/arch/i386/kernel/nmi.c~dsp       2003-05-07 19:30:47.000000000 +0800
++++ linux-rh-2.4.20-8-root/arch/i386/kernel/nmi.c      2003-05-07 19:31:12.000000000 +0800
+@@ -138,7 +138,7 @@ __setup("nmi_watchdog=", setup_nmi_watch
+ struct pm_dev *nmi_pmdev;
+-static void disable_apic_nmi_watchdog(void)
++void disable_apic_nmi_watchdog(void)
+ {
+       switch (boot_cpu_data.x86_vendor) {
+       case X86_VENDOR_AMD:
+
+_
index 5f67fef..f989c2b 100644 (file)
@@ -267,7 +267,7 @@ diff -puNr origin/include/linux/ext3_fs.h linux/include/linux/ext3_fs.h
  #define EXT3_MOUNT_UPDATE_JOURNAL     0x1000  /* Update the journal format */
  #define EXT3_MOUNT_NO_UID32           0x2000  /* Disable 32-bit UIDs */
  #define EXT3_MOUNT_XATTR_USER         0x4000  /* Extended user attributes */
-+#define EXT3_MOUNT_ASYNCDEL          0x10000  /* Delayed deletion */
++#define EXT3_MOUNT_ASYNCDEL          0x20000  /* Delayed deletion */
  
  /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
  #ifndef _LINUX_EXT2_FS_H
index 8c2fcd7..275c6df 100644 (file)
@@ -3,8 +3,8 @@
  include/linux/ext3_fs.h |    2 +
  3 files changed, 121 insertions(+), 24 deletions(-)
 
---- linux-2.4.20/fs/ext3/ialloc.c~extN-noread-2.4.20   2003-05-04 16:41:22.000000000 +0800
-+++ linux-2.4.20-root/fs/ext3/ialloc.c 2003-05-04 17:19:29.000000000 +0800
+--- linux-2.4.20/fs/ext3/ialloc.c~ext3-noread-2.4.20   2003-05-16 12:21:39.000000000 +0800
++++ linux-2.4.20-root/fs/ext3/ialloc.c 2003-05-16 12:21:46.000000000 +0800
 @@ -289,6 +289,37 @@ error_return:
  }
  
@@ -73,8 +73,8 @@
        
        unlock_super (sb);
        if(DQUOT_ALLOC_INODE(inode)) {
---- linux-2.4.20/fs/ext3/inode.c~extN-noread-2.4.20    2003-05-04 16:41:26.000000000 +0800
-+++ linux-2.4.20-root/fs/ext3/inode.c  2003-05-04 17:22:49.000000000 +0800
+--- linux-2.4.20/fs/ext3/inode.c~ext3-noread-2.4.20    2003-05-16 12:21:41.000000000 +0800
++++ linux-2.4.20-root/fs/ext3/inode.c  2003-05-16 12:22:15.000000000 +0800
 @@ -2013,14 +2013,19 @@ out_stop:
        ext3_journal_stop(handle, inode);
  }
 +              block_end = block + NUM_INODE_PREREAD;
 +              if (block_end > itable_end)
 +                      block_end = itable_end;
-+ 
++              block++; 
 +              for (; block < block_end; block++) {
 +                      bh[count] = sb_getblk(inode->i_sb, block);
 +                      if (count && (buffer_uptodate(bh[count]) ||
  void ext3_read_inode(struct inode * inode)
  {
        struct ext3_iloc iloc;
---- linux-2.4.20/include/linux/ext3_fs.h~extN-noread-2.4.20    2003-05-04 16:41:22.000000000 +0800
-+++ linux-2.4.20-root/include/linux/ext3_fs.h  2003-05-04 17:19:29.000000000 +0800
+--- linux-2.4.20/include/linux/ext3_fs.h~ext3-noread-2.4.20    2003-05-16 12:21:39.000000000 +0800
++++ linux-2.4.20-root/include/linux/ext3_fs.h  2003-05-16 12:21:46.000000000 +0800
 @@ -683,6 +683,8 @@ extern int ext3_forget(handle_t *, int, 
  extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
  extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
diff --git a/lustre/kernel_patches/patches/ext3_orphan_lock-2.4.20-rh.patch b/lustre/kernel_patches/patches/ext3_orphan_lock-2.4.20-rh.patch
new file mode 100644 (file)
index 0000000..d029650
--- /dev/null
@@ -0,0 +1,82 @@
+ fs/ext3/namei.c            |   15 +++++++--------
+ fs/ext3/super.c            |    1 +
+ include/linux/ext3_fs_sb.h |    1 +
+ 3 files changed, 9 insertions(+), 8 deletions(-)
+
+--- linux-rh-2.4.20-8/fs/ext3/namei.c~ext3_orphan_lock-2.4.20-rh       2003-05-05 19:49:15.000000000 +0800
++++ linux-rh-2.4.20-8-root/fs/ext3/namei.c     2003-05-05 20:01:28.000000000 +0800
+@@ -1747,8 +1747,8 @@ int ext3_orphan_add(handle_t *handle, st
+       struct super_block *sb = inode->i_sb;
+       struct ext3_iloc iloc;
+       int err = 0, rc;
+-      
+-      lock_super(sb);
++
++      down(&EXT3_SB(sb)->s_orphan_lock);
+       if (!list_empty(&EXT3_I(inode)->i_orphan))
+               goto out_unlock;
+@@ -1796,7 +1796,7 @@ int ext3_orphan_add(handle_t *handle, st
+       jbd_debug(4, "orphan inode %ld will point to %d\n",
+                       inode->i_ino, NEXT_ORPHAN(inode));
+ out_unlock:
+-      unlock_super(sb);
++      up(&EXT3_SB(sb)->s_orphan_lock);
+       ext3_std_error(inode->i_sb, err);
+       return err;
+ }
+@@ -1809,20 +1809,19 @@ int ext3_orphan_del(handle_t *handle, st
+ {
+       struct list_head *prev;
+       struct ext3_inode_info *ei = EXT3_I(inode);
+-      struct ext3_sb_info *sbi;
++      struct ext3_sb_info *sbi = EXT3_SB(inode->i_sb);
+       unsigned long ino_next;
+       struct ext3_iloc iloc;
+       int err = 0;
+-      lock_super(inode->i_sb);
++      down(&sbi->s_orphan_lock);
+       if (list_empty(&ei->i_orphan)) {
+-              unlock_super(inode->i_sb);
++              up(&sbi->s_orphan_lock);
+               return 0;
+       }
+       ino_next = NEXT_ORPHAN(inode);
+       prev = ei->i_orphan.prev;
+-      sbi = EXT3_SB(inode->i_sb);
+       jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino);
+@@ -1871,7 +1870,7 @@ int ext3_orphan_del(handle_t *handle, st
+ out_err:
+       ext3_std_error(inode->i_sb, err);
+ out:
+-      unlock_super(inode->i_sb);
++      up(&sbi->s_orphan_lock);
+       return err;
+ out_brelse:
+--- linux-rh-2.4.20-8/fs/ext3/super.c~ext3_orphan_lock-2.4.20-rh       2003-05-05 19:49:15.000000000 +0800
++++ linux-rh-2.4.20-8-root/fs/ext3/super.c     2003-05-05 19:54:09.000000000 +0800
+@@ -1151,6 +1151,7 @@ struct super_block * ext3_read_super (st
+        */
+       sb->s_op = &ext3_sops;
+       INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
++      sema_init(&sbi->s_orphan_lock, 1);
+       sb->s_root = 0;
+--- linux-rh-2.4.20-8/include/linux/ext3_fs_sb.h~ext3_orphan_lock-2.4.20-rh    2003-05-05 19:49:07.000000000 +0800
++++ linux-rh-2.4.20-8-root/include/linux/ext3_fs_sb.h  2003-05-05 19:54:09.000000000 +0800
+@@ -69,6 +69,7 @@ struct ext3_sb_info {
+       struct inode * s_journal_inode;
+       struct journal_s * s_journal;
+       struct list_head s_orphan;
++      struct semaphore s_orphan_lock;
+       unsigned long s_commit_interval;
+       struct block_device *journal_bdev;
+ #ifdef CONFIG_JBD_DEBUG
+
+_
diff --git a/lustre/kernel_patches/patches/iopen-chaos-2.4.18.patch b/lustre/kernel_patches/patches/iopen-chaos-2.4.18.patch
new file mode 100644 (file)
index 0000000..901ae0d
--- /dev/null
@@ -0,0 +1,400 @@
+ Documentation/filesystems/ext2.txt |   16 ++
+ fs/ext3/Makefile                   |    2 
+ fs/ext3/inode.c                    |    4 
+ fs/ext3/iopen.c                    |  236 +++++++++++++++++++++++++++++++++++++
+ fs/ext3/iopen.h                    |   15 ++
+ fs/ext3/namei.c                    |   12 +
+ fs/ext3/super.c                    |   11 +
+ include/linux/ext3_fs.h            |    2 
+ 8 files changed, 297 insertions(+), 1 deletion(-)
+
+--- linux-2.4.18-p4smp/Documentation/filesystems/ext2.txt~iopen-chaos-2.4.18   2002-05-07 15:53:59.000000000 -0600
++++ linux-2.4.18-p4smp-braam/Documentation/filesystems/ext2.txt        2003-05-17 13:14:22.000000000 -0600
+@@ -35,6 +35,22 @@ resgid=n                    The group ID which may use th
+ sb=n                          Use alternate superblock at this location.
++iopen                         Makes an invisible pseudo-directory called 
++                              __iopen__ available in the root directory
++                              of the filesystem.  Allows open-by-inode-
++                              number.  i.e., inode 3145 can be accessed
++                              via /mntpt/__iopen__/3145
++
++iopen_nopriv                  This option makes the iopen directory be
++                              world-readable.  This may be safer since it
++                              allows daemons to run as an unprivileged user,
++                              however it significantly changes the security
++                              model of a Unix filesystem, since previously
++                              all files under a mode 700 directory were not
++                              generally avilable even if the
++                              permissions on the file itself is
++                              world-readable.
++
+ grpquota,noquota,quota,usrquota       Quota options are silently ignored by ext2.
+--- linux-2.4.18-p4smp/fs/ext3/Makefile~iopen-chaos-2.4.18     2003-05-17 13:12:44.000000000 -0600
++++ linux-2.4.18-p4smp-braam/fs/ext3/Makefile  2003-05-17 13:15:06.000000000 -0600
+@@ -11,7 +11,7 @@ O_TARGET := ext3.o
+ export-objs :=        super.o inode.o xattr.o
+-obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
++obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o\
+               ioctl.o namei.o super.o symlink.o xattr.o
+ obj-m    := $(O_TARGET)
+--- linux-2.4.18-p4smp/fs/ext3/inode.c~iopen-chaos-2.4.18      2003-05-17 13:12:55.000000000 -0600
++++ linux-2.4.18-p4smp-braam/fs/ext3/inode.c   2003-05-17 13:14:22.000000000 -0600
+@@ -31,6 +31,7 @@
+ #include <linux/highuid.h>
+ #include <linux/quotaops.h>
+ #include <linux/module.h>
++#include "iopen.h"
+ /*
+  * SEARCH_FROM_ZERO forces each block allocation to search from the start
+@@ -2135,6 +2136,9 @@ void ext3_read_inode(struct inode * inod
+       struct buffer_head *bh;
+       int block;
+       
++      if (ext3_iopen_get_inode(inode))
++              return;
++      
+       if(ext3_get_inode_loc(inode, &iloc))
+               goto bad_inode;
+       bh = iloc.bh;
+--- /dev/null  2003-01-30 03:24:37.000000000 -0700
++++ linux-2.4.18-p4smp-braam/fs/ext3/iopen.c   2003-05-17 13:14:22.000000000 -0600
+@@ -0,0 +1,236 @@
++/*
++ * linux/fs/ext3/iopen.c
++ *
++ * Special support for open by inode number
++ *
++ * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu).
++ * 
++ * This file may be redistributed under the terms of the GNU General
++ * Public License.
++ */
++
++#include <linux/sched.h>
++#include <linux/fs.h>
++#include <linux/locks.h>
++#include <linux/ext3_jbd.h>
++#include <linux/jbd.h>
++#include <linux/ext3_fs.h>
++#include <linux/smp_lock.h>
++#include "iopen.h"
++
++#ifndef assert
++#define assert(test) J_ASSERT(test)
++#endif
++
++#define IOPEN_NAME_LEN        32
++
++/*
++ * This implements looking up an inode by number.
++ */
++static struct dentry *iopen_lookup(struct inode * dir, struct dentry *dentry)
++{
++      struct inode * inode;
++      unsigned long ino;
++        struct list_head *lp;
++        struct dentry *alternate;
++      char buf[IOPEN_NAME_LEN];
++      
++      if (dentry->d_name.len >= IOPEN_NAME_LEN)
++              return ERR_PTR(-ENAMETOOLONG);
++
++      memcpy(buf, dentry->d_name.name, dentry->d_name.len);
++      buf[dentry->d_name.len] = 0;
++
++      if (strcmp(buf, ".") == 0)
++              ino = dir->i_ino;
++      else if (strcmp(buf, "..") == 0)
++              ino = EXT3_ROOT_INO;
++      else
++              ino = simple_strtoul(buf, 0, 0);
++
++      if ((ino != EXT3_ROOT_INO &&
++           //ino != EXT3_ACL_IDX_INO &&
++           //ino != EXT3_ACL_DATA_INO &&
++           ino < EXT3_FIRST_INO(dir->i_sb)) ||
++          ino > le32_to_cpu(dir->i_sb->u.ext3_sb.s_es->s_inodes_count))
++              return ERR_PTR(-ENOENT);
++
++      inode = iget(dir->i_sb, ino);
++      if (!inode)
++              return ERR_PTR(-EACCES);
++      if (is_bad_inode(inode)) {
++              iput(inode);
++              return ERR_PTR(-ENOENT);
++      }
++
++        /* preferrably return a connected dentry */
++        spin_lock(&dcache_lock);
++        list_for_each(lp, &inode->i_dentry) {
++                alternate = list_entry(lp, struct dentry, d_alias);
++                if (!(alternate->d_flags & DCACHE_NFSD_DISCONNECTED)) {
++                        dget_locked(alternate);
++                        alternate->d_vfs_flags |= DCACHE_REFERENCED;
++                        iput(inode);
++                        spin_unlock(&dcache_lock);
++                        return alternate;
++                }
++        }
++        dentry->d_flags |= DCACHE_NFSD_DISCONNECTED;
++        spin_unlock(&dcache_lock);
++
++      d_add(dentry, inode);
++      return NULL;
++}
++
++#define do_switch(x,y) do { \
++      __typeof__ (x) __tmp = x; \
++      x = y; y = __tmp; } while (0)
++
++static inline void switch_names(struct dentry * dentry, struct dentry * target)
++{
++      const unsigned char *old_name, *new_name;
++
++      memcpy(dentry->d_iname, target->d_iname, DNAME_INLINE_LEN); 
++      old_name = target->d_name.name;
++      new_name = dentry->d_name.name;
++      if (old_name == target->d_iname)
++              old_name = dentry->d_iname;
++      if (new_name == dentry->d_iname)
++              new_name = target->d_iname;
++      target->d_name.name = new_name;
++      dentry->d_name.name = old_name;
++}
++
++
++struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode)
++{
++        struct dentry *tmp, *goal = NULL;
++        struct list_head *lp;
++
++        /* preferrably return a connected dentry */
++        spin_lock(&dcache_lock);
++        /* verify this dentry is really new */
++        assert(list_empty(&de->d_subdirs));
++        assert(list_empty(&de->d_alias));
++        //assert(list_empty(&inode->i_dentry));
++        list_for_each(lp, &inode->i_dentry) {
++                tmp = list_entry(lp, struct dentry, d_alias);
++                if (tmp->d_flags & DCACHE_NFSD_DISCONNECTED) {
++                        goal = tmp;
++                        dget_locked(goal);
++                        break;
++                }
++        }
++        if (!goal) { 
++                spin_unlock(&dcache_lock);
++                return NULL; 
++        }
++
++        /* Move the goal to the de hash queue */
++        goal->d_flags &= ~DCACHE_NFSD_DISCONNECTED;
++      list_del(&goal->d_hash);
++      list_add(&goal->d_hash, &de->d_hash);
++
++      list_del(&goal->d_child);
++      list_del(&de->d_child);
++
++      /* Switch the parents and the names.. */
++      switch_names(goal, de);
++      do_switch(goal->d_parent, de->d_parent);
++      do_switch(goal->d_name.len, de->d_name.len);
++      do_switch(goal->d_name.hash, de->d_name.hash);
++
++      /* And add them back to the (new) parent lists */
++      list_add(&goal->d_child, &goal->d_parent->d_subdirs);
++      list_add(&de->d_child, &de->d_parent->d_subdirs);
++
++        list_for_each(lp, &inode->i_dentry) {
++                goal = list_entry(lp, struct dentry, d_alias);
++                if (goal->d_flags & DCACHE_NFSD_DISCONNECTED) {
++                        assert(1==0);
++                }
++        }
++
++        spin_unlock(&dcache_lock);
++        return goal;
++}
++
++/*
++ * These are the special structures for the iopen pseudo directory.
++ */
++
++static struct inode_operations iopen_inode_operations = {
++      lookup:         iopen_lookup,           /* BKL held */
++};
++
++static struct file_operations iopen_file_operations = {
++      read:           generic_read_dir,
++};
++
++static int match_dentry(struct dentry *dentry, const char *name)
++{
++      int     len;
++
++      len = strlen(name);
++      if (dentry->d_name.len != len)
++              return 0;
++      if (strncmp(dentry->d_name.name, name, len))
++              return 0;
++      return 1;
++}
++
++/*
++ * This function is spliced into ext3_lookup and returns 1 the file
++ * name is __iopen__ and dentry has been filled in appropriately.
++ */
++int ext3_check_for_iopen(struct inode * dir, struct dentry *dentry)
++{
++      struct inode * inode;
++
++      if (dir->i_ino != EXT3_ROOT_INO ||
++          !test_opt(dir->i_sb, IOPEN) ||
++          !match_dentry(dentry, "__iopen__"))
++              return 0;
++
++      inode = iget(dir->i_sb, EXT3_BAD_INO);
++
++      if (!inode) 
++              return 0;
++      d_add(dentry, inode);
++      return 1;
++}
++
++/*
++ * This function is spliced into read_inode; it returns 1 if inode
++ * number is the one for /__iopen__, in which case the inode is filled
++ * in appropriately.  Otherwise, this fuction returns 0.
++ */
++int ext3_iopen_get_inode(struct inode * inode)
++{
++      if (inode->i_ino != EXT3_BAD_INO)
++              return 0;
++
++      inode->i_mode = S_IFDIR | S_IRUSR | S_IXUSR;
++      if (test_opt(inode->i_sb, IOPEN_NOPRIV))
++              inode->i_mode |= 0777;
++      inode->i_uid = 0;
++      inode->i_gid = 0;
++      inode->i_nlink = 1;
++      inode->i_size = 4096;
++      inode->i_atime = CURRENT_TIME;
++      inode->i_ctime = CURRENT_TIME;
++      inode->i_mtime = CURRENT_TIME;
++      inode->u.ext3_i.i_dtime = 0;
++      inode->i_blksize = PAGE_SIZE;   /* This is the optimal IO size
++                                       * (for stat), not the fs block
++                                       * size */  
++      inode->i_blocks = 0;
++      inode->i_version = 1;
++      inode->i_generation = 0;
++
++      inode->i_op = &iopen_inode_operations;
++      inode->i_fop = &iopen_file_operations;
++      inode->i_mapping->a_ops = 0;
++
++      return 1;
++}
+--- /dev/null  2003-01-30 03:24:37.000000000 -0700
++++ linux-2.4.18-p4smp-braam/fs/ext3/iopen.h   2003-05-17 13:14:22.000000000 -0600
+@@ -0,0 +1,15 @@
++/*
++ * iopen.h
++ *
++ * Special support for opening files by inode number.
++ * 
++ * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu).
++ * 
++ * This file may be redistributed under the terms of the GNU General
++ * Public License.
++ */
++
++extern int ext3_check_for_iopen(struct inode * dir, struct dentry *dentry);
++extern int ext3_iopen_get_inode(struct inode * inode);
++
++
+--- linux-2.4.18-p4smp/fs/ext3/namei.c~iopen-chaos-2.4.18      2003-05-17 13:12:54.000000000 -0600
++++ linux-2.4.18-p4smp-braam/fs/ext3/namei.c   2003-05-17 13:17:13.000000000 -0600
+@@ -34,6 +34,7 @@
+ #include <linux/locks.h>
+ #include <linux/quotaops.h>
+ #include <linux/slab.h>
++#include "iopen.h"
+ /*
+  * define how far ahead to read directories while searching them.
+@@ -704,15 +705,22 @@ cleanup_and_exit:
+       return ret;
+ }
++struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode);
++
+ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry)
+ {
+       struct inode * inode;
+       struct ext3_dir_entry_2 * de;
+       struct buffer_head * bh;
++        struct dentry *alternate = NULL;
++
+       if (dentry->d_name.len > EXT3_NAME_LEN)
+               return ERR_PTR(-ENAMETOOLONG);
++      if (ext3_check_for_iopen(dir, dentry))
++              return NULL;
++ 
+       bh = ext3_find_entry(dentry, &de);
+       inode = NULL;
+       if (bh) {
+@@ -723,6 +731,10 @@ static struct dentry *ext3_lookup(struct
+               if (!inode)
+                       return ERR_PTR(-EACCES);
+       }
++                
++        if (inode && (alternate = iopen_connect_dentry(dentry, inode))) 
++                return alternate;
++
+       d_add(dentry, inode);
+       return NULL;
+ }
+--- linux-2.4.18-p4smp/fs/ext3/super.c~iopen-chaos-2.4.18      2003-05-17 13:12:50.000000000 -0600
++++ linux-2.4.18-p4smp-braam/fs/ext3/super.c   2003-05-17 13:14:22.000000000 -0600
+@@ -605,6 +605,17 @@ static int parse_options (char * options
+                        || !strcmp (this_char, "quota")
+                        || !strcmp (this_char, "usrquota"))
+                       /* Don't do anything ;-) */ ;
++              else if (!strcmp (this_char, "iopen")) {
++                      set_opt (sbi->s_mount_opt, IOPEN);
++                      clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
++              } else if (!strcmp (this_char, "noiopen")) {
++                      clear_opt (sbi->s_mount_opt, IOPEN);
++                      clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
++              }
++              else if (!strcmp (this_char, "iopen_nopriv")) {
++                      set_opt (sbi->s_mount_opt, IOPEN);
++                      set_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
++              }
+               else if (!strcmp (this_char, "journal")) {
+                       /* @@@ FIXME */
+                       /* Eventually we will want to be able to create
+--- linux-2.4.18-p4smp/include/linux/ext3_fs.h~iopen-chaos-2.4.18      2003-05-17 13:12:56.000000000 -0600
++++ linux-2.4.18-p4smp-braam/include/linux/ext3_fs.h   2003-05-17 13:25:20.000000000 -0600
+@@ -320,6 +320,8 @@ struct ext3_inode {
+ #define EXT3_MOUNT_UPDATE_JOURNAL     0x1000  /* Update the journal format */
+ #define EXT3_MOUNT_NO_UID32           0x2000  /* Disable 32-bit UIDs */
+ #define EXT3_MOUNT_INDEX              0x4000  /* Enable directory index */
++#define EXT3_MOUNT_IOPEN              0x8000  /* Allow access via iopen */
++#define EXT3_MOUNT_IOPEN_NOPRIV               0x10000  /* Make iopen world-readable */
+ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
+ #ifndef _LINUX_EXT2_FS_H
+
+_
diff --git a/lustre/kernel_patches/patches/iopen.patch b/lustre/kernel_patches/patches/iopen.patch
new file mode 100644 (file)
index 0000000..af62a46
--- /dev/null
@@ -0,0 +1,406 @@
+ Documentation/filesystems/ext2.txt |   16 ++
+ fs/ext3/Makefile                   |    2 
+ fs/ext3/inode.c                    |    4 
+ fs/ext3/iopen.c                    |  240 +++++++++++++++++++++++++++++++++++++
+ fs/ext3/iopen.h                    |   15 ++
+ fs/ext3/namei.c                    |   13 +-
+ fs/ext3/super.c                    |   11 +
+ include/linux/ext3_fs.h            |    2 
+ 8 files changed, 301 insertions(+), 2 deletions(-)
+
+--- linux-2.4.20/Documentation/filesystems/ext2.txt~iopen      2001-07-11 16:44:45.000000000 -0600
++++ linux-2.4.20-braam/Documentation/filesystems/ext2.txt      2003-05-17 14:06:00.000000000 -0600
+@@ -35,6 +35,22 @@ resgid=n                    The group ID which may use th
+ sb=n                          Use alternate superblock at this location.
++iopen                         Makes an invisible pseudo-directory called 
++                              __iopen__ available in the root directory
++                              of the filesystem.  Allows open-by-inode-
++                              number.  i.e., inode 3145 can be accessed
++                              via /mntpt/__iopen__/3145
++
++iopen_nopriv                  This option makes the iopen directory be
++                              world-readable.  This may be safer since it
++                              allows daemons to run as an unprivileged user,
++                              however it significantly changes the security
++                              model of a Unix filesystem, since previously
++                              all files under a mode 700 directory were not
++                              generally avilable even if the
++                              permissions on the file itself is
++                              world-readable.
++
+ grpquota,noquota,quota,usrquota       Quota options are silently ignored by ext2.
+--- linux-2.4.20/fs/ext3/Makefile~iopen        2003-05-17 14:05:57.000000000 -0600
++++ linux-2.4.20-braam/fs/ext3/Makefile        2003-05-17 14:06:00.000000000 -0600
+@@ -11,7 +11,7 @@ O_TARGET := ext3.o
+ export-objs := ext3-exports.o
+-obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
++obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
+               ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o
+ obj-m    := $(O_TARGET)
+--- linux-2.4.20/fs/ext3/inode.c~iopen 2003-05-17 14:06:00.000000000 -0600
++++ linux-2.4.20-braam/fs/ext3/inode.c 2003-05-17 14:06:00.000000000 -0600
+@@ -31,6 +31,7 @@
+ #include <linux/highuid.h>
+ #include <linux/quotaops.h>
+ #include <linux/module.h>
++#include "iopen.h"
+ /*
+  * SEARCH_FROM_ZERO forces each block allocation to search from the start
+@@ -2137,6 +2138,9 @@ void ext3_read_inode(struct inode * inod
+       struct buffer_head *bh;
+       int block;
+       
++      if (ext3_iopen_get_inode(inode))
++              return;
++      
+       if(ext3_get_inode_loc(inode, &iloc))
+               goto bad_inode;
+       bh = iloc.bh;
+--- /dev/null  2003-01-30 03:24:37.000000000 -0700
++++ linux-2.4.20-braam/fs/ext3/iopen.c 2003-05-17 22:18:55.000000000 -0600
+@@ -0,0 +1,240 @@
++
++
++/*
++ * linux/fs/ext3/iopen.c
++ *
++ * Special support for open by inode number
++ *
++ * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu).
++ * 
++ * This file may be redistributed under the terms of the GNU General
++ * Public License.
++ */
++
++#include <linux/sched.h>
++#include <linux/fs.h>
++#include <linux/locks.h>
++#include <linux/ext3_jbd.h>
++#include <linux/jbd.h>
++#include <linux/ext3_fs.h>
++#include <linux/smp_lock.h>
++#include "iopen.h"
++
++#ifndef assert
++#define assert(test) J_ASSERT(test)
++#endif
++
++#define IOPEN_NAME_LEN        32
++
++/*
++ * This implements looking up an inode by number.
++ */
++static struct dentry *iopen_lookup(struct inode * dir, struct dentry *dentry)
++{
++      struct inode * inode;
++      unsigned long ino;
++        struct list_head *lp;
++        struct dentry *alternate;
++      char buf[IOPEN_NAME_LEN];
++      
++      if (dentry->d_name.len >= IOPEN_NAME_LEN)
++              return ERR_PTR(-ENAMETOOLONG);
++
++      memcpy(buf, dentry->d_name.name, dentry->d_name.len);
++      buf[dentry->d_name.len] = 0;
++
++      if (strcmp(buf, ".") == 0)
++              ino = dir->i_ino;
++      else if (strcmp(buf, "..") == 0)
++              ino = EXT3_ROOT_INO;
++      else
++              ino = simple_strtoul(buf, 0, 0);
++
++      if ((ino != EXT3_ROOT_INO &&
++           //ino != EXT3_ACL_IDX_INO &&
++           //ino != EXT3_ACL_DATA_INO &&
++           ino < EXT3_FIRST_INO(dir->i_sb)) ||
++          ino > le32_to_cpu(dir->i_sb->u.ext3_sb.s_es->s_inodes_count))
++              return ERR_PTR(-ENOENT);
++
++      inode = iget(dir->i_sb, ino);
++      if (!inode)
++              return ERR_PTR(-EACCES);
++      if (is_bad_inode(inode)) {
++              iput(inode);
++              return ERR_PTR(-ENOENT);
++      }
++
++        /* preferrably return a connected dentry */
++        spin_lock(&dcache_lock);
++        list_for_each(lp, &inode->i_dentry) {
++                alternate = list_entry(lp, struct dentry, d_alias);
++                assert(!(alternate->d_flags & DCACHE_NFSD_DISCONNECTED));
++        }
++
++        if (!list_empty(&inode->i_dentry)) {
++                alternate = list_entry(inode->i_dentry.next, 
++                                       struct dentry, d_alias);
++                dget_locked(alternate);
++                alternate->d_vfs_flags |= DCACHE_REFERENCED;
++                iput(inode);
++                spin_unlock(&dcache_lock);
++                return alternate;
++        }
++        dentry->d_flags |= DCACHE_NFSD_DISCONNECTED;
++        spin_unlock(&dcache_lock);
++
++      d_add(dentry, inode);
++      return NULL;
++}
++
++#define do_switch(x,y) do { \
++      __typeof__ (x) __tmp = x; \
++      x = y; y = __tmp; } while (0)
++
++static inline void switch_names(struct dentry * dentry, struct dentry * target)
++{
++      const unsigned char *old_name, *new_name;
++
++      memcpy(dentry->d_iname, target->d_iname, DNAME_INLINE_LEN); 
++      old_name = target->d_name.name;
++      new_name = dentry->d_name.name;
++      if (old_name == target->d_iname)
++              old_name = dentry->d_iname;
++      if (new_name == dentry->d_iname)
++              new_name = target->d_iname;
++      target->d_name.name = new_name;
++      dentry->d_name.name = old_name;
++}
++
++
++struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode)
++{
++        struct dentry *tmp, *goal = NULL;
++        struct list_head *lp;
++
++        /* preferrably return a connected dentry */
++        spin_lock(&dcache_lock);
++        /* verify this dentry is really new */
++        assert(!de->d_inode);
++        assert(list_empty(&de->d_subdirs));
++        assert(list_empty(&de->d_alias));
++
++
++        list_for_each(lp, &inode->i_dentry) {
++                tmp = list_entry(lp, struct dentry, d_alias);
++                if (tmp->d_flags & DCACHE_NFSD_DISCONNECTED) {
++                        assert(tmp->d_alias.next == &inode->i_dentry);
++                        assert(tmp->d_alias.prev == &inode->i_dentry);
++                        goal = tmp;
++                        dget_locked(goal);
++                        break;
++                }
++        }
++
++        if (!goal) { 
++                spin_unlock(&dcache_lock);
++                return NULL; 
++        }
++
++        /* Move the goal to the de hash queue */
++        goal->d_flags &= ~DCACHE_NFSD_DISCONNECTED;
++      list_del(&goal->d_hash);
++      list_add(&goal->d_hash, &de->d_hash);
++
++      list_del(&goal->d_child);
++      list_del(&de->d_child);
++
++      /* Switch the parents and the names.. */
++      switch_names(goal, de);
++      do_switch(goal->d_parent, de->d_parent);
++      do_switch(goal->d_name.len, de->d_name.len);
++      do_switch(goal->d_name.hash, de->d_name.hash);
++
++      /* And add them back to the (new) parent lists */
++      list_add(&goal->d_child, &goal->d_parent->d_subdirs);
++      list_add(&de->d_child, &de->d_parent->d_subdirs);
++
++        spin_unlock(&dcache_lock);
++        return goal;
++}
++
++/*
++ * These are the special structures for the iopen pseudo directory.
++ */
++
++static struct inode_operations iopen_inode_operations = {
++      lookup:         iopen_lookup,           /* BKL held */
++};
++
++static struct file_operations iopen_file_operations = {
++      read:           generic_read_dir,
++};
++
++static int match_dentry(struct dentry *dentry, const char *name)
++{
++      int     len;
++
++      len = strlen(name);
++      if (dentry->d_name.len != len)
++              return 0;
++      if (strncmp(dentry->d_name.name, name, len))
++              return 0;
++      return 1;
++}
++
++/*
++ * This function is spliced into ext3_lookup and returns 1 the file
++ * name is __iopen__ and dentry has been filled in appropriately.
++ */
++int ext3_check_for_iopen(struct inode * dir, struct dentry *dentry)
++{
++      struct inode * inode;
++
++      if (dir->i_ino != EXT3_ROOT_INO ||
++          !test_opt(dir->i_sb, IOPEN) ||
++          !match_dentry(dentry, "__iopen__"))
++              return 0;
++
++      inode = iget(dir->i_sb, EXT3_BAD_INO);
++
++      if (!inode) 
++              return 0;
++      d_add(dentry, inode);
++      return 1;
++}
++
++/*
++ * This function is spliced into read_inode; it returns 1 if inode
++ * number is the one for /__iopen__, in which case the inode is filled
++ * in appropriately.  Otherwise, this fuction returns 0.
++ */
++int ext3_iopen_get_inode(struct inode * inode)
++{
++      if (inode->i_ino != EXT3_BAD_INO)
++              return 0;
++
++      inode->i_mode = S_IFDIR | S_IRUSR | S_IXUSR;
++      if (test_opt(inode->i_sb, IOPEN_NOPRIV))
++              inode->i_mode |= 0777;
++      inode->i_uid = 0;
++      inode->i_gid = 0;
++      inode->i_nlink = 1;
++      inode->i_size = 4096;
++      inode->i_atime = CURRENT_TIME;
++      inode->i_ctime = CURRENT_TIME;
++      inode->i_mtime = CURRENT_TIME;
++      inode->u.ext3_i.i_dtime = 0;
++      inode->i_blksize = PAGE_SIZE;   /* This is the optimal IO size
++                                       * (for stat), not the fs block
++                                       * size */  
++      inode->i_blocks = 0;
++      inode->i_version = 1;
++      inode->i_generation = 0;
++
++      inode->i_op = &iopen_inode_operations;
++      inode->i_fop = &iopen_file_operations;
++      inode->i_mapping->a_ops = 0;
++
++      return 1;
++}
+--- /dev/null  2003-01-30 03:24:37.000000000 -0700
++++ linux-2.4.20-braam/fs/ext3/iopen.h 2003-05-17 14:06:00.000000000 -0600
+@@ -0,0 +1,15 @@
++/*
++ * iopen.h
++ *
++ * Special support for opening files by inode number.
++ * 
++ * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu).
++ * 
++ * This file may be redistributed under the terms of the GNU General
++ * Public License.
++ */
++
++extern int ext3_check_for_iopen(struct inode * dir, struct dentry *dentry);
++extern int ext3_iopen_get_inode(struct inode * inode);
++
++
+--- linux-2.4.20/fs/ext3/namei.c~iopen 2003-05-17 14:05:59.000000000 -0600
++++ linux-2.4.20-braam/fs/ext3/namei.c 2003-05-17 22:23:08.000000000 -0600
+@@ -35,7 +35,7 @@
+ #include <linux/string.h>
+ #include <linux/locks.h>
+ #include <linux/quotaops.h>
+-
++#include "iopen.h"
+ /*
+  * define how far ahead to read directories while searching them.
+@@ -921,16 +921,21 @@ errout:
+       return NULL;
+ }
+ #endif
++struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode);
+ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry)
+ {
+       struct inode * inode;
+       struct ext3_dir_entry_2 * de;
+       struct buffer_head * bh;
++        struct dentry *alternate = NULL;
+       if (dentry->d_name.len > EXT3_NAME_LEN)
+               return ERR_PTR(-ENAMETOOLONG);
++      if (ext3_check_for_iopen(dir, dentry))
++              return NULL;
++
+       bh = ext3_find_entry(dentry, &de);
+       inode = NULL;
+       if (bh) {
+@@ -942,6 +947,12 @@ static struct dentry *ext3_lookup(struct
+                       return ERR_PTR(-EACCES);
+               }
+       }
++                
++        if (inode && (alternate = iopen_connect_dentry(dentry, inode))) {
++                iput(inode);
++                return alternate;
++        }
++
+       d_add(dentry, inode);
+       return NULL;
+ }
+--- linux-2.4.20/fs/ext3/super.c~iopen 2003-05-17 14:05:59.000000000 -0600
++++ linux-2.4.20-braam/fs/ext3/super.c 2003-05-17 14:06:00.000000000 -0600
+@@ -820,6 +820,17 @@ static int parse_options (char * options
+                        || !strcmp (this_char, "quota")
+                        || !strcmp (this_char, "usrquota"))
+                       /* Don't do anything ;-) */ ;
++              else if (!strcmp (this_char, "iopen")) {
++                      set_opt (sbi->s_mount_opt, IOPEN);
++                      clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
++              } else if (!strcmp (this_char, "noiopen")) {
++                      clear_opt (sbi->s_mount_opt, IOPEN);
++                      clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
++              }
++              else if (!strcmp (this_char, "iopen_nopriv")) {
++                      set_opt (sbi->s_mount_opt, IOPEN);
++                      set_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
++              }
+               else if (!strcmp (this_char, "journal")) {
+                       /* @@@ FIXME */
+                       /* Eventually we will want to be able to create
+--- linux-2.4.20/include/linux/ext3_fs.h~iopen 2003-05-17 14:05:59.000000000 -0600
++++ linux-2.4.20-braam/include/linux/ext3_fs.h 2003-05-17 14:06:29.000000000 -0600
+@@ -322,6 +322,8 @@ struct ext3_inode {
+ #define EXT3_MOUNT_UPDATE_JOURNAL     0x1000  /* Update the journal format */
+ #define EXT3_MOUNT_NO_UID32           0x2000  /* Disable 32-bit UIDs */
+ #define EXT3_MOUNT_XATTR_USER         0x4000  /* Extended user attributes */
++#define EXT3_MOUNT_IOPEN              0x8000  /* Allow access via iopen */
++#define EXT3_MOUNT_IOPEN_NOPRIV               0x10000  /* Make iopen world-readable */
+ #define EXT3_MOUNT_ASYNCDEL          0x20000  /* Delayed deletion */
+ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
+
+_
diff --git a/lustre/kernel_patches/patches/kmem_cache_validate_2.4.20.patch b/lustre/kernel_patches/patches/kmem_cache_validate_2.4.20.patch
new file mode 100644 (file)
index 0000000..ee66c5a
--- /dev/null
@@ -0,0 +1,105 @@
+ arch/ia64/mm/init.c  |    6 +++++
+ include/linux/slab.h |    1 
+ kernel/ksyms.c       |    1 
+ mm/slab.c            |   53 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 61 insertions(+)
+
+--- linux/arch/ia64/mm/init.c~kmem_cache_validate_hp   Wed Apr  9 11:09:46 2003
++++ linux-mmonroe/arch/ia64/mm/init.c  Wed Apr  9 11:12:23 2003
+@@ -45,6 +45,12 @@ unsigned long vmalloc_end = VMALLOC_END_
+ static struct page *vmem_map;
+ static unsigned long num_dma_physpages;
++struct page *check_get_page(unsigned long kaddr)
++{
++#warning FIXME: Lustre team, is this solid?
++      return virt_to_page(kaddr);
++}
++
+ int
+ do_check_pgt_cache (int low, int high)
+ {
+--- linux/include/linux/slab.h~kmem_cache_validate_hp  Wed Apr  9 11:08:48 2003
++++ linux-mmonroe/include/linux/slab.h Wed Apr  9 11:12:23 2003
+@@ -56,6 +56,7 @@ extern kmem_cache_t *kmem_cache_create(c
+ extern int kmem_cache_destroy(kmem_cache_t *);
+ extern int kmem_cache_shrink(kmem_cache_t *);
+ extern void *kmem_cache_alloc(kmem_cache_t *, int);
++extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp);
+ extern void kmem_cache_free(kmem_cache_t *, void *);
+ extern unsigned int kmem_cache_size(kmem_cache_t *);
+--- linux/kernel/ksyms.c~kmem_cache_validate_hp        Wed Apr  9 11:12:20 2003
++++ linux-mmonroe/kernel/ksyms.c       Wed Apr  9 11:12:23 2003
+@@ -119,6 +119,7 @@ EXPORT_SYMBOL(kmem_find_general_cachep);
+ EXPORT_SYMBOL(kmem_cache_create);
+ EXPORT_SYMBOL(kmem_cache_destroy);
+ EXPORT_SYMBOL(kmem_cache_shrink);
++EXPORT_SYMBOL(kmem_cache_validate);
+ EXPORT_SYMBOL(kmem_cache_alloc);
+ EXPORT_SYMBOL(kmem_cache_free);
+ EXPORT_SYMBOL(kmem_cache_size);
+--- linux/mm/slab.c~kmem_cache_validate_hp     Wed Apr  9 11:08:47 2003
++++ linux-mmonroe/mm/slab.c    Wed Apr  9 11:12:23 2003
+@@ -1205,6 +1205,59 @@ failed:
+  * Called with the cache-lock held.
+  */
++extern struct page *check_get_page(unsigned long kaddr);
++struct page *page_mem_map(struct page *page);
++static int kmem_check_cache_obj (kmem_cache_t * cachep,
++                               slab_t *slabp, void * objp)
++{
++      int i;
++      unsigned int objnr;
++
++#if DEBUG
++      if (cachep->flags & SLAB_RED_ZONE) {
++              objp -= BYTES_PER_WORD;
++              if ( *(unsigned long *)objp != RED_MAGIC2)
++                      /* Either write before start, or a double free. */
++                      return 0;
++              if (*(unsigned long *)(objp+cachep->objsize -
++                              BYTES_PER_WORD) != RED_MAGIC2)
++                      /* Either write past end, or a double free. */
++                      return 0;
++      }
++#endif
++
++      objnr = (objp-slabp->s_mem)/cachep->objsize;
++      if (objnr >= cachep->num)
++              return 0;
++      if (objp != slabp->s_mem + objnr*cachep->objsize)
++              return 0;
++
++      /* Check slab's freelist to see if this obj is there. */
++      for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
++              if (i == objnr)
++                      return 0;
++      }
++      return 1;
++}
++
++
++int kmem_cache_validate(kmem_cache_t *cachep, void *objp)
++{
++      struct page *page = check_get_page((unsigned long)objp);
++
++      if (!VALID_PAGE(page))
++              return 0;
++
++      if (!PageSlab(page))
++              return 0;
++
++      /* XXX check for freed slab objects ? */
++      if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp))
++              return 0;
++
++      return (cachep == GET_PAGE_CACHE(page));
++}
++
+ #if DEBUG
+ static int kmem_extra_free_checks (kmem_cache_t * cachep,
+                       slab_t *slabp, void * objp)
+
+_
diff --git a/lustre/kernel_patches/patches/mcore-2.4.20-8.patch b/lustre/kernel_patches/patches/mcore-2.4.20-8.patch
new file mode 100644 (file)
index 0000000..c8b80eb
--- /dev/null
@@ -0,0 +1,2738 @@
+? linux/.config
+? linux/include/linux/autoconf.h
+? linux/include/linux/modules
+Index: linux/Makefile
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/Makefile,v
+retrieving revision 1.3.2.1
+retrieving revision 1.3.2.1.2.1
+diff -u -r1.3.2.1 -r1.3.2.1.2.1
+--- linux/Makefile     12 Mar 2003 19:48:52 -0000      1.3.2.1
++++ linux/Makefile     1 Apr 2003 12:17:40 -0000       1.3.2.1.2.1
+@@ -99,6 +99,10 @@
+ CFLAGS += -fomit-frame-pointer
+ endif
+ AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS)
++ifeq ($(CONFIG_MCL_COREDUMP),y)
++      CFLAGS += -g
++endif
++
+ #
+ # ROOT_DEV specifies the default root-device when making the image.
+Index: linux/Documentation/Configure.help
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/Documentation/Configure.help,v
+retrieving revision 1.3.2.1
+retrieving revision 1.3.2.1.2.1
+diff -u -r1.3.2.1 -r1.3.2.1.2.1
+--- linux/Documentation/Configure.help 12 Mar 2003 19:48:52 -0000      1.3.2.1
++++ linux/Documentation/Configure.help 1 Apr 2003 12:17:40 -0000       1.3.2.1.2.1
+@@ -21660,6 +21660,35 @@
+   This option allows you to run the kernel with data cache disabled.
+   Say Y if you experience CPM lock-ups.
++Boot kernel image support
++CONFIG_BOOTIMG
++  Add support for booting a new Linux kernel from a running Linux
++  system. You need to download the bootimg(8) utility from
++  ftp://icaftp.epfl.ch/pub/people/almesber/misc/bootimg-current.tar.gz
++  in order to use this functionality.
++
++Protect SMP configuration tables
++CONFIG_BOOTIMG_SMP
++  On SMP systems, the BIOS stores tables with configuration data in
++  memory and an SMP-enabled kernel reads these tables. However, a
++  kernel without SMP support will overwrite such tables. If a kernel
++  without SMP support used bootimg to boot an SMP-enabled kernel, the
++  latter will probably crash when trying to read the SMP tables. The
++  CONFIG_BOOTIMG_SMP option enables minimal support for scanning and
++  protecting of SMP configuration tables also for kernels without SMP
++  support.
++
++In-memory kernel core dump facility
++CONFIG_MCL_COREDUMP
++  In conjunction with bootimg, this allows you to get kernel core dumps
++  of your system at panic() time.  The panic call is modified so that it
++  calls the core dump facility and reboots the system.  On the way back 
++  up, the kernel dump image is written out to disk by the accompanying 
++  init script.  You can use the crash analysis tool to analyze the core 
++  dump.  This tool can be found at :
++
++       http://www.missioncriticallinux.com/download
++
+ #
+ # m68k-specific kernel options
+ # Documented by Chris Lawrence <mailto:quango@themall.net> et al.
+Index: linux/arch/i386/config.in
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/arch/i386/config.in,v
+retrieving revision 1.3.2.1
+retrieving revision 1.3.2.1.2.2
+diff -u -r1.3.2.1 -r1.3.2.1.2.2
+--- linux/arch/i386/config.in  12 Mar 2003 19:49:05 -0000      1.3.2.1
++++ linux/arch/i386/config.in  1 Apr 2003 19:35:12 -0000       1.3.2.1.2.2
+@@ -502,6 +502,12 @@
+    bool '  Magic SysRq key' CONFIG_MAGIC_SYSRQ
+    bool '  Spinlock debugging' CONFIG_DEBUG_SPINLOCK
+    bool '  Compile the kernel with frame pointers' CONFIG_FRAME_POINTER
++   if [ "$CONFIG_FRAME_POINTER " != "n" ]; then
++      bool '  Kernel Core Dump Facility' CONFIG_MCL_COREDUMP
++      if [ "$CONFIG_MCL_COREDUMP" = "y" ]; then
++         bool '  Reboot using bootimg' CONFIG_BOOTIMG
++      fi
++   fi
+ fi
+ endmenu
+Index: linux/arch/i386/vmlinux.lds
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/arch/i386/vmlinux.lds,v
+retrieving revision 1.1.1.1.4.1
+retrieving revision 1.1.1.1.4.1.2.1
+diff -u -r1.1.1.1.4.1 -r1.1.1.1.4.1.2.1
+--- linux/arch/i386/vmlinux.lds        12 Mar 2003 19:49:05 -0000      1.1.1.1.4.1
++++ linux/arch/i386/vmlinux.lds        1 Apr 2003 12:17:40 -0000       1.1.1.1.4.1.2.1
+@@ -19,6 +19,13 @@
+   .rodata : { *(.rodata) *(.rodata.*) }
+   .kstrtab : { *(.kstrtab) }
++  . = ALIGN(16);              /* Relocatable bootimage code */
++  __bootimg_start = .;
++  .bootimg : {
++      *(.bootimg)
++      }
++  __bootimg_end = .;
++
+   . = ALIGN(16);              /* Exception table */
+   __start___ex_table = .;
+   __ex_table : { *(__ex_table) }
+Index: linux/arch/i386/boot/setup.S
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/arch/i386/boot/setup.S,v
+retrieving revision 1.2.2.1
+retrieving revision 1.2.2.1.2.1
+diff -u -r1.2.2.1 -r1.2.2.1.2.1
+--- linux/arch/i386/boot/setup.S       12 Mar 2003 19:49:05 -0000      1.2.2.1
++++ linux/arch/i386/boot/setup.S       1 Apr 2003 12:17:40 -0000       1.2.2.1.2.1
+@@ -105,16 +105,22 @@
+ # flags, unused bits must be zero (RFU) bit within loadflags
+ loadflags:
+ LOADED_HIGH   = 1                     # If set, the kernel is loaded high
++RELOADS_GDT   = 2                     # if set, kernel reloads GDT, such that
++                                      # boot loader does not have to provide
++                                      # GDT in a "safe" memory location
+ CAN_USE_HEAP  = 0x80                  # If set, the loader also has set
+                                       # heap_end_ptr to tell how much
+                                       # space behind setup.S can be used for
+                                       # heap purposes.
+                                       # Only the loader knows what is free
+-#ifndef __BIG_KERNEL__
+-              .byte   0
+-#else
+-              .byte   LOADED_HIGH
++_FLAGS = 0
++#ifdef __BIG_KERNEL__
++              _FLAGS = _FLAGS | LOADED_HIGH
+ #endif
++#ifdef CONFIG_BOOTIMG
++              _FLAGS = _FLAGS | RELOADS_GDT
++#endif
++              .byte _FLAGS
+ setup_move_size: .word  0x8000                # size to move, when setup is not
+                                       # loaded at 0x90000. We will move setup 
+Index: linux/arch/i386/kernel/Makefile
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/arch/i386/kernel/Makefile,v
+retrieving revision 1.2.2.1
+retrieving revision 1.2.2.1.2.1
+diff -u -r1.2.2.1 -r1.2.2.1.2.1
+--- linux/arch/i386/kernel/Makefile    12 Mar 2003 19:49:05 -0000      1.2.2.1
++++ linux/arch/i386/kernel/Makefile    1 Apr 2003 12:17:40 -0000       1.2.2.1.2.1
+@@ -49,6 +49,7 @@
+ obj-$(CONFIG_X86_LONGRUN)     += longrun.o
+ obj-$(CONFIG_ELAN_CPUFREQ)    += elanfreq.o
+ obj-$(CONFIG_PROFILING)               += profile.o
++obj-$(CONFIG_MCL_COREDUMP)    += crash.o
+ include $(TOPDIR)/Rules.make
+Index: linux/arch/i386/kernel/crash.c
+===================================================================
+RCS file: linux/arch/i386/kernel/crash.c
+diff -N linux/arch/i386/kernel/crash.c
+--- /dev/null  1 Jan 1970 00:00:00 -0000
++++ linux/arch/i386/kernel/crash.c     1 Apr 2003 12:17:40 -0000       1.1.6.1
+@@ -0,0 +1,82 @@
++/*
++ *  linux/arch/i386/crash.c
++ *
++ *  Architecture dependant code for MCL in-memory core dump.
++ */
++#include <linux/sched.h>
++#include <linux/types.h>
++#include <linux/smp.h>
++#include <linux/crash.h>
++#include <linux/reboot.h>
++#include <linux/bootimg.h>
++
++inline void crash_save_regs(void) {
++      static unsigned long regs[8];
++
++      __asm__ __volatile__("movl %%ebx,%0" : "=m"(regs[0]));
++      __asm__ __volatile__("movl %%ecx,%0" : "=m"(regs[1]));
++      __asm__ __volatile__("movl %%edx,%0" : "=m"(regs[2]));
++      __asm__ __volatile__("movl %%esi,%0" : "=m"(regs[3]));
++      __asm__ __volatile__("movl %%edi,%0" : "=m"(regs[4]));
++      __asm__ __volatile__("movl %%ebp,%0" : "=m"(regs[5]));
++      __asm__ __volatile__("movl %%eax,%0" : "=m"(regs[6]));
++      __asm__ __volatile__("movl %%esp,%0" : "=m"(regs[7]));
++
++      panic_regs = regs;
++}
++
++/*
++ *  Save the current stack pointer and EIP.
++ */
++void crash_save_current_state(struct task_struct *tp)
++{
++      /*
++       *  Here we save ebp instead of esp just in case the compiler
++       *  decides to put an extra push in before we execute this
++       *  instruction (thus invalidating our frame pointer).
++       */
++      asm volatile("movl %%ebp,%0":"=m" (*(u_long *)&tp->thread.esp));
++      tp->thread.eip = (u_long)crash_save_current_state;
++      panic_ksp[smp_processor_id()] = tp->thread.esp;
++      mb();
++
++      save_core();
++
++      crash_halt_or_reboot(1);
++}
++
++/*
++ *  If we are not the panicking thread, we simply halt.  Otherwise,
++ *  we take care of calling the reboot code.
++ */
++void crash_halt_or_reboot(int boot_cpu)
++{
++#ifdef CONFIG_SMP
++      if (!boot_cpu) {
++              stop_this_cpu(NULL);
++              /* NOTREACHED */
++      }
++#endif
++      machine_restart(NULL);
++}
++
++void crash_cleanup_smp_state(void)
++{
++      /*
++       *  Here we duplicate smp_send_stop.  Crash_halt_or_reboot() calls
++       *  stop_this_cpu.  We now know that we are the only one running, 
++       *  so we finish off the smp_send_stop function.
++       */
++      __cli();
++#ifdef CONFIG_SMP
++      disable_local_APIC();
++#endif
++}
++
++/*
++ *  Core dump IPI
++ */
++void smp_crash_funnel_cpu(void)
++{
++      crash_save_current_state(current);
++}
+Index: linux/arch/i386/kernel/nmi.c
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/arch/i386/kernel/nmi.c,v
+retrieving revision 1.2.2.1
+retrieving revision 1.2.2.1.2.1
+diff -u -r1.2.2.1 -r1.2.2.1.2.1
+--- linux/arch/i386/kernel/nmi.c       12 Mar 2003 19:49:06 -0000      1.2.2.1
++++ linux/arch/i386/kernel/nmi.c       1 Apr 2003 12:17:40 -0000       1.2.2.1.2.1
+@@ -374,11 +374,18 @@
+                       bust_spinlocks(1);
+                       printk("NMI Watchdog detected LOCKUP on CPU%d, eip %08lx, registers:\n", cpu, regs->eip);
+                       show_registers(regs);
++#ifdef CONFIG_MCL_COREDUMP
++                      spin_unlock(&nmi_print_lock);
++                      bust_spinlocks(0);
++                      panic("die");
++                      /* NOTREACHED */
++#else
+                       printk("console shuts up ...\n");
+                       console_silent();
+                       spin_unlock(&nmi_print_lock);
+                       bust_spinlocks(0);
+                       do_exit(SIGSEGV);
++#endif
+               }
+       } else {
+               last_irq_sums[cpu] = sum;
+Index: linux/arch/i386/kernel/process.c
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/arch/i386/kernel/process.c,v
+retrieving revision 1.2.2.2
+retrieving revision 1.2.2.2.2.1
+diff -u -r1.2.2.2 -r1.2.2.2.2.1
+--- linux/arch/i386/kernel/process.c   1 Apr 2003 02:11:17 -0000       1.2.2.2
++++ linux/arch/i386/kernel/process.c   1 Apr 2003 12:17:40 -0000       1.2.2.2.2.1
+@@ -50,6 +50,9 @@
+ #ifdef CONFIG_MATH_EMULATION
+ #include <asm/math_emu.h>
+ #endif
++#ifdef CONFIG_BOOTIMG
++#include <linux/bootimg.h>
++#endif
+ #include <linux/irq.h>
+@@ -377,7 +380,21 @@
+ void machine_restart(char * __unused)
+ {
++#ifdef CONFIG_MCL_COREDUMP
++      extern char *panicmsg;
++      /*
++       *  Only call bootimg if we have a valid descriptor and
++       *  we are in a panic() context.
++       */
++      if (panicmsg)
++#endif
++#ifdef CONFIG_BOOTIMG
++              if (bootimg_dsc.page_dir)
++                      boot_image();
++#endif
++
+ #if CONFIG_SMP
++{
+       int cpuid;
+       
+       cpuid = GET_APIC_ID(apic_read(APIC_ID));
+@@ -413,6 +430,7 @@
+       if (!netdump_func)
+               smp_send_stop();
+       disable_IO_APIC();
++}
+ #endif
+       if(!reboot_thru_bios) {
+Index: linux/arch/i386/kernel/setup.c
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/arch/i386/kernel/setup.c,v
+retrieving revision 1.3.2.1
+retrieving revision 1.3.2.1.2.2
+diff -u -r1.3.2.1 -r1.3.2.1.2.2
+--- linux/arch/i386/kernel/setup.c     12 Mar 2003 19:49:06 -0000      1.3.2.1
++++ linux/arch/i386/kernel/setup.c     1 Apr 2003 17:55:35 -0000       1.3.2.1.2.2
+@@ -116,6 +116,9 @@
+ #include <asm/mpspec.h>
+ #include <asm/mmu_context.h>
+ #include <asm/edd.h>
++#ifdef CONFIG_MCL_COREDUMP
++#include <linux/crash.h>
++#endif
+ /*
+  * Machine setup..
+  */
+@@ -973,6 +976,7 @@
+ static unsigned long __init setup_memory(void)
+ {
+       unsigned long bootmap_size, start_pfn, max_low_pfn;
++      unsigned long bootmap_pages = 0UL, crash_pages = 0UL;
+       /*
+        * partially used pages are not usable - thus
+@@ -992,6 +996,21 @@
+       printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
+               pages_to_mb(highend_pfn - highstart_pfn));
+ #endif
++
++#ifdef CONFIG_MCL_COREDUMP
++      bootmap_pages = bootmem_bootmap_pages(max_low_pfn);
++      crash_pages = crash_pages_needed();
++
++      printk("start_pfn: %d, bootmap_pages: %d\n", start_pfn, bootmap_pages);
++
++      crash_init((u_long)phys_to_virt(PFN_PHYS(start_pfn)),
++                 (u_long)phys_to_virt(PFN_PHYS(LOW_OFFSET + start_pfn)),
++                 (u_long)phys_to_virt(PFN_PHYS(LOW_OFFSET + start_pfn +
++                                               crash_pages)));
++
++      printk("new start_pfn: %08lx\n", PFN_PHYS(start_pfn));
++      printk("crash map starts at %lx\n",(start_pfn+bootmap_pages)*PAGE_SIZE);
++#endif
+       printk(KERN_NOTICE "%ldMB LOWMEM available.\n",
+                       pages_to_mb(max_low_pfn));
+       /*
+@@ -1007,8 +1026,8 @@
+        * the (very unlikely) case of us accidentally initializing the
+        * bootmem allocator with an invalid RAM area.
+        */
+-      reserve_bootmem(HIGH_MEMORY, (PFN_PHYS(start_pfn) +
+-                       bootmap_size + PAGE_SIZE-1) - (HIGH_MEMORY));
++      reserve_bootmem(HIGH_MEMORY, (PFN_PHYS(start_pfn) + bootmap_size + 
++                    ((1+crash_pages)*PAGE_SIZE) + PAGE_SIZE-1) - (HIGH_MEMORY));
+       /*
+        * reserve physical page 0 - it's a special BIOS page on many boxes,
+@@ -1016,6 +1035,16 @@
+        */
+       reserve_bootmem(0, PAGE_SIZE);
++#ifdef CONFIG_BOOTIMG
++      /*
++       * bootimg(8) reads the old parameter block. Note that the copy in
++       * empty_zero_page will vanish when mem_init runs. (Should we
++       * memcpy(phys_to_virt(0x90000), PARAM, PAGE_SIZE);
++       * now ?)
++       */
++      reserve_bootmem(0x90000, PAGE_SIZE);
++#endif
++
+ #ifdef CONFIG_SMP
+       /*
+        * But first pinch a few for the stack/trampoline stuff
+@@ -1032,6 +1061,7 @@
+       find_smp_config();
+ #endif
+ #ifdef CONFIG_BLK_DEV_INITRD
++      printk("caution: initrd may overwrite dump\n"); /* phro */
+       if (LOADER_TYPE && INITRD_START) {
+               if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
+                       reserve_bootmem(INITRD_START, INITRD_SIZE);
+@@ -1172,6 +1202,12 @@
+       smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
+ #endif
+       paging_init();
++#ifdef CONFIG_MCL_COREDUMP
++      /*
++       * Reserve crash pages
++       */
++      crash_mark_dump_reserved();
++#endif
+ #ifdef CONFIG_X86_LOCAL_APIC
+       /*
+        * get boot-time SMP configuration:
+Index: linux/arch/i386/kernel/smp.c
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/arch/i386/kernel/smp.c,v
+retrieving revision 1.3.2.1
+retrieving revision 1.3.2.1.2.1
+diff -u -r1.3.2.1 -r1.3.2.1.2.1
+--- linux/arch/i386/kernel/smp.c       12 Mar 2003 19:49:06 -0000      1.3.2.1
++++ linux/arch/i386/kernel/smp.c       1 Apr 2003 12:17:40 -0000       1.3.2.1.2.1
+@@ -23,6 +23,9 @@
+ #include <asm/pgalloc.h>
+ #include <asm/smpboot.h>
++#ifdef CONFIG_MCL_COREDUMP
++#include <asm/crash.h>
++#endif
+ /*
+  *    Some notes on x86 processor bugs affecting SMP operation:
+  *
+@@ -579,7 +582,7 @@
+       return 0;
+ }
+-static void stop_this_cpu (void * dummy)
++void stop_this_cpu (void * dummy)
+ {
+       /*
+        * Remove this CPU:
+Index: linux/arch/i386/kernel/traps.c
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/arch/i386/kernel/traps.c,v
+retrieving revision 1.3.2.1
+retrieving revision 1.3.2.1.2.1
+diff -u -r1.3.2.1 -r1.3.2.1.2.1
+--- linux/arch/i386/kernel/traps.c     12 Mar 2003 19:49:06 -0000      1.3.2.1
++++ linux/arch/i386/kernel/traps.c     1 Apr 2003 12:17:40 -0000       1.3.2.1.2.1
+@@ -52,6 +52,10 @@
+ #include <linux/irq.h>
+ #include <linux/module.h>
++#ifdef CONFIG_MCL_COREDUMP
++#include <linux/crash.h>
++#endif
++
+ asmlinkage int system_call(void);
+ asmlinkage void lcall7(void);
+ asmlinkage void lcall27(void);
+@@ -309,7 +313,11 @@
+               netdump_func(regs);
+       bust_spinlocks(0);
+       spin_unlock_irq(&die_lock);
+-      do_exit(SIGSEGV);
++#ifdef CONFIG_MCL_COREDUMP 
++      if(panic_on_oops)
++              panic("die");
++#endif
++      do_exit(SIGSEGV);/* NOTREACHED */
+ }
+ static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
+Index: linux/drivers/char/misc.c
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/drivers/char/misc.c,v
+retrieving revision 1.2
+retrieving revision 1.2.4.1
+diff -u -r1.2 -r1.2.4.1
+--- linux/drivers/char/misc.c  25 Sep 2002 17:11:05 -0000      1.2
++++ linux/drivers/char/misc.c  1 Apr 2003 12:17:41 -0000       1.2.4.1
+@@ -78,6 +78,8 @@
+ extern int i8k_init(void);
+ extern int lcd_init(void);
++extern int crash_init_chrdev(void);
++
+ static int misc_read_proc(char *buf, char **start, off_t offset,
+                         int len, int *eof, void *private)
+ {
+@@ -255,6 +257,9 @@
+ int __init misc_init(void)
+ {
+       create_proc_read_entry("misc", 0, 0, misc_read_proc, NULL);
++#ifdef CONFIG_MCL_COREDUMP
++      crash_init_chrdev();
++#endif
+ #ifdef CONFIG_MVME16x
+       rtc_MK48T08_init();
+ #endif
+Index: linux/drivers/char/sysrq.c
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/drivers/char/sysrq.c,v
+retrieving revision 1.2.2.1
+retrieving revision 1.2.2.1.2.2
+diff -u -r1.2.2.1 -r1.2.2.1.2.2
+--- linux/drivers/char/sysrq.c 12 Mar 2003 19:49:47 -0000      1.2.2.1
++++ linux/drivers/char/sysrq.c 1 Apr 2003 17:55:35 -0000       1.2.2.1.2.2
+@@ -97,7 +97,18 @@
+       action_msg:     "Resetting",
+ };
+-
++#ifdef CONFIG_MCL_COREDUMP
++/* kernel core dump sysrq */
++static void sysrq_handle_coredump(int key, struct pt_regs *pt_regs,
++              struct kbd_struct *kbd, struct tty_struct *ttty) {
++      panic("sysrq");
++}
++static struct sysrq_key_op sysrq_coredump_op = {
++      handler:        sysrq_handle_coredump,
++      help_msg:       "Crash",
++      action_msg:     "Dumping core",
++};
++#endif
+ /* SYNC SYSRQ HANDLERS BLOCK */
+@@ -334,7 +345,11 @@
+                it is handled specially on the spark
+                and will never arive */
+ /* b */       &sysrq_reboot_op,
++#ifdef CONFIG_MCL_COREDUMP
++/* c */       &sysrq_coredump_op,
++#else
+ /* c */       NULL,
++#endif
+ /* d */       NULL,
+ /* e */       &sysrq_term_op,
+ /* f */       NULL,
+Index: linux/include/asm-i386/bootimg.h
+===================================================================
+RCS file: linux/include/asm-i386/bootimg.h
+diff -N linux/include/asm-i386/bootimg.h
+--- /dev/null  1 Jan 1970 00:00:00 -0000
++++ linux/include/asm-i386/bootimg.h   1 Apr 2003 12:17:41 -0000       1.1.6.1
+@@ -0,0 +1,141 @@
++/* asm-i386/bootimg.h - Boot image, i386-specific code */
++
++/* Written 2000 by Werner Almesberger */
++
++/*
++ * When porting bootimg(2) to a new architcture, you need to adapt the
++ * functions and definitions in this file.
++ */
++
++
++#ifndef _ASM_I386_BOOTIMG_H
++#define _ASM_I386_BOOTIMG_H
++
++#include <linux/config.h>
++#include <asm/system.h>
++
++#ifdef CONFIG_SMP
++#include <linux/smp.h>
++#include <linux/irq.h>
++#endif
++
++
++/*
++ * The memory page with the code currently executing has been copied from
++ * old_page to new_page. Jump there.
++ *
++ * Note: flush_icache_range has already been called on the new page.
++ */
++
++static inline void jump_relocated(unsigned long old_page,unsigned long new_page)
++{
++      int tmp;
++
++      __asm__ __volatile__(
++      "stc\n\t"
++      "call 1f\n"
++      "1:\tjnc 2f\n\t"
++      "popl %0\n\t"
++      "addl %1,%0\n\t"
++      "addl %1,%%esp\n\t"
++      "clc\n\t"
++      "jmp *%0\n"
++      "2:"
++      : "=&r" (tmp) : "r" (new_page-old_page));
++}
++
++
++/*
++ * Stop paging, such that
++ *  - page tables can be overwritten
++ *  - all physical memory can be accessed
++ *  - all physical memory is identity-mapped
++ *
++ * (Other rules are possible, but need to be encoded in bootimg(8).)
++ */
++
++static inline void stop_paging(void)
++{
++      unsigned long msw;
++
++      __asm__ __volatile__(
++      "movl %%cr0,%0\n\t"
++      "andl $0x7fffffff,%0\n\t"
++      "movl %0,%%cr0\n\t"
++      "jmp 1f\n\t"    /* i486 and such */
++      "1:"
++
++/* Clear the PAE bit in register %cr4 if we were in PAE mode.  The initial
++ * page table set up by the new kernel's bootstrap code is non-PAE regardless
++ * of whether the new kernel is a PAE kernel.  By clearing the PAE bit here,
++ * we make sure the bootstrap code doesn't accidentally enable PAE mode when
++ * it turns on address translation.
++ */
++#ifdef CONFIG_X86_PAE
++      "movl %%cr4,%0\n\t"
++      "andl $0xffffffdf,%0\n\t"
++      "movl %0,%%cr4\n\t"
++#endif
++
++      : "=&r" (msw) : : "memory");
++}
++
++
++/*
++ * Stop any remaining concurrency in the system. If become_only_thread fails
++ * but the system is still usable, become_only_thread should return an error
++ * code. If no recovery is possible, it may as well panic.
++ */
++
++static inline int become_only_thread(void)
++{
++#ifdef CONFIG_SMP
++      smp_send_stop();
++      disable_IO_APIC();
++#endif
++      cli();
++      return 0;
++}
++
++
++/*
++ * A conservative estimate of the number of bytes relocate_and_jump allocated
++ * on the stack. This is only used for sanity checking before running code,
++ * because we can't recover from failure in relocate_and_jump.
++ */
++
++#define RESERVE_MIN_RELOC_STACK       256
++
++
++/*
++ * Change the stack pointer such that stack is at the end of the specified
++ * page. No data on the old stack will be accessed anymore, so no copying is
++ * required.
++ */
++
++static inline void stack_on_page(void *page)
++{
++      __asm__ __volatile__(
++      "push %%ds\n\t"
++      "pop %%ss\n\t"
++      "movl %0,%%esp\n\t"
++      "addl $0x1000,%%esp\n\t"
++      : : "r" (page));
++}
++
++/*
++ * Set up things such that the kernel will be comfortable (e.g. some
++ * architectures expect the boot loader to set registers in certain ways),
++ * and then jump to the kernel's entry address.
++ */
++
++static inline void jump_to_kernel(void (*kernel_entry)(void))
++{
++      __asm__ __volatile__(
++      "mov $0x90000,%%esi\n\t"
++      : : );
++
++      kernel_entry();
++}
++
++#endif
+Index: linux/include/asm-i386/crash.h
+===================================================================
+RCS file: linux/include/asm-i386/crash.h
+diff -N linux/include/asm-i386/crash.h
+--- /dev/null  1 Jan 1970 00:00:00 -0000
++++ linux/include/asm-i386/crash.h     1 Apr 2003 12:17:41 -0000       1.1.6.1
+@@ -0,0 +1,15 @@
++#ifndef __ASM_CRASH_H
++#define __ASM_CRASH_H
++
++#define UPPER_MEM_BACKUP 0
++#define LOWER_MEM_FORWARD 0
++#define LOW_OFFSET 100
++
++/*
++ *  These two functions are inlined on alpha.  That's why they appear
++ *  in the arch dependent include file.
++ */
++void crash_save_current_state(struct task_struct *);
++void crash_halt_or_reboot(int);
++
++#endif
+Index: linux/include/linux/bootimg.h
+===================================================================
+RCS file: linux/include/linux/bootimg.h
+diff -N linux/include/linux/bootimg.h
+--- /dev/null  1 Jan 1970 00:00:00 -0000
++++ linux/include/linux/bootimg.h      1 Apr 2003 12:17:41 -0000       1.1.6.1
+@@ -0,0 +1,84 @@
++/* linux/bootimg.h - Boot image, general definitions */
++
++/* Written 2000 by Werner Almesberger */
++
++
++#ifndef _LINUX_BOOTIMG_H
++#define _LINUX_BOOTIMG_H
++
++
++/*
++ * Constraints on image_map:
++ *  - each image_map[n] is the virtual address of a page-sized memory region
++ *    readable by the user
++ *  - currently, image_map[n] is not required to be page-aligned, but this may
++ *    change in the future if we want to map pages directly to lower memory
++ *    pressure (NB: mapping works for ELF and plain binary images, but usually
++ *    not for (b)zImages, because the prepended boot and setup sectors
++ *    mis-align them)
++ *
++ * Constraints on load_map:
++ *  - each load_map[] is the physical address of a page in RAM
++ */
++
++struct boot_image {
++      void **image_map;       /* pointers to image pages in user memory */
++      int pages;              /* length in pages */
++      unsigned long *load_map;/* list of destination pages (physical addr) */
++      unsigned long start;    /* jump to this physical address */
++      int flags;              /* for future use, must be zero for now */
++};
++
++
++#ifdef __KERNEL__
++
++#define __bootimg __attribute__ ((__section__ (".bootimg")))
++
++
++struct bootimg_dsc {
++      unsigned long self;             /* code page            ALL ADDRESSES */
++      unsigned long scratch;          /* scratch page         ARE PHYSICAL !*/
++      unsigned long **page_dir;       /* src & dst page tables              */
++      void (*jump_to)(void);          /* start address                      */
++      int pages;                      /* number of pages */
++    unsigned long csum; /* Kernel Image checksum */
++};
++
++/*
++ * page_dir contains pointers to pages containing pointers to pages. We call
++ * page_dir a "directory" and the page page_dir[n] points to a "table". The
++ * first PAGES_PER_TABLE/2 entries of page_dir are for source pages, and other
++ * half are for destination pages.
++ */
++
++/*
++ * Note that the definitions used here do not necessarily correspond to the
++ * architecture-specific PTRS_PER_PTE, __pte_offset, etc.
++ */
++ 
++#define PAGES_PER_TABLE       (PAGE_SIZE/sizeof(void *))
++#define FROM_TABLE(i) ((i)/PAGES_PER_TABLE)
++#define TO_TABLE(i)   ((i)/PAGES_PER_TABLE+PAGES_PER_TABLE/2)
++#define PAGE_NR(i)    ((i) % PAGES_PER_TABLE)
++
++
++extern char __bootimg_start,__bootimg_end;    /* linker segment boundaries */
++extern unsigned long *unity_page; /* unity-mapped page for i386 */
++
++/*
++ * relocate_and_jump runs in its own page with its own stack. This makes it
++ * difficult to pass parameters. The solution chosen here is to use the global
++ * variable bootimg_dsc, which is copied into an "auto" variable by
++ * relocate_and_jump before any copying or relocation takes place.
++ */
++
++extern struct bootimg_dsc bootimg_dsc;
++
++typedef void (*relocate_and_jump_t)(void);
++
++void relocate_and_jump(void);
++int  boot_image(void);
++
++#endif /* __KERNEL__ */
++
++#endif
+Index: linux/include/linux/crash.h
+===================================================================
+RCS file: linux/include/linux/crash.h
+diff -N linux/include/linux/crash.h
+--- /dev/null  1 Jan 1970 00:00:00 -0000
++++ linux/include/linux/crash.h        1 Apr 2003 12:17:41 -0000       1.1.6.1
+@@ -0,0 +1,119 @@
++#ifndef __LINUX_CRASH_H
++#define __LINUX_CRASH_H
++
++/* defines for interfacing with user-space (ioctls, etc) */
++struct ioctl_getdump {
++      unsigned long kva;
++      unsigned long buf;
++};
++
++#define CRASH_IOC_MAGIC 'C'
++
++#define CRASH_IOCFREEDUMP _IO(CRASH_IOC_MAGIC, 0)
++#define CRASH_IOCGETDUMP _IOWR(CRASH_IOC_MAGIC, 1, struct ioctl_getdump)
++#define CRASH_IOCBOOTIMG _IOWR(CRASH_IOC_MAGIC, 2, struct boot_image)
++#define CRASH_IOCVERSION _IO(CRASH_IOC_MAGIC, 3)
++
++/* kernel-only part of crash.h */
++#ifdef __KERNEL__
++#include <asm/crash.h>
++
++#define CRASH_K_MINOR (1)
++#define CRASH_K_MAJOR (0)
++
++/*
++ * Crash prototypes.
++ */
++void save_core(void);
++void crash_mark_dump_reserved(void);
++void crash_init(u_long bootmap_va, u_long crash_va, u_long end_alloc_va);
++u_long crash_pages_needed(void);
++void smp_crash_funnel_cpu(void);
++void crash_cleanup_smp_state(void);
++
++/*
++ *  Arch dependant crash.c funcs
++ */
++void crash_save_current_state(struct task_struct *);
++void crash_halt_or_reboot(int);
++inline void crash_save_regs(void);
++
++/*
++ * Crash globals
++ */
++extern u_long crash_dump_header;
++extern volatile u_long panic_ksp[];
++extern volatile int crash_release;
++extern int panic_on_oops;
++extern char *panicmsg;
++extern int panic_processor;
++extern int crash_perform_sync;
++extern unsigned long *panic_regs;
++
++/*
++ * symbols not exported by linux header files
++ */
++extern void stop_this_cpu(void *);
++
++/*  struct crash_map_hdr located at byte offset 0 */
++/* on-disk formats */
++
++#define trunc_page(x)   ((void *)(((unsigned long)(x)) & ~((unsigned long)(PAGE_SIZE - 1))))
++#define round_page(x)   trunc_page(((unsigned long)(x)) + ((unsigned long)(PAGE_SIZE - 1)))
++
++#define CRASH_MAGIC 0x9a8bccdd
++#define CRASH_SOURCE_PAGES 128
++#define CRASH_SUB_MAP_BYTES ((u_long)round_page((CRASH_SOURCE_PAGES+1)*sizeof(u_long)))
++#define CRASH_SUB_MAP_PAGES (CRASH_SUB_MAP_BYTES / PAGE_SIZE)
++#define CRASH_UNCOMPR_BUF_PAGES (CRASH_SOURCE_PAGES + CRASH_SUB_MAP_PAGES)
++#define CRASH_COMPR_BUF_PAGES (CRASH_UNCOMPR_BUF_PAGES + (CRASH_UNCOMPR_BUF_PAGES/4))
++#define CRASH_COMPESS_PRIME_PAGES (2*CRASH_COMPR_BUF_PAGES)
++#define CRASH_ZALLOC_PAGES 16*5*2     /* 2 to handle crash in crash */
++#define CRASH_LOW_WATER_PAGES 100
++
++#define CRASH_CPU_TIMEOUT 5000        /* 5 sec wait for other cpus to stop */
++
++#define CRASH_MARK_RESERVED(addr) (set_bit(PG_reserved,&mem_map[MAP_NR(addr)].flags))
++#define CRASH_CLEAR_RESERVED(addr) (clear_bit(PG_reserved,&mem_map[MAP_NR(addr)].flags))
++#define CRASH_MARK_BOOT_RESERVED(addr) reserve_bootmem(virt_to_phys((void *)addr), PAGE_SIZE);
++
++typedef int boolean_t;
++
++#define TRUE 1
++#define FALSE 0
++
++/* mem structure */
++struct mem_crash_map_hdr {
++      long magic[4];          /* identify crash dump */
++      u_long map;             /* location of map */
++      u_long map_pages;
++      u_long data_pages;
++      u_long compr_units;
++      u_long boot_reserved_start;
++      u_long boot_reserved_end;
++};
++struct mem_crash_map_entry {
++      u_long src_va;          /* source start of larger non-contig 
++                               * block.  a src_va of -1 means that 
++                               * the dest_page_va is the location of 
++                               * the next map page */
++      u_long dest_page_va;    /* dest of this sub block */
++      u_long check_sum;       /* check_sum for dest data */
++};
++
++/* file structure */
++struct crash_map_hdr {
++      long magic[4];          /* identify crash dump */
++      int blk_size;           /* block size for this device */
++      int map_block;          /* location of map */
++      int map_blocks;         /* number of blocks for map */
++};
++struct crash_map_entry {
++      u_long start_va;        /* virtual address */
++      char *exp_data;         /* expanded data in memory */
++      int start_blk;          /* device location */
++      int num_blks;
++};
++
++#endif /* __KERNEL__ */
++#endif /* __LINUX_CRASH_H */
+Index: linux/include/linux/mm.h
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/include/linux/mm.h,v
+retrieving revision 1.2.2.1
+retrieving revision 1.2.2.1.2.2
+diff -u -r1.2.2.1 -r1.2.2.1.2.2
+--- linux/include/linux/mm.h   12 Mar 2003 19:51:27 -0000      1.2.2.1
++++ linux/include/linux/mm.h   1 Apr 2003 17:55:35 -0000       1.2.2.1.2.2
+@@ -331,6 +331,11 @@
+ #define PG_lru                        18
+ #define PG_active_cache               19
+ #define PG_fs_1                       20      /* Filesystem specific */
++#ifdef CONFIG_MCL_COREDUMP
++#define PG_free                       21
++#define PG_shm                        22
++#define PG_anon                       23
++#endif
+ /* Make it prettier to test the above... */
+ #define UnlockPage(page)      unlock_page(page)
+@@ -452,6 +457,11 @@
+ #define PageSetSlab(page)     set_bit(PG_slab, &(page)->flags)
+ #define PageClearSlab(page)   clear_bit(PG_slab, &(page)->flags)
+ #define PageReserved(page)    test_bit(PG_reserved, &(page)->flags)
++#ifdef CONFIG_MCL_COREDUMP
++#define PageFree(page)          (test_bit(PG_free, &(page)->flags))
++#define PageAnon(page)          (test_bit(PG_anon, &(page)->flags))
++#define PageShm(page)           (test_bit(PG_shm, &(page)->flags))
++#endif
+ #define PageActiveAnon(page)          test_bit(PG_active_anon, &(page)->flags)
+ #define SetPageActiveAnon(page)       set_bit(PG_active_anon, &(page)->flags)
+Index: linux/include/linux/reboot.h
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/include/linux/reboot.h,v
+retrieving revision 1.1.1.1
+retrieving revision 1.1.1.1.10.2
+diff -u -r1.1.1.1 -r1.1.1.1.10.2
+--- linux/include/linux/reboot.h       7 May 2002 21:53:47 -0000       1.1.1.1
++++ linux/include/linux/reboot.h       1 Apr 2003 17:55:35 -0000       1.1.1.1.10.2
+@@ -20,6 +20,7 @@
+  * CAD_OFF     Ctrl-Alt-Del sequence sends SIGINT to init task.
+  * POWER_OFF   Stop OS and remove all power from system, if possible.
+  * RESTART2    Restart system using given command string.
++ * COREDUMP    We're taking a core dump, secondary cpus already stopped.
+  */
+ #define       LINUX_REBOOT_CMD_RESTART        0x01234567
+@@ -28,7 +29,9 @@
+ #define       LINUX_REBOOT_CMD_CAD_OFF        0x00000000
+ #define       LINUX_REBOOT_CMD_POWER_OFF      0x4321FEDC
+ #define       LINUX_REBOOT_CMD_RESTART2       0xA1B2C3D4
+-
++#ifdef CONFIG_MCL_COREDUMP
++#define LINUX_REBOOT_CMD_COREDUMP     0x9A8BCCDD
++#endif
+ #ifdef __KERNEL__
+Index: linux/include/linux/sysctl.h
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/include/linux/sysctl.h,v
+retrieving revision 1.3.2.1
+retrieving revision 1.3.2.1.2.1
+diff -u -r1.3.2.1 -r1.3.2.1.2.1
+--- linux/include/linux/sysctl.h       12 Mar 2003 19:51:30 -0000      1.3.2.1
++++ linux/include/linux/sysctl.h       1 Apr 2003 12:17:41 -0000       1.3.2.1.2.1
+@@ -126,6 +126,7 @@
+       KERN_CADPID=54,         /* int: PID of the process to notify on CAD */
+       KERN_CORE_PATTERN=56,   /* string: pattern for core-files */
+       KERN_PID_MAX=55,        /* int: max PID value of processes */
++      KERN_PANIC_ON_OOPS      /* int: panic on oops enabled */
+ };
+Index: linux/init/main.c
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/init/main.c,v
+retrieving revision 1.2.2.1
+retrieving revision 1.2.2.1.2.1
+diff -u -r1.2.2.1 -r1.2.2.1.2.1
+--- linux/init/main.c  12 Mar 2003 19:51:35 -0000      1.2.2.1
++++ linux/init/main.c  1 Apr 2003 12:17:41 -0000       1.2.2.1.2.1
+@@ -70,6 +70,10 @@
+ #include <asm/smp.h>
+ #endif
++#ifdef CONFIG_BOOTIMG
++#include <linux/bootimg.h>
++#endif
++
+ /*
+  * Versions of gcc older than that listed below may actually compile
+  * and link okay, but the end product can have subtle run time bugs.
+@@ -352,10 +356,14 @@
+ {
+       char * command_line;
+       extern char saved_command_line[];
++#if defined(CONFIG_BOOTIMG) && defined(CONFIG_X86_LOCAL_APIC)
++      unsigned long value;
++#endif
+ /*
+  * Interrupts are still disabled. Do necessary setups, then
+  * enable them
+  */
++      printk("start_kernel\n");
+       lock_kernel();
+       printk(linux_banner);
+       setup_arch(&command_line);
+@@ -373,12 +381,26 @@
+        * this. But we do want output early, in case something goes wrong.
+        */
+       console_init();
++
++#ifdef CONFIG_BOOTIMG
++      unity_page = alloc_bootmem_pages(PAGE_SIZE);
++      printk("unity_page addr: %p\n",unity_page);
++#endif
+ #ifdef CONFIG_MODULES
+       init_modules();
+ #endif
+       profile_init();
+       kmem_cache_init();
+       sti();
++#if defined(CONFIG_BOOTIMG) && defined(CONFIG_X86_LOCAL_APIC)
++      /* If we don't make sure the APIC is enabled, AND the LVT0
++       * register is programmed properly, we won't get timer interrupts
++       */
++      setup_local_APIC();
++      
++      value = apic_read(APIC_LVT0);
++      apic_write_around(APIC_LVT0, value & ~APIC_LVT_MASKED);
++#endif
+       calibrate_delay();
+ #ifdef CONFIG_BLK_DEV_INITRD
+       if (initrd_start && !initrd_below_start_ok &&
+Index: linux/kernel/Makefile
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/kernel/Makefile,v
+retrieving revision 1.1.1.1.4.1
+retrieving revision 1.1.1.1.4.1.2.1
+diff -u -r1.1.1.1.4.1 -r1.1.1.1.4.1.2.1
+--- linux/kernel/Makefile      12 Mar 2003 19:51:36 -0000      1.1.1.1.4.1
++++ linux/kernel/Makefile      1 Apr 2003 12:17:41 -0000       1.1.1.1.4.1.2.1
+@@ -22,7 +22,8 @@
+ obj-$(CONFIG_PM) += pm.o
+ obj-$(CONFIG_KALLSYMS) += kallsyms.o
+ obj-$(CONFIG_CPU_FREQ) += cpufreq.o
+-
++obj-$(CONFIG_BOOTIMG) += bootimg.o bootimg_pic.o
++obj-$(CONFIG_MCL_COREDUMP) += crash.o
+ ifneq ($(CONFIG_IA64),y)
+ # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
+Index: linux/kernel/bootimg.c
+===================================================================
+RCS file: linux/kernel/bootimg.c
+diff -N linux/kernel/bootimg.c
+--- /dev/null  1 Jan 1970 00:00:00 -0000
++++ linux/kernel/bootimg.c     1 Apr 2003 12:17:41 -0000       1.1.6.1
+@@ -0,0 +1,301 @@
++/* bootimg.c - Boot another (kernel) image */
++
++/* Written 2000 by Werner Almesberger */
++
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/mm.h>
++#include <linux/capability.h>
++#include <linux/bootimg.h>
++#include <asm/bootimg.h>
++#include <asm/uaccess.h>
++#include <asm/io.h>
++#include <asm/pgtable.h>
++#include <linux/delay.h>
++
++#if 0
++#define DPRINTK_CONT(format,args...) printk(format,##args)
++#else
++#define DPRINTK_CONT(format,args...)
++#endif
++#define DPRINTK(format,args...) DPRINTK_CONT(KERN_DEBUG format,##args)
++
++unsigned long **bootimg_page_dir;
++
++struct bootimg_dsc bootimg_dsc; /* communication with PIC */
++unsigned long *unity_page; /* unity-mapped page for i386 */
++
++static unsigned long bootimg_checksum(unsigned long **page_dir, int num_pages)
++{
++      unsigned long checksum, *page;
++      int i, j;
++
++      checksum = 0;
++
++      for (i = 0; i < num_pages; i++) {
++              page = __va((unsigned long *)
++                          page_dir[FROM_TABLE(i)][PAGE_NR(i)]);
++
++              for (j = 0; j < PAGES_PER_TABLE; j++)
++                      checksum ^= page[j];
++
++              checksum ^= page_dir[TO_TABLE(i)][PAGE_NR(i)];
++      }
++
++        return checksum;
++}
++
++#ifdef CONFIG_X86_PAE
++
++static unsigned long get_identity_mapped_page(void)
++{
++      pgd_t *pgd;
++      pmd_t *pmd;
++      unsigned long phys_addr, page_base;
++
++      /* Set up a 2 Mb identity-mapped page. */
++
++      phys_addr = virt_to_phys(unity_page);
++      pgd = pgd_offset(current->active_mm, phys_addr);
++      pmd = pmd_offset(pgd, phys_addr);
++
++      /* We hardcode this rather than using PMD_MASK just in case the PAE
++               * mode setup ever changes so that 2 Mb pages are no longer used.
++               */
++      page_base = phys_addr & ~((1 << 21) - 1);
++
++      set_pmd(pmd, __pmd(page_base | _PAGE_PSE | _KERNPG_TABLE));
++      __flush_tlb_one(phys_addr);
++
++      return (unsigned long) unity_page;
++}
++
++#else
++
++static unsigned long get_identity_mapped_page(void)
++{
++      set_pgd(pgd_offset(current->active_mm,virt_to_phys(unity_page)),
++              __pgd((_KERNPG_TABLE + _PAGE_PSE + (virt_to_phys(unity_page)&PGDIR_MASK))));
++      __flush_tlb_one(virt_to_phys(unity_page));
++      return (unsigned long)unity_page;
++}
++
++#endif
++
++#if 0 /* Perhaps we'll need this in the future? */
++static void unmap_identity_mapped_page(void)
++{
++      set_pgd(pgd_offset(current->active_mm,virt_to_phys(unity_page)),__pgd(0));
++      __flush_tlb();
++}
++#endif
++
++static int fill_page_dir(unsigned long **page_dir,struct boot_image *image)
++{
++      int i, count=0;
++
++      memset(page_dir,0,PAGE_SIZE);
++      for (i = 0; i < image->pages; i += PAGES_PER_TABLE) {
++              unsigned long **table;
++              int bytes_left;
++
++              table = page_dir+FROM_TABLE(i);
++              *table = (unsigned long *) get_free_page(GFP_KERNEL);
++              if (!*table) return -ENOMEM;
++
++              memset(*table,0,PAGE_SIZE);
++              DPRINTK("page %d: from table %p @ %p\n",i,*table,table);
++              table = page_dir+TO_TABLE(i);
++              *table = (unsigned long *) get_free_page(GFP_KERNEL);
++              if (!*table) return -ENOMEM;
++
++              bytes_left = (image->pages-i)*sizeof(unsigned long);
++              if (copy_from_user(*table,image->load_map+i,
++                  bytes_left > PAGE_SIZE ? PAGE_SIZE : bytes_left))
++                      return -EFAULT;
++              DPRINTK("page %d: to table %p @ %p\n",i,*table,table);
++              count+=2; /* 2 pages per loop */
++      }
++
++      for (i = 0; i < image->pages; i++) {
++              unsigned long page = get_free_page(GFP_KERNEL);
++              void *src;
++
++              if (!page) return -ENOMEM;
++              count++;
++
++              page_dir[FROM_TABLE(i)][PAGE_NR(i)] =
++                  virt_to_phys((void *) page);
++              if (get_user(src,image->image_map+i) ||
++                  copy_from_user((void *) page,src,PAGE_SIZE))
++                      return -EFAULT;
++
++              DPRINTK("page %d: %p->%p->%p @ %p\n",i,src,(void *) page,
++                  (void *) page_dir[FROM_TABLE(i)][PAGE_NR(i)],
++                  &page_dir[FROM_TABLE(i)][PAGE_NR(i)]);
++      }
++
++      DPRINTK("fill_page_dir: %d pages allocated\n", count);
++
++      return 0;
++}
++
++
++static void free_page_dir(unsigned long **page_dir)
++{
++      int i,j,count=0;
++
++      for (i = 0; i < PAGES_PER_TABLE/2; i++)
++              if (page_dir[i])
++                      for (j = 0; j < PAGES_PER_TABLE; j++)
++                              if (page_dir[i][j]) {
++                                      free_page((unsigned long)
++                                          phys_to_virt(page_dir[i][j]));
++                                      count++;
++                              }
++      for (i = 0; i < PAGES_PER_TABLE; i++)
++              if (page_dir[i]) {
++                      free_page((unsigned long) *page_dir[i]);
++                      count++;
++              }
++      DPRINTK("free_page_dir: %d pages freed\n", count);
++}
++
++
++static void convert_table_refs_to_phys(unsigned long **page_dir)
++{
++      int i;
++
++      DPRINTK("PAGES_PER_TABLE: %d\n",PAGES_PER_TABLE);
++      for (i = 0; i < PAGES_PER_TABLE; i++)
++              if (page_dir[i]) {
++                      DPRINTK("table %i: mapped %p -> ",i,page_dir[i]);
++                      page_dir[i] = (unsigned long *)
++                          virt_to_phys(page_dir[i]);
++                      DPRINTK_CONT("%p\n",page_dir[i]);
++              }
++}
++
++
++
++static int fill_bootimg_dsc(struct boot_image *image)
++{
++      unsigned long scratch;
++      int error = -ENOMEM;
++
++      if(bootimg_page_dir) {
++              /* free previously allocated memory */
++              free_page_dir(bootimg_page_dir);
++              free_page((unsigned long) bootimg_page_dir);
++              DPRINTK("free_page (bootimg_page_dir)\n");
++      }
++
++      bootimg_page_dir = (unsigned long **) get_free_page(GFP_KERNEL);
++      if (!bootimg_page_dir) goto out0;
++      DPRINTK("get_free_page (bootimg_page_dir)\n");
++
++      error = fill_page_dir(bootimg_page_dir,image);
++      if (error) goto out1;
++
++      if(!bootimg_dsc.scratch) {
++              scratch = get_free_page(GFP_KERNEL);
++              DPRINTK("get_free_page (scratch)\n");
++      } else
++              scratch = 1; /* already allocated */
++
++      if (!scratch) goto out1;
++      /*
++       * Not all architectures need the code to be identity-mapped, but it
++       * can't hurt ...
++       */
++      DPRINTK("bootimg_page_dir: mapped %p -> ",bootimg_page_dir);
++      bootimg_dsc.page_dir = (unsigned long **) virt_to_phys(bootimg_page_dir);
++      DPRINTK_CONT("%p\n",bootimg_dsc.page_dir);
++      if(!bootimg_dsc.scratch)
++              bootimg_dsc.scratch = virt_to_phys((void *) scratch);
++      bootimg_dsc.jump_to = (void (*)(void)) image->start;
++      bootimg_dsc.pages = image->pages;
++      bootimg_dsc.csum = bootimg_checksum(bootimg_page_dir, image->pages);
++
++      return 0;
++
++out1:
++      free_page_dir(bootimg_page_dir);
++      free_page((unsigned long) bootimg_page_dir);
++      DPRINTK("free_page (bootimg_page_dir)\n");
++      bootimg_page_dir = 0;
++out0:
++      return error;
++}
++
++extern char *panicmsg;
++int boot_image()
++{
++      relocate_and_jump_t code;
++      unsigned long code_page;
++      int error = -ENOMEM;
++
++      if (bootimg_checksum(__va(bootimg_dsc.page_dir),bootimg_dsc.pages) 
++              != bootimg_dsc.csum)
++              printk("Checksum of kernel image failed.  Rebooting via BIOS\n");
++
++      code_page = get_identity_mapped_page();
++      if (!code_page) goto out3;
++      code = (relocate_and_jump_t) virt_to_phys((void *) code_page);
++      memcpy(code,&__bootimg_start,&__bootimg_end-&__bootimg_start);
++      flush_icache_range(&__bootimg_start, &__bootimg_end-&__bootimg_start);
++
++      bootimg_dsc.self = (unsigned long) code;
++      printk(KERN_INFO "Running boot code at 0x%p\n",code);
++      
++      /*
++       * The point of no return. Not even printk may work after a successful
++       * return from become_only_thread.
++       */
++
++      if (!panicmsg) {
++                      error = become_only_thread();
++                      if (error) goto out3;
++      } else {
++#ifdef CONFIG_SMP
++                      disable_IO_APIC();
++#endif
++                      __cli();
++      }
++
++      convert_table_refs_to_phys((unsigned long **)__va(bootimg_dsc.page_dir));
++      stack_on_page(code);
++
++      code();
++
++      panic("PIC code exec failed");
++out3:
++      printk("boot_image() failed!\n");
++      for(;;); 
++}
++
++/* changed from asmlinkage because we're called via an IOCTL on /dev/crash now */
++int sys_bootimg(struct boot_image *user_dsc)
++{
++      struct boot_image dsc;
++
++      if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_MODULE)) return -EPERM;
++      if (&__bootimg_end-&__bootimg_start > PAGE_SIZE-RESERVE_MIN_RELOC_STACK)
++         {
++              printk(KERN_ERR "boot_image: PIC too large (%d bytes)\n",
++                  &__bootimg_end-&__bootimg_start);
++              return -EIO;
++      }
++      if ((void *) relocate_and_jump != (void *) &__bootimg_start) {
++              printk(KERN_ERR "boot_image: relocate_and_jump is mis-placed"
++                  "(0x%p != 0x%p)\n",relocate_and_jump,&__bootimg_start);
++              return -EIO;
++      }
++      
++      if (copy_from_user(&dsc,user_dsc,sizeof(dsc))) return -EFAULT;
++      if (dsc.pages >= PAGES_PER_TABLE*PAGES_PER_TABLE/2) return -EFBIG;
++      if (dsc.flags) return -EINVAL; /* for future use */
++      return fill_bootimg_dsc(&dsc);
++}
+Index: linux/kernel/bootimg_pic.c
+===================================================================
+RCS file: linux/kernel/bootimg_pic.c
+diff -N linux/kernel/bootimg_pic.c
+--- /dev/null  1 Jan 1970 00:00:00 -0000
++++ linux/kernel/bootimg_pic.c 1 Apr 2003 12:17:41 -0000       1.1.6.1
+@@ -0,0 +1,91 @@
++/* bootimg_pic.c - Boot image, position-independent code */
++
++/* Written 2000 by Werner Almesberger */
++
++/*
++ * Strongly inspired by FiPaBoL designed mainly by Otfried Cheong and Roger
++ * Gammans, and written by the latter.
++ */
++
++/*
++ * This code is position-independent and must fit in a single page !
++ * Furthermore, everything (text+data+stack) has to go into the
++ * .bootimg segment.
++ */
++
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/mm.h>
++#include <linux/bootimg.h>
++#include <asm/bootimg.h>
++
++#include <asm/io.h>
++
++#define copy_and_swap(from,to) \
++    ( { my_copy_page(from,to); \
++    tmp = from; \
++    from = to; \
++    to = tmp; } )
++
++
++static inline void my_copy_page(unsigned long from,unsigned long to)
++{
++      unsigned long end = from+PAGE_SIZE;
++
++      do *((unsigned long *) to)++ = *((unsigned long *) from)++;
++      while (from != end);
++}
++
++
++void __bootimg relocate_and_jump(void)
++{
++      struct bootimg_dsc dsc = bootimg_dsc;
++      int i;
++
++      stop_paging();
++      for (i = 0; i < dsc.pages; i++) {
++              unsigned long from,to,tmp;
++
++              from = dsc.page_dir[FROM_TABLE(i)][PAGE_NR(i)];
++              to = dsc.page_dir[TO_TABLE(i)][PAGE_NR(i)];
++              if (from == to) continue;
++              if (to == dsc.self) {
++                      copy_and_swap(dsc.self,dsc.scratch);
++                      /* WARNING: flush_icache_range MUST BE INLINED !!! */
++                      flush_icache_range(dsc.self,dsc.self+PAGE_SIZE-1);
++                      jump_relocated(dsc.scratch,dsc.self);
++              }
++              else if (to == (unsigned long) dsc.page_dir)
++                      copy_and_swap((unsigned long) dsc.page_dir,dsc.scratch);
++              else {
++                      /*
++                       * O((n^2-n)/2), sigh ...
++                       */
++                      unsigned long **table;
++                      int j;
++
++                      for (j = i+1; j < dsc.pages; j++) {
++                              table = dsc.page_dir+FROM_TABLE(j);
++                              if (((unsigned long) *table) == to) {
++                                      copy_and_swap(*table,dsc.scratch);
++                                      break;
++                              }
++                              if ((*table)[PAGE_NR(j)] == to) {
++                                      copy_and_swap((*table)[PAGE_NR(j)],
++                                          dsc.scratch);
++                                      break;
++                              }
++                              table = dsc.page_dir+TO_TABLE(j);
++                              if (((unsigned long) *table) == to) {
++                                      copy_and_swap(*table,dsc.scratch);
++                                      break;
++                              }
++                      }
++              }
++              my_copy_page(from,to);
++              dsc.scratch = from;
++      }
++      jump_to_kernel(dsc.jump_to);
++}
+Index: linux/kernel/crash.c
+===================================================================
+RCS file: linux/kernel/crash.c
+diff -N linux/kernel/crash.c
+--- /dev/null  1 Jan 1970 00:00:00 -0000
++++ linux/kernel/crash.c       1 Apr 2003 12:17:41 -0000       1.1.6.1
+@@ -0,0 +1,886 @@
++#include <linux/locks.h>
++#include <linux/slab.h>
++#include <linux/crash.h>
++#include <linux/vmalloc.h>
++#include <linux/mm.h>
++#include <linux/fs.h>
++#include <linux/ext2_fs.h>
++#include <asm/param.h>
++#include <asm/uaccess.h>
++#include <linux/zlib.h>
++#include <linux/reboot.h>
++#include <linux/delay.h>
++#include <asm/io.h>
++#include <linux/miscdevice.h>
++#include <linux/bootmem.h>
++
++#ifdef CONFIG_BOOTIMG
++#include <linux/bootimg.h>
++#endif
++
++static void crash_print_data_around(u_long p);
++static void crash_free_page(u_long addr);
++static int crash_chksum_page(u_long pg_addr, u_long * sum_addr);
++static void *czalloc(void *arg, unsigned int items, unsigned int size);
++static void czfree(void *arg, void *ptr);
++static u_long crash_alloc_dest_page(void);
++static void crash_free_dest_page(u_long dest);
++static void init_dest_page_alloc(void);
++static int crash_audit_maps(void);
++static u_long crash_get_source_page(void);
++static u_long crash_update_map(u_long map, u_long src_base, u_long dest, u_long * pages);
++static int crash_reset_stream(z_stream * stream);
++static boolean_t crash_is_kseg(u_long addr);
++static u_long *crash_link(u_long p);
++static int crash_chksum(u_long limit, u_long * sum_addr);
++static int crash_audit_map_page(u_long map);
++static void crash_wait_cpus(void);
++static int crash_is_dir_page(struct page *page);
++
++/* for the /dev/crash interface */
++int crash_init_chrdev(void);
++static int crashdev_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
++
++#define CRASH_DEBUG 1
++
++#ifdef CONFIG_BOOTIMG
++extern int sys_bootimg(struct boot_image *);
++#endif
++
++static u_long crash_compr_buf;
++static u_long crash_uncompr_buf;
++static u_long crash_dump_header = 0;
++static u_long crash_dest_free_list = 0;
++static u_long crash_debug = 0;
++
++static u_long crash_cur_pfn;
++
++static u_long src_pages_skipped = 0;
++static u_long src_pages_saved = 0;
++static u_long dest_pages_free = 0;
++
++/* this information is saved from within panic() */
++char *panicmsg = (char *)0;
++int panic_processor = 0;
++int crash_perform_sync = 0;
++
++u_int console_crash = 0;      /* should be moved to alpha branch */
++
++// typedef struct task_struct *task_t;
++
++/*
++ *  Threads active at time of panic:
++ */
++volatile task_t *panic_threads[NR_CPUS];
++volatile unsigned long panic_ksp[NR_CPUS];
++unsigned long *panic_regs = NULL;
++
++int panic_on_oops;            /* for /proc/sys/kernel/panic_on_oops */
++
++extern unsigned long max_low_pfn;
++
++u_long crash_zalloc_start; // , crash_zalloc_end, crash_zalloc_cur;
++
++/* 
++ * Crash Kernel API functions below
++ * crash_pages_needed, computes pages needed for header and compression temp
++ * crash_init, partitions out the allocated pages, sets defaults and 
++ *             initializes the character device.
++ * crash_mark_dump_reserved, marks pages reserved from a previous dump.
++ * save_core, called at panic time to save a dump to memory.
++ */
++u_long crash_pages_needed(void)
++{
++      /* one for the header */
++      return (1 + CRASH_ZALLOC_PAGES + CRASH_UNCOMPR_BUF_PAGES + CRASH_COMPR_BUF_PAGES);
++}
++
++void crash_init(u_long bootmap_va, u_long crash_va, u_long end_alloc_va)
++{
++      struct mem_crash_map_hdr *header;
++      int i;
++
++      /* the default behavior is not NOT panic on a kernel OOPS */
++      panic_on_oops = 0;
++
++      printk("crash_init (crash_va: %08lx)\n", crash_va);
++      for (i = 0; i < NR_CPUS; i++)
++              panic_threads[i] = 0;
++      crash_dump_header = crash_va;
++      crash_va += PAGE_SIZE;
++      crash_zalloc_start = crash_va;
++      crash_va += CRASH_ZALLOC_PAGES * PAGE_SIZE;
++      crash_uncompr_buf = crash_va;
++      crash_va += CRASH_UNCOMPR_BUF_PAGES * PAGE_SIZE;
++      crash_compr_buf = crash_va;
++      crash_va += CRASH_COMPR_BUF_PAGES * PAGE_SIZE;
++#if 0
++      if (crash_va != end_alloc_va)
++              panic("crash_init inconsistency-1\n");
++#endif
++
++      header = (struct mem_crash_map_hdr *)crash_dump_header;
++#ifdef CRASH_DEBUG
++      printk("crash_dump_header %p {\n", header);
++      printk("    magic[0]            = %lx\n", header->magic[0]);
++      printk("    map                 = %lx\n", header->map);
++      printk("    map_pages           = %lx\n", header->map_pages);
++      printk("    data_pages          = %lx\n", header->data_pages);
++      printk("    compr_units         = %lx\n", header->compr_units);
++      printk("    boot_reserved_start = %lx\n", header->boot_reserved_start);
++      printk("    boot_reserved_end   = %lx\n", header->boot_reserved_end);
++#endif
++
++      if (header->magic[0] == CRASH_MAGIC) {
++              printk("crash found\n");
++              if ((header->boot_reserved_start != bootmap_va) ||
++                  (header->boot_reserved_end != end_alloc_va)) {
++                      /* crash audit will catch the corruption */
++                      printk("crash_init inconsistency, dump may be corrupted\n");
++              }
++      } else {
++printk("memset...");
++              memset(header, 0, sizeof(*header));
++printk("done\n");
++      }
++
++      header->boot_reserved_start = bootmap_va;
++      header->boot_reserved_end = end_alloc_va;
++
++}
++
++void crash_mark_dump_reserved(void)
++{
++      struct mem_crash_map_hdr *header;
++      struct mem_crash_map_entry *m;
++
++      header = (struct mem_crash_map_hdr *)crash_dump_header;
++      if (header->magic[0] != CRASH_MAGIC)
++              return;
++      m = (struct mem_crash_map_entry *)header->map;
++#ifdef CRASH_DEBUG
++      printk("\n\n\ncrash_mark_dump_reserved\n\n");
++      printk("crash_dump_header %p {\n", header);
++      printk("    magic[0]            = %lx\n", header->magic[0]);
++      printk("    map                 = %lx\n", header->map);
++      printk("    map_pages           = %lx\n", header->map_pages);
++      printk("    data_pages          = %lx\n", header->data_pages);
++      printk("    compr_units         = %lx\n", header->compr_units);
++      printk("    boot_reserved_start = %lx\n", header->boot_reserved_start);
++      printk("    boot_reserved_end   = %lx\n", header->boot_reserved_end);
++      printk("mem_crash_map_entry %p {\n", m);
++      printk("    src_va              = %lx\n", m->src_va);
++      printk("    dest_page_va        = %lx\n", m->dest_page_va);
++      printk("    check_sum           = %lx\n", m->check_sum);
++#endif
++
++      if (crash_audit_maps()) {
++              header->magic[0] = 0;
++              return;
++      }
++
++      m = (struct mem_crash_map_entry *)header->map;
++ again:
++      CRASH_MARK_BOOT_RESERVED(m);
++      for (; m->src_va; m++) {
++              if (m->src_va == -1) {
++                      m = (struct mem_crash_map_entry *)m->dest_page_va;
++                      goto again;
++              }
++              CRASH_MARK_BOOT_RESERVED(m->dest_page_va);
++      }
++      return;
++}
++
++void save_core(void)
++{
++      int i, j, k;
++      z_stream stream;
++      int err;
++      struct task_struct *tp;
++      struct mem_crash_map_hdr *header;
++      u_long *sub_map;
++      u_long map;
++      u_long src, dest, unc, cp, src_base, comp_pages;
++
++      k = 0;
++      dest = 0;
++      __cli();
++      tp = current;
++      mb();
++      if (smp_processor_id() != 0) {  /* boot_cpu_id is always 0, i think */
++              panic_threads[smp_processor_id()] = tp;
++              crash_halt_or_reboot(0);
++      } else {
++              if (console_crash)
++                      panic_threads[smp_processor_id()] = &init_task_union.task;
++              else
++                      panic_threads[smp_processor_id()] = tp;
++
++              crash_wait_cpus();
++      }
++
++      printk("save_core: started on CPU%d\n", smp_processor_id());
++      if (!crash_dump_header) {
++              printk("save_core: not initialized\n");
++              return;
++      }
++
++      header = (struct mem_crash_map_hdr *)crash_dump_header;
++      header->magic[0] = 0;
++      header->map_pages = 0;
++      header->data_pages = 0;
++      header->compr_units = 0;
++      header->map = 0;
++
++      stream.workspace=(void*)crash_zalloc_start;
++      //      stream.zalloc = czalloc;
++      //      stream.zfree = czfree;
++      //      stream.opaque = (voidpf) 0;
++      stream.next_out = (Bytef *) crash_compr_buf;
++      stream.avail_out = (uInt) (CRASH_COMPR_BUF_PAGES * PAGE_SIZE);
++      stream.next_in = (Bytef *) crash_uncompr_buf;
++      stream.avail_in = (uInt) (CRASH_UNCOMPR_BUF_PAGES * PAGE_SIZE);
++      err = zlib_deflateInit(&stream, Z_BEST_SPEED);
++      if (err != Z_OK) {
++              printk("save_core: bad return %d from deflateInit\n", err);
++              return;
++      }
++
++      init_dest_page_alloc();
++      header->map = map = crash_update_map(0, 0, 0, &header->map_pages);
++      if (!map) {
++              printk("save_core: no dest pages\n");
++              return;
++      }
++      crash_cur_pfn = 0;
++      src_base = 0;
++      src = 0;
++      for (;;) {
++              sub_map = (u_long *) crash_uncompr_buf;
++              unc = crash_uncompr_buf + CRASH_SUB_MAP_PAGES * PAGE_SIZE;
++              for (i = 0; i < CRASH_SOURCE_PAGES; i++) {
++                      src = crash_get_source_page();
++                      if (!src)
++                              break;
++                      if (!i)
++                              src_base = src;
++                      if (!crash_is_kseg(unc) || !crash_is_kseg(src)) {
++                              printk("unc = 0x%lx, src = 0x%lx, i = %d\n", unc, src, i);
++                              i = src = 0;
++                              break;
++                      }
++                      memcpy((void *)unc, (void *)src, PAGE_SIZE);
++                      unc += PAGE_SIZE;
++                      *sub_map++ = src;
++              }
++              *sub_map = 0;
++              if (!i && !src)
++                      break;
++              err = zlib_deflate(&stream, Z_FINISH);
++              if (!(err == Z_STREAM_END)) {
++                      zlib_deflateEnd(&stream);
++                      printk("save_core: bad return %d from deflate, src_base = 0x%lx\n", err,
++                             src_base);
++                      return;
++              }
++              comp_pages = (u_long) round_page(stream.total_out) / PAGE_SIZE;
++              if (crash_debug)
++                      printk("src_base = 0x%lx compressed data in 0x%lx pages\n", src_base,
++                             comp_pages);
++
++              cp = crash_compr_buf;
++              j = 0;
++              if (crash_debug)
++                      printk("\nsrc = %lx\n", src_base);
++              else {
++                      printk(".");
++                      if (!(k++ % 64))
++                              printk("\n");
++              }
++              for (i = 0; i < comp_pages; i++) {
++                      dest = crash_alloc_dest_page();
++                      if (crash_debug) {
++                              printk("%lx ", dest);
++                              if (!(j++ % 8))
++                                      printk("\n");
++                      }
++                      header->data_pages++;
++                      if (!dest) {
++                              printk("save_core: no dest pages\n");
++                              return;
++                      }
++                      if (!crash_is_kseg(dest) || !crash_is_kseg(cp)) {
++                              printk("dest = 0x%lx, cp = 0x%lx, i = %d, comp_pages = 0x%lx\n",
++                                     dest, cp, i, comp_pages);
++                              src = 0;
++                              break;
++                      }
++                      memcpy((void *)dest, (void *)cp, PAGE_SIZE);
++                      cp += PAGE_SIZE;
++                      map = crash_update_map(map, src_base, dest, &header->map_pages); /* links a new map page, if necessary */
++                      if (!map) {
++                              printk("save_core: no map\n");
++                              return;
++                      }
++              }
++              header->compr_units++;
++              if (!src)
++                      break;
++              if (crash_reset_stream(&stream))
++                      return;
++      }
++
++      map = crash_update_map(map, 0, 0, &header->map_pages);
++      header->magic[0] = CRASH_MAGIC;
++
++      if (crash_audit_maps()) {
++              header->magic[0] = 0;
++              return;
++      }
++
++      printk("\nsave_core: src pages skipped = 0x%lx src pages saved = 0x%lx\n",
++             src_pages_skipped, src_pages_saved);
++      printk("save_core: data_pages = 0x%lx map_pages = 0x%lx\n", header->data_pages,
++             header->map_pages);
++      printk("save_core: completed, crash_dump_header = 0x%lx\n", crash_dump_header);
++}
++
++/* helper functions private to this file */
++static int crash_reset_stream(z_stream * stream)
++{
++      int err;
++
++      stream->workspace=(void*)crash_zalloc_start;
++      // stream->zalloc = czalloc;
++      // stream->zfree = czfree;
++      // stream->opaque = (voidpf) 0;
++      stream->next_out = (Bytef *) crash_compr_buf;
++      stream->avail_out = (uInt) (CRASH_COMPR_BUF_PAGES * PAGE_SIZE);
++      stream->next_in = (Bytef *) crash_uncompr_buf;
++      stream->avail_in = (uInt) (CRASH_UNCOMPR_BUF_PAGES * PAGE_SIZE);
++      err = zlib_deflateReset(stream);
++      if (err != Z_OK) {
++              printk("crash_reset_stream: bad return %d from deflateReset\n", err);
++              return 1;
++      }
++      return 0;
++}
++
++static u_long crash_alloc_dest_page(void)
++{
++      u_long addr;
++
++      addr = crash_dest_free_list;
++      if (addr) {
++              crash_dest_free_list = *(u_long *) addr;
++              dest_pages_free--;
++      } else
++              printk("crash_alloc_dest_page: free list empty\n");
++      return addr;
++}
++
++static void crash_free_dest_page(u_long dest)
++{
++      if (!dest) {
++              printk("crash_free_dest_page: freeing addr 0\n");
++              return;
++      }
++      dest_pages_free++;
++      dest = (u_long) trunc_page(dest);
++      *(u_long *) dest = crash_dest_free_list;
++      crash_dest_free_list = dest;
++}
++
++/*
++ *  Stolen from setup.c
++ */
++#define PFN_PHYS(x)   ((x) << PAGE_SHIFT)
++
++static void init_dest_page_alloc(void)
++{
++      u_long va;
++      long i;
++      struct page *page;
++      struct mem_crash_map_hdr *header;
++
++      header = (struct mem_crash_map_hdr *)crash_dump_header;
++      for (i = ((1 << 24) >> PAGE_SHIFT) + LOWER_MEM_FORWARD;
++           i < (max_low_pfn - UPPER_MEM_BACKUP); i++) {
++              va = (u_long) phys_to_virt(PFN_PHYS(i));
++              if ((va >= header->boot_reserved_start) && (va < header->boot_reserved_end))
++                      continue;
++              page = mem_map + i;
++              if (PageLocked(page) || PageReserved(page))
++                      continue;
++              if (PageFree(page) || PageAnon(page) || PageShm(page) || page->buffers)
++                      crash_free_dest_page(va);
++      }
++      if (crash_debug)
++              printk("init_dest_page_alloc: dest_pages_free = 0x%lx\n", dest_pages_free);
++}
++
++static int crash_is_dir_page(struct page *page) {
++      struct inode *tmp_inode;
++
++      if(page->mapping && page->mapping->host) {
++              tmp_inode = (struct inode *)page->mapping->host;
++              if((tmp_inode->i_sb->s_magic == EXT2_SUPER_MAGIC) &&
++                 (S_ISDIR(tmp_inode->i_mode)))
++                      return 1;
++      }
++
++      return 0;
++}
++
++static u_long crash_get_source_page(void)
++{
++      struct page *page;
++      u_long va;
++
++      while (crash_cur_pfn < max_low_pfn) {
++              page = mem_map + crash_cur_pfn;
++              if (!(PageFree(page) || PageAnon(page) || PageShm(page) || page->buffers))
++                      break;
++              src_pages_skipped++;
++              crash_cur_pfn++;
++      }
++      if (crash_cur_pfn == max_low_pfn)
++              return 0;
++
++      va = (u_long) phys_to_virt(PFN_PHYS(crash_cur_pfn));
++      src_pages_saved++;
++      crash_cur_pfn++;
++      return va;
++}
++
++static u_long crash_update_map(u_long map, u_long src_base, u_long dest, u_long * pages)
++{
++      struct mem_crash_map_entry *m;
++
++
++      if (!map) {
++              (*pages)++;
++              return crash_alloc_dest_page();
++      }
++      m = (struct mem_crash_map_entry *)map;
++      m->src_va = src_base;
++      m->dest_page_va = dest;
++      if (dest)
++              if (crash_chksum_page(dest, &m->check_sum))
++                      return 0;
++
++      map += sizeof(struct mem_crash_map_entry);
++
++      m = (struct mem_crash_map_entry *)map;
++      if (!src_base) {        /* end of list */
++              if (crash_chksum((u_long) m, &m->src_va))
++                      return 0;
++      } else if ((map + 3 * sizeof(struct mem_crash_map_entry)) > (u_long) round_page(map)) {
++              m->src_va = -1;
++              map = m->dest_page_va = crash_alloc_dest_page();
++              if (crash_debug)
++                      printk("\nm = 0x%lx m->src_va = 0x%lx m->dest_page_va = 0x%lx\n",
++                             (u_long) trunc_page(m), m->src_va, m->dest_page_va);
++              m++;
++              if (crash_chksum((u_long) m, &m->src_va))
++                      return 0;
++              if (crash_debug)
++                      printk("m = 0x%lx chksum =  m->src_va = 0x%lx\n", (u_long) trunc_page(m),
++                             m->src_va);
++              if (crash_audit_map_page((u_long) m))
++                      return 0;
++              (*pages)++;
++      }
++      return map;
++}
++
++static int crash_chksum(u_long limit, u_long * sum_addr)
++{
++      u_long sum;
++      u_long *addr;
++
++      if (!crash_is_kseg(limit)) {
++              printk("bad addr = 0x%lx to crash_chksum\n", limit);
++              return 1;
++      }
++      sum = 0;
++      addr = (u_long *) trunc_page(limit);
++      for (; (u_long) addr < limit; addr++)
++              sum += *addr;
++      *sum_addr = sum;
++      return 0;
++}
++
++static int crash_chksum_page(u_long pg_addr, u_long * sum_addr)
++{
++      u_long sum, limit;
++      u_long *addr;
++
++      if (!crash_is_kseg(pg_addr)) {
++              printk("bad addr = 0x%lx to crash_chksum_page\n", pg_addr);
++              return 1;
++      }
++
++      sum = 0;
++      addr = (u_long *) trunc_page(pg_addr);
++      limit = (u_long) addr + PAGE_SIZE;
++      for (; (u_long) addr < limit; addr++)
++              sum += *addr;
++      *sum_addr = sum;
++      return 0;
++}
++
++static int crash_audit_maps(void)
++{
++      u_long m, count;
++      u_long *link_addr;
++      struct mem_crash_map_hdr *header;
++
++      header = (struct mem_crash_map_hdr *)crash_dump_header;
++      if (header->magic[0] != CRASH_MAGIC)
++              return 1;
++
++      link_addr = &header->map;
++      m = header->map;
++
++      count = 0;
++      for (;;) {
++              if (!crash_is_kseg(m)) {
++                      printk("crash_audit_maps: bad link 0x%lx at 0x%lx\n", m,
++                             (u_long) link_addr);
++                      return 1;
++              }
++              if (crash_audit_map_page(m)) {
++                      printk("audit failed while on map page %ld\n", count);
++                      return 1;
++              }
++              if (!crash_link(m))
++                      break;
++              link_addr = crash_link(m);
++              m = *link_addr;
++
++              count++;
++      }
++      return 0;
++}
++
++static int crash_audit_map_page(u_long map)
++{
++      struct mem_crash_map_entry *m;
++      u_long sum;
++
++      if (!map || !crash_is_kseg(map)) {
++              printk("crash_audit_map_page: bad map = 0x%lx\n", map);
++              return 1;
++      }
++      map = (u_long) trunc_page((u_long) map);
++      m = (struct mem_crash_map_entry *)map;
++      for (;;) {
++              if ((m->src_va == -1) || (m->src_va == 0)) {
++                      m++;
++                      if (crash_chksum((u_long) m, &sum))
++                              return 1;
++                      if (m->src_va != sum) {
++                              printk("crash_audit_map_page: checksum failure1\n");
++                              printk("m = 0x%lx, sum = 0x%lx, m->src_va = 0x%lx\n",
++                                     (u_long) m, (u_long) sum, (u_long) m->src_va);
++                              crash_print_data_around((u_long) & m->src_va);
++                              return 1;
++                      } else {
++                              return 0;
++                      }
++              } else {
++                      if (crash_chksum_page((u_long) m->dest_page_va, &sum)
++                          || (m->check_sum != sum)) {
++                              printk("crash_audit_map_page: checksum failure2\n");
++                              printk
++                                      ("dest_page_va = 0x%lx, &dest_page_va = 0x%lx, sum = 0x%lx, m->check_sum = 0x%lx\n",
++                                       (u_long) m->dest_page_va, (u_long) (&m->check_sum),
++                                       (u_long) sum, (u_long) m->check_sum);
++                              crash_print_data_around((u_long) & m->check_sum);
++                              return 1;
++                      }
++              }
++              m++;
++      }
++}
++
++static void crash_print_data_around(u_long p)
++{
++      u_long *a;
++      int i;
++
++      if (!crash_is_kseg(p)) {
++              printk("crash_print_data_around: p = 0x%lx not kseg\n", p);
++              return;
++      }
++      a = (u_long *) p;
++      a -= 20;
++      for (i = 0; i < 40; i++)
++              printk("%lx\n", *a++);
++}
++
++#ifdef CRASH_DEBUG
++static void crash_print_map_page(u_long map)
++{
++      struct mem_crash_map_entry *m;
++      int j = 0;
++      u_long sum;
++
++      map = (u_long) trunc_page((u_long) map);
++      m = (struct mem_crash_map_entry *)map;
++      for (;;) {
++              printk("%lx %lx %lx ", m->src_va, m->dest_page_va, m->check_sum);
++              if (!(j++ % 4))
++                      printk("\n");
++              if ((m->src_va == -1) || (m->src_va == 0)) {
++                      m++;
++                      printk("%lx %lx ", m->src_va, m->dest_page_va);
++                      if (crash_chksum((u_long) m, &sum));
++                      else
++                              printk("\nchksum = 0x%lx\n", sum);
++                      return;
++              }
++              m++;
++      }
++}
++#endif /* CRASH_DEBUG */
++
++static void crash_wait_cpus(void)
++{
++      int i;
++      int msecs = 0;
++
++      for (i = 0; i < smp_num_cpus; i++) {
++              if (i != smp_processor_id()) {
++                      while (!panic_threads[i]) {
++                              msecs++;
++                              mdelay(1);
++                              if (msecs > CRASH_CPU_TIMEOUT) {
++                                      /* if other cpus are still running
++                                       * we have to halt, otherwise we could
++                                       * risk using buffer cache pages which
++                                       * could subsequently get flushed to disk.
++                                       */
++                                      printk("Unable to halt other CPUs, halting system.\n");
++                                      crash_halt_or_reboot(0);
++                              }
++                      }
++              }
++      }
++
++      crash_cleanup_smp_state();
++}
++
++
++#if 0
++static void *czalloc(void *arg, unsigned int items, unsigned int size)
++{
++      u_long nbytes;
++      u_long addr;
++
++      nbytes = (u_long) (items * size);
++      nbytes = (u_long) round_page(nbytes);
++      if ((crash_zalloc_cur + nbytes) > crash_zalloc_end)
++              return 0;
++      addr = crash_zalloc_cur;
++      crash_zalloc_cur += nbytes;
++      return ((void *)addr);
++}
++
++static void czfree(void *arg, void *ptr)
++{
++      printk("zfree: ptr = 0x%lx\n", (u_long) ptr);
++}
++#endif
++
++static boolean_t crash_is_kseg(u_long addr)
++{
++      u_long phys;
++
++      phys = virt_to_phys((void *)addr);
++      if (phys < PFN_PHYS(max_low_pfn))
++              return TRUE;
++      else
++              return FALSE;
++}
++
++static u_long *crash_link(u_long p)
++{
++      struct mem_crash_map_entry *m;
++
++      p = (u_long) trunc_page(p);
++      m = (struct mem_crash_map_entry *)p;
++      for (; m->src_va; m++)
++              if (m->src_va == -1)
++                      return &m->dest_page_va;
++
++      return 0;
++}
++
++/* Call this after data written to disk. */
++static int crash_free_crashmem(void)
++{
++      struct mem_crash_map_hdr *header;
++      struct mem_crash_map_entry *m, *last_m;
++
++      if (crash_debug)
++              printk("crash_free_crashmem: \n");
++
++      header = (struct mem_crash_map_hdr *)crash_dump_header;
++      if (crash_audit_maps()) {
++              header->magic[0] = 0;
++              return 1;
++      }
++      m = (struct mem_crash_map_entry *)header->map;
++ again:
++      for (; m->src_va; m++) {
++              if (m->src_va == -1) {
++                      last_m = m;
++                      m = (struct mem_crash_map_entry *)m->dest_page_va;
++                      crash_free_page((unsigned long)last_m);
++                      goto again;
++              }
++              crash_free_page(m->dest_page_va);
++      }
++      if (crash_debug)
++              printk("crash_free_crashmem: 0x%lx freed\n",
++                     (header->data_pages + header->map_pages) * PAGE_SIZE);
++      header->magic[0] = 0;
++      return 0;
++}
++
++static void crash_free_page(u_long addr)
++{
++      struct page *page;
++
++      page = virt_to_page(addr);
++      ClearPageReserved(page);
++      set_page_count(page, 1);
++      __free_page(page);
++}
++
++static int get_dump_helper(u_long kva, u_long buf)
++{
++      struct page *page;
++      struct mem_crash_map_hdr *header;
++
++      header = (struct mem_crash_map_hdr *)crash_dump_header;
++      if (header->magic[0] != CRASH_MAGIC)
++              return 1;
++
++      if (!kva) {
++              if (crash_audit_maps()) {
++                      printk("get_dump_helper: audit failure\n");
++                      header->magic[0] = 0;
++                      return 1;
++              }
++              page = virt_to_page((u_long) crash_dump_header);
++              if (!PageReserved(page)) {
++                      printk("not reserved: crash_dump_header = 0x%lx\n", crash_dump_header);
++                      return 1;
++              }
++              if (copy_to_user((char *)buf, (char *)crash_dump_header,
++                               sizeof(struct mem_crash_map_hdr))) {
++                      printk("get_dump_helper: copy_to_user failed1\n");
++                      return 1;
++              }
++      } else {
++              page = virt_to_page(kva);
++              if (!PageReserved(page)) {
++                      printk("not reserved: kva = 0x%lx\n", kva);
++                      return 1;
++              }
++              if (copy_to_user((char *)buf, (char *)trunc_page(kva), PAGE_SIZE)) {
++                      printk("get_dump_helper: copy_to_user failed2\n");
++                      return 1;
++              }
++      }
++      return 0;
++}
++
++static void free_dump_helper(void)
++{
++      struct mem_crash_map_hdr *header;
++
++      header = (struct mem_crash_map_hdr *)crash_dump_header;
++      if (header->magic[0] != CRASH_MAGIC)
++              return;
++      if (crash_debug)
++              printk("free_dump_helper\n");
++      crash_free_crashmem();
++}
++
++static int crashdev_open(struct inode *inode, struct file *file)
++{
++      /* always return success -- nothing to do here */
++      return 0;
++}
++
++/* character device implementation */
++static struct file_operations crashdev_fops = {
++      ioctl:crashdev_ioctl,
++      open:crashdev_open,
++};
++
++static struct miscdevice crash_miscdev = {
++      190, "crash", &crashdev_fops
++};
++
++int crash_init_chrdev(void)
++{
++      int result;
++
++      result = misc_register(&crash_miscdev);
++
++      if (result < 0)
++              printk(KERN_WARNING "crash: can't register crash device (c 10 190)\n");
++
++      return result;
++}
++
++/* call the original syscalls, just to get things going */
++static int crashdev_ioctl(struct inode *inode, struct file *file,
++                        unsigned int cmd, unsigned long arg)
++{
++      int retval = 0;
++
++      switch (cmd) {
++      case CRASH_IOCFREEDUMP:
++              free_dump_helper();
++              break;
++
++      case CRASH_IOCGETDUMP:
++              if (crash_debug) {
++                      printk("crashdev_ioctl: get dump\n");
++                      printk("vals: %08lx %08lx\n",
++                             ((struct ioctl_getdump *)arg)->kva,
++                             ((struct ioctl_getdump *)arg)->buf);
++              }
++
++              retval = get_dump_helper((u_long) ((struct ioctl_getdump *)arg)->kva,
++                                       (u_long) ((struct ioctl_getdump *)arg)->buf);
++              break;
++
++#ifdef CONFIG_BOOTIMG
++      case CRASH_IOCBOOTIMG:
++              if (crash_debug)
++                      printk("crashdev_ioctl: bootimg\n");
++
++              retval = sys_bootimg((struct boot_image *)arg);
++              break;
++#endif
++
++      case CRASH_IOCVERSION:
++              if (crash_debug)
++                      printk("crashdev_ioctl: version\n");
++              retval = CRASH_K_MINOR | (CRASH_K_MAJOR << 16);
++              break;
++
++      default:
++              return -EINVAL;
++      }
++
++      return retval;
++}
+Index: linux/kernel/module.c
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/kernel/module.c,v
+retrieving revision 1.1.1.1.4.1
+retrieving revision 1.1.1.1.4.1.2.1
+diff -u -r1.1.1.1.4.1 -r1.1.1.1.4.1.2.1
+--- linux/kernel/module.c      12 Mar 2003 19:51:36 -0000      1.1.1.1.4.1
++++ linux/kernel/module.c      1 Apr 2003 12:17:41 -0000       1.1.1.1.4.1.2.1
+@@ -311,7 +311,14 @@
+               error = -EEXIST;
+               goto err1;
+       }
++#if defined(CONFIG_MCL_COREDUMP)
++      /* Call vmalloc_32 instead of module_map (vmalloc for i386)
++       * to avoid being mapped in highmem where mcore can't see us.
++       */
++      if ((mod = (struct module *)vmalloc_32(size)) == NULL) {
++#else
+       if ((mod = (struct module *)module_map(size)) == NULL) {
++#endif
+               error = -ENOMEM;
+               goto err1;
+       }
+Index: linux/kernel/panic.c
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/kernel/panic.c,v
+retrieving revision 1.3.2.1
+retrieving revision 1.3.2.1.2.1
+diff -u -r1.3.2.1 -r1.3.2.1.2.1
+--- linux/kernel/panic.c       12 Mar 2003 19:51:36 -0000      1.3.2.1
++++ linux/kernel/panic.c       1 Apr 2003 12:17:41 -0000       1.3.2.1.2.1
+@@ -19,6 +19,10 @@
+ #include <linux/vt_kern.h>
+ #include <linux/pc_keyb.h>
++#ifdef CONFIG_MCL_COREDUMP
++#include <linux/crash.h>
++#endif
++
+ asmlinkage void sys_sync(void);       /* it's really int */
+ int panic_timeout;
+@@ -197,20 +201,43 @@
+         unsigned long caller = (unsigned long) __builtin_return_address(0);
+ #endif
++#ifdef CONFIG_MCL_COREDUMP
++      crash_save_regs();
++#endif
++
+       bust_spinlocks(1);
+       va_start(args, fmt);
+       vsprintf(buf, fmt, args);
+       va_end(args);
+       printk(KERN_EMERG "Kernel panic: %s\n",buf);
++
++#ifdef CONFIG_MCL_COREDUMP
++      if (!panicmsg) {
++              panicmsg = buf;
++              panic_processor = smp_processor_id();
++              mb();
++      }
++#endif
++
+       if (netdump_func)
+               BUG();
+       if (in_interrupt())
+               printk(KERN_EMERG "In interrupt handler - not syncing\n");
+       else if (!current->pid)
+               printk(KERN_EMERG "In idle task - not syncing\n");
++#ifdef CONFIG_MCL_COREDUMP
++      else if (crash_perform_sync)
++#else
+       else
++#endif
+               sys_sync();
++
+       bust_spinlocks(0);
++
++#ifdef CONFIG_MCL_COREDUMP
++      smp_call_function((void *)smp_crash_funnel_cpu,0,0,0);
++      crash_save_current_state(current);
++#endif
+ #ifdef CONFIG_SMP
+       smp_send_stop();
+Index: linux/kernel/sysctl.c
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/kernel/sysctl.c,v
+retrieving revision 1.2.2.1
+retrieving revision 1.2.2.1.2.1
+diff -u -r1.2.2.1 -r1.2.2.1.2.1
+--- linux/kernel/sysctl.c      12 Mar 2003 19:51:36 -0000      1.2.2.1
++++ linux/kernel/sysctl.c      1 Apr 2003 12:17:41 -0000       1.2.2.1.2.1
+@@ -37,6 +37,10 @@
+ #include <linux/nfs_fs.h>
+ #endif
++#ifdef CONFIG_MCL_COREDUMP
++#include <linux/crash.h>
++#endif
++
+ #if defined(CONFIG_SYSCTL)
+ /* External variables not in a header file. */
+@@ -247,6 +251,10 @@
+       {KERN_SYSRQ, "sysrq", &sysrq_enabled, sizeof (int),
+        0644, NULL, &proc_dointvec},
+ #endif         
++#ifdef CONFIG_MCL_COREDUMP
++      {KERN_PANIC_ON_OOPS, "panic_on_oops", &panic_on_oops, sizeof(int),
++       0644, NULL, &proc_dointvec},
++#endif
+       {KERN_CADPID, "cad_pid", &cad_pid, sizeof (int),
+        0600, NULL, &proc_dointvec},
+       {KERN_MAX_THREADS, "threads-max", &max_threads, sizeof(int),
+Index: linux/lib/Config.in
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/lib/Config.in,v
+retrieving revision 1.2
+retrieving revision 1.2.4.1
+diff -u -r1.2 -r1.2.4.1
+--- linux/lib/Config.in        14 Feb 2003 22:59:23 -0000      1.2
++++ linux/lib/Config.in        1 Apr 2003 12:17:41 -0000       1.2.4.1
+@@ -23,12 +23,14 @@
+   fi
+ fi
+-if [ "$CONFIG_PPP_DEFLATE" = "y" -o \
++if [ "$CONFIG_MCL_COREDUMP" = "y" -o \
++     "$CONFIG_PPP_DEFLATE" = "y" -o \
+      "$CONFIG_JFFS2_FS" = "y" ]; then
+    define_tristate CONFIG_ZLIB_DEFLATE y
+ else
+   if [ "$CONFIG_PPP_DEFLATE" = "m" -o \
+-       "$CONFIG_JFFS2_FS" = "m" ]; then
++       "$CONFIG_JFFS2_FS" = "m" -o \
++       "$CONFIG_MCL_COREDUMP" = "m" ]; then
+      define_tristate CONFIG_ZLIB_DEFLATE m
+   else
+      tristate 'zlib compression support' CONFIG_ZLIB_DEFLATE
+Index: linux/mm/memory.c
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/mm/memory.c,v
+retrieving revision 1.3.2.1
+retrieving revision 1.3.2.1.2.1
+diff -u -r1.3.2.1 -r1.3.2.1.2.1
+--- linux/mm/memory.c  12 Mar 2003 19:51:37 -0000      1.3.2.1
++++ linux/mm/memory.c  1 Apr 2003 12:17:41 -0000       1.3.2.1.2.1
+@@ -1381,6 +1381,10 @@
+       }
+       lock_page(page);
++#ifdef CONFIG_MCL_COREDUMP
++      set_bit(PG_anon, &page->flags);
++#endif
++
+       /*
+        * Back out if somebody else faulted in this pte while we
+        * released the page table lock.
+@@ -1470,6 +1474,9 @@
+               mm->rss++;
+               flush_page_to_ram(page);
+               entry = pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
++#ifdef CONFIG_MCL_COREDUMP
++              set_bit(PG_anon, &page->flags);
++#endif
+               lru_cache_add(page);
+       }
+Index: linux/mm/page_alloc.c
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/mm/page_alloc.c,v
+retrieving revision 1.3.2.1
+retrieving revision 1.3.2.1.2.1
+diff -u -r1.3.2.1 -r1.3.2.1.2.1
+--- linux/mm/page_alloc.c      12 Mar 2003 19:51:37 -0000      1.3.2.1
++++ linux/mm/page_alloc.c      1 Apr 2003 12:17:41 -0000       1.3.2.1.2.1
+@@ -95,6 +95,10 @@
+       struct page *base;
+       per_cpu_t *per_cpu;
+       zone_t *zone;
++#ifdef CONFIG_MCL_COREDUMP
++      struct page *pagemap;
++      int count = 1<<order;
++#endif
+       /*
+        * Yes, think what happens when other parts of the kernel take 
+@@ -163,6 +167,15 @@
+       spin_lock(&zone->lock);
++#ifdef CONFIG_MCL_COREDUMP
++      pagemap = page;
++      do {
++              pagemap->flags |= (1<<PG_free);
++              pagemap->flags &= ~((1<<PG_anon)|(1<<PG_shm));
++              pagemap++;
++      } while(--count);
++#endif
++
+       zone->free_pages -= mask;
+       while (mask + (1 << (MAX_ORDER-1))) {
+@@ -268,6 +281,16 @@
+                       zone->free_pages -= 1UL << order;
+                       page = expand(zone, page, index, order, curr_order, area);
++#ifdef CONFIG_MCL_COREDUMP
++                      {
++                              struct page *pagemap = page;
++                              int             count = 1<<order;
++                              do {
++                                      pagemap->flags &= ~(1<<PG_free);
++                                      pagemap++;
++                              } while (--count);
++                      }
++#endif
+                       spin_unlock_irqrestore(&zone->lock, flags);
+                       set_page_count(page, 1);
+Index: linux/arch/i386//boot/compressed/head.S
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/arch/i386/boot/compressed/head.S,v
+retrieving revision 1.1.1.1
+retrieving revision 1.1.1.1.12.6
+diff -u -r1.1.1.1 -r1.1.1.1.12.6
+--- linux/arch/i386//boot/compressed/head.S    7 May 2002 21:53:54 -0000       1.1.1.1
++++ linux/arch/i386//boot/compressed/head.S    5 Apr 2003 05:51:27 -0000       1.1.1.1.12.6
+@@ -23,6 +23,7 @@
+  */
+ .text
++#include <linux/config.h>
+ #include <linux/linkage.h>
+ #include <asm/segment.h>
+@@ -31,6 +32,55 @@
+ startup_32:
+       cld
+       cli
++
++#ifdef CONFIG_BOOTIMG
++/*
++ * GDT is invalid if we're booted by bootimg, so reload it now
++ */
++      lgdt    %cs:gdt_descr
++      ljmp    $(__KERNEL_CS),$1f
++
++gdt_table_limit = gdt_table_end - gdt_table - 1
++gdt_descr:
++      .word   gdt_table_limit
++      .long   gdt_table
++
++gdt_table: /* stolen from arch/i386/kernel/head.S */
++      .quad 0x0000000000000000        /* NULL descriptor */
++      .quad 0x0000000000000000        /* 0x0b reserved */
++      .quad 0x0000000000000000        /* 0x13 reserved */
++      .quad 0x0000000000000000        /* 0x1b reserved */
++      .quad 0x00cffa000000ffff        /* 0x23 user 4GB code at 0x00000000 */
++      .quad 0x00cff2000000ffff        /* 0x2b user 4GB data at 0x00000000 */
++      .quad 0x0000000000000000        /* 0x33 TLS entry 1 */
++      .quad 0x0000000000000000        /* 0x3b TLS entry 2 */
++      .quad 0x0000000000000000        /* 0x43 TLS entry 3 */
++      .quad 0x0000000000000000        /* 0x4b reserved */
++      .quad 0x0000000000000000        /* 0x53 reserved */
++      .quad 0x0000000000000000        /* 0x5b reserved */
++
++      .quad 0x00cf9a000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
++      .quad 0x00cf92000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */
++      .quad 0x0000000000000000        /* 0x70 TSS descriptor */
++      .quad 0x0000000000000000        /* 0x78 LDT descriptor */
++
++      /* Segments used for calling PnP BIOS */
++      .quad 0x00c09a0000000000        /* 0x80 32-bit code */
++      .quad 0x00809a0000000000        /* 0x88 16-bit code */
++      .quad 0x0080920000000000        /* 0x90 16-bit data */
++      .quad 0x0080920000000000        /* 0x98 16-bit data */
++      .quad 0x0080920000000000        /* 0xa0 16-bit data */
++      /*
++       * The APM segments have byte granularity and their bases
++       * and limits are set at run time.
++       */
++      .quad 0x00409a0000000000        /* 0xa8 APM CS    code */
++      .quad 0x00009a0000000000        /* 0xb0 APM CS 16 code (16 bit) */
++      .quad 0x0040920000000000        /* 0xb8 APM DS    data */
++gdt_table_end:
++
++1:
++#endif
+       movl $(__KERNEL_DS),%eax
+       movl %eax,%ds
+       movl %eax,%es
+@@ -92,7 +142,6 @@
+       cld
+       rep
+       movsl
+-
+       popl %esi       # discard the address
+       popl %ebx       # real mode pointer
+       popl %esi       # low_buffer_start
+@@ -124,5 +173,10 @@
+       movsl
+       movl %ebx,%esi  # Restore setup pointer
+       xorl %ebx,%ebx
++#ifdef CONFIG_BOOTIMG
++        movl $0x100000,%eax
++        jmpl *%eax
++#else
+       ljmp $(__KERNEL_CS), $0x100000
++#endif
+ move_routine_end:
+Index: linux/arch/i386//kernel/head.S
+===================================================================
+RCS file: /chaos/cvs/kernel-rh/linux/arch/i386/kernel/head.S,v
+retrieving revision 1.2.2.1
+retrieving revision 1.2.2.1.2.5
+diff -u -r1.2.2.1 -r1.2.2.1.2.5
+--- linux/arch/i386//kernel/head.S     12 Mar 2003 19:49:06 -0000      1.2.2.1
++++ linux/arch/i386//kernel/head.S     5 Apr 2003 05:51:27 -0000       1.2.2.1.2.5
+@@ -42,6 +42,21 @@
+  * On entry, %esi points to the real-mode code as a 32-bit pointer.
+  */
+ startup_32:
++#ifdef CONFIG_BOOTIMG
++/*
++ * GDT is invalid if we're booted by bootimg, so reload it now
++ */
++      lgdt %cs:_gdt_descr-__PAGE_OFFSET
++      ljmp $(__KERNEL_CS),$1f-__PAGE_OFFSET
++
++gdt_limit = SYMBOL_NAME(cpu_gdt_table_end) - SYMBOL_NAME(cpu_gdt_table) - 1
++
++_gdt_descr:
++      .word gdt_limit
++      .long SYMBOL_NAME(cpu_gdt_table)-__PAGE_OFFSET
++
++1:
++#endif
+ /*
+  * Set segments to known values
+  */
+@@ -452,6 +467,7 @@
+       .quad 0x00409a0000000000        /* 0xa8 APM CS    code */
+       .quad 0x00009a0000000000        /* 0xb0 APM CS 16 code (16 bit) */
+       .quad 0x0040920000000000        /* 0xb8 APM DS    data */
++ENTRY(cpu_gdt_table_end)
+ #if CONFIG_SMP
+       .fill (NR_CPUS-1)*GDT_ENTRIES,8,0 /* other CPU's GDT */
index 06d0fff..b35fee0 100644 (file)
@@ -39356,16 +39356,3 @@ diff -Naur -X ../exclude-files orig/mm/slab.c um/mm/slab.c
  
        seq_printf(m, "%-17s %6lu %6lu %6u %4lu %4lu %4u",
                name, active_objs, num_objs, cachep->objsize,
-diff -puNr origin/arch/i386/kernel/sys_i386.c linux/arch/i386/kernel/sys_i386.c
---- origin/arch/i386/kernel/sys_i386.c 2001-03-19 23:35:09.000000000 +0300
-+++ linux/arch/i386/kernel/sys_i386.c  2003-05-04 11:44:54.000000000 +0400
-@@ -56,7 +56,7 @@ static inline long do_mmap2(
-       }
-       down_write(&current->mm->mmap_sem);
--      error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-+      error = do_mmap_pgoff(current->mm, file, addr, len, prot, flags, pgoff);
-       up_write(&current->mm->mmap_sem);
-       if (file)
-
diff --git a/lustre/kernel_patches/pc/dsp.pc b/lustre/kernel_patches/pc/dsp.pc
new file mode 100644 (file)
index 0000000..fdbf418
--- /dev/null
@@ -0,0 +1,6 @@
+kernel/bootimg.c
+kernel/bootimg_pic.c
+include/asm-i386/apic.h
+include/linux/crash.h
+arch/i386/kernel/crash.c
+arch/i386/kernel/nmi.c
diff --git a/lustre/kernel_patches/pc/ext3_orphan_lock-2.4.20-rh.pc b/lustre/kernel_patches/pc/ext3_orphan_lock-2.4.20-rh.pc
new file mode 100644 (file)
index 0000000..98aebb0
--- /dev/null
@@ -0,0 +1,3 @@
+fs/ext3/namei.c
+fs/ext3/super.c
+include/linux/ext3_fs_sb.h
diff --git a/lustre/kernel_patches/pc/iopen-chaos-2.4.18.pc b/lustre/kernel_patches/pc/iopen-chaos-2.4.18.pc
new file mode 100644 (file)
index 0000000..b40b1f3
--- /dev/null
@@ -0,0 +1,8 @@
+Documentation/filesystems/ext2.txt
+fs/ext3/Makefile
+fs/ext3/inode.c
+fs/ext3/iopen.c
+fs/ext3/iopen.h
+fs/ext3/namei.c
+fs/ext3/super.c
+include/linux/ext3_fs.h
diff --git a/lustre/kernel_patches/pc/iopen.pc b/lustre/kernel_patches/pc/iopen.pc
new file mode 100644 (file)
index 0000000..b40b1f3
--- /dev/null
@@ -0,0 +1,8 @@
+Documentation/filesystems/ext2.txt
+fs/ext3/Makefile
+fs/ext3/inode.c
+fs/ext3/iopen.c
+fs/ext3/iopen.h
+fs/ext3/namei.c
+fs/ext3/super.c
+include/linux/ext3_fs.h
diff --git a/lustre/kernel_patches/pc/kmem_cache_validate_2.4.20.pc b/lustre/kernel_patches/pc/kmem_cache_validate_2.4.20.pc
new file mode 100644 (file)
index 0000000..42028bc
--- /dev/null
@@ -0,0 +1,4 @@
+arch/ia64/mm/init.c
+include/linux/slab.h
+kernel/ksyms.c
+mm/slab.c
diff --git a/lustre/kernel_patches/pc/mcore-2.4.20-8.pc b/lustre/kernel_patches/pc/mcore-2.4.20-8.pc
new file mode 100644 (file)
index 0000000..b290f60
--- /dev/null
@@ -0,0 +1,34 @@
+Makefile
+Documentation/Configure.help
+arch/i386/config.in
+arch/i386/vmlinux.lds
+arch/i386/boot/setup.S
+arch/i386/kernel/Makefile
+arch/i386/kernel/crash.c
+arch/i386/kernel/nmi.c
+arch/i386/kernel/process.c
+arch/i386/kernel/setup.c
+arch/i386/kernel/smp.c
+arch/i386/kernel/traps.c
+drivers/char/misc.c
+drivers/char/sysrq.c
+include/asm-i386/bootimg.h
+include/asm-i386/crash.h
+include/linux/bootimg.h
+include/linux/crash.h
+include/linux/mm.h
+include/linux/reboot.h
+include/linux/sysctl.h
+init/main.c
+kernel/Makefile
+kernel/bootimg.c
+kernel/bootimg_pic.c
+kernel/crash.c
+kernel/module.c
+kernel/panic.c
+kernel/sysctl.c
+lib/Config.in
+mm/memory.c
+mm/page_alloc.c
+arch/i386//boot/compressed/head.S
+arch/i386//kernel/head.S
index 8e6b473..887e3fa 100644 (file)
-um/CREDITS
-um/Documentation/Configure.help
-um/MAINTAINERS
-um/Makefile
-um/arch/um/Makefile
-um/arch/um/Makefile-i386
-um/arch/um/Makefile-ia64
-um/arch/um/Makefile-os-Linux
-um/arch/um/Makefile-ppc
-um/arch/um/Makefile-skas
-um/arch/um/Makefile-tt
-um/arch/um/common.ld.in
-um/arch/um/config.in
-um/arch/um/config.release
-um/arch/um/config_block.in
-um/arch/um/config_char.in
-um/arch/um/config_net.in
-um/arch/um/config_scsi.in
-um/arch/um/defconfig
-um/arch/um/drivers/Makefile
-um/arch/um/drivers/chan_kern.c
-um/arch/um/drivers/chan_user.c
-um/arch/um/drivers/daemon.h
-um/arch/um/drivers/daemon_kern.c
-um/arch/um/drivers/daemon_user.c
-um/arch/um/drivers/fd.c
-um/arch/um/drivers/harddog_kern.c
-um/arch/um/drivers/harddog_user.c
-um/arch/um/drivers/hostaudio_kern.c
-um/arch/um/drivers/hostaudio_user.c
-um/arch/um/drivers/line.c
-um/arch/um/drivers/mcast.h
-um/arch/um/drivers/mcast_kern.c
-um/arch/um/drivers/mcast_user.c
-um/arch/um/drivers/mconsole_kern.c
-um/arch/um/drivers/mconsole_user.c
-um/arch/um/drivers/mmapper_kern.c
-um/arch/um/drivers/net_kern.c
-um/arch/um/drivers/net_user.c
-um/arch/um/drivers/null.c
-um/arch/um/drivers/pcap_kern.c
-um/arch/um/drivers/pcap_user.c
-um/arch/um/drivers/pcap_user.h
-um/arch/um/drivers/port.h
-um/arch/um/drivers/port_kern.c
-um/arch/um/drivers/port_user.c
-um/arch/um/drivers/pty.c
-um/arch/um/drivers/slip.h
-um/arch/um/drivers/slip_kern.c
-um/arch/um/drivers/slip_proto.h
-um/arch/um/drivers/slip_user.c
-um/arch/um/drivers/slirp.h
-um/arch/um/drivers/slirp_kern.c
-um/arch/um/drivers/slirp_user.c
-um/arch/um/drivers/ssl.c
-um/arch/um/drivers/ssl.h
-um/arch/um/drivers/stdio_console.c
-um/arch/um/drivers/stdio_console.h
-um/arch/um/drivers/tty.c
-um/arch/um/drivers/ubd_kern.c
-um/arch/um/drivers/ubd_user.c
-um/arch/um/drivers/xterm.c
-um/arch/um/drivers/xterm.h
-um/arch/um/drivers/xterm_kern.c
-um/arch/um/dyn_link.ld.in
-um/arch/um/fs/Makefile
-um/arch/um/fs/hostfs/Makefile
-um/arch/um/fs/hostfs/hostfs.h
-um/arch/um/fs/hostfs/hostfs_kern.c
-um/arch/um/fs/hostfs/hostfs_user.c
-um/arch/um/fs/hppfs/Makefile
-um/arch/um/fs/hppfs/hppfs_kern.c
-um/arch/um/include/2_5compat.h
-um/arch/um/include/Makefile
-um/arch/um/include/chan_kern.h
-um/arch/um/include/chan_user.h
-um/arch/um/include/choose-mode.h
-um/arch/um/include/frame.h
-um/arch/um/include/frame_kern.h
-um/arch/um/include/frame_user.h
-um/arch/um/include/helper.h
-um/arch/um/include/hostaudio.h
-um/arch/um/include/init.h
-um/arch/um/include/initrd.h
-um/arch/um/include/irq_user.h
-um/arch/um/include/kern.h
-um/arch/um/include/kern_util.h
-um/arch/um/include/line.h
-um/arch/um/include/mconsole.h
-um/arch/um/include/mconsole_kern.h
-um/arch/um/include/mem.h
-um/arch/um/include/mem_user.h
-um/arch/um/include/mode.h
-um/arch/um/include/mode_kern.h
-um/arch/um/include/net_kern.h
-um/arch/um/include/net_user.h
-um/arch/um/include/os.h
-um/arch/um/include/process.h
-um/arch/um/include/ptrace_user.h
-um/arch/um/include/sigcontext.h
-um/arch/um/include/sigio.h
-um/arch/um/include/signal_kern.h
-um/arch/um/include/signal_user.h
-um/arch/um/include/skas_ptrace.h
-um/arch/um/include/syscall_user.h
-um/arch/um/include/sysdep-i386/checksum.h
-um/arch/um/include/sysdep-i386/frame.h
-um/arch/um/include/sysdep-i386/frame_kern.h
-um/arch/um/include/sysdep-i386/frame_user.h
-um/arch/um/include/sysdep-i386/ptrace.h
-um/arch/um/include/sysdep-i386/ptrace_user.h
-um/arch/um/include/sysdep-i386/sigcontext.h
-um/arch/um/include/sysdep-i386/syscalls.h
-um/arch/um/include/sysdep-ia64/ptrace.h
-um/arch/um/include/sysdep-ia64/sigcontext.h
-um/arch/um/include/sysdep-ia64/syscalls.h
-um/arch/um/include/sysdep-ppc/ptrace.h
-um/arch/um/include/sysdep-ppc/sigcontext.h
-um/arch/um/include/sysdep-ppc/syscalls.h
-um/arch/um/include/sysrq.h
-um/arch/um/include/tempfile.h
-um/arch/um/include/time_user.h
-um/arch/um/include/tlb.h
-um/arch/um/include/ubd_user.h
-um/arch/um/include/um_mmu.h
-um/arch/um/include/um_uaccess.h
-um/arch/um/include/umid.h
-um/arch/um/include/uml_uaccess.h
-um/arch/um/include/umn.h
-um/arch/um/include/user.h
-um/arch/um/include/user_util.h
-um/arch/um/kernel/Makefile
-um/arch/um/kernel/checksum.c
-um/arch/um/kernel/config.c.in
-um/arch/um/kernel/exec_kern.c
-um/arch/um/kernel/exitcode.c
-um/arch/um/kernel/frame.c
-um/arch/um/kernel/frame_kern.c
-um/arch/um/kernel/gmon_syms.c
-um/arch/um/kernel/gprof_syms.c
-um/arch/um/kernel/helper.c
-um/arch/um/kernel/init_task.c
-um/arch/um/kernel/initrd_kern.c
-um/arch/um/kernel/initrd_user.c
-um/arch/um/kernel/irq.c
-um/arch/um/kernel/irq_user.c
-um/arch/um/kernel/ksyms.c
-um/arch/um/kernel/mem.c
-um/arch/um/kernel/mem_user.c
-um/arch/um/kernel/mprot.h
-um/arch/um/kernel/process.c
-um/arch/um/kernel/process_kern.c
-um/arch/um/kernel/ptrace.c
-um/arch/um/kernel/reboot.c
-um/arch/um/kernel/resource.c
-um/arch/um/kernel/sigio_kern.c
-um/arch/um/kernel/sigio_user.c
-um/arch/um/kernel/signal_kern.c
-um/arch/um/kernel/signal_user.c
-um/arch/um/kernel/skas/Makefile
-um/arch/um/kernel/skas/exec_kern.c
-um/arch/um/kernel/skas/exec_user.c
-um/arch/um/kernel/skas/include/mmu.h
-um/arch/um/kernel/skas/include/mode.h
-um/arch/um/kernel/skas/include/mode_kern.h
-um/arch/um/kernel/skas/include/proc_mm.h
-um/arch/um/kernel/skas/include/ptrace-skas.h
-um/arch/um/kernel/skas/include/skas.h
-um/arch/um/kernel/skas/include/uaccess.h
-um/arch/um/kernel/skas/mem.c
-um/arch/um/kernel/skas/mem_user.c
-um/arch/um/kernel/skas/mmu.c
-um/arch/um/kernel/skas/process.c
-um/arch/um/kernel/skas/process_kern.c
-um/arch/um/kernel/skas/sys-i386/Makefile
-um/arch/um/kernel/skas/sys-i386/sigcontext.c
-um/arch/um/kernel/skas/syscall_kern.c
-um/arch/um/kernel/skas/syscall_user.c
-um/arch/um/kernel/skas/time.c
-um/arch/um/kernel/skas/tlb.c
-um/arch/um/kernel/skas/trap_user.c
-um/arch/um/kernel/skas/util/Makefile
-um/arch/um/kernel/skas/util/mk_ptregs.c
-um/arch/um/kernel/smp.c
-um/arch/um/kernel/sys_call_table.c
-um/arch/um/kernel/syscall_kern.c
-um/arch/um/kernel/syscall_user.c
-um/arch/um/kernel/sysrq.c
-um/arch/um/kernel/tempfile.c
-um/arch/um/kernel/time.c
-um/arch/um/kernel/time_kern.c
-um/arch/um/kernel/tlb.c
-um/arch/um/kernel/trap_kern.c
-um/arch/um/kernel/trap_user.c
-um/arch/um/kernel/tt/Makefile
-um/arch/um/kernel/tt/exec_kern.c
-um/arch/um/kernel/tt/exec_user.c
-um/arch/um/kernel/tt/gdb.c
-um/arch/um/kernel/tt/gdb_kern.c
-um/arch/um/kernel/tt/include/debug.h
-um/arch/um/kernel/tt/include/mmu.h
-um/arch/um/kernel/tt/include/mode.h
-um/arch/um/kernel/tt/include/mode_kern.h
-um/arch/um/kernel/tt/include/ptrace-tt.h
-um/arch/um/kernel/tt/include/tt.h
-um/arch/um/kernel/tt/include/uaccess.h
-um/arch/um/kernel/tt/ksyms.c
-um/arch/um/kernel/tt/mem.c
-um/arch/um/kernel/tt/mem_user.c
-um/arch/um/kernel/tt/process_kern.c
-um/arch/um/kernel/tt/ptproxy/Makefile
-um/arch/um/kernel/tt/ptproxy/proxy.c
-um/arch/um/kernel/tt/ptproxy/ptproxy.h
-um/arch/um/kernel/tt/ptproxy/ptrace.c
-um/arch/um/kernel/tt/ptproxy/sysdep.c
-um/arch/um/kernel/tt/ptproxy/sysdep.h
-um/arch/um/kernel/tt/ptproxy/wait.c
-um/arch/um/kernel/tt/ptproxy/wait.h
-um/arch/um/kernel/tt/sys-i386/Makefile
-um/arch/um/kernel/tt/sys-i386/sigcontext.c
-um/arch/um/kernel/tt/syscall_kern.c
-um/arch/um/kernel/tt/syscall_user.c
-um/arch/um/kernel/tt/time.c
-um/arch/um/kernel/tt/tlb.c
-um/arch/um/kernel/tt/tracer.c
-um/arch/um/kernel/tt/trap_user.c
-um/arch/um/kernel/tt/uaccess_user.c
-um/arch/um/kernel/tt/unmap.c
-um/arch/um/kernel/tty_log.c
-um/arch/um/kernel/uaccess_user.c
-um/arch/um/kernel/um_arch.c
-um/arch/um/kernel/umid.c
-um/arch/um/kernel/user_syms.c
-um/arch/um/kernel/user_util.c
-um/arch/um/link.ld.in
-um/arch/um/main.c
-um/arch/um/os-Linux/Makefile
-um/arch/um/os-Linux/drivers/Makefile
-um/arch/um/os-Linux/drivers/etap.h
-um/arch/um/os-Linux/drivers/ethertap_kern.c
-um/arch/um/os-Linux/drivers/ethertap_user.c
-um/arch/um/os-Linux/drivers/tuntap.h
-um/arch/um/os-Linux/drivers/tuntap_kern.c
-um/arch/um/os-Linux/drivers/tuntap_user.c
-um/arch/um/os-Linux/file.c
-um/arch/um/os-Linux/include/file.h
-um/arch/um/os-Linux/process.c
-um/arch/um/os-Linux/tty.c
-um/arch/um/sys-i386/Makefile
-um/arch/um/sys-i386/bugs.c
-um/arch/um/sys-i386/checksum.S
-um/arch/um/sys-i386/fault.c
-um/arch/um/sys-i386/ksyms.c
-um/arch/um/sys-i386/ldt.c
-um/arch/um/sys-i386/ptrace.c
-um/arch/um/sys-i386/ptrace_user.c
-um/arch/um/sys-i386/sigcontext.c
-um/arch/um/sys-i386/syscalls.c
-um/arch/um/sys-i386/sysrq.c
-um/arch/um/sys-i386/util/Makefile
-um/arch/um/sys-i386/util/mk_sc.c
-um/arch/um/sys-i386/util/mk_thread_kern.c
-um/arch/um/sys-i386/util/mk_thread_user.c
-um/arch/um/sys-ia64/Makefile
-um/arch/um/sys-ppc/Makefile
-um/arch/um/sys-ppc/misc.S
-um/arch/um/sys-ppc/miscthings.c
-um/arch/um/sys-ppc/ptrace.c
-um/arch/um/sys-ppc/ptrace_user.c
-um/arch/um/sys-ppc/sigcontext.c
-um/arch/um/sys-ppc/sysrq.c
-um/arch/um/util/Makefile
-um/arch/um/util/mk_constants_kern.c
-um/arch/um/util/mk_constants_user.c
-um/arch/um/util/mk_task_kern.c
-um/arch/um/util/mk_task_user.c
-um/drivers/char/Makefile
-um/drivers/char/tty_io.c
-um/drivers/net/setup.c
-um/include/asm-i386/hardirq.h
-um/include/asm-um/a.out.h
-um/include/asm-um/arch-signal-i386.h
-um/include/asm-um/archparam-i386.h
-um/include/asm-um/archparam-ppc.h
-um/include/asm-um/atomic.h
-um/include/asm-um/bitops.h
-um/include/asm-um/boot.h
-um/include/asm-um/bugs.h
-um/include/asm-um/byteorder.h
-um/include/asm-um/cache.h
-um/include/asm-um/checksum.h
-um/include/asm-um/cobalt.h
-um/include/asm-um/current.h
-um/include/asm-um/delay.h
-um/include/asm-um/desc.h
-um/include/asm-um/div64.h
-um/include/asm-um/dma.h
-um/include/asm-um/elf.h
-um/include/asm-um/errno.h
-um/include/asm-um/fcntl.h
-um/include/asm-um/fixmap.h
-um/include/asm-um/floppy.h
-um/include/asm-um/hardirq.h
-um/include/asm-um/hdreg.h
-um/include/asm-um/highmem.h
-um/include/asm-um/hw_irq.h
-um/include/asm-um/ide.h
-um/include/asm-um/init.h
-um/include/asm-um/io.h
-um/include/asm-um/ioctl.h
-um/include/asm-um/ioctls.h
-um/include/asm-um/ipc.h
-um/include/asm-um/ipcbuf.h
-um/include/asm-um/irq.h
-um/include/asm-um/keyboard.h
-um/include/asm-um/kmap_types.h
-um/include/asm-um/linux_logo.h
-um/include/asm-um/locks.h
-um/include/asm-um/mca_dma.h
-um/include/asm-um/mman.h
-um/include/asm-um/mmu.h
-um/include/asm-um/mmu_context.h
-um/include/asm-um/module.h
-um/include/asm-um/msgbuf.h
-um/include/asm-um/mtrr.h
-um/include/asm-um/namei.h
-um/include/asm-um/page.h
-um/include/asm-um/page_offset.h
-um/include/asm-um/param.h
-um/include/asm-um/pci.h
-um/include/asm-um/pgalloc.h
-um/include/asm-um/pgtable.h
-um/include/asm-um/poll.h
-um/include/asm-um/posix_types.h
-um/include/asm-um/processor-generic.h
-um/include/asm-um/processor-i386.h
-um/include/asm-um/processor-ppc.h
-um/include/asm-um/ptrace-generic.h
-um/include/asm-um/ptrace-i386.h
-um/include/asm-um/resource.h
-um/include/asm-um/rwlock.h
-um/include/asm-um/rwsem.h
-um/include/asm-um/scatterlist.h
-um/include/asm-um/segment.h
-um/include/asm-um/semaphore.h
-um/include/asm-um/sembuf.h
-um/include/asm-um/serial.h
-um/include/asm-um/shmbuf.h
-um/include/asm-um/shmparam.h
-um/include/asm-um/sigcontext-generic.h
-um/include/asm-um/sigcontext-i386.h
-um/include/asm-um/sigcontext-ppc.h
-um/include/asm-um/siginfo.h
-um/include/asm-um/signal.h
-um/include/asm-um/smp.h
-um/include/asm-um/smplock.h
-um/include/asm-um/socket.h
-um/include/asm-um/sockios.h
-um/include/asm-um/softirq.h
-um/include/asm-um/spinlock.h
-um/include/asm-um/stat.h
-um/include/asm-um/statfs.h
-um/include/asm-um/string.h
-um/include/asm-um/system-generic.h
-um/include/asm-um/system-i386.h
-um/include/asm-um/system-ppc.h
-um/include/asm-um/termbits.h
-um/include/asm-um/termios.h
-um/include/asm-um/timex.h
-um/include/asm-um/tlb.h
-um/include/asm-um/types.h
-um/include/asm-um/uaccess.h
-um/include/asm-um/ucontext.h
-um/include/asm-um/unaligned.h
-um/include/asm-um/unistd.h
-um/include/asm-um/user.h
-um/include/asm-um/vga.h
-um/include/asm-um/xor.h
-um/include/linux/blk.h
-um/include/linux/fs.h
-um/include/linux/hostfs_fs_i.h
-um/include/linux/hppfs_fs_i.h
-um/include/linux/kernel.h
-um/include/linux/kernel_stat.h
-um/include/linux/mm.h
-um/include/linux/proc_mm.h
-um/include/linux/tty.h
-um/init/do_mounts.c
-um/kernel/panic.c
-um/mm/Makefile
-um/mm/mmap.c
-um/mm/mprotect.c
-um/mm/proc_mm.c
-um/mm/slab.c
-linux/arch/i386/kernel/sys_i386.c
+CREDITS
+Documentation/Configure.help
+MAINTAINERS
+Makefile
+arch/um/Makefile
+arch/um/Makefile-i386
+arch/um/Makefile-ia64
+arch/um/Makefile-os-Linux
+arch/um/Makefile-ppc
+arch/um/Makefile-skas
+arch/um/Makefile-tt
+arch/um/common.ld.in
+arch/um/config.in
+arch/um/config.release
+arch/um/config_block.in
+arch/um/config_char.in
+arch/um/config_net.in
+arch/um/config_scsi.in
+arch/um/defconfig
+arch/um/drivers/Makefile
+arch/um/drivers/chan_kern.c
+arch/um/drivers/chan_user.c
+arch/um/drivers/daemon.h
+arch/um/drivers/daemon_kern.c
+arch/um/drivers/daemon_user.c
+arch/um/drivers/fd.c
+arch/um/drivers/harddog_kern.c
+arch/um/drivers/harddog_user.c
+arch/um/drivers/hostaudio_kern.c
+arch/um/drivers/hostaudio_user.c
+arch/um/drivers/line.c
+arch/um/drivers/mcast.h
+arch/um/drivers/mcast_kern.c
+arch/um/drivers/mcast_user.c
+arch/um/drivers/mconsole_kern.c
+arch/um/drivers/mconsole_user.c
+arch/um/drivers/mmapper_kern.c
+arch/um/drivers/net_kern.c
+arch/um/drivers/net_user.c
+arch/um/drivers/null.c
+arch/um/drivers/pcap_kern.c
+arch/um/drivers/pcap_user.c
+arch/um/drivers/pcap_user.h
+arch/um/drivers/port.h
+arch/um/drivers/port_kern.c
+arch/um/drivers/port_user.c
+arch/um/drivers/pty.c
+arch/um/drivers/slip.h
+arch/um/drivers/slip_kern.c
+arch/um/drivers/slip_proto.h
+arch/um/drivers/slip_user.c
+arch/um/drivers/slirp.h
+arch/um/drivers/slirp_kern.c
+arch/um/drivers/slirp_user.c
+arch/um/drivers/ssl.c
+arch/um/drivers/ssl.h
+arch/um/drivers/stdio_console.c
+arch/um/drivers/stdio_console.h
+arch/um/drivers/tty.c
+arch/um/drivers/ubd_kern.c
+arch/um/drivers/ubd_user.c
+arch/um/drivers/xterm.c
+arch/um/drivers/xterm.h
+arch/um/drivers/xterm_kern.c
+arch/um/dyn_link.ld.in
+arch/um/fs/Makefile
+arch/um/fs/hostfs/Makefile
+arch/um/fs/hostfs/hostfs.h
+arch/um/fs/hostfs/hostfs_kern.c
+arch/um/fs/hostfs/hostfs_user.c
+arch/um/fs/hppfs/Makefile
+arch/um/fs/hppfs/hppfs_kern.c
+arch/um/include/2_5compat.h
+arch/um/include/Makefile
+arch/um/include/chan_kern.h
+arch/um/include/chan_user.h
+arch/um/include/choose-mode.h
+arch/um/include/frame.h
+arch/um/include/frame_kern.h
+arch/um/include/frame_user.h
+arch/um/include/helper.h
+arch/um/include/hostaudio.h
+arch/um/include/init.h
+arch/um/include/initrd.h
+arch/um/include/irq_user.h
+arch/um/include/kern.h
+arch/um/include/kern_util.h
+arch/um/include/line.h
+arch/um/include/mconsole.h
+arch/um/include/mconsole_kern.h
+arch/um/include/mem.h
+arch/um/include/mem_user.h
+arch/um/include/mode.h
+arch/um/include/mode_kern.h
+arch/um/include/net_kern.h
+arch/um/include/net_user.h
+arch/um/include/os.h
+arch/um/include/process.h
+arch/um/include/ptrace_user.h
+arch/um/include/sigcontext.h
+arch/um/include/sigio.h
+arch/um/include/signal_kern.h
+arch/um/include/signal_user.h
+arch/um/include/skas_ptrace.h
+arch/um/include/syscall_user.h
+arch/um/include/sysdep-i386/checksum.h
+arch/um/include/sysdep-i386/frame.h
+arch/um/include/sysdep-i386/frame_kern.h
+arch/um/include/sysdep-i386/frame_user.h
+arch/um/include/sysdep-i386/ptrace.h
+arch/um/include/sysdep-i386/ptrace_user.h
+arch/um/include/sysdep-i386/sigcontext.h
+arch/um/include/sysdep-i386/syscalls.h
+arch/um/include/sysdep-ia64/ptrace.h
+arch/um/include/sysdep-ia64/sigcontext.h
+arch/um/include/sysdep-ia64/syscalls.h
+arch/um/include/sysdep-ppc/ptrace.h
+arch/um/include/sysdep-ppc/sigcontext.h
+arch/um/include/sysdep-ppc/syscalls.h
+arch/um/include/sysrq.h
+arch/um/include/tempfile.h
+arch/um/include/time_user.h
+arch/um/include/tlb.h
+arch/um/include/ubd_user.h
+arch/um/include/um_mmu.h
+arch/um/include/um_uaccess.h
+arch/um/include/umid.h
+arch/um/include/uml_uaccess.h
+arch/um/include/umn.h
+arch/um/include/user.h
+arch/um/include/user_util.h
+arch/um/kernel/Makefile
+arch/um/kernel/checksum.c
+arch/um/kernel/config.c.in
+arch/um/kernel/exec_kern.c
+arch/um/kernel/exitcode.c
+arch/um/kernel/frame.c
+arch/um/kernel/frame_kern.c
+arch/um/kernel/gmon_syms.c
+arch/um/kernel/gprof_syms.c
+arch/um/kernel/helper.c
+arch/um/kernel/init_task.c
+arch/um/kernel/initrd_kern.c
+arch/um/kernel/initrd_user.c
+arch/um/kernel/irq.c
+arch/um/kernel/irq_user.c
+arch/um/kernel/ksyms.c
+arch/um/kernel/mem.c
+arch/um/kernel/mem_user.c
+arch/um/kernel/mprot.h
+arch/um/kernel/process.c
+arch/um/kernel/process_kern.c
+arch/um/kernel/ptrace.c
+arch/um/kernel/reboot.c
+arch/um/kernel/resource.c
+arch/um/kernel/sigio_kern.c
+arch/um/kernel/sigio_user.c
+arch/um/kernel/signal_kern.c
+arch/um/kernel/signal_user.c
+arch/um/kernel/skas/Makefile
+arch/um/kernel/skas/exec_kern.c
+arch/um/kernel/skas/exec_user.c
+arch/um/kernel/skas/include/mmu.h
+arch/um/kernel/skas/include/mode.h
+arch/um/kernel/skas/include/mode_kern.h
+arch/um/kernel/skas/include/proc_mm.h
+arch/um/kernel/skas/include/ptrace-skas.h
+arch/um/kernel/skas/include/skas.h
+arch/um/kernel/skas/include/uaccess.h
+arch/um/kernel/skas/mem.c
+arch/um/kernel/skas/mem_user.c
+arch/um/kernel/skas/mmu.c
+arch/um/kernel/skas/process.c
+arch/um/kernel/skas/process_kern.c
+arch/um/kernel/skas/sys-i386/Makefile
+arch/um/kernel/skas/sys-i386/sigcontext.c
+arch/um/kernel/skas/syscall_kern.c
+arch/um/kernel/skas/syscall_user.c
+arch/um/kernel/skas/time.c
+arch/um/kernel/skas/tlb.c
+arch/um/kernel/skas/trap_user.c
+arch/um/kernel/skas/util/Makefile
+arch/um/kernel/skas/util/mk_ptregs.c
+arch/um/kernel/smp.c
+arch/um/kernel/sys_call_table.c
+arch/um/kernel/syscall_kern.c
+arch/um/kernel/syscall_user.c
+arch/um/kernel/sysrq.c
+arch/um/kernel/tempfile.c
+arch/um/kernel/time.c
+arch/um/kernel/time_kern.c
+arch/um/kernel/tlb.c
+arch/um/kernel/trap_kern.c
+arch/um/kernel/trap_user.c
+arch/um/kernel/tt/Makefile
+arch/um/kernel/tt/exec_kern.c
+arch/um/kernel/tt/exec_user.c
+arch/um/kernel/tt/gdb.c
+arch/um/kernel/tt/gdb_kern.c
+arch/um/kernel/tt/include/debug.h
+arch/um/kernel/tt/include/mmu.h
+arch/um/kernel/tt/include/mode.h
+arch/um/kernel/tt/include/mode_kern.h
+arch/um/kernel/tt/include/ptrace-tt.h
+arch/um/kernel/tt/include/tt.h
+arch/um/kernel/tt/include/uaccess.h
+arch/um/kernel/tt/ksyms.c
+arch/um/kernel/tt/mem.c
+arch/um/kernel/tt/mem_user.c
+arch/um/kernel/tt/process_kern.c
+arch/um/kernel/tt/ptproxy/Makefile
+arch/um/kernel/tt/ptproxy/proxy.c
+arch/um/kernel/tt/ptproxy/ptproxy.h
+arch/um/kernel/tt/ptproxy/ptrace.c
+arch/um/kernel/tt/ptproxy/sysdep.c
+arch/um/kernel/tt/ptproxy/sysdep.h
+arch/um/kernel/tt/ptproxy/wait.c
+arch/um/kernel/tt/ptproxy/wait.h
+arch/um/kernel/tt/sys-i386/Makefile
+arch/um/kernel/tt/sys-i386/sigcontext.c
+arch/um/kernel/tt/syscall_kern.c
+arch/um/kernel/tt/syscall_user.c
+arch/um/kernel/tt/time.c
+arch/um/kernel/tt/tlb.c
+arch/um/kernel/tt/tracer.c
+arch/um/kernel/tt/trap_user.c
+arch/um/kernel/tt/uaccess_user.c
+arch/um/kernel/tt/unmap.c
+arch/um/kernel/tty_log.c
+arch/um/kernel/uaccess_user.c
+arch/um/kernel/um_arch.c
+arch/um/kernel/umid.c
+arch/um/kernel/user_syms.c
+arch/um/kernel/user_util.c
+arch/um/link.ld.in
+arch/um/main.c
+arch/um/os-Linux/Makefile
+arch/um/os-Linux/drivers/Makefile
+arch/um/os-Linux/drivers/etap.h
+arch/um/os-Linux/drivers/ethertap_kern.c
+arch/um/os-Linux/drivers/ethertap_user.c
+arch/um/os-Linux/drivers/tuntap.h
+arch/um/os-Linux/drivers/tuntap_kern.c
+arch/um/os-Linux/drivers/tuntap_user.c
+arch/um/os-Linux/file.c
+arch/um/os-Linux/include/file.h
+arch/um/os-Linux/process.c
+arch/um/os-Linux/tty.c
+arch/um/sys-i386/Makefile
+arch/um/sys-i386/bugs.c
+arch/um/sys-i386/checksum.S
+arch/um/sys-i386/fault.c
+arch/um/sys-i386/ksyms.c
+arch/um/sys-i386/ldt.c
+arch/um/sys-i386/ptrace.c
+arch/um/sys-i386/ptrace_user.c
+arch/um/sys-i386/sigcontext.c
+arch/um/sys-i386/syscalls.c
+arch/um/sys-i386/sysrq.c
+arch/um/sys-i386/util/Makefile
+arch/um/sys-i386/util/mk_sc.c
+arch/um/sys-i386/util/mk_thread_kern.c
+arch/um/sys-i386/util/mk_thread_user.c
+arch/um/sys-ia64/Makefile
+arch/um/sys-ppc/Makefile
+arch/um/sys-ppc/misc.S
+arch/um/sys-ppc/miscthings.c
+arch/um/sys-ppc/ptrace.c
+arch/um/sys-ppc/ptrace_user.c
+arch/um/sys-ppc/sigcontext.c
+arch/um/sys-ppc/sysrq.c
+arch/um/util/Makefile
+arch/um/util/mk_constants_kern.c
+arch/um/util/mk_constants_user.c
+arch/um/util/mk_task_kern.c
+arch/um/util/mk_task_user.c
+drivers/char/Makefile
+drivers/char/tty_io.c
+drivers/net/setup.c
+include/asm-i386/hardirq.h
+include/asm-um/a.out.h
+include/asm-um/arch-signal-i386.h
+include/asm-um/archparam-i386.h
+include/asm-um/archparam-ppc.h
+include/asm-um/atomic.h
+include/asm-um/bitops.h
+include/asm-um/boot.h
+include/asm-um/bugs.h
+include/asm-um/byteorder.h
+include/asm-um/cache.h
+include/asm-um/checksum.h
+include/asm-um/cobalt.h
+include/asm-um/current.h
+include/asm-um/delay.h
+include/asm-um/desc.h
+include/asm-um/div64.h
+include/asm-um/dma.h
+include/asm-um/elf.h
+include/asm-um/errno.h
+include/asm-um/fcntl.h
+include/asm-um/fixmap.h
+include/asm-um/floppy.h
+include/asm-um/hardirq.h
+include/asm-um/hdreg.h
+include/asm-um/highmem.h
+include/asm-um/hw_irq.h
+include/asm-um/ide.h
+include/asm-um/init.h
+include/asm-um/io.h
+include/asm-um/ioctl.h
+include/asm-um/ioctls.h
+include/asm-um/ipc.h
+include/asm-um/ipcbuf.h
+include/asm-um/irq.h
+include/asm-um/keyboard.h
+include/asm-um/kmap_types.h
+include/asm-um/linux_logo.h
+include/asm-um/locks.h
+include/asm-um/mca_dma.h
+include/asm-um/mman.h
+include/asm-um/mmu.h
+include/asm-um/mmu_context.h
+include/asm-um/module.h
+include/asm-um/msgbuf.h
+include/asm-um/mtrr.h
+include/asm-um/namei.h
+include/asm-um/page.h
+include/asm-um/page_offset.h
+include/asm-um/param.h
+include/asm-um/pci.h
+include/asm-um/pgalloc.h
+include/asm-um/pgtable.h
+include/asm-um/poll.h
+include/asm-um/posix_types.h
+include/asm-um/processor-generic.h
+include/asm-um/processor-i386.h
+include/asm-um/processor-ppc.h
+include/asm-um/ptrace-generic.h
+include/asm-um/ptrace-i386.h
+include/asm-um/resource.h
+include/asm-um/rwlock.h
+include/asm-um/rwsem.h
+include/asm-um/scatterlist.h
+include/asm-um/segment.h
+include/asm-um/semaphore.h
+include/asm-um/sembuf.h
+include/asm-um/serial.h
+include/asm-um/shmbuf.h
+include/asm-um/shmparam.h
+include/asm-um/sigcontext-generic.h
+include/asm-um/sigcontext-i386.h
+include/asm-um/sigcontext-ppc.h
+include/asm-um/siginfo.h
+include/asm-um/signal.h
+include/asm-um/smp.h
+include/asm-um/smplock.h
+include/asm-um/socket.h
+include/asm-um/sockios.h
+include/asm-um/softirq.h
+include/asm-um/spinlock.h
+include/asm-um/stat.h
+include/asm-um/statfs.h
+include/asm-um/string.h
+include/asm-um/system-generic.h
+include/asm-um/system-i386.h
+include/asm-um/system-ppc.h
+include/asm-um/termbits.h
+include/asm-um/termios.h
+include/asm-um/timex.h
+include/asm-um/tlb.h
+include/asm-um/types.h
+include/asm-um/uaccess.h
+include/asm-um/ucontext.h
+include/asm-um/unaligned.h
+include/asm-um/unistd.h
+include/asm-um/user.h
+include/asm-um/vga.h
+include/asm-um/xor.h
+include/linux/blk.h
+include/linux/fs.h
+include/linux/hostfs_fs_i.h
+include/linux/hppfs_fs_i.h
+include/linux/kernel.h
+include/linux/kernel_stat.h
+include/linux/mm.h
+include/linux/proc_mm.h
+include/linux/tty.h
+init/do_mounts.c
+kernel/panic.c
+mm/Makefile
+mm/mmap.c
+mm/mprotect.c
+mm/proc_mm.c
+mm/slab.c
diff --git a/lustre/tests/fchdir_test.c b/lustre/tests/fchdir_test.c
new file mode 100644 (file)
index 0000000..83c096e
--- /dev/null
@@ -0,0 +1,41 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+
+int main(int argc, char **argv)
+{
+        int fd;
+        int rc;
+
+        fd = open(".", O_RDONLY);
+        if (fd < 0) {
+                perror("opening '.' :");
+                exit(2);
+        }
+
+        rc = chdir("/mnt/lustre/subdir/subdir");
+        if (rc) { 
+                perror("cannot chdir subdir:");
+                exit(3);
+        }
+
+        rc = fchdir(fd);
+        if (rc) { 
+                perror("cannot fchdir back\n");
+                exit(4);
+        }
+
+        rc = close(fd);
+        if (rc) { 
+                perror("cannot close '.'\n");
+                exit(5);
+        }
+
+        return(0);
+}