#
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.12.2
-# Wed Jul 13 17:05:01 2005
+# Thu Aug  4 14:53:44 2005
 #
 CONFIG_X86=y
 CONFIG_MMU=y
 CONFIG_USB_EGALAX=m
 CONFIG_USB_XPAD=m
 CONFIG_USB_ATI_REMOTE=m
+# CONFIG_USB_APPLETOUCH is not set
 
 #
 # USB Imaging devices
 
 
 CONFIG_DETECT_SOFTLOCKUP=y
 
+# CONFIG_USB_APPLETOUCH is not set
+
 CONFIG_UID16=y
 CONFIG_X86_PC=y
 # CONFIG_X86_ELAN is not set
 
 W:     http://linux-atm.sourceforge.net
 S:     Maintained
 
-AUDIT SUBSYSTEM
-P:     David Woodhouse
-M:     dwmw2@infradead.org
-L:     linux-audit@redhat.com
-W:     http://people.redhat.com/sgrubb/audit/
-S:     Maintained
-
 ATMEL WIRELESS DRIVER
 P:     Simon Kelley
 M:     simon@thekelleys.org.uk
 W:     http://atmelwlandriver.sourceforge.net/
 S:     Maintained
 
+AUDIT SUBSYSTEM
+L:     linux-audit@redhat.com (subscribers-only)
+P:     David Woodhouse
+M:     dwmw2@infradead.org
+L:     linux-audit@redhat.com
+W:     http://people.redhat.com/sgrubb/audit/
+S:     Maintained
+
 AX.25 NETWORK LAYER
 P:     Ralf Baechle
 M:     ralf@linux-mips.org
 
 
 extern unsigned long wall_jiffies;
 
+/* used for timezone offset */
+static long timezone_offset;
+
 DEFINE_SPINLOCK(rtc_lock);
 
 EXPORT_SYMBOL(rtc_lock);
                     xtime.tv_sec - last_rtc_update >= 659 &&
                     abs((xtime.tv_nsec / 1000) - (1000000-1000000/HZ)) < 500000/HZ &&
                     jiffies - wall_jiffies == 1) {
-                       if (ppc_md.set_rtc_time(xtime.tv_sec+1 + time_offset) == 0)
+                       if (ppc_md.set_rtc_time(xtime.tv_sec+1 + timezone_offset) == 0)
                                last_rtc_update = xtime.tv_sec+1;
                        else
                                /* Try again one minute later */
        unsigned old_stamp, stamp, elapsed;
 
         if (ppc_md.time_init != NULL)
-                time_offset = ppc_md.time_init();
+                timezone_offset = ppc_md.time_init();
 
        if (__USE_RTC()) {
                /* 601 processor: dec counts down by 128 every 128ns */
        set_dec(tb_ticks_per_jiffy);
 
        /* If platform provided a timezone (pmac), we correct the time */
-        if (time_offset) {
-               sys_tz.tz_minuteswest = -time_offset / 60;
+        if (timezone_offset) {
+               sys_tz.tz_minuteswest = -timezone_offset / 60;
                sys_tz.tz_dsttime = 0;
-               xtime.tv_sec -= time_offset;
+               xtime.tv_sec -= timezone_offset;
         }
         set_normalized_timespec(&wall_to_monotonic,
                                 -xtime.tv_sec, -xtime.tv_nsec);
 
        return(arg.pid);
 }
 
-static int ptrace_child(void)
+static int ptrace_child(void *arg)
 {
        int ret;
        int pid = os_getpid(), ppid = getppid();
        _exit(ret);
 }
 
-static int start_ptraced_child(void)
+static int start_ptraced_child(void **stack_out)
 {
+       void *stack;
+       unsigned long sp;
        int pid, n, status;
        
-       pid = fork();
-       if(pid == 0)
-               ptrace_child();
-
+       stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
+                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+       if(stack == MAP_FAILED)
+               panic("check_ptrace : mmap failed, errno = %d", errno);
+       sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
+       pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
        if(pid < 0)
-               panic("check_ptrace : fork failed, errno = %d", errno);
+               panic("check_ptrace : clone failed, errno = %d", errno);
        CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
        if(n < 0)
                panic("check_ptrace : wait failed, errno = %d", errno);
                panic("check_ptrace : expected SIGSTOP, got status = %d",
                      status);
 
+       *stack_out = stack;
        return(pid);
 }
 
  * just avoid using sysemu, not panic, but only if SYSEMU features are broken.
  * So only for SYSEMU features we test mustpanic, while normal host features
  * must work anyway!*/
-static int stop_ptraced_child(int pid, int exitcode, int mustexit)
+static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic)
 {
        int status, n, ret = 0;
 
        if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
-               panic("stop_ptraced_child : ptrace failed, errno = %d", errno);
+               panic("check_ptrace : ptrace failed, errno = %d", errno);
        CATCH_EINTR(n = waitpid(pid, &status, 0));
        if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
                int exit_with = WEXITSTATUS(status);
                printk("check_ptrace : child exited with exitcode %d, while "
                      "expecting %d; status 0x%x", exit_with,
                      exitcode, status);
-               if (mustexit)
+               if (mustpanic)
                        panic("\n");
                else
                        printk("\n");
                ret = -1;
        }
 
+       if(munmap(stack, PAGE_SIZE) < 0)
+               panic("check_ptrace : munmap failed, errno = %d", errno);
        return ret;
 }
 
 
 static void __init check_sysemu(void)
 {
+       void *stack;
        int pid, syscall, n, status, count=0;
 
        printk("Checking syscall emulation patch for ptrace...");
        sysemu_supported = 0;
-       pid = start_ptraced_child();
+       pid = start_ptraced_child(&stack);
 
        if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0)
                goto fail;
                panic("check_sysemu : failed to modify system "
                      "call return, errno = %d", errno);
 
-       if (stop_ptraced_child(pid, 0, 0) < 0)
+       if (stop_ptraced_child(pid, stack, 0, 0) < 0)
                goto fail_stopped;
 
        sysemu_supported = 1;
        set_using_sysemu(!force_sysemu_disabled);
 
        printk("Checking advanced syscall emulation patch for ptrace...");
-       pid = start_ptraced_child();
+       pid = start_ptraced_child(&stack);
        while(1){
                count++;
                if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0)
                        break;
                }
        }
-       if (stop_ptraced_child(pid, 0, 0) < 0)
+       if (stop_ptraced_child(pid, stack, 0, 0) < 0)
                goto fail_stopped;
 
        sysemu_supported = 2;
        return;
 
 fail:
-       stop_ptraced_child(pid, 1, 0);
+       stop_ptraced_child(pid, stack, 1, 0);
 fail_stopped:
        printk("missing\n");
 }
 
 void __init check_ptrace(void)
 {
+       void *stack;
        int pid, syscall, n, status;
 
        printk("Checking that ptrace can change system call numbers...");
-       pid = start_ptraced_child();
+       pid = start_ptraced_child(&stack);
 
        if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
                panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno);
                        break;
                }
        }
-       stop_ptraced_child(pid, 0, 1);
+       stop_ptraced_child(pid, stack, 0, 1);
        printk("OK\n");
        check_sysemu();
 }
 static inline int check_skas3_ptrace_support(void)
 {
        struct ptrace_faultinfo fi;
+       void *stack;
        int pid, n, ret = 1;
 
        printf("Checking for the skas3 patch in the host...");
-       pid = start_ptraced_child();
+       pid = start_ptraced_child(&stack);
 
        n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
        if (n < 0) {
        }
 
        init_registers(pid);
-       stop_ptraced_child(pid, 1, 1);
+       stop_ptraced_child(pid, stack, 1, 1);
 
        return(ret);
 }
 
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.12.2
-# Wed Jul 13 17:04:57 2005
+# Thu Aug  4 14:53:43 2005
 #
 CONFIG_X86=y
 CONFIG_MMU=y
 CONFIG_USB_EGALAX=m
 CONFIG_USB_XPAD=m
 CONFIG_USB_ATI_REMOTE=m
+# CONFIG_USB_APPLETOUCH is not set
 
 #
 # USB Imaging devices
 
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.12.2
-# Wed Jul 13 17:04:58 2005
+# Thu Aug  4 14:53:43 2005
 #
 CONFIG_X86=y
 CONFIG_MMU=y
 CONFIG_USB_EGALAX=m
 CONFIG_USB_XPAD=m
 CONFIG_USB_ATI_REMOTE=m
+# CONFIG_USB_APPLETOUCH is not set
 
 #
 # USB Imaging devices
 
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.12.2
-# Wed Jul 13 17:04:59 2005
+# Thu Aug  4 14:53:44 2005
 #
 CONFIG_XEN=y
 CONFIG_ARCH_XEN=y
 CONFIG_USB_EGALAX=m
 CONFIG_USB_XPAD=m
 CONFIG_USB_ATI_REMOTE=m
+# CONFIG_USB_APPLETOUCH is not set
 
 #
 # USB Imaging devices
 
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.12.2
-# Wed Jul 13 17:05:00 2005
+# Thu Aug  4 14:53:44 2005
 #
 CONFIG_XEN=y
 CONFIG_ARCH_XEN=y
 
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.12.2
-# Wed Jul 13 17:05:01 2005
+# Thu Aug  4 14:53:44 2005
 #
 CONFIG_X86=y
 CONFIG_MMU=y
 CONFIG_USB_EGALAX=m
 CONFIG_USB_XPAD=m
 CONFIG_USB_ATI_REMOTE=m
+# CONFIG_USB_APPLETOUCH is not set
 
 #
 # USB Imaging devices
 
                        ld = tty_ldisc_ref(tty);
                        switch (arg) {
                        case TCIFLUSH:
-                               if (ld->flush_buffer)
+                               if (ld && ld->flush_buffer)
                                        ld->flush_buffer(tty);
                                break;
                        case TCIOFLUSH:
-                               if (ld->flush_buffer)
+                               if (ld && ld->flush_buffer)
                                        ld->flush_buffer(tty);
                                /* fall through */
                        case TCOFLUSH:
 
                        /*
                         * now end failed request
                         */
-                       spin_lock_irqsave(&ide_lock, flags);
                        if(blk_fs_request(failed)) {
-                               if(__ide_end_request(drive, failed, 0, failed->hard_nr_sectors))
+                               if(ide_end_dequeued_request(drive, failed, 0, failed->hard_nr_sectors))
                                        BUG();
                        } else {
+                               spin_lock_irqsave(&ide_lock, flags);
                                end_that_request_chunk(failed, 0, failed->data_len);
                                end_that_request_last(failed);
+                               spin_unlock_irqrestore(&ide_lock, flags);
                        }
-                       spin_unlock_irqrestore(&ide_lock, flags);
                }
                else
                        cdrom_analyze_sense_data(drive, NULL , sense);
 
        return ide_stopped;
 }
 
+/**
+ *     ide_end_dequeued_request        -       complete an IDE I/O
+ *     @drive: IDE device for the I/O
+ *     @uptodate:
+ *     @nr_sectors: number of sectors completed
+ *
+ *     Complete an I/O that is no longer on the request queue. This 
+ *     typically occurs when we pull the request and issue a REQUEST_SENSE.
+ *     We must still finish the old request but we must not tamper with the
+ *     queue in the meantime.
+ *
+ *     NOTE: This path does not handle barrier, but barrier is not supported
+ *     on ide-cd anyway.
+ */
+
+int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq,
+                            int uptodate, int nr_sectors)
+{
+       unsigned long flags;
+       int ret = 1;
+
+       spin_lock_irqsave(&ide_lock, flags);
+
+       BUG_ON(!(rq->flags & REQ_STARTED));
+
+       /*
+        * if failfast is set on a request, override number of sectors and
+        * complete the whole request right now
+        */
+       if (blk_noretry_request(rq) && end_io_error(uptodate))
+               nr_sectors = rq->hard_nr_sectors;
+
+       if (!blk_fs_request(rq) && end_io_error(uptodate) && !rq->errors)
+               rq->errors = -EIO;
+
+       /*
+        * decide whether to reenable DMA -- 3 is a random magic for now,
+        * if we DMA timeout more than 3 times, just stay in PIO
+        */
+       if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) {
+               drive->state = 0;
+               HWGROUP(drive)->hwif->ide_dma_on(drive);
+       }
+
+       if (!end_that_request_first(rq, uptodate, nr_sectors)) {
+               add_disk_randomness(rq->rq_disk);
+               if (blk_rq_tagged(rq))
+                       blk_queue_end_tag(drive->queue, rq);
+               end_that_request_last(rq);
+               ret = 0;
+       }
+       spin_unlock_irqrestore(&ide_lock, flags);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(ide_end_dequeued_request);
+
+
 /**
  *     ide_complete_pm_request - end the current Power Management request
  *     @drive: target drive
 
        }
 }
 
+static spinlock_t tune_lock = SPIN_LOCK_UNLOCKED;
+
 /**
  *     piix_tune_drive         -       tune a drive attached to a PIIX
  *     @drive: drive to tune
                            { 2, 3 }, };
 
        pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
-       spin_lock_irqsave(&ide_lock, flags);
+       
+       /* Master v slave is synchronized above us but the slave register is
+          shared by the two hwifs so the corner case of two slave timeouts in
+          parallel must be locked */
+          
+       spin_lock_irqsave(&tune_lock, flags);
        pci_read_config_word(dev, master_port, &master_data);
        if (is_slave) {
                master_data = master_data | 0x4000;
        pci_write_config_word(dev, master_port, master_data);
        if (is_slave)
                pci_write_config_byte(dev, slave_port, slave_data);
-       spin_unlock_irqrestore(&ide_lock, flags);
+       spin_unlock_irqrestore(&tune_lock, flags);
 }
 
 /**
 
                        .default_value = 0,
                        .type          = V4L2_CTRL_TYPE_INTEGER,
                },
-               .off                   = 0,
+               .off                   = 128,
                .reg                   = MO_HUE,
                .mask                  = 0x00ff,
                .shift                 = 0,
 
 
 config 6PACK
        tristate "Serial port 6PACK driver"
-       depends on AX25 && BROKEN_ON_SMP
+       depends on AX25
        ---help---
          6pack is a transmission protocol for the data exchange between your
          PC and your TNC (the Terminal Node Controller acts as a kind of
 
 {
        struct shaper *shaper = dev->priv;
        struct sk_buff *ptr;
-   
-       if (down_trylock(&shaper->sem))
-               return -1;
 
+       spin_lock(&shaper->lock);
        ptr=shaper->sendq.prev;
        
        /*
                 shaper->stats.collisions++;
        }
        shaper_kick(shaper);
-       up(&shaper->sem);
+       spin_unlock(&shaper->lock);
        return 0;
 }
 
 {
        struct shaper *shaper = (struct shaper *)data;
 
-       if (!down_trylock(&shaper->sem)) {
-               shaper_kick(shaper);
-               up(&shaper->sem);
-       } else
-               mod_timer(&shaper->timer, jiffies);
+       spin_lock(&shaper->lock);
+       shaper_kick(shaper);
+       spin_unlock(&shaper->lock);
 }
 
 /*
 }
 
 
-/*
- *     Flush the shaper queues on a closedown
- */
- 
-static void shaper_flush(struct shaper *shaper)
-{
-       struct sk_buff *skb;
-
-       down(&shaper->sem);
-       while((skb=skb_dequeue(&shaper->sendq))!=NULL)
-               dev_kfree_skb(skb);
-       shaper_kick(shaper);
-       up(&shaper->sem);
-}
-
 /*
  *     Bring the interface up. We just disallow this until a 
  *     bind.
 static int shaper_close(struct net_device *dev)
 {
        struct shaper *shaper=dev->priv;
-       shaper_flush(shaper);
+       struct sk_buff *skb;
+
+       while ((skb = skb_dequeue(&shaper->sendq)) != NULL)
+               dev_kfree_skb(skb);
+
+       spin_lock_bh(&shaper->lock);
+       shaper_kick(shaper);
+       spin_unlock_bh(&shaper->lock);
+
        del_timer_sync(&shaper->timer);
        return 0;
 }
        init_timer(&sh->timer);
        sh->timer.function=shaper_timer;
        sh->timer.data=(unsigned long)sh;
+       spin_lock_init(&sh->lock);
 }
 
 /*
 
          To compile this driver as a module, choose M here: the module will be
          called ati_remote.
 
+config USB_APPLETOUCH
+       tristate "Apple USB Touchpad support"
+       depends on USB && INPUT
+       ---help---
+         Say Y here if you want to use an Apple USB Touchpad.
+
+         These are the touchpads that can be found on post-February 2005
+         Apple Powerbooks (prior models have a Synaptics touchpad connected
+         to the ADB bus).
+
+         This driver provides a basic mouse driver but can be interfaced
+         with the synaptics X11 driver to provide acceleration and
+         scrolling in X11.
+
+         For further information, see
+         <file:Documentation/input/appletouch.txt>.
+
+         To compile this driver as a module, choose M here: the
+         module will be called appletouch.
 
 obj-$(CONFIG_USB_POWERMATE)    += powermate.o
 obj-$(CONFIG_USB_WACOM)                += wacom.o
 obj-$(CONFIG_USB_XPAD)         += xpad.o
+obj-$(CONFIG_USB_APPLETOUCH)   += appletouch.o
 
 
 int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
 {
-       struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
-       struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf;
+       /* Offset into iobuf a little in order to defeat pre-set DMA */
+       struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) (us->iobuf + 4);
+       struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) (us->iobuf + 4);
        unsigned int transfer_length = srb->request_bufflen;
        unsigned int residue;
        int result;
        /* Take care of BULK32 devices; set extra byte to 0 */
        if ( unlikely(us->flags & US_FL_BULK32)) {
                cbwlen = 32;
-               us->iobuf[31] = 0;
+               ((unsigned char *)bcb)[31] = 0;
        }
 
        /* set up the command wrapper */
 
        struct char_device_struct *cd = NULL, **cp;
        int i = major_to_index(major);
 
-       up(&chrdevs_lock);
+       down(&chrdevs_lock);
        for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
                if ((*cp)->major == major &&
                    (*cp)->baseminor == baseminor &&
 
 void
 nfs4_state_shutdown(void)
 {
+       if (!nfs4_init)
+               return;
+
        nfs4_lock_state();
        nfs4_release_reclaim();
        __nfs4_state_shutdown();
 
 #include <linux/seq_file.h>
 #include <linux/pagemap.h>
 #include <linux/init.h>
+#include <linux/string.h>
 
 #include <linux/nfs.h>
 #include <linux/nfsd_idmap.h>
 
 #include <asm/uaccess.h>
 
+int nfsd_port = 2049;
+unsigned int nfsd_portbits = 0;
+unsigned int nfsd_versbits = 0;
+
 /*
  *     We have a single directory with 9 nodes in it.
  */
        NFSD_Fh,
        NFSD_Threads,
        NFSD_Leasetime,
+       NFSD_Ports,
+       NFSD_Versions,
 };
 
 /*
 static ssize_t write_filehandle(struct file *file, char *buf, size_t size);
 static ssize_t write_threads(struct file *file, char *buf, size_t size);
 static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
+static ssize_t write_ports(struct file *file, char *buf, size_t size);
+static ssize_t write_versions(struct file *file, char *buf, size_t size);
 
 static ssize_t (*write_op[])(struct file *, char *, size_t) = {
        [NFSD_Svc] = write_svc,
        [NFSD_Fh] = write_filehandle,
        [NFSD_Threads] = write_threads,
        [NFSD_Leasetime] = write_leasetime,
+       [NFSD_Ports] = write_ports,
+       [NFSD_Versions] = write_versions,
 };
 
 static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
        ino_t ino =  file->f_dentry->d_inode->i_ino;
        char *data;
        ssize_t rv;
-
        if (ino >= sizeof(write_op)/sizeof(write_op[0]) || !write_op[ino])
                return -EINVAL;
 
        data = simple_transaction_get(file, buf, size);
        if (IS_ERR(data))
                return PTR_ERR(data);
-
        rv =  write_op[ino](file, data, size);
        if (rv>0) {
                simple_transaction_set(file, rv);
         * qword quoting is used, so filehandle will be \x....
         */
        char *dname, *path;
-       int maxsize;
+       int maxsize = 0;
        char *mesg = buf;
        int len;
        struct auth_domain *dom;
        sprintf(buf, "%d\n", nfsd_nrthreads());
        return strlen(buf);
 }
+static ssize_t write_ports(struct file *file, char *buf, size_t size)
+{
+       /*
+        * Format:
+        *   family proto address port
+        */
+       char *mesg = buf;
+       char *family, *proto, *addr; 
+       int len, port = 0;
+       ssize_t tlen = 0;
+
+       if (buf[size-1] != '\n')
+               return -EINVAL;
+       buf[size-1] = 0;
+
+       family = mesg;
+       len = qword_get(&mesg, family, size);
+       if (len <= 0) return -EINVAL;
+
+       tlen += len;
+       proto = family+len+1;
+       len = qword_get(&mesg, proto, size);
+       if (len <= 0) return -EINVAL;
+
+       tlen += len;
+       addr = proto+len+1;
+       len = qword_get(&mesg, addr, size);
+       if (len <= 0) return -EINVAL;
+
+       len = get_int(&mesg, &port);
+       if (len)
+               return len;
+
+       tlen += sizeof(port);
+       if (port)
+               nfsd_port = port;
+
+       if (strcmp(proto, "tcp") == 0 || strcmp(proto, "TCP") == 0)
+               NFSCTL_TCPSET(nfsd_portbits);
+       if (strcmp(proto, "udp") == 0 || strcmp(proto, "UDP") == 0)
+               NFSCTL_UDPSET(nfsd_portbits);
+
+       return tlen;
+}
+static ssize_t write_versions(struct file *file, char *buf, size_t size)
+{
+       /*
+        * Format:
+        *   [-/+]vers [-/+]vers ...
+        */
+       char *mesg = buf;
+       char *vers, sign;
+       int len, num;
+       ssize_t tlen = 0;
+
+       if (buf[size-1] != '\n')
+               return -EINVAL;
+       buf[size-1] = 0;
+
+       vers = mesg;
+       len = qword_get(&mesg, vers, size);
+       if (len <= 0) return -EINVAL;
+       do {
+               sign = *vers;
+               if (sign == '+' || sign == '-')
+                       num = simple_strtol((vers+1), NULL, 0);
+               else
+                       num = simple_strtol(vers, NULL, 0);
+               switch(num) {
+               case 2:
+               case 3:
+               case 4:
+                       if (sign != '-')
+                               NFSCTL_VERSET(nfsd_versbits, num);
+                       else
+                               NFSCTL_VERUNSET(nfsd_versbits, num);
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               vers += len + 1;
+               tlen += len;
+       } while ((len = qword_get(&mesg, vers, size)) > 0);
+
+       return tlen;
+}
 
 extern time_t nfs4_leasetime(void);
 
 #ifdef CONFIG_NFSD_V4
                [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
 #endif
+               [NFSD_Ports] = {"ports", &transaction_ops, S_IWUSR|S_IRUSR},
+               [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
                /* last one */ {""}
        };
        return simple_fill_super(sb, 0x6e667364, nfsd_files);
 
 #include <linux/nfsd/nfsd.h>
 #include <linux/nfsd/stats.h>
 #include <linux/nfsd/cache.h>
+#include <linux/nfsd/syscall.h>
 #include <linux/lockd/bind.h>
 
 #define NFSDDBG_FACILITY       NFSDDBG_SVC
 extern struct svc_program      nfsd_program;
 static void                    nfsd(struct svc_rqst *rqstp);
 struct timeval                 nfssvc_boot;
-static struct svc_serv                 *nfsd_serv;
-static atomic_t                        nfsd_busy;
-static unsigned long           nfsd_last_call;
-static DEFINE_SPINLOCK(nfsd_call_lock);
+static struct svc_serv                 *nfsd_serv; static atomic_t                     nfsd_busy; static unsigned long         nfsd_last_call; static DEFINE_SPINLOCK(nfsd_call_lock);
 
 struct nfsd_list {
        struct list_head        list;
 };
 static struct list_head nfsd_list = LIST_HEAD_INIT(nfsd_list);
 
+extern struct svc_version nfsd_version2, nfsd_version3, nfsd_version4;
+
+static struct svc_version *    nfsd_version[] = {
+       [2] = &nfsd_version2,
+#if defined(CONFIG_NFSD_V3)
+       [3] = &nfsd_version3,
+#endif
+#if defined(CONFIG_NFSD_V4)
+       [4] = &nfsd_version4,
+#endif
+};
+
+#define NFSD_MINVERS           2
+#define NFSD_NRVERS            (sizeof(nfsd_version)/sizeof(nfsd_version[0]))
+struct svc_program             nfsd_program = {
+       .pg_prog                = NFS_PROGRAM,          /* program number */
+       .pg_nvers               = NFSD_NRVERS,          /* nr of entries in nfsd_version */
+       .pg_vers                = nfsd_version,         /* version table */
+       .pg_name                = "nfsd",               /* program name */
+       .pg_class               = "nfsd",               /* authentication class */
+       .pg_stats               = &nfsd_svcstats,       /* version table */
+       .pg_authenticate        = &svc_set_client,      /* export authentication */
+
+};
+
 /*
  * Maximum number of nfsd processes
  */
 nfsd_svc(unsigned short port, int nrservs)
 {
        int     error;
-       int     none_left;      
+       int     none_left, found_one, i;
        struct list_head *victim;
        
        lock_kernel();
-       dprintk("nfsd: creating service\n");
+       dprintk("nfsd: creating service: port %d vers 0x%x proto 0x%x\n",
+               nfsd_port, nfsd_versbits, nfsd_portbits);
        error = -EINVAL;
        if (nrservs <= 0)
                nrservs = 0;
        if (nrservs > NFSD_MAXSERVS)
                nrservs = NFSD_MAXSERVS;
        
+       /*
+        * If set, use the nfsd_ctlbits to define which
+        * versions that will be advertised
+        */
+       found_one = 0;
+       if (nfsd_versbits) {
+               for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
+                       if (NFSCTL_VERISSET(nfsd_versbits, i)) {
+                               nfsd_program.pg_vers[i] = nfsd_version[i];
+                               found_one = 1;
+                       } else
+                               nfsd_program.pg_vers[i] = NULL;
+               }
+       }
+       if (!found_one) {
+               for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++)
+                       nfsd_program.pg_vers[i] = nfsd_version[i];
+       }
+
        /* Readahead param cache - will no-op if it already exists */
        error = nfsd_racache_init(2*nrservs);
        if (error<0)
        error = nfs4_state_init();
        if (error<0)
                goto out;
+
        if (!nfsd_serv) {
                atomic_set(&nfsd_busy, 0);
                error = -ENOMEM;
                nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE);
                if (nfsd_serv == NULL)
                        goto out;
-               error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
-               if (error < 0)
-                       goto failure;
-
+               if (!nfsd_portbits || NFSCTL_UDPISSET(nfsd_portbits)) {
+                       error = svc_makesock(nfsd_serv, IPPROTO_UDP, nfsd_port);
+                       if (error < 0)
+                               goto failure;
+               }
 #ifdef CONFIG_NFSD_TCP
-               error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
-               if (error < 0)
-                       goto failure;
+               if (!nfsd_portbits || NFSCTL_TCPISSET(nfsd_portbits)) {
+                   error = svc_makesock(nfsd_serv, IPPROTO_TCP, nfsd_port);
+                   if (error < 0)
+                           goto failure;
+               }
 #endif
                do_gettimeofday(&nfssvc_boot);          /* record boot time */
        } else
        return 1;
 }
 
-extern struct svc_version nfsd_version2, nfsd_version3, nfsd_version4;
-
-static struct svc_version *    nfsd_version[] = {
-       [2] = &nfsd_version2,
-#if defined(CONFIG_NFSD_V3)
-       [3] = &nfsd_version3,
-#endif
-#if defined(CONFIG_NFSD_V4)
-       [4] = &nfsd_version4,
-#endif
-};
-
-#define NFSD_NRVERS            (sizeof(nfsd_version)/sizeof(nfsd_version[0]))
-struct svc_program             nfsd_program = {
-       .pg_prog                = NFS_PROGRAM,          /* program number */
-       .pg_nvers               = NFSD_NRVERS,          /* nr of entries in nfsd_version */
-       .pg_vers                = nfsd_version,         /* version table */
-       .pg_name                = "nfsd",               /* program name */
-       .pg_class               = "nfsd",               /* authentication class */
-       .pg_stats               = &nfsd_svcstats,       /* version table */
-       .pg_authenticate        = &svc_set_client,      /* export authentication */
-
-};
 
 struct audit_buffer;
 struct audit_context;
 struct inode;
+struct netlink_skb_parms;
 
 #define AUDITSC_INVALID 0
 #define AUDITSC_SUCCESS 1
 extern int audit_sockaddr(int len, void *addr);
 extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
 extern void audit_signal_info(int sig, struct task_struct *t);
-extern int audit_filter_user(int pid, int type);
+extern int audit_filter_user(struct netlink_skb_parms *cb, int type);
 #else
 #define audit_alloc(t) ({ 0; })
 #define audit_free(t) do { ; } while (0)
 #define audit_sockaddr(len, addr) ({ 0; })
 #define audit_avc_path(dentry, mnt) ({ 0; })
 #define audit_signal_info(s,t) do { ; } while (0)
-#define audit_filter_user(p,t) ({ 1; })
+#define audit_filter_user(cb,t) ({ 1; })
 #endif
 
 #ifdef CONFIG_AUDIT
 extern void                audit_log_lost(const char *message);
 extern struct semaphore audit_netlink_sem;
 #else
-#define audit_log(c,t,f,...) do { ; } while (0)
-#define audit_log_start(c,t) ({ NULL; })
+#define audit_log(c,g,t,f,...) do { ; } while (0)
+#define audit_log_start(c,g,t) ({ NULL; })
 #define audit_log_vformat(b,f,a) do { ; } while (0)
 #define audit_log_format(b,f,...) do { ; } while (0)
 #define audit_log_end(b) do { ; } while (0)
 
 /*
  * Automatically generated C config: don't edit
  * Linux kernel version: 2.6.12.2
- * Wed Jul 13 17:05:01 2005
+ * Thu Aug  4 14:53:44 2005
  */
 #define AUTOCONF_INCLUDED
 #define CONFIG_X86 1
 #define CONFIG_USB_EGALAX_MODULE 1
 #define CONFIG_USB_XPAD_MODULE 1
 #define CONFIG_USB_ATI_REMOTE_MODULE 1
+#undef CONFIG_USB_APPLETOUCH
 
 /*
  * USB Imaging devices
 
        __u32 shapeclock;
        unsigned long recovery; /* Time we can next clock a packet out on
                                   an empty queue */
-       struct semaphore sem;
+       spinlock_t lock;
         struct net_device_stats stats;
        struct net_device *dev;
        int  (*hard_start_xmit) (struct sk_buff *skb,
 
 #define NFSCTL_GETFD           7       /* get an fh by path (used by mountd) */
 #define        NFSCTL_GETFS            8       /* get an fh by path with max FH len */
 
+/*
+ * Macros used to set version and protocol
+ */
+#define NFSCTL_VERSET(_cltbits, _v)   ((_cltbits) |=  (1 << ((_v) - 1)))
+#define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << ((_v) - 1)))
+#define NFSCTL_VERISSET(_cltbits, _v) ((_cltbits) & (1 << ((_v) - 1)))
+
+#define NFSCTL_UDPSET(_cltbits)       ((_cltbits) |=  (1 << (17 - 1)))
+#define NFSCTL_UDPUNSET(_cltbits)     ((_cltbits) &= ~(1 << (17 - 1)))
+#define NFSCTL_UDPISSET(_cltbits)     ((_cltbits) & (1 << (17 - 1)))
+
+#define NFSCTL_TCPSET(_cltbits)       ((_cltbits) |=  (1 << (18 - 1)))
+#define NFSCTL_TCPUNSET(_cltbits)     ((_cltbits) &= ~(1 << (18 - 1)))
+#define NFSCTL_TCPISSET(_cltbits)     ((_cltbits) & (1 << (18 - 1)))
+
+
 /* SVC */
 struct nfsctl_svc {
        unsigned short          svc_port;
 extern int             exp_export(struct nfsctl_export *nxp);
 extern int             exp_unexport(struct nfsctl_export *nxp);
 
+extern int nfsd_port;
+extern unsigned int nfsd_versbits, nfsd_portbits;
+
 #endif /* __KERNEL__ */
 
 #endif /* NFSD_SYSCALL_H */
 
 
 /* Number of outstanding audit_buffers allowed. */
 static int     audit_backlog_limit = 64;
+static int     audit_backlog_wait_time = 60 * HZ;
+static int     audit_backlog_wait_overflow = 0;
 
 /* The identity of the user shutting down the audit system. */
 uid_t          audit_sig_uid = -1;
                                        audit_pid = 0;
                                }
                        } else {
-                               printk(KERN_ERR "%s\n", skb->data + NLMSG_SPACE(0));
+                               printk(KERN_NOTICE "%s\n", skb->data + NLMSG_SPACE(0));
                                kfree_skb(skb);
                        }
                } else {
                if (!audit_enabled && msg_type != AUDIT_USER_AVC)
                        return 0;
 
-               err = audit_filter_user(pid, msg_type);
+               err = audit_filter_user(&NETLINK_CB(skb), msg_type);
                if (err == 1) {
                        err = 0;
                        ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
 }
 
 static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx,
-                                               int gfp_mask, int type)
+                                               unsigned int __nocast gfp_mask, int type)
 {
        unsigned long flags;
        struct audit_buffer *ab = NULL;
        struct timespec         t;
        unsigned int            serial;
        int reserve;
+       unsigned long timeout_start = jiffies;
 
        if (!audit_initialized)
                return NULL;
 
        while (audit_backlog_limit
               && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) {
-               if (gfp_mask & __GFP_WAIT) {
-                       int ret = 1;
+               if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time
+                   && time_before(jiffies, timeout_start + audit_backlog_wait_time)) {
+
                        /* Wait for auditd to drain the queue a little */
                        DECLARE_WAITQUEUE(wait, current);
                        set_current_state(TASK_INTERRUPTIBLE);
 
                        if (audit_backlog_limit &&
                            skb_queue_len(&audit_skb_queue) > audit_backlog_limit)
-                               ret = schedule_timeout(HZ * 60);
+                               schedule_timeout(timeout_start + audit_backlog_wait_time - jiffies);
 
                        __set_current_state(TASK_RUNNING);
                        remove_wait_queue(&audit_backlog_wait, &wait);
-                       if (ret)
-                               continue;
+                       continue;
                }
                if (audit_rate_check())
                        printk(KERN_WARNING
                               skb_queue_len(&audit_skb_queue),
                               audit_backlog_limit);
                audit_log_lost("backlog limit exceeded");
+               audit_backlog_wait_time = audit_backlog_wait_overflow;
+               wake_up(&audit_backlog_wait);
                return NULL;
        }
 
                        ab->skb = NULL;
                        wake_up_interruptible(&kauditd_wait);
                } else {
-                       printk("%s\n", ab->skb->data + NLMSG_SPACE(0));
+                       printk(KERN_NOTICE "%s\n", ab->skb->data + NLMSG_SPACE(0));
                }
        }
        audit_buffer_free(ab);
 
 #include <linux/personality.h>
 #include <linux/time.h>
 #include <linux/kthread.h>
+#include <linux/netlink.h>
+#include <linux/compiler.h>
 #include <asm/unistd.h>
 
 /* 0 = no checking
        int                word = AUDIT_WORD(ctx->major);
        int                bit  = AUDIT_BIT(ctx->major);
 
-       if (audit_pid && ctx->pid == audit_pid)
+       if (audit_pid && tsk->tgid == audit_pid)
                return AUDIT_DISABLED;
 
        rcu_read_lock();
        return AUDIT_BUILD_CONTEXT;
 }
 
-int audit_filter_user(int pid, int type)
+static int audit_filter_user_rules(struct netlink_skb_parms *cb,
+                             struct audit_rule *rule,
+                             enum audit_state *state)
+{
+       int i;
+
+       for (i = 0; i < rule->field_count; i++) {
+               u32 field  = rule->fields[i] & ~AUDIT_NEGATE;
+               u32 value  = rule->values[i];
+               int result = 0;
+
+               switch (field) {
+               case AUDIT_PID:
+                       result = (cb->creds.pid == value);
+                       break;
+               case AUDIT_UID:
+                       result = (cb->creds.uid == value);
+                       break;
+               case AUDIT_GID:
+                       result = (cb->creds.gid == value);
+                       break;
+               case AUDIT_LOGINUID:
+                       result = (cb->loginuid == value);
+                       break;
+               }
+
+               if (rule->fields[i] & AUDIT_NEGATE)
+                       result = !result;
+               if (!result)
+                       return 0;
+       }
+       switch (rule->action) {
+       case AUDIT_NEVER:    *state = AUDIT_DISABLED;       break;
+       case AUDIT_POSSIBLE: *state = AUDIT_BUILD_CONTEXT;  break;
+       case AUDIT_ALWAYS:   *state = AUDIT_RECORD_CONTEXT; break;
+       }
+       return 1;
+}
+
+int audit_filter_user(struct netlink_skb_parms *cb, int type)
 {
-       struct task_struct *tsk;
        struct audit_entry *e;
        enum audit_state   state;
        int ret = 1;
 
-       read_lock(&tasklist_lock);
-       tsk = find_task_by_pid(pid);
-       if (tsk)
-               get_task_struct(tsk);
-       read_unlock(&tasklist_lock);
-
-       if (!tsk)
-               return -ESRCH;
-
        rcu_read_lock();
        list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) {
-               if (audit_filter_rules(tsk, &e->rule, NULL, &state)) {
+               if (audit_filter_user_rules(cb, &e->rule, &state)) {
                        if (state == AUDIT_DISABLED)
                                ret = 0;
                        break;
                }
        }
        rcu_read_unlock();
-       put_task_struct(tsk);
-
-       return 1; /* Audit by default */
 
+       return ret; /* Audit by default */
 }
 
 /* This should be called with task_lock() held. */
        up_read(&mm->mmap_sem);
 }
 
-static void audit_log_exit(struct audit_context *context)
+static void audit_log_exit(struct audit_context *context, unsigned int gfp_mask)
 {
        int i;
        struct audit_buffer *ab;
        struct audit_aux_data *aux;
 
-       ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL);
+       ab = audit_log_start(context, gfp_mask, AUDIT_SYSCALL);
        if (!ab)
                return;         /* audit_panic has been called */
        audit_log_format(ab, "arch=%x syscall=%d",
                return;
 
        /* Check for system calls that do not go through the exit
-        * function (e.g., exit_group), then free context block. */
+        * function (e.g., exit_group), then free context block. 
+        * We use GFP_ATOMIC here because we might be doing this 
+        * in the context of the idle thread */
        if (context->in_syscall && context->auditable)
-               audit_log_exit(context);
+               audit_log_exit(context, GFP_ATOMIC);
 
        audit_free_context(context);
 }
                return;
 
        if (context->in_syscall && context->auditable)
-               audit_log_exit(context);
+               audit_log_exit(context, GFP_KERNEL);
 
        context->in_syscall = 0;
        context->auditable  = 0;
        extern pid_t audit_sig_pid;
        extern uid_t audit_sig_uid;
 
-       if (unlikely(audit_pid && t->pid == audit_pid)) {
+       if (unlikely(audit_pid && t->tgid == audit_pid)) {
                if (sig == SIGTERM || sig == SIGHUP) {
                        struct audit_context *ctx = current->audit_context;
                        audit_sig_pid = current->pid;
 
                 * doesn't use the bridge parent of the indev by using
                 * the BRNF_DONT_TAKE_PARENT mask. */
                if (hook == NF_IP_FORWARD && nf_bridge->physindev == NULL) {
-                       nf_bridge->mask &= BRNF_DONT_TAKE_PARENT;
+                       nf_bridge->mask |= BRNF_DONT_TAKE_PARENT;
                        nf_bridge->physindev = (struct net_device *)in;
                }
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
 
        nf_debug_ip_finish_output2(skb);
 #endif /*CONFIG_NETFILTER_DEBUG*/
 
-       nf_reset(skb);
+#ifdef CONFIG_BRIDGE_NETFILTER
+       /* bridge-netfilter defers calling some IP hooks to the bridge layer
+        * and still needs the conntrack reference.
+        */
+       if (skb->nf_bridge == NULL)
+#endif
+               nf_reset(skb);
 
        if (hh) {
                int hh_alen;