## Automatically generated incremental diff ## From: linux-2.5.66-bk9 ## To: linux-2.5.66-bk10 ## Robot: $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $ diff -urN linux-2.5.66-bk9/Documentation/block/biodoc.txt linux-2.5.66-bk10/Documentation/block/biodoc.txt --- linux-2.5.66-bk9/Documentation/block/biodoc.txt 2003-03-24 14:01:13.000000000 -0800 +++ linux-2.5.66-bk10/Documentation/block/biodoc.txt 2003-04-04 04:32:52.000000000 -0800 @@ -204,7 +204,7 @@ which case a virtual mapping of the page is required. For SCSI it is also done in some scenarios where the low level driver cannot be trusted to handle a single sg entry correctly. The driver is expected to perform the -kmaps as needed on such occasions using the bio_kmap and bio_kmap_irq +kmaps as needed on such occasions using the __bio_kmap_atomic and bio_kmap_irq routines as appropriate. A driver could also use the blk_queue_bounce() routine on its own to bounce highmem i/o to low memory for specific requests if so desired. @@ -1147,9 +1147,9 @@ PIO drivers (or drivers that need to revert to PIO transfer once in a while (IDE for example)), where the CPU is doing the actual data transfer a virtual mapping is needed. If the driver supports highmem I/O, -(Sec 1.1, (ii) ) it needs to use bio_kmap and bio_kmap_irq to temporarily -map a bio into the virtual address space. See how IDE handles this with -ide_map_buffer. +(Sec 1.1, (ii) ) it needs to use __bio_kmap_atomic and bio_kmap_irq to +temporarily map a bio into the virtual address space. See how IDE handles +this with ide_map_buffer. 8. Prior/Related/Impacted patches diff -urN linux-2.5.66-bk9/Documentation/filesystems/porting linux-2.5.66-bk10/Documentation/filesystems/porting --- linux-2.5.66-bk9/Documentation/filesystems/porting 2003-03-24 14:00:14.000000000 -0800 +++ linux-2.5.66-bk10/Documentation/filesystems/porting 2003-04-04 04:32:52.000000000 -0800 @@ -208,10 +208,10 @@ if at least one of the following is true: * filesystem has no cross-directory rename() * dcache_lock is held - * dparent_lock is held (shared) * we know that parent had been locked (e.g. we are looking at ->d_parent of ->lookup() argument). * we are called from ->rename(). + * the child's ->d_lock is held Audit your code and add locking if needed. Notice that any place that is not protected by the conditions above is risky even in the old tree - you had been relying on BKL and that's prone to screwups. Old tree had quite diff -urN linux-2.5.66-bk9/Documentation/filesystems/tmpfs.txt linux-2.5.66-bk10/Documentation/filesystems/tmpfs.txt --- linux-2.5.66-bk9/Documentation/filesystems/tmpfs.txt 2003-03-24 13:59:53.000000000 -0800 +++ linux-2.5.66-bk10/Documentation/filesystems/tmpfs.txt 2003-04-04 04:32:52.000000000 -0800 @@ -54,18 +54,21 @@ 4) And probably a lot more I do not know about :-) -tmpfs has a couple of mount options: +tmpfs has three mount options for sizing: -size: The limit of allocated bytes for this tmpfs instance. The +size: The limit of allocated bytes for this tmpfs instance. The default is half of your physical RAM without swap. If you - oversize your tmpfs instances the machine will deadlock - since the OOM handler will not be able to free that memory. -nr_blocks: The same as size, but in blocks of PAGECACHE_SIZE. + oversize your tmpfs instances the machine will deadlock + since the OOM handler will not be able to free that memory. +nr_blocks: The same as size, but in blocks of PAGE_CACHE_SIZE. nr_inodes: The maximum number of inodes for this instance. The default is half of the number of your physical RAM pages. These parameters accept a suffix k, m or g for kilo, mega and giga and -can be changed on remount. +can be changed on remount. The size parameter also accepts a suffix % +to limit this tmpfs instance to that percentage of your physical RAM: +the default, when neither size nor nr_blocks is specified, is size=50% + To specify the initial root directory you can use the following mount options: @@ -83,15 +86,7 @@ RAM/SWAP in 10240 inodes and it is only accessible by root. -TODOs: - -1) give the size option a percent semantic: If you give a mount option - size=50% the tmpfs instance should be able to grow to 50 percent of - RAM + swap. So the instance should adapt automatically if you add - or remove swap space. -2) Show the number of tmpfs RAM pages. (As shared?) - Author: Christoph Rohland , 1.12.01 Updated: - Hugh Dickins , 17 Oct 2002 + Hugh Dickins , 01 April 2003 diff -urN linux-2.5.66-bk9/Makefile linux-2.5.66-bk10/Makefile --- linux-2.5.66-bk9/Makefile 2003-04-04 04:32:48.000000000 -0800 +++ linux-2.5.66-bk10/Makefile 2003-04-04 04:32:52.000000000 -0800 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 5 SUBLEVEL = 66 -EXTRAVERSION = -bk9 +EXTRAVERSION = -bk10 # *DOCUMENTATION* # To see a list of typical targets execute "make help" diff -urN linux-2.5.66-bk9/arch/i386/kernel/time.c linux-2.5.66-bk10/arch/i386/kernel/time.c --- linux-2.5.66-bk9/arch/i386/kernel/time.c 2003-03-24 14:00:37.000000000 -0800 +++ linux-2.5.66-bk10/arch/i386/kernel/time.c 2003-04-04 04:32:52.000000000 -0800 @@ -138,6 +138,17 @@ clock_was_set(); } +/* monotonic_clock(): returns # of nanoseconds passed since time_init() + * Note: This function is required to return accurate + * time even in the absence of multiple timer ticks. + */ +unsigned long long monotonic_clock(void) +{ + return timer->monotonic_clock(); +} +EXPORT_SYMBOL(monotonic_clock); + + /* * In order to set the CMOS clock precisely, set_rtc_mmss has to be * called 500 ms after the second nowtime has started, because when diff -urN linux-2.5.66-bk9/arch/i386/kernel/timers/timer_cyclone.c linux-2.5.66-bk10/arch/i386/kernel/timers/timer_cyclone.c --- linux-2.5.66-bk9/arch/i386/kernel/timers/timer_cyclone.c 2003-04-04 04:32:48.000000000 -0800 +++ linux-2.5.66-bk10/arch/i386/kernel/timers/timer_cyclone.c 2003-04-04 04:32:52.000000000 -0800 @@ -28,27 +28,46 @@ #define CYCLONE_MPMC_OFFSET 0x51D0 #define CYCLONE_MPCS_OFFSET 0x51A8 #define CYCLONE_TIMER_FREQ 100000000 - +#define CYCLONE_TIMER_MASK (((u64)1<<40)-1) /* 40 bit mask */ int use_cyclone = 0; static u32* volatile cyclone_timer; /* Cyclone MPMC0 register */ -static u32 last_cyclone_timer; +static u32 last_cyclone_low; +static u32 last_cyclone_high; +static unsigned long long monotonic_base; +static rwlock_t monotonic_lock = RW_LOCK_UNLOCKED; + +/* helper macro to atomically read both cyclone counter registers */ +#define read_cyclone_counter(low,high) \ + do{ \ + high = cyclone_timer[1]; low = cyclone_timer[0]; \ + } while (high != cyclone_timer[1]); + static void mark_offset_cyclone(void) { int count; + unsigned long long this_offset, last_offset; + + write_lock(&monotonic_lock); + last_offset = ((unsigned long long)last_cyclone_high<<32)|last_cyclone_low; + spin_lock(&i8253_lock); - /* quickly read the cyclone timer */ - if(cyclone_timer) - last_cyclone_timer = cyclone_timer[0]; + read_cyclone_counter(last_cyclone_low,last_cyclone_high); - /* calculate delay_at_last_interrupt */ + /* read values for delay_at_last_interrupt */ outb_p(0x00, 0x43); /* latch the count ASAP */ count = inb_p(0x40); /* read the latched count */ count |= inb(0x40) << 8; spin_unlock(&i8253_lock); + /* update the monotonic base value */ + this_offset = ((unsigned long long)last_cyclone_high<<32)|last_cyclone_low; + monotonic_base += (this_offset - last_offset) & CYCLONE_TIMER_MASK; + write_unlock(&monotonic_lock); + + /* calculate delay_at_last_interrupt */ count = ((LATCH-1) - count) * TICK_SIZE; delay_at_last_interrupt = (count + LATCH/2) / LATCH; } @@ -64,7 +83,7 @@ offset = cyclone_timer[0]; /* .. relative to previous jiffy */ - offset = offset - last_cyclone_timer; + offset = offset - last_cyclone_low; /* convert cyclone ticks to microseconds */ /* XXX slow, can we speed this up? */ @@ -74,6 +93,27 @@ return delay_at_last_interrupt + offset; } +static unsigned long long monotonic_clock_cyclone(void) +{ + u32 now_low, now_high; + unsigned long long last_offset, this_offset, base; + unsigned long long ret; + + /* atomically read monotonic base & last_offset */ + read_lock_irq(&monotonic_lock); + last_offset = ((unsigned long long)last_cyclone_high<<32)|last_cyclone_low; + base = monotonic_base; + read_unlock_irq(&monotonic_lock); + + /* Read the cyclone counter */ + read_cyclone_counter(now_low,now_high); + this_offset = ((unsigned long long)now_high<<32)|now_low; + + /* convert to nanoseconds */ + ret = base + ((this_offset - last_offset)&CYCLONE_TIMER_MASK); + return ret * (1000000000 / CYCLONE_TIMER_FREQ); +} + static int __init init_cyclone(char* override) { u32* reg; @@ -194,5 +234,6 @@ .init = init_cyclone, .mark_offset = mark_offset_cyclone, .get_offset = get_offset_cyclone, + .monotonic_clock = monotonic_clock_cyclone, .delay = delay_cyclone, }; diff -urN linux-2.5.66-bk9/arch/i386/kernel/timers/timer_none.c linux-2.5.66-bk10/arch/i386/kernel/timers/timer_none.c --- linux-2.5.66-bk9/arch/i386/kernel/timers/timer_none.c 2003-04-04 04:32:48.000000000 -0800 +++ linux-2.5.66-bk10/arch/i386/kernel/timers/timer_none.c 2003-04-04 04:32:52.000000000 -0800 @@ -16,6 +16,11 @@ return 0; } +static unsigned long long monotonic_clock_none(void) +{ + return 0; +} + static void delay_none(unsigned long loops) { int d0; @@ -34,5 +39,6 @@ .init = init_none, .mark_offset = mark_offset_none, .get_offset = get_offset_none, + .monotonic_clock = monotonic_clock_none, .delay = delay_none, }; diff -urN linux-2.5.66-bk9/arch/i386/kernel/timers/timer_pit.c linux-2.5.66-bk10/arch/i386/kernel/timers/timer_pit.c --- linux-2.5.66-bk9/arch/i386/kernel/timers/timer_pit.c 2003-04-04 04:32:48.000000000 -0800 +++ linux-2.5.66-bk10/arch/i386/kernel/timers/timer_pit.c 2003-04-04 04:32:52.000000000 -0800 @@ -31,6 +31,11 @@ /* nothing needed */ } +static unsigned long long monotonic_clock_pit(void) +{ + return 0; +} + static void delay_pit(unsigned long loops) { int d0; @@ -145,5 +150,6 @@ .init = init_pit, .mark_offset = mark_offset_pit, .get_offset = get_offset_pit, + .monotonic_clock = monotonic_clock_pit, .delay = delay_pit, }; diff -urN linux-2.5.66-bk9/arch/i386/kernel/timers/timer_tsc.c linux-2.5.66-bk10/arch/i386/kernel/timers/timer_tsc.c --- linux-2.5.66-bk9/arch/i386/kernel/timers/timer_tsc.c 2003-04-04 04:32:48.000000000 -0800 +++ linux-2.5.66-bk10/arch/i386/kernel/timers/timer_tsc.c 2003-04-04 04:32:52.000000000 -0800 @@ -24,6 +24,38 @@ static int delay_at_last_interrupt; static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */ +static unsigned long last_tsc_high; /* msb 32 bits of Time Stamp Counter */ +static unsigned long long monotonic_base; +static rwlock_t monotonic_lock = RW_LOCK_UNLOCKED; + +/* convert from cycles(64bits) => nanoseconds (64bits) + * basic equation: + * ns = cycles / (freq / ns_per_sec) + * ns = cycles * (ns_per_sec / freq) + * ns = cycles * (10^9 / (cpu_mhz * 10^6)) + * ns = cycles * (10^3 / cpu_mhz) + * + * Then we use scaling math (suggested by george@mvista.com) to get: + * ns = cycles * (10^3 * SC / cpu_mhz) / SC + * ns = cycles * cyc2ns_scale / SC + * + * And since SC is a constant power of two, we can convert the div + * into a shift. + * -johnstul@us.ibm.com "math is hard, lets go shopping!" + */ +static unsigned long cyc2ns_scale; +#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ + +static inline void set_cyc2ns_scale(unsigned long cpu_mhz) +{ + cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz; +} + +static inline unsigned long long cycles_2_ns(unsigned long long cyc) +{ + return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; +} + /* Cached *multiplier* to convert TSC counts to microseconds. * (see the equation below). @@ -61,11 +93,32 @@ return delay_at_last_interrupt + edx; } +static unsigned long long monotonic_clock_tsc(void) +{ + unsigned long long last_offset, this_offset, base; + + /* atomically read monotonic base & last_offset */ + read_lock_irq(&monotonic_lock); + last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; + base = monotonic_base; + read_unlock_irq(&monotonic_lock); + + /* Read the Time Stamp Counter */ + rdtscll(this_offset); + + /* return the value in ns */ + return base + cycles_2_ns(this_offset - last_offset); +} + static void mark_offset_tsc(void) { int count; int countmp; static int count1=0, count2=LATCH; + unsigned long long this_offset, last_offset; + + write_lock(&monotonic_lock); + last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; /* * It is important that these two operations happen almost at * the same time. We do the RDTSC stuff first, since it's @@ -80,7 +133,7 @@ /* read Pentium cycle counter */ - rdtscl(last_tsc_low); + rdtsc(last_tsc_low, last_tsc_high); spin_lock(&i8253_lock); outb_p(0x00, 0x43); /* latch the count ASAP */ @@ -103,6 +156,12 @@ } } + /* update the monotonic base value */ + this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; + monotonic_base += cycles_2_ns(this_offset - last_offset); + write_unlock(&monotonic_lock); + + /* calculate delay_at_last_interrupt */ count = ((LATCH-1) - count) * TICK_SIZE; delay_at_last_interrupt = (count + LATCH/2) / LATCH; } @@ -301,6 +360,7 @@ "0" (eax), "1" (edx)); printk("Detected %lu.%03lu MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000); } + set_cyc2ns_scale(cpu_khz/1000); return 0; } } @@ -334,5 +394,6 @@ .init = init_tsc, .mark_offset = mark_offset_tsc, .get_offset = get_offset_tsc, + .monotonic_clock = monotonic_clock_tsc, .delay = delay_tsc, }; diff -urN linux-2.5.66-bk9/arch/sparc/kernel/sys_sparc.c linux-2.5.66-bk10/arch/sparc/kernel/sys_sparc.c --- linux-2.5.66-bk9/arch/sparc/kernel/sys_sparc.c 2003-03-24 14:00:17.000000000 -0800 +++ linux-2.5.66-bk10/arch/sparc/kernel/sys_sparc.c 2003-04-04 04:32:52.000000000 -0800 @@ -269,11 +269,7 @@ return do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT); } -extern int sys_remap_file_pages(unsigned long start, unsigned long size, - unsigned long prot, unsigned long pgoff, - unsigned long flags); - -int sparc_remap_file_pages(unsigned long start, unsigned long size, +long sparc_remap_file_pages(unsigned long start, unsigned long size, unsigned long prot, unsigned long pgoff, unsigned long flags) { diff -urN linux-2.5.66-bk9/arch/sparc64/boot/Makefile linux-2.5.66-bk10/arch/sparc64/boot/Makefile --- linux-2.5.66-bk9/arch/sparc64/boot/Makefile 2003-04-04 04:32:48.000000000 -0800 +++ linux-2.5.66-bk10/arch/sparc64/boot/Makefile 2003-04-04 04:32:52.000000000 -0800 @@ -19,16 +19,16 @@ # Actual linking -$(obj)/image: FORCE +$(obj)/image: vmlinux FORCE $(call if_changed,strip) @echo ' kernel: $@ is ready' -$(obj)/tftpboot.img: $(obj)/piggyback System.map $(ROOT_IMG) FORCE +$(obj)/tftpboot.img: vmlinux $(obj)/piggyback System.map $(ROOT_IMG) FORCE $(call if_changed,elftoaout) $(call if_changed,piggy) @echo ' kernel: $@ is ready' -$(obj)/vmlinux.aout: FORCE +$(obj)/vmlinux.aout: vmlinux FORCE $(call if_changed,elftoaout) @echo ' kernel: $@ is ready' diff -urN linux-2.5.66-bk9/arch/sparc64/defconfig linux-2.5.66-bk10/arch/sparc64/defconfig --- linux-2.5.66-bk9/arch/sparc64/defconfig 2003-04-04 04:32:48.000000000 -0800 +++ linux-2.5.66-bk10/arch/sparc64/defconfig 2003-04-04 04:32:52.000000000 -0800 @@ -348,7 +348,6 @@ CONFIG_PACKET_MMAP=y CONFIG_NETLINK_DEV=y # CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_NET_KEY=m CONFIG_INET=y @@ -512,6 +511,7 @@ CONFIG_PLIP=m CONFIG_PPP=m # CONFIG_PPP_MULTILINK is not set +CONFIG_PPP_FILTER=y # CONFIG_PPP_ASYNC is not set # CONFIG_PPP_SYNC_TTY is not set # CONFIG_PPP_DEFLATE is not set @@ -1058,9 +1058,12 @@ CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_DEFLATE=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.5.66-bk9/arch/sparc64/kernel/entry.S linux-2.5.66-bk10/arch/sparc64/kernel/entry.S --- linux-2.5.66-bk9/arch/sparc64/kernel/entry.S 2003-03-24 13:59:46.000000000 -0800 +++ linux-2.5.66-bk10/arch/sparc64/kernel/entry.S 2003-04-04 04:32:52.000000000 -0800 @@ -272,7 +272,7 @@ .align 32 fp_other_bounce: call do_fpother - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap clr %l6 @@ -499,7 +499,7 @@ ba,pt %xcc, etrap 109: or %g7, %lo(109b), %g7 call catch_disabled_ivec - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap clr %l6 @@ -606,7 +606,7 @@ done utrap_ill: call bad_trap - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap clr %l6 @@ -711,7 +711,7 @@ mov 11, %o0 mov 0, %o1 call sparc_floppy_irq - add %sp, STACK_BIAS + REGWIN_SZ, %o2 + add %sp, PTREGS_OFF, %o2 b,pt %xcc, rtrap_irq nop @@ -757,7 +757,7 @@ mov %l4, %o1 mov %l5, %o2 call data_access_exception - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap clr %l6 @@ -778,7 +778,7 @@ mov %l4, %o1 mov %l5, %o2 call instruction_access_exception_tl1 - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap clr %l6 @@ -797,7 +797,7 @@ mov %l4, %o1 mov %l5, %o2 call instruction_access_exception - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap clr %l6 @@ -889,7 +889,7 @@ mov %l5, %o1 call cee_log - add %sp, STACK_BIAS + REGWIN_SZ, %o2 + add %sp, PTREGS_OFF, %o2 ba,a,pt %xcc, rtrap_irq /* Capture I/D/E-cache state into per-cpu error scoreboard. @@ -1104,7 +1104,7 @@ rd %pc, %g7 mov 0x0, %o0 call cheetah_plus_parity_error - add %sp, STACK_BIAS + REGWIN_SZ, %o1 + add %sp, PTREGS_OFF, %o1 ba,pt %xcc, rtrap clr %l6 @@ -1134,7 +1134,7 @@ rd %pc, %g7 mov 0x1, %o0 call cheetah_plus_parity_error - add %sp, STACK_BIAS + REGWIN_SZ, %o1 + add %sp, PTREGS_OFF, %o1 ba,pt %xcc, rtrap clr %l6 @@ -1196,7 +1196,7 @@ 1: or %g7, %lo(1b), %g7 mov 0x2, %o0 call cheetah_plus_parity_error - add %sp, STACK_BIAS + REGWIN_SZ, %o1 + add %sp, PTREGS_OFF, %o1 ba,pt %xcc, rtrap clr %l6 @@ -1234,7 +1234,7 @@ 1: or %g7, %lo(1b), %g7 mov 0x3, %o0 call cheetah_plus_parity_error - add %sp, STACK_BIAS + REGWIN_SZ, %o1 + add %sp, PTREGS_OFF, %o1 ba,pt %xcc, rtrap clr %l6 @@ -1290,7 +1290,7 @@ mov %l4, %o1 mov %l5, %o2 call cheetah_fecc_handler - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 ba,a,pt %xcc, rtrap_irq /* Our caller has disabled I-cache and performed membar Sync. */ @@ -1316,7 +1316,7 @@ mov %l4, %o1 mov %l5, %o2 call cheetah_cee_handler - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 ba,a,pt %xcc, rtrap_irq /* Our caller has disabled I-cache+D-cache and performed membar Sync. */ @@ -1342,7 +1342,7 @@ mov %l4, %o1 mov %l5, %o2 call cheetah_deferred_handler - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 ba,a,pt %xcc, rtrap_irq .globl __do_privact @@ -1354,7 +1354,7 @@ ba,pt %xcc, etrap 109: or %g7, %lo(109b), %g7 call do_privact - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap clr %l6 @@ -1381,7 +1381,7 @@ mov %l4, %o1 mov %l5, %o2 call mem_address_unaligned - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap clr %l6 @@ -1399,7 +1399,7 @@ mov %l4, %o1 mov %l5, %o2 call handle_lddfmna - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap clr %l6 @@ -1417,14 +1417,14 @@ mov %l4, %o1 mov %l5, %o2 call handle_stdfmna - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap clr %l6 .globl breakpoint_trap breakpoint_trap: call sparc_breakpoint - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap nop @@ -1460,9 +1460,9 @@ call sys_getppid nop call sys_getpid - stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1] + stx %o0, [%sp + PTREGS_OFF + PT_V9_I1] b,pt %xcc, ret_sys_call - stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0] + stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] /* SunOS getuid() returns uid in %o0 and euid in %o1 */ .globl sunos_getuid @@ -1470,9 +1470,9 @@ call sys32_geteuid16 nop call sys32_getuid16 - stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1] + stx %o0, [%sp + PTREGS_OFF + PT_V9_I1] b,pt %xcc, ret_sys_call - stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0] + stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] /* SunOS getgid() returns gid in %o0 and egid in %o1 */ .globl sunos_getgid @@ -1480,9 +1480,9 @@ call sys32_getegid16 nop call sys32_getgid16 - stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1] + stx %o0, [%sp + PTREGS_OFF + PT_V9_I1] b,pt %xcc, ret_sys_call - stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0] + stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] #endif /* SunOS's execv() call only specifies the argv argument, the @@ -1494,14 +1494,14 @@ ba,pt %xcc, execve_merge or %g1, %lo(sparc_execve), %g1 sunos_execv: - stx %g0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I2] + stx %g0, [%sp + PTREGS_OFF + PT_V9_I2] sys32_execve: sethi %hi(sparc32_execve), %g1 or %g1, %lo(sparc32_execve), %g1 execve_merge: flushw jmpl %g1, %g0 - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 .globl sys_pipe, sys_sigpause, sys_nis_syscall .globl sys_sigsuspend, sys_rt_sigsuspend, sys32_rt_sigsuspend @@ -1512,12 +1512,12 @@ .globl sys32_sigstack .align 32 sys_pipe: ba,pt %xcc, sparc_pipe - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 sys_nis_syscall:ba,pt %xcc, c_sys_nis_syscall - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 sys_memory_ordering: ba,pt %xcc, sparc_memory_ordering - add %sp, STACK_BIAS + REGWIN_SZ, %o1 + add %sp, PTREGS_OFF, %o1 sys_sigaltstack:ba,pt %xcc, do_sigaltstack add %i6, STACK_BIAS, %o2 sys32_sigstack: ba,pt %xcc, do_sys32_sigstack @@ -1527,41 +1527,41 @@ mov %i6, %o2 .align 32 -sys_sigsuspend: add %sp, STACK_BIAS + REGWIN_SZ, %o0 +sys_sigsuspend: add %sp, PTREGS_OFF, %o0 call do_sigsuspend add %o7, 1f-.-4, %o7 nop sys_rt_sigsuspend: /* NOTE: %o0,%o1 have a correct value already */ - add %sp, STACK_BIAS + REGWIN_SZ, %o2 + add %sp, PTREGS_OFF, %o2 call do_rt_sigsuspend add %o7, 1f-.-4, %o7 nop sys32_rt_sigsuspend: /* NOTE: %o0,%o1 have a correct value already */ srl %o0, 0, %o0 - add %sp, STACK_BIAS + REGWIN_SZ, %o2 + add %sp, PTREGS_OFF, %o2 call do_rt_sigsuspend32 add %o7, 1f-.-4, %o7 /* NOTE: %o0 has a correct value already */ -sys_sigpause: add %sp, STACK_BIAS + REGWIN_SZ, %o1 +sys_sigpause: add %sp, PTREGS_OFF, %o1 call do_sigpause add %o7, 1f-.-4, %o7 nop sys32_sigreturn: - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 call do_sigreturn32 add %o7, 1f-.-4, %o7 nop sys_rt_sigreturn: - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 call do_rt_sigreturn add %o7, 1f-.-4, %o7 nop sys32_rt_sigreturn: - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 call do_rt_sigreturn32 add %o7, 1f-.-4, %o7 nop -sys_ptrace: add %sp, STACK_BIAS + REGWIN_SZ, %o0 +sys_ptrace: add %sp, PTREGS_OFF, %o0 call do_ptrace add %o7, 1f-.-4, %o7 nop @@ -1612,7 +1612,7 @@ movrz %o1, %fp, %o1 mov 0, %o3 ba,pt %xcc, sparc_do_fork - add %sp, STACK_BIAS + REGWIN_SZ, %o2 + add %sp, PTREGS_OFF, %o2 ret_from_syscall: /* Clear SPARC_FLAG_NEWCHILD, switch_to leaves thread.flags in * %o7 for us. Check performance counter stuff too. @@ -1638,7 +1638,7 @@ rd %pic, %g0 1: b,pt %xcc, ret_sys_call - ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0], %o0 + ldx [%sp + PTREGS_OFF + PT_V9_I0], %o0 sparc_exit: wrpr %g0, (PSTATE_RMO | PSTATE_PEF | PSTATE_PRIV), %pstate rdpr %otherwin, %g1 rdpr %cansave, %g3 @@ -1686,7 +1686,7 @@ sll %g1, 2, %l4 ! IEU0 Group #ifdef SYSCALL_TRACING call syscall_trace_entry - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 srl %i0, 0, %o0 #endif mov %i4, %o4 ! IEU1 @@ -1714,7 +1714,7 @@ sll %g1, 2, %l4 ! IEU0 Group #ifdef SYSCALL_TRACING call syscall_trace_entry - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 mov %i0, %o0 #endif mov %i1, %o1 ! IEU1 @@ -1731,16 +1731,16 @@ mov %i5, %o5 ! IEU0 nop -3: stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0] +3: stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] ret_sys_call: #ifdef SYSCALL_TRACING mov %o0, %o1 call syscall_trace_exit - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 mov %o1, %o0 #endif - ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TSTATE], %g3 - ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC], %l1 ! pc = npc + ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3 + ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc sra %o0, 0, %o0 mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2 cmp %o0, -ENOIOCTLCMD @@ -1749,12 +1749,12 @@ andcc %l0, _TIF_SYSCALL_TRACE, %l6 andn %g3, %g2, %g3 /* System call success, clear Carry condition code. */ - stx %g3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TSTATE] + stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] bne,pn %icc, linux_syscall_trace2 add %l1, 0x4, %l2 ! npc = npc+4 - stx %l1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TPC] + stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] ba,pt %xcc, rtrap_clr_l6 - stx %l2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC] + stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] 1: /* System call failure, set Carry condition code. @@ -1762,21 +1762,21 @@ */ sub %g0, %o0, %o0 or %g3, %g2, %g3 - stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0] + stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] mov 1, %l6 - stx %g3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TSTATE] + stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] bne,pn %icc, linux_syscall_trace2 add %l1, 0x4, %l2 !npc = npc+4 - stx %l1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TPC] + stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] b,pt %xcc, rtrap - stx %l2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC] + stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] linux_syscall_trace2: call syscall_trace nop - stx %l1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TPC] + stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] ba,pt %xcc, rtrap - stx %l2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC] + stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] .align 32 .globl __flushw_user diff -urN linux-2.5.66-bk9/arch/sparc64/kernel/etrap.S linux-2.5.66-bk10/arch/sparc64/kernel/etrap.S --- linux-2.5.66-bk9/arch/sparc64/kernel/etrap.S 2003-03-24 14:00:19.000000000 -0800 +++ linux-2.5.66-bk10/arch/sparc64/kernel/etrap.S 2003-04-04 04:32:52.000000000 -0800 @@ -15,7 +15,7 @@ #include #include -#define TASK_REGOFF (THREAD_SIZE-TRACEREG_SZ-REGWIN_SZ) +#define TASK_REGOFF (THREAD_SIZE-TRACEREG_SZ-STACKFRAME_SZ) #define ETRAP_PSTATE1 (PSTATE_RMO | PSTATE_PRIV) #define ETRAP_PSTATE2 (PSTATE_RMO | PSTATE_PEF | PSTATE_PRIV | PSTATE_IE) @@ -33,8 +33,8 @@ sllx %g2, 20, %g3 ! IEU0 Group andcc %g1, TSTATE_PRIV, %g0 ! IEU1 or %g1, %g3, %g1 ! IEU0 Group - bne,pn %xcc, 1f ! CTI - sub %sp, REGWIN_SZ+TRACEREG_SZ-STACK_BIAS, %g2 ! IEU1 + bne,pn %xcc, 1f ! CTI + sub %sp, STACKFRAME_SZ+TRACEREG_SZ-STACK_BIAS, %g2 ! IEU1 wrpr %g0, 7, %cleanwin ! Single Group+4bubbles sethi %hi(TASK_REGOFF), %g2 ! IEU0 Group @@ -46,12 +46,12 @@ wr %g0, 0, %fprs ! Single Group+4bubbles 1: rdpr %tpc, %g3 ! Single Group - stx %g1, [%g2 + REGWIN_SZ + PT_V9_TSTATE] ! Store Group + stx %g1, [%g2 + STACKFRAME_SZ + PT_V9_TSTATE] ! Store Group rdpr %tnpc, %g1 ! Single Group - stx %g3, [%g2 + REGWIN_SZ + PT_V9_TPC] ! Store Group + stx %g3, [%g2 + STACKFRAME_SZ + PT_V9_TPC] ! Store Group rd %y, %g3 ! Single Group+4bubbles - stx %g1, [%g2 + REGWIN_SZ + PT_V9_TNPC] ! Store Group - st %g3, [%g2 + REGWIN_SZ + PT_V9_Y] ! Store Group + stx %g1, [%g2 + STACKFRAME_SZ + PT_V9_TNPC] ! Store Group + st %g3, [%g2 + STACKFRAME_SZ + PT_V9_Y] ! Store Group save %g2, -STACK_BIAS, %sp ! Ordering here is critical ! Single Group mov %g6, %l6 ! IEU0 Group @@ -75,23 +75,23 @@ mov %g7, %l2 ! IEU1 wrpr %g0, ETRAP_PSTATE1, %pstate ! Single Group+4bubbles - stx %g1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G1] ! Store Group - stx %g2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G2] ! Store Group - stx %g3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G3] ! Store Group - stx %g4, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G4] ! Store Group - stx %g5, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G5] ! Store Group - stx %g6, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G6] ! Store Group - - stx %g7, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G7] ! Store Group - stx %i0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0] ! Store Group - stx %i1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1] ! Store Group - stx %i2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I2] ! Store Group - stx %i3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I3] ! Store Group - stx %i4, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I4] ! Store Group - stx %i5, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I5] ! Store Group + stx %g1, [%sp + PTREGS_OFF + PT_V9_G1] ! Store Group + stx %g2, [%sp + PTREGS_OFF + PT_V9_G2] ! Store Group + stx %g3, [%sp + PTREGS_OFF + PT_V9_G3] ! Store Group + stx %g4, [%sp + PTREGS_OFF + PT_V9_G4] ! Store Group + stx %g5, [%sp + PTREGS_OFF + PT_V9_G5] ! Store Group + stx %g6, [%sp + PTREGS_OFF + PT_V9_G6] ! Store Group + + stx %g7, [%sp + PTREGS_OFF + PT_V9_G7] ! Store Group + stx %i0, [%sp + PTREGS_OFF + PT_V9_I0] ! Store Group + stx %i1, [%sp + PTREGS_OFF + PT_V9_I1] ! Store Group + stx %i2, [%sp + PTREGS_OFF + PT_V9_I2] ! Store Group + stx %i3, [%sp + PTREGS_OFF + PT_V9_I3] ! Store Group + stx %i4, [%sp + PTREGS_OFF + PT_V9_I4] ! Store Group + stx %i5, [%sp + PTREGS_OFF + PT_V9_I5] ! Store Group - stx %i6, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I6] ! Store Group - stx %i7, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I7] ! Store Group + stx %i6, [%sp + PTREGS_OFF + PT_V9_I6] ! Store Group + stx %i7, [%sp + PTREGS_OFF + PT_V9_I7] ! Store Group wrpr %g0, ETRAP_PSTATE2, %pstate ! Single Group+4bubbles mov %l6, %g6 ! IEU0 jmpl %l2 + 0x4, %g0 ! CTI Group @@ -167,7 +167,7 @@ stx %g1, [%g2 + STACK_BIAS + 0x80] rdpr %tstate, %g1 ! Single Group+4bubbles - sub %g2, REGWIN_SZ + TRACEREG_SZ - STACK_BIAS, %g2 ! IEU1 + sub %g2, STACKFRAME_SZ + TRACEREG_SZ - STACK_BIAS, %g2 ! IEU1 ba,pt %xcc, 1b ! CTI Group andcc %g1, TSTATE_PRIV, %g0 ! IEU0 @@ -179,7 +179,7 @@ andcc %g1, TSTATE_PRIV, %g0 ! IEU1 or %g1, %g3, %g1 ! IEU0 Group bne,pn %xcc, 1f ! CTI - sub %sp, (REGWIN_SZ+TRACEREG_SZ-STACK_BIAS), %g2 ! IEU1 + sub %sp, (STACKFRAME_SZ+TRACEREG_SZ-STACK_BIAS), %g2 ! IEU1 wrpr %g0, 7, %cleanwin ! Single Group+4bubbles sllx %g1, 51, %g3 ! IEU0 Group @@ -189,11 +189,11 @@ add %g6, %g2, %g2 ! IEU0 Group wr %g0, 0, %fprs ! Single Group+4bubbles 1: rdpr %tpc, %g3 ! Single Group - stx %g1, [%g2 + REGWIN_SZ + PT_V9_TSTATE] ! Store Group + stx %g1, [%g2 + STACKFRAME_SZ + PT_V9_TSTATE] ! Store Group rdpr %tnpc, %g1 ! Single Group - stx %g3, [%g2 + REGWIN_SZ + PT_V9_TPC] ! Store Group - stx %g1, [%g2 + REGWIN_SZ + PT_V9_TNPC] ! Store Group + stx %g3, [%g2 + STACKFRAME_SZ + PT_V9_TPC] ! Store Group + stx %g1, [%g2 + STACKFRAME_SZ + PT_V9_TNPC] ! Store Group save %g2, -STACK_BIAS, %sp ! Ordering here is critical ! Single Group mov %g6, %l6 ! IEU0 Group bne,pn %xcc, 2f ! CTI @@ -214,32 +214,32 @@ mov %g5, %l5 ! IEU0 Group add %g7, 0x4, %l2 ! IEU1 wrpr %g0, ETRAP_PSTATE1, %pstate ! Single Group+4bubbles - stx %g1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G1] ! Store Group - stx %g2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G2] ! Store Group + stx %g1, [%sp + PTREGS_OFF + PT_V9_G1] ! Store Group + stx %g2, [%sp + PTREGS_OFF + PT_V9_G2] ! Store Group sllx %l7, 24, %l7 ! IEU0 - stx %g3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G3] ! Store Group + stx %g3, [%sp + PTREGS_OFF + PT_V9_G3] ! Store Group rdpr %cwp, %l0 ! Single Group - stx %g4, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G4] ! Store Group - stx %g5, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G5] ! Store Group - stx %g6, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G6] ! Store Group - stx %g7, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G7] ! Store Group + stx %g4, [%sp + PTREGS_OFF + PT_V9_G4] ! Store Group + stx %g5, [%sp + PTREGS_OFF + PT_V9_G5] ! Store Group + stx %g6, [%sp + PTREGS_OFF + PT_V9_G6] ! Store Group + stx %g7, [%sp + PTREGS_OFF + PT_V9_G7] ! Store Group or %l7, %l0, %l7 ! IEU0 sethi %hi(TSTATE_RMO | TSTATE_PEF), %l0 ! IEU1 or %l7, %l0, %l7 ! IEU0 Group wrpr %l2, %tnpc ! Single Group+4bubbles wrpr %l7, (TSTATE_PRIV | TSTATE_IE), %tstate ! Single Group+4bubbles - stx %i0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0] ! Store Group - stx %i1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1] ! Store Group - stx %i2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I2] ! Store Group - stx %i3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I3] ! Store Group - stx %i4, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I4] ! Store Group + stx %i0, [%sp + PTREGS_OFF + PT_V9_I0] ! Store Group + stx %i1, [%sp + PTREGS_OFF + PT_V9_I1] ! Store Group + stx %i2, [%sp + PTREGS_OFF + PT_V9_I2] ! Store Group + stx %i3, [%sp + PTREGS_OFF + PT_V9_I3] ! Store Group + stx %i4, [%sp + PTREGS_OFF + PT_V9_I4] ! Store Group - stx %i5, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I5] ! Store Group - stx %i6, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I6] ! Store Group + stx %i5, [%sp + PTREGS_OFF + PT_V9_I5] ! Store Group + stx %i6, [%sp + PTREGS_OFF + PT_V9_I6] ! Store Group mov %l6, %g6 ! IEU1 - stx %i7, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I7] ! Store Group + stx %i7, [%sp + PTREGS_OFF + PT_V9_I7] ! Store Group ldx [%g6 + TI_TASK], %g4 ! Load Group done nop diff -urN linux-2.5.66-bk9/arch/sparc64/kernel/head.S linux-2.5.66-bk10/arch/sparc64/kernel/head.S --- linux-2.5.66-bk9/arch/sparc64/kernel/head.S 2003-03-24 14:00:18.000000000 -0800 +++ linux-2.5.66-bk10/arch/sparc64/kernel/head.S 2003-04-04 04:32:52.000000000 -0800 @@ -549,7 +549,7 @@ wr %g0, ASI_P, %asi mov 1, %g5 sllx %g5, THREAD_SHIFT, %g5 - sub %g5, (REGWIN_SZ + STACK_BIAS), %g5 + sub %g5, (STACKFRAME_SZ + STACK_BIAS), %g5 add %g6, %g5, %sp mov 0, %fp diff -urN linux-2.5.66-bk9/arch/sparc64/kernel/itlb_base.S linux-2.5.66-bk10/arch/sparc64/kernel/itlb_base.S --- linux-2.5.66-bk9/arch/sparc64/kernel/itlb_base.S 2003-03-24 14:00:01.000000000 -0800 +++ linux-2.5.66-bk10/arch/sparc64/kernel/itlb_base.S 2003-04-04 04:32:52.000000000 -0800 @@ -59,7 +59,7 @@ /* ITLB ** ICACHE line 3: Finish faults + window fixups */ call do_sparc64_fault ! Call fault handler - add %sp, STACK_BIAS + REGWIN_SZ, %o0! Compute pt_regs arg + add %sp, PTREGS_OFF, %o0! Compute pt_regs arg ba,pt %xcc, rtrap_clr_l6 ! Restore cpu state nop winfix_trampoline: diff -urN linux-2.5.66-bk9/arch/sparc64/kernel/module.c linux-2.5.66-bk10/arch/sparc64/kernel/module.c --- linux-2.5.66-bk9/arch/sparc64/kernel/module.c 2003-03-24 14:00:54.000000000 -0800 +++ linux-2.5.66-bk10/arch/sparc64/kernel/module.c 2003-04-04 04:32:52.000000000 -0800 @@ -231,6 +231,13 @@ ((v >> 10) & 0x3fffff); break; + case R_SPARC_OLO10: + *loc32 = (*loc32 & ~0x1fff) | + (((v & 0x3ff) + + (ELF64_R_TYPE(rel[i].r_info) >> 8)) + & 0x1fff); + break; + default: printk(KERN_ERR "module %s: Unknown relocation: %x\n", me->name, diff -urN linux-2.5.66-bk9/arch/sparc64/kernel/process.c linux-2.5.66-bk10/arch/sparc64/kernel/process.c --- linux-2.5.66-bk9/arch/sparc64/kernel/process.c 2003-03-24 14:00:20.000000000 -0800 +++ linux-2.5.66-bk10/arch/sparc64/kernel/process.c 2003-04-04 04:32:52.000000000 -0800 @@ -39,6 +39,7 @@ #include #include #include +#include /* #define VERBOSE_SHOWREGS */ @@ -341,8 +342,8 @@ regs->u_regs[14] >= (long)current - PAGE_SIZE && regs->u_regs[14] < (long)current + 6 * PAGE_SIZE) { printk ("*********parent**********\n"); - __show_regs((struct pt_regs *)(regs->u_regs[14] + STACK_BIAS + REGWIN_SZ)); - idump_from_user(((struct pt_regs *)(regs->u_regs[14] + STACK_BIAS + REGWIN_SZ))->tpc); + __show_regs((struct pt_regs *)(regs->u_regs[14] + PTREGS_OFF)); + idump_from_user(((struct pt_regs *)(regs->u_regs[14] + PTREGS_OFF))->tpc); printk ("*********endpar**********\n"); } #endif @@ -508,11 +509,11 @@ flush_user_windows(); if ((window = get_thread_wsaved()) != 0) { - int winsize = REGWIN_SZ; + int winsize = sizeof(struct reg_window); int bias = 0; if (test_thread_flag(TIF_32BIT)) - winsize = REGWIN32_SZ; + winsize = sizeof(struct reg_window32); else bias = STACK_BIAS; @@ -533,11 +534,11 @@ { struct thread_info *t = current_thread_info(); unsigned long window; - int winsize = REGWIN_SZ; + int winsize = sizeof(struct reg_window); int bias = 0; if (test_thread_flag(TIF_32BIT)) - winsize = REGWIN32_SZ; + winsize = sizeof(struct reg_window32); else bias = STACK_BIAS; @@ -610,14 +611,14 @@ p->set_child_tid = p->clear_child_tid = NULL; /* Calculate offset to stack_frame & pt_regs */ - child_trap_frame = ((char *)t) + (THREAD_SIZE - (TRACEREG_SZ+REGWIN_SZ)); - memcpy(child_trap_frame, (((struct reg_window *)regs)-1), (TRACEREG_SZ+REGWIN_SZ)); + child_trap_frame = ((char *)t) + (THREAD_SIZE - (TRACEREG_SZ+STACKFRAME_SZ)); + memcpy(child_trap_frame, (((struct sparc_stackf *)regs)-1), (TRACEREG_SZ+STACKFRAME_SZ)); t->flags = (t->flags & ~((0xffUL << TI_FLAG_CWP_SHIFT) | (0xffUL << TI_FLAG_CURRENT_DS_SHIFT))) | _TIF_NEWCHILD | (((regs->tstate + 1) & TSTATE_CWP) << TI_FLAG_CWP_SHIFT); t->ksp = ((unsigned long) child_trap_frame) - STACK_BIAS; - t->kregs = (struct pt_regs *)(child_trap_frame+sizeof(struct reg_window)); + t->kregs = (struct pt_regs *)(child_trap_frame+sizeof(struct sparc_stackf)); t->fpsaved[0] = 0; if (regs->tstate & TSTATE_PRIV) { @@ -636,7 +637,7 @@ flush_register_windows(); memcpy((void *)(t->ksp + STACK_BIAS), (void *)(regs->u_regs[UREG_FP] + STACK_BIAS), - sizeof(struct reg_window)); + sizeof(struct sparc_stackf)); t->kregs->u_regs[UREG_G6] = (unsigned long) t; t->kregs->u_regs[UREG_G4] = (unsigned long) t->task; } else { diff -urN linux-2.5.66-bk9/arch/sparc64/kernel/rtrap.S linux-2.5.66-bk10/arch/sparc64/kernel/rtrap.S --- linux-2.5.66-bk9/arch/sparc64/kernel/rtrap.S 2003-04-04 04:32:48.000000000 -0800 +++ linux-2.5.66-bk10/arch/sparc64/kernel/rtrap.S 2003-04-04 04:32:52.000000000 -0800 @@ -59,7 +59,7 @@ clr %o0 mov %l5, %o2 mov %l6, %o3 - add %sp, STACK_BIAS + REGWIN_SZ, %o1 + add %sp, PTREGS_OFF, %o1 mov %l0, %o4 call do_notify_resume @@ -103,7 +103,7 @@ clr %o0 mov %l5, %o2 mov %l6, %o3 - add %sp, STACK_BIAS + REGWIN_SZ, %o1 + add %sp, PTREGS_OFF, %o1 mov %l0, %o4 call do_notify_resume @@ -132,7 +132,7 @@ clr %o0 mov %l5, %o2 mov %l6, %o3 - add %sp, STACK_BIAS + REGWIN_SZ, %o1 + add %sp, PTREGS_OFF, %o1 mov %l0, %o4 call do_notify_resume wrpr %g0, RTRAP_PSTATE, %pstate diff -urN linux-2.5.66-bk9/arch/sparc64/kernel/signal32.c linux-2.5.66-bk10/arch/sparc64/kernel/signal32.c --- linux-2.5.66-bk9/arch/sparc64/kernel/signal32.c 2003-03-24 13:59:53.000000000 -0800 +++ linux-2.5.66-bk10/arch/sparc64/kernel/signal32.c 2003-04-04 04:32:52.000000000 -0800 @@ -812,7 +812,7 @@ save_and_clear_fpu(); regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; - sfp = (svr4_signal_frame_t *) get_sigframe(sa, regs, REGWIN_SZ + SVR4_SF_ALIGNED); + sfp = (svr4_signal_frame_t *) get_sigframe(sa, regs, sizeof(struct reg_window32) + SVR4_SF_ALIGNED); if (invalid_frame_pointer (sfp, sizeof (*sfp))) do_exit(SIGILL); diff -urN linux-2.5.66-bk9/arch/sparc64/kernel/sparc64_ksyms.c linux-2.5.66-bk10/arch/sparc64/kernel/sparc64_ksyms.c --- linux-2.5.66-bk9/arch/sparc64/kernel/sparc64_ksyms.c 2003-04-04 04:32:48.000000000 -0800 +++ linux-2.5.66-bk10/arch/sparc64/kernel/sparc64_ksyms.c 2003-04-04 04:32:52.000000000 -0800 @@ -379,3 +379,5 @@ /* for solaris compat module */ EXPORT_SYMBOL_GPL(sys_call_table); + +EXPORT_SYMBOL(tick_ops); diff -urN linux-2.5.66-bk9/arch/sparc64/kernel/trampoline.S linux-2.5.66-bk10/arch/sparc64/kernel/trampoline.S --- linux-2.5.66-bk9/arch/sparc64/kernel/trampoline.S 2003-03-24 14:00:18.000000000 -0800 +++ linux-2.5.66-bk10/arch/sparc64/kernel/trampoline.S 2003-04-04 04:32:52.000000000 -0800 @@ -195,7 +195,7 @@ mov 1, %g5 sllx %g5, THREAD_SHIFT, %g5 - sub %g5, (REGWIN_SZ + STACK_BIAS), %g5 + sub %g5, (STACKFRAME_SZ + STACK_BIAS), %g5 add %g6, %g5, %sp mov 0, %fp diff -urN linux-2.5.66-bk9/arch/sparc64/kernel/us2e_cpufreq.c linux-2.5.66-bk10/arch/sparc64/kernel/us2e_cpufreq.c --- linux-2.5.66-bk9/arch/sparc64/kernel/us2e_cpufreq.c 2003-04-04 04:32:48.000000000 -0800 +++ linux-2.5.66-bk10/arch/sparc64/kernel/us2e_cpufreq.c 2003-04-04 04:32:52.000000000 -0800 @@ -256,7 +256,8 @@ freqs.cpu = cpu; cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - us2e_transition(estar, new_bits, clock_tick, old_divisor, divisor); + if (old_divisor != divisor) + us2e_transition(estar, new_bits, clock_tick, old_divisor, divisor); cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); @@ -314,7 +315,7 @@ return cpufreq_frequency_table_cpuinfo(policy, table); } -static int __exit us2e_freq_cpu_exit(struct cpufreq_policy *policy) +static int us2e_freq_cpu_exit(struct cpufreq_policy *policy) { if (cpufreq_us2e_driver) us2e_set_cpu_divider_index(policy->cpu, 0); diff -urN linux-2.5.66-bk9/arch/sparc64/kernel/us3_cpufreq.c linux-2.5.66-bk10/arch/sparc64/kernel/us3_cpufreq.c --- linux-2.5.66-bk9/arch/sparc64/kernel/us3_cpufreq.c 2003-04-04 04:32:48.000000000 -0800 +++ linux-2.5.66-bk10/arch/sparc64/kernel/us3_cpufreq.c 2003-04-04 04:32:52.000000000 -0800 @@ -169,7 +169,7 @@ return cpufreq_frequency_table_cpuinfo(policy, table); } -static int __exit us3_freq_cpu_exit(struct cpufreq_policy *policy) +static int us3_freq_cpu_exit(struct cpufreq_policy *policy) { if (cpufreq_us3_driver) us3_set_cpu_divider_index(policy->cpu, 0); diff -urN linux-2.5.66-bk9/arch/sparc64/kernel/winfixup.S linux-2.5.66-bk10/arch/sparc64/kernel/winfixup.S --- linux-2.5.66-bk9/arch/sparc64/kernel/winfixup.S 2003-03-24 14:00:23.000000000 -0800 +++ linux-2.5.66-bk10/arch/sparc64/kernel/winfixup.S 2003-04-04 04:32:52.000000000 -0800 @@ -80,7 +80,7 @@ * since we must preserve %l5 and %l6, see comment above. */ call do_sparc64_fault - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap nop ! yes, nop is correct @@ -158,7 +158,7 @@ ba,pt %xcc, etrap rd %pc, %g7 call do_sparc64_fault - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 ba,a,pt %xcc, rtrap_clr_l6 .globl winfix_mna, fill_fixup_mna, spill_fixup_mna @@ -197,7 +197,7 @@ mov %o7, %g6 ! Get current back. ldx [%g6 + TI_TASK], %g4 ! Finish it. call mem_address_unaligned - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 b,pt %xcc, rtrap nop ! yes, the nop is correct @@ -258,7 +258,7 @@ mov %l4, %o2 mov %l5, %o1 call mem_address_unaligned - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap clr %l6 @@ -303,7 +303,7 @@ mov %o7, %g6 ! Get current back. ldx [%g6 + TI_TASK], %g4 ! Finish it. call data_access_exception - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 b,pt %xcc, rtrap nop ! yes, the nop is correct @@ -364,7 +364,7 @@ mov %l4, %o1 mov %l5, %o2 call data_access_exception - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 ba,pt %xcc, rtrap clr %l6 diff -urN linux-2.5.66-bk9/arch/sparc64/mm/ultra.S linux-2.5.66-bk10/arch/sparc64/mm/ultra.S --- linux-2.5.66-bk9/arch/sparc64/mm/ultra.S 2003-03-24 14:01:12.000000000 -0800 +++ linux-2.5.66-bk10/arch/sparc64/mm/ultra.S 2003-04-04 04:32:52.000000000 -0800 @@ -594,7 +594,7 @@ b,pt %xcc, etrap_irq 109: or %g7, %lo(109b), %g7 call __show_regs - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 clr %l6 /* Has to be a non-v9 branch due to the large distance. */ b rtrap_xcall diff -urN linux-2.5.66-bk9/arch/sparc64/solaris/entry64.S linux-2.5.66-bk10/arch/sparc64/solaris/entry64.S --- linux-2.5.66-bk9/arch/sparc64/solaris/entry64.S 2003-03-24 13:59:53.000000000 -0800 +++ linux-2.5.66-bk10/arch/sparc64/solaris/entry64.S 2003-04-04 04:32:52.000000000 -0800 @@ -34,7 +34,7 @@ be,pt %icc, 2f srl %i2, 0, %o2 b,pt %xcc, 2f - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 solaris_sucks: /* Solaris is a big system which needs to be able to do all the things @@ -91,7 +91,7 @@ sethi %hi(sys_call_table32), %l6 andcc %l3, 1, %g0 bne,a,pn %icc, 10f - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 10: srl %i2, 0, %o2 mov %i5, %o5 andn %l3, 3, %l7 @@ -101,11 +101,11 @@ 2: call %l7 srl %i3, 0, %o3 ret_from_solaris: - stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0] + stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] ldx [%g6 + TI_FLAGS], %l6 sra %o0, 0, %o0 mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2 - ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TSTATE], %g3 + ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3 cmp %o0, -ENOIOCTLCMD sllx %g2, 32, %g2 bgeu,pn %xcc, 1f @@ -113,21 +113,21 @@ /* System call success, clear Carry condition code. */ andn %g3, %g2, %g3 - stx %g3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TSTATE] + stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] bne,pn %icc, solaris_syscall_trace2 - ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC], %l1 + ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 andcc %l1, 1, %g0 bne,pn %icc, 2f clr %l6 add %l1, 0x4, %l2 - stx %l1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TPC] ! pc = npc + stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] ! pc = npc call rtrap - stx %l2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC] !npc = npc+4 + stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] !npc = npc+4 /* When tnpc & 1, this comes from setcontext and we don't want to advance pc */ 2: andn %l1, 3, %l1 call rtrap - stx %l1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC] !npc = npc&~3 + stx %l1, [%sp + PTREGS_OFF + PT_V9_TNPC] !npc = npc&~3 1: /* System call failure, set Carry condition code. @@ -143,17 +143,17 @@ sll %o0, 2, %o0 or %l6, %lo(solaris_err_table), %l6 ldsw [%l6 + %o0], %o0 -1: stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0] +1: stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] mov 1, %l6 - stx %g3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TSTATE] + stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] bne,pn %icc, solaris_syscall_trace2 - ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC], %l1 + ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 andcc %l1, 1, %g0 bne,pn %icc, 2b add %l1, 0x4, %l2 - stx %l1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TPC] ! pc = npc + stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] ! pc = npc call rtrap - stx %l2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC] !npc = npc+4 + stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] !npc = npc+4 solaris_syscall_trace2: call syscall_trace @@ -161,9 +161,9 @@ andcc %l1, 1, %g0 bne,pn %icc, 2b nop - stx %l1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TPC] + stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] call rtrap - stx %l2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC] + stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] /* This one is tricky, so that's why we do it in assembly */ .globl solaris_sigsuspend @@ -173,14 +173,14 @@ brlz,pn %o0, ret_from_solaris nop call sys_sigsuspend - stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0] + stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] .globl solaris_getpid solaris_getpid: call sys_getppid nop call sys_getpid - stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1] + stx %o0, [%sp + PTREGS_OFF + PT_V9_I1] b,pt %xcc, ret_from_solaris nop @@ -189,7 +189,7 @@ call sys_geteuid nop call sys_getuid - stx %o1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1] + stx %o1, [%sp + PTREGS_OFF + PT_V9_I1] b,pt %xcc, ret_from_solaris nop @@ -198,14 +198,14 @@ call sys_getegid nop call sys_getgid - stx %o1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1] + stx %o1, [%sp + PTREGS_OFF + PT_V9_I1] b,pt %xcc, ret_from_solaris nop .globl solaris_unimplemented solaris_unimplemented: call do_sol_unimplemented - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + add %sp, PTREGS_OFF, %o0 ba,pt %xcc, ret_from_solaris nop diff -urN linux-2.5.66-bk9/crypto/deflate.c linux-2.5.66-bk10/crypto/deflate.c --- linux-2.5.66-bk9/crypto/deflate.c 2003-04-04 04:32:48.000000000 -0800 +++ linux-2.5.66-bk10/crypto/deflate.c 2003-04-04 04:32:52.000000000 -0800 @@ -32,6 +32,7 @@ #include #include #include +#include #define DEFLATE_DEF_LEVEL Z_DEFAULT_COMPRESSION #define DEFLATE_DEF_WINBITS 11 @@ -181,7 +182,18 @@ stream->next_out = (u8 *)dst; stream->avail_out = *dlen; - ret = zlib_inflate(stream, Z_FINISH); + ret = zlib_inflate(stream, Z_SYNC_FLUSH); + /* + * Work around a bug in zlib, which sometimes wants to taste an extra + * byte when being used in the (undocumented) raw deflate mode. + * (From USAGI). + */ + if (ret == Z_OK && !stream->avail_in && stream->avail_out) { + u8 zerostuff = 0; + stream->next_in = &zerostuff; + stream->avail_in = 1; + ret = zlib_inflate(stream, Z_FINISH); + } if (ret != Z_STREAM_END) { ret = -EINVAL; goto out; diff -urN linux-2.5.66-bk9/drivers/atm/iphase.c linux-2.5.66-bk10/drivers/atm/iphase.c --- linux-2.5.66-bk9/drivers/atm/iphase.c 2003-04-04 04:32:48.000000000 -0800 +++ linux-2.5.66-bk10/drivers/atm/iphase.c 2003-04-04 04:32:52.000000000 -0800 @@ -2976,7 +2976,7 @@ make it aligned on a 48 byte boundary. */ total_len = skb->len + sizeof(struct cpcs_trailer); total_len = ((total_len + 47) / 48) * 48; - IF_TX(printk("ia packet len:%d padding:%d\n", total_len, pad);) + IF_TX(printk("ia packet len:%d padding:%d\n", total_len, total_len - skb->len);) /* Put the packet in a tx buffer */ trailer = iadev->tx_buf[desc-1].cpcs; diff -urN linux-2.5.66-bk9/drivers/base/cpu.c linux-2.5.66-bk10/drivers/base/cpu.c --- linux-2.5.66-bk9/drivers/base/cpu.c 2003-04-04 04:32:48.000000000 -0800 +++ linux-2.5.66-bk10/drivers/base/cpu.c 2003-04-04 04:32:52.000000000 -0800 @@ -49,8 +49,12 @@ int __init cpu_dev_init(void) { int error; - if (!(error = devclass_register(&cpu_devclass))) - if ((error = driver_register(&cpu_driver))) + + error = devclass_register(&cpu_devclass); + if (!error) { + error = driver_register(&cpu_driver); + if (error) devclass_unregister(&cpu_devclass); + } return error; } diff -urN linux-2.5.66-bk9/drivers/base/memblk.c linux-2.5.66-bk10/drivers/base/memblk.c --- linux-2.5.66-bk9/drivers/base/memblk.c 2003-04-04 04:32:48.000000000 -0800 +++ linux-2.5.66-bk10/drivers/base/memblk.c 2003-04-04 04:32:52.000000000 -0800 @@ -50,9 +50,13 @@ int __init register_memblk_type(void) { int error; - if (!(error = devclass_register(&memblk_devclass))) - if (error = driver_register(&memblk_driver)) + + error = devclass_register(&memblk_devclass); + if (!error) { + error = driver_register(&memblk_driver); + if (error) devclass_unregister(&memblk_devclass); + } return error; } postcore_initcall(register_memblk_type); diff -urN linux-2.5.66-bk9/drivers/base/node.c linux-2.5.66-bk10/drivers/base/node.c --- linux-2.5.66-bk9/drivers/base/node.c 2003-04-04 04:32:48.000000000 -0800 +++ linux-2.5.66-bk10/drivers/base/node.c 2003-04-04 04:32:52.000000000 -0800 @@ -92,9 +92,13 @@ int __init register_node_type(void) { int error; - if (!(error = devclass_register(&node_devclass))) - if (error = driver_register(&node_driver)) + + error = devclass_register(&node_devclass); + if (!error) { + error = driver_register(&node_driver); + if (error) devclass_unregister(&node_devclass); + } return error; } postcore_initcall(register_node_type); diff -urN linux-2.5.66-bk9/drivers/block/ll_rw_blk.c linux-2.5.66-bk10/drivers/block/ll_rw_blk.c --- linux-2.5.66-bk9/drivers/block/ll_rw_blk.c 2003-03-24 14:00:00.000000000 -0800 +++ linux-2.5.66-bk10/drivers/block/ll_rw_blk.c 2003-04-04 04:32:52.000000000 -0800 @@ -188,7 +188,7 @@ * Caveat: * The driver that does this *must* be able to deal appropriately * with buffers in "highmemory". This can be accomplished by either calling - * bio_kmap() to get a temporary kernel mapping, or by calling + * __bio_kmap_atomic() to get a temporary kernel mapping, or by calling * blk_queue_bounce() to create a buffer in normal memory. **/ void blk_queue_make_request(request_queue_t * q, make_request_fn * mfn) diff -urN linux-2.5.66-bk9/drivers/char/hangcheck-timer.c linux-2.5.66-bk10/drivers/char/hangcheck-timer.c --- linux-2.5.66-bk9/drivers/char/hangcheck-timer.c 2003-03-24 14:00:20.000000000 -0800 +++ linux-2.5.66-bk10/drivers/char/hangcheck-timer.c 2003-04-04 04:32:52.000000000 -0800 @@ -78,11 +78,13 @@ static struct timer_list hangcheck_ticktock = TIMER_INITIALIZER(hangcheck_fire, 0, 0); +extern unsigned long long monotonic_clock(void); + static void hangcheck_fire(unsigned long data) { unsigned long long cur_tsc, tsc_diff; - cur_tsc = get_cycles(); + cur_tsc = monotonic_clock(); if (cur_tsc > hangcheck_tsc) tsc_diff = cur_tsc - hangcheck_tsc; @@ -98,7 +100,7 @@ } } mod_timer(&hangcheck_ticktock, jiffies + (hangcheck_tick*HZ)); - hangcheck_tsc = get_cycles(); + hangcheck_tsc = monotonic_clock(); } @@ -108,10 +110,10 @@ VERSION_STR, hangcheck_tick, hangcheck_margin); hangcheck_tsc_margin = hangcheck_margin + hangcheck_tick; - hangcheck_tsc_margin *= HZ; - hangcheck_tsc_margin *= current_cpu_data.loops_per_jiffy; + hangcheck_tsc_margin *= 1000000000; + - hangcheck_tsc = get_cycles(); + hangcheck_tsc = monotonic_clock(); mod_timer(&hangcheck_ticktock, jiffies + (hangcheck_tick*HZ)); return 0; diff -urN linux-2.5.66-bk9/drivers/char/vt.c linux-2.5.66-bk10/drivers/char/vt.c --- linux-2.5.66-bk9/drivers/char/vt.c 2003-04-04 04:32:48.000000000 -0800 +++ linux-2.5.66-bk10/drivers/char/vt.c 2003-04-04 04:32:52.000000000 -0800 @@ -1313,6 +1313,9 @@ case 14: /* set vesa powerdown interval */ vesa_off_interval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ; break; + case 15: /* Activate the previous console */ + set_console(last_console); + break; } } @@ -2210,6 +2213,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) { char type, data; + int lines; int ret; if (tty->driver.type != TTY_DRIVER_TYPE_CONSOLE) @@ -2266,6 +2270,14 @@ case 12: /* get fg_console */ ret = fg_console; break; + case 13: /* scroll console */ + if (get_user(lines, (char *)arg+1)) { + ret = -EFAULT; + } else { + scrollfront(lines); + ret = 0; + } + break; default: ret = -EINVAL; break; diff -urN linux-2.5.66-bk9/drivers/md/linear.c linux-2.5.66-bk10/drivers/md/linear.c --- linux-2.5.66-bk9/drivers/md/linear.c 2003-04-04 04:32:49.000000000 -0800 +++ linux-2.5.66-bk10/drivers/md/linear.c 2003-04-04 04:32:52.000000000 -0800 @@ -91,6 +91,8 @@ conf->smallest = NULL; cnt = 0; + mddev->array_size = 0; + ITERATE_RDEV(mddev,rdev,tmp) { int j = rdev->raid_disk; dev_info_t *disk = conf->disks + j; @@ -102,6 +104,7 @@ disk->rdev = rdev; disk->size = rdev->size; + mddev->array_size += rdev->size; if (!conf->smallest || (disk->size < conf->smallest->size)) conf->smallest = disk; @@ -121,7 +124,7 @@ unsigned round; unsigned long base; - sz = md_size[mdidx(mddev)]; + sz = mddev->array_size; base = conf->smallest->size; round = sector_div(sz, base); nb_zone = conf->nr_zones = sz + (round ? 1 : 0); diff -urN linux-2.5.66-bk9/drivers/md/md.c linux-2.5.66-bk10/drivers/md/md.c --- linux-2.5.66-bk9/drivers/md/md.c 2003-04-04 04:32:49.000000000 -0800 +++ linux-2.5.66-bk10/drivers/md/md.c 2003-04-04 04:32:52.000000000 -0800 @@ -125,8 +125,6 @@ { .ctl_name = 0 } }; -sector_t md_size[MAX_MD_DEVS]; - static struct block_device_operations md_fops; static struct gendisk *disks[MAX_MD_DEVS]; @@ -288,21 +286,6 @@ return size; } -static sector_t zoned_raid_size(mddev_t *mddev) -{ - mdk_rdev_t * rdev; - struct list_head *tmp; - - /* - * do size and offset calculations. - */ - - ITERATE_RDEV(mddev,rdev,tmp) - md_size[mdidx(mddev)] += rdev->size; - - return 0; -} - static int alloc_disk_sb(mdk_rdev_t * rdev) { if (rdev->sb_page) @@ -1172,7 +1155,7 @@ static void print_rdev(mdk_rdev_t *rdev) { - printk(KERN_INFO "md: rdev %s, SZ:%08llu F:%d S:%d DN:%d ", + printk(KERN_INFO "md: rdev %s, SZ:%08llu F:%d S:%d DN:%u\n", bdev_partition_name(rdev->bdev), (unsigned long long)rdev->size, rdev->faulty, rdev->in_sync, rdev->desc_nr); if (rdev->sb_loaded) { @@ -1197,6 +1180,7 @@ ITERATE_RDEV(mddev,rdev,tmp2) printk("<%s>", bdev_partition_name(rdev->bdev)); + printk("\n"); ITERATE_RDEV(mddev,rdev,tmp2) print_rdev(rdev); @@ -1453,87 +1437,6 @@ return 1; } -static int device_size_calculation(mddev_t * mddev) -{ - int data_disks = 0; - unsigned int readahead; - struct list_head *tmp; - mdk_rdev_t *rdev; - - /* - * Do device size calculation. Bail out if too small. - * (we have to do this after having validated chunk_size, - * because device size has to be modulo chunk_size) - */ - - ITERATE_RDEV(mddev,rdev,tmp) { - if (rdev->faulty) - continue; - if (rdev->size < mddev->chunk_size / 1024) { - printk(KERN_WARNING - "md: Dev %s smaller than chunk_size:" - " %lluk < %dk\n", - bdev_partition_name(rdev->bdev), - (unsigned long long)rdev->size, - mddev->chunk_size / 1024); - return -EINVAL; - } - } - - switch (mddev->level) { - case LEVEL_MULTIPATH: - data_disks = 1; - break; - case -3: - data_disks = 1; - break; - case -2: - data_disks = 1; - break; - case LEVEL_LINEAR: - zoned_raid_size(mddev); - data_disks = 1; - break; - case 0: - zoned_raid_size(mddev); - data_disks = mddev->raid_disks; - break; - case 1: - data_disks = 1; - break; - case 4: - case 5: - data_disks = mddev->raid_disks-1; - break; - default: - printk(KERN_ERR "md: md%d: unsupported raid level %d\n", - mdidx(mddev), mddev->level); - goto abort; - } - if (!md_size[mdidx(mddev)]) - md_size[mdidx(mddev)] = mddev->size * data_disks; - - readahead = (VM_MAX_READAHEAD * 1024) / PAGE_SIZE; - if (!mddev->level || (mddev->level == 4) || (mddev->level == 5)) { - readahead = (mddev->chunk_size>>PAGE_SHIFT) * 4 * data_disks; - if (readahead < data_disks * (MAX_SECTORS>>(PAGE_SHIFT-9))*2) - readahead = data_disks * (MAX_SECTORS>>(PAGE_SHIFT-9))*2; - } else { - // (no multipath branch - it uses the default setting) - if (mddev->level == -3) - readahead = 0; - } - - printk(KERN_INFO "md%d: max total readahead window set to %ldk\n", - mdidx(mddev), readahead*(PAGE_SIZE/1024)); - - printk(KERN_INFO - "md%d: %d data-disks, max readahead per data-disk: %ldk\n", - mdidx(mddev), data_disks, readahead/data_disks*(PAGE_SIZE/1024)); - return 0; -abort: - return 1; -} static struct gendisk *md_probe(dev_t dev, int *part, void *data) { @@ -1597,12 +1500,6 @@ return -EBUSY; /* - * Resize disks to align partitions size on a given - * chunk size. - */ - md_size[mdidx(mddev)] = 0; - - /* * Analyze all RAID superblock(s) */ if (!mddev->raid_disks && analyze_sbs(mddev)) { @@ -1642,6 +1539,21 @@ chunk_size, PAGE_SIZE); return -EINVAL; } + + /* devices must have minimum size of one chunk */ + ITERATE_RDEV(mddev,rdev,tmp) { + if (rdev->faulty) + continue; + if (rdev->size < chunk_size / 1024) { + printk(KERN_WARNING + "md: Dev %s smaller than chunk_size:" + " %lluk < %dk\n", + bdev_partition_name(rdev->bdev), + (unsigned long long)rdev->size, + chunk_size / 1024); + return -EINVAL; + } + } } if (pnum >= MAX_PERSONALITY) { @@ -1658,9 +1570,6 @@ } #endif - if (device_size_calculation(mddev)) - return -EINVAL; - /* * Drop all container device buffers, from now on * the only valid external interface is through the md @@ -1672,18 +1581,6 @@ continue; sync_blockdev(rdev->bdev); invalidate_bdev(rdev->bdev, 0); -#if 0 - /* - * Aside of obvious breakage (code below results in block size set - * according to the sector size of last component instead of the - * maximal sector size), we have more interesting problem here. - * Namely, we actually ought to set _sector_ size for the array - * and that requires per-array request queues. Disabled for now. - */ - md_blocksizes[mdidx(mddev)] = 1024; - if (bdev_hardsect_size(rdev->bdev) > md_blocksizes[mdidx(mddev)]) - md_blocksizes[mdidx(mddev)] = bdev_hardsect_size(rdev->bdev); -#endif } md_probe(mdidx(mddev), NULL, NULL); @@ -1714,8 +1611,8 @@ err = mddev->pers->run(mddev); if (err) { printk(KERN_ERR "md: pers->run() failed ...\n"); - mddev->pers = NULL; module_put(mddev->pers->owner); + mddev->pers = NULL; return -EINVAL; } atomic_set(&mddev->writes_pending,0); @@ -1727,8 +1624,8 @@ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); md_wakeup_thread(mddev->thread); - set_capacity(disk, md_size[mdidx(mddev)]<<1); - return (0); + set_capacity(disk, mddev->array_size<<1); + return 0; } static int restart_array(mddev_t *mddev) @@ -1828,7 +1725,7 @@ export_array(mddev); - md_size[mdidx(mddev)] = 0; + mddev->array_size = 0; disk = disks[mdidx(mddev)]; if (disk) set_capacity(disk, 0); @@ -3052,9 +2949,10 @@ if (!list_empty(&mddev->disks)) { if (mddev->pers) seq_printf(seq, "\n %llu blocks", - (unsigned long long)md_size[mdidx(mddev)]); + (unsigned long long)mddev->array_size); else - seq_printf(seq, "\n %llu blocks", (unsigned long long)size); + seq_printf(seq, "\n %llu blocks", + (unsigned long long)size); } if (mddev->pers) { @@ -3563,11 +3461,6 @@ static void md_geninit(void) { struct proc_dir_entry *p; - int i; - - for(i = 0; i < MAX_MD_DEVS; i++) { - md_size[i] = 0; - } dprintk("md: sizeof(mdp_super_t) = %d\n", (int)sizeof(mdp_super_t)); @@ -3682,7 +3575,6 @@ module_init(md_init) module_exit(md_exit) -EXPORT_SYMBOL(md_size); EXPORT_SYMBOL(register_md_personality); EXPORT_SYMBOL(unregister_md_personality); EXPORT_SYMBOL(md_error); diff -urN linux-2.5.66-bk9/drivers/md/multipath.c linux-2.5.66-bk10/drivers/md/multipath.c --- linux-2.5.66-bk9/drivers/md/multipath.c 2003-04-04 04:32:49.000000000 -0800 +++ linux-2.5.66-bk10/drivers/md/multipath.c 2003-04-04 04:32:52.000000000 -0800 @@ -438,6 +438,7 @@ /* * Ok, everything is just fine now */ + mddev->array_size = mddev->size; return 0; out_free_conf: diff -urN linux-2.5.66-bk9/drivers/md/raid0.c linux-2.5.66-bk10/drivers/md/raid0.c --- linux-2.5.66-bk9/drivers/md/raid0.c 2003-04-04 04:32:49.000000000 -0800 +++ linux-2.5.66-bk10/drivers/md/raid0.c 2003-04-04 04:32:52.000000000 -0800 @@ -196,6 +196,8 @@ sector_t zone0_size; s64 size; raid0_conf_t *conf; + mdk_rdev_t *rdev; + struct list_head *tmp; conf = vmalloc(sizeof (raid0_conf_t)); if (!conf) @@ -205,15 +207,20 @@ if (create_strip_zones (mddev)) goto out_free_conf; + /* calculate array device size */ + mddev->array_size = 0; + ITERATE_RDEV(mddev,rdev,tmp) + mddev->array_size += rdev->size; + printk("raid0 : md_size is %llu blocks.\n", - (unsigned long long)md_size[mdidx(mddev)]); + (unsigned long long)mddev->array_size); printk("raid0 : conf->smallest->size is %llu blocks.\n", (unsigned long long)conf->smallest->size); { #if __GNUC__ < 3 volatile #endif - sector_t s = md_size[mdidx(mddev)]; + sector_t s = mddev->array_size; int round = sector_div(s, (unsigned long)conf->smallest->size) ? 1 : 0; nb_zone = s + round; } diff -urN linux-2.5.66-bk9/drivers/md/raid1.c linux-2.5.66-bk10/drivers/md/raid1.c --- linux-2.5.66-bk9/drivers/md/raid1.c 2003-04-04 04:32:49.000000000 -0800 +++ linux-2.5.66-bk10/drivers/md/raid1.c 2003-04-04 04:32:52.000000000 -0800 @@ -1156,6 +1156,8 @@ /* * Ok, everything is just fine now */ + mddev->array_size = mddev->size; + return 0; out_free_conf: diff -urN linux-2.5.66-bk9/drivers/md/raid5.c linux-2.5.66-bk10/drivers/md/raid5.c --- linux-2.5.66-bk9/drivers/md/raid5.c 2003-04-04 04:32:49.000000000 -0800 +++ linux-2.5.66-bk10/drivers/md/raid5.c 2003-04-04 04:32:52.000000000 -0800 @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -634,12 +635,12 @@ else clen = len; if (clen > 0) { - char *ba = __bio_kmap(bio, i); + char *ba = __bio_kmap_atomic(bio, i, KM_USER0); if (frombio) memcpy(pa+page_offset, ba+b_offset, clen); else memcpy(ba+b_offset, pa+page_offset, clen); - __bio_kunmap(bio, i); + __bio_kunmap_atomic(ba, KM_USER0); } if (clen < len) /* hit end of page */ break; @@ -1549,7 +1550,8 @@ print_raid5_conf(conf); /* Ok, everything is just fine now */ - return (0); + mddev->array_size = mddev->size * (mddev->raid_disks - 1); + return 0; abort: if (conf) { print_raid5_conf(conf); diff -urN linux-2.5.66-bk9/drivers/net/3c59x.c linux-2.5.66-bk10/drivers/net/3c59x.c --- linux-2.5.66-bk9/drivers/net/3c59x.c 2003-03-24 13:59:53.000000000 -0800 +++ linux-2.5.66-bk10/drivers/net/3c59x.c 2003-04-04 04:32:52.000000000 -0800 @@ -464,6 +464,8 @@ CH_3CCFEM656_1, CH_3C450, CH_3C920, + CH_3C982A, + CH_3C982B, }; @@ -557,6 +559,11 @@ PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, {"3c920 Tornado", PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, + {"3c982 Hydra Dual Port A", + PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, }, + {"3c982 Hydra Dual Port B", + PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, }, + {0,}, /* 0 terminated list. */ }; @@ -601,6 +608,8 @@ { 0x10B7, 0x6564, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3CCFEM656_1 }, { 0x10B7, 0x4500, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C450 }, { 0x10B7, 0x9201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C920 }, + { 0x10B7, 0x1201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C982A }, + { 0x10B7, 0x1202, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C982B }, {0,} /* 0 terminated list. */ }; MODULE_DEVICE_TABLE(pci, vortex_pci_tbl); diff -urN linux-2.5.66-bk9/drivers/net/pppox.c linux-2.5.66-bk10/drivers/net/pppox.c --- linux-2.5.66-bk9/drivers/net/pppox.c 2003-03-24 14:01:25.000000000 -0800 +++ linux-2.5.66-bk10/drivers/net/pppox.c 2003-04-04 04:32:52.000000000 -0800 @@ -127,17 +127,13 @@ } static struct net_proto_family pppox_proto_family = { - PF_PPPOX, - pppox_create + .family = PF_PPPOX, + .create = pppox_create, }; static int __init pppox_init(void) { - int err = 0; - - err = sock_register(&pppox_proto_family); - - return err; + return sock_register(&pppox_proto_family); } static void __exit pppox_exit(void) diff -urN linux-2.5.66-bk9/drivers/net/shaper.c linux-2.5.66-bk10/drivers/net/shaper.c --- linux-2.5.66-bk9/drivers/net/shaper.c 2003-03-24 14:01:12.000000000 -0800 +++ linux-2.5.66-bk10/drivers/net/shaper.c 2003-04-04 04:32:52.000000000 -0800 @@ -336,7 +336,7 @@ if(sh_debug) printk("Clock = %ld, jiffies = %ld\n", SHAPERCB(skb)->shapeclock, jiffies); - if(time_before_eq(SHAPERCB(skb)->shapeclock - jiffies, SHAPER_BURST)) + if(time_before_eq(SHAPERCB(skb)->shapeclock, jiffies + SHAPER_BURST)) { /* * Pull the frame and get interrupts back on. diff -urN linux-2.5.66-bk9/drivers/sbus/char/aurora.c linux-2.5.66-bk10/drivers/sbus/char/aurora.c --- linux-2.5.66-bk9/drivers/sbus/char/aurora.c 2003-03-24 14:00:07.000000000 -0800 +++ linux-2.5.66-bk10/drivers/sbus/char/aurora.c 2003-04-04 04:32:52.000000000 -0800 @@ -662,11 +662,8 @@ if (sbus_readb(&bp->r[chip]->r[CD180_MSVR]) & MSVR_CD) wake_up_interruptible(&port->open_wait); else if (!((port->flags & ASYNC_CALLOUT_ACTIVE) && - (port->flags & ASYNC_CALLOUT_NOHUP))) { - MOD_INC_USE_COUNT; - if (schedule_task(&port->tqueue_hangup) == 0) - MOD_DEC_USE_COUNT; - } + (port->flags & ASYNC_CALLOUT_NOHUP))) + schedule_task(&port->tqueue_hangup); } /* We don't have such things yet. My aurora board has DTR and RTS swapped, but that doesn't count in this driver. Let's hope @@ -1212,11 +1209,8 @@ clear_bit(TTY_IO_ERROR, &port->tty->flags); #ifdef MODULE - if (port->count == 1) { - MOD_INC_USE_COUNT; - if((++bp->count) == 1) + if ((port->count == 1) && ((++bp->count) == 1)) bp->flags |= AURORA_BOARD_ACTIVE; - } #endif port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; @@ -1297,7 +1291,6 @@ bp->count = 0; } - MOD_DEC_USE_COUNT; if (!bp->count) bp->flags &= ~AURORA_BOARD_ACTIVE; #endif @@ -2210,7 +2203,6 @@ printk("do_aurora_hangup: end\n"); #endif } - MOD_DEC_USE_COUNT; } static void aurora_hangup(struct tty_struct * tty) @@ -2311,6 +2303,7 @@ /* memset(IRQ_to_board, 0, sizeof(IRQ_to_board));*/ memset(&aurora_driver, 0, sizeof(aurora_driver)); aurora_driver.magic = TTY_DRIVER_MAGIC; + aurora_driver.owner = THIS_MODULE; aurora_driver.name = "ttyA"; aurora_driver.major = AURORA_MAJOR; aurora_driver.num = AURORA_TNPORTS; diff -urN linux-2.5.66-bk9/drivers/scsi/aic7xxx/aic7xxx_osm.c linux-2.5.66-bk10/drivers/scsi/aic7xxx/aic7xxx_osm.c --- linux-2.5.66-bk9/drivers/scsi/aic7xxx/aic7xxx_osm.c 2003-03-24 13:59:57.000000000 -0800 +++ linux-2.5.66-bk10/drivers/scsi/aic7xxx/aic7xxx_osm.c 2003-04-04 04:32:52.000000000 -0800 @@ -4097,7 +4097,7 @@ { struct ahc_linux_target *targ; - del_timer(&dev->timer); + del_timer_sync(&dev->timer); targ = dev->target; targ->devices[dev->lun] = NULL; free(dev, M_DEVBUF); diff -urN linux-2.5.66-bk9/fs/afs/dir.c linux-2.5.66-bk10/fs/afs/dir.c --- linux-2.5.66-bk9/fs/afs/dir.c 2003-03-24 14:00:16.000000000 -0800 +++ linux-2.5.66-bk10/fs/afs/dir.c 2003-04-04 04:32:52.000000000 -0800 @@ -497,11 +497,7 @@ _enter("%s,%x",dentry->d_name.name,flags); - /* lock down the parent dentry so we can peer at it */ - read_lock(&dparent_lock); - parent = dget(dentry->d_parent); - read_unlock(&dparent_lock); - + parent = dget_parent(dentry); dir = parent->d_inode; inode = dentry->d_inode; diff -urN linux-2.5.66-bk9/fs/dcache.c linux-2.5.66-bk10/fs/dcache.c --- linux-2.5.66-bk9/fs/dcache.c 2003-03-24 14:00:02.000000000 -0800 +++ linux-2.5.66-bk10/fs/dcache.c 2003-04-04 04:32:52.000000000 -0800 @@ -27,12 +27,13 @@ #include #include #include +#include #define DCACHE_PARANOIA 1 /* #define DCACHE_DEBUG 1 */ spinlock_t dcache_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED; -rwlock_t dparent_lock __cacheline_aligned_in_smp = RW_LOCK_UNLOCKED; +seqlock_t rename_lock __cacheline_aligned_in_smp = SEQLOCK_UNLOCKED; static kmem_cache_t *dentry_cache; @@ -926,7 +927,7 @@ * is returned. The caller must use d_put to free the entry when it has * finished using it. %NULL is returned on failure. * - * d_lookup is now, dcache_lock free. The hash list is protected using RCU. + * __d_lookup is dcache_lock free. The hash list is protected using RCU. * Memory barriers are used while updating and doing lockless traversal. * To avoid races with d_move while rename is happening, d_move_count is * used. @@ -939,10 +940,27 @@ * * d_lru list is not updated, which can leave non-zero d_count dentries * around in d_lru list. + * + * d_lookup() is protected against the concurrent renames in some unrelated + * directory using the seqlockt_t rename_lock. */ struct dentry * d_lookup(struct dentry * parent, struct qstr * name) { + struct dentry * dentry = NULL; + unsigned long seq; + + do { + seq = read_seqbegin(&rename_lock); + dentry = __d_lookup(parent, name); + if (dentry) + break; + } while (read_seqretry(&rename_lock, seq)); + return dentry; +} + +struct dentry * __d_lookup(struct dentry * parent, struct qstr * name) +{ unsigned int len = name->len; unsigned int hash = name->hash; const unsigned char *str = name->name; @@ -1185,7 +1203,17 @@ printk(KERN_WARNING "VFS: moving negative dcache entry\n"); spin_lock(&dcache_lock); - spin_lock(&dentry->d_lock); + write_seqlock(&rename_lock); + /* + * XXXX: do we really need to take target->d_lock? + */ + if (target < dentry) { + spin_lock(&target->d_lock); + spin_lock(&dentry->d_lock); + } else { + spin_lock(&dentry->d_lock); + spin_lock(&target->d_lock); + } /* Move the dentry to the target hash queue, if on different bucket */ if (dentry->d_bucket != target->d_bucket) { @@ -1205,8 +1233,8 @@ smp_wmb(); do_switch(dentry->d_name.len, target->d_name.len); do_switch(dentry->d_name.hash, target->d_name.hash); + /* ... and switch the parents */ - write_lock(&dparent_lock); if (IS_ROOT(dentry)) { dentry->d_parent = target->d_parent; target->d_parent = target; @@ -1217,11 +1245,12 @@ /* And add them back to the (new) parent lists */ list_add(&target->d_child, &target->d_parent->d_subdirs); } - write_unlock(&dparent_lock); list_add(&dentry->d_child, &dentry->d_parent->d_subdirs); dentry->d_move_count++; + spin_unlock(&target->d_lock); spin_unlock(&dentry->d_lock); + write_sequnlock(&rename_lock); spin_unlock(&dcache_lock); } diff -urN linux-2.5.66-bk9/fs/dnotify.c linux-2.5.66-bk10/fs/dnotify.c --- linux-2.5.66-bk9/fs/dnotify.c 2003-03-24 14:00:14.000000000 -0800 +++ linux-2.5.66-bk10/fs/dnotify.c 2003-04-04 04:32:52.000000000 -0800 @@ -142,6 +142,29 @@ write_unlock(&dn_lock); } +/* + * This is hopelessly wrong, but unfixable without API changes. At + * least it doesn't oops the kernel... + * + * To safely access ->d_parent we need to keep d_move away from it. Use the + * dentry's d_lock for this. + */ +void dnotify_parent(struct dentry *dentry, unsigned long event) +{ + struct dentry *parent; + + spin_lock(&dentry->d_lock); + parent = dentry->d_parent; + if (parent->d_inode->i_dnotify_mask & event) { + dget(parent); + spin_unlock(&dentry->d_lock); + __inode_dir_notify(parent->d_inode, event); + dput(parent); + } else { + spin_unlock(&dentry->d_lock); + } +} + static int __init dnotify_init(void) { dn_cache = kmem_cache_create("dnotify_cache", diff -urN linux-2.5.66-bk9/fs/exportfs/expfs.c linux-2.5.66-bk10/fs/exportfs/expfs.c --- linux-2.5.66-bk9/fs/exportfs/expfs.c 2003-03-24 14:01:17.000000000 -0800 +++ linux-2.5.66-bk10/fs/exportfs/expfs.c 2003-04-04 04:32:52.000000000 -0800 @@ -140,13 +140,20 @@ noprogress= 0; while (target_dir->d_flags & DCACHE_DISCONNECTED && noprogress++ < 10) { struct dentry *pd = target_dir; - read_lock(&dparent_lock); - while (!IS_ROOT(pd) && - (pd->d_parent->d_flags & DCACHE_DISCONNECTED)) - pd = pd->d_parent; dget(pd); - read_unlock(&dparent_lock); + spin_lock(&pd->d_lock); + while (!IS_ROOT(pd) && + (pd->d_parent->d_flags&DCACHE_DISCONNECTED)) { + struct dentry *parent = pd->d_parent; + + dget(parent); + spin_unlock(&pd->d_lock); + dput(pd); + pd = parent; + spin_lock(&pd->d_lock); + } + spin_unlock(&pd->d_lock); if (!IS_ROOT(pd)) { /* must have found a connected parent - great */ @@ -469,11 +476,12 @@ fh[1] = inode->i_generation; if (connectable && !S_ISDIR(inode->i_mode)) { struct inode *parent; - read_lock(&dparent_lock); + + spin_lock(&dentry->d_lock); parent = dentry->d_parent->d_inode; fh[2] = parent->i_ino; fh[3] = parent->i_generation; - read_unlock(&dparent_lock); + spin_unlock(&dentry->d_lock); len = 4; type = 2; } diff -urN linux-2.5.66-bk9/fs/ext2/inode.c linux-2.5.66-bk10/fs/ext2/inode.c --- linux-2.5.66-bk9/fs/ext2/inode.c 2003-03-24 13:59:57.000000000 -0800 +++ linux-2.5.66-bk10/fs/ext2/inode.c 2003-04-04 04:32:52.000000000 -0800 @@ -52,11 +52,16 @@ } /* - * Called at each iput() + * Called at each iput(). + * + * The inode may be "bad" if ext2_read_inode() saw an error from + * ext2_get_inode(), so we need to check that to avoid freeing random disk + * blocks. */ -void ext2_put_inode (struct inode * inode) +void ext2_put_inode(struct inode *inode) { - ext2_discard_prealloc (inode); + if (!is_bad_inode(inode)) + ext2_discard_prealloc(inode); } /* diff -urN linux-2.5.66-bk9/fs/ext3/fsync.c linux-2.5.66-bk10/fs/ext3/fsync.c --- linux-2.5.66-bk9/fs/ext3/fsync.c 2003-04-04 04:32:49.000000000 -0800 +++ linux-2.5.66-bk10/fs/ext3/fsync.c 2003-04-04 04:32:52.000000000 -0800 @@ -72,6 +72,5 @@ * (they were dirtied by commit). But that's OK - the blocks are * safe in-journal, which is all fsync() needs to ensure. */ - ext3_force_commit(inode->i_sb); - return 0; + return ext3_force_commit(inode->i_sb); } diff -urN linux-2.5.66-bk9/fs/ext3/inode.c linux-2.5.66-bk10/fs/ext3/inode.c --- linux-2.5.66-bk9/fs/ext3/inode.c 2003-03-24 14:00:55.000000000 -0800 +++ linux-2.5.66-bk10/fs/ext3/inode.c 2003-04-04 04:32:52.000000000 -0800 @@ -178,10 +178,15 @@ /* * Called at each iput() + * + * The inode may be "bad" if ext3_read_inode() saw an error from + * ext3_get_inode(), so we need to check that to avoid freeing random disk + * blocks. */ -void ext3_put_inode (struct inode * inode) +void ext3_put_inode(struct inode *inode) { - ext3_discard_prealloc (inode); + if (!is_bad_inode(inode)) + ext3_discard_prealloc(inode); } /* @@ -1160,6 +1165,12 @@ if (pos > inode->i_size) inode->i_size = pos; EXT3_I(inode)->i_state |= EXT3_STATE_JDATA; + if (inode->i_size > EXT3_I(inode)->i_disksize) { + EXT3_I(inode)->i_disksize = inode->i_size; + ret2 = ext3_mark_inode_dirty(handle, inode); + if (!ret) + ret = ret2; + } } else { if (ext3_should_order_data(inode)) { ret = walk_page_buffers(handle, page_buffers(page), @@ -1167,14 +1178,18 @@ } /* Be careful here if generic_commit_write becomes a * required invocation after block_prepare_write. */ - if (ret == 0) + if (ret == 0) { + /* + * generic_commit_write() will run mark_inode_dirty() + * if i_size changes. So let's piggyback the + * i_disksize mark_inode_dirty into that. + */ + loff_t new_i_size = + ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; + if (new_i_size > EXT3_I(inode)->i_disksize) + EXT3_I(inode)->i_disksize = new_i_size; ret = generic_commit_write(file, page, from, to); - } - if (inode->i_size > EXT3_I(inode)->i_disksize) { - EXT3_I(inode)->i_disksize = inode->i_size; - ret2 = ext3_mark_inode_dirty(handle, inode); - if (!ret) - ret = ret2; + } } ret2 = ext3_journal_stop(handle); unlock_kernel(); @@ -2349,9 +2364,10 @@ /* * Post the struct inode info into an on-disk inode location in the * buffer-cache. This gobbles the caller's reference to the - * buffer_head in the inode location struct. + * buffer_head in the inode location struct. + * + * The caller must have write access to iloc->bh. */ - static int ext3_do_update_inode(handle_t *handle, struct inode *inode, struct ext3_iloc *iloc) @@ -2361,12 +2377,6 @@ struct buffer_head *bh = iloc->bh; int err = 0, rc, block; - if (handle) { - BUFFER_TRACE(bh, "get_write_access"); - err = ext3_journal_get_write_access(handle, bh); - if (err) - goto out_brelse; - } /* For fields not not tracking in the in-memory inode, * initialise them to zero for new inodes. */ if (ei->i_state & EXT3_STATE_NEW) @@ -2628,22 +2638,21 @@ return ret; } -int -ext3_mark_iloc_dirty(handle_t *handle, - struct inode *inode, - struct ext3_iloc *iloc) +/* + * The caller must have previously called ext3_reserve_inode_write(). + * Give this, we know that the caller already has write access to iloc->bh. + */ +int ext3_mark_iloc_dirty(handle_t *handle, + struct inode *inode, struct ext3_iloc *iloc) { int err = 0; - if (handle) { - /* the do_update_inode consumes one bh->b_count */ - atomic_inc(&iloc->bh->b_count); - err = ext3_do_update_inode(handle, inode, iloc); - /* ext3_do_update_inode() does journal_dirty_metadata */ - brelse(iloc->bh); - } else { - printk(KERN_EMERG "%s: called with no handle!\n", __FUNCTION__); - } + /* the do_update_inode consumes one bh->b_count */ + get_bh(iloc->bh); + + /* ext3_do_update_inode() does journal_dirty_metadata */ + err = ext3_do_update_inode(handle, inode, iloc); + put_bh(iloc->bh); return err; } diff -urN linux-2.5.66-bk9/fs/fat/inode.c linux-2.5.66-bk10/fs/fat/inode.c --- linux-2.5.66-bk9/fs/fat/inode.c 2003-03-24 14:00:21.000000000 -0800 +++ linux-2.5.66-bk10/fs/fat/inode.c 2003-04-04 04:32:52.000000000 -0800 @@ -624,9 +624,9 @@ fh[1] = inode->i_generation; fh[2] = MSDOS_I(inode)->i_location; fh[3] = MSDOS_I(inode)->i_logstart; - read_lock(&dparent_lock); + spin_lock(&de->d_lock); fh[4] = MSDOS_I(de->d_parent->d_inode)->i_logstart; - read_unlock(&dparent_lock); + spin_unlock(&de->d_lock); return 3; } diff -urN linux-2.5.66-bk9/fs/jbd/commit.c linux-2.5.66-bk10/fs/jbd/commit.c --- linux-2.5.66-bk9/fs/jbd/commit.c 2003-03-24 14:01:24.000000000 -0800 +++ linux-2.5.66-bk10/fs/jbd/commit.c 2003-04-04 04:32:52.000000000 -0800 @@ -73,7 +73,7 @@ #endif lock_kernel(); - + J_ASSERT (journal->j_running_transaction != NULL); J_ASSERT (journal->j_committing_transaction == NULL); @@ -173,6 +173,7 @@ * on the transaction lists. Data blocks go first. */ + err = 0; /* * Whenever we unlock the journal and sleep, things can get added * onto ->t_datalist, so we have to keep looping back to write_out_data @@ -251,9 +252,13 @@ jh = jh->b_tprev; /* Wait on the last written */ bh = jh2bh(jh); if (buffer_locked(bh)) { + get_bh(bh); spin_unlock(&journal_datalist_lock); unlock_journal(journal); wait_on_buffer(bh); + if (unlikely(!buffer_uptodate(bh))) + err = -EIO; + put_bh(bh); /* the journal_head may have been removed now */ lock_journal(journal); goto write_out_data; @@ -446,7 +451,10 @@ jbd_debug(3, "JBD: commit phase 4\n"); - /* akpm: these are BJ_IO, and journal_datalist_lock is not needed */ + /* + * akpm: these are BJ_IO, and journal_datalist_lock is not needed. + * See __journal_try_to_free_buffer. + */ wait_for_iobuf: while (commit_transaction->t_iobuf_list != NULL) { struct buffer_head *bh; @@ -455,6 +463,8 @@ if (buffer_locked(bh)) { unlock_journal(journal); wait_on_buffer(bh); + if (unlikely(!buffer_uptodate(bh))) + err = -EIO; lock_journal(journal); goto wait_for_iobuf; } @@ -516,6 +526,8 @@ if (buffer_locked(bh)) { unlock_journal(journal); wait_on_buffer(bh); + if (unlikely(!buffer_uptodate(bh))) + err = -EIO; lock_journal(journal); goto wait_for_ctlbuf; } @@ -563,7 +575,9 @@ struct buffer_head *bh = jh2bh(descriptor); set_buffer_uptodate(bh); sync_dirty_buffer(bh); - __brelse(bh); /* One for getblk() */ + if (unlikely(!buffer_uptodate(bh))) + err = -EIO; + put_bh(bh); /* One for getblk() */ journal_unlock_journal_head(descriptor); } @@ -574,6 +588,12 @@ skip_commit: /* The journal should be unlocked by now. */ + if (err) { + lock_journal(journal); + __journal_abort_hard(journal); + unlock_journal(journal); + } + /* Call any callbacks that had been registered for handles in this * transaction. It is up to the callback to free any allocated * memory. diff -urN linux-2.5.66-bk9/fs/jbd/journal.c linux-2.5.66-bk10/fs/jbd/journal.c --- linux-2.5.66-bk9/fs/jbd/journal.c 2003-03-24 14:00:08.000000000 -0800 +++ linux-2.5.66-bk10/fs/jbd/journal.c 2003-04-04 04:32:52.000000000 -0800 @@ -580,8 +580,10 @@ * Wait for a specified commit to complete. * The caller may not hold the journal lock. */ -void log_wait_commit (journal_t *journal, tid_t tid) +int log_wait_commit (journal_t *journal, tid_t tid) { + int err = 0; + lock_kernel(); #ifdef CONFIG_JBD_DEBUG lock_journal(journal); @@ -598,7 +600,14 @@ wake_up(&journal->j_wait_commit); sleep_on(&journal->j_wait_done_commit); } + + if (unlikely(is_journal_aborted(journal))) { + printk(KERN_EMERG "journal commit I/O error\n"); + err = -EIO; + } + unlock_kernel(); + return err; } /* @@ -1907,6 +1916,29 @@ #endif +kmem_cache_t *jbd_handle_cache; + +static int __init journal_init_handle_cache(void) +{ + jbd_handle_cache = kmem_cache_create("journal_handle", + sizeof(handle_t), + 0, /* offset */ + 0, /* flags */ + NULL, /* ctor */ + NULL); /* dtor */ + if (jbd_handle_cache == NULL) { + printk(KERN_EMERG "JBD: failed to create handle cache\n"); + return -ENOMEM; + } + return 0; +} + +static void journal_destroy_handle_cache(void) +{ + if (jbd_handle_cache) + kmem_cache_destroy(jbd_handle_cache); +} + /* * Module startup and shutdown */ @@ -1918,6 +1950,8 @@ ret = journal_init_revoke_caches(); if (ret == 0) ret = journal_init_journal_head_cache(); + if (ret == 0) + ret = journal_init_handle_cache(); return ret; } @@ -1925,6 +1959,7 @@ { journal_destroy_revoke_caches(); journal_destroy_journal_head_cache(); + journal_destroy_handle_cache(); } static int __init journal_init(void) diff -urN linux-2.5.66-bk9/fs/jbd/transaction.c linux-2.5.66-bk10/fs/jbd/transaction.c --- linux-2.5.66-bk9/fs/jbd/transaction.c 2003-03-24 14:00:14.000000000 -0800 +++ linux-2.5.66-bk10/fs/jbd/transaction.c 2003-04-04 04:32:52.000000000 -0800 @@ -211,10 +211,10 @@ /* Allocate a new handle. This should probably be in a slab... */ static handle_t *new_handle(int nblocks) { - handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); + handle_t *handle = jbd_alloc_handle(GFP_NOFS); if (!handle) return NULL; - memset(handle, 0, sizeof (handle_t)); + memset(handle, 0, sizeof(*handle)); handle->h_buffer_credits = nblocks; handle->h_ref = 1; INIT_LIST_HEAD(&handle->h_jcb); @@ -258,7 +258,7 @@ err = start_this_handle(journal, handle); if (err < 0) { - kfree(handle); + jbd_free_handle(handle); current->journal_info = NULL; return ERR_PTR(err); } @@ -666,7 +666,8 @@ int offset; char *source; - J_ASSERT_JH(jh, buffer_uptodate(jh2bh(jh))); + J_EXPECT_JH(jh, buffer_uptodate(jh2bh(jh)), + "Possible IO failure.\n"); page = jh2bh(jh)->b_page; offset = ((unsigned long) jh2bh(jh)->b_data) & ~PAGE_MASK; source = kmap(page); @@ -1401,9 +1402,9 @@ * to wait for the commit to complete. */ if (handle->h_sync && !(current->flags & PF_MEMALLOC)) - log_wait_commit(journal, tid); + err = log_wait_commit(journal, tid); } - kfree(handle); + jbd_free_handle(handle); return err; } @@ -1417,7 +1418,7 @@ int journal_force_commit(journal_t *journal) { handle_t *handle; - int ret = 0; + int ret; lock_kernel(); handle = journal_start(journal, 1); @@ -1426,7 +1427,7 @@ goto out; } handle->h_sync = 1; - journal_stop(handle); + ret = journal_stop(handle); out: unlock_kernel(); return ret; diff -urN linux-2.5.66-bk9/fs/namei.c linux-2.5.66-bk10/fs/namei.c --- linux-2.5.66-bk9/fs/namei.c 2003-03-24 14:00:16.000000000 -0800 +++ linux-2.5.66-bk10/fs/namei.c 2003-04-04 04:32:52.000000000 -0800 @@ -275,8 +275,14 @@ */ static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags) { - struct dentry * dentry = d_lookup(parent, name); - + struct dentry * dentry = __d_lookup(parent, name); + + /* lockess __d_lookup may fail due to concurrent d_move() + * in some unrelated directory, so try with d_lookup + */ + if (!dentry) + dentry = d_lookup(parent, name); + if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) { dput(dentry); @@ -348,12 +354,9 @@ * negatives from the RCU list walk here, unlike the optimistic * fast walk). * - * We really should do a sequence number thing to avoid this - * all. + * so doing d_lookup() (with seqlock), instead of lockfree __d_lookup */ - spin_lock(&dcache_lock); result = d_lookup(parent, name); - spin_unlock(&dcache_lock); if (!result) { struct dentry * dentry = d_alloc(parent, name); result = ERR_PTR(-ENOMEM); @@ -524,7 +527,7 @@ struct path *path, int flags) { struct vfsmount *mnt = nd->mnt; - struct dentry *dentry = d_lookup(nd->dentry, name); + struct dentry *dentry = __d_lookup(nd->dentry, name); if (!dentry) goto need_lookup; diff -urN linux-2.5.66-bk9/fs/ncpfs/dir.c linux-2.5.66-bk10/fs/ncpfs/dir.c --- linux-2.5.66-bk9/fs/ncpfs/dir.c 2003-03-24 14:00:46.000000000 -0800 +++ linux-2.5.66-bk10/fs/ncpfs/dir.c 2003-04-04 04:32:52.000000000 -0800 @@ -273,9 +273,7 @@ int res, val = 0, len = dentry->d_name.len + 1; __u8 __name[len]; - read_lock(&dparent_lock); - parent = dget(dentry->d_parent); - read_unlock(&dparent_lock); + parent = dget_parent(dentry); dir = parent->d_inode; if (!dentry->d_inode) diff -urN linux-2.5.66-bk9/fs/nfs/dir.c linux-2.5.66-bk10/fs/nfs/dir.c --- linux-2.5.66-bk9/fs/nfs/dir.c 2003-03-24 14:00:37.000000000 -0800 +++ linux-2.5.66-bk10/fs/nfs/dir.c 2003-04-04 04:32:52.000000000 -0800 @@ -503,9 +503,7 @@ struct nfs_fh fhandle; struct nfs_fattr fattr; - read_lock(&dparent_lock); - parent = dget(dentry->d_parent); - read_unlock(&dparent_lock); + parent = dget_parent(dentry); lock_kernel(); dir = parent->d_inode; inode = dentry->d_inode; diff -urN linux-2.5.66-bk9/fs/nfsd/export.c linux-2.5.66-bk10/fs/nfsd/export.c --- linux-2.5.66-bk9/fs/nfsd/export.c 2003-04-04 04:32:49.000000000 -0800 +++ linux-2.5.66-bk10/fs/nfsd/export.c 2003-04-04 04:32:52.000000000 -0800 @@ -543,13 +543,12 @@ dget(dentry); exp = exp_get_by_name(clp, mnt, dentry, reqp); - while (exp == NULL && dentry != dentry->d_parent) { + while (exp == NULL && !IS_ROOT(dentry)) { struct dentry *parent; - read_lock(&dparent_lock); - parent = dget(dentry->d_parent); + + parent = dget_parent(dentry); dput(dentry); dentry = parent; - read_unlock(&dparent_lock); exp = exp_get_by_name(clp, mnt, dentry, reqp); } dput(dentry); diff -urN linux-2.5.66-bk9/fs/nfsd/nfs3xdr.c linux-2.5.66-bk10/fs/nfsd/nfs3xdr.c --- linux-2.5.66-bk9/fs/nfsd/nfs3xdr.c 2003-03-24 13:59:46.000000000 -0800 +++ linux-2.5.66-bk10/fs/nfsd/nfs3xdr.c 2003-04-04 04:32:52.000000000 -0800 @@ -820,9 +820,7 @@ fh_init(&fh, NFS3_FHSIZE); if (isdotent(name, namlen)) { if (namlen == 2) { - read_lock(&dparent_lock); - dchild = dget(dparent->d_parent); - read_unlock(&dparent_lock); + dchild = dget_parent(dparent); } else dchild = dget(dparent); } else diff -urN linux-2.5.66-bk9/fs/nfsd/nfsfh.c linux-2.5.66-bk10/fs/nfsd/nfsfh.c --- linux-2.5.66-bk9/fs/nfsd/nfsfh.c 2003-03-24 14:00:17.000000000 -0800 +++ linux-2.5.66-bk10/fs/nfsd/nfsfh.c 2003-04-04 04:32:52.000000000 -0800 @@ -55,9 +55,7 @@ while (tdentry != exp->ex_dentry && ! IS_ROOT(tdentry)) { /* make sure parents give x permission to user */ int err; - read_lock(&dparent_lock); - parent = dget(tdentry->d_parent); - read_unlock(&dparent_lock); + parent = dget_parent(tdentry); err = permission(parent->d_inode, S_IXOTH); if (err < 0) { dput(parent); diff -urN linux-2.5.66-bk9/fs/nfsd/vfs.c linux-2.5.66-bk10/fs/nfsd/vfs.c --- linux-2.5.66-bk9/fs/nfsd/vfs.c 2003-03-24 14:00:19.000000000 -0800 +++ linux-2.5.66-bk10/fs/nfsd/vfs.c 2003-04-04 04:32:52.000000000 -0800 @@ -112,9 +112,7 @@ if (len==1) dentry = dget(dparent); else if (dparent != exp->ex_dentry) { - read_lock(&dparent_lock); - dentry = dget(dparent->d_parent); - read_unlock(&dparent_lock); + dentry = dget_parent(dparent); } else if (!EX_NOHIDE(exp)) dentry = dget(dparent); /* .. == . just like at / */ else { @@ -125,9 +123,7 @@ dentry = dget(dparent); while(follow_up(&mnt, &dentry)) ; - read_lock(&dparent_lock); - dp = dget(dentry->d_parent); - read_unlock(&dparent_lock); + dp = dget_parent(dentry); dput(dentry); dentry = dp; diff -urN linux-2.5.66-bk9/fs/ntfs/namei.c linux-2.5.66-bk10/fs/ntfs/namei.c --- linux-2.5.66-bk9/fs/ntfs/namei.c 2003-03-24 14:01:14.000000000 -0800 +++ linux-2.5.66-bk10/fs/ntfs/namei.c 2003-04-04 04:32:52.000000000 -0800 @@ -241,7 +241,8 @@ nls_name.hash = full_name_hash(nls_name.name, nls_name.len); /* - * Note: No need for dparent_lock as i_sem is held on the parent inode. + * Note: No need for dent->d_lock lock as i_sem is held on the + * parent inode. */ /* Does a dentry matching the nls_name exist already? */ diff -urN linux-2.5.66-bk9/fs/partitions/check.c linux-2.5.66-bk10/fs/partitions/check.c --- linux-2.5.66-bk9/fs/partitions/check.c 2003-03-24 14:01:25.000000000 -0800 +++ linux-2.5.66-bk10/fs/partitions/check.c 2003-04-04 04:32:52.000000000 -0800 @@ -262,6 +262,7 @@ p->nr_sects = 0; p->reads = p->writes = p->read_sectors = p->write_sectors = 0; devfs_unregister(p->de); + p->de = NULL; kobject_unregister(&p->kobj); } diff -urN linux-2.5.66-bk9/fs/proc/base.c linux-2.5.66-bk10/fs/proc/base.c --- linux-2.5.66-bk9/fs/proc/base.c 2003-04-04 04:32:49.000000000 -0800 +++ linux-2.5.66-bk10/fs/proc/base.c 2003-04-04 04:32:52.000000000 -0800 @@ -583,7 +583,8 @@ if (len > buflen) len = buflen; - copy_to_user(buffer, path, len); + if (copy_to_user(buffer, path, len)) + len = -EFAULT; out: free_page((unsigned long)tmp); return len; diff -urN linux-2.5.66-bk9/fs/reiserfs/inode.c linux-2.5.66-bk10/fs/reiserfs/inode.c --- linux-2.5.66-bk9/fs/reiserfs/inode.c 2003-03-24 14:00:15.000000000 -0800 +++ linux-2.5.66-bk10/fs/reiserfs/inode.c 2003-04-04 04:32:52.000000000 -0800 @@ -1321,7 +1321,7 @@ if (maxlen < 5 || ! need_parent) return 3 ; - read_lock(&dparent_lock); + spin_lock(&dentry->d_lock); inode = dentry->d_parent->d_inode ; data[3] = inode->i_ino ; data[4] = le32_to_cpu(INODE_PKEY (inode)->k_dir_id) ; @@ -1330,7 +1330,7 @@ data[5] = inode->i_generation ; *lenp = 6 ; } - read_unlock(&dparent_lock); + spin_unlock(&dentry->d_lock); return *lenp ; } diff -urN linux-2.5.66-bk9/fs/smbfs/dir.c linux-2.5.66-bk10/fs/smbfs/dir.c --- linux-2.5.66-bk9/fs/smbfs/dir.c 2003-03-24 14:01:46.000000000 -0800 +++ linux-2.5.66-bk10/fs/smbfs/dir.c 2003-04-04 04:32:52.000000000 -0800 @@ -400,14 +400,23 @@ void smb_renew_times(struct dentry * dentry) { - read_lock(&dparent_lock); + dget(dentry); + spin_lock(&dentry->d_lock); for (;;) { + struct dentry *parent; + dentry->d_time = jiffies; if (IS_ROOT(dentry)) break; - dentry = dentry->d_parent; + parent = dentry->d_parent; + dget(parent); + spin_unlock(&dentry->d_lock); + dput(dentry); + dentry = parent; + spin_lock(&dentry->d_lock); } - read_unlock(&dparent_lock); + spin_unlock(&dentry->d_lock); + dput(dentry); } static struct dentry * diff -urN linux-2.5.66-bk9/fs/smbfs/proc.c linux-2.5.66-bk10/fs/smbfs/proc.c --- linux-2.5.66-bk9/fs/smbfs/proc.c 2003-03-24 14:00:03.000000000 -0800 +++ linux-2.5.66-bk10/fs/smbfs/proc.c 2003-04-04 04:32:52.000000000 -0800 @@ -333,10 +333,14 @@ * Build the path string walking the tree backward from end to ROOT * and store it in reversed order [see reverse_string()] */ - read_lock(&dparent_lock); + dget(entry); + spin_lock(&entry->d_lock); while (!IS_ROOT(entry)) { + struct dentry *parent; + if (maxlen < (3<d_lock); + dput(entry); return -ENAMETOOLONG; } @@ -344,7 +348,8 @@ entry->d_name.name, entry->d_name.len, server->local_nls, server->remote_nls); if (len < 0) { - read_unlock(&dparent_lock); + spin_unlock(&entry->d_lock); + dput(entry); return len; } reverse_string(path, len); @@ -357,9 +362,15 @@ *path++ = '\\'; maxlen -= len+1; - entry = entry->d_parent; + parent = entry->d_parent; + dget(parent); + spin_unlock(&entry->d_lock); + dput(entry); + entry = parent; + spin_lock(&entry->d_lock); } - read_unlock(&dparent_lock); + spin_unlock(&entry->d_lock); + dput(entry); reverse_string(buf, path-buf); /* maxlen has space for at least one char */ diff -urN linux-2.5.66-bk9/include/asm-alpha/pgtable.h linux-2.5.66-bk10/include/asm-alpha/pgtable.h --- linux-2.5.66-bk9/include/asm-alpha/pgtable.h 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/include/asm-alpha/pgtable.h 2003-04-04 04:32:53.000000000 -0800 @@ -68,7 +68,7 @@ /* .. and these are ours ... */ #define _PAGE_DIRTY 0x20000 #define _PAGE_ACCESSED 0x40000 -#define _PAGE_FILE 0x80000 /* pagecache or swap? */ +#define _PAGE_FILE 0x80000 /* set:pagecache, unset:swap */ /* * NOTE! The "accessed" bit isn't necessarily exact: it can be kept exactly diff -urN linux-2.5.66-bk9/include/asm-arm/stat.h linux-2.5.66-bk10/include/asm-arm/stat.h --- linux-2.5.66-bk9/include/asm-arm/stat.h 2003-03-24 14:00:00.000000000 -0800 +++ linux-2.5.66-bk10/include/asm-arm/stat.h 2003-04-04 04:32:53.000000000 -0800 @@ -18,15 +18,23 @@ #define STAT_HAVE_NSEC struct stat { +#if defined(__ARMEB__) unsigned short st_dev; unsigned short __pad1; - unsigned long st_ino; +#else + unsigned long st_dev; +#endif + unsigned long st_ino; unsigned short st_mode; unsigned short st_nlink; unsigned short st_uid; unsigned short st_gid; +#if defined(__ARMEB__) unsigned short st_rdev; unsigned short __pad2; +#else + unsigned long st_rdev; +#endif unsigned long st_size; unsigned long st_blksize; unsigned long st_blocks; @@ -46,13 +54,7 @@ * in the hope that the kernel has stretched to using larger sizes. */ struct stat64 { -#if defined(__ARMEB__) - unsigned char __pad0b[6]; - unsigned short st_dev; -#else - unsigned short st_dev; - unsigned char __pad0b[6]; -#endif + unsigned long long st_dev; unsigned char __pad0[4]; #define STAT64_HAS_BROKEN_ST_INO 1 @@ -63,13 +65,7 @@ unsigned long st_uid; unsigned long st_gid; -#if defined(__ARMEB__) - unsigned char __pad3b[6]; - unsigned short st_rdev; -#else /* Must be little */ - unsigned short st_rdev; - unsigned char __pad3b[6]; -#endif + unsigned long long st_rdev; unsigned char __pad3[4]; long long st_size; diff -urN linux-2.5.66-bk9/include/asm-cris/stat.h linux-2.5.66-bk10/include/asm-cris/stat.h --- linux-2.5.66-bk9/include/asm-cris/stat.h 2003-03-24 13:59:54.000000000 -0800 +++ linux-2.5.66-bk10/include/asm-cris/stat.h 2003-04-04 04:32:53.000000000 -0800 @@ -21,15 +21,13 @@ #define STAT_HAVE_NSEC 1 struct stat { - unsigned short st_dev; - unsigned short __pad1; - unsigned long st_ino; + unsigned long st_dev; + unsigned long st_ino; unsigned short st_mode; unsigned short st_nlink; unsigned short st_uid; unsigned short st_gid; - unsigned short st_rdev; - unsigned short __pad2; + unsigned long st_rdev; unsigned long st_size; unsigned long st_blksize; unsigned long st_blocks; @@ -47,8 +45,8 @@ * insane amounts of padding around dev_t's. */ struct stat64 { - unsigned short st_dev; - unsigned char __pad0[10]; + unsigned long long st_dev; + unsigned char __pad0[4]; #define STAT64_HAS_BROKEN_ST_INO 1 unsigned long __st_ino; @@ -59,8 +57,8 @@ unsigned long st_uid; unsigned long st_gid; - unsigned short st_rdev; - unsigned char __pad3[10]; + unsigned long long st_rdev; + unsigned char __pad3[4]; long long st_size; unsigned long st_blksize; diff -urN linux-2.5.66-bk9/include/asm-i386/pgtable.h linux-2.5.66-bk10/include/asm-i386/pgtable.h --- linux-2.5.66-bk9/include/asm-i386/pgtable.h 2003-03-24 14:01:14.000000000 -0800 +++ linux-2.5.66-bk10/include/asm-i386/pgtable.h 2003-04-04 04:32:53.000000000 -0800 @@ -110,7 +110,7 @@ #define _PAGE_PSE 0x080 /* 4 MB (or 2MB) page, Pentium+, if present.. */ #define _PAGE_GLOBAL 0x100 /* Global TLB entry PPro+ */ -#define _PAGE_FILE 0x040 /* pagecache or swap? */ +#define _PAGE_FILE 0x040 /* set:pagecache unset:swap */ #define _PAGE_PROTNONE 0x080 /* If not present */ #define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY) @@ -188,6 +188,10 @@ static inline int pte_dirty(pte_t pte) { return (pte).pte_low & _PAGE_DIRTY; } static inline int pte_young(pte_t pte) { return (pte).pte_low & _PAGE_ACCESSED; } static inline int pte_write(pte_t pte) { return (pte).pte_low & _PAGE_RW; } + +/* + * The following only works if pte_present() is not true. + */ static inline int pte_file(pte_t pte) { return (pte).pte_low & _PAGE_FILE; } static inline pte_t pte_rdprotect(pte_t pte) { (pte).pte_low &= ~_PAGE_USER; return pte; } diff -urN linux-2.5.66-bk9/include/asm-i386/stat.h linux-2.5.66-bk10/include/asm-i386/stat.h --- linux-2.5.66-bk9/include/asm-i386/stat.h 2003-03-24 13:59:56.000000000 -0800 +++ linux-2.5.66-bk10/include/asm-i386/stat.h 2003-04-04 04:32:53.000000000 -0800 @@ -16,15 +16,13 @@ }; struct stat { - unsigned short st_dev; - unsigned short __pad1; - unsigned long st_ino; + unsigned long st_dev; + unsigned long st_ino; unsigned short st_mode; unsigned short st_nlink; unsigned short st_uid; unsigned short st_gid; - unsigned short st_rdev; - unsigned short __pad2; + unsigned long st_rdev; unsigned long st_size; unsigned long st_blksize; unsigned long st_blocks; @@ -42,8 +40,8 @@ * insane amounts of padding around dev_t's. */ struct stat64 { - unsigned short st_dev; - unsigned char __pad0[10]; + unsigned long long st_dev; + unsigned char __pad0[4]; #define STAT64_HAS_BROKEN_ST_INO 1 unsigned long __st_ino; @@ -54,8 +52,8 @@ unsigned long st_uid; unsigned long st_gid; - unsigned short st_rdev; - unsigned char __pad3[10]; + unsigned long long st_rdev; + unsigned char __pad3[4]; long long st_size; unsigned long st_blksize; diff -urN linux-2.5.66-bk9/include/asm-i386/timer.h linux-2.5.66-bk10/include/asm-i386/timer.h --- linux-2.5.66-bk9/include/asm-i386/timer.h 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/include/asm-i386/timer.h 2003-04-04 04:32:53.000000000 -0800 @@ -14,6 +14,7 @@ int (*init)(char *override); void (*mark_offset)(void); unsigned long (*get_offset)(void); + unsigned long long (*monotonic_clock)(void); void (*delay)(unsigned long); }; diff -urN linux-2.5.66-bk9/include/asm-m68k/stat.h linux-2.5.66-bk10/include/asm-m68k/stat.h --- linux-2.5.66-bk9/include/asm-m68k/stat.h 2003-03-24 14:00:39.000000000 -0800 +++ linux-2.5.66-bk10/include/asm-m68k/stat.h 2003-04-04 04:32:53.000000000 -0800 @@ -18,7 +18,7 @@ struct stat { unsigned short st_dev; unsigned short __pad1; - unsigned long st_ino; + unsigned long st_ino; unsigned short st_mode; unsigned short st_nlink; unsigned short st_uid; @@ -42,8 +42,7 @@ * insane amounts of padding around dev_t's. */ struct stat64 { - unsigned char __pad0[6]; - unsigned short st_dev; + unsigned long long st_dev; unsigned char __pad1[2]; #define STAT64_HAS_BROKEN_ST_INO 1 @@ -55,8 +54,7 @@ unsigned long st_uid; unsigned long st_gid; - unsigned char __pad2[6]; - unsigned short st_rdev; + unsigned long long st_rdev; unsigned char __pad3[2]; long long st_size; diff -urN linux-2.5.66-bk9/include/asm-s390/stat.h linux-2.5.66-bk10/include/asm-s390/stat.h --- linux-2.5.66-bk9/include/asm-s390/stat.h 2003-03-24 14:01:43.000000000 -0800 +++ linux-2.5.66-bk10/include/asm-s390/stat.h 2003-04-04 04:32:53.000000000 -0800 @@ -26,7 +26,7 @@ struct stat { unsigned short st_dev; unsigned short __pad1; - unsigned long st_ino; + unsigned long st_ino; unsigned short st_mode; unsigned short st_nlink; unsigned short st_uid; @@ -52,8 +52,7 @@ * insane amounts of padding around dev_t's. */ struct stat64 { - unsigned char __pad0[6]; - unsigned short st_dev; + unsigned long long st_dev; unsigned int __pad1; #define STAT64_HAS_BROKEN_ST_INO 1 unsigned long __st_ino; @@ -61,10 +60,9 @@ unsigned int st_nlink; unsigned long st_uid; unsigned long st_gid; - unsigned char __pad2[6]; - unsigned short st_rdev; + unsigned long long st_rdev; unsigned int __pad3; - long long st_size; + long long st_size; unsigned long st_blksize; unsigned char __pad4[4]; unsigned long __pad5; /* future possible st_blocks high bits */ @@ -75,7 +73,7 @@ unsigned long st_mtime_nsec; unsigned long st_ctime; unsigned long st_ctime_nsec; /* will be high 32 bits of ctime someday */ - unsigned long long st_ino; + unsigned long long st_ino; }; #endif diff -urN linux-2.5.66-bk9/include/asm-sh/stat.h linux-2.5.66-bk10/include/asm-sh/stat.h --- linux-2.5.66-bk9/include/asm-sh/stat.h 2003-03-24 13:59:55.000000000 -0800 +++ linux-2.5.66-bk10/include/asm-sh/stat.h 2003-04-04 04:32:53.000000000 -0800 @@ -44,15 +44,7 @@ * insane amounts of padding around dev_t's. */ struct stat64 { -#if defined(__BIG_ENDIAN__) - unsigned char __pad0b[6]; - unsigned short st_dev; -#elif defined(__LITTLE_ENDIAN__) - unsigned short st_dev; - unsigned char __pad0b[6]; -#else -#error Must know endian to build stat64 structure! -#endif + unsigned long long st_dev; unsigned char __pad0[4]; unsigned long st_ino; @@ -62,13 +54,7 @@ unsigned long st_uid; unsigned long st_gid; -#if defined(__BIG_ENDIAN__) - unsigned char __pad3b[6]; - unsigned short st_rdev; -#else /* Must be little */ - unsigned short st_rdev; - unsigned char __pad3b[6]; -#endif + unsigned long long st_rdev; unsigned char __pad3[4]; long long st_size; diff -urN linux-2.5.66-bk9/include/asm-sparc/stat.h linux-2.5.66-bk10/include/asm-sparc/stat.h --- linux-2.5.66-bk9/include/asm-sparc/stat.h 2003-03-24 14:00:54.000000000 -0800 +++ linux-2.5.66-bk10/include/asm-sparc/stat.h 2003-04-04 04:32:53.000000000 -0800 @@ -41,10 +41,9 @@ #define STAT_HAVE_NSEC 1 struct stat64 { - unsigned char __pad0[6]; - unsigned short st_dev; + unsigned long long st_dev; - unsigned long long st_ino; + unsigned long long st_ino; unsigned int st_mode; unsigned int st_nlink; @@ -52,8 +51,7 @@ unsigned int st_uid; unsigned int st_gid; - unsigned char __pad2[6]; - unsigned short st_rdev; + unsigned long long st_rdev; unsigned char __pad3[8]; diff -urN linux-2.5.66-bk9/include/asm-sparc64/head.h linux-2.5.66-bk10/include/asm-sparc64/head.h --- linux-2.5.66-bk9/include/asm-sparc64/head.h 2003-03-24 14:00:18.000000000 -0800 +++ linux-2.5.66-bk10/include/asm-sparc64/head.h 2003-04-04 04:32:53.000000000 -0800 @@ -6,7 +6,7 @@ #define KERNBASE 0x400000 -#define PTREGS_OFF (STACK_BIAS + REGWIN_SZ) +#define PTREGS_OFF (STACK_BIAS + STACKFRAME_SZ) #define __CHEETAH_ID 0x003e0014 diff -urN linux-2.5.66-bk9/include/asm-sparc64/processor.h linux-2.5.66-bk10/include/asm-sparc64/processor.h --- linux-2.5.66-bk9/include/asm-sparc64/processor.h 2003-03-24 13:59:54.000000000 -0800 +++ linux-2.5.66-bk10/include/asm-sparc64/processor.h 2003-04-04 04:32:53.000000000 -0800 @@ -139,7 +139,7 @@ "stx %%g0, [%0 + %2 + 0x78]\n\t" \ "wrpr %%g0, (1 << 3), %%wstate\n\t" \ : \ - : "r" (regs), "r" (sp - REGWIN_SZ - STACK_BIAS), \ + : "r" (regs), "r" (sp - sizeof(struct reg_window) - STACK_BIAS), \ "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); \ } while (0) @@ -179,7 +179,7 @@ "stx %%g0, [%0 + %2 + 0x78]\n\t" \ "wrpr %%g0, (2 << 3), %%wstate\n\t" \ : \ - : "r" (regs), "r" (sp - REGWIN32_SZ), \ + : "r" (regs), "r" (sp - sizeof(struct reg_window32)), \ "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); \ } while (0) diff -urN linux-2.5.66-bk9/include/asm-sparc64/ptrace.h linux-2.5.66-bk10/include/asm-sparc64/ptrace.h --- linux-2.5.66-bk9/include/asm-sparc64/ptrace.h 2003-03-24 14:00:52.000000000 -0800 +++ linux-2.5.66-bk10/include/asm-sparc64/ptrace.h 2003-04-04 04:32:53.000000000 -0800 @@ -89,11 +89,9 @@ #define TRACEREG_SZ sizeof(struct pt_regs) #define STACKFRAME_SZ sizeof(struct sparc_stackf) -#define REGWIN_SZ sizeof(struct reg_window) #define TRACEREG32_SZ sizeof(struct pt_regs32) #define STACKFRAME32_SZ sizeof(struct sparc_stackf32) -#define REGWIN32_SZ sizeof(struct reg_window32) #ifdef __KERNEL__ #define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV)) @@ -105,11 +103,9 @@ /* For assembly code. */ #define TRACEREG_SZ 0xa0 #define STACKFRAME_SZ 0xc0 -#define REGWIN_SZ 0x80 #define TRACEREG32_SZ 0x50 #define STACKFRAME32_SZ 0x60 -#define REGWIN32_SZ 0x40 #endif #ifdef __KERNEL__ diff -urN linux-2.5.66-bk9/include/asm-sparc64/stat.h linux-2.5.66-bk10/include/asm-sparc64/stat.h --- linux-2.5.66-bk9/include/asm-sparc64/stat.h 2003-03-24 14:01:53.000000000 -0800 +++ linux-2.5.66-bk10/include/asm-sparc64/stat.h 2003-04-04 04:32:53.000000000 -0800 @@ -25,8 +25,7 @@ /* This is sparc32 stat64 structure. */ struct stat64 { - unsigned char __pad0[6]; - unsigned short st_dev; + unsigned long long st_dev; unsigned long long st_ino; @@ -36,8 +35,7 @@ unsigned int st_uid; unsigned int st_gid; - unsigned char __pad2[6]; - unsigned short st_rdev; + unsigned long long st_rdev; unsigned char __pad3[8]; diff -urN linux-2.5.66-bk9/include/asm-sparc64/timex.h linux-2.5.66-bk10/include/asm-sparc64/timex.h --- linux-2.5.66-bk9/include/asm-sparc64/timex.h 2003-03-24 14:00:38.000000000 -0800 +++ linux-2.5.66-bk10/include/asm-sparc64/timex.h 2003-04-04 04:32:53.000000000 -0800 @@ -6,6 +6,8 @@ #ifndef _ASMsparc64_TIMEX_H #define _ASMsparc64_TIMEX_H +#include + #define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ #define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */ #define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \ @@ -14,10 +16,6 @@ /* Getting on the cycle counter on sparc64. */ typedef unsigned long cycles_t; -#define get_cycles() \ -({ cycles_t ret; \ - __asm__ __volatile__("rd %%tick, %0" : "=r" (ret)); \ - ret; \ -}) +#define get_cycles() tick_ops->get_tick() #endif diff -urN linux-2.5.66-bk9/include/asm-sparc64/ttable.h linux-2.5.66-bk10/include/asm-sparc64/ttable.h --- linux-2.5.66-bk9/include/asm-sparc64/ttable.h 2003-03-24 13:59:55.000000000 -0800 +++ linux-2.5.66-bk10/include/asm-sparc64/ttable.h 2003-04-04 04:32:53.000000000 -0800 @@ -27,7 +27,7 @@ ba,pt %xcc, etrap; \ 109: or %g7, %lo(109b), %g7; \ call routine; \ - add %sp, STACK_BIAS + REGWIN_SZ, %o0; \ + add %sp, PTREGS_OFF, %o0; \ ba,pt %xcc, rtrap; \ clr %l6; \ nop; @@ -37,7 +37,7 @@ ba,pt %xcc, etrap; \ 109: or %g7, %lo(109b), %g7; \ call routine; \ - add %sp, STACK_BIAS + REGWIN_SZ, %o0; \ + add %sp, PTREGS_OFF, %o0; \ ba,pt %xcc, rtrap; \ clr %l6; @@ -46,7 +46,7 @@ ba,pt %xcc, do_fptrap; \ 109: or %g7, %lo(109b), %g7; \ call routine; \ - add %sp, STACK_BIAS + REGWIN_SZ, %o0; \ + add %sp, PTREGS_OFF, %o0; \ ba,pt %xcc, rtrap; \ clr %l6; \ nop; @@ -66,7 +66,7 @@ ba,pt %xcc, etraptl1; \ 109: or %g7, %lo(109b), %g7; \ call routine; \ - add %sp, STACK_BIAS + REGWIN_SZ, %o0; \ + add %sp, PTREGS_OFF, %o0; \ ba,pt %xcc, rtrap; \ clr %l6; \ nop; @@ -75,7 +75,7 @@ sethi %hi(109f), %g7; \ ba,pt %xcc, etrap; \ 109: or %g7, %lo(109b), %g7; \ - add %sp, STACK_BIAS + REGWIN_SZ, %o0; \ + add %sp, PTREGS_OFF, %o0; \ call routine; \ mov arg, %o1; \ ba,pt %xcc, rtrap; \ @@ -85,7 +85,7 @@ sethi %hi(109f), %g7; \ ba,pt %xcc, etraptl1; \ 109: or %g7, %lo(109b), %g7; \ - add %sp, STACK_BIAS + REGWIN_SZ, %o0; \ + add %sp, PTREGS_OFF, %o0; \ call routine; \ mov arg, %o1; \ ba,pt %xcc, rtrap; \ @@ -142,7 +142,7 @@ rd %pc, %g7; \ mov level, %o0; \ call routine; \ - add %sp, STACK_BIAS + REGWIN_SZ, %o1; \ + add %sp, PTREGS_OFF, %o1; \ ba,a,pt %xcc, rtrap_irq; #define TICK_SMP_IRQ \ @@ -152,7 +152,7 @@ b,pt %xcc, etrap_irq; \ 109: or %g7, %lo(109b), %g7; \ call smp_percpu_timer_interrupt; \ - add %sp, STACK_BIAS + REGWIN_SZ, %o0; \ + add %sp, PTREGS_OFF, %o0; \ ba,a,pt %xcc, rtrap_irq; #define TRAP_IVEC TRAP_NOSAVE(do_ivec) @@ -165,11 +165,11 @@ ba,pt %xcc, etrap; \ rd %pc, %g7; \ flushw; \ - ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC], %l1; \ + ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1; \ add %l1, 4, %l2; \ - stx %l1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TPC]; \ + stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC]; \ ba,pt %xcc, rtrap_clr_l6; \ - stx %l2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC]; + stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]; /* Before touching these macros, you owe it to yourself to go and * see how arch/sparc64/kernel/winfixup.S works... -DaveM diff -urN linux-2.5.66-bk9/include/asm-v850/stat.h linux-2.5.66-bk10/include/asm-v850/stat.h --- linux-2.5.66-bk9/include/asm-v850/stat.h 2003-03-24 14:01:11.000000000 -0800 +++ linux-2.5.66-bk10/include/asm-v850/stat.h 2003-04-04 04:32:53.000000000 -0800 @@ -17,14 +17,14 @@ #include struct stat { - __kernel_dev_t st_dev; - __kernel_ino_t st_ino; - __kernel_mode_t st_mode; - __kernel_nlink_t st_nlink; - __kernel_uid_t st_uid; - __kernel_gid_t st_gid; - __kernel_dev_t st_rdev; - __kernel_off_t st_size; + unsigned int st_dev; + unsigned long st_ino; + unsigned int st_mode; + unsigned int st_nlink; + unsigned int st_uid; + unsigned int st_gid; + unsigned int st_rdev; + long st_size; unsigned long st_blksize; unsigned long st_blocks; unsigned long st_atime; @@ -38,23 +38,21 @@ }; struct stat64 { - __kernel_dev_t st_dev; - unsigned long __unused0; + unsigned long long st_dev; unsigned long __unused1; - __kernel_ino64_t st_ino; + unsigned long long st_ino; - __kernel_mode_t st_mode; - __kernel_nlink_t st_nlink; + unsigned int st_mode; + unsigned int st_nlink; - __kernel_uid_t st_uid; - __kernel_gid_t st_gid; + unsigned int st_uid; + unsigned int st_gid; - __kernel_dev_t st_rdev; - unsigned long __unused2; + unsigned long long st_rdev; unsigned long __unused3; - __kernel_loff_t st_size; + long long st_size; unsigned long st_blksize; unsigned long st_blocks; /* No. of 512-byte blocks allocated */ diff -urN linux-2.5.66-bk9/include/asm-x86_64/pgtable.h linux-2.5.66-bk10/include/asm-x86_64/pgtable.h --- linux-2.5.66-bk9/include/asm-x86_64/pgtable.h 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/include/asm-x86_64/pgtable.h 2003-04-04 04:32:53.000000000 -0800 @@ -151,7 +151,7 @@ #define _PAGE_ACCESSED 0x020 #define _PAGE_DIRTY 0x040 #define _PAGE_PSE 0x080 /* 2MB page */ -#define _PAGE_FILE 0x040 /* pagecache or swap */ +#define _PAGE_FILE 0x040 /* set:pagecache, unset:swap */ #define _PAGE_GLOBAL 0x100 /* Global TLB entry */ #define _PAGE_PROTNONE 0x080 /* If not present */ diff -urN linux-2.5.66-bk9/include/linux/atm.h linux-2.5.66-bk10/include/linux/atm.h --- linux-2.5.66-bk9/include/linux/atm.h 2003-03-24 14:01:21.000000000 -0800 +++ linux-2.5.66-bk10/include/linux/atm.h 2003-04-04 04:32:53.000000000 -0800 @@ -236,15 +236,4 @@ }; typedef unsigned short atm_backend_t; - -#ifdef __KERNEL__ - -#include /* struct net_proto */ - - -void atmpvc_proto_init(struct net_proto *pro); -void atmsvc_proto_init(struct net_proto *pro); - -#endif /* __KERNEL__ */ - #endif diff -urN linux-2.5.66-bk9/include/linux/bio.h linux-2.5.66-bk10/include/linux/bio.h --- linux-2.5.66-bk9/include/linux/bio.h 2003-03-24 14:01:15.000000000 -0800 +++ linux-2.5.66-bk10/include/linux/bio.h 2003-04-04 04:32:53.000000000 -0800 @@ -148,10 +148,11 @@ * permanent PIO fall back, user is probably better off disabling highmem * I/O completely on that queue (see ide-dma for example) */ -#define __bio_kmap(bio, idx) (kmap(bio_iovec_idx((bio), (idx))->bv_page) + bio_iovec_idx((bio), (idx))->bv_offset) -#define bio_kmap(bio) __bio_kmap((bio), (bio)->bi_idx) -#define __bio_kunmap(bio, idx) kunmap(bio_iovec_idx((bio), (idx))->bv_page) -#define bio_kunmap(bio) __bio_kunmap((bio), (bio)->bi_idx) +#define __bio_kmap_atomic(bio, idx, kmtype) \ + (kmap_atomic(bio_iovec_idx((bio), (idx))->bv_page, kmtype) + \ + bio_iovec_idx((bio), (idx))->bv_offset) + +#define __bio_kunmap_atomic(addr, kmtype) kunmap_atomic(addr, kmtype) /* * merge helpers etc @@ -238,7 +239,7 @@ * might not be a highmem page, but the preempt/irq count * balancing is a lot nicer this way */ - local_save_flags(*flags); + local_irq_save(*flags); addr = (unsigned long) kmap_atomic(bio_page(bio), KM_BIO_SRC_IRQ); if (addr & ~PAGE_MASK) diff -urN linux-2.5.66-bk9/include/linux/dcache.h linux-2.5.66-bk10/include/linux/dcache.h --- linux-2.5.66-bk9/include/linux/dcache.h 2003-03-24 14:01:48.000000000 -0800 +++ linux-2.5.66-bk10/include/linux/dcache.h 2003-04-04 04:32:53.000000000 -0800 @@ -48,19 +48,24 @@ #define init_name_hash() 0 /* partial hash update function. Assume roughly 4 bits per character */ -static __inline__ unsigned long partial_name_hash(unsigned long c, unsigned long prevhash) +static inline unsigned long +partial_name_hash(unsigned long c, unsigned long prevhash) { return (prevhash + (c << 4) + (c >> 4)) * 11; } -/* Finally: cut down the number of bits to a int value (and try to avoid losing bits) */ -static __inline__ unsigned long end_name_hash(unsigned long hash) +/* + * Finally: cut down the number of bits to a int value (and try to avoid + * losing bits) + */ +static inline unsigned long end_name_hash(unsigned long hash) { return (unsigned int) hash; } /* Compute the hash for a name string. */ -static __inline__ unsigned int full_name_hash(const unsigned char * name, unsigned int len) +static inline unsigned int +full_name_hash(const unsigned char *name, unsigned int len) { unsigned long hash = init_name_hash(); while (len--) @@ -149,7 +154,6 @@ #define DCACHE_UNHASHED 0x0010 extern spinlock_t dcache_lock; -extern rwlock_t dparent_lock; /** * d_drop - drop a dentry @@ -168,20 +172,20 @@ * timeouts or autofs deletes). */ -static __inline__ void __d_drop(struct dentry * dentry) +static inline void __d_drop(struct dentry *dentry) { dentry->d_vfs_flags |= DCACHE_UNHASHED; hlist_del_rcu(&dentry->d_hash); } -static __inline__ void d_drop(struct dentry * dentry) +static inline void d_drop(struct dentry *dentry) { spin_lock(&dcache_lock); __d_drop(dentry); spin_unlock(&dcache_lock); } -static __inline__ int dname_external(struct dentry *d) +static inline int dname_external(struct dentry *d) { return d->d_name.name != d->d_iname; } @@ -227,7 +231,7 @@ * The entry was actually filled in earlier during d_alloc(). */ -static __inline__ void d_add(struct dentry * entry, struct inode * inode) +static inline void d_add(struct dentry *entry, struct inode *inode) { d_instantiate(entry, inode); d_rehash(entry); @@ -238,6 +242,7 @@ /* appendix may either be NULL or be used for transname suffixes */ extern struct dentry * d_lookup(struct dentry *, struct qstr *); +extern struct dentry * __d_lookup(struct dentry *, struct qstr *); /* validate "insecure" dentry pointer */ extern int d_validate(struct dentry *, struct dentry *); @@ -259,7 +264,7 @@ * and call dget_locked() instead of dget(). */ -static __inline__ struct dentry * dget(struct dentry *dentry) +static inline struct dentry *dget(struct dentry *dentry) { if (dentry) { if (!atomic_read(&dentry->d_count)) @@ -279,14 +284,24 @@ * Returns true if the dentry passed is not currently hashed. */ -static __inline__ int d_unhashed(struct dentry *dentry) +static inline int d_unhashed(struct dentry *dentry) { return (dentry->d_vfs_flags & DCACHE_UNHASHED); } +static inline struct dentry *dget_parent(struct dentry *dentry) +{ + struct dentry *ret; + + spin_lock(&dentry->d_lock); + ret = dget(dentry->d_parent); + spin_unlock(&dentry->d_lock); + return ret; +} + extern void dput(struct dentry *); -static __inline__ int d_mountpoint(struct dentry *dentry) +static inline int d_mountpoint(struct dentry *dentry) { return dentry->d_mounted; } diff -urN linux-2.5.66-bk9/include/linux/dnotify.h linux-2.5.66-bk10/include/linux/dnotify.h --- linux-2.5.66-bk9/include/linux/dnotify.h 2003-03-24 13:59:54.000000000 -0800 +++ linux-2.5.66-bk10/include/linux/dnotify.h 2003-04-04 04:32:53.000000000 -0800 @@ -18,27 +18,10 @@ extern void __inode_dir_notify(struct inode *, unsigned long); extern void dnotify_flush(struct file *filp, fl_owner_t id); extern int fcntl_dirnotify(int, struct file *, unsigned long); +void dnotify_parent(struct dentry *dentry, unsigned long event); static inline void inode_dir_notify(struct inode *inode, unsigned long event) { if ((inode)->i_dnotify_mask & (event)) __inode_dir_notify(inode, event); } - -/* - * This is hopelessly wrong, but unfixable without API changes. At - * least it doesn't oops the kernel... - */ -static inline void dnotify_parent(struct dentry *dentry, unsigned long event) -{ - struct dentry *parent; - read_lock(&dparent_lock); - parent = dentry->d_parent; - if (parent->d_inode->i_dnotify_mask & event) { - dget(parent); - read_unlock(&dparent_lock); - __inode_dir_notify(parent->d_inode, event); - dput(parent); - } else - read_unlock(&dparent_lock); -} diff -urN linux-2.5.66-bk9/include/linux/elf.h linux-2.5.66-bk10/include/linux/elf.h --- linux-2.5.66-bk9/include/linux/elf.h 2003-03-24 14:00:07.000000000 -0800 +++ linux-2.5.66-bk10/include/linux/elf.h 2003-04-04 04:32:53.000000000 -0800 @@ -274,6 +274,10 @@ #define R_MIPS_LOVENDOR 100 #define R_MIPS_HIVENDOR 127 +/* + * Sparc section types + */ +#define STT_REGISTER 13 /* * Sparc ELF relocation types @@ -311,6 +315,7 @@ #define R_SPARC_10 30 #define R_SPARC_11 31 #define R_SPARC_64 32 +#define R_SPARC_OLO10 33 #define R_SPARC_WDISP16 40 #define R_SPARC_WDISP19 41 #define R_SPARC_7 43 diff -urN linux-2.5.66-bk9/include/linux/fs.h linux-2.5.66-bk10/include/linux/fs.h --- linux-2.5.66-bk9/include/linux/fs.h 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/include/linux/fs.h 2003-04-04 04:32:53.000000000 -0800 @@ -1112,6 +1112,7 @@ extern void invalidate_inode_pages2(struct address_space *mapping); extern void write_inode_now(struct inode *, int); extern int filemap_fdatawrite(struct address_space *); +extern int filemap_flush(struct address_space *); extern int filemap_fdatawait(struct address_space *); extern void sync_supers(void); extern void sync_filesystems(int wait); @@ -1305,9 +1306,10 @@ static inline ino_t parent_ino(struct dentry *dentry) { ino_t res; - read_lock(&dparent_lock); + + spin_lock(&dentry->d_lock); res = dentry->d_parent->d_inode->i_ino; - read_unlock(&dparent_lock); + spin_unlock(&dentry->d_lock); return res; } diff -urN linux-2.5.66-bk9/include/linux/if_pppox.h linux-2.5.66-bk10/include/linux/if_pppox.h --- linux-2.5.66-bk9/include/linux/if_pppox.h 2003-03-24 14:00:08.000000000 -0800 +++ linux-2.5.66-bk10/include/linux/if_pppox.h 2003-04-04 04:32:53.000000000 -0800 @@ -158,8 +158,6 @@ extern struct ppp_channel_ops pppoe_chan_ops; -extern int pppox_proto_init(struct net_proto *np); - #endif /* __KERNEL__ */ #endif /* !(__LINUX_IF_PPPOX_H) */ diff -urN linux-2.5.66-bk9/include/linux/inet.h linux-2.5.66-bk10/include/linux/inet.h --- linux-2.5.66-bk9/include/linux/inet.h 2003-03-24 14:00:10.000000000 -0800 +++ linux-2.5.66-bk10/include/linux/inet.h 2003-04-04 04:32:53.000000000 -0800 @@ -43,11 +43,6 @@ #define _LINUX_INET_H #ifdef __KERNEL__ - -#include - -extern void inet_proto_init(struct net_proto *pro); -extern __u32 in_aton(const char *str); - +extern __u32 in_aton(const char *str); #endif #endif /* _LINUX_INET_H */ diff -urN linux-2.5.66-bk9/include/linux/ip.h linux-2.5.66-bk10/include/linux/ip.h --- linux-2.5.66-bk9/include/linux/ip.h 2003-03-24 14:00:14.000000000 -0800 +++ linux-2.5.66-bk10/include/linux/ip.h 2003-04-04 04:32:53.000000000 -0800 @@ -188,13 +188,13 @@ __u16 reserved; __u32 spi; __u32 seq_no; /* Sequence number */ - __u8 auth_data[4]; /* Variable len but >=4. Mind the 64 bit alignment! */ + __u8 auth_data[0]; /* Variable len but >=4. Mind the 64 bit alignment! */ }; struct ip_esp_hdr { __u32 spi; __u32 seq_no; /* Sequence number */ - __u8 enc_data[8]; /* Variable len but >=8. Mind the 64 bit alignment! */ + __u8 enc_data[0]; /* Variable len but >=8. Mind the 64 bit alignment! */ }; #endif /* _LINUX_IP_H */ diff -urN linux-2.5.66-bk9/include/linux/ipv6.h linux-2.5.66-bk10/include/linux/ipv6.h --- linux-2.5.66-bk9/include/linux/ipv6.h 2003-03-24 14:01:11.000000000 -0800 +++ linux-2.5.66-bk10/include/linux/ipv6.h 2003-04-04 04:32:53.000000000 -0800 @@ -80,13 +80,13 @@ __u16 reserved; __u32 spi; __u32 seq_no; /* Sequence number */ - __u8 auth_data[4]; /* Length variable but >=4. Mind the 64 bit alignment! */ + __u8 auth_data[0]; /* Length variable but >=4. Mind the 64 bit alignment! */ }; struct ipv6_esp_hdr { __u32 spi; __u32 seq_no; /* Sequence number */ - __u8 enc_data[8]; /* Length variable but >=8. Mind the 64 bit alignment! */ + __u8 enc_data[0]; /* Length variable but >=8. Mind the 64 bit alignment! */ }; /* diff -urN linux-2.5.66-bk9/include/linux/jbd.h linux-2.5.66-bk10/include/linux/jbd.h --- linux-2.5.66-bk9/include/linux/jbd.h 2003-03-24 14:01:17.000000000 -0800 +++ linux-2.5.66-bk10/include/linux/jbd.h 2003-04-04 04:32:53.000000000 -0800 @@ -33,6 +33,15 @@ #define journal_oom_retry 1 +/* + * Define JBD_PARANIOD_IOFAIL to cause a kernel BUG() if ext3 finds + * certain classes of error which can occur due to failed IOs. Under + * normal use we want ext3 to continue after such errors, because + * hardware _can_ fail, but for debugging purposes when running tests on + * known-good hardware we may want to trap these errors. + */ +#undef JBD_PARANOID_IOFAIL + #ifdef CONFIG_JBD_DEBUG /* * Define JBD_EXPENSIVE_CHECKING to enable more expensive internal @@ -257,6 +266,23 @@ #define J_ASSERT(assert) do { } while (0) #endif /* JBD_ASSERTIONS */ +#if defined(JBD_PARANOID_IOFAIL) +#define J_EXPECT(expr, why...) J_ASSERT(expr) +#define J_EXPECT_BH(bh, expr, why...) J_ASSERT_BH(bh, expr) +#define J_EXPECT_JH(jh, expr, why...) J_ASSERT_JH(jh, expr) +#else +#define __journal_expect(expr, why...) \ + do { \ + if (!(expr)) { \ + printk(KERN_ERR "EXT3-fs unexpected failure: %s;\n", # expr); \ + printk(KERN_ERR ## why); \ + } \ + } while (0) +#define J_EXPECT(expr, why...) __journal_expect(expr, ## why) +#define J_EXPECT_BH(bh, expr, why...) __journal_expect(expr, ## why) +#define J_EXPECT_JH(jh, expr, why...) __journal_expect(expr, ## why) +#endif + enum jbd_state_bits { BH_JBD /* Has an attached ext3 journal_head */ = BH_PrivateStart, @@ -788,6 +814,21 @@ extern void __journal_remove_journal_head(struct buffer_head *bh); extern void journal_unlock_journal_head(struct journal_head *jh); +/* + * handle management + */ +extern kmem_cache_t *jbd_handle_cache; + +static inline handle_t *jbd_alloc_handle(int gfp_flags) +{ + return kmem_cache_alloc(jbd_handle_cache, gfp_flags); +} + +static inline void jbd_free_handle(handle_t *handle) +{ + kmem_cache_free(jbd_handle_cache, handle); +} + /* Primary revoke support */ #define JOURNAL_REVOKE_DEFAULT_HASH 256 extern int journal_init_revoke(journal_t *, int); @@ -814,7 +855,7 @@ extern int log_space_left (journal_t *); /* Called with journal locked */ extern tid_t log_start_commit (journal_t *, transaction_t *); -extern void log_wait_commit (journal_t *, tid_t); +extern int log_wait_commit (journal_t *, tid_t); extern int log_do_checkpoint (journal_t *, int); extern void log_wait_for_space(journal_t *, int nblocks); diff -urN linux-2.5.66-bk9/include/linux/net.h linux-2.5.66-bk10/include/linux/net.h --- linux-2.5.66-bk9/include/linux/net.h 2003-03-24 14:00:19.000000000 -0800 +++ linux-2.5.66-bk10/include/linux/net.h 2003-04-04 04:32:53.000000000 -0800 @@ -27,7 +27,6 @@ #define NPROTO 32 /* should be enough for now.. */ - #define SYS_SOCKET 1 /* sys_socket(2) */ #define SYS_BIND 2 /* sys_bind(2) */ #define SYS_CONNECT 3 /* sys_connect(2) */ @@ -46,16 +45,15 @@ #define SYS_SENDMSG 16 /* sys_sendmsg(2) */ #define SYS_RECVMSG 17 /* sys_recvmsg(2) */ - typedef enum { - SS_FREE = 0, /* not allocated */ - SS_UNCONNECTED, /* unconnected to any socket */ - SS_CONNECTING, /* in process of connecting */ - SS_CONNECTED, /* connected to socket */ - SS_DISCONNECTING /* in process of disconnecting */ + SS_FREE = 0, /* not allocated */ + SS_UNCONNECTED, /* unconnected to any socket */ + SS_CONNECTING, /* in process of connecting */ + SS_CONNECTED, /* connected to socket */ + SS_DISCONNECTING /* in process of disconnecting */ } socket_state; -#define __SO_ACCEPTCON (1<<16) /* performed a listen */ +#define __SO_ACCEPTCON (1 << 16) /* performed a listen */ #ifdef __KERNEL__ @@ -63,17 +61,26 @@ #define SOCK_ASYNC_WAITDATA 1 #define SOCK_NOSPACE 2 -struct socket -{ +/** + * struct socket - general BSD socket + * @state - socket state (%SS_CONNECTED, etc) + * @flags - socket flags (%SOCK_ASYNC_NOSPACE, etc) + * @ops - protocol specific socket operations + * @fasync_list - Asynchronous wake up list + * @file - File back pointer for gc + * @sk - internal networking protocol agnostic socket representation + * @wait - wait queue for several uses + * @type - socket type (%SOCK_STREAM, etc) + * @passcred - credentials (used only in Unix Sockets (aka PF_LOCAL)) + */ +struct socket { socket_state state; - unsigned long flags; struct proto_ops *ops; - struct fasync_struct *fasync_list; /* Asynchronous wake up list */ - struct file *file; /* File back pointer for gc */ + struct fasync_struct *fasync_list; + struct file *file; struct sock *sk; wait_queue_head_t wait; - short type; unsigned char passcred; }; @@ -83,37 +90,43 @@ struct kiocb; struct proto_ops { - int family; - - int (*release) (struct socket *sock); - int (*bind) (struct socket *sock, struct sockaddr *umyaddr, - int sockaddr_len); - int (*connect) (struct socket *sock, struct sockaddr *uservaddr, - int sockaddr_len, int flags); - int (*socketpair) (struct socket *sock1, struct socket *sock2); - int (*accept) (struct socket *sock, struct socket *newsock, - int flags); - int (*getname) (struct socket *sock, struct sockaddr *uaddr, - int *usockaddr_len, int peer); - unsigned int (*poll) (struct file *file, struct socket *sock, struct poll_table_struct *wait); - int (*ioctl) (struct socket *sock, unsigned int cmd, - unsigned long arg); - int (*listen) (struct socket *sock, int len); - int (*shutdown) (struct socket *sock, int flags); - int (*setsockopt) (struct socket *sock, int level, int optname, - char *optval, int optlen); - int (*getsockopt) (struct socket *sock, int level, int optname, - char *optval, int *optlen); - int (*sendmsg) (struct kiocb *iocb, struct socket *sock, - struct msghdr *m, int total_len); - int (*recvmsg) (struct kiocb *iocb, struct socket *sock, - struct msghdr *m, int total_len, int flags); - int (*mmap) (struct file *file, struct socket *sock, struct vm_area_struct * vma); - ssize_t (*sendpage) (struct socket *sock, struct page *page, int offset, size_t size, int flags); + int family; + int (*release) (struct socket *sock); + int (*bind) (struct socket *sock, + struct sockaddr *umyaddr, + int sockaddr_len); + int (*connect) (struct socket *sock, + struct sockaddr *uservaddr, + int sockaddr_len, int flags); + int (*socketpair)(struct socket *sock1, + struct socket *sock2); + int (*accept) (struct socket *sock, + struct socket *newsock, int flags); + int (*getname) (struct socket *sock, + struct sockaddr *uaddr, + int *usockaddr_len, int peer); + unsigned int (*poll) (struct file *file, struct socket *sock, + struct poll_table_struct *wait); + int (*ioctl) (struct socket *sock, unsigned int cmd, + unsigned long arg); + int (*listen) (struct socket *sock, int len); + int (*shutdown) (struct socket *sock, int flags); + int (*setsockopt)(struct socket *sock, int level, + int optname, char *optval, int optlen); + int (*getsockopt)(struct socket *sock, int level, + int optname, char *optval, int *optlen); + int (*sendmsg) (struct kiocb *iocb, struct socket *sock, + struct msghdr *m, int total_len); + int (*recvmsg) (struct kiocb *iocb, struct socket *sock, + struct msghdr *m, int total_len, + int flags); + int (*mmap) (struct file *file, struct socket *sock, + struct vm_area_struct * vma); + ssize_t (*sendpage) (struct socket *sock, struct page *page, + int offset, size_t size, int flags); }; -struct net_proto_family -{ +struct net_proto_family { int family; int (*create)(struct socket *sock, int protocol); /* These are counters for the number of different methods of @@ -123,30 +136,27 @@ short encrypt_net; }; -struct net_proto -{ - const char *name; /* Protocol name */ - void (*init_func)(struct net_proto *); /* Bootstrap */ -}; - -extern int sock_wake_async(struct socket *sk, int how, int band); -extern int sock_register(struct net_proto_family *fam); -extern int sock_unregister(int family); +extern int sock_wake_async(struct socket *sk, int how, int band); +extern int sock_register(struct net_proto_family *fam); +extern int sock_unregister(int family); extern struct socket *sock_alloc(void); -extern int sock_create(int family, int type, int proto, struct socket **); -extern void sock_release(struct socket *); -extern int sock_sendmsg(struct socket *, struct msghdr *m, int len); -extern int sock_recvmsg(struct socket *, struct msghdr *m, int len, int flags); -extern int sock_readv_writev(int type, struct inode * inode, struct file * file, - const struct iovec * iov, long count, long size); -extern int sock_map_fd(struct socket *sock); - +extern int sock_create(int family, int type, int proto, + struct socket **res); +extern void sock_release(struct socket *sock); +extern int sock_sendmsg(struct socket *sock, struct msghdr *msg, + int len); +extern int sock_recvmsg(struct socket *sock, struct msghdr *msg, + int size, int flags); +extern int sock_readv_writev(int type, struct inode *inode, + struct file *file, + const struct iovec *iov, long count, + long size); +extern int sock_map_fd(struct socket *sock); extern struct socket *sockfd_lookup(int fd, int *err); -#define sockfd_put(sock) fput(sock->file) - -extern int net_ratelimit(void); +#define sockfd_put(sock) fput(sock->file) +extern int net_ratelimit(void); extern unsigned long net_random(void); -extern void net_srandom(unsigned long); +extern void net_srandom(unsigned long); #ifndef CONFIG_SMP #define SOCKOPS_WRAPPED(name) name diff -urN linux-2.5.66-bk9/include/linux/netdevice.h linux-2.5.66-bk10/include/linux/netdevice.h --- linux-2.5.66-bk9/include/linux/netdevice.h 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/include/linux/netdevice.h 2003-04-04 04:32:53.000000000 -0800 @@ -486,6 +486,7 @@ extern int dev_queue_xmit(struct sk_buff *skb); extern int register_netdevice(struct net_device *dev); extern int unregister_netdevice(struct net_device *dev); +extern void synchronize_net(void); extern int register_netdevice_notifier(struct notifier_block *nb); extern int unregister_netdevice_notifier(struct notifier_block *nb); extern int call_netdevice_notifiers(unsigned long val, void *v); diff -urN linux-2.5.66-bk9/include/linux/pfkeyv2.h linux-2.5.66-bk10/include/linux/pfkeyv2.h --- linux-2.5.66-bk9/include/linux/pfkeyv2.h 2003-03-24 14:01:22.000000000 -0800 +++ linux-2.5.66-bk10/include/linux/pfkeyv2.h 2003-04-04 04:32:53.000000000 -0800 @@ -194,6 +194,26 @@ } __attribute__((packed)); /* sizeof(struct sadb_x_ipsecrequest) == 16 */ +/* This defines the TYPE of Nat Traversal in use. Currently only one + * type of NAT-T is supported, draft-ietf-ipsec-udp-encaps-06 + */ +struct sadb_x_nat_t_type { + uint16_t sadb_x_nat_t_type_len; + uint16_t sadb_x_nat_t_type_exttype; + uint8_t sadb_x_nat_t_type_type; + uint8_t sadb_x_nat_t_type_reserved[3]; +} __attribute__((packed)); +/* sizeof(struct sadb_x_nat_t_type) == 8 */ + +/* Pass a NAT Traversal port (Source or Dest port) */ +struct sadb_x_nat_t_port { + uint16_t sadb_x_nat_t_port_len; + uint16_t sadb_x_nat_t_port_exttype; + uint16_t sadb_x_nat_t_port_port; + uint16_t sadb_x_nat_t_port_reserved; +} __attribute__((packed)); +/* sizeof(struct sadb_x_nat_t_port) == 8 */ + /* Message types */ #define SADB_RESERVED 0 #define SADB_GETSPI 1 @@ -218,7 +238,8 @@ #define SADB_X_SPDSETIDX 20 #define SADB_X_SPDEXPIRE 21 #define SADB_X_SPDDELETE2 22 -#define SADB_MAX 22 +#define SADB_X_NAT_T_NEW_MAPPING 23 +#define SADB_MAX 23 /* Security Association flags */ #define SADB_SAFLAGS_PFS 1 @@ -291,7 +312,12 @@ #define SADB_X_EXT_KMPRIVATE 17 #define SADB_X_EXT_POLICY 18 #define SADB_X_EXT_SA2 19 -#define SADB_EXT_MAX 19 +/* The next four entries are for setting up NAT Traversal */ +#define SADB_X_EXT_NAT_T_TYPE 20 +#define SADB_X_EXT_NAT_T_SPORT 21 +#define SADB_X_EXT_NAT_T_DPORT 22 +#define SADB_X_EXT_NAT_T_OA 23 +#define SADB_EXT_MAX 23 /* Identity Extension values */ #define SADB_IDENTTYPE_RESERVED 0 diff -urN linux-2.5.66-bk9/include/linux/raid/md.h linux-2.5.66-bk10/include/linux/raid/md.h --- linux-2.5.66-bk9/include/linux/raid/md.h 2003-03-24 13:59:56.000000000 -0800 +++ linux-2.5.66-bk10/include/linux/raid/md.h 2003-04-04 04:32:53.000000000 -0800 @@ -61,8 +61,6 @@ #define MD_MINOR_VERSION 90 #define MD_PATCHLEVEL_VERSION 0 -extern sector_t md_size[MAX_MD_DEVS]; - extern inline char * bdev_partition_name (struct block_device *bdev) { return partition_name(bdev ? bdev->bd_dev : 0); diff -urN linux-2.5.66-bk9/include/linux/raid/md_k.h linux-2.5.66-bk10/include/linux/raid/md_k.h --- linux-2.5.66-bk9/include/linux/raid/md_k.h 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/include/linux/raid/md_k.h 2003-04-04 04:32:53.000000000 -0800 @@ -203,6 +203,7 @@ int raid_disks; int max_disks; sector_t size; /* used size of component devices */ + sector_t array_size; /* exported array size */ __u64 events; char uuid[16]; diff -urN linux-2.5.66-bk9/include/linux/udp.h linux-2.5.66-bk10/include/linux/udp.h --- linux-2.5.66-bk9/include/linux/udp.h 2003-03-24 14:00:10.000000000 -0800 +++ linux-2.5.66-bk10/include/linux/udp.h 2003-04-04 04:32:53.000000000 -0800 @@ -30,10 +30,15 @@ /* UDP socket options */ #define UDP_CORK 1 /* Never send partially complete segments */ +#define UDP_ENCAP 100 /* Set the socket to accept encapsulated packets */ + +/* UDP encapsulation types */ +#define UDP_ENCAP_ESPINUDP 2 /* draft-ietf-ipsec-udp-encaps-06 */ struct udp_opt { int pending; /* Any pending frames ? */ unsigned int corkflag; /* Cork is required */ + __u16 encap_type; /* Is this an Encapsulation socket? */ /* * Following members retains the infomation to create a UDP header * when the socket is uncorked. diff -urN linux-2.5.66-bk9/include/linux/umsdos_fs.h linux-2.5.66-bk10/include/linux/umsdos_fs.h --- linux-2.5.66-bk9/include/linux/umsdos_fs.h 2003-03-24 13:59:53.000000000 -0800 +++ linux-2.5.66-bk10/include/linux/umsdos_fs.h 2003-04-04 04:32:53.000000000 -0800 @@ -49,7 +49,7 @@ # else # define Printk(x) # endif -#endif +#endif /* __KERNEL__ */ struct umsdos_fake_info { @@ -70,8 +70,7 @@ time_t atime; /* Access time */ time_t mtime; /* Last modification time */ time_t ctime; /* Creation time */ - dev_t rdev; /* major and minor number of a device */ - /* special file */ + unsigned short rdev; /* major and minor of a device special file */ umode_t mode; /* Standard UNIX permissions bits + type of */ char spare[12]; /* unused bytes for future extensions */ /* file, see linux/stat.h */ @@ -129,34 +128,32 @@ struct umsdos_ioctl { struct dirent dos_dirent; struct umsdos_dirent umsdos_dirent; - /* The following structure is used to exchange some data - * with utilities (umsdos_progs/util/umsdosio.c). The first - * releases were using struct stat from "sys/stat.h". This was - * causing some problem for cross compilation of the kernel - * Since I am not really using the structure stat, but only some field - * of it, I have decided to replicate the structure here - * for compatibility with the binaries out there + /* The following structure is used to exchange some data with + * utilities (umsdos_progs/util/umsdosio.c). The first releases + * were using struct stat from "sys/stat.h". This was causing + * some problem for cross compilation of the kernel. + * Since I am not really using the structure stat, but only + * some fields of it, I have decided to replicate the structure + * here for compatibility with the binaries out there. * FIXME PTW 1998, this has probably changed */ struct { - dev_t st_dev; - unsigned short __pad1; - ino_t st_ino; - umode_t st_mode; + unsigned long st_dev; + ino_t st_ino; /* used */ + umode_t st_mode; /* used */ nlink_t st_nlink; __kernel_uid_t st_uid; __kernel_gid_t st_gid; - dev_t st_rdev; - unsigned short __pad2; - off_t st_size; + unsigned long st_rdev; + off_t st_size; /* used */ unsigned long st_blksize; unsigned long st_blocks; - time_t st_atime; + time_t st_atime; /* used */ unsigned long __unused1; - time_t st_mtime; + time_t st_mtime; /* used */ unsigned long __unused2; - time_t st_ctime; + time_t st_ctime; /* used */ unsigned long __unused3; uid_t st_uid32; gid_t st_gid32; diff -urN linux-2.5.66-bk9/include/linux/xfrm.h linux-2.5.66-bk10/include/linux/xfrm.h --- linux-2.5.66-bk9/include/linux/xfrm.h 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/include/linux/xfrm.h 2003-04-04 04:32:53.000000000 -0800 @@ -130,12 +130,19 @@ __u32 calgos; }; +struct xfrm_encap_tmpl { + __u16 encap_type; + __u16 encap_sport; + __u16 encap_dport; +}; + /* Netlink message attributes. */ enum xfrm_attr_type_t { XFRMA_UNSPEC, XFRMA_ALG_AUTH, /* struct xfrm_algo */ XFRMA_ALG_CRYPT, /* struct xfrm_algo */ XFRMA_ALG_COMP, /* struct xfrm_algo */ + XFRMA_ENCAP, /* struct xfrm_algo + struct xfrm_encap_tmpl */ XFRMA_TMPL, /* 1 or more struct xfrm_user_tmpl */ #define XFRMA_MAX XFRMA_TMPL diff -urN linux-2.5.66-bk9/include/net/af_unix.h linux-2.5.66-bk10/include/net/af_unix.h --- linux-2.5.66-bk9/include/net/af_unix.h 2003-03-24 14:01:13.000000000 -0800 +++ linux-2.5.66-bk10/include/net/af_unix.h 2003-04-04 04:32:53.000000000 -0800 @@ -1,6 +1,5 @@ #ifndef __LINUX_NET_AFUNIX_H #define __LINUX_NET_AFUNIX_H -extern void unix_proto_init(struct net_proto *pro); extern void unix_inflight(struct file *fp); extern void unix_notinflight(struct file *fp); typedef struct sock unix_socket; diff -urN linux-2.5.66-bk9/include/net/icmp.h linux-2.5.66-bk10/include/net/icmp.h --- linux-2.5.66-bk9/include/net/icmp.h 2003-03-24 14:01:22.000000000 -0800 +++ linux-2.5.66-bk10/include/net/icmp.h 2003-04-04 04:32:53.000000000 -0800 @@ -39,15 +39,15 @@ #define ICMP_INC_STATS_FIELD(offt) \ (*((unsigned long *) ((void *) \ per_cpu_ptr(icmp_statistics[!in_softirq()],\ - smp_processor_id())) + offt))++; + smp_processor_id()) + offt)))++ #define ICMP_INC_STATS_BH_FIELD(offt) \ (*((unsigned long *) ((void *) \ per_cpu_ptr(icmp_statistics[0], \ - smp_processor_id())) + offt))++; + smp_processor_id()) + offt)))++ #define ICMP_INC_STATS_USER_FIELD(offt) \ (*((unsigned long *) ((void *) \ per_cpu_ptr(icmp_statistics[1], \ - smp_processor_id())) + offt))++; + smp_processor_id()) + offt)))++ extern void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info); extern int icmp_rcv(struct sk_buff *skb); diff -urN linux-2.5.66-bk9/include/net/xfrm.h linux-2.5.66-bk10/include/net/xfrm.h --- linux-2.5.66-bk9/include/net/xfrm.h 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/include/net/xfrm.h 2003-04-04 04:32:53.000000000 -0800 @@ -119,6 +119,9 @@ struct xfrm_algo *ealg; struct xfrm_algo *calg; + /* Data for encapsulator */ + struct xfrm_encap_tmpl *encap; + /* State for replay detection */ struct xfrm_replay_state replay; @@ -192,6 +195,7 @@ extern struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family); extern void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo); +struct xfrm_decap_state; struct xfrm_type { char *description; @@ -200,7 +204,8 @@ int (*init_state)(struct xfrm_state *x, void *args); void (*destructor)(struct xfrm_state *); - int (*input)(struct xfrm_state *, struct sk_buff *skb); + int (*input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb); + int (*post_input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb); int (*output)(struct sk_buff *skb); /* Estimate maximal size of result of transformation of a dgram */ u32 (*get_max_size)(struct xfrm_state *, int size); @@ -246,7 +251,7 @@ __u32 calgos; }; -#define XFRM_MAX_DEPTH 3 +#define XFRM_MAX_DEPTH 4 struct xfrm_policy { @@ -278,6 +283,7 @@ int (*notify)(struct xfrm_state *x, int event); int (*acquire)(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *xp, int dir); struct xfrm_policy *(*compile_policy)(u16 family, int opt, u8 *data, int len, int *dir); + int (*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport); }; extern int xfrm_register_km(struct xfrm_mgr *km); @@ -498,12 +504,26 @@ } u; }; +/* Decapsulation state, used by the input to store data during + * decapsulation procedure, to be used later (during the policy + * check + */ +struct xfrm_decap_state { + char decap_data[20]; + __u16 decap_type; +}; + +struct sec_decap_state { + struct xfrm_state *xvec; + struct xfrm_decap_state decap; +}; + struct sec_path { kmem_cache_t *pool; atomic_t refcnt; int len; - struct xfrm_state *xvec[XFRM_MAX_DEPTH]; + struct sec_decap_state x[XFRM_MAX_DEPTH]; }; static inline struct sec_path * @@ -730,6 +750,7 @@ extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq); extern int xfrm_check_selectors(struct xfrm_state **x, int n, struct flowi *fl); extern int xfrm4_rcv(struct sk_buff *skb); +extern int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type); extern int xfrm6_rcv(struct sk_buff **pskb); extern int xfrm6_clear_mutable_options(struct sk_buff *skb, u16 *nh_offset, int dir); extern int xfrm_user_policy(struct sock *sk, int optname, u8 *optval, int optlen); @@ -760,6 +781,7 @@ extern void km_warn_expired(struct xfrm_state *x); extern void km_expired(struct xfrm_state *x); extern int km_query(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *pol); +extern int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport); extern void xfrm4_input_init(void); extern void xfrm6_input_init(void); diff -urN linux-2.5.66-bk9/kernel/ksyms.c linux-2.5.66-bk10/kernel/ksyms.c --- linux-2.5.66-bk9/kernel/ksyms.c 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/kernel/ksyms.c 2003-04-04 04:32:53.000000000 -0800 @@ -159,7 +159,6 @@ EXPORT_SYMBOL(lookup_hash); EXPORT_SYMBOL(sys_close); EXPORT_SYMBOL(dcache_lock); -EXPORT_SYMBOL(dparent_lock); EXPORT_SYMBOL(d_alloc_root); EXPORT_SYMBOL(d_delete); EXPORT_SYMBOL(dget_locked); diff -urN linux-2.5.66-bk9/kernel/module.c linux-2.5.66-bk10/kernel/module.c --- linux-2.5.66-bk9/kernel/module.c 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/kernel/module.c 2003-04-04 04:32:53.000000000 -0800 @@ -974,6 +974,11 @@ /* Ok if weak. */ if (ELF_ST_BIND(sym[i].st_info) == STB_WEAK) break; +#if defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64) + /* Ok if Sparc register directive. */ + if (ELF_ST_TYPE(sym[i].st_info) == STT_REGISTER) + break; +#endif printk(KERN_WARNING "%s: Unknown symbol %s\n", mod->name, strtab + sym[i].st_name); diff -urN linux-2.5.66-bk9/mm/fadvise.c linux-2.5.66-bk10/mm/fadvise.c --- linux-2.5.66-bk9/mm/fadvise.c 2003-03-24 14:00:19.000000000 -0800 +++ linux-2.5.66-bk10/mm/fadvise.c 2003-04-04 04:32:53.000000000 -0800 @@ -61,6 +61,8 @@ ret = 0; break; case POSIX_FADV_DONTNEED: + if (!bdi_write_congested(mapping->backing_dev_info)) + filemap_flush(mapping); invalidate_mapping_pages(mapping, offset >> PAGE_CACHE_SHIFT, (len >> PAGE_CACHE_SHIFT) + 1); break; diff -urN linux-2.5.66-bk9/mm/filemap.c linux-2.5.66-bk10/mm/filemap.c --- linux-2.5.66-bk9/mm/filemap.c 2003-03-24 14:00:15.000000000 -0800 +++ linux-2.5.66-bk10/mm/filemap.c 2003-04-04 04:32:53.000000000 -0800 @@ -122,11 +122,11 @@ * if a dirty page/buffer is encountered, it must be waited upon, and not just * skipped over. */ -int filemap_fdatawrite(struct address_space *mapping) +static int __filemap_fdatawrite(struct address_space *mapping, int sync_mode) { int ret; struct writeback_control wbc = { - .sync_mode = WB_SYNC_ALL, + .sync_mode = sync_mode, .nr_to_write = mapping->nrpages * 2, }; @@ -140,6 +140,20 @@ return ret; } +int filemap_fdatawrite(struct address_space *mapping) +{ + return __filemap_fdatawrite(mapping, WB_SYNC_ALL); +} + +/* + * This is a mostly non-blocking flush. Not suitable for data-integrity + * purposes. + */ +int filemap_flush(struct address_space *mapping) +{ + return __filemap_fdatawrite(mapping, WB_SYNC_NONE); +} + /** * filemap_fdatawait - walk the list of locked pages of the given address * space and wait for all of them. @@ -1509,9 +1523,8 @@ send_sig(SIGXFSZ, current, 0); return -EFBIG; } - if (*pos > 0xFFFFFFFFULL || *count > limit-(u32)*pos) { - /* send_sig(SIGXFSZ, current, 0); */ - *count = limit - (u32)*pos; + if (*count > limit - (typeof(limit))*pos) { + *count = limit - (typeof(limit))*pos; } } } @@ -1525,9 +1538,8 @@ send_sig(SIGXFSZ, current, 0); return -EFBIG; } - if (*count > MAX_NON_LFS - (u32)*pos) { - /* send_sig(SIGXFSZ, current, 0); */ - *count = MAX_NON_LFS - (u32)*pos; + if (*count > MAX_NON_LFS - (unsigned long)*pos) { + *count = MAX_NON_LFS - (unsigned long)*pos; } } diff -urN linux-2.5.66-bk9/mm/shmem.c linux-2.5.66-bk10/mm/shmem.c --- linux-2.5.66-bk9/mm/shmem.c 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/mm/shmem.c 2003-04-04 04:32:53.000000000 -0800 @@ -35,6 +35,7 @@ #include #include #include +#include /* This magic number is used in glibc for posix shared memory */ #define TMPFS_MAGIC 0x01021994 @@ -750,9 +751,9 @@ * Normally, filepage is NULL on entry, and either found * uptodate immediately, or allocated and zeroed, or read * in under swappage, which is then assigned to filepage. - * But shmem_readpage and shmem_prepare_write pass in a locked - * filepage, which may be found not uptodate by other callers - * too, and may need to be copied from the swappage read in. + * But shmem_prepare_write passes in a locked filepage, + * which may be found not uptodate by other callers too, + * and may need to be copied from the swappage read in. */ repeat: if (!filepage) @@ -839,7 +840,8 @@ SetPageUptodate(filepage); set_page_dirty(filepage); swap_free(swap); - } else if (move_from_swap_cache(swappage, idx, mapping) == 0) { + } else if (!(error = move_from_swap_cache( + swappage, idx, mapping))) { shmem_swp_set(info, entry, 0); shmem_swp_unmap(entry); spin_unlock(&info->lock); @@ -850,8 +852,10 @@ spin_unlock(&info->lock); unlock_page(swappage); page_cache_release(swappage); - /* let kswapd refresh zone for GFP_ATOMICs */ - blk_congestion_wait(WRITE, HZ/50); + if (error == -ENOMEM) { + /* let kswapd refresh zone for GFP_ATOMICs */ + blk_congestion_wait(WRITE, HZ/50); + } goto repeat; } } else if (sgp == SGP_READ && !filepage) { @@ -905,8 +909,6 @@ filepage = NULL; if (error) goto failed; - /* let kswapd refresh zone for GFP_ATOMICs */ - blk_congestion_wait(WRITE, HZ / 50); goto repeat; } } @@ -950,6 +952,7 @@ if (error) return (error == -ENOMEM)? NOPAGE_OOM: NOPAGE_SIGBUS; + mark_page_accessed(page); flush_page_to_ram(page); return page; } @@ -977,6 +980,8 @@ if (err) return err; if (page) { + mark_page_accessed(page); + flush_page_to_ram(page); err = install_page(mm, vma, addr, page, prot); if (err) { page_cache_release(page); @@ -1101,20 +1106,10 @@ static struct inode_operations shmem_symlink_inline_operations; /* - * tmpfs itself makes no use of generic_file_read, generic_file_mmap - * or generic_file_write; but shmem_readpage, shmem_prepare_write and - * simple_commit_write let a tmpfs file be used below the loop driver. + * Normally tmpfs makes no use of shmem_prepare_write, but it + * lets a tmpfs file be used read-write below the loop driver. */ static int -shmem_readpage(struct file *file, struct page *page) -{ - struct inode *inode = page->mapping->host; - int error = shmem_getpage(inode, page->index, &page, SGP_CACHE); - unlock_page(page); - return error; -} - -static int shmem_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to) { struct inode *inode = page->mapping->host; @@ -1125,10 +1120,8 @@ shmem_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { struct inode *inode = file->f_dentry->d_inode; - unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur; loff_t pos; unsigned long written; - long status; int err; loff_t maxpos; @@ -1141,88 +1134,25 @@ down(&inode->i_sem); pos = *ppos; - err = -EINVAL; - if (pos < 0) - goto out_nc; - - err = file->f_error; - if (err) { - file->f_error = 0; - goto out_nc; - } - written = 0; - if (file->f_flags & O_APPEND) - pos = inode->i_size; + err = generic_write_checks(inode, file, &pos, &count, 0); + if (err || !count) + goto out; maxpos = inode->i_size; - if (pos + count > inode->i_size) { + if (maxpos < pos + count) { maxpos = pos + count; - if (maxpos > SHMEM_MAX_BYTES) - maxpos = SHMEM_MAX_BYTES; if (!vm_enough_memory(VM_ACCT(maxpos) - VM_ACCT(inode->i_size))) { err = -ENOMEM; - goto out_nc; - } - } - - /* - * Check whether we've reached the file size limit. - */ - err = -EFBIG; - if (limit != RLIM_INFINITY) { - if (pos >= limit) { - send_sig(SIGXFSZ, current, 0); goto out; } - if (pos > 0xFFFFFFFFULL || count > limit - (u32)pos) { - /* send_sig(SIGXFSZ, current, 0); */ - count = limit - (u32)pos; - } } - /* - * LFS rule - */ - if (pos + count > MAX_NON_LFS && !(file->f_flags&O_LARGEFILE)) { - if (pos >= MAX_NON_LFS) { - send_sig(SIGXFSZ, current, 0); - goto out; - } - if (count > MAX_NON_LFS - (u32)pos) { - /* send_sig(SIGXFSZ, current, 0); */ - count = MAX_NON_LFS - (u32)pos; - } - } - - /* - * Are we about to exceed the fs block limit ? - * - * If we have written data it becomes a short write - * If we have exceeded without writing data we send - * a signal and give them an EFBIG. - * - * Linus frestrict idea will clean these up nicely.. - */ - if (pos >= SHMEM_MAX_BYTES) { - if (count || pos > SHMEM_MAX_BYTES) { - send_sig(SIGXFSZ, current, 0); - err = -EFBIG; - goto out; - } - /* zero-length writes at ->s_maxbytes are OK */ - } - if (pos + count > SHMEM_MAX_BYTES) - count = SHMEM_MAX_BYTES - pos; - - status = 0; - if (count) { - remove_suid(file->f_dentry); - inode->i_ctime = inode->i_mtime = CURRENT_TIME; - } + remove_suid(file->f_dentry); + inode->i_ctime = inode->i_mtime = CURRENT_TIME; - while (count) { + do { struct page *page = NULL; unsigned long bytes, index, offset; char *kaddr; @@ -1240,8 +1170,8 @@ * But it still may be a good idea to prefault below. */ - status = shmem_getpage(inode, index, &page, SGP_WRITE); - if (status) + err = shmem_getpage(inode, index, &page, SGP_WRITE); + if (err) break; left = bytes; @@ -1262,15 +1192,18 @@ flush_dcache_page(page); if (left) { page_cache_release(page); - status = -EFAULT; + err = -EFAULT; break; } + if (!PageReferenced(page)) + SetPageReferenced(page); set_page_dirty(page); page_cache_release(page); /* - * Balance dirty pages?? + * Our dirty pages are not counted in nr_dirty, + * and we do not attempt to balance dirty pages. */ written += bytes; @@ -1279,15 +1212,18 @@ buf += bytes; if (pos > inode->i_size) inode->i_size = pos; - } + + cond_resched(); + } while (count); *ppos = pos; - err = written ? written : status; -out: + if (written) + err = written; + /* Short writes give back address space */ if (inode->i_size != maxpos) vm_unacct_memory(VM_ACCT(maxpos) - VM_ACCT(inode->i_size)); -out_nc: +out: up(&inode->i_sem); return err; } @@ -1336,13 +1272,20 @@ } nr -= offset; - /* If users can be writing to this page using arbitrary - * virtual addresses, take care about potential aliasing - * before reading the page on the kernel side. - */ - if (!list_empty(&mapping->i_mmap_shared) && - page != ZERO_PAGE(0)) - flush_dcache_page(page); + if (page != ZERO_PAGE(0)) { + /* + * If users can be writing to this page using arbitrary + * virtual addresses, take care about potential aliasing + * before reading the page on the kernel side. + */ + if (!list_empty(&mapping->i_mmap_shared)) + flush_dcache_page(page); + /* + * Mark the page accessed if we read the beginning. + */ + if (!offset) + mark_page_accessed(page); + } /* * Ok, we have the page, and it's up-to-date, so @@ -1362,6 +1305,8 @@ page_cache_release(page); if (ret != nr || !desc->count) break; + + cond_resched(); } *ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset; @@ -1595,6 +1540,7 @@ return res; res = vfs_readlink(dentry, buffer, buflen, kmap(page)); kunmap(page); + mark_page_accessed(page); page_cache_release(page); return res; } @@ -1607,6 +1553,7 @@ return res; res = vfs_follow_link(nd, kmap(page)); kunmap(page); + mark_page_accessed(page); page_cache_release(page); return res; } @@ -1641,6 +1588,12 @@ if (!strcmp(this_char,"size")) { unsigned long long size; size = memparse(value,&rest); + if (*rest == '%') { + size <<= PAGE_SHIFT; + size *= totalram_pages; + do_div(size, 100); + rest++; + } if (*rest) goto bad_val; *blocks = size >> PAGE_CACHE_SHIFT; @@ -1706,7 +1659,6 @@ uid_t uid = current->fsuid; gid_t gid = current->fsgid; struct shmem_sb_info *sbinfo; - struct sysinfo si; int err = -ENOMEM; sbinfo = kmalloc(sizeof(struct shmem_sb_info), GFP_KERNEL); @@ -1719,8 +1671,7 @@ * Per default we only allow half of the physical ram per * tmpfs instance */ - si_meminfo(&si); - blocks = inodes = si.totalram / 2; + blocks = inodes = totalram_pages / 2; #ifdef CONFIG_TMPFS if (shmem_parse_options(data, &mode, &uid, &gid, &blocks, &inodes)) { @@ -1813,7 +1764,6 @@ .writepage = shmem_writepage, .set_page_dirty = __set_page_dirty_nobuffers, #ifdef CONFIG_TMPFS - .readpage = shmem_readpage, .prepare_write = shmem_prepare_write, .commit_write = simple_commit_write, #endif @@ -1822,6 +1772,7 @@ static struct file_operations shmem_file_operations = { .mmap = shmem_mmap, #ifdef CONFIG_TMPFS + .llseek = generic_file_llseek, .read = shmem_file_read, .write = shmem_file_write, .fsync = simple_sync_file, diff -urN linux-2.5.66-bk9/net/atm/common.c linux-2.5.66-bk10/net/atm/common.c --- linux-2.5.66-bk9/net/atm/common.c 2003-03-24 14:01:53.000000000 -0800 +++ linux-2.5.66-bk10/net/atm/common.c 2003-04-04 04:32:53.000000000 -0800 @@ -6,8 +6,7 @@ #include #include #include -#include /* struct socket, struct net_proto, struct - proto_ops */ +#include /* struct socket, struct proto_ops */ #include /* ATM stuff */ #include #include /* CLIP_*ENCAP */ diff -urN linux-2.5.66-bk9/net/atm/pvc.c linux-2.5.66-bk10/net/atm/pvc.c --- linux-2.5.66-bk9/net/atm/pvc.c 2003-03-24 14:00:14.000000000 -0800 +++ linux-2.5.66-bk10/net/atm/pvc.c 2003-04-04 04:32:53.000000000 -0800 @@ -4,8 +4,7 @@ #include -#include /* struct socket, struct net_proto, - struct proto_ops */ +#include /* struct socket, struct proto_ops */ #include /* ATM stuff */ #include /* ATM devices */ #include /* Classical IP over ATM */ @@ -111,8 +110,8 @@ static struct net_proto_family pvc_family_ops = { - .family =PF_ATMPVC, - .create =pvc_create, + .family = PF_ATMPVC, + .create = pvc_create, }; diff -urN linux-2.5.66-bk9/net/atm/svc.c linux-2.5.66-bk10/net/atm/svc.c --- linux-2.5.66-bk9/net/atm/svc.c 2003-03-24 14:00:54.000000000 -0800 +++ linux-2.5.66-bk10/net/atm/svc.c 2003-04-04 04:32:53.000000000 -0800 @@ -4,8 +4,7 @@ #include -#include /* struct socket, struct net_proto, - struct proto_ops */ +#include /* struct socket, struct proto_ops */ #include /* error codes */ #include /* printk */ #include @@ -430,8 +429,8 @@ static struct net_proto_family svc_family_ops = { - .family =PF_ATMSVC, - .create =svc_create, + .family = PF_ATMSVC, + .create = svc_create, }; diff -urN linux-2.5.66-bk9/net/bluetooth/af_bluetooth.c linux-2.5.66-bk10/net/bluetooth/af_bluetooth.c --- linux-2.5.66-bk9/net/bluetooth/af_bluetooth.c 2003-03-24 14:00:08.000000000 -0800 +++ linux-2.5.66-bk10/net/bluetooth/af_bluetooth.c 2003-04-04 04:32:53.000000000 -0800 @@ -320,9 +320,9 @@ return err; } -struct net_proto_family bt_sock_family_ops = -{ - PF_BLUETOOTH, bt_sock_create +struct net_proto_family bt_sock_family_ops = { + .family = PF_BLUETOOTH, + .create = bt_sock_create, }; extern int hci_sock_init(void); diff -urN linux-2.5.66-bk9/net/bluetooth/hci_sock.c linux-2.5.66-bk10/net/bluetooth/hci_sock.c --- linux-2.5.66-bk9/net/bluetooth/hci_sock.c 2003-03-24 14:00:45.000000000 -0800 +++ linux-2.5.66-bk10/net/bluetooth/hci_sock.c 2003-04-04 04:32:53.000000000 -0800 @@ -633,7 +633,7 @@ struct net_proto_family hci_sock_family_ops = { .family = PF_BLUETOOTH, - .create = hci_sock_create + .create = hci_sock_create, }; struct notifier_block hci_sock_nblock = { diff -urN linux-2.5.66-bk9/net/bluetooth/l2cap.c linux-2.5.66-bk10/net/bluetooth/l2cap.c --- linux-2.5.66-bk9/net/bluetooth/l2cap.c 2003-03-24 14:01:11.000000000 -0800 +++ linux-2.5.66-bk10/net/bluetooth/l2cap.c 2003-04-04 04:32:53.000000000 -0800 @@ -2103,7 +2103,7 @@ static struct net_proto_family l2cap_sock_family_ops = { .family = PF_BLUETOOTH, - .create = l2cap_sock_create + .create = l2cap_sock_create, }; static struct hci_proto l2cap_hci_proto = { diff -urN linux-2.5.66-bk9/net/bluetooth/sco.c linux-2.5.66-bk10/net/bluetooth/sco.c --- linux-2.5.66-bk9/net/bluetooth/sco.c 2003-03-24 14:00:10.000000000 -0800 +++ linux-2.5.66-bk10/net/bluetooth/sco.c 2003-04-04 04:32:53.000000000 -0800 @@ -988,7 +988,7 @@ static struct net_proto_family sco_sock_family_ops = { .family = PF_BLUETOOTH, - .create = sco_sock_create + .create = sco_sock_create, }; static struct hci_proto sco_hci_proto = { diff -urN linux-2.5.66-bk9/net/core/dev.c linux-2.5.66-bk10/net/core/dev.c --- linux-2.5.66-bk9/net/core/dev.c 2003-03-24 14:00:39.000000000 -0800 +++ linux-2.5.66-bk10/net/core/dev.c 2003-04-04 04:32:53.000000000 -0800 @@ -2646,6 +2646,13 @@ return 0; } +/* Synchronize with packet receive processing. */ +void synchronize_net(void) +{ + br_write_lock_bh(BR_NETPROTO_LOCK); + br_write_unlock_bh(BR_NETPROTO_LOCK); +} + /** * unregister_netdevice - remove device from the kernel * @dev: device @@ -2688,10 +2695,7 @@ return -ENODEV; } - /* Synchronize to net_rx_action. */ - br_write_lock_bh(BR_NETPROTO_LOCK); - br_write_unlock_bh(BR_NETPROTO_LOCK); - + synchronize_net(); #ifdef CONFIG_NET_FASTROUTE dev_clear_fastroute(dev); diff -urN linux-2.5.66-bk9/net/ipv4/af_inet.c linux-2.5.66-bk10/net/ipv4/af_inet.c --- linux-2.5.66-bk9/net/ipv4/af_inet.c 2003-03-24 14:00:02.000000000 -0800 +++ linux-2.5.66-bk10/net/ipv4/af_inet.c 2003-04-04 04:32:53.000000000 -0800 @@ -1122,7 +1122,7 @@ printk(KERN_INFO "NET4: Linux TCP/IP 1.0 for NET4.0\n"); if (sizeof(struct inet_skb_parm) > sizeof(dummy_skb->cb)) { - printk(KERN_CRIT "inet_proto_init: panic\n"); + printk(KERN_CRIT "%s: panic\n", __FUNCTION__); return -EINVAL; } diff -urN linux-2.5.66-bk9/net/ipv4/ah.c linux-2.5.66-bk10/net/ipv4/ah.c --- linux-2.5.66-bk9/net/ipv4/ah.c 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/net/ipv4/ah.c 2003-04-04 04:32:53.000000000 -0800 @@ -9,8 +9,6 @@ #include -#define AH_HLEN_NOICV 12 - /* Clear mutable options and find final destination to substitute * into IP header for icv calculation. Options are already checked * for validity, so paranoia is not required. */ @@ -116,8 +114,8 @@ ah->nexthdr = iph->protocol; } ahp = x->data; - ah->hdrlen = (XFRM_ALIGN8(ahp->icv_trunc_len + - AH_HLEN_NOICV) >> 2) - 2; + ah->hdrlen = (XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + + ahp->icv_trunc_len) >> 2) - 2; ah->reserved = 0; ah->spi = x->id.spi; @@ -154,7 +152,7 @@ return err; } -int ah_input(struct xfrm_state *x, struct sk_buff *skb) +int ah_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) { int ah_hlen; struct iphdr *iph; @@ -169,8 +167,8 @@ ahp = x->data; ah_hlen = (ah->hdrlen + 2) << 2; - if (ah_hlen != XFRM_ALIGN8(ahp->icv_full_len + AH_HLEN_NOICV) && - ah_hlen != XFRM_ALIGN8(ahp->icv_trunc_len + AH_HLEN_NOICV)) + if (ah_hlen != XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + ahp->icv_full_len) && + ah_hlen != XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + ahp->icv_trunc_len)) goto out; if (!pskb_may_pull(skb, ah_hlen)) @@ -286,7 +284,7 @@ if (!ahp->work_icv) goto error; - x->props.header_len = XFRM_ALIGN8(ahp->icv_trunc_len + AH_HLEN_NOICV); + x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + ahp->icv_trunc_len); if (x->props.mode) x->props.header_len += sizeof(struct iphdr); x->data = ahp; diff -urN linux-2.5.66-bk9/net/ipv4/devinet.c linux-2.5.66-bk10/net/ipv4/devinet.c --- linux-2.5.66-bk9/net/ipv4/devinet.c 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/net/ipv4/devinet.c 2003-04-04 04:32:53.000000000 -0800 @@ -1131,166 +1131,166 @@ } devinet_sysctl = { .devinet_vars = { { - .ctl_name = NET_IPV4_CONF_FORWARDING, - .procname = "forwarding", - .data = &ipv4_devconf.forwarding, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler =&devinet_sysctl_forward, - }, - { - .ctl_name = NET_IPV4_CONF_MC_FORWARDING, - .procname = "mc_forwarding", - .data = &ipv4_devconf.mc_forwarding, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler =&proc_dointvec, - }, - { - .ctl_name = NET_IPV4_CONF_ACCEPT_REDIRECTS, - .procname = "accept_redirects", - .data = &ipv4_devconf.accept_redirects, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler =&proc_dointvec, - }, - { - .ctl_name = NET_IPV4_CONF_SECURE_REDIRECTS, - .procname = "secure_redirects", - .data = &ipv4_devconf.secure_redirects, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler =&proc_dointvec, - }, - { - .ctl_name = NET_IPV4_CONF_SHARED_MEDIA, - .procname = "shared_media", - .data = &ipv4_devconf.shared_media, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler =&proc_dointvec, - }, - { - .ctl_name = NET_IPV4_CONF_RP_FILTER, - .procname = "rp_filter", - .data = &ipv4_devconf.rp_filter, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler =&proc_dointvec, - }, - { - .ctl_name = NET_IPV4_CONF_SEND_REDIRECTS, - .procname = "send_redirects", - .data = &ipv4_devconf.send_redirects, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler =&proc_dointvec, - }, - { - .ctl_name = NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE, - .procname = "accept_source_route", - .data = &ipv4_devconf.accept_source_route, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler =&proc_dointvec, - }, - { - .ctl_name = NET_IPV4_CONF_PROXY_ARP, - .procname = "proxy_arp", - .data = &ipv4_devconf.proxy_arp, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler =&proc_dointvec, - }, - { - .ctl_name = NET_IPV4_CONF_MEDIUM_ID, - .procname = "medium_id", - .data = &ipv4_devconf.medium_id, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler =&proc_dointvec, - }, - { - .ctl_name = NET_IPV4_CONF_BOOTP_RELAY, - .procname = "bootp_relay", - .data = &ipv4_devconf.bootp_relay, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler =&proc_dointvec, - }, - { - .ctl_name = NET_IPV4_CONF_LOG_MARTIANS, - .procname = "log_martians", - .data = &ipv4_devconf.log_martians, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler =&proc_dointvec, - }, - { - .ctl_name = NET_IPV4_CONF_TAG, - .procname = "tag", - .data = &ipv4_devconf.tag, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler =&proc_dointvec, - }, - { - .ctl_name = NET_IPV4_CONF_ARPFILTER, - .procname = "arp_filter", - .data = &ipv4_devconf.arp_filter, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler =&proc_dointvec, - }, - { - .ctl_name = NET_IPV4_CONF_NOXFRM, - .procname = "disable_xfrm", - .data = &ipv4_devconf.no_xfrm, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &ipv4_doint_and_flush, - .strategy = &ipv4_doint_and_flush_strategy, - }, - { - .ctl_name = NET_IPV4_CONF_NOPOLICY, - .procname = "disable_policy", - .data = &ipv4_devconf.no_policy, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &ipv4_doint_and_flush, - .strategy = &ipv4_doint_and_flush_strategy, + .ctl_name = NET_IPV4_CONF_FORWARDING, + .procname = "forwarding", + .data = &ipv4_devconf.forwarding, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &devinet_sysctl_forward, + }, + { + .ctl_name = NET_IPV4_CONF_MC_FORWARDING, + .procname = "mc_forwarding", + .data = &ipv4_devconf.mc_forwarding, + .maxlen = sizeof(int), + .mode = 0444, + .proc_handler = &proc_dointvec, + }, + { + .ctl_name = NET_IPV4_CONF_ACCEPT_REDIRECTS, + .procname = "accept_redirects", + .data = &ipv4_devconf.accept_redirects, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { + .ctl_name = NET_IPV4_CONF_SECURE_REDIRECTS, + .procname = "secure_redirects", + .data = &ipv4_devconf.secure_redirects, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { + .ctl_name = NET_IPV4_CONF_SHARED_MEDIA, + .procname = "shared_media", + .data = &ipv4_devconf.shared_media, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { + .ctl_name = NET_IPV4_CONF_RP_FILTER, + .procname = "rp_filter", + .data = &ipv4_devconf.rp_filter, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { + .ctl_name = NET_IPV4_CONF_SEND_REDIRECTS, + .procname = "send_redirects", + .data = &ipv4_devconf.send_redirects, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { + .ctl_name = NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE, + .procname = "accept_source_route", + .data = &ipv4_devconf.accept_source_route, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { + .ctl_name = NET_IPV4_CONF_PROXY_ARP, + .procname = "proxy_arp", + .data = &ipv4_devconf.proxy_arp, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { + .ctl_name = NET_IPV4_CONF_MEDIUM_ID, + .procname = "medium_id", + .data = &ipv4_devconf.medium_id, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { + .ctl_name = NET_IPV4_CONF_BOOTP_RELAY, + .procname = "bootp_relay", + .data = &ipv4_devconf.bootp_relay, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { + .ctl_name = NET_IPV4_CONF_LOG_MARTIANS, + .procname = "log_martians", + .data = &ipv4_devconf.log_martians, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { + .ctl_name = NET_IPV4_CONF_TAG, + .procname = "tag", + .data = &ipv4_devconf.tag, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { + .ctl_name = NET_IPV4_CONF_ARPFILTER, + .procname = "arp_filter", + .data = &ipv4_devconf.arp_filter, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { + .ctl_name = NET_IPV4_CONF_NOXFRM, + .procname = "disable_xfrm", + .data = &ipv4_devconf.no_xfrm, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &ipv4_doint_and_flush, + .strategy = &ipv4_doint_and_flush_strategy, + }, + { + .ctl_name = NET_IPV4_CONF_NOPOLICY, + .procname = "disable_policy", + .data = &ipv4_devconf.no_policy, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &ipv4_doint_and_flush, + .strategy = &ipv4_doint_and_flush_strategy, }, }, .devinet_dev = { { - .ctl_name = NET_PROTO_CONF_ALL, - .procname = "all", - .mode = 0555, - .child = devinet_sysctl.devinet_vars, + .ctl_name = NET_PROTO_CONF_ALL, + .procname = "all", + .mode = 0555, + .child = devinet_sysctl.devinet_vars, }, }, .devinet_conf_dir = { { - .ctl_name = NET_IPV4_CONF, - .procname = "conf", - .mode = 0555, - .child = devinet_sysctl.devinet_dev, + .ctl_name = NET_IPV4_CONF, + .procname = "conf", + .mode = 0555, + .child = devinet_sysctl.devinet_dev, }, }, .devinet_proto_dir = { { - .ctl_name = NET_IPV4, - .procname = "ipv4", - .mode = 0555, - .child = devinet_sysctl.devinet_conf_dir, + .ctl_name = NET_IPV4, + .procname = "ipv4", + .mode = 0555, + .child = devinet_sysctl.devinet_conf_dir, }, }, .devinet_root_dir = { { - .ctl_name = CTL_NET, - .procname = "net", - .mode = 0555, - .child = devinet_sysctl.devinet_proto_dir, + .ctl_name = CTL_NET, + .procname = "net", + .mode = 0555, + .child = devinet_sysctl.devinet_proto_dir, }, }, }; diff -urN linux-2.5.66-bk9/net/ipv4/esp.c linux-2.5.66-bk10/net/ipv4/esp.c --- linux-2.5.66-bk9/net/ipv4/esp.c 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/net/ipv4/esp.c 2003-04-04 04:32:53.000000000 -0800 @@ -8,10 +8,17 @@ #include #include #include - +#include #define MAX_SG_ONSTACK 4 +/* decapsulation data for use when post-processing */ +struct esp_decap_data { + xfrm_address_t saddr; + __u16 sport; + __u8 proto; +}; + int esp_output(struct sk_buff *skb) { int err; @@ -22,6 +29,8 @@ struct crypto_tfm *tfm; struct esp_data *esp; struct sk_buff *trailer; + struct udphdr *uh = NULL; + struct xfrm_encap_tmpl *encap = NULL; int blksize; int clen; int alen; @@ -76,10 +85,28 @@ *(u8*)(trailer->tail + clen-skb->len - 2) = (clen - skb->len)-2; pskb_put(skb, trailer, clen - skb->len); + encap = x->encap; + iph = skb->nh.iph; if (x->props.mode) { top_iph = (struct iphdr*)skb_push(skb, x->props.header_len); esph = (struct ip_esp_hdr*)(top_iph+1); + if (encap && encap->encap_type) { + switch (encap->encap_type) { + case UDP_ENCAP_ESPINUDP: + uh = (struct udphdr*) esph; + esph = (struct ip_esp_hdr*)(uh+1); + top_iph->protocol = IPPROTO_UDP; + break; + default: + printk(KERN_INFO + "esp_output(): Unhandled encap: %u\n", + encap->encap_type); + top_iph->protocol = IPPROTO_ESP; + break; + } + } else + top_iph->protocol = IPPROTO_ESP; *(u8*)(trailer->tail - 1) = IPPROTO_IPIP; top_iph->ihl = 5; top_iph->version = 4; @@ -89,7 +116,6 @@ if (!(top_iph->frag_off)) ip_select_ident(top_iph, dst, 0); top_iph->ttl = iph->ttl; /* TTL disclosed */ - top_iph->protocol = IPPROTO_ESP; top_iph->check = 0; top_iph->saddr = x->props.saddr.a4; top_iph->daddr = x->id.daddr.a4; @@ -98,14 +124,37 @@ esph = (struct ip_esp_hdr*)skb_push(skb, x->props.header_len); top_iph = (struct iphdr*)skb_push(skb, iph->ihl*4); memcpy(top_iph, &tmp_iph, iph->ihl*4); + if (encap && encap->encap_type) { + switch (encap->encap_type) { + case UDP_ENCAP_ESPINUDP: + uh = (struct udphdr*) esph; + esph = (struct ip_esp_hdr*)(uh+1); + top_iph->protocol = IPPROTO_UDP; + break; + default: + printk(KERN_INFO + "esp_output(): Unhandled encap: %u\n", + encap->encap_type); + top_iph->protocol = IPPROTO_ESP; + break; + } + } else + top_iph->protocol = IPPROTO_ESP; iph = &tmp_iph.iph; top_iph->tot_len = htons(skb->len + alen); - top_iph->protocol = IPPROTO_ESP; top_iph->check = 0; top_iph->frag_off = iph->frag_off; *(u8*)(trailer->tail - 1) = iph->protocol; } + /* this is non-NULL only with UDP Encapsulation */ + if (encap && uh) { + uh->source = encap->encap_sport; + uh->dest = encap->encap_dport; + uh->len = htons(skb->len + alen - sizeof(struct iphdr)); + uh->check = 0; + } + esph->spi = x->id.spi; esph->seq_no = htonl(++x->replay.oseq); @@ -134,7 +183,7 @@ if (esp->auth.icv_full_len) { esp->auth.icv(esp, skb, (u8*)esph-skb->data, - 8+esp->conf.ivlen+clen, trailer->tail); + sizeof(struct ip_esp_hdr) + esp->conf.ivlen+clen, trailer->tail); pskb_put(skb, trailer, alen); } @@ -163,7 +212,7 @@ * expensive, so we only support truncated data, which is the recommended * and common case. */ -int esp_input(struct xfrm_state *x, struct sk_buff *skb) +int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) { struct iphdr *iph; struct ip_esp_hdr *esph; @@ -171,8 +220,9 @@ struct sk_buff *trailer; int blksize = crypto_tfm_alg_blocksize(esp->conf.tfm); int alen = esp->auth.icv_trunc_len; - int elen = skb->len - 8 - esp->conf.ivlen - alen; + int elen = skb->len - sizeof(struct ip_esp_hdr) - esp->conf.ivlen - alen; int nfrags; + int encap_len = 0; if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr))) goto out; @@ -220,7 +270,7 @@ if (!sg) goto out; } - skb_to_sgvec(skb, sg, 8+esp->conf.ivlen, elen); + skb_to_sgvec(skb, sg, sizeof(struct ip_esp_hdr) + esp->conf.ivlen, elen); crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen); if (unlikely(sg != sgbuf)) kfree(sg); @@ -234,11 +284,45 @@ /* ... check padding bits here. Silly. :-) */ + if (x->encap && decap && decap->decap_type) { + struct esp_decap_data *encap_data; + struct udphdr *uh = (struct udphdr *) (iph+1); + + encap_data = (struct esp_decap_data *) (decap->decap_data); + encap_data->proto = 0; + + switch (decap->decap_type) { + case UDP_ENCAP_ESPINUDP: + + if ((void*)uh == (void*)esph) { + printk(KERN_DEBUG + "esp_input(): Got ESP; expecting ESPinUDP\n"); + break; + } + + encap_data->proto = AF_INET; + encap_data->saddr.a4 = iph->saddr; + encap_data->sport = uh->source; + encap_len = (void*)esph - (void*)uh; + if (encap_len != sizeof(*uh)) + printk(KERN_DEBUG + "esp_input(): UDP -> ESP: too much room: %d\n", + encap_len); + break; + + default: + printk(KERN_INFO + "esp_input(): processing unknown encap type: %u\n", + decap->decap_type); + break; + } + } + iph->protocol = nexthdr[1]; pskb_trim(skb, skb->len - alen - padlen - 2); memcpy(workbuf, skb->nh.raw, iph->ihl*4); - skb->h.raw = skb_pull(skb, 8 + esp->conf.ivlen); - skb->nh.raw += 8 + esp->conf.ivlen; + skb->h.raw = skb_pull(skb, sizeof(struct ip_esp_hdr) + esp->conf.ivlen); + skb->nh.raw += encap_len + sizeof(struct ip_esp_hdr) + esp->conf.ivlen; memcpy(skb->nh.raw, workbuf, iph->ihl*4); skb->nh.iph->tot_len = htons(skb->len); } @@ -249,6 +333,70 @@ return -EINVAL; } +int esp_post_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) +{ + + if (x->encap) { + struct xfrm_encap_tmpl *encap; + struct esp_decap_data *decap_data; + + encap = x->encap; + decap_data = (struct esp_decap_data *)(decap->decap_data); + + /* first, make sure that the decap type == the encap type */ + if (encap->encap_type != decap->decap_type) + return -EINVAL; + + /* Next, if we don't have an encap type, then ignore it */ + if (!encap->encap_type) + return 0; + + switch (encap->encap_type) { + case UDP_ENCAP_ESPINUDP: + /* + * 1) if the NAT-T peer's IP or port changed then + * advertize the change to the keying daemon. + * This is an inbound SA, so just compare + * SRC ports. + */ + if (decap_data->proto == AF_INET && + (decap_data->saddr.a4 != x->props.saddr.a4 || + decap_data->sport != encap->encap_sport)) { + xfrm_address_t ipaddr; + + ipaddr.a4 = decap_data->saddr.a4; + km_new_mapping(x, &ipaddr, decap_data->sport); + + /* XXX: perhaps add an extra + * policy check here, to see + * if we should allow or + * reject a packet from a + * different source + * address/port. + */ + } + + /* + * 2) ignore UDP/TCP checksums in case + * of NAT-T in Transport Mode, or + * perform other post-processing fixes + * as per * draft-ietf-ipsec-udp-encaps-06, + * section 3.1.2 + */ + if (!x->props.mode) + skb->ip_summed = CHECKSUM_UNNECESSARY; + + break; + default: + printk(KERN_INFO + "esp4_post_input(): Unhandled encap type: %u\n", + encap->encap_type); + break; + } + } + return 0; +} + static u32 esp4_get_max_size(struct xfrm_state *x, int mtu) { struct esp_data *esp = x->data; @@ -365,9 +513,25 @@ get_random_bytes(esp->conf.ivec, esp->conf.ivlen); } crypto_cipher_setkey(esp->conf.tfm, esp->conf.key, esp->conf.key_len); - x->props.header_len = 8 + esp->conf.ivlen; + x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen; if (x->props.mode) x->props.header_len += sizeof(struct iphdr); + if (x->encap) { + struct xfrm_encap_tmpl *encap = x->encap; + + if (encap->encap_type) { + switch (encap->encap_type) { + case UDP_ENCAP_ESPINUDP: + x->props.header_len += sizeof(struct udphdr); + break; + default: + printk (KERN_INFO + "esp_init_state(): Unhandled encap type: %u\n", + encap->encap_type); + break; + } + } + } x->data = esp; x->props.trailer_len = esp4_get_max_size(x, 0) - x->props.header_len; return 0; @@ -393,6 +557,7 @@ .destructor = esp_destroy, .get_max_size = esp4_get_max_size, .input = esp_input, + .post_input = esp_post_input, .output = esp_output }; @@ -404,6 +569,15 @@ int __init esp4_init(void) { + struct xfrm_decap_state decap; + + if (sizeof(struct esp_decap_data) < + sizeof(decap.decap_data)) { + extern void decap_data_too_small(void); + + decap_data_too_small(); + } + SET_MODULE_OWNER(&esp_type); if (xfrm_register_type(&esp_type, AF_INET) < 0) { printk(KERN_INFO "ip esp init: can't add xfrm type\n"); diff -urN linux-2.5.66-bk9/net/ipv4/fib_hash.c linux-2.5.66-bk10/net/ipv4/fib_hash.c --- linux-2.5.66-bk9/net/ipv4/fib_hash.c 2003-03-24 14:00:35.000000000 -0800 +++ linux-2.5.66-bk10/net/ipv4/fib_hash.c 2003-04-04 04:32:53.000000000 -0800 @@ -936,14 +936,10 @@ goto out; } - for (;;) { - iter->zone = iter->zone->fz_next; + iter->zone = iter->zone->fz_next; - if (!iter->zone) - goto out; - if (iter->zone->fz_next) - break; - } + if (!iter->zone) + goto out; iter->hash = iter->zone->fz_hash; iter->bucket = 0; diff -urN linux-2.5.66-bk9/net/ipv4/netfilter/ip_conntrack_core.c linux-2.5.66-bk10/net/ipv4/netfilter/ip_conntrack_core.c --- linux-2.5.66-bk9/net/ipv4/netfilter/ip_conntrack_core.c 2003-03-24 13:59:46.000000000 -0800 +++ linux-2.5.66-bk10/net/ipv4/netfilter/ip_conntrack_core.c 2003-04-04 04:32:53.000000000 -0800 @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -1160,8 +1159,7 @@ WRITE_UNLOCK(&ip_conntrack_lock); /* Someone could be still looking at the helper in a bh. */ - br_write_lock_bh(BR_NETPROTO_LOCK); - br_write_unlock_bh(BR_NETPROTO_LOCK); + synchronize_net(); } /* Refresh conntrack for this many jiffies. */ @@ -1401,8 +1399,7 @@ /* This makes sure all current packets have passed through netfilter framework. Roll on, two-stage module delete... */ - br_write_lock_bh(BR_NETPROTO_LOCK); - br_write_unlock_bh(BR_NETPROTO_LOCK); + synchronize_net(); i_see_dead_people: ip_ct_selective_cleanup(kill_all, NULL); diff -urN linux-2.5.66-bk9/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.5.66-bk10/net/ipv4/netfilter/ip_conntrack_standalone.c --- linux-2.5.66-bk9/net/ipv4/netfilter/ip_conntrack_standalone.c 2003-03-24 14:00:21.000000000 -0800 +++ linux-2.5.66-bk10/net/ipv4/netfilter/ip_conntrack_standalone.c 2003-04-04 04:32:53.000000000 -0800 @@ -15,7 +15,6 @@ #include #include #include -#include #include #define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_conntrack_lock) @@ -342,8 +341,7 @@ WRITE_UNLOCK(&ip_conntrack_lock); /* Somebody could be still looking at the proto in bh. */ - br_write_lock_bh(BR_NETPROTO_LOCK); - br_write_unlock_bh(BR_NETPROTO_LOCK); + synchronize_net(); /* Remove all contrack entries for this protocol */ ip_ct_selective_cleanup(kill_proto, &proto->proto); diff -urN linux-2.5.66-bk9/net/ipv4/netfilter/ip_nat_helper.c linux-2.5.66-bk10/net/ipv4/netfilter/ip_nat_helper.c --- linux-2.5.66-bk9/net/ipv4/netfilter/ip_nat_helper.c 2003-03-24 14:00:08.000000000 -0800 +++ linux-2.5.66-bk10/net/ipv4/netfilter/ip_nat_helper.c 2003-04-04 04:32:53.000000000 -0800 @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -545,8 +544,7 @@ WRITE_UNLOCK(&ip_nat_lock); /* Someone could be still looking at the helper in a bh. */ - br_write_lock_bh(BR_NETPROTO_LOCK); - br_write_unlock_bh(BR_NETPROTO_LOCK); + synchronize_net(); /* Find anything using it, and umm, kill them. We can't turn them into normal connections: if we've adjusted SYNs, then diff -urN linux-2.5.66-bk9/net/ipv4/netfilter/ip_nat_snmp_basic.c linux-2.5.66-bk10/net/ipv4/netfilter/ip_nat_snmp_basic.c --- linux-2.5.66-bk9/net/ipv4/netfilter/ip_nat_snmp_basic.c 2003-03-24 14:01:17.000000000 -0800 +++ linux-2.5.66-bk10/net/ipv4/netfilter/ip_nat_snmp_basic.c 2003-04-04 04:32:53.000000000 -0800 @@ -50,7 +50,6 @@ #include #include #include -#include #include #include #include @@ -1351,8 +1350,7 @@ { ip_nat_helper_unregister(&snmp); ip_nat_helper_unregister(&snmp_trap); - br_write_lock_bh(BR_NETPROTO_LOCK); - br_write_unlock_bh(BR_NETPROTO_LOCK); + synchronize_net(); } module_init(init); diff -urN linux-2.5.66-bk9/net/ipv4/netfilter/ip_nat_standalone.c linux-2.5.66-bk10/net/ipv4/netfilter/ip_nat_standalone.c --- linux-2.5.66-bk9/net/ipv4/netfilter/ip_nat_standalone.c 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/net/ipv4/netfilter/ip_nat_standalone.c 2003-04-04 04:32:53.000000000 -0800 @@ -24,7 +24,6 @@ #include #include #include -#include #define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock) #define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock) @@ -286,8 +285,7 @@ WRITE_UNLOCK(&ip_nat_lock); /* Someone could be still looking at the proto in a bh. */ - br_write_lock_bh(BR_NETPROTO_LOCK); - br_write_unlock_bh(BR_NETPROTO_LOCK); + synchronize_net(); } static int init_or_cleanup(int init) diff -urN linux-2.5.66-bk9/net/ipv4/netfilter/ip_queue.c linux-2.5.66-bk10/net/ipv4/netfilter/ip_queue.c --- linux-2.5.66-bk9/net/ipv4/netfilter/ip_queue.c 2003-03-24 14:01:53.000000000 -0800 +++ linux-2.5.66-bk10/net/ipv4/netfilter/ip_queue.c 2003-04-04 04:32:53.000000000 -0800 @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -679,8 +678,7 @@ cleanup: nf_unregister_queue_handler(PF_INET); - br_write_lock_bh(BR_NETPROTO_LOCK); - br_write_unlock_bh(BR_NETPROTO_LOCK); + synchronize_net(); ipq_flush(NF_DROP); cleanup_sysctl: diff -urN linux-2.5.66-bk9/net/ipv4/netfilter/ipfwadm_core.c linux-2.5.66-bk10/net/ipv4/netfilter/ipfwadm_core.c --- linux-2.5.66-bk9/net/ipv4/netfilter/ipfwadm_core.c 2003-03-24 14:00:19.000000000 -0800 +++ linux-2.5.66-bk10/net/ipv4/netfilter/ipfwadm_core.c 2003-04-04 04:32:53.000000000 -0800 @@ -132,6 +132,8 @@ #include #include +MODULE_LICENSE("Dual BSD/GPL"); + /* * Implement IP packet firewall */ diff -urN linux-2.5.66-bk9/net/ipv4/udp.c linux-2.5.66-bk10/net/ipv4/udp.c --- linux-2.5.66-bk9/net/ipv4/udp.c 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/net/ipv4/udp.c 2003-04-04 04:32:53.000000000 -0800 @@ -69,6 +69,7 @@ * YOSHIFUJI Hideaki @USAGI and: Support IPV6_V6ONLY socket option, which * Alexey Kuznetsov: allow both IPv4 and IPv6 sockets to bind * a single port at the same time. + * Derek Atkins : Add Encapulation Support * * * This program is free software; you can redistribute it and/or @@ -941,8 +942,90 @@ inet_sock_release(sk); } +/* return: + * 1 if the the UDP system should process it + * 0 if we should drop this packet + * -1 if it should get processed by xfrm4_rcv_encap + */ +static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb) +{ + struct udp_opt *up = udp_sk(sk); + struct udphdr *uh = skb->h.uh; + struct iphdr *iph; + int iphlen, len; + + __u8 *udpdata = (__u8 *)uh + sizeof(struct udphdr); + __u32 *udpdata32 = (__u32 *)udpdata; + __u16 encap_type = up->encap_type; + + /* if we're overly short, let UDP handle it */ + if (udpdata > skb->tail) + return 1; + + /* if this is not encapsulated socket, then just return now */ + if (!encap_type) + return 1; + + len = skb->tail - udpdata; + + switch (encap_type) { + case UDP_ENCAP_ESPINUDP: + /* Check if this is a keepalive packet. If so, eat it. */ + if (len == 1 && udpdata[0] == 0xff) { + return 0; + } else if (len > sizeof(struct ip_esp_hdr) && udpdata32[0] != 0 ) { + /* ESP Packet without Non-ESP header */ + len = sizeof(struct udphdr); + } else + /* Must be an IKE packet.. pass it through */ + return 1; + + /* At this point we are sure that this is an ESPinUDP packet, + * so we need to remove 'len' bytes from the packet (the UDP + * header and optional ESP marker bytes) and then modify the + * protocol to ESP, and then call into the transform receiver. + */ + + /* Now we can update and verify the packet length... */ + iph = skb->nh.iph; + iphlen = iph->ihl << 2; + iph->tot_len = htons(ntohs(iph->tot_len) - len); + if (skb->len < iphlen + len) { + /* packet is too small!?! */ + return 0; + } + + /* pull the data buffer up to the ESP header and set the + * transport header to point to ESP. Keep UDP on the stack + * for later. + */ + skb->h.raw = skb_pull(skb, len); + + /* modify the protocol (it's ESP!) */ + iph->protocol = IPPROTO_ESP; + + /* and let the caller know to send this into the ESP processor... */ + return -1; + + default: + printk(KERN_INFO "udp_encap_rcv(): Unhandled UDP encap type: %u\n", + encap_type); + return 1; + } +} + +/* returns: + * -1: error + * 0: success + * >0: "udp encap" protocol resubmission + * + * Note that in the success and error cases, the skb is assumed to + * have either been requeued or freed. + */ static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) { + struct udp_opt *up = udp_sk(sk); + /* * Charge it to the socket, dropping if the queue is full. */ @@ -951,6 +1034,33 @@ return -1; } + if (up->encap_type) { + /* + * This is an encapsulation socket, so let's see if this is + * an encapsulated packet. + * If it's a keepalive packet, then just eat it. + * If it's an encapsulateed packet, then pass it to the + * IPsec xfrm input and return the response + * appropriately. Otherwise, just fall through and + * pass this up the UDP socket. + */ + int ret; + + ret = udp_encap_rcv(sk, skb); + if (ret == 0) { + /* Eat the packet .. */ + kfree_skb(skb); + return 0; + } + if (ret < 0) { + /* process the ESP packet */ + ret = xfrm4_rcv_encap(skb, up->encap_type); + UDP_INC_STATS_BH(UdpInDatagrams); + return -ret; + } + /* FALLTHROUGH -- it's a UDP Packet */ + } + if (sk->filter && skb->ip_summed != CHECKSUM_UNNECESSARY) { if (__udp_checksum_complete(skb)) { UDP_INC_STATS_BH(UdpInErrors); @@ -996,8 +1106,13 @@ if(sknext) skb1 = skb_clone(skb, GFP_ATOMIC); - if(skb1) - udp_queue_rcv_skb(sk, skb1); + if(skb1) { + int ret = udp_queue_rcv_skb(sk, skb1); + if (ret > 0) + /* we should probably re-process instead + * of dropping packets here. */ + kfree_skb(skb1); + } sk = sknext; } while(sknext); } else @@ -1070,8 +1185,14 @@ sk = udp_v4_lookup(saddr, uh->source, daddr, uh->dest, skb->dev->ifindex); if (sk != NULL) { - udp_queue_rcv_skb(sk, skb); + int ret = udp_queue_rcv_skb(sk, skb); sock_put(sk); + + /* a return value > 0 means to resubmit the input, but + * it it wants the return to be -protocol, or 0 + */ + if (ret > 0) + return -ret; return 0; } @@ -1163,6 +1284,10 @@ } break; + case UDP_ENCAP: + up->encap_type = val; + break; + default: err = -ENOPROTOOPT; break; @@ -1193,6 +1318,10 @@ val = up->corkflag; break; + case UDP_ENCAP: + val = up->encap_type; + break; + default: return -ENOPROTOOPT; }; diff -urN linux-2.5.66-bk9/net/ipv4/xfrm4_input.c linux-2.5.66-bk10/net/ipv4/xfrm4_input.c --- linux-2.5.66-bk9/net/ipv4/xfrm4_input.c 2003-03-24 14:00:01.000000000 -0800 +++ linux-2.5.66-bk10/net/ipv4/xfrm4_input.c 2003-04-04 04:32:53.000000000 -0800 @@ -4,6 +4,8 @@ * Changes: * YOSHIFUJI Hideaki @USAGI * Split up af-specific portion + * Derek Atkins + * Add Encapsulation support * */ @@ -14,9 +16,14 @@ int xfrm4_rcv(struct sk_buff *skb) { + return xfrm4_rcv_encap(skb, 0); +} + +int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) +{ int err; u32 spi, seq; - struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH]; + struct sec_decap_state xfrm_vec[XFRM_MAX_DEPTH]; struct xfrm_state *x; int xfrm_nr = 0; int decaps = 0; @@ -41,9 +48,13 @@ if (x->props.replay_window && xfrm_replay_check(x, seq)) goto drop_unlock; - if (x->type->input(x, skb)) + xfrm_vec[xfrm_nr].decap.decap_type = encap_type; + if (x->type->input(x, &(xfrm_vec[xfrm_nr].decap), skb)) goto drop_unlock; + /* only the first xfrm gets the encap type */ + encap_type = 0; + if (x->props.replay_window) xfrm_replay_advance(x, seq); @@ -52,7 +63,7 @@ spin_unlock(&x->lock); - xfrm_vec[xfrm_nr++] = x; + xfrm_vec[xfrm_nr++].xvec = x; iph = skb->nh.iph; @@ -91,7 +102,7 @@ if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH) goto drop; - memcpy(skb->sp->xvec+skb->sp->len, xfrm_vec, xfrm_nr*sizeof(void*)); + memcpy(skb->sp->x+skb->sp->len, xfrm_vec, xfrm_nr*sizeof(struct sec_decap_state)); skb->sp->len += xfrm_nr; if (decaps) { @@ -110,7 +121,8 @@ xfrm_state_put(x); drop: while (--xfrm_nr >= 0) - xfrm_state_put(xfrm_vec[xfrm_nr]); + xfrm_state_put(xfrm_vec[xfrm_nr].xvec); + kfree_skb(skb); return 0; } diff -urN linux-2.5.66-bk9/net/ipv6/af_inet6.c linux-2.5.66-bk10/net/ipv6/af_inet6.c --- linux-2.5.66-bk9/net/ipv6/af_inet6.c 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/net/ipv6/af_inet6.c 2003-04-04 04:32:53.000000000 -0800 @@ -536,8 +536,8 @@ }; struct net_proto_family inet6_family_ops = { - .family =PF_INET6, - .create =inet6_create, + .family = PF_INET6, + .create = inet6_create, }; #ifdef MODULE @@ -557,13 +557,13 @@ #endif static struct inet_protosw rawv6_protosw = { - .type = SOCK_RAW, - .protocol = IPPROTO_IP, /* wild card */ - .prot = &rawv6_prot, - .ops = &inet6_dgram_ops, - .capability =CAP_NET_RAW, - .no_check = UDP_CSUM_DEFAULT, - .flags = INET_PROTOSW_REUSE, + .type = SOCK_RAW, + .protocol = IPPROTO_IP, /* wild card */ + .prot = &rawv6_prot, + .ops = &inet6_dgram_ops, + .capability = CAP_NET_RAW, + .no_check = UDP_CSUM_DEFAULT, + .flags = INET_PROTOSW_REUSE, }; #define INETSW6_ARRAY_LEN (sizeof(inetsw6_array) / sizeof(struct inet_protosw)) @@ -702,7 +702,9 @@ kfree_percpu(udp_stats_in6[0]); kfree_percpu(udp_stats_in6[1]); } - + +extern int ipv6_misc_proc_init(void); + static int __init inet6_init(void) { struct sk_buff *dummy_skb; @@ -786,10 +788,9 @@ goto proc_tcp6_fail; if (!proc_net_create("udp6", 0, udp6_get_info)) goto proc_udp6_fail; - if (!proc_net_create("sockstat6", 0, afinet6_get_info)) - goto proc_sockstat6_fail; - if (!proc_net_create("snmp6", 0, afinet6_get_snmp)) - goto proc_snmp6_fail; + if (ipv6_misc_proc_init()) + goto proc_misc6_fail; + if (!proc_net_create("anycast6", 0, anycast6_get_info)) goto proc_anycast6_fail; #endif @@ -800,7 +801,7 @@ addrconf_init(); sit_init(); - /* Init v6 extention headers. */ + /* Init v6 extension headers. */ ipv6_hopopts_init(); ipv6_rthdr_init(); ipv6_frag_init(); @@ -815,10 +816,9 @@ #ifdef CONFIG_PROC_FS proc_anycast6_fail: - proc_net_remove("anycast6"); -proc_snmp6_fail: + proc_net_remove("snmp6"); proc_net_remove("sockstat6"); -proc_sockstat6_fail: +proc_misc6_fail: proc_net_remove("udp6"); proc_udp6_fail: proc_net_remove("tcp6"); diff -urN linux-2.5.66-bk9/net/ipv6/ah6.c linux-2.5.66-bk10/net/ipv6/ah6.c --- linux-2.5.66-bk9/net/ipv6/ah6.c 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/net/ipv6/ah6.c 2003-04-04 04:32:53.000000000 -0800 @@ -36,8 +36,6 @@ #include #include -#define AH_HLEN_NOICV 12 - /* XXX no ipv6 ah specific */ #define NIP6(addr) \ ntohs((addr).s6_addr16[0]),\ @@ -110,8 +108,8 @@ skb->nh.ipv6h->hop_limit = 0; ahp = x->data; - ah->hdrlen = (XFRM_ALIGN8(ahp->icv_trunc_len + - AH_HLEN_NOICV) >> 2) - 2; + ah->hdrlen = (XFRM_ALIGN8(sizeof(struct ipv6_auth_hdr) + + ahp->icv_trunc_len) >> 2) - 2; ah->reserved = 0; ah->spi = x->id.spi; @@ -148,7 +146,7 @@ return err; } -int ah6_input(struct xfrm_state *x, struct sk_buff *skb) +int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) { int ah_hlen; struct ipv6hdr *iph; @@ -165,8 +163,8 @@ ahp = x->data; ah_hlen = (ah->hdrlen + 2) << 2; - if (ah_hlen != XFRM_ALIGN8(ahp->icv_full_len + AH_HLEN_NOICV) && - ah_hlen != XFRM_ALIGN8(ahp->icv_trunc_len + AH_HLEN_NOICV)) + if (ah_hlen != XFRM_ALIGN8(sizeof(struct ipv6_auth_hdr) + ahp->icv_full_len) && + ah_hlen != XFRM_ALIGN8(sizeof(struct ipv6_auth_hdr) + ahp->icv_trunc_len)) goto out; if (!pskb_may_pull(skb, ah_hlen)) @@ -285,7 +283,7 @@ if (!ahp->work_icv) goto error; - x->props.header_len = XFRM_ALIGN8(ahp->icv_trunc_len + AH_HLEN_NOICV); + x->props.header_len = XFRM_ALIGN8(sizeof(struct ipv6_auth_hdr) + ahp->icv_trunc_len); if (x->props.mode) x->props.header_len += sizeof(struct ipv6hdr); x->data = ahp; diff -urN linux-2.5.66-bk9/net/ipv6/esp6.c linux-2.5.66-bk10/net/ipv6/esp6.c --- linux-2.5.66-bk9/net/ipv6/esp6.c 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/net/ipv6/esp6.c 2003-04-04 04:32:53.000000000 -0800 @@ -232,7 +232,7 @@ if (esp->auth.icv_full_len) { esp->auth.icv(esp, skb, (u8*)esph-skb->data, - 8+esp->conf.ivlen+clen, trailer->tail); + sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen+clen, trailer->tail); pskb_put(skb, trailer, alen); } @@ -254,7 +254,7 @@ return err; } -int esp6_input(struct xfrm_state *x, struct sk_buff *skb) +int esp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) { struct ipv6hdr *iph; struct ipv6_esp_hdr *esph; @@ -262,7 +262,7 @@ struct sk_buff *trailer; int blksize = crypto_tfm_alg_blocksize(esp->conf.tfm); int alen = esp->auth.icv_trunc_len; - int elen = skb->len - 8 - esp->conf.ivlen - alen; + int elen = skb->len - sizeof(struct ipv6_esp_hdr) - esp->conf.ivlen - alen; int hdr_len = skb->h.raw - skb->nh.raw; int nfrags; @@ -319,7 +319,7 @@ if (!sg) goto out; } - skb_to_sgvec(skb, sg, 8+esp->conf.ivlen, elen); + skb_to_sgvec(skb, sg, sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen, elen); crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen); if (unlikely(sg != sgbuf)) kfree(sg); @@ -338,8 +338,8 @@ ret_nexthdr = ((struct ipv6hdr*)tmp_hdr)->nexthdr = nexthdr[1]; pskb_trim(skb, skb->len - alen - padlen - 2); - skb->h.raw = skb_pull(skb, 8 + esp->conf.ivlen); - skb->nh.raw += 8 + esp->conf.ivlen; + skb->h.raw = skb_pull(skb, sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen); + skb->nh.raw += sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen; memcpy(skb->nh.raw, tmp_hdr, hdr_len); } kfree(tmp_hdr); @@ -466,7 +466,7 @@ get_random_bytes(esp->conf.ivec, esp->conf.ivlen); } crypto_cipher_setkey(esp->conf.tfm, esp->conf.key, esp->conf.key_len); - x->props.header_len = 8 + esp->conf.ivlen; + x->props.header_len = sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen; if (x->props.mode) x->props.header_len += sizeof(struct ipv6hdr); x->data = esp; diff -urN linux-2.5.66-bk9/net/ipv6/proc.c linux-2.5.66-bk10/net/ipv6/proc.c --- linux-2.5.66-bk9/net/ipv6/proc.c 2003-03-24 14:00:19.000000000 -0800 +++ linux-2.5.66-bk10/net/ipv6/proc.c 2003-04-04 04:32:53.000000000 -0800 @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include #include @@ -37,22 +39,17 @@ return res; } -int afinet6_get_info(char *buffer, char **start, off_t offset, int length) +static int sockstat6_seq_show(struct seq_file *seq, void *v) { - int len = 0; - len += sprintf(buffer+len, "TCP6: inuse %d\n", + seq_printf(seq, "TCP6: inuse %d\n", fold_prot_inuse(&tcpv6_prot)); - len += sprintf(buffer+len, "UDP6: inuse %d\n", + seq_printf(seq, "UDP6: inuse %d\n", fold_prot_inuse(&udpv6_prot)); - len += sprintf(buffer+len, "RAW6: inuse %d\n", + seq_printf(seq, "RAW6: inuse %d\n", fold_prot_inuse(&rawv6_prot)); - len += sprintf(buffer+len, "FRAG6: inuse %d memory %d\n", + seq_printf(seq, "FRAG6: inuse %d memory %d\n", ip6_frag_nqueues, atomic_read(&ip6_frag_mem)); - *start = buffer + offset; - len -= offset; - if(len > length) - len = length; - return len; + return 0; } @@ -154,23 +151,63 @@ return res; } -int afinet6_get_snmp(char *buffer, char **start, off_t offset, int length) +static int snmp6_seq_show(struct seq_file *seq, void *v) { - int len = 0; int i; for (i=0; i length) - len = length; - if(len < 0) - len = 0; +static struct file_operations snmp6_seq_fops = { + .open = snmp6_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; - *start = buffer + offset; +int __init ipv6_misc_proc_init(void) +{ + int rc = 0; + struct proc_dir_entry *p; - return len; + p = create_proc_entry("snmp6", S_IRUGO, proc_net); + if (!p) + goto proc_snmp6_fail; + else + p->proc_fops = &snmp6_seq_fops; + p = create_proc_entry("sockstat6", S_IRUGO, proc_net); + if (!p) + goto proc_sockstat6_fail; + else + p->proc_fops = &sockstat6_seq_fops; +out: + return rc; + +proc_sockstat6_fail: + remove_proc_entry("snmp6", proc_net); +proc_snmp6_fail: + rc = -ENOMEM; + goto out; } diff -urN linux-2.5.66-bk9/net/ipv6/tcp_ipv6.c linux-2.5.66-bk10/net/ipv6/tcp_ipv6.c --- linux-2.5.66-bk9/net/ipv6/tcp_ipv6.c 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/net/ipv6/tcp_ipv6.c 2003-04-04 04:32:53.000000000 -0800 @@ -1639,10 +1639,10 @@ if(sk->state == TCP_TIME_WAIT) goto do_time_wait; - if (sk_filter(sk, skb, 0)) + if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) goto discard_and_relse; - if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) + if (sk_filter(sk, skb, 0)) goto discard_and_relse; skb->dev = NULL; diff -urN linux-2.5.66-bk9/net/ipv6/xfrm6_input.c linux-2.5.66-bk10/net/ipv6/xfrm6_input.c --- linux-2.5.66-bk9/net/ipv6/xfrm6_input.c 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/net/ipv6/xfrm6_input.c 2003-04-04 04:32:53.000000000 -0800 @@ -128,7 +128,7 @@ struct sk_buff *skb = *pskb; int err; u32 spi, seq; - struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH]; + struct sec_decap_state xfrm_vec[XFRM_MAX_DEPTH]; struct xfrm_state *x; int xfrm_nr = 0; int decaps = 0; @@ -172,7 +172,7 @@ if (x->props.replay_window && xfrm_replay_check(x, seq)) goto drop_unlock; - nexthdr = x->type->input(x, skb); + nexthdr = x->type->input(x, &(xfrm_vec[xfrm_nr].decap), skb); if (nexthdr <= 0) goto drop_unlock; @@ -184,7 +184,7 @@ spin_unlock(&x->lock); - xfrm_vec[xfrm_nr++] = x; + xfrm_vec[xfrm_nr++].xvec = x; iph = skb->nh.ipv6h; @@ -228,7 +228,7 @@ if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH) goto drop; - memcpy(skb->sp->xvec+skb->sp->len, xfrm_vec, xfrm_nr*sizeof(void*)); + memcpy(skb->sp->x+skb->sp->len, xfrm_vec, xfrm_nr*sizeof(struct sec_decap_state)); skb->sp->len += xfrm_nr; if (decaps) { @@ -248,7 +248,7 @@ drop: if (tmp_hdr) kfree(tmp_hdr); while (--xfrm_nr >= 0) - xfrm_state_put(xfrm_vec[xfrm_nr]); + xfrm_state_put(xfrm_vec[xfrm_nr].xvec); kfree_skb(skb); return 0; } diff -urN linux-2.5.66-bk9/net/irda/af_irda.c linux-2.5.66-bk10/net/irda/af_irda.c --- linux-2.5.66-bk9/net/irda/af_irda.c 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/net/irda/af_irda.c 2003-04-04 04:32:53.000000000 -0800 @@ -2407,8 +2407,8 @@ } static struct net_proto_family irda_family_ops = { - .family =PF_IRDA, - .create =irda_create, + .family = PF_IRDA, + .create = irda_create, }; static struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = { diff -urN linux-2.5.66-bk9/net/key/af_key.c linux-2.5.66-bk10/net/key/af_key.c --- linux-2.5.66-bk9/net/key/af_key.c 2003-03-24 14:00:10.000000000 -0800 +++ linux-2.5.66-bk10/net/key/af_key.c 2003-04-04 04:32:53.000000000 -0800 @@ -11,6 +11,7 @@ * Alexey Kuznetsov * Kunihiro Ishiguro * Kazunori MIYAZAWA / USAGI Project + * Derek Atkins */ #include @@ -345,6 +346,10 @@ [SADB_X_EXT_KMPRIVATE] = (u8) sizeof(struct sadb_x_kmprivate), [SADB_X_EXT_POLICY] = (u8) sizeof(struct sadb_x_policy), [SADB_X_EXT_SA2] = (u8) sizeof(struct sadb_x_sa2), + [SADB_X_EXT_NAT_T_TYPE] = (u8) sizeof(struct sadb_x_nat_t_type), + [SADB_X_EXT_NAT_T_SPORT] = (u8) sizeof(struct sadb_x_nat_t_port), + [SADB_X_EXT_NAT_T_DPORT] = (u8) sizeof(struct sadb_x_nat_t_port), + [SADB_X_EXT_NAT_T_OA] = (u8) sizeof(struct sadb_address), }; /* Verify sadb_address_{len,prefixlen} against sa_family. */ @@ -442,7 +447,8 @@ return -EINVAL; if (ext_type == SADB_EXT_ADDRESS_SRC || ext_type == SADB_EXT_ADDRESS_DST || - ext_type == SADB_EXT_ADDRESS_PROXY) { + ext_type == SADB_EXT_ADDRESS_PROXY || + ext_type == SADB_X_EXT_NAT_T_OA) { if (verify_address_len(p)) return -EINVAL; } @@ -601,6 +607,7 @@ int auth_key_size = 0; int encrypt_key_size = 0; int sockaddr_size; + struct xfrm_encap_tmpl *natt = NULL; /* address family check */ sockaddr_size = pfkey_sockaddr_size(x->props.family); @@ -639,6 +646,15 @@ size += sizeof(struct sadb_key) + encrypt_key_size; } } + if (x->encap) + natt = x->encap; + + if (natt && natt->encap_type) { + size += sizeof(struct sadb_x_nat_t_type); + size += sizeof(struct sadb_x_nat_t_port); + size += sizeof(struct sadb_x_nat_t_port); + } + skb = alloc_skb(size + 16, GFP_ATOMIC); if (skb == NULL) return ERR_PTR(-ENOBUFS); @@ -858,6 +874,34 @@ sa2->sadb_x_sa2_sequence = 0; sa2->sadb_x_sa2_reqid = x->props.reqid; + if (natt && natt->encap_type) { + struct sadb_x_nat_t_type *n_type; + struct sadb_x_nat_t_port *n_port; + + /* type */ + n_type = (struct sadb_x_nat_t_type*) skb_put(skb, sizeof(*n_type)); + n_type->sadb_x_nat_t_type_len = sizeof(*n_type)/sizeof(uint64_t); + n_type->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE; + n_type->sadb_x_nat_t_type_type = natt->encap_type; + n_type->sadb_x_nat_t_type_reserved[0] = 0; + n_type->sadb_x_nat_t_type_reserved[1] = 0; + n_type->sadb_x_nat_t_type_reserved[2] = 0; + + /* source port */ + n_port = (struct sadb_x_nat_t_port*) skb_put(skb, sizeof (*n_port)); + n_port->sadb_x_nat_t_port_len = sizeof(*n_port)/sizeof(uint64_t); + n_port->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_SPORT; + n_port->sadb_x_nat_t_port_port = natt->encap_sport; + n_port->sadb_x_nat_t_port_reserved = 0; + + /* dest port */ + n_port = (struct sadb_x_nat_t_port*) skb_put(skb, sizeof (*n_port)); + n_port->sadb_x_nat_t_port_len = sizeof(*n_port)/sizeof(uint64_t); + n_port->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_DPORT; + n_port->sadb_x_nat_t_port_port = natt->encap_dport; + n_port->sadb_x_nat_t_port_reserved = 0; + } + return skb; } @@ -1017,6 +1061,30 @@ x->sel.prefixlen_s = addr->sadb_address_prefixlen; } + if (ext_hdrs[SADB_X_EXT_NAT_T_TYPE-1]) { + struct sadb_x_nat_t_type* n_type; + struct xfrm_encap_tmpl *natt; + + x->encap = kmalloc(sizeof(*x->encap), GFP_KERNEL); + if (!x->encap) + goto out; + + natt = x->encap; + n_type = ext_hdrs[SADB_X_EXT_NAT_T_TYPE-1]; + natt->encap_type = n_type->sadb_x_nat_t_type_type; + + if (ext_hdrs[SADB_X_EXT_NAT_T_SPORT-1]) { + struct sadb_x_nat_t_port* n_port = + ext_hdrs[SADB_X_EXT_NAT_T_SPORT-1]; + natt->encap_sport = n_port->sadb_x_nat_t_port_port; + } + if (ext_hdrs[SADB_X_EXT_NAT_T_DPORT-1]) { + struct sadb_x_nat_t_port* n_port = + ext_hdrs[SADB_X_EXT_NAT_T_DPORT-1]; + natt->encap_dport = n_port->sadb_x_nat_t_port_port; + } + } + x->type = xfrm_get_type(proto, x->props.family); if (x->type == NULL) goto out; @@ -1033,6 +1101,8 @@ kfree(x->ealg); if (x->calg) kfree(x->calg); + if (x->encap) + kfree(x->encap); kfree(x); return ERR_PTR(-ENOBUFS); } @@ -2051,7 +2121,6 @@ return 0; } - typedef int (*pfkey_handler)(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs); static pfkey_handler pfkey_funcs[SADB_MAX + 1] = { @@ -2467,6 +2536,155 @@ return NULL; } +static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport) +{ + struct sk_buff *skb; + struct sadb_msg *hdr; + struct sadb_sa *sa; + struct sadb_address *addr; + struct sadb_x_nat_t_port *n_port; + struct sockaddr_in *sin; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + struct sockaddr_in6 *sin6; +#endif + int sockaddr_size; + int size; + __u8 satype = (x->id.proto == IPPROTO_ESP ? SADB_SATYPE_ESP : 0); + struct xfrm_encap_tmpl *natt = NULL; + + sockaddr_size = pfkey_sockaddr_size(x->props.family); + if (!sockaddr_size) + return -EINVAL; + + if (!satype) + return -EINVAL; + + if (!x->encap) + return -EINVAL; + + natt = x->encap; + + /* Build an SADB_X_NAT_T_NEW_MAPPING message: + * + * HDR | SA | ADDRESS_SRC (old addr) | NAT_T_SPORT (old port) | + * ADDRESS_DST (new addr) | NAT_T_DPORT (new port) + */ + + size = sizeof(struct sadb_msg) + + sizeof(struct sadb_sa) + + (sizeof(struct sadb_address) * 2) + + (sockaddr_size * 2) + + (sizeof(struct sadb_x_nat_t_port) * 2); + + skb = alloc_skb(size + 16, GFP_ATOMIC); + if (skb == NULL) + return -ENOMEM; + + hdr = (struct sadb_msg *) skb_put(skb, sizeof(struct sadb_msg)); + hdr->sadb_msg_version = PF_KEY_V2; + hdr->sadb_msg_type = SADB_X_NAT_T_NEW_MAPPING; + hdr->sadb_msg_satype = satype; + hdr->sadb_msg_len = size / sizeof(uint64_t); + hdr->sadb_msg_errno = 0; + hdr->sadb_msg_reserved = 0; + hdr->sadb_msg_seq = x->km.seq = get_acqseq(); + hdr->sadb_msg_pid = 0; + + /* SA */ + sa = (struct sadb_sa *) skb_put(skb, sizeof(struct sadb_sa)); + sa->sadb_sa_len = sizeof(struct sadb_sa)/sizeof(uint64_t); + sa->sadb_sa_exttype = SADB_EXT_SA; + sa->sadb_sa_spi = x->id.spi; + sa->sadb_sa_replay = 0; + sa->sadb_sa_state = 0; + sa->sadb_sa_auth = 0; + sa->sadb_sa_encrypt = 0; + sa->sadb_sa_flags = 0; + + /* ADDRESS_SRC (old addr) */ + addr = (struct sadb_address*) + skb_put(skb, sizeof(struct sadb_address)+sockaddr_size); + addr->sadb_address_len = + (sizeof(struct sadb_address)+sockaddr_size)/ + sizeof(uint64_t); + addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; + addr->sadb_address_proto = 0; + addr->sadb_address_reserved = 0; + if (x->props.family == AF_INET) { + addr->sadb_address_prefixlen = 32; + + sin = (struct sockaddr_in *) (addr + 1); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = x->props.saddr.a4; + sin->sin_port = 0; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + else if (x->props.family == AF_INET6) { + addr->sadb_address_prefixlen = 128; + + sin6 = (struct sockaddr_in6 *) (addr + 1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = 0; + sin6->sin6_flowinfo = 0; + memcpy(&sin6->sin6_addr, + x->props.saddr.a6, sizeof(struct in6_addr)); + sin6->sin6_scope_id = 0; + } +#endif + else + BUG(); + + /* NAT_T_SPORT (old port) */ + n_port = (struct sadb_x_nat_t_port*) skb_put(skb, sizeof (*n_port)); + n_port->sadb_x_nat_t_port_len = sizeof(*n_port)/sizeof(uint64_t); + n_port->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_SPORT; + n_port->sadb_x_nat_t_port_port = natt->encap_sport; + n_port->sadb_x_nat_t_port_reserved = 0; + + /* ADDRESS_DST (new addr) */ + addr = (struct sadb_address*) + skb_put(skb, sizeof(struct sadb_address)+sockaddr_size); + addr->sadb_address_len = + (sizeof(struct sadb_address)+sockaddr_size)/ + sizeof(uint64_t); + addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; + addr->sadb_address_proto = 0; + addr->sadb_address_reserved = 0; + if (x->props.family == AF_INET) { + addr->sadb_address_prefixlen = 32; + + sin = (struct sockaddr_in *) (addr + 1); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = ipaddr->a4; + sin->sin_port = 0; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + else if (x->props.family == AF_INET6) { + addr->sadb_address_prefixlen = 128; + + sin6 = (struct sockaddr_in6 *) (addr + 1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = 0; + sin6->sin6_flowinfo = 0; + memcpy(&sin6->sin6_addr, &ipaddr->a6, sizeof(struct in6_addr)); + sin6->sin6_scope_id = 0; + } +#endif + else + BUG(); + + /* NAT_T_DPORT (new port) */ + n_port = (struct sadb_x_nat_t_port*) skb_put(skb, sizeof (*n_port)); + n_port->sadb_x_nat_t_port_len = sizeof(*n_port)/sizeof(uint64_t); + n_port->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_DPORT; + n_port->sadb_x_nat_t_port_port = sport; + n_port->sadb_x_nat_t_port_reserved = 0; + + return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL); +} + static int pfkey_sendmsg(struct kiocb *kiocb, struct socket *sock, struct msghdr *msg, int len) { @@ -2632,6 +2850,7 @@ .notify = pfkey_send_notify, .acquire = pfkey_send_acquire, .compile_policy = pfkey_compile_policy, + .new_mapping = pfkey_send_new_mapping, }; static void __exit ipsec_pfkey_exit(void) diff -urN linux-2.5.66-bk9/net/netlink/af_netlink.c linux-2.5.66-bk10/net/netlink/af_netlink.c --- linux-2.5.66-bk9/net/netlink/af_netlink.c 2003-03-24 14:00:39.000000000 -0800 +++ linux-2.5.66-bk10/net/netlink/af_netlink.c 2003-04-04 04:32:53.000000000 -0800 @@ -1050,8 +1050,8 @@ }; struct net_proto_family netlink_family_ops = { - .family =PF_NETLINK, - .create =netlink_create, + .family = PF_NETLINK, + .create = netlink_create, }; static int __init netlink_proto_init(void) diff -urN linux-2.5.66-bk9/net/netsyms.c linux-2.5.66-bk10/net/netsyms.c --- linux-2.5.66-bk9/net/netsyms.c 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/net/netsyms.c 2003-04-04 04:32:53.000000000 -0800 @@ -292,6 +292,7 @@ EXPORT_SYMBOL(xfrm_user_policy); EXPORT_SYMBOL(km_waitq); +EXPORT_SYMBOL(km_new_mapping); EXPORT_SYMBOL(xfrm_cfg_sem); EXPORT_SYMBOL(xfrm_policy_alloc); EXPORT_SYMBOL(__xfrm_policy_destroy); @@ -544,6 +545,7 @@ EXPORT_SYMBOL(loopback_dev); EXPORT_SYMBOL(register_netdevice); EXPORT_SYMBOL(unregister_netdevice); +EXPORT_SYMBOL(synchronize_net); EXPORT_SYMBOL(netdev_state_change); EXPORT_SYMBOL(dev_new_index); EXPORT_SYMBOL(dev_get_by_flags); diff -urN linux-2.5.66-bk9/net/rose/af_rose.c linux-2.5.66-bk10/net/rose/af_rose.c --- linux-2.5.66-bk9/net/rose/af_rose.c 2003-03-24 14:00:38.000000000 -0800 +++ linux-2.5.66-bk10/net/rose/af_rose.c 2003-04-04 04:32:53.000000000 -0800 @@ -1434,7 +1434,7 @@ .family = PF_ROSE, .release = rose_release, - .bind = rose_bind, + .bind = rose_bind, .connect = rose_connect, .socketpair = sock_no_socketpair, .accept = rose_accept, diff -urN linux-2.5.66-bk9/net/unix/af_unix.c linux-2.5.66-bk10/net/unix/af_unix.c --- linux-2.5.66-bk9/net/unix/af_unix.c 2003-03-24 14:00:51.000000000 -0800 +++ linux-2.5.66-bk10/net/unix/af_unix.c 2003-04-04 04:32:53.000000000 -0800 @@ -1945,9 +1945,8 @@ struct sk_buff *dummy_skb; printk(banner); - if (sizeof(struct unix_skb_parms) > sizeof(dummy_skb->cb)) - { - printk(KERN_CRIT "unix_proto_init: panic\n"); + if (sizeof(struct unix_skb_parms) > sizeof(dummy_skb->cb)) { + printk(KERN_CRIT "%s: panic\n", __FUNCTION__); return -1; } /* allocate our sock slab cache */ diff -urN linux-2.5.66-bk9/net/wanrouter/af_wanpipe.c linux-2.5.66-bk10/net/wanrouter/af_wanpipe.c --- linux-2.5.66-bk9/net/wanrouter/af_wanpipe.c 2003-03-24 14:01:47.000000000 -0800 +++ linux-2.5.66-bk10/net/wanrouter/af_wanpipe.c 2003-04-04 04:32:53.000000000 -0800 @@ -2561,13 +2561,13 @@ .family = PF_WANPIPE, .release = wanpipe_release, - .bind = wanpipe_bind, + .bind = wanpipe_bind, .connect = wanpipe_connect, .socketpair = sock_no_socketpair, .accept = wanpipe_accept, .getname = wanpipe_getname, - .poll = wanpipe_poll, - .ioctl = wanpipe_ioctl, + .poll = wanpipe_poll, + .ioctl = wanpipe_ioctl, .listen = wanpipe_listen, .shutdown = sock_no_shutdown, .setsockopt = sock_no_setsockopt, @@ -2577,12 +2577,12 @@ }; static struct net_proto_family wanpipe_family_ops = { - .family =PF_WANPIPE, - .create =wanpipe_create, + .family = PF_WANPIPE, + .create = wanpipe_create, }; struct notifier_block wanpipe_netdev_notifier = { - .notifier_call =wanpipe_notifier, + .notifier_call = wanpipe_notifier, }; diff -urN linux-2.5.66-bk9/net/xfrm/xfrm_input.c linux-2.5.66-bk10/net/xfrm/xfrm_input.c --- linux-2.5.66-bk9/net/xfrm/xfrm_input.c 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/net/xfrm/xfrm_input.c 2003-04-04 04:32:53.000000000 -0800 @@ -14,7 +14,7 @@ { int i; for (i = 0; i < sp->len; i++) - xfrm_state_put(sp->xvec[i]); + xfrm_state_put(sp->x[i].xvec); kmem_cache_free(sp->pool, sp); } diff -urN linux-2.5.66-bk9/net/xfrm/xfrm_policy.c linux-2.5.66-bk10/net/xfrm/xfrm_policy.c --- linux-2.5.66-bk9/net/xfrm/xfrm_policy.c 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/net/xfrm/xfrm_policy.c 2003-04-04 04:32:53.000000000 -0800 @@ -9,6 +9,7 @@ * Kazunori MIYAZAWA @USAGI * YOSHIFUJI Hideaki * Split up af-specific portion + * Derek Atkins Add the post_input processor * */ @@ -889,7 +890,7 @@ unsigned short family) { for (; idx < sp->len; idx++) { - if (xfrm_state_ok(tmpl, sp->xvec[idx], family)) + if (xfrm_state_ok(tmpl, sp->x[idx].xvec, family)) return ++idx; } return -1; @@ -922,7 +923,15 @@ int i; for (i=skb->sp->len-1; i>=0; i--) { - if (!xfrm_selector_match(&skb->sp->xvec[i]->sel, &fl, family)) + struct sec_decap_state *xvec = &(skb->sp->x[i]); + if (!xfrm_selector_match(&xvec->xvec->sel, &fl, family)) + return 0; + + /* If there is a post_input processor, try running it */ + if (xvec->xvec->type->post_input && + (xvec->xvec->type->post_input)(xvec->xvec, + &(xvec->decap), + skb) != 0) return 0; } } diff -urN linux-2.5.66-bk9/net/xfrm/xfrm_state.c linux-2.5.66-bk10/net/xfrm/xfrm_state.c --- linux-2.5.66-bk9/net/xfrm/xfrm_state.c 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/net/xfrm/xfrm_state.c 2003-04-04 04:32:53.000000000 -0800 @@ -8,12 +8,15 @@ * IPv6 support * YOSHIFUJI Hideaki @USAGI * Split up af-specific functions + * Derek Atkins + * Add UDP Encapsulation * */ #include #include #include +#include /* Each xfrm_state may be linked to two tables: @@ -154,6 +157,8 @@ kfree(x->ealg); if (x->calg) kfree(x->calg); + if (x->encap) + kfree(x->encap); if (x->type) xfrm_put_type(x->type); kfree(x); @@ -176,10 +181,27 @@ spin_unlock(&xfrm_state_lock); if (del_timer(&x->timer)) atomic_dec(&x->refcnt); - if (atomic_read(&x->refcnt) != 1) + + /* The number two in this test is the reference + * mentioned in the comment below plus the reference + * our caller holds. A larger value means that + * there are DSTs attached to this xfrm_state. + */ + if (atomic_read(&x->refcnt) > 2) xfrm_flush_bundles(x); } + /* All xfrm_state objects are created by one of two possible + * paths: + * + * 1) xfrm_state_alloc --> xfrm_state_insert + * 2) xfrm_state_lookup --> xfrm_state_insert + * + * The xfrm_state_lookup or xfrm_state_alloc call gives a + * reference, and that is what we are dropping here. + */ + atomic_dec(&x->refcnt); + if (kill && x->type) x->type->destructor(x); wake_up(&km_waitq); @@ -614,6 +636,22 @@ return err; } +int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport) +{ + int err = -EINVAL; + struct xfrm_mgr *km; + + read_lock(&xfrm_km_lock); + list_for_each_entry(km, &xfrm_km_list, list) { + if (km->new_mapping) + err = km->new_mapping(x, ipaddr, sport); + if (!err) + break; + } + read_unlock(&xfrm_km_lock); + return err; +} + int xfrm_user_policy(struct sock *sk, int optname, u8 *optval, int optlen) { int err; diff -urN linux-2.5.66-bk9/net/xfrm/xfrm_user.c linux-2.5.66-bk10/net/xfrm/xfrm_user.c --- linux-2.5.66-bk9/net/xfrm/xfrm_user.c 2003-04-04 04:32:50.000000000 -0800 +++ linux-2.5.66-bk10/net/xfrm/xfrm_user.c 2003-04-04 04:32:53.000000000 -0800 @@ -26,6 +26,7 @@ #include #include #include +#include static struct sock *xfrm_nl; @@ -66,6 +67,20 @@ return 0; } +static int verify_encap_tmpl(struct rtattr **xfrma) +{ + struct rtattr *rt = xfrma[XFRMA_ENCAP - 1]; + struct xfrm_encap_tmpl *encap; + + if (!rt) + return 0; + + if ((rt->rta_len - sizeof(*rt)) < sizeof(*encap)) + return -EINVAL; + + return 0; +} + static int verify_newsa_info(struct xfrm_usersa_info *p, struct rtattr **xfrma) { @@ -121,6 +136,8 @@ goto out; if ((err = verify_one_alg(xfrma, XFRMA_ALG_COMP))) goto out; + if ((err = verify_encap_tmpl(xfrma))) + goto out; err = -EINVAL; switch (p->mode) { @@ -156,6 +173,24 @@ return 0; } +static int attach_encap_tmpl(struct xfrm_encap_tmpl **encapp, struct rtattr *u_arg) +{ + struct rtattr *rta = u_arg; + struct xfrm_encap_tmpl *p, *uencap; + + if (!rta) + return 0; + + uencap = RTA_DATA(rta); + p = kmalloc(sizeof(*p), GFP_KERNEL); + if (!p) + return -ENOMEM; + + memcpy(p, uencap, sizeof(*p)); + *encapp = p; + return 0; +} + static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p) { memcpy(&x->id, &p->id, sizeof(x->id)); @@ -186,6 +221,8 @@ goto error; if ((err = attach_one_algo(&x->calg, xfrma[XFRMA_ALG_COMP-1]))) goto error; + if ((err = attach_encap_tmpl(&x->encap, xfrma[XFRMA_ENCAP-1]))) + goto error; err = -ENOENT; x->type = xfrm_get_type(x->id.proto, x->props.family); @@ -301,6 +338,9 @@ if (x->calg) RTA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg); + if (x->encap) + RTA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap); + nlh->nlmsg_len = skb->tail - b; out: sp->this_idx++; diff -urN linux-2.5.66-bk9/scripts/modpost.c linux-2.5.66-bk10/scripts/modpost.c --- linux-2.5.66-bk9/scripts/modpost.c 2003-03-24 14:00:08.000000000 -0800 +++ linux-2.5.66-bk10/scripts/modpost.c 2003-04-04 04:32:53.000000000 -0800 @@ -296,6 +296,12 @@ /* ignore global offset table */ if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0) break; + if (info->hdr->e_machine == EM_SPARC || + info->hdr->e_machine == EM_SPARCV9) { + /* Ignore register directives. */ + if (ELF_ST_TYPE(sym->st_info) == STT_REGISTER) + break; + } if (memcmp(symname, MODULE_SYMBOL_PREFIX, strlen(MODULE_SYMBOL_PREFIX)) == 0) { diff -urN linux-2.5.66-bk9/scripts/modpost.h linux-2.5.66-bk10/scripts/modpost.h --- linux-2.5.66-bk9/scripts/modpost.h 2003-03-24 13:59:46.000000000 -0800 +++ linux-2.5.66-bk10/scripts/modpost.h 2003-04-04 04:32:53.000000000 -0800 @@ -17,6 +17,7 @@ #define Elf_Shdr Elf32_Shdr #define Elf_Sym Elf32_Sym #define ELF_ST_BIND ELF32_ST_BIND +#define ELF_ST_TYPE ELF32_ST_TYPE #else @@ -24,6 +25,7 @@ #define Elf_Shdr Elf64_Shdr #define Elf_Sym Elf64_Sym #define ELF_ST_BIND ELF64_ST_BIND +#define ELF_ST_TYPE ELF64_ST_TYPE #endif diff -urN linux-2.5.66-bk9/sound/pci/cs46xx/cs46xx_lib.c linux-2.5.66-bk10/sound/pci/cs46xx/cs46xx_lib.c --- linux-2.5.66-bk9/sound/pci/cs46xx/cs46xx_lib.c 2003-03-24 13:59:58.000000000 -0800 +++ linux-2.5.66-bk10/sound/pci/cs46xx/cs46xx_lib.c 2003-04-04 04:32:53.000000000 -0800 @@ -3381,7 +3381,9 @@ /* Manage the EAPD bit on the Crystal 4297 and the Analog AD1885 */ +#ifdef CONFIG_SND_CS46XX_NEW_DSP int old = chip->amplifier; +#endif int oval, val; chip->amplifier += change;