Merge master.kernel.org:/pub/scm/linux/kernel/git/tglx/hrtimer-2.6
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index dd0bfc2..fe11fcc 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -856,6 +856,49 @@
 
 	mga=		[HW,DRM]
 
+	migration_cost=
+			[KNL,SMP] debug: override scheduler migration costs
+			Format: <level-1-usecs>,<level-2-usecs>,...
+			This debugging option can be used to override the
+			default scheduler migration cost matrix. The numbers
+			are indexed by 'CPU domain distance'.
+			E.g. migration_cost=1000,2000,3000 on an SMT NUMA
+			box will set up an intra-core migration cost of
+			1 msec, an inter-core migration cost of 2 msecs,
+			and an inter-node migration cost of 3 msecs.
+
+			WARNING: using the wrong values here can break
+			scheduler performance, so it's only for scheduler
+			development purposes, not production environments.
+
+	migration_debug=
+			[KNL,SMP] migration cost auto-detect verbosity
+			Format=<0|1|2>
+			If a system's migration matrix reported at bootup
+			seems erroneous then this option can be used to
+			increase verbosity of the detection process.
+			We default to 0 (no extra messages), 1 will print
+			some more information, and 2 will be really
+			verbose (probably only useful if you also have a
+			serial console attached to the system).
+
+	migration_factor=
+			[KNL,SMP] multiply/divide migration costs by a factor
+			Format=<percent>
+			This debug option can be used to proportionally
+			increase or decrease the auto-detected migration
+			costs for all entries of the migration matrix.
+			E.g. migration_factor=150 will increase migration
+			costs by 50%. (and thus the scheduler will be less
+			eager migrating cache-hot tasks)
+			migration_factor=80 will decrease migration costs
+			by 20%. (thus the scheduler will be more eager to
+			migrate tasks)
+
+			WARNING: using the wrong values here can break
+			scheduler performance, so it's only for scheduler
+			development purposes, not production environments.
+
 	mousedev.tap_time=
 			[MOUSE] Maximum time between finger touching and
 			leaving touchpad surface for touch to be considered
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index abb739b..9924fd0 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -276,7 +276,7 @@
 {
 	extern void ret_from_fork(void);
 
-	struct thread_info *childti = p->thread_info;
+	struct thread_info *childti = task_thread_info(p);
 	struct pt_regs * childregs;
 	struct switch_stack * childstack, *stack;
 	unsigned long stack_offset, settls;
@@ -285,7 +285,7 @@
 	if (!(regs->ps & 8))
 		stack_offset = (PAGE_SIZE-1) & (unsigned long) regs;
 	childregs = (struct pt_regs *)
-	  (stack_offset + PAGE_SIZE + (long) childti);
+	  (stack_offset + PAGE_SIZE + task_stack_page(p));
 		
 	*childregs = *regs;
 	settls = regs->r20;
@@ -428,30 +428,15 @@
 int
 dump_elf_task(elf_greg_t *dest, struct task_struct *task)
 {
-	struct thread_info *ti;
-	struct pt_regs *pt;
-
-	ti = task->thread_info;
-	pt = (struct pt_regs *)((unsigned long)ti + 2*PAGE_SIZE) - 1;
-
-	dump_elf_thread(dest, pt, ti);
-
+	dump_elf_thread(dest, task_pt_regs(task), task_thread_info(task));
 	return 1;
 }
 
 int
 dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task)
 {
-	struct thread_info *ti;
-	struct pt_regs *pt;
-	struct switch_stack *sw;
-
-	ti = task->thread_info;
-	pt = (struct pt_regs *)((unsigned long)ti + 2*PAGE_SIZE) - 1;
-	sw = (struct switch_stack *)pt - 1;
-
+	struct switch_stack *sw = (struct switch_stack *)task_pt_regs(task) - 1;
 	memcpy(dest, sw->fp, 32 * 8);
-
 	return 1;
 }
 
@@ -492,8 +477,8 @@
 unsigned long
 thread_saved_pc(task_t *t)
 {
-	unsigned long base = (unsigned long)t->thread_info;
-	unsigned long fp, sp = t->thread_info->pcb.ksp;
+	unsigned long base = (unsigned long)task_stack_page(t);
+	unsigned long fp, sp = task_thread_info(t)->pcb.ksp;
 
 	if (sp > base && sp+6*8 < base + 16*1024) {
 		fp = ((unsigned long*)sp)[6];
@@ -523,7 +508,7 @@
 
 	pc = thread_saved_pc(p);
 	if (in_sched_functions(pc)) {
-		schedule_frame = ((unsigned long *)p->thread_info->pcb.ksp)[6];
+		schedule_frame = ((unsigned long *)task_thread_info(p)->pcb.ksp)[6];
 		return ((unsigned long *)schedule_frame)[12];
 	}
 	return pc;
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
index 9969d21..0cd0605 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -72,6 +72,13 @@
 	REG_R0 = 0, REG_F0 = 32, REG_FPCR = 63, REG_PC = 64
 };
 
+#define PT_REG(reg) \
+  (PAGE_SIZE*2 - sizeof(struct pt_regs) + offsetof(struct pt_regs, reg))
+
+#define SW_REG(reg) \
+ (PAGE_SIZE*2 - sizeof(struct pt_regs) - sizeof(struct switch_stack) \
+  + offsetof(struct switch_stack, reg))
+
 static int regoff[] = {
 	PT_REG(	   r0), PT_REG(	   r1), PT_REG(	   r2), PT_REG(	  r3),
 	PT_REG(	   r4), PT_REG(	   r5), PT_REG(	   r6), PT_REG(	  r7),
@@ -103,14 +110,14 @@
 	unsigned long *addr;
 
 	if (regno == 30) {
-		addr = &task->thread_info->pcb.usp;
+		addr = &task_thread_info(task)->pcb.usp;
 	} else if (regno == 65) {
-		addr = &task->thread_info->pcb.unique;
+		addr = &task_thread_info(task)->pcb.unique;
 	} else if (regno == 31 || regno > 65) {
 		zero = 0;
 		addr = &zero;
 	} else {
-		addr = (void *)task->thread_info + regoff[regno];
+		addr = task_stack_page(task) + regoff[regno];
 	}
 	return addr;
 }
@@ -125,7 +132,7 @@
 	if (regno == 63) {
 		unsigned long fpcr = *get_reg_addr(task, regno);
 		unsigned long swcr
-		  = task->thread_info->ieee_state & IEEE_SW_MASK;
+		  = task_thread_info(task)->ieee_state & IEEE_SW_MASK;
 		swcr = swcr_update_status(swcr, fpcr);
 		return fpcr | swcr;
 	}
@@ -139,8 +146,8 @@
 put_reg(struct task_struct *task, unsigned long regno, unsigned long data)
 {
 	if (regno == 63) {
-		task->thread_info->ieee_state
-		  = ((task->thread_info->ieee_state & ~IEEE_SW_MASK)
+		task_thread_info(task)->ieee_state
+		  = ((task_thread_info(task)->ieee_state & ~IEEE_SW_MASK)
 		     | (data & IEEE_SW_MASK));
 		data = (data & FPCR_DYN_MASK) | ieee_swcr_to_fpcr(data);
 	}
@@ -188,35 +195,35 @@
 		 * branch (emulation can be tricky for fp branches).
 		 */
 		displ = ((s32)(insn << 11)) >> 9;
-		child->thread_info->bpt_addr[nsaved++] = pc + 4;
+		task_thread_info(child)->bpt_addr[nsaved++] = pc + 4;
 		if (displ)		/* guard against unoptimized code */
-			child->thread_info->bpt_addr[nsaved++]
+			task_thread_info(child)->bpt_addr[nsaved++]
 			  = pc + 4 + displ;
 		DBG(DBG_BPT, ("execing branch\n"));
 	} else if (op_code == 0x1a) {
 		reg_b = (insn >> 16) & 0x1f;
-		child->thread_info->bpt_addr[nsaved++] = get_reg(child, reg_b);
+		task_thread_info(child)->bpt_addr[nsaved++] = get_reg(child, reg_b);
 		DBG(DBG_BPT, ("execing jump\n"));
 	} else {
-		child->thread_info->bpt_addr[nsaved++] = pc + 4;
+		task_thread_info(child)->bpt_addr[nsaved++] = pc + 4;
 		DBG(DBG_BPT, ("execing normal insn\n"));
 	}
 
 	/* install breakpoints: */
 	for (i = 0; i < nsaved; ++i) {
-		res = read_int(child, child->thread_info->bpt_addr[i],
+		res = read_int(child, task_thread_info(child)->bpt_addr[i],
 			       (int *) &insn);
 		if (res < 0)
 			return res;
-		child->thread_info->bpt_insn[i] = insn;
+		task_thread_info(child)->bpt_insn[i] = insn;
 		DBG(DBG_BPT, ("    -> next_pc=%lx\n",
-			      child->thread_info->bpt_addr[i]));
-		res = write_int(child, child->thread_info->bpt_addr[i],
+			      task_thread_info(child)->bpt_addr[i]));
+		res = write_int(child, task_thread_info(child)->bpt_addr[i],
 				BREAKINST);
 		if (res < 0)
 			return res;
 	}
-	child->thread_info->bpt_nsaved = nsaved;
+	task_thread_info(child)->bpt_nsaved = nsaved;
 	return 0;
 }
 
@@ -227,9 +234,9 @@
 int
 ptrace_cancel_bpt(struct task_struct * child)
 {
-	int i, nsaved = child->thread_info->bpt_nsaved;
+	int i, nsaved = task_thread_info(child)->bpt_nsaved;
 
-	child->thread_info->bpt_nsaved = 0;
+	task_thread_info(child)->bpt_nsaved = 0;
 
 	if (nsaved > 2) {
 		printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved);
@@ -237,8 +244,8 @@
 	}
 
 	for (i = 0; i < nsaved; ++i) {
-		write_int(child, child->thread_info->bpt_addr[i],
-			  child->thread_info->bpt_insn[i]);
+		write_int(child, task_thread_info(child)->bpt_addr[i],
+			  task_thread_info(child)->bpt_insn[i]);
 	}
 	return (nsaved != 0);
 }
@@ -355,7 +362,7 @@
 		if (!valid_signal(data))
 			break;
 		/* Mark single stepping.  */
-		child->thread_info->bpt_nsaved = -1;
+		task_thread_info(child)->bpt_nsaved = -1;
 		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 		child->exit_code = data;
 		wake_up_process(child);
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index da0be34..4b87352 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -302,7 +302,7 @@
 		 + hwrpb->processor_offset
 		 + cpuid * hwrpb->processor_size);
 	hwpcb = (struct pcb_struct *) cpu->hwpcb;
-	ipcb = &idle->thread_info->pcb;
+	ipcb = &task_thread_info(idle)->pcb;
 
 	/* Initialize the CPU's HWPCB to something just good enough for
 	   us to get started.  Immediately after starting, we'll swpctx
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 54a21bd..4b4e4cf 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -342,10 +342,10 @@
 void release_thread(struct task_struct *dead_task)
 {
 #if defined(CONFIG_VFP)
-	vfp_release_thread(&dead_task->thread_info->vfpstate);
+	vfp_release_thread(&task_thread_info(dead_task)->vfpstate);
 #endif
 #if defined(CONFIG_IWMMXT)
-	iwmmxt_task_release(dead_task->thread_info);
+	iwmmxt_task_release(task_thread_info(dead_task));
 #endif
 }
 
@@ -355,10 +355,9 @@
 copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start,
 	    unsigned long stk_sz, struct task_struct *p, struct pt_regs *regs)
 {
-	struct thread_info *thread = p->thread_info;
-	struct pt_regs *childregs;
+	struct thread_info *thread = task_thread_info(p);
+	struct pt_regs *childregs = task_pt_regs(p);
 
-	childregs = (void *)thread + THREAD_START_SP - sizeof(*regs);
 	*childregs = *regs;
 	childregs->ARM_r0 = 0;
 	childregs->ARM_sp = stack_start;
@@ -460,8 +459,8 @@
 	if (!p || p == current || p->state == TASK_RUNNING)
 		return 0;
 
-	stack_start = (unsigned long)(p->thread_info + 1);
-	stack_end = ((unsigned long)p->thread_info) + THREAD_SIZE;
+	stack_start = (unsigned long)end_of_stack(p);
+	stack_end = (unsigned long)task_stack_page(p) + THREAD_SIZE;
 
 	fp = thread_saved_fp(p);
 	do {
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 2b84f78..e591f72b 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -55,23 +55,6 @@
 #endif
 
 /*
- * Get the address of the live pt_regs for the specified task.
- * These are saved onto the top kernel stack when the process
- * is not running.
- *
- * Note: if a user thread is execve'd from kernel space, the
- * kernel stack will not be empty on entry to the kernel, so
- * ptracing these tasks will fail.
- */
-static inline struct pt_regs *
-get_user_regs(struct task_struct *task)
-{
-	return (struct pt_regs *)
-		((unsigned long)task->thread_info + THREAD_SIZE -
-				 8 - sizeof(struct pt_regs));
-}
-
-/*
  * this routine will get a word off of the processes privileged stack.
  * the offset is how far from the base addr as stored in the THREAD.
  * this routine assumes that all the privileged stacks are in our
@@ -79,7 +62,7 @@
  */
 static inline long get_user_reg(struct task_struct *task, int offset)
 {
-	return get_user_regs(task)->uregs[offset];
+	return task_pt_regs(task)->uregs[offset];
 }
 
 /*
@@ -91,7 +74,7 @@
 static inline int
 put_user_reg(struct task_struct *task, int offset, long data)
 {
-	struct pt_regs newregs, *regs = get_user_regs(task);
+	struct pt_regs newregs, *regs = task_pt_regs(task);
 	int ret = -EINVAL;
 
 	newregs = *regs;
@@ -421,7 +404,7 @@
 	u32 insn;
 	int res;
 
-	regs = get_user_regs(child);
+	regs = task_pt_regs(child);
 	pc = instruction_pointer(regs);
 
 	if (thumb_mode(regs)) {
@@ -572,7 +555,7 @@
  */
 static int ptrace_getregs(struct task_struct *tsk, void __user *uregs)
 {
-	struct pt_regs *regs = get_user_regs(tsk);
+	struct pt_regs *regs = task_pt_regs(tsk);
 
 	return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0;
 }
@@ -587,7 +570,7 @@
 
 	ret = -EFAULT;
 	if (copy_from_user(&newregs, uregs, sizeof(struct pt_regs)) == 0) {
-		struct pt_regs *regs = get_user_regs(tsk);
+		struct pt_regs *regs = task_pt_regs(tsk);
 
 		ret = -EINVAL;
 		if (valid_user_regs(&newregs)) {
@@ -604,7 +587,7 @@
  */
 static int ptrace_getfpregs(struct task_struct *tsk, void __user *ufp)
 {
-	return copy_to_user(ufp, &tsk->thread_info->fpstate,
+	return copy_to_user(ufp, &task_thread_info(tsk)->fpstate,
 			    sizeof(struct user_fp)) ? -EFAULT : 0;
 }
 
@@ -613,7 +596,7 @@
  */
 static int ptrace_setfpregs(struct task_struct *tsk, void __user *ufp)
 {
-	struct thread_info *thread = tsk->thread_info;
+	struct thread_info *thread = task_thread_info(tsk);
 	thread->used_cp[1] = thread->used_cp[2] = 1;
 	return copy_from_user(&thread->fpstate, ufp,
 			      sizeof(struct user_fp)) ? -EFAULT : 0;
@@ -626,7 +609,7 @@
  */
 static int ptrace_getwmmxregs(struct task_struct *tsk, void __user *ufp)
 {
-	struct thread_info *thread = tsk->thread_info;
+	struct thread_info *thread = task_thread_info(tsk);
 	void *ptr = &thread->fpstate;
 
 	if (!test_ti_thread_flag(thread, TIF_USING_IWMMXT))
@@ -643,7 +626,7 @@
  */
 static int ptrace_setwmmxregs(struct task_struct *tsk, void __user *ufp)
 {
-	struct thread_info *thread = tsk->thread_info;
+	struct thread_info *thread = task_thread_info(tsk);
 	void *ptr = &thread->fpstate;
 
 	if (!test_ti_thread_flag(thread, TIF_USING_IWMMXT))
@@ -779,7 +762,7 @@
 #endif
 
 		case PTRACE_GET_THREAD_AREA:
-			ret = put_user(child->thread_info->tp_value,
+			ret = put_user(task_thread_info(child)->tp_value,
 				       (unsigned long __user *) data);
 			break;
 
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 373c095..7338948 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -114,7 +114,7 @@
 	 * We need to tell the secondary core where to find
 	 * its stack and the page tables.
 	 */
-	secondary_data.stack = (void *)idle->thread_info + THREAD_START_SP;
+	secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
 	secondary_data.pgdir = virt_to_phys(pgd);
 	wmb();
 
@@ -245,7 +245,7 @@
 	__asm__("mov	sp, %0\n"
 	"	b	secondary_start_kernel"
 		:
-		: "r" ((void *)current->thread_info + THREAD_SIZE - 8));
+		: "r" (task_stack_page(current) + THREAD_SIZE - 8));
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index c9fe6f5..93cfd3f 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -164,7 +164,7 @@
 	} else if (verify_stack(fp)) {
 		printk("invalid frame pointer 0x%08x", fp);
 		ok = 0;
-	} else if (fp < (unsigned long)(tsk->thread_info + 1))
+	} else if (fp < (unsigned long)end_of_stack(tsk))
 		printk("frame pointer underflow");
 	printk("\n");
 
@@ -210,7 +210,7 @@
 
 	if (!user_mode(regs) || in_interrupt()) {
 		dump_mem("Stack: ", regs->ARM_sp,
-			 THREAD_SIZE + (unsigned long)tsk->thread_info);
+			 THREAD_SIZE + (unsigned long)task_stack_page(tsk));
 		dump_backtrace(regs, tsk);
 		dump_instr(regs);
 	}
diff --git a/arch/arm26/kernel/process.c b/arch/arm26/kernel/process.c
index 15833a0..3863056 100644
--- a/arch/arm26/kernel/process.c
+++ b/arch/arm26/kernel/process.c
@@ -277,10 +277,9 @@
 copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start,
 	    unsigned long unused, struct task_struct *p, struct pt_regs *regs)
 {
-	struct thread_info *thread = p->thread_info;
-	struct pt_regs *childregs;
+	struct thread_info *thread = task_thread_info(p);
+	struct pt_regs *childregs = task_pt_regs(p);
 
-	childregs = __get_user_regs(thread);
 	*childregs = *regs;
 	childregs->ARM_r0 = 0;
 	childregs->ARM_sp = stack_start;
diff --git a/arch/arm26/kernel/ptrace.c b/arch/arm26/kernel/ptrace.c
index 4e6b735..3c3371d 100644
--- a/arch/arm26/kernel/ptrace.c
+++ b/arch/arm26/kernel/ptrace.c
@@ -40,21 +40,6 @@
 #define BREAKINST_ARM	0xef9f0001
 
 /*
- * Get the address of the live pt_regs for the specified task.
- * These are saved onto the top kernel stack when the process
- * is not running.
- *
- * Note: if a user thread is execve'd from kernel space, the
- * kernel stack will not be empty on entry to the kernel, so
- * ptracing these tasks will fail.
- */
-static inline struct pt_regs *
-get_user_regs(struct task_struct *task)
-{
-	return __get_user_regs(task->thread_info);
-}
-
-/*
  * this routine will get a word off of the processes privileged stack.
  * the offset is how far from the base addr as stored in the THREAD.
  * this routine assumes that all the privileged stacks are in our
@@ -62,7 +47,7 @@
  */
 static inline long get_user_reg(struct task_struct *task, int offset)
 {
-	return get_user_regs(task)->uregs[offset];
+	return task_pt_regs(task)->uregs[offset];
 }
 
 /*
@@ -74,7 +59,7 @@
 static inline int
 put_user_reg(struct task_struct *task, int offset, long data)
 {
-	struct pt_regs newregs, *regs = get_user_regs(task);
+	struct pt_regs newregs, *regs = task_pt_regs(task);
 	int ret = -EINVAL;
 
 	newregs = *regs;
@@ -377,7 +362,7 @@
 	u32 insn;
 	int res;
 
-	regs = get_user_regs(child);
+	regs = task_pt_regs(child);
 	pc = instruction_pointer(regs);
 
 	res = read_instr(child, pc, &insn);
@@ -500,7 +485,7 @@
  */
 static int ptrace_getregs(struct task_struct *tsk, void *uregs)
 {
-	struct pt_regs *regs = get_user_regs(tsk);
+	struct pt_regs *regs = task_pt_regs(tsk);
 
 	return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0;
 }
@@ -515,7 +500,7 @@
 
 	ret = -EFAULT;
 	if (copy_from_user(&newregs, uregs, sizeof(struct pt_regs)) == 0) {
-		struct pt_regs *regs = get_user_regs(tsk);
+		struct pt_regs *regs = task_pt_regs(tsk);
 
 		ret = -EINVAL;
 		if (valid_user_regs(&newregs)) {
@@ -532,7 +517,7 @@
  */
 static int ptrace_getfpregs(struct task_struct *tsk, void *ufp)
 {
-	return copy_to_user(ufp, &tsk->thread_info->fpstate,
+	return copy_to_user(ufp, &task_thread_info(tsk)->fpstate,
 			    sizeof(struct user_fp)) ? -EFAULT : 0;
 }
 
@@ -542,7 +527,7 @@
 static int ptrace_setfpregs(struct task_struct *tsk, void *ufp)
 {
 	set_stopped_child_used_math(tsk);
-	return copy_from_user(&tsk->thread_info->fpstate, ufp,
+	return copy_from_user(&task_threas_info(tsk)->fpstate, ufp,
 			      sizeof(struct user_fp)) ? -EFAULT : 0;
 }
 
diff --git a/arch/arm26/kernel/traps.c b/arch/arm26/kernel/traps.c
index f64f590..5847ea5 100644
--- a/arch/arm26/kernel/traps.c
+++ b/arch/arm26/kernel/traps.c
@@ -132,7 +132,7 @@
 
 /*static*/ void __dump_stack(struct task_struct *tsk, unsigned long sp)
 {
-	dump_mem("Stack: ", sp, 8192+(unsigned long)tsk->thread_info);
+	dump_mem("Stack: ", sp, 8192+(unsigned long)task_stack_page(tsk));
 }
 
 void dump_stack(void)
@@ -158,7 +158,7 @@
 	} else if (verify_stack(fp)) {
 		printk("invalid frame pointer 0x%08x", fp);
 		ok = 0;
-	} else if (fp < (unsigned long)(tsk->thread_info + 1))
+	} else if (fp < (unsigned long)end_of_stack(tsk))
 		printk("frame pointer underflow");
 	printk("\n");
 
@@ -168,7 +168,7 @@
 
 /* FIXME - this is probably wrong.. */
 void show_stack(struct task_struct *task, unsigned long *sp) {
-	dump_mem("Stack: ", (unsigned long)sp, 8192+(unsigned long)task->thread_info);
+	dump_mem("Stack: ", (unsigned long)sp, 8192+(unsigned long)task_stack_page(task));
 }
 
 DEFINE_SPINLOCK(die_lock);
@@ -187,7 +187,7 @@
 	printk("CPU: %d\n", smp_processor_id());
 	show_regs(regs);
 	printk("Process %s (pid: %d, stack limit = 0x%p)\n",
-		current->comm, current->pid, tsk->thread_info + 1);
+		current->comm, current->pid, end_of_stack(tsk));
 
 	if (!user_mode(regs) || in_interrupt()) {
 		__dump_stack(tsk, (unsigned long)(regs + 1));
diff --git a/arch/cris/arch-v10/kernel/process.c b/arch/cris/arch-v10/kernel/process.c
index 69e28b4..0a675ce 100644
--- a/arch/cris/arch-v10/kernel/process.c
+++ b/arch/cris/arch-v10/kernel/process.c
@@ -79,7 +79,7 @@
  */
 unsigned long thread_saved_pc(struct task_struct *t)
 {
-	return (unsigned long)user_regs(t->thread_info)->irp;
+	return task_pt_regs(t)->irp;
 }
 
 static void kernel_thread_helper(void* dummy, int (*fn)(void *), void * arg)
@@ -128,7 +128,7 @@
 	 * remember that the task_struct doubles as the kernel stack for the task
 	 */
 
-	childregs = user_regs(p->thread_info);        
+	childregs = task_pt_regs(p);
         
 	*childregs = *regs;  /* struct copy of pt_regs */
         
diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c
index 6cbd34a..f214f74 100644
--- a/arch/cris/arch-v10/kernel/ptrace.c
+++ b/arch/cris/arch-v10/kernel/ptrace.c
@@ -37,7 +37,7 @@
 	if (regno == PT_USP)
 		return task->thread.usp;
 	else if (regno < PT_MAX)
-		return ((unsigned long *)user_regs(task->thread_info))[regno];
+		return ((unsigned long *)task_pt_regs(task))[regno];
 	else
 		return 0;
 }
@@ -51,7 +51,7 @@
 	if (regno == PT_USP)
 		task->thread.usp = data;
 	else if (regno < PT_MAX)
-		((unsigned long *)user_regs(task->thread_info))[regno] = data;
+		((unsigned long *)task_pt_regs(task))[regno] = data;
 	else
 		return -1;
 	return 0;
diff --git a/arch/cris/arch-v32/kernel/process.c b/arch/cris/arch-v32/kernel/process.c
index 882be42..8435131 100644
--- a/arch/cris/arch-v32/kernel/process.c
+++ b/arch/cris/arch-v32/kernel/process.c
@@ -96,7 +96,7 @@
  */
 unsigned long thread_saved_pc(struct task_struct *t)
 {
-	return (unsigned long)user_regs(t->thread_info)->erp;
+	return task_pt_regs(t)->erp;
 }
 
 static void
@@ -148,7 +148,7 @@
 	 * fix it up. Note: the task_struct doubles as the kernel stack for the
 	 * task.
 	 */
-	childregs = user_regs(p->thread_info);
+	childregs = task_pt_regs(p);
 	*childregs = *regs;	/* Struct copy of pt_regs. */
         p->set_child_tid = p->clear_child_tid = NULL;
         childregs->r10 = 0;	/* Child returns 0 after a fork/clone. */
@@ -157,7 +157,7 @@
 	 * The TLS is in $mof beacuse it is the 5th argument to sys_clone.
 	 */
 	if (p->mm && (clone_flags & CLONE_SETTLS)) {
-		p->thread_info->tls = regs->mof;
+		task_thread_info(p)->tls = regs->mof;
 	}
 
 	/* Put the switch stack right below the pt_regs. */
diff --git a/arch/cris/arch-v32/kernel/ptrace.c b/arch/cris/arch-v32/kernel/ptrace.c
index 5528b83..82cf2e3 100644
--- a/arch/cris/arch-v32/kernel/ptrace.c
+++ b/arch/cris/arch-v32/kernel/ptrace.c
@@ -46,7 +46,7 @@
 	unsigned long ret;
 
 	if (regno <= PT_EDA)
-		ret = ((unsigned long *)user_regs(task->thread_info))[regno];
+		ret = ((unsigned long *)task_pt_regs(task))[regno];
 	else if (regno == PT_USP)
 		ret = task->thread.usp;
 	else if (regno == PT_PPC)
@@ -65,13 +65,13 @@
 int put_reg(struct task_struct *task, unsigned int regno, unsigned long data)
 {
 	if (regno <= PT_EDA)
-		((unsigned long *)user_regs(task->thread_info))[regno] = data;
+		((unsigned long *)task_pt_regs(task))[regno] = data;
 	else if (regno == PT_USP)
 		task->thread.usp = data;
 	else if (regno == PT_PPC) {
 		/* Write pseudo-PC to ERP only if changed. */
 		if (data != get_pseudo_pc(task))
-			((unsigned long *)user_regs(task->thread_info))[PT_ERP] = data;
+			task_pt_regs(task)->erp = data;
 	} else if (regno <= PT_MAX)
 		return put_debugreg(task->pid, regno, data);
 	else
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c
index 13867f4..da40d19 100644
--- a/arch/cris/arch-v32/kernel/smp.c
+++ b/arch/cris/arch-v32/kernel/smp.c
@@ -113,10 +113,10 @@
 	if (IS_ERR(idle))
 		panic("SMP: fork failed for CPU:%d", cpuid);
 
-	idle->thread_info->cpu = cpuid;
+	task_thread_info(idle)->cpu = cpuid;
 
 	/* Information to the CPU that is about to boot */
-	smp_init_current_idle_thread = idle->thread_info;
+	smp_init_current_idle_thread = task_thread_info(idle);
 	cpu_now_booting = cpuid;
 
 	/* Wait for CPU to come online */
diff --git a/arch/cris/arch-v32/mm/tlb.c b/arch/cris/arch-v32/mm/tlb.c
index b08a28b..9d75d76 100644
--- a/arch/cris/arch-v32/mm/tlb.c
+++ b/arch/cris/arch-v32/mm/tlb.c
@@ -198,9 +198,9 @@
 	per_cpu(current_pgd, cpu) = next->pgd;
 
 	/* Switch context in the MMU. */
-        if (tsk && tsk->thread_info)
+        if (tsk && task_thread_info(tsk))
         {
-          SPEC_REG_WR(SPEC_REG_PID, next->context.page_id | tsk->thread_info->tls);
+          SPEC_REG_WR(SPEC_REG_PID, next->context.page_id | task_thread_info(tsk)->tls);
         }
         else
         {
diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c
index c448837..0fff8a6 100644
--- a/arch/frv/kernel/process.c
+++ b/arch/frv/kernel/process.c
@@ -204,7 +204,7 @@
 
 	regs0 = __kernel_frame0_ptr;
 	childregs0 = (struct pt_regs *)
-		((unsigned long) p->thread_info + THREAD_SIZE - USER_CONTEXT_SIZE);
+		(task_stack_page(p) + THREAD_SIZE - USER_CONTEXT_SIZE);
 	childregs = childregs0;
 
 	/* set up the userspace frame (the only place that the USP is stored) */
@@ -220,7 +220,7 @@
 		*childregs = *regs;
 		childregs->sp = (unsigned long) childregs0;
 		childregs->next_frame = childregs0;
-		childregs->gr15 = (unsigned long) p->thread_info;
+		childregs->gr15 = (unsigned long) task_thread_info(p);
 		childregs->gr29 = (unsigned long) p;
 	}
 
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
index 585ed5e..ed79ae2 100644
--- a/arch/h8300/kernel/process.c
+++ b/arch/h8300/kernel/process.c
@@ -195,7 +195,7 @@
 {
 	struct pt_regs * childregs;
 
-	childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
+	childregs = (struct pt_regs *) (THREAD_SIZE + task_stack_page(p)) - 1;
 
 	*childregs = *regs;
 	childregs->retpc = (unsigned long) ret_from_fork;
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 035928f..2185377 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -424,18 +424,7 @@
 	struct task_struct *tsk;
 	int err;
 
-	childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
-	/*
-	 * The below -8 is to reserve 8 bytes on top of the ring0 stack.
-	 * This is necessary to guarantee that the entire "struct pt_regs"
-	 * is accessable even if the CPU haven't stored the SS/ESP registers
-	 * on the stack (interrupt gate does not save these registers
-	 * when switching to the same priv ring).
-	 * Therefore beware: accessing the xss/esp fields of the
-	 * "struct pt_regs" is possible, but they may contain the
-	 * completely wrong values.
-	 */
-	childregs = (struct pt_regs *) ((unsigned long) childregs - 8);
+	childregs = task_pt_regs(p);
 	*childregs = *regs;
 	childregs->eax = 0;
 	childregs->esp = esp;
@@ -540,12 +529,7 @@
  */
 int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
 {
-	struct pt_regs ptregs;
-	
-	ptregs = *(struct pt_regs *)
-		((unsigned long)tsk->thread_info +
-		/* see comments in copy_thread() about -8 */
-		THREAD_SIZE - sizeof(ptregs) - 8);
+	struct pt_regs ptregs = *task_pt_regs(tsk);
 	ptregs.xcs &= 0xffff;
 	ptregs.xds &= 0xffff;
 	ptregs.xes &= 0xffff;
@@ -601,8 +585,8 @@
 	 * gcc should eliminate the ->thread_info dereference if
 	 * has_secure_computing returns 0 at compile time (SECCOMP=n).
 	 */
-	prev = prev_p->thread_info;
-	next = next_p->thread_info;
+	prev = task_thread_info(prev_p);
+	next = task_thread_info(next_p);
 
 	if (has_secure_computing(prev) || has_secure_computing(next)) {
 		/* slow path here */
@@ -787,7 +771,7 @@
 	int count = 0;
 	if (!p || p == current || p->state == TASK_RUNNING)
 		return 0;
-	stack_page = (unsigned long)p->thread_info;
+	stack_page = (unsigned long)task_stack_page(p);
 	esp = p->thread.esp;
 	if (!stack_page || esp < stack_page || esp > top_esp+stack_page)
 		return 0;
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index b3c2e2c..255adb4 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -875,8 +875,7 @@
 		/* initialize thread_struct.  we really want to avoid destroy
 		 * idle tread
 		 */
-		idle->thread.esp = (unsigned long)(((struct pt_regs *)
-			(THREAD_SIZE + (unsigned long) idle->thread_info)) - 1);
+		idle->thread.esp = (unsigned long)task_pt_regs(idle);
 		init_idle(idle, cpu);
 		return idle;
 	}
@@ -1096,6 +1095,7 @@
 			cachesize = 16; /* Pentiums, 2x8kB cache */
 			bandwidth = 100;
 		}
+		max_cache_size = cachesize * 1024;
 	}
 }
 
diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c
index cbdb0af..0c90ae5 100644
--- a/arch/i386/kernel/vm86.c
+++ b/arch/i386/kernel/vm86.c
@@ -311,7 +311,7 @@
 		"movl %1,%%ebp\n\t"
 		"jmp resume_userspace"
 		: /* no outputs */
-		:"r" (&info->regs), "r" (tsk->thread_info) : "ax");
+		:"r" (&info->regs), "r" (task_thread_info(tsk)) : "ax");
 	/* we never return here */
 }
 
diff --git a/arch/ia64/ia32/elfcore32.h b/arch/ia64/ia32/elfcore32.h
index b73b8b6..a47f63b 100644
--- a/arch/ia64/ia32/elfcore32.h
+++ b/arch/ia64/ia32/elfcore32.h
@@ -95,8 +95,7 @@
 static inline int elf_core_copy_task_regs(struct task_struct *t,
 					  elf_gregset_t* elfregs)
 {
-	struct pt_regs *pp = ia64_task_regs(t);
-	ELF_CORE_COPY_REGS((*elfregs), pp);
+	ELF_CORE_COPY_REGS((*elfregs), task_pt_regs(t));
 	return 1;
 }
 
diff --git a/arch/ia64/ia32/ia32_signal.c b/arch/ia64/ia32/ia32_signal.c
index aa891c9..5856510 100644
--- a/arch/ia64/ia32/ia32_signal.c
+++ b/arch/ia64/ia32/ia32_signal.c
@@ -255,7 +255,7 @@
 	 */
 	fp_tos = (fsr>>11)&0x7;
 	fr8_st_map = (8-fp_tos)&0x7;
-	ptp = ia64_task_regs(tsk);
+	ptp = task_pt_regs(tsk);
 	fpregp = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15);
 	ia64f2ia32f(fpregp, &ptp->f8);
 	copy_to_user(&save->_st[(0+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
@@ -389,7 +389,7 @@
 	fr8_st_map = (8-fp_tos)&0x7;
 	fpregp = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15);
 
-	ptp = ia64_task_regs(tsk);
+	ptp = task_pt_regs(tsk);
 	copy_from_user(fpregp, &save->_st[(0+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
 	ia32f2ia64f(&ptp->f8, fpregp);
 	copy_from_user(fpregp, &save->_st[(1+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
diff --git a/arch/ia64/ia32/ia32_support.c b/arch/ia64/ia32/ia32_support.c
index 4f63004..c187743 100644
--- a/arch/ia64/ia32/ia32_support.c
+++ b/arch/ia64/ia32/ia32_support.c
@@ -58,7 +58,7 @@
 void
 ia32_load_segment_descriptors (struct task_struct *task)
 {
-	struct pt_regs *regs = ia64_task_regs(task);
+	struct pt_regs *regs = task_pt_regs(task);
 
 	/* Setup the segment descriptors */
 	regs->r24 = load_desc(regs->r16 >> 16);		/* ESD */
@@ -113,7 +113,7 @@
 ia32_load_state (struct task_struct *t)
 {
 	unsigned long eflag, fsr, fcr, fir, fdr, tssd;
-	struct pt_regs *regs = ia64_task_regs(t);
+	struct pt_regs *regs = task_pt_regs(t);
 
 	eflag = t->thread.eflag;
 	fsr = t->thread.fsr;
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index 0668b2b7..3945d37 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -1482,7 +1482,7 @@
 {
 	struct pt_regs *child_regs;
 
-	child_regs = ia64_task_regs(child);
+	child_regs = task_pt_regs(child);
 	switch (regno / sizeof(int)) {
 	      case PT_EBX: return child_regs->r11;
 	      case PT_ECX: return child_regs->r9;
@@ -1510,7 +1510,7 @@
 {
 	struct pt_regs *child_regs;
 
-	child_regs = ia64_task_regs(child);
+	child_regs = task_pt_regs(child);
 	switch (regno / sizeof(int)) {
 	      case PT_EBX: child_regs->r11 = value; break;
 	      case PT_ECX: child_regs->r9 = value; break;
@@ -1626,7 +1626,7 @@
 	 *  Stack frames start with 16-bytes of temp space
 	 */
 	swp = (struct switch_stack *)(tsk->thread.ksp + 16);
-	ptp = ia64_task_regs(tsk);
+	ptp = task_pt_regs(tsk);
 	tos = (tsk->thread.fsr >> 11) & 7;
 	for (i = 0; i < 8; i++)
 		put_fpreg(i, &save->st_space[i], ptp, swp, tos);
@@ -1659,7 +1659,7 @@
 	 *  Stack frames start with 16-bytes of temp space
 	 */
 	swp = (struct switch_stack *)(tsk->thread.ksp + 16);
-	ptp = ia64_task_regs(tsk);
+	ptp = task_pt_regs(tsk);
 	tos = (tsk->thread.fsr >> 11) & 7;
 	for (i = 0; i < 8; i++)
 		get_fpreg(i, &save->st_space[i], ptp, swp, tos);
@@ -1690,7 +1690,7 @@
          *  Stack frames start with 16-bytes of temp space
          */
         swp = (struct switch_stack *)(tsk->thread.ksp + 16);
-        ptp = ia64_task_regs(tsk);
+        ptp = task_pt_regs(tsk);
 	tos = (tsk->thread.fsr >> 11) & 7;
         for (i = 0; i < 8; i++)
 		put_fpreg(i, (struct _fpreg_ia32 __user *)&save->st_space[4*i], ptp, swp, tos);
@@ -1734,7 +1734,7 @@
 	 *  Stack frames start with 16-bytes of temp space
 	 */
 	swp = (struct switch_stack *)(tsk->thread.ksp + 16);
-	ptp = ia64_task_regs(tsk);
+	ptp = task_pt_regs(tsk);
 	tos = (tsk->thread.fsr >> 11) & 7;
 	for (i = 0; i < 8; i++)
 	get_fpreg(i, (struct _fpreg_ia32 __user *)&save->st_space[4*i], ptp, swp, tos);
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index 355af15..ee7eec9 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -766,7 +766,7 @@
 			l = strlen(previous_current->comm);
 		snprintf(comm, sizeof(comm), "%s %*s %d",
 			current->comm, l, previous_current->comm,
-			previous_current->thread_info->cpu);
+			task_thread_info(previous_current)->cpu);
 	}
 	memcpy(current->comm, comm, sizeof(current->comm));
 
@@ -1423,7 +1423,7 @@
 	struct task_struct *p = (struct task_struct *)((char *)mca_data + offset);
 	struct thread_info *ti;
 	memset(p, 0, KERNEL_STACK_SIZE);
-	ti = (struct thread_info *)((char *)p + IA64_TASK_SIZE);
+	ti = task_thread_info(p);
 	ti->flags = _TIF_MCA_INIT;
 	ti->preempt_count = 1;
 	ti->task = p;
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index c026ac1..bd87cb6 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -1710,7 +1710,7 @@
 pfm_syswide_force_stop(void *info)
 {
 	pfm_context_t   *ctx = (pfm_context_t *)info;
-	struct pt_regs *regs = ia64_task_regs(current);
+	struct pt_regs *regs = task_pt_regs(current);
 	struct task_struct *owner;
 	unsigned long flags;
 	int ret;
@@ -1815,7 +1815,7 @@
 	is_system = ctx->ctx_fl_system;
 
 	task = PFM_CTX_TASK(ctx);
-	regs = ia64_task_regs(task);
+	regs = task_pt_regs(task);
 
 	DPRINT(("ctx_state=%d is_current=%d\n",
 		state,
@@ -1945,7 +1945,7 @@
 	is_system = ctx->ctx_fl_system;
 
 	task = PFM_CTX_TASK(ctx);
-	regs = ia64_task_regs(task);
+	regs = task_pt_regs(task);
 
 	DPRINT(("ctx_state=%d is_current=%d\n", 
 		state,
@@ -4052,7 +4052,7 @@
 	 	 */
 		ia64_psr(regs)->up = 0;
 	} else {
-		tregs = ia64_task_regs(task);
+		tregs = task_pt_regs(task);
 
 		/*
 	 	 * stop monitoring at the user level
@@ -4134,7 +4134,7 @@
 		ia64_psr(regs)->up = 1;
 
 	} else {
-		tregs = ia64_task_regs(ctx->ctx_task);
+		tregs = task_pt_regs(ctx->ctx_task);
 
 		/*
 		 * start monitoring at the kernel level the next
@@ -4404,7 +4404,7 @@
 		/*
 		 * when not current, task MUST be stopped, so this is safe
 		 */
-		regs = ia64_task_regs(task);
+		regs = task_pt_regs(task);
 
 		/* force a full reload */
 		ctx->ctx_last_activation = PFM_INVALID_ACTIVATION;
@@ -4530,7 +4530,7 @@
 	/*
 	 * per-task mode
 	 */
-	tregs = task == current ? regs : ia64_task_regs(task);
+	tregs = task == current ? regs : task_pt_regs(task);
 
 	if (task == current) {
 		/*
@@ -4593,7 +4593,7 @@
 {
 	pfm_context_t *ctx;
 	unsigned long flags;
-	struct pt_regs *regs = ia64_task_regs(task);
+	struct pt_regs *regs = task_pt_regs(task);
 	int ret, state;
 	int free_ok = 0;
 
@@ -4926,7 +4926,7 @@
 	if (unlikely(ret)) goto abort_locked;
 
 skip_fd:
-	ret = (*func)(ctx, args_k, count, ia64_task_regs(current));
+	ret = (*func)(ctx, args_k, count, task_pt_regs(current));
 
 	call_made = 1;
 
@@ -5050,7 +5050,7 @@
 
 	pfm_clear_task_notify();
 
-	regs = ia64_task_regs(current);
+	regs = task_pt_regs(current);
 
 	/*
 	 * extract reason for being here and clear
@@ -5794,7 +5794,7 @@
 	 * on every CPU, so we can rely on the pid to identify the idle task.
 	 */
 	if ((info & PFM_CPUINFO_EXCL_IDLE) == 0 || task->pid) {
-		regs = ia64_task_regs(task);
+		regs = task_pt_regs(task);
 		ia64_psr(regs)->pp = is_ctxswin ? dcr_pp : 0;
 		return;
 	}
@@ -5877,7 +5877,7 @@
 	flags = pfm_protect_ctx_ctxsw(ctx);
 
 	if (ctx->ctx_state == PFM_CTX_ZOMBIE) {
-		struct pt_regs *regs = ia64_task_regs(task);
+		struct pt_regs *regs = task_pt_regs(task);
 
 		pfm_clear_psr_up();
 
@@ -6077,7 +6077,7 @@
 	BUG_ON(psr & IA64_PSR_I);
 
 	if (unlikely(ctx->ctx_state == PFM_CTX_ZOMBIE)) {
-		struct pt_regs *regs = ia64_task_regs(task);
+		struct pt_regs *regs = task_pt_regs(task);
 
 		BUG_ON(ctx->ctx_smpl_hdr);
 
@@ -6446,7 +6446,7 @@
 {
 	struct pt_regs *regs;
 
-	regs = ia64_task_regs(current);
+	regs = task_pt_regs(current);
 
 	DPRINT(("called\n"));
 
@@ -6472,7 +6472,7 @@
 {
 	struct pt_regs *regs;
 
-	regs = ia64_task_regs(current);
+	regs = task_pt_regs(current);
 
 	DPRINT(("called\n"));
 
@@ -6754,7 +6754,7 @@
 	local_irq_save(flags);
 
 	this_cpu = smp_processor_id();
-	regs     = ia64_task_regs(current);
+	regs     = task_pt_regs(current);
 	info     = PFM_CPUINFO_GET();
 	dcr      = ia64_getreg(_IA64_REG_CR_DCR);
 
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index e9904c7..309d596 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -328,7 +328,7 @@
 #endif
 
 #ifdef CONFIG_IA32_SUPPORT
-	if (IS_IA32_PROCESS(ia64_task_regs(task)))
+	if (IS_IA32_PROCESS(task_pt_regs(task)))
 		ia32_save_state(task);
 #endif
 }
@@ -353,7 +353,7 @@
 #endif
 
 #ifdef CONFIG_IA32_SUPPORT
-	if (IS_IA32_PROCESS(ia64_task_regs(task)))
+	if (IS_IA32_PROCESS(task_pt_regs(task)))
 		ia32_load_state(task);
 #endif
 }
@@ -488,7 +488,7 @@
 	 * If we're cloning an IA32 task then save the IA32 extra
 	 * state from the current task to the new task
 	 */
-	if (IS_IA32_PROCESS(ia64_task_regs(current))) {
+	if (IS_IA32_PROCESS(task_pt_regs(current))) {
 		ia32_save_state(p);
 		if (clone_flags & CLONE_SETTLS)
 			retval = ia32_clone_tls(p, child_ptregs);
@@ -701,7 +701,7 @@
 kernel_thread_helper (int (*fn)(void *), void *arg)
 {
 #ifdef CONFIG_IA32_SUPPORT
-	if (IS_IA32_PROCESS(ia64_task_regs(current))) {
+	if (IS_IA32_PROCESS(task_pt_regs(current))) {
 		/* A kernel thread is always a 64-bit process. */
 		current->thread.map_base  = DEFAULT_MAP_BASE;
 		current->thread.task_size = DEFAULT_TASK_SIZE;
@@ -722,7 +722,7 @@
 	current->thread.flags &= ~(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID);
 	ia64_drop_fpu(current);
 #ifdef CONFIG_IA32_SUPPORT
-	if (IS_IA32_PROCESS(ia64_task_regs(current))) {
+	if (IS_IA32_PROCESS(task_pt_regs(current))) {
 		ia32_drop_partial_page_list(current);
 		current->thread.task_size = IA32_PAGE_OFFSET;
 		set_fs(USER_DS);
@@ -755,7 +755,7 @@
 	if (current->thread.flags & IA64_THREAD_DBG_VALID)
 		pfm_release_debug_registers(current);
 #endif
-	if (IS_IA32_PROCESS(ia64_task_regs(current)))
+	if (IS_IA32_PROCESS(task_pt_regs(current)))
 		ia32_drop_partial_page_list(current);
 }
 
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index 8d88eee..eaed14a 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -254,7 +254,7 @@
 	long num_regs, nbits;
 	struct pt_regs *pt;
 
-	pt = ia64_task_regs(task);
+	pt = task_pt_regs(task);
 	kbsp = (unsigned long *) sw->ar_bspstore;
 	ubspstore = (unsigned long *) pt->ar_bspstore;
 
@@ -314,7 +314,7 @@
 	struct pt_regs *pt;
 	unsigned long cfm, *urbs_kargs;
 
-	pt = ia64_task_regs(task);
+	pt = task_pt_regs(task);
 	kbsp = (unsigned long *) sw->ar_bspstore;
 	ubspstore = (unsigned long *) pt->ar_bspstore;
 
@@ -407,7 +407,7 @@
 
 	urbs_end = (long *) user_rbs_end;
 	laddr = (unsigned long *) addr;
-	child_regs = ia64_task_regs(child);
+	child_regs = task_pt_regs(child);
 	bspstore = (unsigned long *) child_regs->ar_bspstore;
 	krbs = (unsigned long *) child + IA64_RBS_OFFSET/8;
 	if (on_kernel_rbs(addr, (unsigned long) bspstore,
@@ -467,7 +467,7 @@
 	struct pt_regs *child_regs;
 
 	laddr = (unsigned long *) addr;
-	child_regs = ia64_task_regs(child);
+	child_regs = task_pt_regs(child);
 	bspstore = (unsigned long *) child_regs->ar_bspstore;
 	krbs = (unsigned long *) child + IA64_RBS_OFFSET/8;
 	if (on_kernel_rbs(addr, (unsigned long) bspstore,
@@ -567,7 +567,7 @@
 		 */
 		return 0;
 
-	thread_regs = ia64_task_regs(thread);
+	thread_regs = task_pt_regs(thread);
 	thread_rbs_end = ia64_get_user_rbs_end(thread, thread_regs, NULL);
 	if (!on_kernel_rbs(addr, thread_regs->ar_bspstore, thread_rbs_end))
 		return 0;
@@ -627,7 +627,7 @@
 inline void
 ia64_flush_fph (struct task_struct *task)
 {
-	struct ia64_psr *psr = ia64_psr(ia64_task_regs(task));
+	struct ia64_psr *psr = ia64_psr(task_pt_regs(task));
 
 	/*
 	 * Prevent migrating this task while
@@ -653,7 +653,7 @@
 void
 ia64_sync_fph (struct task_struct *task)
 {
-	struct ia64_psr *psr = ia64_psr(ia64_task_regs(task));
+	struct ia64_psr *psr = ia64_psr(task_pt_regs(task));
 
 	ia64_flush_fph(task);
 	if (!(task->thread.flags & IA64_THREAD_FPH_VALID)) {
@@ -794,7 +794,7 @@
 					  + offsetof(struct pt_regs, reg)))
 
 
-	pt = ia64_task_regs(child);
+	pt = task_pt_regs(child);
 	sw = (struct switch_stack *) (child->thread.ksp + 16);
 
 	if ((addr & 0x7) != 0) {
@@ -1120,7 +1120,7 @@
 	if (!access_ok(VERIFY_WRITE, ppr, sizeof(struct pt_all_user_regs)))
 		return -EIO;
 
-	pt = ia64_task_regs(child);
+	pt = task_pt_regs(child);
 	sw = (struct switch_stack *) (child->thread.ksp + 16);
 	unw_init_from_blocked_task(&info, child);
 	if (unw_unwind_to_user(&info) < 0) {
@@ -1265,7 +1265,7 @@
 	if (!access_ok(VERIFY_READ, ppr, sizeof(struct pt_all_user_regs)))
 		return -EIO;
 
-	pt = ia64_task_regs(child);
+	pt = task_pt_regs(child);
 	sw = (struct switch_stack *) (child->thread.ksp + 16);
 	unw_init_from_blocked_task(&info, child);
 	if (unw_unwind_to_user(&info) < 0) {
@@ -1403,7 +1403,7 @@
 void
 ptrace_disable (struct task_struct *child)
 {
-	struct ia64_psr *child_psr = ia64_psr(ia64_task_regs(child));
+	struct ia64_psr *child_psr = ia64_psr(task_pt_regs(child));
 
 	/* make sure the single step/taken-branch trap bits are not set: */
 	child_psr->ss = 0;
@@ -1456,7 +1456,7 @@
 	if (ret < 0)
 		goto out_tsk;
 
-	pt = ia64_task_regs(child);
+	pt = task_pt_regs(child);
 	sw = (struct switch_stack *) (child->thread.ksp + 16);
 
 	switch (request) {
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index c33305d..c076657 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -60,6 +60,7 @@
 #include <asm/smp.h>
 #include <asm/system.h>
 #include <asm/unistd.h>
+#include <asm/system.h>
 
 #if defined(CONFIG_SMP) && (IA64_CPU_SIZE > PAGE_SIZE)
 # error "struct cpuinfo_ia64 too big!"
@@ -695,6 +696,7 @@
 get_max_cacheline_size (void)
 {
 	unsigned long line_size, max = 1;
+	unsigned int cache_size = 0;
 	u64 l, levels, unique_caches;
         pal_cache_config_info_t cci;
         s64 status;
@@ -724,6 +726,8 @@
 		line_size = 1 << cci.pcci_line_size;
 		if (line_size > max)
 			max = line_size;
+		if (cache_size < cci.pcci_cache_size)
+			cache_size = cci.pcci_cache_size;
 		if (!cci.pcci_unified) {
 			status = ia64_pal_cache_config_info(l,
 						    /* cache_type (instruction)= */ 1,
@@ -740,6 +744,9 @@
 			ia64_i_cache_stride_shift = cci.pcci_stride;
 	}
   out:
+#ifdef CONFIG_SMP
+	max_cache_size = max(max_cache_size, cache_size);
+#endif
 	if (max > ia64_max_cacheline_size)
 		ia64_max_cacheline_size = max;
 }
@@ -794,7 +801,7 @@
 #endif
 
 	/* Clear the stack memory reserved for pt_regs: */
-	memset(ia64_task_regs(current), 0, sizeof(struct pt_regs));
+	memset(task_pt_regs(current), 0, sizeof(struct pt_regs));
 
 	ia64_set_kr(IA64_KR_FPU_OWNER, 0);
 
@@ -870,6 +877,15 @@
 	pm_idle = default_idle;
 }
 
+/*
+ * On SMP systems, when the scheduler does migration-cost autodetection,
+ * it needs a way to flush as much of the CPU's caches as possible.
+ */
+void sched_cacheflush(void)
+{
+	ia64_sal_cache_flush(3);
+}
+
 void
 check_bugs (void)
 {
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 58ce07e..463f6bb 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -655,11 +655,11 @@
 
 		if (!t)
 			return;
-		t->thread_info->sigdelayed.signo = signo;
-		t->thread_info->sigdelayed.code = code;
-		t->thread_info->sigdelayed.addr = addr;
-		t->thread_info->sigdelayed.start_time = start_time;
-		t->thread_info->sigdelayed.pid = pid;
+		task_thread_info(t)->sigdelayed.signo = signo;
+		task_thread_info(t)->sigdelayed.code = code;
+		task_thread_info(t)->sigdelayed.addr = addr;
+		task_thread_info(t)->sigdelayed.start_time = start_time;
+		task_thread_info(t)->sigdelayed.pid = pid;
 		wmb();
 		set_tsk_thread_flag(t, TIF_SIGDELAYED);
 	}
diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
index f2dbcd1..c7b943f 100644
--- a/arch/ia64/kernel/sys_ia64.c
+++ b/arch/ia64/kernel/sys_ia64.c
@@ -151,7 +151,7 @@
 asmlinkage long
 sys_pipe (void)
 {
-	struct pt_regs *regs = ia64_task_regs(current);
+	struct pt_regs *regs = task_pt_regs(current);
 	int fd[2];
 	int retval;
 
diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c
index 2a1f250..5dfc7ea 100644
--- a/arch/m32r/kernel/process.c
+++ b/arch/m32r/kernel/process.c
@@ -242,13 +242,10 @@
 int copy_thread(int nr, unsigned long clone_flags, unsigned long spu,
 	unsigned long unused, struct task_struct *tsk, struct pt_regs *regs)
 {
-	struct pt_regs *childregs;
-	unsigned long sp = (unsigned long)tsk->thread_info + THREAD_SIZE;
+	struct pt_regs *childregs = task_pt_regs(tsk);
 	extern void ret_from_fork(void);
 
 	/* Copy registers */
-	sp -= sizeof (struct pt_regs);
-	childregs = (struct pt_regs *)sp;
 	*childregs = *regs;
 
 	childregs->spu = spu;
diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c
index 9b75caa..340a3bf 100644
--- a/arch/m32r/kernel/ptrace.c
+++ b/arch/m32r/kernel/ptrace.c
@@ -35,23 +35,6 @@
 #include <asm/mmu_context.h>
 
 /*
- * Get the address of the live pt_regs for the specified task.
- * These are saved onto the top kernel stack when the process
- * is not running.
- *
- * Note: if a user thread is execve'd from kernel space, the
- * kernel stack will not be empty on entry to the kernel, so
- * ptracing these tasks will fail.
- */
-static inline struct pt_regs *
-get_user_regs(struct task_struct *task)
-{
-        return (struct pt_regs *)
-                ((unsigned long)task->thread_info + THREAD_SIZE
-                 - sizeof(struct pt_regs));
-}
-
-/*
  * This routine will get a word off of the process kernel stack.
  */
 static inline unsigned long int
@@ -59,7 +42,7 @@
 {
 	unsigned long *stack;
 
-	stack = (unsigned long *)get_user_regs(task);
+	stack = (unsigned long *)task_pt_regs(task);
 
 	return stack[offset];
 }
@@ -72,7 +55,7 @@
 {
 	unsigned long *stack;
 
-	stack = (unsigned long *)get_user_regs(task);
+	stack = (unsigned long *)task_pt_regs(task);
 	stack[offset] = data;
 
 	return 0;
@@ -208,7 +191,7 @@
  */
 static int ptrace_getregs(struct task_struct *tsk, void __user *uregs)
 {
-	struct pt_regs *regs = get_user_regs(tsk);
+	struct pt_regs *regs = task_pt_regs(tsk);
 
 	return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0;
 }
@@ -223,7 +206,7 @@
 
 	ret = -EFAULT;
 	if (copy_from_user(&newregs, uregs, sizeof(struct pt_regs)) == 0) {
-		struct pt_regs *regs = get_user_regs(tsk);
+		struct pt_regs *regs = task_pt_regs(tsk);
 		*regs = newregs;
 		ret = 0;
 	}
diff --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c
index b90c541..d7ec16e 100644
--- a/arch/m32r/kernel/smpboot.c
+++ b/arch/m32r/kernel/smpboot.c
@@ -286,7 +286,7 @@
 	/* So we see what's up   */
 	printk("Booting processor %d/%d\n", phys_id, cpu_id);
 	stack_start.spi = (void *)idle->thread.sp;
-	idle->thread_info->cpu = cpu_id;
+	task_thread_info(idle)->cpu = cpu_id;
 
 	/*
 	 * Send Startup IPI
diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c
index d9edf2d..b0aa61b 100644
--- a/arch/m68k/amiga/amiints.c
+++ b/arch/m68k/amiga/amiints.c
@@ -126,9 +126,9 @@
 		gayle.inten = GAYLE_IRQ_IDE;
 
 	/* turn off all interrupts and enable the master interrupt bit */
-	custom.intena = 0x7fff;
-	custom.intreq = 0x7fff;
-	custom.intena = IF_SETCLR | IF_INTEN;
+	amiga_custom.intena = 0x7fff;
+	amiga_custom.intreq = 0x7fff;
+	amiga_custom.intena = IF_SETCLR | IF_INTEN;
 
 	cia_init_IRQ(&ciaa_base);
 	cia_init_IRQ(&ciab_base);
@@ -245,7 +245,7 @@
 
 	/* enable the interrupt */
 	if (irq < IRQ_AMIGA_PORTS && !ami_ablecount[irq])
-		custom.intena = IF_SETCLR | amiga_intena_vals[irq];
+		amiga_custom.intena = IF_SETCLR | amiga_intena_vals[irq];
 
 	return error;
 }
@@ -274,7 +274,7 @@
 		amiga_delete_irq(&ami_irq_list[irq], dev_id);
 		/* if server list empty, disable the interrupt */
 		if (!ami_irq_list[irq] && irq < IRQ_AMIGA_PORTS)
-			custom.intena = amiga_intena_vals[irq];
+			amiga_custom.intena = amiga_intena_vals[irq];
 	} else {
 		if (ami_irq_list[irq]->dev_id != dev_id)
 			printk("%s: removing probably wrong IRQ %d from %s\n",
@@ -283,7 +283,7 @@
 		ami_irq_list[irq]->flags   = 0;
 		ami_irq_list[irq]->dev_id  = NULL;
 		ami_irq_list[irq]->devname = NULL;
-		custom.intena = amiga_intena_vals[irq];
+		amiga_custom.intena = amiga_intena_vals[irq];
 	}
 }
 
@@ -327,7 +327,7 @@
 	}
 
 	/* enable the interrupt */
-	custom.intena = IF_SETCLR | amiga_intena_vals[irq];
+	amiga_custom.intena = IF_SETCLR | amiga_intena_vals[irq];
 }
 
 void amiga_disable_irq(unsigned int irq)
@@ -358,7 +358,7 @@
 	}
 
 	/* disable the interrupt */
-	custom.intena = amiga_intena_vals[irq];
+	amiga_custom.intena = amiga_intena_vals[irq];
 }
 
 inline void amiga_do_irq(int irq, struct pt_regs *fp)
@@ -373,7 +373,7 @@
 
 	kstat_cpu(0).irqs[SYS_IRQS + irq]++;
 
-	custom.intreq = amiga_intena_vals[irq];
+	amiga_custom.intreq = amiga_intena_vals[irq];
 
 	for (node = ami_irq_list[irq]; node; node = node->next)
 		node->handler(irq, node->dev_id, fp);
@@ -385,23 +385,23 @@
 
 static irqreturn_t ami_int1(int irq, void *dev_id, struct pt_regs *fp)
 {
-	unsigned short ints = custom.intreqr & custom.intenar;
+	unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar;
 
 	/* if serial transmit buffer empty, interrupt */
 	if (ints & IF_TBE) {
-		custom.intreq = IF_TBE;
+		amiga_custom.intreq = IF_TBE;
 		amiga_do_irq(IRQ_AMIGA_TBE, fp);
 	}
 
 	/* if floppy disk transfer complete, interrupt */
 	if (ints & IF_DSKBLK) {
-		custom.intreq = IF_DSKBLK;
+		amiga_custom.intreq = IF_DSKBLK;
 		amiga_do_irq(IRQ_AMIGA_DSKBLK, fp);
 	}
 
 	/* if software interrupt set, interrupt */
 	if (ints & IF_SOFT) {
-		custom.intreq = IF_SOFT;
+		amiga_custom.intreq = IF_SOFT;
 		amiga_do_irq(IRQ_AMIGA_SOFT, fp);
 	}
 	return IRQ_HANDLED;
@@ -409,17 +409,17 @@
 
 static irqreturn_t ami_int3(int irq, void *dev_id, struct pt_regs *fp)
 {
-	unsigned short ints = custom.intreqr & custom.intenar;
+	unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar;
 
 	/* if a blitter interrupt */
 	if (ints & IF_BLIT) {
-		custom.intreq = IF_BLIT;
+		amiga_custom.intreq = IF_BLIT;
 		amiga_do_irq(IRQ_AMIGA_BLIT, fp);
 	}
 
 	/* if a copper interrupt */
 	if (ints & IF_COPER) {
-		custom.intreq = IF_COPER;
+		amiga_custom.intreq = IF_COPER;
 		amiga_do_irq(IRQ_AMIGA_COPPER, fp);
 	}
 
@@ -431,29 +431,29 @@
 
 static irqreturn_t ami_int4(int irq, void *dev_id, struct pt_regs *fp)
 {
-	unsigned short ints = custom.intreqr & custom.intenar;
+	unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar;
 
 	/* if audio 0 interrupt */
 	if (ints & IF_AUD0) {
-		custom.intreq = IF_AUD0;
+		amiga_custom.intreq = IF_AUD0;
 		amiga_do_irq(IRQ_AMIGA_AUD0, fp);
 	}
 
 	/* if audio 1 interrupt */
 	if (ints & IF_AUD1) {
-		custom.intreq = IF_AUD1;
+		amiga_custom.intreq = IF_AUD1;
 		amiga_do_irq(IRQ_AMIGA_AUD1, fp);
 	}
 
 	/* if audio 2 interrupt */
 	if (ints & IF_AUD2) {
-		custom.intreq = IF_AUD2;
+		amiga_custom.intreq = IF_AUD2;
 		amiga_do_irq(IRQ_AMIGA_AUD2, fp);
 	}
 
 	/* if audio 3 interrupt */
 	if (ints & IF_AUD3) {
-		custom.intreq = IF_AUD3;
+		amiga_custom.intreq = IF_AUD3;
 		amiga_do_irq(IRQ_AMIGA_AUD3, fp);
 	}
 	return IRQ_HANDLED;
@@ -461,7 +461,7 @@
 
 static irqreturn_t ami_int5(int irq, void *dev_id, struct pt_regs *fp)
 {
-	unsigned short ints = custom.intreqr & custom.intenar;
+	unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar;
 
 	/* if serial receive buffer full interrupt */
 	if (ints & IF_RBF) {
@@ -471,7 +471,7 @@
 
 	/* if a disk sync interrupt */
 	if (ints & IF_DSKSYN) {
-		custom.intreq = IF_DSKSYN;
+		amiga_custom.intreq = IF_DSKSYN;
 		amiga_do_irq(IRQ_AMIGA_DSKSYN, fp);
 	}
 	return IRQ_HANDLED;
diff --git a/arch/m68k/amiga/amisound.c b/arch/m68k/amiga/amisound.c
index bd5d134e..ae94db5 100644
--- a/arch/m68k/amiga/amisound.c
+++ b/arch/m68k/amiga/amisound.c
@@ -24,6 +24,8 @@
 };
 #define DATA_SIZE	(sizeof(sine_data)/sizeof(sine_data[0]))
 
+#define custom amiga_custom
+
     /*
      * The minimum period for audio may be modified by the frame buffer
      * device since it depends on htotal (for OCS/ECS/AGA)
diff --git a/arch/m68k/amiga/cia.c b/arch/m68k/amiga/cia.c
index 7d55682..9476eb9 100644
--- a/arch/m68k/amiga/cia.c
+++ b/arch/m68k/amiga/cia.c
@@ -60,7 +60,7 @@
 	else
 		base->icr_data &= ~mask;
 	if (base->icr_data & base->icr_mask)
-		custom.intreq = IF_SETCLR | base->int_mask;
+		amiga_custom.intreq = IF_SETCLR | base->int_mask;
 	return old & base->icr_mask;
 }
 
@@ -89,7 +89,7 @@
 		}
 	}
 	if (base->icr_data & base->icr_mask)
-		custom.intreq = IF_SETCLR | base->int_mask;
+		amiga_custom.intreq = IF_SETCLR | base->int_mask;
 	return old;
 }
 
@@ -133,7 +133,7 @@
 	mach_irq = base->cia_irq;
 	irq = SYS_IRQS + mach_irq;
 	ints = cia_set_irq(base, CIA_ICR_ALL);
-	custom.intreq = base->int_mask;
+	amiga_custom.intreq = base->int_mask;
 	for (i = 0; i < CIA_IRQS; i++, irq++, mach_irq++) {
 		if (ints & 1) {
 			kstat_cpu(0).irqs[irq]++;
@@ -162,7 +162,7 @@
 	/* install CIA handler */
 	request_irq(base->handler_irq, cia_handler, 0, base->name, base);
 
-	custom.intena = IF_SETCLR | base->int_mask;
+	amiga_custom.intena = IF_SETCLR | base->int_mask;
 }
 
 int cia_get_irq_list(struct ciabase *base, struct seq_file *p)
diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c
index 4775e18..12e3706 100644
--- a/arch/m68k/amiga/config.c
+++ b/arch/m68k/amiga/config.c
@@ -105,9 +105,6 @@
 static int amiga_set_clock_mmss (unsigned long);
 static unsigned int amiga_get_ss (void);
 extern void amiga_mksound( unsigned int count, unsigned int ticks );
-#ifdef CONFIG_AMIGA_FLOPPY
-extern void amiga_floppy_setup(char *, int *);
-#endif
 static void amiga_reset (void);
 extern void amiga_init_sound(void);
 static void amiga_savekmsg_init(void);
@@ -290,7 +287,7 @@
     case CS_OCS:
     case CS_ECS:
     case CS_AGA:
-      switch (custom.deniseid & 0xf) {
+      switch (amiga_custom.deniseid & 0xf) {
       case 0x0c:
 	AMIGAHW_SET(DENISE_HR);
 	break;
@@ -303,7 +300,7 @@
       AMIGAHW_SET(DENISE);
       break;
     }
-    switch ((custom.vposr>>8) & 0x7f) {
+    switch ((amiga_custom.vposr>>8) & 0x7f) {
     case 0x00:
       AMIGAHW_SET(AGNUS_PAL);
       break;
@@ -427,13 +424,7 @@
 
   mach_set_clock_mmss  = amiga_set_clock_mmss;
   mach_get_ss          = amiga_get_ss;
-#ifdef CONFIG_AMIGA_FLOPPY
-  mach_floppy_setup    = amiga_floppy_setup;
-#endif
   mach_reset           = amiga_reset;
-#ifdef CONFIG_DUMMY_CONSOLE
-  conswitchp           = &dummy_con;
-#endif
 #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)
   mach_beep            = amiga_mksound;
 #endif
@@ -447,9 +438,9 @@
   amiga_colorclock = 5*amiga_eclock;	/* 3.5 MHz */
 
   /* clear all DMA bits */
-  custom.dmacon = DMAF_ALL;
+  amiga_custom.dmacon = DMAF_ALL;
   /* ensure that the DMA master bit is set */
-  custom.dmacon = DMAF_SETCLR | DMAF_MASTER;
+  amiga_custom.dmacon = DMAF_SETCLR | DMAF_MASTER;
 
   /* don't use Z2 RAM as system memory on Z3 capable machines */
   if (AMIGAHW_PRESENT(ZORRO3)) {
@@ -830,8 +821,8 @@
 
 static void amiga_serial_putc(char c)
 {
-    custom.serdat = (unsigned char)c | 0x100;
-    while (!(custom.serdatr & 0x2000))
+    amiga_custom.serdat = (unsigned char)c | 0x100;
+    while (!(amiga_custom.serdatr & 0x2000))
 	;
 }
 
@@ -855,11 +846,11 @@
 {
     int ch;
 
-    while (!(custom.intreqr & IF_RBF))
+    while (!(amiga_custom.intreqr & IF_RBF))
 	barrier();
-    ch = custom.serdatr & 0xff;
+    ch = amiga_custom.serdatr & 0xff;
     /* clear the interrupt, so that another character can be read */
-    custom.intreq = IF_RBF;
+    amiga_custom.intreq = IF_RBF;
     return ch;
 }
 
diff --git a/arch/m68k/apollo/config.c b/arch/m68k/apollo/config.c
index 2649294..d401962 100644
--- a/arch/m68k/apollo/config.c
+++ b/arch/m68k/apollo/config.c
@@ -176,9 +176,6 @@
 	mach_set_clock_mmss  = dn_dummy_set_clock_mmss; /* */
 	mach_process_int     = dn_process_int;
 	mach_reset	     = dn_dummy_reset;  /* */
-#ifdef CONFIG_DUMMY_CONSOLE
-        conswitchp           = &dummy_con;
-#endif
 #ifdef CONFIG_HEARTBEAT
 	mach_heartbeat = dn_heartbeat;
 #endif
diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c
index 9261d2d..1012b08e5 100644
--- a/arch/m68k/atari/config.c
+++ b/arch/m68k/atari/config.c
@@ -52,9 +52,6 @@
 
 /* local function prototypes */
 static void atari_reset( void );
-#ifdef CONFIG_ATARI_FLOPPY
-extern void atari_floppy_setup(char *, int *);
-#endif
 static void atari_get_model(char *model);
 static int atari_get_hardware_list(char *buffer);
 
@@ -244,12 +241,6 @@
     mach_get_irq_list	 = show_atari_interrupts;
     mach_gettimeoffset   = atari_gettimeoffset;
     mach_reset           = atari_reset;
-#ifdef CONFIG_ATARI_FLOPPY
-    mach_floppy_setup	 = atari_floppy_setup;
-#endif
-#ifdef CONFIG_DUMMY_CONSOLE
-    conswitchp	         = &dummy_con;
-#endif
     mach_max_dma_address = 0xffffff;
 #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)
     mach_beep          = atari_mksound;
diff --git a/arch/m68k/bvme6000/rtc.c b/arch/m68k/bvme6000/rtc.c
index f7573f2..703cbc6 100644
--- a/arch/m68k/bvme6000/rtc.c
+++ b/arch/m68k/bvme6000/rtc.c
@@ -47,6 +47,7 @@
 	unsigned char msr;
 	unsigned long flags;
 	struct rtc_time wtime;
+	void __user *argp = (void __user *)arg;
 
 	switch (cmd) {
 	case RTC_RD_TIME:	/* Read the time/date from RTC	*/
@@ -69,7 +70,7 @@
 		} while (wtime.tm_sec != BCD2BIN(rtc->bcd_sec));
 		rtc->msr = msr;
 		local_irq_restore(flags);
-		return copy_to_user((void *)arg, &wtime, sizeof wtime) ?
+		return copy_to_user(argp, &wtime, sizeof wtime) ?
 								-EFAULT : 0;
 	}
 	case RTC_SET_TIME:	/* Set the RTC */
@@ -81,8 +82,7 @@
 		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
 
-		if (copy_from_user(&rtc_tm, (struct rtc_time*)arg,
-				   sizeof(struct rtc_time)))
+		if (copy_from_user(&rtc_tm, argp, sizeof(struct rtc_time)))
 			return -EFAULT;
 
 		yrs = rtc_tm.tm_year;
diff --git a/arch/m68k/hp300/config.c b/arch/m68k/hp300/config.c
index a0b854f..6d129ee 100644
--- a/arch/m68k/hp300/config.c
+++ b/arch/m68k/hp300/config.c
@@ -261,9 +261,6 @@
 #ifdef CONFIG_HEARTBEAT
 	mach_heartbeat       = hp300_pulse;
 #endif
-#ifdef CONFIG_DUMMY_CONSOLE
-	conswitchp	     = &dummy_con;
-#endif
 	mach_max_dma_address = 0xffffffff;
 
 	if (hp300_model >= HP_330 && hp300_model <= HP_433S && hp300_model != HP_350) {
diff --git a/arch/m68k/kernel/asm-offsets.c b/arch/m68k/kernel/asm-offsets.c
index c787c5b..246a882 100644
--- a/arch/m68k/kernel/asm-offsets.c
+++ b/arch/m68k/kernel/asm-offsets.c
@@ -92,7 +92,7 @@
 	DEFINE(TRAP_TRACE, TRAP_TRACE);
 
 	/* offsets into the custom struct */
-	DEFINE(CUSTOMBASE, &custom);
+	DEFINE(CUSTOMBASE, &amiga_custom);
 	DEFINE(C_INTENAR, offsetof(struct CUSTOM, intenar));
 	DEFINE(C_INTREQR, offsetof(struct CUSTOM, intreqr));
 	DEFINE(C_INTENA, offsetof(struct CUSTOM, intena));
diff --git a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S
index d4336d8..70002c1 100644
--- a/arch/m68k/kernel/head.S
+++ b/arch/m68k/kernel/head.S
@@ -273,8 +273,10 @@
  * Macintosh console support
  */
 
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE
 #define CONSOLE
 #define CONSOLE_PENGUIN
+#endif
 
 /*
  * Macintosh serial debug support; outputs boot info to the printer
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index 13d10932..3f9cb55 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -238,10 +238,9 @@
 {
 	struct pt_regs * childregs;
 	struct switch_stack * childstack, *stack;
-	unsigned long stack_offset, *retp;
+	unsigned long *retp;
 
-	stack_offset = THREAD_SIZE - sizeof(struct pt_regs);
-	childregs = (struct pt_regs *) ((unsigned long) (p->thread_info) + stack_offset);
+	childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;
 
 	*childregs = *regs;
 	childregs->d0 = 0;
@@ -386,7 +385,7 @@
 	if (!p || p == current || p->state == TASK_RUNNING)
 		return 0;
 
-	stack_page = (unsigned long)(p->thread_info);
+	stack_page = (unsigned long)task_stack_page(p);
 	fp = ((struct switch_stack *)p->thread.ksp)->a6;
 	do {
 		if (fp < stack_page+sizeof(struct thread_info) ||
diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c
index d6ca992..750d5b3 100644
--- a/arch/m68k/kernel/setup.c
+++ b/arch/m68k/kernel/setup.c
@@ -84,9 +84,6 @@
 void (*mach_halt)( void );
 void (*mach_power_off)( void );
 long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */
-#if defined(CONFIG_AMIGA_FLOPPY) || defined(CONFIG_ATARI_FLOPPY)
-void (*mach_floppy_setup) (char *, int *) __initdata = NULL;
-#endif
 #ifdef CONFIG_HEARTBEAT
 void (*mach_heartbeat) (int);
 EXPORT_SYMBOL(mach_heartbeat);
@@ -100,6 +97,8 @@
 #if defined(CONFIG_ISA) && defined(MULTI_ISA)
 int isa_type;
 int isa_sex;
+EXPORT_SYMBOL(isa_type);
+EXPORT_SYMBOL(isa_sex);
 #endif
 
 extern int amiga_parse_bootinfo(const struct bi_record *);
@@ -280,6 +279,10 @@
 	    }
 	}
 
+#ifdef CONFIG_DUMMY_CONSOLE
+	conswitchp = &dummy_con;
+#endif
+
 	switch (m68k_machtype) {
 #ifdef CONFIG_AMIGA
 	    case MACH_AMIGA:
@@ -521,16 +524,6 @@
     return(len);
 }
 
-
-#if defined(CONFIG_AMIGA_FLOPPY) || defined(CONFIG_ATARI_FLOPPY)
-void __init floppy_setup(char *str, int *ints)
-{
-	if (mach_floppy_setup)
-		mach_floppy_setup (str, ints);
-}
-
-#endif
-
 void check_bugs(void)
 {
 #ifndef CONFIG_M68KFPU_EMU
diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
index 9c636a4..866917b 100644
--- a/arch/m68k/kernel/signal.c
+++ b/arch/m68k/kernel/signal.c
@@ -96,7 +96,7 @@
 asmlinkage int
 do_rt_sigsuspend(struct pt_regs *regs)
 {
-	sigset_t *unewset = (sigset_t *)regs->d1;
+	sigset_t __user *unewset = (sigset_t __user *)regs->d1;
 	size_t sigsetsize = (size_t)regs->d2;
 	sigset_t saveset, newset;
 
@@ -122,8 +122,8 @@
 }
 
 asmlinkage int
-sys_sigaction(int sig, const struct old_sigaction *act,
-	      struct old_sigaction *oact)
+sys_sigaction(int sig, const struct old_sigaction __user *act,
+	      struct old_sigaction __user *oact)
 {
 	struct k_sigaction new_ka, old_ka;
 	int ret;
@@ -154,7 +154,7 @@
 }
 
 asmlinkage int
-sys_sigaltstack(const stack_t *uss, stack_t *uoss)
+sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
 {
 	return do_sigaltstack(uss, uoss, rdusp());
 }
@@ -169,10 +169,10 @@
 
 struct sigframe
 {
-	char *pretcode;
+	char __user *pretcode;
 	int sig;
 	int code;
-	struct sigcontext *psc;
+	struct sigcontext __user *psc;
 	char retcode[8];
 	unsigned long extramask[_NSIG_WORDS-1];
 	struct sigcontext sc;
@@ -180,10 +180,10 @@
 
 struct rt_sigframe
 {
-	char *pretcode;
+	char __user *pretcode;
 	int sig;
-	struct siginfo *pinfo;
-	void *puc;
+	struct siginfo __user *pinfo;
+	void __user *puc;
 	char retcode[8];
 	struct siginfo info;
 	struct ucontext uc;
@@ -248,7 +248,7 @@
 #define uc_formatvec	uc_filler[FPCONTEXT_SIZE/4]
 #define uc_extra	uc_filler[FPCONTEXT_SIZE/4+1]
 
-static inline int rt_restore_fpu_state(struct ucontext *uc)
+static inline int rt_restore_fpu_state(struct ucontext __user *uc)
 {
 	unsigned char fpstate[FPCONTEXT_SIZE];
 	int context_size = CPU_IS_060 ? 8 : 0;
@@ -267,7 +267,7 @@
 		return 0;
 	}
 
-	if (__get_user(*(long *)fpstate, (long *)&uc->uc_fpstate))
+	if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate))
 		goto out;
 	if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
 		if (!CPU_IS_060)
@@ -306,7 +306,7 @@
 				    "m" (*fpregs.f_fpcntl));
 	}
 	if (context_size &&
-	    __copy_from_user(fpstate + 4, (long *)&uc->uc_fpstate + 1,
+	    __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1,
 			     context_size))
 		goto out;
 	__asm__ volatile (".chip 68k/68881\n\t"
@@ -319,7 +319,7 @@
 }
 
 static inline int
-restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, void *fp,
+restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp,
 		   int *pd0)
 {
 	int fsize, formatvec;
@@ -404,10 +404,10 @@
 
 static inline int
 rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
-		    struct ucontext *uc, int *pd0)
+		    struct ucontext __user *uc, int *pd0)
 {
 	int fsize, temp;
-	greg_t *gregs = uc->uc_mcontext.gregs;
+	greg_t __user *gregs = uc->uc_mcontext.gregs;
 	unsigned long usp;
 	int err;
 
@@ -506,7 +506,7 @@
 	struct switch_stack *sw = (struct switch_stack *) &__unused;
 	struct pt_regs *regs = (struct pt_regs *) (sw + 1);
 	unsigned long usp = rdusp();
-	struct sigframe *frame = (struct sigframe *)(usp - 4);
+	struct sigframe __user *frame = (struct sigframe __user *)(usp - 4);
 	sigset_t set;
 	int d0;
 
@@ -536,7 +536,7 @@
 	struct switch_stack *sw = (struct switch_stack *) &__unused;
 	struct pt_regs *regs = (struct pt_regs *) (sw + 1);
 	unsigned long usp = rdusp();
-	struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4);
+	struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4);
 	sigset_t set;
 	int d0;
 
@@ -596,7 +596,7 @@
 	}
 }
 
-static inline int rt_save_fpu_state(struct ucontext *uc, struct pt_regs *regs)
+static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs)
 {
 	unsigned char fpstate[FPCONTEXT_SIZE];
 	int context_size = CPU_IS_060 ? 8 : 0;
@@ -617,7 +617,7 @@
 			  ".chip 68k"
 			  : : "m" (*fpstate) : "memory");
 
-	err |= __put_user(*(long *)fpstate, (long *)&uc->uc_fpstate);
+	err |= __put_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate);
 	if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
 		fpregset_t fpregs;
 		if (!CPU_IS_060)
@@ -642,7 +642,7 @@
 				    sizeof(fpregs));
 	}
 	if (context_size)
-		err |= copy_to_user((long *)&uc->uc_fpstate + 1, fpstate + 4,
+		err |= copy_to_user((long __user *)&uc->uc_fpstate + 1, fpstate + 4,
 				    context_size);
 	return err;
 }
@@ -662,10 +662,10 @@
 	save_fpu_state(sc, regs);
 }
 
-static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
+static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs)
 {
 	struct switch_stack *sw = (struct switch_stack *)regs - 1;
-	greg_t *gregs = uc->uc_mcontext.gregs;
+	greg_t __user *gregs = uc->uc_mcontext.gregs;
 	int err = 0;
 
 	err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
@@ -753,7 +753,7 @@
 	}
 }
 
-static inline void *
+static inline void __user *
 get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
 {
 	unsigned long usp;
@@ -766,13 +766,13 @@
 		if (!on_sig_stack(usp))
 			usp = current->sas_ss_sp + current->sas_ss_size;
 	}
-	return (void *)((usp - frame_size) & -8UL);
+	return (void __user *)((usp - frame_size) & -8UL);
 }
 
 static void setup_frame (int sig, struct k_sigaction *ka,
 			 sigset_t *set, struct pt_regs *regs)
 {
-	struct sigframe *frame;
+	struct sigframe __user *frame;
 	int fsize = frame_extra_sizes[regs->format];
 	struct sigcontext context;
 	int err = 0;
@@ -813,7 +813,7 @@
 	err |= __put_user(frame->retcode, &frame->pretcode);
 	/* moveq #,d0; trap #0 */
 	err |= __put_user(0x70004e40 + (__NR_sigreturn << 16),
-			  (long *)(frame->retcode));
+			  (long __user *)(frame->retcode));
 
 	if (err)
 		goto give_sigsegv;
@@ -849,7 +849,7 @@
 static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
 			    sigset_t *set, struct pt_regs *regs)
 {
-	struct rt_sigframe *frame;
+	struct rt_sigframe __user *frame;
 	int fsize = frame_extra_sizes[regs->format];
 	int err = 0;
 
@@ -880,8 +880,8 @@
 
 	/* Create the ucontext.  */
 	err |= __put_user(0, &frame->uc.uc_flags);
-	err |= __put_user(0, &frame->uc.uc_link);
-	err |= __put_user((void *)current->sas_ss_sp,
+	err |= __put_user(NULL, &frame->uc.uc_link);
+	err |= __put_user((void __user *)current->sas_ss_sp,
 			  &frame->uc.uc_stack.ss_sp);
 	err |= __put_user(sas_ss_flags(rdusp()),
 			  &frame->uc.uc_stack.ss_flags);
@@ -893,8 +893,8 @@
 	err |= __put_user(frame->retcode, &frame->pretcode);
 	/* moveq #,d0; notb d0; trap #0 */
 	err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16),
-			  (long *)(frame->retcode + 0));
-	err |= __put_user(0x4e40, (short *)(frame->retcode + 4));
+			  (long __user *)(frame->retcode + 0));
+	err |= __put_user(0x4e40, (short __user *)(frame->retcode + 4));
 
 	if (err)
 		goto give_sigsegv;
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c
index 640895b..143c552 100644
--- a/arch/m68k/kernel/sys_m68k.c
+++ b/arch/m68k/kernel/sys_m68k.c
@@ -32,7 +32,7 @@
  * sys_pipe() is the normal C calling standard for creating
  * a pipe. It's not the way unix traditionally does this, though.
  */
-asmlinkage int sys_pipe(unsigned long * fildes)
+asmlinkage int sys_pipe(unsigned long __user * fildes)
 {
 	int fd[2];
 	int error;
@@ -94,7 +94,7 @@
 	unsigned long offset;
 };
 
-asmlinkage int old_mmap(struct mmap_arg_struct *arg)
+asmlinkage int old_mmap(struct mmap_arg_struct __user *arg)
 {
 	struct mmap_arg_struct a;
 	int error = -EFAULT;
@@ -160,11 +160,11 @@
 
 struct sel_arg_struct {
 	unsigned long n;
-	fd_set *inp, *outp, *exp;
-	struct timeval *tvp;
+	fd_set __user *inp, *outp, *exp;
+	struct timeval __user *tvp;
 };
 
-asmlinkage int old_select(struct sel_arg_struct *arg)
+asmlinkage int old_select(struct sel_arg_struct __user *arg)
 {
 	struct sel_arg_struct a;
 
@@ -180,7 +180,7 @@
  * This is really horribly ugly.
  */
 asmlinkage int sys_ipc (uint call, int first, int second,
-			int third, void *ptr, long fifth)
+			int third, void __user *ptr, long fifth)
 {
 	int version, ret;
 
@@ -190,14 +190,14 @@
 	if (call <= SEMCTL)
 		switch (call) {
 		case SEMOP:
-			return sys_semop (first, (struct sembuf *)ptr, second);
+			return sys_semop (first, ptr, second);
 		case SEMGET:
 			return sys_semget (first, second, third);
 		case SEMCTL: {
 			union semun fourth;
 			if (!ptr)
 				return -EINVAL;
-			if (get_user(fourth.__pad, (void **) ptr))
+			if (get_user(fourth.__pad, (void __user *__user *) ptr))
 				return -EFAULT;
 			return sys_semctl (first, second, third, fourth);
 			}
@@ -207,31 +207,26 @@
 	if (call <= MSGCTL)
 		switch (call) {
 		case MSGSND:
-			return sys_msgsnd (first, (struct msgbuf *) ptr,
-					  second, third);
+			return sys_msgsnd (first, ptr, second, third);
 		case MSGRCV:
 			switch (version) {
 			case 0: {
 				struct ipc_kludge tmp;
 				if (!ptr)
 					return -EINVAL;
-				if (copy_from_user (&tmp,
-						    (struct ipc_kludge *)ptr,
-						    sizeof (tmp)))
+				if (copy_from_user (&tmp, ptr, sizeof (tmp)))
 					return -EFAULT;
 				return sys_msgrcv (first, tmp.msgp, second,
 						   tmp.msgtyp, third);
 				}
 			default:
-				return sys_msgrcv (first,
-						   (struct msgbuf *) ptr,
+				return sys_msgrcv (first, ptr,
 						   second, fifth, third);
 			}
 		case MSGGET:
 			return sys_msgget ((key_t) first, second);
 		case MSGCTL:
-			return sys_msgctl (first, second,
-					   (struct msqid_ds *) ptr);
+			return sys_msgctl (first, second, ptr);
 		default:
 			return -ENOSYS;
 		}
@@ -241,20 +236,18 @@
 			switch (version) {
 			default: {
 				ulong raddr;
-				ret = do_shmat (first, (char *) ptr,
-						 second, &raddr);
+				ret = do_shmat (first, ptr, second, &raddr);
 				if (ret)
 					return ret;
-				return put_user (raddr, (ulong *) third);
+				return put_user (raddr, (ulong __user *) third);
 			}
 			}
 		case SHMDT:
-			return sys_shmdt ((char *)ptr);
+			return sys_shmdt (ptr);
 		case SHMGET:
 			return sys_shmget (first, second, third);
 		case SHMCTL:
-			return sys_shmctl (first, second,
-					   (struct shmid_ds *) ptr);
+			return sys_shmctl (first, second, ptr);
 		default:
 			return -ENOSYS;
 		}
diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c
index deb36e8..cdf58fb 100644
--- a/arch/m68k/kernel/traps.c
+++ b/arch/m68k/kernel/traps.c
@@ -169,25 +169,25 @@
 
 	if (CPU_IS_060 && !FPU_IS_EMU) {
 		/* set up IFPSP entry points */
-		asmlinkage void snan_vec(void) asm ("_060_fpsp_snan");
-		asmlinkage void operr_vec(void) asm ("_060_fpsp_operr");
-		asmlinkage void ovfl_vec(void) asm ("_060_fpsp_ovfl");
-		asmlinkage void unfl_vec(void) asm ("_060_fpsp_unfl");
-		asmlinkage void dz_vec(void) asm ("_060_fpsp_dz");
-		asmlinkage void inex_vec(void) asm ("_060_fpsp_inex");
-		asmlinkage void fline_vec(void) asm ("_060_fpsp_fline");
-		asmlinkage void unsupp_vec(void) asm ("_060_fpsp_unsupp");
-		asmlinkage void effadd_vec(void) asm ("_060_fpsp_effadd");
+		asmlinkage void snan_vec6(void) asm ("_060_fpsp_snan");
+		asmlinkage void operr_vec6(void) asm ("_060_fpsp_operr");
+		asmlinkage void ovfl_vec6(void) asm ("_060_fpsp_ovfl");
+		asmlinkage void unfl_vec6(void) asm ("_060_fpsp_unfl");
+		asmlinkage void dz_vec6(void) asm ("_060_fpsp_dz");
+		asmlinkage void inex_vec6(void) asm ("_060_fpsp_inex");
+		asmlinkage void fline_vec6(void) asm ("_060_fpsp_fline");
+		asmlinkage void unsupp_vec6(void) asm ("_060_fpsp_unsupp");
+		asmlinkage void effadd_vec6(void) asm ("_060_fpsp_effadd");
 
-		vectors[VEC_FPNAN] = snan_vec;
-		vectors[VEC_FPOE] = operr_vec;
-		vectors[VEC_FPOVER] = ovfl_vec;
-		vectors[VEC_FPUNDER] = unfl_vec;
-		vectors[VEC_FPDIVZ] = dz_vec;
-		vectors[VEC_FPIR] = inex_vec;
-		vectors[VEC_LINE11] = fline_vec;
-		vectors[VEC_FPUNSUP] = unsupp_vec;
-		vectors[VEC_UNIMPEA] = effadd_vec;
+		vectors[VEC_FPNAN] = snan_vec6;
+		vectors[VEC_FPOE] = operr_vec6;
+		vectors[VEC_FPOVER] = ovfl_vec6;
+		vectors[VEC_FPUNDER] = unfl_vec6;
+		vectors[VEC_FPDIVZ] = dz_vec6;
+		vectors[VEC_FPIR] = inex_vec6;
+		vectors[VEC_LINE11] = fline_vec6;
+		vectors[VEC_FPUNSUP] = unsupp_vec6;
+		vectors[VEC_UNIMPEA] = effadd_vec6;
 	}
 
         /* if running on an amiga, make the NMI interrupt do nothing */
diff --git a/arch/m68k/kernel/vmlinux-std.lds b/arch/m68k/kernel/vmlinux-std.lds
index e58654f..69d1d3d 100644
--- a/arch/m68k/kernel/vmlinux-std.lds
+++ b/arch/m68k/kernel/vmlinux-std.lds
@@ -13,6 +13,7 @@
   .text : {
 	*(.text)
 	SCHED_TEXT
+	LOCK_TEXT
 	*(.fixup)
 	*(.gnu.warning)
 	} :text = 0x4e75
diff --git a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds
index cc37e8d..65cc39c 100644
--- a/arch/m68k/kernel/vmlinux-sun3.lds
+++ b/arch/m68k/kernel/vmlinux-sun3.lds
@@ -14,6 +14,7 @@
 	*(.head)
 	*(.text)
 	SCHED_TEXT
+	LOCK_TEXT
 	*(.fixup)
 	*(.gnu.warning)
 	} :text = 0x4e75
@@ -66,7 +67,7 @@
 	__initramfs_end = .;
 	. = ALIGN(8192);
 	__init_end = .;
-	.init.task : { *(init_task) }
+	.data.init.task : { *(.data.init_task) }
 
 
   .bss : { *(.bss) }		/* BSS */
diff --git a/arch/m68k/lib/checksum.c b/arch/m68k/lib/checksum.c
index 4a5c544..cb13c6e 100644
--- a/arch/m68k/lib/checksum.c
+++ b/arch/m68k/lib/checksum.c
@@ -134,7 +134,7 @@
  */
 
 unsigned int
-csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst,
+csum_partial_copy_from_user(const unsigned char __user *src, unsigned char *dst,
 			    int len, int sum, int *csum_err)
 {
 	/*
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index cd19cbb..14f8d3f4 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -212,9 +212,6 @@
 	mach_reset           = mac_reset;
 	mach_halt            = mac_poweroff;
 	mach_power_off       = mac_poweroff;
-#ifdef CONFIG_DUMMY_CONSOLE
-	conswitchp	         = &dummy_con;
-#endif
 	mach_max_dma_address = 0xffffffff;
 #if 0
 	mach_debug_init	 = mac_debug_init;
diff --git a/arch/m68k/mac/iop.c b/arch/m68k/mac/iop.c
index d889ba8..9179a37 100644
--- a/arch/m68k/mac/iop.c
+++ b/arch/m68k/mac/iop.c
@@ -293,8 +293,8 @@
 	}
 
 	for (i = 0 ; i < NUM_IOP_CHAN ; i++) {
-		iop_send_queue[IOP_NUM_SCC][i] = 0;
-		iop_send_queue[IOP_NUM_ISM][i] = 0;
+		iop_send_queue[IOP_NUM_SCC][i] = NULL;
+		iop_send_queue[IOP_NUM_ISM][i] = NULL;
 		iop_listeners[IOP_NUM_SCC][i].devname = NULL;
 		iop_listeners[IOP_NUM_SCC][i].handler = NULL;
 		iop_listeners[IOP_NUM_ISM][i].devname = NULL;
diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c
index 5b80d7c..bbb0c3b 100644
--- a/arch/m68k/mac/misc.c
+++ b/arch/m68k/mac/misc.c
@@ -39,72 +39,163 @@
 extern struct mac_booter_data mac_bi_data;
 static void (*rom_reset)(void);
 
-#ifdef CONFIG_ADB
-/*
- * Return the current time as the number of seconds since January 1, 1904.
- */
-
-static long adb_read_time(void)
+#ifdef CONFIG_ADB_CUDA
+static long cuda_read_time(void)
 {
-	volatile struct adb_request req;
+	struct adb_request req;
 	long time;
 
-	adb_request((struct adb_request *) &req, NULL,
-			ADBREQ_RAW|ADBREQ_SYNC,
-			2, CUDA_PACKET, CUDA_GET_TIME);
+	if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0)
+		return 0;
+	while (!req.complete)
+		cuda_poll();
 
 	time = (req.reply[3] << 24) | (req.reply[4] << 16)
 		| (req.reply[5] << 8) | req.reply[6];
 	return time - RTC_OFFSET;
 }
 
-/*
- * Set the current system time
- */
-
-static void adb_write_time(long data)
+static void cuda_write_time(long data)
 {
-	volatile struct adb_request req;
-
+	struct adb_request req;
 	data += RTC_OFFSET;
+	if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME,
+			(data >> 24) & 0xFF, (data >> 16) & 0xFF,
+			(data >> 8) & 0xFF, data & 0xFF) < 0)
+		return;
+	while (!req.complete)
+		cuda_poll();
+}
 
-	adb_request((struct adb_request *) &req, NULL,
-			ADBREQ_RAW|ADBREQ_SYNC,
-			6, CUDA_PACKET, CUDA_SET_TIME,
+static __u8 cuda_read_pram(int offset)
+{
+	struct adb_request req;
+	if (cuda_request(&req, NULL, 4, CUDA_PACKET, CUDA_GET_PRAM,
+			(offset >> 8) & 0xFF, offset & 0xFF) < 0)
+		return 0;
+	while (!req.complete)
+		cuda_poll();
+	return req.reply[3];
+}
+
+static void cuda_write_pram(int offset, __u8 data)
+{
+	struct adb_request req;
+	if (cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_SET_PRAM,
+			(offset >> 8) & 0xFF, offset & 0xFF, data) < 0)
+		return;
+	while (!req.complete)
+		cuda_poll();
+}
+#else
+#define cuda_read_time() 0
+#define cuda_write_time(n)
+#define cuda_read_pram NULL
+#define cuda_write_pram NULL
+#endif
+
+#ifdef CONFIG_ADB_PMU68K
+static long pmu_read_time(void)
+{
+	struct adb_request req;
+	long time;
+
+	if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
+		return 0;
+	while (!req.complete)
+		pmu_poll();
+
+	time = (req.reply[0] << 24) | (req.reply[1] << 16)
+		| (req.reply[2] << 8) | req.reply[3];
+	return time - RTC_OFFSET;
+}
+
+static void pmu_write_time(long data)
+{
+	struct adb_request req;
+	data += RTC_OFFSET;
+	if (pmu_request(&req, NULL, 5, PMU_SET_RTC,
+			(data >> 24) & 0xFF, (data >> 16) & 0xFF,
+			(data >> 8) & 0xFF, data & 0xFF) < 0)
+		return;
+	while (!req.complete)
+		pmu_poll();
+}
+
+static __u8 pmu_read_pram(int offset)
+{
+	struct adb_request req;
+	if (pmu_request(&req, NULL, 3, PMU_READ_NVRAM,
+			(offset >> 8) & 0xFF, offset & 0xFF) < 0)
+		return 0;
+	while (!req.complete)
+		pmu_poll();
+	return req.reply[3];
+}
+
+static void pmu_write_pram(int offset, __u8 data)
+{
+	struct adb_request req;
+	if (pmu_request(&req, NULL, 4, PMU_WRITE_NVRAM,
+			(offset >> 8) & 0xFF, offset & 0xFF, data) < 0)
+		return;
+	while (!req.complete)
+		pmu_poll();
+}
+#else
+#define pmu_read_time() 0
+#define pmu_write_time(n)
+#define pmu_read_pram NULL
+#define pmu_write_pram NULL
+#endif
+
+#ifdef CONFIG_ADB_MACIISI
+extern int maciisi_request(struct adb_request *req,
+			void (*done)(struct adb_request *), int nbytes, ...);
+
+static long maciisi_read_time(void)
+{
+	struct adb_request req;
+	long time;
+
+	if (maciisi_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME))
+		return 0;
+
+	time = (req.reply[3] << 24) | (req.reply[4] << 16)
+		| (req.reply[5] << 8) | req.reply[6];
+	return time - RTC_OFFSET;
+}
+
+static void maciisi_write_time(long data)
+{
+	struct adb_request req;
+	data += RTC_OFFSET;
+	maciisi_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME,
 			(data >> 24) & 0xFF, (data >> 16) & 0xFF,
 			(data >> 8) & 0xFF, data & 0xFF);
 }
 
-/*
- * Get a byte from the NVRAM
- */
-
-static __u8 adb_read_pram(int offset)
+static __u8 maciisi_read_pram(int offset)
 {
-	volatile struct adb_request req;
-
-	adb_request((struct adb_request *) &req, NULL,
-			ADBREQ_RAW|ADBREQ_SYNC,
-			4, CUDA_PACKET, CUDA_GET_PRAM,
-			(offset >> 8) & 0xFF, offset & 0xFF);
+	struct adb_request req;
+	if (maciisi_request(&req, NULL, 4, CUDA_PACKET, CUDA_GET_PRAM,
+			(offset >> 8) & 0xFF, offset & 0xFF))
+		return 0;
 	return req.reply[3];
 }
 
-/*
- * Write a byte to the NVRAM
- */
-
-static void adb_write_pram(int offset, __u8 data)
+static void maciisi_write_pram(int offset, __u8 data)
 {
-	volatile struct adb_request req;
-
-	adb_request((struct adb_request *) &req, NULL,
-			ADBREQ_RAW|ADBREQ_SYNC,
-			5, CUDA_PACKET, CUDA_SET_PRAM,
-			(offset >> 8) & 0xFF, offset & 0xFF,
-			data);
+	struct adb_request req;
+	maciisi_request(&req, NULL, 5, CUDA_PACKET, CUDA_SET_PRAM,
+			(offset >> 8) & 0xFF, offset & 0xFF, data);
 }
-#endif /* CONFIG_ADB */
+#else
+#define maciisi_read_time() 0
+#define maciisi_write_time(n)
+#define maciisi_read_pram NULL
+#define maciisi_write_pram NULL
+#endif
 
 /*
  * VIA PRAM/RTC access routines
@@ -305,42 +396,55 @@
 
 static void cuda_restart(void)
 {
-	adb_request(NULL, NULL, ADBREQ_RAW|ADBREQ_SYNC,
-			2, CUDA_PACKET, CUDA_RESET_SYSTEM);
+	struct adb_request req;
+	if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_RESET_SYSTEM) < 0)
+		return;
+	while (!req.complete)
+		cuda_poll();
 }
 
 static void cuda_shutdown(void)
 {
-	adb_request(NULL, NULL, ADBREQ_RAW|ADBREQ_SYNC,
-			2, CUDA_PACKET, CUDA_POWERDOWN);
+	struct adb_request req;
+	if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_POWERDOWN) < 0)
+		return;
+	while (!req.complete)
+		cuda_poll();
 }
 
 #endif /* CONFIG_ADB_CUDA */
 
-#ifdef CONFIG_ADB_PMU
+#ifdef CONFIG_ADB_PMU68K
 
 void pmu_restart(void)
 {
-	adb_request(NULL, NULL, ADBREQ_RAW|ADBREQ_SYNC,
-			3, PMU_PACKET, PMU_SET_INTR_MASK,
-			PMU_INT_ADB|PMU_INT_TICK);
-
-	adb_request(NULL, NULL, ADBREQ_RAW|ADBREQ_SYNC,
-			2, PMU_PACKET, PMU_RESET);
+	struct adb_request req;
+	if (pmu_request(&req, NULL,
+			2, PMU_SET_INTR_MASK, PMU_INT_ADB|PMU_INT_TICK) < 0)
+		return;
+	while (!req.complete)
+		pmu_poll();
+	if (pmu_request(&req, NULL, 1, PMU_RESET) < 0)
+		return;
+	while (!req.complete)
+		pmu_poll();
 }
 
 void pmu_shutdown(void)
 {
-	adb_request(NULL, NULL, ADBREQ_RAW|ADBREQ_SYNC,
-			3, PMU_PACKET, PMU_SET_INTR_MASK,
-			PMU_INT_ADB|PMU_INT_TICK);
-
-	adb_request(NULL, NULL, ADBREQ_RAW|ADBREQ_SYNC,
-			6, PMU_PACKET, PMU_SHUTDOWN,
-			'M', 'A', 'T', 'T');
+	struct adb_request req;
+	if (pmu_request(&req, NULL,
+			2, PMU_SET_INTR_MASK, PMU_INT_ADB|PMU_INT_TICK) < 0)
+		return;
+	while (!req.complete)
+		pmu_poll();
+	if (pmu_request(&req, NULL, 5, PMU_SHUTDOWN, 'M', 'A', 'T', 'T') < 0)
+		return;
+	while (!req.complete)
+		pmu_poll();
 }
 
-#endif /* CONFIG_ADB_PMU */
+#endif
 
 /*
  *-------------------------------------------------------------------
@@ -351,21 +455,22 @@
 
 void mac_pram_read(int offset, __u8 *buffer, int len)
 {
-	__u8 (*func)(int) = NULL;
+	__u8 (*func)(int);
 	int i;
 
-	if (macintosh_config->adb_type == MAC_ADB_IISI ||
-	    macintosh_config->adb_type == MAC_ADB_PB1 ||
-	    macintosh_config->adb_type == MAC_ADB_PB2 ||
-	    macintosh_config->adb_type == MAC_ADB_CUDA) {
-#ifdef CONFIG_ADB
-		func = adb_read_pram;
-#else
-		return;
-#endif
-	} else {
+	switch(macintosh_config->adb_type) {
+	case MAC_ADB_IISI:
+		func = maciisi_read_pram; break;
+	case MAC_ADB_PB1:
+	case MAC_ADB_PB2:
+		func = pmu_read_pram; break;
+	case MAC_ADB_CUDA:
+		func = cuda_read_pram; break;
+	default:
 		func = via_read_pram;
 	}
+	if (!func)
+		return;
 	for (i = 0 ; i < len ; i++) {
 		buffer[i] = (*func)(offset++);
 	}
@@ -373,21 +478,22 @@
 
 void mac_pram_write(int offset, __u8 *buffer, int len)
 {
-	void (*func)(int, __u8) = NULL;
+	void (*func)(int, __u8);
 	int i;
 
-	if (macintosh_config->adb_type == MAC_ADB_IISI ||
-	    macintosh_config->adb_type == MAC_ADB_PB1 ||
-	    macintosh_config->adb_type == MAC_ADB_PB2 ||
-	    macintosh_config->adb_type == MAC_ADB_CUDA) {
-#ifdef CONFIG_ADB
-		func = adb_write_pram;
-#else
-		return;
-#endif
-	} else {
+	switch(macintosh_config->adb_type) {
+	case MAC_ADB_IISI:
+		func = maciisi_write_pram; break;
+	case MAC_ADB_PB1:
+	case MAC_ADB_PB2:
+		func = pmu_write_pram; break;
+	case MAC_ADB_CUDA:
+		func = cuda_write_pram; break;
+	default:
 		func = via_write_pram;
 	}
+	if (!func)
+		return;
 	for (i = 0 ; i < len ; i++) {
 		(*func)(offset++, buffer[i]);
 	}
@@ -408,7 +514,7 @@
 	} else if (macintosh_config->adb_type == MAC_ADB_CUDA) {
 		cuda_shutdown();
 #endif
-#ifdef CONFIG_ADB_PMU
+#ifdef CONFIG_ADB_PMU68K
 	} else if (macintosh_config->adb_type == MAC_ADB_PB1
 		|| macintosh_config->adb_type == MAC_ADB_PB2) {
 		pmu_shutdown();
@@ -448,7 +554,7 @@
 	} else if (macintosh_config->adb_type == MAC_ADB_CUDA) {
 		cuda_restart();
 #endif
-#ifdef CONFIG_ADB_PMU
+#ifdef CONFIG_ADB_PMU68K
 	} else if (macintosh_config->adb_type == MAC_ADB_PB1
 		|| macintosh_config->adb_type == MAC_ADB_PB2) {
 		pmu_restart();
@@ -466,12 +572,13 @@
 		/* make a 1-to-1 mapping, using the transparent tran. reg. */
 		unsigned long virt = (unsigned long) mac_reset;
 		unsigned long phys = virt_to_phys(mac_reset);
+		unsigned long addr = (phys&0xFF000000)|0x8777;
 		unsigned long offset = phys-virt;
 		local_irq_disable(); /* lets not screw this up, ok? */
 		__asm__ __volatile__(".chip 68030\n\t"
 				     "pmove %0,%/tt0\n\t"
 				     ".chip 68k"
-				     : : "m" ((phys&0xFF000000)|0x8777));
+				     : : "m" (addr));
 		/* Now jump to physical address so we can disable MMU */
 		__asm__ __volatile__(
                     ".chip 68030\n\t"
@@ -588,20 +695,22 @@
 	unsigned long now;
 
 	if (!op) { /* read */
-		if (macintosh_config->adb_type == MAC_ADB_II) {
+		switch (macintosh_config->adb_type) {
+		case MAC_ADB_II:
+		case MAC_ADB_IOP:
 			now = via_read_time();
-		} else
-#ifdef CONFIG_ADB
-		if ((macintosh_config->adb_type == MAC_ADB_IISI) ||
-			   (macintosh_config->adb_type == MAC_ADB_PB1) ||
-			   (macintosh_config->adb_type == MAC_ADB_PB2) ||
-			   (macintosh_config->adb_type == MAC_ADB_CUDA)) {
-			now = adb_read_time();
-		} else
-#endif
-		if (macintosh_config->adb_type == MAC_ADB_IOP) {
-			now = via_read_time();
-		} else {
+			break;
+		case MAC_ADB_IISI:
+			now = maciisi_read_time();
+			break;
+		case MAC_ADB_PB1:
+		case MAC_ADB_PB2:
+			now = pmu_read_time();
+			break;
+		case MAC_ADB_CUDA:
+			now = cuda_read_time();
+			break;
+		default:
 			now = 0;
 		}
 
@@ -619,15 +728,20 @@
 		now = mktime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
 			     t->tm_hour, t->tm_min, t->tm_sec);
 
-		if (macintosh_config->adb_type == MAC_ADB_II) {
+		switch (macintosh_config->adb_type) {
+		case MAC_ADB_II:
+		case MAC_ADB_IOP:
 			via_write_time(now);
-		} else if ((macintosh_config->adb_type == MAC_ADB_IISI) ||
-			   (macintosh_config->adb_type == MAC_ADB_PB1) ||
-			   (macintosh_config->adb_type == MAC_ADB_PB2) ||
-			   (macintosh_config->adb_type == MAC_ADB_CUDA)) {
-			adb_write_time(now);
-		} else if (macintosh_config->adb_type == MAC_ADB_IOP) {
-			via_write_time(now);
+			break;
+		case MAC_ADB_CUDA:
+			cuda_write_time(now);
+			break;
+		case MAC_ADB_PB1:
+		case MAC_ADB_PB2:
+			pmu_write_time(now);
+			break;
+		case MAC_ADB_IISI:
+			maciisi_write_time(now);
 		}
 #endif
 	}
diff --git a/arch/m68k/math-emu/multi_arith.h b/arch/m68k/math-emu/multi_arith.h
index 02251e5..4ad0ca9 100644
--- a/arch/m68k/math-emu/multi_arith.h
+++ b/arch/m68k/math-emu/multi_arith.h
@@ -366,7 +366,7 @@
 
 #define fp_mul64(desth, destl, src1, src2) ({				\
 	asm ("mulu.l %2,%1:%0" : "=d" (destl), "=d" (desth)		\
-		: "g" (src1), "0" (src2));				\
+		: "dm" (src1), "0" (src2));				\
 })
 #define fp_div64(quot, rem, srch, srcl, div)				\
 	asm ("divu.l %2,%1:%0" : "=d" (quot), "=d" (rem)		\
diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c
index fe2383e..85ad19a 100644
--- a/arch/m68k/mm/kmap.c
+++ b/arch/m68k/mm/kmap.c
@@ -102,7 +102,7 @@
  */
 /* Rewritten by Andreas Schwab to remove all races. */
 
-void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
+void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
 {
 	struct vm_struct *area;
 	unsigned long virtaddr, retaddr;
@@ -121,7 +121,7 @@
 	if (MACH_IS_AMIGA) {
 		if ((physaddr >= 0x40000000) && (physaddr + size < 0x60000000)
 		    && (cacheflag == IOMAP_NOCACHE_SER))
-			return (void *)physaddr;
+			return (void __iomem *)physaddr;
 	}
 #endif
 
@@ -218,21 +218,21 @@
 #endif
 	flush_tlb_all();
 
-	return (void *)retaddr;
+	return (void __iomem *)retaddr;
 }
 
 /*
  * Unmap a ioremap()ed region again
  */
-void iounmap(void *addr)
+void iounmap(void __iomem *addr)
 {
 #ifdef CONFIG_AMIGA
 	if ((!MACH_IS_AMIGA) ||
 	    (((unsigned long)addr < 0x40000000) ||
 	     ((unsigned long)addr > 0x60000000)))
-			free_io_area(addr);
+			free_io_area((__force void *)addr);
 #else
-	free_io_area(addr);
+	free_io_area((__force void *)addr);
 #endif
 }
 
diff --git a/arch/m68k/mvme16x/rtc.c b/arch/m68k/mvme16x/rtc.c
index 30f5921..a69fe30 100644
--- a/arch/m68k/mvme16x/rtc.c
+++ b/arch/m68k/mvme16x/rtc.c
@@ -45,6 +45,7 @@
 	volatile MK48T08ptr_t rtc = (MK48T08ptr_t)MVME_RTC_BASE;
 	unsigned long flags;
 	struct rtc_time wtime;
+	void __user *argp = (void __user *)arg;
 
 	switch (cmd) {
 	case RTC_RD_TIME:	/* Read the time/date from RTC	*/
@@ -64,7 +65,7 @@
 		wtime.tm_wday = BCD2BIN(rtc->bcd_dow)-1;
 		rtc->ctrl = 0;
 		local_irq_restore(flags);
-		return copy_to_user((void *)arg, &wtime, sizeof wtime) ?
+		return copy_to_user(argp, &wtime, sizeof wtime) ?
 								-EFAULT : 0;
 	}
 	case RTC_SET_TIME:	/* Set the RTC */
@@ -76,8 +77,7 @@
 		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
 
-		if (copy_from_user(&rtc_tm, (struct rtc_time*)arg,
-				   sizeof(struct rtc_time)))
+		if (copy_from_user(&rtc_tm, argp, sizeof(struct rtc_time)))
 			return -EFAULT;
 
 		yrs = rtc_tm.tm_year;
diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c
index 02b626bae..5e0f9b0 100644
--- a/arch/m68k/q40/config.c
+++ b/arch/m68k/q40/config.c
@@ -36,8 +36,6 @@
 #include <asm/machdep.h>
 #include <asm/q40_master.h>
 
-extern void floppy_setup(char *str, int *ints);
-
 extern irqreturn_t q40_process_int (int level, struct pt_regs *regs);
 extern irqreturn_t (*q40_default_handler[]) (int, void *, struct pt_regs *);  /* added just for debugging */
 extern void q40_init_IRQ (void);
@@ -194,9 +192,6 @@
     mach_heartbeat = q40_heartbeat;
 #endif
     mach_halt = q40_halt;
-#ifdef CONFIG_DUMMY_CONSOLE
-    conswitchp = &dummy_con;
-#endif
 
     /* disable a few things that SMSQ might have left enabled */
     q40_disable_irqs();
diff --git a/arch/m68k/sun3/config.c b/arch/m68k/sun3/config.c
index 77d05bc..f1ca0df 100644
--- a/arch/m68k/sun3/config.c
+++ b/arch/m68k/sun3/config.c
@@ -160,9 +160,6 @@
 	mach_hwclk           =  sun3_hwclk;
 	mach_halt	     =  sun3_halt;
 	mach_get_hardware_list = sun3_get_hardware_list;
-#if defined(CONFIG_DUMMY_CONSOLE)
-	conswitchp	     = &dummy_con;
-#endif
 
 	memory_start = ((((int)&_end) + 0x2000) & ~0x1fff);
 // PROM seems to want the last couple of physical pages. --m
diff --git a/arch/m68k/sun3x/config.c b/arch/m68k/sun3x/config.c
index 0ef547f..0920f5d 100644
--- a/arch/m68k/sun3x/config.c
+++ b/arch/m68k/sun3x/config.c
@@ -71,10 +71,6 @@
 	mach_get_model       = sun3_get_model;
 	mach_get_hardware_list = sun3x_get_hardware_list;
 
-#ifdef CONFIG_DUMMY_CONSOLE
-	conswitchp	     = &dummy_con;
-#endif
-
 	sun3_intreg = (unsigned char *)SUN3X_INTREG;
 
 	/* only the serial console is known to work anyway... */
diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c
index 8b3cf57..99bf438 100644
--- a/arch/m68knommu/kernel/process.c
+++ b/arch/m68knommu/kernel/process.c
@@ -198,10 +198,9 @@
 {
 	struct pt_regs * childregs;
 	struct switch_stack * childstack, *stack;
-	unsigned long stack_offset, *retp;
+	unsigned long *retp;
 
-	stack_offset = THREAD_SIZE - sizeof(struct pt_regs);
-	childregs = (struct pt_regs *) ((unsigned long) p->thread_info + stack_offset);
+	childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;
 
 	*childregs = *regs;
 	childregs->d0 = 0;
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 0476a4d..fa98f10 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -140,12 +140,12 @@
 int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
 	unsigned long unused, struct task_struct *p, struct pt_regs *regs)
 {
-	struct thread_info *ti = p->thread_info;
+	struct thread_info *ti = task_thread_info(p);
 	struct pt_regs *childregs;
 	long childksp;
 	p->set_child_tid = p->clear_child_tid = NULL;
 
-	childksp = (unsigned long)ti + THREAD_SIZE - 32;
+	childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE - 32;
 
 	preempt_disable();
 
@@ -229,9 +229,7 @@
 
 int dump_task_regs (struct task_struct *tsk, elf_gregset_t *regs)
 {
-	struct thread_info *ti = tsk->thread_info;
-	long ksp = (unsigned long)ti + THREAD_SIZE - 32;
-	elf_dump_regs(&(*regs)[0], (struct pt_regs *) ksp - 1);
+	elf_dump_regs(*regs, task_pt_regs(tsk));
 	return 1;
 }
 
@@ -409,7 +407,7 @@
 	if (!p || p == current || p->state == TASK_RUNNING)
 		return 0;
 
-	stack_page = (unsigned long)p->thread_info;
+	stack_page = (unsigned long)task_stack_page(p);
 	if (!stack_page || !mips_frame_info_initialized)
 		return 0;
 
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 8d25493..f838b36 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -64,8 +64,7 @@
 	if (!access_ok(VERIFY_WRITE, data, 38 * 8))
 		return -EIO;
 
-	regs = (struct pt_regs *) ((unsigned long) child->thread_info +
-	       THREAD_SIZE - 32 - sizeof(struct pt_regs));
+	regs = task_pt_regs(child);
 
 	for (i = 0; i < 32; i++)
 		__put_user (regs->regs[i], data + i);
@@ -92,8 +91,7 @@
 	if (!access_ok(VERIFY_READ, data, 38 * 8))
 		return -EIO;
 
-	regs = (struct pt_regs *) ((unsigned long) child->thread_info +
-	       THREAD_SIZE - 32 - sizeof(struct pt_regs));
+	regs = task_pt_regs(child);
 
 	for (i = 0; i < 32; i++)
 		__get_user (regs->regs[i], data + i);
@@ -198,8 +196,7 @@
 		struct pt_regs *regs;
 		unsigned long tmp = 0;
 
-		regs = (struct pt_regs *) ((unsigned long) child->thread_info +
-		       THREAD_SIZE - 32 - sizeof(struct pt_regs));
+		regs = task_pt_regs(child);
 		ret = 0;  /* Default return value. */
 
 		switch (addr) {
@@ -314,8 +311,7 @@
 	case PTRACE_POKEUSR: {
 		struct pt_regs *regs;
 		ret = 0;
-		regs = (struct pt_regs *) ((unsigned long) child->thread_info +
-		       THREAD_SIZE - 32 - sizeof(struct pt_regs));
+		regs = task_pt_regs(child);
 
 		switch (addr) {
 		case 0 ... 31:
@@ -442,7 +438,7 @@
 		break;
 
 	case PTRACE_GET_THREAD_AREA:
-		ret = put_user(child->thread_info->tp_value,
+		ret = put_user(task_thread_info(child)->tp_value,
 				(unsigned long __user *) data);
 		break;
 
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
index 1f998bf..0c82b25 100644
--- a/arch/mips/kernel/ptrace32.c
+++ b/arch/mips/kernel/ptrace32.c
@@ -126,8 +126,7 @@
 		struct pt_regs *regs;
 		unsigned int tmp;
 
-		regs = (struct pt_regs *) ((unsigned long) child->thread_info +
-		       THREAD_SIZE - 32 - sizeof(struct pt_regs));
+		regs = task_pt_regs(child);
 		ret = 0;  /* Default return value. */
 
 		switch (addr) {
@@ -259,8 +258,7 @@
 	case PTRACE_POKEUSR: {
 		struct pt_regs *regs;
 		ret = 0;
-		regs = (struct pt_regs *) ((unsigned long) child->thread_info +
-		       THREAD_SIZE - 32 - sizeof(struct pt_regs));
+		regs = task_pt_regs(child);
 
 		switch (addr) {
 		case 0 ... 31:
@@ -377,7 +375,7 @@
 		break;
 
 	case PTRACE_GET_THREAD_AREA:
-		ret = put_user(child->thread_info->tp_value,
+		ret = put_user(task_thread_info(child)->tp_value,
 				(unsigned int __user *) (unsigned long) data);
 		break;
 
@@ -391,7 +389,7 @@
 		break;
 
 	case PTRACE_GET_THREAD_AREA_3264:
-		ret = put_user(child->thread_info->tp_value,
+		ret = put_user(task_thread_info(child)->tp_value,
 				(unsigned long __user *) (unsigned long) data);
 		break;
 
diff --git a/arch/mips/kernel/smp_mt.c b/arch/mips/kernel/smp_mt.c
index d429544..794a1c3 100644
--- a/arch/mips/kernel/smp_mt.c
+++ b/arch/mips/kernel/smp_mt.c
@@ -287,6 +287,7 @@
  */
 void prom_boot_secondary(int cpu, struct task_struct *idle)
 {
+	struct thread_info *gp = task_thread_info(idle);
 	dvpe();
 	set_c0_mvpcontrol(MVPCONTROL_VPC);
 
@@ -307,11 +308,9 @@
 	write_tc_gpr_sp( __KSTK_TOS(idle));
 
 	/* global pointer */
-	write_tc_gpr_gp((unsigned long)idle->thread_info);
+	write_tc_gpr_gp((unsigned long)gp);
 
-	flush_icache_range((unsigned long)idle->thread_info,
-					   (unsigned long)idle->thread_info +
-					   sizeof(struct thread_info));
+	flush_icache_range((unsigned long)gp, (unsigned long)(gp + 1));
 
 	/* finally out of configuration and into chaos */
 	clear_c0_mvpcontrol(MVPCONTROL_VPC);
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 0068819..3323584 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -263,7 +263,7 @@
 
 void sys_set_thread_area(unsigned long addr)
 {
-	struct thread_info *ti = current->thread_info;
+	struct thread_info *ti = task_thread_info(current);
 
 	ti->tp_value = addr;
 
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 7058893..59a1879 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -519,7 +519,7 @@
  */
 static inline int simulate_rdhwr(struct pt_regs *regs)
 {
-	struct thread_info *ti = current->thread_info;
+	struct thread_info *ti = task_thread_info(current);
 	unsigned int opcode;
 
 	if (unlikely(get_insn_opcode(regs, &opcode)))
diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c
index 0527170..f17f575 100644
--- a/arch/mips/pmc-sierra/yosemite/smp.c
+++ b/arch/mips/pmc-sierra/yosemite/smp.c
@@ -93,8 +93,8 @@
  */
 void prom_boot_secondary(int cpu, struct task_struct *idle)
 {
-	unsigned long gp = (unsigned long) idle->thread_info;
-	unsigned long sp = gp + THREAD_SIZE - 32;
+	unsigned long gp = (unsigned long) task_thread_info(idle);
+	unsigned long sp = __KSTK_TOP(idle);
 
 	secondary_sp = sp;
 	secondary_gp = gp;
diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c
index 3a8291b..dbef3f6 100644
--- a/arch/mips/sgi-ip27/ip27-smp.c
+++ b/arch/mips/sgi-ip27/ip27-smp.c
@@ -168,8 +168,8 @@
  */
 void __init prom_boot_secondary(int cpu, struct task_struct *idle)
 {
-	unsigned long gp = (unsigned long) idle->thread_info;
-	unsigned long sp = gp + THREAD_SIZE - 32;
+	unsigned long gp = (unsigned long)task_thread_info(idle);
+	unsigned long sp = __KSTK_TOS(idle);
 
 	LAUNCH_SLAVE(cputonasid(cpu),cputoslice(cpu),
 		(launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap),
diff --git a/arch/mips/sibyte/cfe/smp.c b/arch/mips/sibyte/cfe/smp.c
index e848512..4477af3 100644
--- a/arch/mips/sibyte/cfe/smp.c
+++ b/arch/mips/sibyte/cfe/smp.c
@@ -60,7 +60,7 @@
 
 	retval = cfe_cpu_start(cpu_logical_map(cpu), &smp_bootstrap,
 			       __KSTK_TOS(idle),
-			       (unsigned long)idle->thread_info, 0);
+			       (unsigned long)task_thread_info(idle), 0);
 	if (retval != 0)
 		printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);
 }
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 4eb70a4..5da4167 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -295,7 +295,7 @@
 	    struct task_struct * p, struct pt_regs * pregs)
 {
 	struct pt_regs * cregs = &(p->thread.regs);
-	struct thread_info *ti = p->thread_info;
+	void *stack = task_stack_page(p);
 	
 	/* We have to use void * instead of a function pointer, because
 	 * function pointers aren't a pointer to the function on 64-bit.
@@ -322,7 +322,7 @@
 	 */
 	if (usp == 1) {
 		/* kernel thread */
-		cregs->ksp = (((unsigned long)(ti)) + THREAD_SZ_ALGN);
+		cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN;
 		/* Must exit via ret_from_kernel_thread in order
 		 * to call schedule_tail()
 		 */
@@ -344,7 +344,7 @@
 		 */
 
 		/* Use same stack depth as parent */
-		cregs->ksp = ((unsigned long)(ti))
+		cregs->ksp = (unsigned long)stack
 			+ (pregs->gr[21] & (THREAD_SIZE - 1));
 		cregs->gr[30] = usp;
 		if (p->personality == PER_HPUX) {
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 17f23c2..25564b7 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -517,7 +517,7 @@
 	if (IS_ERR(idle))
 		panic("SMP: fork failed for CPU:%d", cpuid);
 
-	idle->thread_info->cpu = cpuid;
+	task_thread_info(idle)->cpu = cpuid;
 
 	/* Let _start know what logical CPU we're booting
 	** (offset into init_tasks[],cpu_data[])
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index bbfa1bd..a94699d 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -11,7 +11,8 @@
 endif
 
 obj-y				:= semaphore.o cputable.o ptrace.o syscalls.o \
-				   irq.o align.o signal_32.o pmc.o vdso.o
+				   irq.o align.o signal_32.o pmc.o vdso.o \
+				   init_task.o process.o
 obj-y				+= vdso32/
 obj-$(CONFIG_PPC64)		+= setup_64.o binfmt_elf32.o sys_ppc32.o \
 				   signal_64.o ptrace32.o systbl.o \
@@ -44,8 +45,7 @@
 extra-$(CONFIG_8xx)		:= head_8xx.o
 extra-y				+= vmlinux.lds
 
-obj-y				+= process.o init_task.o time.o \
-				   prom.o traps.o setup-common.o udbg.o
+obj-y				+= time.o prom.o traps.o setup-common.o udbg.o
 obj-$(CONFIG_PPC32)		+= entry_32.o setup_32.o misc_32.o systbl.o
 obj-$(CONFIG_PPC64)		+= misc_64.o dma_64.o iommu.o
 obj-$(CONFIG_PPC_MULTIPLATFORM)	+= prom_init.o
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 24fe70f..c367520 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -53,6 +53,7 @@
 #ifdef CONFIG_PPC_MULTIPLATFORM
 static void fixup_resource(struct resource *res, struct pci_dev *dev);
 static void do_bus_setup(struct pci_bus *bus);
+static void phbs_remap_io(void);
 #endif
 
 /* pci_io_base -- the base address from which io bars are offsets.
@@ -251,6 +252,7 @@
 		kfree(phb);
 }
 
+#ifndef CONFIG_PPC_ISERIES
 void __devinit pcibios_claim_one_bus(struct pci_bus *b)
 {
 	struct pci_dev *dev;
@@ -275,7 +277,6 @@
 EXPORT_SYMBOL_GPL(pcibios_claim_one_bus);
 #endif
 
-#ifndef CONFIG_PPC_ISERIES
 static void __init pcibios_claim_of_setup(void)
 {
 	struct pci_bus *b;
@@ -1218,7 +1219,7 @@
 }
 EXPORT_SYMBOL(remap_bus_range);
 
-void phbs_remap_io(void)
+static void phbs_remap_io(void)
 {
 	struct pci_controller *hose, *tmp;
 
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 105d560..5770399 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -201,13 +201,13 @@
 }
 #endif /* CONFIG_SPE */
 
+#ifndef CONFIG_SMP
 /*
  * If we are doing lazy switching of CPU state (FP, altivec or SPE),
  * and the current task has some state, discard it.
  */
-static inline void discard_lazy_cpu_state(void)
+void discard_lazy_cpu_state(void)
 {
-#ifndef CONFIG_SMP
 	preempt_disable();
 	if (last_task_used_math == current)
 		last_task_used_math = NULL;
@@ -220,9 +220,10 @@
 		last_task_used_spe = NULL;
 #endif
 	preempt_enable();
-#endif /* CONFIG_SMP */
 }
+#endif /* CONFIG_SMP */
 
+#ifdef CONFIG_PPC_MERGE		/* XXX for now */
 int set_dabr(unsigned long dabr)
 {
 	if (ppc_md.set_dabr)
@@ -231,6 +232,7 @@
 	mtspr(SPRN_DABR, dabr);
 	return 0;
 }
+#endif
 
 #ifdef CONFIG_PPC64
 DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array);
@@ -424,7 +426,7 @@
 	if (trap == 0x300 || trap == 0x600)
 		printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr);
 	printk("TASK = %p[%d] '%s' THREAD: %p",
-	       current, current->pid, current->comm, current->thread_info);
+	       current, current->pid, current->comm, task_thread_info(current));
 
 #ifdef CONFIG_SMP
 	printk(" CPU: %d", smp_processor_id());
@@ -503,7 +505,7 @@
 {
 	struct pt_regs *childregs, *kregs;
 	extern void ret_from_fork(void);
-	unsigned long sp = (unsigned long)p->thread_info + THREAD_SIZE;
+	unsigned long sp = (unsigned long)task_stack_page(p) + THREAD_SIZE;
 
 	CHECK_FULL_REGS(regs);
 	/* Copy registers */
@@ -516,7 +518,7 @@
 #ifdef CONFIG_PPC32
 		childregs->gpr[2] = (unsigned long) p;
 #else
-		clear_ti_thread_flag(p->thread_info, TIF_32BIT);
+		clear_tsk_thread_flag(p, TIF_32BIT);
 #endif
 		p->thread.regs = NULL;	/* no user register state */
 	} else {
@@ -588,10 +590,8 @@
 	 * set.  Do it now.
 	 */
 	if (!current->thread.regs) {
-		unsigned long childregs = (unsigned long)current->thread_info +
-						THREAD_SIZE;
-		childregs -= sizeof(struct pt_regs);
-		current->thread.regs = (struct pt_regs *)childregs;
+		struct pt_regs *regs = task_stack_page(current) + THREAD_SIZE;
+		current->thread.regs = regs - 1;
 	}
 
 	memset(regs->gpr, 0, sizeof(regs->gpr));
@@ -767,7 +767,7 @@
 static int validate_sp(unsigned long sp, struct task_struct *p,
 		       unsigned long nbytes)
 {
-	unsigned long stack_page = (unsigned long)p->thread_info;
+	unsigned long stack_page = (unsigned long)task_stack_page(p);
 
 	if (sp >= stack_page + sizeof(struct thread_struct)
 	    && sp <= stack_page + THREAD_SIZE - nbytes)
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 34ab0da..02e2115 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -1100,17 +1100,37 @@
 
 static void __init early_reserve_mem(void)
 {
-	unsigned long base, size;
-	unsigned long *reserve_map;
+	u64 base, size;
+	u64 *reserve_map;
 
-	reserve_map = (unsigned long *)(((unsigned long)initial_boot_params) +
+	reserve_map = (u64 *)(((unsigned long)initial_boot_params) +
 					initial_boot_params->off_mem_rsvmap);
+#ifdef CONFIG_PPC32
+	/* 
+	 * Handle the case where we might be booting from an old kexec
+	 * image that setup the mem_rsvmap as pairs of 32-bit values
+	 */
+	if (*reserve_map > 0xffffffffull) {
+		u32 base_32, size_32;
+		u32 *reserve_map_32 = (u32 *)reserve_map;
+
+		while (1) {
+			base_32 = *(reserve_map_32++);
+			size_32 = *(reserve_map_32++);
+			if (size_32 == 0)
+				break;
+			DBG("reserving: %lx -> %lx\n", base_32, size_32);
+			lmb_reserve(base_32, size_32);
+		}
+		return;
+	}
+#endif
 	while (1) {
 		base = *(reserve_map++);
 		size = *(reserve_map++);
 		if (size == 0)
 			break;
-		DBG("reserving: %lx -> %lx\n", base, size);
+		DBG("reserving: %llx -> %llx\n", base, size);
 		lmb_reserve(base, size);
 	}
 
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index e381f2f..d963a12 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -137,8 +137,8 @@
 };
 
 struct mem_map_entry {
-	unsigned long	base;
-	unsigned long	size;
+	u64	base;
+	u64	size;
 };
 
 typedef u32 cell_t;
@@ -897,9 +897,9 @@
  * If problems seem to show up, it would be a good start to track
  * them down.
  */
-static void reserve_mem(unsigned long base, unsigned long size)
+static void reserve_mem(u64 base, u64 size)
 {
-	unsigned long top = base + size;
+	u64 top = base + size;
 	unsigned long cnt = RELOC(mem_reserve_cnt);
 
 	if (size == 0)
diff --git a/arch/powerpc/kernel/ptrace-common.h b/arch/powerpc/kernel/ptrace-common.h
index b1babb7..5ccbdbe 100644
--- a/arch/powerpc/kernel/ptrace-common.h
+++ b/arch/powerpc/kernel/ptrace-common.h
@@ -62,7 +62,7 @@
 	struct pt_regs *regs = task->thread.regs;
 	if (regs != NULL)
 		regs->msr |= MSR_SE;
-	set_ti_thread_flag(task->thread_info, TIF_SINGLESTEP);
+	set_tsk_thread_flag(task, TIF_SINGLESTEP);
 }
 
 static inline void clear_single_step(struct task_struct *task)
@@ -70,7 +70,7 @@
 	struct pt_regs *regs = task->thread.regs;
 	if (regs != NULL)
 		regs->msr &= ~MSR_SE;
-	clear_ti_thread_flag(task->thread_info, TIF_SINGLESTEP);
+	clear_tsk_thread_flag(task, TIF_SINGLESTEP);
 }
 
 #ifdef CONFIG_ALTIVEC
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index d3f0b6d..177bba7 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -497,6 +497,15 @@
 	if (err)
 		return 1;
 
+	/*
+	 * Do this before updating the thread state in
+	 * current->thread.fpr/vr/evr.  That way, if we get preempted
+	 * and another task grabs the FPU/Altivec/SPE, it won't be
+	 * tempted to save the current CPU state into the thread_struct
+	 * and corrupt what we are writing there.
+	 */
+	discard_lazy_cpu_state();
+
 	/* force the process to reload the FP registers from
 	   current->thread when it next does FP instructions */
 	regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
@@ -538,18 +547,6 @@
 		return 1;
 #endif /* CONFIG_SPE */
 
-#ifndef CONFIG_SMP
-	preempt_disable();
-	if (last_task_used_math == current)
-		last_task_used_math = NULL;
-	if (last_task_used_altivec == current)
-		last_task_used_altivec = NULL;
-#ifdef CONFIG_SPE
-	if (last_task_used_spe == current)
-		last_task_used_spe = NULL;
-#endif
-	preempt_enable();
-#endif
 	return 0;
 }
 
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 5462bef..7b9d999 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -207,10 +207,20 @@
 
 	if (!sig)
 		regs->gpr[13] = save_r13;
-	err |= __copy_from_user(&current->thread.fpr, &sc->fp_regs, FP_REGS_SIZE);
 	if (set != NULL)
 		err |=  __get_user(set->sig[0], &sc->oldmask);
 
+	/*
+	 * Do this before updating the thread state in
+	 * current->thread.fpr/vr.  That way, if we get preempted
+	 * and another task grabs the FPU/Altivec, it won't be
+	 * tempted to save the current CPU state into the thread_struct
+	 * and corrupt what we are writing there.
+	 */
+	discard_lazy_cpu_state();
+
+	err |= __copy_from_user(&current->thread.fpr, &sc->fp_regs, FP_REGS_SIZE);
+
 #ifdef CONFIG_ALTIVEC
 	err |= __get_user(v_regs, &sc->v_regs);
 	err |= __get_user(msr, &sc->gp_regs[PT_MSR]);
@@ -229,14 +239,6 @@
 		current->thread.vrsave = 0;
 #endif /* CONFIG_ALTIVEC */
 
-#ifndef CONFIG_SMP
-	preempt_disable();
-	if (last_task_used_math == current)
-		last_task_used_math = NULL;
-	if (last_task_used_altivec == current)
-		last_task_used_altivec = NULL;
-	preempt_enable();
-#endif
 	/* Force reload of FP/VEC */
 	regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1 | MSR_VEC);
 
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index d381ec9..c8458c5 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -338,8 +338,8 @@
 #ifdef CONFIG_PPC64
 	paca[cpu].__current = p;
 #endif
-	current_set[cpu] = p->thread_info;
-	p->thread_info->cpu = cpu;
+	current_set[cpu] = task_thread_info(p);
+	task_thread_info(p)->cpu = cpu;
 }
 
 void __init smp_prepare_cpus(unsigned int max_cpus)
@@ -375,7 +375,7 @@
 #ifdef CONFIG_PPC64
 	paca[boot_cpuid].__current = current;
 #endif
-	current_set[boot_cpuid] = current->thread_info;
+	current_set[boot_cpuid] = task_thread_info(current);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/powerpc/platforms/cell/pervasive.c b/arch/powerpc/platforms/cell/pervasive.c
index 85152544..e0e051c 100644
--- a/arch/powerpc/platforms/cell/pervasive.c
+++ b/arch/powerpc/platforms/cell/pervasive.c
@@ -142,7 +142,7 @@
 	}
 }
 
-int cbe_system_reset_exception(struct pt_regs *regs)
+static int cbe_system_reset_exception(struct pt_regs *regs)
 {
 	switch (regs->msr & SRR1_WAKEMASK) {
 	case SRR1_WAKEEE:
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index 18e25e6..b33a444 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -57,7 +57,7 @@
 #define DBG(fmt...)
 #endif
 
-void cell_show_cpuinfo(struct seq_file *m)
+static void cell_show_cpuinfo(struct seq_file *m)
 {
 	struct device_node *root;
 	const char *model = "";
diff --git a/arch/powerpc/platforms/cell/smp.c b/arch/powerpc/platforms/cell/smp.c
index de96ead..bdf6c5f 100644
--- a/arch/powerpc/platforms/cell/smp.c
+++ b/arch/powerpc/platforms/cell/smp.c
@@ -86,7 +86,7 @@
 	pcpu = get_hard_smp_processor_id(lcpu);
 
 	/* Fixup atomic count: it exited inside IRQ handler. */
-	paca[lcpu].__current->thread_info->preempt_count	= 0;
+	task_thread_info(paca[lcpu].__current)->preempt_count	= 0;
 
 	/*
 	 * If the RTAS start-cpu token does not exist then presume the
diff --git a/arch/powerpc/platforms/cell/spufs/syscalls.c b/arch/powerpc/platforms/cell/spufs/syscalls.c
index d549aa7..e6565a9 100644
--- a/arch/powerpc/platforms/cell/spufs/syscalls.c
+++ b/arch/powerpc/platforms/cell/spufs/syscalls.c
@@ -29,7 +29,9 @@
  * value of the spu_status register after the SPU has stopped.
  *
  */
-long do_spu_run(struct file *filp, __u32 __user *unpc, __u32 __user *ustatus)
+static long do_spu_run(struct file *filp,
+			__u32 __user *unpc,
+			__u32 __user *ustatus)
 {
 	long ret;
 	struct spufs_inode_info *i;
diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile
index 127b465..ce8c0b9 100644
--- a/arch/powerpc/platforms/iseries/Makefile
+++ b/arch/powerpc/platforms/iseries/Makefile
@@ -1,8 +1,8 @@
 EXTRA_CFLAGS	+= -mno-minimal-toc
 
 obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \
-	hvcall.o proc.o htab.o iommu.o misc.o
-obj-$(CONFIG_PCI) += pci.o irq.o vpdinfo.o
+	hvcall.o proc.o htab.o iommu.o misc.o irq.o
+obj-$(CONFIG_PCI) += pci.o vpdinfo.o
 obj-$(CONFIG_IBMVIO) += vio.o
 obj-$(CONFIG_SMP) += smp.o
 obj-$(CONFIG_VIOPATH) += viopath.o
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index 2b54eeb..bea0b70 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -34,6 +34,8 @@
 #include <asm/pci-bridge.h>
 #include <asm/iseries/hv_call_xm.h>
 
+#include "iommu.h"
+
 extern struct list_head iSeries_Global_Device_List;
 
 
diff --git a/arch/powerpc/platforms/iseries/iommu.h b/arch/powerpc/platforms/iseries/iommu.h
new file mode 100644
index 0000000..cb5658f
--- /dev/null
+++ b/arch/powerpc/platforms/iseries/iommu.h
@@ -0,0 +1,35 @@
+#ifndef _PLATFORMS_ISERIES_IOMMU_H
+#define _PLATFORMS_ISERIES_IOMMU_H
+
+/*
+ * Copyright (C) 2005  Stephen Rothwell, IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the:
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330,
+ * Boston, MA  02111-1307  USA
+ */
+
+struct device_node;
+struct iommu_table;
+
+/* Creates table for an individual device node */
+extern void iommu_devnode_init_iSeries(struct device_node *dn);
+
+/* Get table parameters from HV */
+extern void iommu_table_getparms_iSeries(unsigned long busno,
+		unsigned char slotno, unsigned char virtbus,
+		struct iommu_table *tbl);
+
+#endif /* _PLATFORMS_ISERIES_IOMMU_H */
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index 42e978e..83442ea 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -48,6 +48,8 @@
 extern void iSeries_smp_message_recv(struct pt_regs *);
 #endif
 
+#ifdef CONFIG_PCI
+
 enum pci_event_type {
 	pe_bus_created		= 0,	/* PHB has been created */
 	pe_bus_error		= 1,	/* PHB has failed */
@@ -147,20 +149,11 @@
 static void pci_event_handler(struct HvLpEvent *event, struct pt_regs *regs)
 {
 	if (event && (event->xType == HvLpEvent_Type_PciIo)) {
-		switch (event->xFlags.xFunction) {
-		case HvLpEvent_Function_Int:
+		if (hvlpevent_is_int(event))
 			int_received((struct pci_event *)event, regs);
-			break;
-		case HvLpEvent_Function_Ack:
+		else
 			printk(KERN_ERR
 				"pci_event_handler: unexpected ack received\n");
-			break;
-		default:
-			printk(KERN_ERR
-				"pci_event_handler: unexpected event function %d\n",
-				(int)event->xFlags.xFunction);
-			break;
-		}
 	} else if (event)
 		printk(KERN_ERR
 			"pci_event_handler: Unrecognized PCI event type 0x%x\n",
@@ -334,6 +327,8 @@
 	return virtirq;
 }
 
+#endif /* CONFIG_PCI */
+
 /*
  * Get the next pending IRQ.
  */
@@ -353,6 +348,7 @@
 	if (hvlpevent_is_pending())
 		process_hvlpevents(regs);
 
+#ifdef CONFIG_PCI
 	if (num_pending_irqs) {
 		spin_lock(&pending_irqs_lock);
 		for (irq = 0; irq < NR_IRQS; irq++) {
@@ -366,6 +362,7 @@
 		if (irq >= NR_IRQS)
 			irq = -2;
 	}
+#endif
 
 	return irq;
 }
diff --git a/arch/powerpc/platforms/iseries/lpardata.c b/arch/powerpc/platforms/iseries/lpardata.c
index ea72385..438e2db 100644
--- a/arch/powerpc/platforms/iseries/lpardata.c
+++ b/arch/powerpc/platforms/iseries/lpardata.c
@@ -93,10 +93,7 @@
 	.xPirEnvironMode = 0,		/* Piranha stuff */
 	.xPirConsoleMode = 0,
 	.xPirDasdMode = 0,
-	.xLparInstalled = 0,
-	.xSysPartitioned = 0,
-	.xHwSyncedTBs = 0,
-	.xIntProcUtilHmt = 0,
+	.flags = 0,
 	.xSpVpdFormat = 0,
 	.xIntProcRatio = 0,
 	.xPlicVrmIndex = 0,		/* VRM index of PLIC */
diff --git a/arch/powerpc/platforms/iseries/lpevents.c b/arch/powerpc/platforms/iseries/lpevents.c
index e9fb98b..0b88530 100644
--- a/arch/powerpc/platforms/iseries/lpevents.c
+++ b/arch/powerpc/platforms/iseries/lpevents.c
@@ -53,7 +53,7 @@
 	struct HvLpEvent * event;
 	event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr;
 
-	if (event->xFlags.xValid) {
+	if (hvlpevent_is_valid(event)) {
 		/* rmb() needed only for weakly consistent machines (regatta) */
 		rmb();
 		/* Set pointer to next potential event */
@@ -84,7 +84,7 @@
 
 	next_event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr;
 
-	return next_event->xFlags.xValid |
+	return hvlpevent_is_valid(next_event) ||
 		hvlpevent_queue.xPlicOverflowIntPending;
 }
 
@@ -101,18 +101,18 @@
 	switch (extra) {
 	case 3:
 		tmp = (struct HvLpEvent*)((char*)event + 3 * LpEventAlign);
-		tmp->xFlags.xValid = 0;
+		hvlpevent_invalidate(tmp);
 	case 2:
 		tmp = (struct HvLpEvent*)((char*)event + 2 * LpEventAlign);
-		tmp->xFlags.xValid = 0;
+		hvlpevent_invalidate(tmp);
 	case 1:
 		tmp = (struct HvLpEvent*)((char*)event + 1 * LpEventAlign);
-		tmp->xFlags.xValid = 0;
+		hvlpevent_invalidate(tmp);
 	}
 
 	mb();
 
-	event->xFlags.xValid = 0;
+	hvlpevent_invalidate(event);
 }
 
 void process_hvlpevents(struct pt_regs *regs)
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c
index 49e7e4b..a41d8b7 100644
--- a/arch/powerpc/platforms/iseries/mf.c
+++ b/arch/powerpc/platforms/iseries/mf.c
@@ -251,10 +251,7 @@
 	}
 	memset(ev, 0, sizeof(struct pending_event));
 	hev = &ev->event.hp_lp_event;
-	hev->xFlags.xValid = 1;
-	hev->xFlags.xAckType = HvLpEvent_AckType_ImmediateAck;
-	hev->xFlags.xAckInd = HvLpEvent_AckInd_DoAck;
-	hev->xFlags.xFunction = HvLpEvent_Function_Int;
+	hev->flags = HV_LP_EVENT_VALID | HV_LP_EVENT_DO_ACK | HV_LP_EVENT_INT;
 	hev->xType = HvLpEvent_Type_MachineFac;
 	hev->xSourceLp = HvLpConfig_getLpIndex();
 	hev->xTargetLp = primary_lp;
@@ -518,17 +515,10 @@
 static void hv_handler(struct HvLpEvent *event, struct pt_regs *regs)
 {
 	if ((event != NULL) && (event->xType == HvLpEvent_Type_MachineFac)) {
-		switch(event->xFlags.xFunction) {
-		case HvLpEvent_Function_Ack:
+		if (hvlpevent_is_ack(event))
 			handle_ack((struct io_mf_lp_event *)event);
-			break;
-		case HvLpEvent_Function_Int:
+		else
 			handle_int((struct io_mf_lp_event *)event);
-			break;
-		default:
-			printk(KERN_ERR "mf.c: non ack/int event received\n");
-			break;
-		}
 	} else
 		printk(KERN_ERR "mf.c: alien event received\n");
 }
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index dafc518..a19833b 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -43,6 +43,7 @@
 #include "irq.h"
 #include "pci.h"
 #include "call_pci.h"
+#include "iommu.h"
 
 extern unsigned long io_page_mask;
 
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
index 384360e..ad36ab0 100644
--- a/arch/powerpc/platforms/iseries/vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -22,6 +22,8 @@
 #include <asm/iseries/hv_lp_config.h>
 #include <asm/iseries/hv_call_xm.h>
 
+#include "iommu.h"
+
 struct device *iSeries_vio_dev = &vio_bus_device.dev;
 EXPORT_SYMBOL(iSeries_vio_dev);
 
diff --git a/arch/powerpc/platforms/iseries/viopath.c b/arch/powerpc/platforms/iseries/viopath.c
index 84267269..622a301 100644
--- a/arch/powerpc/platforms/iseries/viopath.c
+++ b/arch/powerpc/platforms/iseries/viopath.c
@@ -270,7 +270,7 @@
 	 * First see if this is just a normal monitor message from the
 	 * other partition
 	 */
-	if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
+	if (hvlpevent_is_int(event)) {
 		remoteLp = event->xSourceLp;
 		if (!viopathStatus[remoteLp].isActive)
 			sendMonMsg(remoteLp);
@@ -331,13 +331,12 @@
 {
 	if (!event)
 		return;
-	if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
+	if (hvlpevent_is_int(event)) {
 		printk(VIOPATH_KERN_WARN
 		       "unexpected config request from partition %d",
 		       event->xSourceLp);
 
-		if ((event->xFlags.xFunction == HvLpEvent_Function_Int) &&
-		    (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck)) {
+		if (hvlpevent_need_ack(event)) {
 			event->xRc = HvLpEvent_Rc_InvalidSubtype;
 			HvCallEvent_ackLpEvent(event);
 		}
@@ -377,7 +376,7 @@
 	int subtype = (event->xSubtype & VIOMAJOR_SUBTYPE_MASK)
 		>> VIOMAJOR_SUBTYPE_SHIFT;
 
-	if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
+	if (hvlpevent_is_int(event)) {
 		remoteLp = event->xSourceLp;
 		/*
 		 * The isActive is checked because if the hosting partition
@@ -436,8 +435,7 @@
 		       "unexpected virtual io event subtype %d from partition %d\n",
 		       event->xSubtype, remoteLp);
 		/* No handler.  Ack if necessary */
-		if ((event->xFlags.xFunction == HvLpEvent_Function_Int) &&
-		    (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck)) {
+		if (hvlpevent_is_int(event) && hvlpevent_need_ack(event)) {
 			event->xRc = HvLpEvent_Rc_InvalidSubtype;
 			HvCallEvent_ackLpEvent(event);
 		}
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 3b1a9d4..89c4c36 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -278,7 +278,7 @@
 }
 #endif
 
-void __init pmac_setup_arch(void)
+static void __init pmac_setup_arch(void)
 {
 	struct device_node *cpu, *ic;
 	int *fp;
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 17cea7f..8357831 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -208,10 +208,11 @@
 {
 	while (dn) {
 		if (PCI_DN(dn)) {
-			PCI_DN(dn)->eeh_mode |= mode_flag;
-
 			/* Mark the pci device driver too */
 			struct pci_dev *dev = PCI_DN(dn)->pcidev;
+
+			PCI_DN(dn)->eeh_mode |= mode_flag;
+
 			if (dev && dev->driver)
 				dev->error_state = pci_channel_io_frozen;
 
diff --git a/arch/powerpc/platforms/pseries/hvcserver.c b/arch/powerpc/platforms/pseries/hvcserver.c
index 4d58417..22bfb5c 100644
--- a/arch/powerpc/platforms/pseries/hvcserver.c
+++ b/arch/powerpc/platforms/pseries/hvcserver.c
@@ -40,7 +40,7 @@
  * functions aren't performance sensitive, so this conversion isn't an
  * issue.
  */
-int hvcs_convert(long to_convert)
+static int hvcs_convert(long to_convert)
 {
 	switch (to_convert) {
 		case H_Success:
@@ -91,7 +91,7 @@
 EXPORT_SYMBOL(hvcs_free_partner_info);
 
 /* Helper function for hvcs_get_partner_info */
-int hvcs_next_partner(uint32_t unit_address,
+static int hvcs_next_partner(uint32_t unit_address,
 		unsigned long last_p_partition_ID,
 		unsigned long last_p_unit_address, unsigned long *pi_buff)
 
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 169f914..48cfbfc 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -51,8 +51,6 @@
 
 #define DBG(fmt...)
 
-extern int is_python(struct device_node *);
-
 static void tce_build_pSeries(struct iommu_table *tbl, long index, 
 			      long npages, unsigned long uaddr, 
 			      enum dma_data_direction direction)
diff --git a/arch/powerpc/platforms/pseries/scanlog.c b/arch/powerpc/platforms/pseries/scanlog.c
index 2edc947..5064349 100644
--- a/arch/powerpc/platforms/pseries/scanlog.c
+++ b/arch/powerpc/platforms/pseries/scanlog.c
@@ -192,7 +192,7 @@
 	.release	= scanlog_release,
 };
 
-int __init scanlog_init(void)
+static int __init scanlog_init(void)
 {
 	struct proc_dir_entry *ent;
 
@@ -222,7 +222,7 @@
 	return 0;
 }
 
-void __exit scanlog_cleanup(void)
+static void __exit scanlog_cleanup(void)
 {
 	if (proc_ppc64_scan_log_dump) {
 		kfree(proc_ppc64_scan_log_dump->data);
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 8903cf6..68b7f08 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -86,7 +86,7 @@
 
 struct mpic *pSeries_mpic;
 
-void pSeries_show_cpuinfo(struct seq_file *m)
+static void pSeries_show_cpuinfo(struct seq_file *m)
 {
 	struct device_node *root;
 	const char *model = "";
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index 25181c5..8e6b1ed 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -93,7 +93,7 @@
 	return cpu_status;
 }
 
-int pSeries_cpu_disable(void)
+static int pSeries_cpu_disable(void)
 {
 	int cpu = smp_processor_id();
 
@@ -109,7 +109,7 @@
 	return 0;
 }
 
-void pSeries_cpu_die(unsigned int cpu)
+static void pSeries_cpu_die(unsigned int cpu)
 {
 	int tries;
 	int cpu_status;
@@ -282,7 +282,7 @@
 	pcpu = get_hard_smp_processor_id(lcpu);
 
 	/* Fixup atomic count: it exited inside IRQ handler. */
-	paca[lcpu].__current->thread_info->preempt_count	= 0;
+	task_thread_info(paca[lcpu].__current)->preempt_count	= 0;
 
 	/* 
 	 * If the RTAS start-cpu token does not exist then presume the
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 0c0cfa3..fd823c7 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -381,7 +381,7 @@
 
 #ifdef CONFIG_SMP
 
-irqreturn_t xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
 {
 	int cpu = smp_processor_id();
 
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index e00b46b..977de9d 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -139,7 +139,6 @@
 
 		*(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK);
 
-		rpn++;
 		uaddr += DART_PAGE_SIZE;
 	}
 
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 22612ed..7d02fa2 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -311,7 +311,7 @@
 }
 #endif
 
-int xmon_core(struct pt_regs *regs, int fromipi)
+static int xmon_core(struct pt_regs *regs, int fromipi)
 {
 	int cmd = 0;
 	unsigned long msr;
@@ -528,7 +528,7 @@
 	return IRQ_HANDLED;
 }
 
-int xmon_bpt(struct pt_regs *regs)
+static int xmon_bpt(struct pt_regs *regs)
 {
 	struct bpt *bp;
 	unsigned long offset;
@@ -554,7 +554,7 @@
 	return 1;
 }
 
-int xmon_sstep(struct pt_regs *regs)
+static int xmon_sstep(struct pt_regs *regs)
 {
 	if (user_mode(regs))
 		return 0;
@@ -562,7 +562,7 @@
 	return 1;
 }
 
-int xmon_dabr_match(struct pt_regs *regs)
+static int xmon_dabr_match(struct pt_regs *regs)
 {
 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
 		return 0;
@@ -572,7 +572,7 @@
 	return 1;
 }
 
-int xmon_iabr_match(struct pt_regs *regs)
+static int xmon_iabr_match(struct pt_regs *regs)
 {
 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
 		return 0;
@@ -582,7 +582,7 @@
 	return 1;
 }
 
-int xmon_ipi(struct pt_regs *regs)
+static int xmon_ipi(struct pt_regs *regs)
 {
 #ifdef CONFIG_SMP
 	if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
@@ -591,7 +591,7 @@
 	return 0;
 }
 
-int xmon_fault_handler(struct pt_regs *regs)
+static int xmon_fault_handler(struct pt_regs *regs)
 {
 	struct bpt *bp;
 	unsigned long offset;
diff --git a/arch/ppc/amiga/amiints.c b/arch/ppc/amiga/amiints.c
index 91195e2..5f35cf3 100644
--- a/arch/ppc/amiga/amiints.c
+++ b/arch/ppc/amiga/amiints.c
@@ -96,8 +96,8 @@
 		gayle.inten = GAYLE_IRQ_IDE;
 
 	/* turn off all interrupts... */
-	custom.intena = 0x7fff;
-	custom.intreq = 0x7fff;
+	amiga_custom.intena = 0x7fff;
+	amiga_custom.intreq = 0x7fff;
 
 #ifdef CONFIG_APUS
 	/* Clear any inter-CPU interrupt requests. Circumvents bug in
@@ -110,7 +110,7 @@
 	APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_IPLMASK);
 #endif
 	/* ... and enable the master interrupt bit */
-	custom.intena = IF_SETCLR | IF_INTEN;
+	amiga_custom.intena = IF_SETCLR | IF_INTEN;
 
 	cia_init_IRQ(&ciaa_base);
 	cia_init_IRQ(&ciab_base);
@@ -151,7 +151,7 @@
 	}
 
 	/* enable the interrupt */
-	custom.intena = IF_SETCLR | ami_intena_vals[irq];
+	amiga_custom.intena = IF_SETCLR | ami_intena_vals[irq];
 }
 
 void amiga_disable_irq(unsigned int irq)
@@ -177,7 +177,7 @@
 	}
 
 	/* disable the interrupt */
-	custom.intena = ami_intena_vals[irq];
+	amiga_custom.intena = ami_intena_vals[irq];
 }
 
 inline void amiga_do_irq(int irq, struct pt_regs *fp)
@@ -196,7 +196,7 @@
 
 	kstat_cpu(0).irqs[irq]++;
 
-	custom.intreq = ami_intena_vals[irq];
+	amiga_custom.intreq = ami_intena_vals[irq];
 
 	for (action = desc->action; action; action = action->next)
 		action->handler(irq, action->dev_id, fp);
@@ -208,40 +208,40 @@
 
 static void ami_int1(int irq, void *dev_id, struct pt_regs *fp)
 {
-	unsigned short ints = custom.intreqr & custom.intenar;
+	unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar;
 
 	/* if serial transmit buffer empty, interrupt */
 	if (ints & IF_TBE) {
-		custom.intreq = IF_TBE;
+		amiga_custom.intreq = IF_TBE;
 		amiga_do_irq(IRQ_AMIGA_TBE, fp);
 	}
 
 	/* if floppy disk transfer complete, interrupt */
 	if (ints & IF_DSKBLK) {
-		custom.intreq = IF_DSKBLK;
+		amiga_custom.intreq = IF_DSKBLK;
 		amiga_do_irq(IRQ_AMIGA_DSKBLK, fp);
 	}
 
 	/* if software interrupt set, interrupt */
 	if (ints & IF_SOFT) {
-		custom.intreq = IF_SOFT;
+		amiga_custom.intreq = IF_SOFT;
 		amiga_do_irq(IRQ_AMIGA_SOFT, fp);
 	}
 }
 
 static void ami_int3(int irq, void *dev_id, struct pt_regs *fp)
 {
-	unsigned short ints = custom.intreqr & custom.intenar;
+	unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar;
 
 	/* if a blitter interrupt */
 	if (ints & IF_BLIT) {
-		custom.intreq = IF_BLIT;
+		amiga_custom.intreq = IF_BLIT;
 		amiga_do_irq(IRQ_AMIGA_BLIT, fp);
 	}
 
 	/* if a copper interrupt */
 	if (ints & IF_COPER) {
-		custom.intreq = IF_COPER;
+		amiga_custom.intreq = IF_COPER;
 		amiga_do_irq(IRQ_AMIGA_COPPER, fp);
 	}
 
@@ -252,36 +252,36 @@
 
 static void ami_int4(int irq, void *dev_id, struct pt_regs *fp)
 {
-	unsigned short ints = custom.intreqr & custom.intenar;
+	unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar;
 
 	/* if audio 0 interrupt */
 	if (ints & IF_AUD0) {
-		custom.intreq = IF_AUD0;
+		amiga_custom.intreq = IF_AUD0;
 		amiga_do_irq(IRQ_AMIGA_AUD0, fp);
 	}
 
 	/* if audio 1 interrupt */
 	if (ints & IF_AUD1) {
-		custom.intreq = IF_AUD1;
+		amiga_custom.intreq = IF_AUD1;
 		amiga_do_irq(IRQ_AMIGA_AUD1, fp);
 	}
 
 	/* if audio 2 interrupt */
 	if (ints & IF_AUD2) {
-		custom.intreq = IF_AUD2;
+		amiga_custom.intreq = IF_AUD2;
 		amiga_do_irq(IRQ_AMIGA_AUD2, fp);
 	}
 
 	/* if audio 3 interrupt */
 	if (ints & IF_AUD3) {
-		custom.intreq = IF_AUD3;
+		amiga_custom.intreq = IF_AUD3;
 		amiga_do_irq(IRQ_AMIGA_AUD3, fp);
 	}
 }
 
 static void ami_int5(int irq, void *dev_id, struct pt_regs *fp)
 {
-	unsigned short ints = custom.intreqr & custom.intenar;
+	unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar;
 
 	/* if serial receive buffer full interrupt */
 	if (ints & IF_RBF) {
@@ -291,7 +291,7 @@
 
 	/* if a disk sync interrupt */
 	if (ints & IF_DSKSYN) {
-		custom.intreq = IF_DSKSYN;
+		amiga_custom.intreq = IF_DSKSYN;
 		amiga_do_irq(IRQ_AMIGA_DSKSYN, fp);
 	}
 }
diff --git a/arch/ppc/amiga/cia.c b/arch/ppc/amiga/cia.c
index ad96146..4431c58 100644
--- a/arch/ppc/amiga/cia.c
+++ b/arch/ppc/amiga/cia.c
@@ -66,7 +66,7 @@
 	else
 		base->icr_data &= ~mask;
 	if (base->icr_data & base->icr_mask)
-		custom.intreq = IF_SETCLR | base->int_mask;
+		amiga_custom.intreq = IF_SETCLR | base->int_mask;
 	return old & base->icr_mask;
 }
 
@@ -114,7 +114,7 @@
 	base->icr_mask &= CIA_ICR_ALL;
 
 	if (base->icr_data & base->icr_mask)
-		custom.intreq = IF_SETCLR | base->int_mask;
+		amiga_custom.intreq = IF_SETCLR | base->int_mask;
 	return old;
 }
 
@@ -145,7 +145,7 @@
 	irq = base->cia_irq;
 	desc = irq_desc + irq;
 	ints = cia_set_irq_private(base, CIA_ICR_ALL);
-	custom.intreq = base->int_mask;
+	amiga_custom.intreq = base->int_mask;
 	for (i = 0; i < CIA_IRQS; i++, irq++) {
 		if (ints & 1) {
 			kstat_cpu(0).irqs[irq]++;
@@ -174,5 +174,5 @@
 	action->name = base->name;
 	setup_irq(base->handler_irq, &amiga_sys_irqaction[base->handler_irq-IRQ_AMIGA_AUTO]);
 
-	custom.intena = IF_SETCLR | base->int_mask;
+	amiga_custom.intena = IF_SETCLR | base->int_mask;
 }
diff --git a/arch/ppc/amiga/config.c b/arch/ppc/amiga/config.c
index af881d7..60e2da1 100644
--- a/arch/ppc/amiga/config.c
+++ b/arch/ppc/amiga/config.c
@@ -90,9 +90,6 @@
 static void a2000_gettod (int *, int *, int *, int *, int *, int *);
 static int amiga_hwclk (int, struct hwclk_time *);
 static int amiga_set_clock_mmss (unsigned long);
-#ifdef CONFIG_AMIGA_FLOPPY
-extern void amiga_floppy_setup(char *, int *);
-#endif
 static void amiga_reset (void);
 extern void amiga_init_sound(void);
 static void amiga_savekmsg_init(void);
@@ -281,7 +278,7 @@
     case CS_OCS:
     case CS_ECS:
     case CS_AGA:
-      switch (custom.deniseid & 0xf) {
+      switch (amiga_custom.deniseid & 0xf) {
       case 0x0c:
 	AMIGAHW_SET(DENISE_HR);
 	break;
@@ -294,7 +291,7 @@
       AMIGAHW_SET(DENISE);
       break;
     }
-    switch ((custom.vposr>>8) & 0x7f) {
+    switch ((amiga_custom.vposr>>8) & 0x7f) {
     case 0x00:
       AMIGAHW_SET(AGNUS_PAL);
       break;
@@ -419,9 +416,6 @@
 
   mach_hwclk           = amiga_hwclk;
   mach_set_clock_mmss  = amiga_set_clock_mmss;
-#ifdef CONFIG_AMIGA_FLOPPY
-  mach_floppy_setup    = amiga_floppy_setup;
-#endif
   mach_reset           = amiga_reset;
 #ifdef CONFIG_HEARTBEAT
   mach_heartbeat = amiga_heartbeat;
@@ -432,9 +426,9 @@
   amiga_colorclock = 5*amiga_eclock;	/* 3.5 MHz */
 
   /* clear all DMA bits */
-  custom.dmacon = DMAF_ALL;
+  amiga_custom.dmacon = DMAF_ALL;
   /* ensure that the DMA master bit is set */
-  custom.dmacon = DMAF_SETCLR | DMAF_MASTER;
+  amiga_custom.dmacon = DMAF_SETCLR | DMAF_MASTER;
 
   /* request all RAM */
   for (i = 0; i < m68k_num_memory; i++) {
@@ -753,9 +747,9 @@
 
 static void amiga_serial_putc(char c)
 {
-    custom.serdat = (unsigned char)c | 0x100;
+    amiga_custom.serdat = (unsigned char)c | 0x100;
     mb();
-    while (!(custom.serdatr & 0x2000))
+    while (!(amiga_custom.serdatr & 0x2000))
        ;
 }
 
@@ -785,11 +779,11 @@
 {
     int ch;
 
-    while (!(custom.intreqr & IF_RBF))
+    while (!(amiga_custom.intreqr & IF_RBF))
 	barrier();
-    ch = custom.serdatr & 0xff;
+    ch = amiga_custom.serdatr & 0xff;
     /* clear the interrupt, so that another character can be read */
-    custom.intreq = IF_RBF;
+    amiga_custom.intreq = IF_RBF;
     return ch;
 }
 
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index e6c1d615..ca02013 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -13,7 +13,6 @@
 extra-y				+= vmlinux.lds
 
 obj-y				:= entry.o traps.o idle.o time.o misc.o \
-					process.o \
 					setup.o \
 					ppc_htab.o
 obj-$(CONFIG_6xx)		+= l2cr.o cpu_setup_6xx.o
diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c
deleted file mode 100644
index 25cbdc8..0000000
--- a/arch/ppc/kernel/process.c
+++ /dev/null
@@ -1,851 +0,0 @@
-/*
- *  arch/ppc/kernel/process.c
- *
- *  Derived from "arch/i386/kernel/process.c"
- *    Copyright (C) 1995  Linus Torvalds
- *
- *  Updated and modified by Cort Dougan (cort@cs.nmt.edu) and
- *  Paul Mackerras (paulus@cs.anu.edu.au)
- *
- *  PowerPC version
- *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version
- *  2 of the License, or (at your option) any later version.
- *
- */
-
-#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/user.h>
-#include <linux/elf.h>
-#include <linux/init.h>
-#include <linux/prctl.h>
-#include <linux/init_task.h>
-#include <linux/module.h>
-#include <linux/kallsyms.h>
-#include <linux/mqueue.h>
-#include <linux/hardirq.h>
-
-#include <asm/pgtable.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/processor.h>
-#include <asm/mmu.h>
-#include <asm/prom.h>
-
-extern unsigned long _get_SP(void);
-
-struct task_struct *last_task_used_math = NULL;
-struct task_struct *last_task_used_altivec = NULL;
-struct task_struct *last_task_used_spe = NULL;
-
-static struct fs_struct init_fs = INIT_FS;
-static struct files_struct init_files = INIT_FILES;
-static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
-static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
-struct mm_struct init_mm = INIT_MM(init_mm);
-EXPORT_SYMBOL(init_mm);
-
-/* this is 8kB-aligned so we can get to the thread_info struct
-   at the base of it from the stack pointer with 1 integer instruction. */
-union thread_union init_thread_union
-	__attribute__((__section__(".data.init_task"))) =
-{ INIT_THREAD_INFO(init_task) };
-
-/* initial task structure */
-struct task_struct init_task = INIT_TASK(init_task);
-EXPORT_SYMBOL(init_task);
-
-/* only used to get secondary processor up */
-struct task_struct *current_set[NR_CPUS] = {&init_task, };
-
-#undef SHOW_TASK_SWITCHES
-#undef CHECK_STACK
-
-#if defined(CHECK_STACK)
-unsigned long
-kernel_stack_top(struct task_struct *tsk)
-{
-	return ((unsigned long)tsk) + sizeof(union task_union);
-}
-
-unsigned long
-task_top(struct task_struct *tsk)
-{
-	return ((unsigned long)tsk) + sizeof(struct thread_info);
-}
-
-/* check to make sure the kernel stack is healthy */
-int check_stack(struct task_struct *tsk)
-{
-	unsigned long stack_top = kernel_stack_top(tsk);
-	unsigned long tsk_top = task_top(tsk);
-	int ret = 0;
-
-#if 0
-	/* check thread magic */
-	if ( tsk->thread.magic != THREAD_MAGIC )
-	{
-		ret |= 1;
-		printk("thread.magic bad: %08x\n", tsk->thread.magic);
-	}
-#endif
-
-	if ( !tsk )
-		printk("check_stack(): tsk bad tsk %p\n",tsk);
-
-	/* check if stored ksp is bad */
-	if ( (tsk->thread.ksp > stack_top) || (tsk->thread.ksp < tsk_top) )
-	{
-		printk("stack out of bounds: %s/%d\n"
-		       " tsk_top %08lx ksp %08lx stack_top %08lx\n",
-		       tsk->comm,tsk->pid,
-		       tsk_top, tsk->thread.ksp, stack_top);
-		ret |= 2;
-	}
-
-	/* check if stack ptr RIGHT NOW is bad */
-	if ( (tsk == current) && ((_get_SP() > stack_top ) || (_get_SP() < tsk_top)) )
-	{
-		printk("current stack ptr out of bounds: %s/%d\n"
-		       " tsk_top %08lx sp %08lx stack_top %08lx\n",
-		       current->comm,current->pid,
-		       tsk_top, _get_SP(), stack_top);
-		ret |= 4;
-	}
-
-#if 0
-	/* check amount of free stack */
-	for ( i = (unsigned long *)task_top(tsk) ; i < kernel_stack_top(tsk) ; i++ )
-	{
-		if ( !i )
-			printk("check_stack(): i = %p\n", i);
-		if ( *i != 0 )
-		{
-			/* only notify if it's less than 900 bytes */
-			if ( (i - (unsigned long *)task_top(tsk))  < 900 )
-				printk("%d bytes free on stack\n",
-				       i - task_top(tsk));
-			break;
-		}
-	}
-#endif
-
-	if (ret)
-	{
-		panic("bad kernel stack");
-	}
-	return(ret);
-}
-#endif /* defined(CHECK_STACK) */
-
-/*
- * Make sure the floating-point register state in the
- * the thread_struct is up to date for task tsk.
- */
-void flush_fp_to_thread(struct task_struct *tsk)
-{
-	if (tsk->thread.regs) {
-		/*
-		 * We need to disable preemption here because if we didn't,
-		 * another process could get scheduled after the regs->msr
-		 * test but before we have finished saving the FP registers
-		 * to the thread_struct.  That process could take over the
-		 * FPU, and then when we get scheduled again we would store
-		 * bogus values for the remaining FP registers.
-		 */
-		preempt_disable();
-		if (tsk->thread.regs->msr & MSR_FP) {
-#ifdef CONFIG_SMP
-			/*
-			 * This should only ever be called for current or
-			 * for a stopped child process.  Since we save away
-			 * the FP register state on context switch on SMP,
-			 * there is something wrong if a stopped child appears
-			 * to still have its FP state in the CPU registers.
-			 */
-			BUG_ON(tsk != current);
-#endif
-			giveup_fpu(current);
-		}
-		preempt_enable();
-	}
-}
-
-void enable_kernel_fp(void)
-{
-	WARN_ON(preemptible());
-
-#ifdef CONFIG_SMP
-	if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
-		giveup_fpu(current);
-	else
-		giveup_fpu(NULL);	/* just enables FP for kernel */
-#else
-	giveup_fpu(last_task_used_math);
-#endif /* CONFIG_SMP */
-}
-EXPORT_SYMBOL(enable_kernel_fp);
-
-int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
-{
-	preempt_disable();
-	if (tsk->thread.regs && (tsk->thread.regs->msr & MSR_FP))
-		giveup_fpu(tsk);
-	preempt_enable();
-	memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs));
-	return 1;
-}
-
-#ifdef CONFIG_ALTIVEC
-void enable_kernel_altivec(void)
-{
-	WARN_ON(preemptible());
-
-#ifdef CONFIG_SMP
-	if (current->thread.regs && (current->thread.regs->msr & MSR_VEC))
-		giveup_altivec(current);
-	else
-		giveup_altivec(NULL);	/* just enable AltiVec for kernel - force */
-#else
-	giveup_altivec(last_task_used_altivec);
-#endif /* __SMP __ */
-}
-EXPORT_SYMBOL(enable_kernel_altivec);
-
-/*
- * Make sure the VMX/Altivec register state in the
- * the thread_struct is up to date for task tsk.
- */
-void flush_altivec_to_thread(struct task_struct *tsk)
-{
-	if (tsk->thread.regs) {
-		preempt_disable();
-		if (tsk->thread.regs->msr & MSR_VEC) {
-#ifdef CONFIG_SMP
-			BUG_ON(tsk != current);
-#endif
-			giveup_altivec(current);
-		}
-		preempt_enable();
-	}
-}
-
-int dump_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
-{
-	if (regs->msr & MSR_VEC)
-		giveup_altivec(current);
-	memcpy(vrregs, &current->thread.vr[0], sizeof(*vrregs));
-	return 1;
-}
-#endif /* CONFIG_ALTIVEC */
-
-#ifdef CONFIG_SPE
-void
-enable_kernel_spe(void)
-{
-	WARN_ON(preemptible());
-
-#ifdef CONFIG_SMP
-	if (current->thread.regs && (current->thread.regs->msr & MSR_SPE))
-		giveup_spe(current);
-	else
-		giveup_spe(NULL);	/* just enable SPE for kernel - force */
-#else
-	giveup_spe(last_task_used_spe);
-#endif /* __SMP __ */
-}
-EXPORT_SYMBOL(enable_kernel_spe);
-
-void flush_spe_to_thread(struct task_struct *tsk)
-{
-	if (tsk->thread.regs) {
-		preempt_disable();
-		if (tsk->thread.regs->msr & MSR_SPE) {
-#ifdef CONFIG_SMP
-			BUG_ON(tsk != current);
-#endif
-			giveup_spe(current);
-		}
-		preempt_enable();
-	}
-}
-
-int dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs)
-{
-	if (regs->msr & MSR_SPE)
-		giveup_spe(current);
-	/* We copy u32 evr[32] + u64 acc + u32 spefscr -> 35 */
-	memcpy(evrregs, &current->thread.evr[0], sizeof(u32) * 35);
-	return 1;
-}
-#endif /* CONFIG_SPE */
-
-struct task_struct *__switch_to(struct task_struct *prev,
-	struct task_struct *new)
-{
-	struct thread_struct *new_thread, *old_thread;
-	unsigned long s;
-	struct task_struct *last;
-
-	local_irq_save(s);
-#ifdef CHECK_STACK
-	check_stack(prev);
-	check_stack(new);
-#endif
-
-#ifdef CONFIG_SMP
-	/* avoid complexity of lazy save/restore of fpu
-	 * by just saving it every time we switch out if
-	 * this task used the fpu during the last quantum.
-	 *
-	 * If it tries to use the fpu again, it'll trap and
-	 * reload its fp regs.  So we don't have to do a restore
-	 * every switch, just a save.
-	 *  -- Cort
-	 */
-	if (prev->thread.regs && (prev->thread.regs->msr & MSR_FP))
-		giveup_fpu(prev);
-#ifdef CONFIG_ALTIVEC
-	/*
-	 * If the previous thread used altivec in the last quantum
-	 * (thus changing altivec regs) then save them.
-	 * We used to check the VRSAVE register but not all apps
-	 * set it, so we don't rely on it now (and in fact we need
-	 * to save & restore VSCR even if VRSAVE == 0).  -- paulus
-	 *
-	 * On SMP we always save/restore altivec regs just to avoid the
-	 * complexity of changing processors.
-	 *  -- Cort
-	 */
-	if ((prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)))
-		giveup_altivec(prev);
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_SPE
-	/*
-	 * If the previous thread used spe in the last quantum
-	 * (thus changing spe regs) then save them.
-	 *
-	 * On SMP we always save/restore spe regs just to avoid the
-	 * complexity of changing processors.
-	 */
-	if ((prev->thread.regs && (prev->thread.regs->msr & MSR_SPE)))
-		giveup_spe(prev);
-#endif /* CONFIG_SPE */
-#endif /* CONFIG_SMP */
-
-#ifdef CONFIG_ALTIVEC
-	/* Avoid the trap.  On smp this this never happens since
-	 * we don't set last_task_used_altivec -- Cort
-	 */
-	if (new->thread.regs && last_task_used_altivec == new)
-		new->thread.regs->msr |= MSR_VEC;
-#endif
-#ifdef CONFIG_SPE
-	/* Avoid the trap.  On smp this this never happens since
-	 * we don't set last_task_used_spe
-	 */
-	if (new->thread.regs && last_task_used_spe == new)
-		new->thread.regs->msr |= MSR_SPE;
-#endif /* CONFIG_SPE */
-	new_thread = &new->thread;
-	old_thread = &current->thread;
-	last = _switch(old_thread, new_thread);
-	local_irq_restore(s);
-	return last;
-}
-
-void show_regs(struct pt_regs * regs)
-{
-	int i, trap;
-
-	printk("NIP: %08lX LR: %08lX SP: %08lX REGS: %p TRAP: %04lx    %s\n",
-	       regs->nip, regs->link, regs->gpr[1], regs, regs->trap,
-	       print_tainted());
-	printk("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
-	       regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
-	       regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
-	       regs->msr&MSR_IR ? 1 : 0,
-	       regs->msr&MSR_DR ? 1 : 0);
-	trap = TRAP(regs);
-	if (trap == 0x300 || trap == 0x600)
-		printk("DAR: %08lX, DSISR: %08lX\n", regs->dar, regs->dsisr);
-	printk("TASK = %p[%d] '%s' THREAD: %p\n",
-	       current, current->pid, current->comm, current->thread_info);
-	printk("Last syscall: %ld ", current->thread.last_syscall);
-
-#ifdef CONFIG_SMP
-	printk(" CPU: %d", smp_processor_id());
-#endif /* CONFIG_SMP */
-
-	for (i = 0;  i < 32;  i++) {
-		long r;
-		if ((i % 8) == 0)
-			printk("\n" KERN_INFO "GPR%02d: ", i);
-		if (__get_user(r, &regs->gpr[i]))
-			break;
-		printk("%08lX ", r);
-		if (i == 12 && !FULL_REGS(regs))
-			break;
-	}
-	printk("\n");
-#ifdef CONFIG_KALLSYMS
-	/*
-	 * Lookup NIP late so we have the best change of getting the
-	 * above info out without failing
-	 */
-	printk("NIP [%08lx] ", regs->nip);
-	print_symbol("%s\n", regs->nip);
-	printk("LR [%08lx] ", regs->link);
-	print_symbol("%s\n", regs->link);
-#endif
-	show_stack(current, (unsigned long *) regs->gpr[1]);
-}
-
-void exit_thread(void)
-{
-	preempt_disable();
-	if (last_task_used_math == current)
-		last_task_used_math = NULL;
-	if (last_task_used_altivec == current)
-		last_task_used_altivec = NULL;
-#ifdef CONFIG_SPE
-	if (last_task_used_spe == current)
-		last_task_used_spe = NULL;
-#endif
-	preempt_enable();
-}
-
-void flush_thread(void)
-{
-	preempt_disable();
-	if (last_task_used_math == current)
-		last_task_used_math = NULL;
-	if (last_task_used_altivec == current)
-		last_task_used_altivec = NULL;
-#ifdef CONFIG_SPE
-	if (last_task_used_spe == current)
-		last_task_used_spe = NULL;
-#endif
-	preempt_enable();
-}
-
-void
-release_thread(struct task_struct *t)
-{
-}
-
-/*
- * This gets called before we allocate a new thread and copy
- * the current task into it.
- */
-void prepare_to_copy(struct task_struct *tsk)
-{
-	struct pt_regs *regs = tsk->thread.regs;
-
-	if (regs == NULL)
-		return;
-	preempt_disable();
-	if (regs->msr & MSR_FP)
-		giveup_fpu(current);
-#ifdef CONFIG_ALTIVEC
-	if (regs->msr & MSR_VEC)
-		giveup_altivec(current);
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_SPE
-	if (regs->msr & MSR_SPE)
-		giveup_spe(current);
-#endif /* CONFIG_SPE */
-	preempt_enable();
-}
-
-/*
- * Copy a thread..
- */
-int
-copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
-	    unsigned long unused,
-	    struct task_struct *p, struct pt_regs *regs)
-{
-	struct pt_regs *childregs, *kregs;
-	extern void ret_from_fork(void);
-	unsigned long sp = (unsigned long)p->thread_info + THREAD_SIZE;
-	unsigned long childframe;
-
-	CHECK_FULL_REGS(regs);
-	/* Copy registers */
-	sp -= sizeof(struct pt_regs);
-	childregs = (struct pt_regs *) sp;
-	*childregs = *regs;
-	if ((childregs->msr & MSR_PR) == 0) {
-		/* for kernel thread, set `current' and stackptr in new task */
-		childregs->gpr[1] = sp + sizeof(struct pt_regs);
-		childregs->gpr[2] = (unsigned long) p;
-		p->thread.regs = NULL;	/* no user register state */
-	} else {
-		childregs->gpr[1] = usp;
-		p->thread.regs = childregs;
-		if (clone_flags & CLONE_SETTLS)
-			childregs->gpr[2] = childregs->gpr[6];
-	}
-	childregs->gpr[3] = 0;  /* Result from fork() */
-	sp -= STACK_FRAME_OVERHEAD;
-	childframe = sp;
-
-	/*
-	 * The way this works is that at some point in the future
-	 * some task will call _switch to switch to the new task.
-	 * That will pop off the stack frame created below and start
-	 * the new task running at ret_from_fork.  The new task will
-	 * do some house keeping and then return from the fork or clone
-	 * system call, using the stack frame created above.
-	 */
-	sp -= sizeof(struct pt_regs);
-	kregs = (struct pt_regs *) sp;
-	sp -= STACK_FRAME_OVERHEAD;
-	p->thread.ksp = sp;
-	kregs->nip = (unsigned long)ret_from_fork;
-
-	p->thread.last_syscall = -1;
-
-	return 0;
-}
-
-/*
- * Set up a thread for executing a new program
- */
-void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp)
-{
-	set_fs(USER_DS);
-	memset(regs->gpr, 0, sizeof(regs->gpr));
-	regs->ctr = 0;
-	regs->link = 0;
-	regs->xer = 0;
-	regs->ccr = 0;
-	regs->mq = 0;
-	regs->nip = nip;
-	regs->gpr[1] = sp;
-	regs->msr = MSR_USER;
-	preempt_disable();
-	if (last_task_used_math == current)
-		last_task_used_math = NULL;
-	if (last_task_used_altivec == current)
-		last_task_used_altivec = NULL;
-#ifdef CONFIG_SPE
-	if (last_task_used_spe == current)
-		last_task_used_spe = NULL;
-#endif
-	preempt_enable();
-	memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
-	current->thread.fpscr.val = 0;
-#ifdef CONFIG_ALTIVEC
-	memset(current->thread.vr, 0, sizeof(current->thread.vr));
-	memset(&current->thread.vscr, 0, sizeof(current->thread.vscr));
-	current->thread.vrsave = 0;
-	current->thread.used_vr = 0;
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_SPE
-	memset(current->thread.evr, 0, sizeof(current->thread.evr));
-	current->thread.acc = 0;
-	current->thread.spefscr = 0;
-	current->thread.used_spe = 0;
-#endif /* CONFIG_SPE */
-}
-
-#define PR_FP_ALL_EXCEPT (PR_FP_EXC_DIV | PR_FP_EXC_OVF | PR_FP_EXC_UND \
-		| PR_FP_EXC_RES | PR_FP_EXC_INV)
-
-int set_fpexc_mode(struct task_struct *tsk, unsigned int val)
-{
-	struct pt_regs *regs = tsk->thread.regs;
-
-	/* This is a bit hairy.  If we are an SPE enabled  processor
-	 * (have embedded fp) we store the IEEE exception enable flags in
-	 * fpexc_mode.  fpexc_mode is also used for setting FP exception
-	 * mode (asyn, precise, disabled) for 'Classic' FP. */
-	if (val & PR_FP_EXC_SW_ENABLE) {
-#ifdef CONFIG_SPE
-		tsk->thread.fpexc_mode = val &
-			(PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT);
-#else
-		return -EINVAL;
-#endif
-	} else {
-		/* on a CONFIG_SPE this does not hurt us.  The bits that
-		 * __pack_fe01 use do not overlap with bits used for
-		 * PR_FP_EXC_SW_ENABLE.  Additionally, the MSR[FE0,FE1] bits
-		 * on CONFIG_SPE implementations are reserved so writing to
-		 * them does not change anything */
-		if (val > PR_FP_EXC_PRECISE)
-			return -EINVAL;
-		tsk->thread.fpexc_mode = __pack_fe01(val);
-		if (regs != NULL && (regs->msr & MSR_FP) != 0)
-			regs->msr = (regs->msr & ~(MSR_FE0|MSR_FE1))
-				| tsk->thread.fpexc_mode;
-	}
-	return 0;
-}
-
-int get_fpexc_mode(struct task_struct *tsk, unsigned long adr)
-{
-	unsigned int val;
-
-	if (tsk->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE)
-#ifdef CONFIG_SPE
-		val = tsk->thread.fpexc_mode;
-#else
-		return -EINVAL;
-#endif
-	else
-		val = __unpack_fe01(tsk->thread.fpexc_mode);
-	return put_user(val, (unsigned int __user *) adr);
-}
-
-int sys_clone(unsigned long clone_flags, unsigned long usp,
-	      int __user *parent_tidp, void __user *child_threadptr,
-	      int __user *child_tidp, int p6,
-	      struct pt_regs *regs)
-{
-	CHECK_FULL_REGS(regs);
-	if (usp == 0)
-		usp = regs->gpr[1];	/* stack pointer for child */
- 	return do_fork(clone_flags, usp, regs, 0, parent_tidp, child_tidp);
-}
-
-int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
-	     unsigned long p4, unsigned long p5, unsigned long p6,
-	     struct pt_regs *regs)
-{
-	CHECK_FULL_REGS(regs);
-	return do_fork(SIGCHLD, regs->gpr[1], regs, 0, NULL, NULL);
-}
-
-int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
-	      unsigned long p4, unsigned long p5, unsigned long p6,
-	      struct pt_regs *regs)
-{
-	CHECK_FULL_REGS(regs);
-	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1],
-			regs, 0, NULL, NULL);
-}
-
-int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
-	       unsigned long a3, unsigned long a4, unsigned long a5,
-	       struct pt_regs *regs)
-{
-	int error;
-	char * filename;
-
-	filename = getname((char __user *) a0);
-	error = PTR_ERR(filename);
-	if (IS_ERR(filename))
-		goto out;
-	preempt_disable();
-	if (regs->msr & MSR_FP)
-		giveup_fpu(current);
-#ifdef CONFIG_ALTIVEC
-	if (regs->msr & MSR_VEC)
-		giveup_altivec(current);
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_SPE
-	if (regs->msr & MSR_SPE)
-		giveup_spe(current);
-#endif /* CONFIG_SPE */
-	preempt_enable();
-	error = do_execve(filename, (char __user *__user *) a1,
-			  (char __user *__user *) a2, regs);
-	if (error == 0) {
-		task_lock(current);
-		current->ptrace &= ~PT_DTRACE;
-		task_unlock(current);
-	}
-	putname(filename);
-out:
-	return error;
-}
-
-void dump_stack(void)
-{
-	show_stack(current, NULL);
-}
-
-EXPORT_SYMBOL(dump_stack);
-
-void show_stack(struct task_struct *tsk, unsigned long *stack)
-{
-	unsigned long sp, stack_top, prev_sp, ret;
-	int count = 0;
-	unsigned long next_exc = 0;
-	struct pt_regs *regs;
-	extern char ret_from_except, ret_from_except_full, ret_from_syscall;
-
-	sp = (unsigned long) stack;
-	if (tsk == NULL)
-		tsk = current;
-	if (sp == 0) {
-		if (tsk == current)
-			asm("mr %0,1" : "=r" (sp));
-		else
-			sp = tsk->thread.ksp;
-	}
-
-	prev_sp = (unsigned long) (tsk->thread_info + 1);
-	stack_top = (unsigned long) tsk->thread_info + THREAD_SIZE;
-	while (count < 16 && sp > prev_sp && sp < stack_top && (sp & 3) == 0) {
-		if (count == 0) {
-			printk("Call trace:");
-#ifdef CONFIG_KALLSYMS
-			printk("\n");
-#endif
-		} else {
-			if (next_exc) {
-				ret = next_exc;
-				next_exc = 0;
-			} else
-				ret = *(unsigned long *)(sp + 4);
-			printk(" [%08lx] ", ret);
-#ifdef CONFIG_KALLSYMS
-			print_symbol("%s", ret);
-			printk("\n");
-#endif
-			if (ret == (unsigned long) &ret_from_except
-			    || ret == (unsigned long) &ret_from_except_full
-			    || ret == (unsigned long) &ret_from_syscall) {
-				/* sp + 16 points to an exception frame */
-				regs = (struct pt_regs *) (sp + 16);
-				if (sp + 16 + sizeof(*regs) <= stack_top)
-					next_exc = regs->nip;
-			}
-		}
-		++count;
-		sp = *(unsigned long *)sp;
-	}
-#ifndef CONFIG_KALLSYMS
-	if (count > 0)
-		printk("\n");
-#endif
-}
-
-#if 0
-/*
- * Low level print for debugging - Cort
- */
-int __init ll_printk(const char *fmt, ...)
-{
-        va_list args;
-	char buf[256];
-        int i;
-
-        va_start(args, fmt);
-        i=vsprintf(buf,fmt,args);
-	ll_puts(buf);
-        va_end(args);
-        return i;
-}
-
-int lines = 24, cols = 80;
-int orig_x = 0, orig_y = 0;
-
-void puthex(unsigned long val)
-{
-	unsigned char buf[10];
-	int i;
-	for (i = 7;  i >= 0;  i--)
-	{
-		buf[i] = "0123456789ABCDEF"[val & 0x0F];
-		val >>= 4;
-	}
-	buf[8] = '\0';
-	prom_print(buf);
-}
-
-void __init ll_puts(const char *s)
-{
-	int x,y;
-	char *vidmem = (char *)/*(_ISA_MEM_BASE + 0xB8000) */0xD00B8000;
-	char c;
-	extern int mem_init_done;
-
-	if ( mem_init_done ) /* assume this means we can printk */
-	{
-		printk(s);
-		return;
-	}
-
-#if 0
-	if ( have_of )
-	{
-		prom_print(s);
-		return;
-	}
-#endif
-
-	/*
-	 * can't ll_puts on chrp without openfirmware yet.
-	 * vidmem just needs to be setup for it.
-	 * -- Cort
-	 */
-	if ( _machine != _MACH_prep )
-		return;
-	x = orig_x;
-	y = orig_y;
-
-	while ( ( c = *s++ ) != '\0' ) {
-		if ( c == '\n' ) {
-			x = 0;
-			if ( ++y >= lines ) {
-				/*scroll();*/
-				/*y--;*/
-				y = 0;
-			}
-		} else {
-			vidmem [ ( x + cols * y ) * 2 ] = c;
-			if ( ++x >= cols ) {
-				x = 0;
-				if ( ++y >= lines ) {
-					/*scroll();*/
-					/*y--;*/
-					y = 0;
-				}
-			}
-		}
-	}
-
-	orig_x = x;
-	orig_y = y;
-}
-#endif
-
-unsigned long get_wchan(struct task_struct *p)
-{
-	unsigned long ip, sp;
-	unsigned long stack_page = (unsigned long) p->thread_info;
-	int count = 0;
-	if (!p || p == current || p->state == TASK_RUNNING)
-		return 0;
-	sp = p->thread.ksp;
-	do {
-		sp = *(unsigned long *)sp;
-		if (sp < stack_page || sp >= stack_page + 8188)
-			return 0;
-		if (count > 0) {
-			ip = *(unsigned long *)(sp + 4);
-			if (!in_sched_functions(ip))
-				return ip;
-		}
-	} while (count++ < 16);
-	return 0;
-}
diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
index becbfa3..e55cdda 100644
--- a/arch/ppc/kernel/smp.c
+++ b/arch/ppc/kernel/smp.c
@@ -318,7 +318,7 @@
 		p = fork_idle(cpu);
 		if (IS_ERR(p))
 			panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p));
-		p->thread_info->cpu = cpu;
+		task_thread_info(p)->cpu = cpu;
 		idle_tasks[cpu] = p;
 	}
 }
@@ -369,7 +369,7 @@
 	char buf[32];
 	int c;
 
-	secondary_ti = idle_tasks[cpu]->thread_info;
+	secondary_ti = task_thread_info(idle_tasks[cpu]);
 	mb();
 
 	/*
diff --git a/arch/ppc/platforms/apus_setup.c b/arch/ppc/platforms/apus_setup.c
index 2f74fde..c42c500 100644
--- a/arch/ppc/platforms/apus_setup.c
+++ b/arch/ppc/platforms/apus_setup.c
@@ -55,9 +55,6 @@
 int (*mach_set_clock_mmss) (unsigned long) = NULL;
 void (*mach_reset)( void );
 long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */
-#if defined(CONFIG_AMIGA_FLOPPY)
-void (*mach_floppy_setup) (char *, int *) __initdata = NULL;
-#endif
 #ifdef CONFIG_HEARTBEAT
 void (*mach_heartbeat) (int) = NULL;
 extern void apus_heartbeat (void);
@@ -76,7 +73,6 @@
 
 struct mem_info ramdisk;
 
-extern void amiga_floppy_setup(char *, int *);
 extern void config_amiga(void);
 
 static int __60nsram = 0;
@@ -305,16 +301,6 @@
 {
 }
 
-/*********************************************************** FLOPPY */
-#if defined(CONFIG_AMIGA_FLOPPY)
-__init
-void floppy_setup(char *str, int *ints)
-{
-	if (mach_floppy_setup)
-		mach_floppy_setup (str, ints);
-}
-#endif
-
 /*********************************************************** MEMORY */
 #define KMAP_MAX 32
 unsigned long kmap_chunks[KMAP_MAX*3];
@@ -574,9 +560,9 @@
 
 int __debug_ser_out( unsigned char c )
 {
-	custom.serdat = c | 0x100;
+	amiga_custom.serdat = c | 0x100;
 	mb();
-	while (!(custom.serdatr & 0x2000))
+	while (!(amiga_custom.serdatr & 0x2000))
 		barrier();
 	return 1;
 }
@@ -586,11 +572,11 @@
 	unsigned char c;
 
 	/* XXX: is that ok?? derived from amiga_ser.c... */
-	while( !(custom.intreqr & IF_RBF) )
+	while( !(amiga_custom.intreqr & IF_RBF) )
 		barrier();
-	c = custom.serdatr;
+	c = amiga_custom.serdatr;
 	/* clear the interrupt, so that another character can be read */
-	custom.intreq = IF_RBF;
+	amiga_custom.intreq = IF_RBF;
 	return c;
 }
 
@@ -601,10 +587,10 @@
 	local_irq_save(flags);
 
 	/* turn off Rx and Tx interrupts */
-	custom.intena = IF_RBF | IF_TBE;
+	amiga_custom.intena = IF_RBF | IF_TBE;
 
 	/* clear any pending interrupt */
-	custom.intreq = IF_RBF | IF_TBE;
+	amiga_custom.intreq = IF_RBF | IF_TBE;
 
 	local_irq_restore(flags);
 
@@ -617,7 +603,7 @@
 
 #ifdef CONFIG_KGDB
 	/* turn Rx interrupts on for GDB */
-	custom.intena = IF_SETCLR | IF_RBF;
+	amiga_custom.intena = IF_SETCLR | IF_RBF;
 	ser_RTSon();
 #endif
 
diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c
index 2b483b4..9075a75 100644
--- a/arch/ppc/xmon/xmon.c
+++ b/arch/ppc/xmon/xmon.c
@@ -99,7 +99,7 @@
 static void insert_bpts(void);
 static struct bpt *at_breakpoint(unsigned pc);
 static void bpt_cmds(void);
-static void cacheflush(void);
+void cacheflush(void);
 #ifdef CONFIG_SMP
 static void cpu_cmd(void);
 #endif /* CONFIG_SMP */
diff --git a/arch/s390/kernel/binfmt_elf32.c b/arch/s390/kernel/binfmt_elf32.c
index 03ba589..1f451c2 100644
--- a/arch/s390/kernel/binfmt_elf32.c
+++ b/arch/s390/kernel/binfmt_elf32.c
@@ -112,7 +112,7 @@
 
 static inline int dump_task_regs32(struct task_struct *tsk, elf_gregset_t *regs)
 {
-	struct pt_regs *ptregs = __KSTK_PTREGS(tsk);
+	struct pt_regs *ptregs = task_pt_regs(tsk);
 	int i;
 
 	memcpy(&regs->psw.mask, &ptregs->psw.mask, 4);
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 7dd58f8..2ff90a1 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -153,7 +153,7 @@
 {
 	struct task_struct *tsk = current;
 
-        printk("CPU:    %d    %s\n", tsk->thread_info->cpu, print_tainted());
+        printk("CPU:    %d    %s\n", task_thread_info(tsk)->cpu, print_tainted());
         printk("Process %s (pid: %d, task: %p, ksp: %p)\n",
 	       current->comm, current->pid, (void *) tsk,
 	       (void *) tsk->thread.ksp);
@@ -217,8 +217,7 @@
             struct pt_regs childregs;
           } *frame;
 
-        frame = ((struct fake_frame *)
-		 (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
+        frame = container_of(task_pt_regs(p), struct fake_frame, childregs);
         p->thread.ksp = (unsigned long) frame;
 	/* Store access registers to kernel stack of new process. */
         frame->childregs = *regs;
@@ -358,11 +357,10 @@
 	unsigned long return_address;
 	int count;
 
-	if (!p || p == current || p->state == TASK_RUNNING || !p->thread_info)
+	if (!p || p == current || p->state == TASK_RUNNING || !task_stack_page(p))
 		return 0;
-	low = (struct stack_frame *) p->thread_info;
-	high = (struct stack_frame *)
-		((unsigned long) p->thread_info + THREAD_SIZE) - 1;
+	low = task_stack_page(p);
+	high = (struct stack_frame *) task_pt_regs(p);
 	sf = (struct stack_frame *) (p->thread.ksp & PSW_ADDR_INSN);
 	if (sf <= low || sf > high)
 		return 0;
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index cc02232..37dfe33 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -52,7 +52,7 @@
 	struct pt_regs *regs;
 	per_struct *per_info;
 
-	regs = __KSTK_PTREGS(task);
+	regs = task_pt_regs(task);
 	per_info = (per_struct *) &task->thread.per_info;
 	per_info->control_regs.bits.em_instruction_fetch =
 		per_info->single_step | per_info->instruction_fetch;
@@ -150,7 +150,7 @@
 		/*
 		 * psw and gprs are stored on the stack
 		 */
-		tmp = *(addr_t *)((addr_t) &__KSTK_PTREGS(child)->psw + addr);
+		tmp = *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr);
 		if (addr == (addr_t) &dummy->regs.psw.mask)
 			/* Remove per bit from user psw. */
 			tmp &= ~PSW_MASK_PER;
@@ -176,7 +176,7 @@
 		/*
 		 * orig_gpr2 is stored on the kernel stack
 		 */
-		tmp = (addr_t) __KSTK_PTREGS(child)->orig_gpr2;
+		tmp = (addr_t) task_pt_regs(child)->orig_gpr2;
 
 	} else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
 		/* 
@@ -243,7 +243,7 @@
 			   high order bit but older gdb's rely on it */
 			data |= PSW_ADDR_AMODE;
 #endif
-		*(addr_t *)((addr_t) &__KSTK_PTREGS(child)->psw + addr) = data;
+		*(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data;
 
 	} else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) {
 		/*
@@ -267,7 +267,7 @@
 		/*
 		 * orig_gpr2 is stored on the kernel stack
 		 */
-		__KSTK_PTREGS(child)->orig_gpr2 = data;
+		task_pt_regs(child)->orig_gpr2 = data;
 
 	} else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
 		/*
@@ -393,15 +393,15 @@
 		 */
 		if (addr == (addr_t) &dummy32->regs.psw.mask) {
 			/* Fake a 31 bit psw mask. */
-			tmp = (__u32)(__KSTK_PTREGS(child)->psw.mask >> 32);
+			tmp = (__u32)(task_pt_regs(child)->psw.mask >> 32);
 			tmp = PSW32_MASK_MERGE(PSW32_USER_BITS, tmp);
 		} else if (addr == (addr_t) &dummy32->regs.psw.addr) {
 			/* Fake a 31 bit psw address. */
-			tmp = (__u32) __KSTK_PTREGS(child)->psw.addr |
+			tmp = (__u32) task_pt_regs(child)->psw.addr |
 				PSW32_ADDR_AMODE31;
 		} else {
 			/* gpr 0-15 */
-			tmp = *(__u32 *)((addr_t) &__KSTK_PTREGS(child)->psw +
+			tmp = *(__u32 *)((addr_t) &task_pt_regs(child)->psw +
 					 addr*2 + 4);
 		}
 	} else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) {
@@ -415,7 +415,7 @@
 		/*
 		 * orig_gpr2 is stored on the kernel stack
 		 */
-		tmp = *(__u32*)((addr_t) &__KSTK_PTREGS(child)->orig_gpr2 + 4);
+		tmp = *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4);
 
 	} else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
 		/*
@@ -472,15 +472,15 @@
 			if (tmp != PSW32_MASK_MERGE(PSW32_USER_BITS, tmp))
 				/* Invalid psw mask. */
 				return -EINVAL;
-			__KSTK_PTREGS(child)->psw.mask =
+			task_pt_regs(child)->psw.mask =
 				PSW_MASK_MERGE(PSW_USER32_BITS, (__u64) tmp << 32);
 		} else if (addr == (addr_t) &dummy32->regs.psw.addr) {
 			/* Build a 64 bit psw address from 31 bit address. */
-			__KSTK_PTREGS(child)->psw.addr = 
+			task_pt_regs(child)->psw.addr =
 				(__u64) tmp & PSW32_ADDR_INSN;
 		} else {
 			/* gpr 0-15 */
-			*(__u32*)((addr_t) &__KSTK_PTREGS(child)->psw
+			*(__u32*)((addr_t) &task_pt_regs(child)->psw
 				  + addr*2 + 4) = tmp;
 		}
 	} else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) {
@@ -494,7 +494,7 @@
 		/*
 		 * orig_gpr2 is stored on the kernel stack
 		 */
-		*(__u32*)((addr_t) &__KSTK_PTREGS(child)->orig_gpr2 + 4) = tmp;
+		*(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4) = tmp;
 
 	} else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
 		/*
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index e10f4ca..cbfcfd0 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -657,7 +657,7 @@
 	idle = current_set[cpu];
         cpu_lowcore = lowcore_ptr[cpu];
 	cpu_lowcore->kernel_stack = (unsigned long)
-		idle->thread_info + (THREAD_SIZE);
+		task_stack_page(idle) + (THREAD_SIZE);
 	sf = (struct stack_frame *) (cpu_lowcore->kernel_stack
 				     - sizeof(struct pt_regs)
 				     - sizeof(struct stack_frame));
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index c36353e..b0d8ca8 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -282,7 +282,7 @@
 {
 	if (!cpu_isset(smp_processor_id(), nohz_cpu_mask))
 		return;
-	account_ticks(__KSTK_PTREGS(current));
+	account_ticks(task_pt_regs(current));
 	cpu_clear(smp_processor_id(), nohz_cpu_mask);
 }
 
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 95d1099..5d21e9e 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -136,8 +136,8 @@
 	sp = __show_trace(sp, S390_lowcore.async_stack - ASYNC_SIZE,
 			  S390_lowcore.async_stack);
 	if (task)
-		__show_trace(sp, (unsigned long) task->thread_info,
-			     (unsigned long) task->thread_info + THREAD_SIZE);
+		__show_trace(sp, (unsigned long) task_stack_page(task),
+			     (unsigned long) task_stack_page(task) + THREAD_SIZE);
 	else
 		__show_trace(sp, S390_lowcore.thread_info,
 			     S390_lowcore.thread_info + THREAD_SIZE);
@@ -240,7 +240,7 @@
 {
 	struct pt_regs *regs;
 
-	regs = __KSTK_PTREGS(task);
+	regs = task_pt_regs(task);
 	buffer += sprintf(buffer, "task: %p, ksp: %p\n",
 		       task, (void *)task->thread.ksp);
 	buffer += sprintf(buffer, "User PSW : %p %p\n",
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 8a2bea3..aac15e4 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -191,13 +191,8 @@
 {
 #if defined(CONFIG_SH_FPU)
 	struct task_struct *tsk = current;
-	struct pt_regs *regs = (struct pt_regs *)
-				((unsigned long)tsk->thread_info
-				 + THREAD_SIZE - sizeof(struct pt_regs)
-				 - sizeof(unsigned long));
-
 	/* Forget lazy FPU state */
-	clear_fpu(tsk, regs);
+	clear_fpu(tsk, task_pt_regs(tsk));
 	clear_used_math();
 #endif
 }
@@ -232,13 +227,7 @@
 {
 	struct pt_regs ptregs;
 	
-	ptregs = *(struct pt_regs *)
-		((unsigned long)tsk->thread_info + THREAD_SIZE
-		 - sizeof(struct pt_regs)
-#ifdef CONFIG_SH_DSP
-		 - sizeof(struct pt_dspregs)
-#endif
-		 - sizeof(unsigned long));
+	ptregs = *task_pt_regs(tsk);
 	elf_core_copy_regs(regs, &ptregs);
 
 	return 1;
@@ -252,11 +241,7 @@
 #if defined(CONFIG_SH_FPU)
 	fpvalid = !!tsk_used_math(tsk);
 	if (fpvalid) {
-		struct pt_regs *regs = (struct pt_regs *)
-					((unsigned long)tsk->thread_info
-					 + THREAD_SIZE - sizeof(struct pt_regs)
-					 - sizeof(unsigned long));
-		unlazy_fpu(tsk, regs);
+		unlazy_fpu(tsk, task_pt_regs(tsk));
 		memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu));
 	}
 #endif
@@ -279,18 +264,13 @@
 	copy_to_stopped_child_used_math(p);
 #endif
 
-	childregs = ((struct pt_regs *)
-		(THREAD_SIZE + (unsigned long) p->thread_info)
-#ifdef CONFIG_SH_DSP
-		- sizeof(struct pt_dspregs)
-#endif
-		- sizeof(unsigned long)) - 1;
+	childregs = task_pt_regs(p);
 	*childregs = *regs;
 
 	if (user_mode(regs)) {
 		childregs->regs[15] = usp;
 	} else {
-		childregs->regs[15] = (unsigned long)p->thread_info + THREAD_SIZE;
+		childregs->regs[15] = (unsigned long)task_stack_page(p) + THREAD_SIZE;
 	}
         if (clone_flags & CLONE_SETTLS) {
 		childregs->gbr = childregs->regs[0];
@@ -333,11 +313,7 @@
 struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *next)
 {
 #if defined(CONFIG_SH_FPU)
-	struct pt_regs *regs = (struct pt_regs *)
-				((unsigned long)prev->thread_info
-				 + THREAD_SIZE - sizeof(struct pt_regs)
-				 - sizeof(unsigned long));
-	unlazy_fpu(prev, regs);
+	unlazy_fpu(prev, task_pt_regs(prev));
 #endif
 
 #ifdef CONFIG_PREEMPT
@@ -346,13 +322,7 @@
 		struct pt_regs *regs;
 
 		local_irq_save(flags);
-		regs = (struct pt_regs *)
-			((unsigned long)prev->thread_info
-			 + THREAD_SIZE - sizeof(struct pt_regs)
-#ifdef CONFIG_SH_DSP
-			 - sizeof(struct pt_dspregs)
-#endif
-			 - sizeof(unsigned long));
+		regs = task_pt_regs(prev);
 		if (user_mode(regs) && regs->regs[15] >= 0xc0000000) {
 			int offset = (int)regs->regs[15];
 
@@ -372,7 +342,7 @@
 	 */
 	asm volatile("ldc	%0, r7_bank"
 		     : /* no output */
-		     : "r" (next->thread_info));
+		     : "r" (task_thread_info(next)));
 
 #ifdef CONFIG_MMU
 	/* If no tasks are using the UBC, we're done */
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
index 1a8be06..3887b4f 100644
--- a/arch/sh/kernel/ptrace.c
+++ b/arch/sh/kernel/ptrace.c
@@ -41,12 +41,7 @@
 {
 	unsigned char *stack;
 
-	stack = (unsigned char *)
-		task->thread_info + THREAD_SIZE	- sizeof(struct pt_regs)
-#ifdef CONFIG_SH_DSP
-		- sizeof(struct pt_dspregs)
-#endif
-		- sizeof(unsigned long);
+	stack = (unsigned char *)task_pt_regs(task);
 	stack += offset;
 	return (*((int *)stack));
 }
@@ -59,12 +54,7 @@
 {
 	unsigned char *stack;
 
-	stack = (unsigned char *)
-		task->thread_info + THREAD_SIZE - sizeof(struct pt_regs)
-#ifdef CONFIG_SH_DSP
-		- sizeof(struct pt_dspregs)
-#endif
-		- sizeof(unsigned long);
+	stack = (unsigned char *)task_pt_regs(task);
 	stack += offset;
 	*(unsigned long *) stack = data;
 	return 0;
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index 59e49b1..62c7d1c 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -103,7 +103,7 @@
 	if (IS_ERR(tsk))
 		panic("Failed forking idle task for cpu %d\n", cpu);
 	
-	tsk->thread_info->cpu = cpu;
+	task_thread_info(tsk)->cpu = cpu;
 
 	cpu_set(cpu, cpu_online_map);
 
diff --git a/arch/sh64/kernel/process.c b/arch/sh64/kernel/process.c
index 419b5a7..1da9c61 100644
--- a/arch/sh64/kernel/process.c
+++ b/arch/sh64/kernel/process.c
@@ -744,7 +744,7 @@
 	}
 #endif
 	/* Copy from sh version */
-	childregs = ((struct pt_regs *)(THREAD_SIZE + (unsigned long) p->thread_info )) - 1;
+	childregs = (struct pt_regs *)(THREAD_SIZE + task_stack_page(p)) - 1;
 
 	*childregs = *regs;
 
@@ -752,7 +752,7 @@
 		childregs->regs[15] = usp;
 		p->thread.uregs = childregs;
 	} else {
-		childregs->regs[15] = (unsigned long)p->thread_info + THREAD_SIZE;
+		childregs->regs[15] = (unsigned long)task_stack_page(p) + THREAD_SIZE;
 	}
 
 	childregs->regs[9] = 0; /* Set return value for child */
diff --git a/arch/sh64/lib/dbg.c b/arch/sh64/lib/dbg.c
index 526feda..5808733 100644
--- a/arch/sh64/lib/dbg.c
+++ b/arch/sh64/lib/dbg.c
@@ -174,7 +174,7 @@
 	struct ring_node *rr;
 
 	pid = current->pid;
-	stack_bottom = (unsigned long) current->thread_info;
+	stack_bottom = (unsigned long) task_stack_page(current);
 	asm volatile("ori r15, 0, %0" : "=r" (sp));
 	rr = event_ring + event_ptr;
 	rr->evt = evt;
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index ea86474..fbb05a4 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -302,7 +302,7 @@
 	int count = 0;
 
 	if (tsk != NULL)
-		task_base = (unsigned long) tsk->thread_info;
+		task_base = (unsigned long) task_stack_page(tsk);
 	else
 		task_base = (unsigned long) current_thread_info();
 
@@ -337,7 +337,7 @@
  */
 unsigned long thread_saved_pc(struct task_struct *tsk)
 {
-	return tsk->thread_info->kpc;
+	return task_thread_info(tsk)->kpc;
 }
 
 /*
@@ -392,7 +392,7 @@
 		/* We must fixup kregs as well. */
 		/* XXX This was not fixed for ti for a while, worked. Unused? */
 		current->thread.kregs = (struct pt_regs *)
-		    ((char *)current->thread_info + (THREAD_SIZE - TRACEREG_SZ));
+		    (task_stack_page(current) + (THREAD_SIZE - TRACEREG_SZ));
 	}
 }
 
@@ -459,7 +459,7 @@
 		unsigned long unused,
 		struct task_struct *p, struct pt_regs *regs)
 {
-	struct thread_info *ti = p->thread_info;
+	struct thread_info *ti = task_thread_info(p);
 	struct pt_regs *childregs;
 	char *new_stack;
 
@@ -482,7 +482,7 @@
 	 *  V                      V (stk.fr.) V  (pt_regs)  { (stk.fr.) }
 	 *  +----- - - - - - ------+===========+============={+==========}+
 	 */
-	new_stack = (char*)ti + THREAD_SIZE;
+	new_stack = task_stack_page(p) + THREAD_SIZE;
 	if (regs->psr & PSR_PS)
 		new_stack -= STACKFRAME_SZ;
 	new_stack -= STACKFRAME_SZ + TRACEREG_SZ;
@@ -724,7 +724,7 @@
             task->state == TASK_RUNNING)
 		goto out;
 
-	fp = task->thread_info->ksp + bias;
+	fp = task_thread_info(task)->ksp + bias;
 	do {
 		/* Bogus frame pointer? */
 		if (fp < (task_base + sizeof(struct thread_info)) ||
diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c
index fc470c0..1baf13e 100644
--- a/arch/sparc/kernel/ptrace.c
+++ b/arch/sparc/kernel/ptrace.c
@@ -75,7 +75,7 @@
 				   struct task_struct *tsk, long __user *addr)
 {
 	struct pt_regs *cregs = tsk->thread.kregs;
-	struct thread_info *t = tsk->thread_info;
+	struct thread_info *t = task_thread_info(tsk);
 	int v;
 	
 	if(offset >= 1024)
@@ -170,7 +170,7 @@
 				    struct task_struct *tsk)
 {
 	struct pt_regs *cregs = tsk->thread.kregs;
-	struct thread_info *t = tsk->thread_info;
+	struct thread_info *t = task_thread_info(tsk);
 	unsigned long value = regs->u_regs[UREG_I3];
 
 	if(offset >= 1024)
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
index cc1fc89..40d426c 100644
--- a/arch/sparc/kernel/sun4d_smp.c
+++ b/arch/sparc/kernel/sun4d_smp.c
@@ -200,7 +200,7 @@
 			/* Cook up an idler for this guy. */
 			p = fork_idle(i);
 			cpucount++;
-			current_set[i] = p->thread_info;
+			current_set[i] = task_thread_info(p);
 			for (no = 0; !cpu_find_by_instance(no, NULL, &mid)
 				     && mid != i; no++) ;
 
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
index f113422..a21f27d 100644
--- a/arch/sparc/kernel/sun4m_smp.c
+++ b/arch/sparc/kernel/sun4m_smp.c
@@ -173,7 +173,7 @@
 			/* Cook up an idler for this guy. */
 			p = fork_idle(i);
 			cpucount++;
-			current_set[i] = p->thread_info;
+			current_set[i] = task_thread_info(p);
 			/* See trampoline.S for details... */
 			entry += ((i-1) * 3);
 
diff --git a/arch/sparc/kernel/traps.c b/arch/sparc/kernel/traps.c
index 3f451ae..41d45c2 100644
--- a/arch/sparc/kernel/traps.c
+++ b/arch/sparc/kernel/traps.c
@@ -291,7 +291,7 @@
 #ifndef CONFIG_SMP
 	if(!fpt) {
 #else
-        if(!(fpt->thread_info->flags & _TIF_USEDFPU)) {
+        if(!(task_thread_info(fpt)->flags & _TIF_USEDFPU)) {
 #endif
 		fpsave(&fake_regs[0], &fake_fsr, &fake_queue[0], &fake_depth);
 		regs->psr &= ~PSR_EF;
@@ -334,7 +334,7 @@
 	/* nope, better SIGFPE the offending process... */
 	       
 #ifdef CONFIG_SMP
-	fpt->thread_info->flags &= ~_TIF_USEDFPU;
+	task_thread_info(fpt)->flags &= ~_TIF_USEDFPU;
 #endif
 	if(psr & PSR_PS) {
 		/* The first fsr store/load we tried trapped,
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 02f9dec..1dc3650 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -390,7 +390,7 @@
 
 unsigned long thread_saved_pc(struct task_struct *tsk)
 {
-	struct thread_info *ti = tsk->thread_info;
+	struct thread_info *ti = task_thread_info(tsk);
 	unsigned long ret = 0xdeadbeefUL;
 	
 	if (ti && ti->ksp) {
@@ -616,11 +616,11 @@
 		unsigned long unused,
 		struct task_struct *p, struct pt_regs *regs)
 {
-	struct thread_info *t = p->thread_info;
+	struct thread_info *t = task_thread_info(p);
 	char *child_trap_frame;
 
 	/* Calculate offset to stack_frame & pt_regs */
-	child_trap_frame = ((char *)t) + (THREAD_SIZE - (TRACEREG_SZ+STACKFRAME_SZ));
+	child_trap_frame = task_stack_page(p) + (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))) |
@@ -845,9 +845,9 @@
             task->state == TASK_RUNNING)
 		goto out;
 
-	thread_info_base = (unsigned long) task->thread_info;
+	thread_info_base = (unsigned long) task_stack_page(task);
 	bias = STACK_BIAS;
-	fp = task->thread_info->ksp + bias;
+	fp = task_thread_info(task)->ksp + bias;
 
 	do {
 		/* Bogus frame pointer? */
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
index 84d3df2..3f9746f 100644
--- a/arch/sparc64/kernel/ptrace.c
+++ b/arch/sparc64/kernel/ptrace.c
@@ -296,7 +296,7 @@
 	case PTRACE_GETREGS: {
 		struct pt_regs32 __user *pregs =
 			(struct pt_regs32 __user *) addr;
-		struct pt_regs *cregs = child->thread_info->kregs;
+		struct pt_regs *cregs = task_pt_regs(child);
 		int rval;
 
 		if (__put_user(tstate_to_psr(cregs->tstate), (&pregs->psr)) ||
@@ -320,11 +320,11 @@
 
 	case PTRACE_GETREGS64: {
 		struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
-		struct pt_regs *cregs = child->thread_info->kregs;
+		struct pt_regs *cregs = task_pt_regs(child);
 		unsigned long tpc = cregs->tpc;
 		int rval;
 
-		if ((child->thread_info->flags & _TIF_32BIT) != 0)
+		if ((task_thread_info(child)->flags & _TIF_32BIT) != 0)
 			tpc &= 0xffffffff;
 		if (__put_user(cregs->tstate, (&pregs->tstate)) ||
 		    __put_user(tpc, (&pregs->tpc)) ||
@@ -348,7 +348,7 @@
 	case PTRACE_SETREGS: {
 		struct pt_regs32 __user *pregs =
 			(struct pt_regs32 __user *) addr;
-		struct pt_regs *cregs = child->thread_info->kregs;
+		struct pt_regs *cregs = task_pt_regs(child);
 		unsigned int psr, pc, npc, y;
 		int i;
 
@@ -381,7 +381,7 @@
 
 	case PTRACE_SETREGS64: {
 		struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
-		struct pt_regs *cregs = child->thread_info->kregs;
+		struct pt_regs *cregs = task_pt_regs(child);
 		unsigned long tstate, tpc, tnpc, y;
 		int i;
 
@@ -395,7 +395,7 @@
 			pt_error_return(regs, EFAULT);
 			goto out_tsk;
 		}
-		if ((child->thread_info->flags & _TIF_32BIT) != 0) {
+		if ((task_thread_info(child)->flags & _TIF_32BIT) != 0) {
 			tpc &= 0xffffffff;
 			tnpc &= 0xffffffff;
 		}
@@ -430,11 +430,11 @@
 			} fpq[16];
 		};
 		struct fps __user *fps = (struct fps __user *) addr;
-		unsigned long *fpregs = child->thread_info->fpregs;
+		unsigned long *fpregs = task_thread_info(child)->fpregs;
 
 		if (copy_to_user(&fps->regs[0], fpregs,
 				 (32 * sizeof(unsigned int))) ||
-		    __put_user(child->thread_info->xfsr[0], (&fps->fsr)) ||
+		    __put_user(task_thread_info(child)->xfsr[0], (&fps->fsr)) ||
 		    __put_user(0, (&fps->fpqd)) ||
 		    __put_user(0, (&fps->flags)) ||
 		    __put_user(0, (&fps->extra)) ||
@@ -452,11 +452,11 @@
 			unsigned long fsr;
 		};
 		struct fps __user *fps = (struct fps __user *) addr;
-		unsigned long *fpregs = child->thread_info->fpregs;
+		unsigned long *fpregs = task_thread_info(child)->fpregs;
 
 		if (copy_to_user(&fps->regs[0], fpregs,
 				 (64 * sizeof(unsigned int))) ||
-		    __put_user(child->thread_info->xfsr[0], (&fps->fsr))) {
+		    __put_user(task_thread_info(child)->xfsr[0], (&fps->fsr))) {
 			pt_error_return(regs, EFAULT);
 			goto out_tsk;
 		}
@@ -477,7 +477,7 @@
 			} fpq[16];
 		};
 		struct fps __user *fps = (struct fps __user *) addr;
-		unsigned long *fpregs = child->thread_info->fpregs;
+		unsigned long *fpregs = task_thread_info(child)->fpregs;
 		unsigned fsr;
 
 		if (copy_from_user(fpregs, &fps->regs[0],
@@ -486,11 +486,11 @@
 			pt_error_return(regs, EFAULT);
 			goto out_tsk;
 		}
-		child->thread_info->xfsr[0] &= 0xffffffff00000000UL;
-		child->thread_info->xfsr[0] |= fsr;
-		if (!(child->thread_info->fpsaved[0] & FPRS_FEF))
-			child->thread_info->gsr[0] = 0;
-		child->thread_info->fpsaved[0] |= (FPRS_FEF | FPRS_DL);
+		task_thread_info(child)->xfsr[0] &= 0xffffffff00000000UL;
+		task_thread_info(child)->xfsr[0] |= fsr;
+		if (!(task_thread_info(child)->fpsaved[0] & FPRS_FEF))
+			task_thread_info(child)->gsr[0] = 0;
+		task_thread_info(child)->fpsaved[0] |= (FPRS_FEF | FPRS_DL);
 		pt_succ_return(regs, 0);
 		goto out_tsk;
 	}
@@ -501,17 +501,17 @@
 			unsigned long fsr;
 		};
 		struct fps __user *fps = (struct fps __user *) addr;
-		unsigned long *fpregs = child->thread_info->fpregs;
+		unsigned long *fpregs = task_thread_info(child)->fpregs;
 
 		if (copy_from_user(fpregs, &fps->regs[0],
 				   (64 * sizeof(unsigned int))) ||
-		    __get_user(child->thread_info->xfsr[0], (&fps->fsr))) {
+		    __get_user(task_thread_info(child)->xfsr[0], (&fps->fsr))) {
 			pt_error_return(regs, EFAULT);
 			goto out_tsk;
 		}
-		if (!(child->thread_info->fpsaved[0] & FPRS_FEF))
-			child->thread_info->gsr[0] = 0;
-		child->thread_info->fpsaved[0] |= (FPRS_FEF | FPRS_DL | FPRS_DU);
+		if (!(task_thread_info(child)->fpsaved[0] & FPRS_FEF))
+			task_thread_info(child)->gsr[0] = 0;
+		task_thread_info(child)->fpsaved[0] |= (FPRS_FEF | FPRS_DL | FPRS_DU);
 		pt_succ_return(regs, 0);
 		goto out_tsk;
 	}
@@ -562,8 +562,8 @@
 #ifdef DEBUG_PTRACE
 		printk("CONT: %s [%d]: set exit_code = %x %lx %lx\n", child->comm,
 			child->pid, child->exit_code,
-			child->thread_info->kregs->tpc,
-			child->thread_info->kregs->tnpc);
+			task_pt_regs(child)->tpc,
+			task_pt_regs(child)->tnpc);
 		       
 #endif
 		wake_up_process(child);
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index 4818053..2507458 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -520,7 +520,7 @@
 	rd_doload = ((ram_flags & RAMDISK_LOAD_FLAG) != 0);	
 #endif
 
-	init_task.thread_info->kregs = &fake_swapper_regs;
+	task_thread_info(&init_task)->kregs = &fake_swapper_regs;
 
 #ifdef CONFIG_IP_PNP
 	if (!ic_set_manually) {
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 6efc03df..1fb6323 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -335,7 +335,7 @@
 
 	p = fork_idle(cpu);
 	callin_flag = 0;
-	cpu_new_thread = p->thread_info;
+	cpu_new_thread = task_thread_info(p);
 	cpu_set(cpu, cpu_callout_map);
 
 	cpu_find_by_mid(cpu, &cpu_node);
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index 5570e7b..8d44ae5 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -1808,7 +1808,7 @@
 void show_stack(struct task_struct *tsk, unsigned long *_ksp)
 {
 	unsigned long pc, fp, thread_base, ksp;
-	struct thread_info *tp = tsk->thread_info;
+	void *tp = task_stack_page(tsk);
 	struct reg_window *rw;
 	int count = 0;
 
@@ -1862,7 +1862,7 @@
 			return 0;
 	}
 
-	thread_base = (unsigned long) task->thread_info;
+	thread_base = (unsigned long) task_stack_page(task);
 	thread_end = thread_base + sizeof(union thread_union);
 	if (rw_addr >= thread_base &&
 	    rw_addr < thread_end &&
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
index d2d3f25..7f13b85 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process_kern.c
@@ -107,7 +107,7 @@
 {
 	struct task_struct *task = t;
 
-	cpu_tasks[task->thread_info->cpu] = ((struct cpu_task) 
+	cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task)
 		{ external_pid(task), task });
 }
 
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
index 09790cc..dc41c6d 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -118,7 +118,7 @@
 		handler = new_thread_handler;
 	}
 
-	new_thread(p->thread_info, &p->thread.mode.skas.switch_buf,
+	new_thread(task_stack_page(p), &p->thread.mode.skas.switch_buf,
 		   &p->thread.mode.skas.fork_buf, handler);
 	return(0);
 }
@@ -185,7 +185,7 @@
 
 	init_task.thread.request.u.thread.proc = start_kernel_proc;
 	init_task.thread.request.u.thread.arg = NULL;
-	return(start_idle_thread(init_task.thread_info,
+	return(start_idle_thread(task_stack_page(&init_task),
 				 &init_task.thread.mode.skas.switch_buf,
 				 &init_task.thread.mode.skas.fork_buf));
 }
diff --git a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c
index 136e54c..8f40e48 100644
--- a/arch/um/kernel/tt/exec_kern.c
+++ b/arch/um/kernel/tt/exec_kern.c
@@ -39,7 +39,7 @@
 		do_exit(SIGKILL);
 	}
 		
-	new_pid = start_fork_tramp(current->thread_info, stack, 0, exec_tramp);
+	new_pid = start_fork_tramp(task_stack_page(current), stack, 0, exec_tramp);
 	if(new_pid < 0){
 		printk(KERN_ERR 
 		       "flush_thread : new thread failed, errno = %d\n",
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
index 14d4622..6253530 100644
--- a/arch/um/kernel/tt/process_kern.c
+++ b/arch/um/kernel/tt/process_kern.c
@@ -36,7 +36,7 @@
 	from = prev;
 	to = next;
 
-	cpu = from->thread_info->cpu;
+	cpu = task_thread_info(from)->cpu;
 	if(cpu == 0)
 		forward_interrupts(to->thread.mode.tt.extern_pid);
 #ifdef CONFIG_SMP
@@ -253,7 +253,7 @@
 
 	clone_flags &= CLONE_VM;
 	p->thread.temp_stack = stack;
-	new_pid = start_fork_tramp(p->thread_info, stack, clone_flags, tramp);
+	new_pid = start_fork_tramp(task_stack_page(p), stack, clone_flags, tramp);
 	if(new_pid < 0){
 		printk(KERN_ERR "copy_thread : clone failed - errno = %d\n", 
 		       -new_pid);
@@ -343,7 +343,7 @@
 		pid = thread->request.u.exec.pid;
 		do_exec(thread->mode.tt.extern_pid, pid);
 		thread->mode.tt.extern_pid = pid;
-		cpu_tasks[task->thread_info->cpu].pid = pid;
+		cpu_tasks[task_thread_info(task)->cpu].pid = pid;
 		break;
 	case OP_FORK:
 		attach_process(thread->request.u.fork.pid);
@@ -425,7 +425,7 @@
 	int pages;
 
 	pages = (1 << CONFIG_KERNEL_STACK_ORDER);
-	sp = (void *) ((unsigned long) init_task.thread_info) +
+	sp = task_stack_page(&init_task) +
 		pages * PAGE_SIZE - sizeof(unsigned long);
 	return(tracer(start_kernel_proc, sp));
 }
diff --git a/arch/v850/kernel/process.c b/arch/v850/kernel/process.c
index 062ffa0..eb90993 100644
--- a/arch/v850/kernel/process.c
+++ b/arch/v850/kernel/process.c
@@ -114,7 +114,7 @@
 		 struct task_struct *p, struct pt_regs *regs)
 {
 	/* Start pushing stuff from the top of the child's kernel stack.  */
-	unsigned long orig_ksp = (unsigned long)p->thread_info + THREAD_SIZE;
+	unsigned long orig_ksp = task_tos(p);
 	unsigned long ksp = orig_ksp;
 	/* We push two `state save' stack fames (see entry.S) on the new
 	   kernel stack:
diff --git a/arch/v850/kernel/ptrace.c b/arch/v850/kernel/ptrace.c
index 18492d0..67e0575 100644
--- a/arch/v850/kernel/ptrace.c
+++ b/arch/v850/kernel/ptrace.c
@@ -58,7 +58,7 @@
 		regs = thread_saved_regs (t);
 	else
 		/* Register saved during kernel entry (or not available).  */
-		regs = task_regs (t);
+		regs = task_pt_regs (t);
 
 	return (v850_reg_t *)((char *)regs + reg_offs);
 }
diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c
index 2b760d0..029bdda 100644
--- a/arch/x86_64/ia32/ia32_binfmt.c
+++ b/arch/x86_64/ia32/ia32_binfmt.c
@@ -197,8 +197,7 @@
 
 static inline int elf_core_copy_task_regs(struct task_struct *t, elf_gregset_t* elfregs)
 {	
-	struct pt_regs *pp = (struct pt_regs *)(t->thread.rsp0);
-	--pp;
+	struct pt_regs *pp = task_pt_regs(t);
 	ELF_CORE_COPY_REGS((*elfregs), pp);
 	/* fix wrong segments */ 
 	(*elfregs)[7] = t->thread.ds; 
@@ -217,7 +216,7 @@
 	if (!tsk_used_math(tsk))
 		return 0;
 	if (!regs)
-		regs = ((struct pt_regs *)tsk->thread.rsp0) - 1;
+		regs = task_pt_regs(tsk);
 	if (tsk == current)
 		unlazy_fpu(tsk);
 	set_fs(KERNEL_DS); 
@@ -233,7 +232,7 @@
 static inline int 
 elf_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu)
 {
-	struct pt_regs *regs = ((struct pt_regs *)(t->thread.rsp0))-1; 
+	struct pt_regs *regs = task_pt_regs(t);
 	if (!tsk_used_math(t))
 		return 0;
 	if (t == current)
diff --git a/arch/x86_64/ia32/ptrace32.c b/arch/x86_64/ia32/ptrace32.c
index ea4394e..23a4515 100644
--- a/arch/x86_64/ia32/ptrace32.c
+++ b/arch/x86_64/ia32/ptrace32.c
@@ -41,7 +41,7 @@
 static int putreg32(struct task_struct *child, unsigned regno, u32 val)
 {
 	int i;
-	__u64 *stack = (__u64 *)(child->thread.rsp0 - sizeof(struct pt_regs)); 
+	__u64 *stack = (__u64 *)task_pt_regs(child);
 
 	switch (regno) {
 	case offsetof(struct user32, regs.fs):
@@ -137,7 +137,7 @@
 
 static int getreg32(struct task_struct *child, unsigned regno, u32 *val)
 {
-	__u64 *stack = (__u64 *)(child->thread.rsp0 - sizeof(struct pt_regs)); 
+	__u64 *stack = (__u64 *)task_pt_regs(child);
 
 	switch (regno) {
 	case offsetof(struct user32, regs.fs):
@@ -238,7 +238,7 @@
 	if (ret < 0)
 		goto out;
 
-	childregs = (struct pt_regs *)(child->thread.rsp0 - sizeof(struct pt_regs)); 
+	childregs = task_pt_regs(child);
 
 	switch (request) {
 	case PTRACE_PEEKDATA:
diff --git a/arch/x86_64/kernel/i387.c b/arch/x86_64/kernel/i387.c
index d9b22b6..a5d7e16 100644
--- a/arch/x86_64/kernel/i387.c
+++ b/arch/x86_64/kernel/i387.c
@@ -95,7 +95,7 @@
 	if (!used_math())
 		return 0;
 	clear_used_math(); /* trigger finit */
-	if (tsk->thread_info->status & TS_USEDFPU) {
+	if (task_thread_info(tsk)->status & TS_USEDFPU) {
 		err = save_i387_checking((struct i387_fxsave_struct __user *)buf);
 		if (err) return err;
 		stts();
diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c
index b61965f..5ecd34a 100644
--- a/arch/x86_64/kernel/i8259.c
+++ b/arch/x86_64/kernel/i8259.c
@@ -133,7 +133,7 @@
 {
 	if (irq > 256) { 
 		char var;
-		printk("return %p stack %p ti %p\n", __builtin_return_address(0), &var, current->thread_info); 
+		printk("return %p stack %p ti %p\n", __builtin_return_address(0), &var, task_thread_info(current));
 
 		BUG(); 
 	}
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 669cf0e..8ded407 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -451,7 +451,7 @@
 	struct task_struct *me = current;
 
 	childregs = ((struct pt_regs *)
-			(THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
+			(THREAD_SIZE + task_stack_page(p))) - 1;
 	*childregs = *regs;
 
 	childregs->rax = 0;
@@ -463,7 +463,7 @@
 	p->thread.rsp0 = (unsigned long) (childregs+1);
 	p->thread.userrsp = me->thread.userrsp; 
 
-	set_ti_thread_flag(p->thread_info, TIF_FORK);
+	set_tsk_thread_flag(p, TIF_FORK);
 
 	p->thread.fs = me->thread.fs;
 	p->thread.gs = me->thread.gs;
@@ -590,7 +590,7 @@
 	write_pda(oldrsp, next->userrsp); 
 	write_pda(pcurrent, next_p); 
 	write_pda(kernelstack,
-	    (unsigned long)next_p->thread_info + THREAD_SIZE - PDA_STACKOFFSET);
+		  task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
 
 	/*
 	 * Now maybe reload the debug registers
@@ -704,7 +704,7 @@
 
 	if (!p || p == current || p->state==TASK_RUNNING)
 		return 0; 
-	stack = (unsigned long)p->thread_info; 
+	stack = (unsigned long)task_stack_page(p);
 	if (p->thread.rsp < stack || p->thread.rsp > stack+THREAD_SIZE)
 		return 0;
 	fp = *(u64 *)(p->thread.rsp);
@@ -822,8 +822,7 @@
 {
 	struct pt_regs *pp, ptregs;
 
-	pp = (struct pt_regs *)(tsk->thread.rsp0);
-	--pp; 
+	pp = task_pt_regs(tsk);
 
 	ptregs = *pp; 
 	ptregs.cs &= 0xffff;
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
index 86248bc..5320562 100644
--- a/arch/x86_64/kernel/ptrace.c
+++ b/arch/x86_64/kernel/ptrace.c
@@ -67,12 +67,6 @@
 	return (*((unsigned long *)stack));
 }
 
-static inline struct pt_regs *get_child_regs(struct task_struct *task)
-{
-	struct pt_regs *regs = (void *)task->thread.rsp0;
-	return regs - 1;
-}
-
 /*
  * this routine will put a word on the processes privileged stack. 
  * the offset is how far from the base addr as stored in the TSS.  
@@ -170,7 +164,7 @@
 
 static void set_singlestep(struct task_struct *child)
 {
-	struct pt_regs *regs = get_child_regs(child);
+	struct pt_regs *regs = task_pt_regs(child);
 
 	/*
 	 * Always set TIF_SINGLESTEP - this guarantees that
@@ -208,7 +202,7 @@
 
 	/* But touch TF only if it was set by us.. */
 	if (child->ptrace & PT_DTRACE) {
-		struct pt_regs *regs = get_child_regs(child);
+		struct pt_regs *regs = task_pt_regs(child);
 		regs->eflags &= ~TRAP_FLAG;
 		child->ptrace &= ~PT_DTRACE;
 	}
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index c9e941a..a28756e 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -776,7 +776,7 @@
 
 	if (c_idle.idle) {
 		c_idle.idle->thread.rsp = (unsigned long) (((struct pt_regs *)
-			(THREAD_SIZE + (unsigned long) c_idle.idle->thread_info)) - 1);
+			(THREAD_SIZE +  task_stack_page(c_idle.idle))) - 1);
 		init_idle(c_idle.idle, cpu);
 		goto do_rest;
 	}
@@ -814,7 +814,7 @@
 	init_rsp = c_idle.idle->thread.rsp;
 	per_cpu(init_tss,cpu).rsp0 = init_rsp;
 	initial_code = start_secondary;
-	clear_ti_thread_flag(c_idle.idle->thread_info, TIF_FORK);
+	clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
 
 	printk(KERN_INFO "Booting processor %d/%d APIC 0x%x\n", cpu,
 		cpus_weight(cpu_present_map),
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index 2671fd4..8bb0aed 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -308,7 +308,7 @@
 	printk("CPU %d ", cpu);
 	__show_regs(regs);
 	printk("Process %s (pid: %d, threadinfo %p, task %p)\n",
-		cur->comm, cur->pid, cur->thread_info, cur);
+		cur->comm, cur->pid, task_thread_info(cur), cur);
 
 	/*
 	 * When in-kernel, we also print out the stack and code at the
@@ -666,7 +666,7 @@
 		;
 	/* Exception from user space */
 	else if (user_mode(eregs))
-		regs = ((struct pt_regs *)current->thread.rsp0) - 1;
+		regs = task_pt_regs(current);
 	/* Exception from kernel and interrupts are enabled. Move to
  	   kernel process stack. */
 	else if (eregs->eflags & X86_EFLAGS_IF)
@@ -912,7 +912,7 @@
 	if (!used_math())
 		init_fpu(me);
 	restore_fpu_checking(&me->thread.i387.fxsave);
-	me->thread_info->status |= TS_USEDFPU;
+	task_thread_info(me)->status |= TS_USEDFPU;
 }
 
 void __init trap_init(void)
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
index 6a44b54..f1f5966 100644
--- a/arch/xtensa/kernel/process.c
+++ b/arch/xtensa/kernel/process.c
@@ -145,7 +145,7 @@
 	int user_mode = user_mode(regs);
 
 	/* Set up new TSS. */
-	tos = (unsigned long)p->thread_info + THREAD_SIZE;
+	tos = (unsigned long)task_stack_page(p) + THREAD_SIZE;
 	if (user_mode)
 		childregs = (struct pt_regs*)(tos - PT_USER_SIZE);
 	else
@@ -217,7 +217,7 @@
 unsigned long get_wchan(struct task_struct *p)
 {
 	unsigned long sp, pc;
-	unsigned long stack_page = (unsigned long) p->thread_info;
+	unsigned long stack_page = (unsigned long) task_stack_page(p);
 	int count = 0;
 
 	if (!p || p == current || p->state == TASK_RUNNING)
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
index ab5c4c6..4cc8528 100644
--- a/arch/xtensa/kernel/ptrace.c
+++ b/arch/xtensa/kernel/ptrace.c
@@ -72,7 +72,7 @@
 		struct pt_regs *regs;
 		unsigned long tmp;
 
-		regs = xtensa_pt_regs(child);
+		regs = task_pt_regs(child);
 		tmp = 0;  /* Default return value. */
 
 		switch(addr) {
@@ -149,7 +149,7 @@
 	case PTRACE_POKEUSR:
 		{
 		struct pt_regs *regs;
-		regs = xtensa_pt_regs(child);
+		regs = task_pt_regs(child);
 
 		switch (addr) {
 		case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1:
@@ -240,7 +240,7 @@
 		 * elf_gregset_t format. */
 
 		xtensa_gregset_t format;
-		struct pt_regs *regs = xtensa_pt_regs(child);
+		struct pt_regs *regs = task_pt_regs(child);
 
 		do_copy_regs (&format, regs, child);
 
@@ -257,7 +257,7 @@
 		 * values in the elf_gregset_t format. */
 
 		xtensa_gregset_t format;
-		struct pt_regs *regs = xtensa_pt_regs(child);
+		struct pt_regs *regs = task_pt_regs(child);
 
 		if (copy_from_user(&format,(void *)data,sizeof(elf_gregset_t))){
 			ret = -EFAULT;
@@ -281,7 +281,7 @@
 		 * elf_fpregset_t format. */
 
 		elf_fpregset_t fpregs;
-		struct pt_regs *regs = xtensa_pt_regs(child);
+		struct pt_regs *regs = task_pt_regs(child);
 
 		do_save_fpregs (&fpregs, regs, child);
 
@@ -299,7 +299,7 @@
 		 * values in the elf_fpregset_t format.
 		 */
 		elf_fpregset_t fpregs;
-		struct pt_regs *regs = xtensa_pt_regs(child);
+		struct pt_regs *regs = task_pt_regs(child);
 
 		ret = 0;
 		if (copy_from_user(&fpregs, (void *)data, sizeof(elf_fpregset_t))) {
diff --git a/block/elevator.c b/block/elevator.c
index 99a4d7b..1d075917 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -610,23 +610,23 @@
 	 * request is released from the driver, io must be done
 	 */
 	if (blk_account_rq(rq)) {
-		struct request *first_rq = list_entry_rq(q->queue_head.next);
-
 		q->in_flight--;
+		if (blk_sorted_rq(rq) && e->ops->elevator_completed_req_fn)
+			e->ops->elevator_completed_req_fn(q, rq);
+	}
 
-		/*
-		 * Check if the queue is waiting for fs requests to be
-		 * drained for flush sequence.
-		 */
-		if (q->ordseq && q->in_flight == 0 &&
+	/*
+	 * Check if the queue is waiting for fs requests to be
+	 * drained for flush sequence.
+	 */
+	if (unlikely(q->ordseq)) {
+		struct request *first_rq = list_entry_rq(q->queue_head.next);
+		if (q->in_flight == 0 &&
 		    blk_ordered_cur_seq(q) == QUEUE_ORDSEQ_DRAIN &&
 		    blk_ordered_req_seq(first_rq) > QUEUE_ORDSEQ_DRAIN) {
 			blk_ordered_complete_seq(q, QUEUE_ORDSEQ_DRAIN, 0);
 			q->request_fn(q);
 		}
-
-		if (blk_sorted_rq(rq) && e->ops->elevator_completed_req_fn)
-			e->ops->elevator_completed_req_fn(q, rq);
 	}
 }
 
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 3c679d3..b6e2909 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -194,6 +194,8 @@
  */
 #define MAX_ERRORS 12
 
+#define custom amiga_custom
+
 /* Prevent "aliased" accesses. */
 static int fd_ref[4] = { 0,0,0,0 };
 static int fd_device[4] = { 0, 0, 0, 0 };
@@ -1439,6 +1441,7 @@
 {
 	int drive = iminor(inode) & 3;
 	static struct floppy_struct getprm;
+	void __user *argp = (void __user *)param;
 
 	switch(cmd){
 	case FDFMTBEG:
@@ -1484,9 +1487,7 @@
 		getprm.head=unit[drive].type->heads;
 		getprm.sect=unit[drive].dtype->sects * unit[drive].type->sect_mult;
 		getprm.size=unit[drive].blocks;
-		if (copy_to_user((void *)param,
-				 (void *)&getprm,
-				 sizeof(struct floppy_struct)))
+		if (copy_to_user(argp, &getprm, sizeof(struct floppy_struct)))
 			return -EFAULT;
 		break;
 	case FDSETPRM:
@@ -1498,8 +1499,7 @@
 		break;
 #ifdef RAW_IOCTL
 	case IOCTL_RAW_TRACK:
-		if (copy_to_user((void *)param, raw_buf,
-				 unit[drive].type->read_size))
+		if (copy_to_user(argp, raw_buf, unit[drive].type->read_size))
 			return -EFAULT;
 		else
 			return unit[drive].type->read_size;
@@ -1654,12 +1654,6 @@
 	.media_changed	= amiga_floppy_change,
 };
 
-void __init amiga_floppy_setup (char *str, int *ints)
-{
-	printk (KERN_INFO "amiflop: Setting default df0 to %x\n", ints[1]);
-	fd_def_df0 = ints[1];
-}
-
 static int __init fd_probe_drives(void)
 {
 	int drive,drives,nomem;
@@ -1845,4 +1839,18 @@
 	unregister_blkdev(FLOPPY_MAJOR, "fd");
 }
 #endif
+
+#else
+static int __init amiga_floppy_setup (char *str)
+{
+	int n;
+	if (!MACH_IS_AMIGA)
+		return 0;
+	if (!get_option(&str, &n))
+		return 0;
+	printk (KERN_INFO "amiflop: Setting default df0 to %x\n", n);
+	fd_def_df0 = n;
+}
+
+__setup("floppy=", amiga_floppy_setup);
 #endif
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index 3aa68a5..f8ce235 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -1361,7 +1361,7 @@
 		   formats, for 'permanent user-defined' parameter:
 		   restore default_params[] here if flagged valid! */
 		if (default_params[drive].blocks == 0)
-			UDT = 0;
+			UDT = NULL;
 		else
 			UDT = &default_params[drive];
 	}
@@ -1495,6 +1495,7 @@
 	struct floppy_struct getprm;
 	int settype;
 	struct floppy_struct setprm;
+	void __user *argp = (void __user *)param;
 
 	switch (cmd) {
 	case FDGETPRM:
@@ -1521,7 +1522,7 @@
 		getprm.head = 2;
 		getprm.track = dtp->blocks/dtp->spt/2;
 		getprm.stretch = dtp->stretch;
-		if (copy_to_user((void *)param, &getprm, sizeof(getprm)))
+		if (copy_to_user(argp, &getprm, sizeof(getprm)))
 			return -EFAULT;
 		return 0;
 	}
@@ -1540,7 +1541,7 @@
 		/* get the parameters from user space */
 		if (floppy->ref != 1 && floppy->ref != -1)
 			return -EBUSY;
-		if (copy_from_user(&setprm, (void *) param, sizeof(setprm)))
+		if (copy_from_user(&setprm, argp, sizeof(setprm)))
 			return -EFAULT;
 		/* 
 		 * first of all: check for floppy change and revalidate, 
@@ -1647,7 +1648,7 @@
 	case FDFMTTRK:
 		if (floppy->ref != 1 && floppy->ref != -1)
 			return -EBUSY;
-		if (copy_from_user(&fmt_desc, (void *) param, sizeof(fmt_desc)))
+		if (copy_from_user(&fmt_desc, argp, sizeof(fmt_desc)))
 			return -EFAULT;
 		return do_format(drive, type, &fmt_desc);
 	case FDCLRPRM:
@@ -1950,14 +1951,20 @@
 	return -ENOMEM;
 }
 
-
-void __init atari_floppy_setup( char *str, int *ints )
+#ifndef MODULE
+static int __init atari_floppy_setup(char *str)
 {
+	int ints[3 + FD_MAX_UNITS];
 	int i;
+
+	if (!MACH_IS_ATARI)
+		return 0;
+
+	str = get_options(str, 3 + FD_MAX_UNITS, ints);
 	
 	if (ints[0] < 1) {
 		printk(KERN_ERR "ataflop_setup: no arguments!\n" );
-		return;
+		return 0;
 	}
 	else if (ints[0] > 2+FD_MAX_UNITS) {
 		printk(KERN_ERR "ataflop_setup: too many arguments\n" );
@@ -1977,9 +1984,13 @@
 		else
 			UserSteprate[i-3] = ints[i];
 	}
+	return 1;
 }
 
-static void atari_floppy_exit(void)
+__setup("floppy=", atari_floppy_setup);
+#endif
+
+static void __exit atari_floppy_exit(void)
 {
 	int i;
 	blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index d1aaf31b..f63e07b 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -293,6 +293,7 @@
 	u16 viocmd;
 	HvLpEvent_Rc hvrc;
 	struct vioblocklpevent *bevent;
+	struct HvLpEvent *hev;
 	struct scatterlist sg[VIOMAXBLOCKDMA];
 	int sgindex;
 	int statindex;
@@ -347,22 +348,19 @@
 		 * token so we can match the response up later
 		 */
 		memset(bevent, 0, sizeof(struct vioblocklpevent));
-		bevent->event.xFlags.xValid = 1;
-		bevent->event.xFlags.xFunction = HvLpEvent_Function_Int;
-		bevent->event.xFlags.xAckInd = HvLpEvent_AckInd_DoAck;
-		bevent->event.xFlags.xAckType = HvLpEvent_AckType_ImmediateAck;
-		bevent->event.xType = HvLpEvent_Type_VirtualIo;
-		bevent->event.xSubtype = viocmd;
-		bevent->event.xSourceLp = HvLpConfig_getLpIndex();
-		bevent->event.xTargetLp = viopath_hostLp;
-		bevent->event.xSizeMinus1 =
+		hev = &bevent->event;
+		hev->flags = HV_LP_EVENT_VALID | HV_LP_EVENT_DO_ACK |
+			HV_LP_EVENT_INT;
+		hev->xType = HvLpEvent_Type_VirtualIo;
+		hev->xSubtype = viocmd;
+		hev->xSourceLp = HvLpConfig_getLpIndex();
+		hev->xTargetLp = viopath_hostLp;
+		hev->xSizeMinus1 =
 			offsetof(struct vioblocklpevent, u.rw_data.dma_info) +
 			(sizeof(bevent->u.rw_data.dma_info[0]) * nsg) - 1;
-		bevent->event.xSourceInstanceId =
-			viopath_sourceinst(viopath_hostLp);
-		bevent->event.xTargetInstanceId =
-			viopath_targetinst(viopath_hostLp);
-		bevent->event.xCorrelationToken = (u64)req;
+		hev->xSourceInstanceId = viopath_sourceinst(viopath_hostLp);
+		hev->xTargetInstanceId = viopath_targetinst(viopath_hostLp);
+		hev->xCorrelationToken = (u64)req;
 		bevent->version = VIOVERSION;
 		bevent->disk = DEVICE_NO(d);
 		bevent->u.rw_data.offset = start;
@@ -649,10 +647,10 @@
 		/* Notification that a partition went away! */
 		return;
 	/* First, we should NEVER get an int here...only acks */
-	if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
+	if (hvlpevent_is_int(event)) {
 		printk(VIOD_KERN_WARNING
 		       "Yikes! got an int in viodasd event handler!\n");
-		if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) {
+		if (hvlpevent_need_ack(event)) {
 			event->xRc = HvLpEvent_Rc_InvalidSubtype;
 			HvCallEvent_ackLpEvent(event);
 		}
@@ -695,7 +693,7 @@
 
 	default:
 		printk(VIOD_KERN_WARNING "invalid subtype!");
-		if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) {
+		if (hvlpevent_need_ack(event)) {
 			event->xRc = HvLpEvent_Rc_InvalidSubtype;
 			HvCallEvent_ackLpEvent(event);
 		}
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index b519178..193446e 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -542,10 +542,10 @@
 		/* Notification that a partition went away! */
 		return;
 	/* First, we should NEVER get an int here...only acks */
-	if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
+	if (hvlpevent_is_int(event)) {
 		printk(VIOCD_KERN_WARNING
 				"Yikes! got an int in viocd event handler!\n");
-		if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) {
+		if (hvlpevent_need_ack(event)) {
 			event->xRc = HvLpEvent_Rc_InvalidSubtype;
 			HvCallEvent_ackLpEvent(event);
 		}
@@ -616,7 +616,7 @@
 		printk(VIOCD_KERN_WARNING
 				"message with invalid subtype %0x04X!\n",
 				event->xSubtype & VIOMINOR_SUBTYPE_MASK);
-		if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) {
+		if (hvlpevent_need_ack(event)) {
 			event->xRc = HvLpEvent_Rc_InvalidSubtype;
 			HvCallEvent_ackLpEvent(event);
 		}
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 869518e..667a21c 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -99,6 +99,7 @@
 #define _INLINE_ inline
 #endif
 
+#define custom amiga_custom
 static char *serial_name = "Amiga-builtin serial driver";
 
 static struct tty_driver *serial_driver;
@@ -1088,7 +1089,7 @@
  */
 
 static int get_serial_info(struct async_struct * info,
-			   struct serial_struct * retinfo)
+			   struct serial_struct __user * retinfo)
 {
 	struct serial_struct tmp;
 	struct serial_state *state = info->state;
@@ -1112,7 +1113,7 @@
 }
 
 static int set_serial_info(struct async_struct * info,
-			   struct serial_struct * new_info)
+			   struct serial_struct __user * new_info)
 {
 	struct serial_struct new_serial;
  	struct serial_state old_state, *state;
@@ -1193,7 +1194,7 @@
  * 	    transmit holding register is empty.  This functionality
  * 	    allows an RS485 driver to be written in user space. 
  */
-static int get_lsr_info(struct async_struct * info, unsigned int *value)
+static int get_lsr_info(struct async_struct * info, unsigned int __user *value)
 {
 	unsigned char status;
 	unsigned int result;
@@ -1284,6 +1285,7 @@
 	struct async_struct * info = (struct async_struct *)tty->driver_data;
 	struct async_icount cprev, cnow;	/* kernel counter temps */
 	struct serial_icounter_struct icount;
+	void __user *argp = (void __user *)arg;
 	unsigned long flags;
 
 	if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
@@ -1298,19 +1300,17 @@
 
 	switch (cmd) {
 		case TIOCGSERIAL:
-			return get_serial_info(info,
-					       (struct serial_struct *) arg);
+			return get_serial_info(info, argp);
 		case TIOCSSERIAL:
-			return set_serial_info(info,
-					       (struct serial_struct *) arg);
+			return set_serial_info(info, argp);
 		case TIOCSERCONFIG:
 			return 0;
 
 		case TIOCSERGETLSR: /* Get line status register */
-			return get_lsr_info(info, (unsigned int *) arg);
+			return get_lsr_info(info, argp);
 
 		case TIOCSERGSTRUCT:
-			if (copy_to_user((struct async_struct *) arg,
+			if (copy_to_user(argp,
 					 info, sizeof(struct async_struct)))
 				return -EFAULT;
 			return 0;
@@ -1369,7 +1369,7 @@
 			icount.brk = cnow.brk;
 			icount.buf_overrun = cnow.buf_overrun;
 
-			if (copy_to_user((void *)arg, &icount, sizeof(icount)))
+			if (copy_to_user(argp, &icount, sizeof(icount)))
 				return -EFAULT;
 			return 0;
 		case TIOCSERGWILD:
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index 8693835..e233cf2 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -165,7 +165,7 @@
 	return 0;
 }
 
-static int dsp56k_upload(u_char *bin, int len)
+static int dsp56k_upload(u_char __user *bin, int len)
 {
 	int i;
 	u_char *p;
@@ -199,7 +199,7 @@
 	return 0;
 }
 
-static ssize_t dsp56k_read(struct file *file, char *buf, size_t count,
+static ssize_t dsp56k_read(struct file *file, char __user *buf, size_t count,
 			   loff_t *ppos)
 {
 	struct inode *inode = file->f_dentry->d_inode;
@@ -225,10 +225,10 @@
 		}
 		case 2:  /* 16 bit */
 		{
-			short *data;
+			short __user *data;
 
 			count /= 2;
-			data = (short*) buf;
+			data = (short __user *) buf;
 			handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_RECEIVE,
 				  put_user(dsp56k_host_interface.data.w[1], data+n++));
 			return 2*n;
@@ -244,10 +244,10 @@
 		}
 		case 4:  /* 32 bit */
 		{
-			long *data;
+			long __user *data;
 
 			count /= 4;
-			data = (long*) buf;
+			data = (long __user *) buf;
 			handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_RECEIVE,
 				  put_user(dsp56k_host_interface.data.l, data+n++));
 			return 4*n;
@@ -262,7 +262,7 @@
 	}
 }
 
-static ssize_t dsp56k_write(struct file *file, const char *buf, size_t count,
+static ssize_t dsp56k_write(struct file *file, const char __user *buf, size_t count,
 			    loff_t *ppos)
 {
 	struct inode *inode = file->f_dentry->d_inode;
@@ -287,10 +287,10 @@
 		}
 		case 2:  /* 16 bit */
 		{
-			const short *data;
+			const short __user *data;
 
 			count /= 2;
-			data = (const short *)buf;
+			data = (const short __user *)buf;
 			handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_TRANSMIT,
 				  get_user(dsp56k_host_interface.data.w[1], data+n++));
 			return 2*n;
@@ -306,10 +306,10 @@
 		}
 		case 4:  /* 32 bit */
 		{
-			const long *data;
+			const long __user *data;
 
 			count /= 4;
-			data = (const long *)buf;
+			data = (const long __user *)buf;
 			handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_TRANSMIT,
 				  get_user(dsp56k_host_interface.data.l, data+n++));
 			return 4*n;
@@ -328,6 +328,7 @@
 			unsigned int cmd, unsigned long arg)
 {
 	int dev = iminor(inode) & 0x0f;
+	void __user *argp = (void __user *)arg;
 
 	switch(dev)
 	{
@@ -336,9 +337,9 @@
 		switch(cmd) {
 		case DSP56K_UPLOAD:
 		{
-			char *bin;
+			char __user *bin;
 			int r, len;
-			struct dsp56k_upload *binary = (struct dsp56k_upload *) arg;
+			struct dsp56k_upload __user *binary = argp;
     
 			if(get_user(len, &binary->len) < 0)
 				return -EFAULT;
@@ -372,7 +373,7 @@
 		case DSP56K_HOST_FLAGS:
 		{
 			int dir, out, status;
-			struct dsp56k_host_flags *hf = (struct dsp56k_host_flags*) arg;
+			struct dsp56k_host_flags __user *hf = argp;
     
 			if(get_user(dir, &hf->dir) < 0)
 				return -EFAULT;
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 704c3c0..29c41f4 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -534,7 +534,7 @@
  	return virtr + wrote;
 }
 
-#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI))
+#if defined(CONFIG_ISA) || !defined(__mc68000__)
 static ssize_t read_port(struct file * file, char __user * buf,
 			 size_t count, loff_t *ppos)
 {
@@ -795,7 +795,7 @@
 	.write		= write_null,
 };
 
-#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI))
+#if defined(CONFIG_ISA) || !defined(__mc68000__)
 static struct file_operations port_fops = {
 	.llseek		= memory_lseek,
 	.read		= read_port,
@@ -865,7 +865,7 @@
 		case 3:
 			filp->f_op = &null_fops;
 			break;
-#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI))
+#if defined(CONFIG_ISA) || !defined(__mc68000__)
 		case 4:
 			filp->f_op = &port_fops;
 			break;
@@ -912,7 +912,7 @@
 	{1, "mem",     S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
 	{2, "kmem",    S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
 	{3, "null",    S_IRUGO | S_IWUGO,           &null_fops},
-#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI))
+#if defined(CONFIG_ISA) || !defined(__mc68000__)
 	{4, "port",    S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
 #endif
 	{5, "zero",    S_IRUGO | S_IWUGO,           &zero_fops},
diff --git a/drivers/char/scc.h b/drivers/char/scc.h
index 51810f7..93998f5 100644
--- a/drivers/char/scc.h
+++ b/drivers/char/scc.h
@@ -399,7 +399,7 @@
 		__asm__ __volatile__ ( "tstb %0" : : "g" (*_scc_del) : "cc" );\
     } while (0)
 
-extern unsigned char scc_shadow[2][16];
+static unsigned char scc_shadow[2][16];
 
 /* The following functions should relax the somehow complicated
  * register access of the SCC. _SCCwrite() stores all written values
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c
index faee5e7..4e53603 100644
--- a/drivers/char/viocons.c
+++ b/drivers/char/viocons.c
@@ -476,19 +476,19 @@
  */
 static void initDataEvent(struct viocharlpevent *viochar, HvLpIndex lp)
 {
+	struct HvLpEvent *hev = &viochar->event;
+
 	memset(viochar, 0, sizeof(struct viocharlpevent));
 
-	viochar->event.xFlags.xValid = 1;
-	viochar->event.xFlags.xFunction = HvLpEvent_Function_Int;
-	viochar->event.xFlags.xAckInd = HvLpEvent_AckInd_NoAck;
-	viochar->event.xFlags.xAckType = HvLpEvent_AckType_DeferredAck;
-	viochar->event.xType = HvLpEvent_Type_VirtualIo;
-	viochar->event.xSubtype = viomajorsubtype_chario | viochardata;
-	viochar->event.xSourceLp = HvLpConfig_getLpIndex();
-	viochar->event.xTargetLp = lp;
-	viochar->event.xSizeMinus1 = sizeof(struct viocharlpevent);
-	viochar->event.xSourceInstanceId = viopath_sourceinst(lp);
-	viochar->event.xTargetInstanceId = viopath_targetinst(lp);
+	hev->flags = HV_LP_EVENT_VALID | HV_LP_EVENT_DEFERRED_ACK |
+		HV_LP_EVENT_INT;
+	hev->xType = HvLpEvent_Type_VirtualIo;
+	hev->xSubtype = viomajorsubtype_chario | viochardata;
+	hev->xSourceLp = HvLpConfig_getLpIndex();
+	hev->xTargetLp = lp;
+	hev->xSizeMinus1 = sizeof(struct viocharlpevent);
+	hev->xSourceInstanceId = viopath_sourceinst(lp);
+	hev->xTargetInstanceId = viopath_targetinst(lp);
 }
 
 /*
@@ -752,7 +752,7 @@
 	struct port_info *pi;
 	int reject = 0;
 
-	if (event->xFlags.xFunction == HvLpEvent_Function_Ack) {
+	if (hvlpevent_is_ack(event)) {
 		if (port >= VTTY_PORTS)
 			return;
 
@@ -788,7 +788,7 @@
 	}
 
 	/* This had better require an ack, otherwise complain */
-	if (event->xFlags.xAckInd != HvLpEvent_AckInd_DoAck) {
+	if (!hvlpevent_need_ack(event)) {
 		printk(VIOCONS_KERN_WARN "viocharopen without ack bit!\n");
 		return;
 	}
@@ -856,7 +856,7 @@
 	struct viocharlpevent *cevent = (struct viocharlpevent *)event;
 	u8 port = cevent->virtual_device;
 
-	if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
+	if (hvlpevent_is_int(event)) {
 		if (port >= VTTY_PORTS) {
 			printk(VIOCONS_KERN_WARN
 					"close message from invalid virtual device.\n");
@@ -1056,8 +1056,7 @@
 		vioHandleConfig(event);
 		break;
 	default:
-		if ((event->xFlags.xFunction == HvLpEvent_Function_Int) &&
-		    (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck)) {
+		if (hvlpevent_is_int(event) && hvlpevent_need_ack(event)) {
 			event->xRc = HvLpEvent_Rc_InvalidSubtype;
 			HvCallEvent_ackLpEvent(event);
 		}
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 362b335..745979f 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -159,7 +159,7 @@
 #ifdef CONFIG_X86_64
 #  define COMPAT_TEST is_compat_task()
 #elif defined(CONFIG_IA64)
-#  define COMPAT_TEST IS_IA32_PROCESS(ia64_task_regs(current))
+#  define COMPAT_TEST IS_IA32_PROCESS(task_pt_regs(current))
 #elif defined(CONFIG_S390)
 #  define COMPAT_TEST test_thread_flag(TIF_31BIT)
 #elif defined(CONFIG_MIPS)
diff --git a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c
index 8558a99..ec55a29 100644
--- a/drivers/input/joystick/amijoy.c
+++ b/drivers/input/joystick/amijoy.c
@@ -64,8 +64,8 @@
 		if (amijoy[i]) {
 
 			switch (i) {
-				case 0: data = ~custom.joy0dat; button = (~ciaa.pra >> 6) & 1; break;
-				case 1: data = ~custom.joy1dat; button = (~ciaa.pra >> 7) & 1; break;
+				case 0: data = ~amiga_custom.joy0dat; button = (~ciaa.pra >> 6) & 1; break;
+				case 1: data = ~amiga_custom.joy1dat; button = (~ciaa.pra >> 7) & 1; break;
 			}
 
 			input_regs(amijoy_dev[i], fp);
diff --git a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c
index d13d4c8..c8b2cc9 100644
--- a/drivers/input/mouse/amimouse.c
+++ b/drivers/input/mouse/amimouse.c
@@ -41,7 +41,7 @@
 	unsigned short joy0dat, potgor;
 	int nx, ny, dx, dy;
 
-	joy0dat = custom.joy0dat;
+	joy0dat = amiga_custom.joy0dat;
 
 	nx = joy0dat & 0xff;
 	ny = joy0dat >> 8;
@@ -57,7 +57,7 @@
 	amimouse_lastx = nx;
 	amimouse_lasty = ny;
 
-	potgor = custom.potgor;
+	potgor = amiga_custom.potgor;
 
 	input_regs(amimouse_dev, fp);
 
@@ -77,7 +77,7 @@
 {
 	unsigned short joy0dat;
 
-	joy0dat = custom.joy0dat;
+	joy0dat = amiga_custom.joy0dat;
 
 	amimouse_lastx = joy0dat & 0xff;
 	amimouse_lasty = joy0dat >> 8;
diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c
index 71aeb91..d56d400 100644
--- a/drivers/macintosh/adb-iop.c
+++ b/drivers/macintosh/adb-iop.c
@@ -239,7 +239,7 @@
 
 	local_irq_save(flags);
 
-	req->next = 0;
+	req->next = NULL;
 	req->sent = 0;
 	req->complete = 0;
 	req->reply_len = 0;
diff --git a/drivers/macintosh/via-macii.c b/drivers/macintosh/via-macii.c
index e9a159a..2a2ffe0 100644
--- a/drivers/macintosh/via-macii.c
+++ b/drivers/macintosh/via-macii.c
@@ -260,7 +260,7 @@
 		return -EINVAL;
 	}
 	
-	req->next = 0;
+	req->next = NULL;
 	req->sent = 0;
 	req->complete = 0;
 	req->reply_len = 0;
@@ -295,7 +295,7 @@
 	unsigned long flags;
 
 	local_irq_save(flags);
-	if (via[IFR] & SR_INT) macii_interrupt(0, 0, 0);
+	if (via[IFR] & SR_INT) macii_interrupt(0, NULL, NULL);
 	local_irq_restore(flags);
 }
 
diff --git a/drivers/macintosh/via-maciisi.c b/drivers/macintosh/via-maciisi.c
index a196697..0129fcc 100644
--- a/drivers/macintosh/via-maciisi.c
+++ b/drivers/macintosh/via-maciisi.c
@@ -294,6 +294,24 @@
 		printk(KERN_ERR "maciisi_send_request: poll timed out!\n");
 }
 
+int
+maciisi_request(struct adb_request *req, void (*done)(struct adb_request *),
+	    int nbytes, ...)
+{
+	va_list list;
+	int i;
+
+	req->nbytes = nbytes;
+	req->done = done;
+	req->reply_expected = 0;
+	va_start(list, nbytes);
+	for (i = 0; i < nbytes; i++)
+		req->data[i++] = va_arg(list, int);
+	va_end(list);
+
+	return maciisi_send_request(req, 1);
+}
+
 /* Enqueue a request, and run the queue if possible */
 static int
 maciisi_write(struct adb_request* req)
@@ -308,7 +326,7 @@
 		req->complete = 1;
 		return -EINVAL;
 	}
-	req->next = 0;
+	req->next = NULL;
 	req->sent = 0;
 	req->complete = 0;
 	req->reply_len = 0;
@@ -403,7 +421,7 @@
 
 	local_irq_save(flags);
 	if (via[IFR] & SR_INT) {
-		maciisi_interrupt(0, 0, 0);
+		maciisi_interrupt(0, NULL, NULL);
 	}
 	else /* avoid calling this function too quickly in a loop */
 		udelay(ADB_DELAY);
diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c
index 6f80d76..f08e52f 100644
--- a/drivers/macintosh/via-pmu68k.c
+++ b/drivers/macintosh/via-pmu68k.c
@@ -493,7 +493,7 @@
 		return -EINVAL;
 	}
 
-	req->next = 0;
+	req->next = NULL;
 	req->sent = 0;
 	req->complete = 0;
 	local_irq_save(flags);
@@ -717,7 +717,7 @@
 				printk(KERN_ERR "PMU: extra ADB reply\n");
 				return;
 			}
-			req_awaiting_reply = 0;
+			req_awaiting_reply = NULL;
 			if (len <= 2)
 				req->reply_len = 0;
 			else {
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 0302723f..1778104 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1238,6 +1238,7 @@
 	mdk_rdev_t *same_pdev;
 	char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE];
 	struct kobject *ko;
+	char *s;
 
 	if (rdev->mddev) {
 		MD_BUG();
@@ -1277,6 +1278,8 @@
 	bdevname(rdev->bdev,b);
 	if (kobject_set_name(&rdev->kobj, "dev-%s", b) < 0)
 		return -ENOMEM;
+	while ( (s=strchr(rdev->kobj.k_name, '/')) != NULL)
+		*s = '!';
 			
 	list_add(&rdev->same_set, &mddev->disks);
 	rdev->mddev = mddev;
diff --git a/drivers/net/hplance.c b/drivers/net/hplance.c
index 08703d6..d841063 100644
--- a/drivers/net/hplance.c
+++ b/drivers/net/hplance.c
@@ -150,7 +150,7 @@
         lp->lance.name = (char*)d->name;                /* discards const, shut up gcc */
         lp->lance.base = va;
         lp->lance.init_block = (struct lance_init_block *)(va + HPLANCE_MEMOFF); /* CPU addr */
-        lp->lance.lance_init_block = 0;                 /* LANCE addr of same RAM */
+        lp->lance.lance_init_block = NULL;              /* LANCE addr of same RAM */
         lp->lance.busmaster_regval = LE_C3_BSWP;        /* we're bigendian */
         lp->lance.irq = d->ipl;
         lp->lance.writerap = hplance_writerap;
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index 77eadf8..f0f04be 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -590,9 +590,9 @@
 {
 	struct veth_lpevent *veth_event = (struct veth_lpevent *)event;
 
-	if (event->xFlags.xFunction == HvLpEvent_Function_Ack)
+	if (hvlpevent_is_ack(event))
 		veth_handle_ack(veth_event);
-	else if (event->xFlags.xFunction == HvLpEvent_Function_Int)
+	else
 		veth_handle_int(veth_event);
 }
 
diff --git a/drivers/net/mac8390.c b/drivers/net/mac8390.c
index d8c99f0..06cb460 100644
--- a/drivers/net/mac8390.c
+++ b/drivers/net/mac8390.c
@@ -559,55 +559,52 @@
 /* directly from daynaport.c by Alan Cox */
 static void dayna_memcpy_fromcard(struct net_device *dev, void *to, int from, int count)
 {
-	volatile unsigned short *ptr;
-	unsigned short *target=to;
+	volatile unsigned char *ptr;
+	unsigned char *target=to;
 	from<<=1;	/* word, skip overhead */
-	ptr=(unsigned short *)(dev->mem_start+from);
+	ptr=(unsigned char *)(dev->mem_start+from);
 	/* Leading byte? */
 	if (from&2) {
-		*((char *)target)++ = *(((char *)ptr++)-1);
+		*target++ = ptr[-1];
+		ptr += 2;
 		count--;
 	}
 	while(count>=2)
 	{
-		*target++=*ptr++;	/* Copy and */
-		ptr++;			/* skip cruft */
+		*(unsigned short *)target = *(unsigned short volatile *)ptr;
+		ptr += 4;			/* skip cruft */
+		target += 2;
 		count-=2;
 	}
 	/* Trailing byte? */
 	if(count)
-	{
-		/* Big endian */
-		unsigned short v=*ptr;
-		*((char *)target)=v>>8;
-	}
+		*target = *ptr;
 }
 
 static void dayna_memcpy_tocard(struct net_device *dev, int to, const void *from, int count)
 {
 	volatile unsigned short *ptr;
-	const unsigned short *src=from;
+	const unsigned char *src=from;
 	to<<=1;	/* word, skip overhead */
 	ptr=(unsigned short *)(dev->mem_start+to);
 	/* Leading byte? */
 	if (to&2) { /* avoid a byte write (stomps on other data) */
-		ptr[-1] = (ptr[-1]&0xFF00)|*((unsigned char *)src)++;
+		ptr[-1] = (ptr[-1]&0xFF00)|*src++;
 		ptr++;
 		count--;
 	}
 	while(count>=2)
 	{
-		*ptr++=*src++;		/* Copy and */
+		*ptr++=*(unsigned short *)src;		/* Copy and */
 		ptr++;			/* skip cruft */
+		src += 2;
 		count-=2;
 	}
 	/* Trailing byte? */
 	if(count)
 	{
-		/* Big endian */
-		unsigned short v=*src;
 		/* card doesn't like byte writes */
-		*ptr=(*ptr&0x00FF)|(v&0xFF00);
+		*ptr=(*ptr&0x00FF)|(*src << 8);
 	}
 }
 
diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c
index 5c8fcd4..01bdb233 100644
--- a/drivers/net/sun3lance.c
+++ b/drivers/net/sun3lance.c
@@ -389,7 +389,7 @@
 	dev->stop = &lance_close;
 	dev->get_stats = &lance_get_stats;
 	dev->set_multicast_list = &set_multicast_list;
-	dev->set_mac_address = 0;
+	dev->set_mac_address = NULL;
 //	KLUDGE -- REMOVE ME
 	set_bit(__LINK_STATE_PRESENT, &dev->state);
 
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index f062ea0..6e0c059 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -45,7 +45,7 @@
 obj-$(CONFIG_BLZ2060_SCSI)	+= NCR53C9x.o	blz2060.o
 obj-$(CONFIG_BLZ1230_SCSI)	+= NCR53C9x.o	blz1230.o
 obj-$(CONFIG_FASTLANE_SCSI)	+= NCR53C9x.o	fastlane.o
-obj-$(CONFIG_OKTAGON_SCSI)	+= NCR53C9x.o	oktagon_esp.o	oktagon_io.o
+obj-$(CONFIG_OKTAGON_SCSI)	+= NCR53C9x.o	oktagon_esp_mod.o
 obj-$(CONFIG_ATARI_SCSI)	+= atari_scsi.o
 obj-$(CONFIG_MAC_SCSI)		+= mac_scsi.o
 obj-$(CONFIG_SCSI_MAC_ESP)	+= mac_esp.o	NCR53C9x.o
@@ -164,6 +164,7 @@
 zalon7xx-objs	:= zalon.o ncr53c8xx.o
 NCR_Q720_mod-objs	:= NCR_Q720.o ncr53c8xx.o
 libata-objs	:= libata-core.o libata-scsi.o
+oktagon_esp_mod-objs	:= oktagon_esp.o oktagon_io.o
 
 # Files generated that shall be removed upon make clean
 clean-files :=	53c7xx_d.h 53c700_d.h	\
diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c
index 640590b..c7dd015 100644
--- a/drivers/scsi/NCR53C9x.c
+++ b/drivers/scsi/NCR53C9x.c
@@ -1799,6 +1799,7 @@
 		 */
 		int oldphase, i = 0; /* or where we left off last time ?? esp->current_data ?? */
 		int fifocnt = 0;
+		unsigned char *p = phys_to_virt((unsigned long)SCptr->SCp.ptr);
 
 		oldphase = esp_read(eregs->esp_status) & ESP_STAT_PMASK;
 
@@ -1860,7 +1861,7 @@
 
 				/* read fifo */
 				for(j=0;j<fifocnt;j++)
-					SCptr->SCp.ptr[i++] = esp_read(eregs->esp_fdata);
+					p[i++] = esp_read(eregs->esp_fdata);
 
 				ESPDATA(("(%d) ", i));
 
@@ -1882,7 +1883,7 @@
 
 				/* fill fifo */
 				for(j=0;j<this_count;j++)
-					esp_write(eregs->esp_fdata, SCptr->SCp.ptr[i++]);
+					esp_write(eregs->esp_fdata, p[i++]);
 
 				/* how many left if this goes out ?? */
 				hmuch -= this_count;
diff --git a/drivers/scsi/blz1230.c b/drivers/scsi/blz1230.c
index 763e409..3867ac2 100644
--- a/drivers/scsi/blz1230.c
+++ b/drivers/scsi/blz1230.c
@@ -224,7 +224,7 @@
 static void dma_dump_state(struct NCR_ESP *esp)
 {
 	ESPLOG(("intreq:<%04x>, intena:<%04x>\n",
-		custom.intreqr, custom.intenar));
+		amiga_custom.intreqr, amiga_custom.intenar));
 }
 
 void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length)
@@ -298,7 +298,7 @@
 
 static int dma_ports_p(struct NCR_ESP *esp)
 {
-	return ((custom.intenar) & IF_PORTS);
+	return ((amiga_custom.intenar) & IF_PORTS);
 }
 
 static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
diff --git a/drivers/scsi/blz2060.c b/drivers/scsi/blz2060.c
index d72d05f..4ebe69e 100644
--- a/drivers/scsi/blz2060.c
+++ b/drivers/scsi/blz2060.c
@@ -190,7 +190,7 @@
 static void dma_dump_state(struct NCR_ESP *esp)
 {
 	ESPLOG(("intreq:<%04x>, intena:<%04x>\n",
-		custom.intreqr, custom.intenar));
+		amiga_custom.intreqr, amiga_custom.intenar));
 }
 
 static void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length)
@@ -251,7 +251,7 @@
 
 static int dma_ports_p(struct NCR_ESP *esp)
 {
-	return ((custom.intenar) & IF_PORTS);
+	return ((amiga_custom.intenar) & IF_PORTS);
 }
 
 static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
diff --git a/drivers/scsi/cyberstorm.c b/drivers/scsi/cyberstorm.c
index f9b940e..a4a4fac 100644
--- a/drivers/scsi/cyberstorm.c
+++ b/drivers/scsi/cyberstorm.c
@@ -223,7 +223,7 @@
 		esp->esp_id, ((struct cyber_dma_registers *)
 			      (esp->dregs))->cond_reg));
 	ESPLOG(("intreq:<%04x>, intena:<%04x>\n",
-		custom.intreqr, custom.intenar));
+		amiga_custom.intreqr, amiga_custom.intenar));
 }
 
 static void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length)
@@ -322,7 +322,7 @@
 
 static int dma_ports_p(struct NCR_ESP *esp)
 {
-	return ((custom.intenar) & IF_PORTS);
+	return ((amiga_custom.intenar) & IF_PORTS);
 }
 
 static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
diff --git a/drivers/scsi/cyberstormII.c b/drivers/scsi/cyberstormII.c
index a3caabf..3a803d7 100644
--- a/drivers/scsi/cyberstormII.c
+++ b/drivers/scsi/cyberstormII.c
@@ -200,7 +200,7 @@
 		esp->esp_id, ((struct cyberII_dma_registers *)
 			      (esp->dregs))->cond_reg));
 	ESPLOG(("intreq:<%04x>, intena:<%04x>\n",
-		custom.intreqr, custom.intenar));
+		amiga_custom.intreqr, amiga_custom.intenar));
 }
 
 static void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length)
@@ -259,7 +259,7 @@
 
 static int dma_ports_p(struct NCR_ESP *esp)
 {
-	return ((custom.intenar) & IF_PORTS);
+	return ((amiga_custom.intenar) & IF_PORTS);
 }
 
 static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
diff --git a/drivers/scsi/fastlane.c b/drivers/scsi/fastlane.c
index ccee68b..8ae9c40 100644
--- a/drivers/scsi/fastlane.c
+++ b/drivers/scsi/fastlane.c
@@ -268,7 +268,7 @@
 		esp->esp_id, ((struct fastlane_dma_registers *)
 			      (esp->dregs))->cond_reg));
 	ESPLOG(("intreq:<%04x>, intena:<%04x>\n",
-		custom.intreqr, custom.intenar));
+		amiga_custom.intreqr, amiga_custom.intenar));
 }
 
 static void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length)
@@ -368,7 +368,7 @@
 
 static int dma_ports_p(struct NCR_ESP *esp)
 {
-	return ((custom.intenar) & IF_PORTS);
+	return ((amiga_custom.intenar) & IF_PORTS);
 }
 
 static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
diff --git a/drivers/scsi/oktagon_esp.c b/drivers/scsi/oktagon_esp.c
index 5d9c9ad..dee426f 100644
--- a/drivers/scsi/oktagon_esp.c
+++ b/drivers/scsi/oktagon_esp.c
@@ -490,7 +490,7 @@
 
 static int dma_ports_p(struct NCR_ESP *esp)
 {
-	return ((custom.intenar) & IF_PORTS);
+	return ((amiga_custom.intenar) & IF_PORTS);
 }
 
 static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c
index fd63add..fb53eea 100644
--- a/drivers/scsi/wd33c93.c
+++ b/drivers/scsi/wd33c93.c
@@ -465,7 +465,7 @@
 	 */
 
 	cmd = (struct scsi_cmnd *) hostdata->input_Q;
-	prev = 0;
+	prev = NULL;
 	while (cmd) {
 		if (!(hostdata->busy[cmd->device->id] & (1 << cmd->device->lun)))
 			break;
@@ -1569,7 +1569,7 @@
  */
 
 	tmp = (struct scsi_cmnd *) hostdata->input_Q;
-	prev = 0;
+	prev = NULL;
 	while (tmp) {
 		if (tmp == cmd) {
 			if (prev)
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index d549e21..2c42a81 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -590,6 +590,8 @@
 #define highw(x)	((u_long)(x)>>16 & 0xffff)
 #define loww(x)		((u_long)(x) & 0xffff)
 
+#define custom		amiga_custom
+
 #define VBlankOn()	custom.intena = IF_SETCLR|IF_COPER
 #define VBlankOff()	custom.intena = IF_COPER
 
@@ -1164,8 +1166,8 @@
 static void ami_init_display(void);
 static void ami_do_blank(void);
 static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix);
-static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data);
-static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data);
+static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data);
+static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data);
 static int ami_get_cursorstate(struct fb_cursorstate *state);
 static int ami_set_cursorstate(struct fb_cursorstate *state);
 static void ami_set_sprite(void);
@@ -2179,6 +2181,7 @@
 		struct fb_var_cursorinfo var;
 		struct fb_cursorstate state;
 	} crsr;
+	void __user *argp = (void __user *)arg;
 	int i;
 
 	switch (cmd) {
@@ -2186,33 +2189,32 @@
 			i = ami_get_fix_cursorinfo(&crsr.fix);
 			if (i)
 				return i;
-			return copy_to_user((void *)arg, &crsr.fix,
+			return copy_to_user(argp, &crsr.fix,
 					    sizeof(crsr.fix)) ? -EFAULT : 0;
 
 		case FBIOGET_VCURSORINFO:
 			i = ami_get_var_cursorinfo(&crsr.var,
-				((struct fb_var_cursorinfo *)arg)->data);
+				((struct fb_var_cursorinfo __user *)arg)->data);
 			if (i)
 				return i;
-			return copy_to_user((void *)arg, &crsr.var,
+			return copy_to_user(argp, &crsr.var,
 					    sizeof(crsr.var)) ? -EFAULT : 0;
 
 		case FBIOPUT_VCURSORINFO:
-			if (copy_from_user(&crsr.var, (void *)arg,
-					   sizeof(crsr.var)))
+			if (copy_from_user(&crsr.var, argp, sizeof(crsr.var)))
 				return -EFAULT;
 			return ami_set_var_cursorinfo(&crsr.var,
-				((struct fb_var_cursorinfo *)arg)->data);
+				((struct fb_var_cursorinfo __user *)arg)->data);
 
 		case FBIOGET_CURSORSTATE:
 			i = ami_get_cursorstate(&crsr.state);
 			if (i)
 				return i;
-			return copy_to_user((void *)arg, &crsr.state,
+			return copy_to_user(argp, &crsr.state,
 					    sizeof(crsr.state)) ? -EFAULT : 0;
 
 		case FBIOPUT_CURSORSTATE:
-			if (copy_from_user(&crsr.state, (void *)arg,
+			if (copy_from_user(&crsr.state, argp,
 					   sizeof(crsr.state)))
 				return -EFAULT;
 			return ami_set_cursorstate(&crsr.state);
@@ -3325,7 +3327,7 @@
 	return 0;
 }
 
-static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data)
+static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data)
 {
 	struct amifb_par *par = &currentpar;
 	register u_short *lspr, *sspr;
@@ -3347,14 +3349,14 @@
 	var->yspot = par->crsr.spot_y;
 	if (size > var->height*var->width)
 		return -ENAMETOOLONG;
-	if (!access_ok(VERIFY_WRITE, (void *)data, size))
+	if (!access_ok(VERIFY_WRITE, data, size))
 		return -EFAULT;
 	delta = 1<<par->crsr.fmode;
 	lspr = lofsprite + (delta<<1);
 	if (par->bplcon0 & BPC0_LACE)
 		sspr = shfsprite + (delta<<1);
 	else
-		sspr = 0;
+		sspr = NULL;
 	for (height = (short)var->height-1; height >= 0; height--) {
 		bits = 0; words = delta; datawords = 0;
 		for (width = (short)var->width-1; width >= 0; width--) {
@@ -3400,7 +3402,7 @@
 	return 0;
 }
 
-static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data)
+static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data)
 {
 	struct amifb_par *par = &currentpar;
 	register u_short *lspr, *sspr;
@@ -3427,7 +3429,7 @@
 		return -EINVAL;
 	if (!var->height)
 		return -EINVAL;
-	if (!access_ok(VERIFY_READ, (void *)data, var->width*var->height))
+	if (!access_ok(VERIFY_READ, data, var->width*var->height))
 		return -EFAULT;
 	delta = 1<<fmode;
 	lofsprite = shfsprite = (u_short *)spritememory;
@@ -3442,13 +3444,13 @@
 		if (((var->height+2)<<fmode<<2) > SPRITEMEMSIZE)
 			return -EINVAL;
 		memset(lspr, 0, (var->height+2)<<fmode<<2);
-		sspr = 0;
+		sspr = NULL;
 	}
 	for (height = (short)var->height-1; height >= 0; height--) {
 		bits = 16; words = delta; datawords = 0;
 		for (width = (short)var->width-1; width >= 0; width--) {
 			unsigned long tdata = 0;
-			get_user(tdata, (char *)data);
+			get_user(tdata, data);
 			data++;
 #ifdef __mc68000__
 			asm volatile (
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index e370125..ed81005 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -3501,7 +3501,7 @@
 
 static int __devinit atyfb_atari_probe(void)
 {
-	struct aty_par *par;
+	struct atyfb_par *par;
 	struct fb_info *info;
 	int m64_num;
 	u32 clock_r;
diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c
index cfc748e..e6cbd9d 100644
--- a/drivers/video/macfb.c
+++ b/drivers/video/macfb.c
@@ -609,18 +609,19 @@
 	}
 }
 
-void __init macfb_init(void)
+static int __init macfb_init(void)
 {
 	int video_cmap_len, video_is_nubus = 0;
 	struct nubus_dev* ndev = NULL;
 	char *option = NULL;
+	int err;
 
 	if (fb_get_options("macfb", &option))
 		return -ENODEV;
 	macfb_setup(option);
 
 	if (!MACH_IS_MAC) 
-		return;
+		return -ENODEV;
 
 	/* There can only be one internal video controller anyway so
 	   we're not too worried about this */
@@ -958,11 +959,11 @@
 
 	fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0);
 	
-	if (register_framebuffer(&fb_info) < 0)
-		return;
-
-	printk("fb%d: %s frame buffer device\n",
-	       fb_info.node, fb_info.fix.id);
+	err = register_framebuffer(&fb_info);
+	if (!err)
+		printk("fb%d: %s frame buffer device\n",
+		       fb_info.node, fb_info.fix.id);
+	return err;
 }
 
 module_init(macfb_init);
diff --git a/drivers/zorro/proc.c b/drivers/zorro/proc.c
index 1a409c2..7aa2d3d 100644
--- a/drivers/zorro/proc.c
+++ b/drivers/zorro/proc.c
@@ -45,7 +45,7 @@
 }
 
 static ssize_t
-proc_bus_zorro_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
+proc_bus_zorro_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
 {
 	struct inode *ino = file->f_dentry->d_inode;
 	struct proc_dir_entry *dp = PDE(ino);
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index f0b7256..5dd0207 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -122,6 +122,7 @@
 #include <linux/dvb/dmx.h>
 #include <linux/dvb/frontend.h>
 #include <linux/dvb/video.h>
+#include <linux/lp.h>
 
 /* Aiee. Someone does not find a difference between int and long */
 #define EXT2_IOC32_GETFLAGS               _IOR('f', 1, int)
@@ -2735,6 +2736,20 @@
 }
 #endif
 
+static int
+lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct compat_timeval *tc = (struct compat_timeval *)arg;
+	struct timeval *tn = compat_alloc_user_space(sizeof(struct timeval));
+	struct timeval ts;
+	if (get_user(ts.tv_sec, &tc->tv_sec) ||
+	    get_user(ts.tv_usec, &tc->tv_usec) ||
+	    put_user(ts.tv_sec, &tn->tv_sec) ||
+	    put_user(ts.tv_usec, &tn->tv_usec))
+		return -EFAULT;
+	return sys_ioctl(fd, cmd, (unsigned long)tn);
+}
+
 #define HANDLE_IOCTL(cmd,handler) \
 	{ (cmd), (ioctl_trans_handler_t)(handler) },
 
@@ -2962,6 +2977,20 @@
 HANDLE_IOCTL(VIDEO_GET_EVENT, do_video_get_event)
 HANDLE_IOCTL(VIDEO_STILLPICTURE, do_video_stillpicture)
 HANDLE_IOCTL(VIDEO_SET_SPU_PALETTE, do_video_set_spu_palette)
+
+/* parport */
+COMPATIBLE_IOCTL(LPTIME)
+COMPATIBLE_IOCTL(LPCHAR)
+COMPATIBLE_IOCTL(LPABORTOPEN)
+COMPATIBLE_IOCTL(LPCAREFUL)
+COMPATIBLE_IOCTL(LPWAIT)
+COMPATIBLE_IOCTL(LPSETIRQ)
+COMPATIBLE_IOCTL(LPGETSTATUS)
+COMPATIBLE_IOCTL(LPGETSTATUS)
+COMPATIBLE_IOCTL(LPRESET)
+/*LPGETSTATS not implemented, but no kernels seem to compile it in anyways*/
+COMPATIBLE_IOCTL(LPGETFLAGS)
+HANDLE_IOCTL(LPSETTIMEOUT, lp_timeout_trans)
 };
 
 int ioctl_table_size = ARRAY_SIZE(ioctl_start);
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 94d3cdf..d1db8c1 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -40,11 +40,10 @@
 #include "xfs_rw.h"
 #include "xfs_iomap.h"
 #include <linux/mpage.h>
+#include <linux/pagevec.h>
 #include <linux/writeback.h>
 
 STATIC void xfs_count_page_state(struct page *, int *, int *, int *);
-STATIC void xfs_convert_page(struct inode *, struct page *, xfs_iomap_t *,
-		struct writeback_control *wbc, void *, int, int);
 
 #if defined(XFS_RW_TRACE)
 void
@@ -55,17 +54,15 @@
 	int		mask)
 {
 	xfs_inode_t	*ip;
-	bhv_desc_t	*bdp;
 	vnode_t		*vp = LINVFS_GET_VP(inode);
 	loff_t		isize = i_size_read(inode);
-	loff_t		offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
+	loff_t		offset = page_offset(page);
 	int		delalloc = -1, unmapped = -1, unwritten = -1;
 
 	if (page_has_buffers(page))
 		xfs_count_page_state(page, &delalloc, &unmapped, &unwritten);
 
-	bdp = vn_bhv_lookup(VN_BHV_HEAD(vp), &xfs_vnodeops);
-	ip = XFS_BHVTOI(bdp);
+	ip = xfs_vtoi(vp);
 	if (!ip->i_rwtrace)
 		return;
 
@@ -103,15 +100,56 @@
 		queue_work(xfsdatad_workqueue, &ioend->io_work);
 }
 
+/*
+ * We're now finished for good with this ioend structure.
+ * Update the page state via the associated buffer_heads,
+ * release holds on the inode and bio, and finally free
+ * up memory.  Do not use the ioend after this.
+ */
 STATIC void
 xfs_destroy_ioend(
 	xfs_ioend_t		*ioend)
 {
+	struct buffer_head	*bh, *next;
+
+	for (bh = ioend->io_buffer_head; bh; bh = next) {
+		next = bh->b_private;
+		bh->b_end_io(bh, ioend->io_uptodate);
+	}
+
 	vn_iowake(ioend->io_vnode);
 	mempool_free(ioend, xfs_ioend_pool);
 }
 
 /*
+ * Buffered IO write completion for delayed allocate extents.
+ * TODO: Update ondisk isize now that we know the file data
+ * has been flushed (i.e. the notorious "NULL file" problem).
+ */
+STATIC void
+xfs_end_bio_delalloc(
+	void			*data)
+{
+	xfs_ioend_t		*ioend = data;
+
+	xfs_destroy_ioend(ioend);
+}
+
+/*
+ * Buffered IO write completion for regular, written extents.
+ */
+STATIC void
+xfs_end_bio_written(
+	void			*data)
+{
+	xfs_ioend_t		*ioend = data;
+
+	xfs_destroy_ioend(ioend);
+}
+
+/*
+ * IO write completion for unwritten extents.
+ *
  * Issue transactions to convert a buffer range from unwritten
  * to written extents.
  */
@@ -123,21 +161,10 @@
 	vnode_t			*vp = ioend->io_vnode;
 	xfs_off_t		offset = ioend->io_offset;
 	size_t			size = ioend->io_size;
-	struct buffer_head	*bh, *next;
 	int			error;
 
 	if (ioend->io_uptodate)
 		VOP_BMAP(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL, error);
-
-	/* ioend->io_buffer_head is only non-NULL for buffered I/O */
-	for (bh = ioend->io_buffer_head; bh; bh = next) {
-		next = bh->b_private;
-
-		bh->b_end_io = NULL;
-		clear_buffer_unwritten(bh);
-		end_buffer_async_write(bh, ioend->io_uptodate);
-	}
-
 	xfs_destroy_ioend(ioend);
 }
 
@@ -149,7 +176,8 @@
  */
 STATIC xfs_ioend_t *
 xfs_alloc_ioend(
-	struct inode		*inode)
+	struct inode		*inode,
+	unsigned int		type)
 {
 	xfs_ioend_t		*ioend;
 
@@ -162,45 +190,25 @@
 	 */
 	atomic_set(&ioend->io_remaining, 1);
 	ioend->io_uptodate = 1; /* cleared if any I/O fails */
+	ioend->io_list = NULL;
+	ioend->io_type = type;
 	ioend->io_vnode = LINVFS_GET_VP(inode);
 	ioend->io_buffer_head = NULL;
+	ioend->io_buffer_tail = NULL;
 	atomic_inc(&ioend->io_vnode->v_iocount);
 	ioend->io_offset = 0;
 	ioend->io_size = 0;
 
-	INIT_WORK(&ioend->io_work, xfs_end_bio_unwritten, ioend);
+	if (type == IOMAP_UNWRITTEN)
+		INIT_WORK(&ioend->io_work, xfs_end_bio_unwritten, ioend);
+	else if (type == IOMAP_DELAY)
+		INIT_WORK(&ioend->io_work, xfs_end_bio_delalloc, ioend);
+	else
+		INIT_WORK(&ioend->io_work, xfs_end_bio_written, ioend);
 
 	return ioend;
 }
 
-void
-linvfs_unwritten_done(
-	struct buffer_head	*bh,
-	int			uptodate)
-{
-	xfs_ioend_t		*ioend = bh->b_private;
-	static spinlock_t	unwritten_done_lock = SPIN_LOCK_UNLOCKED;
-	unsigned long		flags;
-
-	ASSERT(buffer_unwritten(bh));
-	bh->b_end_io = NULL;
-
-	if (!uptodate)
-		ioend->io_uptodate = 0;
-
-	/*
-	 * Deep magic here.  We reuse b_private in the buffer_heads to build
-	 * a chain for completing the I/O from user context after we've issued
-	 * a transaction to convert the unwritten extent.
-	 */
-	spin_lock_irqsave(&unwritten_done_lock, flags);
-	bh->b_private = ioend->io_buffer_head;
-	ioend->io_buffer_head = bh;
-	spin_unlock_irqrestore(&unwritten_done_lock, flags);
-
-	xfs_finish_ioend(ioend);
-}
-
 STATIC int
 xfs_map_blocks(
 	struct inode		*inode,
@@ -218,138 +226,260 @@
 	return -error;
 }
 
-/*
- * Finds the corresponding mapping in block @map array of the
- * given @offset within a @page.
- */
-STATIC xfs_iomap_t *
-xfs_offset_to_map(
-	struct page		*page,
+STATIC inline int
+xfs_iomap_valid(
 	xfs_iomap_t		*iomapp,
-	unsigned long		offset)
+	loff_t			offset)
 {
-	loff_t			full_offset;	/* offset from start of file */
+	return offset >= iomapp->iomap_offset &&
+		offset < iomapp->iomap_offset + iomapp->iomap_bsize;
+}
 
-	ASSERT(offset < PAGE_CACHE_SIZE);
+/*
+ * BIO completion handler for buffered IO.
+ */
+STATIC int
+xfs_end_bio(
+	struct bio		*bio,
+	unsigned int		bytes_done,
+	int			error)
+{
+	xfs_ioend_t		*ioend = bio->bi_private;
 
-	full_offset = page->index;		/* NB: using 64bit number */
-	full_offset <<= PAGE_CACHE_SHIFT;	/* offset from file start */
-	full_offset += offset;			/* offset from page start */
+	if (bio->bi_size)
+		return 1;
 
-	if (full_offset < iomapp->iomap_offset)
-		return NULL;
-	if (iomapp->iomap_offset + (iomapp->iomap_bsize -1) >= full_offset)
-		return iomapp;
-	return NULL;
+	ASSERT(ioend);
+	ASSERT(atomic_read(&bio->bi_cnt) >= 1);
+
+	/* Toss bio and pass work off to an xfsdatad thread */
+	if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
+		ioend->io_uptodate = 0;
+	bio->bi_private = NULL;
+	bio->bi_end_io = NULL;
+
+	bio_put(bio);
+	xfs_finish_ioend(ioend);
+	return 0;
+}
+
+STATIC void
+xfs_submit_ioend_bio(
+	xfs_ioend_t	*ioend,
+	struct bio	*bio)
+{
+	atomic_inc(&ioend->io_remaining);
+
+	bio->bi_private = ioend;
+	bio->bi_end_io = xfs_end_bio;
+
+	submit_bio(WRITE, bio);
+	ASSERT(!bio_flagged(bio, BIO_EOPNOTSUPP));
+	bio_put(bio);
+}
+
+STATIC struct bio *
+xfs_alloc_ioend_bio(
+	struct buffer_head	*bh)
+{
+	struct bio		*bio;
+	int			nvecs = bio_get_nr_vecs(bh->b_bdev);
+
+	do {
+		bio = bio_alloc(GFP_NOIO, nvecs);
+		nvecs >>= 1;
+	} while (!bio);
+
+	ASSERT(bio->bi_private == NULL);
+	bio->bi_sector = bh->b_blocknr * (bh->b_size >> 9);
+	bio->bi_bdev = bh->b_bdev;
+	bio_get(bio);
+	return bio;
+}
+
+STATIC void
+xfs_start_buffer_writeback(
+	struct buffer_head	*bh)
+{
+	ASSERT(buffer_mapped(bh));
+	ASSERT(buffer_locked(bh));
+	ASSERT(!buffer_delay(bh));
+	ASSERT(!buffer_unwritten(bh));
+
+	mark_buffer_async_write(bh);
+	set_buffer_uptodate(bh);
+	clear_buffer_dirty(bh);
+}
+
+STATIC void
+xfs_start_page_writeback(
+	struct page		*page,
+	struct writeback_control *wbc,
+	int			clear_dirty,
+	int			buffers)
+{
+	ASSERT(PageLocked(page));
+	ASSERT(!PageWriteback(page));
+	set_page_writeback(page);
+	if (clear_dirty)
+		clear_page_dirty(page);
+	unlock_page(page);
+	if (!buffers) {
+		end_page_writeback(page);
+		wbc->pages_skipped++;	/* We didn't write this page */
+	}
+}
+
+static inline int bio_add_buffer(struct bio *bio, struct buffer_head *bh)
+{
+	return bio_add_page(bio, bh->b_page, bh->b_size, bh_offset(bh));
+}
+
+/*
+ * Submit all of the bios for all of the ioends we have saved up,
+ * covering the initial writepage page and also any probed pages.
+ */
+STATIC void
+xfs_submit_ioend(
+	xfs_ioend_t		*ioend)
+{
+	xfs_ioend_t		*next;
+	struct buffer_head	*bh;
+	struct bio		*bio;
+	sector_t		lastblock = 0;
+
+	do {
+		next = ioend->io_list;
+		bio = NULL;
+
+		for (bh = ioend->io_buffer_head; bh; bh = bh->b_private) {
+			xfs_start_buffer_writeback(bh);
+
+			if (!bio) {
+ retry:
+				bio = xfs_alloc_ioend_bio(bh);
+			} else if (bh->b_blocknr != lastblock + 1) {
+				xfs_submit_ioend_bio(ioend, bio);
+				goto retry;
+			}
+
+			if (bio_add_buffer(bio, bh) != bh->b_size) {
+				xfs_submit_ioend_bio(ioend, bio);
+				goto retry;
+			}
+
+			lastblock = bh->b_blocknr;
+		}
+		if (bio)
+			xfs_submit_ioend_bio(ioend, bio);
+		xfs_finish_ioend(ioend);
+	} while ((ioend = next) != NULL);
+}
+
+/*
+ * Cancel submission of all buffer_heads so far in this endio.
+ * Toss the endio too.  Only ever called for the initial page
+ * in a writepage request, so only ever one page.
+ */
+STATIC void
+xfs_cancel_ioend(
+	xfs_ioend_t		*ioend)
+{
+	xfs_ioend_t		*next;
+	struct buffer_head	*bh, *next_bh;
+
+	do {
+		next = ioend->io_list;
+		bh = ioend->io_buffer_head;
+		do {
+			next_bh = bh->b_private;
+			clear_buffer_async_write(bh);
+			unlock_buffer(bh);
+		} while ((bh = next_bh) != NULL);
+
+		vn_iowake(ioend->io_vnode);
+		mempool_free(ioend, xfs_ioend_pool);
+	} while ((ioend = next) != NULL);
+}
+
+/*
+ * Test to see if we've been building up a completion structure for
+ * earlier buffers -- if so, we try to append to this ioend if we
+ * can, otherwise we finish off any current ioend and start another.
+ * Return true if we've finished the given ioend.
+ */
+STATIC void
+xfs_add_to_ioend(
+	struct inode		*inode,
+	struct buffer_head	*bh,
+	xfs_off_t		offset,
+	unsigned int		type,
+	xfs_ioend_t		**result,
+	int			need_ioend)
+{
+	xfs_ioend_t		*ioend = *result;
+
+	if (!ioend || need_ioend || type != ioend->io_type) {
+		xfs_ioend_t	*previous = *result;
+
+		ioend = xfs_alloc_ioend(inode, type);
+		ioend->io_offset = offset;
+		ioend->io_buffer_head = bh;
+		ioend->io_buffer_tail = bh;
+		if (previous)
+			previous->io_list = ioend;
+		*result = ioend;
+	} else {
+		ioend->io_buffer_tail->b_private = bh;
+		ioend->io_buffer_tail = bh;
+	}
+
+	bh->b_private = NULL;
+	ioend->io_size += bh->b_size;
 }
 
 STATIC void
 xfs_map_at_offset(
-	struct page		*page,
 	struct buffer_head	*bh,
-	unsigned long		offset,
+	loff_t			offset,
 	int			block_bits,
 	xfs_iomap_t		*iomapp)
 {
 	xfs_daddr_t		bn;
-	loff_t			delta;
 	int			sector_shift;
 
 	ASSERT(!(iomapp->iomap_flags & IOMAP_HOLE));
 	ASSERT(!(iomapp->iomap_flags & IOMAP_DELAY));
 	ASSERT(iomapp->iomap_bn != IOMAP_DADDR_NULL);
 
-	delta = page->index;
-	delta <<= PAGE_CACHE_SHIFT;
-	delta += offset;
-	delta -= iomapp->iomap_offset;
-	delta >>= block_bits;
-
 	sector_shift = block_bits - BBSHIFT;
-	bn = iomapp->iomap_bn >> sector_shift;
-	bn += delta;
-	BUG_ON(!bn && !(iomapp->iomap_flags & IOMAP_REALTIME));
+	bn = (iomapp->iomap_bn >> sector_shift) +
+	      ((offset - iomapp->iomap_offset) >> block_bits);
+
+	ASSERT(bn || (iomapp->iomap_flags & IOMAP_REALTIME));
 	ASSERT((bn << sector_shift) >= iomapp->iomap_bn);
 
 	lock_buffer(bh);
 	bh->b_blocknr = bn;
-	bh->b_bdev = iomapp->iomap_target->pbr_bdev;
+	bh->b_bdev = iomapp->iomap_target->bt_bdev;
 	set_buffer_mapped(bh);
 	clear_buffer_delay(bh);
+	clear_buffer_unwritten(bh);
 }
 
 /*
- * Look for a page at index which is unlocked and contains our
- * unwritten extent flagged buffers at its head.  Returns page
- * locked and with an extra reference count, and length of the
- * unwritten extent component on this page that we can write,
- * in units of filesystem blocks.
- */
-STATIC struct page *
-xfs_probe_unwritten_page(
-	struct address_space	*mapping,
-	pgoff_t			index,
-	xfs_iomap_t		*iomapp,
-	xfs_ioend_t		*ioend,
-	unsigned long		max_offset,
-	unsigned long		*fsbs,
-	unsigned int            bbits)
-{
-	struct page		*page;
-
-	page = find_trylock_page(mapping, index);
-	if (!page)
-		return NULL;
-	if (PageWriteback(page))
-		goto out;
-
-	if (page->mapping && page_has_buffers(page)) {
-		struct buffer_head	*bh, *head;
-		unsigned long		p_offset = 0;
-
-		*fsbs = 0;
-		bh = head = page_buffers(page);
-		do {
-			if (!buffer_unwritten(bh) || !buffer_uptodate(bh))
-				break;
-			if (!xfs_offset_to_map(page, iomapp, p_offset))
-				break;
-			if (p_offset >= max_offset)
-				break;
-			xfs_map_at_offset(page, bh, p_offset, bbits, iomapp);
-			set_buffer_unwritten_io(bh);
-			bh->b_private = ioend;
-			p_offset += bh->b_size;
-			(*fsbs)++;
-		} while ((bh = bh->b_this_page) != head);
-
-		if (p_offset)
-			return page;
-	}
-
-out:
-	unlock_page(page);
-	return NULL;
-}
-
-/*
- * Look for a page at index which is unlocked and not mapped
- * yet - clustering for mmap write case.
+ * Look for a page at index that is suitable for clustering.
  */
 STATIC unsigned int
-xfs_probe_unmapped_page(
-	struct address_space	*mapping,
-	pgoff_t			index,
-	unsigned int		pg_offset)
+xfs_probe_page(
+	struct page		*page,
+	unsigned int		pg_offset,
+	int			mapped)
 {
-	struct page		*page;
 	int			ret = 0;
 
-	page = find_trylock_page(mapping, index);
-	if (!page)
-		return 0;
 	if (PageWriteback(page))
-		goto out;
+		return 0;
 
 	if (page->mapping && PageDirty(page)) {
 		if (page_has_buffers(page)) {
@@ -357,79 +487,101 @@
 
 			bh = head = page_buffers(page);
 			do {
-				if (buffer_mapped(bh) || !buffer_uptodate(bh))
+				if (!buffer_uptodate(bh))
+					break;
+				if (mapped != buffer_mapped(bh))
 					break;
 				ret += bh->b_size;
 				if (ret >= pg_offset)
 					break;
 			} while ((bh = bh->b_this_page) != head);
 		} else
-			ret = PAGE_CACHE_SIZE;
+			ret = mapped ? 0 : PAGE_CACHE_SIZE;
 	}
 
-out:
-	unlock_page(page);
 	return ret;
 }
 
-STATIC unsigned int
-xfs_probe_unmapped_cluster(
+STATIC size_t
+xfs_probe_cluster(
 	struct inode		*inode,
 	struct page		*startpage,
 	struct buffer_head	*bh,
-	struct buffer_head	*head)
+	struct buffer_head	*head,
+	int			mapped)
 {
+	struct pagevec		pvec;
 	pgoff_t			tindex, tlast, tloff;
-	unsigned int		pg_offset, len, total = 0;
-	struct address_space	*mapping = inode->i_mapping;
+	size_t			total = 0;
+	int			done = 0, i;
 
 	/* First sum forwards in this page */
 	do {
-		if (buffer_mapped(bh))
-			break;
+		if (mapped != buffer_mapped(bh))
+			return total;
 		total += bh->b_size;
 	} while ((bh = bh->b_this_page) != head);
 
-	/* If we reached the end of the page, sum forwards in
-	 * following pages.
-	 */
-	if (bh == head) {
-		tlast = i_size_read(inode) >> PAGE_CACHE_SHIFT;
-		/* Prune this back to avoid pathological behavior */
-		tloff = min(tlast, startpage->index + 64);
-		for (tindex = startpage->index + 1; tindex < tloff; tindex++) {
-			len = xfs_probe_unmapped_page(mapping, tindex,
-							PAGE_CACHE_SIZE);
-			if (!len)
-				return total;
+	/* if we reached the end of the page, sum forwards in following pages */
+	tlast = i_size_read(inode) >> PAGE_CACHE_SHIFT;
+	tindex = startpage->index + 1;
+
+	/* Prune this back to avoid pathological behavior */
+	tloff = min(tlast, startpage->index + 64);
+
+	pagevec_init(&pvec, 0);
+	while (!done && tindex <= tloff) {
+		unsigned len = min_t(pgoff_t, PAGEVEC_SIZE, tlast - tindex + 1);
+
+		if (!pagevec_lookup(&pvec, inode->i_mapping, tindex, len))
+			break;
+
+		for (i = 0; i < pagevec_count(&pvec); i++) {
+			struct page *page = pvec.pages[i];
+			size_t pg_offset, len = 0;
+
+			if (tindex == tlast) {
+				pg_offset =
+				    i_size_read(inode) & (PAGE_CACHE_SIZE - 1);
+				if (!pg_offset) {
+					done = 1;
+					break;
+				}
+			} else
+				pg_offset = PAGE_CACHE_SIZE;
+
+			if (page->index == tindex && !TestSetPageLocked(page)) {
+				len = xfs_probe_page(page, pg_offset, mapped);
+				unlock_page(page);
+			}
+
+			if (!len) {
+				done = 1;
+				break;
+			}
+
 			total += len;
+			tindex++;
 		}
-		if (tindex == tlast &&
-		    (pg_offset = i_size_read(inode) & (PAGE_CACHE_SIZE - 1))) {
-			total += xfs_probe_unmapped_page(mapping,
-							tindex, pg_offset);
-		}
+
+		pagevec_release(&pvec);
+		cond_resched();
 	}
+
 	return total;
 }
 
 /*
- * Probe for a given page (index) in the inode and test if it is delayed
- * and without unwritten buffers.  Returns page locked and with an extra
- * reference count.
+ * Test if a given page is suitable for writing as part of an unwritten
+ * or delayed allocate extent.
  */
-STATIC struct page *
-xfs_probe_delalloc_page(
-	struct inode		*inode,
-	pgoff_t			index)
+STATIC int
+xfs_is_delayed_page(
+	struct page		*page,
+	unsigned int		type)
 {
-	struct page		*page;
-
-	page = find_trylock_page(inode->i_mapping, index);
-	if (!page)
-		return NULL;
 	if (PageWriteback(page))
-		goto out;
+		return 0;
 
 	if (page->mapping && page_has_buffers(page)) {
 		struct buffer_head	*bh, *head;
@@ -437,243 +589,156 @@
 
 		bh = head = page_buffers(page);
 		do {
-			if (buffer_unwritten(bh)) {
-				acceptable = 0;
+			if (buffer_unwritten(bh))
+				acceptable = (type == IOMAP_UNWRITTEN);
+			else if (buffer_delay(bh))
+				acceptable = (type == IOMAP_DELAY);
+			else if (buffer_mapped(bh))
+				acceptable = (type == 0);
+			else
 				break;
-			} else if (buffer_delay(bh)) {
-				acceptable = 1;
-			}
 		} while ((bh = bh->b_this_page) != head);
 
 		if (acceptable)
-			return page;
+			return 1;
 	}
 
-out:
-	unlock_page(page);
-	return NULL;
-}
-
-STATIC int
-xfs_map_unwritten(
-	struct inode		*inode,
-	struct page		*start_page,
-	struct buffer_head	*head,
-	struct buffer_head	*curr,
-	unsigned long		p_offset,
-	int			block_bits,
-	xfs_iomap_t		*iomapp,
-	struct writeback_control *wbc,
-	int			startio,
-	int			all_bh)
-{
-	struct buffer_head	*bh = curr;
-	xfs_iomap_t		*tmp;
-	xfs_ioend_t		*ioend;
-	loff_t			offset;
-	unsigned long		nblocks = 0;
-
-	offset = start_page->index;
-	offset <<= PAGE_CACHE_SHIFT;
-	offset += p_offset;
-
-	ioend = xfs_alloc_ioend(inode);
-
-	/* First map forwards in the page consecutive buffers
-	 * covering this unwritten extent
-	 */
-	do {
-		if (!buffer_unwritten(bh))
-			break;
-		tmp = xfs_offset_to_map(start_page, iomapp, p_offset);
-		if (!tmp)
-			break;
-		xfs_map_at_offset(start_page, bh, p_offset, block_bits, iomapp);
-		set_buffer_unwritten_io(bh);
-		bh->b_private = ioend;
-		p_offset += bh->b_size;
-		nblocks++;
-	} while ((bh = bh->b_this_page) != head);
-
-	atomic_add(nblocks, &ioend->io_remaining);
-
-	/* If we reached the end of the page, map forwards in any
-	 * following pages which are also covered by this extent.
-	 */
-	if (bh == head) {
-		struct address_space	*mapping = inode->i_mapping;
-		pgoff_t			tindex, tloff, tlast;
-		unsigned long		bs;
-		unsigned int		pg_offset, bbits = inode->i_blkbits;
-		struct page		*page;
-
-		tlast = i_size_read(inode) >> PAGE_CACHE_SHIFT;
-		tloff = (iomapp->iomap_offset + iomapp->iomap_bsize) >> PAGE_CACHE_SHIFT;
-		tloff = min(tlast, tloff);
-		for (tindex = start_page->index + 1; tindex < tloff; tindex++) {
-			page = xfs_probe_unwritten_page(mapping,
-						tindex, iomapp, ioend,
-						PAGE_CACHE_SIZE, &bs, bbits);
-			if (!page)
-				break;
-			nblocks += bs;
-			atomic_add(bs, &ioend->io_remaining);
-			xfs_convert_page(inode, page, iomapp, wbc, ioend,
-							startio, all_bh);
-			/* stop if converting the next page might add
-			 * enough blocks that the corresponding byte
-			 * count won't fit in our ulong page buf length */
-			if (nblocks >= ((ULONG_MAX - PAGE_SIZE) >> block_bits))
-				goto enough;
-		}
-
-		if (tindex == tlast &&
-		    (pg_offset = (i_size_read(inode) & (PAGE_CACHE_SIZE - 1)))) {
-			page = xfs_probe_unwritten_page(mapping,
-							tindex, iomapp, ioend,
-							pg_offset, &bs, bbits);
-			if (page) {
-				nblocks += bs;
-				atomic_add(bs, &ioend->io_remaining);
-				xfs_convert_page(inode, page, iomapp, wbc, ioend,
-							startio, all_bh);
-				if (nblocks >= ((ULONG_MAX - PAGE_SIZE) >> block_bits))
-					goto enough;
-			}
-		}
-	}
-
-enough:
-	ioend->io_size = (xfs_off_t)nblocks << block_bits;
-	ioend->io_offset = offset;
-	xfs_finish_ioend(ioend);
 	return 0;
 }
 
-STATIC void
-xfs_submit_page(
-	struct page		*page,
-	struct writeback_control *wbc,
-	struct buffer_head	*bh_arr[],
-	int			bh_count,
-	int			probed_page,
-	int			clear_dirty)
-{
-	struct buffer_head	*bh;
-	int			i;
-
-	BUG_ON(PageWriteback(page));
-	if (bh_count)
-		set_page_writeback(page);
-	if (clear_dirty)
-		clear_page_dirty(page);
-	unlock_page(page);
-
-	if (bh_count) {
-		for (i = 0; i < bh_count; i++) {
-			bh = bh_arr[i];
-			mark_buffer_async_write(bh);
-			if (buffer_unwritten(bh))
-				set_buffer_unwritten_io(bh);
-			set_buffer_uptodate(bh);
-			clear_buffer_dirty(bh);
-		}
-
-		for (i = 0; i < bh_count; i++)
-			submit_bh(WRITE, bh_arr[i]);
-
-		if (probed_page && clear_dirty)
-			wbc->nr_to_write--;	/* Wrote an "extra" page */
-	}
-}
-
 /*
  * Allocate & map buffers for page given the extent map. Write it out.
  * except for the original page of a writepage, this is called on
  * delalloc/unwritten pages only, for the original page it is possible
  * that the page has no mapping at all.
  */
-STATIC void
+STATIC int
 xfs_convert_page(
 	struct inode		*inode,
 	struct page		*page,
-	xfs_iomap_t		*iomapp,
+	loff_t			tindex,
+	xfs_iomap_t		*mp,
+	xfs_ioend_t		**ioendp,
 	struct writeback_control *wbc,
-	void			*private,
 	int			startio,
 	int			all_bh)
 {
-	struct buffer_head	*bh_arr[MAX_BUF_PER_PAGE], *bh, *head;
-	xfs_iomap_t		*mp = iomapp, *tmp;
-	unsigned long		offset, end_offset;
-	int			index = 0;
+	struct buffer_head	*bh, *head;
+	xfs_off_t		end_offset;
+	unsigned long		p_offset;
+	unsigned int		type;
 	int			bbits = inode->i_blkbits;
 	int			len, page_dirty;
+	int			count = 0, done = 0, uptodate = 1;
+ 	xfs_off_t		offset = page_offset(page);
 
-	end_offset = (i_size_read(inode) & (PAGE_CACHE_SIZE - 1));
+	if (page->index != tindex)
+		goto fail;
+	if (TestSetPageLocked(page))
+		goto fail;
+	if (PageWriteback(page))
+		goto fail_unlock_page;
+	if (page->mapping != inode->i_mapping)
+		goto fail_unlock_page;
+	if (!xfs_is_delayed_page(page, (*ioendp)->io_type))
+		goto fail_unlock_page;
 
 	/*
 	 * page_dirty is initially a count of buffers on the page before
 	 * EOF and is decrememted as we move each into a cleanable state.
+	 *
+	 * Derivation:
+	 *
+	 * End offset is the highest offset that this page should represent.
+	 * If we are on the last page, (end_offset & (PAGE_CACHE_SIZE - 1))
+	 * will evaluate non-zero and be less than PAGE_CACHE_SIZE and
+	 * hence give us the correct page_dirty count. On any other page,
+	 * it will be zero and in that case we need page_dirty to be the
+	 * count of buffers on the page.
 	 */
-	len = 1 << inode->i_blkbits;
-	end_offset = max(end_offset, PAGE_CACHE_SIZE);
-	end_offset = roundup(end_offset, len);
-	page_dirty = end_offset / len;
+	end_offset = min_t(unsigned long long,
+			(xfs_off_t)(page->index + 1) << PAGE_CACHE_SHIFT,
+			i_size_read(inode));
 
-	offset = 0;
+	len = 1 << inode->i_blkbits;
+	p_offset = min_t(unsigned long, end_offset & (PAGE_CACHE_SIZE - 1),
+					PAGE_CACHE_SIZE);
+	p_offset = p_offset ? roundup(p_offset, len) : PAGE_CACHE_SIZE;
+	page_dirty = p_offset / len;
+
 	bh = head = page_buffers(page);
 	do {
 		if (offset >= end_offset)
 			break;
-		if (!(PageUptodate(page) || buffer_uptodate(bh)))
-			continue;
-		if (buffer_mapped(bh) && all_bh &&
-		    !(buffer_unwritten(bh) || buffer_delay(bh))) {
-			if (startio) {
-				lock_buffer(bh);
-				bh_arr[index++] = bh;
-				page_dirty--;
-			}
+		if (!buffer_uptodate(bh))
+			uptodate = 0;
+		if (!(PageUptodate(page) || buffer_uptodate(bh))) {
+			done = 1;
 			continue;
 		}
-		tmp = xfs_offset_to_map(page, mp, offset);
-		if (!tmp)
-			continue;
-		ASSERT(!(tmp->iomap_flags & IOMAP_HOLE));
-		ASSERT(!(tmp->iomap_flags & IOMAP_DELAY));
 
-		/* If this is a new unwritten extent buffer (i.e. one
-		 * that we haven't passed in private data for, we must
-		 * now map this buffer too.
-		 */
-		if (buffer_unwritten(bh) && !bh->b_end_io) {
-			ASSERT(tmp->iomap_flags & IOMAP_UNWRITTEN);
-			xfs_map_unwritten(inode, page, head, bh, offset,
-					bbits, tmp, wbc, startio, all_bh);
-		} else if (! (buffer_unwritten(bh) && buffer_locked(bh))) {
-			xfs_map_at_offset(page, bh, offset, bbits, tmp);
-			if (buffer_unwritten(bh)) {
-				set_buffer_unwritten_io(bh);
-				bh->b_private = private;
-				ASSERT(private);
+		if (buffer_unwritten(bh) || buffer_delay(bh)) {
+			if (buffer_unwritten(bh))
+				type = IOMAP_UNWRITTEN;
+			else
+				type = IOMAP_DELAY;
+
+			if (!xfs_iomap_valid(mp, offset)) {
+				done = 1;
+				continue;
+			}
+
+			ASSERT(!(mp->iomap_flags & IOMAP_HOLE));
+			ASSERT(!(mp->iomap_flags & IOMAP_DELAY));
+
+			xfs_map_at_offset(bh, offset, bbits, mp);
+			if (startio) {
+				xfs_add_to_ioend(inode, bh, offset,
+						type, ioendp, done);
+			} else {
+				set_buffer_dirty(bh);
+				unlock_buffer(bh);
+				mark_buffer_dirty(bh);
+			}
+			page_dirty--;
+			count++;
+		} else {
+			type = 0;
+			if (buffer_mapped(bh) && all_bh && startio) {
+				lock_buffer(bh);
+				xfs_add_to_ioend(inode, bh, offset,
+						type, ioendp, done);
+				count++;
+				page_dirty--;
+			} else {
+				done = 1;
 			}
 		}
-		if (startio) {
-			bh_arr[index++] = bh;
-		} else {
-			set_buffer_dirty(bh);
-			unlock_buffer(bh);
-			mark_buffer_dirty(bh);
-		}
-		page_dirty--;
 	} while (offset += len, (bh = bh->b_this_page) != head);
 
-	if (startio && index) {
-		xfs_submit_page(page, wbc, bh_arr, index, 1, !page_dirty);
-	} else {
-		unlock_page(page);
+	if (uptodate && bh == head)
+		SetPageUptodate(page);
+
+	if (startio) {
+		if (count) {
+			struct backing_dev_info *bdi;
+
+			bdi = inode->i_mapping->backing_dev_info;
+			if (bdi_write_congested(bdi)) {
+				wbc->encountered_congestion = 1;
+				done = 1;
+			} else if (--wbc->nr_to_write <= 0) {
+				done = 1;
+			}
+		}
+		xfs_start_page_writeback(page, wbc, !page_dirty, count);
 	}
+
+	return done;
+ fail_unlock_page:
+	unlock_page(page);
+ fail:
+	return 1;
 }
 
 /*
@@ -685,19 +750,31 @@
 	struct inode		*inode,
 	pgoff_t			tindex,
 	xfs_iomap_t		*iomapp,
+	xfs_ioend_t		**ioendp,
 	struct writeback_control *wbc,
 	int			startio,
 	int			all_bh,
 	pgoff_t			tlast)
 {
-	struct page		*page;
+	struct pagevec		pvec;
+	int			done = 0, i;
 
-	for (; tindex <= tlast; tindex++) {
-		page = xfs_probe_delalloc_page(inode, tindex);
-		if (!page)
+	pagevec_init(&pvec, 0);
+	while (!done && tindex <= tlast) {
+		unsigned len = min_t(pgoff_t, PAGEVEC_SIZE, tlast - tindex + 1);
+
+		if (!pagevec_lookup(&pvec, inode->i_mapping, tindex, len))
 			break;
-		xfs_convert_page(inode, page, iomapp, wbc, NULL,
-				startio, all_bh);
+
+		for (i = 0; i < pagevec_count(&pvec); i++) {
+			done = xfs_convert_page(inode, pvec.pages[i], tindex++,
+					iomapp, ioendp, wbc, startio, all_bh);
+			if (done)
+				break;
+		}
+
+		pagevec_release(&pvec);
+		cond_resched();
 	}
 }
 
@@ -728,18 +805,22 @@
 	int		startio,
 	int		unmapped) /* also implies page uptodate */
 {
-	struct buffer_head	*bh_arr[MAX_BUF_PER_PAGE], *bh, *head;
-	xfs_iomap_t		*iomp, iomap;
+	struct buffer_head	*bh, *head;
+	xfs_iomap_t		iomap;
+	xfs_ioend_t		*ioend = NULL, *iohead = NULL;
 	loff_t			offset;
 	unsigned long           p_offset = 0;
+	unsigned int		type;
 	__uint64_t              end_offset;
 	pgoff_t                 end_index, last_index, tlast;
-	int			len, err, i, cnt = 0, uptodate = 1;
-	int			flags;
-	int			page_dirty;
+	ssize_t			size, len;
+	int			flags, err, iomap_valid = 0, uptodate = 1;
+	int			page_dirty, count = 0, trylock_flag = 0;
+	int			all_bh = unmapped;
 
 	/* wait for other IO threads? */
-	flags = (startio && wbc->sync_mode != WB_SYNC_NONE) ? 0 : BMAPI_TRYLOCK;
+	if (startio && (wbc->sync_mode == WB_SYNC_NONE && wbc->nonblocking))
+		trylock_flag |= BMAPI_TRYLOCK;
 
 	/* Is this page beyond the end of the file? */
 	offset = i_size_read(inode);
@@ -754,161 +835,173 @@
 		}
 	}
 
-	end_offset = min_t(unsigned long long,
-			(loff_t)(page->index + 1) << PAGE_CACHE_SHIFT, offset);
-	offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
-
 	/*
 	 * page_dirty is initially a count of buffers on the page before
 	 * EOF and is decrememted as we move each into a cleanable state.
-	 */
+	 *
+	 * Derivation:
+	 *
+	 * End offset is the highest offset that this page should represent.
+	 * If we are on the last page, (end_offset & (PAGE_CACHE_SIZE - 1))
+	 * will evaluate non-zero and be less than PAGE_CACHE_SIZE and
+	 * hence give us the correct page_dirty count. On any other page,
+	 * it will be zero and in that case we need page_dirty to be the
+	 * count of buffers on the page.
+ 	 */
+	end_offset = min_t(unsigned long long,
+			(xfs_off_t)(page->index + 1) << PAGE_CACHE_SHIFT, offset);
 	len = 1 << inode->i_blkbits;
-	p_offset = max(p_offset, PAGE_CACHE_SIZE);
-	p_offset = roundup(p_offset, len);
+	p_offset = min_t(unsigned long, end_offset & (PAGE_CACHE_SIZE - 1),
+					PAGE_CACHE_SIZE);
+	p_offset = p_offset ? roundup(p_offset, len) : PAGE_CACHE_SIZE;
 	page_dirty = p_offset / len;
 
-	iomp = NULL;
-	p_offset = 0;
 	bh = head = page_buffers(page);
+	offset = page_offset(page);
+	flags = -1;
+	type = 0;
+
+	/* TODO: cleanup count and page_dirty */
 
 	do {
 		if (offset >= end_offset)
 			break;
 		if (!buffer_uptodate(bh))
 			uptodate = 0;
-		if (!(PageUptodate(page) || buffer_uptodate(bh)) && !startio)
+		if (!(PageUptodate(page) || buffer_uptodate(bh)) && !startio) {
+			/*
+			 * the iomap is actually still valid, but the ioend
+			 * isn't.  shouldn't happen too often.
+			 */
+			iomap_valid = 0;
 			continue;
-
-		if (iomp) {
-			iomp = xfs_offset_to_map(page, &iomap, p_offset);
 		}
 
+		if (iomap_valid)
+			iomap_valid = xfs_iomap_valid(&iomap, offset);
+
 		/*
 		 * First case, map an unwritten extent and prepare for
 		 * extent state conversion transaction on completion.
-		 */
-		if (buffer_unwritten(bh)) {
-			if (!startio)
-				continue;
-			if (!iomp) {
-				err = xfs_map_blocks(inode, offset, len, &iomap,
-						BMAPI_WRITE|BMAPI_IGNSTATE);
-				if (err) {
-					goto error;
-				}
-				iomp = xfs_offset_to_map(page, &iomap,
-								p_offset);
-			}
-			if (iomp) {
-				if (!bh->b_end_io) {
-					err = xfs_map_unwritten(inode, page,
-							head, bh, p_offset,
-							inode->i_blkbits, iomp,
-							wbc, startio, unmapped);
-					if (err) {
-						goto error;
-					}
-				} else {
-					set_bit(BH_Lock, &bh->b_state);
-				}
-				BUG_ON(!buffer_locked(bh));
-				bh_arr[cnt++] = bh;
-				page_dirty--;
-			}
-		/*
+		 *
 		 * Second case, allocate space for a delalloc buffer.
 		 * We can return EAGAIN here in the release page case.
-		 */
-		} else if (buffer_delay(bh)) {
-			if (!iomp) {
-				err = xfs_map_blocks(inode, offset, len, &iomap,
-						BMAPI_ALLOCATE | flags);
-				if (err) {
-					goto error;
-				}
-				iomp = xfs_offset_to_map(page, &iomap,
-								p_offset);
+		 *
+		 * Third case, an unmapped buffer was found, and we are
+		 * in a path where we need to write the whole page out.
+ 		 */
+		if (buffer_unwritten(bh) || buffer_delay(bh) ||
+		    ((buffer_uptodate(bh) || PageUptodate(page)) &&
+		     !buffer_mapped(bh) && (unmapped || startio))) {
+		     	/*
+			 * Make sure we don't use a read-only iomap
+			 */
+		     	if (flags == BMAPI_READ)
+				iomap_valid = 0;
+
+			if (buffer_unwritten(bh)) {
+				type = IOMAP_UNWRITTEN;
+				flags = BMAPI_WRITE|BMAPI_IGNSTATE;
+			} else if (buffer_delay(bh)) {
+				type = IOMAP_DELAY;
+				flags = BMAPI_ALLOCATE;
+				if (!startio)
+					flags |= trylock_flag;
+			} else {
+				type = IOMAP_NEW;
+				flags = BMAPI_WRITE|BMAPI_MMAP;
 			}
-			if (iomp) {
-				xfs_map_at_offset(page, bh, p_offset,
-						inode->i_blkbits, iomp);
+
+			if (!iomap_valid) {
+				if (type == IOMAP_NEW) {
+					size = xfs_probe_cluster(inode,
+							page, bh, head, 0);
+				} else {
+					size = len;
+				}
+
+				err = xfs_map_blocks(inode, offset, size,
+						&iomap, flags);
+				if (err)
+					goto error;
+				iomap_valid = xfs_iomap_valid(&iomap, offset);
+			}
+			if (iomap_valid) {
+				xfs_map_at_offset(bh, offset,
+						inode->i_blkbits, &iomap);
 				if (startio) {
-					bh_arr[cnt++] = bh;
+					xfs_add_to_ioend(inode, bh, offset,
+							type, &ioend,
+							!iomap_valid);
 				} else {
 					set_buffer_dirty(bh);
 					unlock_buffer(bh);
 					mark_buffer_dirty(bh);
 				}
 				page_dirty--;
+				count++;
+			}
+		} else if (buffer_uptodate(bh) && startio) {
+			/*
+			 * we got here because the buffer is already mapped.
+			 * That means it must already have extents allocated
+			 * underneath it. Map the extent by reading it.
+			 */
+			if (!iomap_valid || type != 0) {
+				flags = BMAPI_READ;
+				size = xfs_probe_cluster(inode, page, bh,
+								head, 1);
+				err = xfs_map_blocks(inode, offset, size,
+						&iomap, flags);
+				if (err)
+					goto error;
+				iomap_valid = xfs_iomap_valid(&iomap, offset);
+			}
+
+			type = 0;
+			if (!test_and_set_bit(BH_Lock, &bh->b_state)) {
+				ASSERT(buffer_mapped(bh));
+				if (iomap_valid)
+					all_bh = 1;
+				xfs_add_to_ioend(inode, bh, offset, type,
+						&ioend, !iomap_valid);
+				page_dirty--;
+				count++;
+			} else {
+				iomap_valid = 0;
 			}
 		} else if ((buffer_uptodate(bh) || PageUptodate(page)) &&
 			   (unmapped || startio)) {
-
-			if (!buffer_mapped(bh)) {
-				int	size;
-
-				/*
-				 * Getting here implies an unmapped buffer
-				 * was found, and we are in a path where we
-				 * need to write the whole page out.
-				 */
-				if (!iomp) {
-					size = xfs_probe_unmapped_cluster(
-							inode, page, bh, head);
-					err = xfs_map_blocks(inode, offset,
-							size, &iomap,
-							BMAPI_WRITE|BMAPI_MMAP);
-					if (err) {
-						goto error;
-					}
-					iomp = xfs_offset_to_map(page, &iomap,
-								     p_offset);
-				}
-				if (iomp) {
-					xfs_map_at_offset(page,
-							bh, p_offset,
-							inode->i_blkbits, iomp);
-					if (startio) {
-						bh_arr[cnt++] = bh;
-					} else {
-						set_buffer_dirty(bh);
-						unlock_buffer(bh);
-						mark_buffer_dirty(bh);
-					}
-					page_dirty--;
-				}
-			} else if (startio) {
-				if (buffer_uptodate(bh) &&
-				    !test_and_set_bit(BH_Lock, &bh->b_state)) {
-					bh_arr[cnt++] = bh;
-					page_dirty--;
-				}
-			}
+			iomap_valid = 0;
 		}
-	} while (offset += len, p_offset += len,
-		((bh = bh->b_this_page) != head));
+
+		if (!iohead)
+			iohead = ioend;
+
+	} while (offset += len, ((bh = bh->b_this_page) != head));
 
 	if (uptodate && bh == head)
 		SetPageUptodate(page);
 
-	if (startio) {
-		xfs_submit_page(page, wbc, bh_arr, cnt, 0, !page_dirty);
-	}
+	if (startio)
+		xfs_start_page_writeback(page, wbc, 1, count);
 
-	if (iomp) {
-		offset = (iomp->iomap_offset + iomp->iomap_bsize - 1) >>
+	if (ioend && iomap_valid) {
+		offset = (iomap.iomap_offset + iomap.iomap_bsize - 1) >>
 					PAGE_CACHE_SHIFT;
 		tlast = min_t(pgoff_t, offset, last_index);
-		xfs_cluster_write(inode, page->index + 1, iomp, wbc,
-					startio, unmapped, tlast);
+		xfs_cluster_write(inode, page->index + 1, &iomap, &ioend,
+					wbc, startio, all_bh, tlast);
 	}
 
+	if (iohead)
+		xfs_submit_ioend(iohead);
+
 	return page_dirty;
 
 error:
-	for (i = 0; i < cnt; i++) {
-		unlock_buffer(bh_arr[i]);
-	}
+	if (iohead)
+		xfs_cancel_ioend(iohead);
 
 	/*
 	 * If it's delalloc and we have nowhere to put it,
@@ -916,9 +1009,8 @@
 	 * us to try again.
 	 */
 	if (err != -EAGAIN) {
-		if (!unmapped) {
+		if (!unmapped)
 			block_invalidatepage(page, 0);
-		}
 		ClearPageUptodate(page);
 	}
 	return err;
@@ -982,7 +1074,7 @@
 	}
 
 	/* If this is a realtime file, data might be on a new device */
-	bh_result->b_bdev = iomap.iomap_target->pbr_bdev;
+	bh_result->b_bdev = iomap.iomap_target->bt_bdev;
 
 	/* If we previously allocated a block out beyond eof and
 	 * we are now coming back to use it then we will need to
@@ -1094,10 +1186,10 @@
 	if (error)
 		return -error;
 
-	iocb->private = xfs_alloc_ioend(inode);
+	iocb->private = xfs_alloc_ioend(inode, IOMAP_UNWRITTEN);
 
 	ret = blockdev_direct_IO_own_locking(rw, iocb, inode,
-		iomap.iomap_target->pbr_bdev,
+		iomap.iomap_target->bt_bdev,
 		iov, offset, nr_segs,
 		linvfs_get_blocks_direct,
 		linvfs_end_io_direct);
diff --git a/fs/xfs/linux-2.6/xfs_aops.h b/fs/xfs/linux-2.6/xfs_aops.h
index 4720758..55339dd 100644
--- a/fs/xfs/linux-2.6/xfs_aops.h
+++ b/fs/xfs/linux-2.6/xfs_aops.h
@@ -23,14 +23,24 @@
 
 typedef void (*xfs_ioend_func_t)(void *);
 
+/*
+ * xfs_ioend struct manages large extent writes for XFS.
+ * It can manage several multi-page bio's at once.
+ */
 typedef struct xfs_ioend {
+	struct xfs_ioend	*io_list;	/* next ioend in chain */
+	unsigned int		io_type;	/* delalloc / unwritten */
 	unsigned int		io_uptodate;	/* I/O status register */
 	atomic_t		io_remaining;	/* hold count */
 	struct vnode		*io_vnode;	/* file being written to */
 	struct buffer_head	*io_buffer_head;/* buffer linked list head */
+	struct buffer_head	*io_buffer_tail;/* buffer linked list tail */
 	size_t			io_size;	/* size of the extent */
 	xfs_off_t		io_offset;	/* offset in the file */
 	struct work_struct	io_work;	/* xfsdatad work queue */
 } xfs_ioend_t;
 
+extern struct address_space_operations linvfs_aops;
+extern int linvfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
+
 #endif /* __XFS_IOPS_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index 6fe21d2..e44b7c1 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -31,76 +31,77 @@
 #include <linux/kthread.h>
 #include "xfs_linux.h"
 
-STATIC kmem_cache_t *pagebuf_zone;
-STATIC kmem_shaker_t pagebuf_shake;
+STATIC kmem_zone_t *xfs_buf_zone;
+STATIC kmem_shaker_t xfs_buf_shake;
+STATIC int xfsbufd(void *);
 STATIC int xfsbufd_wakeup(int, gfp_t);
-STATIC void pagebuf_delwri_queue(xfs_buf_t *, int);
+STATIC void xfs_buf_delwri_queue(xfs_buf_t *, int);
 
 STATIC struct workqueue_struct *xfslogd_workqueue;
 struct workqueue_struct *xfsdatad_workqueue;
 
-#ifdef PAGEBUF_TRACE
+#ifdef XFS_BUF_TRACE
 void
-pagebuf_trace(
-	xfs_buf_t	*pb,
+xfs_buf_trace(
+	xfs_buf_t	*bp,
 	char		*id,
 	void		*data,
 	void		*ra)
 {
-	ktrace_enter(pagebuf_trace_buf,
-		pb, id,
-		(void *)(unsigned long)pb->pb_flags,
-		(void *)(unsigned long)pb->pb_hold.counter,
-		(void *)(unsigned long)pb->pb_sema.count.counter,
+	ktrace_enter(xfs_buf_trace_buf,
+		bp, id,
+		(void *)(unsigned long)bp->b_flags,
+		(void *)(unsigned long)bp->b_hold.counter,
+		(void *)(unsigned long)bp->b_sema.count.counter,
 		(void *)current,
 		data, ra,
-		(void *)(unsigned long)((pb->pb_file_offset>>32) & 0xffffffff),
-		(void *)(unsigned long)(pb->pb_file_offset & 0xffffffff),
-		(void *)(unsigned long)pb->pb_buffer_length,
+		(void *)(unsigned long)((bp->b_file_offset>>32) & 0xffffffff),
+		(void *)(unsigned long)(bp->b_file_offset & 0xffffffff),
+		(void *)(unsigned long)bp->b_buffer_length,
 		NULL, NULL, NULL, NULL, NULL);
 }
-ktrace_t *pagebuf_trace_buf;
-#define PAGEBUF_TRACE_SIZE	4096
-#define PB_TRACE(pb, id, data)	\
-	pagebuf_trace(pb, id, (void *)data, (void *)__builtin_return_address(0))
+ktrace_t *xfs_buf_trace_buf;
+#define XFS_BUF_TRACE_SIZE	4096
+#define XB_TRACE(bp, id, data)	\
+	xfs_buf_trace(bp, id, (void *)data, (void *)__builtin_return_address(0))
 #else
-#define PB_TRACE(pb, id, data)	do { } while (0)
+#define XB_TRACE(bp, id, data)	do { } while (0)
 #endif
 
-#ifdef PAGEBUF_LOCK_TRACKING
-# define PB_SET_OWNER(pb)	((pb)->pb_last_holder = current->pid)
-# define PB_CLEAR_OWNER(pb)	((pb)->pb_last_holder = -1)
-# define PB_GET_OWNER(pb)	((pb)->pb_last_holder)
+#ifdef XFS_BUF_LOCK_TRACKING
+# define XB_SET_OWNER(bp)	((bp)->b_last_holder = current->pid)
+# define XB_CLEAR_OWNER(bp)	((bp)->b_last_holder = -1)
+# define XB_GET_OWNER(bp)	((bp)->b_last_holder)
 #else
-# define PB_SET_OWNER(pb)	do { } while (0)
-# define PB_CLEAR_OWNER(pb)	do { } while (0)
-# define PB_GET_OWNER(pb)	do { } while (0)
+# define XB_SET_OWNER(bp)	do { } while (0)
+# define XB_CLEAR_OWNER(bp)	do { } while (0)
+# define XB_GET_OWNER(bp)	do { } while (0)
 #endif
 
-#define pb_to_gfp(flags) \
-	((((flags) & PBF_READ_AHEAD) ? __GFP_NORETRY : \
-	  ((flags) & PBF_DONT_BLOCK) ? GFP_NOFS : GFP_KERNEL) | __GFP_NOWARN)
+#define xb_to_gfp(flags) \
+	((((flags) & XBF_READ_AHEAD) ? __GFP_NORETRY : \
+	  ((flags) & XBF_DONT_BLOCK) ? GFP_NOFS : GFP_KERNEL) | __GFP_NOWARN)
 
-#define pb_to_km(flags) \
-	 (((flags) & PBF_DONT_BLOCK) ? KM_NOFS : KM_SLEEP)
+#define xb_to_km(flags) \
+	 (((flags) & XBF_DONT_BLOCK) ? KM_NOFS : KM_SLEEP)
 
-#define pagebuf_allocate(flags) \
-	kmem_zone_alloc(pagebuf_zone, pb_to_km(flags))
-#define pagebuf_deallocate(pb) \
-	kmem_zone_free(pagebuf_zone, (pb));
+#define xfs_buf_allocate(flags) \
+	kmem_zone_alloc(xfs_buf_zone, xb_to_km(flags))
+#define xfs_buf_deallocate(bp) \
+	kmem_zone_free(xfs_buf_zone, (bp));
 
 /*
- * Page Region interfaces.
+ *	Page Region interfaces.
  *
- * For pages in filesystems where the blocksize is smaller than the
- * pagesize, we use the page->private field (long) to hold a bitmap
- * of uptodate regions within the page.
+ *	For pages in filesystems where the blocksize is smaller than the
+ *	pagesize, we use the page->private field (long) to hold a bitmap
+ * 	of uptodate regions within the page.
  *
- * Each such region is "bytes per page / bits per long" bytes long.
+ *	Each such region is "bytes per page / bits per long" bytes long.
  *
- * NBPPR == number-of-bytes-per-page-region
- * BTOPR == bytes-to-page-region (rounded up)
- * BTOPRT == bytes-to-page-region-truncated (rounded down)
+ *	NBPPR == number-of-bytes-per-page-region
+ *	BTOPR == bytes-to-page-region (rounded up)
+ *	BTOPRT == bytes-to-page-region-truncated (rounded down)
  */
 #if (BITS_PER_LONG == 32)
 #define PRSHIFT		(PAGE_CACHE_SHIFT - 5)	/* (32 == 1<<5) */
@@ -159,7 +160,7 @@
 }
 
 /*
- * Mapping of multi-page buffers into contiguous virtual space
+ *	Mapping of multi-page buffers into contiguous virtual space
  */
 
 typedef struct a_list {
@@ -172,7 +173,7 @@
 STATIC DEFINE_SPINLOCK(as_lock);
 
 /*
- * Try to batch vunmaps because they are costly.
+ *	Try to batch vunmaps because they are costly.
  */
 STATIC void
 free_address(
@@ -215,83 +216,83 @@
 }
 
 /*
- *	Internal pagebuf object manipulation
+ *	Internal xfs_buf_t object manipulation
  */
 
 STATIC void
-_pagebuf_initialize(
-	xfs_buf_t		*pb,
+_xfs_buf_initialize(
+	xfs_buf_t		*bp,
 	xfs_buftarg_t		*target,
-	loff_t			range_base,
+	xfs_off_t		range_base,
 	size_t			range_length,
-	page_buf_flags_t	flags)
+	xfs_buf_flags_t		flags)
 {
 	/*
-	 * We don't want certain flags to appear in pb->pb_flags.
+	 * We don't want certain flags to appear in b_flags.
 	 */
-	flags &= ~(PBF_LOCK|PBF_MAPPED|PBF_DONT_BLOCK|PBF_READ_AHEAD);
+	flags &= ~(XBF_LOCK|XBF_MAPPED|XBF_DONT_BLOCK|XBF_READ_AHEAD);
 
-	memset(pb, 0, sizeof(xfs_buf_t));
-	atomic_set(&pb->pb_hold, 1);
-	init_MUTEX_LOCKED(&pb->pb_iodonesema);
-	INIT_LIST_HEAD(&pb->pb_list);
-	INIT_LIST_HEAD(&pb->pb_hash_list);
-	init_MUTEX_LOCKED(&pb->pb_sema); /* held, no waiters */
-	PB_SET_OWNER(pb);
-	pb->pb_target = target;
-	pb->pb_file_offset = range_base;
+	memset(bp, 0, sizeof(xfs_buf_t));
+	atomic_set(&bp->b_hold, 1);
+	init_MUTEX_LOCKED(&bp->b_iodonesema);
+	INIT_LIST_HEAD(&bp->b_list);
+	INIT_LIST_HEAD(&bp->b_hash_list);
+	init_MUTEX_LOCKED(&bp->b_sema); /* held, no waiters */
+	XB_SET_OWNER(bp);
+	bp->b_target = target;
+	bp->b_file_offset = range_base;
 	/*
 	 * Set buffer_length and count_desired to the same value initially.
 	 * I/O routines should use count_desired, which will be the same in
 	 * most cases but may be reset (e.g. XFS recovery).
 	 */
-	pb->pb_buffer_length = pb->pb_count_desired = range_length;
-	pb->pb_flags = flags;
-	pb->pb_bn = XFS_BUF_DADDR_NULL;
-	atomic_set(&pb->pb_pin_count, 0);
-	init_waitqueue_head(&pb->pb_waiters);
+	bp->b_buffer_length = bp->b_count_desired = range_length;
+	bp->b_flags = flags;
+	bp->b_bn = XFS_BUF_DADDR_NULL;
+	atomic_set(&bp->b_pin_count, 0);
+	init_waitqueue_head(&bp->b_waiters);
 
-	XFS_STATS_INC(pb_create);
-	PB_TRACE(pb, "initialize", target);
+	XFS_STATS_INC(xb_create);
+	XB_TRACE(bp, "initialize", target);
 }
 
 /*
- * Allocate a page array capable of holding a specified number
- * of pages, and point the page buf at it.
+ *	Allocate a page array capable of holding a specified number
+ *	of pages, and point the page buf at it.
  */
 STATIC int
-_pagebuf_get_pages(
-	xfs_buf_t		*pb,
+_xfs_buf_get_pages(
+	xfs_buf_t		*bp,
 	int			page_count,
-	page_buf_flags_t	flags)
+	xfs_buf_flags_t		flags)
 {
 	/* Make sure that we have a page list */
-	if (pb->pb_pages == NULL) {
-		pb->pb_offset = page_buf_poff(pb->pb_file_offset);
-		pb->pb_page_count = page_count;
-		if (page_count <= PB_PAGES) {
-			pb->pb_pages = pb->pb_page_array;
+	if (bp->b_pages == NULL) {
+		bp->b_offset = xfs_buf_poff(bp->b_file_offset);
+		bp->b_page_count = page_count;
+		if (page_count <= XB_PAGES) {
+			bp->b_pages = bp->b_page_array;
 		} else {
-			pb->pb_pages = kmem_alloc(sizeof(struct page *) *
-					page_count, pb_to_km(flags));
-			if (pb->pb_pages == NULL)
+			bp->b_pages = kmem_alloc(sizeof(struct page *) *
+					page_count, xb_to_km(flags));
+			if (bp->b_pages == NULL)
 				return -ENOMEM;
 		}
-		memset(pb->pb_pages, 0, sizeof(struct page *) * page_count);
+		memset(bp->b_pages, 0, sizeof(struct page *) * page_count);
 	}
 	return 0;
 }
 
 /*
- *	Frees pb_pages if it was malloced.
+ *	Frees b_pages if it was allocated.
  */
 STATIC void
-_pagebuf_free_pages(
+_xfs_buf_free_pages(
 	xfs_buf_t	*bp)
 {
-	if (bp->pb_pages != bp->pb_page_array) {
-		kmem_free(bp->pb_pages,
-			  bp->pb_page_count * sizeof(struct page *));
+	if (bp->b_pages != bp->b_page_array) {
+		kmem_free(bp->b_pages,
+			  bp->b_page_count * sizeof(struct page *));
 	}
 }
 
@@ -299,79 +300,79 @@
  *	Releases the specified buffer.
  *
  * 	The modification state of any associated pages is left unchanged.
- * 	The buffer most not be on any hash - use pagebuf_rele instead for
+ * 	The buffer most not be on any hash - use xfs_buf_rele instead for
  * 	hashed and refcounted buffers
  */
 void
-pagebuf_free(
+xfs_buf_free(
 	xfs_buf_t		*bp)
 {
-	PB_TRACE(bp, "free", 0);
+	XB_TRACE(bp, "free", 0);
 
-	ASSERT(list_empty(&bp->pb_hash_list));
+	ASSERT(list_empty(&bp->b_hash_list));
 
-	if (bp->pb_flags & _PBF_PAGE_CACHE) {
+	if (bp->b_flags & _XBF_PAGE_CACHE) {
 		uint		i;
 
-		if ((bp->pb_flags & PBF_MAPPED) && (bp->pb_page_count > 1))
-			free_address(bp->pb_addr - bp->pb_offset);
+		if ((bp->b_flags & XBF_MAPPED) && (bp->b_page_count > 1))
+			free_address(bp->b_addr - bp->b_offset);
 
-		for (i = 0; i < bp->pb_page_count; i++)
-			page_cache_release(bp->pb_pages[i]);
-		_pagebuf_free_pages(bp);
-	} else if (bp->pb_flags & _PBF_KMEM_ALLOC) {
+		for (i = 0; i < bp->b_page_count; i++)
+			page_cache_release(bp->b_pages[i]);
+		_xfs_buf_free_pages(bp);
+	} else if (bp->b_flags & _XBF_KMEM_ALLOC) {
 		 /*
-		  * XXX(hch): bp->pb_count_desired might be incorrect (see
-		  * pagebuf_associate_memory for details), but fortunately
+		  * XXX(hch): bp->b_count_desired might be incorrect (see
+		  * xfs_buf_associate_memory for details), but fortunately
 		  * the Linux version of kmem_free ignores the len argument..
 		  */
-		kmem_free(bp->pb_addr, bp->pb_count_desired);
-		_pagebuf_free_pages(bp);
+		kmem_free(bp->b_addr, bp->b_count_desired);
+		_xfs_buf_free_pages(bp);
 	}
 
-	pagebuf_deallocate(bp);
+	xfs_buf_deallocate(bp);
 }
 
 /*
  *	Finds all pages for buffer in question and builds it's page list.
  */
 STATIC int
-_pagebuf_lookup_pages(
+_xfs_buf_lookup_pages(
 	xfs_buf_t		*bp,
 	uint			flags)
 {
-	struct address_space	*mapping = bp->pb_target->pbr_mapping;
-	size_t			blocksize = bp->pb_target->pbr_bsize;
-	size_t			size = bp->pb_count_desired;
+	struct address_space	*mapping = bp->b_target->bt_mapping;
+	size_t			blocksize = bp->b_target->bt_bsize;
+	size_t			size = bp->b_count_desired;
 	size_t			nbytes, offset;
-	gfp_t			gfp_mask = pb_to_gfp(flags);
+	gfp_t			gfp_mask = xb_to_gfp(flags);
 	unsigned short		page_count, i;
 	pgoff_t			first;
-	loff_t			end;
+	xfs_off_t		end;
 	int			error;
 
-	end = bp->pb_file_offset + bp->pb_buffer_length;
-	page_count = page_buf_btoc(end) - page_buf_btoct(bp->pb_file_offset);
+	end = bp->b_file_offset + bp->b_buffer_length;
+	page_count = xfs_buf_btoc(end) - xfs_buf_btoct(bp->b_file_offset);
 
-	error = _pagebuf_get_pages(bp, page_count, flags);
+	error = _xfs_buf_get_pages(bp, page_count, flags);
 	if (unlikely(error))
 		return error;
-	bp->pb_flags |= _PBF_PAGE_CACHE;
+	bp->b_flags |= _XBF_PAGE_CACHE;
 
-	offset = bp->pb_offset;
-	first = bp->pb_file_offset >> PAGE_CACHE_SHIFT;
+	offset = bp->b_offset;
+	first = bp->b_file_offset >> PAGE_CACHE_SHIFT;
 
-	for (i = 0; i < bp->pb_page_count; i++) {
+	for (i = 0; i < bp->b_page_count; i++) {
 		struct page	*page;
 		uint		retries = 0;
 
 	      retry:
 		page = find_or_create_page(mapping, first + i, gfp_mask);
 		if (unlikely(page == NULL)) {
-			if (flags & PBF_READ_AHEAD) {
-				bp->pb_page_count = i;
-				for (i = 0; i < bp->pb_page_count; i++)
-					unlock_page(bp->pb_pages[i]);
+			if (flags & XBF_READ_AHEAD) {
+				bp->b_page_count = i;
+				for (i = 0; i < bp->b_page_count; i++)
+					unlock_page(bp->b_pages[i]);
 				return -ENOMEM;
 			}
 
@@ -387,13 +388,13 @@
 					"deadlock in %s (mode:0x%x)\n",
 					__FUNCTION__, gfp_mask);
 
-			XFS_STATS_INC(pb_page_retries);
+			XFS_STATS_INC(xb_page_retries);
 			xfsbufd_wakeup(0, gfp_mask);
 			blk_congestion_wait(WRITE, HZ/50);
 			goto retry;
 		}
 
-		XFS_STATS_INC(pb_page_found);
+		XFS_STATS_INC(xb_page_found);
 
 		nbytes = min_t(size_t, size, PAGE_CACHE_SIZE - offset);
 		size -= nbytes;
@@ -401,27 +402,27 @@
 		if (!PageUptodate(page)) {
 			page_count--;
 			if (blocksize >= PAGE_CACHE_SIZE) {
-				if (flags & PBF_READ)
-					bp->pb_locked = 1;
+				if (flags & XBF_READ)
+					bp->b_locked = 1;
 			} else if (!PagePrivate(page)) {
 				if (test_page_region(page, offset, nbytes))
 					page_count++;
 			}
 		}
 
-		bp->pb_pages[i] = page;
+		bp->b_pages[i] = page;
 		offset = 0;
 	}
 
-	if (!bp->pb_locked) {
-		for (i = 0; i < bp->pb_page_count; i++)
-			unlock_page(bp->pb_pages[i]);
+	if (!bp->b_locked) {
+		for (i = 0; i < bp->b_page_count; i++)
+			unlock_page(bp->b_pages[i]);
 	}
 
-	if (page_count == bp->pb_page_count)
-		bp->pb_flags |= PBF_DONE;
+	if (page_count == bp->b_page_count)
+		bp->b_flags |= XBF_DONE;
 
-	PB_TRACE(bp, "lookup_pages", (long)page_count);
+	XB_TRACE(bp, "lookup_pages", (long)page_count);
 	return error;
 }
 
@@ -429,23 +430,23 @@
  *	Map buffer into kernel address-space if nessecary.
  */
 STATIC int
-_pagebuf_map_pages(
+_xfs_buf_map_pages(
 	xfs_buf_t		*bp,
 	uint			flags)
 {
 	/* A single page buffer is always mappable */
-	if (bp->pb_page_count == 1) {
-		bp->pb_addr = page_address(bp->pb_pages[0]) + bp->pb_offset;
-		bp->pb_flags |= PBF_MAPPED;
-	} else if (flags & PBF_MAPPED) {
+	if (bp->b_page_count == 1) {
+		bp->b_addr = page_address(bp->b_pages[0]) + bp->b_offset;
+		bp->b_flags |= XBF_MAPPED;
+	} else if (flags & XBF_MAPPED) {
 		if (as_list_len > 64)
 			purge_addresses();
-		bp->pb_addr = vmap(bp->pb_pages, bp->pb_page_count,
-				VM_MAP, PAGE_KERNEL);
-		if (unlikely(bp->pb_addr == NULL))
+		bp->b_addr = vmap(bp->b_pages, bp->b_page_count,
+					VM_MAP, PAGE_KERNEL);
+		if (unlikely(bp->b_addr == NULL))
 			return -ENOMEM;
-		bp->pb_addr += bp->pb_offset;
-		bp->pb_flags |= PBF_MAPPED;
+		bp->b_addr += bp->b_offset;
+		bp->b_flags |= XBF_MAPPED;
 	}
 
 	return 0;
@@ -456,9 +457,7 @@
  */
 
 /*
- *	_pagebuf_find
- *
- *	Looks up, and creates if absent, a lockable buffer for
+ *	Look up, and creates if absent, a lockable buffer for
  *	a given range of an inode.  The buffer is returned
  *	locked.	 If other overlapping buffers exist, they are
  *	released before the new buffer is created and locked,
@@ -466,55 +465,55 @@
  *	are unlocked.  No I/O is implied by this call.
  */
 xfs_buf_t *
-_pagebuf_find(
+_xfs_buf_find(
 	xfs_buftarg_t		*btp,	/* block device target		*/
-	loff_t			ioff,	/* starting offset of range	*/
+	xfs_off_t		ioff,	/* starting offset of range	*/
 	size_t			isize,	/* length of range		*/
-	page_buf_flags_t	flags,	/* PBF_TRYLOCK			*/
-	xfs_buf_t		*new_pb)/* newly allocated buffer	*/
+	xfs_buf_flags_t		flags,
+	xfs_buf_t		*new_bp)
 {
-	loff_t			range_base;
+	xfs_off_t		range_base;
 	size_t			range_length;
 	xfs_bufhash_t		*hash;
-	xfs_buf_t		*pb, *n;
+	xfs_buf_t		*bp, *n;
 
 	range_base = (ioff << BBSHIFT);
 	range_length = (isize << BBSHIFT);
 
 	/* Check for IOs smaller than the sector size / not sector aligned */
-	ASSERT(!(range_length < (1 << btp->pbr_sshift)));
-	ASSERT(!(range_base & (loff_t)btp->pbr_smask));
+	ASSERT(!(range_length < (1 << btp->bt_sshift)));
+	ASSERT(!(range_base & (xfs_off_t)btp->bt_smask));
 
 	hash = &btp->bt_hash[hash_long((unsigned long)ioff, btp->bt_hashshift)];
 
 	spin_lock(&hash->bh_lock);
 
-	list_for_each_entry_safe(pb, n, &hash->bh_list, pb_hash_list) {
-		ASSERT(btp == pb->pb_target);
-		if (pb->pb_file_offset == range_base &&
-		    pb->pb_buffer_length == range_length) {
+	list_for_each_entry_safe(bp, n, &hash->bh_list, b_hash_list) {
+		ASSERT(btp == bp->b_target);
+		if (bp->b_file_offset == range_base &&
+		    bp->b_buffer_length == range_length) {
 			/*
-			 * If we look at something bring it to the
+			 * If we look at something, bring it to the
 			 * front of the list for next time.
 			 */
-			atomic_inc(&pb->pb_hold);
-			list_move(&pb->pb_hash_list, &hash->bh_list);
+			atomic_inc(&bp->b_hold);
+			list_move(&bp->b_hash_list, &hash->bh_list);
 			goto found;
 		}
 	}
 
 	/* No match found */
-	if (new_pb) {
-		_pagebuf_initialize(new_pb, btp, range_base,
+	if (new_bp) {
+		_xfs_buf_initialize(new_bp, btp, range_base,
 				range_length, flags);
-		new_pb->pb_hash = hash;
-		list_add(&new_pb->pb_hash_list, &hash->bh_list);
+		new_bp->b_hash = hash;
+		list_add(&new_bp->b_hash_list, &hash->bh_list);
 	} else {
-		XFS_STATS_INC(pb_miss_locked);
+		XFS_STATS_INC(xb_miss_locked);
 	}
 
 	spin_unlock(&hash->bh_lock);
-	return new_pb;
+	return new_bp;
 
 found:
 	spin_unlock(&hash->bh_lock);
@@ -523,74 +522,72 @@
 	 * if this does not work then we need to drop the
 	 * spinlock and do a hard attempt on the semaphore.
 	 */
-	if (down_trylock(&pb->pb_sema)) {
-		if (!(flags & PBF_TRYLOCK)) {
+	if (down_trylock(&bp->b_sema)) {
+		if (!(flags & XBF_TRYLOCK)) {
 			/* wait for buffer ownership */
-			PB_TRACE(pb, "get_lock", 0);
-			pagebuf_lock(pb);
-			XFS_STATS_INC(pb_get_locked_waited);
+			XB_TRACE(bp, "get_lock", 0);
+			xfs_buf_lock(bp);
+			XFS_STATS_INC(xb_get_locked_waited);
 		} else {
 			/* We asked for a trylock and failed, no need
 			 * to look at file offset and length here, we
-			 * know that this pagebuf at least overlaps our
-			 * pagebuf and is locked, therefore our buffer
-			 * either does not exist, or is this buffer
+			 * know that this buffer at least overlaps our
+			 * buffer and is locked, therefore our buffer
+			 * either does not exist, or is this buffer.
 			 */
-
-			pagebuf_rele(pb);
-			XFS_STATS_INC(pb_busy_locked);
-			return (NULL);
+			xfs_buf_rele(bp);
+			XFS_STATS_INC(xb_busy_locked);
+			return NULL;
 		}
 	} else {
 		/* trylock worked */
-		PB_SET_OWNER(pb);
+		XB_SET_OWNER(bp);
 	}
 
-	if (pb->pb_flags & PBF_STALE) {
-		ASSERT((pb->pb_flags & _PBF_DELWRI_Q) == 0);
-		pb->pb_flags &= PBF_MAPPED;
+	if (bp->b_flags & XBF_STALE) {
+		ASSERT((bp->b_flags & _XBF_DELWRI_Q) == 0);
+		bp->b_flags &= XBF_MAPPED;
 	}
-	PB_TRACE(pb, "got_lock", 0);
-	XFS_STATS_INC(pb_get_locked);
-	return (pb);
+	XB_TRACE(bp, "got_lock", 0);
+	XFS_STATS_INC(xb_get_locked);
+	return bp;
 }
 
 /*
- *	xfs_buf_get_flags assembles a buffer covering the specified range.
- *
+ *	Assembles a buffer covering the specified range.
  *	Storage in memory for all portions of the buffer will be allocated,
  *	although backing storage may not be.
  */
 xfs_buf_t *
-xfs_buf_get_flags(			/* allocate a buffer		*/
+xfs_buf_get_flags(
 	xfs_buftarg_t		*target,/* target for buffer		*/
-	loff_t			ioff,	/* starting offset of range	*/
+	xfs_off_t		ioff,	/* starting offset of range	*/
 	size_t			isize,	/* length of range		*/
-	page_buf_flags_t	flags)	/* PBF_TRYLOCK			*/
+	xfs_buf_flags_t		flags)
 {
-	xfs_buf_t		*pb, *new_pb;
+	xfs_buf_t		*bp, *new_bp;
 	int			error = 0, i;
 
-	new_pb = pagebuf_allocate(flags);
-	if (unlikely(!new_pb))
+	new_bp = xfs_buf_allocate(flags);
+	if (unlikely(!new_bp))
 		return NULL;
 
-	pb = _pagebuf_find(target, ioff, isize, flags, new_pb);
-	if (pb == new_pb) {
-		error = _pagebuf_lookup_pages(pb, flags);
+	bp = _xfs_buf_find(target, ioff, isize, flags, new_bp);
+	if (bp == new_bp) {
+		error = _xfs_buf_lookup_pages(bp, flags);
 		if (error)
 			goto no_buffer;
 	} else {
-		pagebuf_deallocate(new_pb);
-		if (unlikely(pb == NULL))
+		xfs_buf_deallocate(new_bp);
+		if (unlikely(bp == NULL))
 			return NULL;
 	}
 
-	for (i = 0; i < pb->pb_page_count; i++)
-		mark_page_accessed(pb->pb_pages[i]);
+	for (i = 0; i < bp->b_page_count; i++)
+		mark_page_accessed(bp->b_pages[i]);
 
-	if (!(pb->pb_flags & PBF_MAPPED)) {
-		error = _pagebuf_map_pages(pb, flags);
+	if (!(bp->b_flags & XBF_MAPPED)) {
+		error = _xfs_buf_map_pages(bp, flags);
 		if (unlikely(error)) {
 			printk(KERN_WARNING "%s: failed to map pages\n",
 					__FUNCTION__);
@@ -598,97 +595,97 @@
 		}
 	}
 
-	XFS_STATS_INC(pb_get);
+	XFS_STATS_INC(xb_get);
 
 	/*
 	 * Always fill in the block number now, the mapped cases can do
 	 * their own overlay of this later.
 	 */
-	pb->pb_bn = ioff;
-	pb->pb_count_desired = pb->pb_buffer_length;
+	bp->b_bn = ioff;
+	bp->b_count_desired = bp->b_buffer_length;
 
-	PB_TRACE(pb, "get", (unsigned long)flags);
-	return pb;
+	XB_TRACE(bp, "get", (unsigned long)flags);
+	return bp;
 
  no_buffer:
-	if (flags & (PBF_LOCK | PBF_TRYLOCK))
-		pagebuf_unlock(pb);
-	pagebuf_rele(pb);
+	if (flags & (XBF_LOCK | XBF_TRYLOCK))
+		xfs_buf_unlock(bp);
+	xfs_buf_rele(bp);
 	return NULL;
 }
 
 xfs_buf_t *
 xfs_buf_read_flags(
 	xfs_buftarg_t		*target,
-	loff_t			ioff,
+	xfs_off_t		ioff,
 	size_t			isize,
-	page_buf_flags_t	flags)
+	xfs_buf_flags_t		flags)
 {
-	xfs_buf_t		*pb;
+	xfs_buf_t		*bp;
 
-	flags |= PBF_READ;
+	flags |= XBF_READ;
 
-	pb = xfs_buf_get_flags(target, ioff, isize, flags);
-	if (pb) {
-		if (!XFS_BUF_ISDONE(pb)) {
-			PB_TRACE(pb, "read", (unsigned long)flags);
-			XFS_STATS_INC(pb_get_read);
-			pagebuf_iostart(pb, flags);
-		} else if (flags & PBF_ASYNC) {
-			PB_TRACE(pb, "read_async", (unsigned long)flags);
+	bp = xfs_buf_get_flags(target, ioff, isize, flags);
+	if (bp) {
+		if (!XFS_BUF_ISDONE(bp)) {
+			XB_TRACE(bp, "read", (unsigned long)flags);
+			XFS_STATS_INC(xb_get_read);
+			xfs_buf_iostart(bp, flags);
+		} else if (flags & XBF_ASYNC) {
+			XB_TRACE(bp, "read_async", (unsigned long)flags);
 			/*
 			 * Read ahead call which is already satisfied,
 			 * drop the buffer
 			 */
 			goto no_buffer;
 		} else {
-			PB_TRACE(pb, "read_done", (unsigned long)flags);
+			XB_TRACE(bp, "read_done", (unsigned long)flags);
 			/* We do not want read in the flags */
-			pb->pb_flags &= ~PBF_READ;
+			bp->b_flags &= ~XBF_READ;
 		}
 	}
 
-	return pb;
+	return bp;
 
  no_buffer:
-	if (flags & (PBF_LOCK | PBF_TRYLOCK))
-		pagebuf_unlock(pb);
-	pagebuf_rele(pb);
+	if (flags & (XBF_LOCK | XBF_TRYLOCK))
+		xfs_buf_unlock(bp);
+	xfs_buf_rele(bp);
 	return NULL;
 }
 
 /*
- * If we are not low on memory then do the readahead in a deadlock
- * safe manner.
+ *	If we are not low on memory then do the readahead in a deadlock
+ *	safe manner.
  */
 void
-pagebuf_readahead(
+xfs_buf_readahead(
 	xfs_buftarg_t		*target,
-	loff_t			ioff,
+	xfs_off_t		ioff,
 	size_t			isize,
-	page_buf_flags_t	flags)
+	xfs_buf_flags_t		flags)
 {
 	struct backing_dev_info *bdi;
 
-	bdi = target->pbr_mapping->backing_dev_info;
+	bdi = target->bt_mapping->backing_dev_info;
 	if (bdi_read_congested(bdi))
 		return;
 
-	flags |= (PBF_TRYLOCK|PBF_ASYNC|PBF_READ_AHEAD);
+	flags |= (XBF_TRYLOCK|XBF_ASYNC|XBF_READ_AHEAD);
 	xfs_buf_read_flags(target, ioff, isize, flags);
 }
 
 xfs_buf_t *
-pagebuf_get_empty(
+xfs_buf_get_empty(
 	size_t			len,
 	xfs_buftarg_t		*target)
 {
-	xfs_buf_t		*pb;
+	xfs_buf_t		*bp;
 
-	pb = pagebuf_allocate(0);
-	if (pb)
-		_pagebuf_initialize(pb, target, 0, len, 0);
-	return pb;
+	bp = xfs_buf_allocate(0);
+	if (bp)
+		_xfs_buf_initialize(bp, target, 0, len, 0);
+	return bp;
 }
 
 static inline struct page *
@@ -704,8 +701,8 @@
 }
 
 int
-pagebuf_associate_memory(
-	xfs_buf_t		*pb,
+xfs_buf_associate_memory(
+	xfs_buf_t		*bp,
 	void			*mem,
 	size_t			len)
 {
@@ -722,40 +719,40 @@
 		page_count++;
 
 	/* Free any previous set of page pointers */
-	if (pb->pb_pages)
-		_pagebuf_free_pages(pb);
+	if (bp->b_pages)
+		_xfs_buf_free_pages(bp);
 
-	pb->pb_pages = NULL;
-	pb->pb_addr = mem;
+	bp->b_pages = NULL;
+	bp->b_addr = mem;
 
-	rval = _pagebuf_get_pages(pb, page_count, 0);
+	rval = _xfs_buf_get_pages(bp, page_count, 0);
 	if (rval)
 		return rval;
 
-	pb->pb_offset = offset;
+	bp->b_offset = offset;
 	ptr = (size_t) mem & PAGE_CACHE_MASK;
 	end = PAGE_CACHE_ALIGN((size_t) mem + len);
 	end_cur = end;
 	/* set up first page */
-	pb->pb_pages[0] = mem_to_page(mem);
+	bp->b_pages[0] = mem_to_page(mem);
 
 	ptr += PAGE_CACHE_SIZE;
-	pb->pb_page_count = ++i;
+	bp->b_page_count = ++i;
 	while (ptr < end) {
-		pb->pb_pages[i] = mem_to_page((void *)ptr);
-		pb->pb_page_count = ++i;
+		bp->b_pages[i] = mem_to_page((void *)ptr);
+		bp->b_page_count = ++i;
 		ptr += PAGE_CACHE_SIZE;
 	}
-	pb->pb_locked = 0;
+	bp->b_locked = 0;
 
-	pb->pb_count_desired = pb->pb_buffer_length = len;
-	pb->pb_flags |= PBF_MAPPED;
+	bp->b_count_desired = bp->b_buffer_length = len;
+	bp->b_flags |= XBF_MAPPED;
 
 	return 0;
 }
 
 xfs_buf_t *
-pagebuf_get_no_daddr(
+xfs_buf_get_noaddr(
 	size_t			len,
 	xfs_buftarg_t		*target)
 {
@@ -764,10 +761,10 @@
 	void			*data;
 	int			error;
 
-	bp = pagebuf_allocate(0);
+	bp = xfs_buf_allocate(0);
 	if (unlikely(bp == NULL))
 		goto fail;
-	_pagebuf_initialize(bp, target, 0, len, 0);
+	_xfs_buf_initialize(bp, target, 0, len, 0);
 
  try_again:
 	data = kmem_alloc(malloc_len, KM_SLEEP | KM_MAYFAIL);
@@ -776,78 +773,73 @@
 
 	/* check whether alignment matches.. */
 	if ((__psunsigned_t)data !=
-	    ((__psunsigned_t)data & ~target->pbr_smask)) {
+	    ((__psunsigned_t)data & ~target->bt_smask)) {
 		/* .. else double the size and try again */
 		kmem_free(data, malloc_len);
 		malloc_len <<= 1;
 		goto try_again;
 	}
 
-	error = pagebuf_associate_memory(bp, data, len);
+	error = xfs_buf_associate_memory(bp, data, len);
 	if (error)
 		goto fail_free_mem;
-	bp->pb_flags |= _PBF_KMEM_ALLOC;
+	bp->b_flags |= _XBF_KMEM_ALLOC;
 
-	pagebuf_unlock(bp);
+	xfs_buf_unlock(bp);
 
-	PB_TRACE(bp, "no_daddr", data);
+	XB_TRACE(bp, "no_daddr", data);
 	return bp;
  fail_free_mem:
 	kmem_free(data, malloc_len);
  fail_free_buf:
-	pagebuf_free(bp);
+	xfs_buf_free(bp);
  fail:
 	return NULL;
 }
 
 /*
- *	pagebuf_hold
- *
  *	Increment reference count on buffer, to hold the buffer concurrently
  *	with another thread which may release (free) the buffer asynchronously.
- *
  *	Must hold the buffer already to call this function.
  */
 void
-pagebuf_hold(
-	xfs_buf_t		*pb)
+xfs_buf_hold(
+	xfs_buf_t		*bp)
 {
-	atomic_inc(&pb->pb_hold);
-	PB_TRACE(pb, "hold", 0);
+	atomic_inc(&bp->b_hold);
+	XB_TRACE(bp, "hold", 0);
 }
 
 /*
- *	pagebuf_rele
- *
- *	pagebuf_rele releases a hold on the specified buffer.  If the
- *	the hold count is 1, pagebuf_rele calls pagebuf_free.
+ *	Releases a hold on the specified buffer.  If the
+ *	the hold count is 1, calls xfs_buf_free.
  */
 void
-pagebuf_rele(
-	xfs_buf_t		*pb)
+xfs_buf_rele(
+	xfs_buf_t		*bp)
 {
-	xfs_bufhash_t		*hash = pb->pb_hash;
+	xfs_bufhash_t		*hash = bp->b_hash;
 
-	PB_TRACE(pb, "rele", pb->pb_relse);
+	XB_TRACE(bp, "rele", bp->b_relse);
 
-	if (atomic_dec_and_lock(&pb->pb_hold, &hash->bh_lock)) {
-		if (pb->pb_relse) {
-			atomic_inc(&pb->pb_hold);
+	if (atomic_dec_and_lock(&bp->b_hold, &hash->bh_lock)) {
+		if (bp->b_relse) {
+			atomic_inc(&bp->b_hold);
 			spin_unlock(&hash->bh_lock);
-			(*(pb->pb_relse)) (pb);
-		} else if (pb->pb_flags & PBF_FS_MANAGED) {
+			(*(bp->b_relse)) (bp);
+		} else if (bp->b_flags & XBF_FS_MANAGED) {
 			spin_unlock(&hash->bh_lock);
 		} else {
-			ASSERT(!(pb->pb_flags & (PBF_DELWRI|_PBF_DELWRI_Q)));
-			list_del_init(&pb->pb_hash_list);
+			ASSERT(!(bp->b_flags & (XBF_DELWRI|_XBF_DELWRI_Q)));
+			list_del_init(&bp->b_hash_list);
 			spin_unlock(&hash->bh_lock);
-			pagebuf_free(pb);
+			xfs_buf_free(bp);
 		}
 	} else {
 		/*
 		 * Catch reference count leaks
 		 */
-		ASSERT(atomic_read(&pb->pb_hold) >= 0);
+		ASSERT(atomic_read(&bp->b_hold) >= 0);
 	}
 }
 
@@ -863,168 +855,122 @@
  */
 
 /*
- *	pagebuf_cond_lock
- *
- *	pagebuf_cond_lock locks a buffer object, if it is not already locked.
- *	Note that this in no way
- *	locks the underlying pages, so it is only useful for synchronizing
- *	concurrent use of page buffer objects, not for synchronizing independent
- *	access to the underlying pages.
+ *	Locks a buffer object, if it is not already locked.
+ *	Note that this in no way locks the underlying pages, so it is only
+ *	useful for synchronizing concurrent use of buffer objects, not for
+ *	synchronizing independent access to the underlying pages.
  */
 int
-pagebuf_cond_lock(			/* lock buffer, if not locked	*/
-					/* returns -EBUSY if locked)	*/
-	xfs_buf_t		*pb)
+xfs_buf_cond_lock(
+	xfs_buf_t		*bp)
 {
 	int			locked;
 
-	locked = down_trylock(&pb->pb_sema) == 0;
+	locked = down_trylock(&bp->b_sema) == 0;
 	if (locked) {
-		PB_SET_OWNER(pb);
+		XB_SET_OWNER(bp);
 	}
-	PB_TRACE(pb, "cond_lock", (long)locked);
-	return(locked ? 0 : -EBUSY);
+	XB_TRACE(bp, "cond_lock", (long)locked);
+	return locked ? 0 : -EBUSY;
 }
 
 #if defined(DEBUG) || defined(XFS_BLI_TRACE)
-/*
- *	pagebuf_lock_value
- *
- *	Return lock value for a pagebuf
- */
 int
-pagebuf_lock_value(
-	xfs_buf_t		*pb)
+xfs_buf_lock_value(
+	xfs_buf_t		*bp)
 {
-	return(atomic_read(&pb->pb_sema.count));
+	return atomic_read(&bp->b_sema.count);
 }
 #endif
 
 /*
- *	pagebuf_lock
- *
- *	pagebuf_lock locks a buffer object.  Note that this in no way
- *	locks the underlying pages, so it is only useful for synchronizing
- *	concurrent use of page buffer objects, not for synchronizing independent
- *	access to the underlying pages.
+ *	Locks a buffer object.
+ *	Note that this in no way locks the underlying pages, so it is only
+ *	useful for synchronizing concurrent use of buffer objects, not for
+ *	synchronizing independent access to the underlying pages.
  */
-int
-pagebuf_lock(
-	xfs_buf_t		*pb)
+void
+xfs_buf_lock(
+	xfs_buf_t		*bp)
 {
-	PB_TRACE(pb, "lock", 0);
-	if (atomic_read(&pb->pb_io_remaining))
-		blk_run_address_space(pb->pb_target->pbr_mapping);
-	down(&pb->pb_sema);
-	PB_SET_OWNER(pb);
-	PB_TRACE(pb, "locked", 0);
-	return 0;
+	XB_TRACE(bp, "lock", 0);
+	if (atomic_read(&bp->b_io_remaining))
+		blk_run_address_space(bp->b_target->bt_mapping);
+	down(&bp->b_sema);
+	XB_SET_OWNER(bp);
+	XB_TRACE(bp, "locked", 0);
 }
 
 /*
- *	pagebuf_unlock
- *
- *	pagebuf_unlock releases the lock on the buffer object created by
- *	pagebuf_lock or pagebuf_cond_lock (not any pinning of underlying pages
- *	created by pagebuf_pin).
- *
+ *	Releases the lock on the buffer object.
  *	If the buffer is marked delwri but is not queued, do so before we
- *	unlock the buffer as we need to set flags correctly. We also need to
+ *	unlock the buffer as we need to set flags correctly.  We also need to
  *	take a reference for the delwri queue because the unlocker is going to
  *	drop their's and they don't know we just queued it.
  */
 void
-pagebuf_unlock(				/* unlock buffer		*/
-	xfs_buf_t		*pb)	/* buffer to unlock		*/
+xfs_buf_unlock(
+	xfs_buf_t		*bp)
 {
-	if ((pb->pb_flags & (PBF_DELWRI|_PBF_DELWRI_Q)) == PBF_DELWRI) {
-		atomic_inc(&pb->pb_hold);
-		pb->pb_flags |= PBF_ASYNC;
-		pagebuf_delwri_queue(pb, 0);
+	if ((bp->b_flags & (XBF_DELWRI|_XBF_DELWRI_Q)) == XBF_DELWRI) {
+		atomic_inc(&bp->b_hold);
+		bp->b_flags |= XBF_ASYNC;
+		xfs_buf_delwri_queue(bp, 0);
 	}
 
-	PB_CLEAR_OWNER(pb);
-	up(&pb->pb_sema);
-	PB_TRACE(pb, "unlock", 0);
+	XB_CLEAR_OWNER(bp);
+	up(&bp->b_sema);
+	XB_TRACE(bp, "unlock", 0);
 }
 
 
 /*
  *	Pinning Buffer Storage in Memory
- */
-
-/*
- *	pagebuf_pin
- *
- *	pagebuf_pin locks all of the memory represented by a buffer in
- *	memory.  Multiple calls to pagebuf_pin and pagebuf_unpin, for
- *	the same or different buffers affecting a given page, will
- *	properly count the number of outstanding "pin" requests.  The
- *	buffer may be released after the pagebuf_pin and a different
- *	buffer used when calling pagebuf_unpin, if desired.
- *	pagebuf_pin should be used by the file system when it wants be
- *	assured that no attempt will be made to force the affected
- *	memory to disk.	 It does not assure that a given logical page
- *	will not be moved to a different physical page.
+ *	Ensure that no attempt to force a buffer to disk will succeed.
  */
 void
-pagebuf_pin(
-	xfs_buf_t		*pb)
+xfs_buf_pin(
+	xfs_buf_t		*bp)
 {
-	atomic_inc(&pb->pb_pin_count);
-	PB_TRACE(pb, "pin", (long)pb->pb_pin_count.counter);
+	atomic_inc(&bp->b_pin_count);
+	XB_TRACE(bp, "pin", (long)bp->b_pin_count.counter);
 }
 
-/*
- *	pagebuf_unpin
- *
- *	pagebuf_unpin reverses the locking of memory performed by
- *	pagebuf_pin.  Note that both functions affected the logical
- *	pages associated with the buffer, not the buffer itself.
- */
 void
-pagebuf_unpin(
-	xfs_buf_t		*pb)
+xfs_buf_unpin(
+	xfs_buf_t		*bp)
 {
-	if (atomic_dec_and_test(&pb->pb_pin_count)) {
-		wake_up_all(&pb->pb_waiters);
-	}
-	PB_TRACE(pb, "unpin", (long)pb->pb_pin_count.counter);
+	if (atomic_dec_and_test(&bp->b_pin_count))
+		wake_up_all(&bp->b_waiters);
+	XB_TRACE(bp, "unpin", (long)bp->b_pin_count.counter);
 }
 
 int
-pagebuf_ispin(
-	xfs_buf_t		*pb)
+xfs_buf_ispin(
+	xfs_buf_t		*bp)
 {
-	return atomic_read(&pb->pb_pin_count);
+	return atomic_read(&bp->b_pin_count);
 }
 
-/*
- *	pagebuf_wait_unpin
- *
- *	pagebuf_wait_unpin waits until all of the memory associated
- *	with the buffer is not longer locked in memory.  It returns
- *	immediately if none of the affected pages are locked.
- */
-static inline void
-_pagebuf_wait_unpin(
-	xfs_buf_t		*pb)
+STATIC void
+xfs_buf_wait_unpin(
+	xfs_buf_t		*bp)
 {
 	DECLARE_WAITQUEUE	(wait, current);
 
-	if (atomic_read(&pb->pb_pin_count) == 0)
+	if (atomic_read(&bp->b_pin_count) == 0)
 		return;
 
-	add_wait_queue(&pb->pb_waiters, &wait);
+	add_wait_queue(&bp->b_waiters, &wait);
 	for (;;) {
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		if (atomic_read(&pb->pb_pin_count) == 0)
+		if (atomic_read(&bp->b_pin_count) == 0)
 			break;
-		if (atomic_read(&pb->pb_io_remaining))
-			blk_run_address_space(pb->pb_target->pbr_mapping);
+		if (atomic_read(&bp->b_io_remaining))
+			blk_run_address_space(bp->b_target->bt_mapping);
 		schedule();
 	}
-	remove_wait_queue(&pb->pb_waiters, &wait);
+	remove_wait_queue(&bp->b_waiters, &wait);
 	set_current_state(TASK_RUNNING);
 }
 
@@ -1032,241 +978,216 @@
  *	Buffer Utility Routines
  */
 
-/*
- *	pagebuf_iodone
- *
- *	pagebuf_iodone marks a buffer for which I/O is in progress
- *	done with respect to that I/O.	The pb_iodone routine, if
- *	present, will be called as a side-effect.
- */
 STATIC void
-pagebuf_iodone_work(
+xfs_buf_iodone_work(
 	void			*v)
 {
 	xfs_buf_t		*bp = (xfs_buf_t *)v;
 
-	if (bp->pb_iodone)
-		(*(bp->pb_iodone))(bp);
-	else if (bp->pb_flags & PBF_ASYNC)
+	if (bp->b_iodone)
+		(*(bp->b_iodone))(bp);
+	else if (bp->b_flags & XBF_ASYNC)
 		xfs_buf_relse(bp);
 }
 
 void
-pagebuf_iodone(
-	xfs_buf_t		*pb,
+xfs_buf_ioend(
+	xfs_buf_t		*bp,
 	int			schedule)
 {
-	pb->pb_flags &= ~(PBF_READ | PBF_WRITE);
-	if (pb->pb_error == 0)
-		pb->pb_flags |= PBF_DONE;
+	bp->b_flags &= ~(XBF_READ | XBF_WRITE);
+	if (bp->b_error == 0)
+		bp->b_flags |= XBF_DONE;
 
-	PB_TRACE(pb, "iodone", pb->pb_iodone);
+	XB_TRACE(bp, "iodone", bp->b_iodone);
 
-	if ((pb->pb_iodone) || (pb->pb_flags & PBF_ASYNC)) {
+	if ((bp->b_iodone) || (bp->b_flags & XBF_ASYNC)) {
 		if (schedule) {
-			INIT_WORK(&pb->pb_iodone_work, pagebuf_iodone_work, pb);
-			queue_work(xfslogd_workqueue, &pb->pb_iodone_work);
+			INIT_WORK(&bp->b_iodone_work, xfs_buf_iodone_work, bp);
+			queue_work(xfslogd_workqueue, &bp->b_iodone_work);
 		} else {
-			pagebuf_iodone_work(pb);
+			xfs_buf_iodone_work(bp);
 		}
 	} else {
-		up(&pb->pb_iodonesema);
+		up(&bp->b_iodonesema);
 	}
 }
 
-/*
- *	pagebuf_ioerror
- *
- *	pagebuf_ioerror sets the error code for a buffer.
- */
 void
-pagebuf_ioerror(			/* mark/clear buffer error flag */
-	xfs_buf_t		*pb,	/* buffer to mark		*/
-	int			error)	/* error to store (0 if none)	*/
+xfs_buf_ioerror(
+	xfs_buf_t		*bp,
+	int			error)
 {
 	ASSERT(error >= 0 && error <= 0xffff);
-	pb->pb_error = (unsigned short)error;
-	PB_TRACE(pb, "ioerror", (unsigned long)error);
+	bp->b_error = (unsigned short)error;
+	XB_TRACE(bp, "ioerror", (unsigned long)error);
 }
 
 /*
- *	pagebuf_iostart
- *
- *	pagebuf_iostart initiates I/O on a buffer, based on the flags supplied.
- *	If necessary, it will arrange for any disk space allocation required,
- *	and it will break up the request if the block mappings require it.
- *	The pb_iodone routine in the buffer supplied will only be called
+ *	Initiate I/O on a buffer, based on the flags supplied.
+ *	The b_iodone routine in the buffer supplied will only be called
  *	when all of the subsidiary I/O requests, if any, have been completed.
- *	pagebuf_iostart calls the pagebuf_ioinitiate routine or
- *	pagebuf_iorequest, if the former routine is not defined, to start
- *	the I/O on a given low-level request.
  */
 int
-pagebuf_iostart(			/* start I/O on a buffer	  */
-	xfs_buf_t		*pb,	/* buffer to start		  */
-	page_buf_flags_t	flags)	/* PBF_LOCK, PBF_ASYNC, PBF_READ, */
-					/* PBF_WRITE, PBF_DELWRI,	  */
-					/* PBF_DONT_BLOCK		  */
+xfs_buf_iostart(
+	xfs_buf_t		*bp,
+	xfs_buf_flags_t		flags)
 {
 	int			status = 0;
 
-	PB_TRACE(pb, "iostart", (unsigned long)flags);
+	XB_TRACE(bp, "iostart", (unsigned long)flags);
 
-	if (flags & PBF_DELWRI) {
-		pb->pb_flags &= ~(PBF_READ | PBF_WRITE | PBF_ASYNC);
-		pb->pb_flags |= flags & (PBF_DELWRI | PBF_ASYNC);
-		pagebuf_delwri_queue(pb, 1);
+	if (flags & XBF_DELWRI) {
+		bp->b_flags &= ~(XBF_READ | XBF_WRITE | XBF_ASYNC);
+		bp->b_flags |= flags & (XBF_DELWRI | XBF_ASYNC);
+		xfs_buf_delwri_queue(bp, 1);
 		return status;
 	}
 
-	pb->pb_flags &= ~(PBF_READ | PBF_WRITE | PBF_ASYNC | PBF_DELWRI | \
-			PBF_READ_AHEAD | _PBF_RUN_QUEUES);
-	pb->pb_flags |= flags & (PBF_READ | PBF_WRITE | PBF_ASYNC | \
-			PBF_READ_AHEAD | _PBF_RUN_QUEUES);
+	bp->b_flags &= ~(XBF_READ | XBF_WRITE | XBF_ASYNC | XBF_DELWRI | \
+			XBF_READ_AHEAD | _XBF_RUN_QUEUES);
+	bp->b_flags |= flags & (XBF_READ | XBF_WRITE | XBF_ASYNC | \
+			XBF_READ_AHEAD | _XBF_RUN_QUEUES);
 
-	BUG_ON(pb->pb_bn == XFS_BUF_DADDR_NULL);
+	BUG_ON(bp->b_bn == XFS_BUF_DADDR_NULL);
 
 	/* For writes allow an alternate strategy routine to precede
 	 * the actual I/O request (which may not be issued at all in
 	 * a shutdown situation, for example).
 	 */
-	status = (flags & PBF_WRITE) ?
-		pagebuf_iostrategy(pb) : pagebuf_iorequest(pb);
+	status = (flags & XBF_WRITE) ?
+		xfs_buf_iostrategy(bp) : xfs_buf_iorequest(bp);
 
 	/* Wait for I/O if we are not an async request.
 	 * Note: async I/O request completion will release the buffer,
 	 * and that can already be done by this point.  So using the
 	 * buffer pointer from here on, after async I/O, is invalid.
 	 */
-	if (!status && !(flags & PBF_ASYNC))
-		status = pagebuf_iowait(pb);
+	if (!status && !(flags & XBF_ASYNC))
+		status = xfs_buf_iowait(bp);
 
 	return status;
 }
 
-/*
- * Helper routine for pagebuf_iorequest
- */
-
 STATIC __inline__ int
-_pagebuf_iolocked(
-	xfs_buf_t		*pb)
+_xfs_buf_iolocked(
+	xfs_buf_t		*bp)
 {
-	ASSERT(pb->pb_flags & (PBF_READ|PBF_WRITE));
-	if (pb->pb_flags & PBF_READ)
-		return pb->pb_locked;
+	ASSERT(bp->b_flags & (XBF_READ | XBF_WRITE));
+	if (bp->b_flags & XBF_READ)
+		return bp->b_locked;
 	return 0;
 }
 
 STATIC __inline__ void
-_pagebuf_iodone(
-	xfs_buf_t		*pb,
+_xfs_buf_ioend(
+	xfs_buf_t		*bp,
 	int			schedule)
 {
-	if (atomic_dec_and_test(&pb->pb_io_remaining) == 1) {
-		pb->pb_locked = 0;
-		pagebuf_iodone(pb, schedule);
+	if (atomic_dec_and_test(&bp->b_io_remaining) == 1) {
+		bp->b_locked = 0;
+		xfs_buf_ioend(bp, schedule);
 	}
 }
 
 STATIC int
-bio_end_io_pagebuf(
+xfs_buf_bio_end_io(
 	struct bio		*bio,
 	unsigned int		bytes_done,
 	int			error)
 {
-	xfs_buf_t		*pb = (xfs_buf_t *)bio->bi_private;
-	unsigned int		blocksize = pb->pb_target->pbr_bsize;
+	xfs_buf_t		*bp = (xfs_buf_t *)bio->bi_private;
+	unsigned int		blocksize = bp->b_target->bt_bsize;
 	struct bio_vec		*bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
 
 	if (bio->bi_size)
 		return 1;
 
 	if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
-		pb->pb_error = EIO;
+		bp->b_error = EIO;
 
 	do {
 		struct page	*page = bvec->bv_page;
 
-		if (unlikely(pb->pb_error)) {
-			if (pb->pb_flags & PBF_READ)
+		if (unlikely(bp->b_error)) {
+			if (bp->b_flags & XBF_READ)
 				ClearPageUptodate(page);
 			SetPageError(page);
-		} else if (blocksize == PAGE_CACHE_SIZE) {
+		} else if (blocksize >= PAGE_CACHE_SIZE) {
 			SetPageUptodate(page);
 		} else if (!PagePrivate(page) &&
-				(pb->pb_flags & _PBF_PAGE_CACHE)) {
+				(bp->b_flags & _XBF_PAGE_CACHE)) {
 			set_page_region(page, bvec->bv_offset, bvec->bv_len);
 		}
 
 		if (--bvec >= bio->bi_io_vec)
 			prefetchw(&bvec->bv_page->flags);
 
-		if (_pagebuf_iolocked(pb)) {
+		if (_xfs_buf_iolocked(bp)) {
 			unlock_page(page);
 		}
 	} while (bvec >= bio->bi_io_vec);
 
-	_pagebuf_iodone(pb, 1);
+	_xfs_buf_ioend(bp, 1);
 	bio_put(bio);
 	return 0;
 }
 
 STATIC void
-_pagebuf_ioapply(
-	xfs_buf_t		*pb)
+_xfs_buf_ioapply(
+	xfs_buf_t		*bp)
 {
 	int			i, rw, map_i, total_nr_pages, nr_pages;
 	struct bio		*bio;
-	int			offset = pb->pb_offset;
-	int			size = pb->pb_count_desired;
-	sector_t		sector = pb->pb_bn;
-	unsigned int		blocksize = pb->pb_target->pbr_bsize;
-	int			locking = _pagebuf_iolocked(pb);
+	int			offset = bp->b_offset;
+	int			size = bp->b_count_desired;
+	sector_t		sector = bp->b_bn;
+	unsigned int		blocksize = bp->b_target->bt_bsize;
+	int			locking = _xfs_buf_iolocked(bp);
 
-	total_nr_pages = pb->pb_page_count;
+	total_nr_pages = bp->b_page_count;
 	map_i = 0;
 
-	if (pb->pb_flags & _PBF_RUN_QUEUES) {
-		pb->pb_flags &= ~_PBF_RUN_QUEUES;
-		rw = (pb->pb_flags & PBF_READ) ? READ_SYNC : WRITE_SYNC;
+	if (bp->b_flags & _XBF_RUN_QUEUES) {
+		bp->b_flags &= ~_XBF_RUN_QUEUES;
+		rw = (bp->b_flags & XBF_READ) ? READ_SYNC : WRITE_SYNC;
 	} else {
-		rw = (pb->pb_flags & PBF_READ) ? READ : WRITE;
+		rw = (bp->b_flags & XBF_READ) ? READ : WRITE;
 	}
 
-	if (pb->pb_flags & PBF_ORDERED) {
-		ASSERT(!(pb->pb_flags & PBF_READ));
+	if (bp->b_flags & XBF_ORDERED) {
+		ASSERT(!(bp->b_flags & XBF_READ));
 		rw = WRITE_BARRIER;
 	}
 
-	/* Special code path for reading a sub page size pagebuf in --
+	/* Special code path for reading a sub page size buffer in --
 	 * we populate up the whole page, and hence the other metadata
 	 * in the same page.  This optimization is only valid when the
-	 * filesystem block size and the page size are equal.
+	 * filesystem block size is not smaller than the page size.
 	 */
-	if ((pb->pb_buffer_length < PAGE_CACHE_SIZE) &&
-	    (pb->pb_flags & PBF_READ) && locking &&
-	    (blocksize == PAGE_CACHE_SIZE)) {
+	if ((bp->b_buffer_length < PAGE_CACHE_SIZE) &&
+	    (bp->b_flags & XBF_READ) && locking &&
+	    (blocksize >= PAGE_CACHE_SIZE)) {
 		bio = bio_alloc(GFP_NOIO, 1);
 
-		bio->bi_bdev = pb->pb_target->pbr_bdev;
+		bio->bi_bdev = bp->b_target->bt_bdev;
 		bio->bi_sector = sector - (offset >> BBSHIFT);
-		bio->bi_end_io = bio_end_io_pagebuf;
-		bio->bi_private = pb;
+		bio->bi_end_io = xfs_buf_bio_end_io;
+		bio->bi_private = bp;
 
-		bio_add_page(bio, pb->pb_pages[0], PAGE_CACHE_SIZE, 0);
+		bio_add_page(bio, bp->b_pages[0], PAGE_CACHE_SIZE, 0);
 		size = 0;
 
-		atomic_inc(&pb->pb_io_remaining);
+		atomic_inc(&bp->b_io_remaining);
 
 		goto submit_io;
 	}
 
 	/* Lock down the pages which we need to for the request */
-	if (locking && (pb->pb_flags & PBF_WRITE) && (pb->pb_locked == 0)) {
+	if (locking && (bp->b_flags & XBF_WRITE) && (bp->b_locked == 0)) {
 		for (i = 0; size; i++) {
 			int		nbytes = PAGE_CACHE_SIZE - offset;
-			struct page	*page = pb->pb_pages[i];
+			struct page	*page = bp->b_pages[i];
 
 			if (nbytes > size)
 				nbytes = size;
@@ -1276,30 +1197,30 @@
 			size -= nbytes;
 			offset = 0;
 		}
-		offset = pb->pb_offset;
-		size = pb->pb_count_desired;
+		offset = bp->b_offset;
+		size = bp->b_count_desired;
 	}
 
 next_chunk:
-	atomic_inc(&pb->pb_io_remaining);
+	atomic_inc(&bp->b_io_remaining);
 	nr_pages = BIO_MAX_SECTORS >> (PAGE_SHIFT - BBSHIFT);
 	if (nr_pages > total_nr_pages)
 		nr_pages = total_nr_pages;
 
 	bio = bio_alloc(GFP_NOIO, nr_pages);
-	bio->bi_bdev = pb->pb_target->pbr_bdev;
+	bio->bi_bdev = bp->b_target->bt_bdev;
 	bio->bi_sector = sector;
-	bio->bi_end_io = bio_end_io_pagebuf;
-	bio->bi_private = pb;
+	bio->bi_end_io = xfs_buf_bio_end_io;
+	bio->bi_private = bp;
 
 	for (; size && nr_pages; nr_pages--, map_i++) {
-		int	nbytes = PAGE_CACHE_SIZE - offset;
+		int	rbytes, nbytes = PAGE_CACHE_SIZE - offset;
 
 		if (nbytes > size)
 			nbytes = size;
 
-		if (bio_add_page(bio, pb->pb_pages[map_i],
-					nbytes, offset) < nbytes)
+		rbytes = bio_add_page(bio, bp->b_pages[map_i], nbytes, offset);
+		if (rbytes < nbytes)
 			break;
 
 		offset = 0;
@@ -1315,107 +1236,102 @@
 			goto next_chunk;
 	} else {
 		bio_put(bio);
-		pagebuf_ioerror(pb, EIO);
+		xfs_buf_ioerror(bp, EIO);
 	}
 }
 
-/*
- *	pagebuf_iorequest -- the core I/O request routine.
- */
 int
-pagebuf_iorequest(			/* start real I/O		*/
-	xfs_buf_t		*pb)	/* buffer to convey to device	*/
+xfs_buf_iorequest(
+	xfs_buf_t		*bp)
 {
-	PB_TRACE(pb, "iorequest", 0);
+	XB_TRACE(bp, "iorequest", 0);
 
-	if (pb->pb_flags & PBF_DELWRI) {
-		pagebuf_delwri_queue(pb, 1);
+	if (bp->b_flags & XBF_DELWRI) {
+		xfs_buf_delwri_queue(bp, 1);
 		return 0;
 	}
 
-	if (pb->pb_flags & PBF_WRITE) {
-		_pagebuf_wait_unpin(pb);
+	if (bp->b_flags & XBF_WRITE) {
+		xfs_buf_wait_unpin(bp);
 	}
 
-	pagebuf_hold(pb);
+	xfs_buf_hold(bp);
 
 	/* Set the count to 1 initially, this will stop an I/O
 	 * completion callout which happens before we have started
-	 * all the I/O from calling pagebuf_iodone too early.
+	 * all the I/O from calling xfs_buf_ioend too early.
 	 */
-	atomic_set(&pb->pb_io_remaining, 1);
-	_pagebuf_ioapply(pb);
-	_pagebuf_iodone(pb, 0);
+	atomic_set(&bp->b_io_remaining, 1);
+	_xfs_buf_ioapply(bp);
+	_xfs_buf_ioend(bp, 0);
 
-	pagebuf_rele(pb);
+	xfs_buf_rele(bp);
 	return 0;
 }
 
 /*
- *	pagebuf_iowait
- *
- *	pagebuf_iowait waits for I/O to complete on the buffer supplied.
- *	It returns immediately if no I/O is pending.  In any case, it returns
- *	the error code, if any, or 0 if there is no error.
+ *	Waits for I/O to complete on the buffer supplied.
+ *	It returns immediately if no I/O is pending.
+ *	It returns the I/O error code, if any, or 0 if there was no error.
  */
 int
-pagebuf_iowait(
-	xfs_buf_t		*pb)
+xfs_buf_iowait(
+	xfs_buf_t		*bp)
 {
-	PB_TRACE(pb, "iowait", 0);
-	if (atomic_read(&pb->pb_io_remaining))
-		blk_run_address_space(pb->pb_target->pbr_mapping);
-	down(&pb->pb_iodonesema);
-	PB_TRACE(pb, "iowaited", (long)pb->pb_error);
-	return pb->pb_error;
+	XB_TRACE(bp, "iowait", 0);
+	if (atomic_read(&bp->b_io_remaining))
+		blk_run_address_space(bp->b_target->bt_mapping);
+	down(&bp->b_iodonesema);
+	XB_TRACE(bp, "iowaited", (long)bp->b_error);
+	return bp->b_error;
 }
 
-caddr_t
-pagebuf_offset(
-	xfs_buf_t		*pb,
+xfs_caddr_t
+xfs_buf_offset(
+	xfs_buf_t		*bp,
 	size_t			offset)
 {
 	struct page		*page;
 
-	offset += pb->pb_offset;
+	if (bp->b_flags & XBF_MAPPED)
+		return XFS_BUF_PTR(bp) + offset;
 
-	page = pb->pb_pages[offset >> PAGE_CACHE_SHIFT];
-	return (caddr_t) page_address(page) + (offset & (PAGE_CACHE_SIZE - 1));
+	offset += bp->b_offset;
+	page = bp->b_pages[offset >> PAGE_CACHE_SHIFT];
+	return (xfs_caddr_t)page_address(page) + (offset & (PAGE_CACHE_SIZE-1));
 }
 
 /*
- *	pagebuf_iomove
- *
  *	Move data into or out of a buffer.
  */
 void
-pagebuf_iomove(
-	xfs_buf_t		*pb,	/* buffer to process		*/
+xfs_buf_iomove(
+	xfs_buf_t		*bp,	/* buffer to process		*/
 	size_t			boff,	/* starting buffer offset	*/
 	size_t			bsize,	/* length to copy		*/
 	caddr_t			data,	/* data address			*/
-	page_buf_rw_t		mode)	/* read/write flag		*/
+	xfs_buf_rw_t		mode)	/* read/write/zero flag		*/
 {
 	size_t			bend, cpoff, csize;
 	struct page		*page;
 
 	bend = boff + bsize;
 	while (boff < bend) {
-		page = pb->pb_pages[page_buf_btoct(boff + pb->pb_offset)];
-		cpoff = page_buf_poff(boff + pb->pb_offset);
+		page = bp->b_pages[xfs_buf_btoct(boff + bp->b_offset)];
+		cpoff = xfs_buf_poff(boff + bp->b_offset);
 		csize = min_t(size_t,
-			      PAGE_CACHE_SIZE-cpoff, pb->pb_count_desired-boff);
+			      PAGE_CACHE_SIZE-cpoff, bp->b_count_desired-boff);
 
 		ASSERT(((csize + cpoff) <= PAGE_CACHE_SIZE));
 
 		switch (mode) {
-		case PBRW_ZERO:
+		case XBRW_ZERO:
 			memset(page_address(page) + cpoff, 0, csize);
 			break;
-		case PBRW_READ:
+		case XBRW_READ:
 			memcpy(data, page_address(page) + cpoff, csize);
 			break;
-		case PBRW_WRITE:
+		case XBRW_WRITE:
 			memcpy(page_address(page) + cpoff, data, csize);
 		}
 
@@ -1425,12 +1341,12 @@
 }
 
 /*
- *	Handling of buftargs.
+ *	Handling of buffer targets (buftargs).
  */
 
 /*
- * Wait for any bufs with callbacks that have been submitted but
- * have not yet returned... walk the hash list for the target.
+ *	Wait for any bufs with callbacks that have been submitted but
+ *	have not yet returned... walk the hash list for the target.
  */
 void
 xfs_wait_buftarg(
@@ -1444,15 +1360,15 @@
 		hash = &btp->bt_hash[i];
 again:
 		spin_lock(&hash->bh_lock);
-		list_for_each_entry_safe(bp, n, &hash->bh_list, pb_hash_list) {
-			ASSERT(btp == bp->pb_target);
-			if (!(bp->pb_flags & PBF_FS_MANAGED)) {
+		list_for_each_entry_safe(bp, n, &hash->bh_list, b_hash_list) {
+			ASSERT(btp == bp->b_target);
+			if (!(bp->b_flags & XBF_FS_MANAGED)) {
 				spin_unlock(&hash->bh_lock);
 				/*
 				 * Catch superblock reference count leaks
 				 * immediately
 				 */
-				BUG_ON(bp->pb_bn == 0);
+				BUG_ON(bp->b_bn == 0);
 				delay(100);
 				goto again;
 			}
@@ -1462,9 +1378,9 @@
 }
 
 /*
- * Allocate buffer hash table for a given target.
- * For devices containing metadata (i.e. not the log/realtime devices)
- * we need to allocate a much larger hash table.
+ *	Allocate buffer hash table for a given target.
+ *	For devices containing metadata (i.e. not the log/realtime devices)
+ *	we need to allocate a much larger hash table.
  */
 STATIC void
 xfs_alloc_bufhash(
@@ -1487,11 +1403,34 @@
 xfs_free_bufhash(
 	xfs_buftarg_t		*btp)
 {
-	kmem_free(btp->bt_hash,
-			(1 << btp->bt_hashshift) * sizeof(xfs_bufhash_t));
+	kmem_free(btp->bt_hash, (1<<btp->bt_hashshift) * sizeof(xfs_bufhash_t));
 	btp->bt_hash = NULL;
 }
 
+/*
+ *	buftarg list for delwrite queue processing
+ */
+STATIC LIST_HEAD(xfs_buftarg_list);
+STATIC DEFINE_SPINLOCK(xfs_buftarg_lock);
+
+STATIC void
+xfs_register_buftarg(
+	xfs_buftarg_t           *btp)
+{
+	spin_lock(&xfs_buftarg_lock);
+	list_add(&btp->bt_list, &xfs_buftarg_list);
+	spin_unlock(&xfs_buftarg_lock);
+}
+
+STATIC void
+xfs_unregister_buftarg(
+	xfs_buftarg_t           *btp)
+{
+	spin_lock(&xfs_buftarg_lock);
+	list_del(&btp->bt_list);
+	spin_unlock(&xfs_buftarg_lock);
+}
+
 void
 xfs_free_buftarg(
 	xfs_buftarg_t		*btp,
@@ -1499,9 +1438,16 @@
 {
 	xfs_flush_buftarg(btp, 1);
 	if (external)
-		xfs_blkdev_put(btp->pbr_bdev);
+		xfs_blkdev_put(btp->bt_bdev);
 	xfs_free_bufhash(btp);
-	iput(btp->pbr_mapping->host);
+	iput(btp->bt_mapping->host);
+
+	/* Unregister the buftarg first so that we don't get a
+	 * wakeup finding a non-existent task
+	 */
+	xfs_unregister_buftarg(btp);
+	kthread_stop(btp->bt_task);
+
 	kmem_free(btp, sizeof(*btp));
 }
 
@@ -1512,11 +1458,11 @@
 	unsigned int		sectorsize,
 	int			verbose)
 {
-	btp->pbr_bsize = blocksize;
-	btp->pbr_sshift = ffs(sectorsize) - 1;
-	btp->pbr_smask = sectorsize - 1;
+	btp->bt_bsize = blocksize;
+	btp->bt_sshift = ffs(sectorsize) - 1;
+	btp->bt_smask = sectorsize - 1;
 
-	if (set_blocksize(btp->pbr_bdev, sectorsize)) {
+	if (set_blocksize(btp->bt_bdev, sectorsize)) {
 		printk(KERN_WARNING
 			"XFS: Cannot set_blocksize to %u on device %s\n",
 			sectorsize, XFS_BUFTARG_NAME(btp));
@@ -1536,10 +1482,10 @@
 }
 
 /*
-* When allocating the initial buffer target we have not yet
-* read in the superblock, so don't know what sized sectors
-* are being used is at this early stage.  Play safe.
-*/
+ *	When allocating the initial buffer target we have not yet
+ *	read in the superblock, so don't know what sized sectors
+ *	are being used is at this early stage.  Play safe.
+ */
 STATIC int
 xfs_setsize_buftarg_early(
 	xfs_buftarg_t		*btp,
@@ -1587,10 +1533,30 @@
 	mapping->a_ops = &mapping_aops;
 	mapping->backing_dev_info = bdi;
 	mapping_set_gfp_mask(mapping, GFP_NOFS);
-	btp->pbr_mapping = mapping;
+	btp->bt_mapping = mapping;
 	return 0;
 }
 
+STATIC int
+xfs_alloc_delwrite_queue(
+	xfs_buftarg_t		*btp)
+{
+	int	error = 0;
+
+	INIT_LIST_HEAD(&btp->bt_list);
+	INIT_LIST_HEAD(&btp->bt_delwrite_queue);
+	spinlock_init(&btp->bt_delwrite_lock, "delwri_lock");
+	btp->bt_flags = 0;
+	btp->bt_task = kthread_run(xfsbufd, btp, "xfsbufd");
+	if (IS_ERR(btp->bt_task)) {
+		error = PTR_ERR(btp->bt_task);
+		goto out_error;
+	}
+	xfs_register_buftarg(btp);
+out_error:
+	return error;
+}
+
 xfs_buftarg_t *
 xfs_alloc_buftarg(
 	struct block_device	*bdev,
@@ -1600,12 +1566,14 @@
 
 	btp = kmem_zalloc(sizeof(*btp), KM_SLEEP);
 
-	btp->pbr_dev =  bdev->bd_dev;
-	btp->pbr_bdev = bdev;
+	btp->bt_dev =  bdev->bd_dev;
+	btp->bt_bdev = bdev;
 	if (xfs_setsize_buftarg_early(btp, bdev))
 		goto error;
 	if (xfs_mapping_buftarg(btp, bdev))
 		goto error;
+	if (xfs_alloc_delwrite_queue(btp))
+		goto error;
 	xfs_alloc_bufhash(btp, external);
 	return btp;
 
@@ -1616,83 +1584,81 @@
 
 
 /*
- * Pagebuf delayed write buffer handling
+ *	Delayed write buffer handling
  */
-
-STATIC LIST_HEAD(pbd_delwrite_queue);
-STATIC DEFINE_SPINLOCK(pbd_delwrite_lock);
-
 STATIC void
-pagebuf_delwri_queue(
-	xfs_buf_t		*pb,
+xfs_buf_delwri_queue(
+	xfs_buf_t		*bp,
 	int			unlock)
 {
-	PB_TRACE(pb, "delwri_q", (long)unlock);
-	ASSERT((pb->pb_flags & (PBF_DELWRI|PBF_ASYNC)) ==
-					(PBF_DELWRI|PBF_ASYNC));
+	struct list_head	*dwq = &bp->b_target->bt_delwrite_queue;
+	spinlock_t		*dwlk = &bp->b_target->bt_delwrite_lock;
 
-	spin_lock(&pbd_delwrite_lock);
+	XB_TRACE(bp, "delwri_q", (long)unlock);
+	ASSERT((bp->b_flags&(XBF_DELWRI|XBF_ASYNC)) == (XBF_DELWRI|XBF_ASYNC));
+
+	spin_lock(dwlk);
 	/* If already in the queue, dequeue and place at tail */
-	if (!list_empty(&pb->pb_list)) {
-		ASSERT(pb->pb_flags & _PBF_DELWRI_Q);
-		if (unlock) {
-			atomic_dec(&pb->pb_hold);
-		}
-		list_del(&pb->pb_list);
+	if (!list_empty(&bp->b_list)) {
+		ASSERT(bp->b_flags & _XBF_DELWRI_Q);
+		if (unlock)
+			atomic_dec(&bp->b_hold);
+		list_del(&bp->b_list);
 	}
 
-	pb->pb_flags |= _PBF_DELWRI_Q;
-	list_add_tail(&pb->pb_list, &pbd_delwrite_queue);
-	pb->pb_queuetime = jiffies;
-	spin_unlock(&pbd_delwrite_lock);
+	bp->b_flags |= _XBF_DELWRI_Q;
+	list_add_tail(&bp->b_list, dwq);
+	bp->b_queuetime = jiffies;
+	spin_unlock(dwlk);
 
 	if (unlock)
-		pagebuf_unlock(pb);
+		xfs_buf_unlock(bp);
 }
 
 void
-pagebuf_delwri_dequeue(
-	xfs_buf_t		*pb)
+xfs_buf_delwri_dequeue(
+	xfs_buf_t		*bp)
 {
+	spinlock_t		*dwlk = &bp->b_target->bt_delwrite_lock;
 	int			dequeued = 0;
 
-	spin_lock(&pbd_delwrite_lock);
-	if ((pb->pb_flags & PBF_DELWRI) && !list_empty(&pb->pb_list)) {
-		ASSERT(pb->pb_flags & _PBF_DELWRI_Q);
-		list_del_init(&pb->pb_list);
+	spin_lock(dwlk);
+	if ((bp->b_flags & XBF_DELWRI) && !list_empty(&bp->b_list)) {
+		ASSERT(bp->b_flags & _XBF_DELWRI_Q);
+		list_del_init(&bp->b_list);
 		dequeued = 1;
 	}
-	pb->pb_flags &= ~(PBF_DELWRI|_PBF_DELWRI_Q);
-	spin_unlock(&pbd_delwrite_lock);
+	bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q);
+	spin_unlock(dwlk);
 
 	if (dequeued)
-		pagebuf_rele(pb);
+		xfs_buf_rele(bp);
 
-	PB_TRACE(pb, "delwri_dq", (long)dequeued);
+	XB_TRACE(bp, "delwri_dq", (long)dequeued);
 }
 
 STATIC void
-pagebuf_runall_queues(
+xfs_buf_runall_queues(
 	struct workqueue_struct	*queue)
 {
 	flush_workqueue(queue);
 }
 
-/* Defines for pagebuf daemon */
-STATIC struct task_struct *xfsbufd_task;
-STATIC int xfsbufd_force_flush;
-STATIC int xfsbufd_force_sleep;
-
 STATIC int
 xfsbufd_wakeup(
 	int			priority,
 	gfp_t			mask)
 {
-	if (xfsbufd_force_sleep)
-		return 0;
-	xfsbufd_force_flush = 1;
-	barrier();
-	wake_up_process(xfsbufd_task);
+	xfs_buftarg_t		*btp;
+
+	spin_lock(&xfs_buftarg_lock);
+	list_for_each_entry(btp, &xfs_buftarg_list, bt_list) {
+		if (test_bit(XBT_FORCE_SLEEP, &btp->bt_flags))
+			continue;
+		set_bit(XBT_FORCE_FLUSH, &btp->bt_flags);
+		wake_up_process(btp->bt_task);
+	}
+	spin_unlock(&xfs_buftarg_lock);
 	return 0;
 }
 
@@ -1702,67 +1668,70 @@
 {
 	struct list_head	tmp;
 	unsigned long		age;
-	xfs_buftarg_t		*target;
-	xfs_buf_t		*pb, *n;
+	xfs_buftarg_t		*target = (xfs_buftarg_t *)data;
+	xfs_buf_t		*bp, *n;
+	struct list_head	*dwq = &target->bt_delwrite_queue;
+	spinlock_t		*dwlk = &target->bt_delwrite_lock;
 
 	current->flags |= PF_MEMALLOC;
 
 	INIT_LIST_HEAD(&tmp);
 	do {
 		if (unlikely(freezing(current))) {
-			xfsbufd_force_sleep = 1;
+			set_bit(XBT_FORCE_SLEEP, &target->bt_flags);
 			refrigerator();
 		} else {
-			xfsbufd_force_sleep = 0;
+			clear_bit(XBT_FORCE_SLEEP, &target->bt_flags);
 		}
 
 		schedule_timeout_interruptible(
 			xfs_buf_timer_centisecs * msecs_to_jiffies(10));
 
 		age = xfs_buf_age_centisecs * msecs_to_jiffies(10);
-		spin_lock(&pbd_delwrite_lock);
-		list_for_each_entry_safe(pb, n, &pbd_delwrite_queue, pb_list) {
-			PB_TRACE(pb, "walkq1", (long)pagebuf_ispin(pb));
-			ASSERT(pb->pb_flags & PBF_DELWRI);
+		spin_lock(dwlk);
+		list_for_each_entry_safe(bp, n, dwq, b_list) {
+			XB_TRACE(bp, "walkq1", (long)xfs_buf_ispin(bp));
+			ASSERT(bp->b_flags & XBF_DELWRI);
 
-			if (!pagebuf_ispin(pb) && !pagebuf_cond_lock(pb)) {
-				if (!xfsbufd_force_flush &&
+			if (!xfs_buf_ispin(bp) && !xfs_buf_cond_lock(bp)) {
+				if (!test_bit(XBT_FORCE_FLUSH,
+						&target->bt_flags) &&
 				    time_before(jiffies,
-						pb->pb_queuetime + age)) {
-					pagebuf_unlock(pb);
+						bp->b_queuetime + age)) {
+					xfs_buf_unlock(bp);
 					break;
 				}
 
-				pb->pb_flags &= ~(PBF_DELWRI|_PBF_DELWRI_Q);
-				pb->pb_flags |= PBF_WRITE;
-				list_move(&pb->pb_list, &tmp);
+				bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q);
+				bp->b_flags |= XBF_WRITE;
+				list_move(&bp->b_list, &tmp);
 			}
 		}
-		spin_unlock(&pbd_delwrite_lock);
+		spin_unlock(dwlk);
 
 		while (!list_empty(&tmp)) {
-			pb = list_entry(tmp.next, xfs_buf_t, pb_list);
-			target = pb->pb_target;
+			bp = list_entry(tmp.next, xfs_buf_t, b_list);
+			ASSERT(target == bp->b_target);
 
-			list_del_init(&pb->pb_list);
-			pagebuf_iostrategy(pb);
+			list_del_init(&bp->b_list);
+			xfs_buf_iostrategy(bp);
 
-			blk_run_address_space(target->pbr_mapping);
+			blk_run_address_space(target->bt_mapping);
 		}
 
 		if (as_list_len > 0)
 			purge_addresses();
 
-		xfsbufd_force_flush = 0;
+		clear_bit(XBT_FORCE_FLUSH, &target->bt_flags);
 	} while (!kthread_should_stop());
 
 	return 0;
 }
 
 /*
- * Go through all incore buffers, and release buffers if they belong to
- * the given device. This is used in filesystem error handling to
- * preserve the consistency of its metadata.
+ *	Go through all incore buffers, and release buffers if they belong to
+ *	the given device. This is used in filesystem error handling to
+ *	preserve the consistency of its metadata.
  */
 int
 xfs_flush_buftarg(
@@ -1770,73 +1739,72 @@
 	int			wait)
 {
 	struct list_head	tmp;
-	xfs_buf_t		*pb, *n;
+	xfs_buf_t		*bp, *n;
 	int			pincount = 0;
+	struct list_head	*dwq = &target->bt_delwrite_queue;
+	spinlock_t		*dwlk = &target->bt_delwrite_lock;
 
-	pagebuf_runall_queues(xfsdatad_workqueue);
-	pagebuf_runall_queues(xfslogd_workqueue);
+	xfs_buf_runall_queues(xfsdatad_workqueue);
+	xfs_buf_runall_queues(xfslogd_workqueue);
 
 	INIT_LIST_HEAD(&tmp);
-	spin_lock(&pbd_delwrite_lock);
-	list_for_each_entry_safe(pb, n, &pbd_delwrite_queue, pb_list) {
-
-		if (pb->pb_target != target)
-			continue;
-
-		ASSERT(pb->pb_flags & (PBF_DELWRI|_PBF_DELWRI_Q));
-		PB_TRACE(pb, "walkq2", (long)pagebuf_ispin(pb));
-		if (pagebuf_ispin(pb)) {
+	spin_lock(dwlk);
+	list_for_each_entry_safe(bp, n, dwq, b_list) {
+		ASSERT(bp->b_target == target);
+		ASSERT(bp->b_flags & (XBF_DELWRI | _XBF_DELWRI_Q));
+		XB_TRACE(bp, "walkq2", (long)xfs_buf_ispin(bp));
+		if (xfs_buf_ispin(bp)) {
 			pincount++;
 			continue;
 		}
 
-		list_move(&pb->pb_list, &tmp);
+		list_move(&bp->b_list, &tmp);
 	}
-	spin_unlock(&pbd_delwrite_lock);
+	spin_unlock(dwlk);
 
 	/*
 	 * Dropped the delayed write list lock, now walk the temporary list
 	 */
-	list_for_each_entry_safe(pb, n, &tmp, pb_list) {
-		pagebuf_lock(pb);
-		pb->pb_flags &= ~(PBF_DELWRI|_PBF_DELWRI_Q);
-		pb->pb_flags |= PBF_WRITE;
+	list_for_each_entry_safe(bp, n, &tmp, b_list) {
+		xfs_buf_lock(bp);
+		bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q);
+		bp->b_flags |= XBF_WRITE;
 		if (wait)
-			pb->pb_flags &= ~PBF_ASYNC;
+			bp->b_flags &= ~XBF_ASYNC;
 		else
-			list_del_init(&pb->pb_list);
+			list_del_init(&bp->b_list);
 
-		pagebuf_iostrategy(pb);
+		xfs_buf_iostrategy(bp);
 	}
 
 	/*
 	 * Remaining list items must be flushed before returning
 	 */
 	while (!list_empty(&tmp)) {
-		pb = list_entry(tmp.next, xfs_buf_t, pb_list);
+		bp = list_entry(tmp.next, xfs_buf_t, b_list);
 
-		list_del_init(&pb->pb_list);
-		xfs_iowait(pb);
-		xfs_buf_relse(pb);
+		list_del_init(&bp->b_list);
+		xfs_iowait(bp);
+		xfs_buf_relse(bp);
 	}
 
 	if (wait)
-		blk_run_address_space(target->pbr_mapping);
+		blk_run_address_space(target->bt_mapping);
 
 	return pincount;
 }
 
 int __init
-pagebuf_init(void)
+xfs_buf_init(void)
 {
 	int		error = -ENOMEM;
 
-#ifdef PAGEBUF_TRACE
-	pagebuf_trace_buf = ktrace_alloc(PAGEBUF_TRACE_SIZE, KM_SLEEP);
+#ifdef XFS_BUF_TRACE
+	xfs_buf_trace_buf = ktrace_alloc(XFS_BUF_TRACE_SIZE, KM_SLEEP);
 #endif
 
-	pagebuf_zone = kmem_zone_init(sizeof(xfs_buf_t), "xfs_buf");
-	if (!pagebuf_zone)
+	xfs_buf_zone = kmem_zone_init(sizeof(xfs_buf_t), "xfs_buf");
+	if (!xfs_buf_zone)
 		goto out_free_trace_buf;
 
 	xfslogd_workqueue = create_workqueue("xfslogd");
@@ -1847,42 +1815,33 @@
 	if (!xfsdatad_workqueue)
 		goto out_destroy_xfslogd_workqueue;
 
-	xfsbufd_task = kthread_run(xfsbufd, NULL, "xfsbufd");
-	if (IS_ERR(xfsbufd_task)) {
-		error = PTR_ERR(xfsbufd_task);
+	xfs_buf_shake = kmem_shake_register(xfsbufd_wakeup);
+	if (!xfs_buf_shake)
 		goto out_destroy_xfsdatad_workqueue;
-	}
-
-	pagebuf_shake = kmem_shake_register(xfsbufd_wakeup);
-	if (!pagebuf_shake)
-		goto out_stop_xfsbufd;
 
 	return 0;
 
- out_stop_xfsbufd:
-	kthread_stop(xfsbufd_task);
  out_destroy_xfsdatad_workqueue:
 	destroy_workqueue(xfsdatad_workqueue);
  out_destroy_xfslogd_workqueue:
 	destroy_workqueue(xfslogd_workqueue);
  out_free_buf_zone:
-	kmem_zone_destroy(pagebuf_zone);
+	kmem_zone_destroy(xfs_buf_zone);
  out_free_trace_buf:
-#ifdef PAGEBUF_TRACE
-	ktrace_free(pagebuf_trace_buf);
+#ifdef XFS_BUF_TRACE
+	ktrace_free(xfs_buf_trace_buf);
 #endif
 	return error;
 }
 
 void
-pagebuf_terminate(void)
+xfs_buf_terminate(void)
 {
-	kmem_shake_deregister(pagebuf_shake);
-	kthread_stop(xfsbufd_task);
+	kmem_shake_deregister(xfs_buf_shake);
 	destroy_workqueue(xfsdatad_workqueue);
 	destroy_workqueue(xfslogd_workqueue);
-	kmem_zone_destroy(pagebuf_zone);
-#ifdef PAGEBUF_TRACE
-	ktrace_free(pagebuf_trace_buf);
+	kmem_zone_destroy(xfs_buf_zone);
+#ifdef XFS_BUF_TRACE
+	ktrace_free(xfs_buf_trace_buf);
 #endif
 }
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h
index 237a35b..4dd6592 100644
--- a/fs/xfs/linux-2.6/xfs_buf.h
+++ b/fs/xfs/linux-2.6/xfs_buf.h
@@ -32,44 +32,47 @@
  *	Base types
  */
 
-#define XFS_BUF_DADDR_NULL ((xfs_daddr_t) (-1LL))
+#define XFS_BUF_DADDR_NULL	((xfs_daddr_t) (-1LL))
 
-#define page_buf_ctob(pp)	((pp) * PAGE_CACHE_SIZE)
-#define page_buf_btoc(dd)	(((dd) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT)
-#define page_buf_btoct(dd)	((dd) >> PAGE_CACHE_SHIFT)
-#define page_buf_poff(aa)	((aa) & ~PAGE_CACHE_MASK)
+#define xfs_buf_ctob(pp)	((pp) * PAGE_CACHE_SIZE)
+#define xfs_buf_btoc(dd)	(((dd) + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT)
+#define xfs_buf_btoct(dd)	((dd) >> PAGE_CACHE_SHIFT)
+#define xfs_buf_poff(aa)	((aa) & ~PAGE_CACHE_MASK)
 
-typedef enum page_buf_rw_e {
-	PBRW_READ = 1,			/* transfer into target memory */
-	PBRW_WRITE = 2,			/* transfer from target memory */
-	PBRW_ZERO = 3			/* Zero target memory */
-} page_buf_rw_t;
+typedef enum {
+	XBRW_READ = 1,			/* transfer into target memory */
+	XBRW_WRITE = 2,			/* transfer from target memory */
+	XBRW_ZERO = 3,			/* Zero target memory */
+} xfs_buf_rw_t;
 
-
-typedef enum page_buf_flags_e {		/* pb_flags values */
-	PBF_READ = (1 << 0),	/* buffer intended for reading from device */
-	PBF_WRITE = (1 << 1),	/* buffer intended for writing to device   */
-	PBF_MAPPED = (1 << 2),  /* buffer mapped (pb_addr valid)           */
-	PBF_ASYNC = (1 << 4),   /* initiator will not wait for completion  */
-	PBF_DONE = (1 << 5),    /* all pages in the buffer uptodate	   */
-	PBF_DELWRI = (1 << 6),  /* buffer has dirty pages                  */
-	PBF_STALE = (1 << 7),	/* buffer has been staled, do not find it  */
-	PBF_FS_MANAGED = (1 << 8),  /* filesystem controls freeing memory  */
- 	PBF_ORDERED = (1 << 11),    /* use ordered writes		   */
-	PBF_READ_AHEAD = (1 << 12), /* asynchronous read-ahead		   */
+typedef enum {
+	XBF_READ = (1 << 0),	/* buffer intended for reading from device */
+	XBF_WRITE = (1 << 1),	/* buffer intended for writing to device   */
+	XBF_MAPPED = (1 << 2),  /* buffer mapped (b_addr valid)            */
+	XBF_ASYNC = (1 << 4),   /* initiator will not wait for completion  */
+	XBF_DONE = (1 << 5),    /* all pages in the buffer uptodate	   */
+	XBF_DELWRI = (1 << 6),  /* buffer has dirty pages                  */
+	XBF_STALE = (1 << 7),	/* buffer has been staled, do not find it  */
+	XBF_FS_MANAGED = (1 << 8),  /* filesystem controls freeing memory  */
+ 	XBF_ORDERED = (1 << 11),    /* use ordered writes		   */
+	XBF_READ_AHEAD = (1 << 12), /* asynchronous read-ahead		   */
 
 	/* flags used only as arguments to access routines */
-	PBF_LOCK = (1 << 14),       /* lock requested			   */
-	PBF_TRYLOCK = (1 << 15),    /* lock requested, but do not wait	   */
-	PBF_DONT_BLOCK = (1 << 16), /* do not block in current thread	   */
+	XBF_LOCK = (1 << 14),       /* lock requested			   */
+	XBF_TRYLOCK = (1 << 15),    /* lock requested, but do not wait	   */
+	XBF_DONT_BLOCK = (1 << 16), /* do not block in current thread	   */
 
 	/* flags used only internally */
-	_PBF_PAGE_CACHE = (1 << 17),/* backed by pagecache		   */
-	_PBF_KMEM_ALLOC = (1 << 18),/* backed by kmem_alloc()		   */
-	_PBF_RUN_QUEUES = (1 << 19),/* run block device task queue	   */
-	_PBF_DELWRI_Q = (1 << 21),   /* buffer on delwri queue		   */
-} page_buf_flags_t;
+	_XBF_PAGE_CACHE = (1 << 17),/* backed by pagecache		   */
+	_XBF_KMEM_ALLOC = (1 << 18),/* backed by kmem_alloc()		   */
+	_XBF_RUN_QUEUES = (1 << 19),/* run block device task queue	   */
+	_XBF_DELWRI_Q = (1 << 21),   /* buffer on delwri queue		   */
+} xfs_buf_flags_t;
 
+typedef enum {
+	XBT_FORCE_SLEEP = (0 << 1),
+	XBT_FORCE_FLUSH = (1 << 1),
+} xfs_buftarg_flags_t;
 
 typedef struct xfs_bufhash {
 	struct list_head	bh_list;
@@ -77,477 +80,350 @@
 } xfs_bufhash_t;
 
 typedef struct xfs_buftarg {
-	dev_t			pbr_dev;
-	struct block_device	*pbr_bdev;
-	struct address_space	*pbr_mapping;
-	unsigned int		pbr_bsize;
-	unsigned int		pbr_sshift;
-	size_t			pbr_smask;
+	dev_t			bt_dev;
+	struct block_device	*bt_bdev;
+	struct address_space	*bt_mapping;
+	unsigned int		bt_bsize;
+	unsigned int		bt_sshift;
+	size_t			bt_smask;
 
-	/* per-device buffer hash table */
+	/* per device buffer hash table */
 	uint			bt_hashmask;
 	uint			bt_hashshift;
 	xfs_bufhash_t		*bt_hash;
+
+	/* per device delwri queue */
+	struct task_struct	*bt_task;
+	struct list_head	bt_list;
+	struct list_head	bt_delwrite_queue;
+	spinlock_t		bt_delwrite_lock;
+	unsigned long		bt_flags;
 } xfs_buftarg_t;
 
 /*
- *	xfs_buf_t:  Buffer structure for page cache-based buffers
+ *	xfs_buf_t:  Buffer structure for pagecache-based buffers
  *
- * This buffer structure is used by the page cache buffer management routines
- * to refer to an assembly of pages forming a logical buffer.  The actual I/O
- * is performed with buffer_head structures, as required by drivers.
- * 
- * The buffer structure is used on temporary basis only, and discarded when
- * released.  The real data storage is recorded in the page cache.  Metadata is
+ * This buffer structure is used by the pagecache buffer management routines
+ * to refer to an assembly of pages forming a logical buffer.
+ *
+ * The buffer structure is used on a temporary basis only, and discarded when
+ * released.  The real data storage is recorded in the pagecache. Buffers are
  * hashed to the block device on which the file system resides.
  */
 
 struct xfs_buf;
+typedef void (*xfs_buf_iodone_t)(struct xfs_buf *);
+typedef void (*xfs_buf_relse_t)(struct xfs_buf *);
+typedef int (*xfs_buf_bdstrat_t)(struct xfs_buf *);
 
-/* call-back function on I/O completion */
-typedef void (*page_buf_iodone_t)(struct xfs_buf *);
-/* call-back function on I/O completion */
-typedef void (*page_buf_relse_t)(struct xfs_buf *);
-/* pre-write function */
-typedef int (*page_buf_bdstrat_t)(struct xfs_buf *);
-
-#define PB_PAGES	2
+#define XB_PAGES	2
 
 typedef struct xfs_buf {
-	struct semaphore	pb_sema;	/* semaphore for lockables  */
-	unsigned long		pb_queuetime;	/* time buffer was queued   */
-	atomic_t		pb_pin_count;	/* pin count		    */
-	wait_queue_head_t	pb_waiters;	/* unpin waiters	    */
-	struct list_head	pb_list;
-	page_buf_flags_t	pb_flags;	/* status flags */
-	struct list_head	pb_hash_list;	/* hash table list */
-	xfs_bufhash_t		*pb_hash;	/* hash table list start */
-	xfs_buftarg_t		*pb_target;	/* buffer target (device) */
-	atomic_t		pb_hold;	/* reference count */
-	xfs_daddr_t		pb_bn;		/* block number for I/O */
-	loff_t			pb_file_offset;	/* offset in file */
-	size_t			pb_buffer_length; /* size of buffer in bytes */
-	size_t			pb_count_desired; /* desired transfer size */
-	void			*pb_addr;	/* virtual address of buffer */
-	struct work_struct	pb_iodone_work;
-	atomic_t		pb_io_remaining;/* #outstanding I/O requests */
-	page_buf_iodone_t	pb_iodone;	/* I/O completion function */
-	page_buf_relse_t	pb_relse;	/* releasing function */
-	page_buf_bdstrat_t	pb_strat;	/* pre-write function */
-	struct semaphore	pb_iodonesema;	/* Semaphore for I/O waiters */
-	void			*pb_fspriv;
-	void			*pb_fspriv2;
-	void			*pb_fspriv3;
-	unsigned short		pb_error;	/* error code on I/O */
- 	unsigned short		pb_locked;	/* page array is locked */
- 	unsigned int		pb_page_count;	/* size of page array */
-	unsigned int		pb_offset;	/* page offset in first page */
-	struct page		**pb_pages;	/* array of page pointers */
-	struct page		*pb_page_array[PB_PAGES]; /* inline pages */
-#ifdef PAGEBUF_LOCK_TRACKING
-	int			pb_last_holder;
+	struct semaphore	b_sema;		/* semaphore for lockables */
+	unsigned long		b_queuetime;	/* time buffer was queued */
+	atomic_t		b_pin_count;	/* pin count */
+	wait_queue_head_t	b_waiters;	/* unpin waiters */
+	struct list_head	b_list;
+	xfs_buf_flags_t		b_flags;	/* status flags */
+	struct list_head	b_hash_list;	/* hash table list */
+	xfs_bufhash_t		*b_hash;	/* hash table list start */
+	xfs_buftarg_t		*b_target;	/* buffer target (device) */
+	atomic_t		b_hold;		/* reference count */
+	xfs_daddr_t		b_bn;		/* block number for I/O */
+	xfs_off_t		b_file_offset;	/* offset in file */
+	size_t			b_buffer_length;/* size of buffer in bytes */
+	size_t			b_count_desired;/* desired transfer size */
+	void			*b_addr;	/* virtual address of buffer */
+	struct work_struct	b_iodone_work;
+	atomic_t		b_io_remaining;	/* #outstanding I/O requests */
+	xfs_buf_iodone_t	b_iodone;	/* I/O completion function */
+	xfs_buf_relse_t		b_relse;	/* releasing function */
+	xfs_buf_bdstrat_t	b_strat;	/* pre-write function */
+	struct semaphore	b_iodonesema;	/* Semaphore for I/O waiters */
+	void			*b_fspriv;
+	void			*b_fspriv2;
+	void			*b_fspriv3;
+	unsigned short		b_error;	/* error code on I/O */
+	unsigned short		b_locked;	/* page array is locked */
+	unsigned int		b_page_count;	/* size of page array */
+	unsigned int		b_offset;	/* page offset in first page */
+	struct page		**b_pages;	/* array of page pointers */
+	struct page		*b_page_array[XB_PAGES]; /* inline pages */
+#ifdef XFS_BUF_LOCK_TRACKING
+	int			b_last_holder;
 #endif
 } xfs_buf_t;
 
 
 /* Finding and Reading Buffers */
-
-extern xfs_buf_t *_pagebuf_find(	/* find buffer for block if	*/
-					/* the block is in memory	*/
-		xfs_buftarg_t *,	/* inode for block		*/
-		loff_t,			/* starting offset of range	*/
-		size_t,			/* length of range		*/
-		page_buf_flags_t,	/* PBF_LOCK			*/
-	        xfs_buf_t *);		/* newly allocated buffer	*/
-
+extern xfs_buf_t *_xfs_buf_find(xfs_buftarg_t *, xfs_off_t, size_t,
+				xfs_buf_flags_t, xfs_buf_t *);
 #define xfs_incore(buftarg,blkno,len,lockit) \
-	_pagebuf_find(buftarg, blkno ,len, lockit, NULL)
+	_xfs_buf_find(buftarg, blkno ,len, lockit, NULL)
 
-extern xfs_buf_t *xfs_buf_get_flags(	/* allocate a buffer		*/
-		xfs_buftarg_t *,	/* inode for buffer		*/
-		loff_t,			/* starting offset of range     */
-		size_t,			/* length of range              */
-		page_buf_flags_t);	/* PBF_LOCK, PBF_READ,		*/
-					/* PBF_ASYNC			*/
-
+extern xfs_buf_t *xfs_buf_get_flags(xfs_buftarg_t *, xfs_off_t, size_t,
+				xfs_buf_flags_t);
 #define xfs_buf_get(target, blkno, len, flags) \
-	xfs_buf_get_flags((target), (blkno), (len), PBF_LOCK | PBF_MAPPED)
+	xfs_buf_get_flags((target), (blkno), (len), XBF_LOCK | XBF_MAPPED)
 
-extern xfs_buf_t *xfs_buf_read_flags(	/* allocate and read a buffer	*/
-		xfs_buftarg_t *,	/* inode for buffer		*/
-		loff_t,			/* starting offset of range	*/
-		size_t,			/* length of range		*/
-		page_buf_flags_t);	/* PBF_LOCK, PBF_ASYNC		*/
-
+extern xfs_buf_t *xfs_buf_read_flags(xfs_buftarg_t *, xfs_off_t, size_t,
+				xfs_buf_flags_t);
 #define xfs_buf_read(target, blkno, len, flags) \
-	xfs_buf_read_flags((target), (blkno), (len), PBF_LOCK | PBF_MAPPED)
+	xfs_buf_read_flags((target), (blkno), (len), XBF_LOCK | XBF_MAPPED)
 
-extern xfs_buf_t *pagebuf_get_empty(	/* allocate pagebuf struct with	*/
-					/*  no memory or disk address	*/
-		size_t len,
-		xfs_buftarg_t *);	/* mount point "fake" inode	*/
-
-extern xfs_buf_t *pagebuf_get_no_daddr(/* allocate pagebuf struct	*/
-					/* without disk address		*/
-		size_t len,
-		xfs_buftarg_t *);	/* mount point "fake" inode	*/
-
-extern int pagebuf_associate_memory(
-		xfs_buf_t *,
-		void *,
-		size_t);
-
-extern void pagebuf_hold(		/* increment reference count	*/
-		xfs_buf_t *);		/* buffer to hold		*/
-
-extern void pagebuf_readahead(		/* read ahead into cache	*/
-		xfs_buftarg_t  *,	/* target for buffer (or NULL)	*/
-		loff_t,			/* starting offset of range     */
-		size_t,			/* length of range              */
-		page_buf_flags_t);	/* additional read flags	*/
+extern xfs_buf_t *xfs_buf_get_empty(size_t, xfs_buftarg_t *);
+extern xfs_buf_t *xfs_buf_get_noaddr(size_t, xfs_buftarg_t *);
+extern int xfs_buf_associate_memory(xfs_buf_t *, void *, size_t);
+extern void xfs_buf_hold(xfs_buf_t *);
+extern void xfs_buf_readahead(xfs_buftarg_t *, xfs_off_t, size_t,
+				xfs_buf_flags_t);
 
 /* Releasing Buffers */
-
-extern void pagebuf_free(		/* deallocate a buffer		*/
-		xfs_buf_t *);		/* buffer to deallocate		*/
-
-extern void pagebuf_rele(		/* release hold on a buffer	*/
-		xfs_buf_t *);		/* buffer to release		*/
+extern void xfs_buf_free(xfs_buf_t *);
+extern void xfs_buf_rele(xfs_buf_t *);
 
 /* Locking and Unlocking Buffers */
-
-extern int pagebuf_cond_lock(		/* lock buffer, if not locked	*/
-					/* (returns -EBUSY if locked)	*/
-		xfs_buf_t *);		/* buffer to lock		*/
-
-extern int pagebuf_lock_value(		/* return count on lock		*/
-		xfs_buf_t *);          /* buffer to check              */
-
-extern int pagebuf_lock(		/* lock buffer                  */
-		xfs_buf_t *);          /* buffer to lock               */
-
-extern void pagebuf_unlock(		/* unlock buffer		*/
-		xfs_buf_t *);		/* buffer to unlock		*/
+extern int xfs_buf_cond_lock(xfs_buf_t *);
+extern int xfs_buf_lock_value(xfs_buf_t *);
+extern void xfs_buf_lock(xfs_buf_t *);
+extern void xfs_buf_unlock(xfs_buf_t *);
 
 /* Buffer Read and Write Routines */
+extern void xfs_buf_ioend(xfs_buf_t *,	int);
+extern void xfs_buf_ioerror(xfs_buf_t *, int);
+extern int xfs_buf_iostart(xfs_buf_t *, xfs_buf_flags_t);
+extern int xfs_buf_iorequest(xfs_buf_t *);
+extern int xfs_buf_iowait(xfs_buf_t *);
+extern void xfs_buf_iomove(xfs_buf_t *, size_t, size_t, xfs_caddr_t,
+				xfs_buf_rw_t);
 
-extern void pagebuf_iodone(		/* mark buffer I/O complete	*/
-		xfs_buf_t *,		/* buffer to mark		*/
-		int);			/* run completion locally, or in
-					 * a helper thread.		*/
-
-extern void pagebuf_ioerror(		/* mark buffer in error	(or not) */
-		xfs_buf_t *,		/* buffer to mark		*/
-		int);			/* error to store (0 if none)	*/
-
-extern int pagebuf_iostart(		/* start I/O on a buffer	*/
-		xfs_buf_t *,		/* buffer to start		*/
-		page_buf_flags_t);	/* PBF_LOCK, PBF_ASYNC,		*/
-					/* PBF_READ, PBF_WRITE,		*/
-					/* PBF_DELWRI			*/
-
-extern int pagebuf_iorequest(		/* start real I/O		*/
-		xfs_buf_t *);		/* buffer to convey to device	*/
-
-extern int pagebuf_iowait(		/* wait for buffer I/O done	*/
-		xfs_buf_t *);		/* buffer to wait on		*/
-
-extern void pagebuf_iomove(		/* move data in/out of pagebuf	*/
-		xfs_buf_t *,		/* buffer to manipulate		*/
-		size_t,			/* starting buffer offset	*/
-		size_t,			/* length in buffer		*/
-		caddr_t,		/* data pointer			*/
-		page_buf_rw_t);		/* direction			*/
-
-static inline int pagebuf_iostrategy(xfs_buf_t *pb)
+static inline int xfs_buf_iostrategy(xfs_buf_t *bp)
 {
-	return pb->pb_strat ? pb->pb_strat(pb) : pagebuf_iorequest(pb);
+	return bp->b_strat ? bp->b_strat(bp) : xfs_buf_iorequest(bp);
 }
 
-static inline int pagebuf_geterror(xfs_buf_t *pb)
+static inline int xfs_buf_geterror(xfs_buf_t *bp)
 {
-	return pb ? pb->pb_error : ENOMEM;
+	return bp ? bp->b_error : ENOMEM;
 }
 
 /* Buffer Utility Routines */
-
-extern caddr_t pagebuf_offset(		/* pointer at offset in buffer	*/
-		xfs_buf_t *,		/* buffer to offset into	*/
-		size_t);		/* offset			*/
+extern xfs_caddr_t xfs_buf_offset(xfs_buf_t *, size_t);
 
 /* Pinning Buffer Storage in Memory */
-
-extern void pagebuf_pin(		/* pin buffer in memory		*/
-		xfs_buf_t *);		/* buffer to pin		*/
-
-extern void pagebuf_unpin(		/* unpin buffered data		*/
-		xfs_buf_t *);		/* buffer to unpin		*/
-
-extern int pagebuf_ispin(		/* check if buffer is pinned	*/
-		xfs_buf_t *);		/* buffer to check		*/
+extern void xfs_buf_pin(xfs_buf_t *);
+extern void xfs_buf_unpin(xfs_buf_t *);
+extern int xfs_buf_ispin(xfs_buf_t *);
 
 /* Delayed Write Buffer Routines */
-
-extern void pagebuf_delwri_dequeue(xfs_buf_t *);
+extern void xfs_buf_delwri_dequeue(xfs_buf_t *);
 
 /* Buffer Daemon Setup Routines */
+extern int xfs_buf_init(void);
+extern void xfs_buf_terminate(void);
 
-extern int pagebuf_init(void);
-extern void pagebuf_terminate(void);
-
-
-#ifdef PAGEBUF_TRACE
-extern ktrace_t *pagebuf_trace_buf;
-extern void pagebuf_trace(
-		xfs_buf_t *,		/* buffer being traced		*/
-		char *,			/* description of operation	*/
-		void *,			/* arbitrary diagnostic value	*/
-		void *);		/* return address		*/
+#ifdef XFS_BUF_TRACE
+extern ktrace_t *xfs_buf_trace_buf;
+extern void xfs_buf_trace(xfs_buf_t *, char *, void *, void *);
 #else
-# define pagebuf_trace(pb, id, ptr, ra)	do { } while (0)
+#define xfs_buf_trace(bp,id,ptr,ra)	do { } while (0)
 #endif
 
-#define pagebuf_target_name(target)	\
-	({ char __b[BDEVNAME_SIZE]; bdevname((target)->pbr_bdev, __b); __b; })
+#define xfs_buf_target_name(target)	\
+	({ char __b[BDEVNAME_SIZE]; bdevname((target)->bt_bdev, __b); __b; })
 
 
+#define XFS_B_ASYNC		XBF_ASYNC
+#define XFS_B_DELWRI		XBF_DELWRI
+#define XFS_B_READ		XBF_READ
+#define XFS_B_WRITE		XBF_WRITE
+#define XFS_B_STALE		XBF_STALE
 
-/* These are just for xfs_syncsub... it sets an internal variable
- * then passes it to VOP_FLUSH_PAGES or adds the flags to a newly gotten buf_t
- */
-#define XFS_B_ASYNC		PBF_ASYNC
-#define XFS_B_DELWRI		PBF_DELWRI
-#define XFS_B_READ		PBF_READ
-#define XFS_B_WRITE		PBF_WRITE
-#define XFS_B_STALE		PBF_STALE
+#define XFS_BUF_TRYLOCK		XBF_TRYLOCK
+#define XFS_INCORE_TRYLOCK	XBF_TRYLOCK
+#define XFS_BUF_LOCK		XBF_LOCK
+#define XFS_BUF_MAPPED		XBF_MAPPED
 
-#define XFS_BUF_TRYLOCK		PBF_TRYLOCK
-#define XFS_INCORE_TRYLOCK	PBF_TRYLOCK
-#define XFS_BUF_LOCK		PBF_LOCK
-#define XFS_BUF_MAPPED		PBF_MAPPED
+#define BUF_BUSY		XBF_DONT_BLOCK
 
-#define BUF_BUSY		PBF_DONT_BLOCK
+#define XFS_BUF_BFLAGS(bp)	((bp)->b_flags)
+#define XFS_BUF_ZEROFLAGS(bp)	\
+	((bp)->b_flags &= ~(XBF_READ|XBF_WRITE|XBF_ASYNC|XBF_DELWRI))
 
-#define XFS_BUF_BFLAGS(x)	((x)->pb_flags)
-#define XFS_BUF_ZEROFLAGS(x)	\
-	((x)->pb_flags &= ~(PBF_READ|PBF_WRITE|PBF_ASYNC|PBF_DELWRI))
-
-#define XFS_BUF_STALE(x)	((x)->pb_flags |= XFS_B_STALE)
-#define XFS_BUF_UNSTALE(x)	((x)->pb_flags &= ~XFS_B_STALE)
-#define XFS_BUF_ISSTALE(x)	((x)->pb_flags & XFS_B_STALE)
-#define XFS_BUF_SUPER_STALE(x)	do {				\
-					XFS_BUF_STALE(x);	\
-					pagebuf_delwri_dequeue(x);	\
-					XFS_BUF_DONE(x);	\
+#define XFS_BUF_STALE(bp)	((bp)->b_flags |= XFS_B_STALE)
+#define XFS_BUF_UNSTALE(bp)	((bp)->b_flags &= ~XFS_B_STALE)
+#define XFS_BUF_ISSTALE(bp)	((bp)->b_flags & XFS_B_STALE)
+#define XFS_BUF_SUPER_STALE(bp)	do {				\
+					XFS_BUF_STALE(bp);	\
+					xfs_buf_delwri_dequeue(bp);	\
+					XFS_BUF_DONE(bp);	\
 				} while (0)
 
-#define XFS_BUF_MANAGE		PBF_FS_MANAGED
-#define XFS_BUF_UNMANAGE(x)	((x)->pb_flags &= ~PBF_FS_MANAGED)
+#define XFS_BUF_MANAGE		XBF_FS_MANAGED
+#define XFS_BUF_UNMANAGE(bp)	((bp)->b_flags &= ~XBF_FS_MANAGED)
 
-#define XFS_BUF_DELAYWRITE(x)	 ((x)->pb_flags |= PBF_DELWRI)
-#define XFS_BUF_UNDELAYWRITE(x)	 pagebuf_delwri_dequeue(x)
-#define XFS_BUF_ISDELAYWRITE(x)	 ((x)->pb_flags & PBF_DELWRI)
+#define XFS_BUF_DELAYWRITE(bp)		((bp)->b_flags |= XBF_DELWRI)
+#define XFS_BUF_UNDELAYWRITE(bp)	xfs_buf_delwri_dequeue(bp)
+#define XFS_BUF_ISDELAYWRITE(bp)	((bp)->b_flags & XBF_DELWRI)
 
-#define XFS_BUF_ERROR(x,no)	 pagebuf_ioerror(x,no)
-#define XFS_BUF_GETERROR(x)	 pagebuf_geterror(x)
-#define XFS_BUF_ISERROR(x)	 (pagebuf_geterror(x)?1:0)
+#define XFS_BUF_ERROR(bp,no)	xfs_buf_ioerror(bp,no)
+#define XFS_BUF_GETERROR(bp)	xfs_buf_geterror(bp)
+#define XFS_BUF_ISERROR(bp)	(xfs_buf_geterror(bp) ? 1 : 0)
 
-#define XFS_BUF_DONE(x)		 ((x)->pb_flags |= PBF_DONE)
-#define XFS_BUF_UNDONE(x)	 ((x)->pb_flags &= ~PBF_DONE)
-#define XFS_BUF_ISDONE(x)	 ((x)->pb_flags & PBF_DONE)
+#define XFS_BUF_DONE(bp)	((bp)->b_flags |= XBF_DONE)
+#define XFS_BUF_UNDONE(bp)	((bp)->b_flags &= ~XBF_DONE)
+#define XFS_BUF_ISDONE(bp)	((bp)->b_flags & XBF_DONE)
 
-#define XFS_BUF_BUSY(x)		 do { } while (0)
-#define XFS_BUF_UNBUSY(x)	 do { } while (0)
-#define XFS_BUF_ISBUSY(x)	 (1)
+#define XFS_BUF_BUSY(bp)	do { } while (0)
+#define XFS_BUF_UNBUSY(bp)	do { } while (0)
+#define XFS_BUF_ISBUSY(bp)	(1)
 
-#define XFS_BUF_ASYNC(x)	 ((x)->pb_flags |= PBF_ASYNC)
-#define XFS_BUF_UNASYNC(x)	 ((x)->pb_flags &= ~PBF_ASYNC)
-#define XFS_BUF_ISASYNC(x)	 ((x)->pb_flags & PBF_ASYNC)
+#define XFS_BUF_ASYNC(bp)	((bp)->b_flags |= XBF_ASYNC)
+#define XFS_BUF_UNASYNC(bp)	((bp)->b_flags &= ~XBF_ASYNC)
+#define XFS_BUF_ISASYNC(bp)	((bp)->b_flags & XBF_ASYNC)
 
-#define XFS_BUF_ORDERED(x)	 ((x)->pb_flags |= PBF_ORDERED)
-#define XFS_BUF_UNORDERED(x)	 ((x)->pb_flags &= ~PBF_ORDERED)
-#define XFS_BUF_ISORDERED(x)	 ((x)->pb_flags & PBF_ORDERED)
+#define XFS_BUF_ORDERED(bp)	((bp)->b_flags |= XBF_ORDERED)
+#define XFS_BUF_UNORDERED(bp)	((bp)->b_flags &= ~XBF_ORDERED)
+#define XFS_BUF_ISORDERED(bp)	((bp)->b_flags & XBF_ORDERED)
 
-#define XFS_BUF_SHUT(x)		 printk("XFS_BUF_SHUT not implemented yet\n")
-#define XFS_BUF_UNSHUT(x)	 printk("XFS_BUF_UNSHUT not implemented yet\n")
-#define XFS_BUF_ISSHUT(x)	 (0)
+#define XFS_BUF_SHUT(bp)	do { } while (0)
+#define XFS_BUF_UNSHUT(bp)	do { } while (0)
+#define XFS_BUF_ISSHUT(bp)	(0)
 
-#define XFS_BUF_HOLD(x)		pagebuf_hold(x)
-#define XFS_BUF_READ(x)		((x)->pb_flags |= PBF_READ)
-#define XFS_BUF_UNREAD(x)	((x)->pb_flags &= ~PBF_READ)
-#define XFS_BUF_ISREAD(x)	((x)->pb_flags & PBF_READ)
+#define XFS_BUF_HOLD(bp)	xfs_buf_hold(bp)
+#define XFS_BUF_READ(bp)	((bp)->b_flags |= XBF_READ)
+#define XFS_BUF_UNREAD(bp)	((bp)->b_flags &= ~XBF_READ)
+#define XFS_BUF_ISREAD(bp)	((bp)->b_flags & XBF_READ)
 
-#define XFS_BUF_WRITE(x)	((x)->pb_flags |= PBF_WRITE)
-#define XFS_BUF_UNWRITE(x)	((x)->pb_flags &= ~PBF_WRITE)
-#define XFS_BUF_ISWRITE(x)	((x)->pb_flags & PBF_WRITE)
+#define XFS_BUF_WRITE(bp)	((bp)->b_flags |= XBF_WRITE)
+#define XFS_BUF_UNWRITE(bp)	((bp)->b_flags &= ~XBF_WRITE)
+#define XFS_BUF_ISWRITE(bp)	((bp)->b_flags & XBF_WRITE)
 
-#define XFS_BUF_ISUNINITIAL(x)	 (0)
-#define XFS_BUF_UNUNINITIAL(x)	 (0)
+#define XFS_BUF_ISUNINITIAL(bp)	(0)
+#define XFS_BUF_UNUNINITIAL(bp)	(0)
 
-#define XFS_BUF_BP_ISMAPPED(bp)	 1
+#define XFS_BUF_BP_ISMAPPED(bp)	(1)
 
-#define XFS_BUF_IODONE_FUNC(buf)	(buf)->pb_iodone
-#define XFS_BUF_SET_IODONE_FUNC(buf, func)	\
-			(buf)->pb_iodone = (func)
-#define XFS_BUF_CLR_IODONE_FUNC(buf)		\
-			(buf)->pb_iodone = NULL
-#define XFS_BUF_SET_BDSTRAT_FUNC(buf, func)	\
-			(buf)->pb_strat = (func)
-#define XFS_BUF_CLR_BDSTRAT_FUNC(buf)		\
-			(buf)->pb_strat = NULL
+#define XFS_BUF_IODONE_FUNC(bp)			((bp)->b_iodone)
+#define XFS_BUF_SET_IODONE_FUNC(bp, func)	((bp)->b_iodone = (func))
+#define XFS_BUF_CLR_IODONE_FUNC(bp)		((bp)->b_iodone = NULL)
+#define XFS_BUF_SET_BDSTRAT_FUNC(bp, func)	((bp)->b_strat = (func))
+#define XFS_BUF_CLR_BDSTRAT_FUNC(bp)		((bp)->b_strat = NULL)
 
-#define XFS_BUF_FSPRIVATE(buf, type)		\
-			((type)(buf)->pb_fspriv)
-#define XFS_BUF_SET_FSPRIVATE(buf, value)	\
-			(buf)->pb_fspriv = (void *)(value)
-#define XFS_BUF_FSPRIVATE2(buf, type)		\
-			((type)(buf)->pb_fspriv2)
-#define XFS_BUF_SET_FSPRIVATE2(buf, value)	\
-			(buf)->pb_fspriv2 = (void *)(value)
-#define XFS_BUF_FSPRIVATE3(buf, type)		\
-			((type)(buf)->pb_fspriv3)
-#define XFS_BUF_SET_FSPRIVATE3(buf, value)	\
-			(buf)->pb_fspriv3  = (void *)(value)
-#define XFS_BUF_SET_START(buf)
+#define XFS_BUF_FSPRIVATE(bp, type)		((type)(bp)->b_fspriv)
+#define XFS_BUF_SET_FSPRIVATE(bp, val)		((bp)->b_fspriv = (void*)(val))
+#define XFS_BUF_FSPRIVATE2(bp, type)		((type)(bp)->b_fspriv2)
+#define XFS_BUF_SET_FSPRIVATE2(bp, val)		((bp)->b_fspriv2 = (void*)(val))
+#define XFS_BUF_FSPRIVATE3(bp, type)		((type)(bp)->b_fspriv3)
+#define XFS_BUF_SET_FSPRIVATE3(bp, val)		((bp)->b_fspriv3 = (void*)(val))
+#define XFS_BUF_SET_START(bp)			do { } while (0)
+#define XFS_BUF_SET_BRELSE_FUNC(bp, func)	((bp)->b_relse = (func))
 
-#define XFS_BUF_SET_BRELSE_FUNC(buf, value) \
-			(buf)->pb_relse = (value)
+#define XFS_BUF_PTR(bp)			(xfs_caddr_t)((bp)->b_addr)
+#define XFS_BUF_SET_PTR(bp, val, cnt)	xfs_buf_associate_memory(bp, val, cnt)
+#define XFS_BUF_ADDR(bp)		((bp)->b_bn)
+#define XFS_BUF_SET_ADDR(bp, bno)	((bp)->b_bn = (xfs_daddr_t)(bno))
+#define XFS_BUF_OFFSET(bp)		((bp)->b_file_offset)
+#define XFS_BUF_SET_OFFSET(bp, off)	((bp)->b_file_offset = (off))
+#define XFS_BUF_COUNT(bp)		((bp)->b_count_desired)
+#define XFS_BUF_SET_COUNT(bp, cnt)	((bp)->b_count_desired = (cnt))
+#define XFS_BUF_SIZE(bp)		((bp)->b_buffer_length)
+#define XFS_BUF_SET_SIZE(bp, cnt)	((bp)->b_buffer_length = (cnt))
 
-#define XFS_BUF_PTR(bp)		(xfs_caddr_t)((bp)->pb_addr)
+#define XFS_BUF_SET_VTYPE_REF(bp, type, ref)	do { } while (0)
+#define XFS_BUF_SET_VTYPE(bp, type)		do { } while (0)
+#define XFS_BUF_SET_REF(bp, ref)		do { } while (0)
 
-static inline xfs_caddr_t xfs_buf_offset(xfs_buf_t *bp, size_t offset)
+#define XFS_BUF_ISPINNED(bp)	xfs_buf_ispin(bp)
+
+#define XFS_BUF_VALUSEMA(bp)	xfs_buf_lock_value(bp)
+#define XFS_BUF_CPSEMA(bp)	(xfs_buf_cond_lock(bp) == 0)
+#define XFS_BUF_VSEMA(bp)	xfs_buf_unlock(bp)
+#define XFS_BUF_PSEMA(bp,x)	xfs_buf_lock(bp)
+#define XFS_BUF_V_IODONESEMA(bp) up(&bp->b_iodonesema);
+
+#define XFS_BUF_SET_TARGET(bp, target)	((bp)->b_target = (target))
+#define XFS_BUF_TARGET(bp)		((bp)->b_target)
+#define XFS_BUFTARG_NAME(target)	xfs_buf_target_name(target)
+
+static inline int xfs_bawrite(void *mp, xfs_buf_t *bp)
 {
-	if (bp->pb_flags & PBF_MAPPED)
-		return XFS_BUF_PTR(bp) + offset;
-	return (xfs_caddr_t) pagebuf_offset(bp, offset);
+	bp->b_fspriv3 = mp;
+	bp->b_strat = xfs_bdstrat_cb;
+	xfs_buf_delwri_dequeue(bp);
+	return xfs_buf_iostart(bp, XBF_WRITE | XBF_ASYNC | _XBF_RUN_QUEUES);
 }
 
-#define XFS_BUF_SET_PTR(bp, val, count)		\
-				pagebuf_associate_memory(bp, val, count)
-#define XFS_BUF_ADDR(bp)	((bp)->pb_bn)
-#define XFS_BUF_SET_ADDR(bp, blk)		\
-			((bp)->pb_bn = (xfs_daddr_t)(blk))
-#define XFS_BUF_OFFSET(bp)	((bp)->pb_file_offset)
-#define XFS_BUF_SET_OFFSET(bp, off)		\
-			((bp)->pb_file_offset = (off))
-#define XFS_BUF_COUNT(bp)	((bp)->pb_count_desired)
-#define XFS_BUF_SET_COUNT(bp, cnt)		\
-			((bp)->pb_count_desired = (cnt))
-#define XFS_BUF_SIZE(bp)	((bp)->pb_buffer_length)
-#define XFS_BUF_SET_SIZE(bp, cnt)		\
-			((bp)->pb_buffer_length = (cnt))
-#define XFS_BUF_SET_VTYPE_REF(bp, type, ref)
-#define XFS_BUF_SET_VTYPE(bp, type)
-#define XFS_BUF_SET_REF(bp, ref)
-
-#define XFS_BUF_ISPINNED(bp)	pagebuf_ispin(bp)
-
-#define XFS_BUF_VALUSEMA(bp)	pagebuf_lock_value(bp)
-#define XFS_BUF_CPSEMA(bp)	(pagebuf_cond_lock(bp) == 0)
-#define XFS_BUF_VSEMA(bp)	pagebuf_unlock(bp)
-#define XFS_BUF_PSEMA(bp,x)	pagebuf_lock(bp)
-#define XFS_BUF_V_IODONESEMA(bp) up(&bp->pb_iodonesema);
-
-/* setup the buffer target from a buftarg structure */
-#define XFS_BUF_SET_TARGET(bp, target)	\
-		(bp)->pb_target = (target)
-#define XFS_BUF_TARGET(bp)	((bp)->pb_target)
-#define XFS_BUFTARG_NAME(target)	\
-		pagebuf_target_name(target)
-
-#define XFS_BUF_SET_VTYPE_REF(bp, type, ref)
-#define XFS_BUF_SET_VTYPE(bp, type)
-#define XFS_BUF_SET_REF(bp, ref)
-
-static inline int	xfs_bawrite(void *mp, xfs_buf_t *bp)
+static inline void xfs_buf_relse(xfs_buf_t *bp)
 {
-	bp->pb_fspriv3 = mp;
-	bp->pb_strat = xfs_bdstrat_cb;
-	pagebuf_delwri_dequeue(bp);
-	return pagebuf_iostart(bp, PBF_WRITE | PBF_ASYNC | _PBF_RUN_QUEUES);
+	if (!bp->b_relse)
+		xfs_buf_unlock(bp);
+	xfs_buf_rele(bp);
 }
 
-static inline void	xfs_buf_relse(xfs_buf_t *bp)
-{
-	if (!bp->pb_relse)
-		pagebuf_unlock(bp);
-	pagebuf_rele(bp);
-}
-
-#define xfs_bpin(bp)		pagebuf_pin(bp)
-#define xfs_bunpin(bp)		pagebuf_unpin(bp)
+#define xfs_bpin(bp)		xfs_buf_pin(bp)
+#define xfs_bunpin(bp)		xfs_buf_unpin(bp)
 
 #define xfs_buftrace(id, bp)	\
-	    pagebuf_trace(bp, id, NULL, (void *)__builtin_return_address(0))
+	    xfs_buf_trace(bp, id, NULL, (void *)__builtin_return_address(0))
 
-#define xfs_biodone(pb)		    \
-	    pagebuf_iodone(pb, 0)
+#define xfs_biodone(bp)		xfs_buf_ioend(bp, 0)
 
-#define xfs_biomove(pb, off, len, data, rw) \
-	    pagebuf_iomove((pb), (off), (len), (data), \
-		((rw) == XFS_B_WRITE) ? PBRW_WRITE : PBRW_READ)
+#define xfs_biomove(bp, off, len, data, rw) \
+	    xfs_buf_iomove((bp), (off), (len), (data), \
+		((rw) == XFS_B_WRITE) ? XBRW_WRITE : XBRW_READ)
 
-#define xfs_biozero(pb, off, len) \
-	    pagebuf_iomove((pb), (off), (len), NULL, PBRW_ZERO)
+#define xfs_biozero(bp, off, len) \
+	    xfs_buf_iomove((bp), (off), (len), NULL, XBRW_ZERO)
 
 
-static inline int	XFS_bwrite(xfs_buf_t *pb)
+static inline int XFS_bwrite(xfs_buf_t *bp)
 {
-	int	iowait = (pb->pb_flags & PBF_ASYNC) == 0;
+	int	iowait = (bp->b_flags & XBF_ASYNC) == 0;
 	int	error = 0;
 
 	if (!iowait)
-		pb->pb_flags |= _PBF_RUN_QUEUES;
+		bp->b_flags |= _XBF_RUN_QUEUES;
 
-	pagebuf_delwri_dequeue(pb);
-	pagebuf_iostrategy(pb);
+	xfs_buf_delwri_dequeue(bp);
+	xfs_buf_iostrategy(bp);
 	if (iowait) {
-		error = pagebuf_iowait(pb);
-		xfs_buf_relse(pb);
+		error = xfs_buf_iowait(bp);
+		xfs_buf_relse(bp);
 	}
 	return error;
 }
 
-#define XFS_bdwrite(pb)		     \
-	    pagebuf_iostart(pb, PBF_DELWRI | PBF_ASYNC)
+#define XFS_bdwrite(bp)		xfs_buf_iostart(bp, XBF_DELWRI | XBF_ASYNC)
 
 static inline int xfs_bdwrite(void *mp, xfs_buf_t *bp)
 {
-	bp->pb_strat = xfs_bdstrat_cb;
-	bp->pb_fspriv3 = mp;
-
-	return pagebuf_iostart(bp, PBF_DELWRI | PBF_ASYNC);
+	bp->b_strat = xfs_bdstrat_cb;
+	bp->b_fspriv3 = mp;
+	return xfs_buf_iostart(bp, XBF_DELWRI | XBF_ASYNC);
 }
 
-#define XFS_bdstrat(bp) pagebuf_iorequest(bp)
+#define XFS_bdstrat(bp) xfs_buf_iorequest(bp)
 
-#define xfs_iowait(pb)	pagebuf_iowait(pb)
+#define xfs_iowait(bp)	xfs_buf_iowait(bp)
 
 #define xfs_baread(target, rablkno, ralen)  \
-	pagebuf_readahead((target), (rablkno), (ralen), PBF_DONT_BLOCK)
-
-#define xfs_buf_get_empty(len, target)	pagebuf_get_empty((len), (target))
-#define xfs_buf_get_noaddr(len, target)	pagebuf_get_no_daddr((len), (target))
-#define xfs_buf_free(bp)		pagebuf_free(bp)
+	xfs_buf_readahead((target), (rablkno), (ralen), XBF_DONT_BLOCK)
 
 
 /*
  *	Handling of buftargs.
  */
-
 extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *, int);
 extern void xfs_free_buftarg(xfs_buftarg_t *, int);
 extern void xfs_wait_buftarg(xfs_buftarg_t *);
 extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int);
 extern int xfs_flush_buftarg(xfs_buftarg_t *, int);
 
-#define xfs_getsize_buftarg(buftarg) \
-	block_size((buftarg)->pbr_bdev)
-#define xfs_readonly_buftarg(buftarg) \
-	bdev_read_only((buftarg)->pbr_bdev)
-#define xfs_binval(buftarg) \
-	xfs_flush_buftarg(buftarg, 1)
-#define XFS_bflush(buftarg) \
-	xfs_flush_buftarg(buftarg, 1)
+#define xfs_getsize_buftarg(buftarg)	block_size((buftarg)->bt_bdev)
+#define xfs_readonly_buftarg(buftarg)	bdev_read_only((buftarg)->bt_bdev)
+
+#define xfs_binval(buftarg)		xfs_flush_buftarg(buftarg, 1)
+#define XFS_bflush(buftarg)		xfs_flush_buftarg(buftarg, 1)
 
 #endif	/* __XFS_BUF_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 06111d0..ced4404 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -509,16 +509,14 @@
 	vnode_t		*vp = LINVFS_GET_VP(inode);
 	xfs_mount_t	*mp = XFS_VFSTOM(vp->v_vfsp);
 	int		error = 0;
-	bhv_desc_t	*bdp;
 	xfs_inode_t	*ip;
 
 	if (vp->v_vfsp->vfs_flag & VFS_DMI) {
-		bdp = vn_bhv_lookup(VN_BHV_HEAD(vp), &xfs_vnodeops);
-		if (!bdp) {
+		ip = xfs_vtoi(vp);
+		if (!ip) {
 			error = -EINVAL;
 			goto open_exec_out;
 		}
-		ip = XFS_BHVTOI(bdp);
 		if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ)) {
 			error = -XFS_SEND_DATA(mp, DM_EVENT_READ, vp,
 					       0, 0, 0, NULL);
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index 21667ba..4db4779 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -146,13 +146,10 @@
 
 	if (cmd != XFS_IOC_PATH_TO_FSHANDLE) {
 		xfs_inode_t	*ip;
-		bhv_desc_t	*bhv;
 		int		lock_mode;
 
 		/* need to get access to the xfs_inode to read the generation */
-		bhv = vn_bhv_lookup_unlocked(VN_BHV_HEAD(vp), &xfs_vnodeops);
-		ASSERT(bhv);
-		ip = XFS_BHVTOI(bhv);
+		ip = xfs_vtoi(vp);
 		ASSERT(ip);
 		lock_mode = xfs_ilock_map_shared(ip);
 
@@ -751,9 +748,8 @@
 			(ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
 			mp->m_rtdev_targp : mp->m_ddev_targp;
 
-		da.d_mem = da.d_miniosz = 1 << target->pbr_sshift;
-		/* The size dio will do in one go */
-		da.d_maxiosz = 64 * PAGE_CACHE_SIZE;
+		da.d_mem = da.d_miniosz = 1 << target->bt_sshift;
+		da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1);
 
 		if (copy_to_user(arg, &da, sizeof(da)))
 			return -XFS_ERROR(EFAULT);
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 9b8ee34..4bd3d03 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -54,11 +54,46 @@
 #include <linux/capability.h>
 #include <linux/xattr.h>
 #include <linux/namei.h>
+#include <linux/security.h>
 
 #define IS_NOATIME(inode) ((inode->i_sb->s_flags & MS_NOATIME) ||	\
 	(S_ISDIR(inode->i_mode) && inode->i_sb->s_flags & MS_NODIRATIME))
 
 /*
+ * Get a XFS inode from a given vnode.
+ */
+xfs_inode_t *
+xfs_vtoi(
+	struct vnode	*vp)
+{
+	bhv_desc_t      *bdp;
+
+	bdp = bhv_lookup_range(VN_BHV_HEAD(vp),
+			VNODE_POSITION_XFS, VNODE_POSITION_XFS);
+	if (unlikely(bdp == NULL))
+		return NULL;
+	return XFS_BHVTOI(bdp);
+}
+
+/*
+ * Bring the atime in the XFS inode uptodate.
+ * Used before logging the inode to disk or when the Linux inode goes away.
+ */
+void
+xfs_synchronize_atime(
+	xfs_inode_t	*ip)
+{
+	vnode_t		*vp;
+
+	vp = XFS_ITOV_NULL(ip);
+	if (vp) {
+		struct inode *inode = &vp->v_inode;
+		ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec;
+		ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec;
+	}
+}
+
+/*
  * Change the requested timestamp in the given inode.
  * We don't lock across timestamp updates, and we don't log them but
  * we do record the fact that there is dirty information in core.
@@ -77,23 +112,6 @@
 	struct inode	*inode = LINVFS_GET_IP(XFS_ITOV(ip));
 	timespec_t	tv;
 
-	/*
-	 * We're not supposed to change timestamps in readonly-mounted
-	 * filesystems.  Throw it away if anyone asks us.
-	 */
-	if (unlikely(IS_RDONLY(inode)))
-		return;
-
-	/*
-	 * Don't update access timestamps on reads if mounted "noatime".
-	 * Throw it away if anyone asks us.
-	 */
-	if (unlikely(
-	    (ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) &&
-	    (flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG)) ==
-			XFS_ICHGTIME_ACC))
-		return;
-
 	nanotime(&tv);
 	if (flags & XFS_ICHGTIME_MOD) {
 		inode->i_mtime = tv;
@@ -130,8 +148,6 @@
  * Variant on the above which avoids querying the system clock
  * in situations where we know the Linux inode timestamps have
  * just been updated (and so we can update our inode cheaply).
- * We also skip the readonly and noatime checks here, they are
- * also catered for already.
  */
 void
 xfs_ichgtime_fast(
@@ -142,32 +158,23 @@
 	timespec_t	*tvp;
 
 	/*
+	 * Atime updates for read() & friends are handled lazily now, and
+	 * explicit updates must go through xfs_ichgtime()
+	 */
+	ASSERT((flags & XFS_ICHGTIME_ACC) == 0);
+
+	/*
 	 * We're not supposed to change timestamps in readonly-mounted
 	 * filesystems.  Throw it away if anyone asks us.
 	 */
 	if (unlikely(IS_RDONLY(inode)))
 		return;
 
-	/*
-	 * Don't update access timestamps on reads if mounted "noatime".
-	 * Throw it away if anyone asks us.
-	 */
-	if (unlikely(
-	    (ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) &&
-	    ((flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG)) ==
-			XFS_ICHGTIME_ACC)))
-		return;
-
 	if (flags & XFS_ICHGTIME_MOD) {
 		tvp = &inode->i_mtime;
 		ip->i_d.di_mtime.t_sec = (__int32_t)tvp->tv_sec;
 		ip->i_d.di_mtime.t_nsec = (__int32_t)tvp->tv_nsec;
 	}
-	if (flags & XFS_ICHGTIME_ACC) {
-		tvp = &inode->i_atime;
-		ip->i_d.di_atime.t_sec = (__int32_t)tvp->tv_sec;
-		ip->i_d.di_atime.t_nsec = (__int32_t)tvp->tv_nsec;
-	}
 	if (flags & XFS_ICHGTIME_CHG) {
 		tvp = &inode->i_ctime;
 		ip->i_d.di_ctime.t_sec = (__int32_t)tvp->tv_sec;
@@ -214,6 +221,39 @@
 }
 
 /*
+ * Hook in SELinux.  This is not quite correct yet, what we really need
+ * here (as we do for default ACLs) is a mechanism by which creation of
+ * these attrs can be journalled at inode creation time (along with the
+ * inode, of course, such that log replay can't cause these to be lost).
+ */
+STATIC int
+linvfs_init_security(
+	struct vnode	*vp,
+	struct inode	*dir)
+{
+	struct inode	*ip = LINVFS_GET_IP(vp);
+	size_t		length;
+	void		*value;
+	char		*name;
+	int		error;
+
+	error = security_inode_init_security(ip, dir, &name, &value, &length);
+	if (error) {
+		if (error == -EOPNOTSUPP)
+			return 0;
+		return -error;
+	}
+
+	VOP_ATTR_SET(vp, name, value, length, ATTR_SECURE, NULL, error);
+	if (!error)
+		VMODIFY(vp);
+
+	kfree(name);
+	kfree(value);
+	return error;
+}
+
+/*
  * Determine whether a process has a valid fs_struct (kernel daemons
  * like knfsd don't have an fs_struct).
  *
@@ -278,6 +318,9 @@
 		break;
 	}
 
+	if (!error)
+		error = linvfs_init_security(vp, dir);
+
 	if (default_acl) {
 		if (!error) {
 			error = _ACL_INHERIT(vp, &va, default_acl);
@@ -294,8 +337,6 @@
 				teardown.d_inode = ip = LINVFS_GET_IP(vp);
 				teardown.d_name = dentry->d_name;
 
-				vn_mark_bad(vp);
-				
 				if (S_ISDIR(mode))
 					VOP_RMDIR(dvp, &teardown, NULL, err2);
 				else
@@ -506,7 +547,7 @@
 	ASSERT(dentry);
 	ASSERT(nd);
 
-	link = (char *)kmalloc(MAXNAMELEN+1, GFP_KERNEL);
+	link = (char *)kmalloc(MAXPATHLEN+1, GFP_KERNEL);
 	if (!link) {
 		nd_set_link(nd, ERR_PTR(-ENOMEM));
 		return NULL;
@@ -522,12 +563,12 @@
 	vp = LINVFS_GET_VP(dentry->d_inode);
 
 	iov.iov_base = link;
-	iov.iov_len = MAXNAMELEN;
+	iov.iov_len = MAXPATHLEN;
 
 	uio->uio_iov = &iov;
 	uio->uio_offset = 0;
 	uio->uio_segflg = UIO_SYSSPACE;
-	uio->uio_resid = MAXNAMELEN;
+	uio->uio_resid = MAXPATHLEN;
 	uio->uio_iovcnt = 1;
 
 	VOP_READLINK(vp, uio, 0, NULL, error);
@@ -535,7 +576,7 @@
 		kfree(link);
 		link = ERR_PTR(-error);
 	} else {
-		link[MAXNAMELEN - uio->uio_resid] = '\0';
+		link[MAXPATHLEN - uio->uio_resid] = '\0';
 	}
 	kfree(uio);
 
diff --git a/fs/xfs/linux-2.6/xfs_iops.h b/fs/xfs/linux-2.6/xfs_iops.h
index ee784b6..6899a6b 100644
--- a/fs/xfs/linux-2.6/xfs_iops.h
+++ b/fs/xfs/linux-2.6/xfs_iops.h
@@ -26,11 +26,6 @@
 extern struct file_operations linvfs_invis_file_operations;
 extern struct file_operations linvfs_dir_operations;
 
-extern struct address_space_operations linvfs_aops;
-
-extern int linvfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
-extern void linvfs_unwritten_done(struct buffer_head *, int);
-
 extern int xfs_ioctl(struct bhv_desc *, struct inode *, struct file *,
                         int, unsigned int, void __user *);
 
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index d8e21ba..67389b7 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -110,10 +110,6 @@
  * delalloc and these ondisk-uninitialised buffers.
  */
 BUFFER_FNS(PrivateStart, unwritten);
-static inline void set_buffer_unwritten_io(struct buffer_head *bh)
-{
-	bh->b_end_io = linvfs_unwritten_done;
-}
 
 #define restricted_chown	xfs_params.restrict_chown.val
 #define irix_sgid_inherit	xfs_params.sgid_inherit.val
@@ -232,7 +228,7 @@
 #define xfs_itruncate_data(ip, off)	\
 	(-vmtruncate(LINVFS_GET_IP(XFS_ITOV(ip)), (off)))
 #define xfs_statvfs_fsid(statp, mp)	\
-	({ u64 id = huge_encode_dev((mp)->m_dev);	\
+	({ u64 id = huge_encode_dev((mp)->m_ddev_targp->bt_dev); \
 	   __kernel_fsid_t *fsid = &(statp)->f_fsid;	\
 	(fsid->val[0] = (u32)id, fsid->val[1] = (u32)(id >> 32)); })
 
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 885dfaf..e0ab45f 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -233,8 +233,8 @@
 		xfs_buftarg_t	*target =
 			(ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
 				mp->m_rtdev_targp : mp->m_ddev_targp;
-		if ((*offset & target->pbr_smask) ||
-		    (size & target->pbr_smask)) {
+		if ((*offset & target->bt_smask) ||
+		    (size & target->bt_smask)) {
 			if (*offset == ip->i_d.di_size) {
 				return (0);
 			}
@@ -281,9 +281,6 @@
 
 	xfs_iunlock(ip, XFS_IOLOCK_SHARED);
 
-	if (likely(!(ioflags & IO_INVIS)))
-		xfs_ichgtime_fast(ip, inode, XFS_ICHGTIME_ACC);
-
 unlock_isem:
 	if (unlikely(ioflags & IO_ISDIRECT))
 		mutex_unlock(&inode->i_mutex);
@@ -346,9 +343,6 @@
 	if (ret > 0)
 		XFS_STATS_ADD(xs_read_bytes, ret);
 
-	if (likely(!(ioflags & IO_INVIS)))
-		xfs_ichgtime_fast(ip, LINVFS_GET_IP(vp), XFS_ICHGTIME_ACC);
-
 	return ret;
 }
 
@@ -362,7 +356,6 @@
 xfs_zero_last_block(
 	struct inode	*ip,
 	xfs_iocore_t	*io,
-	xfs_off_t	offset,
 	xfs_fsize_t	isize,
 	xfs_fsize_t	end_size)
 {
@@ -371,19 +364,16 @@
 	int		nimaps;
 	int		zero_offset;
 	int		zero_len;
-	int		isize_fsb_offset;
 	int		error = 0;
 	xfs_bmbt_irec_t	imap;
 	loff_t		loff;
-	size_t		lsize;
 
 	ASSERT(ismrlocked(io->io_lock, MR_UPDATE) != 0);
-	ASSERT(offset > isize);
 
 	mp = io->io_mount;
 
-	isize_fsb_offset = XFS_B_FSB_OFFSET(mp, isize);
-	if (isize_fsb_offset == 0) {
+	zero_offset = XFS_B_FSB_OFFSET(mp, isize);
+	if (zero_offset == 0) {
 		/*
 		 * There are no extra bytes in the last block on disk to
 		 * zero, so return.
@@ -413,10 +403,8 @@
 	 */
 	XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL| XFS_EXTSIZE_RD);
 	loff = XFS_FSB_TO_B(mp, last_fsb);
-	lsize = XFS_FSB_TO_B(mp, 1);
 
-	zero_offset = isize_fsb_offset;
-	zero_len = mp->m_sb.sb_blocksize - isize_fsb_offset;
+	zero_len = mp->m_sb.sb_blocksize - zero_offset;
 
 	error = xfs_iozero(ip, loff + zero_offset, zero_len, end_size);
 
@@ -447,20 +435,17 @@
 	struct inode	*ip = LINVFS_GET_IP(vp);
 	xfs_fileoff_t	start_zero_fsb;
 	xfs_fileoff_t	end_zero_fsb;
-	xfs_fileoff_t	prev_zero_fsb;
 	xfs_fileoff_t	zero_count_fsb;
 	xfs_fileoff_t	last_fsb;
 	xfs_extlen_t	buf_len_fsb;
-	xfs_extlen_t	prev_zero_count;
 	xfs_mount_t	*mp;
 	int		nimaps;
 	int		error = 0;
 	xfs_bmbt_irec_t	imap;
-	loff_t		loff;
-	size_t		lsize;
 
 	ASSERT(ismrlocked(io->io_lock, MR_UPDATE));
 	ASSERT(ismrlocked(io->io_iolock, MR_UPDATE));
+	ASSERT(offset > isize);
 
 	mp = io->io_mount;
 
@@ -468,7 +453,7 @@
 	 * First handle zeroing the block on which isize resides.
 	 * We only zero a part of that block so it is handled specially.
 	 */
-	error = xfs_zero_last_block(ip, io, offset, isize, end_size);
+	error = xfs_zero_last_block(ip, io, isize, end_size);
 	if (error) {
 		ASSERT(ismrlocked(io->io_lock, MR_UPDATE));
 		ASSERT(ismrlocked(io->io_iolock, MR_UPDATE));
@@ -496,8 +481,6 @@
 	}
 
 	ASSERT(start_zero_fsb <= end_zero_fsb);
-	prev_zero_fsb = NULLFILEOFF;
-	prev_zero_count = 0;
 	while (start_zero_fsb <= end_zero_fsb) {
 		nimaps = 1;
 		zero_count_fsb = end_zero_fsb - start_zero_fsb + 1;
@@ -519,10 +502,7 @@
 			 * that sits on a hole and sets the page as P_HOLE
 			 * and calls remapf if it is a mapped file.
 			 */
-			prev_zero_fsb = NULLFILEOFF;
-			prev_zero_count = 0;
-			start_zero_fsb = imap.br_startoff +
-					 imap.br_blockcount;
+			start_zero_fsb = imap.br_startoff + imap.br_blockcount;
 			ASSERT(start_zero_fsb <= (end_zero_fsb + 1));
 			continue;
 		}
@@ -543,17 +523,15 @@
 		 */
 		XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD);
 
-		loff = XFS_FSB_TO_B(mp, start_zero_fsb);
-		lsize = XFS_FSB_TO_B(mp, buf_len_fsb);
-
-		error = xfs_iozero(ip, loff, lsize, end_size);
+		error = xfs_iozero(ip,
+				   XFS_FSB_TO_B(mp, start_zero_fsb),
+				   XFS_FSB_TO_B(mp, buf_len_fsb),
+				   end_size);
 
 		if (error) {
 			goto out_lock;
 		}
 
-		prev_zero_fsb = start_zero_fsb;
-		prev_zero_count = buf_len_fsb;
 		start_zero_fsb = imap.br_startoff + buf_len_fsb;
 		ASSERT(start_zero_fsb <= (end_zero_fsb + 1));
 
@@ -640,7 +618,7 @@
 			(xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
 				mp->m_rtdev_targp : mp->m_ddev_targp;
 
-		if ((pos & target->pbr_smask) || (count & target->pbr_smask))
+		if ((pos & target->bt_smask) || (count & target->bt_smask))
 			return XFS_ERROR(-EINVAL);
 
 		if (!VN_CACHED(vp) && pos < i_size_read(inode))
@@ -831,6 +809,10 @@
 		goto retry;
 	}
 
+	isize = i_size_read(inode);
+	if (unlikely(ret < 0 && ret != -EFAULT && *offset > isize))
+		*offset = isize;
+
 	if (*offset > xip->i_d.di_size) {
 		xfs_ilock(xip, XFS_ILOCK_EXCL);
 		if (*offset > xip->i_d.di_size) {
@@ -956,7 +938,7 @@
 
 	mp = XFS_BUF_FSPRIVATE3(bp, xfs_mount_t *);
 	if (!XFS_FORCED_SHUTDOWN(mp)) {
-		pagebuf_iorequest(bp);
+		xfs_buf_iorequest(bp);
 		return 0;
 	} else {
 		xfs_buftrace("XFS__BDSTRAT IOERROR", bp);
@@ -1009,7 +991,7 @@
 		 * if (XFS_BUF_IS_GRIO(bp)) {
 		 */
 
-		pagebuf_iorequest(bp);
+		xfs_buf_iorequest(bp);
 		return 0;
 	}
 
diff --git a/fs/xfs/linux-2.6/xfs_stats.c b/fs/xfs/linux-2.6/xfs_stats.c
index 6c40a74..8955720 100644
--- a/fs/xfs/linux-2.6/xfs_stats.c
+++ b/fs/xfs/linux-2.6/xfs_stats.c
@@ -34,7 +34,7 @@
 	__uint64_t	xs_write_bytes = 0;
 	__uint64_t	xs_read_bytes = 0;
 
-	static struct xstats_entry {
+	static const struct xstats_entry {
 		char	*desc;
 		int	endpoint;
 	} xstats[] = {
diff --git a/fs/xfs/linux-2.6/xfs_stats.h b/fs/xfs/linux-2.6/xfs_stats.h
index 50027c4..8ba7a2f 100644
--- a/fs/xfs/linux-2.6/xfs_stats.h
+++ b/fs/xfs/linux-2.6/xfs_stats.h
@@ -109,15 +109,15 @@
 	__uint32_t		vn_remove;	/* # times vn_remove called */
 	__uint32_t		vn_free;	/* # times vn_free called */
 #define XFSSTAT_END_BUF			(XFSSTAT_END_VNODE_OPS+9)
-	__uint32_t		pb_get;
-	__uint32_t		pb_create;
-	__uint32_t		pb_get_locked;
-	__uint32_t		pb_get_locked_waited;
-	__uint32_t		pb_busy_locked;
-	__uint32_t		pb_miss_locked;
-	__uint32_t		pb_page_retries;
-	__uint32_t		pb_page_found;
-	__uint32_t		pb_get_read;
+	__uint32_t		xb_get;
+	__uint32_t		xb_create;
+	__uint32_t		xb_get_locked;
+	__uint32_t		xb_get_locked_waited;
+	__uint32_t		xb_busy_locked;
+	__uint32_t		xb_miss_locked;
+	__uint32_t		xb_page_retries;
+	__uint32_t		xb_page_found;
+	__uint32_t		xb_get_read;
 /* Extra precision counters */
 	__uint64_t		xs_xstrat_bytes;
 	__uint64_t		xs_write_bytes;
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 6116b5b..f22e426 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -306,13 +306,15 @@
 		xfs_fs_cmn_err(CE_NOTE, mp,
 		  "Disabling barriers, not supported with external log device");
 		mp->m_flags &= ~XFS_MOUNT_BARRIER;
+		return;
 	}
 
-	if (mp->m_ddev_targp->pbr_bdev->bd_disk->queue->ordered ==
+	if (mp->m_ddev_targp->bt_bdev->bd_disk->queue->ordered ==
 					QUEUE_ORDERED_NONE) {
 		xfs_fs_cmn_err(CE_NOTE, mp,
 		  "Disabling barriers, not supported by the underlying device");
 		mp->m_flags &= ~XFS_MOUNT_BARRIER;
+		return;
 	}
 
 	error = xfs_barrier_test(mp);
@@ -320,6 +322,7 @@
 		xfs_fs_cmn_err(CE_NOTE, mp,
 		  "Disabling barriers, trial barrier write failed");
 		mp->m_flags &= ~XFS_MOUNT_BARRIER;
+		return;
 	}
 }
 
@@ -327,7 +330,7 @@
 xfs_blkdev_issue_flush(
 	xfs_buftarg_t		*buftarg)
 {
-	blkdev_issue_flush(buftarg->pbr_bdev, NULL);
+	blkdev_issue_flush(buftarg->bt_bdev, NULL);
 }
 
 STATIC struct inode *
@@ -576,7 +579,7 @@
 		timeleft = schedule_timeout_interruptible(timeleft);
 		/* swsusp */
 		try_to_freeze();
-		if (kthread_should_stop())
+		if (kthread_should_stop() && list_empty(&vfsp->vfs_sync_list))
 			break;
 
 		spin_lock(&vfsp->vfs_sync_lock);
@@ -966,9 +969,9 @@
 	if (error < 0)
 		goto undo_zones;
 
-	error = pagebuf_init();
+	error = xfs_buf_init();
 	if (error < 0)
-		goto undo_pagebuf;
+		goto undo_buffers;
 
 	vn_init();
 	xfs_init();
@@ -982,9 +985,9 @@
 	return 0;
 
 undo_register:
-	pagebuf_terminate();
+	xfs_buf_terminate();
 
-undo_pagebuf:
+undo_buffers:
 	linvfs_destroy_zones();
 
 undo_zones:
@@ -998,7 +1001,7 @@
 	XFS_DM_EXIT(&xfs_fs_type);
 	unregister_filesystem(&xfs_fs_type);
 	xfs_cleanup();
-	pagebuf_terminate();
+	xfs_buf_terminate();
 	linvfs_destroy_zones();
 	ktrace_uninit();
 }
diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c
index e9bbcb4..260dd84 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.c
+++ b/fs/xfs/linux-2.6/xfs_vnode.c
@@ -106,7 +106,6 @@
 	inode->i_blocks	    = vap->va_nblocks;
 	inode->i_mtime	    = vap->va_mtime;
 	inode->i_ctime	    = vap->va_ctime;
-	inode->i_atime	    = vap->va_atime;
 	inode->i_blksize    = vap->va_blocksize;
 	if (vap->va_xflags & XFS_XFLAG_IMMUTABLE)
 		inode->i_flags |= S_IMMUTABLE;
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index f2bbb32..0fe2419 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -566,6 +566,25 @@
 }
 
 /*
+ * Extracting atime values in various formats
+ */
+static inline void vn_atime_to_bstime(struct vnode *vp, xfs_bstime_t *bs_atime)
+{
+	bs_atime->tv_sec = vp->v_inode.i_atime.tv_sec;
+	bs_atime->tv_nsec = vp->v_inode.i_atime.tv_nsec;
+}
+
+static inline void vn_atime_to_timespec(struct vnode *vp, struct timespec *ts)
+{
+	*ts = vp->v_inode.i_atime;
+}
+
+static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt)
+{
+	*tt = vp->v_inode.i_atime.tv_sec;
+}
+
+/*
  * Some useful predicates.
  */
 #define VN_MAPPED(vp)	mapping_mapped(LINVFS_GET_IP(vp)->i_mapping)
diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c
index 2f69822..2ec6b44 100644
--- a/fs/xfs/quota/xfs_dquot_item.c
+++ b/fs/xfs/quota/xfs_dquot_item.c
@@ -239,7 +239,7 @@
 	 * trying to duplicate our effort.
 	 */
 	ASSERT(qip->qli_pushbuf_flag != 0);
-	ASSERT(qip->qli_push_owner == get_thread_id());
+	ASSERT(qip->qli_push_owner == current_pid());
 
 	/*
 	 * If flushlock isn't locked anymore, chances are that the
@@ -333,7 +333,7 @@
 			qip->qli_pushbuf_flag = 1;
 			ASSERT(qip->qli_format.qlf_blkno == dqp->q_blkno);
 #ifdef DEBUG
-			qip->qli_push_owner = get_thread_id();
+			qip->qli_push_owner = current_pid();
 #endif
 			/*
 			 * The dquot is left locked.
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index bb6991a..7dcdd06 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -1392,11 +1392,12 @@
 {
 	xfs_trans_t	*tp;
 	int		error;
-	unsigned long s;
+	unsigned long	s;
 	cred_t		zerocr;
+	xfs_inode_t	zeroino;
 	int		committed;
 
-	tp = xfs_trans_alloc(mp,XFS_TRANS_QM_QINOCREATE);
+	tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QINOCREATE);
 	if ((error = xfs_trans_reserve(tp,
 				      XFS_QM_QINOCREATE_SPACE_RES(mp),
 				      XFS_CREATE_LOG_RES(mp), 0,
@@ -1406,8 +1407,9 @@
 		return (error);
 	}
 	memset(&zerocr, 0, sizeof(zerocr));
+	memset(&zeroino, 0, sizeof(zeroino));
 
-	if ((error = xfs_dir_ialloc(&tp, mp->m_rootip, S_IFREG, 1, 0,
+	if ((error = xfs_dir_ialloc(&tp, &zeroino, S_IFREG, 1, 0,
 				   &zerocr, 0, 1, ip, &committed))) {
 		xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES |
 				 XFS_TRANS_ABORT);
@@ -1918,9 +1920,7 @@
 	 * at this point (because we intentionally didn't in dqget_noattach).
 	 */
 	if (error) {
-		xfs_qm_dqpurge_all(mp,
-				   XFS_QMOPT_UQUOTA|XFS_QMOPT_GQUOTA|
-				   XFS_QMOPT_PQUOTA|XFS_QMOPT_QUOTAOFF);
+		xfs_qm_dqpurge_all(mp, XFS_QMOPT_QUOTALL | XFS_QMOPT_QUOTAOFF);
 		goto error_return;
 	}
 	/*
@@ -2743,6 +2743,7 @@
 		xfs_dqunlock(udqp);
 		ASSERT(ip->i_udquot == NULL);
 		ip->i_udquot = udqp;
+		ASSERT(XFS_IS_UQUOTA_ON(tp->t_mountp));
 		ASSERT(ip->i_d.di_uid == be32_to_cpu(udqp->q_core.d_id));
 		xfs_trans_mod_dquot(tp, udqp, XFS_TRANS_DQ_ICOUNT, 1);
 	}
@@ -2752,7 +2753,10 @@
 		xfs_dqunlock(gdqp);
 		ASSERT(ip->i_gdquot == NULL);
 		ip->i_gdquot = gdqp;
-		ASSERT(ip->i_d.di_gid == be32_to_cpu(gdqp->q_core.d_id));
+		ASSERT(XFS_IS_OQUOTA_ON(tp->t_mountp));
+		ASSERT((XFS_IS_GQUOTA_ON(tp->t_mountp) ?
+			ip->i_d.di_gid : ip->i_d.di_projid) ==
+				be32_to_cpu(gdqp->q_core.d_id));
 		xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1);
 	}
 }
diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
index bb6dc91..b08b3d9 100644
--- a/fs/xfs/support/debug.c
+++ b/fs/xfs/support/debug.c
@@ -27,45 +27,12 @@
 /* Translate from CE_FOO to KERN_FOO, err_level(CE_FOO) == KERN_FOO */
 #define XFS_MAX_ERR_LEVEL	7
 #define XFS_ERR_MASK		((1 << 3) - 1)
-static char		*err_level[XFS_MAX_ERR_LEVEL+1] =
+static const char * const	err_level[XFS_MAX_ERR_LEVEL+1] =
 					{KERN_EMERG, KERN_ALERT, KERN_CRIT,
 					 KERN_ERR, KERN_WARNING, KERN_NOTICE,
 					 KERN_INFO, KERN_DEBUG};
 
 void
-assfail(char *a, char *f, int l)
-{
-    printk("XFS assertion failed: %s, file: %s, line: %d\n", a, f, l);
-    BUG();
-}
-
-#if ((defined(DEBUG) || defined(INDUCE_IO_ERRROR)) && !defined(NO_WANT_RANDOM))
-
-unsigned long
-random(void)
-{
-	static unsigned long	RandomValue = 1;
-	/* cycles pseudo-randomly through all values between 1 and 2^31 - 2 */
-	register long	rv = RandomValue;
-	register long	lo;
-	register long	hi;
-
-	hi = rv / 127773;
-	lo = rv % 127773;
-	rv = 16807 * lo - 2836 * hi;
-	if( rv <= 0 ) rv += 2147483647;
-	return( RandomValue = rv );
-}
-
-int
-get_thread_id(void)
-{
-	return current->pid;
-}
-
-#endif /* DEBUG || INDUCE_IO_ERRROR || !NO_WANT_RANDOM */
-
-void
 cmn_err(register int level, char *fmt, ...)
 {
 	char	*fp = fmt;
@@ -90,7 +57,6 @@
 		BUG();
 }
 
-
 void
 icmn_err(register int level, char *fmt, va_list ap)
 {
@@ -109,3 +75,27 @@
 	if (level == CE_PANIC)
 		BUG();
 }
+
+void
+assfail(char *expr, char *file, int line)
+{
+	printk("Assertion failed: %s, file: %s, line: %d\n", expr, file, line);
+	BUG();
+}
+
+#if ((defined(DEBUG) || defined(INDUCE_IO_ERRROR)) && !defined(NO_WANT_RANDOM))
+unsigned long random(void)
+{
+	static unsigned long	RandomValue = 1;
+	/* cycles pseudo-randomly through all values between 1 and 2^31 - 2 */
+	register long	rv = RandomValue;
+	register long	lo;
+	register long	hi;
+
+	hi = rv / 127773;
+	lo = rv % 127773;
+	rv = 16807 * lo - 2836 * hi;
+	if (rv <= 0) rv += 2147483647;
+	return RandomValue = rv;
+}
+#endif /* DEBUG || INDUCE_IO_ERRROR || !NO_WANT_RANDOM */
diff --git a/fs/xfs/support/debug.h b/fs/xfs/support/debug.h
index aff5586..e3bf581 100644
--- a/fs/xfs/support/debug.h
+++ b/fs/xfs/support/debug.h
@@ -31,24 +31,23 @@
 	__attribute__ ((format (printf, 2, 0)));
 extern void cmn_err(int, char *, ...)
 	__attribute__ ((format (printf, 2, 3)));
+extern void assfail(char *expr, char *f, int l);
+
+#define prdev(fmt,targ,args...) \
+	printk("Device %s - " fmt "\n", XFS_BUFTARG_NAME(targ), ## args)
+
+#define ASSERT_ALWAYS(expr)	\
+	(unlikely((expr) != 0) ? (void)0 : assfail(#expr, __FILE__, __LINE__))
+
+#ifndef DEBUG
+# define ASSERT(expr)	((void)0)
+#else
+# define ASSERT(expr)	ASSERT_ALWAYS(expr)
+extern unsigned long random(void);
+#endif
 
 #ifndef STATIC
 # define STATIC static
 #endif
 
-#ifdef DEBUG
-# define ASSERT(EX)	((EX) ? ((void)0) : assfail(#EX, __FILE__, __LINE__))
-#else
-# define ASSERT(x)	((void)0)
-#endif
-
-extern void assfail(char *, char *, int);
-#ifdef DEBUG
-extern unsigned long random(void);
-extern int get_thread_id(void);
-#endif
-
-#define ASSERT_ALWAYS(EX)  ((EX)?((void)0):assfail(#EX, __FILE__, __LINE__))
-#define	debug_stop_all_cpus(param)	/* param is "cpumask_t *" */
-
 #endif  /* __XFS_SUPPORT_DEBUG_H__ */
diff --git a/fs/xfs/support/uuid.c b/fs/xfs/support/uuid.c
index 69ec4f5..a3d565a 100644
--- a/fs/xfs/support/uuid.c
+++ b/fs/xfs/support/uuid.c
@@ -27,6 +27,16 @@
 	mutex_init(&uuid_monitor);
 }
 
+
+/* IRIX interpretation of an uuid_t */
+typedef struct {
+	__be32	uu_timelow;
+	__be16	uu_timemid;
+	__be16	uu_timehi;
+	__be16	uu_clockseq;
+	__be16	uu_node[3];
+} xfs_uu_t;
+
 /*
  * uuid_getnodeuniq - obtain the node unique fields of a UUID.
  *
@@ -36,16 +46,11 @@
 void
 uuid_getnodeuniq(uuid_t *uuid, int fsid [2])
 {
-	char	*uu = (char *)uuid;
+	xfs_uu_t *uup = (xfs_uu_t *)uuid;
 
-	/* on IRIX, this function assumes big-endian fields within
-	 * the uuid, so we use INT_GET to get the same result on
-	 * little-endian systems
-	 */
-
-	fsid[0] = (INT_GET(*(u_int16_t*)(uu+8), ARCH_CONVERT) << 16) +
-		   INT_GET(*(u_int16_t*)(uu+4), ARCH_CONVERT);
-	fsid[1] =  INT_GET(*(u_int32_t*)(uu  ), ARCH_CONVERT);
+	fsid[0] = (be16_to_cpu(uup->uu_clockseq) << 16) |
+		   be16_to_cpu(uup->uu_timemid);
+	fsid[1] = be16_to_cpu(uup->uu_timelow);
 }
 
 void
diff --git a/fs/xfs/xfs_arch.h b/fs/xfs/xfs_arch.h
index 68e5051..c483689 100644
--- a/fs/xfs/xfs_arch.h
+++ b/fs/xfs/xfs_arch.h
@@ -40,6 +40,22 @@
 #undef XFS_NATIVE_HOST
 #endif
 
+#ifdef XFS_NATIVE_HOST
+#define cpu_to_be16(val)	((__be16)(val))
+#define cpu_to_be32(val)	((__be32)(val))
+#define cpu_to_be64(val)	((__be64)(val))
+#define be16_to_cpu(val)	((__uint16_t)(val))
+#define be32_to_cpu(val)	((__uint32_t)(val))
+#define be64_to_cpu(val)	((__uint64_t)(val))
+#else
+#define cpu_to_be16(val)	(__swab16((__uint16_t)(val)))
+#define cpu_to_be32(val)	(__swab32((__uint32_t)(val)))
+#define cpu_to_be64(val)	(__swab64((__uint64_t)(val)))
+#define be16_to_cpu(val)	(__swab16((__be16)(val)))
+#define be32_to_cpu(val)	(__swab32((__be32)(val)))
+#define be64_to_cpu(val)	(__swab64((__be64)(val)))
+#endif
+
 #endif	/* __KERNEL__ */
 
 /* do we need conversion? */
@@ -186,7 +202,7 @@
  */ 
 
 #define XFS_GET_DIR_INO4(di) \
-	(((u32)(di).i[0] << 24) | ((di).i[1] << 16) | ((di).i[2] << 8) | ((di).i[3]))
+	(((__u32)(di).i[0] << 24) | ((di).i[1] << 16) | ((di).i[2] << 8) | ((di).i[3]))
 
 #define XFS_PUT_DIR_INO4(from, di) \
 do { \
@@ -197,9 +213,9 @@
 } while (0)
 
 #define XFS_DI_HI(di) \
-	(((u32)(di).i[1] << 16) | ((di).i[2] << 8) | ((di).i[3]))
+	(((__u32)(di).i[1] << 16) | ((di).i[2] << 8) | ((di).i[3]))
 #define XFS_DI_LO(di) \
-	(((u32)(di).i[4] << 24) | ((di).i[5] << 16) | ((di).i[6] << 8) | ((di).i[7]))
+	(((__u32)(di).i[4] << 24) | ((di).i[5] << 16) | ((di).i[6] << 8) | ((di).i[7]))
 
 #define XFS_GET_DIR_INO8(di)        \
 	(((xfs_ino_t)XFS_DI_LO(di) & 0xffffffffULL) | \
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 1c74218..fe91eac 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -128,7 +128,7 @@
 		return (offset >= minforkoff) ? minforkoff : 0;
 	}
 
-	if (unlikely(mp->m_flags & XFS_MOUNT_COMPAT_ATTR)) {
+	if (!(mp->m_flags & XFS_MOUNT_ATTR2)) {
 		if (bytes <= XFS_IFORK_ASIZE(dp))
 			return mp->m_attroffset >> 3;
 		return 0;
@@ -157,7 +157,7 @@
 {
 	unsigned long s;
 
-	if (!(mp->m_flags & XFS_MOUNT_COMPAT_ATTR) &&
+	if ((mp->m_flags & XFS_MOUNT_ATTR2) &&
 	    !(XFS_SB_VERSION_HASATTR2(&mp->m_sb))) {
 		s = XFS_SB_LOCK(mp);
 		if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb)) {
@@ -311,7 +311,7 @@
 	 */
 	totsize -= size;
 	if (totsize == sizeof(xfs_attr_sf_hdr_t) && !args->addname &&
-	    !(mp->m_flags & XFS_MOUNT_COMPAT_ATTR)) {
+	    (mp->m_flags & XFS_MOUNT_ATTR2)) {
 		/*
 		 * Last attribute now removed, revert to original
 		 * inode format making all literal area available
@@ -330,7 +330,7 @@
 		dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize);
 		ASSERT(dp->i_d.di_forkoff);
 		ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) || args->addname ||
-			(mp->m_flags & XFS_MOUNT_COMPAT_ATTR));
+			!(mp->m_flags & XFS_MOUNT_ATTR2));
 		dp->i_afp->if_ext_max =
 			XFS_IFORK_ASIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
 		dp->i_df.if_ext_max =
@@ -739,7 +739,7 @@
 				+ name_loc->namelen
 				+ INT_GET(name_loc->valuelen, ARCH_CONVERT);
 	}
-	if (!(dp->i_mount->m_flags & XFS_MOUNT_COMPAT_ATTR) &&
+	if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) &&
 	    (bytes == sizeof(struct xfs_attr_sf_hdr)))
 		return(-1);
 	return(xfs_attr_shortform_bytesfit(dp, bytes));
@@ -778,7 +778,7 @@
 		goto out;
 
 	if (forkoff == -1) {
-		ASSERT(!(dp->i_mount->m_flags & XFS_MOUNT_COMPAT_ATTR));
+		ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2);
 
 		/*
 		 * Last attribute was removed, revert to original
diff --git a/fs/xfs/xfs_attr_leaf.h b/fs/xfs/xfs_attr_leaf.h
index f6143ff..541e3410 100644
--- a/fs/xfs/xfs_attr_leaf.h
+++ b/fs/xfs/xfs_attr_leaf.h
@@ -63,7 +63,7 @@
  * the leaf_entry.  The namespaces are independent only because we also look
  * at the namespace bit when we are looking for a matching attribute name.
  *
- * We also store a "incomplete" bit in the leaf_entry.  It shows that an
+ * We also store an "incomplete" bit in the leaf_entry.  It shows that an
  * attribute is in the middle of being created and should not be shown to
  * the user if we crash during the time that the bit is set.  We clear the
  * bit when we have finished setting up the attribute.  We do this because
@@ -72,42 +72,48 @@
  */
 #define XFS_ATTR_LEAF_MAPSIZE	3	/* how many freespace slots */
 
+typedef struct xfs_attr_leaf_map {	/* RLE map of free bytes */
+	__uint16_t	base;	 	/* base of free region */
+	__uint16_t	size;	  	/* length of free region */
+} xfs_attr_leaf_map_t;
+
+typedef struct xfs_attr_leaf_hdr {	/* constant-structure header block */
+	xfs_da_blkinfo_t info;		/* block type, links, etc. */
+	__uint16_t	count;		/* count of active leaf_entry's */
+	__uint16_t	usedbytes;	/* num bytes of names/values stored */
+	__uint16_t	firstused;	/* first used byte in name area */
+	__uint8_t	holes;		/* != 0 if blk needs compaction */
+	__uint8_t	pad1;
+	xfs_attr_leaf_map_t freemap[XFS_ATTR_LEAF_MAPSIZE];
+					/* N largest free regions */
+} xfs_attr_leaf_hdr_t;
+
+typedef struct xfs_attr_leaf_entry {	/* sorted on key, not name */
+	xfs_dahash_t	hashval;	/* hash value of name */
+	__uint16_t	nameidx;	/* index into buffer of name/value */
+	__uint8_t	flags;		/* LOCAL/ROOT/SECURE/INCOMPLETE flag */
+	__uint8_t	pad2;		/* unused pad byte */
+} xfs_attr_leaf_entry_t;
+
+typedef struct xfs_attr_leaf_name_local {
+	__uint16_t	valuelen;	/* number of bytes in value */
+	__uint8_t	namelen;	/* length of name bytes */
+	__uint8_t	nameval[1];	/* name/value bytes */
+} xfs_attr_leaf_name_local_t;
+
+typedef struct xfs_attr_leaf_name_remote {
+	xfs_dablk_t	valueblk;	/* block number of value bytes */
+	__uint32_t	valuelen;	/* number of bytes in value */
+	__uint8_t	namelen;	/* length of name bytes */
+	__uint8_t	name[1];	/* name bytes */
+} xfs_attr_leaf_name_remote_t;
+
 typedef struct xfs_attr_leafblock {
-	struct xfs_attr_leaf_hdr {	/* constant-structure header block */
-		xfs_da_blkinfo_t info;	/* block type, links, etc. */
-		__uint16_t count;	/* count of active leaf_entry's */
-		__uint16_t usedbytes;	/* num bytes of names/values stored */
-		__uint16_t firstused;	/* first used byte in name area */
-		__uint8_t  holes;	/* != 0 if blk needs compaction */
-		__uint8_t  pad1;
-		struct xfs_attr_leaf_map {	  /* RLE map of free bytes */
-			__uint16_t base;	  /* base of free region */
-			__uint16_t size;	  /* length of free region */
-		} freemap[XFS_ATTR_LEAF_MAPSIZE]; /* N largest free regions */
-	} hdr;
-	struct xfs_attr_leaf_entry {	/* sorted on key, not name */
-		xfs_dahash_t hashval;	/* hash value of name */
-		__uint16_t nameidx;	/* index into buffer of name/value */
-		__uint8_t flags;	/* LOCAL/ROOT/SECURE/INCOMPLETE flag */
-		__uint8_t pad2;		/* unused pad byte */
-	} entries[1];			/* variable sized array */
-	struct xfs_attr_leaf_name_local {
-		__uint16_t valuelen;	/* number of bytes in value */
-		__uint8_t namelen;	/* length of name bytes */
-		__uint8_t nameval[1];	/* name/value bytes */
-	} namelist;			/* grows from bottom of buf */
-	struct xfs_attr_leaf_name_remote {
-		xfs_dablk_t valueblk;	/* block number of value bytes */
-		__uint32_t valuelen;	/* number of bytes in value */
-		__uint8_t namelen;	/* length of name bytes */
-		__uint8_t name[1];	/* name bytes */
-	} valuelist;			/* grows from bottom of buf */
+	xfs_attr_leaf_hdr_t	hdr;	/* constant-structure header block */
+	xfs_attr_leaf_entry_t	entries[1];	/* sorted on key, not name */
+	xfs_attr_leaf_name_local_t namelist;	/* grows from bottom of buf */
+	xfs_attr_leaf_name_remote_t valuelist;	/* grows from bottom of buf */
 } xfs_attr_leafblock_t;
-typedef struct xfs_attr_leaf_hdr xfs_attr_leaf_hdr_t;
-typedef struct xfs_attr_leaf_map xfs_attr_leaf_map_t;
-typedef struct xfs_attr_leaf_entry xfs_attr_leaf_entry_t;
-typedef struct xfs_attr_leaf_name_local xfs_attr_leaf_name_local_t;
-typedef struct xfs_attr_leaf_name_remote xfs_attr_leaf_name_remote_t;
 
 /*
  * Flags used in the leaf_entry[i].flags field.
@@ -150,7 +156,8 @@
 		(leafp))[INT_GET((leafp)->entries[idx].nameidx, ARCH_CONVERT)];
 }
 
-#define XFS_ATTR_LEAF_NAME(leafp,idx)		xfs_attr_leaf_name(leafp,idx)
+#define XFS_ATTR_LEAF_NAME(leafp,idx)		\
+	xfs_attr_leaf_name(leafp,idx)
 static inline char *xfs_attr_leaf_name(xfs_attr_leafblock_t *leafp, int idx)
 {
 	return (&((char *)
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index e415a46..70625e5 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -2146,13 +2146,176 @@
 	return 0; /* keep gcc quite */
 }
 
+/*
+ * Adjust the size of the new extent based on di_extsize and rt extsize.
+ */
+STATIC int
+xfs_bmap_extsize_align(
+	xfs_mount_t	*mp,
+	xfs_bmbt_irec_t	*gotp,		/* next extent pointer */
+	xfs_bmbt_irec_t	*prevp,		/* previous extent pointer */
+	xfs_extlen_t	extsz,		/* align to this extent size */
+	int		rt,		/* is this a realtime inode? */
+	int		eof,		/* is extent at end-of-file? */
+	int		delay,		/* creating delalloc extent? */
+	int		convert,	/* overwriting unwritten extent? */
+	xfs_fileoff_t	*offp,		/* in/out: aligned offset */
+	xfs_extlen_t	*lenp)		/* in/out: aligned length */
+{
+	xfs_fileoff_t	orig_off;	/* original offset */
+	xfs_extlen_t	orig_alen;	/* original length */
+	xfs_fileoff_t	orig_end;	/* original off+len */
+	xfs_fileoff_t	nexto;		/* next file offset */
+	xfs_fileoff_t	prevo;		/* previous file offset */
+	xfs_fileoff_t	align_off;	/* temp for offset */
+	xfs_extlen_t	align_alen;	/* temp for length */
+	xfs_extlen_t	temp;		/* temp for calculations */
+
+	if (convert)
+		return 0;
+
+	orig_off = align_off = *offp;
+	orig_alen = align_alen = *lenp;
+	orig_end = orig_off + orig_alen;
+
+	/*
+	 * If this request overlaps an existing extent, then don't
+	 * attempt to perform any additional alignment.
+	 */
+	if (!delay && !eof &&
+	    (orig_off >= gotp->br_startoff) &&
+	    (orig_end <= gotp->br_startoff + gotp->br_blockcount)) {
+		return 0;
+	}
+
+	/*
+	 * If the file offset is unaligned vs. the extent size
+	 * we need to align it.  This will be possible unless
+	 * the file was previously written with a kernel that didn't
+	 * perform this alignment, or if a truncate shot us in the
+	 * foot.
+	 */
+	temp = do_mod(orig_off, extsz);
+	if (temp) {
+		align_alen += temp;
+		align_off -= temp;
+	}
+	/*
+	 * Same adjustment for the end of the requested area.
+	 */
+	if ((temp = (align_alen % extsz))) {
+		align_alen += extsz - temp;
+	}
+	/*
+	 * If the previous block overlaps with this proposed allocation
+	 * then move the start forward without adjusting the length.
+	 */
+	if (prevp->br_startoff != NULLFILEOFF) {
+		if (prevp->br_startblock == HOLESTARTBLOCK)
+			prevo = prevp->br_startoff;
+		else
+			prevo = prevp->br_startoff + prevp->br_blockcount;
+	} else
+		prevo = 0;
+	if (align_off != orig_off && align_off < prevo)
+		align_off = prevo;
+	/*
+	 * If the next block overlaps with this proposed allocation
+	 * then move the start back without adjusting the length,
+	 * but not before offset 0.
+	 * This may of course make the start overlap previous block,
+	 * and if we hit the offset 0 limit then the next block
+	 * can still overlap too.
+	 */
+	if (!eof && gotp->br_startoff != NULLFILEOFF) {
+		if ((delay && gotp->br_startblock == HOLESTARTBLOCK) ||
+		    (!delay && gotp->br_startblock == DELAYSTARTBLOCK))
+			nexto = gotp->br_startoff + gotp->br_blockcount;
+		else
+			nexto = gotp->br_startoff;
+	} else
+		nexto = NULLFILEOFF;
+	if (!eof &&
+	    align_off + align_alen != orig_end &&
+	    align_off + align_alen > nexto)
+		align_off = nexto > align_alen ? nexto - align_alen : 0;
+	/*
+	 * If we're now overlapping the next or previous extent that
+	 * means we can't fit an extsz piece in this hole.  Just move
+	 * the start forward to the first valid spot and set
+	 * the length so we hit the end.
+	 */
+	if (align_off != orig_off && align_off < prevo)
+		align_off = prevo;
+	if (align_off + align_alen != orig_end &&
+	    align_off + align_alen > nexto &&
+	    nexto != NULLFILEOFF) {
+		ASSERT(nexto > prevo);
+		align_alen = nexto - align_off;
+	}
+
+	/*
+	 * If realtime, and the result isn't a multiple of the realtime
+	 * extent size we need to remove blocks until it is.
+	 */
+	if (rt && (temp = (align_alen % mp->m_sb.sb_rextsize))) {
+		/*
+		 * We're not covering the original request, or
+		 * we won't be able to once we fix the length.
+		 */
+		if (orig_off < align_off ||
+		    orig_end > align_off + align_alen ||
+		    align_alen - temp < orig_alen)
+			return XFS_ERROR(EINVAL);
+		/*
+		 * Try to fix it by moving the start up.
+		 */
+		if (align_off + temp <= orig_off) {
+			align_alen -= temp;
+			align_off += temp;
+		}
+		/*
+		 * Try to fix it by moving the end in.
+		 */
+		else if (align_off + align_alen - temp >= orig_end)
+			align_alen -= temp;
+		/*
+		 * Set the start to the minimum then trim the length.
+		 */
+		else {
+			align_alen -= orig_off - align_off;
+			align_off = orig_off;
+			align_alen -= align_alen % mp->m_sb.sb_rextsize;
+		}
+		/*
+		 * Result doesn't cover the request, fail it.
+		 */
+		if (orig_off < align_off || orig_end > align_off + align_alen)
+			return XFS_ERROR(EINVAL);
+	} else {
+		ASSERT(orig_off >= align_off);
+		ASSERT(orig_end <= align_off + align_alen);
+	}
+
+#ifdef DEBUG
+	if (!eof && gotp->br_startoff != NULLFILEOFF)
+		ASSERT(align_off + align_alen <= gotp->br_startoff);
+	if (prevp->br_startoff != NULLFILEOFF)
+		ASSERT(align_off >= prevp->br_startoff + prevp->br_blockcount);
+#endif
+
+	*lenp = align_alen;
+	*offp = align_off;
+	return 0;
+}
+
 #define XFS_ALLOC_GAP_UNITS	4
 
 /*
  * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file.
  * It figures out where to ask the underlying allocator to put the new extent.
  */
-STATIC int				/* error */
+STATIC int
 xfs_bmap_alloc(
 	xfs_bmalloca_t	*ap)		/* bmap alloc argument struct */
 {
@@ -2163,10 +2326,10 @@
 	xfs_mount_t	*mp;		/* mount point structure */
 	int		nullfb;		/* true if ap->firstblock isn't set */
 	int		rt;		/* true if inode is realtime */
-#ifdef __KERNEL__
-	xfs_extlen_t	prod=0;		/* product factor for allocators */
-	xfs_extlen_t	ralen=0;	/* realtime allocation length */
-#endif
+	xfs_extlen_t	prod = 0;	/* product factor for allocators */
+	xfs_extlen_t	ralen = 0;	/* realtime allocation length */
+	xfs_extlen_t	align;		/* minimum allocation alignment */
+	xfs_rtblock_t	rtx;
 
 #define	ISVALID(x,y)	\
 	(rt ? \
@@ -2182,125 +2345,25 @@
 	nullfb = ap->firstblock == NULLFSBLOCK;
 	rt = XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata;
 	fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock);
-#ifdef __KERNEL__
 	if (rt) {
-		xfs_extlen_t	extsz;		/* file extent size for rt */
-		xfs_fileoff_t	nexto;		/* next file offset */
-		xfs_extlen_t	orig_alen;	/* original ap->alen */
-		xfs_fileoff_t	orig_end;	/* original off+len */
-		xfs_fileoff_t	orig_off;	/* original ap->off */
-		xfs_extlen_t	mod_off;	/* modulus calculations */
-		xfs_fileoff_t	prevo;		/* previous file offset */
-		xfs_rtblock_t	rtx;		/* realtime extent number */
-		xfs_extlen_t	temp;		/* temp for rt calculations */
+		align = ap->ip->i_d.di_extsize ?
+			ap->ip->i_d.di_extsize : mp->m_sb.sb_rextsize;
+		/* Set prod to match the extent size */
+		prod = align / mp->m_sb.sb_rextsize;
 
-		/*
-		 * Set prod to match the realtime extent size.
-		 */
-		if (!(extsz = ap->ip->i_d.di_extsize))
-			extsz = mp->m_sb.sb_rextsize;
-		prod = extsz / mp->m_sb.sb_rextsize;
-		orig_off = ap->off;
-		orig_alen = ap->alen;
-		orig_end = orig_off + orig_alen;
-		/*
-		 * If the file offset is unaligned vs. the extent size
-		 * we need to align it.  This will be possible unless
-		 * the file was previously written with a kernel that didn't
-		 * perform this alignment.
-		 */
-		mod_off = do_mod(orig_off, extsz);
-		if (mod_off) {
-			ap->alen += mod_off;
-			ap->off -= mod_off;
-		}
-		/*
-		 * Same adjustment for the end of the requested area.
-		 */
-		if ((temp = (ap->alen % extsz)))
-			ap->alen += extsz - temp;
-		/*
-		 * If the previous block overlaps with this proposed allocation
-		 * then move the start forward without adjusting the length.
-		 */
-		prevo =
-			ap->prevp->br_startoff == NULLFILEOFF ?
-				0 :
-				(ap->prevp->br_startoff +
-				 ap->prevp->br_blockcount);
-		if (ap->off != orig_off && ap->off < prevo)
-			ap->off = prevo;
-		/*
-		 * If the next block overlaps with this proposed allocation
-		 * then move the start back without adjusting the length,
-		 * but not before offset 0.
-		 * This may of course make the start overlap previous block,
-		 * and if we hit the offset 0 limit then the next block
-		 * can still overlap too.
-		 */
-		nexto = (ap->eof || ap->gotp->br_startoff == NULLFILEOFF) ?
-			NULLFILEOFF : ap->gotp->br_startoff;
-		if (!ap->eof &&
-		    ap->off + ap->alen != orig_end &&
-		    ap->off + ap->alen > nexto)
-			ap->off = nexto > ap->alen ? nexto - ap->alen : 0;
-		/*
-		 * If we're now overlapping the next or previous extent that
-		 * means we can't fit an extsz piece in this hole.  Just move
-		 * the start forward to the first valid spot and set
-		 * the length so we hit the end.
-		 */
-		if ((ap->off != orig_off && ap->off < prevo) ||
-		    (ap->off + ap->alen != orig_end &&
-		     ap->off + ap->alen > nexto)) {
-			ap->off = prevo;
-			ap->alen = nexto - prevo;
-		}
-		/*
-		 * If the result isn't a multiple of rtextents we need to
-		 * remove blocks until it is.
-		 */
-		if ((temp = (ap->alen % mp->m_sb.sb_rextsize))) {
-			/*
-			 * We're not covering the original request, or
-			 * we won't be able to once we fix the length.
-			 */
-			if (orig_off < ap->off ||
-			    orig_end > ap->off + ap->alen ||
-			    ap->alen - temp < orig_alen)
-				return XFS_ERROR(EINVAL);
-			/*
-			 * Try to fix it by moving the start up.
-			 */
-			if (ap->off + temp <= orig_off) {
-				ap->alen -= temp;
-				ap->off += temp;
-			}
-			/*
-			 * Try to fix it by moving the end in.
-			 */
-			else if (ap->off + ap->alen - temp >= orig_end)
-				ap->alen -= temp;
-			/*
-			 * Set the start to the minimum then trim the length.
-			 */
-			else {
-				ap->alen -= orig_off - ap->off;
-				ap->off = orig_off;
-				ap->alen -= ap->alen % mp->m_sb.sb_rextsize;
-			}
-			/*
-			 * Result doesn't cover the request, fail it.
-			 */
-			if (orig_off < ap->off || orig_end > ap->off + ap->alen)
-				return XFS_ERROR(EINVAL);
-		}
+		error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp,
+						align, rt, ap->eof, 0,
+						ap->conv, &ap->off, &ap->alen);
+		if (error)
+			return error;
+		ASSERT(ap->alen);
 		ASSERT(ap->alen % mp->m_sb.sb_rextsize == 0);
+
 		/*
 		 * If the offset & length are not perfectly aligned
 		 * then kill prod, it will just get us in trouble.
 		 */
-		if (do_mod(ap->off, extsz) || ap->alen % extsz)
+		if (do_mod(ap->off, align) || ap->alen % align)
 			prod = 1;
 		/*
 		 * Set ralen to be the actual requested length in rtextents.
@@ -2326,15 +2389,24 @@
 			ap->rval = rtx * mp->m_sb.sb_rextsize;
 		} else
 			ap->rval = 0;
+	} else {
+		align = (ap->userdata && ap->ip->i_d.di_extsize &&
+			(ap->ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE)) ?
+			ap->ip->i_d.di_extsize : 0;
+		if (unlikely(align)) {
+			error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp,
+							align, rt,
+							ap->eof, 0, ap->conv,
+							&ap->off, &ap->alen);
+			ASSERT(!error);
+			ASSERT(ap->alen);
+		}
+		if (nullfb)
+			ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino);
+		else
+			ap->rval = ap->firstblock;
 	}
-#else
-	if (rt)
-		ap->rval = 0;
-#endif	/* __KERNEL__ */
-	else if (nullfb)
-		ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino);
-	else
-		ap->rval = ap->firstblock;
+
 	/*
 	 * If allocating at eof, and there's a previous real block,
 	 * try to use it's last block as our starting point.
@@ -2598,11 +2670,12 @@
 			args.total = ap->total;
 			args.minlen = ap->minlen;
 		}
-		if (ap->ip->i_d.di_extsize) {
+		if (unlikely(ap->userdata && ap->ip->i_d.di_extsize &&
+			    (ap->ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE))) {
 			args.prod = ap->ip->i_d.di_extsize;
 			if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod)))
 				args.mod = (xfs_extlen_t)(args.prod - args.mod);
-		} else if (mp->m_sb.sb_blocksize >= NBPP) {
+		} else if (unlikely(mp->m_sb.sb_blocksize >= NBPP)) {
 			args.prod = 1;
 			args.mod = 0;
 		} else {
@@ -3580,14 +3653,16 @@
 
 	ep = xfs_bmap_do_search_extents(base, lastx, nextents, bno, eofp,
 					  lastxp, gotp, prevp);
-	rt = ip->i_d.di_flags & XFS_DIFLAG_REALTIME;
-	if(!rt && !gotp->br_startblock && (*lastxp != NULLEXTNUM)) {
+	rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);
+	if (unlikely(!rt && !gotp->br_startblock && (*lastxp != NULLEXTNUM))) {
                 cmn_err(CE_PANIC,"Access to block zero: fs: <%s> inode: %lld "
 			"start_block : %llx start_off : %llx blkcnt : %llx "
 			"extent-state : %x \n",
-			(ip->i_mount)->m_fsname,(long long)ip->i_ino,
-			gotp->br_startblock, gotp->br_startoff,
-			gotp->br_blockcount,gotp->br_state);
+			(ip->i_mount)->m_fsname, (long long)ip->i_ino,
+			(unsigned long long)gotp->br_startblock,
+			(unsigned long long)gotp->br_startoff,
+			(unsigned long long)gotp->br_blockcount,
+			gotp->br_state);
         }
         return ep;
 }
@@ -3875,7 +3950,7 @@
 		ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size);
 		if (!ip->i_d.di_forkoff)
 			ip->i_d.di_forkoff = mp->m_attroffset >> 3;
-		else if (!(mp->m_flags & XFS_MOUNT_COMPAT_ATTR))
+		else if (mp->m_flags & XFS_MOUNT_ATTR2)
 			version = 2;
 		break;
 	default:
@@ -4023,13 +4098,13 @@
 	 */
 	if (whichfork == XFS_DATA_FORK) {
 		maxleafents = MAXEXTNUM;
-		sz = (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) ?
-			mp->m_attroffset : XFS_BMDR_SPACE_CALC(MINDBTPTRS);
+		sz = (mp->m_flags & XFS_MOUNT_ATTR2) ?
+			XFS_BMDR_SPACE_CALC(MINDBTPTRS) : mp->m_attroffset;
 	} else {
 		maxleafents = MAXAEXTNUM;
-		sz = (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) ?
-			mp->m_sb.sb_inodesize - mp->m_attroffset :
-			XFS_BMDR_SPACE_CALC(MINABTPTRS);
+		sz = (mp->m_flags & XFS_MOUNT_ATTR2) ?
+			XFS_BMDR_SPACE_CALC(MINABTPTRS) :
+			mp->m_sb.sb_inodesize - mp->m_attroffset;
 	}
 	maxrootrecs = (int)XFS_BTREE_BLOCK_MAXRECS(sz, xfs_bmdr, 0);
 	minleafrecs = mp->m_bmap_dmnr[0];
@@ -4418,8 +4493,8 @@
 		num_recs = be16_to_cpu(block->bb_numrecs);
 		if (unlikely(i + num_recs > room)) {
 			ASSERT(i + num_recs <= room);
-			xfs_fs_cmn_err(CE_WARN, ip->i_mount,
-				"corrupt dinode %Lu, (btree extents).  Unmount and run xfs_repair.",
+			xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
+				"corrupt dinode %Lu, (btree extents).",
 				(unsigned long long) ip->i_ino);
 			XFS_ERROR_REPORT("xfs_bmap_read_extents(1)",
 					 XFS_ERRLEVEL_LOW,
@@ -4590,6 +4665,7 @@
 	char		contig;		/* allocation must be one extent */
 	char		delay;		/* this request is for delayed alloc */
 	char		exact;		/* don't do all of wasdelayed extent */
+	char		convert;	/* unwritten extent I/O completion */
 	xfs_bmbt_rec_t	*ep;		/* extent list entry pointer */
 	int		error;		/* error return */
 	xfs_bmbt_irec_t	got;		/* current extent list record */
@@ -4643,7 +4719,7 @@
 	}
 	if (XFS_FORCED_SHUTDOWN(mp))
 		return XFS_ERROR(EIO);
-	rt = XFS_IS_REALTIME_INODE(ip);
+	rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);
 	ifp = XFS_IFORK_PTR(ip, whichfork);
 	ASSERT(ifp->if_ext_max ==
 	       XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
@@ -4654,6 +4730,7 @@
 	delay = (flags & XFS_BMAPI_DELAY) != 0;
 	trim = (flags & XFS_BMAPI_ENTIRE) == 0;
 	userdata = (flags & XFS_BMAPI_METADATA) == 0;
+	convert = (flags & XFS_BMAPI_CONVERT) != 0;
 	exact = (flags & XFS_BMAPI_EXACT) != 0;
 	rsvd = (flags & XFS_BMAPI_RSVBLOCKS) != 0;
 	contig = (flags & XFS_BMAPI_CONTIG) != 0;
@@ -4748,15 +4825,25 @@
 			}
 			minlen = contig ? alen : 1;
 			if (delay) {
-				xfs_extlen_t	extsz = 0;
+				xfs_extlen_t	extsz;
 
 				/* Figure out the extent size, adjust alen */
 				if (rt) {
 					if (!(extsz = ip->i_d.di_extsize))
 						extsz = mp->m_sb.sb_rextsize;
-					alen = roundup(alen, extsz);
-					extsz = alen / mp->m_sb.sb_rextsize;
+				} else {
+					extsz = ip->i_d.di_extsize;
 				}
+				if (extsz) {
+					error = xfs_bmap_extsize_align(mp,
+							&got, &prev, extsz,
+							rt, eof, delay, convert,
+							&aoff, &alen);
+					ASSERT(!error);
+				}
+
+				if (rt)
+					extsz = alen / mp->m_sb.sb_rextsize;
 
 				/*
 				 * Make a transaction-less quota reservation for
@@ -4785,32 +4872,33 @@
 					xfs_bmap_worst_indlen(ip, alen);
 				ASSERT(indlen > 0);
 
-				if (rt)
+				if (rt) {
 					error = xfs_mod_incore_sb(mp,
 							XFS_SBS_FREXTENTS,
 							-(extsz), rsvd);
-				else
+				} else {
 					error = xfs_mod_incore_sb(mp,
 							XFS_SBS_FDBLOCKS,
 							-(alen), rsvd);
+				}
 				if (!error) {
 					error = xfs_mod_incore_sb(mp,
 							XFS_SBS_FDBLOCKS,
 							-(indlen), rsvd);
-					if (error && rt) {
-						xfs_mod_incore_sb(ip->i_mount,
+					if (error && rt)
+						xfs_mod_incore_sb(mp,
 							XFS_SBS_FREXTENTS,
 							extsz, rsvd);
-					} else if (error) {
-						xfs_mod_incore_sb(ip->i_mount,
+					else if (error)
+						xfs_mod_incore_sb(mp,
 							XFS_SBS_FDBLOCKS,
 							alen, rsvd);
-					}
 				}
 
 				if (error) {
-					if (XFS_IS_QUOTA_ON(ip->i_mount))
+					if (XFS_IS_QUOTA_ON(mp))
 						/* unreserve the blocks now */
+						(void)
 						XFS_TRANS_UNRESERVE_QUOTA_NBLKS(
 							mp, NULL, ip,
 							(long)alen, 0, rt ?
@@ -4849,6 +4937,7 @@
 				bma.firstblock = *firstblock;
 				bma.alen = alen;
 				bma.off = aoff;
+				bma.conv = convert;
 				bma.wasdel = wasdelay;
 				bma.minlen = minlen;
 				bma.low = flist->xbf_low;
@@ -5270,8 +5359,7 @@
 		return 0;
 	}
 	XFS_STATS_INC(xs_blk_unmap);
-	isrt = (whichfork == XFS_DATA_FORK) &&
-	       (ip->i_d.di_flags & XFS_DIFLAG_REALTIME);
+	isrt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);
 	start = bno;
 	bno = start + len - 1;
 	ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
@@ -5443,7 +5531,7 @@
 		}
 		if (wasdel) {
 			ASSERT(STARTBLOCKVAL(del.br_startblock) > 0);
-			/* Update realtim/data freespace, unreserve quota */
+			/* Update realtime/data freespace, unreserve quota */
 			if (isrt) {
 				xfs_filblks_t rtexts;
 
@@ -5451,14 +5539,14 @@
 				do_div(rtexts, mp->m_sb.sb_rextsize);
 				xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS,
 						(int)rtexts, rsvd);
-				XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip,
-					-((long)del.br_blockcount), 0,
+				(void)XFS_TRANS_RESERVE_QUOTA_NBLKS(mp,
+					NULL, ip, -((long)del.br_blockcount), 0,
 					XFS_QMOPT_RES_RTBLKS);
 			} else {
 				xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS,
 						(int)del.br_blockcount, rsvd);
-				XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip,
-					-((long)del.br_blockcount), 0,
+				(void)XFS_TRANS_RESERVE_QUOTA_NBLKS(mp,
+					NULL, ip, -((long)del.br_blockcount), 0,
 					XFS_QMOPT_RES_REGBLKS);
 			}
 			ip->i_delayed_blks -= del.br_blockcount;
@@ -5652,7 +5740,9 @@
 		   ip->i_d.di_format != XFS_DINODE_FMT_LOCAL)
 		return XFS_ERROR(EINVAL);
 	if (whichfork == XFS_DATA_FORK) {
-		if (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC) {
+		if ((ip->i_d.di_extsize && (ip->i_d.di_flags &
+				(XFS_DIFLAG_REALTIME|XFS_DIFLAG_EXTSIZE))) ||
+		    ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC|XFS_DIFLAG_APPEND)){
 			prealloced = 1;
 			fixlen = XFS_MAXIOFFSET(mp);
 		} else {
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index 2e0717a..12cc63d 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -62,6 +62,10 @@
 #define	XFS_BMAPI_IGSTATE	0x200	/* Ignore state - */
 					/* combine contig. space */
 #define	XFS_BMAPI_CONTIG	0x400	/* must allocate only one extent */
+/*	XFS_BMAPI_DIRECT_IO	0x800	*/
+#define XFS_BMAPI_CONVERT	0x1000	/* unwritten extent conversion - */
+					/* need write cache flushing and no */
+					/* additional allocation alignments */
 
 #define	XFS_BMAPI_AFLAG(w)	xfs_bmapi_aflag(w)
 static inline int xfs_bmapi_aflag(int w)
@@ -101,7 +105,8 @@
 	char			wasdel;	/* replacing a delayed allocation */
 	char			userdata;/* set if is user data */
 	char			low;	/* low on space, using seq'l ags */
-	char			aeof;   /* allocated space at eof */
+	char			aeof;	/* allocated space at eof */
+	char			conv;	/* overwriting unwritten extents */
 } xfs_bmalloca_t;
 
 #ifdef __KERNEL__
diff --git a/fs/xfs/xfs_clnt.h b/fs/xfs/xfs_clnt.h
index 328a528..f57cc9a 100644
--- a/fs/xfs/xfs_clnt.h
+++ b/fs/xfs/xfs_clnt.h
@@ -57,7 +57,7 @@
 /*
  * XFS mount option flags -- args->flags1
  */
-#define	XFSMNT_COMPAT_ATTR	0x00000001	/* do not use ATTR2 format */
+#define	XFSMNT_ATTR2		0x00000001	/* allow ATTR2 EA format */
 #define	XFSMNT_WSYNC		0x00000002	/* safe mode nfs mount
 						 * compatible */
 #define	XFSMNT_INO64		0x00000004	/* move inode numbers up
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index 070259a..c6191d0 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -60,8 +60,6 @@
 	xfs_bstat_t	*sbp;
 	struct file	*fp = NULL, *tfp = NULL;
 	vnode_t		*vp, *tvp;
-	bhv_desc_t      *bdp, *tbdp;
-	vn_bhv_head_t   *bhp, *tbhp;
 	static uint	lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL;
 	int		ilf_fields, tilf_fields;
 	int		error = 0;
@@ -90,13 +88,10 @@
 		goto error0;
 	}
 
-	bhp = VN_BHV_HEAD(vp);
-	bdp = vn_bhv_lookup(bhp, &xfs_vnodeops);
-	if (bdp == NULL) {
+	ip = xfs_vtoi(vp);
+	if (ip == NULL) {
 		error = XFS_ERROR(EBADF);
 		goto error0;
-	} else {
-		ip = XFS_BHVTOI(bdp);
 	}
 
 	if (((tfp = fget((int)sxp->sx_fdtmp)) == NULL) ||
@@ -105,13 +100,10 @@
 		goto error0;
 	}
 
-	tbhp = VN_BHV_HEAD(tvp);
-	tbdp = vn_bhv_lookup(tbhp, &xfs_vnodeops);
-	if (tbdp == NULL) {
+	tip = xfs_vtoi(tvp);
+	if (tip == NULL) {
 		error = XFS_ERROR(EBADF);
 		goto error0;
-	} else {
-		tip = XFS_BHVTOI(tbdp);
 	}
 
 	if (ip->i_mount != tip->i_mount) {
diff --git a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h
index c5a0e53..79d0d9e 100644
--- a/fs/xfs/xfs_dinode.h
+++ b/fs/xfs/xfs_dinode.h
@@ -199,10 +199,16 @@
 
 #define XFS_DFORK_DSIZE(dip,mp) \
 	XFS_CFORK_DSIZE_DISK(&(dip)->di_core, mp)
+#define XFS_DFORK_DSIZE_HOST(dip,mp) \
+	XFS_CFORK_DSIZE(&(dip)->di_core, mp)
 #define XFS_DFORK_ASIZE(dip,mp) \
 	XFS_CFORK_ASIZE_DISK(&(dip)->di_core, mp)
+#define XFS_DFORK_ASIZE_HOST(dip,mp) \
+	XFS_CFORK_ASIZE(&(dip)->di_core, mp)
 #define	XFS_DFORK_SIZE(dip,mp,w) \
 	XFS_CFORK_SIZE_DISK(&(dip)->di_core, mp, w)
+#define	XFS_DFORK_SIZE_HOST(dip,mp,w) \
+	XFS_CFORK_SIZE(&(dip)->di_core, mp, w)
 
 #define	XFS_DFORK_Q(dip)                    XFS_CFORK_Q_DISK(&(dip)->di_core)
 #define	XFS_DFORK_BOFF(dip)		    XFS_CFORK_BOFF_DISK(&(dip)->di_core)
@@ -216,6 +222,7 @@
 #define	XFS_CFORK_FMT_SET(dcp,w,n) \
 	((w) == XFS_DATA_FORK ? \
 		((dcp)->di_format = (n)) : ((dcp)->di_aformat = (n)))
+#define	XFS_DFORK_FORMAT(dip,w) XFS_CFORK_FORMAT(&(dip)->di_core, w)
 
 #define	XFS_CFORK_NEXTENTS_DISK(dcp,w) \
 	((w) == XFS_DATA_FORK ? \
@@ -223,13 +230,13 @@
 	 	INT_GET((dcp)->di_anextents, ARCH_CONVERT))
 #define XFS_CFORK_NEXTENTS(dcp,w) \
 	((w) == XFS_DATA_FORK ? (dcp)->di_nextents : (dcp)->di_anextents)
+#define	XFS_DFORK_NEXTENTS(dip,w) XFS_CFORK_NEXTENTS_DISK(&(dip)->di_core, w)
+#define	XFS_DFORK_NEXTENTS_HOST(dip,w) XFS_CFORK_NEXTENTS(&(dip)->di_core, w)
 
 #define	XFS_CFORK_NEXT_SET(dcp,w,n) \
 	((w) == XFS_DATA_FORK ? \
 		((dcp)->di_nextents = (n)) : ((dcp)->di_anextents = (n)))
 
-#define	XFS_DFORK_NEXTENTS(dip,w) XFS_CFORK_NEXTENTS_DISK(&(dip)->di_core, w)
-
 #define	XFS_BUF_TO_DINODE(bp)	((xfs_dinode_t *)XFS_BUF_PTR(bp))
 
 /*
@@ -246,8 +253,10 @@
 #define XFS_DIFLAG_NOATIME_BIT   6	/* do not update atime */
 #define XFS_DIFLAG_NODUMP_BIT    7	/* do not dump */
 #define XFS_DIFLAG_RTINHERIT_BIT 8	/* create with realtime bit set */
-#define XFS_DIFLAG_PROJINHERIT_BIT  9	/* create with parents projid */
-#define XFS_DIFLAG_NOSYMLINKS_BIT  10	/* disallow symlink creation */
+#define XFS_DIFLAG_PROJINHERIT_BIT   9	/* create with parents projid */
+#define XFS_DIFLAG_NOSYMLINKS_BIT   10	/* disallow symlink creation */
+#define XFS_DIFLAG_EXTSIZE_BIT      11	/* inode extent size allocator hint */
+#define XFS_DIFLAG_EXTSZINHERIT_BIT 12	/* inherit inode extent size */
 #define XFS_DIFLAG_REALTIME      (1 << XFS_DIFLAG_REALTIME_BIT)
 #define XFS_DIFLAG_PREALLOC      (1 << XFS_DIFLAG_PREALLOC_BIT)
 #define XFS_DIFLAG_NEWRTBM       (1 << XFS_DIFLAG_NEWRTBM_BIT)
@@ -259,11 +268,14 @@
 #define XFS_DIFLAG_RTINHERIT     (1 << XFS_DIFLAG_RTINHERIT_BIT)
 #define XFS_DIFLAG_PROJINHERIT   (1 << XFS_DIFLAG_PROJINHERIT_BIT)
 #define XFS_DIFLAG_NOSYMLINKS    (1 << XFS_DIFLAG_NOSYMLINKS_BIT)
+#define XFS_DIFLAG_EXTSIZE       (1 << XFS_DIFLAG_EXTSIZE_BIT)
+#define XFS_DIFLAG_EXTSZINHERIT  (1 << XFS_DIFLAG_EXTSZINHERIT_BIT)
 
 #define XFS_DIFLAG_ANY \
 	(XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \
 	 XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \
 	 XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \
-	 XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS)
+	 XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \
+	 XFS_DIFLAG_EXTSZINHERIT)
 
 #endif	/* __XFS_DINODE_H__ */
diff --git a/fs/xfs/xfs_dir.c b/fs/xfs/xfs_dir.c
index 3dd3039..bb87d2a 100644
--- a/fs/xfs/xfs_dir.c
+++ b/fs/xfs/xfs_dir.c
@@ -176,7 +176,7 @@
 	uint shortcount, leafcount, count;
 
 	mp->m_dirversion = 1;
-	if (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) {
+	if (!(mp->m_flags & XFS_MOUNT_ATTR2)) {
 		shortcount = (mp->m_attroffset -
 				(uint)sizeof(xfs_dir_sf_hdr_t)) /
 				 (uint)sizeof(xfs_dir_sf_entry_t);
diff --git a/fs/xfs/xfs_dir.h b/fs/xfs/xfs_dir.h
index 488defe..8cc8afb 100644
--- a/fs/xfs/xfs_dir.h
+++ b/fs/xfs/xfs_dir.h
@@ -135,6 +135,8 @@
 	((mp)->m_dirops.xd_shortform_to_single(args))
 
 #define	XFS_DIR_IS_V1(mp)	((mp)->m_dirversion == 1)
+#define	XFS_DIR_IS_V2(mp)	((mp)->m_dirversion == 2)
 extern xfs_dirops_t xfsv1_dirops;
+extern xfs_dirops_t xfsv2_dirops;
 
 #endif	/* __XFS_DIR_H__ */
diff --git a/fs/xfs/xfs_dir2.h b/fs/xfs/xfs_dir2.h
index 7e24ffe..3158f5d 100644
--- a/fs/xfs/xfs_dir2.h
+++ b/fs/xfs/xfs_dir2.h
@@ -72,9 +72,6 @@
 	struct uio	*uio;		/* uio control structure */
 } xfs_dir2_put_args_t;
 
-#define	XFS_DIR_IS_V2(mp)	((mp)->m_dirversion == 2)
-extern xfs_dirops_t	xfsv2_dirops;
-
 /*
  * Other interfaces used by the rest of the dir v2 code.
  */
diff --git a/fs/xfs/xfs_dir_leaf.h b/fs/xfs/xfs_dir_leaf.h
index ab6b09e..eb8cd9a 100644
--- a/fs/xfs/xfs_dir_leaf.h
+++ b/fs/xfs/xfs_dir_leaf.h
@@ -67,34 +67,38 @@
  */
 #define XFS_DIR_LEAF_MAPSIZE	3	/* how many freespace slots */
 
+typedef struct xfs_dir_leaf_map {	/* RLE map of free bytes */
+	__uint16_t	base;	 	/* base of free region */
+	__uint16_t	size; 		/* run length of free region */
+} xfs_dir_leaf_map_t;
+
+typedef struct xfs_dir_leaf_hdr {	/* constant-structure header block */
+	xfs_da_blkinfo_t info;		/* block type, links, etc. */
+	__uint16_t	count;		/* count of active leaf_entry's */
+	__uint16_t	namebytes;	/* num bytes of name strings stored */
+	__uint16_t	firstused;	/* first used byte in name area */
+	__uint8_t	holes;		/* != 0 if blk needs compaction */
+	__uint8_t	pad1;
+	xfs_dir_leaf_map_t freemap[XFS_DIR_LEAF_MAPSIZE];
+} xfs_dir_leaf_hdr_t;
+
+typedef struct xfs_dir_leaf_entry {	/* sorted on key, not name */
+	xfs_dahash_t	hashval;	/* hash value of name */
+	__uint16_t	nameidx;	/* index into buffer of name */
+	__uint8_t	namelen;	/* length of name string */
+	__uint8_t	pad2;
+} xfs_dir_leaf_entry_t;
+
+typedef struct xfs_dir_leaf_name {
+	xfs_dir_ino_t	inumber;	/* inode number for this key */
+	__uint8_t	name[1];	/* name string itself */
+} xfs_dir_leaf_name_t;
+
 typedef struct xfs_dir_leafblock {
-	struct xfs_dir_leaf_hdr {	/* constant-structure header block */
-		xfs_da_blkinfo_t info;	/* block type, links, etc. */
-		__uint16_t count;	/* count of active leaf_entry's */
-		__uint16_t namebytes;	/* num bytes of name strings stored */
-		__uint16_t firstused;	/* first used byte in name area */
-		__uint8_t  holes;	/* != 0 if blk needs compaction */
-		__uint8_t  pad1;
-		struct xfs_dir_leaf_map {/* RLE map of free bytes */
-			__uint16_t base; /* base of free region */
-			__uint16_t size; /* run length of free region */
-		} freemap[XFS_DIR_LEAF_MAPSIZE]; /* N largest free regions */
-	} hdr;
-	struct xfs_dir_leaf_entry {	/* sorted on key, not name */
-		xfs_dahash_t hashval;	/* hash value of name */
-		__uint16_t nameidx;	/* index into buffer of name */
-		__uint8_t namelen;	/* length of name string */
-		__uint8_t pad2;
-	} entries[1];			/* var sized array */
-	struct xfs_dir_leaf_name {
-		xfs_dir_ino_t inumber;	/* inode number for this key */
-		__uint8_t name[1];	/* name string itself */
-	} namelist[1];			/* grows from bottom of buf */
+	xfs_dir_leaf_hdr_t	hdr;	/* constant-structure header block */
+	xfs_dir_leaf_entry_t	entries[1];	/* var sized array */
+	xfs_dir_leaf_name_t	namelist[1];	/* grows from bottom of buf */
 } xfs_dir_leafblock_t;
-typedef struct xfs_dir_leaf_hdr xfs_dir_leaf_hdr_t;
-typedef struct xfs_dir_leaf_map xfs_dir_leaf_map_t;
-typedef struct xfs_dir_leaf_entry xfs_dir_leaf_entry_t;
-typedef struct xfs_dir_leaf_name xfs_dir_leaf_name_t;
 
 /*
  * Length of name for which a 512-byte block filesystem
@@ -126,11 +130,10 @@
 #define	XFS_PUT_COOKIE(c,mp,bno,entry,hash)	\
 	((c).s.be = XFS_DA_MAKE_BNOENTRY(mp, bno, entry), (c).s.h = (hash))
 
-typedef struct xfs_dir_put_args
-{
+typedef struct xfs_dir_put_args {
 	xfs_dircook_t	cook;		/* cookie of (next) entry */
 	xfs_intino_t	ino;		/* inode number */
-	struct xfs_dirent	*dbp;		/* buffer pointer */
+	struct xfs_dirent *dbp;		/* buffer pointer */
 	char		*name;		/* directory entry name */
 	int		namelen;	/* length of name */
 	int		done;		/* output: set if value was stored */
@@ -138,7 +141,8 @@
 	struct uio	*uio;		/* uio control structure */
 } xfs_dir_put_args_t;
 
-#define XFS_DIR_LEAF_ENTSIZE_BYNAME(len)	xfs_dir_leaf_entsize_byname(len)
+#define XFS_DIR_LEAF_ENTSIZE_BYNAME(len)	\
+	xfs_dir_leaf_entsize_byname(len)
 static inline int xfs_dir_leaf_entsize_byname(int len)
 {
 	return (uint)sizeof(xfs_dir_leaf_name_t)-1 + len;
diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c
index d7b6b5d..2a21c50 100644
--- a/fs/xfs/xfs_error.c
+++ b/fs/xfs/xfs_error.c
@@ -54,7 +54,6 @@
 		if (e != xfs_etrap[i])
 			continue;
 		cmn_err(CE_NOTE, "xfs_error_trap: error %d", e);
-		debug_stop_all_cpus((void *)-1LL);
 		BUG();
 		break;
 	}
diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h
index 06d8a84..26b8e70 100644
--- a/fs/xfs/xfs_error.h
+++ b/fs/xfs/xfs_error.h
@@ -18,9 +18,6 @@
 #ifndef	__XFS_ERROR_H__
 #define	__XFS_ERROR_H__
 
-#define prdev(fmt,targ,args...) \
-	printk("XFS: device %s - " fmt "\n", XFS_BUFTARG_NAME(targ), ## args)
-
 #define XFS_ERECOVER	1	/* Failure to recover log */
 #define XFS_ELOGSTAT	2	/* Failure to stat log in user space */
 #define XFS_ENOLOGSPACE	3	/* Reservation too large */
@@ -182,8 +179,11 @@
 struct xfs_mount;
 /* PRINTFLIKE4 */
 extern void xfs_cmn_err(int panic_tag, int level, struct xfs_mount *mp,
-			    char *fmt, ...);
+			char *fmt, ...);
 /* PRINTFLIKE3 */
 extern void xfs_fs_cmn_err(int level, struct xfs_mount *mp, char *fmt, ...);
 
+#define xfs_fs_repair_cmn_err(level, mp, fmt, args...) \
+	xfs_fs_cmn_err(level, mp, fmt "  Unmount and run xfs_repair.", ## args)
+
 #endif	/* __XFS_ERROR_H__ */
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index ba096f8..14010f1 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -3,15 +3,15 @@
  * All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
  *
  * This program is distributed in the hope that it would be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
+ * You should have received a copy of the GNU Lesser General Public License
  * along with this program; if not, write the Free Software Foundation,
  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
@@ -65,6 +65,8 @@
 #define XFS_XFLAG_RTINHERIT	0x00000100	/* create with rt bit set */
 #define XFS_XFLAG_PROJINHERIT	0x00000200	/* create with parents projid */
 #define XFS_XFLAG_NOSYMLINKS	0x00000400	/* disallow symlink creation */
+#define XFS_XFLAG_EXTSIZE	0x00000800	/* extent size allocator hint */
+#define XFS_XFLAG_EXTSZINHERIT	0x00001000	/* inherit inode extent size */
 #define XFS_XFLAG_HASATTR	0x80000000	/* no DIFLAG for this	*/
 
 /*
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index d1236d6..163031c 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -540,6 +540,32 @@
 	return(0);
 }
 
+void
+xfs_fs_log_dummy(xfs_mount_t *mp)
+{
+	xfs_trans_t *tp;
+	xfs_inode_t *ip;
+
+
+	tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1);
+	atomic_inc(&mp->m_active_trans);
+	if (xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0)) {
+		xfs_trans_cancel(tp, 0);
+		return;
+	}
+
+	ip = mp->m_rootip;
+	xfs_ilock(ip, XFS_ILOCK_EXCL);
+
+	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
+	xfs_trans_ihold(tp, ip);
+	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+	xfs_trans_set_sync(tp);
+	xfs_trans_commit(tp, 0, NULL);
+
+	xfs_iunlock(ip, XFS_ILOCK_EXCL);
+}
+
 int
 xfs_fs_goingdown(
 	xfs_mount_t	*mp,
diff --git a/fs/xfs/xfs_fsops.h b/fs/xfs/xfs_fsops.h
index f32713f..300d0c9 100644
--- a/fs/xfs/xfs_fsops.h
+++ b/fs/xfs/xfs_fsops.h
@@ -25,5 +25,6 @@
 extern int xfs_reserve_blocks(xfs_mount_t *mp, __uint64_t *inval,
 				xfs_fsop_resblks_t *outval);
 extern int xfs_fs_goingdown(xfs_mount_t *mp, __uint32_t inflags);
+extern void xfs_fs_log_dummy(xfs_mount_t *mp);
 
 #endif	/* __XFS_FSOPS_H__ */
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index fc19eed..8e380a1 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -493,7 +493,6 @@
 
 retry:
 	if ((inode = iget_locked(XFS_MTOVFS(mp)->vfs_super, ino))) {
-		bhv_desc_t	*bdp;
 		xfs_inode_t	*ip;
 
 		vp = LINVFS_GET_VP(inode);
@@ -517,14 +516,12 @@
 			 * to wait for the inode to go away.
 			 */
 			if (is_bad_inode(inode) ||
-			    ((bdp = vn_bhv_lookup(VN_BHV_HEAD(vp),
-						  &xfs_vnodeops)) == NULL)) {
+			    ((ip = xfs_vtoi(vp)) == NULL)) {
 				iput(inode);
 				delay(1);
 				goto retry;
 			}
 
-			ip = XFS_BHVTOI(bdp);
 			if (lock_flags != 0)
 				xfs_ilock(ip, lock_flags);
 			XFS_STATS_INC(xs_ig_found);
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index df0d457..1d7f5a7 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -404,9 +404,8 @@
 	    INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) +
 		INT_GET(dip->di_core.di_anextents, ARCH_CONVERT) >
 	    INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT))) {
-		xfs_fs_cmn_err(CE_WARN, ip->i_mount,
-			"corrupt dinode %Lu, extent total = %d, nblocks = %Lu."
-			"  Unmount and run xfs_repair.",
+		xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
+			"corrupt dinode %Lu, extent total = %d, nblocks = %Lu.",
 			(unsigned long long)ip->i_ino,
 			(int)(INT_GET(dip->di_core.di_nextents, ARCH_CONVERT)
 			    + INT_GET(dip->di_core.di_anextents, ARCH_CONVERT)),
@@ -418,9 +417,8 @@
 	}
 
 	if (unlikely(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT) > ip->i_mount->m_sb.sb_inodesize)) {
-		xfs_fs_cmn_err(CE_WARN, ip->i_mount,
-			"corrupt dinode %Lu, forkoff = 0x%x."
-			"  Unmount and run xfs_repair.",
+		xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
+			"corrupt dinode %Lu, forkoff = 0x%x.",
 			(unsigned long long)ip->i_ino,
 			(int)(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT)));
 		XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW,
@@ -451,8 +449,9 @@
 			 * no local regular files yet
 			 */
 			if (unlikely((INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & S_IFMT) == S_IFREG)) {
-				xfs_fs_cmn_err(CE_WARN, ip->i_mount,
-					"corrupt inode (local format for regular file) %Lu.  Unmount and run xfs_repair.",
+				xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
+					"corrupt inode %Lu "
+					"(local format for regular file).",
 					(unsigned long long) ip->i_ino);
 				XFS_CORRUPTION_ERROR("xfs_iformat(4)",
 						     XFS_ERRLEVEL_LOW,
@@ -462,8 +461,9 @@
 
 			di_size = INT_GET(dip->di_core.di_size, ARCH_CONVERT);
 			if (unlikely(di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) {
-				xfs_fs_cmn_err(CE_WARN, ip->i_mount,
-					"corrupt inode %Lu (bad size %Ld for local inode).  Unmount and run xfs_repair.",
+				xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
+					"corrupt inode %Lu "
+					"(bad size %Ld for local inode).",
 					(unsigned long long) ip->i_ino,
 					(long long) di_size);
 				XFS_CORRUPTION_ERROR("xfs_iformat(5)",
@@ -551,8 +551,9 @@
 	 * kmem_alloc() or memcpy() below.
 	 */
 	if (unlikely(size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) {
-		xfs_fs_cmn_err(CE_WARN, ip->i_mount,
-			"corrupt inode %Lu (bad size %d for local fork, size = %d).  Unmount and run xfs_repair.",
+		xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
+			"corrupt inode %Lu "
+			"(bad size %d for local fork, size = %d).",
 			(unsigned long long) ip->i_ino, size,
 			XFS_DFORK_SIZE(dip, ip->i_mount, whichfork));
 		XFS_CORRUPTION_ERROR("xfs_iformat_local", XFS_ERRLEVEL_LOW,
@@ -610,8 +611,8 @@
 	 * kmem_alloc() or memcpy() below.
 	 */
 	if (unlikely(size < 0 || size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) {
-		xfs_fs_cmn_err(CE_WARN, ip->i_mount,
-			"corrupt inode %Lu ((a)extents = %d).  Unmount and run xfs_repair.",
+		xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
+			"corrupt inode %Lu ((a)extents = %d).",
 			(unsigned long long) ip->i_ino, nex);
 		XFS_CORRUPTION_ERROR("xfs_iformat_extents(1)", XFS_ERRLEVEL_LOW,
 				     ip->i_mount, dip);
@@ -692,8 +693,8 @@
 	    || XFS_BMDR_SPACE_CALC(nrecs) >
 			XFS_DFORK_SIZE(dip, ip->i_mount, whichfork)
 	    || XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks)) {
-		xfs_fs_cmn_err(CE_WARN, ip->i_mount,
-			"corrupt inode %Lu (btree).  Unmount and run xfs_repair.",
+		xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
+			"corrupt inode %Lu (btree).",
 			(unsigned long long) ip->i_ino);
 		XFS_ERROR_REPORT("xfs_iformat_btree", XFS_ERRLEVEL_LOW,
 				 ip->i_mount);
@@ -809,6 +810,10 @@
 			flags |= XFS_XFLAG_PROJINHERIT;
 		if (di_flags & XFS_DIFLAG_NOSYMLINKS)
 			flags |= XFS_XFLAG_NOSYMLINKS;
+		if (di_flags & XFS_DIFLAG_EXTSIZE)
+			flags |= XFS_XFLAG_EXTSIZE;
+		if (di_flags & XFS_DIFLAG_EXTSZINHERIT)
+			flags |= XFS_XFLAG_EXTSZINHERIT;
 	}
 
 	return flags;
@@ -1192,11 +1197,19 @@
 			if ((mode & S_IFMT) == S_IFDIR) {
 				if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT)
 					di_flags |= XFS_DIFLAG_RTINHERIT;
-			} else {
+				if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) {
+					di_flags |= XFS_DIFLAG_EXTSZINHERIT;
+					ip->i_d.di_extsize = pip->i_d.di_extsize;
+				}
+			} else if ((mode & S_IFMT) == S_IFREG) {
 				if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) {
 					di_flags |= XFS_DIFLAG_REALTIME;
 					ip->i_iocore.io_flags |= XFS_IOCORE_RT;
 				}
+				if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) {
+					di_flags |= XFS_DIFLAG_EXTSIZE;
+					ip->i_d.di_extsize = pip->i_d.di_extsize;
+				}
 			}
 			if ((pip->i_d.di_flags & XFS_DIFLAG_NOATIME) &&
 			    xfs_inherit_noatime)
@@ -1262,7 +1275,7 @@
 	if ((ip->i_d.di_mode & S_IFMT) != S_IFREG)
 		return;
 
-	if ( ip->i_d.di_flags & XFS_DIFLAG_REALTIME )
+	if (ip->i_d.di_flags & (XFS_DIFLAG_REALTIME | XFS_DIFLAG_EXTSIZE))
 		return;
 
 	nimaps = 2;
@@ -1765,22 +1778,19 @@
 	xfs_fsize_t	new_size,
 	cred_t		*credp)
 {
-	xfs_fsize_t	isize;
 	int		error;
 
 	ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0);
 	ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0);
 	ASSERT(new_size > ip->i_d.di_size);
 
-	error = 0;
-	isize = ip->i_d.di_size;
 	/*
 	 * Zero any pages that may have been created by
 	 * xfs_write_file() beyond the end of the file
 	 * and any blocks between the old and new file sizes.
 	 */
-	error = xfs_zero_eof(XFS_ITOV(ip), &ip->i_iocore, new_size, isize,
-				new_size);
+	error = xfs_zero_eof(XFS_ITOV(ip), &ip->i_iocore, new_size,
+			     ip->i_d.di_size, new_size);
 	return error;
 }
 
@@ -3355,6 +3365,11 @@
 	ip->i_update_core = 0;
 	SYNCHRONIZE();
 
+	/*
+	 * Make sure to get the latest atime from the Linux inode.
+	 */
+	xfs_synchronize_atime(ip);
+
 	if (XFS_TEST_ERROR(INT_GET(dip->di_core.di_magic,ARCH_CONVERT) != XFS_DINODE_MAGIC,
 			       mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) {
 		xfs_cmn_err(XFS_PTAG_IFLUSH, CE_ALERT, mp,
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 124d30e..1cfbcf1 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -436,6 +436,10 @@
 xfs_fsize_t	xfs_file_last_byte(xfs_inode_t *);
 void		xfs_lock_inodes(xfs_inode_t **, int, int, uint);
 
+xfs_inode_t	*xfs_vtoi(struct vnode *vp);
+
+void		xfs_synchronize_atime(xfs_inode_t *);
+
 #define xfs_ipincount(ip)	((unsigned int) atomic_read(&ip->i_pincount))
 
 #ifdef DEBUG
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index 7f3363c..36aa1fc 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -271,6 +271,11 @@
 	if (ip->i_update_size)
 		ip->i_update_size = 0;
 
+	/*
+	 * Make sure to get the latest atime from the Linux inode.
+	 */
+	xfs_synchronize_atime(ip);
+
 	vecp->i_addr = (xfs_caddr_t)&ip->i_d;
 	vecp->i_len  = sizeof(xfs_dinode_core_t);
 	XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_ICORE);
@@ -603,7 +608,7 @@
 		if (iip->ili_pushbuf_flag == 0) {
 			iip->ili_pushbuf_flag = 1;
 #ifdef DEBUG
-			iip->ili_push_owner = get_thread_id();
+			iip->ili_push_owner = current_pid();
 #endif
 			/*
 			 * Inode is left locked in shared mode.
@@ -782,7 +787,7 @@
 	 * trying to duplicate our effort.
 	 */
 	ASSERT(iip->ili_pushbuf_flag != 0);
-	ASSERT(iip->ili_push_owner == get_thread_id());
+	ASSERT(iip->ili_push_owner == current_pid());
 
 	/*
 	 * If flushlock isn't locked anymore, chances are that the
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index ca7afc8..788917f3 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -262,7 +262,7 @@
 	case BMAPI_WRITE:
 		/* If we found an extent, return it */
 		if (nimaps &&
-		    (imap.br_startblock != HOLESTARTBLOCK) && 
+		    (imap.br_startblock != HOLESTARTBLOCK) &&
 		    (imap.br_startblock != DELAYSTARTBLOCK)) {
 			xfs_iomap_map_trace(XFS_IOMAP_WRITE_MAP, io,
 					offset, count, iomapp, &imap, flags);
@@ -317,6 +317,58 @@
 }
 
 STATIC int
+xfs_iomap_eof_align_last_fsb(
+	xfs_mount_t	*mp,
+	xfs_iocore_t	*io,
+	xfs_fsize_t	isize,
+	xfs_extlen_t	extsize,
+	xfs_fileoff_t	*last_fsb)
+{
+	xfs_fileoff_t	new_last_fsb = 0;
+	xfs_extlen_t	align;
+	int		eof, error;
+
+	if (io->io_flags & XFS_IOCORE_RT)
+		;
+	/*
+	 * If mounted with the "-o swalloc" option, roundup the allocation
+	 * request to a stripe width boundary if the file size is >=
+	 * stripe width and we are allocating past the allocation eof.
+	 */
+	else if (mp->m_swidth && (mp->m_flags & XFS_MOUNT_SWALLOC) &&
+	        (isize >= XFS_FSB_TO_B(mp, mp->m_swidth)))
+		new_last_fsb = roundup_64(*last_fsb, mp->m_swidth);
+	/*
+	 * Roundup the allocation request to a stripe unit (m_dalign) boundary
+	 * if the file size is >= stripe unit size, and we are allocating past
+	 * the allocation eof.
+	 */
+	else if (mp->m_dalign && (isize >= XFS_FSB_TO_B(mp, mp->m_dalign)))
+		new_last_fsb = roundup_64(*last_fsb, mp->m_dalign);
+
+	/*
+	 * Always round up the allocation request to an extent boundary
+	 * (when file on a real-time subvolume or has di_extsize hint).
+	 */
+	if (extsize) {
+		if (new_last_fsb)
+			align = roundup_64(new_last_fsb, extsize);
+		else
+			align = extsize;
+		new_last_fsb = roundup_64(*last_fsb, align);
+	}
+
+	if (new_last_fsb) {
+		error = XFS_BMAP_EOF(mp, io, new_last_fsb, XFS_DATA_FORK, &eof);
+		if (error)
+			return error;
+		if (eof)
+			*last_fsb = new_last_fsb;
+	}
+	return 0;
+}
+
+STATIC int
 xfs_flush_space(
 	xfs_inode_t	*ip,
 	int		*fsynced,
@@ -362,19 +414,20 @@
 	xfs_iocore_t	*io = &ip->i_iocore;
 	xfs_fileoff_t	offset_fsb;
 	xfs_fileoff_t	last_fsb;
-	xfs_filblks_t	count_fsb;
+	xfs_filblks_t	count_fsb, resaligned;
 	xfs_fsblock_t	firstfsb;
+	xfs_extlen_t	extsz, temp;
+	xfs_fsize_t	isize;
 	int		nimaps;
-	int		error;
 	int		bmapi_flag;
 	int		quota_flag;
 	int		rt;
 	xfs_trans_t	*tp;
 	xfs_bmbt_irec_t imap;
 	xfs_bmap_free_t free_list;
-	xfs_filblks_t	qblocks, resblks;
+	uint		qblocks, resblks, resrtextents;
 	int		committed;
-	int		resrtextents;
+	int		error;
 
 	/*
 	 * Make sure that the dquots are there. This doesn't hold
@@ -384,38 +437,53 @@
 	if (error)
 		return XFS_ERROR(error);
 
-	offset_fsb = XFS_B_TO_FSBT(mp, offset);
-	last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count)));
-	count_fsb = last_fsb - offset_fsb;
-	if (found && (ret_imap->br_startblock == HOLESTARTBLOCK)) {
-		xfs_fileoff_t	map_last_fsb;
-
-		map_last_fsb = ret_imap->br_blockcount + ret_imap->br_startoff;
-		if (map_last_fsb < last_fsb) {
-			last_fsb = map_last_fsb;
-			count_fsb = last_fsb - offset_fsb;
-		}
-		ASSERT(count_fsb > 0);
-	}
-
-	/*
-	 * Determine if reserving space on the data or realtime partition.
-	 */
-	if ((rt = XFS_IS_REALTIME_INODE(ip))) {
-		xfs_extlen_t	extsz;
-
+	rt = XFS_IS_REALTIME_INODE(ip);
+	if (unlikely(rt)) {
 		if (!(extsz = ip->i_d.di_extsize))
 			extsz = mp->m_sb.sb_rextsize;
-		resrtextents = qblocks = (count_fsb + extsz - 1);
-		do_div(resrtextents, mp->m_sb.sb_rextsize);
-		resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
-		quota_flag = XFS_QMOPT_RES_RTBLKS;
 	} else {
-		resrtextents = 0;
-		resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, count_fsb);
-		quota_flag = XFS_QMOPT_RES_REGBLKS;
+		extsz = ip->i_d.di_extsize;
 	}
 
+	isize = ip->i_d.di_size;
+	if (io->io_new_size > isize)
+		isize = io->io_new_size;
+
+  	offset_fsb = XFS_B_TO_FSBT(mp, offset);
+  	last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count)));
+	if ((offset + count) > isize) {
+		error = xfs_iomap_eof_align_last_fsb(mp, io, isize, extsz,
+							&last_fsb);
+		if (error)
+			goto error_out;
+	} else {
+		if (found && (ret_imap->br_startblock == HOLESTARTBLOCK))
+			last_fsb = MIN(last_fsb, (xfs_fileoff_t)
+					ret_imap->br_blockcount +
+					ret_imap->br_startoff);
+	}
+	count_fsb = last_fsb - offset_fsb;
+	ASSERT(count_fsb > 0);
+
+	resaligned = count_fsb;
+	if (unlikely(extsz)) {
+		if ((temp = do_mod(offset_fsb, extsz)))
+			resaligned += temp;
+		if ((temp = do_mod(resaligned, extsz)))
+			resaligned += extsz - temp;
+	}
+
+	if (unlikely(rt)) {
+		resrtextents = qblocks = resaligned;
+		resrtextents /= mp->m_sb.sb_rextsize;
+  		resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
+  		quota_flag = XFS_QMOPT_RES_RTBLKS;
+  	} else {
+  		resrtextents = 0;
+		resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, resaligned);
+  		quota_flag = XFS_QMOPT_RES_REGBLKS;
+  	}
+
 	/*
 	 * Allocate and setup the transaction
 	 */
@@ -425,7 +493,6 @@
 			XFS_WRITE_LOG_RES(mp), resrtextents,
 			XFS_TRANS_PERM_LOG_RES,
 			XFS_WRITE_LOG_COUNT);
-
 	/*
 	 * Check for running out of space, note: need lock to return
 	 */
@@ -435,20 +502,20 @@
 	if (error)
 		goto error_out;
 
-	if (XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag)) {
-		error = (EDQUOT);
+	error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip,
+					      qblocks, 0, quota_flag);
+	if (error)
 		goto error1;
-	}
 
-	bmapi_flag = XFS_BMAPI_WRITE;
 	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
 	xfs_trans_ihold(tp, ip);
 
-	if (!(flags & BMAPI_MMAP) && (offset < ip->i_d.di_size || rt))
+	bmapi_flag = XFS_BMAPI_WRITE;
+	if ((flags & BMAPI_DIRECT) && (offset < ip->i_d.di_size || extsz))
 		bmapi_flag |= XFS_BMAPI_PREALLOC;
 
 	/*
-	 * Issue the bmapi() call to allocate the blocks
+	 * Issue the xfs_bmapi() call to allocate the blocks
 	 */
 	XFS_BMAP_INIT(&free_list, &firstfsb);
 	nimaps = 1;
@@ -483,8 +550,10 @@
                         "extent-state : %x \n",
                         (ip->i_mount)->m_fsname,
                         (long long)ip->i_ino,
-                        ret_imap->br_startblock, ret_imap->br_startoff,
-                        ret_imap->br_blockcount,ret_imap->br_state);
+                        (unsigned long long)ret_imap->br_startblock,
+			(unsigned long long)ret_imap->br_startoff,
+                        (unsigned long long)ret_imap->br_blockcount,
+			ret_imap->br_state);
         }
 	return 0;
 
@@ -500,6 +569,63 @@
 	return XFS_ERROR(error);
 }
 
+/*
+ * If the caller is doing a write at the end of the file,
+ * then extend the allocation out to the file system's write
+ * iosize.  We clean up any extra space left over when the
+ * file is closed in xfs_inactive().
+ *
+ * For sync writes, we are flushing delayed allocate space to
+ * try to make additional space available for allocation near
+ * the filesystem full boundary - preallocation hurts in that
+ * situation, of course.
+ */
+STATIC int
+xfs_iomap_eof_want_preallocate(
+	xfs_mount_t	*mp,
+	xfs_iocore_t	*io,
+	xfs_fsize_t	isize,
+	xfs_off_t	offset,
+	size_t		count,
+	int		ioflag,
+	xfs_bmbt_irec_t *imap,
+	int		nimaps,
+	int		*prealloc)
+{
+	xfs_fileoff_t   start_fsb;
+	xfs_filblks_t   count_fsb;
+	xfs_fsblock_t	firstblock;
+	int		n, error, imaps;
+
+	*prealloc = 0;
+	if ((ioflag & BMAPI_SYNC) || (offset + count) <= isize)
+		return 0;
+
+	/*
+	 * If there are any real blocks past eof, then don't
+	 * do any speculative allocation.
+	 */
+	start_fsb = XFS_B_TO_FSBT(mp, ((xfs_ufsize_t)(offset + count - 1)));
+	count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp));
+	while (count_fsb > 0) {
+		imaps = nimaps;
+		firstblock = NULLFSBLOCK;
+		error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb,
+				  0, &firstblock, 0, imap, &imaps, NULL);
+		if (error)
+			return error;
+		for (n = 0; n < imaps; n++) {
+			if ((imap[n].br_startblock != HOLESTARTBLOCK) &&
+			    (imap[n].br_startblock != DELAYSTARTBLOCK))
+				return 0;
+			start_fsb += imap[n].br_blockcount;
+			count_fsb -= imap[n].br_blockcount;
+		}
+	}
+	*prealloc = 1;
+	return 0;
+}
+
 int
 xfs_iomap_write_delay(
 	xfs_inode_t	*ip,
@@ -513,13 +639,15 @@
 	xfs_iocore_t	*io = &ip->i_iocore;
 	xfs_fileoff_t	offset_fsb;
 	xfs_fileoff_t	last_fsb;
-	xfs_fsize_t	isize;
+	xfs_off_t	aligned_offset;
+	xfs_fileoff_t	ioalign;
 	xfs_fsblock_t	firstblock;
+	xfs_extlen_t	extsz;
+	xfs_fsize_t	isize;
 	int		nimaps;
-	int		error;
 	xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS];
-	int		aeof;
-	int		fsynced = 0;
+	int		prealloc, fsynced = 0;
+	int		error;
 
 	ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE) != 0);
 
@@ -527,152 +655,57 @@
 	 * Make sure that the dquots are there. This doesn't hold
 	 * the ilock across a disk read.
 	 */
-
 	error = XFS_QM_DQATTACH(mp, ip, XFS_QMOPT_ILOCKED);
 	if (error)
 		return XFS_ERROR(error);
 
+	if (XFS_IS_REALTIME_INODE(ip)) {
+		if (!(extsz = ip->i_d.di_extsize))
+			extsz = mp->m_sb.sb_rextsize;
+	} else {
+		extsz = ip->i_d.di_extsize;
+	}
+
+	offset_fsb = XFS_B_TO_FSBT(mp, offset);
+
 retry:
 	isize = ip->i_d.di_size;
-	if (io->io_new_size > isize) {
+	if (io->io_new_size > isize)
 		isize = io->io_new_size;
-	}
 
-	aeof = 0;
-	offset_fsb = XFS_B_TO_FSBT(mp, offset);
-	last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count)));
-	/*
-	 * If the caller is doing a write at the end of the file,
-	 * then extend the allocation (and the buffer used for the write)
-	 * out to the file system's write iosize.  We clean up any extra
-	 * space left over when the file is closed in xfs_inactive().
-	 *
-	 * For sync writes, we are flushing delayed allocate space to
-	 * try to make additional space available for allocation near
-	 * the filesystem full boundary - preallocation hurts in that
-	 * situation, of course.
-	 */
-	if (!(ioflag & BMAPI_SYNC) && ((offset + count) > ip->i_d.di_size)) {
-		xfs_off_t	aligned_offset;
-		xfs_filblks_t   count_fsb;
-		unsigned int	iosize;
-		xfs_fileoff_t	ioalign;
-		int		n;
-		xfs_fileoff_t   start_fsb;
+	error = xfs_iomap_eof_want_preallocate(mp, io, isize, offset, count,
+				ioflag, imap, XFS_WRITE_IMAPS, &prealloc);
+	if (error)
+		return error;
 
-		/*
-		 * If there are any real blocks past eof, then don't
-		 * do any speculative allocation.
-		 */
-		start_fsb = XFS_B_TO_FSBT(mp,
-					((xfs_ufsize_t)(offset + count - 1)));
-		count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp));
-		while (count_fsb > 0) {
-			nimaps = XFS_WRITE_IMAPS;
-			error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb,
-					0, &firstblock, 0, imap, &nimaps, NULL);
-			if (error) {
-				return error;
-			}
-			for (n = 0; n < nimaps; n++) {
-				if ( !(io->io_flags & XFS_IOCORE_RT)  && 
-					!imap[n].br_startblock) {
-					cmn_err(CE_PANIC,"Access to block "
-						"zero:  fs <%s> inode: %lld "
-						"start_block : %llx start_off "
-						": %llx blkcnt : %llx "
-						"extent-state : %x \n",
-						(ip->i_mount)->m_fsname,
-						(long long)ip->i_ino,
-						imap[n].br_startblock,
-						imap[n].br_startoff,
-						imap[n].br_blockcount,
-						imap[n].br_state);
-        			}
-				if ((imap[n].br_startblock != HOLESTARTBLOCK) &&
-				    (imap[n].br_startblock != DELAYSTARTBLOCK)) {
-					goto write_map;
-				}
-				start_fsb += imap[n].br_blockcount;
-				count_fsb -= imap[n].br_blockcount;
-			}
-		}
-		iosize = mp->m_writeio_blocks;
+	if (prealloc) {
 		aligned_offset = XFS_WRITEIO_ALIGN(mp, (offset + count - 1));
 		ioalign = XFS_B_TO_FSBT(mp, aligned_offset);
-		last_fsb = ioalign + iosize;
-		aeof = 1;
+		last_fsb = ioalign + mp->m_writeio_blocks;
+	} else {
+		last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count)));
 	}
-write_map:
+
+	if (prealloc || extsz) {
+		error = xfs_iomap_eof_align_last_fsb(mp, io, isize, extsz,
+							&last_fsb);
+		if (error)
+			return error;
+	}
+
 	nimaps = XFS_WRITE_IMAPS;
 	firstblock = NULLFSBLOCK;
-
-	/*
-	 * If mounted with the "-o swalloc" option, roundup the allocation
-	 * request to a stripe width boundary if the file size is >=
-	 * stripe width and we are allocating past the allocation eof.
-	 */
-	if (!(io->io_flags & XFS_IOCORE_RT) && mp->m_swidth 
-	    && (mp->m_flags & XFS_MOUNT_SWALLOC)
-	    && (isize >= XFS_FSB_TO_B(mp, mp->m_swidth)) && aeof) {
-		int eof;
-		xfs_fileoff_t new_last_fsb;
-
-		new_last_fsb = roundup_64(last_fsb, mp->m_swidth);
-		error = xfs_bmap_eof(ip, new_last_fsb, XFS_DATA_FORK, &eof);
-		if (error) {
-			return error;
-		}
-		if (eof) {
-			last_fsb = new_last_fsb;
-		}
-	/*
-	 * Roundup the allocation request to a stripe unit (m_dalign) boundary
-	 * if the file size is >= stripe unit size, and we are allocating past
-	 * the allocation eof.
-	 */
-	} else if (!(io->io_flags & XFS_IOCORE_RT) && mp->m_dalign &&
-		   (isize >= XFS_FSB_TO_B(mp, mp->m_dalign)) && aeof) {
-		int eof;
-		xfs_fileoff_t new_last_fsb;
-		new_last_fsb = roundup_64(last_fsb, mp->m_dalign);
-		error = xfs_bmap_eof(ip, new_last_fsb, XFS_DATA_FORK, &eof);
-		if (error) {
-			return error;
-		}
-		if (eof) {
-			last_fsb = new_last_fsb;
-		}
-	/*
-	 * Round up the allocation request to a real-time extent boundary
-	 * if the file is on the real-time subvolume.
-	 */
-	} else if (io->io_flags & XFS_IOCORE_RT && aeof) {
-		int eof;
-		xfs_fileoff_t new_last_fsb;
-
-		new_last_fsb = roundup_64(last_fsb, mp->m_sb.sb_rextsize);
-		error = XFS_BMAP_EOF(mp, io, new_last_fsb, XFS_DATA_FORK, &eof);
-		if (error) {
-			return error;
-		}
-		if (eof)
-			last_fsb = new_last_fsb;
-	}
 	error = xfs_bmapi(NULL, ip, offset_fsb,
 			  (xfs_filblks_t)(last_fsb - offset_fsb),
 			  XFS_BMAPI_DELAY | XFS_BMAPI_WRITE |
 			  XFS_BMAPI_ENTIRE, &firstblock, 1, imap,
 			  &nimaps, NULL);
-	/*
-	 * This can be EDQUOT, if nimaps == 0
-	 */
-	if (error && (error != ENOSPC)) {
+	if (error && (error != ENOSPC))
 		return XFS_ERROR(error);
-	}
+
 	/*
 	 * If bmapi returned us nothing, and if we didn't get back EDQUOT,
-	 * then we must have run out of space.
+	 * then we must have run out of space - flush delalloc, and retry..
 	 */
 	if (nimaps == 0) {
 		xfs_iomap_enter_trace(XFS_IOMAP_WRITE_NOSPACE,
@@ -684,17 +717,21 @@
 		goto retry;
 	}
 
-	*ret_imap = imap[0];
-	*nmaps = 1;
-	if ( !(io->io_flags & XFS_IOCORE_RT)  && !ret_imap->br_startblock) {
+	if (!(io->io_flags & XFS_IOCORE_RT)  && !ret_imap->br_startblock) {
 		cmn_err(CE_PANIC,"Access to block zero:  fs <%s> inode: %lld "
                         "start_block : %llx start_off : %llx blkcnt : %llx "
                         "extent-state : %x \n",
                         (ip->i_mount)->m_fsname,
                         (long long)ip->i_ino,
-                        ret_imap->br_startblock, ret_imap->br_startoff,
-                        ret_imap->br_blockcount,ret_imap->br_state);
+                        (unsigned long long)ret_imap->br_startblock,
+			(unsigned long long)ret_imap->br_startoff,
+                        (unsigned long long)ret_imap->br_blockcount,
+			ret_imap->br_state);
 	}
+
+	*ret_imap = imap[0];
+	*nmaps = 1;
+
 	return 0;
 }
 
@@ -820,17 +857,21 @@
 		 */
 
 		for (i = 0; i < nimaps; i++) {
-			if ( !(io->io_flags & XFS_IOCORE_RT)  && 
-				!imap[i].br_startblock) {
+			if (!(io->io_flags & XFS_IOCORE_RT)  &&
+			    !imap[i].br_startblock) {
 				cmn_err(CE_PANIC,"Access to block zero:  "
 					"fs <%s> inode: %lld "
-					"start_block : %llx start_off : %llx " 
+					"start_block : %llx start_off : %llx "
 					"blkcnt : %llx extent-state : %x \n",
 					(ip->i_mount)->m_fsname,
 					(long long)ip->i_ino,
-					imap[i].br_startblock,
-					imap[i].br_startoff,
-				        imap[i].br_blockcount,imap[i].br_state);
+					(unsigned long long)
+						imap[i].br_startblock,
+					(unsigned long long)
+						imap[i].br_startoff,
+					(unsigned long long)
+				        	imap[i].br_blockcount,
+					imap[i].br_state);
                         }
 			if ((offset_fsb >= imap[i].br_startoff) &&
 			    (offset_fsb < (imap[i].br_startoff +
@@ -867,17 +908,17 @@
 {
 	xfs_mount_t	*mp = ip->i_mount;
 	xfs_iocore_t    *io = &ip->i_iocore;
-	xfs_trans_t	*tp;
 	xfs_fileoff_t	offset_fsb;
 	xfs_filblks_t	count_fsb;
 	xfs_filblks_t	numblks_fsb;
-	xfs_bmbt_irec_t	imap;
+	xfs_fsblock_t	firstfsb;
+	int		nimaps;
+	xfs_trans_t	*tp;
+	xfs_bmbt_irec_t imap;
+	xfs_bmap_free_t free_list;
+	uint		resblks;
 	int		committed;
 	int		error;
-	int		nres;
-	int		nimaps;
-	xfs_fsblock_t	firstfsb;
-	xfs_bmap_free_t	free_list;
 
 	xfs_iomap_enter_trace(XFS_IOMAP_UNWRITTEN,
 				&ip->i_iocore, offset, count);
@@ -886,9 +927,9 @@
 	count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count);
 	count_fsb = (xfs_filblks_t)(count_fsb - offset_fsb);
 
-	do {
-		nres = XFS_DIOSTRAT_SPACE_RES(mp, 0);
+	resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0) << 1;
 
+	do {
 		/*
 		 * set up a transaction to convert the range of extents
 		 * from unwritten to real. Do allocations in a loop until
@@ -896,7 +937,7 @@
 		 */
 
 		tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE);
-		error = xfs_trans_reserve(tp, nres,
+		error = xfs_trans_reserve(tp, resblks,
 				XFS_WRITE_LOG_RES(mp), 0,
 				XFS_TRANS_PERM_LOG_RES,
 				XFS_WRITE_LOG_COUNT);
@@ -915,7 +956,7 @@
 		XFS_BMAP_INIT(&free_list, &firstfsb);
 		nimaps = 1;
 		error = xfs_bmapi(tp, ip, offset_fsb, count_fsb,
-				  XFS_BMAPI_WRITE, &firstfsb,
+				  XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb,
 				  1, &imap, &nimaps, &free_list);
 		if (error)
 			goto error_on_bmapi_transaction;
@@ -929,15 +970,17 @@
 		xfs_iunlock(ip, XFS_ILOCK_EXCL);
 		if (error)
 			goto error0;
-		
+
 		if ( !(io->io_flags & XFS_IOCORE_RT)  && !imap.br_startblock) {
 			cmn_err(CE_PANIC,"Access to block zero:  fs <%s> "
 				"inode: %lld start_block : %llx start_off : "
 				"%llx blkcnt : %llx extent-state : %x \n",
 				(ip->i_mount)->m_fsname,
 				(long long)ip->i_ino,
-				imap.br_startblock,imap.br_startoff,
-				imap.br_blockcount,imap.br_state);
+				(unsigned long long)imap.br_startblock,
+				(unsigned long long)imap.br_startoff,
+				(unsigned long long)imap.br_blockcount,
+				imap.br_state);
         	}
 
 		if ((numblks_fsb = imap.br_blockcount) == 0) {
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index f63646e..c59450e 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -56,6 +56,7 @@
 {
 	xfs_dinode_core_t *dic;		/* dinode core info pointer */
 	xfs_inode_t	*ip;		/* incore inode pointer */
+	vnode_t		*vp;
 	int		error;
 
 	error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno);
@@ -72,6 +73,7 @@
 		goto out_iput;
 	}
 
+	vp = XFS_ITOV(ip);
 	dic = &ip->i_d;
 
 	/* xfs_iget returns the following without needing
@@ -84,8 +86,7 @@
 	buf->bs_uid = dic->di_uid;
 	buf->bs_gid = dic->di_gid;
 	buf->bs_size = dic->di_size;
-	buf->bs_atime.tv_sec = dic->di_atime.t_sec;
-	buf->bs_atime.tv_nsec = dic->di_atime.t_nsec;
+	vn_atime_to_bstime(vp, &buf->bs_atime);
 	buf->bs_mtime.tv_sec = dic->di_mtime.t_sec;
 	buf->bs_mtime.tv_nsec = dic->di_mtime.t_nsec;
 	buf->bs_ctime.tv_sec = dic->di_ctime.t_sec;
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 29af512..3d9a36e 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -178,6 +178,83 @@
 #define	xlog_trace_iclog(iclog,state)
 #endif /* XFS_LOG_TRACE */
 
+
+static void
+xlog_ins_ticketq(struct xlog_ticket **qp, struct xlog_ticket *tic)
+{
+	if (*qp) {
+		tic->t_next	    = (*qp);
+		tic->t_prev	    = (*qp)->t_prev;
+		(*qp)->t_prev->t_next = tic;
+		(*qp)->t_prev	    = tic;
+	} else {
+		tic->t_prev = tic->t_next = tic;
+		*qp = tic;
+	}
+
+	tic->t_flags |= XLOG_TIC_IN_Q;
+}
+
+static void
+xlog_del_ticketq(struct xlog_ticket **qp, struct xlog_ticket *tic)
+{
+	if (tic == tic->t_next) {
+		*qp = NULL;
+	} else {
+		*qp = tic->t_next;
+		tic->t_next->t_prev = tic->t_prev;
+		tic->t_prev->t_next = tic->t_next;
+	}
+
+	tic->t_next = tic->t_prev = NULL;
+	tic->t_flags &= ~XLOG_TIC_IN_Q;
+}
+
+static void
+xlog_grant_sub_space(struct log *log, int bytes)
+{
+	log->l_grant_write_bytes -= bytes;
+	if (log->l_grant_write_bytes < 0) {
+		log->l_grant_write_bytes += log->l_logsize;
+		log->l_grant_write_cycle--;
+	}
+
+	log->l_grant_reserve_bytes -= bytes;
+	if ((log)->l_grant_reserve_bytes < 0) {
+		log->l_grant_reserve_bytes += log->l_logsize;
+		log->l_grant_reserve_cycle--;
+	}
+
+}
+
+static void
+xlog_grant_add_space_write(struct log *log, int bytes)
+{
+	log->l_grant_write_bytes += bytes;
+	if (log->l_grant_write_bytes > log->l_logsize) {
+		log->l_grant_write_bytes -= log->l_logsize;
+		log->l_grant_write_cycle++;
+	}
+}
+
+static void
+xlog_grant_add_space_reserve(struct log *log, int bytes)
+{
+	log->l_grant_reserve_bytes += bytes;
+	if (log->l_grant_reserve_bytes > log->l_logsize) {
+		log->l_grant_reserve_bytes -= log->l_logsize;
+		log->l_grant_reserve_cycle++;
+	}
+}
+
+static inline void
+xlog_grant_add_space(struct log *log, int bytes)
+{
+	xlog_grant_add_space_write(log, bytes);
+	xlog_grant_add_space_reserve(log, bytes);
+}
+
+
 /*
  * NOTES:
  *
@@ -428,7 +505,7 @@
 		if (readonly)
 			vfsp->vfs_flag &= ~VFS_RDONLY;
 
-		error = xlog_recover(mp->m_log, readonly);
+		error = xlog_recover(mp->m_log);
 
 		if (readonly)
 			vfsp->vfs_flag |= VFS_RDONLY;
@@ -1320,8 +1397,7 @@
 
 	/* move grant heads by roundoff in sync */
 	s = GRANT_LOCK(log);
-	XLOG_GRANT_ADD_SPACE(log, roundoff, 'w');
-	XLOG_GRANT_ADD_SPACE(log, roundoff, 'r');
+	xlog_grant_add_space(log, roundoff);
 	GRANT_UNLOCK(log, s);
 
 	/* put cycle number in every block */
@@ -1515,7 +1591,6 @@
  * print out info relating to regions written which consume
  * the reservation
  */
-#if defined(XFS_LOG_RES_DEBUG)
 STATIC void
 xlog_print_tic_res(xfs_mount_t *mp, xlog_ticket_t *ticket)
 {
@@ -1605,11 +1680,11 @@
 			ticket->t_res_arr_sum, ticket->t_res_o_flow,
 			ticket->t_res_num_ophdrs, ophdr_spc,
 			ticket->t_res_arr_sum + 
-			  ticket->t_res_o_flow + ophdr_spc,
+			ticket->t_res_o_flow + ophdr_spc,
 			ticket->t_res_num);
 
 	for (i = 0; i < ticket->t_res_num; i++) {
-	   	uint r_type = ticket->t_res_arr[i].r_type; 
+		uint r_type = ticket->t_res_arr[i].r_type; 
 		cmn_err(CE_WARN,
 			    "region[%u]: %s - %u bytes\n",
 			    i, 
@@ -1618,9 +1693,6 @@
 			    ticket->t_res_arr[i].r_len);
 	}
 }
-#else
-#define xlog_print_tic_res(mp, ticket)
-#endif
 
 /*
  * Write some region out to in-core log
@@ -2389,7 +2461,7 @@
 
 	/* something is already sleeping; insert new transaction at end */
 	if (log->l_reserve_headq) {
-		XLOG_INS_TICKETQ(log->l_reserve_headq, tic);
+		xlog_ins_ticketq(&log->l_reserve_headq, tic);
 		xlog_trace_loggrant(log, tic,
 				    "xlog_grant_log_space: sleep 1");
 		/*
@@ -2422,7 +2494,7 @@
 				     log->l_grant_reserve_bytes);
 	if (free_bytes < need_bytes) {
 		if ((tic->t_flags & XLOG_TIC_IN_Q) == 0)
-			XLOG_INS_TICKETQ(log->l_reserve_headq, tic);
+			xlog_ins_ticketq(&log->l_reserve_headq, tic);
 		xlog_trace_loggrant(log, tic,
 				    "xlog_grant_log_space: sleep 2");
 		XFS_STATS_INC(xs_sleep_logspace);
@@ -2439,11 +2511,10 @@
 		s = GRANT_LOCK(log);
 		goto redo;
 	} else if (tic->t_flags & XLOG_TIC_IN_Q)
-		XLOG_DEL_TICKETQ(log->l_reserve_headq, tic);
+		xlog_del_ticketq(&log->l_reserve_headq, tic);
 
 	/* we've got enough space */
-	XLOG_GRANT_ADD_SPACE(log, need_bytes, 'w');
-	XLOG_GRANT_ADD_SPACE(log, need_bytes, 'r');
+	xlog_grant_add_space(log, need_bytes);
 #ifdef DEBUG
 	tail_lsn = log->l_tail_lsn;
 	/*
@@ -2464,7 +2535,7 @@
 
  error_return:
 	if (tic->t_flags & XLOG_TIC_IN_Q)
-		XLOG_DEL_TICKETQ(log->l_reserve_headq, tic);
+		xlog_del_ticketq(&log->l_reserve_headq, tic);
 	xlog_trace_loggrant(log, tic, "xlog_grant_log_space: err_ret");
 	/*
 	 * If we are failing, make sure the ticket doesn't have any
@@ -2533,7 +2604,7 @@
 
 		if (ntic != log->l_write_headq) {
 			if ((tic->t_flags & XLOG_TIC_IN_Q) == 0)
-				XLOG_INS_TICKETQ(log->l_write_headq, tic);
+				xlog_ins_ticketq(&log->l_write_headq, tic);
 
 			xlog_trace_loggrant(log, tic,
 				    "xlog_regrant_write_log_space: sleep 1");
@@ -2565,7 +2636,7 @@
 				     log->l_grant_write_bytes);
 	if (free_bytes < need_bytes) {
 		if ((tic->t_flags & XLOG_TIC_IN_Q) == 0)
-			XLOG_INS_TICKETQ(log->l_write_headq, tic);
+			xlog_ins_ticketq(&log->l_write_headq, tic);
 		XFS_STATS_INC(xs_sleep_logspace);
 		sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s);
 
@@ -2581,9 +2652,10 @@
 		s = GRANT_LOCK(log);
 		goto redo;
 	} else if (tic->t_flags & XLOG_TIC_IN_Q)
-		XLOG_DEL_TICKETQ(log->l_write_headq, tic);
+		xlog_del_ticketq(&log->l_write_headq, tic);
 
-	XLOG_GRANT_ADD_SPACE(log, need_bytes, 'w'); /* we've got enough space */
+	/* we've got enough space */
+	xlog_grant_add_space_write(log, need_bytes);
 #ifdef DEBUG
 	tail_lsn = log->l_tail_lsn;
 	if (CYCLE_LSN(tail_lsn) != log->l_grant_write_cycle) {
@@ -2600,7 +2672,7 @@
 
  error_return:
 	if (tic->t_flags & XLOG_TIC_IN_Q)
-		XLOG_DEL_TICKETQ(log->l_reserve_headq, tic);
+		xlog_del_ticketq(&log->l_reserve_headq, tic);
 	xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: err_ret");
 	/*
 	 * If we are failing, make sure the ticket doesn't have any
@@ -2633,8 +2705,7 @@
 		ticket->t_cnt--;
 
 	s = GRANT_LOCK(log);
-	XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'w');
-	XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'r');
+	xlog_grant_sub_space(log, ticket->t_curr_res);
 	ticket->t_curr_res = ticket->t_unit_res;
 	XLOG_TIC_RESET_RES(ticket);
 	xlog_trace_loggrant(log, ticket,
@@ -2647,7 +2718,7 @@
 		return;
 	}
 
-	XLOG_GRANT_ADD_SPACE(log, ticket->t_unit_res, 'r');
+	xlog_grant_add_space_reserve(log, ticket->t_unit_res);
 	xlog_trace_loggrant(log, ticket,
 			    "xlog_regrant_reserve_log_space: exit");
 	xlog_verify_grant_head(log, 0);
@@ -2683,8 +2754,7 @@
 	s = GRANT_LOCK(log);
 	xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: enter");
 
-	XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'w');
-	XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'r');
+	xlog_grant_sub_space(log, ticket->t_curr_res);
 
 	xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: sub current");
 
@@ -2693,8 +2763,7 @@
 	 */
 	if (ticket->t_cnt > 0) {
 		ASSERT(ticket->t_flags & XLOG_TIC_PERM_RESERV);
-		XLOG_GRANT_SUB_SPACE(log, ticket->t_unit_res*ticket->t_cnt,'w');
-		XLOG_GRANT_SUB_SPACE(log, ticket->t_unit_res*ticket->t_cnt,'r');
+		xlog_grant_sub_space(log, ticket->t_unit_res*ticket->t_cnt);
 	}
 
 	xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: exit");
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h
index f40d439..4b2ac88 100644
--- a/fs/xfs/xfs_log.h
+++ b/fs/xfs/xfs_log.h
@@ -96,7 +96,6 @@
 
 
 /* Region types for iovec's i_type */
-#if defined(XFS_LOG_RES_DEBUG)
 #define XLOG_REG_TYPE_BFORMAT		1
 #define XLOG_REG_TYPE_BCHUNK		2
 #define XLOG_REG_TYPE_EFI_FORMAT	3
@@ -117,21 +116,13 @@
 #define XLOG_REG_TYPE_COMMIT		18
 #define XLOG_REG_TYPE_TRANSHDR		19
 #define XLOG_REG_TYPE_MAX		19
-#endif
 
-#if defined(XFS_LOG_RES_DEBUG)
 #define XLOG_VEC_SET_TYPE(vecp, t) ((vecp)->i_type = (t))
-#else
-#define XLOG_VEC_SET_TYPE(vecp, t)
-#endif
-
 
 typedef struct xfs_log_iovec {
 	xfs_caddr_t		i_addr;		/* beginning address of region */
 	int		i_len;		/* length in bytes of region */
-#if defined(XFS_LOG_RES_DEBUG)
- 	uint		i_type;		/* type of region */
-#endif
+	uint		i_type;		/* type of region */
 } xfs_log_iovec_t;
 
 typedef void* xfs_log_ticket_t;
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
index 4518b18..34bcbf5 100644
--- a/fs/xfs/xfs_log_priv.h
+++ b/fs/xfs/xfs_log_priv.h
@@ -253,7 +253,6 @@
 
 
 /* Ticket reservation region accounting */ 
-#if defined(XFS_LOG_RES_DEBUG)
 #define XLOG_TIC_LEN_MAX	15
 #define XLOG_TIC_RESET_RES(t) ((t)->t_res_num = \
 				(t)->t_res_arr_sum = (t)->t_res_num_ophdrs = 0)
@@ -278,15 +277,9 @@
  * we don't care about.
  */
 typedef struct xlog_res {
-	uint	r_len;
-	uint	r_type;
+	uint	r_len;	/* region length		:4 */
+	uint	r_type;	/* region's transaction type	:4 */
 } xlog_res_t;
-#else
-#define XLOG_TIC_RESET_RES(t)
-#define XLOG_TIC_ADD_OPHDR(t)
-#define XLOG_TIC_ADD_REGION(t, len, type)
-#endif
-
 
 typedef struct xlog_ticket {
 	sv_t		   t_sema;	 /* sleep on this semaphore      : 20 */
@@ -301,14 +294,12 @@
 	char		   t_flags;	 /* properties of reservation	 : 1  */
 	uint		   t_trans_type; /* transaction type             : 4  */
 
-#if defined (XFS_LOG_RES_DEBUG)
         /* reservation array fields */
 	uint		   t_res_num;                    /* num in array : 4 */
-	xlog_res_t	   t_res_arr[XLOG_TIC_LEN_MAX];  /* array of res : X */ 
 	uint		   t_res_num_ophdrs;		 /* num op hdrs  : 4 */
 	uint		   t_res_arr_sum;		 /* array sum    : 4 */
 	uint		   t_res_o_flow;		 /* sum overflow : 4 */
-#endif
+	xlog_res_t	   t_res_arr[XLOG_TIC_LEN_MAX];  /* array of res : 8 * 15 */ 
 } xlog_ticket_t;
 
 #endif
@@ -494,71 +485,13 @@
 
 #define XLOG_FORCED_SHUTDOWN(log)	((log)->l_flags & XLOG_IO_ERROR)
 
-#define XLOG_GRANT_SUB_SPACE(log,bytes,type)				\
-    {									\
-	if (type == 'w') {						\
-		(log)->l_grant_write_bytes -= (bytes);			\
-		if ((log)->l_grant_write_bytes < 0) {			\
-			(log)->l_grant_write_bytes += (log)->l_logsize;	\
-			(log)->l_grant_write_cycle--;			\
-		}							\
-	} else {							\
-		(log)->l_grant_reserve_bytes -= (bytes);		\
-		if ((log)->l_grant_reserve_bytes < 0) {			\
-			(log)->l_grant_reserve_bytes += (log)->l_logsize;\
-			(log)->l_grant_reserve_cycle--;			\
-		}							\
-	 }								\
-    }
-#define XLOG_GRANT_ADD_SPACE(log,bytes,type)				\
-    {									\
-	if (type == 'w') {						\
-		(log)->l_grant_write_bytes += (bytes);			\
-		if ((log)->l_grant_write_bytes > (log)->l_logsize) {	\
-			(log)->l_grant_write_bytes -= (log)->l_logsize;	\
-			(log)->l_grant_write_cycle++;			\
-		}							\
-	} else {							\
-		(log)->l_grant_reserve_bytes += (bytes);		\
-		if ((log)->l_grant_reserve_bytes > (log)->l_logsize) {	\
-			(log)->l_grant_reserve_bytes -= (log)->l_logsize;\
-			(log)->l_grant_reserve_cycle++;			\
-		}							\
-	 }								\
-    }
-#define XLOG_INS_TICKETQ(q, tic)			\
-    {							\
-	if (q) {					\
-		(tic)->t_next	    = (q);		\
-		(tic)->t_prev	    = (q)->t_prev;	\
-		(q)->t_prev->t_next = (tic);		\
-		(q)->t_prev	    = (tic);		\
-	} else {					\
-		(tic)->t_prev = (tic)->t_next = (tic);	\
-		(q) = (tic);				\
-	}						\
-	(tic)->t_flags |= XLOG_TIC_IN_Q;		\
-    }
-#define XLOG_DEL_TICKETQ(q, tic)			\
-    {							\
-	if ((tic) == (tic)->t_next) {			\
-		(q) = NULL;				\
-	} else {					\
-		(q) = (tic)->t_next;			\
-		(tic)->t_next->t_prev = (tic)->t_prev;	\
-		(tic)->t_prev->t_next = (tic)->t_next;	\
-	}						\
-	(tic)->t_next = (tic)->t_prev = NULL;		\
-	(tic)->t_flags &= ~XLOG_TIC_IN_Q;		\
-    }
 
 /* common routines */
 extern xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp);
 extern int	 xlog_find_tail(xlog_t	*log,
 				xfs_daddr_t *head_blk,
-				xfs_daddr_t *tail_blk,
-				int readonly);
-extern int	 xlog_recover(xlog_t *log, int readonly);
+				xfs_daddr_t *tail_blk);
+extern int	 xlog_recover(xlog_t *log);
 extern int	 xlog_recover_finish(xlog_t *log, int mfsi_flags);
 extern void	 xlog_pack_data(xlog_t *log, xlog_in_core_t *iclog, int);
 extern void	 xlog_recover_process_iunlinks(xlog_t *log);
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 8ab7df7..7d46cbd 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -783,8 +783,7 @@
 xlog_find_tail(
 	xlog_t			*log,
 	xfs_daddr_t		*head_blk,
-	xfs_daddr_t		*tail_blk,
-	int			readonly)
+	xfs_daddr_t		*tail_blk)
 {
 	xlog_rec_header_t	*rhead;
 	xlog_op_header_t	*op_head;
@@ -2563,10 +2562,12 @@
 
 	/*
 	 * The logitem format's flag tells us if this was user quotaoff,
-	 * group quotaoff or both.
+	 * group/project quotaoff or both.
 	 */
 	if (qoff_f->qf_flags & XFS_UQUOTA_ACCT)
 		log->l_quotaoffs_flag |= XFS_DQ_USER;
+	if (qoff_f->qf_flags & XFS_PQUOTA_ACCT)
+		log->l_quotaoffs_flag |= XFS_DQ_PROJ;
 	if (qoff_f->qf_flags & XFS_GQUOTA_ACCT)
 		log->l_quotaoffs_flag |= XFS_DQ_GROUP;
 
@@ -3890,14 +3891,13 @@
  */
 int
 xlog_recover(
-	xlog_t		*log,
-	int		readonly)
+	xlog_t		*log)
 {
 	xfs_daddr_t	head_blk, tail_blk;
 	int		error;
 
 	/* find the tail of the log */
-	if ((error = xlog_find_tail(log, &head_blk, &tail_blk, readonly)))
+	if ((error = xlog_find_tail(log, &head_blk, &tail_blk)))
 		return error;
 
 	if (tail_blk != head_blk) {
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 303af86..6088e14 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -51,7 +51,7 @@
 STATIC void	xfs_uuid_unmount(xfs_mount_t *mp);
 STATIC void	xfs_unmountfs_wait(xfs_mount_t *);
 
-static struct {
+static const struct {
     short offset;
     short type;     /* 0 = integer
 		* 1 = binary / string (no translation)
@@ -1077,8 +1077,7 @@
 
 	xfs_iflush_all(mp);
 
-	XFS_QM_DQPURGEALL(mp,
-		XFS_QMOPT_UQUOTA | XFS_QMOPT_GQUOTA | XFS_QMOPT_UMOUNTING);
+	XFS_QM_DQPURGEALL(mp, XFS_QMOPT_QUOTALL | XFS_QMOPT_UMOUNTING);
 
 	/*
 	 * Flush out the log synchronously so that we know for sure
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 3432fd5..cd3cf96 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -308,7 +308,6 @@
 	xfs_buftarg_t		*m_ddev_targp;	/* saves taking the address */
 	xfs_buftarg_t		*m_logdev_targp;/* ptr to log device */
 	xfs_buftarg_t		*m_rtdev_targp;	/* ptr to rt device */
-#define m_dev		m_ddev_targp->pbr_dev
 	__uint8_t		m_dircook_elog;	/* log d-cookie entry bits */
 	__uint8_t		m_blkbit_log;	/* blocklog + NBBY */
 	__uint8_t		m_blkbb_log;	/* blocklog - BBSHIFT */
@@ -393,7 +392,7 @@
 						   user */
 #define XFS_MOUNT_NOALIGN	(1ULL << 7)	/* turn off stripe alignment
 						   allocations */
-#define XFS_MOUNT_COMPAT_ATTR	(1ULL << 8)	/* do not use attr2 format */
+#define XFS_MOUNT_ATTR2		(1ULL << 8)	/* allow use of attr2 format */
 			     /*	(1ULL << 9)	-- currently unused */
 #define XFS_MOUNT_NORECOVERY	(1ULL << 10)	/* no recovery - dirty fs */
 #define XFS_MOUNT_SHARED	(1ULL << 11)	/* shared mount */
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
index 4d4e8f4..81a05cf 100644
--- a/fs/xfs/xfs_rename.c
+++ b/fs/xfs/xfs_rename.c
@@ -243,7 +243,6 @@
 	xfs_inode_t	*inodes[4];
 	int		target_ip_dropped = 0;	/* dropped target_ip link? */
 	vnode_t		*src_dir_vp;
-	bhv_desc_t	*target_dir_bdp;
 	int		spaceres;
 	int		target_link_zero = 0;
 	int		num_inodes;
@@ -260,14 +259,12 @@
 	 * Find the XFS behavior descriptor for the target directory
 	 * vnode since it was not handed to us.
 	 */
-	target_dir_bdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(target_dir_vp),
-						&xfs_vnodeops);
-	if (target_dir_bdp == NULL) {
+	target_dp = xfs_vtoi(target_dir_vp);
+	if (target_dp == NULL) {
 		return XFS_ERROR(EXDEV);
 	}
 
 	src_dp = XFS_BHVTOI(src_dir_bdp);
-	target_dp = XFS_BHVTOI(target_dir_bdp);
 	mp = src_dp->i_mount;
 
 	if (DM_EVENT_ENABLED(src_dir_vp->v_vfsp, src_dp, DM_EVENT_RENAME) ||
diff --git a/fs/xfs/xfs_rw.c b/fs/xfs/xfs_rw.c
index c4b2087..a59c102 100644
--- a/fs/xfs/xfs_rw.c
+++ b/fs/xfs/xfs_rw.c
@@ -238,6 +238,7 @@
 	}
 	return (EIO);
 }
+
 /*
  * Prints out an ALERT message about I/O error.
  */
@@ -252,11 +253,9 @@
  "I/O error in filesystem (\"%s\") meta-data dev %s block 0x%llx"
  "       (\"%s\") error %d buf count %zd",
 		(!mp || !mp->m_fsname) ? "(fs name not set)" : mp->m_fsname,
-		XFS_BUFTARG_NAME(bp->pb_target),
-		(__uint64_t)blkno,
-		func,
-		XFS_BUF_GETERROR(bp),
-		XFS_BUF_COUNT(bp));
+		XFS_BUFTARG_NAME(XFS_BUF_TARGET(bp)),
+		(__uint64_t)blkno, func,
+		XFS_BUF_GETERROR(bp), XFS_BUF_COUNT(bp));
 }
 
 /*
diff --git a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h
index 4a17d33..bf168a9 100644
--- a/fs/xfs/xfs_sb.h
+++ b/fs/xfs/xfs_sb.h
@@ -68,18 +68,6 @@
 	(XFS_SB_VERSION_NUMBITS | \
 	 XFS_SB_VERSION_OKREALFBITS | \
 	 XFS_SB_VERSION_OKSASHFBITS)
-#define XFS_SB_VERSION_MKFS(ia,dia,extflag,dirv2,na,sflag,morebits)	\
-	(((ia) || (dia) || (extflag) || (dirv2) || (na) || (sflag) || \
-	  (morebits)) ? \
-		(XFS_SB_VERSION_4 | \
-		 ((ia) ? XFS_SB_VERSION_ALIGNBIT : 0) | \
-		 ((dia) ? XFS_SB_VERSION_DALIGNBIT : 0) | \
-		 ((extflag) ? XFS_SB_VERSION_EXTFLGBIT : 0) | \
-		 ((dirv2) ? XFS_SB_VERSION_DIRV2BIT : 0) | \
-		 ((na) ? XFS_SB_VERSION_LOGV2BIT : 0) | \
-		 ((sflag) ? XFS_SB_VERSION_SECTORBIT : 0) | \
-		 ((morebits) ? XFS_SB_VERSION_MOREBITSBIT : 0)) : \
-		XFS_SB_VERSION_1)
 
 /*
  * There are two words to hold XFS "feature" bits: the original
@@ -105,11 +93,6 @@
 	(XFS_SB_VERSION2_OKREALFBITS |	\
 	 XFS_SB_VERSION2_OKSASHFBITS )
 
-/*
- * mkfs macro to set up sb_features2 word
- */
-#define	XFS_SB_VERSION2_MKFS(resvd1, sbcntr)	0
-
 typedef struct xfs_sb
 {
 	__uint32_t	sb_magicnum;	/* magic number == XFS_SB_MAGIC */
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 279e043..d3d714e 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -1014,6 +1014,7 @@
 	xfs_log_item_t		*lip;
 	int			i;
 #endif
+	xfs_mount_t		*mp = tp->t_mountp;
 
 	/*
 	 * See if the caller is being too lazy to figure out if
@@ -1026,9 +1027,10 @@
 	 * filesystem.  This happens in paths where we detect
 	 * corruption and decide to give up.
 	 */
-	if ((tp->t_flags & XFS_TRANS_DIRTY) &&
-	    !XFS_FORCED_SHUTDOWN(tp->t_mountp))
-		xfs_force_shutdown(tp->t_mountp, XFS_CORRUPT_INCORE);
+	if ((tp->t_flags & XFS_TRANS_DIRTY) && !XFS_FORCED_SHUTDOWN(mp)) {
+		XFS_ERROR_REPORT("xfs_trans_cancel", XFS_ERRLEVEL_LOW, mp);
+		xfs_force_shutdown(mp, XFS_CORRUPT_INCORE);
+	}
 #ifdef DEBUG
 	if (!(flags & XFS_TRANS_ABORT)) {
 		licp = &(tp->t_items);
@@ -1040,7 +1042,7 @@
 				}
 
 				lip = lidp->lid_item;
-				if (!XFS_FORCED_SHUTDOWN(tp->t_mountp))
+				if (!XFS_FORCED_SHUTDOWN(mp))
 					ASSERT(!(lip->li_type == XFS_LI_EFD));
 			}
 			licp = licp->lic_next;
@@ -1048,7 +1050,7 @@
 	}
 #endif
 	xfs_trans_unreserve_and_mod_sb(tp);
-	XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(tp->t_mountp, tp);
+	XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(mp, tp);
 
 	if (tp->t_ticket) {
 		if (flags & XFS_TRANS_RELEASE_LOG_RES) {
@@ -1057,7 +1059,7 @@
 		} else {
 			log_flags = 0;
 		}
-		xfs_log_done(tp->t_mountp, tp->t_ticket, NULL, log_flags);
+		xfs_log_done(mp, tp->t_ticket, NULL, log_flags);
 	}
 
 	/* mark this thread as no longer being in a transaction */
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index a889963..d77901c 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -973,7 +973,6 @@
 void		xfs_trans_bhold_release(xfs_trans_t *, struct xfs_buf *);
 void		xfs_trans_binval(xfs_trans_t *, struct xfs_buf *);
 void		xfs_trans_inode_buf(xfs_trans_t *, struct xfs_buf *);
-void		xfs_trans_inode_buf(xfs_trans_t *, struct xfs_buf *);
 void		xfs_trans_stale_inode_buf(xfs_trans_t *, struct xfs_buf *);
 void		xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint);
 void		xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *);
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
index fefe1d6..34654ec 100644
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -55,16 +55,13 @@
 	xfs_inode_t	**ipp)
 {
 	vnode_t		*vp;
-	bhv_desc_t	*bdp;
 
 	vp = VNAME_TO_VNODE(dentry);
-	bdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(vp), &xfs_vnodeops);
-	if (!bdp) {
-		*ipp = NULL;
+
+	*ipp = xfs_vtoi(vp);
+	if (!*ipp)
 		return XFS_ERROR(ENOENT);
-	}
 	VN_HOLD(vp);
-	*ipp = XFS_BHVTOI(bdp);
 	return 0;
 }
 
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index 7bdbd99..b6ad370 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -53,6 +53,7 @@
 #include "xfs_acl.h"
 #include "xfs_attr.h"
 #include "xfs_clnt.h"
+#include "xfs_fsops.h"
 
 STATIC int xfs_sync(bhv_desc_t *, int, cred_t *);
 
@@ -290,8 +291,8 @@
 		mp->m_flags |= XFS_MOUNT_IDELETE;
 	if (ap->flags & XFSMNT_DIRSYNC)
 		mp->m_flags |= XFS_MOUNT_DIRSYNC;
-	if (ap->flags & XFSMNT_COMPAT_ATTR)
-		mp->m_flags |= XFS_MOUNT_COMPAT_ATTR;
+	if (ap->flags & XFSMNT_ATTR2)
+		mp->m_flags |= XFS_MOUNT_ATTR2;
 
 	if (ap->flags2 & XFSMNT2_COMPAT_IOSIZE)
 		mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
@@ -312,6 +313,8 @@
 		mp->m_flags |= XFS_MOUNT_NOUUID;
 	if (ap->flags & XFSMNT_BARRIER)
 		mp->m_flags |= XFS_MOUNT_BARRIER;
+	else
+		mp->m_flags &= ~XFS_MOUNT_BARRIER;
 
 	return 0;
 }
@@ -330,10 +333,11 @@
 
 	/* Fail a mount where the logbuf is smaller then the log stripe */
 	if (XFS_SB_VERSION_HASLOGV2(&mp->m_sb)) {
-		if ((ap->logbufsize == -1) &&
+		if ((ap->logbufsize <= 0) &&
 		    (mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE)) {
 			mp->m_logbsize = mp->m_sb.sb_logsunit;
-		} else if (ap->logbufsize < mp->m_sb.sb_logsunit) {
+		} else if (ap->logbufsize > 0 &&
+			   ap->logbufsize < mp->m_sb.sb_logsunit) {
 			cmn_err(CE_WARN,
 	"XFS: logbuf size must be greater than or equal to log stripe size");
 			return XFS_ERROR(EINVAL);
@@ -347,6 +351,10 @@
 		}
 	}
 
+	if (XFS_SB_VERSION_HASATTR2(&mp->m_sb)) {
+		mp->m_flags |= XFS_MOUNT_ATTR2;
+	}
+
 	/*
 	 * prohibit r/w mounts of read-only filesystems
 	 */
@@ -382,10 +390,6 @@
 			return XFS_ERROR(EINVAL);
 	}
 
-	if (XFS_SB_VERSION_HASATTR2(&mp->m_sb)) {
-		mp->m_flags &= ~XFS_MOUNT_COMPAT_ATTR;
-	}
-
 	return 0;
 }
 
@@ -504,13 +508,13 @@
 	if (error)
 		goto error2;
 
+	if ((mp->m_flags & XFS_MOUNT_BARRIER) && !(vfsp->vfs_flag & VFS_RDONLY))
+		xfs_mountfs_check_barriers(mp);
+
 	error = XFS_IOINIT(vfsp, args, flags);
 	if (error)
 		goto error2;
 
-	if ((args->flags & XFSMNT_BARRIER) &&
-	    !(XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY))
-		xfs_mountfs_check_barriers(mp);
 	return 0;
 
 error2:
@@ -655,6 +659,11 @@
 	else
 		mp->m_flags &= ~XFS_MOUNT_NOATIME;
 
+	if (args->flags & XFSMNT_BARRIER)
+		mp->m_flags |= XFS_MOUNT_BARRIER;
+	else
+		mp->m_flags &= ~XFS_MOUNT_BARRIER;
+
 	if ((vfsp->vfs_flag & VFS_RDONLY) &&
 	    !(*flags & MS_RDONLY)) {
 		vfsp->vfs_flag &= ~VFS_RDONLY;
@@ -1634,6 +1643,7 @@
 #define MNTOPT_NORECOVERY   "norecovery"   /* don't run XFS recovery */
 #define MNTOPT_BARRIER	"barrier"	/* use writer barriers for log write and
 					 * unwritten extent conversion */
+#define MNTOPT_NOBARRIER "nobarrier"	/* .. disable */
 #define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */
 #define MNTOPT_64BITINODE   "inode64"	/* inodes can be allocated anywhere */
 #define MNTOPT_IKEEP	"ikeep"		/* do not free empty inode clusters */
@@ -1680,7 +1690,6 @@
 	int			iosize;
 
 	args->flags2 |= XFSMNT2_COMPAT_IOSIZE;
-	args->flags |= XFSMNT_COMPAT_ATTR;
 
 #if 0	/* XXX: off by default, until some remaining issues ironed out */
 	args->flags |= XFSMNT_IDELETE; /* default to on */
@@ -1806,6 +1815,8 @@
 			args->flags |= XFSMNT_NOUUID;
 		} else if (!strcmp(this_char, MNTOPT_BARRIER)) {
 			args->flags |= XFSMNT_BARRIER;
+		} else if (!strcmp(this_char, MNTOPT_NOBARRIER)) {
+			args->flags &= ~XFSMNT_BARRIER;
 		} else if (!strcmp(this_char, MNTOPT_IKEEP)) {
 			args->flags &= ~XFSMNT_IDELETE;
 		} else if (!strcmp(this_char, MNTOPT_NOIKEEP)) {
@@ -1815,9 +1826,9 @@
 		} else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) {
 			args->flags2 |= XFSMNT2_COMPAT_IOSIZE;
 		} else if (!strcmp(this_char, MNTOPT_ATTR2)) {
-			args->flags &= ~XFSMNT_COMPAT_ATTR;
+			args->flags |= XFSMNT_ATTR2;
 		} else if (!strcmp(this_char, MNTOPT_NOATTR2)) {
-			args->flags |= XFSMNT_COMPAT_ATTR;
+			args->flags &= ~XFSMNT_ATTR2;
 		} else if (!strcmp(this_char, "osyncisdsync")) {
 			/* no-op, this is now the default */
 printk("XFS: osyncisdsync is now the default, option is deprecated.\n");
@@ -1892,7 +1903,6 @@
 		{ XFS_MOUNT_NOUUID,		"," MNTOPT_NOUUID },
 		{ XFS_MOUNT_NORECOVERY,		"," MNTOPT_NORECOVERY },
 		{ XFS_MOUNT_OSYNCISOSYNC,	"," MNTOPT_OSYNCISOSYNC },
-		{ XFS_MOUNT_BARRIER,		"," MNTOPT_BARRIER },
 		{ XFS_MOUNT_IDELETE,		"," MNTOPT_NOIKEEP },
 		{ 0, NULL }
 	};
@@ -1914,33 +1924,28 @@
 
 	if (mp->m_logbufs > 0)
 		seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs);
-
 	if (mp->m_logbsize > 0)
 		seq_printf(m, "," MNTOPT_LOGBSIZE "=%dk", mp->m_logbsize >> 10);
 
 	if (mp->m_logname)
 		seq_printf(m, "," MNTOPT_LOGDEV "=%s", mp->m_logname);
-
 	if (mp->m_rtname)
 		seq_printf(m, "," MNTOPT_RTDEV "=%s", mp->m_rtname);
 
 	if (mp->m_dalign > 0)
 		seq_printf(m, "," MNTOPT_SUNIT "=%d",
 				(int)XFS_FSB_TO_BB(mp, mp->m_dalign));
-
 	if (mp->m_swidth > 0)
 		seq_printf(m, "," MNTOPT_SWIDTH "=%d",
 				(int)XFS_FSB_TO_BB(mp, mp->m_swidth));
 
-	if (!(mp->m_flags & XFS_MOUNT_COMPAT_ATTR))
-		seq_printf(m, "," MNTOPT_ATTR2);
-
 	if (!(mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE))
 		seq_printf(m, "," MNTOPT_LARGEIO);
+	if (mp->m_flags & XFS_MOUNT_BARRIER)
+		seq_printf(m, "," MNTOPT_BARRIER);
 
 	if (!(vfsp->vfs_flag & VFS_32BITINODES))
 		seq_printf(m, "," MNTOPT_64BITINODE);
-
 	if (vfsp->vfs_flag & VFS_GRPID)
 		seq_printf(m, "," MNTOPT_GRPID);
 
@@ -1959,6 +1964,7 @@
 	/* Push the superblock and write an unmount record */
 	xfs_log_unmount_write(mp);
 	xfs_unmountfs_writesb(mp);
+	xfs_fs_log_dummy(mp);
 }
 
 
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index e92cacd..8076cc9 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -185,8 +185,7 @@
 		break;
 	}
 
-	vap->va_atime.tv_sec = ip->i_d.di_atime.t_sec;
-	vap->va_atime.tv_nsec = ip->i_d.di_atime.t_nsec;
+	vn_atime_to_timespec(vp, &vap->va_atime);
 	vap->va_mtime.tv_sec = ip->i_d.di_mtime.t_sec;
 	vap->va_mtime.tv_nsec = ip->i_d.di_mtime.t_nsec;
 	vap->va_ctime.tv_sec = ip->i_d.di_ctime.t_sec;
@@ -544,24 +543,6 @@
 		}
 
 		/*
-		 * Can't set extent size unless the file is marked, or
-		 * about to be marked as a realtime file.
-		 *
-		 * This check will be removed when fixed size extents
-		 * with buffered data writes is implemented.
-		 *
-		 */
-		if ((mask & XFS_AT_EXTSIZE)			&&
-		    ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) !=
-		     vap->va_extsize) &&
-		    (!((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ||
-		       ((mask & XFS_AT_XFLAGS) &&
-			(vap->va_xflags & XFS_XFLAG_REALTIME))))) {
-			code = XFS_ERROR(EINVAL);
-			goto error_return;
-		}
-
-		/*
 		 * Can't change realtime flag if any extents are allocated.
 		 */
 		if ((ip->i_d.di_nextents || ip->i_delayed_blks) &&
@@ -823,13 +804,17 @@
 					di_flags |= XFS_DIFLAG_RTINHERIT;
 				if (vap->va_xflags & XFS_XFLAG_NOSYMLINKS)
 					di_flags |= XFS_DIFLAG_NOSYMLINKS;
-			} else {
+				if (vap->va_xflags & XFS_XFLAG_EXTSZINHERIT)
+					di_flags |= XFS_DIFLAG_EXTSZINHERIT;
+			} else if ((ip->i_d.di_mode & S_IFMT) == S_IFREG) {
 				if (vap->va_xflags & XFS_XFLAG_REALTIME) {
 					di_flags |= XFS_DIFLAG_REALTIME;
 					ip->i_iocore.io_flags |= XFS_IOCORE_RT;
 				} else {
 					ip->i_iocore.io_flags &= ~XFS_IOCORE_RT;
 				}
+				if (vap->va_xflags & XFS_XFLAG_EXTSIZE)
+					di_flags |= XFS_DIFLAG_EXTSIZE;
 			}
 			ip->i_d.di_flags = di_flags;
 		}
@@ -999,10 +984,6 @@
 		goto error_return;
 	}
 
-	if (!(ioflags & IO_INVIS)) {
-		xfs_ichgtime(ip, XFS_ICHGTIME_ACC);
-	}
-
 	/*
 	 * See if the symlink is stored inline.
 	 */
@@ -1234,7 +1215,8 @@
 	xfs_iunlock(ip, XFS_ILOCK_SHARED);
 
 	if (!error && (nimaps != 0) &&
-	    (imap.br_startblock != HOLESTARTBLOCK)) {
+	    (imap.br_startblock != HOLESTARTBLOCK ||
+	     ip->i_delayed_blks)) {
 		/*
 		 * Attach the dquots to the inode up front.
 		 */
@@ -1569,9 +1551,11 @@
 
 	if (ip->i_d.di_nlink != 0) {
 		if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) &&
-		     ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0)) &&
+		     ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0 ||
+		       ip->i_delayed_blks > 0)) &&
 		     (ip->i_df.if_flags & XFS_IFEXTENTS))  &&
-		    (!(ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC|XFS_DIFLAG_APPEND)))) {
+		    (!(ip->i_d.di_flags &
+				(XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)))) {
 			if ((error = xfs_inactive_free_eofblocks(mp, ip)))
 				return (error);
 			/* Update linux inode block count after free above */
@@ -1628,7 +1612,8 @@
 	 * only one with a reference to the inode.
 	 */
 	truncate = ((ip->i_d.di_nlink == 0) &&
-	    ((ip->i_d.di_size != 0) || (ip->i_d.di_nextents > 0)) &&
+            ((ip->i_d.di_size != 0) || (ip->i_d.di_nextents > 0) ||
+             (ip->i_delayed_blks > 0)) &&
 	    ((ip->i_d.di_mode & S_IFMT) == S_IFREG));
 
 	mp = ip->i_mount;
@@ -1646,10 +1631,12 @@
 
 	if (ip->i_d.di_nlink != 0) {
 		if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) &&
-		     ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0)) &&
-		     (ip->i_df.if_flags & XFS_IFEXTENTS))  &&
-		    (!(ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC|XFS_DIFLAG_APPEND)) ||
-		     (ip->i_delayed_blks != 0))) {
+                     ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0 ||
+                       ip->i_delayed_blks > 0)) &&
+		      (ip->i_df.if_flags & XFS_IFEXTENTS) &&
+		     (!(ip->i_d.di_flags &
+				(XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) ||
+		      (ip->i_delayed_blks != 0)))) {
 			if ((error = xfs_inactive_free_eofblocks(mp, ip)))
 				return (VN_INACTIVE_CACHE);
 			/* Update linux inode block count after free above */
@@ -2593,7 +2580,6 @@
 	int			cancel_flags;
 	int			committed;
 	vnode_t			*target_dir_vp;
-	bhv_desc_t		*src_bdp;
 	int			resblks;
 	char			*target_name = VNAME(dentry);
 	int			target_namelen;
@@ -2606,8 +2592,7 @@
 	if (VN_ISDIR(src_vp))
 		return XFS_ERROR(EPERM);
 
-	src_bdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(src_vp), &xfs_vnodeops);
-	sip = XFS_BHVTOI(src_bdp);
+	sip = xfs_vtoi(src_vp);
 	tdp = XFS_BHVTOI(target_dir_bdp);
 	mp = tdp->i_mount;
 	if (XFS_FORCED_SHUTDOWN(mp))
@@ -3240,7 +3225,6 @@
 	xfs_trans_t	*tp = NULL;
 	int		error = 0;
 	uint		lock_mode;
-	xfs_off_t	start_offset;
 
 	vn_trace_entry(BHV_TO_VNODE(dir_bdp), __FUNCTION__,
 					       (inst_t *)__return_address);
@@ -3251,11 +3235,7 @@
 	}
 
 	lock_mode = xfs_ilock_map_shared(dp);
-	start_offset = uiop->uio_offset;
 	error = XFS_DIR_GETDENTS(dp->i_mount, tp, dp, uiop, eofp);
-	if (start_offset != uiop->uio_offset) {
-		xfs_ichgtime(dp, XFS_ICHGTIME_ACC);
-	}
 	xfs_iunlock_map_shared(dp, lock_mode);
 	return error;
 }
@@ -3832,7 +3812,12 @@
 	vn_iowait(vp);
 
 	ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0);
-	ASSERT(VN_CACHED(vp) == 0);
+
+	/*
+	 * Make sure the atime in the XFS inode is correct before freeing the
+	 * Linux inode.
+	 */
+	xfs_synchronize_atime(ip);
 
 	/* If we have nothing to flush with this inode then complete the
 	 * teardown now, otherwise break the link between the xfs inode
@@ -4002,42 +3987,36 @@
 	int			alloc_type,
 	int			attr_flags)
 {
+	xfs_mount_t		*mp = ip->i_mount;
+	xfs_off_t		count;
 	xfs_filblks_t		allocated_fsb;
 	xfs_filblks_t		allocatesize_fsb;
-	int			committed;
-	xfs_off_t		count;
-	xfs_filblks_t		datablocks;
-	int			error;
-	xfs_fsblock_t		firstfsb;
-	xfs_bmap_free_t		free_list;
-	xfs_bmbt_irec_t		*imapp;
-	xfs_bmbt_irec_t		imaps[1];
-	xfs_mount_t		*mp;
-	int			numrtextents;
-	int			reccount;
-	uint			resblks;
-	int			rt;
-	int			rtextsize;
+	xfs_extlen_t		extsz, temp;
 	xfs_fileoff_t		startoffset_fsb;
+	xfs_fsblock_t		firstfsb;
+	int			nimaps;
+	int			bmapi_flag;
+	int			quota_flag;
+	int			rt;
 	xfs_trans_t		*tp;
-	int			xfs_bmapi_flags;
+	xfs_bmbt_irec_t		imaps[1], *imapp;
+	xfs_bmap_free_t		free_list;
+	uint			qblocks, resblks, resrtextents;
+	int			committed;
+	int			error;
 
 	vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address);
-	mp = ip->i_mount;
 
 	if (XFS_FORCED_SHUTDOWN(mp))
 		return XFS_ERROR(EIO);
 
-	/*
-	 * determine if this is a realtime file
-	 */
-	if ((rt = XFS_IS_REALTIME_INODE(ip)) != 0) {
-		if (ip->i_d.di_extsize)
-			rtextsize = ip->i_d.di_extsize;
-		else
-			rtextsize = mp->m_sb.sb_rextsize;
-	} else
-		rtextsize = 0;
+	rt = XFS_IS_REALTIME_INODE(ip);
+	if (unlikely(rt)) {
+		if (!(extsz = ip->i_d.di_extsize))
+			extsz = mp->m_sb.sb_rextsize;
+	} else {
+		extsz = ip->i_d.di_extsize;
+	}
 
 	if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
 		return error;
@@ -4048,8 +4027,8 @@
 	count = len;
 	error = 0;
 	imapp = &imaps[0];
-	reccount = 1;
-	xfs_bmapi_flags = XFS_BMAPI_WRITE | (alloc_type ? XFS_BMAPI_PREALLOC : 0);
+	nimaps = 1;
+	bmapi_flag = XFS_BMAPI_WRITE | (alloc_type ? XFS_BMAPI_PREALLOC : 0);
 	startoffset_fsb	= XFS_B_TO_FSBT(mp, offset);
 	allocatesize_fsb = XFS_B_TO_FSB(mp, count);
 
@@ -4070,43 +4049,51 @@
 	}
 
 	/*
-	 * allocate file space until done or until there is an error
+	 * Allocate file space until done or until there is an error
 	 */
 retry:
 	while (allocatesize_fsb && !error) {
-		/*
-		 * determine if reserving space on
-		 * the data or realtime partition.
-		 */
-		if (rt) {
-			xfs_fileoff_t s, e;
+		xfs_fileoff_t	s, e;
 
+		/*
+		 * Determine space reservations for data/realtime.
+		 */
+		if (unlikely(extsz)) {
 			s = startoffset_fsb;
-			do_div(s, rtextsize);
-			s *= rtextsize;
-			e = roundup_64(startoffset_fsb + allocatesize_fsb,
-				rtextsize);
-			numrtextents = (int)(e - s) / mp->m_sb.sb_rextsize;
-			datablocks = 0;
+			do_div(s, extsz);
+			s *= extsz;
+			e = startoffset_fsb + allocatesize_fsb;
+			if ((temp = do_mod(startoffset_fsb, extsz)))
+				e += temp;
+			if ((temp = do_mod(e, extsz)))
+				e += extsz - temp;
 		} else {
-			datablocks = allocatesize_fsb;
-			numrtextents = 0;
+			s = 0;
+			e = allocatesize_fsb;
+		}
+
+		if (unlikely(rt)) {
+			resrtextents = qblocks = (uint)(e - s);
+			resrtextents /= mp->m_sb.sb_rextsize;
+			resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
+			quota_flag = XFS_QMOPT_RES_RTBLKS;
+		} else {
+			resrtextents = 0;
+			resblks = qblocks = \
+				XFS_DIOSTRAT_SPACE_RES(mp, (uint)(e - s));
+			quota_flag = XFS_QMOPT_RES_REGBLKS;
 		}
 
 		/*
-		 * allocate and setup the transaction
+		 * Allocate and setup the transaction.
 		 */
 		tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
-		resblks = XFS_DIOSTRAT_SPACE_RES(mp, datablocks);
-		error = xfs_trans_reserve(tp,
-					  resblks,
-					  XFS_WRITE_LOG_RES(mp),
-					  numrtextents,
+		error = xfs_trans_reserve(tp, resblks,
+					  XFS_WRITE_LOG_RES(mp), resrtextents,
 					  XFS_TRANS_PERM_LOG_RES,
 					  XFS_WRITE_LOG_COUNT);
-
 		/*
-		 * check for running out of space
+		 * Check for running out of space
 		 */
 		if (error) {
 			/*
@@ -4117,8 +4104,8 @@
 			break;
 		}
 		xfs_ilock(ip, XFS_ILOCK_EXCL);
-		error = XFS_TRANS_RESERVE_QUOTA(mp, tp,
-				ip->i_udquot, ip->i_gdquot, resblks, 0, 0);
+		error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip,
+						      qblocks, 0, quota_flag);
 		if (error)
 			goto error1;
 
@@ -4126,19 +4113,19 @@
 		xfs_trans_ihold(tp, ip);
 
 		/*
-		 * issue the bmapi() call to allocate the blocks
+		 * Issue the xfs_bmapi() call to allocate the blocks
 		 */
 		XFS_BMAP_INIT(&free_list, &firstfsb);
 		error = xfs_bmapi(tp, ip, startoffset_fsb,
-				  allocatesize_fsb, xfs_bmapi_flags,
-				  &firstfsb, 0, imapp, &reccount,
+				  allocatesize_fsb, bmapi_flag,
+				  &firstfsb, 0, imapp, &nimaps,
 				  &free_list);
 		if (error) {
 			goto error0;
 		}
 
 		/*
-		 * complete the transaction
+		 * Complete the transaction
 		 */
 		error = xfs_bmap_finish(&tp, &free_list, firstfsb, &committed);
 		if (error) {
@@ -4153,7 +4140,7 @@
 
 		allocated_fsb = imapp->br_blockcount;
 
-		if (reccount == 0) {
+		if (nimaps == 0) {
 			error = XFS_ERROR(ENOSPC);
 			break;
 		}
@@ -4176,9 +4163,11 @@
 
 	return error;
 
- error0:
+error0:	/* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
 	xfs_bmap_cancel(&free_list);
- error1:
+	XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag);
+
+error1:	/* Just cancel transaction */
 	xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
 	xfs_iunlock(ip, XFS_ILOCK_EXCL);
 	goto dmapi_enospc_check;
@@ -4423,8 +4412,8 @@
 		}
 		xfs_ilock(ip, XFS_ILOCK_EXCL);
 		error = XFS_TRANS_RESERVE_QUOTA(mp, tp,
-				ip->i_udquot, ip->i_gdquot, resblks, 0, rt ?
-				XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS);
+				ip->i_udquot, ip->i_gdquot, resblks, 0,
+				XFS_QMOPT_RES_REGBLKS);
 		if (error)
 			goto error1;
 
diff --git a/include/asm-alpha/mmu_context.h b/include/asm-alpha/mmu_context.h
index a714d0c..6f92482 100644
--- a/include/asm-alpha/mmu_context.h
+++ b/include/asm-alpha/mmu_context.h
@@ -156,7 +156,7 @@
 	/* Always update the PCB ASN.  Another thread may have allocated
 	   a new mm->context (via flush_tlb_mm) without the ASN serial
 	   number wrapping.  We have no way to detect when this is needed.  */
-	next->thread_info->pcb.asn = mmc & HARDWARE_ASN_MASK;
+	task_thread_info(next)->pcb.asn = mmc & HARDWARE_ASN_MASK;
 }
 
 __EXTERN_INLINE void
@@ -235,7 +235,7 @@
 		if (cpu_online(i))
 			mm->context[i] = 0;
 	if (tsk != current)
-		tsk->thread_info->pcb.ptbr
+		task_thread_info(tsk)->pcb.ptbr
 		  = ((unsigned long)mm->pgd - IDENT_ADDR) >> PAGE_SHIFT;
 	return 0;
 }
@@ -249,7 +249,7 @@
 static inline void
 enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
 {
-	tsk->thread_info->pcb.ptbr
+	task_thread_info(tsk)->pcb.ptbr
 	  = ((unsigned long)mm->pgd - IDENT_ADDR) >> PAGE_SHIFT;
 }
 
diff --git a/include/asm-alpha/processor.h b/include/asm-alpha/processor.h
index bb1a7a3..425b7b6 100644
--- a/include/asm-alpha/processor.h
+++ b/include/asm-alpha/processor.h
@@ -52,19 +52,10 @@
 
 unsigned long get_wchan(struct task_struct *p);
 
-/* See arch/alpha/kernel/ptrace.c for details.  */
-#define PT_REG(reg) \
-  (PAGE_SIZE*2 - sizeof(struct pt_regs) + offsetof(struct pt_regs, reg))
-
-#define SW_REG(reg) \
- (PAGE_SIZE*2 - sizeof(struct pt_regs) - sizeof(struct switch_stack) \
-  + offsetof(struct switch_stack, reg))
-
-#define KSTK_EIP(tsk) \
-  (*(unsigned long *)(PT_REG(pc) + (unsigned long) ((tsk)->thread_info)))
+#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc)
 
 #define KSTK_ESP(tsk) \
-  ((tsk) == current ? rdusp() : (tsk)->thread_info->pcb.usp)
+  ((tsk) == current ? rdusp() : task_thread_info(tsk)->pcb.usp)
 
 #define cpu_relax()	barrier()
 
diff --git a/include/asm-alpha/ptrace.h b/include/asm-alpha/ptrace.h
index 072375c..9933b8b 100644
--- a/include/asm-alpha/ptrace.h
+++ b/include/asm-alpha/ptrace.h
@@ -75,10 +75,10 @@
 #define profile_pc(regs) instruction_pointer(regs)
 extern void show_regs(struct pt_regs *);
 
-#define alpha_task_regs(task) \
-  ((struct pt_regs *) ((long) (task)->thread_info + 2*PAGE_SIZE) - 1)
+#define task_pt_regs(task) \
+  ((struct pt_regs *) (task_stack_page(task) + 2*PAGE_SIZE) - 1)
 
-#define force_successful_syscall_return() (alpha_task_regs(current)->r0 = 0)
+#define force_successful_syscall_return() (task_pt_regs(current)->r0 = 0)
 
 #endif
 
diff --git a/include/asm-alpha/system.h b/include/asm-alpha/system.h
index 050e86d..cc9c7e8 100644
--- a/include/asm-alpha/system.h
+++ b/include/asm-alpha/system.h
@@ -131,15 +131,25 @@
 extern void halt(void) __attribute__((noreturn));
 #define __halt() __asm__ __volatile__ ("call_pal %0 #halt" : : "i" (PAL_halt))
 
-#define switch_to(P,N,L)						\
-  do {									\
-    (L) = alpha_switch_to(virt_to_phys(&(N)->thread_info->pcb), (P));	\
-    check_mmu_context();						\
+#define switch_to(P,N,L)						 \
+  do {									 \
+    (L) = alpha_switch_to(virt_to_phys(&task_thread_info(N)->pcb), (P)); \
+    check_mmu_context();						 \
   } while (0)
 
 struct task_struct;
 extern struct task_struct *alpha_switch_to(unsigned long, struct task_struct*);
 
+/*
+ * On SMP systems, when the scheduler does migration-cost autodetection,
+ * it needs a way to flush as much of the CPU's caches as possible.
+ *
+ * TODO: fill this in!
+ */
+static inline void sched_cacheflush(void)
+{
+}
+
 #define imb() \
 __asm__ __volatile__ ("call_pal %0 #imb" : : "i" (PAL_imb) : "memory")
 
diff --git a/include/asm-alpha/thread_info.h b/include/asm-alpha/thread_info.h
index d51491e..69ffd93 100644
--- a/include/asm-alpha/thread_info.h
+++ b/include/asm-alpha/thread_info.h
@@ -54,8 +54,6 @@
 #define alloc_thread_info(tsk) \
   ((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
 #define free_thread_info(ti) free_pages((unsigned long) (ti), 1)
-#define get_thread_info(ti) get_task_struct((ti)->task)
-#define put_thread_info(ti) put_task_struct((ti)->task)
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/include/asm-arm/processor.h b/include/asm-arm/processor.h
index 7d4118e..3129069 100644
--- a/include/asm-arm/processor.h
+++ b/include/asm-arm/processor.h
@@ -85,9 +85,11 @@
  */
 extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
 
-#define KSTK_REGS(tsk)	(((struct pt_regs *)(THREAD_START_SP + (unsigned long)(tsk)->thread_info)) - 1)
-#define KSTK_EIP(tsk)	KSTK_REGS(tsk)->ARM_pc
-#define KSTK_ESP(tsk)	KSTK_REGS(tsk)->ARM_sp
+#define task_pt_regs(p) \
+	((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
+
+#define KSTK_EIP(tsk)	task_pt_regs(tsk)->ARM_pc
+#define KSTK_ESP(tsk)	task_pt_regs(tsk)->ARM_sp
 
 /*
  * Prefetching support - only ARMv5.
diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h
index 5621d61..eb2de8c 100644
--- a/include/asm-arm/system.h
+++ b/include/asm-arm/system.h
@@ -168,10 +168,20 @@
 
 #define switch_to(prev,next,last)					\
 do {									\
-	last = __switch_to(prev,prev->thread_info,next->thread_info);	\
+	last = __switch_to(prev,task_thread_info(prev), task_thread_info(next));	\
 } while (0)
 
 /*
+ * On SMP systems, when the scheduler does migration-cost autodetection,
+ * it needs a way to flush as much of the CPU's caches as possible.
+ *
+ * TODO: fill this in!
+ */
+static inline void sched_cacheflush(void)
+{
+}
+
+/*
  * CPU interrupt mask handling.
  */
 #if __LINUX_ARM_ARCH__ >= 6
diff --git a/include/asm-arm/thread_info.h b/include/asm-arm/thread_info.h
index 7c98557..33a33cb 100644
--- a/include/asm-arm/thread_info.h
+++ b/include/asm-arm/thread_info.h
@@ -96,13 +96,10 @@
 extern struct thread_info *alloc_thread_info(struct task_struct *task);
 extern void free_thread_info(struct thread_info *);
 
-#define get_thread_info(ti)	get_task_struct((ti)->task)
-#define put_thread_info(ti)	put_task_struct((ti)->task)
-
 #define thread_saved_pc(tsk)	\
-	((unsigned long)(pc_pointer((tsk)->thread_info->cpu_context.pc)))
+	((unsigned long)(pc_pointer(task_thread_info(tsk)->cpu_context.pc)))
 #define thread_saved_fp(tsk)	\
-	((unsigned long)((tsk)->thread_info->cpu_context.fp))
+	((unsigned long)(task_thread_info(tsk)->cpu_context.fp))
 
 extern void iwmmxt_task_disable(struct thread_info *);
 extern void iwmmxt_task_copy(struct thread_info *, void *);
diff --git a/include/asm-arm26/system.h b/include/asm-arm26/system.h
index f23fac1..ca4ccfc 100644
--- a/include/asm-arm26/system.h
+++ b/include/asm-arm26/system.h
@@ -111,10 +111,20 @@
 
 #define switch_to(prev,next,last)					\
 do {									\
-	last = __switch_to(prev,prev->thread_info,next->thread_info);	\
+	last = __switch_to(prev,task_thread_info(prev),task_thread_info(next));	\
 } while (0)
 
 /*
+ * On SMP systems, when the scheduler does migration-cost autodetection,
+ * it needs a way to flush as much of the CPU's caches as possible.
+ *
+ * TODO: fill this in!
+ */
+static inline void sched_cacheflush(void)
+{
+}
+
+/*
  * Save the current interrupt enable state & disable IRQs
  */
 #define local_irq_save(x)                               \
diff --git a/include/asm-arm26/thread_info.h b/include/asm-arm26/thread_info.h
index aff3e56..a65e58a 100644
--- a/include/asm-arm26/thread_info.h
+++ b/include/asm-arm26/thread_info.h
@@ -82,18 +82,15 @@
 
 /* FIXME - PAGE_SIZE < 32K */
 #define THREAD_SIZE		(8*32768) // FIXME - this needs attention (see kernel/fork.c which gets a nice div by zero if this is lower than 8*32768
-#define __get_user_regs(x) (((struct pt_regs *)((unsigned long)(x) + THREAD_SIZE - 8)) - 1)
+#define task_pt_regs(task) ((struct pt_regs *)(task_stack_page(task) + THREAD_SIZE - 8) - 1)
 
 extern struct thread_info *alloc_thread_info(struct task_struct *task);
 extern void free_thread_info(struct thread_info *);
 
-#define get_thread_info(ti)	get_task_struct((ti)->task)
-#define put_thread_info(ti)	put_task_struct((ti)->task)
-
 #define thread_saved_pc(tsk)	\
-	((unsigned long)(pc_pointer((tsk)->thread_info->cpu_context.pc)))
+	((unsigned long)(pc_pointer(task_thread_info(tsk)->cpu_context.pc)))
 #define thread_saved_fp(tsk)	\
-	((unsigned long)((tsk)->thread_info->cpu_context.fp))
+	((unsigned long)(task_thread_info(tsk)->cpu_context.fp))
 
 #else /* !__ASSEMBLY__ */
 
diff --git a/include/asm-cris/arch-v10/processor.h b/include/asm-cris/arch-v10/processor.h
index e23df8d..cc692c7 100644
--- a/include/asm-cris/arch-v10/processor.h
+++ b/include/asm-cris/arch-v10/processor.h
@@ -40,7 +40,7 @@
 #define KSTK_EIP(tsk)	\
 ({			\
 	unsigned long eip = 0;   \
-	unsigned long regs = (unsigned long)user_regs(tsk); \
+	unsigned long regs = (unsigned long)task_pt_regs(tsk); \
 	if (regs > PAGE_SIZE && \
 		virt_addr_valid(regs)) \
 	eip = ((struct pt_regs *)regs)->irp; \
diff --git a/include/asm-cris/arch-v32/processor.h b/include/asm-cris/arch-v32/processor.h
index 8c939bf..32bf2e5 100644
--- a/include/asm-cris/arch-v32/processor.h
+++ b/include/asm-cris/arch-v32/processor.h
@@ -36,7 +36,7 @@
 #define KSTK_EIP(tsk)		\
 ({				\
 	unsigned long eip = 0;	\
-	unsigned long regs = (unsigned long)user_regs(tsk); \
+	unsigned long regs = (unsigned long)task_pt_regs(tsk); \
 	if (regs > PAGE_SIZE && virt_addr_valid(regs))	    \
 		eip = ((struct pt_regs *)regs)->erp;	    \
 	eip; \
diff --git a/include/asm-cris/processor.h b/include/asm-cris/processor.h
index dce4100..961e2bc 100644
--- a/include/asm-cris/processor.h
+++ b/include/asm-cris/processor.h
@@ -45,7 +45,8 @@
  * Dito but for the currently running task
  */
 
-#define current_regs() user_regs(current->thread_info)
+#define task_pt_regs(task) user_regs(task_thread_info(task))
+#define current_regs() task_pt_regs(current)
 
 static inline void prepare_to_copy(struct task_struct *tsk)
 {
diff --git a/include/asm-cris/thread_info.h b/include/asm-cris/thread_info.h
index cef0140..7ad853c 100644
--- a/include/asm-cris/thread_info.h
+++ b/include/asm-cris/thread_info.h
@@ -69,8 +69,6 @@
 /* thread information allocation */
 #define alloc_thread_info(tsk) ((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
 #define free_thread_info(ti) free_pages((unsigned long) (ti), 1)
-#define get_thread_info(ti) get_task_struct((ti)->task)
-#define put_thread_info(ti) put_task_struct((ti)->task)
 
 #endif /* !__ASSEMBLY__ */
 
diff --git a/include/asm-frv/thread_info.h b/include/asm-frv/thread_info.h
index 60f6b2a..a5576e0 100644
--- a/include/asm-frv/thread_info.h
+++ b/include/asm-frv/thread_info.h
@@ -110,8 +110,6 @@
 #endif
 
 #define free_thread_info(info)	kfree(info)
-#define get_thread_info(ti)	get_task_struct((ti)->task)
-#define put_thread_info(ti)	put_task_struct((ti)->task)
 
 #else /* !__ASSEMBLY__ */
 
diff --git a/include/asm-h8300/thread_info.h b/include/asm-h8300/thread_info.h
index bfcc755..45f09dc 100644
--- a/include/asm-h8300/thread_info.h
+++ b/include/asm-h8300/thread_info.h
@@ -69,8 +69,6 @@
 #define alloc_thread_info(tsk) ((struct thread_info *) \
 				__get_free_pages(GFP_KERNEL, 1))
 #define free_thread_info(ti)	free_pages((unsigned long) (ti), 1)
-#define get_thread_info(ti)	get_task_struct((ti)->task)
-#define put_thread_info(ti)	put_task_struct((ti)->task)
 #endif /* __ASSEMBLY__ */
 
 /*
diff --git a/include/asm-i386/i387.h b/include/asm-i386/i387.h
index 6747006..152d0ba 100644
--- a/include/asm-i386/i387.h
+++ b/include/asm-i386/i387.h
@@ -49,19 +49,19 @@
 		X86_FEATURE_FXSR,
 		"m" (tsk->thread.i387.fxsave)
 		:"memory");
-	tsk->thread_info->status &= ~TS_USEDFPU;
+	task_thread_info(tsk)->status &= ~TS_USEDFPU;
 }
 
 #define __unlazy_fpu( tsk ) do { \
-	if ((tsk)->thread_info->status & TS_USEDFPU) \
+	if (task_thread_info(tsk)->status & TS_USEDFPU) \
 		save_init_fpu( tsk ); \
 } while (0)
 
 #define __clear_fpu( tsk )					\
 do {								\
-	if ((tsk)->thread_info->status & TS_USEDFPU) {		\
+	if (task_thread_info(tsk)->status & TS_USEDFPU) {		\
 		asm volatile("fnclex ; fwait");				\
-		(tsk)->thread_info->status &= ~TS_USEDFPU;	\
+		task_thread_info(tsk)->status &= ~TS_USEDFPU;	\
 		stts();						\
 	}							\
 } while (0)
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index 13ecf66..feca5d9 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -561,10 +561,20 @@
        (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
 })
 
+/*
+ * The below -8 is to reserve 8 bytes on top of the ring0 stack.
+ * This is necessary to guarantee that the entire "struct pt_regs"
+ * is accessable even if the CPU haven't stored the SS/ESP registers
+ * on the stack (interrupt gate does not save these registers
+ * when switching to the same priv ring).
+ * Therefore beware: accessing the xss/esp fields of the
+ * "struct pt_regs" is possible, but they may contain the
+ * completely wrong values.
+ */
 #define task_pt_regs(task)                                             \
 ({                                                                     \
        struct pt_regs *__regs__;                                       \
-       __regs__ = (struct pt_regs *)KSTK_TOP((task)->thread_info);     \
+       __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
        __regs__ - 1;                                                   \
 })
 
diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h
index 9c0593b..36a92ed 100644
--- a/include/asm-i386/system.h
+++ b/include/asm-i386/system.h
@@ -548,6 +548,15 @@
 extern int es7000_plat;
 void cpu_idle_wait(void);
 
+/*
+ * On SMP systems, when the scheduler does migration-cost autodetection,
+ * it needs a way to flush as much of the CPU's caches as possible:
+ */
+static inline void sched_cacheflush(void)
+{
+	wbinvd();
+}
+
 extern unsigned long arch_align_stack(unsigned long sp);
 
 #endif
diff --git a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h
index 8fbf791..2493e77 100644
--- a/include/asm-i386/thread_info.h
+++ b/include/asm-i386/thread_info.h
@@ -111,8 +111,6 @@
 #endif
 
 #define free_thread_info(info)	kfree(info)
-#define get_thread_info(ti) get_task_struct((ti)->task)
-#define put_thread_info(ti) put_task_struct((ti)->task)
 
 #else /* !__ASSEMBLY__ */
 
diff --git a/include/asm-i386/topology.h b/include/asm-i386/topology.h
index 0ec27c9..d7e19eb 100644
--- a/include/asm-i386/topology.h
+++ b/include/asm-i386/topology.h
@@ -72,7 +72,6 @@
 	.max_interval		= 32,			\
 	.busy_factor		= 32,			\
 	.imbalance_pct		= 125,			\
-	.cache_hot_time		= (10*1000000),		\
 	.cache_nice_tries	= 1,			\
 	.busy_idx		= 3,			\
 	.idle_idx		= 1,			\
diff --git a/include/asm-ia64/compat.h b/include/asm-ia64/compat.h
index aaf11f4..c0b1910 100644
--- a/include/asm-ia64/compat.h
+++ b/include/asm-ia64/compat.h
@@ -192,7 +192,7 @@
 static __inline__ void __user *
 compat_alloc_user_space (long len)
 {
-	struct pt_regs *regs = ia64_task_regs(current);
+	struct pt_regs *regs = task_pt_regs(current);
 	return (void __user *) (((regs->r12 & 0xffffffff) & -16) - len);
 }
 
diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h
index 94e07e7..8c648bf 100644
--- a/include/asm-ia64/processor.h
+++ b/include/asm-ia64/processor.h
@@ -352,7 +352,7 @@
 /* Return instruction pointer of blocked task TSK.  */
 #define KSTK_EIP(tsk)					\
   ({							\
-	struct pt_regs *_regs = ia64_task_regs(tsk);	\
+	struct pt_regs *_regs = task_pt_regs(tsk);	\
 	_regs->cr_iip + ia64_psr(_regs)->ri;		\
   })
 
diff --git a/include/asm-ia64/ptrace.h b/include/asm-ia64/ptrace.h
index 2c703d6..9471cdc 100644
--- a/include/asm-ia64/ptrace.h
+++ b/include/asm-ia64/ptrace.h
@@ -248,7 +248,7 @@
 })
 
   /* given a pointer to a task_struct, return the user's pt_regs */
-# define ia64_task_regs(t)		(((struct pt_regs *) ((char *) (t) + IA64_STK_OFFSET)) - 1)
+# define task_pt_regs(t)		(((struct pt_regs *) ((char *) (t) + IA64_STK_OFFSET)) - 1)
 # define ia64_psr(regs)			((struct ia64_psr *) &(regs)->cr_ipsr)
 # define user_mode(regs)		(((struct ia64_psr *) &(regs)->cr_ipsr)->cpl != 0)
 # define user_stack(task,regs)	((long) regs - (long) task == IA64_STK_OFFSET - sizeof(*regs))
@@ -271,7 +271,7 @@
    *
    * On ia64, we can clear the user's pt_regs->r8 to force a successful syscall.
    */
-# define force_successful_syscall_return()	(ia64_task_regs(current)->r8 = 0)
+# define force_successful_syscall_return()	(task_pt_regs(current)->r8 = 0)
 
   struct task_struct;			/* forward decl */
   struct unw_frame_info;		/* forward decl */
diff --git a/include/asm-ia64/system.h b/include/asm-ia64/system.h
index 635235f..80c5a23 100644
--- a/include/asm-ia64/system.h
+++ b/include/asm-ia64/system.h
@@ -219,14 +219,14 @@
 
 #define IA64_HAS_EXTRA_STATE(t)							\
 	((t)->thread.flags & (IA64_THREAD_DBG_VALID|IA64_THREAD_PM_VALID)	\
-	 || IS_IA32_PROCESS(ia64_task_regs(t)) || PERFMON_IS_SYSWIDE())
+	 || IS_IA32_PROCESS(task_pt_regs(t)) || PERFMON_IS_SYSWIDE())
 
 #define __switch_to(prev,next,last) do {							 \
 	if (IA64_HAS_EXTRA_STATE(prev))								 \
 		ia64_save_extra(prev);								 \
 	if (IA64_HAS_EXTRA_STATE(next))								 \
 		ia64_load_extra(next);								 \
-	ia64_psr(ia64_task_regs(next))->dfh = !ia64_is_local_fpu_owner(next);			 \
+	ia64_psr(task_pt_regs(next))->dfh = !ia64_is_local_fpu_owner(next);			 \
 	(last) = ia64_switch_to((next));							 \
 } while (0)
 
@@ -238,8 +238,8 @@
  * the latest fph state from another CPU.  In other words: eager save, lazy restore.
  */
 # define switch_to(prev,next,last) do {						\
-	if (ia64_psr(ia64_task_regs(prev))->mfh && ia64_is_local_fpu_owner(prev)) {				\
-		ia64_psr(ia64_task_regs(prev))->mfh = 0;			\
+	if (ia64_psr(task_pt_regs(prev))->mfh && ia64_is_local_fpu_owner(prev)) {				\
+		ia64_psr(task_pt_regs(prev))->mfh = 0;			\
 		(prev)->thread.flags |= IA64_THREAD_FPH_VALID;			\
 		__ia64_save_fpu((prev)->thread.fph);				\
 	}									\
@@ -279,6 +279,7 @@
 #define ia64_platform_is(x) (strcmp(x, platform_name) == 0)
 
 void cpu_idle_wait(void);
+void sched_cacheflush(void);
 
 #define arch_align_stack(x) (x)
 
diff --git a/include/asm-ia64/thread_info.h b/include/asm-ia64/thread_info.h
index 171b220..653bb7f 100644
--- a/include/asm-ia64/thread_info.h
+++ b/include/asm-ia64/thread_info.h
@@ -57,11 +57,20 @@
 /* how to get the thread information struct from C */
 #define current_thread_info()	((struct thread_info *) ((char *) current + IA64_TASK_SIZE))
 #define alloc_thread_info(tsk)	((struct thread_info *) ((char *) (tsk) + IA64_TASK_SIZE))
+#define task_thread_info(tsk)	((struct thread_info *) ((char *) (tsk) + IA64_TASK_SIZE))
 #else
 #define current_thread_info()	((struct thread_info *) 0)
 #define alloc_thread_info(tsk)	((struct thread_info *) 0)
+#define task_thread_info(tsk)	((struct thread_info *) 0)
 #endif
 #define free_thread_info(ti)	/* nothing */
+#define task_stack_page(tsk)	((void *)(tsk))
+
+#define __HAVE_THREAD_FUNCTIONS
+#define setup_thread_stack(p, org) \
+	*task_thread_info(p) = *task_thread_info(org); \
+	task_thread_info(p)->task = (p);
+#define end_of_stack(p) (unsigned long *)((void *)(p) + IA64_RBS_OFFSET)
 
 #define __HAVE_ARCH_TASK_STRUCT_ALLOCATOR
 #define alloc_task_struct()	((task_t *)__get_free_pages(GFP_KERNEL, KERNEL_STACK_SIZE_ORDER))
diff --git a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h
index f7c3304..d8aae4d 100644
--- a/include/asm-ia64/topology.h
+++ b/include/asm-ia64/topology.h
@@ -55,7 +55,6 @@
 	.max_interval		= 4,			\
 	.busy_factor		= 64,			\
 	.imbalance_pct		= 125,			\
-	.cache_hot_time		= (10*1000000),		\
 	.per_cpu_gain		= 100,			\
 	.cache_nice_tries	= 2,			\
 	.busy_idx		= 2,			\
@@ -81,7 +80,6 @@
 	.max_interval		= 8*(min(num_online_cpus(), 32)), \
 	.busy_factor		= 64,			\
 	.imbalance_pct		= 125,			\
-	.cache_hot_time		= (10*1000000),		\
 	.cache_nice_tries	= 2,			\
 	.busy_idx		= 3,			\
 	.idle_idx		= 2,			\
diff --git a/include/asm-m32r/ptrace.h b/include/asm-m32r/ptrace.h
index 55cd7ec..0d058b2 100644
--- a/include/asm-m32r/ptrace.h
+++ b/include/asm-m32r/ptrace.h
@@ -163,6 +163,9 @@
 
 extern void withdraw_debug_trap(struct pt_regs *regs);
 
+#define task_pt_regs(task) \
+        ((struct pt_regs *)(task_stack_page(task) + THREAD_SIZE) - 1)
+
 #endif /* __KERNEL */
 
 #endif /* _ASM_M32R_PTRACE_H */
diff --git a/include/asm-m32r/system.h b/include/asm-m32r/system.h
index dcf619a..06c12a0 100644
--- a/include/asm-m32r/system.h
+++ b/include/asm-m32r/system.h
@@ -68,6 +68,16 @@
 	last = __last; \
 } while(0)
 
+/*
+ * On SMP systems, when the scheduler does migration-cost autodetection,
+ * it needs a way to flush as much of the CPU's caches as possible.
+ *
+ * TODO: fill this in!
+ */
+static inline void sched_cacheflush(void)
+{
+}
+
 /* Interrupt Control */
 #if !defined(CONFIG_CHIP_M32102) && !defined(CONFIG_CHIP_M32104)
 #define local_irq_enable() \
diff --git a/include/asm-m32r/thread_info.h b/include/asm-m32r/thread_info.h
index 0f58936..22aff32 100644
--- a/include/asm-m32r/thread_info.h
+++ b/include/asm-m32r/thread_info.h
@@ -110,8 +110,6 @@
 #endif
 
 #define free_thread_info(info) kfree(info)
-#define get_thread_info(ti) get_task_struct((ti)->task)
-#define put_thread_info(ti) put_task_struct((ti)->task)
 
 #define TI_FLAG_FAULT_CODE_SHIFT	28
 
diff --git a/include/asm-m68k/amigahw.h b/include/asm-m68k/amigahw.h
index 3ae5d8d..a16fe4e 100644
--- a/include/asm-m68k/amigahw.h
+++ b/include/asm-m68k/amigahw.h
@@ -274,7 +274,7 @@
 #define ZTWO_VADDR(x) (((unsigned long)(x))+zTwoBase)
 
 #define CUSTOM_PHYSADDR     (0xdff000)
-#define custom ((*(volatile struct CUSTOM *)(zTwoBase+CUSTOM_PHYSADDR)))
+#define amiga_custom ((*(volatile struct CUSTOM *)(zTwoBase+CUSTOM_PHYSADDR)))
 
 #define CIAA_PHYSADDR	  (0xbfe001)
 #define CIAB_PHYSADDR	  (0xbfd000)
@@ -294,12 +294,12 @@
 {
 	if (amiga_chipset == CS_ECS || amiga_chipset == CS_AGA) {
 		/* program Denise/Lisa for a higher maximum play rate */
-		custom.htotal = 113;        /* 31 kHz */
-		custom.vtotal = 223;        /* 70 Hz */
-		custom.beamcon0 = 0x4390;   /* HARDDIS, VAR{BEAM,VSY,HSY,CSY}EN */
+		amiga_custom.htotal = 113;        /* 31 kHz */
+		amiga_custom.vtotal = 223;        /* 70 Hz */
+		amiga_custom.beamcon0 = 0x4390;   /* HARDDIS, VAR{BEAM,VSY,HSY,CSY}EN */
 		/* suspend the monitor */
-		custom.hsstrt = custom.hsstop = 116;
-		custom.vsstrt = custom.vsstop = 226;
+		amiga_custom.hsstrt = amiga_custom.hsstop = 116;
+		amiga_custom.vsstrt = amiga_custom.vsstop = 226;
 		amiga_audio_min_period = 57;
 	}
 }
diff --git a/include/asm-m68k/amigaints.h b/include/asm-m68k/amigaints.h
index 2aff4cf..aa968d0 100644
--- a/include/asm-m68k/amigaints.h
+++ b/include/asm-m68k/amigaints.h
@@ -109,8 +109,6 @@
 extern void amiga_do_irq(int irq, struct pt_regs *fp);
 extern void amiga_do_irq_list(int irq, struct pt_regs *fp);
 
-extern unsigned short amiga_intena_vals[];
-
 /* CIA interrupt control register bits */
 
 #define CIA_ICR_TA	0x01
diff --git a/include/asm-m68k/checksum.h b/include/asm-m68k/checksum.h
index 78860c2..17280ef 100644
--- a/include/asm-m68k/checksum.h
+++ b/include/asm-m68k/checksum.h
@@ -25,7 +25,7 @@
  * better 64-bit) boundary
  */
 
-extern unsigned int csum_partial_copy_from_user(const unsigned char *src,
+extern unsigned int csum_partial_copy_from_user(const unsigned char __user *src,
 						unsigned char *dst,
 						int len, int sum,
 						int *csum_err);
diff --git a/include/asm-m68k/dsp56k.h b/include/asm-m68k/dsp56k.h
index ab3dd33..2d8c0c9 100644
--- a/include/asm-m68k/dsp56k.h
+++ b/include/asm-m68k/dsp56k.h
@@ -13,7 +13,7 @@
 /* Used for uploading DSP binary code */
 struct dsp56k_upload {
 	int len;
-	char *bin;
+	char __user *bin;
 };
 
 /* For the DSP host flags */
diff --git a/include/asm-m68k/floppy.h b/include/asm-m68k/floppy.h
index c6e708d..63a05ed 100644
--- a/include/asm-m68k/floppy.h
+++ b/include/asm-m68k/floppy.h
@@ -46,7 +46,7 @@
 
 static int virtual_dma_count=0;
 static int virtual_dma_residue=0;
-static char *virtual_dma_addr=0;
+static char *virtual_dma_addr=NULL;
 static int virtual_dma_mode=0;
 static int doing_pdma=0;
 
diff --git a/include/asm-m68k/hardirq.h b/include/asm-m68k/hardirq.h
index 728318b..5e1c5826 100644
--- a/include/asm-m68k/hardirq.h
+++ b/include/asm-m68k/hardirq.h
@@ -14,13 +14,4 @@
 
 #define HARDIRQ_BITS	8
 
-/*
- * The hardirq mask has to be large enough to have
- * space for potentially all IRQ sources in the system
- * nesting on a single CPU:
- */
-#if (1 << HARDIRQ_BITS) < NR_IRQS
-# error HARDIRQ_BITS is too low!
-#endif
-
 #endif
diff --git a/include/asm-m68k/io.h b/include/asm-m68k/io.h
index 6bb8b0d..dcfaa35 100644
--- a/include/asm-m68k/io.h
+++ b/include/asm-m68k/io.h
@@ -24,6 +24,7 @@
 #ifdef __KERNEL__
 
 #include <linux/config.h>
+#include <linux/compiler.h>
 #include <asm/raw_io.h>
 #include <asm/virtconvert.h>
 
@@ -120,68 +121,68 @@
  * be compiled in so the case statement will be optimised away
  */
 
-static inline u8 *isa_itb(unsigned long addr)
+static inline u8 __iomem *isa_itb(unsigned long addr)
 {
   switch(ISA_TYPE)
     {
 #ifdef CONFIG_Q40
-    case Q40_ISA: return (u8 *)Q40_ISA_IO_B(addr);
+    case Q40_ISA: return (u8 __iomem *)Q40_ISA_IO_B(addr);
 #endif
 #ifdef CONFIG_GG2
-    case GG2_ISA: return (u8 *)GG2_ISA_IO_B(addr);
+    case GG2_ISA: return (u8 __iomem *)GG2_ISA_IO_B(addr);
 #endif
 #ifdef CONFIG_AMIGA_PCMCIA
-    case AG_ISA: return (u8 *)AG_ISA_IO_B(addr);
+    case AG_ISA: return (u8 __iomem *)AG_ISA_IO_B(addr);
 #endif
-    default: return 0; /* avoid warnings, just in case */
+    default: return NULL; /* avoid warnings, just in case */
     }
 }
-static inline u16 *isa_itw(unsigned long addr)
+static inline u16 __iomem *isa_itw(unsigned long addr)
 {
   switch(ISA_TYPE)
     {
 #ifdef CONFIG_Q40
-    case Q40_ISA: return (u16 *)Q40_ISA_IO_W(addr);
+    case Q40_ISA: return (u16 __iomem *)Q40_ISA_IO_W(addr);
 #endif
 #ifdef CONFIG_GG2
-    case GG2_ISA: return (u16 *)GG2_ISA_IO_W(addr);
+    case GG2_ISA: return (u16 __iomem *)GG2_ISA_IO_W(addr);
 #endif
 #ifdef CONFIG_AMIGA_PCMCIA
-    case AG_ISA: return (u16 *)AG_ISA_IO_W(addr);
+    case AG_ISA: return (u16 __iomem *)AG_ISA_IO_W(addr);
 #endif
-    default: return 0; /* avoid warnings, just in case */
+    default: return NULL; /* avoid warnings, just in case */
     }
 }
-static inline u8 *isa_mtb(unsigned long addr)
+static inline u8 __iomem *isa_mtb(unsigned long addr)
 {
   switch(ISA_TYPE)
     {
 #ifdef CONFIG_Q40
-    case Q40_ISA: return (u8 *)Q40_ISA_MEM_B(addr);
+    case Q40_ISA: return (u8 __iomem *)Q40_ISA_MEM_B(addr);
 #endif
 #ifdef CONFIG_GG2
-    case GG2_ISA: return (u8 *)GG2_ISA_MEM_B(addr);
+    case GG2_ISA: return (u8 __iomem *)GG2_ISA_MEM_B(addr);
 #endif
 #ifdef CONFIG_AMIGA_PCMCIA
-    case AG_ISA: return (u8 *)addr;
+    case AG_ISA: return (u8 __iomem *)addr;
 #endif
-    default: return 0; /* avoid warnings, just in case */
+    default: return NULL; /* avoid warnings, just in case */
     }
 }
-static inline u16 *isa_mtw(unsigned long addr)
+static inline u16 __iomem *isa_mtw(unsigned long addr)
 {
   switch(ISA_TYPE)
     {
 #ifdef CONFIG_Q40
-    case Q40_ISA: return (u16 *)Q40_ISA_MEM_W(addr);
+    case Q40_ISA: return (u16 __iomem *)Q40_ISA_MEM_W(addr);
 #endif
 #ifdef CONFIG_GG2
-    case GG2_ISA: return (u16 *)GG2_ISA_MEM_W(addr);
+    case GG2_ISA: return (u16 __iomem *)GG2_ISA_MEM_W(addr);
 #endif
 #ifdef CONFIG_AMIGA_PCMCIA
-    case AG_ISA: return (u16 *)addr;
+    case AG_ISA: return (u16 __iomem *)addr;
 #endif
-    default: return 0; /* avoid warnings, just in case */
+    default: return NULL; /* avoid warnings, just in case */
     }
 }
 
@@ -326,20 +327,20 @@
 
 #define mmiowb()
 
-static inline void *ioremap(unsigned long physaddr, unsigned long size)
+static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
 }
-static inline void *ioremap_nocache(unsigned long physaddr, unsigned long size)
+static inline void __iomem *ioremap_nocache(unsigned long physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
 }
-static inline void *ioremap_writethrough(unsigned long physaddr,
+static inline void __iomem *ioremap_writethrough(unsigned long physaddr,
 					 unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
 }
-static inline void *ioremap_fullcache(unsigned long physaddr,
+static inline void __iomem *ioremap_fullcache(unsigned long physaddr,
 				      unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
diff --git a/include/asm-m68k/irq.h b/include/asm-m68k/irq.h
index 127ad19..325c86f 100644
--- a/include/asm-m68k/irq.h
+++ b/include/asm-m68k/irq.h
@@ -23,6 +23,15 @@
 #endif
 
 /*
+ * The hardirq mask has to be large enough to have
+ * space for potentially all IRQ sources in the system
+ * nesting on a single CPU:
+ */
+#if (1 << HARDIRQ_BITS) < NR_IRQS
+# error HARDIRQ_BITS is too low!
+#endif
+
+/*
  * Interrupt source definitions
  * General interrupt sources are the level 1-7.
  * Adding an interrupt service routine for one of these sources
diff --git a/include/asm-m68k/machdep.h b/include/asm-m68k/machdep.h
index a0dd5c4..7d3fee3 100644
--- a/include/asm-m68k/machdep.h
+++ b/include/asm-m68k/machdep.h
@@ -34,7 +34,6 @@
 extern unsigned long (*mach_hd_init) (unsigned long, unsigned long);
 extern void (*mach_hd_setup)(char *, int *);
 extern long mach_max_dma_address;
-extern void (*mach_floppy_setup)(char *, int *);
 extern void (*mach_heartbeat) (int);
 extern void (*mach_l2_flush) (int);
 extern void (*mach_beep) (unsigned int, unsigned int);
diff --git a/include/asm-m68k/raw_io.h b/include/asm-m68k/raw_io.h
index 041f0a8..5439bca 100644
--- a/include/asm-m68k/raw_io.h
+++ b/include/asm-m68k/raw_io.h
@@ -19,9 +19,9 @@
 #define IOMAP_NOCACHE_NONSER		2
 #define IOMAP_WRITETHROUGH		3
 
-extern void iounmap(void *addr);
+extern void iounmap(void __iomem *addr);
 
-extern void *__ioremap(unsigned long physaddr, unsigned long size,
+extern void __iomem *__ioremap(unsigned long physaddr, unsigned long size,
 		       int cacheflag);
 extern void __iounmap(void *addr, unsigned long size);
 
@@ -30,21 +30,21 @@
  * two accesses to memory, which may be undesirable for some devices.
  */
 #define in_8(addr) \
-    ({ u8 __v = (*(volatile u8 *) (addr)); __v; })
+    ({ u8 __v = (*(__force volatile u8 *) (addr)); __v; })
 #define in_be16(addr) \
-    ({ u16 __v = (*(volatile u16 *) (addr)); __v; })
+    ({ u16 __v = (*(__force volatile u16 *) (addr)); __v; })
 #define in_be32(addr) \
-    ({ u32 __v = (*(volatile u32 *) (addr)); __v; })
+    ({ u32 __v = (*(__force volatile u32 *) (addr)); __v; })
 #define in_le16(addr) \
-    ({ u16 __v = le16_to_cpu(*(volatile u16 *) (addr)); __v; })
+    ({ u16 __v = le16_to_cpu(*(__force volatile u16 *) (addr)); __v; })
 #define in_le32(addr) \
-    ({ u32 __v = le32_to_cpu(*(volatile u32 *) (addr)); __v; })
+    ({ u32 __v = le32_to_cpu(*(__force volatile u32 *) (addr)); __v; })
 
-#define out_8(addr,b) (void)((*(volatile u8 *) (addr)) = (b))
-#define out_be16(addr,w) (void)((*(volatile u16 *) (addr)) = (w))
-#define out_be32(addr,l) (void)((*(volatile u32 *) (addr)) = (l))
-#define out_le16(addr,w) (void)((*(volatile u16 *) (addr)) = cpu_to_le16(w))
-#define out_le32(addr,l) (void)((*(volatile u32 *) (addr)) = cpu_to_le32(l))
+#define out_8(addr,b) (void)((*(__force volatile u8 *) (addr)) = (b))
+#define out_be16(addr,w) (void)((*(__force volatile u16 *) (addr)) = (w))
+#define out_be32(addr,l) (void)((*(__force volatile u32 *) (addr)) = (l))
+#define out_le16(addr,w) (void)((*(__force volatile u16 *) (addr)) = cpu_to_le16(w))
+#define out_le32(addr,l) (void)((*(__force volatile u32 *) (addr)) = cpu_to_le32(l))
 
 #define raw_inb in_8
 #define raw_inw in_be16
@@ -54,7 +54,7 @@
 #define raw_outw(val,port) out_be16((port),(val))
 #define raw_outl(val,port) out_be32((port),(val))
 
-static inline void raw_insb(volatile u8 *port, u8 *buf, unsigned int len)
+static inline void raw_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len)
 {
 	unsigned int i;
 
@@ -62,7 +62,7 @@
 		*buf++ = in_8(port);
 }
 
-static inline void raw_outsb(volatile u8 *port, const u8 *buf,
+static inline void raw_outsb(volatile u8 __iomem *port, const u8 *buf,
 			     unsigned int len)
 {
 	unsigned int i;
@@ -71,7 +71,7 @@
 		out_8(port, *buf++);
 }
 
-static inline void raw_insw(volatile u16 *port, u16 *buf, unsigned int nr)
+static inline void raw_insw(volatile u16 __iomem *port, u16 *buf, unsigned int nr)
 {
 	unsigned int tmp;
 
@@ -110,7 +110,7 @@
 	}
 }
 
-static inline void raw_outsw(volatile u16 *port, const u16 *buf,
+static inline void raw_outsw(volatile u16 __iomem *port, const u16 *buf,
 			     unsigned int nr)
 {
 	unsigned int tmp;
@@ -150,7 +150,7 @@
 	}
 }
 
-static inline void raw_insl(volatile u32 *port, u32 *buf, unsigned int nr)
+static inline void raw_insl(volatile u32 __iomem *port, u32 *buf, unsigned int nr)
 {
 	unsigned int tmp;
 
@@ -189,7 +189,7 @@
 	}
 }
 
-static inline void raw_outsl(volatile u32 *port, const u32 *buf,
+static inline void raw_outsl(volatile u32 __iomem *port, const u32 *buf,
 			     unsigned int nr)
 {
 	unsigned int tmp;
@@ -230,7 +230,7 @@
 }
 
 
-static inline void raw_insw_swapw(volatile u16 *port, u16 *buf,
+static inline void raw_insw_swapw(volatile u16 __iomem *port, u16 *buf,
 				  unsigned int nr)
 {
     if ((nr) % 8)
@@ -283,7 +283,7 @@
 		: "d0", "a0", "a1", "d6");
 }
 
-static inline void raw_outsw_swapw(volatile u16 *port, const u16 *buf,
+static inline void raw_outsw_swapw(volatile u16 __iomem *port, const u16 *buf,
 				   unsigned int nr)
 {
     if ((nr) % 8)
diff --git a/include/asm-m68k/signal.h b/include/asm-m68k/signal.h
index a0cdf90..b7b7ea2 100644
--- a/include/asm-m68k/signal.h
+++ b/include/asm-m68k/signal.h
@@ -144,7 +144,7 @@
 #endif /* __KERNEL__ */
 
 typedef struct sigaltstack {
-	void *ss_sp;
+	void __user *ss_sp;
 	int ss_flags;
 	size_t ss_size;
 } stack_t;
diff --git a/include/asm-m68k/sun3_pgtable.h b/include/asm-m68k/sun3_pgtable.h
index e974bb0..5156a28 100644
--- a/include/asm-m68k/sun3_pgtable.h
+++ b/include/asm-m68k/sun3_pgtable.h
@@ -211,7 +211,7 @@
 	return pte.pte & SUN3_PAGE_PGNUM_MASK;
 }
 
-static inline pte_t pgoff_to_pte(inline unsigned off)
+static inline pte_t pgoff_to_pte(unsigned off)
 {
 	pte_t pte = { off + SUN3_PAGE_ACCESSED };
 	return pte;
diff --git a/include/asm-m68k/sun3ints.h b/include/asm-m68k/sun3ints.h
index fd838eb..bd038fc 100644
--- a/include/asm-m68k/sun3ints.h
+++ b/include/asm-m68k/sun3ints.h
@@ -31,7 +31,6 @@
 		    );
 extern void sun3_init_IRQ (void);
 extern irqreturn_t (*sun3_default_handler[]) (int, void *, struct pt_regs *);
-extern irqreturn_t (*sun3_inthandler[]) (int, void *, struct pt_regs *);
 extern void sun3_free_irq (unsigned int irq, void *dev_id);
 extern void sun3_enable_interrupts (void);
 extern void sun3_disable_interrupts (void);
diff --git a/include/asm-m68k/sun3xflop.h b/include/asm-m68k/sun3xflop.h
index fda1ecc..98a9f79 100644
--- a/include/asm-m68k/sun3xflop.h
+++ b/include/asm-m68k/sun3xflop.h
@@ -208,7 +208,7 @@
 
 	if(!once) {
 		once = 1;
-		error = request_irq(FLOPPY_IRQ, sun3xflop_hardint, SA_INTERRUPT, "floppy", 0);
+		error = request_irq(FLOPPY_IRQ, sun3xflop_hardint, SA_INTERRUPT, "floppy", NULL);
 		return ((error == 0) ? 0 : -1);
 	} else return 0;
 }
@@ -238,7 +238,7 @@
 	*sun3x_fdc.fcr_r = 0;
 
 	/* Success... */
-	floppy_set_flags(0, 1, FD_BROKEN_DCL); // I don't know how to detect this.
+	floppy_set_flags(NULL, 1, FD_BROKEN_DCL); // I don't know how to detect this.
 	allowed_drive_mask = 0x01;
 	return (int) SUN3X_FDC;
 }
diff --git a/include/asm-m68k/thread_info.h b/include/asm-m68k/thread_info.h
index 9532ca3..c4d622a 100644
--- a/include/asm-m68k/thread_info.h
+++ b/include/asm-m68k/thread_info.h
@@ -37,6 +37,7 @@
 #define init_stack		(init_thread_union.stack)
 
 #define task_thread_info(tsk)	(&(tsk)->thread.info)
+#define task_stack_page(tsk)	((void *)(tsk)->thread_info)
 #define current_thread_info()	task_thread_info(current)
 
 #define __HAVE_THREAD_FUNCTIONS
diff --git a/include/asm-m68k/uaccess.h b/include/asm-m68k/uaccess.h
index f5cedf1..2ffd87b 100644
--- a/include/asm-m68k/uaccess.h
+++ b/include/asm-m68k/uaccess.h
@@ -42,6 +42,7 @@
 ({							\
     int __pu_err;					\
     typeof(*(ptr)) __pu_val = (x);			\
+    __chk_user_ptr(ptr);				\
     switch (sizeof (*(ptr))) {				\
     case 1:						\
 	__put_user_asm(__pu_err, __pu_val, ptr, b);	\
@@ -91,6 +92,7 @@
 ({								\
     int __gu_err;						\
     typeof(*(ptr)) __gu_val;					\
+    __chk_user_ptr(ptr);					\
     switch (sizeof(*(ptr))) {					\
     case 1:							\
 	__get_user_asm(__gu_err, __gu_val, ptr, b, "=d");	\
@@ -105,7 +107,7 @@
         __gu_err = __constant_copy_from_user(&__gu_val, ptr, 8);  \
         break;                                                  \
     default:							\
-	__gu_val = 0;						\
+	__gu_val = (typeof(*(ptr)))0;				\
 	__gu_err = __get_user_bad();				\
 	break;							\
     }								\
@@ -134,7 +136,7 @@
      : "m"(*(ptr)), "i" (-EFAULT), "0"(0))
 
 static inline unsigned long
-__generic_copy_from_user(void *to, const void *from, unsigned long n)
+__generic_copy_from_user(void *to, const void __user *from, unsigned long n)
 {
     unsigned long tmp;
     __asm__ __volatile__
@@ -189,7 +191,7 @@
 }
 
 static inline unsigned long
-__generic_copy_to_user(void *to, const void *from, unsigned long n)
+__generic_copy_to_user(void __user *to, const void *from, unsigned long n)
 {
     unsigned long tmp;
     __asm__ __volatile__
@@ -264,7 +266,7 @@
 	 : "d0", "memory")
 
 static inline unsigned long
-__constant_copy_from_user(void *to, const void *from, unsigned long n)
+__constant_copy_from_user(void *to, const void __user *from, unsigned long n)
 {
     switch (n) {
     case 0:
@@ -520,7 +522,7 @@
 #define __copy_from_user_inatomic __copy_from_user
 
 static inline unsigned long
-__constant_copy_to_user(void *to, const void *from, unsigned long n)
+__constant_copy_to_user(void __user *to, const void *from, unsigned long n)
 {
     switch (n) {
     case 0:
@@ -766,7 +768,7 @@
  */
 
 static inline long
-strncpy_from_user(char *dst, const char *src, long count)
+strncpy_from_user(char *dst, const char __user *src, long count)
 {
     long res;
     if (count == 0) return count;
@@ -799,11 +801,11 @@
  *
  * Return 0 on exception, a value greater than N if too long
  */
-static inline long strnlen_user(const char *src, long n)
+static inline long strnlen_user(const char __user *src, long n)
 {
 	long res;
 
-	res = -(long)src;
+	res = -(unsigned long)src;
 	__asm__ __volatile__
 		("1:\n"
 		 "   tstl %2\n"
@@ -842,7 +844,7 @@
  */
 
 static inline unsigned long
-clear_user(void *to, unsigned long n)
+clear_user(void __user *to, unsigned long n)
 {
     __asm__ __volatile__
 	("   tstl %1\n"
diff --git a/include/asm-m68k/zorro.h b/include/asm-m68k/zorro.h
index cf81658..5ce97c2 100644
--- a/include/asm-m68k/zorro.h
+++ b/include/asm-m68k/zorro.h
@@ -15,24 +15,24 @@
 #define z_memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
 #define z_memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
 
-static inline void *z_remap_nocache_ser(unsigned long physaddr,
+static inline void __iomem *z_remap_nocache_ser(unsigned long physaddr,
 					unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
 }
 
-static inline void *z_remap_nocache_nonser(unsigned long physaddr,
+static inline void __iomem *z_remap_nocache_nonser(unsigned long physaddr,
 					   unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_NOCACHE_NONSER);
 }
 
-static inline void *z_remap_writethrough(unsigned long physaddr,
+static inline void __iomem *z_remap_writethrough(unsigned long physaddr,
 					 unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
 }
-static inline void *z_remap_fullcache(unsigned long physaddr,
+static inline void __iomem *z_remap_fullcache(unsigned long physaddr,
 				      unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
diff --git a/include/asm-m68knommu/machdep.h b/include/asm-m68knommu/machdep.h
index 5a9f9c29..27c90af 100644
--- a/include/asm-m68knommu/machdep.h
+++ b/include/asm-m68knommu/machdep.h
@@ -38,7 +38,6 @@
 extern unsigned long (*mach_hd_init) (unsigned long, unsigned long);
 extern void (*mach_hd_setup)(char *, int *);
 extern long mach_max_dma_address;
-extern void (*mach_floppy_setup)(char *, int *);
 extern void (*mach_floppy_eject)(void);
 extern void (*mach_heartbeat) (int);
 extern void (*mach_l2_flush) (int);
diff --git a/include/asm-m68knommu/thread_info.h b/include/asm-m68knommu/thread_info.h
index 7b9a3fa..b8f009e 100644
--- a/include/asm-m68knommu/thread_info.h
+++ b/include/asm-m68knommu/thread_info.h
@@ -75,8 +75,6 @@
 #define alloc_thread_info(tsk) ((struct thread_info *) \
 				__get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER))
 #define free_thread_info(ti)	free_pages((unsigned long) (ti), THREAD_SIZE_ORDER)
-#define get_thread_info(ti)	get_task_struct((ti)->task)
-#define put_thread_info(ti)	put_task_struct((ti)->task)
 #endif /* __ASSEMBLY__ */
 
 #define	PREEMPT_ACTIVE	0x4000000
diff --git a/include/asm-mips/mach-ip27/topology.h b/include/asm-mips/mach-ip27/topology.h
index 82141c7..59d26b5 100644
--- a/include/asm-mips/mach-ip27/topology.h
+++ b/include/asm-mips/mach-ip27/topology.h
@@ -27,7 +27,6 @@
 	.max_interval		= 32,			\
 	.busy_factor		= 32,			\
 	.imbalance_pct		= 125,			\
-	.cache_hot_time		= (10*1000),		\
 	.cache_nice_tries	= 1,			\
 	.per_cpu_gain		= 100,			\
 	.flags			= SD_LOAD_BALANCE	\
diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h
index de53055..39d2bd5 100644
--- a/include/asm-mips/processor.h
+++ b/include/asm-mips/processor.h
@@ -200,11 +200,11 @@
 
 unsigned long get_wchan(struct task_struct *p);
 
-#define __PT_REG(reg) ((long)&((struct pt_regs *)0)->reg - sizeof(struct pt_regs))
-#define __KSTK_TOS(tsk) ((unsigned long)(tsk->thread_info) + THREAD_SIZE - 32)
-#define KSTK_EIP(tsk) (*(unsigned long *)(__KSTK_TOS(tsk) + __PT_REG(cp0_epc)))
-#define KSTK_ESP(tsk) (*(unsigned long *)(__KSTK_TOS(tsk) + __PT_REG(regs[29])))
-#define KSTK_STATUS(tsk) (*(unsigned long *)(__KSTK_TOS(tsk) + __PT_REG(cp0_status)))
+#define __KSTK_TOS(tsk) ((unsigned long)task_stack_page(tsk) + THREAD_SIZE - 32)
+#define task_pt_regs(tsk) ((struct pt_regs *)__KSTK_TOS(tsk) - 1)
+#define KSTK_EIP(tsk) (task_pt_regs(tsk)->cp0_epc)
+#define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[29])
+#define KSTK_STATUS(tsk) (task_pt_regs(tsk)->cp0_status)
 
 #define cpu_relax()	barrier()
 
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
index 330c4e4..e8e5d41 100644
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -159,11 +159,21 @@
 do {									\
 	if (cpu_has_dsp)						\
 		__save_dsp(prev);					\
-	(last) = resume(prev, next, next->thread_info);			\
+	(last) = resume(prev, next, task_thread_info(next));		\
 	if (cpu_has_dsp)						\
 		__restore_dsp(current);					\
 } while(0)
 
+/*
+ * On SMP systems, when the scheduler does migration-cost autodetection,
+ * it needs a way to flush as much of the CPU's caches as possible.
+ *
+ * TODO: fill this in!
+ */
+static inline void sched_cacheflush(void)
+{
+}
+
 static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
 {
 	__u32 retval;
diff --git a/include/asm-mips/thread_info.h b/include/asm-mips/thread_info.h
index e6c2447..1612b3f 100644
--- a/include/asm-mips/thread_info.h
+++ b/include/asm-mips/thread_info.h
@@ -97,8 +97,6 @@
 #endif
 
 #define free_thread_info(info) kfree(info)
-#define get_thread_info(ti) get_task_struct((ti)->task)
-#define put_thread_info(ti) put_task_struct((ti)->task)
 
 #endif /* !__ASSEMBLY__ */
 
diff --git a/include/asm-parisc/system.h b/include/asm-parisc/system.h
index f3928d3..a5a973c 100644
--- a/include/asm-parisc/system.h
+++ b/include/asm-parisc/system.h
@@ -49,6 +49,15 @@
 	(last) = _switch_to(prev, next);			\
 } while(0)
 
+/*
+ * On SMP systems, when the scheduler does migration-cost autodetection,
+ * it needs a way to flush as much of the CPU's caches as possible.
+ *
+ * TODO: fill this in!
+ */
+static inline void sched_cacheflush(void)
+{
+}
 
 
 /* interrupt control */
diff --git a/include/asm-parisc/thread_info.h b/include/asm-parisc/thread_info.h
index 57bbb76..ac32f14 100644
--- a/include/asm-parisc/thread_info.h
+++ b/include/asm-parisc/thread_info.h
@@ -43,9 +43,6 @@
 #define alloc_thread_info(tsk) ((struct thread_info *) \
 			__get_free_pages(GFP_KERNEL, THREAD_ORDER))
 #define free_thread_info(ti)    free_pages((unsigned long) (ti), THREAD_ORDER)
-#define get_thread_info(ti)     get_task_struct((ti)->task)
-#define put_thread_info(ti)     put_task_struct((ti)->task)
-
 
 /* how to get the thread information struct from C */
 #define current_thread_info()	((struct thread_info *)mfctl(30))
diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h
index 8a8393e..d5677cb 100644
--- a/include/asm-powerpc/iommu.h
+++ b/include/asm-powerpc/iommu.h
@@ -64,25 +64,6 @@
 
 #endif /* CONFIG_PPC_MULTIPLATFORM */
 
-#ifdef CONFIG_PPC_PSERIES
-
-/* Creates table for an individual device node */
-extern void iommu_devnode_init_pSeries(struct device_node *dn);
-
-#endif /* CONFIG_PPC_PSERIES */
-
-#ifdef CONFIG_PPC_ISERIES
-
-/* Creates table for an individual device node */
-extern void iommu_devnode_init_iSeries(struct device_node *dn);
-/* Get table parameters from HV */
-extern void iommu_table_getparms_iSeries(unsigned long busno,
-					 unsigned char slotno,
-					 unsigned char virtbus,
-					 struct iommu_table* tbl);
-
-#endif /* CONFIG_PPC_ISERIES */
-
 /* Initializes an iommu_table based in values set in the passed-in
  * structure
  */
diff --git a/include/asm-powerpc/iseries/hv_call.h b/include/asm-powerpc/iseries/hv_call.h
index e9f831c..162d653 100644
--- a/include/asm-powerpc/iseries/hv_call.h
+++ b/include/asm-powerpc/iseries/hv_call.h
@@ -1,5 +1,4 @@
 /*
- * HvCall.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
  *
  * This program is free software; you can redistribute it and/or modify
@@ -15,8 +14,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-/*
+ *
  * This file contains the "hypervisor call" interface which is used to
  * drive the hypervisor from the OS.
  */
diff --git a/include/asm-powerpc/iseries/hv_call_event.h b/include/asm-powerpc/iseries/hv_call_event.h
index 46763a3..4cec476 100644
--- a/include/asm-powerpc/iseries/hv_call_event.h
+++ b/include/asm-powerpc/iseries/hv_call_event.h
@@ -1,5 +1,4 @@
 /*
- * HvCallEvent.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
  *
  * This program is free software; you can redistribute it and/or modify
@@ -15,8 +14,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-/*
+ *
  * This file contains the "hypervisor call" interface which is used to
  * drive the hypervisor from the OS.
  */
@@ -33,32 +31,9 @@
 typedef u8 HvLpEvent_AckInd;
 typedef u8 HvLpEvent_AckType;
 
-struct	HvCallEvent_PackedParms {
-	u8		xAckType:1;
-	u8		xAckInd:1;
-	u8		xRsvd:1;
-	u8		xTargetLp:5;
-	u8		xType;
-	u16		xSubtype;
-	HvLpInstanceId	xSourceInstId;
-	HvLpInstanceId	xTargetInstId;
-};
-
 typedef u8 HvLpDma_Direction;
 typedef u8 HvLpDma_AddressType;
 
-struct	HvCallEvent_PackedDmaParms {
-	u8		xDirection:1;
-	u8		xLocalAddrType:1;
-	u8		xRemoteAddrType:1;
-	u8		xRsvd1:5;
-	HvLpIndex	xRemoteLp;
-	u8		xType;
-	u8		xRsvd2;
-	HvLpInstanceId	xLocalInstId;
-	HvLpInstanceId	xRemoteInstId;
-};
-
 typedef u64 HvLpEvent_Rc;
 typedef u64 HvLpDma_Rc;
 
@@ -92,11 +67,8 @@
 static inline void HvCallEvent_setLpEventStack(u8 queueIndex,
 		char *eventStackAddr, u32 eventStackSize)
 {
-	u64 abs_addr;
-
-	abs_addr = virt_to_abs(eventStackAddr);
-	HvCall3(HvCallEventSetLpEventStack, queueIndex, abs_addr,
-			eventStackSize);
+	HvCall3(HvCallEventSetLpEventStack, queueIndex,
+			virt_to_abs(eventStackAddr), eventStackSize);
 }
 
 static inline void HvCallEvent_setLpEventQueueInterruptProc(u8 queueIndex,
@@ -108,14 +80,7 @@
 
 static inline HvLpEvent_Rc HvCallEvent_signalLpEvent(struct HvLpEvent *event)
 {
-	u64 abs_addr;
-
-#ifdef DEBUG_SENDEVENT
-	printk("HvCallEvent_signalLpEvent: *event = %016lx\n ",
-			(unsigned long)event);
-#endif
-	abs_addr = virt_to_abs(event);
-	return HvCall1(HvCallEventSignalLpEvent, abs_addr);
+	return HvCall1(HvCallEventSignalLpEvent, virt_to_abs(event));
 }
 
 static inline HvLpEvent_Rc HvCallEvent_signalLpEventFast(HvLpIndex targetLp,
@@ -127,17 +92,21 @@
 {
 	/* Pack the misc bits into a single Dword to pass to PLIC */
 	union {
-		struct HvCallEvent_PackedParms	parms;
+		struct {
+			u8		ack_and_target;
+			u8		type;
+			u16		subtype;
+			HvLpInstanceId	src_inst;
+			HvLpInstanceId	target_inst;
+		} parms;
 		u64		dword;
 	} packed;
-	packed.parms.xAckType	= ackType;
-	packed.parms.xAckInd	= ackInd;
-	packed.parms.xRsvd	= 0;
-	packed.parms.xTargetLp	= targetLp;
-	packed.parms.xType	= type;
-	packed.parms.xSubtype	= subtype;
-	packed.parms.xSourceInstId	= sourceInstanceId;
-	packed.parms.xTargetInstId	= targetInstanceId;
+
+	packed.parms.ack_and_target = (ackType << 7) | (ackInd << 6) | targetLp;
+	packed.parms.type = type;
+	packed.parms.subtype = subtype;
+	packed.parms.src_inst = sourceInstanceId;
+	packed.parms.target_inst = targetInstanceId;
 
 	return HvCall7(HvCallEventSignalLpEventParms, packed.dword,
 			correlationToken, eventData1, eventData2,
@@ -146,18 +115,12 @@
 
 static inline HvLpEvent_Rc HvCallEvent_ackLpEvent(struct HvLpEvent *event)
 {
-	u64 abs_addr;
-
-	abs_addr = virt_to_abs(event);
-	return HvCall1(HvCallEventAckLpEvent, abs_addr);
+	return HvCall1(HvCallEventAckLpEvent, virt_to_abs(event));
 }
 
 static inline HvLpEvent_Rc HvCallEvent_cancelLpEvent(struct HvLpEvent *event)
 {
-	u64 abs_addr;
-
-	abs_addr = virt_to_abs(event);
-	return HvCall1(HvCallEventCancelLpEvent, abs_addr);
+	return HvCall1(HvCallEventCancelLpEvent, virt_to_abs(event));
 }
 
 static inline HvLpInstanceId HvCallEvent_getSourceLpInstanceId(
@@ -195,59 +158,34 @@
 {
 	/* Pack the misc bits into a single Dword to pass to PLIC */
 	union {
-		struct HvCallEvent_PackedDmaParms	parms;
+		struct {
+			u8		flags;
+			HvLpIndex	remote;
+			u8		type;
+			u8		reserved;
+			HvLpInstanceId	local_inst;
+			HvLpInstanceId	remote_inst;
+		} parms;
 		u64		dword;
 	} packed;
 
-	packed.parms.xDirection		= direction;
-	packed.parms.xLocalAddrType	= localAddressType;
-	packed.parms.xRemoteAddrType	= remoteAddressType;
-	packed.parms.xRsvd1		= 0;
-	packed.parms.xRemoteLp		= remoteLp;
-	packed.parms.xType		= type;
-	packed.parms.xRsvd2		= 0;
-	packed.parms.xLocalInstId	= localInstanceId;
-	packed.parms.xRemoteInstId	= remoteInstanceId;
+	packed.parms.flags = (direction << 7) |
+		(localAddressType << 6) | (remoteAddressType << 5);
+	packed.parms.remote = remoteLp;
+	packed.parms.type = type;
+	packed.parms.reserved = 0;
+	packed.parms.local_inst = localInstanceId;
+	packed.parms.remote_inst = remoteInstanceId;
 
 	return HvCall4(HvCallEventDmaBufList, packed.dword, localBufList,
 			remoteBufList, transferLength);
 }
 
-static inline HvLpDma_Rc HvCallEvent_dmaSingle(HvLpEvent_Type type,
-		HvLpIndex remoteLp, HvLpDma_Direction direction,
-		HvLpInstanceId localInstanceId,
-		HvLpInstanceId remoteInstanceId,
-		HvLpDma_AddressType localAddressType,
-		HvLpDma_AddressType remoteAddressType,
-		u64 localAddrOrTce, u64 remoteAddrOrTce, u32 transferLength)
-{
-	/* Pack the misc bits into a single Dword to pass to PLIC */
-	union {
-		struct HvCallEvent_PackedDmaParms	parms;
-		u64		dword;
-	} packed;
-
-	packed.parms.xDirection		= direction;
-	packed.parms.xLocalAddrType	= localAddressType;
-	packed.parms.xRemoteAddrType	= remoteAddressType;
-	packed.parms.xRsvd1		= 0;
-	packed.parms.xRemoteLp		= remoteLp;
-	packed.parms.xType		= type;
-	packed.parms.xRsvd2		= 0;
-	packed.parms.xLocalInstId	= localInstanceId;
-	packed.parms.xRemoteInstId	= remoteInstanceId;
-
-	return (HvLpDma_Rc)HvCall4(HvCallEventDmaSingle, packed.dword,
-			localAddrOrTce, remoteAddrOrTce, transferLength);
-}
-
 static inline HvLpDma_Rc HvCallEvent_dmaToSp(void *local, u32 remote,
 		u32 length, HvLpDma_Direction dir)
 {
-	u64 abs_addr;
-
-	abs_addr = virt_to_abs(local);
-	return HvCall4(HvCallEventDmaToSp, abs_addr, remote, length, dir);
+	return HvCall4(HvCallEventDmaToSp, virt_to_abs(local), remote,
+			length, dir);
 }
 
 #endif /* _ASM_POWERPC_ISERIES_HV_CALL_EVENT_H */
diff --git a/include/asm-powerpc/iseries/hv_call_sc.h b/include/asm-powerpc/iseries/hv_call_sc.h
index dec7e9d..f5d2109 100644
--- a/include/asm-powerpc/iseries/hv_call_sc.h
+++ b/include/asm-powerpc/iseries/hv_call_sc.h
@@ -1,5 +1,4 @@
 /*
- * HvCallSc.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/include/asm-powerpc/iseries/hv_lp_config.h b/include/asm-powerpc/iseries/hv_lp_config.h
index bc00f03..df8b207 100644
--- a/include/asm-powerpc/iseries/hv_lp_config.h
+++ b/include/asm-powerpc/iseries/hv_lp_config.h
@@ -1,5 +1,4 @@
 /*
- * HvLpConfig.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/include/asm-powerpc/iseries/hv_lp_event.h b/include/asm-powerpc/iseries/hv_lp_event.h
index 499ab1a..4065a4d 100644
--- a/include/asm-powerpc/iseries/hv_lp_event.h
+++ b/include/asm-powerpc/iseries/hv_lp_event.h
@@ -1,5 +1,4 @@
 /*
- * HvLpEvent.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
  *
  * This program is free software; you can redistribute it and/or modify
@@ -32,17 +31,8 @@
  * partitions through PLIC.
  */
 
-struct HvEventFlags {
-	u8	xValid:1;	/* Indicates a valid request	x00-x00 */
-	u8	xRsvd1:4;	/* Reserved			... */
-	u8	xAckType:1;	/* Immediate or deferred	... */
-	u8	xAckInd:1;	/* Indicates if ACK required	... */
-	u8	xFunction:1;	/* Interrupt or Acknowledge	... */
-};
-
-
 struct HvLpEvent {
-	struct HvEventFlags xFlags;	/* Event flags		      x00-x00 */
+	u8	flags;			/* Event flags		      x00-x00 */
 	u8	xType;			/* Type of message	      x01-x01 */
 	u16	xSubtype;		/* Subtype for event	      x02-x03 */
 	u8	xSourceLp;		/* Source LP		      x04-x04 */
@@ -126,6 +116,11 @@
 #define HvLpEvent_AckType_ImmediateAck 0
 #define HvLpEvent_AckType_DeferredAck 1
 
+#define HV_LP_EVENT_INT			0x01
+#define HV_LP_EVENT_DO_ACK		0x02
+#define HV_LP_EVENT_DEFERRED_ACK	0x04
+#define HV_LP_EVENT_VALID		0x80
+
 #define HvLpDma_Direction_LocalToRemote 0
 #define HvLpDma_Direction_RemoteToLocal 1
 
@@ -139,4 +134,29 @@
 #define HvLpDma_Rc_InvalidAddress 4
 #define HvLpDma_Rc_InvalidLength 5
 
+static inline int hvlpevent_is_valid(struct HvLpEvent *h)
+{
+	return h->flags & HV_LP_EVENT_VALID;
+}
+
+static inline void hvlpevent_invalidate(struct HvLpEvent *h)
+{
+	h->flags &= ~ HV_LP_EVENT_VALID;
+}
+
+static inline int hvlpevent_is_int(struct HvLpEvent *h)
+{
+	return h->flags & HV_LP_EVENT_INT;
+}
+
+static inline int hvlpevent_is_ack(struct HvLpEvent *h)
+{
+	return !hvlpevent_is_int(h);
+}
+
+static inline int hvlpevent_need_ack(struct HvLpEvent *h)
+{
+	return h->flags & HV_LP_EVENT_DO_ACK;
+}
+
 #endif /* _ASM_POWERPC_ISERIES_HV_LP_EVENT_H */
diff --git a/include/asm-powerpc/iseries/hv_types.h b/include/asm-powerpc/iseries/hv_types.h
index c38f7e3..c3e6d2a 100644
--- a/include/asm-powerpc/iseries/hv_types.h
+++ b/include/asm-powerpc/iseries/hv_types.h
@@ -1,5 +1,4 @@
 /*
- * HvTypes.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/include/asm-powerpc/iseries/iseries_io.h b/include/asm-powerpc/iseries/iseries_io.h
index 56b2113..496aa85 100644
--- a/include/asm-powerpc/iseries/iseries_io.h
+++ b/include/asm-powerpc/iseries/iseries_io.h
@@ -6,7 +6,7 @@
 #ifdef CONFIG_PPC_ISERIES
 #include <linux/types.h>
 /*
- * File iSeries_io.h created by Allan Trautman on Thu Dec 28 2000.
+ * Created by Allan Trautman on Thu Dec 28 2000.
  *
  * Remaps the io.h for the iSeries Io
  * Copyright (C) 2000  Allan H Trautman, IBM Corporation
@@ -32,6 +32,7 @@
  * End Change Activity
  */
 
+#ifdef CONFIG_PCI
 extern u8   iSeries_Read_Byte(const volatile void __iomem * IoAddress);
 extern u16  iSeries_Read_Word(const volatile void __iomem * IoAddress);
 extern u32  iSeries_Read_Long(const volatile void __iomem * IoAddress);
@@ -44,6 +45,17 @@
 		size_t n);
 extern void iSeries_memcpy_fromio(void *dest,
 		const volatile void __iomem *source, size_t n);
+#else
+static inline u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
+{
+	return 0xff;
+}
+
+static inline void iSeries_Write_Byte(u8 IoData,
+		volatile void __iomem *IoAddress)
+{
+}
+#endif	/* CONFIG_PCI */
 
 #endif /* CONFIG_PPC_ISERIES */
 #endif /* _ASM_POWERPC_ISERIES_ISERIES_IO_H */
diff --git a/include/asm-powerpc/iseries/it_exp_vpd_panel.h b/include/asm-powerpc/iseries/it_exp_vpd_panel.h
index 66a17a2..304a609 100644
--- a/include/asm-powerpc/iseries/it_exp_vpd_panel.h
+++ b/include/asm-powerpc/iseries/it_exp_vpd_panel.h
@@ -1,5 +1,4 @@
 /*
- * ItExtVpdPanel.h
  * Copyright (C) 2002  Dave Boutcher IBM Corporation
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/include/asm-powerpc/iseries/it_lp_naca.h b/include/asm-powerpc/iseries/it_lp_naca.h
index c3ef1de..4fdcf05 100644
--- a/include/asm-powerpc/iseries/it_lp_naca.h
+++ b/include/asm-powerpc/iseries/it_lp_naca.h
@@ -1,5 +1,4 @@
 /*
- * ItLpNaca.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
  *
  * This program is free software; you can redistribute it and/or modify
@@ -37,17 +36,13 @@
 	u8	xLpIndex;		// LP Index			x0B-x0B
 	u16	xMaxLpQueues;		// Number of allocated queues	x0C-x0D
 	u16	xLpQueueOffset;		// Offset to start of LP queues	x0E-x0F
-	u8	xPirEnvironMode:8;	// Piranha or hardware		x10-x10
-	u8	xPirConsoleMode:8;	// Piranha console indicator	x11-x11
-	u8	xPirDasdMode:8;		// Piranha dasd indicator	x12-x12
+	u8	xPirEnvironMode;	// Piranha or hardware		x10-x10
+	u8	xPirConsoleMode;	// Piranha console indicator	x11-x11
+	u8	xPirDasdMode;		// Piranha dasd indicator	x12-x12
 	u8	xRsvd1_0[5];		// Reserved for Piranha related	x13-x17
-	u8	xLparInstalled:1;	// Is LPAR installed on system	x18-x1F
-	u8	xSysPartitioned:1;	// Is the system partitioned	...
-	u8	xHwSyncedTBs:1;		// Hardware synced TBs		...
-	u8	xIntProcUtilHmt:1;	// Utilize HMT for interrupts	...
-	u8	xRsvd1_1:4;		// Reserved			...
-	u8	xSpVpdFormat:8;		// VPD areas are in CSP format	...
-	u8	xIntProcRatio:8;	// Ratio of int procs to procs	...
+	u8	flags;			// flags, see below		x18-x1F
+	u8	xSpVpdFormat;		// VPD areas are in CSP format	...
+	u8	xIntProcRatio;		// Ratio of int procs to procs	...
 	u8	xRsvd1_2[5];		// Reserved			...
 	u16	xRsvd1_3;		// Reserved			x20-x21
 	u16	xPlicVrmIndex;		// VRM index of PLIC		x22-x23
@@ -77,4 +72,9 @@
 
 extern struct ItLpNaca		itLpNaca;
 
+#define ITLPNACA_LPAR		0x80	/* Is LPAR installed on the system */
+#define ITLPNACA_PARTITIONED	0x40	/* Is the system partitioned */
+#define ITLPNACA_HWSYNCEDTBS	0x20	/* Hardware synced TBs */
+#define ITLPNACA_HMTINT		0x10	/* Utilize MHT for interrupts */
+
 #endif /* _ASM_POWERPC_ISERIES_IT_LP_NACA_H */
diff --git a/include/asm-powerpc/iseries/it_lp_queue.h b/include/asm-powerpc/iseries/it_lp_queue.h
index a60d03a..b7c6fc1 100644
--- a/include/asm-powerpc/iseries/it_lp_queue.h
+++ b/include/asm-powerpc/iseries/it_lp_queue.h
@@ -1,5 +1,4 @@
 /*
- * ItLpQueue.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/include/asm-powerpc/iseries/it_lp_reg_save.h b/include/asm-powerpc/iseries/it_lp_reg_save.h
index 81824e1..5403b75 100644
--- a/include/asm-powerpc/iseries/it_lp_reg_save.h
+++ b/include/asm-powerpc/iseries/it_lp_reg_save.h
@@ -1,5 +1,4 @@
 /*
- * ItLpRegSave.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
  *
  * This program is free software; you can redistribute it and/or modify
@@ -83,4 +82,4 @@
 
 extern struct ItLpRegSave iseries_reg_save[];
 
-#endif /* _ITLPREGSAVE_H */
+#endif /* _ASM_POWERPC_ISERIES_IT_LP_REG_SAVE_H */
diff --git a/include/asm-powerpc/iseries/lpar_map.h b/include/asm-powerpc/iseries/lpar_map.h
index 84fc321..2ec384d 100644
--- a/include/asm-powerpc/iseries/lpar_map.h
+++ b/include/asm-powerpc/iseries/lpar_map.h
@@ -1,5 +1,4 @@
 /*
- * LparMap.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/include/asm-powerpc/iseries/mf.h b/include/asm-powerpc/iseries/mf.h
index e7bd57a..857e520 100644
--- a/include/asm-powerpc/iseries/mf.h
+++ b/include/asm-powerpc/iseries/mf.h
@@ -1,5 +1,4 @@
 /*
- * mf.h
  * Copyright (C) 2001  Troy D. Armstrong IBM Corporation
  * Copyright (C) 2004  Stephen Rothwell IBM Corporation
  *
diff --git a/include/asm-powerpc/iseries/vio.h b/include/asm-powerpc/iseries/vio.h
index 7e3a469..72a97d3 100644
--- a/include/asm-powerpc/iseries/vio.h
+++ b/include/asm-powerpc/iseries/vio.h
@@ -1,5 +1,4 @@
 /* -*- linux-c -*-
- *  drivers/char/vio.h
  *
  *  iSeries Virtual I/O Message Path header
  *
diff --git a/include/asm-powerpc/pci-bridge.h b/include/asm-powerpc/pci-bridge.h
index b0d816f..38de92d 100644
--- a/include/asm-powerpc/pci-bridge.h
+++ b/include/asm-powerpc/pci-bridge.h
@@ -142,8 +142,6 @@
 
 extern int pcibios_remove_root_bus(struct pci_controller *phb);
 
-extern void phbs_remap_io(void);
-
 static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus)
 {
 	struct device_node *busdn = bus->sysdata;
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index 0c58e32..9b822af 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -133,6 +133,14 @@
 extern void cvt_fd(float *from, double *to, struct thread_struct *thread);
 extern void cvt_df(double *from, float *to, struct thread_struct *thread);
 
+#ifndef CONFIG_SMP
+extern void discard_lazy_cpu_state(void);
+#else
+static inline void discard_lazy_cpu_state(void)
+{
+}
+#endif
+
 #ifdef CONFIG_ALTIVEC
 extern void flush_altivec_to_thread(struct task_struct *);
 #else
@@ -175,6 +183,16 @@
 extern struct task_struct *_switch(struct thread_struct *prev,
 				   struct thread_struct *next);
 
+/*
+ * On SMP systems, when the scheduler does migration-cost autodetection,
+ * it needs a way to flush as much of the CPU's caches as possible.
+ *
+ * TODO: fill this in!
+ */
+static inline void sched_cacheflush(void)
+{
+}
+
 extern unsigned int rtas_data;
 extern int mem_init_done;	/* set on boot once kmalloc can be called */
 extern unsigned long memory_limit;
diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h
index ac1e80e..7e09d7c 100644
--- a/include/asm-powerpc/thread_info.h
+++ b/include/asm-powerpc/thread_info.h
@@ -89,9 +89,6 @@
 
 #endif /* THREAD_SHIFT < PAGE_SHIFT */
 
-#define get_thread_info(ti)	get_task_struct((ti)->task)
-#define put_thread_info(ti)	put_task_struct((ti)->task)
-
 /* how to get the thread information struct from C */
 static inline struct thread_info *current_thread_info(void)
 {
diff --git a/include/asm-powerpc/topology.h b/include/asm-powerpc/topology.h
index 9f3d4da..1e19cd0 100644
--- a/include/asm-powerpc/topology.h
+++ b/include/asm-powerpc/topology.h
@@ -39,7 +39,6 @@
 	.max_interval		= 32,			\
 	.busy_factor		= 32,			\
 	.imbalance_pct		= 125,			\
-	.cache_hot_time		= (10*1000000),		\
 	.cache_nice_tries	= 1,			\
 	.per_cpu_gain		= 100,			\
 	.busy_idx		= 3,			\
diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h
index bd99cb5..fb49c0c 100644
--- a/include/asm-ppc/system.h
+++ b/include/asm-ppc/system.h
@@ -4,7 +4,6 @@
 #ifndef __PPC_SYSTEM_H
 #define __PPC_SYSTEM_H
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 
 #include <asm/atomic.h>
@@ -39,7 +38,7 @@
 #ifdef CONFIG_SMP
 #define smp_mb()	mb()
 #define smp_rmb()	rmb()
-#define smp_wmb()	wmb()
+#define smp_wmb()	__asm__ __volatile__ ("eieio" : : : "memory")
 #define smp_read_barrier_depends()	read_barrier_depends()
 #else
 #define smp_mb()	barrier()
@@ -74,6 +73,7 @@
 extern void read_rtc_time(void);
 extern void pmac_find_display(void);
 extern void giveup_fpu(struct task_struct *);
+extern void disable_kernel_fp(void);
 extern void enable_kernel_fp(void);
 extern void flush_fp_to_thread(struct task_struct *);
 extern void enable_kernel_altivec(void);
@@ -86,6 +86,14 @@
 extern void cvt_fd(float *from, double *to, struct thread_struct *thread);
 extern void cvt_df(double *from, float *to, struct thread_struct *thread);
 
+#ifndef CONFIG_SMP
+extern void discard_lazy_cpu_state(void);
+#else
+static inline void discard_lazy_cpu_state(void)
+{
+}
+#endif
+
 #ifdef CONFIG_ALTIVEC
 extern void flush_altivec_to_thread(struct task_struct *);
 #else
@@ -123,6 +131,16 @@
 	struct task_struct *);
 #define switch_to(prev, next, last)	((last) = __switch_to((prev), (next)))
 
+/*
+ * On SMP systems, when the scheduler does migration-cost autodetection,
+ * it needs a way to flush as much of the CPU's caches as possible.
+ *
+ * TODO: fill this in!
+ */
+static inline void sched_cacheflush(void)
+{
+}
+
 struct thread_struct;
 extern struct task_struct *_switch(struct thread_struct *prev,
 				   struct thread_struct *next);
diff --git a/include/asm-s390/elf.h b/include/asm-s390/elf.h
index 372d51c..710646e 100644
--- a/include/asm-s390/elf.h
+++ b/include/asm-s390/elf.h
@@ -163,7 +163,7 @@
 
 static inline int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
 {
-	struct pt_regs *ptregs = __KSTK_PTREGS(tsk);
+	struct pt_regs *ptregs = task_pt_regs(tsk);
 	memcpy(&regs->psw, &ptregs->psw, sizeof(regs->psw)+sizeof(regs->gprs));
 	memcpy(regs->acrs, tsk->thread.acrs, sizeof(regs->acrs));
 	regs->orig_gpr2 = ptregs->orig_gpr2;
diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h
index 4ec652e..c5cbc4b 100644
--- a/include/asm-s390/processor.h
+++ b/include/asm-s390/processor.h
@@ -191,10 +191,10 @@
 extern void show_trace(struct task_struct *task, unsigned long *sp);
 
 unsigned long get_wchan(struct task_struct *p);
-#define __KSTK_PTREGS(tsk) ((struct pt_regs *) \
-        ((unsigned long) tsk->thread_info + THREAD_SIZE - sizeof(struct pt_regs)))
-#define KSTK_EIP(tsk)	(__KSTK_PTREGS(tsk)->psw.addr)
-#define KSTK_ESP(tsk)	(__KSTK_PTREGS(tsk)->gprs[15])
+#define task_pt_regs(tsk) ((struct pt_regs *) \
+        (task_stack_page(tsk) + THREAD_SIZE) - 1)
+#define KSTK_EIP(tsk)	(task_pt_regs(tsk)->psw.addr)
+#define KSTK_ESP(tsk)	(task_pt_regs(tsk)->gprs[15])
 
 /*
  * Give up the time slice of the virtual PU.
diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h
index 864cae7..c7c3a9a 100644
--- a/include/asm-s390/system.h
+++ b/include/asm-s390/system.h
@@ -104,6 +104,16 @@
 	prev = __switch_to(prev,next);					     \
 } while (0)
 
+/*
+ * On SMP systems, when the scheduler does migration-cost autodetection,
+ * it needs a way to flush as much of the CPU's caches as possible.
+ *
+ * TODO: fill this in!
+ */
+static inline void sched_cacheflush(void)
+{
+}
+
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 extern void account_user_vtime(struct task_struct *);
 extern void account_system_vtime(struct task_struct *);
diff --git a/include/asm-s390/thread_info.h b/include/asm-s390/thread_info.h
index 6c18a3f..f3797a5 100644
--- a/include/asm-s390/thread_info.h
+++ b/include/asm-s390/thread_info.h
@@ -81,8 +81,6 @@
 #define alloc_thread_info(tsk) ((struct thread_info *) \
 	__get_free_pages(GFP_KERNEL,THREAD_ORDER))
 #define free_thread_info(ti) free_pages((unsigned long) (ti),THREAD_ORDER)
-#define get_thread_info(ti) get_task_struct((ti)->task)
-#define put_thread_info(ti) put_task_struct((ti)->task)
 
 #endif
 
diff --git a/include/asm-sh/ptrace.h b/include/asm-sh/ptrace.h
index 0f75e16..792fc35 100644
--- a/include/asm-sh/ptrace.h
+++ b/include/asm-sh/ptrace.h
@@ -91,6 +91,16 @@
 #define instruction_pointer(regs) ((regs)->pc)
 extern void show_regs(struct pt_regs *);
 
+#ifdef CONFIG_SH_DSP
+#define task_pt_regs(task) \
+	((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE \
+		 - sizeof(struct pt_dspregs) - sizeof(unsigned long)) - 1)
+#else
+#define task_pt_regs(task) \
+	((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE \
+		 - sizeof(unsigned long)) - 1)
+#endif
+
 static inline unsigned long profile_pc(struct pt_regs *regs)
 {
 	unsigned long pc = instruction_pointer(regs);
diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h
index 28a3c2d..bb03304 100644
--- a/include/asm-sh/system.h
+++ b/include/asm-sh/system.h
@@ -57,6 +57,16 @@
 	last = __last;							\
 } while (0)
 
+/*
+ * On SMP systems, when the scheduler does migration-cost autodetection,
+ * it needs a way to flush as much of the CPU's caches as possible.
+ *
+ * TODO: fill this in!
+ */
+static inline void sched_cacheflush(void)
+{
+}
+
 #define nop() __asm__ __volatile__ ("nop")
 
 
diff --git a/include/asm-sh/thread_info.h b/include/asm-sh/thread_info.h
index 46080ce..85f0c11 100644
--- a/include/asm-sh/thread_info.h
+++ b/include/asm-sh/thread_info.h
@@ -60,8 +60,6 @@
 #define THREAD_SIZE (2*PAGE_SIZE)
 #define alloc_thread_info(ti) ((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
 #define free_thread_info(ti) free_pages((unsigned long) (ti), 1)
-#define get_thread_info(ti) get_task_struct((ti)->task)
-#define put_thread_info(ti) put_task_struct((ti)->task)
 
 #else /* !__ASSEMBLY__ */
 
diff --git a/include/asm-sh64/thread_info.h b/include/asm-sh64/thread_info.h
index 10f024c..1f825cb 100644
--- a/include/asm-sh64/thread_info.h
+++ b/include/asm-sh64/thread_info.h
@@ -66,8 +66,6 @@
 
 #define alloc_thread_info(ti) ((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
 #define free_thread_info(ti) free_pages((unsigned long) (ti), 1)
-#define get_thread_info(ti) get_task_struct((ti)->task)
-#define put_thread_info(ti) put_task_struct((ti)->task)
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/include/asm-sparc/system.h b/include/asm-sparc/system.h
index 1f6b71f..58dd162 100644
--- a/include/asm-sparc/system.h
+++ b/include/asm-sparc/system.h
@@ -155,7 +155,7 @@
 	"here:\n"									\
         : "=&r" (last)									\
         : "r" (&(current_set[hard_smp_processor_id()])),	\
-	  "r" ((next)->thread_info),				\
+	  "r" (task_thread_info(next)),				\
 	  "i" (TI_KPSR),					\
 	  "i" (TI_KSP),						\
 	  "i" (TI_TASK)						\
@@ -166,6 +166,16 @@
 	} while(0)
 
 /*
+ * On SMP systems, when the scheduler does migration-cost autodetection,
+ * it needs a way to flush as much of the CPU's caches as possible.
+ *
+ * TODO: fill this in!
+ */
+static inline void sched_cacheflush(void)
+{
+}
+
+/*
  * Changing the IRQ level on the Sparc.
  */
 extern void local_irq_restore(unsigned long);
diff --git a/include/asm-sparc/thread_info.h b/include/asm-sparc/thread_info.h
index ff6ccb3..65f060b 100644
--- a/include/asm-sparc/thread_info.h
+++ b/include/asm-sparc/thread_info.h
@@ -92,9 +92,6 @@
 BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *)
 #define free_thread_info(ti) BTFIXUP_CALL(free_thread_info)(ti)
 
-#define get_thread_info(ti)	get_task_struct((ti)->task)
-#define put_thread_info(ti)	put_task_struct((ti)->task)
-
 #endif /* __ASSEMBLY__ */
 
 /*
diff --git a/include/asm-sparc64/elf.h b/include/asm-sparc64/elf.h
index 9145811..69539a8 100644
--- a/include/asm-sparc64/elf.h
+++ b/include/asm-sparc64/elf.h
@@ -119,7 +119,7 @@
 #endif
 
 #define ELF_CORE_COPY_TASK_REGS(__tsk, __elf_regs)	\
-	({ ELF_CORE_COPY_REGS((*(__elf_regs)), (__tsk)->thread_info->kregs); 1; })
+	({ ELF_CORE_COPY_REGS((*(__elf_regs)), task_pt_regs(__tsk)); 1; })
 
 /*
  * This is used to ensure we don't load something for the wrong architecture.
diff --git a/include/asm-sparc64/mmu_context.h b/include/asm-sparc64/mmu_context.h
index 08ba72d..57ee7b3 100644
--- a/include/asm-sparc64/mmu_context.h
+++ b/include/asm-sparc64/mmu_context.h
@@ -60,7 +60,7 @@
 	register unsigned long pgd_cache asm("o4"); \
 	paddr = __pa((__mm)->pgd); \
 	pgd_cache = 0UL; \
-	if ((__tsk)->thread_info->flags & _TIF_32BIT) \
+	if (task_thread_info(__tsk)->flags & _TIF_32BIT) \
 		pgd_cache = get_pgd_cache((__mm)->pgd); \
 	__asm__ __volatile__("wrpr	%%g0, 0x494, %%pstate\n\t" \
 			     "mov	%3, %%g4\n\t" \
diff --git a/include/asm-sparc64/processor.h b/include/asm-sparc64/processor.h
index 3169f3e..cd8d9b4 100644
--- a/include/asm-sparc64/processor.h
+++ b/include/asm-sparc64/processor.h
@@ -186,8 +186,9 @@
 
 extern unsigned long get_wchan(struct task_struct *task);
 
-#define KSTK_EIP(tsk)  ((tsk)->thread_info->kregs->tpc)
-#define KSTK_ESP(tsk)  ((tsk)->thread_info->kregs->u_regs[UREG_FP])
+#define task_pt_regs(tsk) (task_thread_info(tsk)->kregs)
+#define KSTK_EIP(tsk)  (task_pt_regs(tsk)->tpc)
+#define KSTK_ESP(tsk)  (task_pt_regs(tsk)->u_regs[UREG_FP])
 
 #define cpu_relax()	barrier()
 
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
index 309f146..af254e5 100644
--- a/include/asm-sparc64/system.h
+++ b/include/asm-sparc64/system.h
@@ -208,7 +208,7 @@
 	/* If you are tempted to conditionalize the following */	\
 	/* so that ASI is only written if it changes, think again. */	\
 	__asm__ __volatile__("wr %%g0, %0, %%asi"			\
-	: : "r" (__thread_flag_byte_ptr(next->thread_info)[TI_FLAG_BYTE_CURRENT_DS]));\
+	: : "r" (__thread_flag_byte_ptr(task_thread_info(next))[TI_FLAG_BYTE_CURRENT_DS]));\
 	__asm__ __volatile__(						\
 	"mov	%%g4, %%g7\n\t"						\
 	"wrpr	%%g0, 0x95, %%pstate\n\t"				\
@@ -238,7 +238,7 @@
 	"b,a ret_from_syscall\n\t"					\
 	"1:\n\t"							\
 	: "=&r" (last)							\
-	: "0" (next->thread_info),					\
+	: "0" (task_thread_info(next)),					\
 	  "i" (TI_WSTATE), "i" (TI_KSP), "i" (TI_NEW_CHILD),            \
 	  "i" (TI_CWP), "i" (TI_TASK)					\
 	: "cc",								\
@@ -253,6 +253,16 @@
 	}								\
 } while(0)
 
+/*
+ * On SMP systems, when the scheduler does migration-cost autodetection,
+ * it needs a way to flush as much of the CPU's caches as possible.
+ *
+ * TODO: fill this in!
+ */
+static inline void sched_cacheflush(void)
+{
+}
+
 static inline unsigned long xchg32(__volatile__ unsigned int *m, unsigned int val)
 {
 	unsigned long tmp1, tmp2;
diff --git a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h
index 97267f0..705c719 100644
--- a/include/asm-um/thread_info.h
+++ b/include/asm-um/thread_info.h
@@ -56,9 +56,6 @@
 	((struct thread_info *) kmalloc(THREAD_SIZE, GFP_KERNEL))
 #define free_thread_info(ti) kfree(ti)
 
-#define get_thread_info(ti) get_task_struct((ti)->task)
-#define put_thread_info(ti) put_task_struct((ti)->task)
-
 #endif
 
 #define PREEMPT_ACTIVE		0x10000000
diff --git a/include/asm-v850/processor.h b/include/asm-v850/processor.h
index 98f9294..2d31308 100644
--- a/include/asm-v850/processor.h
+++ b/include/asm-v850/processor.h
@@ -98,10 +98,10 @@
 
 
 /* Return some info about the user process TASK.  */
-#define task_tos(task)	((unsigned long)(task)->thread_info + THREAD_SIZE)
-#define task_regs(task) ((struct pt_regs *)task_tos (task) - 1)
-#define task_sp(task)	(task_regs (task)->gpr[GPR_SP])
-#define task_pc(task)	(task_regs (task)->pc)
+#define task_tos(task)	((unsigned long)task_stack_page(task) + THREAD_SIZE)
+#define task_pt_regs(task) ((struct pt_regs *)task_tos (task) - 1)
+#define task_sp(task)	(task_pt_regs (task)->gpr[GPR_SP])
+#define task_pc(task)	(task_pt_regs (task)->pc)
 /* Grotty old names for some.  */
 #define KSTK_EIP(task)	task_pc (task)
 #define KSTK_ESP(task)	task_sp (task)
diff --git a/include/asm-v850/thread_info.h b/include/asm-v850/thread_info.h
index e4cfad9..82b8f28 100644
--- a/include/asm-v850/thread_info.h
+++ b/include/asm-v850/thread_info.h
@@ -58,8 +58,6 @@
 #define alloc_thread_info(tsk) ((struct thread_info *) \
 				__get_free_pages(GFP_KERNEL, 1))
 #define free_thread_info(ti)	free_pages((unsigned long) (ti), 1)
-#define get_thread_info(ti)	get_task_struct((ti)->task)
-#define put_thread_info(ti)	put_task_struct((ti)->task)
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/include/asm-x86_64/compat.h b/include/asm-x86_64/compat.h
index 3863a7d..b37ab82 100644
--- a/include/asm-x86_64/compat.h
+++ b/include/asm-x86_64/compat.h
@@ -198,7 +198,7 @@
 
 static __inline__ void __user *compat_alloc_user_space(long len)
 {
-	struct pt_regs *regs = (void *)current->thread.rsp0 - sizeof(struct pt_regs); 
+	struct pt_regs *regs = task_pt_regs(current);
 	return (void __user *)regs->rsp - len; 
 }
 
diff --git a/include/asm-x86_64/i387.h b/include/asm-x86_64/i387.h
index 57f7e14..876eb9a 100644
--- a/include/asm-x86_64/i387.h
+++ b/include/asm-x86_64/i387.h
@@ -30,7 +30,7 @@
  */
 
 #define unlazy_fpu(tsk) do { \
-	if ((tsk)->thread_info->status & TS_USEDFPU) \
+	if (task_thread_info(tsk)->status & TS_USEDFPU) \
 		save_init_fpu(tsk); \
 } while (0)
 
@@ -46,9 +46,9 @@
 }
 
 #define clear_fpu(tsk) do { \
-	if ((tsk)->thread_info->status & TS_USEDFPU) {		\
+	if (task_thread_info(tsk)->status & TS_USEDFPU) {	\
 		tolerant_fwait();				\
-		(tsk)->thread_info->status &= ~TS_USEDFPU;	\
+		task_thread_info(tsk)->status &= ~TS_USEDFPU;	\
 		stts();						\
 	}							\
 } while (0)
@@ -170,10 +170,10 @@
 	preempt_enable();
 }
 
-static inline void save_init_fpu( struct task_struct *tsk )
+static inline void save_init_fpu(struct task_struct *tsk)
 {
  	__fxsave_clear(tsk);
-	tsk->thread_info->status &= ~TS_USEDFPU;
+	task_thread_info(tsk)->status &= ~TS_USEDFPU;
 	stts();
 }
 
diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h
index 394dd72..87a282b 100644
--- a/include/asm-x86_64/processor.h
+++ b/include/asm-x86_64/processor.h
@@ -321,8 +321,8 @@
 #define thread_saved_pc(t) (*(unsigned long *)((t)->thread.rsp - 8))
 
 extern unsigned long get_wchan(struct task_struct *p);
-#define KSTK_EIP(tsk) \
-	(((struct pt_regs *)(tsk->thread.rsp0 - sizeof(struct pt_regs)))->rip)
+#define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.rsp0 - 1)
+#define KSTK_EIP(tsk) (task_pt_regs(tsk)->rip)
 #define KSTK_ESP(tsk) -1 /* sorry. doesn't work for syscall. */
 
 
diff --git a/include/asm-x86_64/system.h b/include/asm-x86_64/system.h
index 38c1e8a..0eacbef 100644
--- a/include/asm-x86_64/system.h
+++ b/include/asm-x86_64/system.h
@@ -193,6 +193,15 @@
 #define wbinvd() \
 	__asm__ __volatile__ ("wbinvd": : :"memory");
 
+/*
+ * On SMP systems, when the scheduler does migration-cost autodetection,
+ * it needs a way to flush as much of the CPU's caches as possible.
+ */
+static inline void sched_cacheflush(void)
+{
+	wbinvd();
+}
+
 #endif	/* __KERNEL__ */
 
 #define nop() __asm__ __volatile__ ("nop")
diff --git a/include/asm-x86_64/thread_info.h b/include/asm-x86_64/thread_info.h
index eb7c5fd..4ac0e0a 100644
--- a/include/asm-x86_64/thread_info.h
+++ b/include/asm-x86_64/thread_info.h
@@ -76,8 +76,6 @@
 #define alloc_thread_info(tsk) \
 	((struct thread_info *) __get_free_pages(GFP_KERNEL,THREAD_ORDER))
 #define free_thread_info(ti) free_pages((unsigned long) (ti), THREAD_ORDER)
-#define get_thread_info(ti) get_task_struct((ti)->task)
-#define put_thread_info(ti) put_task_struct((ti)->task)
 
 #else /* !__ASSEMBLY__ */
 
diff --git a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h
index 7d82bc5..2fa7f27 100644
--- a/include/asm-x86_64/topology.h
+++ b/include/asm-x86_64/topology.h
@@ -39,7 +39,6 @@
 	.max_interval		= 32,			\
 	.busy_factor		= 32,			\
 	.imbalance_pct		= 125,			\
-	.cache_hot_time		= (10*1000000),		\
 	.cache_nice_tries	= 2,			\
 	.busy_idx		= 3,			\
 	.idle_idx		= 2,			\
diff --git a/include/asm-xtensa/processor.h b/include/asm-xtensa/processor.h
index 9cab5e4..d1d72ad 100644
--- a/include/asm-xtensa/processor.h
+++ b/include/asm-xtensa/processor.h
@@ -184,12 +184,12 @@
 #define release_segments(mm)	do { } while(0)
 #define forget_segments()	do { } while (0)
 
-#define thread_saved_pc(tsk)	(xtensa_pt_regs(tsk)->pc)
+#define thread_saved_pc(tsk)	(task_pt_regs(tsk)->pc)
 
 extern unsigned long get_wchan(struct task_struct *p);
 
-#define KSTK_EIP(tsk)		(xtensa_pt_regs(tsk)->pc)
-#define KSTK_ESP(tsk)		(xtensa_pt_regs(tsk)->areg[1])
+#define KSTK_EIP(tsk)		(task_pt_regs(tsk)->pc)
+#define KSTK_ESP(tsk)		(task_pt_regs(tsk)->areg[1])
 
 #define cpu_relax()  do { } while (0)
 
diff --git a/include/asm-xtensa/ptrace.h b/include/asm-xtensa/ptrace.h
index aa4fd7f..a5ac71a 100644
--- a/include/asm-xtensa/ptrace.h
+++ b/include/asm-xtensa/ptrace.h
@@ -113,8 +113,8 @@
 };
 
 #ifdef __KERNEL__
-# define xtensa_pt_regs(tsk) ((struct pt_regs*) \
-  (((long)(tsk)->thread_info + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4)) - 1)
+# define task_pt_regs(tsk) ((struct pt_regs*) \
+  (task_stack_page(tsk) + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4) - 1)
 # define user_mode(regs) (((regs)->ps & 0x00000020)!=0)
 # define instruction_pointer(regs) ((regs)->pc)
 extern void show_regs(struct pt_regs *);
diff --git a/include/asm-xtensa/thread_info.h b/include/asm-xtensa/thread_info.h
index af208d4..5ae34ab 100644
--- a/include/asm-xtensa/thread_info.h
+++ b/include/asm-xtensa/thread_info.h
@@ -93,8 +93,6 @@
 /* thread information allocation */
 #define alloc_thread_info(tsk) ((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
 #define free_thread_info(ti) free_pages((unsigned long) (ti), 1)
-#define get_thread_info(ti) get_task_struct((ti)->task)
-#define put_thread_info(ti) put_task_struct((ti)->task)
 
 #else /* !__ASSEMBLY__ */
 
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 3b74c4b..a72e171 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -631,7 +631,14 @@
 
 extern void partition_sched_domains(cpumask_t *partition1,
 				    cpumask_t *partition2);
-#endif /* CONFIG_SMP */
+
+/*
+ * Maximum cache size the migration-costs auto-tuning code will
+ * search from:
+ */
+extern unsigned int max_cache_size;
+
+#endif	/* CONFIG_SMP */
 
 
 struct io_context;			/* See blkdev.h */
@@ -689,9 +696,12 @@
 
 	int lock_depth;		/* BKL lock depth */
 
-#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW)
+#if defined(CONFIG_SMP)
+	int last_waker_cpu;	/* CPU that last woke this task up */
+#if defined(__ARCH_WANT_UNLOCKED_CTXSW)
 	int oncpu;
 #endif
+#endif
 	int prio, static_prio;
 	struct list_head run_list;
 	prio_array_t *array;
@@ -1230,6 +1240,7 @@
 #ifndef __HAVE_THREAD_FUNCTIONS
 
 #define task_thread_info(task) (task)->thread_info
+#define task_stack_page(task) ((void*)((task)->thread_info))
 
 static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
 {
diff --git a/include/linux/topology.h b/include/linux/topology.h
index 3df1d47..315a516 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -86,7 +86,6 @@
 	.max_interval		= 2,			\
 	.busy_factor		= 8,			\
 	.imbalance_pct		= 110,			\
-	.cache_hot_time		= 0,			\
 	.cache_nice_tries	= 0,			\
 	.per_cpu_gain		= 25,			\
 	.busy_idx		= 0,			\
@@ -117,7 +116,6 @@
 	.max_interval		= 4,			\
 	.busy_factor		= 64,			\
 	.imbalance_pct		= 125,			\
-	.cache_hot_time		= (5*1000000/2),	\
 	.cache_nice_tries	= 1,			\
 	.per_cpu_gain		= 100,			\
 	.busy_idx		= 2,			\
diff --git a/kernel/sched.c b/kernel/sched.c
index c0c60c9..c9dec2a 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -34,6 +34,7 @@
 #include <linux/notifier.h>
 #include <linux/profile.h>
 #include <linux/suspend.h>
+#include <linux/vmalloc.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/smp.h>
@@ -1289,6 +1290,9 @@
 		}
 	}
 
+	if (p->last_waker_cpu != this_cpu)
+		goto out_set_cpu;
+
 	if (unlikely(!cpu_isset(this_cpu, p->cpus_allowed)))
 		goto out_set_cpu;
 
@@ -1359,6 +1363,8 @@
 		cpu = task_cpu(p);
 	}
 
+	p->last_waker_cpu = this_cpu;
+
 out_activate:
 #endif /* CONFIG_SMP */
 	if (old_state == TASK_UNINTERRUPTIBLE) {
@@ -1440,9 +1446,12 @@
 #ifdef CONFIG_SCHEDSTATS
 	memset(&p->sched_info, 0, sizeof(p->sched_info));
 #endif
-#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW)
+#if defined(CONFIG_SMP)
+	p->last_waker_cpu = cpu;
+#if defined(__ARCH_WANT_UNLOCKED_CTXSW)
 	p->oncpu = 0;
 #endif
+#endif
 #ifdef CONFIG_PREEMPT
 	/* Want to start with kernel preemption disabled. */
 	task_thread_info(p)->preempt_count = 1;
@@ -5082,7 +5091,470 @@
 
 #define SD_NODES_PER_DOMAIN 16
 
+/*
+ * Self-tuning task migration cost measurement between source and target CPUs.
+ *
+ * This is done by measuring the cost of manipulating buffers of varying
+ * sizes. For a given buffer-size here are the steps that are taken:
+ *
+ * 1) the source CPU reads+dirties a shared buffer
+ * 2) the target CPU reads+dirties the same shared buffer
+ *
+ * We measure how long they take, in the following 4 scenarios:
+ *
+ *  - source: CPU1, target: CPU2 | cost1
+ *  - source: CPU2, target: CPU1 | cost2
+ *  - source: CPU1, target: CPU1 | cost3
+ *  - source: CPU2, target: CPU2 | cost4
+ *
+ * We then calculate the cost3+cost4-cost1-cost2 difference - this is
+ * the cost of migration.
+ *
+ * We then start off from a small buffer-size and iterate up to larger
+ * buffer sizes, in 5% steps - measuring each buffer-size separately, and
+ * doing a maximum search for the cost. (The maximum cost for a migration
+ * normally occurs when the working set size is around the effective cache
+ * size.)
+ */
+#define SEARCH_SCOPE		2
+#define MIN_CACHE_SIZE		(64*1024U)
+#define DEFAULT_CACHE_SIZE	(5*1024*1024U)
+#define ITERATIONS		2
+#define SIZE_THRESH		130
+#define COST_THRESH		130
+
+/*
+ * The migration cost is a function of 'domain distance'. Domain
+ * distance is the number of steps a CPU has to iterate down its
+ * domain tree to share a domain with the other CPU. The farther
+ * two CPUs are from each other, the larger the distance gets.
+ *
+ * Note that we use the distance only to cache measurement results,
+ * the distance value is not used numerically otherwise. When two
+ * CPUs have the same distance it is assumed that the migration
+ * cost is the same. (this is a simplification but quite practical)
+ */
+#define MAX_DOMAIN_DISTANCE 32
+
+static unsigned long long migration_cost[MAX_DOMAIN_DISTANCE] =
+		{ [ 0 ... MAX_DOMAIN_DISTANCE-1 ] = -1LL };
+
+/*
+ * Allow override of migration cost - in units of microseconds.
+ * E.g. migration_cost=1000,2000,3000 will set up a level-1 cost
+ * of 1 msec, level-2 cost of 2 msecs and level3 cost of 3 msecs:
+ */
+static int __init migration_cost_setup(char *str)
+{
+	int ints[MAX_DOMAIN_DISTANCE+1], i;
+
+	str = get_options(str, ARRAY_SIZE(ints), ints);
+
+	printk("#ints: %d\n", ints[0]);
+	for (i = 1; i <= ints[0]; i++) {
+		migration_cost[i-1] = (unsigned long long)ints[i]*1000;
+		printk("migration_cost[%d]: %Ld\n", i-1, migration_cost[i-1]);
+	}
+	return 1;
+}
+
+__setup ("migration_cost=", migration_cost_setup);
+
+/*
+ * Global multiplier (divisor) for migration-cutoff values,
+ * in percentiles. E.g. use a value of 150 to get 1.5 times
+ * longer cache-hot cutoff times.
+ *
+ * (We scale it from 100 to 128 to long long handling easier.)
+ */
+
+#define MIGRATION_FACTOR_SCALE 128
+
+static unsigned int migration_factor = MIGRATION_FACTOR_SCALE;
+
+static int __init setup_migration_factor(char *str)
+{
+	get_option(&str, &migration_factor);
+	migration_factor = migration_factor * MIGRATION_FACTOR_SCALE / 100;
+	return 1;
+}
+
+__setup("migration_factor=", setup_migration_factor);
+
+/*
+ * Estimated distance of two CPUs, measured via the number of domains
+ * we have to pass for the two CPUs to be in the same span:
+ */
+static unsigned long domain_distance(int cpu1, int cpu2)
+{
+	unsigned long distance = 0;
+	struct sched_domain *sd;
+
+	for_each_domain(cpu1, sd) {
+		WARN_ON(!cpu_isset(cpu1, sd->span));
+		if (cpu_isset(cpu2, sd->span))
+			return distance;
+		distance++;
+	}
+	if (distance >= MAX_DOMAIN_DISTANCE) {
+		WARN_ON(1);
+		distance = MAX_DOMAIN_DISTANCE-1;
+	}
+
+	return distance;
+}
+
+static unsigned int migration_debug;
+
+static int __init setup_migration_debug(char *str)
+{
+	get_option(&str, &migration_debug);
+	return 1;
+}
+
+__setup("migration_debug=", setup_migration_debug);
+
+/*
+ * Maximum cache-size that the scheduler should try to measure.
+ * Architectures with larger caches should tune this up during
+ * bootup. Gets used in the domain-setup code (i.e. during SMP
+ * bootup).
+ */
+unsigned int max_cache_size;
+
+static int __init setup_max_cache_size(char *str)
+{
+	get_option(&str, &max_cache_size);
+	return 1;
+}
+
+__setup("max_cache_size=", setup_max_cache_size);
+
+/*
+ * Dirty a big buffer in a hard-to-predict (for the L2 cache) way. This
+ * is the operation that is timed, so we try to generate unpredictable
+ * cachemisses that still end up filling the L2 cache:
+ */
+static void touch_cache(void *__cache, unsigned long __size)
+{
+	unsigned long size = __size/sizeof(long), chunk1 = size/3,
+			chunk2 = 2*size/3;
+	unsigned long *cache = __cache;
+	int i;
+
+	for (i = 0; i < size/6; i += 8) {
+		switch (i % 6) {
+			case 0: cache[i]++;
+			case 1: cache[size-1-i]++;
+			case 2: cache[chunk1-i]++;
+			case 3: cache[chunk1+i]++;
+			case 4: cache[chunk2-i]++;
+			case 5: cache[chunk2+i]++;
+		}
+	}
+}
+
+/*
+ * Measure the cache-cost of one task migration. Returns in units of nsec.
+ */
+static unsigned long long measure_one(void *cache, unsigned long size,
+				      int source, int target)
+{
+	cpumask_t mask, saved_mask;
+	unsigned long long t0, t1, t2, t3, cost;
+
+	saved_mask = current->cpus_allowed;
+
+	/*
+	 * Flush source caches to RAM and invalidate them:
+	 */
+	sched_cacheflush();
+
+	/*
+	 * Migrate to the source CPU:
+	 */
+	mask = cpumask_of_cpu(source);
+	set_cpus_allowed(current, mask);
+	WARN_ON(smp_processor_id() != source);
+
+	/*
+	 * Dirty the working set:
+	 */
+	t0 = sched_clock();
+	touch_cache(cache, size);
+	t1 = sched_clock();
+
+	/*
+	 * Migrate to the target CPU, dirty the L2 cache and access
+	 * the shared buffer. (which represents the working set
+	 * of a migrated task.)
+	 */
+	mask = cpumask_of_cpu(target);
+	set_cpus_allowed(current, mask);
+	WARN_ON(smp_processor_id() != target);
+
+	t2 = sched_clock();
+	touch_cache(cache, size);
+	t3 = sched_clock();
+
+	cost = t1-t0 + t3-t2;
+
+	if (migration_debug >= 2)
+		printk("[%d->%d]: %8Ld %8Ld %8Ld => %10Ld.\n",
+			source, target, t1-t0, t1-t0, t3-t2, cost);
+	/*
+	 * Flush target caches to RAM and invalidate them:
+	 */
+	sched_cacheflush();
+
+	set_cpus_allowed(current, saved_mask);
+
+	return cost;
+}
+
+/*
+ * Measure a series of task migrations and return the average
+ * result. Since this code runs early during bootup the system
+ * is 'undisturbed' and the average latency makes sense.
+ *
+ * The algorithm in essence auto-detects the relevant cache-size,
+ * so it will properly detect different cachesizes for different
+ * cache-hierarchies, depending on how the CPUs are connected.
+ *
+ * Architectures can prime the upper limit of the search range via
+ * max_cache_size, otherwise the search range defaults to 20MB...64K.
+ */
+static unsigned long long
+measure_cost(int cpu1, int cpu2, void *cache, unsigned int size)
+{
+	unsigned long long cost1, cost2;
+	int i;
+
+	/*
+	 * Measure the migration cost of 'size' bytes, over an
+	 * average of 10 runs:
+	 *
+	 * (We perturb the cache size by a small (0..4k)
+	 *  value to compensate size/alignment related artifacts.
+	 *  We also subtract the cost of the operation done on
+	 *  the same CPU.)
+	 */
+	cost1 = 0;
+
+	/*
+	 * dry run, to make sure we start off cache-cold on cpu1,
+	 * and to get any vmalloc pagefaults in advance:
+	 */
+	measure_one(cache, size, cpu1, cpu2);
+	for (i = 0; i < ITERATIONS; i++)
+		cost1 += measure_one(cache, size - i*1024, cpu1, cpu2);
+
+	measure_one(cache, size, cpu2, cpu1);
+	for (i = 0; i < ITERATIONS; i++)
+		cost1 += measure_one(cache, size - i*1024, cpu2, cpu1);
+
+	/*
+	 * (We measure the non-migrating [cached] cost on both
+	 *  cpu1 and cpu2, to handle CPUs with different speeds)
+	 */
+	cost2 = 0;
+
+	measure_one(cache, size, cpu1, cpu1);
+	for (i = 0; i < ITERATIONS; i++)
+		cost2 += measure_one(cache, size - i*1024, cpu1, cpu1);
+
+	measure_one(cache, size, cpu2, cpu2);
+	for (i = 0; i < ITERATIONS; i++)
+		cost2 += measure_one(cache, size - i*1024, cpu2, cpu2);
+
+	/*
+	 * Get the per-iteration migration cost:
+	 */
+	do_div(cost1, 2*ITERATIONS);
+	do_div(cost2, 2*ITERATIONS);
+
+	return cost1 - cost2;
+}
+
+static unsigned long long measure_migration_cost(int cpu1, int cpu2)
+{
+	unsigned long long max_cost = 0, fluct = 0, avg_fluct = 0;
+	unsigned int max_size, size, size_found = 0;
+	long long cost = 0, prev_cost;
+	void *cache;
+
+	/*
+	 * Search from max_cache_size*5 down to 64K - the real relevant
+	 * cachesize has to lie somewhere inbetween.
+	 */
+	if (max_cache_size) {
+		max_size = max(max_cache_size * SEARCH_SCOPE, MIN_CACHE_SIZE);
+		size = max(max_cache_size / SEARCH_SCOPE, MIN_CACHE_SIZE);
+	} else {
+		/*
+		 * Since we have no estimation about the relevant
+		 * search range
+		 */
+		max_size = DEFAULT_CACHE_SIZE * SEARCH_SCOPE;
+		size = MIN_CACHE_SIZE;
+	}
+
+	if (!cpu_online(cpu1) || !cpu_online(cpu2)) {
+		printk("cpu %d and %d not both online!\n", cpu1, cpu2);
+		return 0;
+	}
+
+	/*
+	 * Allocate the working set:
+	 */
+	cache = vmalloc(max_size);
+	if (!cache) {
+		printk("could not vmalloc %d bytes for cache!\n", 2*max_size);
+		return 1000000; // return 1 msec on very small boxen
+	}
+
+	while (size <= max_size) {
+		prev_cost = cost;
+		cost = measure_cost(cpu1, cpu2, cache, size);
+
+		/*
+		 * Update the max:
+		 */
+		if (cost > 0) {
+			if (max_cost < cost) {
+				max_cost = cost;
+				size_found = size;
+			}
+		}
+		/*
+		 * Calculate average fluctuation, we use this to prevent
+		 * noise from triggering an early break out of the loop:
+		 */
+		fluct = abs(cost - prev_cost);
+		avg_fluct = (avg_fluct + fluct)/2;
+
+		if (migration_debug)
+			printk("-> [%d][%d][%7d] %3ld.%ld [%3ld.%ld] (%ld): (%8Ld %8Ld)\n",
+				cpu1, cpu2, size,
+				(long)cost / 1000000,
+				((long)cost / 100000) % 10,
+				(long)max_cost / 1000000,
+				((long)max_cost / 100000) % 10,
+				domain_distance(cpu1, cpu2),
+				cost, avg_fluct);
+
+		/*
+		 * If we iterated at least 20% past the previous maximum,
+		 * and the cost has dropped by more than 20% already,
+		 * (taking fluctuations into account) then we assume to
+		 * have found the maximum and break out of the loop early:
+		 */
+		if (size_found && (size*100 > size_found*SIZE_THRESH))
+			if (cost+avg_fluct <= 0 ||
+				max_cost*100 > (cost+avg_fluct)*COST_THRESH) {
+
+				if (migration_debug)
+					printk("-> found max.\n");
+				break;
+			}
+		/*
+		 * Increase the cachesize in 5% steps:
+		 */
+		size = size * 20 / 19;
+	}
+
+	if (migration_debug)
+		printk("[%d][%d] working set size found: %d, cost: %Ld\n",
+			cpu1, cpu2, size_found, max_cost);
+
+	vfree(cache);
+
+	/*
+	 * A task is considered 'cache cold' if at least 2 times
+	 * the worst-case cost of migration has passed.
+	 *
+	 * (this limit is only listened to if the load-balancing
+	 * situation is 'nice' - if there is a large imbalance we
+	 * ignore it for the sake of CPU utilization and
+	 * processing fairness.)
+	 */
+	return 2 * max_cost * migration_factor / MIGRATION_FACTOR_SCALE;
+}
+
+static void calibrate_migration_costs(const cpumask_t *cpu_map)
+{
+	int cpu1 = -1, cpu2 = -1, cpu, orig_cpu = raw_smp_processor_id();
+	unsigned long j0, j1, distance, max_distance = 0;
+	struct sched_domain *sd;
+
+	j0 = jiffies;
+
+	/*
+	 * First pass - calculate the cacheflush times:
+	 */
+	for_each_cpu_mask(cpu1, *cpu_map) {
+		for_each_cpu_mask(cpu2, *cpu_map) {
+			if (cpu1 == cpu2)
+				continue;
+			distance = domain_distance(cpu1, cpu2);
+			max_distance = max(max_distance, distance);
+			/*
+			 * No result cached yet?
+			 */
+			if (migration_cost[distance] == -1LL)
+				migration_cost[distance] =
+					measure_migration_cost(cpu1, cpu2);
+		}
+	}
+	/*
+	 * Second pass - update the sched domain hierarchy with
+	 * the new cache-hot-time estimations:
+	 */
+	for_each_cpu_mask(cpu, *cpu_map) {
+		distance = 0;
+		for_each_domain(cpu, sd) {
+			sd->cache_hot_time = migration_cost[distance];
+			distance++;
+		}
+	}
+	/*
+	 * Print the matrix:
+	 */
+	if (migration_debug)
+		printk("migration: max_cache_size: %d, cpu: %d MHz:\n",
+			max_cache_size,
+#ifdef CONFIG_X86
+			cpu_khz/1000
+#else
+			-1
+#endif
+		);
+	printk("migration_cost=");
+	for (distance = 0; distance <= max_distance; distance++) {
+		if (distance)
+			printk(",");
+		printk("%ld", (long)migration_cost[distance] / 1000);
+	}
+	printk("\n");
+	j1 = jiffies;
+	if (migration_debug)
+		printk("migration: %ld seconds\n", (j1-j0)/HZ);
+
+	/*
+	 * Move back to the original CPU. NUMA-Q gets confused
+	 * if we migrate to another quad during bootup.
+	 */
+	if (raw_smp_processor_id() != orig_cpu) {
+		cpumask_t mask = cpumask_of_cpu(orig_cpu),
+			saved_mask = current->cpus_allowed;
+
+		set_cpus_allowed(current, mask);
+		set_cpus_allowed(current, saved_mask);
+	}
+}
+
 #ifdef CONFIG_NUMA
+
 /**
  * find_next_best_node - find the next node to include in a sched_domain
  * @node: node whose sched_domain we're building
@@ -5448,6 +5920,10 @@
 #endif
 		cpu_attach_domain(sd, i);
 	}
+	/*
+	 * Tune cache-hot values:
+	 */
+	calibrate_migration_costs(cpu_map);
 }
 /*
  * Set up scheduler domains and groups.  Callers must hold the hotplug lock.
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 1850d0a..b62cab5 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -208,6 +208,8 @@
 		page = vm_normal_page(vma, addr, *pte);
 		if (!page)
 			continue;
+		if (PageReserved(page))
+			continue;
 		nid = page_to_nid(page);
 		if (node_isset(nid, *nodes) == !!(flags & MPOL_MF_INVERT))
 			continue;
@@ -290,7 +292,7 @@
 static inline int vma_migratable(struct vm_area_struct *vma)
 {
 	if (vma->vm_flags & (
-		VM_LOCKED|VM_IO|VM_HUGETLB|VM_PFNMAP))
+		VM_LOCKED|VM_IO|VM_HUGETLB|VM_PFNMAP|VM_RESERVED))
 		return 0;
 	return 1;
 }
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index d41a066..8c960b4 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1742,7 +1742,7 @@
 	unsigned long end_pfn = start_pfn + size;
 	unsigned long pfn;
 
-	for (pfn = start_pfn; pfn < end_pfn; pfn++, page++) {
+	for (pfn = start_pfn; pfn < end_pfn; pfn++) {
 		if (!early_pfn_valid(pfn))
 			continue;
 		page = pfn_to_page(pfn);
diff --git a/mm/swap.c b/mm/swap.c
index ee6d71c..cbb48e7 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -384,6 +384,8 @@
 	return pagevec_count(pvec);
 }
 
+EXPORT_SYMBOL(pagevec_lookup);
+
 unsigned pagevec_lookup_tag(struct pagevec *pvec, struct address_space *mapping,
 		pgoff_t *index, int tag, unsigned nr_pages)
 {
diff --git a/mm/tiny-shmem.c b/mm/tiny-shmem.c
index cdc6d43..f9d6a9c 100644
--- a/mm/tiny-shmem.c
+++ b/mm/tiny-shmem.c
@@ -90,7 +90,7 @@
 	file->f_mode = FMODE_WRITE | FMODE_READ;
 
 	/* notify everyone as to the change of file size */
-	error = do_truncate(dentry, size, file);
+	error = do_truncate(dentry, size, 0, file);
 	if (error < 0)
 		goto close_file;
 
diff --git a/sound/oss/dmasound/dmasound.h b/sound/oss/dmasound/dmasound.h
index 222014caf..a1b0b92 100644
--- a/sound/oss/dmasound/dmasound.h
+++ b/sound/oss/dmasound/dmasound.h
@@ -270,7 +270,6 @@
 #define SW_INPUT_VOLUME_SCALE	4
 #define SW_INPUT_VOLUME_DEFAULT	(128 / SW_INPUT_VOLUME_SCALE)
 
-extern int expand_bal;	/* Balance factor for expanding (not volume!) */
 extern int expand_read_bal;	/* Balance factor for reading */
 extern uint software_input_volume; /* software implemented recording volume! */
 
diff --git a/sound/oss/dmasound/dmasound_atari.c b/sound/oss/dmasound/dmasound_atari.c
index 59eb53f..dc31373 100644
--- a/sound/oss/dmasound/dmasound_atari.c
+++ b/sound/oss/dmasound/dmasound_atari.c
@@ -67,46 +67,46 @@
  * ++geert: split in even more functions (one per format)
  */
 
-static ssize_t ata_ct_law(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ct_law(const u_char __user *userPtr, size_t userCount,
 			  u_char frame[], ssize_t *frameUsed,
 			  ssize_t frameLeft);
-static ssize_t ata_ct_s8(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ct_s8(const u_char __user *userPtr, size_t userCount,
 			 u_char frame[], ssize_t *frameUsed,
 			 ssize_t frameLeft);
-static ssize_t ata_ct_u8(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ct_u8(const u_char __user *userPtr, size_t userCount,
 			 u_char frame[], ssize_t *frameUsed,
 			 ssize_t frameLeft);
-static ssize_t ata_ct_s16be(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ct_s16be(const u_char __user *userPtr, size_t userCount,
 			    u_char frame[], ssize_t *frameUsed,
 			    ssize_t frameLeft);
-static ssize_t ata_ct_u16be(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ct_u16be(const u_char __user *userPtr, size_t userCount,
 			    u_char frame[], ssize_t *frameUsed,
 			    ssize_t frameLeft);
-static ssize_t ata_ct_s16le(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ct_s16le(const u_char __user *userPtr, size_t userCount,
 			    u_char frame[], ssize_t *frameUsed,
 			    ssize_t frameLeft);
-static ssize_t ata_ct_u16le(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ct_u16le(const u_char __user *userPtr, size_t userCount,
 			    u_char frame[], ssize_t *frameUsed,
 			    ssize_t frameLeft);
-static ssize_t ata_ctx_law(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ctx_law(const u_char __user *userPtr, size_t userCount,
 			   u_char frame[], ssize_t *frameUsed,
 			   ssize_t frameLeft);
-static ssize_t ata_ctx_s8(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ctx_s8(const u_char __user *userPtr, size_t userCount,
 			  u_char frame[], ssize_t *frameUsed,
 			  ssize_t frameLeft);
-static ssize_t ata_ctx_u8(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ctx_u8(const u_char __user *userPtr, size_t userCount,
 			  u_char frame[], ssize_t *frameUsed,
 			  ssize_t frameLeft);
-static ssize_t ata_ctx_s16be(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ctx_s16be(const u_char __user *userPtr, size_t userCount,
 			     u_char frame[], ssize_t *frameUsed,
 			     ssize_t frameLeft);
-static ssize_t ata_ctx_u16be(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ctx_u16be(const u_char __user *userPtr, size_t userCount,
 			     u_char frame[], ssize_t *frameUsed,
 			     ssize_t frameLeft);
-static ssize_t ata_ctx_s16le(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ctx_s16le(const u_char __user *userPtr, size_t userCount,
 			     u_char frame[], ssize_t *frameUsed,
 			     ssize_t frameLeft);
-static ssize_t ata_ctx_u16le(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ctx_u16le(const u_char __user *userPtr, size_t userCount,
 			     u_char frame[], ssize_t *frameUsed,
 			     ssize_t frameLeft);
 
@@ -151,7 +151,7 @@
 /*** Translations ************************************************************/
 
 
-static ssize_t ata_ct_law(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ct_law(const u_char __user *userPtr, size_t userCount,
 			  u_char frame[], ssize_t *frameUsed,
 			  ssize_t frameLeft)
 {
@@ -176,7 +176,7 @@
 }
 
 
-static ssize_t ata_ct_s8(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ct_s8(const u_char __user *userPtr, size_t userCount,
 			 u_char frame[], ssize_t *frameUsed,
 			 ssize_t frameLeft)
 {
@@ -194,7 +194,7 @@
 }
 
 
-static ssize_t ata_ct_u8(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ct_u8(const u_char __user *userPtr, size_t userCount,
 			 u_char frame[], ssize_t *frameUsed,
 			 ssize_t frameLeft)
 {
@@ -217,8 +217,9 @@
 		used = count*2;
 		while (count > 0) {
 			u_short data;
-			if (get_user(data, ((u_short *)userPtr)++))
+			if (get_user(data, (u_short __user *)userPtr))
 				return -EFAULT;
+			userPtr += 2;
 			*p++ = data ^ 0x8080;
 			count--;
 		}
@@ -228,7 +229,7 @@
 }
 
 
-static ssize_t ata_ct_s16be(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ct_s16be(const u_char __user *userPtr, size_t userCount,
 			    u_char frame[], ssize_t *frameUsed,
 			    ssize_t frameLeft)
 {
@@ -240,8 +241,9 @@
 		used = count*2;
 		while (count > 0) {
 			u_short data;
-			if (get_user(data, ((u_short *)userPtr)++))
+			if (get_user(data, (u_short __user *)userPtr))
 				return -EFAULT;
+			userPtr += 2;
 			*p++ = data;
 			*p++ = data;
 			count--;
@@ -259,7 +261,7 @@
 }
 
 
-static ssize_t ata_ct_u16be(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ct_u16be(const u_char __user *userPtr, size_t userCount,
 			    u_char frame[], ssize_t *frameUsed,
 			    ssize_t frameLeft)
 {
@@ -271,8 +273,9 @@
 		used = count*2;
 		while (count > 0) {
 			u_short data;
-			if (get_user(data, ((u_short *)userPtr)++))
+			if (get_user(data, (u_short __user *)userPtr))
 				return -EFAULT;
+			userPtr += 2;
 			data ^= 0x8000;
 			*p++ = data;
 			*p++ = data;
@@ -284,9 +287,10 @@
 		count = min_t(unsigned long, userCount, frameLeft)>>2;
 		used = count*4;
 		while (count > 0) {
-			u_long data;
-			if (get_user(data, ((u_int *)userPtr)++))
+			u_int data;
+			if (get_user(data, (u_int __user *)userPtr))
 				return -EFAULT;
+			userPtr += 4;
 			*p++ = data ^ 0x80008000;
 			count--;
 		}
@@ -296,7 +300,7 @@
 }
 
 
-static ssize_t ata_ct_s16le(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ct_s16le(const u_char __user *userPtr, size_t userCount,
 			    u_char frame[], ssize_t *frameUsed,
 			    ssize_t frameLeft)
 {
@@ -309,8 +313,9 @@
 		used = count*2;
 		while (count > 0) {
 			u_short data;
-			if (get_user(data, ((u_short *)userPtr)++))
+			if (get_user(data, (u_short __user *)userPtr))
 				return -EFAULT;
+			userPtr += 2;
 			data = le2be16(data);
 			*p++ = data;
 			*p++ = data;
@@ -323,8 +328,9 @@
 		used = count*4;
 		while (count > 0) {
 			u_long data;
-			if (get_user(data, ((u_int *)userPtr)++))
+			if (get_user(data, (u_int __user *)userPtr))
 				return -EFAULT;
+			userPtr += 4;
 			data = le2be16dbl(data);
 			*p++ = data;
 			count--;
@@ -335,7 +341,7 @@
 }
 
 
-static ssize_t ata_ct_u16le(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ct_u16le(const u_char __user *userPtr, size_t userCount,
 			    u_char frame[], ssize_t *frameUsed,
 			    ssize_t frameLeft)
 {
@@ -348,8 +354,9 @@
 		used = count*2;
 		while (count > 0) {
 			u_short data;
-			if (get_user(data, ((u_short *)userPtr)++))
+			if (get_user(data, (u_short __user *)userPtr))
 				return -EFAULT;
+			userPtr += 2;
 			data = le2be16(data) ^ 0x8000;
 			*p++ = data;
 			*p++ = data;
@@ -361,8 +368,9 @@
 		used = count;
 		while (count > 0) {
 			u_long data;
-			if (get_user(data, ((u_int *)userPtr)++))
+			if (get_user(data, (u_int __user *)userPtr))
 				return -EFAULT;
+			userPtr += 4;
 			data = le2be16dbl(data) ^ 0x80008000;
 			*p++ = data;
 			count--;
@@ -373,7 +381,7 @@
 }
 
 
-static ssize_t ata_ctx_law(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ctx_law(const u_char __user *userPtr, size_t userCount,
 			   u_char frame[], ssize_t *frameUsed,
 			   ssize_t frameLeft)
 {
@@ -435,7 +443,7 @@
 }
 
 
-static ssize_t ata_ctx_s8(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ctx_s8(const u_char __user *userPtr, size_t userCount,
 			  u_char frame[], ssize_t *frameUsed,
 			  ssize_t frameLeft)
 {
@@ -470,8 +478,9 @@
 			if (bal < 0) {
 				if (userCount < 2)
 					break;
-				if (get_user(data, ((u_short *)userPtr)++))
+				if (get_user(data, (u_short __user *)userPtr))
 					return -EFAULT;
+				userPtr += 2;
 				userCount -= 2;
 				bal += hSpeed;
 			}
@@ -488,7 +497,7 @@
 }
 
 
-static ssize_t ata_ctx_u8(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ctx_u8(const u_char __user *userPtr, size_t userCount,
 			  u_char frame[], ssize_t *frameUsed,
 			  ssize_t frameLeft)
 {
@@ -524,8 +533,9 @@
 			if (bal < 0) {
 				if (userCount < 2)
 					break;
-				if (get_user(data, ((u_short *)userPtr)++))
+				if (get_user(data, (u_short __user *)userPtr))
 					return -EFAULT;
+				userPtr += 2;
 				data ^= 0x8080;
 				userCount -= 2;
 				bal += hSpeed;
@@ -543,7 +553,7 @@
 }
 
 
-static ssize_t ata_ctx_s16be(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ctx_s16be(const u_char __user *userPtr, size_t userCount,
 			     u_char frame[], ssize_t *frameUsed,
 			     ssize_t frameLeft)
 {
@@ -561,8 +571,9 @@
 			if (bal < 0) {
 				if (userCount < 2)
 					break;
-				if (get_user(data, ((u_short *)userPtr)++))
+				if (get_user(data, (u_short __user *)userPtr))
 					return -EFAULT;
+				userPtr += 2;
 				userCount -= 2;
 				bal += hSpeed;
 			}
@@ -579,8 +590,9 @@
 			if (bal < 0) {
 				if (userCount < 4)
 					break;
-				if (get_user(data, ((u_int *)userPtr)++))
+				if (get_user(data, (u_int __user *)userPtr))
 					return -EFAULT;
+				userPtr += 4;
 				userCount -= 4;
 				bal += hSpeed;
 			}
@@ -597,7 +609,7 @@
 }
 
 
-static ssize_t ata_ctx_u16be(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ctx_u16be(const u_char __user *userPtr, size_t userCount,
 			     u_char frame[], ssize_t *frameUsed,
 			     ssize_t frameLeft)
 {
@@ -615,8 +627,9 @@
 			if (bal < 0) {
 				if (userCount < 2)
 					break;
-				if (get_user(data, ((u_short *)userPtr)++))
+				if (get_user(data, (u_short __user *)userPtr))
 					return -EFAULT;
+				userPtr += 2;
 				data ^= 0x8000;
 				userCount -= 2;
 				bal += hSpeed;
@@ -634,8 +647,9 @@
 			if (bal < 0) {
 				if (userCount < 4)
 					break;
-				if (get_user(data, ((u_int *)userPtr)++))
+				if (get_user(data, (u_int __user *)userPtr))
 					return -EFAULT;
+				userPtr += 4;
 				data ^= 0x80008000;
 				userCount -= 4;
 				bal += hSpeed;
@@ -653,7 +667,7 @@
 }
 
 
-static ssize_t ata_ctx_s16le(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ctx_s16le(const u_char __user *userPtr, size_t userCount,
 			     u_char frame[], ssize_t *frameUsed,
 			     ssize_t frameLeft)
 {
@@ -671,8 +685,9 @@
 			if (bal < 0) {
 				if (userCount < 2)
 					break;
-				if (get_user(data, ((u_short *)userPtr)++))
+				if (get_user(data, (u_short __user *)userPtr))
 					return -EFAULT;
+				userPtr += 2;
 				data = le2be16(data);
 				userCount -= 2;
 				bal += hSpeed;
@@ -690,8 +705,9 @@
 			if (bal < 0) {
 				if (userCount < 4)
 					break;
-				if (get_user(data, ((u_int *)userPtr)++))
+				if (get_user(data, (u_int __user *)userPtr))
 					return -EFAULT;
+				userPtr += 4;
 				data = le2be16dbl(data);
 				userCount -= 4;
 				bal += hSpeed;
@@ -709,7 +725,7 @@
 }
 
 
-static ssize_t ata_ctx_u16le(const u_char *userPtr, size_t userCount,
+static ssize_t ata_ctx_u16le(const u_char __user *userPtr, size_t userCount,
 			     u_char frame[], ssize_t *frameUsed,
 			     ssize_t frameLeft)
 {
@@ -727,8 +743,9 @@
 			if (bal < 0) {
 				if (userCount < 2)
 					break;
-				if (get_user(data, ((u_short *)userPtr)++))
+				if (get_user(data, (u_short __user *)userPtr))
 					return -EFAULT;
+				userPtr += 2;
 				data = le2be16(data) ^ 0x8000;
 				userCount -= 2;
 				bal += hSpeed;
@@ -746,8 +763,9 @@
 			if (bal < 0) {
 				if (userCount < 4)
 					break;
-				if (get_user(data, ((u_int *)userPtr)++))
+				if (get_user(data, (u_int __user *)userPtr))
 					return -EFAULT;
+				userPtr += 4;
 				data = le2be16dbl(data) ^ 0x80008000;
 				userCount -= 4;
 				bal += hSpeed;
diff --git a/sound/oss/dmasound/dmasound_paula.c b/sound/oss/dmasound/dmasound_paula.c
index d59f60b..494070a 100644
--- a/sound/oss/dmasound/dmasound_paula.c
+++ b/sound/oss/dmasound/dmasound_paula.c
@@ -34,6 +34,7 @@
 #define DMASOUND_PAULA_REVISION 0
 #define DMASOUND_PAULA_EDITION 4
 
+#define custom amiga_custom
    /*
     *	The minimum period for audio depends on htotal (for OCS/ECS/AGA)
     *	(Imported from arch/m68k/amiga/amisound.c)
@@ -156,7 +157,7 @@
      *  Native format
      */
 
-static ssize_t ami_ct_s8(const u_char *userPtr, size_t userCount,
+static ssize_t ami_ct_s8(const u_char __user *userPtr, size_t userCount,
 			 u_char frame[], ssize_t *frameUsed, ssize_t frameLeft)
 {
 	ssize_t count, used;
@@ -189,7 +190,7 @@
      */
 
 #define GENERATE_AMI_CT8(funcname, convsample)				\
-static ssize_t funcname(const u_char *userPtr, size_t userCount,	\
+static ssize_t funcname(const u_char __user *userPtr, size_t userCount,	\
 			u_char frame[], ssize_t *frameUsed,		\
 			ssize_t frameLeft)				\
 {									\
@@ -240,10 +241,11 @@
      */
 
 #define GENERATE_AMI_CT_16(funcname, convsample)			\
-static ssize_t funcname(const u_char *userPtr, size_t userCount,	\
+static ssize_t funcname(const u_char __user *userPtr, size_t userCount,	\
 			u_char frame[], ssize_t *frameUsed,		\
 			ssize_t frameLeft)				\
 {									\
+	const u_short __user *ptr = (const u_short __user *)userPtr;	\
 	ssize_t count, used;						\
 	u_short data;							\
 									\
@@ -253,7 +255,7 @@
 		count = min_t(size_t, userCount, frameLeft)>>1 & ~1;	\
 		used = count*2;						\
 		while (count > 0) {					\
-			if (get_user(data, ((u_short *)userPtr)++))	\
+			if (get_user(data, ptr++))			\
 				return -EFAULT;				\
 			data = convsample(data);			\
 			*high++ = data>>8;				\
@@ -268,12 +270,12 @@
 		count = min_t(size_t, userCount, frameLeft)>>2 & ~1;	\
 		used = count*4;						\
 		while (count > 0) {					\
-			if (get_user(data, ((u_short *)userPtr)++))	\
+			if (get_user(data, ptr++))			\
 				return -EFAULT;				\
 			data = convsample(data);			\
 			*lefth++ = data>>8;				\
 			*leftl++ = (data>>2) & 0x3f;			\
-			if (get_user(data, ((u_short *)userPtr)++))	\
+			if (get_user(data, ptr++))			\
 				return -EFAULT;				\
 			data = convsample(data);			\
 			*righth++ = data>>8;				\
diff --git a/sound/oss/dmasound/dmasound_q40.c b/sound/oss/dmasound/dmasound_q40.c
index 1ddaa62..e2081f3 100644
--- a/sound/oss/dmasound/dmasound_q40.c
+++ b/sound/oss/dmasound/dmasound_q40.c
@@ -58,7 +58,7 @@
 
 
 /* userCount, frameUsed, frameLeft == byte counts */
-static ssize_t q40_ct_law(const u_char *userPtr, size_t userCount,
+static ssize_t q40_ct_law(const u_char __user *userPtr, size_t userCount,
 			   u_char frame[], ssize_t *frameUsed,
 			   ssize_t frameLeft)
 {
@@ -79,7 +79,7 @@
 }
 
 
-static ssize_t q40_ct_s8(const u_char *userPtr, size_t userCount,
+static ssize_t q40_ct_s8(const u_char __user *userPtr, size_t userCount,
 			  u_char frame[], ssize_t *frameUsed,
 			  ssize_t frameLeft)
 {
@@ -98,7 +98,7 @@
 	return used;
 }
 
-static ssize_t q40_ct_u8(const u_char *userPtr, size_t userCount,
+static ssize_t q40_ct_u8(const u_char __user *userPtr, size_t userCount,
 			  u_char frame[], ssize_t *frameUsed,
 			  ssize_t frameLeft)
 {
@@ -114,7 +114,7 @@
 
 
 /* a bit too complicated to optimise right now ..*/
-static ssize_t q40_ctx_law(const u_char *userPtr, size_t userCount,
+static ssize_t q40_ctx_law(const u_char __user *userPtr, size_t userCount,
 			    u_char frame[], ssize_t *frameUsed,
 			    ssize_t frameLeft)
 {
@@ -152,7 +152,7 @@
 }
 
 
-static ssize_t q40_ctx_s8(const u_char *userPtr, size_t userCount,
+static ssize_t q40_ctx_s8(const u_char __user *userPtr, size_t userCount,
 			   u_char frame[], ssize_t *frameUsed,
 			   ssize_t frameLeft)
 {
@@ -189,7 +189,7 @@
 }
 
 
-static ssize_t q40_ctx_u8(const u_char *userPtr, size_t userCount,
+static ssize_t q40_ctx_u8(const u_char __user *userPtr, size_t userCount,
 			   u_char frame[], ssize_t *frameUsed,
 			   ssize_t frameLeft)
 {
@@ -224,7 +224,7 @@
 }
 
 /* compressing versions */
-static ssize_t q40_ctc_law(const u_char *userPtr, size_t userCount,
+static ssize_t q40_ctc_law(const u_char __user *userPtr, size_t userCount,
 			    u_char frame[], ssize_t *frameUsed,
 			    ssize_t frameLeft)
 {
@@ -265,7 +265,7 @@
 }
 
 
-static ssize_t q40_ctc_s8(const u_char *userPtr, size_t userCount,
+static ssize_t q40_ctc_s8(const u_char __user *userPtr, size_t userCount,
 			   u_char frame[], ssize_t *frameUsed,
 			   ssize_t frameLeft)
 {
@@ -304,7 +304,7 @@
 }
 
 
-static ssize_t q40_ctc_u8(const u_char *userPtr, size_t userCount,
+static ssize_t q40_ctc_u8(const u_char __user *userPtr, size_t userCount,
 			   u_char frame[], ssize_t *frameUsed,
 			   ssize_t frameLeft)
 {
diff --git a/sound/oss/dmasound/trans_16.c b/sound/oss/dmasound/trans_16.c
index 23562e9..ca973ac 100644
--- a/sound/oss/dmasound/trans_16.c
+++ b/sound/oss/dmasound/trans_16.c
@@ -17,6 +17,7 @@
 #include <asm/uaccess.h>
 #include "dmasound.h"
 
+extern int expand_bal;	/* Balance factor for expanding (not volume!) */
 static short dmasound_alaw2dma16[] ;
 static short dmasound_ulaw2dma16[] ;