From f623e9553fa1a8893eb73aa6b8b5f7a229ed03fb Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Thu, 12 Jan 2006 18:44:32 +0000 Subject: [PATCH] --- yaml --- r: 18215 b: refs/heads/master c: f392ecfa12de9a2baf72789b00557bac040d6171 h: refs/heads/master i: 18213: 667a05ce9bdd92588e826ee7c0db562670df8ac7 18211: 1b82bc2dec9c273a32b9d2206790180a8e4263cf 18207: 9b4687e0531519c2ad13171435b0d3d717429bd9 v: v3 --- [refs] | 2 +- trunk/Documentation/kernel-parameters.txt | 43 - trunk/arch/alpha/kernel/process.c | 29 +- trunk/arch/alpha/kernel/ptrace.c | 47 +- trunk/arch/alpha/kernel/smp.c | 2 +- trunk/arch/arm/kernel/process.c | 13 +- trunk/arch/arm/kernel/ptrace.c | 37 +- trunk/arch/arm/kernel/smp.c | 4 +- trunk/arch/arm/kernel/traps.c | 4 +- trunk/arch/arm26/kernel/process.c | 5 +- trunk/arch/arm26/kernel/ptrace.c | 29 +- trunk/arch/arm26/kernel/traps.c | 8 +- trunk/arch/cris/arch-v10/kernel/process.c | 4 +- trunk/arch/cris/arch-v10/kernel/ptrace.c | 4 +- trunk/arch/cris/arch-v32/kernel/process.c | 6 +- trunk/arch/cris/arch-v32/kernel/ptrace.c | 6 +- trunk/arch/cris/arch-v32/kernel/smp.c | 4 +- trunk/arch/cris/arch-v32/mm/tlb.c | 4 +- trunk/arch/frv/kernel/process.c | 4 +- trunk/arch/h8300/kernel/process.c | 2 +- trunk/arch/i386/kernel/process.c | 26 +- trunk/arch/i386/kernel/smpboot.c | 4 +- trunk/arch/i386/kernel/vm86.c | 2 +- trunk/arch/ia64/ia32/elfcore32.h | 3 +- trunk/arch/ia64/ia32/ia32_signal.c | 4 +- trunk/arch/ia64/ia32/ia32_support.c | 4 +- trunk/arch/ia64/ia32/sys_ia32.c | 12 +- trunk/arch/ia64/kernel/mca.c | 4 +- trunk/arch/ia64/kernel/perfmon.c | 32 +- trunk/arch/ia64/kernel/process.c | 12 +- trunk/arch/ia64/kernel/ptrace.c | 24 +- trunk/arch/ia64/kernel/setup.c | 18 +- trunk/arch/ia64/kernel/signal.c | 10 +- trunk/arch/ia64/kernel/sys_ia64.c | 2 +- trunk/arch/m32r/kernel/process.c | 5 +- trunk/arch/m32r/kernel/ptrace.c | 25 +- trunk/arch/m32r/kernel/smpboot.c | 2 +- trunk/arch/m68k/amiga/amiints.c | 46 +- trunk/arch/m68k/amiga/amisound.c | 2 - trunk/arch/m68k/amiga/cia.c | 8 +- trunk/arch/m68k/amiga/config.c | 27 +- trunk/arch/m68k/apollo/config.c | 3 + trunk/arch/m68k/atari/config.c | 9 + trunk/arch/m68k/bvme6000/rtc.c | 6 +- trunk/arch/m68k/hp300/config.c | 3 + trunk/arch/m68k/kernel/asm-offsets.c | 2 +- trunk/arch/m68k/kernel/head.S | 2 - trunk/arch/m68k/kernel/process.c | 7 +- trunk/arch/m68k/kernel/setup.c | 19 +- trunk/arch/m68k/kernel/signal.c | 62 +- trunk/arch/m68k/kernel/sys_m68k.c | 39 +- trunk/arch/m68k/kernel/traps.c | 38 +- trunk/arch/m68k/kernel/vmlinux-std.lds | 1 - trunk/arch/m68k/kernel/vmlinux-sun3.lds | 3 +- trunk/arch/m68k/lib/checksum.c | 2 +- trunk/arch/m68k/mac/config.c | 3 + trunk/arch/m68k/mac/iop.c | 4 +- trunk/arch/m68k/mac/misc.c | 326 ++-- trunk/arch/m68k/math-emu/multi_arith.h | 2 +- trunk/arch/m68k/mm/kmap.c | 12 +- trunk/arch/m68k/mvme16x/rtc.c | 6 +- trunk/arch/m68k/q40/config.c | 5 + trunk/arch/m68k/sun3/config.c | 3 + trunk/arch/m68k/sun3x/config.c | 4 + trunk/arch/m68knommu/kernel/process.c | 5 +- trunk/arch/mips/kernel/process.c | 10 +- trunk/arch/mips/kernel/ptrace.c | 14 +- trunk/arch/mips/kernel/ptrace32.c | 10 +- trunk/arch/mips/kernel/smp_mt.c | 7 +- trunk/arch/mips/kernel/syscall.c | 2 +- trunk/arch/mips/kernel/traps.c | 2 +- trunk/arch/mips/pmc-sierra/yosemite/smp.c | 4 +- trunk/arch/mips/sgi-ip27/ip27-smp.c | 4 +- trunk/arch/mips/sibyte/cfe/smp.c | 2 +- trunk/arch/parisc/kernel/process.c | 6 +- trunk/arch/parisc/kernel/smp.c | 2 +- trunk/arch/powerpc/kernel/Makefile | 6 +- trunk/arch/powerpc/kernel/pci_64.c | 5 +- trunk/arch/powerpc/kernel/process.c | 22 +- trunk/arch/powerpc/kernel/prom.c | 28 +- trunk/arch/powerpc/kernel/prom_init.c | 8 +- trunk/arch/powerpc/kernel/ptrace-common.h | 4 +- trunk/arch/powerpc/kernel/signal_32.c | 21 +- trunk/arch/powerpc/kernel/signal_64.c | 20 +- trunk/arch/powerpc/kernel/smp.c | 6 +- trunk/arch/powerpc/platforms/cell/pervasive.c | 2 +- trunk/arch/powerpc/platforms/cell/setup.c | 2 +- trunk/arch/powerpc/platforms/cell/smp.c | 2 +- .../powerpc/platforms/cell/spufs/syscalls.c | 4 +- trunk/arch/powerpc/platforms/iseries/Makefile | 4 +- trunk/arch/powerpc/platforms/iseries/iommu.c | 2 - trunk/arch/powerpc/platforms/iseries/iommu.h | 35 - trunk/arch/powerpc/platforms/iseries/irq.c | 19 +- .../arch/powerpc/platforms/iseries/lpardata.c | 5 +- .../arch/powerpc/platforms/iseries/lpevents.c | 12 +- trunk/arch/powerpc/platforms/iseries/mf.c | 16 +- trunk/arch/powerpc/platforms/iseries/pci.c | 1 - trunk/arch/powerpc/platforms/iseries/vio.c | 2 - .../arch/powerpc/platforms/iseries/viopath.c | 12 +- trunk/arch/powerpc/platforms/powermac/setup.c | 2 +- trunk/arch/powerpc/platforms/pseries/eeh.c | 5 +- .../powerpc/platforms/pseries/hvcserver.c | 4 +- trunk/arch/powerpc/platforms/pseries/iommu.c | 2 + .../arch/powerpc/platforms/pseries/scanlog.c | 4 +- trunk/arch/powerpc/platforms/pseries/setup.c | 2 +- trunk/arch/powerpc/platforms/pseries/smp.c | 6 +- trunk/arch/powerpc/platforms/pseries/xics.c | 2 +- trunk/arch/powerpc/sysdev/dart_iommu.c | 1 + trunk/arch/powerpc/xmon/xmon.c | 14 +- trunk/arch/ppc/amiga/amiints.c | 40 +- trunk/arch/ppc/amiga/cia.c | 8 +- trunk/arch/ppc/amiga/config.c | 24 +- trunk/arch/ppc/kernel/Makefile | 1 + trunk/arch/ppc/kernel/process.c | 851 ++++++++++ trunk/arch/ppc/kernel/smp.c | 4 +- trunk/arch/ppc/platforms/apus_setup.c | 30 +- trunk/arch/ppc/xmon/xmon.c | 2 +- trunk/arch/s390/kernel/binfmt_elf32.c | 2 +- trunk/arch/s390/kernel/process.c | 12 +- trunk/arch/s390/kernel/ptrace.c | 26 +- trunk/arch/s390/kernel/smp.c | 2 +- trunk/arch/s390/kernel/time.c | 2 +- trunk/arch/s390/kernel/traps.c | 6 +- trunk/arch/sh/kernel/process.c | 46 +- trunk/arch/sh/kernel/ptrace.c | 14 +- trunk/arch/sh/kernel/smp.c | 2 +- trunk/arch/sh64/kernel/process.c | 4 +- trunk/arch/sh64/lib/dbg.c | 2 +- trunk/arch/sparc/kernel/process.c | 12 +- trunk/arch/sparc/kernel/ptrace.c | 4 +- trunk/arch/sparc/kernel/sun4d_smp.c | 2 +- trunk/arch/sparc/kernel/sun4m_smp.c | 2 +- trunk/arch/sparc/kernel/traps.c | 4 +- trunk/arch/sparc64/kernel/process.c | 10 +- trunk/arch/sparc64/kernel/ptrace.c | 46 +- trunk/arch/sparc64/kernel/setup.c | 2 +- trunk/arch/sparc64/kernel/smp.c | 2 +- trunk/arch/sparc64/kernel/traps.c | 4 +- trunk/arch/um/kernel/process_kern.c | 2 +- trunk/arch/um/kernel/skas/process_kern.c | 4 +- trunk/arch/um/kernel/tt/exec_kern.c | 2 +- trunk/arch/um/kernel/tt/process_kern.c | 8 +- trunk/arch/v850/kernel/process.c | 2 +- trunk/arch/v850/kernel/ptrace.c | 2 +- trunk/arch/x86_64/ia32/ia32_binfmt.c | 7 +- trunk/arch/x86_64/ia32/ptrace32.c | 6 +- trunk/arch/x86_64/kernel/i387.c | 2 +- trunk/arch/x86_64/kernel/i8259.c | 2 +- trunk/arch/x86_64/kernel/process.c | 11 +- trunk/arch/x86_64/kernel/ptrace.c | 10 +- trunk/arch/x86_64/kernel/smpboot.c | 4 +- trunk/arch/x86_64/kernel/traps.c | 6 +- trunk/arch/xtensa/kernel/process.c | 4 +- trunk/arch/xtensa/kernel/ptrace.c | 12 +- trunk/block/elevator.c | 20 +- trunk/drivers/block/amiflop.c | 30 +- trunk/drivers/block/ataflop.c | 27 +- trunk/drivers/block/viodasd.c | 32 +- trunk/drivers/cdrom/viocd.c | 6 +- trunk/drivers/char/amiserial.c | 20 +- trunk/drivers/char/dsp56k.c | 29 +- trunk/drivers/char/mem.c | 8 +- trunk/drivers/char/scc.h | 2 +- trunk/drivers/char/viocons.c | 31 +- trunk/drivers/ide/ide-io.c | 34 +- trunk/drivers/ide/ide-probe.c | 2 + trunk/drivers/input/evdev.c | 2 +- trunk/drivers/input/joystick/amijoy.c | 4 +- trunk/drivers/input/mouse/amimouse.c | 6 +- trunk/drivers/macintosh/adb-iop.c | 2 +- trunk/drivers/macintosh/via-macii.c | 4 +- trunk/drivers/macintosh/via-maciisi.c | 22 +- trunk/drivers/macintosh/via-pmu68k.c | 4 +- trunk/drivers/md/md.c | 3 - trunk/drivers/mfd/ucb1x00-core.c | 27 +- trunk/drivers/mmc/mmc_block.c | 11 +- trunk/drivers/net/hplance.c | 2 +- trunk/drivers/net/iseries_veth.c | 4 +- trunk/drivers/net/mac8390.c | 31 +- trunk/drivers/net/sun3lance.c | 2 +- trunk/drivers/scsi/Makefile | 3 +- trunk/drivers/scsi/NCR53C9x.c | 5 +- trunk/drivers/scsi/blz1230.c | 4 +- trunk/drivers/scsi/blz2060.c | 4 +- trunk/drivers/scsi/cyberstorm.c | 4 +- trunk/drivers/scsi/cyberstormII.c | 4 +- trunk/drivers/scsi/fastlane.c | 4 +- trunk/drivers/scsi/oktagon_esp.c | 2 +- trunk/drivers/scsi/wd33c93.c | 4 +- trunk/drivers/serial/8250.c | 11 +- trunk/drivers/serial/crisv10.c | 11 +- trunk/drivers/serial/pmac_zilog.c | 23 +- trunk/drivers/serial/serial_core.c | 15 +- trunk/drivers/serial/serial_txx9.c | 11 +- trunk/drivers/video/amifb.c | 36 +- trunk/drivers/video/aty/atyfb_base.c | 2 +- trunk/drivers/video/macfb.c | 15 +- trunk/drivers/zorro/proc.c | 2 +- trunk/fs/compat_ioctl.c | 29 - trunk/fs/xfs/linux-2.6/xfs_aops.c | 1088 ++++++------- trunk/fs/xfs/linux-2.6/xfs_aops.h | 10 - trunk/fs/xfs/linux-2.6/xfs_buf.c | 1373 +++++++++-------- trunk/fs/xfs/linux-2.6/xfs_buf.h | 696 +++++---- trunk/fs/xfs/linux-2.6/xfs_file.c | 6 +- trunk/fs/xfs/linux-2.6/xfs_ioctl.c | 10 +- trunk/fs/xfs/linux-2.6/xfs_iops.c | 121 +- trunk/fs/xfs/linux-2.6/xfs_iops.h | 5 + trunk/fs/xfs/linux-2.6/xfs_linux.h | 6 +- trunk/fs/xfs/linux-2.6/xfs_lrw.c | 56 +- trunk/fs/xfs/linux-2.6/xfs_stats.c | 2 +- trunk/fs/xfs/linux-2.6/xfs_stats.h | 18 +- trunk/fs/xfs/linux-2.6/xfs_super.c | 19 +- trunk/fs/xfs/linux-2.6/xfs_vnode.c | 1 + trunk/fs/xfs/linux-2.6/xfs_vnode.h | 19 - trunk/fs/xfs/quota/xfs_dquot_item.c | 4 +- trunk/fs/xfs/quota/xfs_qm.c | 18 +- trunk/fs/xfs/support/debug.c | 60 +- trunk/fs/xfs/support/debug.h | 25 +- trunk/fs/xfs/support/uuid.c | 23 +- trunk/fs/xfs/xfs_arch.h | 22 +- trunk/fs/xfs/xfs_attr_leaf.c | 12 +- trunk/fs/xfs/xfs_attr_leaf.h | 79 +- trunk/fs/xfs/xfs_bmap.c | 412 ++--- trunk/fs/xfs/xfs_bmap.h | 7 +- trunk/fs/xfs/xfs_clnt.h | 2 +- trunk/fs/xfs/xfs_dfrag.c | 16 +- trunk/fs/xfs/xfs_dinode.h | 22 +- trunk/fs/xfs/xfs_dir.c | 2 +- trunk/fs/xfs/xfs_dir.h | 2 - trunk/fs/xfs/xfs_dir2.h | 3 + trunk/fs/xfs/xfs_dir_leaf.h | 64 +- trunk/fs/xfs/xfs_error.c | 1 + trunk/fs/xfs/xfs_error.h | 8 +- trunk/fs/xfs/xfs_fs.h | 10 +- trunk/fs/xfs/xfs_fsops.c | 26 - trunk/fs/xfs/xfs_fsops.h | 1 - trunk/fs/xfs/xfs_iget.c | 5 +- trunk/fs/xfs/xfs_inode.c | 61 +- trunk/fs/xfs/xfs_inode.h | 4 - trunk/fs/xfs/xfs_inode_item.c | 9 +- trunk/fs/xfs/xfs_iomap.c | 425 +++-- trunk/fs/xfs/xfs_itable.c | 5 +- trunk/fs/xfs/xfs_log.c | 123 +- trunk/fs/xfs/xfs_log.h | 11 +- trunk/fs/xfs/xfs_log_priv.h | 77 +- trunk/fs/xfs/xfs_log_recover.c | 12 +- trunk/fs/xfs/xfs_mount.c | 5 +- trunk/fs/xfs/xfs_mount.h | 3 +- trunk/fs/xfs/xfs_rename.c | 7 +- trunk/fs/xfs/xfs_rw.c | 9 +- trunk/fs/xfs/xfs_sb.h | 17 + trunk/fs/xfs/xfs_trans.c | 14 +- trunk/fs/xfs/xfs_trans.h | 1 + trunk/fs/xfs/xfs_utils.c | 9 +- trunk/fs/xfs/xfs_vfsops.c | 50 +- trunk/fs/xfs/xfs_vnodeops.c | 193 +-- trunk/include/asm-alpha/mmu_context.h | 6 +- trunk/include/asm-alpha/processor.h | 13 +- trunk/include/asm-alpha/ptrace.h | 6 +- trunk/include/asm-alpha/system.h | 18 +- trunk/include/asm-alpha/thread_info.h | 2 + trunk/include/asm-arm/processor.h | 8 +- trunk/include/asm-arm/system.h | 12 +- trunk/include/asm-arm/thread_info.h | 7 +- trunk/include/asm-arm26/system.h | 12 +- trunk/include/asm-arm26/thread_info.h | 9 +- trunk/include/asm-cris/arch-v10/processor.h | 2 +- trunk/include/asm-cris/arch-v32/processor.h | 2 +- trunk/include/asm-cris/processor.h | 3 +- trunk/include/asm-cris/thread_info.h | 2 + trunk/include/asm-frv/thread_info.h | 2 + trunk/include/asm-h8300/thread_info.h | 2 + trunk/include/asm-i386/i387.h | 8 +- trunk/include/asm-i386/processor.h | 12 +- trunk/include/asm-i386/system.h | 9 - trunk/include/asm-i386/thread_info.h | 2 + trunk/include/asm-i386/topology.h | 1 + trunk/include/asm-ia64/compat.h | 2 +- trunk/include/asm-ia64/processor.h | 2 +- trunk/include/asm-ia64/ptrace.h | 4 +- trunk/include/asm-ia64/system.h | 9 +- trunk/include/asm-ia64/thread_info.h | 9 - trunk/include/asm-ia64/topology.h | 2 + trunk/include/asm-m32r/ptrace.h | 3 - trunk/include/asm-m32r/system.h | 10 - trunk/include/asm-m32r/thread_info.h | 2 + trunk/include/asm-m68k/amigahw.h | 12 +- trunk/include/asm-m68k/amigaints.h | 2 + trunk/include/asm-m68k/checksum.h | 2 +- trunk/include/asm-m68k/dsp56k.h | 2 +- trunk/include/asm-m68k/floppy.h | 2 +- trunk/include/asm-m68k/hardirq.h | 9 + trunk/include/asm-m68k/io.h | 49 +- trunk/include/asm-m68k/irq.h | 9 - trunk/include/asm-m68k/machdep.h | 1 + trunk/include/asm-m68k/raw_io.h | 40 +- trunk/include/asm-m68k/signal.h | 2 +- trunk/include/asm-m68k/sun3_pgtable.h | 2 +- trunk/include/asm-m68k/sun3ints.h | 1 + trunk/include/asm-m68k/sun3xflop.h | 4 +- trunk/include/asm-m68k/thread_info.h | 1 - trunk/include/asm-m68k/uaccess.h | 20 +- trunk/include/asm-m68k/zorro.h | 8 +- trunk/include/asm-m68knommu/machdep.h | 1 + trunk/include/asm-m68knommu/thread_info.h | 2 + trunk/include/asm-mips/mach-ip27/topology.h | 1 + trunk/include/asm-mips/processor.h | 10 +- trunk/include/asm-mips/system.h | 12 +- trunk/include/asm-mips/thread_info.h | 2 + trunk/include/asm-parisc/system.h | 9 - trunk/include/asm-parisc/thread_info.h | 3 + trunk/include/asm-powerpc/iommu.h | 19 + trunk/include/asm-powerpc/iseries/hv_call.h | 4 +- .../asm-powerpc/iseries/hv_call_event.h | 134 +- .../include/asm-powerpc/iseries/hv_call_sc.h | 1 + .../asm-powerpc/iseries/hv_lp_config.h | 1 + .../include/asm-powerpc/iseries/hv_lp_event.h | 42 +- trunk/include/asm-powerpc/iseries/hv_types.h | 1 + .../include/asm-powerpc/iseries/iseries_io.h | 14 +- .../asm-powerpc/iseries/it_exp_vpd_panel.h | 1 + .../include/asm-powerpc/iseries/it_lp_naca.h | 22 +- .../include/asm-powerpc/iseries/it_lp_queue.h | 1 + .../asm-powerpc/iseries/it_lp_reg_save.h | 3 +- trunk/include/asm-powerpc/iseries/lpar_map.h | 1 + trunk/include/asm-powerpc/iseries/mf.h | 1 + trunk/include/asm-powerpc/iseries/vio.h | 1 + trunk/include/asm-powerpc/pci-bridge.h | 2 + trunk/include/asm-powerpc/system.h | 18 - trunk/include/asm-powerpc/thread_info.h | 3 + trunk/include/asm-powerpc/topology.h | 1 + trunk/include/asm-ppc/system.h | 22 +- trunk/include/asm-s390/elf.h | 2 +- trunk/include/asm-s390/processor.h | 8 +- trunk/include/asm-s390/system.h | 10 - trunk/include/asm-s390/thread_info.h | 2 + trunk/include/asm-sh/ptrace.h | 10 - trunk/include/asm-sh/system.h | 10 - trunk/include/asm-sh/thread_info.h | 2 + trunk/include/asm-sh64/thread_info.h | 2 + trunk/include/asm-sparc/system.h | 12 +- trunk/include/asm-sparc/thread_info.h | 3 + trunk/include/asm-sparc64/elf.h | 2 +- trunk/include/asm-sparc64/mmu_context.h | 2 +- trunk/include/asm-sparc64/processor.h | 5 +- trunk/include/asm-sparc64/system.h | 14 +- trunk/include/asm-um/thread_info.h | 3 + trunk/include/asm-v850/processor.h | 8 +- trunk/include/asm-v850/thread_info.h | 2 + trunk/include/asm-x86_64/compat.h | 2 +- trunk/include/asm-x86_64/i387.h | 10 +- trunk/include/asm-x86_64/processor.h | 4 +- trunk/include/asm-x86_64/system.h | 9 - trunk/include/asm-x86_64/thread_info.h | 2 + trunk/include/asm-x86_64/topology.h | 1 + trunk/include/asm-xtensa/processor.h | 6 +- trunk/include/asm-xtensa/ptrace.h | 4 +- trunk/include/asm-xtensa/thread_info.h | 2 + trunk/include/linux/hrtimer.h | 12 +- trunk/include/linux/ide.h | 1 + trunk/include/linux/ktime.h | 4 +- trunk/include/linux/sched.h | 15 +- trunk/include/linux/topology.h | 2 + trunk/kernel/hrtimer.c | 34 +- trunk/kernel/sched.c | 478 +----- trunk/mm/mempolicy.c | 4 +- trunk/mm/page_alloc.c | 2 +- trunk/mm/swap.c | 2 - trunk/mm/tiny-shmem.c | 2 +- trunk/sound/oss/dmasound/dmasound.h | 1 + trunk/sound/oss/dmasound/dmasound_atari.c | 112 +- trunk/sound/oss/dmasound/dmasound_paula.c | 14 +- trunk/sound/oss/dmasound/dmasound_q40.c | 18 +- trunk/sound/oss/dmasound/trans_16.c | 1 - 373 files changed, 5067 insertions(+), 4982 deletions(-) delete mode 100644 trunk/arch/powerpc/platforms/iseries/iommu.h create mode 100644 trunk/arch/ppc/kernel/process.c diff --git a/[refs] b/[refs] index 911dd20aac0a..c6231f69e93e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: a2b421fee37d34c09bd2a14d3e9294f838c64370 +refs/heads/master: f392ecfa12de9a2baf72789b00557bac040d6171 diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index fe11fccf7e41..dd0bfc291a68 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -856,49 +856,6 @@ running once the system is up. mga= [HW,DRM] - migration_cost= - [KNL,SMP] debug: override scheduler migration costs - Format: ,,... - 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= - 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/trunk/arch/alpha/kernel/process.c b/trunk/arch/alpha/kernel/process.c index 9924fd07743a..abb739b88ed1 100644 --- a/trunk/arch/alpha/kernel/process.c +++ b/trunk/arch/alpha/kernel/process.c @@ -276,7 +276,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, { extern void ret_from_fork(void); - struct thread_info *childti = task_thread_info(p); + struct thread_info *childti = p->thread_info; struct pt_regs * childregs; struct switch_stack * childstack, *stack; unsigned long stack_offset, settls; @@ -285,7 +285,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, if (!(regs->ps & 8)) stack_offset = (PAGE_SIZE-1) & (unsigned long) regs; childregs = (struct pt_regs *) - (stack_offset + PAGE_SIZE + task_stack_page(p)); + (stack_offset + PAGE_SIZE + (long) childti); *childregs = *regs; settls = regs->r20; @@ -428,15 +428,30 @@ dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt, struct thread_info *ti) int dump_elf_task(elf_greg_t *dest, struct task_struct *task) { - dump_elf_thread(dest, task_pt_regs(task), task_thread_info(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); + return 1; } int dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task) { - struct switch_stack *sw = (struct switch_stack *)task_pt_regs(task) - 1; + 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; + memcpy(dest, sw->fp, 32 * 8); + return 1; } @@ -477,8 +492,8 @@ do_sys_execve(char __user *ufilename, char __user * __user *argv, unsigned long thread_saved_pc(task_t *t) { - unsigned long base = (unsigned long)task_stack_page(t); - unsigned long fp, sp = task_thread_info(t)->pcb.ksp; + unsigned long base = (unsigned long)t->thread_info; + unsigned long fp, sp = t->thread_info->pcb.ksp; if (sp > base && sp+6*8 < base + 16*1024) { fp = ((unsigned long*)sp)[6]; @@ -508,7 +523,7 @@ get_wchan(struct task_struct *p) pc = thread_saved_pc(p); if (in_sched_functions(pc)) { - schedule_frame = ((unsigned long *)task_thread_info(p)->pcb.ksp)[6]; + schedule_frame = ((unsigned long *)p->thread_info->pcb.ksp)[6]; return ((unsigned long *)schedule_frame)[12]; } return pc; diff --git a/trunk/arch/alpha/kernel/ptrace.c b/trunk/arch/alpha/kernel/ptrace.c index 0cd060598f9a..9969d212e94d 100644 --- a/trunk/arch/alpha/kernel/ptrace.c +++ b/trunk/arch/alpha/kernel/ptrace.c @@ -72,13 +72,6 @@ enum { 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), @@ -110,14 +103,14 @@ get_reg_addr(struct task_struct * task, unsigned long regno) unsigned long *addr; if (regno == 30) { - addr = &task_thread_info(task)->pcb.usp; + addr = &task->thread_info->pcb.usp; } else if (regno == 65) { - addr = &task_thread_info(task)->pcb.unique; + addr = &task->thread_info->pcb.unique; } else if (regno == 31 || regno > 65) { zero = 0; addr = &zero; } else { - addr = task_stack_page(task) + regoff[regno]; + addr = (void *)task->thread_info + regoff[regno]; } return addr; } @@ -132,7 +125,7 @@ get_reg(struct task_struct * task, unsigned long regno) if (regno == 63) { unsigned long fpcr = *get_reg_addr(task, regno); unsigned long swcr - = task_thread_info(task)->ieee_state & IEEE_SW_MASK; + = task->thread_info->ieee_state & IEEE_SW_MASK; swcr = swcr_update_status(swcr, fpcr); return fpcr | swcr; } @@ -146,8 +139,8 @@ static int put_reg(struct task_struct *task, unsigned long regno, unsigned long data) { if (regno == 63) { - task_thread_info(task)->ieee_state - = ((task_thread_info(task)->ieee_state & ~IEEE_SW_MASK) + task->thread_info->ieee_state + = ((task->thread_info->ieee_state & ~IEEE_SW_MASK) | (data & IEEE_SW_MASK)); data = (data & FPCR_DYN_MASK) | ieee_swcr_to_fpcr(data); } @@ -195,35 +188,35 @@ ptrace_set_bpt(struct task_struct * child) * branch (emulation can be tricky for fp branches). */ displ = ((s32)(insn << 11)) >> 9; - task_thread_info(child)->bpt_addr[nsaved++] = pc + 4; + child->thread_info->bpt_addr[nsaved++] = pc + 4; if (displ) /* guard against unoptimized code */ - task_thread_info(child)->bpt_addr[nsaved++] + child->thread_info->bpt_addr[nsaved++] = pc + 4 + displ; DBG(DBG_BPT, ("execing branch\n")); } else if (op_code == 0x1a) { reg_b = (insn >> 16) & 0x1f; - task_thread_info(child)->bpt_addr[nsaved++] = get_reg(child, reg_b); + child->thread_info->bpt_addr[nsaved++] = get_reg(child, reg_b); DBG(DBG_BPT, ("execing jump\n")); } else { - task_thread_info(child)->bpt_addr[nsaved++] = pc + 4; + child->thread_info->bpt_addr[nsaved++] = pc + 4; DBG(DBG_BPT, ("execing normal insn\n")); } /* install breakpoints: */ for (i = 0; i < nsaved; ++i) { - res = read_int(child, task_thread_info(child)->bpt_addr[i], + res = read_int(child, child->thread_info->bpt_addr[i], (int *) &insn); if (res < 0) return res; - task_thread_info(child)->bpt_insn[i] = insn; + child->thread_info->bpt_insn[i] = insn; DBG(DBG_BPT, (" -> next_pc=%lx\n", - task_thread_info(child)->bpt_addr[i])); - res = write_int(child, task_thread_info(child)->bpt_addr[i], + child->thread_info->bpt_addr[i])); + res = write_int(child, child->thread_info->bpt_addr[i], BREAKINST); if (res < 0) return res; } - task_thread_info(child)->bpt_nsaved = nsaved; + child->thread_info->bpt_nsaved = nsaved; return 0; } @@ -234,9 +227,9 @@ ptrace_set_bpt(struct task_struct * child) int ptrace_cancel_bpt(struct task_struct * child) { - int i, nsaved = task_thread_info(child)->bpt_nsaved; + int i, nsaved = child->thread_info->bpt_nsaved; - task_thread_info(child)->bpt_nsaved = 0; + child->thread_info->bpt_nsaved = 0; if (nsaved > 2) { printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved); @@ -244,8 +237,8 @@ ptrace_cancel_bpt(struct task_struct * child) } for (i = 0; i < nsaved; ++i) { - write_int(child, task_thread_info(child)->bpt_addr[i], - task_thread_info(child)->bpt_insn[i]); + write_int(child, child->thread_info->bpt_addr[i], + child->thread_info->bpt_insn[i]); } return (nsaved != 0); } @@ -362,7 +355,7 @@ do_sys_ptrace(long request, long pid, long addr, long data, if (!valid_signal(data)) break; /* Mark single stepping. */ - task_thread_info(child)->bpt_nsaved = -1; + child->thread_info->bpt_nsaved = -1; clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); child->exit_code = data; wake_up_process(child); diff --git a/trunk/arch/alpha/kernel/smp.c b/trunk/arch/alpha/kernel/smp.c index 4b873527ce1c..da0be3465791 100644 --- a/trunk/arch/alpha/kernel/smp.c +++ b/trunk/arch/alpha/kernel/smp.c @@ -302,7 +302,7 @@ secondary_cpu_start(int cpuid, struct task_struct *idle) + hwrpb->processor_offset + cpuid * hwrpb->processor_size); hwpcb = (struct pcb_struct *) cpu->hwpcb; - ipcb = &task_thread_info(idle)->pcb; + ipcb = &idle->thread_info->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/trunk/arch/arm/kernel/process.c b/trunk/arch/arm/kernel/process.c index 4b4e4cf79c80..54a21bdcba5c 100644 --- a/trunk/arch/arm/kernel/process.c +++ b/trunk/arch/arm/kernel/process.c @@ -342,10 +342,10 @@ void flush_thread(void) void release_thread(struct task_struct *dead_task) { #if defined(CONFIG_VFP) - vfp_release_thread(&task_thread_info(dead_task)->vfpstate); + vfp_release_thread(&dead_task->thread_info->vfpstate); #endif #if defined(CONFIG_IWMMXT) - iwmmxt_task_release(task_thread_info(dead_task)); + iwmmxt_task_release(dead_task->thread_info); #endif } @@ -355,9 +355,10 @@ int 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 = task_thread_info(p); - struct pt_regs *childregs = task_pt_regs(p); + struct thread_info *thread = p->thread_info; + struct pt_regs *childregs; + childregs = (void *)thread + THREAD_START_SP - sizeof(*regs); *childregs = *regs; childregs->ARM_r0 = 0; childregs->ARM_sp = stack_start; @@ -459,8 +460,8 @@ unsigned long get_wchan(struct task_struct *p) if (!p || p == current || p->state == TASK_RUNNING) return 0; - stack_start = (unsigned long)end_of_stack(p); - stack_end = (unsigned long)task_stack_page(p) + THREAD_SIZE; + stack_start = (unsigned long)(p->thread_info + 1); + stack_end = ((unsigned long)p->thread_info) + THREAD_SIZE; fp = thread_saved_fp(p); do { diff --git a/trunk/arch/arm/kernel/ptrace.c b/trunk/arch/arm/kernel/ptrace.c index e591f72bcdeb..2b84f78d7b0f 100644 --- a/trunk/arch/arm/kernel/ptrace.c +++ b/trunk/arch/arm/kernel/ptrace.c @@ -54,6 +54,23 @@ #define BREAKINST_THUMB 0xde01 #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. @@ -62,7 +79,7 @@ */ static inline long get_user_reg(struct task_struct *task, int offset) { - return task_pt_regs(task)->uregs[offset]; + return get_user_regs(task)->uregs[offset]; } /* @@ -74,7 +91,7 @@ static inline long get_user_reg(struct task_struct *task, int offset) static inline int put_user_reg(struct task_struct *task, int offset, long data) { - struct pt_regs newregs, *regs = task_pt_regs(task); + struct pt_regs newregs, *regs = get_user_regs(task); int ret = -EINVAL; newregs = *regs; @@ -404,7 +421,7 @@ void ptrace_set_bpt(struct task_struct *child) u32 insn; int res; - regs = task_pt_regs(child); + regs = get_user_regs(child); pc = instruction_pointer(regs); if (thumb_mode(regs)) { @@ -555,7 +572,7 @@ static int ptrace_write_user(struct task_struct *tsk, unsigned long off, */ static int ptrace_getregs(struct task_struct *tsk, void __user *uregs) { - struct pt_regs *regs = task_pt_regs(tsk); + struct pt_regs *regs = get_user_regs(tsk); return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0; } @@ -570,7 +587,7 @@ static int ptrace_setregs(struct task_struct *tsk, void __user *uregs) ret = -EFAULT; if (copy_from_user(&newregs, uregs, sizeof(struct pt_regs)) == 0) { - struct pt_regs *regs = task_pt_regs(tsk); + struct pt_regs *regs = get_user_regs(tsk); ret = -EINVAL; if (valid_user_regs(&newregs)) { @@ -587,7 +604,7 @@ static int ptrace_setregs(struct task_struct *tsk, void __user *uregs) */ static int ptrace_getfpregs(struct task_struct *tsk, void __user *ufp) { - return copy_to_user(ufp, &task_thread_info(tsk)->fpstate, + return copy_to_user(ufp, &tsk->thread_info->fpstate, sizeof(struct user_fp)) ? -EFAULT : 0; } @@ -596,7 +613,7 @@ static int ptrace_getfpregs(struct task_struct *tsk, void __user *ufp) */ static int ptrace_setfpregs(struct task_struct *tsk, void __user *ufp) { - struct thread_info *thread = task_thread_info(tsk); + struct thread_info *thread = tsk->thread_info; thread->used_cp[1] = thread->used_cp[2] = 1; return copy_from_user(&thread->fpstate, ufp, sizeof(struct user_fp)) ? -EFAULT : 0; @@ -609,7 +626,7 @@ static int ptrace_setfpregs(struct task_struct *tsk, void __user *ufp) */ static int ptrace_getwmmxregs(struct task_struct *tsk, void __user *ufp) { - struct thread_info *thread = task_thread_info(tsk); + struct thread_info *thread = tsk->thread_info; void *ptr = &thread->fpstate; if (!test_ti_thread_flag(thread, TIF_USING_IWMMXT)) @@ -626,7 +643,7 @@ static int ptrace_getwmmxregs(struct task_struct *tsk, void __user *ufp) */ static int ptrace_setwmmxregs(struct task_struct *tsk, void __user *ufp) { - struct thread_info *thread = task_thread_info(tsk); + struct thread_info *thread = tsk->thread_info; void *ptr = &thread->fpstate; if (!test_ti_thread_flag(thread, TIF_USING_IWMMXT)) @@ -762,7 +779,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) #endif case PTRACE_GET_THREAD_AREA: - ret = put_user(task_thread_info(child)->tp_value, + ret = put_user(child->thread_info->tp_value, (unsigned long __user *) data); break; diff --git a/trunk/arch/arm/kernel/smp.c b/trunk/arch/arm/kernel/smp.c index 7338948bd7d3..373c0959bc2f 100644 --- a/trunk/arch/arm/kernel/smp.c +++ b/trunk/arch/arm/kernel/smp.c @@ -114,7 +114,7 @@ int __cpuinit __cpu_up(unsigned int cpu) * We need to tell the secondary core where to find * its stack and the page tables. */ - secondary_data.stack = task_stack_page(idle) + THREAD_START_SP; + secondary_data.stack = (void *)idle->thread_info + THREAD_START_SP; secondary_data.pgdir = virt_to_phys(pgd); wmb(); @@ -245,7 +245,7 @@ void __cpuexit cpu_die(void) __asm__("mov sp, %0\n" " b secondary_start_kernel" : - : "r" (task_stack_page(current) + THREAD_SIZE - 8)); + : "r" ((void *)current->thread_info + THREAD_SIZE - 8)); } #endif /* CONFIG_HOTPLUG_CPU */ diff --git a/trunk/arch/arm/kernel/traps.c b/trunk/arch/arm/kernel/traps.c index 93cfd3ffcc72..c9fe6f5f7ee3 100644 --- a/trunk/arch/arm/kernel/traps.c +++ b/trunk/arch/arm/kernel/traps.c @@ -164,7 +164,7 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) } else if (verify_stack(fp)) { printk("invalid frame pointer 0x%08x", fp); ok = 0; - } else if (fp < (unsigned long)end_of_stack(tsk)) + } else if (fp < (unsigned long)(tsk->thread_info + 1)) printk("frame pointer underflow"); printk("\n"); @@ -210,7 +210,7 @@ static void __die(const char *str, int err, struct thread_info *thread, struct p if (!user_mode(regs) || in_interrupt()) { dump_mem("Stack: ", regs->ARM_sp, - THREAD_SIZE + (unsigned long)task_stack_page(tsk)); + THREAD_SIZE + (unsigned long)tsk->thread_info); dump_backtrace(regs, tsk); dump_instr(regs); } diff --git a/trunk/arch/arm26/kernel/process.c b/trunk/arch/arm26/kernel/process.c index 386305659171..15833a0057dd 100644 --- a/trunk/arch/arm26/kernel/process.c +++ b/trunk/arch/arm26/kernel/process.c @@ -277,9 +277,10 @@ int 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 = task_thread_info(p); - struct pt_regs *childregs = task_pt_regs(p); + struct thread_info *thread = p->thread_info; + struct pt_regs *childregs; + childregs = __get_user_regs(thread); *childregs = *regs; childregs->ARM_r0 = 0; childregs->ARM_sp = stack_start; diff --git a/trunk/arch/arm26/kernel/ptrace.c b/trunk/arch/arm26/kernel/ptrace.c index 3c3371d4683e..4e6b7356a722 100644 --- a/trunk/arch/arm26/kernel/ptrace.c +++ b/trunk/arch/arm26/kernel/ptrace.c @@ -39,6 +39,21 @@ */ #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. @@ -47,7 +62,7 @@ */ static inline long get_user_reg(struct task_struct *task, int offset) { - return task_pt_regs(task)->uregs[offset]; + return get_user_regs(task)->uregs[offset]; } /* @@ -59,7 +74,7 @@ static inline long get_user_reg(struct task_struct *task, int offset) static inline int put_user_reg(struct task_struct *task, int offset, long data) { - struct pt_regs newregs, *regs = task_pt_regs(task); + struct pt_regs newregs, *regs = get_user_regs(task); int ret = -EINVAL; newregs = *regs; @@ -362,7 +377,7 @@ void ptrace_set_bpt(struct task_struct *child) u32 insn; int res; - regs = task_pt_regs(child); + regs = get_user_regs(child); pc = instruction_pointer(regs); res = read_instr(child, pc, &insn); @@ -485,7 +500,7 @@ static int ptrace_write_user(struct task_struct *tsk, unsigned long off, */ static int ptrace_getregs(struct task_struct *tsk, void *uregs) { - struct pt_regs *regs = task_pt_regs(tsk); + struct pt_regs *regs = get_user_regs(tsk); return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0; } @@ -500,7 +515,7 @@ static int ptrace_setregs(struct task_struct *tsk, void *uregs) ret = -EFAULT; if (copy_from_user(&newregs, uregs, sizeof(struct pt_regs)) == 0) { - struct pt_regs *regs = task_pt_regs(tsk); + struct pt_regs *regs = get_user_regs(tsk); ret = -EINVAL; if (valid_user_regs(&newregs)) { @@ -517,7 +532,7 @@ static int ptrace_setregs(struct task_struct *tsk, void *uregs) */ static int ptrace_getfpregs(struct task_struct *tsk, void *ufp) { - return copy_to_user(ufp, &task_thread_info(tsk)->fpstate, + return copy_to_user(ufp, &tsk->thread_info->fpstate, sizeof(struct user_fp)) ? -EFAULT : 0; } @@ -527,7 +542,7 @@ static int ptrace_getfpregs(struct task_struct *tsk, void *ufp) static int ptrace_setfpregs(struct task_struct *tsk, void *ufp) { set_stopped_child_used_math(tsk); - return copy_from_user(&task_threas_info(tsk)->fpstate, ufp, + return copy_from_user(&tsk->thread_info->fpstate, ufp, sizeof(struct user_fp)) ? -EFAULT : 0; } diff --git a/trunk/arch/arm26/kernel/traps.c b/trunk/arch/arm26/kernel/traps.c index 5847ea5d7747..f64f59022392 100644 --- a/trunk/arch/arm26/kernel/traps.c +++ b/trunk/arch/arm26/kernel/traps.c @@ -132,7 +132,7 @@ static void dump_instr(struct pt_regs *regs) /*static*/ void __dump_stack(struct task_struct *tsk, unsigned long sp) { - dump_mem("Stack: ", sp, 8192+(unsigned long)task_stack_page(tsk)); + dump_mem("Stack: ", sp, 8192+(unsigned long)tsk->thread_info); } void dump_stack(void) @@ -158,7 +158,7 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) } else if (verify_stack(fp)) { printk("invalid frame pointer 0x%08x", fp); ok = 0; - } else if (fp < (unsigned long)end_of_stack(tsk)) + } else if (fp < (unsigned long)(tsk->thread_info + 1)) printk("frame pointer underflow"); printk("\n"); @@ -168,7 +168,7 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) /* 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_stack_page(task)); + dump_mem("Stack: ", (unsigned long)sp, 8192+(unsigned long)task->thread_info); } DEFINE_SPINLOCK(die_lock); @@ -187,7 +187,7 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err) printk("CPU: %d\n", smp_processor_id()); show_regs(regs); printk("Process %s (pid: %d, stack limit = 0x%p)\n", - current->comm, current->pid, end_of_stack(tsk)); + current->comm, current->pid, tsk->thread_info + 1); if (!user_mode(regs) || in_interrupt()) { __dump_stack(tsk, (unsigned long)(regs + 1)); diff --git a/trunk/arch/cris/arch-v10/kernel/process.c b/trunk/arch/cris/arch-v10/kernel/process.c index 0a675ce9e099..69e28b4057e8 100644 --- a/trunk/arch/cris/arch-v10/kernel/process.c +++ b/trunk/arch/cris/arch-v10/kernel/process.c @@ -79,7 +79,7 @@ void hard_reset_now (void) */ unsigned long thread_saved_pc(struct task_struct *t) { - return task_pt_regs(t)->irp; + return (unsigned long)user_regs(t->thread_info)->irp; } static void kernel_thread_helper(void* dummy, int (*fn)(void *), void * arg) @@ -128,7 +128,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, * remember that the task_struct doubles as the kernel stack for the task */ - childregs = task_pt_regs(p); + childregs = user_regs(p->thread_info); *childregs = *regs; /* struct copy of pt_regs */ diff --git a/trunk/arch/cris/arch-v10/kernel/ptrace.c b/trunk/arch/cris/arch-v10/kernel/ptrace.c index f214f74f264e..6cbd34a27b90 100644 --- a/trunk/arch/cris/arch-v10/kernel/ptrace.c +++ b/trunk/arch/cris/arch-v10/kernel/ptrace.c @@ -37,7 +37,7 @@ inline long get_reg(struct task_struct *task, unsigned int regno) if (regno == PT_USP) return task->thread.usp; else if (regno < PT_MAX) - return ((unsigned long *)task_pt_regs(task))[regno]; + return ((unsigned long *)user_regs(task->thread_info))[regno]; else return 0; } @@ -51,7 +51,7 @@ inline int put_reg(struct task_struct *task, unsigned int regno, if (regno == PT_USP) task->thread.usp = data; else if (regno < PT_MAX) - ((unsigned long *)task_pt_regs(task))[regno] = data; + ((unsigned long *)user_regs(task->thread_info))[regno] = data; else return -1; return 0; diff --git a/trunk/arch/cris/arch-v32/kernel/process.c b/trunk/arch/cris/arch-v32/kernel/process.c index 843513102d3c..882be42114f7 100644 --- a/trunk/arch/cris/arch-v32/kernel/process.c +++ b/trunk/arch/cris/arch-v32/kernel/process.c @@ -96,7 +96,7 @@ hard_reset_now(void) */ unsigned long thread_saved_pc(struct task_struct *t) { - return task_pt_regs(t)->erp; + return (unsigned long)user_regs(t->thread_info)->erp; } static void @@ -148,7 +148,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, * fix it up. Note: the task_struct doubles as the kernel stack for the * task. */ - childregs = task_pt_regs(p); + childregs = user_regs(p->thread_info); *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 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, * The TLS is in $mof beacuse it is the 5th argument to sys_clone. */ if (p->mm && (clone_flags & CLONE_SETTLS)) { - task_thread_info(p)->tls = regs->mof; + p->thread_info->tls = regs->mof; } /* Put the switch stack right below the pt_regs. */ diff --git a/trunk/arch/cris/arch-v32/kernel/ptrace.c b/trunk/arch/cris/arch-v32/kernel/ptrace.c index 82cf2e3624a4..5528b83a622b 100644 --- a/trunk/arch/cris/arch-v32/kernel/ptrace.c +++ b/trunk/arch/cris/arch-v32/kernel/ptrace.c @@ -46,7 +46,7 @@ long get_reg(struct task_struct *task, unsigned int regno) unsigned long ret; if (regno <= PT_EDA) - ret = ((unsigned long *)task_pt_regs(task))[regno]; + ret = ((unsigned long *)user_regs(task->thread_info))[regno]; else if (regno == PT_USP) ret = task->thread.usp; else if (regno == PT_PPC) @@ -65,13 +65,13 @@ long get_reg(struct task_struct *task, unsigned int regno) int put_reg(struct task_struct *task, unsigned int regno, unsigned long data) { if (regno <= PT_EDA) - ((unsigned long *)task_pt_regs(task))[regno] = data; + ((unsigned long *)user_regs(task->thread_info))[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)) - task_pt_regs(task)->erp = data; + ((unsigned long *)user_regs(task->thread_info))[PT_ERP] = data; } else if (regno <= PT_MAX) return put_debugreg(task->pid, regno, data); else diff --git a/trunk/arch/cris/arch-v32/kernel/smp.c b/trunk/arch/cris/arch-v32/kernel/smp.c index da40d19a151e..13867f4fad16 100644 --- a/trunk/arch/cris/arch-v32/kernel/smp.c +++ b/trunk/arch/cris/arch-v32/kernel/smp.c @@ -113,10 +113,10 @@ smp_boot_one_cpu(int cpuid) if (IS_ERR(idle)) panic("SMP: fork failed for CPU:%d", cpuid); - task_thread_info(idle)->cpu = cpuid; + idle->thread_info->cpu = cpuid; /* Information to the CPU that is about to boot */ - smp_init_current_idle_thread = task_thread_info(idle); + smp_init_current_idle_thread = idle->thread_info; cpu_now_booting = cpuid; /* Wait for CPU to come online */ diff --git a/trunk/arch/cris/arch-v32/mm/tlb.c b/trunk/arch/cris/arch-v32/mm/tlb.c index 9d75d7692303..b08a28bb58ab 100644 --- a/trunk/arch/cris/arch-v32/mm/tlb.c +++ b/trunk/arch/cris/arch-v32/mm/tlb.c @@ -198,9 +198,9 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next, per_cpu(current_pgd, cpu) = next->pgd; /* Switch context in the MMU. */ - if (tsk && task_thread_info(tsk)) + if (tsk && tsk->thread_info) { - SPEC_REG_WR(SPEC_REG_PID, next->context.page_id | task_thread_info(tsk)->tls); + SPEC_REG_WR(SPEC_REG_PID, next->context.page_id | tsk->thread_info->tls); } else { diff --git a/trunk/arch/frv/kernel/process.c b/trunk/arch/frv/kernel/process.c index 0fff8a61ef2a..c4488379ac3b 100644 --- a/trunk/arch/frv/kernel/process.c +++ b/trunk/arch/frv/kernel/process.c @@ -204,7 +204,7 @@ int copy_thread(int nr, unsigned long clone_flags, regs0 = __kernel_frame0_ptr; childregs0 = (struct pt_regs *) - (task_stack_page(p) + THREAD_SIZE - USER_CONTEXT_SIZE); + ((unsigned long) p->thread_info + THREAD_SIZE - USER_CONTEXT_SIZE); childregs = childregs0; /* set up the userspace frame (the only place that the USP is stored) */ @@ -220,7 +220,7 @@ int copy_thread(int nr, unsigned long clone_flags, *childregs = *regs; childregs->sp = (unsigned long) childregs0; childregs->next_frame = childregs0; - childregs->gr15 = (unsigned long) task_thread_info(p); + childregs->gr15 = (unsigned long) p->thread_info; childregs->gr29 = (unsigned long) p; } diff --git a/trunk/arch/h8300/kernel/process.c b/trunk/arch/h8300/kernel/process.c index ed79ae20e88d..585ed5efd0f7 100644 --- a/trunk/arch/h8300/kernel/process.c +++ b/trunk/arch/h8300/kernel/process.c @@ -195,7 +195,7 @@ int copy_thread(int nr, unsigned long clone_flags, { struct pt_regs * childregs; - childregs = (struct pt_regs *) (THREAD_SIZE + task_stack_page(p)) - 1; + childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1; *childregs = *regs; childregs->retpc = (unsigned long) ret_from_fork; diff --git a/trunk/arch/i386/kernel/process.c b/trunk/arch/i386/kernel/process.c index 2185377fdde1..035928f3f6c1 100644 --- a/trunk/arch/i386/kernel/process.c +++ b/trunk/arch/i386/kernel/process.c @@ -424,7 +424,18 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, struct task_struct *tsk; int err; - childregs = task_pt_regs(p); + 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 = *regs; childregs->eax = 0; childregs->esp = esp; @@ -529,7 +540,12 @@ EXPORT_SYMBOL(dump_thread); */ int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) { - struct pt_regs ptregs = *task_pt_regs(tsk); + 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); ptregs.xcs &= 0xffff; ptregs.xds &= 0xffff; ptregs.xes &= 0xffff; @@ -585,8 +601,8 @@ static inline void disable_tsc(struct task_struct *prev_p, * gcc should eliminate the ->thread_info dereference if * has_secure_computing returns 0 at compile time (SECCOMP=n). */ - prev = task_thread_info(prev_p); - next = task_thread_info(next_p); + prev = prev_p->thread_info; + next = next_p->thread_info; if (has_secure_computing(prev) || has_secure_computing(next)) { /* slow path here */ @@ -771,7 +787,7 @@ unsigned long get_wchan(struct task_struct *p) int count = 0; if (!p || p == current || p->state == TASK_RUNNING) return 0; - stack_page = (unsigned long)task_stack_page(p); + stack_page = (unsigned long)p->thread_info; esp = p->thread.esp; if (!stack_page || esp < stack_page || esp > top_esp+stack_page) return 0; diff --git a/trunk/arch/i386/kernel/smpboot.c b/trunk/arch/i386/kernel/smpboot.c index 255adb498268..b3c2e2c26743 100644 --- a/trunk/arch/i386/kernel/smpboot.c +++ b/trunk/arch/i386/kernel/smpboot.c @@ -875,7 +875,8 @@ static inline struct task_struct * alloc_idle_task(int cpu) /* initialize thread_struct. we really want to avoid destroy * idle tread */ - idle->thread.esp = (unsigned long)task_pt_regs(idle); + idle->thread.esp = (unsigned long)(((struct pt_regs *) + (THREAD_SIZE + (unsigned long) idle->thread_info)) - 1); init_idle(idle, cpu); return idle; } @@ -1095,7 +1096,6 @@ static void smp_tune_scheduling (void) cachesize = 16; /* Pentiums, 2x8kB cache */ bandwidth = 100; } - max_cache_size = cachesize * 1024; } } diff --git a/trunk/arch/i386/kernel/vm86.c b/trunk/arch/i386/kernel/vm86.c index 0c90ae54ddfa..cbdb0afed76a 100644 --- a/trunk/arch/i386/kernel/vm86.c +++ b/trunk/arch/i386/kernel/vm86.c @@ -311,7 +311,7 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk "movl %1,%%ebp\n\t" "jmp resume_userspace" : /* no outputs */ - :"r" (&info->regs), "r" (task_thread_info(tsk)) : "ax"); + :"r" (&info->regs), "r" (tsk->thread_info) : "ax"); /* we never return here */ } diff --git a/trunk/arch/ia64/ia32/elfcore32.h b/trunk/arch/ia64/ia32/elfcore32.h index a47f63b204fb..b73b8b6b10c1 100644 --- a/trunk/arch/ia64/ia32/elfcore32.h +++ b/trunk/arch/ia64/ia32/elfcore32.h @@ -95,7 +95,8 @@ static inline void elf_core_copy_regs(elf_gregset_t *elfregs, static inline int elf_core_copy_task_regs(struct task_struct *t, elf_gregset_t* elfregs) { - ELF_CORE_COPY_REGS((*elfregs), task_pt_regs(t)); + struct pt_regs *pp = ia64_task_regs(t); + ELF_CORE_COPY_REGS((*elfregs), pp); return 1; } diff --git a/trunk/arch/ia64/ia32/ia32_signal.c b/trunk/arch/ia64/ia32/ia32_signal.c index 5856510210fa..aa891c9bc9b6 100644 --- a/trunk/arch/ia64/ia32/ia32_signal.c +++ b/trunk/arch/ia64/ia32/ia32_signal.c @@ -255,7 +255,7 @@ save_ia32_fpstate_live (struct _fpstate_ia32 __user *save) */ fp_tos = (fsr>>11)&0x7; fr8_st_map = (8-fp_tos)&0x7; - ptp = task_pt_regs(tsk); + ptp = ia64_task_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 @@ restore_ia32_fpstate_live (struct _fpstate_ia32 __user *save) fr8_st_map = (8-fp_tos)&0x7; fpregp = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15); - ptp = task_pt_regs(tsk); + ptp = ia64_task_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/trunk/arch/ia64/ia32/ia32_support.c b/trunk/arch/ia64/ia32/ia32_support.c index c187743965a0..4f630043b3ae 100644 --- a/trunk/arch/ia64/ia32/ia32_support.c +++ b/trunk/arch/ia64/ia32/ia32_support.c @@ -58,7 +58,7 @@ load_desc (u16 selector) void ia32_load_segment_descriptors (struct task_struct *task) { - struct pt_regs *regs = task_pt_regs(task); + struct pt_regs *regs = ia64_task_regs(task); /* Setup the segment descriptors */ regs->r24 = load_desc(regs->r16 >> 16); /* ESD */ @@ -113,7 +113,7 @@ void ia32_load_state (struct task_struct *t) { unsigned long eflag, fsr, fcr, fir, fdr, tssd; - struct pt_regs *regs = task_pt_regs(t); + struct pt_regs *regs = ia64_task_regs(t); eflag = t->thread.eflag; fsr = t->thread.fsr; diff --git a/trunk/arch/ia64/ia32/sys_ia32.c b/trunk/arch/ia64/ia32/sys_ia32.c index 3945d378bd7e..0668b2b7714d 100644 --- a/trunk/arch/ia64/ia32/sys_ia32.c +++ b/trunk/arch/ia64/ia32/sys_ia32.c @@ -1482,7 +1482,7 @@ getreg (struct task_struct *child, int regno) { struct pt_regs *child_regs; - child_regs = task_pt_regs(child); + child_regs = ia64_task_regs(child); switch (regno / sizeof(int)) { case PT_EBX: return child_regs->r11; case PT_ECX: return child_regs->r9; @@ -1510,7 +1510,7 @@ putreg (struct task_struct *child, int regno, unsigned int value) { struct pt_regs *child_regs; - child_regs = task_pt_regs(child); + child_regs = ia64_task_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 @@ save_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct __user * Stack frames start with 16-bytes of temp space */ swp = (struct switch_stack *)(tsk->thread.ksp + 16); - ptp = task_pt_regs(tsk); + ptp = ia64_task_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 @@ restore_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct __us * Stack frames start with 16-bytes of temp space */ swp = (struct switch_stack *)(tsk->thread.ksp + 16); - ptp = task_pt_regs(tsk); + ptp = ia64_task_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 @@ save_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct __user * Stack frames start with 16-bytes of temp space */ swp = (struct switch_stack *)(tsk->thread.ksp + 16); - ptp = task_pt_regs(tsk); + ptp = ia64_task_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 @@ restore_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct __u * Stack frames start with 16-bytes of temp space */ swp = (struct switch_stack *)(tsk->thread.ksp + 16); - ptp = task_pt_regs(tsk); + ptp = ia64_task_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/trunk/arch/ia64/kernel/mca.c b/trunk/arch/ia64/kernel/mca.c index ee7eec9ee576..355af15287c7 100644 --- a/trunk/arch/ia64/kernel/mca.c +++ b/trunk/arch/ia64/kernel/mca.c @@ -766,7 +766,7 @@ ia64_mca_modify_original_stack(struct pt_regs *regs, l = strlen(previous_current->comm); snprintf(comm, sizeof(comm), "%s %*s %d", current->comm, l, previous_current->comm, - task_thread_info(previous_current)->cpu); + previous_current->thread_info->cpu); } memcpy(current->comm, comm, sizeof(current->comm)); @@ -1423,7 +1423,7 @@ format_mca_init_stack(void *mca_data, unsigned long offset, struct task_struct *p = (struct task_struct *)((char *)mca_data + offset); struct thread_info *ti; memset(p, 0, KERNEL_STACK_SIZE); - ti = task_thread_info(p); + ti = (struct thread_info *)((char *)p + IA64_TASK_SIZE); ti->flags = _TIF_MCA_INIT; ti->preempt_count = 1; ti->task = p; diff --git a/trunk/arch/ia64/kernel/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index bd87cb6b7a81..c026ac1142a6 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -1710,7 +1710,7 @@ static void pfm_syswide_force_stop(void *info) { pfm_context_t *ctx = (pfm_context_t *)info; - struct pt_regs *regs = task_pt_regs(current); + struct pt_regs *regs = ia64_task_regs(current); struct task_struct *owner; unsigned long flags; int ret; @@ -1815,7 +1815,7 @@ pfm_flush(struct file *filp) is_system = ctx->ctx_fl_system; task = PFM_CTX_TASK(ctx); - regs = task_pt_regs(task); + regs = ia64_task_regs(task); DPRINT(("ctx_state=%d is_current=%d\n", state, @@ -1945,7 +1945,7 @@ pfm_close(struct inode *inode, struct file *filp) is_system = ctx->ctx_fl_system; task = PFM_CTX_TASK(ctx); - regs = task_pt_regs(task); + regs = ia64_task_regs(task); DPRINT(("ctx_state=%d is_current=%d\n", state, @@ -4052,7 +4052,7 @@ pfm_stop(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) */ ia64_psr(regs)->up = 0; } else { - tregs = task_pt_regs(task); + tregs = ia64_task_regs(task); /* * stop monitoring at the user level @@ -4134,7 +4134,7 @@ pfm_start(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) ia64_psr(regs)->up = 1; } else { - tregs = task_pt_regs(ctx->ctx_task); + tregs = ia64_task_regs(ctx->ctx_task); /* * start monitoring at the kernel level the next @@ -4404,7 +4404,7 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) /* * when not current, task MUST be stopped, so this is safe */ - regs = task_pt_regs(task); + regs = ia64_task_regs(task); /* force a full reload */ ctx->ctx_last_activation = PFM_INVALID_ACTIVATION; @@ -4530,7 +4530,7 @@ pfm_context_unload(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg /* * per-task mode */ - tregs = task == current ? regs : task_pt_regs(task); + tregs = task == current ? regs : ia64_task_regs(task); if (task == current) { /* @@ -4593,7 +4593,7 @@ pfm_exit_thread(struct task_struct *task) { pfm_context_t *ctx; unsigned long flags; - struct pt_regs *regs = task_pt_regs(task); + struct pt_regs *regs = ia64_task_regs(task); int ret, state; int free_ok = 0; @@ -4926,7 +4926,7 @@ sys_perfmonctl (int fd, int cmd, void __user *arg, int count) if (unlikely(ret)) goto abort_locked; skip_fd: - ret = (*func)(ctx, args_k, count, task_pt_regs(current)); + ret = (*func)(ctx, args_k, count, ia64_task_regs(current)); call_made = 1; @@ -5050,7 +5050,7 @@ pfm_handle_work(void) pfm_clear_task_notify(); - regs = task_pt_regs(current); + regs = ia64_task_regs(current); /* * extract reason for being here and clear @@ -5794,7 +5794,7 @@ pfm_syst_wide_update_task(struct task_struct *task, unsigned long info, int is_c * 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 = task_pt_regs(task); + regs = ia64_task_regs(task); ia64_psr(regs)->pp = is_ctxswin ? dcr_pp : 0; return; } @@ -5877,7 +5877,7 @@ pfm_save_regs(struct task_struct *task) flags = pfm_protect_ctx_ctxsw(ctx); if (ctx->ctx_state == PFM_CTX_ZOMBIE) { - struct pt_regs *regs = task_pt_regs(task); + struct pt_regs *regs = ia64_task_regs(task); pfm_clear_psr_up(); @@ -6077,7 +6077,7 @@ pfm_load_regs (struct task_struct *task) BUG_ON(psr & IA64_PSR_I); if (unlikely(ctx->ctx_state == PFM_CTX_ZOMBIE)) { - struct pt_regs *regs = task_pt_regs(task); + struct pt_regs *regs = ia64_task_regs(task); BUG_ON(ctx->ctx_smpl_hdr); @@ -6446,7 +6446,7 @@ pfm_alt_save_pmu_state(void *data) { struct pt_regs *regs; - regs = task_pt_regs(current); + regs = ia64_task_regs(current); DPRINT(("called\n")); @@ -6472,7 +6472,7 @@ pfm_alt_restore_pmu_state(void *data) { struct pt_regs *regs; - regs = task_pt_regs(current); + regs = ia64_task_regs(current); DPRINT(("called\n")); @@ -6754,7 +6754,7 @@ dump_pmu_state(const char *from) local_irq_save(flags); this_cpu = smp_processor_id(); - regs = task_pt_regs(current); + regs = ia64_task_regs(current); info = PFM_CPUINFO_GET(); dcr = ia64_getreg(_IA64_REG_CR_DCR); diff --git a/trunk/arch/ia64/kernel/process.c b/trunk/arch/ia64/kernel/process.c index 309d59658e5f..e9904c74d2ba 100644 --- a/trunk/arch/ia64/kernel/process.c +++ b/trunk/arch/ia64/kernel/process.c @@ -328,7 +328,7 @@ ia64_save_extra (struct task_struct *task) #endif #ifdef CONFIG_IA32_SUPPORT - if (IS_IA32_PROCESS(task_pt_regs(task))) + if (IS_IA32_PROCESS(ia64_task_regs(task))) ia32_save_state(task); #endif } @@ -353,7 +353,7 @@ ia64_load_extra (struct task_struct *task) #endif #ifdef CONFIG_IA32_SUPPORT - if (IS_IA32_PROCESS(task_pt_regs(task))) + if (IS_IA32_PROCESS(ia64_task_regs(task))) ia32_load_state(task); #endif } @@ -488,7 +488,7 @@ copy_thread (int nr, unsigned long clone_flags, * 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(task_pt_regs(current))) { + if (IS_IA32_PROCESS(ia64_task_regs(current))) { ia32_save_state(p); if (clone_flags & CLONE_SETTLS) retval = ia32_clone_tls(p, child_ptregs); @@ -701,7 +701,7 @@ int kernel_thread_helper (int (*fn)(void *), void *arg) { #ifdef CONFIG_IA32_SUPPORT - if (IS_IA32_PROCESS(task_pt_regs(current))) { + if (IS_IA32_PROCESS(ia64_task_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 @@ flush_thread (void) current->thread.flags &= ~(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID); ia64_drop_fpu(current); #ifdef CONFIG_IA32_SUPPORT - if (IS_IA32_PROCESS(task_pt_regs(current))) { + if (IS_IA32_PROCESS(ia64_task_regs(current))) { ia32_drop_partial_page_list(current); current->thread.task_size = IA32_PAGE_OFFSET; set_fs(USER_DS); @@ -755,7 +755,7 @@ exit_thread (void) if (current->thread.flags & IA64_THREAD_DBG_VALID) pfm_release_debug_registers(current); #endif - if (IS_IA32_PROCESS(task_pt_regs(current))) + if (IS_IA32_PROCESS(ia64_task_regs(current))) ia32_drop_partial_page_list(current); } diff --git a/trunk/arch/ia64/kernel/ptrace.c b/trunk/arch/ia64/kernel/ptrace.c index eaed14aac6aa..8d88eeea02d1 100644 --- a/trunk/arch/ia64/kernel/ptrace.c +++ b/trunk/arch/ia64/kernel/ptrace.c @@ -254,7 +254,7 @@ get_rnat (struct task_struct *task, struct switch_stack *sw, long num_regs, nbits; struct pt_regs *pt; - pt = task_pt_regs(task); + pt = ia64_task_regs(task); kbsp = (unsigned long *) sw->ar_bspstore; ubspstore = (unsigned long *) pt->ar_bspstore; @@ -314,7 +314,7 @@ put_rnat (struct task_struct *task, struct switch_stack *sw, struct pt_regs *pt; unsigned long cfm, *urbs_kargs; - pt = task_pt_regs(task); + pt = ia64_task_regs(task); kbsp = (unsigned long *) sw->ar_bspstore; ubspstore = (unsigned long *) pt->ar_bspstore; @@ -407,7 +407,7 @@ ia64_peek (struct task_struct *child, struct switch_stack *child_stack, urbs_end = (long *) user_rbs_end; laddr = (unsigned long *) addr; - child_regs = task_pt_regs(child); + child_regs = ia64_task_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 @@ ia64_poke (struct task_struct *child, struct switch_stack *child_stack, struct pt_regs *child_regs; laddr = (unsigned long *) addr; - child_regs = task_pt_regs(child); + child_regs = ia64_task_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 @@ thread_matches (struct task_struct *thread, unsigned long addr) */ return 0; - thread_regs = task_pt_regs(thread); + thread_regs = ia64_task_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 @@ find_thread_for_addr (struct task_struct *child, unsigned long addr) inline void ia64_flush_fph (struct task_struct *task) { - struct ia64_psr *psr = ia64_psr(task_pt_regs(task)); + struct ia64_psr *psr = ia64_psr(ia64_task_regs(task)); /* * Prevent migrating this task while @@ -653,7 +653,7 @@ ia64_flush_fph (struct task_struct *task) void ia64_sync_fph (struct task_struct *task) { - struct ia64_psr *psr = ia64_psr(task_pt_regs(task)); + struct ia64_psr *psr = ia64_psr(ia64_task_regs(task)); ia64_flush_fph(task); if (!(task->thread.flags & IA64_THREAD_FPH_VALID)) { @@ -794,7 +794,7 @@ access_uarea (struct task_struct *child, unsigned long addr, + offsetof(struct pt_regs, reg))) - pt = task_pt_regs(child); + pt = ia64_task_regs(child); sw = (struct switch_stack *) (child->thread.ksp + 16); if ((addr & 0x7) != 0) { @@ -1120,7 +1120,7 @@ ptrace_getregs (struct task_struct *child, struct pt_all_user_regs __user *ppr) if (!access_ok(VERIFY_WRITE, ppr, sizeof(struct pt_all_user_regs))) return -EIO; - pt = task_pt_regs(child); + pt = ia64_task_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 @@ ptrace_setregs (struct task_struct *child, struct pt_all_user_regs __user *ppr) if (!access_ok(VERIFY_READ, ppr, sizeof(struct pt_all_user_regs))) return -EIO; - pt = task_pt_regs(child); + pt = ia64_task_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 @@ ptrace_setregs (struct task_struct *child, struct pt_all_user_regs __user *ppr) void ptrace_disable (struct task_struct *child) { - struct ia64_psr *child_psr = ia64_psr(task_pt_regs(child)); + struct ia64_psr *child_psr = ia64_psr(ia64_task_regs(child)); /* make sure the single step/taken-branch trap bits are not set: */ child_psr->ss = 0; @@ -1456,7 +1456,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data) if (ret < 0) goto out_tsk; - pt = task_pt_regs(child); + pt = ia64_task_regs(child); sw = (struct switch_stack *) (child->thread.ksp + 16); switch (request) { diff --git a/trunk/arch/ia64/kernel/setup.c b/trunk/arch/ia64/kernel/setup.c index c0766575a3a2..c33305d8e5eb 100644 --- a/trunk/arch/ia64/kernel/setup.c +++ b/trunk/arch/ia64/kernel/setup.c @@ -60,7 +60,6 @@ #include #include #include -#include #if defined(CONFIG_SMP) && (IA64_CPU_SIZE > PAGE_SIZE) # error "struct cpuinfo_ia64 too big!" @@ -696,7 +695,6 @@ static void 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; @@ -726,8 +724,6 @@ get_max_cacheline_size (void) 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, @@ -744,9 +740,6 @@ get_max_cacheline_size (void) 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; } @@ -801,7 +794,7 @@ cpu_init (void) #endif /* Clear the stack memory reserved for pt_regs: */ - memset(task_pt_regs(current), 0, sizeof(struct pt_regs)); + memset(ia64_task_regs(current), 0, sizeof(struct pt_regs)); ia64_set_kr(IA64_KR_FPU_OWNER, 0); @@ -877,15 +870,6 @@ cpu_init (void) 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/trunk/arch/ia64/kernel/signal.c b/trunk/arch/ia64/kernel/signal.c index 463f6bb44d07..58ce07efc56e 100644 --- a/trunk/arch/ia64/kernel/signal.c +++ b/trunk/arch/ia64/kernel/signal.c @@ -655,11 +655,11 @@ set_sigdelayed(pid_t pid, int signo, int code, void __user *addr) if (!t) return; - 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; + 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; wmb(); set_tsk_thread_flag(t, TIF_SIGDELAYED); } diff --git a/trunk/arch/ia64/kernel/sys_ia64.c b/trunk/arch/ia64/kernel/sys_ia64.c index c7b943f10199..f2dbcd1db0d4 100644 --- a/trunk/arch/ia64/kernel/sys_ia64.c +++ b/trunk/arch/ia64/kernel/sys_ia64.c @@ -151,7 +151,7 @@ ia64_brk (unsigned long brk) asmlinkage long sys_pipe (void) { - struct pt_regs *regs = task_pt_regs(current); + struct pt_regs *regs = ia64_task_regs(current); int fd[2]; int retval; diff --git a/trunk/arch/m32r/kernel/process.c b/trunk/arch/m32r/kernel/process.c index 5dfc7ea45cf7..2a1f250349b7 100644 --- a/trunk/arch/m32r/kernel/process.c +++ b/trunk/arch/m32r/kernel/process.c @@ -242,10 +242,13 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) 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 = task_pt_regs(tsk); + struct pt_regs *childregs; + unsigned long sp = (unsigned long)tsk->thread_info + THREAD_SIZE; 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/trunk/arch/m32r/kernel/ptrace.c b/trunk/arch/m32r/kernel/ptrace.c index 340a3bf59b88..9b75caaf5cec 100644 --- a/trunk/arch/m32r/kernel/ptrace.c +++ b/trunk/arch/m32r/kernel/ptrace.c @@ -34,6 +34,23 @@ #include #include +/* + * 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. */ @@ -42,7 +59,7 @@ get_stack_long(struct task_struct *task, int offset) { unsigned long *stack; - stack = (unsigned long *)task_pt_regs(task); + stack = (unsigned long *)get_user_regs(task); return stack[offset]; } @@ -55,7 +72,7 @@ put_stack_long(struct task_struct *task, int offset, unsigned long data) { unsigned long *stack; - stack = (unsigned long *)task_pt_regs(task); + stack = (unsigned long *)get_user_regs(task); stack[offset] = data; return 0; @@ -191,7 +208,7 @@ static int ptrace_write_user(struct task_struct *tsk, unsigned long off, */ static int ptrace_getregs(struct task_struct *tsk, void __user *uregs) { - struct pt_regs *regs = task_pt_regs(tsk); + struct pt_regs *regs = get_user_regs(tsk); return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0; } @@ -206,7 +223,7 @@ static int ptrace_setregs(struct task_struct *tsk, void __user *uregs) ret = -EFAULT; if (copy_from_user(&newregs, uregs, sizeof(struct pt_regs)) == 0) { - struct pt_regs *regs = task_pt_regs(tsk); + struct pt_regs *regs = get_user_regs(tsk); *regs = newregs; ret = 0; } diff --git a/trunk/arch/m32r/kernel/smpboot.c b/trunk/arch/m32r/kernel/smpboot.c index d7ec16e7fb25..b90c54169fa5 100644 --- a/trunk/arch/m32r/kernel/smpboot.c +++ b/trunk/arch/m32r/kernel/smpboot.c @@ -286,7 +286,7 @@ static void __init do_boot_cpu(int phys_id) /* So we see what's up */ printk("Booting processor %d/%d\n", phys_id, cpu_id); stack_start.spi = (void *)idle->thread.sp; - task_thread_info(idle)->cpu = cpu_id; + idle->thread_info->cpu = cpu_id; /* * Send Startup IPI diff --git a/trunk/arch/m68k/amiga/amiints.c b/trunk/arch/m68k/amiga/amiints.c index b0aa61bf8700..d9edf2d1a492 100644 --- a/trunk/arch/m68k/amiga/amiints.c +++ b/trunk/arch/m68k/amiga/amiints.c @@ -126,9 +126,9 @@ void __init amiga_init_IRQ(void) gayle.inten = GAYLE_IRQ_IDE; /* turn off all interrupts and enable the master interrupt bit */ - amiga_custom.intena = 0x7fff; - amiga_custom.intreq = 0x7fff; - amiga_custom.intena = IF_SETCLR | IF_INTEN; + custom.intena = 0x7fff; + custom.intreq = 0x7fff; + custom.intena = IF_SETCLR | IF_INTEN; cia_init_IRQ(&ciaa_base); cia_init_IRQ(&ciab_base); @@ -245,7 +245,7 @@ int amiga_request_irq(unsigned int irq, /* enable the interrupt */ if (irq < IRQ_AMIGA_PORTS && !ami_ablecount[irq]) - amiga_custom.intena = IF_SETCLR | amiga_intena_vals[irq]; + custom.intena = IF_SETCLR | amiga_intena_vals[irq]; return error; } @@ -274,7 +274,7 @@ void amiga_free_irq(unsigned int irq, void *dev_id) 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) - amiga_custom.intena = amiga_intena_vals[irq]; + 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 @@ void amiga_free_irq(unsigned int irq, void *dev_id) ami_irq_list[irq]->flags = 0; ami_irq_list[irq]->dev_id = NULL; ami_irq_list[irq]->devname = NULL; - amiga_custom.intena = amiga_intena_vals[irq]; + custom.intena = amiga_intena_vals[irq]; } } @@ -327,7 +327,7 @@ void amiga_enable_irq(unsigned int irq) } /* enable the interrupt */ - amiga_custom.intena = IF_SETCLR | amiga_intena_vals[irq]; + custom.intena = IF_SETCLR | amiga_intena_vals[irq]; } void amiga_disable_irq(unsigned int irq) @@ -358,7 +358,7 @@ void amiga_disable_irq(unsigned int irq) } /* disable the interrupt */ - amiga_custom.intena = amiga_intena_vals[irq]; + custom.intena = amiga_intena_vals[irq]; } inline void amiga_do_irq(int irq, struct pt_regs *fp) @@ -373,7 +373,7 @@ void amiga_do_irq_list(int irq, struct pt_regs *fp) kstat_cpu(0).irqs[SYS_IRQS + irq]++; - amiga_custom.intreq = amiga_intena_vals[irq]; + 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 @@ void amiga_do_irq_list(int irq, struct pt_regs *fp) static irqreturn_t ami_int1(int irq, void *dev_id, struct pt_regs *fp) { - unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; + unsigned short ints = custom.intreqr & custom.intenar; /* if serial transmit buffer empty, interrupt */ if (ints & IF_TBE) { - amiga_custom.intreq = IF_TBE; + custom.intreq = IF_TBE; amiga_do_irq(IRQ_AMIGA_TBE, fp); } /* if floppy disk transfer complete, interrupt */ if (ints & IF_DSKBLK) { - amiga_custom.intreq = IF_DSKBLK; + custom.intreq = IF_DSKBLK; amiga_do_irq(IRQ_AMIGA_DSKBLK, fp); } /* if software interrupt set, interrupt */ if (ints & IF_SOFT) { - amiga_custom.intreq = IF_SOFT; + custom.intreq = IF_SOFT; amiga_do_irq(IRQ_AMIGA_SOFT, fp); } return IRQ_HANDLED; @@ -409,17 +409,17 @@ static irqreturn_t ami_int1(int irq, void *dev_id, struct pt_regs *fp) static irqreturn_t ami_int3(int irq, void *dev_id, struct pt_regs *fp) { - unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; + unsigned short ints = custom.intreqr & custom.intenar; /* if a blitter interrupt */ if (ints & IF_BLIT) { - amiga_custom.intreq = IF_BLIT; + custom.intreq = IF_BLIT; amiga_do_irq(IRQ_AMIGA_BLIT, fp); } /* if a copper interrupt */ if (ints & IF_COPER) { - amiga_custom.intreq = IF_COPER; + custom.intreq = IF_COPER; amiga_do_irq(IRQ_AMIGA_COPPER, fp); } @@ -431,29 +431,29 @@ static irqreturn_t ami_int3(int irq, void *dev_id, struct pt_regs *fp) static irqreturn_t ami_int4(int irq, void *dev_id, struct pt_regs *fp) { - unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; + unsigned short ints = custom.intreqr & custom.intenar; /* if audio 0 interrupt */ if (ints & IF_AUD0) { - amiga_custom.intreq = IF_AUD0; + custom.intreq = IF_AUD0; amiga_do_irq(IRQ_AMIGA_AUD0, fp); } /* if audio 1 interrupt */ if (ints & IF_AUD1) { - amiga_custom.intreq = IF_AUD1; + custom.intreq = IF_AUD1; amiga_do_irq(IRQ_AMIGA_AUD1, fp); } /* if audio 2 interrupt */ if (ints & IF_AUD2) { - amiga_custom.intreq = IF_AUD2; + custom.intreq = IF_AUD2; amiga_do_irq(IRQ_AMIGA_AUD2, fp); } /* if audio 3 interrupt */ if (ints & IF_AUD3) { - amiga_custom.intreq = IF_AUD3; + custom.intreq = IF_AUD3; amiga_do_irq(IRQ_AMIGA_AUD3, fp); } return IRQ_HANDLED; @@ -461,7 +461,7 @@ static irqreturn_t ami_int4(int irq, void *dev_id, struct pt_regs *fp) static irqreturn_t ami_int5(int irq, void *dev_id, struct pt_regs *fp) { - unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; + unsigned short ints = custom.intreqr & custom.intenar; /* if serial receive buffer full interrupt */ if (ints & IF_RBF) { @@ -471,7 +471,7 @@ static irqreturn_t ami_int5(int irq, void *dev_id, struct pt_regs *fp) /* if a disk sync interrupt */ if (ints & IF_DSKSYN) { - amiga_custom.intreq = IF_DSKSYN; + custom.intreq = IF_DSKSYN; amiga_do_irq(IRQ_AMIGA_DSKSYN, fp); } return IRQ_HANDLED; diff --git a/trunk/arch/m68k/amiga/amisound.c b/trunk/arch/m68k/amiga/amisound.c index ae94db5d93b2..bd5d134e9f12 100644 --- a/trunk/arch/m68k/amiga/amisound.c +++ b/trunk/arch/m68k/amiga/amisound.c @@ -24,8 +24,6 @@ static const signed char sine_data[] = { }; #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/trunk/arch/m68k/amiga/cia.c b/trunk/arch/m68k/amiga/cia.c index 9476eb9440f5..7d55682615e3 100644 --- a/trunk/arch/m68k/amiga/cia.c +++ b/trunk/arch/m68k/amiga/cia.c @@ -60,7 +60,7 @@ unsigned char cia_set_irq(struct ciabase *base, unsigned char mask) else base->icr_data &= ~mask; if (base->icr_data & base->icr_mask) - amiga_custom.intreq = IF_SETCLR | base->int_mask; + custom.intreq = IF_SETCLR | base->int_mask; return old & base->icr_mask; } @@ -89,7 +89,7 @@ unsigned char cia_able_irq(struct ciabase *base, unsigned char mask) } } if (base->icr_data & base->icr_mask) - amiga_custom.intreq = IF_SETCLR | base->int_mask; + custom.intreq = IF_SETCLR | base->int_mask; return old; } @@ -133,7 +133,7 @@ static irqreturn_t cia_handler(int irq, void *dev_id, struct pt_regs *fp) mach_irq = base->cia_irq; irq = SYS_IRQS + mach_irq; ints = cia_set_irq(base, CIA_ICR_ALL); - amiga_custom.intreq = base->int_mask; + 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 @@ void __init cia_init_IRQ(struct ciabase *base) /* install CIA handler */ request_irq(base->handler_irq, cia_handler, 0, base->name, base); - amiga_custom.intena = IF_SETCLR | base->int_mask; + custom.intena = IF_SETCLR | base->int_mask; } int cia_get_irq_list(struct ciabase *base, struct seq_file *p) diff --git a/trunk/arch/m68k/amiga/config.c b/trunk/arch/m68k/amiga/config.c index 12e3706fe02c..4775e18a78f0 100644 --- a/trunk/arch/m68k/amiga/config.c +++ b/trunk/arch/m68k/amiga/config.c @@ -105,6 +105,9 @@ static int a2000_hwclk (int, struct rtc_time *); 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); @@ -287,7 +290,7 @@ static void __init amiga_identify(void) case CS_OCS: case CS_ECS: case CS_AGA: - switch (amiga_custom.deniseid & 0xf) { + switch (custom.deniseid & 0xf) { case 0x0c: AMIGAHW_SET(DENISE_HR); break; @@ -300,7 +303,7 @@ static void __init amiga_identify(void) AMIGAHW_SET(DENISE); break; } - switch ((amiga_custom.vposr>>8) & 0x7f) { + switch ((custom.vposr>>8) & 0x7f) { case 0x00: AMIGAHW_SET(AGNUS_PAL); break; @@ -424,7 +427,13 @@ void __init config_amiga(void) 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 @@ -438,9 +447,9 @@ void __init config_amiga(void) amiga_colorclock = 5*amiga_eclock; /* 3.5 MHz */ /* clear all DMA bits */ - amiga_custom.dmacon = DMAF_ALL; + custom.dmacon = DMAF_ALL; /* ensure that the DMA master bit is set */ - amiga_custom.dmacon = DMAF_SETCLR | DMAF_MASTER; + custom.dmacon = DMAF_SETCLR | DMAF_MASTER; /* don't use Z2 RAM as system memory on Z3 capable machines */ if (AMIGAHW_PRESENT(ZORRO3)) { @@ -821,8 +830,8 @@ static void amiga_savekmsg_init(void) static void amiga_serial_putc(char c) { - amiga_custom.serdat = (unsigned char)c | 0x100; - while (!(amiga_custom.serdatr & 0x2000)) + custom.serdat = (unsigned char)c | 0x100; + while (!(custom.serdatr & 0x2000)) ; } @@ -846,11 +855,11 @@ int amiga_serial_console_wait_key(struct console *co) { int ch; - while (!(amiga_custom.intreqr & IF_RBF)) + while (!(custom.intreqr & IF_RBF)) barrier(); - ch = amiga_custom.serdatr & 0xff; + ch = custom.serdatr & 0xff; /* clear the interrupt, so that another character can be read */ - amiga_custom.intreq = IF_RBF; + custom.intreq = IF_RBF; return ch; } diff --git a/trunk/arch/m68k/apollo/config.c b/trunk/arch/m68k/apollo/config.c index d401962d9b25..264929471253 100644 --- a/trunk/arch/m68k/apollo/config.c +++ b/trunk/arch/m68k/apollo/config.c @@ -176,6 +176,9 @@ void config_apollo(void) { 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/trunk/arch/m68k/atari/config.c b/trunk/arch/m68k/atari/config.c index 1012b08e5522..9261d2deeaf5 100644 --- a/trunk/arch/m68k/atari/config.c +++ b/trunk/arch/m68k/atari/config.c @@ -52,6 +52,9 @@ int atari_rtc_year_offset; /* 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); @@ -241,6 +244,12 @@ void __init config_atari(void) 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/trunk/arch/m68k/bvme6000/rtc.c b/trunk/arch/m68k/bvme6000/rtc.c index 703cbc6dc9cc..f7573f2bcb9c 100644 --- a/trunk/arch/m68k/bvme6000/rtc.c +++ b/trunk/arch/m68k/bvme6000/rtc.c @@ -47,7 +47,6 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 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 */ @@ -70,7 +69,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, } while (wtime.tm_sec != BCD2BIN(rtc->bcd_sec)); rtc->msr = msr; local_irq_restore(flags); - return copy_to_user(argp, &wtime, sizeof wtime) ? + return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; } case RTC_SET_TIME: /* Set the RTC */ @@ -82,7 +81,8 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, if (!capable(CAP_SYS_ADMIN)) return -EACCES; - if (copy_from_user(&rtc_tm, argp, sizeof(struct rtc_time))) + if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, + sizeof(struct rtc_time))) return -EFAULT; yrs = rtc_tm.tm_year; diff --git a/trunk/arch/m68k/hp300/config.c b/trunk/arch/m68k/hp300/config.c index 6d129eef370f..a0b854f3f94a 100644 --- a/trunk/arch/m68k/hp300/config.c +++ b/trunk/arch/m68k/hp300/config.c @@ -260,6 +260,9 @@ void __init config_hp300(void) mach_reset = hp300_reset; #ifdef CONFIG_HEARTBEAT mach_heartbeat = hp300_pulse; +#endif +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; #endif mach_max_dma_address = 0xffffffff; diff --git a/trunk/arch/m68k/kernel/asm-offsets.c b/trunk/arch/m68k/kernel/asm-offsets.c index 246a8820c223..c787c5ba9513 100644 --- a/trunk/arch/m68k/kernel/asm-offsets.c +++ b/trunk/arch/m68k/kernel/asm-offsets.c @@ -92,7 +92,7 @@ int main(void) DEFINE(TRAP_TRACE, TRAP_TRACE); /* offsets into the custom struct */ - DEFINE(CUSTOMBASE, &amiga_custom); + DEFINE(CUSTOMBASE, &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/trunk/arch/m68k/kernel/head.S b/trunk/arch/m68k/kernel/head.S index 70002c146eed..d4336d846df1 100644 --- a/trunk/arch/m68k/kernel/head.S +++ b/trunk/arch/m68k/kernel/head.S @@ -273,10 +273,8 @@ * 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/trunk/arch/m68k/kernel/process.c b/trunk/arch/m68k/kernel/process.c index 3f9cb55d0356..13d109328a42 100644 --- a/trunk/arch/m68k/kernel/process.c +++ b/trunk/arch/m68k/kernel/process.c @@ -238,9 +238,10 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, { struct pt_regs * childregs; struct switch_stack * childstack, *stack; - unsigned long *retp; + unsigned long stack_offset, *retp; - childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1; + stack_offset = THREAD_SIZE - sizeof(struct pt_regs); + childregs = (struct pt_regs *) ((unsigned long) (p->thread_info) + stack_offset); *childregs = *regs; childregs->d0 = 0; @@ -385,7 +386,7 @@ unsigned long get_wchan(struct task_struct *p) if (!p || p == current || p->state == TASK_RUNNING) return 0; - stack_page = (unsigned long)task_stack_page(p); + stack_page = (unsigned long)(p->thread_info); fp = ((struct switch_stack *)p->thread.ksp)->a6; do { if (fp < stack_page+sizeof(struct thread_info) || diff --git a/trunk/arch/m68k/kernel/setup.c b/trunk/arch/m68k/kernel/setup.c index 750d5b3c971f..d6ca99242e5a 100644 --- a/trunk/arch/m68k/kernel/setup.c +++ b/trunk/arch/m68k/kernel/setup.c @@ -84,6 +84,9 @@ void (*mach_reset)( void ); 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); @@ -97,8 +100,6 @@ void (*mach_beep)(unsigned int, unsigned int); #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 *); @@ -279,10 +280,6 @@ void __init setup_arch(char **cmdline_p) } } -#ifdef CONFIG_DUMMY_CONSOLE - conswitchp = &dummy_con; -#endif - switch (m68k_machtype) { #ifdef CONFIG_AMIGA case MACH_AMIGA: @@ -524,6 +521,16 @@ int get_hardware_list(char *buffer) 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/trunk/arch/m68k/kernel/signal.c b/trunk/arch/m68k/kernel/signal.c index 866917bfa028..9c636a4c238d 100644 --- a/trunk/arch/m68k/kernel/signal.c +++ b/trunk/arch/m68k/kernel/signal.c @@ -96,7 +96,7 @@ asmlinkage int do_sigsuspend(struct pt_regs *regs) asmlinkage int do_rt_sigsuspend(struct pt_regs *regs) { - sigset_t __user *unewset = (sigset_t __user *)regs->d1; + sigset_t *unewset = (sigset_t *)regs->d1; size_t sigsetsize = (size_t)regs->d2; sigset_t saveset, newset; @@ -122,8 +122,8 @@ do_rt_sigsuspend(struct pt_regs *regs) } asmlinkage int -sys_sigaction(int sig, const struct old_sigaction __user *act, - struct old_sigaction __user *oact) +sys_sigaction(int sig, const struct old_sigaction *act, + struct old_sigaction *oact) { struct k_sigaction new_ka, old_ka; int ret; @@ -154,7 +154,7 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, } asmlinkage int -sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) +sys_sigaltstack(const stack_t *uss, stack_t *uoss) { return do_sigaltstack(uss, uoss, rdusp()); } @@ -169,10 +169,10 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) struct sigframe { - char __user *pretcode; + char *pretcode; int sig; int code; - struct sigcontext __user *psc; + struct sigcontext *psc; char retcode[8]; unsigned long extramask[_NSIG_WORDS-1]; struct sigcontext sc; @@ -180,10 +180,10 @@ struct sigframe struct rt_sigframe { - char __user *pretcode; + char *pretcode; int sig; - struct siginfo __user *pinfo; - void __user *puc; + struct siginfo *pinfo; + void *puc; char retcode[8]; struct siginfo info; struct ucontext uc; @@ -248,7 +248,7 @@ static inline int restore_fpu_state(struct sigcontext *sc) #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 __user *uc) +static inline int rt_restore_fpu_state(struct ucontext *uc) { unsigned char fpstate[FPCONTEXT_SIZE]; int context_size = CPU_IS_060 ? 8 : 0; @@ -267,7 +267,7 @@ static inline int rt_restore_fpu_state(struct ucontext __user *uc) return 0; } - if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate)) + if (__get_user(*(long *)fpstate, (long *)&uc->uc_fpstate)) goto out; if (CPU_IS_060 ? fpstate[2] : fpstate[0]) { if (!CPU_IS_060) @@ -306,7 +306,7 @@ static inline int rt_restore_fpu_state(struct ucontext __user *uc) "m" (*fpregs.f_fpcntl)); } if (context_size && - __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1, + __copy_from_user(fpstate + 4, (long *)&uc->uc_fpstate + 1, context_size)) goto out; __asm__ volatile (".chip 68k/68881\n\t" @@ -319,7 +319,7 @@ static inline int rt_restore_fpu_state(struct ucontext __user *uc) } static inline int -restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp, +restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, void *fp, int *pd0) { int fsize, formatvec; @@ -404,10 +404,10 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __u static inline int rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw, - struct ucontext __user *uc, int *pd0) + struct ucontext *uc, int *pd0) { int fsize, temp; - greg_t __user *gregs = uc->uc_mcontext.gregs; + greg_t *gregs = uc->uc_mcontext.gregs; unsigned long usp; int err; @@ -506,7 +506,7 @@ asmlinkage int do_sigreturn(unsigned long __unused) struct switch_stack *sw = (struct switch_stack *) &__unused; struct pt_regs *regs = (struct pt_regs *) (sw + 1); unsigned long usp = rdusp(); - struct sigframe __user *frame = (struct sigframe __user *)(usp - 4); + struct sigframe *frame = (struct sigframe *)(usp - 4); sigset_t set; int d0; @@ -536,7 +536,7 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused) struct switch_stack *sw = (struct switch_stack *) &__unused; struct pt_regs *regs = (struct pt_regs *) (sw + 1); unsigned long usp = rdusp(); - struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4); + struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4); sigset_t set; int d0; @@ -596,7 +596,7 @@ static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs) } } -static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs) +static inline int rt_save_fpu_state(struct ucontext *uc, struct pt_regs *regs) { unsigned char fpstate[FPCONTEXT_SIZE]; int context_size = CPU_IS_060 ? 8 : 0; @@ -617,7 +617,7 @@ static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs * ".chip 68k" : : "m" (*fpstate) : "memory"); - err |= __put_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate); + err |= __put_user(*(long *)fpstate, (long *)&uc->uc_fpstate); if (CPU_IS_060 ? fpstate[2] : fpstate[0]) { fpregset_t fpregs; if (!CPU_IS_060) @@ -642,7 +642,7 @@ static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs * sizeof(fpregs)); } if (context_size) - err |= copy_to_user((long __user *)&uc->uc_fpstate + 1, fpstate + 4, + err |= copy_to_user((long *)&uc->uc_fpstate + 1, fpstate + 4, context_size); return err; } @@ -662,10 +662,10 @@ static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, save_fpu_state(sc, regs); } -static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs) +static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs) { struct switch_stack *sw = (struct switch_stack *)regs - 1; - greg_t __user *gregs = uc->uc_mcontext.gregs; + greg_t *gregs = uc->uc_mcontext.gregs; int err = 0; err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version); @@ -753,7 +753,7 @@ static inline void push_cache (unsigned long vaddr) } } -static inline void __user * +static inline void * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) { unsigned long usp; @@ -766,13 +766,13 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) if (!on_sig_stack(usp)) usp = current->sas_ss_sp + current->sas_ss_size; } - return (void __user *)((usp - frame_size) & -8UL); + return (void *)((usp - frame_size) & -8UL); } static void setup_frame (int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *regs) { - struct sigframe __user *frame; + struct sigframe *frame; int fsize = frame_extra_sizes[regs->format]; struct sigcontext context; int err = 0; @@ -813,7 +813,7 @@ static void setup_frame (int sig, struct k_sigaction *ka, err |= __put_user(frame->retcode, &frame->pretcode); /* moveq #,d0; trap #0 */ err |= __put_user(0x70004e40 + (__NR_sigreturn << 16), - (long __user *)(frame->retcode)); + (long *)(frame->retcode)); if (err) goto give_sigsegv; @@ -849,7 +849,7 @@ static void setup_frame (int sig, struct k_sigaction *ka, static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, struct pt_regs *regs) { - struct rt_sigframe __user *frame; + struct rt_sigframe *frame; int fsize = frame_extra_sizes[regs->format]; int err = 0; @@ -880,8 +880,8 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, /* Create the ucontext. */ err |= __put_user(0, &frame->uc.uc_flags); - err |= __put_user(NULL, &frame->uc.uc_link); - err |= __put_user((void __user *)current->sas_ss_sp, + err |= __put_user(0, &frame->uc.uc_link); + err |= __put_user((void *)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 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, err |= __put_user(frame->retcode, &frame->pretcode); /* moveq #,d0; notb d0; trap #0 */ err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16), - (long __user *)(frame->retcode + 0)); - err |= __put_user(0x4e40, (short __user *)(frame->retcode + 4)); + (long *)(frame->retcode + 0)); + err |= __put_user(0x4e40, (short *)(frame->retcode + 4)); if (err) goto give_sigsegv; diff --git a/trunk/arch/m68k/kernel/sys_m68k.c b/trunk/arch/m68k/kernel/sys_m68k.c index 143c552d38f3..640895b2c51a 100644 --- a/trunk/arch/m68k/kernel/sys_m68k.c +++ b/trunk/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 __user * fildes) +asmlinkage int sys_pipe(unsigned long * fildes) { int fd[2]; int error; @@ -94,7 +94,7 @@ struct mmap_arg_struct { unsigned long offset; }; -asmlinkage int old_mmap(struct mmap_arg_struct __user *arg) +asmlinkage int old_mmap(struct mmap_arg_struct *arg) { struct mmap_arg_struct a; int error = -EFAULT; @@ -160,11 +160,11 @@ asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg) struct sel_arg_struct { unsigned long n; - fd_set __user *inp, *outp, *exp; - struct timeval __user *tvp; + fd_set *inp, *outp, *exp; + struct timeval *tvp; }; -asmlinkage int old_select(struct sel_arg_struct __user *arg) +asmlinkage int old_select(struct sel_arg_struct *arg) { struct sel_arg_struct a; @@ -180,7 +180,7 @@ asmlinkage int old_select(struct sel_arg_struct __user *arg) * This is really horribly ugly. */ asmlinkage int sys_ipc (uint call, int first, int second, - int third, void __user *ptr, long fifth) + int third, void *ptr, long fifth) { int version, ret; @@ -190,14 +190,14 @@ asmlinkage int sys_ipc (uint call, int first, int second, if (call <= SEMCTL) switch (call) { case SEMOP: - return sys_semop (first, ptr, second); + return sys_semop (first, (struct sembuf *)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 __user *__user *) ptr)) + if (get_user(fourth.__pad, (void **) ptr)) return -EFAULT; return sys_semctl (first, second, third, fourth); } @@ -207,26 +207,31 @@ asmlinkage int sys_ipc (uint call, int first, int second, if (call <= MSGCTL) switch (call) { case MSGSND: - return sys_msgsnd (first, ptr, second, third); + return sys_msgsnd (first, (struct msgbuf *) ptr, + second, third); case MSGRCV: switch (version) { case 0: { struct ipc_kludge tmp; if (!ptr) return -EINVAL; - if (copy_from_user (&tmp, ptr, sizeof (tmp))) + if (copy_from_user (&tmp, + (struct ipc_kludge *)ptr, + sizeof (tmp))) return -EFAULT; return sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third); } default: - return sys_msgrcv (first, ptr, + return sys_msgrcv (first, + (struct msgbuf *) ptr, second, fifth, third); } case MSGGET: return sys_msgget ((key_t) first, second); case MSGCTL: - return sys_msgctl (first, second, ptr); + return sys_msgctl (first, second, + (struct msqid_ds *) ptr); default: return -ENOSYS; } @@ -236,18 +241,20 @@ asmlinkage int sys_ipc (uint call, int first, int second, switch (version) { default: { ulong raddr; - ret = do_shmat (first, ptr, second, &raddr); + ret = do_shmat (first, (char *) ptr, + second, &raddr); if (ret) return ret; - return put_user (raddr, (ulong __user *) third); + return put_user (raddr, (ulong *) third); } } case SHMDT: - return sys_shmdt (ptr); + return sys_shmdt ((char *)ptr); case SHMGET: return sys_shmget (first, second, third); case SHMCTL: - return sys_shmctl (first, second, ptr); + return sys_shmctl (first, second, + (struct shmid_ds *) ptr); default: return -ENOSYS; } diff --git a/trunk/arch/m68k/kernel/traps.c b/trunk/arch/m68k/kernel/traps.c index cdf58fbb3e73..deb36e8b04a2 100644 --- a/trunk/arch/m68k/kernel/traps.c +++ b/trunk/arch/m68k/kernel/traps.c @@ -169,25 +169,25 @@ void __init trap_init (void) if (CPU_IS_060 && !FPU_IS_EMU) { /* set up IFPSP entry points */ - 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_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; + 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"); + + 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; } /* if running on an amiga, make the NMI interrupt do nothing */ diff --git a/trunk/arch/m68k/kernel/vmlinux-std.lds b/trunk/arch/m68k/kernel/vmlinux-std.lds index 69d1d3d30c78..e58654f3f8dd 100644 --- a/trunk/arch/m68k/kernel/vmlinux-std.lds +++ b/trunk/arch/m68k/kernel/vmlinux-std.lds @@ -13,7 +13,6 @@ SECTIONS .text : { *(.text) SCHED_TEXT - LOCK_TEXT *(.fixup) *(.gnu.warning) } :text = 0x4e75 diff --git a/trunk/arch/m68k/kernel/vmlinux-sun3.lds b/trunk/arch/m68k/kernel/vmlinux-sun3.lds index 65cc39c24185..cc37e8d3c1e2 100644 --- a/trunk/arch/m68k/kernel/vmlinux-sun3.lds +++ b/trunk/arch/m68k/kernel/vmlinux-sun3.lds @@ -14,7 +14,6 @@ SECTIONS *(.head) *(.text) SCHED_TEXT - LOCK_TEXT *(.fixup) *(.gnu.warning) } :text = 0x4e75 @@ -67,7 +66,7 @@ __init_begin = .; __initramfs_end = .; . = ALIGN(8192); __init_end = .; - .data.init.task : { *(.data.init_task) } + .init.task : { *(init_task) } .bss : { *(.bss) } /* BSS */ diff --git a/trunk/arch/m68k/lib/checksum.c b/trunk/arch/m68k/lib/checksum.c index cb13c6e3ccae..4a5c5445c610 100644 --- a/trunk/arch/m68k/lib/checksum.c +++ b/trunk/arch/m68k/lib/checksum.c @@ -134,7 +134,7 @@ EXPORT_SYMBOL(csum_partial); */ unsigned int -csum_partial_copy_from_user(const unsigned char __user *src, unsigned char *dst, +csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, int len, int sum, int *csum_err) { /* diff --git a/trunk/arch/m68k/mac/config.c b/trunk/arch/m68k/mac/config.c index 14f8d3f4e195..cd19cbb213e8 100644 --- a/trunk/arch/m68k/mac/config.c +++ b/trunk/arch/m68k/mac/config.c @@ -212,6 +212,9 @@ void __init config_mac(void) 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/trunk/arch/m68k/mac/iop.c b/trunk/arch/m68k/mac/iop.c index 9179a3798407..d889ba80ccdc 100644 --- a/trunk/arch/m68k/mac/iop.c +++ b/trunk/arch/m68k/mac/iop.c @@ -293,8 +293,8 @@ void __init iop_init(void) } for (i = 0 ; i < NUM_IOP_CHAN ; i++) { - iop_send_queue[IOP_NUM_SCC][i] = NULL; - iop_send_queue[IOP_NUM_ISM][i] = NULL; + iop_send_queue[IOP_NUM_SCC][i] = 0; + iop_send_queue[IOP_NUM_ISM][i] = 0; 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/trunk/arch/m68k/mac/misc.c b/trunk/arch/m68k/mac/misc.c index bbb0c3b95e9c..5b80d7cd954a 100644 --- a/trunk/arch/m68k/mac/misc.c +++ b/trunk/arch/m68k/mac/misc.c @@ -39,163 +39,72 @@ extern struct mac_booter_data mac_bi_data; static void (*rom_reset)(void); -#ifdef CONFIG_ADB_CUDA -static long cuda_read_time(void) +#ifdef CONFIG_ADB +/* + * Return the current time as the number of seconds since January 1, 1904. + */ + +static long adb_read_time(void) { - struct adb_request req; + volatile struct adb_request req; long time; - if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0) - return 0; - while (!req.complete) - cuda_poll(); + adb_request((struct adb_request *) &req, NULL, + ADBREQ_RAW|ADBREQ_SYNC, + 2, CUDA_PACKET, CUDA_GET_TIME); time = (req.reply[3] << 24) | (req.reply[4] << 16) | (req.reply[5] << 8) | req.reply[6]; return time - RTC_OFFSET; } -static void cuda_write_time(long data) -{ - 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(); -} - -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 +/* + * Set the current system time + */ -#ifdef CONFIG_ADB_PMU68K -static long pmu_read_time(void) +static void adb_write_time(long data) { - struct adb_request req; - long time; - - if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0) - return 0; - while (!req.complete) - pmu_poll(); + volatile struct adb_request req; - 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(); + adb_request((struct adb_request *) &req, NULL, + ADBREQ_RAW|ADBREQ_SYNC, + 6, CUDA_PACKET, CUDA_SET_TIME, + (data >> 24) & 0xFF, (data >> 16) & 0xFF, + (data >> 8) & 0xFF, data & 0xFF); } -#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, ...); +/* + * Get a byte from the NVRAM + */ -static long maciisi_read_time(void) +static __u8 adb_read_pram(int offset) { - struct adb_request req; - long time; + volatile struct adb_request req; - 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; + adb_request((struct adb_request *) &req, NULL, + ADBREQ_RAW|ADBREQ_SYNC, + 4, CUDA_PACKET, CUDA_GET_PRAM, + (offset >> 8) & 0xFF, offset & 0xFF); + return req.reply[3]; } -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); -} +/* + * Write a byte to the NVRAM + */ -static __u8 maciisi_read_pram(int offset) +static void adb_write_pram(int offset, __u8 data) { - 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]; -} + volatile struct adb_request req; -static void maciisi_write_pram(int offset, __u8 data) -{ - struct adb_request req; - maciisi_request(&req, NULL, 5, CUDA_PACKET, CUDA_SET_PRAM, - (offset >> 8) & 0xFF, offset & 0xFF, data); + adb_request((struct adb_request *) &req, NULL, + ADBREQ_RAW|ADBREQ_SYNC, + 5, CUDA_PACKET, CUDA_SET_PRAM, + (offset >> 8) & 0xFF, offset & 0xFF, + data); } -#else -#define maciisi_read_time() 0 -#define maciisi_write_time(n) -#define maciisi_read_pram NULL -#define maciisi_write_pram NULL -#endif +#endif /* CONFIG_ADB */ /* * VIA PRAM/RTC access routines @@ -396,55 +305,42 @@ static void oss_shutdown(void) static void cuda_restart(void) { - struct adb_request req; - if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_RESET_SYSTEM) < 0) - return; - while (!req.complete) - cuda_poll(); + adb_request(NULL, NULL, ADBREQ_RAW|ADBREQ_SYNC, + 2, CUDA_PACKET, CUDA_RESET_SYSTEM); } static void cuda_shutdown(void) { - struct adb_request req; - if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_POWERDOWN) < 0) - return; - while (!req.complete) - cuda_poll(); + adb_request(NULL, NULL, ADBREQ_RAW|ADBREQ_SYNC, + 2, CUDA_PACKET, CUDA_POWERDOWN); } #endif /* CONFIG_ADB_CUDA */ -#ifdef CONFIG_ADB_PMU68K +#ifdef CONFIG_ADB_PMU void pmu_restart(void) { - 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(); + 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); } void pmu_shutdown(void) { - 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(); + 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'); } -#endif +#endif /* CONFIG_ADB_PMU */ /* *------------------------------------------------------------------- @@ -455,22 +351,21 @@ void pmu_shutdown(void) void mac_pram_read(int offset, __u8 *buffer, int len) { - __u8 (*func)(int); + __u8 (*func)(int) = NULL; int i; - 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: + 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 { func = via_read_pram; } - if (!func) - return; for (i = 0 ; i < len ; i++) { buffer[i] = (*func)(offset++); } @@ -478,22 +373,21 @@ void mac_pram_read(int offset, __u8 *buffer, int len) void mac_pram_write(int offset, __u8 *buffer, int len) { - void (*func)(int, __u8); + void (*func)(int, __u8) = NULL; int i; - 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: + 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 { func = via_write_pram; } - if (!func) - return; for (i = 0 ; i < len ; i++) { (*func)(offset++, buffer[i]); } @@ -514,7 +408,7 @@ void mac_poweroff(void) } else if (macintosh_config->adb_type == MAC_ADB_CUDA) { cuda_shutdown(); #endif -#ifdef CONFIG_ADB_PMU68K +#ifdef CONFIG_ADB_PMU } else if (macintosh_config->adb_type == MAC_ADB_PB1 || macintosh_config->adb_type == MAC_ADB_PB2) { pmu_shutdown(); @@ -554,7 +448,7 @@ void mac_reset(void) } else if (macintosh_config->adb_type == MAC_ADB_CUDA) { cuda_restart(); #endif -#ifdef CONFIG_ADB_PMU68K +#ifdef CONFIG_ADB_PMU } else if (macintosh_config->adb_type == MAC_ADB_PB1 || macintosh_config->adb_type == MAC_ADB_PB2) { pmu_restart(); @@ -572,13 +466,12 @@ void mac_reset(void) /* 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" (addr)); + : : "m" ((phys&0xFF000000)|0x8777)); /* Now jump to physical address so we can disable MMU */ __asm__ __volatile__( ".chip 68030\n\t" @@ -695,22 +588,20 @@ int mac_hwclk(int op, struct rtc_time *t) unsigned long now; if (!op) { /* read */ - switch (macintosh_config->adb_type) { - case MAC_ADB_II: - case MAC_ADB_IOP: + if (macintosh_config->adb_type == MAC_ADB_II) { now = via_read_time(); - 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: + } 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 { now = 0; } @@ -728,20 +619,15 @@ int mac_hwclk(int op, struct rtc_time *t) now = mktime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); - switch (macintosh_config->adb_type) { - case MAC_ADB_II: - case MAC_ADB_IOP: + if (macintosh_config->adb_type == MAC_ADB_II) { + 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/trunk/arch/m68k/math-emu/multi_arith.h b/trunk/arch/m68k/math-emu/multi_arith.h index 4ad0ca918e2e..02251e5afd89 100644 --- a/trunk/arch/m68k/math-emu/multi_arith.h +++ b/trunk/arch/m68k/math-emu/multi_arith.h @@ -366,7 +366,7 @@ static inline void fp_submant(struct fp_ext *dest, struct fp_ext *src1, #define fp_mul64(desth, destl, src1, src2) ({ \ asm ("mulu.l %2,%1:%0" : "=d" (destl), "=d" (desth) \ - : "dm" (src1), "0" (src2)); \ + : "g" (src1), "0" (src2)); \ }) #define fp_div64(quot, rem, srch, srcl, div) \ asm ("divu.l %2,%1:%0" : "=d" (quot), "=d" (rem) \ diff --git a/trunk/arch/m68k/mm/kmap.c b/trunk/arch/m68k/mm/kmap.c index 85ad19a0ac79..fe2383e36b06 100644 --- a/trunk/arch/m68k/mm/kmap.c +++ b/trunk/arch/m68k/mm/kmap.c @@ -102,7 +102,7 @@ static inline void free_io_area(void *addr) */ /* Rewritten by Andreas Schwab to remove all races. */ -void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag) +void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag) { struct vm_struct *area; unsigned long virtaddr, retaddr; @@ -121,7 +121,7 @@ void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cachefla if (MACH_IS_AMIGA) { if ((physaddr >= 0x40000000) && (physaddr + size < 0x60000000) && (cacheflag == IOMAP_NOCACHE_SER)) - return (void __iomem *)physaddr; + return (void *)physaddr; } #endif @@ -218,21 +218,21 @@ void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cachefla #endif flush_tlb_all(); - return (void __iomem *)retaddr; + return (void *)retaddr; } /* * Unmap a ioremap()ed region again */ -void iounmap(void __iomem *addr) +void iounmap(void *addr) { #ifdef CONFIG_AMIGA if ((!MACH_IS_AMIGA) || (((unsigned long)addr < 0x40000000) || ((unsigned long)addr > 0x60000000))) - free_io_area((__force void *)addr); + free_io_area(addr); #else - free_io_area((__force void *)addr); + free_io_area(addr); #endif } diff --git a/trunk/arch/m68k/mvme16x/rtc.c b/trunk/arch/m68k/mvme16x/rtc.c index a69fe3048edc..30f5921ece9b 100644 --- a/trunk/arch/m68k/mvme16x/rtc.c +++ b/trunk/arch/m68k/mvme16x/rtc.c @@ -45,7 +45,6 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 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 */ @@ -65,7 +64,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, wtime.tm_wday = BCD2BIN(rtc->bcd_dow)-1; rtc->ctrl = 0; local_irq_restore(flags); - return copy_to_user(argp, &wtime, sizeof wtime) ? + return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; } case RTC_SET_TIME: /* Set the RTC */ @@ -77,7 +76,8 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, if (!capable(CAP_SYS_ADMIN)) return -EACCES; - if (copy_from_user(&rtc_tm, argp, sizeof(struct rtc_time))) + if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, + sizeof(struct rtc_time))) return -EFAULT; yrs = rtc_tm.tm_year; diff --git a/trunk/arch/m68k/q40/config.c b/trunk/arch/m68k/q40/config.c index 5e0f9b04d45e..02b626bae4ae 100644 --- a/trunk/arch/m68k/q40/config.c +++ b/trunk/arch/m68k/q40/config.c @@ -36,6 +36,8 @@ #include #include +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); @@ -192,6 +194,9 @@ void __init config_q40(void) 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/trunk/arch/m68k/sun3/config.c b/trunk/arch/m68k/sun3/config.c index f1ca0dfbaa67..77d05bcc3221 100644 --- a/trunk/arch/m68k/sun3/config.c +++ b/trunk/arch/m68k/sun3/config.c @@ -160,6 +160,9 @@ void __init config_sun3(void) 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/trunk/arch/m68k/sun3x/config.c b/trunk/arch/m68k/sun3x/config.c index 0920f5d33606..0ef547f5494d 100644 --- a/trunk/arch/m68k/sun3x/config.c +++ b/trunk/arch/m68k/sun3x/config.c @@ -71,6 +71,10 @@ void __init config_sun3x(void) 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/trunk/arch/m68knommu/kernel/process.c b/trunk/arch/m68knommu/kernel/process.c index 99bf43824795..8b3cf57ba706 100644 --- a/trunk/arch/m68knommu/kernel/process.c +++ b/trunk/arch/m68knommu/kernel/process.c @@ -198,9 +198,10 @@ int copy_thread(int nr, unsigned long clone_flags, { struct pt_regs * childregs; struct switch_stack * childstack, *stack; - unsigned long *retp; + unsigned long stack_offset, *retp; - childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1; + stack_offset = THREAD_SIZE - sizeof(struct pt_regs); + childregs = (struct pt_regs *) ((unsigned long) p->thread_info + stack_offset); *childregs = *regs; childregs->d0 = 0; diff --git a/trunk/arch/mips/kernel/process.c b/trunk/arch/mips/kernel/process.c index fa98f10d0132..0476a4dce14e 100644 --- a/trunk/arch/mips/kernel/process.c +++ b/trunk/arch/mips/kernel/process.c @@ -140,12 +140,12 @@ void flush_thread(void) 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 = task_thread_info(p); + struct thread_info *ti = p->thread_info; struct pt_regs *childregs; long childksp; p->set_child_tid = p->clear_child_tid = NULL; - childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE - 32; + childksp = (unsigned long)ti + THREAD_SIZE - 32; preempt_disable(); @@ -229,7 +229,9 @@ void elf_dump_regs(elf_greg_t *gp, struct pt_regs *regs) int dump_task_regs (struct task_struct *tsk, elf_gregset_t *regs) { - elf_dump_regs(*regs, task_pt_regs(tsk)); + 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); return 1; } @@ -407,7 +409,7 @@ unsigned long get_wchan(struct task_struct *p) if (!p || p == current || p->state == TASK_RUNNING) return 0; - stack_page = (unsigned long)task_stack_page(p); + stack_page = (unsigned long)p->thread_info; if (!stack_page || !mips_frame_info_initialized) return 0; diff --git a/trunk/arch/mips/kernel/ptrace.c b/trunk/arch/mips/kernel/ptrace.c index f838b36cc765..8d2549335304 100644 --- a/trunk/arch/mips/kernel/ptrace.c +++ b/trunk/arch/mips/kernel/ptrace.c @@ -64,7 +64,8 @@ int ptrace_getregs (struct task_struct *child, __s64 __user *data) if (!access_ok(VERIFY_WRITE, data, 38 * 8)) return -EIO; - regs = task_pt_regs(child); + regs = (struct pt_regs *) ((unsigned long) child->thread_info + + THREAD_SIZE - 32 - sizeof(struct pt_regs)); for (i = 0; i < 32; i++) __put_user (regs->regs[i], data + i); @@ -91,7 +92,8 @@ int ptrace_setregs (struct task_struct *child, __s64 __user *data) if (!access_ok(VERIFY_READ, data, 38 * 8)) return -EIO; - regs = task_pt_regs(child); + regs = (struct pt_regs *) ((unsigned long) child->thread_info + + THREAD_SIZE - 32 - sizeof(struct pt_regs)); for (i = 0; i < 32; i++) __get_user (regs->regs[i], data + i); @@ -196,7 +198,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) struct pt_regs *regs; unsigned long tmp = 0; - regs = task_pt_regs(child); + regs = (struct pt_regs *) ((unsigned long) child->thread_info + + THREAD_SIZE - 32 - sizeof(struct pt_regs)); ret = 0; /* Default return value. */ switch (addr) { @@ -311,7 +314,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) case PTRACE_POKEUSR: { struct pt_regs *regs; ret = 0; - regs = task_pt_regs(child); + regs = (struct pt_regs *) ((unsigned long) child->thread_info + + THREAD_SIZE - 32 - sizeof(struct pt_regs)); switch (addr) { case 0 ... 31: @@ -438,7 +442,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; case PTRACE_GET_THREAD_AREA: - ret = put_user(task_thread_info(child)->tp_value, + ret = put_user(child->thread_info->tp_value, (unsigned long __user *) data); break; diff --git a/trunk/arch/mips/kernel/ptrace32.c b/trunk/arch/mips/kernel/ptrace32.c index 0c82b25d8c6d..1f998bfde165 100644 --- a/trunk/arch/mips/kernel/ptrace32.c +++ b/trunk/arch/mips/kernel/ptrace32.c @@ -126,7 +126,8 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) struct pt_regs *regs; unsigned int tmp; - regs = task_pt_regs(child); + regs = (struct pt_regs *) ((unsigned long) child->thread_info + + THREAD_SIZE - 32 - sizeof(struct pt_regs)); ret = 0; /* Default return value. */ switch (addr) { @@ -258,7 +259,8 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) case PTRACE_POKEUSR: { struct pt_regs *regs; ret = 0; - regs = task_pt_regs(child); + regs = (struct pt_regs *) ((unsigned long) child->thread_info + + THREAD_SIZE - 32 - sizeof(struct pt_regs)); switch (addr) { case 0 ... 31: @@ -375,7 +377,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) break; case PTRACE_GET_THREAD_AREA: - ret = put_user(task_thread_info(child)->tp_value, + ret = put_user(child->thread_info->tp_value, (unsigned int __user *) (unsigned long) data); break; @@ -389,7 +391,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) break; case PTRACE_GET_THREAD_AREA_3264: - ret = put_user(task_thread_info(child)->tp_value, + ret = put_user(child->thread_info->tp_value, (unsigned long __user *) (unsigned long) data); break; diff --git a/trunk/arch/mips/kernel/smp_mt.c b/trunk/arch/mips/kernel/smp_mt.c index 794a1c3de2a4..d429544ba4bc 100644 --- a/trunk/arch/mips/kernel/smp_mt.c +++ b/trunk/arch/mips/kernel/smp_mt.c @@ -287,7 +287,6 @@ void prom_prepare_cpus(unsigned int max_cpus) */ void prom_boot_secondary(int cpu, struct task_struct *idle) { - struct thread_info *gp = task_thread_info(idle); dvpe(); set_c0_mvpcontrol(MVPCONTROL_VPC); @@ -308,9 +307,11 @@ void prom_boot_secondary(int cpu, struct task_struct *idle) write_tc_gpr_sp( __KSTK_TOS(idle)); /* global pointer */ - write_tc_gpr_gp((unsigned long)gp); + write_tc_gpr_gp((unsigned long)idle->thread_info); - flush_icache_range((unsigned long)gp, (unsigned long)(gp + 1)); + flush_icache_range((unsigned long)idle->thread_info, + (unsigned long)idle->thread_info + + sizeof(struct thread_info)); /* finally out of configuration and into chaos */ clear_c0_mvpcontrol(MVPCONTROL_VPC); diff --git a/trunk/arch/mips/kernel/syscall.c b/trunk/arch/mips/kernel/syscall.c index 332358430ff5..006881942aa2 100644 --- a/trunk/arch/mips/kernel/syscall.c +++ b/trunk/arch/mips/kernel/syscall.c @@ -263,7 +263,7 @@ asmlinkage int sys_olduname(struct oldold_utsname * name) void sys_set_thread_area(unsigned long addr) { - struct thread_info *ti = task_thread_info(current); + struct thread_info *ti = current->thread_info; ti->tp_value = addr; diff --git a/trunk/arch/mips/kernel/traps.c b/trunk/arch/mips/kernel/traps.c index 59a187956de0..7058893d5ad2 100644 --- a/trunk/arch/mips/kernel/traps.c +++ b/trunk/arch/mips/kernel/traps.c @@ -519,7 +519,7 @@ static inline int simulate_llsc(struct pt_regs *regs) */ static inline int simulate_rdhwr(struct pt_regs *regs) { - struct thread_info *ti = task_thread_info(current); + struct thread_info *ti = current->thread_info; unsigned int opcode; if (unlikely(get_insn_opcode(regs, &opcode))) diff --git a/trunk/arch/mips/pmc-sierra/yosemite/smp.c b/trunk/arch/mips/pmc-sierra/yosemite/smp.c index f17f575f58f0..0527170d6adb 100644 --- a/trunk/arch/mips/pmc-sierra/yosemite/smp.c +++ b/trunk/arch/mips/pmc-sierra/yosemite/smp.c @@ -93,8 +93,8 @@ void __init prom_prepare_cpus(unsigned int max_cpus) */ void prom_boot_secondary(int cpu, struct task_struct *idle) { - unsigned long gp = (unsigned long) task_thread_info(idle); - unsigned long sp = __KSTK_TOP(idle); + unsigned long gp = (unsigned long) idle->thread_info; + unsigned long sp = gp + THREAD_SIZE - 32; secondary_sp = sp; secondary_gp = gp; diff --git a/trunk/arch/mips/sgi-ip27/ip27-smp.c b/trunk/arch/mips/sgi-ip27/ip27-smp.c index dbef3f6b5650..3a8291b7d26d 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-smp.c +++ b/trunk/arch/mips/sgi-ip27/ip27-smp.c @@ -168,8 +168,8 @@ void __init prom_prepare_cpus(unsigned int max_cpus) */ void __init prom_boot_secondary(int cpu, struct task_struct *idle) { - unsigned long gp = (unsigned long)task_thread_info(idle); - unsigned long sp = __KSTK_TOS(idle); + unsigned long gp = (unsigned long) idle->thread_info; + unsigned long sp = gp + THREAD_SIZE - 32; LAUNCH_SLAVE(cputonasid(cpu),cputoslice(cpu), (launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap), diff --git a/trunk/arch/mips/sibyte/cfe/smp.c b/trunk/arch/mips/sibyte/cfe/smp.c index 4477af3d8074..e8485124b8fc 100644 --- a/trunk/arch/mips/sibyte/cfe/smp.c +++ b/trunk/arch/mips/sibyte/cfe/smp.c @@ -60,7 +60,7 @@ void prom_boot_secondary(int cpu, struct task_struct *idle) retval = cfe_cpu_start(cpu_logical_map(cpu), &smp_bootstrap, __KSTK_TOS(idle), - (unsigned long)task_thread_info(idle), 0); + (unsigned long)idle->thread_info, 0); if (retval != 0) printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval); } diff --git a/trunk/arch/parisc/kernel/process.c b/trunk/arch/parisc/kernel/process.c index 5da41677e70b..4eb70a40ec7e 100644 --- a/trunk/arch/parisc/kernel/process.c +++ b/trunk/arch/parisc/kernel/process.c @@ -295,7 +295,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, struct task_struct * p, struct pt_regs * pregs) { struct pt_regs * cregs = &(p->thread.regs); - void *stack = task_stack_page(p); + struct thread_info *ti = p->thread_info; /* 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 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, */ if (usp == 1) { /* kernel thread */ - cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN; + cregs->ksp = (((unsigned long)(ti)) + THREAD_SZ_ALGN); /* Must exit via ret_from_kernel_thread in order * to call schedule_tail() */ @@ -344,7 +344,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, */ /* Use same stack depth as parent */ - cregs->ksp = (unsigned long)stack + cregs->ksp = ((unsigned long)(ti)) + (pregs->gr[21] & (THREAD_SIZE - 1)); cregs->gr[30] = usp; if (p->personality == PER_HPUX) { diff --git a/trunk/arch/parisc/kernel/smp.c b/trunk/arch/parisc/kernel/smp.c index 25564b7ca6bb..17f23c26f1ca 100644 --- a/trunk/arch/parisc/kernel/smp.c +++ b/trunk/arch/parisc/kernel/smp.c @@ -517,7 +517,7 @@ int __init smp_boot_one_cpu(int cpuid) if (IS_ERR(idle)) panic("SMP: fork failed for CPU:%d", cpuid); - task_thread_info(idle)->cpu = cpuid; + idle->thread_info->cpu = cpuid; /* Let _start know what logical CPU we're booting ** (offset into init_tasks[],cpu_data[]) diff --git a/trunk/arch/powerpc/kernel/Makefile b/trunk/arch/powerpc/kernel/Makefile index a94699d8dc52..bbfa1bdceb4d 100644 --- a/trunk/arch/powerpc/kernel/Makefile +++ b/trunk/arch/powerpc/kernel/Makefile @@ -11,8 +11,7 @@ CFLAGS_btext.o += -fPIC endif obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ - irq.o align.o signal_32.o pmc.o vdso.o \ - init_task.o process.o + irq.o align.o signal_32.o pmc.o vdso.o obj-y += vdso32/ obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ signal_64.o ptrace32.o systbl.o \ @@ -45,7 +44,8 @@ extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o extra-$(CONFIG_8xx) := head_8xx.o extra-y += vmlinux.lds -obj-y += time.o prom.o traps.o setup-common.o udbg.o +obj-y += process.o init_task.o 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/trunk/arch/powerpc/kernel/pci_64.c b/trunk/arch/powerpc/kernel/pci_64.c index c367520bc1c3..24fe70f40b66 100644 --- a/trunk/arch/powerpc/kernel/pci_64.c +++ b/trunk/arch/powerpc/kernel/pci_64.c @@ -53,7 +53,6 @@ EXPORT_SYMBOL(io_page_mask); #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. @@ -252,7 +251,6 @@ void pcibios_free_controller(struct pci_controller *phb) kfree(phb); } -#ifndef CONFIG_PPC_ISERIES void __devinit pcibios_claim_one_bus(struct pci_bus *b) { struct pci_dev *dev; @@ -277,6 +275,7 @@ void __devinit pcibios_claim_one_bus(struct pci_bus *b) EXPORT_SYMBOL_GPL(pcibios_claim_one_bus); #endif +#ifndef CONFIG_PPC_ISERIES static void __init pcibios_claim_of_setup(void) { struct pci_bus *b; @@ -1219,7 +1218,7 @@ int remap_bus_range(struct pci_bus *bus) } EXPORT_SYMBOL(remap_bus_range); -static void phbs_remap_io(void) +void phbs_remap_io(void) { struct pci_controller *hose, *tmp; diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c index 57703994a063..105d5609ff57 100644 --- a/trunk/arch/powerpc/kernel/process.c +++ b/trunk/arch/powerpc/kernel/process.c @@ -201,13 +201,13 @@ int dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs) } #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. */ -void discard_lazy_cpu_state(void) +static inline void discard_lazy_cpu_state(void) { +#ifndef CONFIG_SMP preempt_disable(); if (last_task_used_math == current) last_task_used_math = NULL; @@ -220,10 +220,9 @@ void discard_lazy_cpu_state(void) last_task_used_spe = NULL; #endif preempt_enable(); -} #endif /* CONFIG_SMP */ +} -#ifdef CONFIG_PPC_MERGE /* XXX for now */ int set_dabr(unsigned long dabr) { if (ppc_md.set_dabr) @@ -232,7 +231,6 @@ int set_dabr(unsigned long dabr) mtspr(SPRN_DABR, dabr); return 0; } -#endif #ifdef CONFIG_PPC64 DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array); @@ -426,7 +424,7 @@ void show_regs(struct pt_regs * regs) 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, task_thread_info(current)); + current, current->pid, current->comm, current->thread_info); #ifdef CONFIG_SMP printk(" CPU: %d", smp_processor_id()); @@ -505,7 +503,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, { struct pt_regs *childregs, *kregs; extern void ret_from_fork(void); - unsigned long sp = (unsigned long)task_stack_page(p) + THREAD_SIZE; + unsigned long sp = (unsigned long)p->thread_info + THREAD_SIZE; CHECK_FULL_REGS(regs); /* Copy registers */ @@ -518,7 +516,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, #ifdef CONFIG_PPC32 childregs->gpr[2] = (unsigned long) p; #else - clear_tsk_thread_flag(p, TIF_32BIT); + clear_ti_thread_flag(p->thread_info, TIF_32BIT); #endif p->thread.regs = NULL; /* no user register state */ } else { @@ -590,8 +588,10 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) * set. Do it now. */ if (!current->thread.regs) { - struct pt_regs *regs = task_stack_page(current) + THREAD_SIZE; - current->thread.regs = regs - 1; + unsigned long childregs = (unsigned long)current->thread_info + + THREAD_SIZE; + childregs -= sizeof(struct pt_regs); + current->thread.regs = (struct pt_regs *)childregs; } memset(regs->gpr, 0, sizeof(regs->gpr)); @@ -767,7 +767,7 @@ int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, static int validate_sp(unsigned long sp, struct task_struct *p, unsigned long nbytes) { - unsigned long stack_page = (unsigned long)task_stack_page(p); + unsigned long stack_page = (unsigned long)p->thread_info; if (sp >= stack_page + sizeof(struct thread_struct) && sp <= stack_page + THREAD_SIZE - nbytes) diff --git a/trunk/arch/powerpc/kernel/prom.c b/trunk/arch/powerpc/kernel/prom.c index 02e2115323e4..34ab0daec3a7 100644 --- a/trunk/arch/powerpc/kernel/prom.c +++ b/trunk/arch/powerpc/kernel/prom.c @@ -1100,37 +1100,17 @@ static int __init early_init_dt_scan_memory(unsigned long node, static void __init early_reserve_mem(void) { - u64 base, size; - u64 *reserve_map; + unsigned long base, size; + unsigned long *reserve_map; - reserve_map = (u64 *)(((unsigned long)initial_boot_params) + + reserve_map = (unsigned long *)(((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: %llx -> %llx\n", base, size); + DBG("reserving: %lx -> %lx\n", base, size); lmb_reserve(base, size); } diff --git a/trunk/arch/powerpc/kernel/prom_init.c b/trunk/arch/powerpc/kernel/prom_init.c index d963a12ec640..e381f2fc121c 100644 --- a/trunk/arch/powerpc/kernel/prom_init.c +++ b/trunk/arch/powerpc/kernel/prom_init.c @@ -137,8 +137,8 @@ struct prom_t { }; struct mem_map_entry { - u64 base; - u64 size; + unsigned long base; + unsigned long size; }; typedef u32 cell_t; @@ -897,9 +897,9 @@ static unsigned long __init prom_next_cell(int s, cell_t **cellp) * If problems seem to show up, it would be a good start to track * them down. */ -static void reserve_mem(u64 base, u64 size) +static void reserve_mem(unsigned long base, unsigned long size) { - u64 top = base + size; + unsigned long top = base + size; unsigned long cnt = RELOC(mem_reserve_cnt); if (size == 0) diff --git a/trunk/arch/powerpc/kernel/ptrace-common.h b/trunk/arch/powerpc/kernel/ptrace-common.h index 5ccbdbe0d5c9..b1babb729673 100644 --- a/trunk/arch/powerpc/kernel/ptrace-common.h +++ b/trunk/arch/powerpc/kernel/ptrace-common.h @@ -62,7 +62,7 @@ static inline void set_single_step(struct task_struct *task) struct pt_regs *regs = task->thread.regs; if (regs != NULL) regs->msr |= MSR_SE; - set_tsk_thread_flag(task, TIF_SINGLESTEP); + set_ti_thread_flag(task->thread_info, TIF_SINGLESTEP); } static inline void clear_single_step(struct task_struct *task) @@ -70,7 +70,7 @@ static inline void clear_single_step(struct task_struct *task) struct pt_regs *regs = task->thread.regs; if (regs != NULL) regs->msr &= ~MSR_SE; - clear_tsk_thread_flag(task, TIF_SINGLESTEP); + clear_ti_thread_flag(task->thread_info, TIF_SINGLESTEP); } #ifdef CONFIG_ALTIVEC diff --git a/trunk/arch/powerpc/kernel/signal_32.c b/trunk/arch/powerpc/kernel/signal_32.c index 177bba78fb0b..d3f0b6d452fb 100644 --- a/trunk/arch/powerpc/kernel/signal_32.c +++ b/trunk/arch/powerpc/kernel/signal_32.c @@ -497,15 +497,6 @@ static long restore_user_regs(struct pt_regs *regs, 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); @@ -547,6 +538,18 @@ static long restore_user_regs(struct pt_regs *regs, 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/trunk/arch/powerpc/kernel/signal_64.c b/trunk/arch/powerpc/kernel/signal_64.c index 7b9d999e2115..5462bef898f6 100644 --- a/trunk/arch/powerpc/kernel/signal_64.c +++ b/trunk/arch/powerpc/kernel/signal_64.c @@ -207,20 +207,10 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig, if (!sig) regs->gpr[13] = save_r13; + err |= __copy_from_user(¤t->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(¤t->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]); @@ -239,6 +229,14 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig, 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/trunk/arch/powerpc/kernel/smp.c b/trunk/arch/powerpc/kernel/smp.c index c8458c531b25..d381ec90b759 100644 --- a/trunk/arch/powerpc/kernel/smp.c +++ b/trunk/arch/powerpc/kernel/smp.c @@ -338,8 +338,8 @@ static void __init smp_create_idle(unsigned int cpu) #ifdef CONFIG_PPC64 paca[cpu].__current = p; #endif - current_set[cpu] = task_thread_info(p); - task_thread_info(p)->cpu = cpu; + current_set[cpu] = p->thread_info; + p->thread_info->cpu = cpu; } void __init smp_prepare_cpus(unsigned int max_cpus) @@ -375,7 +375,7 @@ void __devinit smp_prepare_boot_cpu(void) #ifdef CONFIG_PPC64 paca[boot_cpuid].__current = current; #endif - current_set[boot_cpuid] = task_thread_info(current); + current_set[boot_cpuid] = current->thread_info; } #ifdef CONFIG_HOTPLUG_CPU diff --git a/trunk/arch/powerpc/platforms/cell/pervasive.c b/trunk/arch/powerpc/platforms/cell/pervasive.c index e0e051c675dd..85152544c153 100644 --- a/trunk/arch/powerpc/platforms/cell/pervasive.c +++ b/trunk/arch/powerpc/platforms/cell/pervasive.c @@ -142,7 +142,7 @@ static void cbe_idle(void) } } -static int cbe_system_reset_exception(struct pt_regs *regs) +int cbe_system_reset_exception(struct pt_regs *regs) { switch (regs->msr & SRR1_WAKEMASK) { case SRR1_WAKEEE: diff --git a/trunk/arch/powerpc/platforms/cell/setup.c b/trunk/arch/powerpc/platforms/cell/setup.c index b33a4443f5a9..18e25e65c04b 100644 --- a/trunk/arch/powerpc/platforms/cell/setup.c +++ b/trunk/arch/powerpc/platforms/cell/setup.c @@ -57,7 +57,7 @@ #define DBG(fmt...) #endif -static void cell_show_cpuinfo(struct seq_file *m) +void cell_show_cpuinfo(struct seq_file *m) { struct device_node *root; const char *model = ""; diff --git a/trunk/arch/powerpc/platforms/cell/smp.c b/trunk/arch/powerpc/platforms/cell/smp.c index bdf6c5fe58c0..de96eadf419d 100644 --- a/trunk/arch/powerpc/platforms/cell/smp.c +++ b/trunk/arch/powerpc/platforms/cell/smp.c @@ -86,7 +86,7 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu) pcpu = get_hard_smp_processor_id(lcpu); /* Fixup atomic count: it exited inside IRQ handler. */ - task_thread_info(paca[lcpu].__current)->preempt_count = 0; + paca[lcpu].__current->thread_info->preempt_count = 0; /* * If the RTAS start-cpu token does not exist then presume the diff --git a/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c b/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c index e6565a949ddc..d549aa7ebea6 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c @@ -29,9 +29,7 @@ * value of the spu_status register after the SPU has stopped. * */ -static long do_spu_run(struct file *filp, - __u32 __user *unpc, - __u32 __user *ustatus) +long do_spu_run(struct file *filp, __u32 __user *unpc, __u32 __user *ustatus) { long ret; struct spufs_inode_info *i; diff --git a/trunk/arch/powerpc/platforms/iseries/Makefile b/trunk/arch/powerpc/platforms/iseries/Makefile index ce8c0b943fa0..127b465308be 100644 --- a/trunk/arch/powerpc/platforms/iseries/Makefile +++ b/trunk/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 irq.o -obj-$(CONFIG_PCI) += pci.o vpdinfo.o + hvcall.o proc.o htab.o iommu.o misc.o +obj-$(CONFIG_PCI) += pci.o irq.o vpdinfo.o obj-$(CONFIG_IBMVIO) += vio.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_VIOPATH) += viopath.o diff --git a/trunk/arch/powerpc/platforms/iseries/iommu.c b/trunk/arch/powerpc/platforms/iseries/iommu.c index bea0b703f409..2b54eeb2c899 100644 --- a/trunk/arch/powerpc/platforms/iseries/iommu.c +++ b/trunk/arch/powerpc/platforms/iseries/iommu.c @@ -34,8 +34,6 @@ #include #include -#include "iommu.h" - extern struct list_head iSeries_Global_Device_List; diff --git a/trunk/arch/powerpc/platforms/iseries/iommu.h b/trunk/arch/powerpc/platforms/iseries/iommu.h deleted file mode 100644 index cb5658fbe657..000000000000 --- a/trunk/arch/powerpc/platforms/iseries/iommu.h +++ /dev/null @@ -1,35 +0,0 @@ -#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/trunk/arch/powerpc/platforms/iseries/irq.c b/trunk/arch/powerpc/platforms/iseries/irq.c index 83442ea77476..42e978e4897a 100644 --- a/trunk/arch/powerpc/platforms/iseries/irq.c +++ b/trunk/arch/powerpc/platforms/iseries/irq.c @@ -48,8 +48,6 @@ 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 */ @@ -149,11 +147,20 @@ static void int_received(struct pci_event *event, struct pt_regs *regs) static void pci_event_handler(struct HvLpEvent *event, struct pt_regs *regs) { if (event && (event->xType == HvLpEvent_Type_PciIo)) { - if (hvlpevent_is_int(event)) + switch (event->xFlags.xFunction) { + case HvLpEvent_Function_Int: int_received((struct pci_event *)event, regs); - else + break; + case HvLpEvent_Function_Ack: 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", @@ -327,8 +334,6 @@ int __init iSeries_allocate_IRQ(HvBusNumber bus, return virtirq; } -#endif /* CONFIG_PCI */ - /* * Get the next pending IRQ. */ @@ -348,7 +353,6 @@ int iSeries_get_irq(struct pt_regs *regs) 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++) { @@ -362,7 +366,6 @@ int iSeries_get_irq(struct pt_regs *regs) if (irq >= NR_IRQS) irq = -2; } -#endif return irq; } diff --git a/trunk/arch/powerpc/platforms/iseries/lpardata.c b/trunk/arch/powerpc/platforms/iseries/lpardata.c index 438e2dba63b5..ea72385aaf0a 100644 --- a/trunk/arch/powerpc/platforms/iseries/lpardata.c +++ b/trunk/arch/powerpc/platforms/iseries/lpardata.c @@ -93,7 +93,10 @@ struct ItLpNaca itLpNaca = { .xPirEnvironMode = 0, /* Piranha stuff */ .xPirConsoleMode = 0, .xPirDasdMode = 0, - .flags = 0, + .xLparInstalled = 0, + .xSysPartitioned = 0, + .xHwSyncedTBs = 0, + .xIntProcUtilHmt = 0, .xSpVpdFormat = 0, .xIntProcRatio = 0, .xPlicVrmIndex = 0, /* VRM index of PLIC */ diff --git a/trunk/arch/powerpc/platforms/iseries/lpevents.c b/trunk/arch/powerpc/platforms/iseries/lpevents.c index 0b885300d1d1..e9fb98bf895f 100644 --- a/trunk/arch/powerpc/platforms/iseries/lpevents.c +++ b/trunk/arch/powerpc/platforms/iseries/lpevents.c @@ -53,7 +53,7 @@ static struct HvLpEvent * get_next_hvlpevent(void) struct HvLpEvent * event; event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; - if (hvlpevent_is_valid(event)) { + if (event->xFlags.xValid) { /* rmb() needed only for weakly consistent machines (regatta) */ rmb(); /* Set pointer to next potential event */ @@ -84,7 +84,7 @@ int hvlpevent_is_pending(void) next_event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; - return hvlpevent_is_valid(next_event) || + return next_event->xFlags.xValid | hvlpevent_queue.xPlicOverflowIntPending; } @@ -101,18 +101,18 @@ static void hvlpevent_clear_valid(struct HvLpEvent * event) switch (extra) { case 3: tmp = (struct HvLpEvent*)((char*)event + 3 * LpEventAlign); - hvlpevent_invalidate(tmp); + tmp->xFlags.xValid = 0; case 2: tmp = (struct HvLpEvent*)((char*)event + 2 * LpEventAlign); - hvlpevent_invalidate(tmp); + tmp->xFlags.xValid = 0; case 1: tmp = (struct HvLpEvent*)((char*)event + 1 * LpEventAlign); - hvlpevent_invalidate(tmp); + tmp->xFlags.xValid = 0; } mb(); - hvlpevent_invalidate(event); + event->xFlags.xValid = 0; } void process_hvlpevents(struct pt_regs *regs) diff --git a/trunk/arch/powerpc/platforms/iseries/mf.c b/trunk/arch/powerpc/platforms/iseries/mf.c index a41d8b78c0cd..49e7e4b85847 100644 --- a/trunk/arch/powerpc/platforms/iseries/mf.c +++ b/trunk/arch/powerpc/platforms/iseries/mf.c @@ -251,7 +251,10 @@ static struct pending_event *new_pending_event(void) } memset(ev, 0, sizeof(struct pending_event)); hev = &ev->event.hp_lp_event; - hev->flags = HV_LP_EVENT_VALID | HV_LP_EVENT_DO_ACK | HV_LP_EVENT_INT; + hev->xFlags.xValid = 1; + hev->xFlags.xAckType = HvLpEvent_AckType_ImmediateAck; + hev->xFlags.xAckInd = HvLpEvent_AckInd_DoAck; + hev->xFlags.xFunction = HvLpEvent_Function_Int; hev->xType = HvLpEvent_Type_MachineFac; hev->xSourceLp = HvLpConfig_getLpIndex(); hev->xTargetLp = primary_lp; @@ -515,10 +518,17 @@ static void handle_ack(struct io_mf_lp_event *event) static void hv_handler(struct HvLpEvent *event, struct pt_regs *regs) { if ((event != NULL) && (event->xType == HvLpEvent_Type_MachineFac)) { - if (hvlpevent_is_ack(event)) + switch(event->xFlags.xFunction) { + case HvLpEvent_Function_Ack: handle_ack((struct io_mf_lp_event *)event); - else + break; + case HvLpEvent_Function_Int: 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/trunk/arch/powerpc/platforms/iseries/pci.c b/trunk/arch/powerpc/platforms/iseries/pci.c index a19833b880e4..dafc518fbb83 100644 --- a/trunk/arch/powerpc/platforms/iseries/pci.c +++ b/trunk/arch/powerpc/platforms/iseries/pci.c @@ -43,7 +43,6 @@ #include "irq.h" #include "pci.h" #include "call_pci.h" -#include "iommu.h" extern unsigned long io_page_mask; diff --git a/trunk/arch/powerpc/platforms/iseries/vio.c b/trunk/arch/powerpc/platforms/iseries/vio.c index ad36ab0639f0..384360ee06ec 100644 --- a/trunk/arch/powerpc/platforms/iseries/vio.c +++ b/trunk/arch/powerpc/platforms/iseries/vio.c @@ -22,8 +22,6 @@ #include #include -#include "iommu.h" - struct device *iSeries_vio_dev = &vio_bus_device.dev; EXPORT_SYMBOL(iSeries_vio_dev); diff --git a/trunk/arch/powerpc/platforms/iseries/viopath.c b/trunk/arch/powerpc/platforms/iseries/viopath.c index 622a30149b48..842672695598 100644 --- a/trunk/arch/powerpc/platforms/iseries/viopath.c +++ b/trunk/arch/powerpc/platforms/iseries/viopath.c @@ -270,7 +270,7 @@ static void handleMonitorEvent(struct HvLpEvent *event) * First see if this is just a normal monitor message from the * other partition */ - if (hvlpevent_is_int(event)) { + if (event->xFlags.xFunction == HvLpEvent_Function_Int) { remoteLp = event->xSourceLp; if (!viopathStatus[remoteLp].isActive) sendMonMsg(remoteLp); @@ -331,12 +331,13 @@ static void handleConfig(struct HvLpEvent *event) { if (!event) return; - if (hvlpevent_is_int(event)) { + if (event->xFlags.xFunction == HvLpEvent_Function_Int) { printk(VIOPATH_KERN_WARN "unexpected config request from partition %d", event->xSourceLp); - if (hvlpevent_need_ack(event)) { + if ((event->xFlags.xFunction == HvLpEvent_Function_Int) && + (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck)) { event->xRc = HvLpEvent_Rc_InvalidSubtype; HvCallEvent_ackLpEvent(event); } @@ -376,7 +377,7 @@ static void vio_handleEvent(struct HvLpEvent *event, struct pt_regs *regs) int subtype = (event->xSubtype & VIOMAJOR_SUBTYPE_MASK) >> VIOMAJOR_SUBTYPE_SHIFT; - if (hvlpevent_is_int(event)) { + if (event->xFlags.xFunction == HvLpEvent_Function_Int) { remoteLp = event->xSourceLp; /* * The isActive is checked because if the hosting partition @@ -435,7 +436,8 @@ static void vio_handleEvent(struct HvLpEvent *event, struct pt_regs *regs) "unexpected virtual io event subtype %d from partition %d\n", event->xSubtype, remoteLp); /* No handler. Ack if necessary */ - if (hvlpevent_is_int(event) && hvlpevent_need_ack(event)) { + if ((event->xFlags.xFunction == HvLpEvent_Function_Int) && + (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck)) { event->xRc = HvLpEvent_Rc_InvalidSubtype; HvCallEvent_ackLpEvent(event); } diff --git a/trunk/arch/powerpc/platforms/powermac/setup.c b/trunk/arch/powerpc/platforms/powermac/setup.c index 89c4c3636161..3b1a9d4fcbc6 100644 --- a/trunk/arch/powerpc/platforms/powermac/setup.c +++ b/trunk/arch/powerpc/platforms/powermac/setup.c @@ -278,7 +278,7 @@ static void __init l2cr_init(void) } #endif -static void __init pmac_setup_arch(void) +void __init pmac_setup_arch(void) { struct device_node *cpu, *ic; int *fp; diff --git a/trunk/arch/powerpc/platforms/pseries/eeh.c b/trunk/arch/powerpc/platforms/pseries/eeh.c index 83578313ee7e..17cea7f2afd3 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh.c @@ -208,11 +208,10 @@ static void __eeh_mark_slot (struct device_node *dn, int mode_flag) { while (dn) { if (PCI_DN(dn)) { - /* Mark the pci device driver too */ - struct pci_dev *dev = PCI_DN(dn)->pcidev; - PCI_DN(dn)->eeh_mode |= mode_flag; + /* Mark the pci device driver too */ + struct pci_dev *dev = PCI_DN(dn)->pcidev; if (dev && dev->driver) dev->error_state = pci_channel_io_frozen; diff --git a/trunk/arch/powerpc/platforms/pseries/hvcserver.c b/trunk/arch/powerpc/platforms/pseries/hvcserver.c index 22bfb5c89db9..4d584172055a 100644 --- a/trunk/arch/powerpc/platforms/pseries/hvcserver.c +++ b/trunk/arch/powerpc/platforms/pseries/hvcserver.c @@ -40,7 +40,7 @@ MODULE_VERSION(HVCS_ARCH_VERSION); * functions aren't performance sensitive, so this conversion isn't an * issue. */ -static int hvcs_convert(long to_convert) +int hvcs_convert(long to_convert) { switch (to_convert) { case H_Success: @@ -91,7 +91,7 @@ int hvcs_free_partner_info(struct list_head *head) EXPORT_SYMBOL(hvcs_free_partner_info); /* Helper function for hvcs_get_partner_info */ -static int hvcs_next_partner(uint32_t unit_address, +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/trunk/arch/powerpc/platforms/pseries/iommu.c b/trunk/arch/powerpc/platforms/pseries/iommu.c index 48cfbfc43f99..169f9148789c 100644 --- a/trunk/arch/powerpc/platforms/pseries/iommu.c +++ b/trunk/arch/powerpc/platforms/pseries/iommu.c @@ -51,6 +51,8 @@ #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/trunk/arch/powerpc/platforms/pseries/scanlog.c b/trunk/arch/powerpc/platforms/pseries/scanlog.c index 50643496eb63..2edc947f7c44 100644 --- a/trunk/arch/powerpc/platforms/pseries/scanlog.c +++ b/trunk/arch/powerpc/platforms/pseries/scanlog.c @@ -192,7 +192,7 @@ struct file_operations scanlog_fops = { .release = scanlog_release, }; -static int __init scanlog_init(void) +int __init scanlog_init(void) { struct proc_dir_entry *ent; @@ -222,7 +222,7 @@ static int __init scanlog_init(void) return 0; } -static void __exit scanlog_cleanup(void) +void __exit scanlog_cleanup(void) { if (proc_ppc64_scan_log_dump) { kfree(proc_ppc64_scan_log_dump->data); diff --git a/trunk/arch/powerpc/platforms/pseries/setup.c b/trunk/arch/powerpc/platforms/pseries/setup.c index 68b7f086d63d..8903cf63236a 100644 --- a/trunk/arch/powerpc/platforms/pseries/setup.c +++ b/trunk/arch/powerpc/platforms/pseries/setup.c @@ -86,7 +86,7 @@ static void pseries_dedicated_idle(void); struct mpic *pSeries_mpic; -static void pSeries_show_cpuinfo(struct seq_file *m) +void pSeries_show_cpuinfo(struct seq_file *m) { struct device_node *root; const char *model = ""; diff --git a/trunk/arch/powerpc/platforms/pseries/smp.c b/trunk/arch/powerpc/platforms/pseries/smp.c index 8e6b1ed1396e..25181c594d73 100644 --- a/trunk/arch/powerpc/platforms/pseries/smp.c +++ b/trunk/arch/powerpc/platforms/pseries/smp.c @@ -93,7 +93,7 @@ static int query_cpu_stopped(unsigned int pcpu) return cpu_status; } -static int pSeries_cpu_disable(void) +int pSeries_cpu_disable(void) { int cpu = smp_processor_id(); @@ -109,7 +109,7 @@ static int pSeries_cpu_disable(void) return 0; } -static void pSeries_cpu_die(unsigned int cpu) +void pSeries_cpu_die(unsigned int cpu) { int tries; int cpu_status; @@ -282,7 +282,7 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu) pcpu = get_hard_smp_processor_id(lcpu); /* Fixup atomic count: it exited inside IRQ handler. */ - task_thread_info(paca[lcpu].__current)->preempt_count = 0; + paca[lcpu].__current->thread_info->preempt_count = 0; /* * If the RTAS start-cpu token does not exist then presume the diff --git a/trunk/arch/powerpc/platforms/pseries/xics.c b/trunk/arch/powerpc/platforms/pseries/xics.c index fd823c7c9ac8..0c0cfa32eb58 100644 --- a/trunk/arch/powerpc/platforms/pseries/xics.c +++ b/trunk/arch/powerpc/platforms/pseries/xics.c @@ -381,7 +381,7 @@ int xics_get_irq(struct pt_regs *regs) #ifdef CONFIG_SMP -static irqreturn_t xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs) +irqreturn_t xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs) { int cpu = smp_processor_id(); diff --git a/trunk/arch/powerpc/sysdev/dart_iommu.c b/trunk/arch/powerpc/sysdev/dart_iommu.c index 977de9db8754..e00b46b9514e 100644 --- a/trunk/arch/powerpc/sysdev/dart_iommu.c +++ b/trunk/arch/powerpc/sysdev/dart_iommu.c @@ -139,6 +139,7 @@ static void dart_build(struct iommu_table *tbl, long index, *(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK); + rpn++; uaddr += DART_PAGE_SIZE; } diff --git a/trunk/arch/powerpc/xmon/xmon.c b/trunk/arch/powerpc/xmon/xmon.c index 7d02fa2a8990..22612ed5379c 100644 --- a/trunk/arch/powerpc/xmon/xmon.c +++ b/trunk/arch/powerpc/xmon/xmon.c @@ -311,7 +311,7 @@ static void release_output_lock(void) } #endif -static int xmon_core(struct pt_regs *regs, int fromipi) +int xmon_core(struct pt_regs *regs, int fromipi) { int cmd = 0; unsigned long msr; @@ -528,7 +528,7 @@ xmon_irq(int irq, void *d, struct pt_regs *regs) return IRQ_HANDLED; } -static int xmon_bpt(struct pt_regs *regs) +int xmon_bpt(struct pt_regs *regs) { struct bpt *bp; unsigned long offset; @@ -554,7 +554,7 @@ static int xmon_bpt(struct pt_regs *regs) return 1; } -static int xmon_sstep(struct pt_regs *regs) +int xmon_sstep(struct pt_regs *regs) { if (user_mode(regs)) return 0; @@ -562,7 +562,7 @@ static int xmon_sstep(struct pt_regs *regs) return 1; } -static int xmon_dabr_match(struct pt_regs *regs) +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 @@ static int xmon_dabr_match(struct pt_regs *regs) return 1; } -static int xmon_iabr_match(struct pt_regs *regs) +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 @@ static int xmon_iabr_match(struct pt_regs *regs) return 1; } -static int xmon_ipi(struct pt_regs *regs) +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 @@ static int xmon_ipi(struct pt_regs *regs) return 0; } -static int xmon_fault_handler(struct pt_regs *regs) +int xmon_fault_handler(struct pt_regs *regs) { struct bpt *bp; unsigned long offset; diff --git a/trunk/arch/ppc/amiga/amiints.c b/trunk/arch/ppc/amiga/amiints.c index 5f35cf3986f7..91195e2ce38d 100644 --- a/trunk/arch/ppc/amiga/amiints.c +++ b/trunk/arch/ppc/amiga/amiints.c @@ -96,8 +96,8 @@ void amiga_init_IRQ(void) gayle.inten = GAYLE_IRQ_IDE; /* turn off all interrupts... */ - amiga_custom.intena = 0x7fff; - amiga_custom.intreq = 0x7fff; + custom.intena = 0x7fff; + custom.intreq = 0x7fff; #ifdef CONFIG_APUS /* Clear any inter-CPU interrupt requests. Circumvents bug in @@ -110,7 +110,7 @@ void amiga_init_IRQ(void) APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_IPLMASK); #endif /* ... and enable the master interrupt bit */ - amiga_custom.intena = IF_SETCLR | IF_INTEN; + custom.intena = IF_SETCLR | IF_INTEN; cia_init_IRQ(&ciaa_base); cia_init_IRQ(&ciab_base); @@ -151,7 +151,7 @@ void amiga_enable_irq(unsigned int irq) } /* enable the interrupt */ - amiga_custom.intena = IF_SETCLR | ami_intena_vals[irq]; + custom.intena = IF_SETCLR | ami_intena_vals[irq]; } void amiga_disable_irq(unsigned int irq) @@ -177,7 +177,7 @@ void amiga_disable_irq(unsigned int irq) } /* disable the interrupt */ - amiga_custom.intena = ami_intena_vals[irq]; + custom.intena = ami_intena_vals[irq]; } inline void amiga_do_irq(int irq, struct pt_regs *fp) @@ -196,7 +196,7 @@ void amiga_do_irq_list(int irq, struct pt_regs *fp) kstat_cpu(0).irqs[irq]++; - amiga_custom.intreq = ami_intena_vals[irq]; + 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 @@ void amiga_do_irq_list(int irq, struct pt_regs *fp) static void ami_int1(int irq, void *dev_id, struct pt_regs *fp) { - unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; + unsigned short ints = custom.intreqr & custom.intenar; /* if serial transmit buffer empty, interrupt */ if (ints & IF_TBE) { - amiga_custom.intreq = IF_TBE; + custom.intreq = IF_TBE; amiga_do_irq(IRQ_AMIGA_TBE, fp); } /* if floppy disk transfer complete, interrupt */ if (ints & IF_DSKBLK) { - amiga_custom.intreq = IF_DSKBLK; + custom.intreq = IF_DSKBLK; amiga_do_irq(IRQ_AMIGA_DSKBLK, fp); } /* if software interrupt set, interrupt */ if (ints & IF_SOFT) { - amiga_custom.intreq = IF_SOFT; + 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 = amiga_custom.intreqr & amiga_custom.intenar; + unsigned short ints = custom.intreqr & custom.intenar; /* if a blitter interrupt */ if (ints & IF_BLIT) { - amiga_custom.intreq = IF_BLIT; + custom.intreq = IF_BLIT; amiga_do_irq(IRQ_AMIGA_BLIT, fp); } /* if a copper interrupt */ if (ints & IF_COPER) { - amiga_custom.intreq = IF_COPER; + custom.intreq = IF_COPER; amiga_do_irq(IRQ_AMIGA_COPPER, fp); } @@ -252,36 +252,36 @@ static void ami_int3(int irq, void *dev_id, struct pt_regs *fp) static void ami_int4(int irq, void *dev_id, struct pt_regs *fp) { - unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; + unsigned short ints = custom.intreqr & custom.intenar; /* if audio 0 interrupt */ if (ints & IF_AUD0) { - amiga_custom.intreq = IF_AUD0; + custom.intreq = IF_AUD0; amiga_do_irq(IRQ_AMIGA_AUD0, fp); } /* if audio 1 interrupt */ if (ints & IF_AUD1) { - amiga_custom.intreq = IF_AUD1; + custom.intreq = IF_AUD1; amiga_do_irq(IRQ_AMIGA_AUD1, fp); } /* if audio 2 interrupt */ if (ints & IF_AUD2) { - amiga_custom.intreq = IF_AUD2; + custom.intreq = IF_AUD2; amiga_do_irq(IRQ_AMIGA_AUD2, fp); } /* if audio 3 interrupt */ if (ints & IF_AUD3) { - amiga_custom.intreq = IF_AUD3; + 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 = amiga_custom.intreqr & amiga_custom.intenar; + unsigned short ints = custom.intreqr & custom.intenar; /* if serial receive buffer full interrupt */ if (ints & IF_RBF) { @@ -291,7 +291,7 @@ static void ami_int5(int irq, void *dev_id, struct pt_regs *fp) /* if a disk sync interrupt */ if (ints & IF_DSKSYN) { - amiga_custom.intreq = IF_DSKSYN; + custom.intreq = IF_DSKSYN; amiga_do_irq(IRQ_AMIGA_DSKSYN, fp); } } diff --git a/trunk/arch/ppc/amiga/cia.c b/trunk/arch/ppc/amiga/cia.c index 4431c58f611a..ad961465b6cb 100644 --- a/trunk/arch/ppc/amiga/cia.c +++ b/trunk/arch/ppc/amiga/cia.c @@ -66,7 +66,7 @@ static unsigned char cia_set_irq_private(struct ciabase *base, else base->icr_data &= ~mask; if (base->icr_data & base->icr_mask) - amiga_custom.intreq = IF_SETCLR | base->int_mask; + custom.intreq = IF_SETCLR | base->int_mask; return old & base->icr_mask; } @@ -114,7 +114,7 @@ static unsigned char cia_able_irq_private(struct ciabase *base, base->icr_mask &= CIA_ICR_ALL; if (base->icr_data & base->icr_mask) - amiga_custom.intreq = IF_SETCLR | base->int_mask; + custom.intreq = IF_SETCLR | base->int_mask; return old; } @@ -145,7 +145,7 @@ static void cia_handler(int irq, void *dev_id, struct pt_regs *fp) irq = base->cia_irq; desc = irq_desc + irq; ints = cia_set_irq_private(base, CIA_ICR_ALL); - amiga_custom.intreq = base->int_mask; + 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 @@ void __init cia_init_IRQ(struct ciabase *base) action->name = base->name; setup_irq(base->handler_irq, &amiga_sys_irqaction[base->handler_irq-IRQ_AMIGA_AUTO]); - amiga_custom.intena = IF_SETCLR | base->int_mask; + custom.intena = IF_SETCLR | base->int_mask; } diff --git a/trunk/arch/ppc/amiga/config.c b/trunk/arch/ppc/amiga/config.c index 60e2da1c92c0..af881d7454dd 100644 --- a/trunk/arch/ppc/amiga/config.c +++ b/trunk/arch/ppc/amiga/config.c @@ -90,6 +90,9 @@ static void a3000_gettod (int *, int *, int *, int *, int *, int *); 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); @@ -278,7 +281,7 @@ static void __init amiga_identify(void) case CS_OCS: case CS_ECS: case CS_AGA: - switch (amiga_custom.deniseid & 0xf) { + switch (custom.deniseid & 0xf) { case 0x0c: AMIGAHW_SET(DENISE_HR); break; @@ -291,7 +294,7 @@ static void __init amiga_identify(void) AMIGAHW_SET(DENISE); break; } - switch ((amiga_custom.vposr>>8) & 0x7f) { + switch ((custom.vposr>>8) & 0x7f) { case 0x00: AMIGAHW_SET(AGNUS_PAL); break; @@ -416,6 +419,9 @@ void __init config_amiga(void) 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; @@ -426,9 +432,9 @@ void __init config_amiga(void) amiga_colorclock = 5*amiga_eclock; /* 3.5 MHz */ /* clear all DMA bits */ - amiga_custom.dmacon = DMAF_ALL; + custom.dmacon = DMAF_ALL; /* ensure that the DMA master bit is set */ - amiga_custom.dmacon = DMAF_SETCLR | DMAF_MASTER; + custom.dmacon = DMAF_SETCLR | DMAF_MASTER; /* request all RAM */ for (i = 0; i < m68k_num_memory; i++) { @@ -747,9 +753,9 @@ static void amiga_savekmsg_init(void) static void amiga_serial_putc(char c) { - amiga_custom.serdat = (unsigned char)c | 0x100; + custom.serdat = (unsigned char)c | 0x100; mb(); - while (!(amiga_custom.serdatr & 0x2000)) + while (!(custom.serdatr & 0x2000)) ; } @@ -779,11 +785,11 @@ int amiga_serial_console_wait_key(struct console *co) { int ch; - while (!(amiga_custom.intreqr & IF_RBF)) + while (!(custom.intreqr & IF_RBF)) barrier(); - ch = amiga_custom.serdatr & 0xff; + ch = custom.serdatr & 0xff; /* clear the interrupt, so that another character can be read */ - amiga_custom.intreq = IF_RBF; + custom.intreq = IF_RBF; return ch; } diff --git a/trunk/arch/ppc/kernel/Makefile b/trunk/arch/ppc/kernel/Makefile index ca0201300868..e6c1d615bb86 100644 --- a/trunk/arch/ppc/kernel/Makefile +++ b/trunk/arch/ppc/kernel/Makefile @@ -13,6 +13,7 @@ extra-$(CONFIG_POWER4) += idle_power4.o 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/trunk/arch/ppc/kernel/process.c b/trunk/arch/ppc/kernel/process.c new file mode 100644 index 000000000000..25cbdc8d2941 --- /dev/null +++ b/trunk/arch/ppc/kernel/process.c @@ -0,0 +1,851 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +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, ¤t->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, ¤t->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 = ¤t->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, ®s->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(¤t->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/trunk/arch/ppc/kernel/smp.c b/trunk/arch/ppc/kernel/smp.c index e55cdda6149a..becbfa397556 100644 --- a/trunk/arch/ppc/kernel/smp.c +++ b/trunk/arch/ppc/kernel/smp.c @@ -318,7 +318,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) p = fork_idle(cpu); if (IS_ERR(p)) panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p)); - task_thread_info(p)->cpu = cpu; + p->thread_info->cpu = cpu; idle_tasks[cpu] = p; } } @@ -369,7 +369,7 @@ int __cpu_up(unsigned int cpu) char buf[32]; int c; - secondary_ti = task_thread_info(idle_tasks[cpu]); + secondary_ti = idle_tasks[cpu]->thread_info; mb(); /* diff --git a/trunk/arch/ppc/platforms/apus_setup.c b/trunk/arch/ppc/platforms/apus_setup.c index c42c50073da5..2f74fde98ebc 100644 --- a/trunk/arch/ppc/platforms/apus_setup.c +++ b/trunk/arch/ppc/platforms/apus_setup.c @@ -55,6 +55,9 @@ int (*mach_hwclk) (int, struct hwclk_time*) = NULL; 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); @@ -73,6 +76,7 @@ struct mem_info m68k_memory[NUM_MEMINFO];/* memory description */ struct mem_info ramdisk; +extern void amiga_floppy_setup(char *, int *); extern void config_amiga(void); static int __60nsram = 0; @@ -301,6 +305,16 @@ void kbd_reset_setup(char *str, int *ints) { } +/*********************************************************** 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]; @@ -560,9 +574,9 @@ static __inline__ void ser_RTSon(void) int __debug_ser_out( unsigned char c ) { - amiga_custom.serdat = c | 0x100; + custom.serdat = c | 0x100; mb(); - while (!(amiga_custom.serdatr & 0x2000)) + while (!(custom.serdatr & 0x2000)) barrier(); return 1; } @@ -572,11 +586,11 @@ unsigned char __debug_ser_in( void ) unsigned char c; /* XXX: is that ok?? derived from amiga_ser.c... */ - while( !(amiga_custom.intreqr & IF_RBF) ) + while( !(custom.intreqr & IF_RBF) ) barrier(); - c = amiga_custom.serdatr; + c = custom.serdatr; /* clear the interrupt, so that another character can be read */ - amiga_custom.intreq = IF_RBF; + custom.intreq = IF_RBF; return c; } @@ -587,10 +601,10 @@ int __debug_serinit( void ) local_irq_save(flags); /* turn off Rx and Tx interrupts */ - amiga_custom.intena = IF_RBF | IF_TBE; + custom.intena = IF_RBF | IF_TBE; /* clear any pending interrupt */ - amiga_custom.intreq = IF_RBF | IF_TBE; + custom.intreq = IF_RBF | IF_TBE; local_irq_restore(flags); @@ -603,7 +617,7 @@ int __debug_serinit( void ) #ifdef CONFIG_KGDB /* turn Rx interrupts on for GDB */ - amiga_custom.intena = IF_SETCLR | IF_RBF; + custom.intena = IF_SETCLR | IF_RBF; ser_RTSon(); #endif diff --git a/trunk/arch/ppc/xmon/xmon.c b/trunk/arch/ppc/xmon/xmon.c index 9075a7538e26..2b483b4f1602 100644 --- a/trunk/arch/ppc/xmon/xmon.c +++ b/trunk/arch/ppc/xmon/xmon.c @@ -99,7 +99,7 @@ static void remove_bpts(void); static void insert_bpts(void); static struct bpt *at_breakpoint(unsigned pc); static void bpt_cmds(void); -void cacheflush(void); +static void cacheflush(void); #ifdef CONFIG_SMP static void cpu_cmd(void); #endif /* CONFIG_SMP */ diff --git a/trunk/arch/s390/kernel/binfmt_elf32.c b/trunk/arch/s390/kernel/binfmt_elf32.c index 1f451c2cb071..03ba5893f17b 100644 --- a/trunk/arch/s390/kernel/binfmt_elf32.c +++ b/trunk/arch/s390/kernel/binfmt_elf32.c @@ -112,7 +112,7 @@ static inline int dump_regs32(struct pt_regs *ptregs, elf_gregset_t *regs) static inline int dump_task_regs32(struct task_struct *tsk, elf_gregset_t *regs) { - struct pt_regs *ptregs = task_pt_regs(tsk); + struct pt_regs *ptregs = __KSTK_PTREGS(tsk); int i; memcpy(®s->psw.mask, &ptregs->psw.mask, 4); diff --git a/trunk/arch/s390/kernel/process.c b/trunk/arch/s390/kernel/process.c index 2ff90a1a1056..7dd58f8ac6b5 100644 --- a/trunk/arch/s390/kernel/process.c +++ b/trunk/arch/s390/kernel/process.c @@ -153,7 +153,7 @@ void show_regs(struct pt_regs *regs) { struct task_struct *tsk = current; - printk("CPU: %d %s\n", task_thread_info(tsk)->cpu, print_tainted()); + printk("CPU: %d %s\n", tsk->thread_info->cpu, print_tainted()); printk("Process %s (pid: %d, task: %p, ksp: %p)\n", current->comm, current->pid, (void *) tsk, (void *) tsk->thread.ksp); @@ -217,7 +217,8 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp, struct pt_regs childregs; } *frame; - frame = container_of(task_pt_regs(p), struct fake_frame, childregs); + frame = ((struct fake_frame *) + (THREAD_SIZE + (unsigned long) p->thread_info)) - 1; p->thread.ksp = (unsigned long) frame; /* Store access registers to kernel stack of new process. */ frame->childregs = *regs; @@ -357,10 +358,11 @@ unsigned long get_wchan(struct task_struct *p) unsigned long return_address; int count; - if (!p || p == current || p->state == TASK_RUNNING || !task_stack_page(p)) + if (!p || p == current || p->state == TASK_RUNNING || !p->thread_info) return 0; - low = task_stack_page(p); - high = (struct stack_frame *) task_pt_regs(p); + low = (struct stack_frame *) p->thread_info; + high = (struct stack_frame *) + ((unsigned long) p->thread_info + THREAD_SIZE) - 1; sf = (struct stack_frame *) (p->thread.ksp & PSW_ADDR_INSN); if (sf <= low || sf > high) return 0; diff --git a/trunk/arch/s390/kernel/ptrace.c b/trunk/arch/s390/kernel/ptrace.c index 37dfe33dab73..cc02232aa96e 100644 --- a/trunk/arch/s390/kernel/ptrace.c +++ b/trunk/arch/s390/kernel/ptrace.c @@ -52,7 +52,7 @@ FixPerRegisters(struct task_struct *task) struct pt_regs *regs; per_struct *per_info; - regs = task_pt_regs(task); + regs = __KSTK_PTREGS(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 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data) /* * psw and gprs are stored on the stack */ - tmp = *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr); + tmp = *(addr_t *)((addr_t) &__KSTK_PTREGS(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 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data) /* * orig_gpr2 is stored on the kernel stack */ - tmp = (addr_t) task_pt_regs(child)->orig_gpr2; + tmp = (addr_t) __KSTK_PTREGS(child)->orig_gpr2; } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) { /* @@ -243,7 +243,7 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data) high order bit but older gdb's rely on it */ data |= PSW_ADDR_AMODE; #endif - *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data; + *(addr_t *)((addr_t) &__KSTK_PTREGS(child)->psw + addr) = data; } else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) { /* @@ -267,7 +267,7 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data) /* * orig_gpr2 is stored on the kernel stack */ - task_pt_regs(child)->orig_gpr2 = data; + __KSTK_PTREGS(child)->orig_gpr2 = data; } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) { /* @@ -393,15 +393,15 @@ peek_user_emu31(struct task_struct *child, addr_t addr, addr_t data) */ if (addr == (addr_t) &dummy32->regs.psw.mask) { /* Fake a 31 bit psw mask. */ - tmp = (__u32)(task_pt_regs(child)->psw.mask >> 32); + tmp = (__u32)(__KSTK_PTREGS(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) task_pt_regs(child)->psw.addr | + tmp = (__u32) __KSTK_PTREGS(child)->psw.addr | PSW32_ADDR_AMODE31; } else { /* gpr 0-15 */ - tmp = *(__u32 *)((addr_t) &task_pt_regs(child)->psw + + tmp = *(__u32 *)((addr_t) &__KSTK_PTREGS(child)->psw + addr*2 + 4); } } else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) { @@ -415,7 +415,7 @@ peek_user_emu31(struct task_struct *child, addr_t addr, addr_t data) /* * orig_gpr2 is stored on the kernel stack */ - tmp = *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4); + tmp = *(__u32*)((addr_t) &__KSTK_PTREGS(child)->orig_gpr2 + 4); } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) { /* @@ -472,15 +472,15 @@ poke_user_emu31(struct task_struct *child, addr_t addr, addr_t data) if (tmp != PSW32_MASK_MERGE(PSW32_USER_BITS, tmp)) /* Invalid psw mask. */ return -EINVAL; - task_pt_regs(child)->psw.mask = + __KSTK_PTREGS(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. */ - task_pt_regs(child)->psw.addr = + __KSTK_PTREGS(child)->psw.addr = (__u64) tmp & PSW32_ADDR_INSN; } else { /* gpr 0-15 */ - *(__u32*)((addr_t) &task_pt_regs(child)->psw + *(__u32*)((addr_t) &__KSTK_PTREGS(child)->psw + addr*2 + 4) = tmp; } } else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) { @@ -494,7 +494,7 @@ poke_user_emu31(struct task_struct *child, addr_t addr, addr_t data) /* * orig_gpr2 is stored on the kernel stack */ - *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4) = tmp; + *(__u32*)((addr_t) &__KSTK_PTREGS(child)->orig_gpr2 + 4) = tmp; } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) { /* diff --git a/trunk/arch/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c index cbfcfd02a43a..e10f4ca00499 100644 --- a/trunk/arch/s390/kernel/smp.c +++ b/trunk/arch/s390/kernel/smp.c @@ -657,7 +657,7 @@ __cpu_up(unsigned int cpu) idle = current_set[cpu]; cpu_lowcore = lowcore_ptr[cpu]; cpu_lowcore->kernel_stack = (unsigned long) - task_stack_page(idle) + (THREAD_SIZE); + idle->thread_info + (THREAD_SIZE); sf = (struct stack_frame *) (cpu_lowcore->kernel_stack - sizeof(struct pt_regs) - sizeof(struct stack_frame)); diff --git a/trunk/arch/s390/kernel/time.c b/trunk/arch/s390/kernel/time.c index b0d8ca8e5eeb..c36353e8c140 100644 --- a/trunk/arch/s390/kernel/time.c +++ b/trunk/arch/s390/kernel/time.c @@ -282,7 +282,7 @@ static inline void start_hz_timer(void) { if (!cpu_isset(smp_processor_id(), nohz_cpu_mask)) return; - account_ticks(task_pt_regs(current)); + account_ticks(__KSTK_PTREGS(current)); cpu_clear(smp_processor_id(), nohz_cpu_mask); } diff --git a/trunk/arch/s390/kernel/traps.c b/trunk/arch/s390/kernel/traps.c index 5d21e9e6e7b4..95d109968619 100644 --- a/trunk/arch/s390/kernel/traps.c +++ b/trunk/arch/s390/kernel/traps.c @@ -136,8 +136,8 @@ void show_trace(struct task_struct *task, unsigned long * stack) sp = __show_trace(sp, S390_lowcore.async_stack - ASYNC_SIZE, S390_lowcore.async_stack); if (task) - __show_trace(sp, (unsigned long) task_stack_page(task), - (unsigned long) task_stack_page(task) + THREAD_SIZE); + __show_trace(sp, (unsigned long) task->thread_info, + (unsigned long) task->thread_info + THREAD_SIZE); else __show_trace(sp, S390_lowcore.thread_info, S390_lowcore.thread_info + THREAD_SIZE); @@ -240,7 +240,7 @@ char *task_show_regs(struct task_struct *task, char *buffer) { struct pt_regs *regs; - regs = task_pt_regs(task); + regs = __KSTK_PTREGS(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/trunk/arch/sh/kernel/process.c b/trunk/arch/sh/kernel/process.c index aac15e42d03b..8a2bea34ddd2 100644 --- a/trunk/arch/sh/kernel/process.c +++ b/trunk/arch/sh/kernel/process.c @@ -191,8 +191,13 @@ void flush_thread(void) { #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, task_pt_regs(tsk)); + clear_fpu(tsk, regs); clear_used_math(); #endif } @@ -227,7 +232,13 @@ int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) { struct pt_regs ptregs; - ptregs = *task_pt_regs(tsk); + 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)); elf_core_copy_regs(regs, &ptregs); return 1; @@ -241,7 +252,11 @@ dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *fpu) #if defined(CONFIG_SH_FPU) fpvalid = !!tsk_used_math(tsk); if (fpvalid) { - unlazy_fpu(tsk, task_pt_regs(tsk)); + 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); memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu)); } #endif @@ -264,13 +279,18 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, copy_to_stopped_child_used_math(p); #endif - childregs = task_pt_regs(p); + 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 = *regs; if (user_mode(regs)) { childregs->regs[15] = usp; } else { - childregs->regs[15] = (unsigned long)task_stack_page(p) + THREAD_SIZE; + childregs->regs[15] = (unsigned long)p->thread_info + THREAD_SIZE; } if (clone_flags & CLONE_SETTLS) { childregs->gbr = childregs->regs[0]; @@ -313,7 +333,11 @@ ubc_set_tracing(int asid, unsigned long pc) struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *next) { #if defined(CONFIG_SH_FPU) - unlazy_fpu(prev, task_pt_regs(prev)); + 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); #endif #ifdef CONFIG_PREEMPT @@ -322,7 +346,13 @@ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *ne struct pt_regs *regs; local_irq_save(flags); - regs = task_pt_regs(prev); + 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)); if (user_mode(regs) && regs->regs[15] >= 0xc0000000) { int offset = (int)regs->regs[15]; @@ -342,7 +372,7 @@ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *ne */ asm volatile("ldc %0, r7_bank" : /* no output */ - : "r" (task_thread_info(next))); + : "r" (next->thread_info)); #ifdef CONFIG_MMU /* If no tasks are using the UBC, we're done */ diff --git a/trunk/arch/sh/kernel/ptrace.c b/trunk/arch/sh/kernel/ptrace.c index 3887b4f6feb2..1a8be06519ec 100644 --- a/trunk/arch/sh/kernel/ptrace.c +++ b/trunk/arch/sh/kernel/ptrace.c @@ -41,7 +41,12 @@ static inline int get_stack_long(struct task_struct *task, int offset) { unsigned char *stack; - stack = (unsigned char *)task_pt_regs(task); + 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 += offset; return (*((int *)stack)); } @@ -54,7 +59,12 @@ static inline int put_stack_long(struct task_struct *task, int offset, { unsigned char *stack; - stack = (unsigned char *)task_pt_regs(task); + 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 += offset; *(unsigned long *) stack = data; return 0; diff --git a/trunk/arch/sh/kernel/smp.c b/trunk/arch/sh/kernel/smp.c index 62c7d1c0ad7b..59e49b18252c 100644 --- a/trunk/arch/sh/kernel/smp.c +++ b/trunk/arch/sh/kernel/smp.c @@ -103,7 +103,7 @@ int __cpu_up(unsigned int cpu) if (IS_ERR(tsk)) panic("Failed forking idle task for cpu %d\n", cpu); - task_thread_info(tsk)->cpu = cpu; + tsk->thread_info->cpu = cpu; cpu_set(cpu, cpu_online_map); diff --git a/trunk/arch/sh64/kernel/process.c b/trunk/arch/sh64/kernel/process.c index 1da9c61d6823..419b5a710441 100644 --- a/trunk/arch/sh64/kernel/process.c +++ b/trunk/arch/sh64/kernel/process.c @@ -744,7 +744,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, } #endif /* Copy from sh version */ - childregs = (struct pt_regs *)(THREAD_SIZE + task_stack_page(p)) - 1; + childregs = ((struct pt_regs *)(THREAD_SIZE + (unsigned long) p->thread_info )) - 1; *childregs = *regs; @@ -752,7 +752,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, childregs->regs[15] = usp; p->thread.uregs = childregs; } else { - childregs->regs[15] = (unsigned long)task_stack_page(p) + THREAD_SIZE; + childregs->regs[15] = (unsigned long)p->thread_info + THREAD_SIZE; } childregs->regs[9] = 0; /* Set return value for child */ diff --git a/trunk/arch/sh64/lib/dbg.c b/trunk/arch/sh64/lib/dbg.c index 58087331b8a6..526fedae6db8 100644 --- a/trunk/arch/sh64/lib/dbg.c +++ b/trunk/arch/sh64/lib/dbg.c @@ -174,7 +174,7 @@ void evt_debug(int evt, int ret_addr, int event, int tra, struct pt_regs *regs) struct ring_node *rr; pid = current->pid; - stack_bottom = (unsigned long) task_stack_page(current); + stack_bottom = (unsigned long) current->thread_info; asm volatile("ori r15, 0, %0" : "=r" (sp)); rr = event_ring + event_ptr; rr->evt = evt; diff --git a/trunk/arch/sparc/kernel/process.c b/trunk/arch/sparc/kernel/process.c index fbb05a452e51..ea8647411462 100644 --- a/trunk/arch/sparc/kernel/process.c +++ b/trunk/arch/sparc/kernel/process.c @@ -302,7 +302,7 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp) int count = 0; if (tsk != NULL) - task_base = (unsigned long) task_stack_page(tsk); + task_base = (unsigned long) tsk->thread_info; else task_base = (unsigned long) current_thread_info(); @@ -337,7 +337,7 @@ EXPORT_SYMBOL(dump_stack); */ unsigned long thread_saved_pc(struct task_struct *tsk) { - return task_thread_info(tsk)->kpc; + return tsk->thread_info->kpc; } /* @@ -392,7 +392,7 @@ void flush_thread(void) /* We must fixup kregs as well. */ /* XXX This was not fixed for ti for a while, worked. Unused? */ current->thread.kregs = (struct pt_regs *) - (task_stack_page(current) + (THREAD_SIZE - TRACEREG_SZ)); + ((char *)current->thread_info + (THREAD_SIZE - TRACEREG_SZ)); } } @@ -459,7 +459,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, unsigned long unused, struct task_struct *p, struct pt_regs *regs) { - struct thread_info *ti = task_thread_info(p); + struct thread_info *ti = p->thread_info; struct pt_regs *childregs; char *new_stack; @@ -482,7 +482,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, * V V (stk.fr.) V (pt_regs) { (stk.fr.) } * +----- - - - - - ------+===========+============={+==========}+ */ - new_stack = task_stack_page(p) + THREAD_SIZE; + new_stack = (char*)ti + THREAD_SIZE; if (regs->psr & PSR_PS) new_stack -= STACKFRAME_SZ; new_stack -= STACKFRAME_SZ + TRACEREG_SZ; @@ -724,7 +724,7 @@ unsigned long get_wchan(struct task_struct *task) task->state == TASK_RUNNING) goto out; - fp = task_thread_info(task)->ksp + bias; + fp = task->thread_info->ksp + bias; do { /* Bogus frame pointer? */ if (fp < (task_base + sizeof(struct thread_info)) || diff --git a/trunk/arch/sparc/kernel/ptrace.c b/trunk/arch/sparc/kernel/ptrace.c index 1baf13ed5c3a..fc470c0e9dc6 100644 --- a/trunk/arch/sparc/kernel/ptrace.c +++ b/trunk/arch/sparc/kernel/ptrace.c @@ -75,7 +75,7 @@ static inline void read_sunos_user(struct pt_regs *regs, unsigned long offset, struct task_struct *tsk, long __user *addr) { struct pt_regs *cregs = tsk->thread.kregs; - struct thread_info *t = task_thread_info(tsk); + struct thread_info *t = tsk->thread_info; int v; if(offset >= 1024) @@ -170,7 +170,7 @@ static inline void write_sunos_user(struct pt_regs *regs, unsigned long offset, struct task_struct *tsk) { struct pt_regs *cregs = tsk->thread.kregs; - struct thread_info *t = task_thread_info(tsk); + struct thread_info *t = tsk->thread_info; unsigned long value = regs->u_regs[UREG_I3]; if(offset >= 1024) diff --git a/trunk/arch/sparc/kernel/sun4d_smp.c b/trunk/arch/sparc/kernel/sun4d_smp.c index 40d426cce824..cc1fc898495c 100644 --- a/trunk/arch/sparc/kernel/sun4d_smp.c +++ b/trunk/arch/sparc/kernel/sun4d_smp.c @@ -200,7 +200,7 @@ void __init smp4d_boot_cpus(void) /* Cook up an idler for this guy. */ p = fork_idle(i); cpucount++; - current_set[i] = task_thread_info(p); + current_set[i] = p->thread_info; for (no = 0; !cpu_find_by_instance(no, NULL, &mid) && mid != i; no++) ; diff --git a/trunk/arch/sparc/kernel/sun4m_smp.c b/trunk/arch/sparc/kernel/sun4m_smp.c index a21f27d10e55..f113422a3727 100644 --- a/trunk/arch/sparc/kernel/sun4m_smp.c +++ b/trunk/arch/sparc/kernel/sun4m_smp.c @@ -173,7 +173,7 @@ void __init smp4m_boot_cpus(void) /* Cook up an idler for this guy. */ p = fork_idle(i); cpucount++; - current_set[i] = task_thread_info(p); + current_set[i] = p->thread_info; /* See trampoline.S for details... */ entry += ((i-1) * 3); diff --git a/trunk/arch/sparc/kernel/traps.c b/trunk/arch/sparc/kernel/traps.c index 41d45c298fb2..3f451ae66482 100644 --- a/trunk/arch/sparc/kernel/traps.c +++ b/trunk/arch/sparc/kernel/traps.c @@ -291,7 +291,7 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, #ifndef CONFIG_SMP if(!fpt) { #else - if(!(task_thread_info(fpt)->flags & _TIF_USEDFPU)) { + if(!(fpt->thread_info->flags & _TIF_USEDFPU)) { #endif fpsave(&fake_regs[0], &fake_fsr, &fake_queue[0], &fake_depth); regs->psr &= ~PSR_EF; @@ -334,7 +334,7 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, /* nope, better SIGFPE the offending process... */ #ifdef CONFIG_SMP - task_thread_info(fpt)->flags &= ~_TIF_USEDFPU; + fpt->thread_info->flags &= ~_TIF_USEDFPU; #endif if(psr & PSR_PS) { /* The first fsr store/load we tried trapped, diff --git a/trunk/arch/sparc64/kernel/process.c b/trunk/arch/sparc64/kernel/process.c index 1dc3650c5cae..02f9dec1d459 100644 --- a/trunk/arch/sparc64/kernel/process.c +++ b/trunk/arch/sparc64/kernel/process.c @@ -390,7 +390,7 @@ void show_regs32(struct pt_regs32 *regs) unsigned long thread_saved_pc(struct task_struct *tsk) { - struct thread_info *ti = task_thread_info(tsk); + struct thread_info *ti = tsk->thread_info; unsigned long ret = 0xdeadbeefUL; if (ti && ti->ksp) { @@ -616,11 +616,11 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, unsigned long unused, struct task_struct *p, struct pt_regs *regs) { - struct thread_info *t = task_thread_info(p); + struct thread_info *t = p->thread_info; char *child_trap_frame; /* Calculate offset to stack_frame & pt_regs */ - child_trap_frame = task_stack_page(p) + (THREAD_SIZE - (TRACEREG_SZ+STACKFRAME_SZ)); + child_trap_frame = ((char *)t) + (THREAD_SIZE - (TRACEREG_SZ+STACKFRAME_SZ)); memcpy(child_trap_frame, (((struct sparc_stackf *)regs)-1), (TRACEREG_SZ+STACKFRAME_SZ)); t->flags = (t->flags & ~((0xffUL << TI_FLAG_CWP_SHIFT) | (0xffUL << TI_FLAG_CURRENT_DS_SHIFT))) | @@ -845,9 +845,9 @@ unsigned long get_wchan(struct task_struct *task) task->state == TASK_RUNNING) goto out; - thread_info_base = (unsigned long) task_stack_page(task); + thread_info_base = (unsigned long) task->thread_info; bias = STACK_BIAS; - fp = task_thread_info(task)->ksp + bias; + fp = task->thread_info->ksp + bias; do { /* Bogus frame pointer? */ diff --git a/trunk/arch/sparc64/kernel/ptrace.c b/trunk/arch/sparc64/kernel/ptrace.c index 3f9746f856d2..84d3df2264cb 100644 --- a/trunk/arch/sparc64/kernel/ptrace.c +++ b/trunk/arch/sparc64/kernel/ptrace.c @@ -296,7 +296,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) case PTRACE_GETREGS: { struct pt_regs32 __user *pregs = (struct pt_regs32 __user *) addr; - struct pt_regs *cregs = task_pt_regs(child); + struct pt_regs *cregs = child->thread_info->kregs; int rval; if (__put_user(tstate_to_psr(cregs->tstate), (&pregs->psr)) || @@ -320,11 +320,11 @@ asmlinkage void do_ptrace(struct pt_regs *regs) case PTRACE_GETREGS64: { struct pt_regs __user *pregs = (struct pt_regs __user *) addr; - struct pt_regs *cregs = task_pt_regs(child); + struct pt_regs *cregs = child->thread_info->kregs; unsigned long tpc = cregs->tpc; int rval; - if ((task_thread_info(child)->flags & _TIF_32BIT) != 0) + if ((child->thread_info->flags & _TIF_32BIT) != 0) tpc &= 0xffffffff; if (__put_user(cregs->tstate, (&pregs->tstate)) || __put_user(tpc, (&pregs->tpc)) || @@ -348,7 +348,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) case PTRACE_SETREGS: { struct pt_regs32 __user *pregs = (struct pt_regs32 __user *) addr; - struct pt_regs *cregs = task_pt_regs(child); + struct pt_regs *cregs = child->thread_info->kregs; unsigned int psr, pc, npc, y; int i; @@ -381,7 +381,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) case PTRACE_SETREGS64: { struct pt_regs __user *pregs = (struct pt_regs __user *) addr; - struct pt_regs *cregs = task_pt_regs(child); + struct pt_regs *cregs = child->thread_info->kregs; unsigned long tstate, tpc, tnpc, y; int i; @@ -395,7 +395,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) pt_error_return(regs, EFAULT); goto out_tsk; } - if ((task_thread_info(child)->flags & _TIF_32BIT) != 0) { + if ((child->thread_info->flags & _TIF_32BIT) != 0) { tpc &= 0xffffffff; tnpc &= 0xffffffff; } @@ -430,11 +430,11 @@ asmlinkage void do_ptrace(struct pt_regs *regs) } fpq[16]; }; struct fps __user *fps = (struct fps __user *) addr; - unsigned long *fpregs = task_thread_info(child)->fpregs; + unsigned long *fpregs = child->thread_info->fpregs; if (copy_to_user(&fps->regs[0], fpregs, (32 * sizeof(unsigned int))) || - __put_user(task_thread_info(child)->xfsr[0], (&fps->fsr)) || + __put_user(child->thread_info->xfsr[0], (&fps->fsr)) || __put_user(0, (&fps->fpqd)) || __put_user(0, (&fps->flags)) || __put_user(0, (&fps->extra)) || @@ -452,11 +452,11 @@ asmlinkage void do_ptrace(struct pt_regs *regs) unsigned long fsr; }; struct fps __user *fps = (struct fps __user *) addr; - unsigned long *fpregs = task_thread_info(child)->fpregs; + unsigned long *fpregs = child->thread_info->fpregs; if (copy_to_user(&fps->regs[0], fpregs, (64 * sizeof(unsigned int))) || - __put_user(task_thread_info(child)->xfsr[0], (&fps->fsr))) { + __put_user(child->thread_info->xfsr[0], (&fps->fsr))) { pt_error_return(regs, EFAULT); goto out_tsk; } @@ -477,7 +477,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) } fpq[16]; }; struct fps __user *fps = (struct fps __user *) addr; - unsigned long *fpregs = task_thread_info(child)->fpregs; + unsigned long *fpregs = child->thread_info->fpregs; unsigned fsr; if (copy_from_user(fpregs, &fps->regs[0], @@ -486,11 +486,11 @@ asmlinkage void do_ptrace(struct pt_regs *regs) pt_error_return(regs, EFAULT); goto out_tsk; } - 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); + 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); pt_succ_return(regs, 0); goto out_tsk; } @@ -501,17 +501,17 @@ asmlinkage void do_ptrace(struct pt_regs *regs) unsigned long fsr; }; struct fps __user *fps = (struct fps __user *) addr; - unsigned long *fpregs = task_thread_info(child)->fpregs; + unsigned long *fpregs = child->thread_info->fpregs; if (copy_from_user(fpregs, &fps->regs[0], (64 * sizeof(unsigned int))) || - __get_user(task_thread_info(child)->xfsr[0], (&fps->fsr))) { + __get_user(child->thread_info->xfsr[0], (&fps->fsr))) { pt_error_return(regs, EFAULT); goto out_tsk; } - 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); + 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); pt_succ_return(regs, 0); goto out_tsk; } @@ -562,8 +562,8 @@ asmlinkage void do_ptrace(struct pt_regs *regs) #ifdef DEBUG_PTRACE printk("CONT: %s [%d]: set exit_code = %x %lx %lx\n", child->comm, child->pid, child->exit_code, - task_pt_regs(child)->tpc, - task_pt_regs(child)->tnpc); + child->thread_info->kregs->tpc, + child->thread_info->kregs->tnpc); #endif wake_up_process(child); diff --git a/trunk/arch/sparc64/kernel/setup.c b/trunk/arch/sparc64/kernel/setup.c index 250745896aee..48180531562f 100644 --- a/trunk/arch/sparc64/kernel/setup.c +++ b/trunk/arch/sparc64/kernel/setup.c @@ -520,7 +520,7 @@ void __init setup_arch(char **cmdline_p) rd_doload = ((ram_flags & RAMDISK_LOAD_FLAG) != 0); #endif - task_thread_info(&init_task)->kregs = &fake_swapper_regs; + init_task.thread_info->kregs = &fake_swapper_regs; #ifdef CONFIG_IP_PNP if (!ic_set_manually) { diff --git a/trunk/arch/sparc64/kernel/smp.c b/trunk/arch/sparc64/kernel/smp.c index 1fb6323e65a4..6efc03df51c3 100644 --- a/trunk/arch/sparc64/kernel/smp.c +++ b/trunk/arch/sparc64/kernel/smp.c @@ -335,7 +335,7 @@ static int __devinit smp_boot_one_cpu(unsigned int cpu) p = fork_idle(cpu); callin_flag = 0; - cpu_new_thread = task_thread_info(p); + cpu_new_thread = p->thread_info; cpu_set(cpu, cpu_callout_map); cpu_find_by_mid(cpu, &cpu_node); diff --git a/trunk/arch/sparc64/kernel/traps.c b/trunk/arch/sparc64/kernel/traps.c index 8d44ae5a15e3..5570e7bb22bb 100644 --- a/trunk/arch/sparc64/kernel/traps.c +++ b/trunk/arch/sparc64/kernel/traps.c @@ -1808,7 +1808,7 @@ static void user_instruction_dump (unsigned int __user *pc) void show_stack(struct task_struct *tsk, unsigned long *_ksp) { unsigned long pc, fp, thread_base, ksp; - void *tp = task_stack_page(tsk); + struct thread_info *tp = tsk->thread_info; struct reg_window *rw; int count = 0; @@ -1862,7 +1862,7 @@ static inline int is_kernel_stack(struct task_struct *task, return 0; } - thread_base = (unsigned long) task_stack_page(task); + thread_base = (unsigned long) task->thread_info; thread_end = thread_base + sizeof(union thread_union); if (rw_addr >= thread_base && rw_addr < thread_end && diff --git a/trunk/arch/um/kernel/process_kern.c b/trunk/arch/um/kernel/process_kern.c index 7f13b85d2656..d2d3f256778c 100644 --- a/trunk/arch/um/kernel/process_kern.c +++ b/trunk/arch/um/kernel/process_kern.c @@ -107,7 +107,7 @@ void set_current(void *t) { struct task_struct *task = t; - cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task) + cpu_tasks[task->thread_info->cpu] = ((struct cpu_task) { external_pid(task), task }); } diff --git a/trunk/arch/um/kernel/skas/process_kern.c b/trunk/arch/um/kernel/skas/process_kern.c index dc41c6dc2f34..09790ccb161c 100644 --- a/trunk/arch/um/kernel/skas/process_kern.c +++ b/trunk/arch/um/kernel/skas/process_kern.c @@ -118,7 +118,7 @@ int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp, handler = new_thread_handler; } - new_thread(task_stack_page(p), &p->thread.mode.skas.switch_buf, + new_thread(p->thread_info, &p->thread.mode.skas.switch_buf, &p->thread.mode.skas.fork_buf, handler); return(0); } @@ -185,7 +185,7 @@ int start_uml_skas(void) init_task.thread.request.u.thread.proc = start_kernel_proc; init_task.thread.request.u.thread.arg = NULL; - return(start_idle_thread(task_stack_page(&init_task), + return(start_idle_thread(init_task.thread_info, &init_task.thread.mode.skas.switch_buf, &init_task.thread.mode.skas.fork_buf)); } diff --git a/trunk/arch/um/kernel/tt/exec_kern.c b/trunk/arch/um/kernel/tt/exec_kern.c index 8f40e4838736..136e54c47d37 100644 --- a/trunk/arch/um/kernel/tt/exec_kern.c +++ b/trunk/arch/um/kernel/tt/exec_kern.c @@ -39,7 +39,7 @@ void flush_thread_tt(void) do_exit(SIGKILL); } - new_pid = start_fork_tramp(task_stack_page(current), stack, 0, exec_tramp); + new_pid = start_fork_tramp(current->thread_info, stack, 0, exec_tramp); if(new_pid < 0){ printk(KERN_ERR "flush_thread : new thread failed, errno = %d\n", diff --git a/trunk/arch/um/kernel/tt/process_kern.c b/trunk/arch/um/kernel/tt/process_kern.c index 62535303aa27..14d4622a5fb8 100644 --- a/trunk/arch/um/kernel/tt/process_kern.c +++ b/trunk/arch/um/kernel/tt/process_kern.c @@ -36,7 +36,7 @@ void switch_to_tt(void *prev, void *next) from = prev; to = next; - cpu = task_thread_info(from)->cpu; + cpu = from->thread_info->cpu; if(cpu == 0) forward_interrupts(to->thread.mode.tt.extern_pid); #ifdef CONFIG_SMP @@ -253,7 +253,7 @@ int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp, clone_flags &= CLONE_VM; p->thread.temp_stack = stack; - new_pid = start_fork_tramp(task_stack_page(p), stack, clone_flags, tramp); + new_pid = start_fork_tramp(p->thread_info, stack, clone_flags, tramp); if(new_pid < 0){ printk(KERN_ERR "copy_thread : clone failed - errno = %d\n", -new_pid); @@ -343,7 +343,7 @@ int do_proc_op(void *t, int proc_id) 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(task)->cpu].pid = pid; + cpu_tasks[task->thread_info->cpu].pid = pid; break; case OP_FORK: attach_process(thread->request.u.fork.pid); @@ -425,7 +425,7 @@ int start_uml_tt(void) int pages; pages = (1 << CONFIG_KERNEL_STACK_ORDER); - sp = task_stack_page(&init_task) + + sp = (void *) ((unsigned long) init_task.thread_info) + pages * PAGE_SIZE - sizeof(unsigned long); return(tracer(start_kernel_proc, sp)); } diff --git a/trunk/arch/v850/kernel/process.c b/trunk/arch/v850/kernel/process.c index eb909937958b..062ffa0a9998 100644 --- a/trunk/arch/v850/kernel/process.c +++ b/trunk/arch/v850/kernel/process.c @@ -114,7 +114,7 @@ int copy_thread (int nr, unsigned long clone_flags, struct task_struct *p, struct pt_regs *regs) { /* Start pushing stuff from the top of the child's kernel stack. */ - unsigned long orig_ksp = task_tos(p); + unsigned long orig_ksp = (unsigned long)p->thread_info + THREAD_SIZE; unsigned long ksp = orig_ksp; /* We push two `state save' stack fames (see entry.S) on the new kernel stack: diff --git a/trunk/arch/v850/kernel/ptrace.c b/trunk/arch/v850/kernel/ptrace.c index 67e057509664..18492d02aaf6 100644 --- a/trunk/arch/v850/kernel/ptrace.c +++ b/trunk/arch/v850/kernel/ptrace.c @@ -58,7 +58,7 @@ static v850_reg_t *reg_save_addr (unsigned reg_offs, struct task_struct *t) regs = thread_saved_regs (t); else /* Register saved during kernel entry (or not available). */ - regs = task_pt_regs (t); + regs = task_regs (t); return (v850_reg_t *)((char *)regs + reg_offs); } diff --git a/trunk/arch/x86_64/ia32/ia32_binfmt.c b/trunk/arch/x86_64/ia32/ia32_binfmt.c index 029bddab0459..2b760d0d9ce2 100644 --- a/trunk/arch/x86_64/ia32/ia32_binfmt.c +++ b/trunk/arch/x86_64/ia32/ia32_binfmt.c @@ -197,7 +197,8 @@ static inline void elf_core_copy_regs(elf_gregset_t *elfregs, struct pt_regs *re static inline int elf_core_copy_task_regs(struct task_struct *t, elf_gregset_t* elfregs) { - struct pt_regs *pp = task_pt_regs(t); + struct pt_regs *pp = (struct pt_regs *)(t->thread.rsp0); + --pp; ELF_CORE_COPY_REGS((*elfregs), pp); /* fix wrong segments */ (*elfregs)[7] = t->thread.ds; @@ -216,7 +217,7 @@ elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs, elf_fpr if (!tsk_used_math(tsk)) return 0; if (!regs) - regs = task_pt_regs(tsk); + regs = ((struct pt_regs *)tsk->thread.rsp0) - 1; if (tsk == current) unlazy_fpu(tsk); set_fs(KERNEL_DS); @@ -232,7 +233,7 @@ elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs, elf_fpr static inline int elf_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu) { - struct pt_regs *regs = task_pt_regs(t); + struct pt_regs *regs = ((struct pt_regs *)(t->thread.rsp0))-1; if (!tsk_used_math(t)) return 0; if (t == current) diff --git a/trunk/arch/x86_64/ia32/ptrace32.c b/trunk/arch/x86_64/ia32/ptrace32.c index 23a4515a73b4..ea4394e021d6 100644 --- a/trunk/arch/x86_64/ia32/ptrace32.c +++ b/trunk/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 *)task_pt_regs(child); + __u64 *stack = (__u64 *)(child->thread.rsp0 - sizeof(struct pt_regs)); switch (regno) { case offsetof(struct user32, regs.fs): @@ -137,7 +137,7 @@ static int putreg32(struct task_struct *child, unsigned regno, u32 val) static int getreg32(struct task_struct *child, unsigned regno, u32 *val) { - __u64 *stack = (__u64 *)task_pt_regs(child); + __u64 *stack = (__u64 *)(child->thread.rsp0 - sizeof(struct pt_regs)); switch (regno) { case offsetof(struct user32, regs.fs): @@ -238,7 +238,7 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) if (ret < 0) goto out; - childregs = task_pt_regs(child); + childregs = (struct pt_regs *)(child->thread.rsp0 - sizeof(struct pt_regs)); switch (request) { case PTRACE_PEEKDATA: diff --git a/trunk/arch/x86_64/kernel/i387.c b/trunk/arch/x86_64/kernel/i387.c index a5d7e16b928e..d9b22b633e39 100644 --- a/trunk/arch/x86_64/kernel/i387.c +++ b/trunk/arch/x86_64/kernel/i387.c @@ -95,7 +95,7 @@ int save_i387(struct _fpstate __user *buf) if (!used_math()) return 0; clear_used_math(); /* trigger finit */ - if (task_thread_info(tsk)->status & TS_USEDFPU) { + if (tsk->thread_info->status & TS_USEDFPU) { err = save_i387_checking((struct i387_fxsave_struct __user *)buf); if (err) return err; stts(); diff --git a/trunk/arch/x86_64/kernel/i8259.c b/trunk/arch/x86_64/kernel/i8259.c index 5ecd34ab8c2b..b61965f0fb34 100644 --- a/trunk/arch/x86_64/kernel/i8259.c +++ b/trunk/arch/x86_64/kernel/i8259.c @@ -133,7 +133,7 @@ static void end_8259A_irq (unsigned int irq) { if (irq > 256) { char var; - printk("return %p stack %p ti %p\n", __builtin_return_address(0), &var, task_thread_info(current)); + printk("return %p stack %p ti %p\n", __builtin_return_address(0), &var, current->thread_info); BUG(); } diff --git a/trunk/arch/x86_64/kernel/process.c b/trunk/arch/x86_64/kernel/process.c index 8ded407e4a94..669cf0ed3266 100644 --- a/trunk/arch/x86_64/kernel/process.c +++ b/trunk/arch/x86_64/kernel/process.c @@ -451,7 +451,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp, struct task_struct *me = current; childregs = ((struct pt_regs *) - (THREAD_SIZE + task_stack_page(p))) - 1; + (THREAD_SIZE + (unsigned long) p->thread_info)) - 1; *childregs = *regs; childregs->rax = 0; @@ -463,7 +463,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp, p->thread.rsp0 = (unsigned long) (childregs+1); p->thread.userrsp = me->thread.userrsp; - set_tsk_thread_flag(p, TIF_FORK); + set_ti_thread_flag(p->thread_info, TIF_FORK); p->thread.fs = me->thread.fs; p->thread.gs = me->thread.gs; @@ -590,7 +590,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) write_pda(oldrsp, next->userrsp); write_pda(pcurrent, next_p); write_pda(kernelstack, - task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET); + (unsigned long)next_p->thread_info + THREAD_SIZE - PDA_STACKOFFSET); /* * Now maybe reload the debug registers @@ -704,7 +704,7 @@ unsigned long get_wchan(struct task_struct *p) if (!p || p == current || p->state==TASK_RUNNING) return 0; - stack = (unsigned long)task_stack_page(p); + stack = (unsigned long)p->thread_info; if (p->thread.rsp < stack || p->thread.rsp > stack+THREAD_SIZE) return 0; fp = *(u64 *)(p->thread.rsp); @@ -822,7 +822,8 @@ int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) { struct pt_regs *pp, ptregs; - pp = task_pt_regs(tsk); + pp = (struct pt_regs *)(tsk->thread.rsp0); + --pp; ptregs = *pp; ptregs.cs &= 0xffff; diff --git a/trunk/arch/x86_64/kernel/ptrace.c b/trunk/arch/x86_64/kernel/ptrace.c index 53205622351c..86248bc9303e 100644 --- a/trunk/arch/x86_64/kernel/ptrace.c +++ b/trunk/arch/x86_64/kernel/ptrace.c @@ -67,6 +67,12 @@ static inline unsigned long get_stack_long(struct task_struct *task, int offset) 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. @@ -164,7 +170,7 @@ static int is_at_popf(struct task_struct *child, struct pt_regs *regs) static void set_singlestep(struct task_struct *child) { - struct pt_regs *regs = task_pt_regs(child); + struct pt_regs *regs = get_child_regs(child); /* * Always set TIF_SINGLESTEP - this guarantees that @@ -202,7 +208,7 @@ static void clear_singlestep(struct task_struct *child) /* But touch TF only if it was set by us.. */ if (child->ptrace & PT_DTRACE) { - struct pt_regs *regs = task_pt_regs(child); + struct pt_regs *regs = get_child_regs(child); regs->eflags &= ~TRAP_FLAG; child->ptrace &= ~PT_DTRACE; } diff --git a/trunk/arch/x86_64/kernel/smpboot.c b/trunk/arch/x86_64/kernel/smpboot.c index a28756ef7cef..c9e941ae5019 100644 --- a/trunk/arch/x86_64/kernel/smpboot.c +++ b/trunk/arch/x86_64/kernel/smpboot.c @@ -776,7 +776,7 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid) if (c_idle.idle) { c_idle.idle->thread.rsp = (unsigned long) (((struct pt_regs *) - (THREAD_SIZE + task_stack_page(c_idle.idle))) - 1); + (THREAD_SIZE + (unsigned long) c_idle.idle->thread_info)) - 1); init_idle(c_idle.idle, cpu); goto do_rest; } @@ -814,7 +814,7 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid) init_rsp = c_idle.idle->thread.rsp; per_cpu(init_tss,cpu).rsp0 = init_rsp; initial_code = start_secondary; - clear_tsk_thread_flag(c_idle.idle, TIF_FORK); + clear_ti_thread_flag(c_idle.idle->thread_info, TIF_FORK); printk(KERN_INFO "Booting processor %d/%d APIC 0x%x\n", cpu, cpus_weight(cpu_present_map), diff --git a/trunk/arch/x86_64/kernel/traps.c b/trunk/arch/x86_64/kernel/traps.c index 8bb0aeda78b9..2671fd46ea85 100644 --- a/trunk/arch/x86_64/kernel/traps.c +++ b/trunk/arch/x86_64/kernel/traps.c @@ -308,7 +308,7 @@ void show_registers(struct pt_regs *regs) printk("CPU %d ", cpu); __show_regs(regs); printk("Process %s (pid: %d, threadinfo %p, task %p)\n", - cur->comm, cur->pid, task_thread_info(cur), cur); + cur->comm, cur->pid, cur->thread_info, cur); /* * When in-kernel, we also print out the stack and code at the @@ -666,7 +666,7 @@ asmlinkage struct pt_regs *sync_regs(struct pt_regs *eregs) ; /* Exception from user space */ else if (user_mode(eregs)) - regs = task_pt_regs(current); + regs = ((struct pt_regs *)current->thread.rsp0) - 1; /* Exception from kernel and interrupts are enabled. Move to kernel process stack. */ else if (eregs->eflags & X86_EFLAGS_IF) @@ -912,7 +912,7 @@ asmlinkage void math_state_restore(void) if (!used_math()) init_fpu(me); restore_fpu_checking(&me->thread.i387.fxsave); - task_thread_info(me)->status |= TS_USEDFPU; + me->thread_info->status |= TS_USEDFPU; } void __init trap_init(void) diff --git a/trunk/arch/xtensa/kernel/process.c b/trunk/arch/xtensa/kernel/process.c index f1f596644bfc..6a44b54ae817 100644 --- a/trunk/arch/xtensa/kernel/process.c +++ b/trunk/arch/xtensa/kernel/process.c @@ -145,7 +145,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, int user_mode = user_mode(regs); /* Set up new TSS. */ - tos = (unsigned long)task_stack_page(p) + THREAD_SIZE; + tos = (unsigned long)p->thread_info + THREAD_SIZE; if (user_mode) childregs = (struct pt_regs*)(tos - PT_USER_SIZE); else @@ -217,7 +217,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) unsigned long get_wchan(struct task_struct *p) { unsigned long sp, pc; - unsigned long stack_page = (unsigned long) task_stack_page(p); + unsigned long stack_page = (unsigned long) p->thread_info; int count = 0; if (!p || p == current || p->state == TASK_RUNNING) diff --git a/trunk/arch/xtensa/kernel/ptrace.c b/trunk/arch/xtensa/kernel/ptrace.c index 4cc85285a70a..ab5c4c65b5c4 100644 --- a/trunk/arch/xtensa/kernel/ptrace.c +++ b/trunk/arch/xtensa/kernel/ptrace.c @@ -72,7 +72,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) struct pt_regs *regs; unsigned long tmp; - regs = task_pt_regs(child); + regs = xtensa_pt_regs(child); tmp = 0; /* Default return value. */ switch(addr) { @@ -149,7 +149,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) case PTRACE_POKEUSR: { struct pt_regs *regs; - regs = task_pt_regs(child); + regs = xtensa_pt_regs(child); switch (addr) { case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1: @@ -240,7 +240,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) * elf_gregset_t format. */ xtensa_gregset_t format; - struct pt_regs *regs = task_pt_regs(child); + struct pt_regs *regs = xtensa_pt_regs(child); do_copy_regs (&format, regs, child); @@ -257,7 +257,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) * values in the elf_gregset_t format. */ xtensa_gregset_t format; - struct pt_regs *regs = task_pt_regs(child); + struct pt_regs *regs = xtensa_pt_regs(child); if (copy_from_user(&format,(void *)data,sizeof(elf_gregset_t))){ ret = -EFAULT; @@ -281,7 +281,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) * elf_fpregset_t format. */ elf_fpregset_t fpregs; - struct pt_regs *regs = task_pt_regs(child); + struct pt_regs *regs = xtensa_pt_regs(child); do_save_fpregs (&fpregs, regs, child); @@ -299,7 +299,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) * values in the elf_fpregset_t format. */ elf_fpregset_t fpregs; - struct pt_regs *regs = task_pt_regs(child); + struct pt_regs *regs = xtensa_pt_regs(child); ret = 0; if (copy_from_user(&fpregs, (void *)data, sizeof(elf_fpregset_t))) { diff --git a/trunk/block/elevator.c b/trunk/block/elevator.c index 1d0759178e4b..99a4d7b2f8ad 100644 --- a/trunk/block/elevator.c +++ b/trunk/block/elevator.c @@ -610,23 +610,23 @@ void elv_completed_request(request_queue_t *q, struct request *rq) * 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 (unlikely(q->ordseq)) { - struct request *first_rq = list_entry_rq(q->queue_head.next); - if (q->in_flight == 0 && + /* + * Check if the queue is waiting for fs requests to be + * drained for flush sequence. + */ + if (q->ordseq && 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/trunk/drivers/block/amiflop.c b/trunk/drivers/block/amiflop.c index b6e290956214..3c679d30b698 100644 --- a/trunk/drivers/block/amiflop.c +++ b/trunk/drivers/block/amiflop.c @@ -194,8 +194,6 @@ static DECLARE_WAIT_QUEUE_HEAD(ms_wait); */ #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 }; @@ -1441,7 +1439,6 @@ static int fd_ioctl(struct inode *inode, struct file *filp, { int drive = iminor(inode) & 3; static struct floppy_struct getprm; - void __user *argp = (void __user *)param; switch(cmd){ case FDFMTBEG: @@ -1487,7 +1484,9 @@ static int fd_ioctl(struct inode *inode, struct file *filp, 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(argp, &getprm, sizeof(struct floppy_struct))) + if (copy_to_user((void *)param, + (void *)&getprm, + sizeof(struct floppy_struct))) return -EFAULT; break; case FDSETPRM: @@ -1499,7 +1498,8 @@ static int fd_ioctl(struct inode *inode, struct file *filp, break; #ifdef RAW_IOCTL case IOCTL_RAW_TRACK: - if (copy_to_user(argp, raw_buf, unit[drive].type->read_size)) + if (copy_to_user((void *)param, raw_buf, + unit[drive].type->read_size)) return -EFAULT; else return unit[drive].type->read_size; @@ -1654,6 +1654,12 @@ static struct block_device_operations floppy_fops = { .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; @@ -1839,18 +1845,4 @@ void cleanup_module(void) 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/trunk/drivers/block/ataflop.c b/trunk/drivers/block/ataflop.c index f8ce235ccfc3..3aa68a5447d6 100644 --- a/trunk/drivers/block/ataflop.c +++ b/trunk/drivers/block/ataflop.c @@ -1361,7 +1361,7 @@ static int floppy_revalidate(struct gendisk *disk) formats, for 'permanent user-defined' parameter: restore default_params[] here if flagged valid! */ if (default_params[drive].blocks == 0) - UDT = NULL; + UDT = 0; else UDT = &default_params[drive]; } @@ -1495,7 +1495,6 @@ static int fd_ioctl(struct inode *inode, struct file *filp, struct floppy_struct getprm; int settype; struct floppy_struct setprm; - void __user *argp = (void __user *)param; switch (cmd) { case FDGETPRM: @@ -1522,7 +1521,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, getprm.head = 2; getprm.track = dtp->blocks/dtp->spt/2; getprm.stretch = dtp->stretch; - if (copy_to_user(argp, &getprm, sizeof(getprm))) + if (copy_to_user((void *)param, &getprm, sizeof(getprm))) return -EFAULT; return 0; } @@ -1541,7 +1540,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, /* get the parameters from user space */ if (floppy->ref != 1 && floppy->ref != -1) return -EBUSY; - if (copy_from_user(&setprm, argp, sizeof(setprm))) + if (copy_from_user(&setprm, (void *) param, sizeof(setprm))) return -EFAULT; /* * first of all: check for floppy change and revalidate, @@ -1648,7 +1647,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, case FDFMTTRK: if (floppy->ref != 1 && floppy->ref != -1) return -EBUSY; - if (copy_from_user(&fmt_desc, argp, sizeof(fmt_desc))) + if (copy_from_user(&fmt_desc, (void *) param, sizeof(fmt_desc))) return -EFAULT; return do_format(drive, type, &fmt_desc); case FDCLRPRM: @@ -1951,20 +1950,14 @@ static int __init atari_floppy_init (void) return -ENOMEM; } -#ifndef MODULE -static int __init atari_floppy_setup(char *str) + +void __init atari_floppy_setup( char *str, int *ints ) { - 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 0; + return; } else if (ints[0] > 2+FD_MAX_UNITS) { printk(KERN_ERR "ataflop_setup: too many arguments\n" ); @@ -1984,13 +1977,9 @@ static int __init atari_floppy_setup(char *str) else UserSteprate[i-3] = ints[i]; } - return 1; } -__setup("floppy=", atari_floppy_setup); -#endif - -static void __exit atari_floppy_exit(void) +static void atari_floppy_exit(void) { int i; blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); diff --git a/trunk/drivers/block/viodasd.c b/trunk/drivers/block/viodasd.c index f63e07bd9f9c..d1aaf31bd97e 100644 --- a/trunk/drivers/block/viodasd.c +++ b/trunk/drivers/block/viodasd.c @@ -293,7 +293,6 @@ static int send_request(struct request *req) u16 viocmd; HvLpEvent_Rc hvrc; struct vioblocklpevent *bevent; - struct HvLpEvent *hev; struct scatterlist sg[VIOMAXBLOCKDMA]; int sgindex; int statindex; @@ -348,19 +347,22 @@ static int send_request(struct request *req) * token so we can match the response up later */ memset(bevent, 0, sizeof(struct vioblocklpevent)); - 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 = + 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 = offsetof(struct vioblocklpevent, u.rw_data.dma_info) + (sizeof(bevent->u.rw_data.dma_info[0]) * nsg) - 1; - hev->xSourceInstanceId = viopath_sourceinst(viopath_hostLp); - hev->xTargetInstanceId = viopath_targetinst(viopath_hostLp); - hev->xCorrelationToken = (u64)req; + bevent->event.xSourceInstanceId = + viopath_sourceinst(viopath_hostLp); + bevent->event.xTargetInstanceId = + viopath_targetinst(viopath_hostLp); + bevent->event.xCorrelationToken = (u64)req; bevent->version = VIOVERSION; bevent->disk = DEVICE_NO(d); bevent->u.rw_data.offset = start; @@ -647,10 +649,10 @@ static void handle_block_event(struct HvLpEvent *event) /* Notification that a partition went away! */ return; /* First, we should NEVER get an int here...only acks */ - if (hvlpevent_is_int(event)) { + if (event->xFlags.xFunction == HvLpEvent_Function_Int) { printk(VIOD_KERN_WARNING "Yikes! got an int in viodasd event handler!\n"); - if (hvlpevent_need_ack(event)) { + if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) { event->xRc = HvLpEvent_Rc_InvalidSubtype; HvCallEvent_ackLpEvent(event); } @@ -693,7 +695,7 @@ static void handle_block_event(struct HvLpEvent *event) default: printk(VIOD_KERN_WARNING "invalid subtype!"); - if (hvlpevent_need_ack(event)) { + if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) { event->xRc = HvLpEvent_Rc_InvalidSubtype; HvCallEvent_ackLpEvent(event); } diff --git a/trunk/drivers/cdrom/viocd.c b/trunk/drivers/cdrom/viocd.c index 193446e6a08a..b5191780ecca 100644 --- a/trunk/drivers/cdrom/viocd.c +++ b/trunk/drivers/cdrom/viocd.c @@ -542,10 +542,10 @@ static void vio_handle_cd_event(struct HvLpEvent *event) /* Notification that a partition went away! */ return; /* First, we should NEVER get an int here...only acks */ - if (hvlpevent_is_int(event)) { + if (event->xFlags.xFunction == HvLpEvent_Function_Int) { printk(VIOCD_KERN_WARNING "Yikes! got an int in viocd event handler!\n"); - if (hvlpevent_need_ack(event)) { + if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) { event->xRc = HvLpEvent_Rc_InvalidSubtype; HvCallEvent_ackLpEvent(event); } @@ -616,7 +616,7 @@ static void vio_handle_cd_event(struct HvLpEvent *event) printk(VIOCD_KERN_WARNING "message with invalid subtype %0x04X!\n", event->xSubtype & VIOMINOR_SUBTYPE_MASK); - if (hvlpevent_need_ack(event)) { + if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) { event->xRc = HvLpEvent_Rc_InvalidSubtype; HvCallEvent_ackLpEvent(event); } diff --git a/trunk/drivers/char/amiserial.c b/trunk/drivers/char/amiserial.c index 667a21c72edb..869518e4035f 100644 --- a/trunk/drivers/char/amiserial.c +++ b/trunk/drivers/char/amiserial.c @@ -99,7 +99,6 @@ static char *serial_version = "4.30"; #define _INLINE_ inline #endif -#define custom amiga_custom static char *serial_name = "Amiga-builtin serial driver"; static struct tty_driver *serial_driver; @@ -1089,7 +1088,7 @@ static void rs_unthrottle(struct tty_struct * tty) */ static int get_serial_info(struct async_struct * info, - struct serial_struct __user * retinfo) + struct serial_struct * retinfo) { struct serial_struct tmp; struct serial_state *state = info->state; @@ -1113,7 +1112,7 @@ static int get_serial_info(struct async_struct * info, } static int set_serial_info(struct async_struct * info, - struct serial_struct __user * new_info) + struct serial_struct * new_info) { struct serial_struct new_serial; struct serial_state old_state, *state; @@ -1194,7 +1193,7 @@ static int set_serial_info(struct async_struct * info, * 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 __user *value) +static int get_lsr_info(struct async_struct * info, unsigned int *value) { unsigned char status; unsigned int result; @@ -1285,7 +1284,6 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, 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")) @@ -1300,17 +1298,19 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, switch (cmd) { case TIOCGSERIAL: - return get_serial_info(info, argp); + return get_serial_info(info, + (struct serial_struct *) arg); case TIOCSSERIAL: - return set_serial_info(info, argp); + return set_serial_info(info, + (struct serial_struct *) arg); case TIOCSERCONFIG: return 0; case TIOCSERGETLSR: /* Get line status register */ - return get_lsr_info(info, argp); + return get_lsr_info(info, (unsigned int *) arg); case TIOCSERGSTRUCT: - if (copy_to_user(argp, + if (copy_to_user((struct async_struct *) arg, info, sizeof(struct async_struct))) return -EFAULT; return 0; @@ -1369,7 +1369,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, icount.brk = cnow.brk; icount.buf_overrun = cnow.buf_overrun; - if (copy_to_user(argp, &icount, sizeof(icount))) + if (copy_to_user((void *)arg, &icount, sizeof(icount))) return -EFAULT; return 0; case TIOCSERGWILD: diff --git a/trunk/drivers/char/dsp56k.c b/trunk/drivers/char/dsp56k.c index e233cf280bc0..8693835cb2d5 100644 --- a/trunk/drivers/char/dsp56k.c +++ b/trunk/drivers/char/dsp56k.c @@ -165,7 +165,7 @@ static int dsp56k_reset(void) return 0; } -static int dsp56k_upload(u_char __user *bin, int len) +static int dsp56k_upload(u_char *bin, int len) { int i; u_char *p; @@ -199,7 +199,7 @@ static int dsp56k_upload(u_char __user *bin, int len) return 0; } -static ssize_t dsp56k_read(struct file *file, char __user *buf, size_t count, +static ssize_t dsp56k_read(struct file *file, char *buf, size_t count, loff_t *ppos) { struct inode *inode = file->f_dentry->d_inode; @@ -225,10 +225,10 @@ static ssize_t dsp56k_read(struct file *file, char __user *buf, size_t count, } case 2: /* 16 bit */ { - short __user *data; + short *data; count /= 2; - data = (short __user *) buf; + data = (short*) 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 @@ static ssize_t dsp56k_read(struct file *file, char __user *buf, size_t count, } case 4: /* 32 bit */ { - long __user *data; + long *data; count /= 4; - data = (long __user *) buf; + data = (long*) 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_read(struct file *file, char __user *buf, size_t count, } } -static ssize_t dsp56k_write(struct file *file, const char __user *buf, size_t count, +static ssize_t dsp56k_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { struct inode *inode = file->f_dentry->d_inode; @@ -287,10 +287,10 @@ static ssize_t dsp56k_write(struct file *file, const char __user *buf, size_t co } case 2: /* 16 bit */ { - const short __user *data; + const short *data; count /= 2; - data = (const short __user *)buf; + data = (const short *)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 @@ static ssize_t dsp56k_write(struct file *file, const char __user *buf, size_t co } case 4: /* 32 bit */ { - const long __user *data; + const long *data; count /= 4; - data = (const long __user *)buf; + data = (const long *)buf; handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_TRANSMIT, get_user(dsp56k_host_interface.data.l, data+n++)); return 4*n; @@ -328,7 +328,6 @@ static int dsp56k_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int dev = iminor(inode) & 0x0f; - void __user *argp = (void __user *)arg; switch(dev) { @@ -337,9 +336,9 @@ static int dsp56k_ioctl(struct inode *inode, struct file *file, switch(cmd) { case DSP56K_UPLOAD: { - char __user *bin; + char *bin; int r, len; - struct dsp56k_upload __user *binary = argp; + struct dsp56k_upload *binary = (struct dsp56k_upload *) arg; if(get_user(len, &binary->len) < 0) return -EFAULT; @@ -373,7 +372,7 @@ static int dsp56k_ioctl(struct inode *inode, struct file *file, case DSP56K_HOST_FLAGS: { int dir, out, status; - struct dsp56k_host_flags __user *hf = argp; + struct dsp56k_host_flags *hf = (struct dsp56k_host_flags*) arg; if(get_user(dir, &hf->dir) < 0) return -EFAULT; diff --git a/trunk/drivers/char/mem.c b/trunk/drivers/char/mem.c index 29c41f4418c0..704c3c07f0ab 100644 --- a/trunk/drivers/char/mem.c +++ b/trunk/drivers/char/mem.c @@ -534,7 +534,7 @@ static ssize_t write_kmem(struct file * file, const char __user * buf, return virtr + wrote; } -#if defined(CONFIG_ISA) || !defined(__mc68000__) +#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI)) static ssize_t read_port(struct file * file, char __user * buf, size_t count, loff_t *ppos) { @@ -795,7 +795,7 @@ static struct file_operations null_fops = { .write = write_null, }; -#if defined(CONFIG_ISA) || !defined(__mc68000__) +#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI)) static struct file_operations port_fops = { .llseek = memory_lseek, .read = read_port, @@ -865,7 +865,7 @@ static int memory_open(struct inode * inode, struct file * filp) case 3: filp->f_op = &null_fops; break; -#if defined(CONFIG_ISA) || !defined(__mc68000__) +#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI)) case 4: filp->f_op = &port_fops; break; @@ -912,7 +912,7 @@ static const struct { {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__) +#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI)) {4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops}, #endif {5, "zero", S_IRUGO | S_IWUGO, &zero_fops}, diff --git a/trunk/drivers/char/scc.h b/trunk/drivers/char/scc.h index 93998f5baff5..51810f72f1a9 100644 --- a/trunk/drivers/char/scc.h +++ b/trunk/drivers/char/scc.h @@ -399,7 +399,7 @@ struct scc_port { __asm__ __volatile__ ( "tstb %0" : : "g" (*_scc_del) : "cc" );\ } while (0) -static unsigned char scc_shadow[2][16]; +extern 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/trunk/drivers/char/viocons.c b/trunk/drivers/char/viocons.c index 4e5360388748..faee5e7acaf7 100644 --- a/trunk/drivers/char/viocons.c +++ b/trunk/drivers/char/viocons.c @@ -476,19 +476,19 @@ static struct port_info *get_port_data(struct tty_struct *tty) */ static void initDataEvent(struct viocharlpevent *viochar, HvLpIndex lp) { - struct HvLpEvent *hev = &viochar->event; - memset(viochar, 0, sizeof(struct viocharlpevent)); - 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); + 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); } /* @@ -752,7 +752,7 @@ static void vioHandleOpenEvent(struct HvLpEvent *event) struct port_info *pi; int reject = 0; - if (hvlpevent_is_ack(event)) { + if (event->xFlags.xFunction == HvLpEvent_Function_Ack) { if (port >= VTTY_PORTS) return; @@ -788,7 +788,7 @@ static void vioHandleOpenEvent(struct HvLpEvent *event) } /* This had better require an ack, otherwise complain */ - if (!hvlpevent_need_ack(event)) { + if (event->xFlags.xAckInd != HvLpEvent_AckInd_DoAck) { printk(VIOCONS_KERN_WARN "viocharopen without ack bit!\n"); return; } @@ -856,7 +856,7 @@ static void vioHandleCloseEvent(struct HvLpEvent *event) struct viocharlpevent *cevent = (struct viocharlpevent *)event; u8 port = cevent->virtual_device; - if (hvlpevent_is_int(event)) { + if (event->xFlags.xFunction == HvLpEvent_Function_Int) { if (port >= VTTY_PORTS) { printk(VIOCONS_KERN_WARN "close message from invalid virtual device.\n"); @@ -1056,7 +1056,8 @@ static void vioHandleCharEvent(struct HvLpEvent *event) vioHandleConfig(event); break; default: - if (hvlpevent_is_int(event) && hvlpevent_need_ack(event)) { + if ((event->xFlags.xFunction == HvLpEvent_Function_Int) && + (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck)) { event->xRc = HvLpEvent_Rc_InvalidSubtype; HvCallEvent_ackLpEvent(event); } diff --git a/trunk/drivers/ide/ide-io.c b/trunk/drivers/ide/ide-io.c index 8d50df4526a4..bcbaeb50bb93 100644 --- a/trunk/drivers/ide/ide-io.c +++ b/trunk/drivers/ide/ide-io.c @@ -55,9 +55,22 @@ #include #include +void ide_softirq_done(struct request *rq) +{ + request_queue_t *q = rq->q; + + add_disk_randomness(rq->rq_disk); + end_that_request_chunk(rq, 1, rq->data_len); + + spin_lock_irq(q->queue_lock); + end_that_request_last(rq, 1); + spin_unlock_irq(q->queue_lock); +} + int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate, int nr_sectors) { + unsigned int nbytes; int ret = 1; BUG_ON(!(rq->flags & REQ_STARTED)); @@ -81,12 +94,27 @@ int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate, HWGROUP(drive)->hwif->ide_dma_on(drive); } - if (!end_that_request_first(rq, uptodate, nr_sectors)) { - add_disk_randomness(rq->rq_disk); + /* + * For partial completions (or non fs/pc requests), use the regular + * direct completion path. Same thing for requests that failed, to + * preserve the ->errors value we use the normal completion path + * for those + */ + nbytes = nr_sectors << 9; + if (!rq->errors && rq_all_done(rq, nbytes)) { + rq->data_len = nbytes; blkdev_dequeue_request(rq); HWGROUP(drive)->rq = NULL; - end_that_request_last(rq, uptodate); + blk_complete_request(rq); ret = 0; + } else { + if (!end_that_request_first(rq, uptodate, nr_sectors)) { + add_disk_randomness(rq->rq_disk); + blkdev_dequeue_request(rq); + HWGROUP(drive)->rq = NULL; + end_that_request_last(rq, uptodate); + ret = 0; + } } return ret; diff --git a/trunk/drivers/ide/ide-probe.c b/trunk/drivers/ide/ide-probe.c index e7425546b4b1..7cb2d86601db 100644 --- a/trunk/drivers/ide/ide-probe.c +++ b/trunk/drivers/ide/ide-probe.c @@ -1011,6 +1011,8 @@ static int ide_init_queue(ide_drive_t *drive) blk_queue_max_hw_segments(q, max_sg_entries); blk_queue_max_phys_segments(q, max_sg_entries); + blk_queue_softirq_done(q, ide_softirq_done); + /* assign drive queue */ drive->queue = q; diff --git a/trunk/drivers/input/evdev.c b/trunk/drivers/input/evdev.c index 745979f33dc2..362b33556b1a 100644 --- a/trunk/drivers/input/evdev.c +++ b/trunk/drivers/input/evdev.c @@ -159,7 +159,7 @@ struct input_event_compat { #ifdef CONFIG_X86_64 # define COMPAT_TEST is_compat_task() #elif defined(CONFIG_IA64) -# define COMPAT_TEST IS_IA32_PROCESS(task_pt_regs(current)) +# define COMPAT_TEST IS_IA32_PROCESS(ia64_task_regs(current)) #elif defined(CONFIG_S390) # define COMPAT_TEST test_thread_flag(TIF_31BIT) #elif defined(CONFIG_MIPS) diff --git a/trunk/drivers/input/joystick/amijoy.c b/trunk/drivers/input/joystick/amijoy.c index ec55a29fc861..8558a99f6635 100644 --- a/trunk/drivers/input/joystick/amijoy.c +++ b/trunk/drivers/input/joystick/amijoy.c @@ -64,8 +64,8 @@ static irqreturn_t amijoy_interrupt(int irq, void *dummy, struct pt_regs *fp) if (amijoy[i]) { switch (i) { - case 0: data = ~amiga_custom.joy0dat; button = (~ciaa.pra >> 6) & 1; break; - case 1: data = ~amiga_custom.joy1dat; button = (~ciaa.pra >> 7) & 1; break; + case 0: data = ~custom.joy0dat; button = (~ciaa.pra >> 6) & 1; break; + case 1: data = ~custom.joy1dat; button = (~ciaa.pra >> 7) & 1; break; } input_regs(amijoy_dev[i], fp); diff --git a/trunk/drivers/input/mouse/amimouse.c b/trunk/drivers/input/mouse/amimouse.c index c8b2cc9f184c..d13d4c8fe3c5 100644 --- a/trunk/drivers/input/mouse/amimouse.c +++ b/trunk/drivers/input/mouse/amimouse.c @@ -41,7 +41,7 @@ static irqreturn_t amimouse_interrupt(int irq, void *dummy, struct pt_regs *fp) unsigned short joy0dat, potgor; int nx, ny, dx, dy; - joy0dat = amiga_custom.joy0dat; + joy0dat = custom.joy0dat; nx = joy0dat & 0xff; ny = joy0dat >> 8; @@ -57,7 +57,7 @@ static irqreturn_t amimouse_interrupt(int irq, void *dummy, struct pt_regs *fp) amimouse_lastx = nx; amimouse_lasty = ny; - potgor = amiga_custom.potgor; + potgor = custom.potgor; input_regs(amimouse_dev, fp); @@ -77,7 +77,7 @@ static int amimouse_open(struct input_dev *dev) { unsigned short joy0dat; - joy0dat = amiga_custom.joy0dat; + joy0dat = custom.joy0dat; amimouse_lastx = joy0dat & 0xff; amimouse_lasty = joy0dat >> 8; diff --git a/trunk/drivers/macintosh/adb-iop.c b/trunk/drivers/macintosh/adb-iop.c index d56d400b6aaa..71aeb912ec61 100644 --- a/trunk/drivers/macintosh/adb-iop.c +++ b/trunk/drivers/macintosh/adb-iop.c @@ -239,7 +239,7 @@ static int adb_iop_write(struct adb_request *req) local_irq_save(flags); - req->next = NULL; + req->next = 0; req->sent = 0; req->complete = 0; req->reply_len = 0; diff --git a/trunk/drivers/macintosh/via-macii.c b/trunk/drivers/macintosh/via-macii.c index 2a2ffe060169..e9a159ad3022 100644 --- a/trunk/drivers/macintosh/via-macii.c +++ b/trunk/drivers/macintosh/via-macii.c @@ -260,7 +260,7 @@ static int macii_write(struct adb_request *req) return -EINVAL; } - req->next = NULL; + req->next = 0; req->sent = 0; req->complete = 0; req->reply_len = 0; @@ -295,7 +295,7 @@ static void macii_poll(void) unsigned long flags; local_irq_save(flags); - if (via[IFR] & SR_INT) macii_interrupt(0, NULL, NULL); + if (via[IFR] & SR_INT) macii_interrupt(0, 0, 0); local_irq_restore(flags); } diff --git a/trunk/drivers/macintosh/via-maciisi.c b/trunk/drivers/macintosh/via-maciisi.c index 0129fcc3b183..a1966975d58f 100644 --- a/trunk/drivers/macintosh/via-maciisi.c +++ b/trunk/drivers/macintosh/via-maciisi.c @@ -294,24 +294,6 @@ static void maciisi_sync(struct adb_request *req) 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) @@ -326,7 +308,7 @@ maciisi_write(struct adb_request* req) req->complete = 1; return -EINVAL; } - req->next = NULL; + req->next = 0; req->sent = 0; req->complete = 0; req->reply_len = 0; @@ -421,7 +403,7 @@ maciisi_poll(void) local_irq_save(flags); if (via[IFR] & SR_INT) { - maciisi_interrupt(0, NULL, NULL); + maciisi_interrupt(0, 0, 0); } else /* avoid calling this function too quickly in a loop */ udelay(ADB_DELAY); diff --git a/trunk/drivers/macintosh/via-pmu68k.c b/trunk/drivers/macintosh/via-pmu68k.c index f08e52f2107b..6f80d76ac17c 100644 --- a/trunk/drivers/macintosh/via-pmu68k.c +++ b/trunk/drivers/macintosh/via-pmu68k.c @@ -493,7 +493,7 @@ pmu_queue_request(struct adb_request *req) return -EINVAL; } - req->next = NULL; + req->next = 0; req->sent = 0; req->complete = 0; local_irq_save(flags); @@ -717,7 +717,7 @@ pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs) printk(KERN_ERR "PMU: extra ADB reply\n"); return; } - req_awaiting_reply = NULL; + req_awaiting_reply = 0; if (len <= 2) req->reply_len = 0; else { diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 1778104e106c..0302723fa21f 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -1238,7 +1238,6 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) mdk_rdev_t *same_pdev; char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; struct kobject *ko; - char *s; if (rdev->mddev) { MD_BUG(); @@ -1278,8 +1277,6 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) 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/trunk/drivers/mfd/ucb1x00-core.c b/trunk/drivers/mfd/ucb1x00-core.c index aff83f966803..b42e0fbab59b 100644 --- a/trunk/drivers/mfd/ucb1x00-core.c +++ b/trunk/drivers/mfd/ucb1x00-core.c @@ -24,14 +24,13 @@ #include #include #include -#include #include #include #include "ucb1x00.h" -static DEFINE_MUTEX(ucb1x00_mutex); +static DECLARE_MUTEX(ucb1x00_sem); static LIST_HEAD(ucb1x00_drivers); static LIST_HEAD(ucb1x00_devices); @@ -522,12 +521,12 @@ static int ucb1x00_probe(struct mcp *mcp) goto err_irq; INIT_LIST_HEAD(&ucb->devs); - mutex_lock(&ucb1x00_mutex); + down(&ucb1x00_sem); list_add(&ucb->node, &ucb1x00_devices); list_for_each_entry(drv, &ucb1x00_drivers, node) { ucb1x00_add_dev(ucb, drv); } - mutex_unlock(&ucb1x00_mutex); + up(&ucb1x00_sem); goto out; err_irq: @@ -545,13 +544,13 @@ static void ucb1x00_remove(struct mcp *mcp) struct ucb1x00 *ucb = mcp_get_drvdata(mcp); struct list_head *l, *n; - mutex_lock(&ucb1x00_mutex); + down(&ucb1x00_sem); list_del(&ucb->node); list_for_each_safe(l, n, &ucb->devs) { struct ucb1x00_dev *dev = list_entry(l, struct ucb1x00_dev, dev_node); ucb1x00_remove_dev(dev); } - mutex_unlock(&ucb1x00_mutex); + up(&ucb1x00_sem); free_irq(ucb->irq, ucb); class_device_unregister(&ucb->cdev); @@ -562,12 +561,12 @@ int ucb1x00_register_driver(struct ucb1x00_driver *drv) struct ucb1x00 *ucb; INIT_LIST_HEAD(&drv->devs); - mutex_lock(&ucb1x00_mutex); + down(&ucb1x00_sem); list_add(&drv->node, &ucb1x00_drivers); list_for_each_entry(ucb, &ucb1x00_devices, node) { ucb1x00_add_dev(ucb, drv); } - mutex_unlock(&ucb1x00_mutex); + up(&ucb1x00_sem); return 0; } @@ -575,13 +574,13 @@ void ucb1x00_unregister_driver(struct ucb1x00_driver *drv) { struct list_head *n, *l; - mutex_lock(&ucb1x00_mutex); + down(&ucb1x00_sem); list_del(&drv->node); list_for_each_safe(l, n, &drv->devs) { struct ucb1x00_dev *dev = list_entry(l, struct ucb1x00_dev, drv_node); ucb1x00_remove_dev(dev); } - mutex_unlock(&ucb1x00_mutex); + up(&ucb1x00_sem); } static int ucb1x00_suspend(struct mcp *mcp, pm_message_t state) @@ -589,12 +588,12 @@ static int ucb1x00_suspend(struct mcp *mcp, pm_message_t state) struct ucb1x00 *ucb = mcp_get_drvdata(mcp); struct ucb1x00_dev *dev; - mutex_lock(&ucb1x00_mutex); + down(&ucb1x00_sem); list_for_each_entry(dev, &ucb->devs, dev_node) { if (dev->drv->suspend) dev->drv->suspend(dev, state); } - mutex_unlock(&ucb1x00_mutex); + up(&ucb1x00_sem); return 0; } @@ -603,12 +602,12 @@ static int ucb1x00_resume(struct mcp *mcp) struct ucb1x00 *ucb = mcp_get_drvdata(mcp); struct ucb1x00_dev *dev; - mutex_lock(&ucb1x00_mutex); + down(&ucb1x00_sem); list_for_each_entry(dev, &ucb->devs, dev_node) { if (dev->drv->resume) dev->drv->resume(dev); } - mutex_unlock(&ucb1x00_mutex); + up(&ucb1x00_sem); return 0; } diff --git a/trunk/drivers/mmc/mmc_block.c b/trunk/drivers/mmc/mmc_block.c index 9b7c37e0e574..f2c42b13945d 100644 --- a/trunk/drivers/mmc/mmc_block.c +++ b/trunk/drivers/mmc/mmc_block.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -58,33 +57,33 @@ struct mmc_blk_data { unsigned int read_only; }; -static DEFINE_MUTEX(open_lock); +static DECLARE_MUTEX(open_lock); static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) { struct mmc_blk_data *md; - mutex_lock(&open_lock); + down(&open_lock); md = disk->private_data; if (md && md->usage == 0) md = NULL; if (md) md->usage++; - mutex_unlock(&open_lock); + up(&open_lock); return md; } static void mmc_blk_put(struct mmc_blk_data *md) { - mutex_lock(&open_lock); + down(&open_lock); md->usage--; if (md->usage == 0) { put_disk(md->disk); mmc_cleanup_queue(&md->queue); kfree(md); } - mutex_unlock(&open_lock); + up(&open_lock); } static int mmc_blk_open(struct inode *inode, struct file *filp) diff --git a/trunk/drivers/net/hplance.c b/trunk/drivers/net/hplance.c index d8410634bcaf..08703d6f934c 100644 --- a/trunk/drivers/net/hplance.c +++ b/trunk/drivers/net/hplance.c @@ -150,7 +150,7 @@ static void __init hplance_init(struct net_device *dev, struct dio_dev *d) 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 = NULL; /* LANCE addr of same RAM */ + lp->lance.lance_init_block = 0; /* 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/trunk/drivers/net/iseries_veth.c b/trunk/drivers/net/iseries_veth.c index f0f04be989d6..77eadf84cb2c 100644 --- a/trunk/drivers/net/iseries_veth.c +++ b/trunk/drivers/net/iseries_veth.c @@ -590,9 +590,9 @@ static void veth_handle_event(struct HvLpEvent *event, struct pt_regs *regs) { struct veth_lpevent *veth_event = (struct veth_lpevent *)event; - if (hvlpevent_is_ack(event)) + if (event->xFlags.xFunction == HvLpEvent_Function_Ack) veth_handle_ack(veth_event); - else + else if (event->xFlags.xFunction == HvLpEvent_Function_Int) veth_handle_int(veth_event); } diff --git a/trunk/drivers/net/mac8390.c b/trunk/drivers/net/mac8390.c index 06cb460361a8..d8c99f038fa0 100644 --- a/trunk/drivers/net/mac8390.c +++ b/trunk/drivers/net/mac8390.c @@ -559,52 +559,55 @@ static void mac8390_no_reset(struct net_device *dev) /* directly from daynaport.c by Alan Cox */ static void dayna_memcpy_fromcard(struct net_device *dev, void *to, int from, int count) { - volatile unsigned char *ptr; - unsigned char *target=to; + volatile unsigned short *ptr; + unsigned short *target=to; from<<=1; /* word, skip overhead */ - ptr=(unsigned char *)(dev->mem_start+from); + ptr=(unsigned short *)(dev->mem_start+from); /* Leading byte? */ if (from&2) { - *target++ = ptr[-1]; - ptr += 2; + *((char *)target)++ = *(((char *)ptr++)-1); count--; } while(count>=2) { - *(unsigned short *)target = *(unsigned short volatile *)ptr; - ptr += 4; /* skip cruft */ - target += 2; + *target++=*ptr++; /* Copy and */ + ptr++; /* skip cruft */ count-=2; } /* Trailing byte? */ if(count) - *target = *ptr; + { + /* Big endian */ + unsigned short v=*ptr; + *((char *)target)=v>>8; + } } static void dayna_memcpy_tocard(struct net_device *dev, int to, const void *from, int count) { volatile unsigned short *ptr; - const unsigned char *src=from; + const unsigned short *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)|*src++; + ptr[-1] = (ptr[-1]&0xFF00)|*((unsigned char *)src)++; ptr++; count--; } while(count>=2) { - *ptr++=*(unsigned short *)src; /* Copy and */ + *ptr++=*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)|(*src << 8); + *ptr=(*ptr&0x00FF)|(v&0xFF00); } } diff --git a/trunk/drivers/net/sun3lance.c b/trunk/drivers/net/sun3lance.c index 01bdb2334058..5c8fcd40ef4d 100644 --- a/trunk/drivers/net/sun3lance.c +++ b/trunk/drivers/net/sun3lance.c @@ -389,7 +389,7 @@ static int __init lance_probe( struct net_device *dev) dev->stop = &lance_close; dev->get_stats = &lance_get_stats; dev->set_multicast_list = &set_multicast_list; - dev->set_mac_address = NULL; + dev->set_mac_address = 0; // KLUDGE -- REMOVE ME set_bit(__LINK_STATE_PRESENT, &dev->state); diff --git a/trunk/drivers/scsi/Makefile b/trunk/drivers/scsi/Makefile index 6e0c059df6a5..f062ea0f813a 100644 --- a/trunk/drivers/scsi/Makefile +++ b/trunk/drivers/scsi/Makefile @@ -45,7 +45,7 @@ obj-$(CONFIG_CYBERSTORMII_SCSI) += NCR53C9x.o cyberstormII.o 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_mod.o +obj-$(CONFIG_OKTAGON_SCSI) += NCR53C9x.o oktagon_esp.o oktagon_io.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,7 +164,6 @@ CFLAGS_ncr53c8xx.o := $(ncr53c8xx-flags-y) $(ncr53c8xx-flags-m) 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/trunk/drivers/scsi/NCR53C9x.c b/trunk/drivers/scsi/NCR53C9x.c index c7dd0154d012..640590bd014a 100644 --- a/trunk/drivers/scsi/NCR53C9x.c +++ b/trunk/drivers/scsi/NCR53C9x.c @@ -1799,7 +1799,6 @@ static int esp_do_data(struct NCR_ESP *esp, struct ESP_regs *eregs) */ 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; @@ -1861,7 +1860,7 @@ static int esp_do_data(struct NCR_ESP *esp, struct ESP_regs *eregs) /* read fifo */ for(j=0;jesp_fdata); + SCptr->SCp.ptr[i++] = esp_read(eregs->esp_fdata); ESPDATA(("(%d) ", i)); @@ -1883,7 +1882,7 @@ static int esp_do_data(struct NCR_ESP *esp, struct ESP_regs *eregs) /* fill fifo */ for(j=0;jesp_fdata, p[i++]); + esp_write(eregs->esp_fdata, SCptr->SCp.ptr[i++]); /* how many left if this goes out ?? */ hmuch -= this_count; diff --git a/trunk/drivers/scsi/blz1230.c b/trunk/drivers/scsi/blz1230.c index 3867ac2de4c2..763e409a1ff3 100644 --- a/trunk/drivers/scsi/blz1230.c +++ b/trunk/drivers/scsi/blz1230.c @@ -224,7 +224,7 @@ static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp) static void dma_dump_state(struct NCR_ESP *esp) { ESPLOG(("intreq:<%04x>, intena:<%04x>\n", - amiga_custom.intreqr, amiga_custom.intenar)); + custom.intreqr, custom.intenar)); } void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length) @@ -298,7 +298,7 @@ static int dma_irq_p(struct NCR_ESP *esp) static int dma_ports_p(struct NCR_ESP *esp) { - return ((amiga_custom.intenar) & IF_PORTS); + return ((custom.intenar) & IF_PORTS); } static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) diff --git a/trunk/drivers/scsi/blz2060.c b/trunk/drivers/scsi/blz2060.c index 4ebe69e32756..d72d05fffdfa 100644 --- a/trunk/drivers/scsi/blz2060.c +++ b/trunk/drivers/scsi/blz2060.c @@ -190,7 +190,7 @@ static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp) static void dma_dump_state(struct NCR_ESP *esp) { ESPLOG(("intreq:<%04x>, intena:<%04x>\n", - amiga_custom.intreqr, amiga_custom.intenar)); + custom.intreqr, custom.intenar)); } static void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length) @@ -251,7 +251,7 @@ static void dma_led_on(struct NCR_ESP *esp) static int dma_ports_p(struct NCR_ESP *esp) { - return ((amiga_custom.intenar) & IF_PORTS); + return ((custom.intenar) & IF_PORTS); } static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) diff --git a/trunk/drivers/scsi/cyberstorm.c b/trunk/drivers/scsi/cyberstorm.c index a4a4fac5c0a1..f9b940e56430 100644 --- a/trunk/drivers/scsi/cyberstorm.c +++ b/trunk/drivers/scsi/cyberstorm.c @@ -223,7 +223,7 @@ static void dma_dump_state(struct NCR_ESP *esp) esp->esp_id, ((struct cyber_dma_registers *) (esp->dregs))->cond_reg)); ESPLOG(("intreq:<%04x>, intena:<%04x>\n", - amiga_custom.intreqr, amiga_custom.intenar)); + custom.intreqr, custom.intenar)); } static void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length) @@ -322,7 +322,7 @@ static void dma_led_on(struct NCR_ESP *esp) static int dma_ports_p(struct NCR_ESP *esp) { - return ((amiga_custom.intenar) & IF_PORTS); + return ((custom.intenar) & IF_PORTS); } static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) diff --git a/trunk/drivers/scsi/cyberstormII.c b/trunk/drivers/scsi/cyberstormII.c index 3a803d73bc5f..a3caabfd7557 100644 --- a/trunk/drivers/scsi/cyberstormII.c +++ b/trunk/drivers/scsi/cyberstormII.c @@ -200,7 +200,7 @@ static void dma_dump_state(struct NCR_ESP *esp) esp->esp_id, ((struct cyberII_dma_registers *) (esp->dregs))->cond_reg)); ESPLOG(("intreq:<%04x>, intena:<%04x>\n", - amiga_custom.intreqr, amiga_custom.intenar)); + custom.intreqr, custom.intenar)); } static void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length) @@ -259,7 +259,7 @@ static void dma_led_on(struct NCR_ESP *esp) static int dma_ports_p(struct NCR_ESP *esp) { - return ((amiga_custom.intenar) & IF_PORTS); + return ((custom.intenar) & IF_PORTS); } static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) diff --git a/trunk/drivers/scsi/fastlane.c b/trunk/drivers/scsi/fastlane.c index 8ae9c406a83b..ccee68b52f7e 100644 --- a/trunk/drivers/scsi/fastlane.c +++ b/trunk/drivers/scsi/fastlane.c @@ -268,7 +268,7 @@ static void dma_dump_state(struct NCR_ESP *esp) esp->esp_id, ((struct fastlane_dma_registers *) (esp->dregs))->cond_reg)); ESPLOG(("intreq:<%04x>, intena:<%04x>\n", - amiga_custom.intreqr, amiga_custom.intenar)); + custom.intreqr, custom.intenar)); } static void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length) @@ -368,7 +368,7 @@ static void dma_led_on(struct NCR_ESP *esp) static int dma_ports_p(struct NCR_ESP *esp) { - return ((amiga_custom.intenar) & IF_PORTS); + return ((custom.intenar) & IF_PORTS); } static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) diff --git a/trunk/drivers/scsi/oktagon_esp.c b/trunk/drivers/scsi/oktagon_esp.c index dee426f8c07b..5d9c9ada814f 100644 --- a/trunk/drivers/scsi/oktagon_esp.c +++ b/trunk/drivers/scsi/oktagon_esp.c @@ -490,7 +490,7 @@ static void dma_led_on(struct NCR_ESP *esp) static int dma_ports_p(struct NCR_ESP *esp) { - return ((amiga_custom.intenar) & IF_PORTS); + return ((custom.intenar) & IF_PORTS); } static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) diff --git a/trunk/drivers/scsi/wd33c93.c b/trunk/drivers/scsi/wd33c93.c index fb53eeaee617..fd63add6a577 100644 --- a/trunk/drivers/scsi/wd33c93.c +++ b/trunk/drivers/scsi/wd33c93.c @@ -465,7 +465,7 @@ wd33c93_execute(struct Scsi_Host *instance) */ cmd = (struct scsi_cmnd *) hostdata->input_Q; - prev = NULL; + prev = 0; while (cmd) { if (!(hostdata->busy[cmd->device->id] & (1 << cmd->device->lun))) break; @@ -1569,7 +1569,7 @@ wd33c93_abort(struct scsi_cmnd * cmd) */ tmp = (struct scsi_cmnd *) hostdata->input_Q; - prev = NULL; + prev = 0; while (tmp) { if (tmp == cmd) { if (prev) diff --git a/trunk/drivers/serial/8250.c b/trunk/drivers/serial/8250.c index 54e5cc0dd5f8..fb610c3634a4 100644 --- a/trunk/drivers/serial/8250.c +++ b/trunk/drivers/serial/8250.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -2467,7 +2468,7 @@ static struct platform_device *serial8250_isa_devs; * 16x50 serial ports to be configured at run-time, to support PCMCIA * modems and PCI multiport cards. */ -static DECLARE_MUTEX(serial_sem); +static DEFINE_MUTEX(serial_mutex); static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *port) { @@ -2522,7 +2523,7 @@ int serial8250_register_port(struct uart_port *port) if (port->uartclk == 0) return -EINVAL; - down(&serial_sem); + mutex_lock(&serial_mutex); uart = serial8250_find_match_or_unused(port); if (uart) { @@ -2544,7 +2545,7 @@ int serial8250_register_port(struct uart_port *port) if (ret == 0) ret = uart->port.line; } - up(&serial_sem); + mutex_unlock(&serial_mutex); return ret; } @@ -2561,7 +2562,7 @@ void serial8250_unregister_port(int line) { struct uart_8250_port *uart = &serial8250_ports[line]; - down(&serial_sem); + mutex_lock(&serial_mutex); uart_remove_one_port(&serial8250_reg, &uart->port); if (serial8250_isa_devs) { uart->port.flags &= ~UPF_BOOT_AUTOCONF; @@ -2571,7 +2572,7 @@ void serial8250_unregister_port(int line) } else { uart->port.dev = NULL; } - up(&serial_sem); + mutex_unlock(&serial_mutex); } EXPORT_SYMBOL(serial8250_unregister_port); diff --git a/trunk/drivers/serial/crisv10.c b/trunk/drivers/serial/crisv10.c index 08c42c000188..be12623d8544 100644 --- a/trunk/drivers/serial/crisv10.c +++ b/trunk/drivers/serial/crisv10.c @@ -442,6 +442,7 @@ static char *serial_version = "$Revision: 1.25 $"; #include #include #include +#include #include #include @@ -1315,11 +1316,7 @@ static const struct control_pins e100_modem_pins[NR_PORTS] = * memory if large numbers of serial ports are open. */ static unsigned char *tmp_buf; -#ifdef DECLARE_MUTEX -static DECLARE_MUTEX(tmp_buf_sem); -#else -static struct semaphore tmp_buf_sem = MUTEX; -#endif +static DEFINE_MUTEX(tmp_buf_mutex); /* Calculate the chartime depending on baudrate, numbor of bits etc. */ static void update_char_time(struct e100_serial * info) @@ -3661,7 +3658,7 @@ rs_raw_write(struct tty_struct * tty, int from_user, * design. */ if (from_user) { - down(&tmp_buf_sem); + mutex_lock(&tmp_buf_mutex); while (1) { int c1; c = CIRC_SPACE_TO_END(info->xmit.head, @@ -3692,7 +3689,7 @@ rs_raw_write(struct tty_struct * tty, int from_user, count -= c; ret += c; } - up(&tmp_buf_sem); + mutex_unlock(&tmp_buf_mutex); } else { cli(); while (count) { diff --git a/trunk/drivers/serial/pmac_zilog.c b/trunk/drivers/serial/pmac_zilog.c index f330d6c0e0df..5f52883e64d2 100644 --- a/trunk/drivers/serial/pmac_zilog.c +++ b/trunk/drivers/serial/pmac_zilog.c @@ -60,6 +60,7 @@ #include #include #include +#include #include #include #include @@ -96,7 +97,7 @@ MODULE_LICENSE("GPL"); */ static struct uart_pmac_port pmz_ports[MAX_ZS_PORTS]; static int pmz_ports_count; -static DECLARE_MUTEX(pmz_irq_sem); +static DEFINE_MUTEX(pmz_irq_mutex); static struct uart_driver pmz_uart_reg = { .owner = THIS_MODULE, @@ -922,7 +923,7 @@ static int pmz_startup(struct uart_port *port) if (uap->node == NULL) return -ENODEV; - down(&pmz_irq_sem); + mutex_lock(&pmz_irq_mutex); uap->flags |= PMACZILOG_FLAG_IS_OPEN; @@ -940,11 +941,11 @@ static int pmz_startup(struct uart_port *port) dev_err(&uap->dev->ofdev.dev, "Unable to register zs interrupt handler.\n"); pmz_set_scc_power(uap, 0); - up(&pmz_irq_sem); + mutex_unlock(&pmz_irq_mutex); return -ENXIO; } - up(&pmz_irq_sem); + mutex_unlock(&pmz_irq_mutex); /* Right now, we deal with delay by blocking here, I'll be * smarter later on @@ -981,7 +982,7 @@ static void pmz_shutdown(struct uart_port *port) if (uap->node == NULL) return; - down(&pmz_irq_sem); + mutex_lock(&pmz_irq_mutex); /* Release interrupt handler */ free_irq(uap->port.irq, uap); @@ -1002,7 +1003,7 @@ static void pmz_shutdown(struct uart_port *port) if (ZS_IS_CONS(uap) || ZS_IS_ASLEEP(uap)) { spin_unlock_irqrestore(&port->lock, flags); - up(&pmz_irq_sem); + mutex_unlock(&pmz_irq_mutex); return; } @@ -1019,7 +1020,7 @@ static void pmz_shutdown(struct uart_port *port) spin_unlock_irqrestore(&port->lock, flags); - up(&pmz_irq_sem); + mutex_unlock(&pmz_irq_mutex); pmz_debug("pmz: shutdown() done.\n"); } @@ -1591,7 +1592,7 @@ static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state) state = pmz_uart_reg.state + uap->port.line; - down(&pmz_irq_sem); + mutex_lock(&pmz_irq_mutex); down(&state->sem); spin_lock_irqsave(&uap->port.lock, flags); @@ -1624,7 +1625,7 @@ static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state) pmz_set_scc_power(uap, 0); up(&state->sem); - up(&pmz_irq_sem); + mutex_unlock(&pmz_irq_mutex); pmz_debug("suspend, switching complete\n"); @@ -1651,7 +1652,7 @@ static int pmz_resume(struct macio_dev *mdev) state = pmz_uart_reg.state + uap->port.line; - down(&pmz_irq_sem); + mutex_lock(&pmz_irq_mutex); down(&state->sem); spin_lock_irqsave(&uap->port.lock, flags); @@ -1685,7 +1686,7 @@ static int pmz_resume(struct macio_dev *mdev) bail: up(&state->sem); - up(&pmz_irq_sem); + mutex_unlock(&pmz_irq_mutex); /* Right now, we deal with delay by blocking here, I'll be * smarter later on diff --git a/trunk/drivers/serial/serial_core.c b/trunk/drivers/serial/serial_core.c index 9589509fc5bd..2ca620900bcc 100644 --- a/trunk/drivers/serial/serial_core.c +++ b/trunk/drivers/serial/serial_core.c @@ -33,6 +33,7 @@ #include #include /* for serial_state and serial_icounter_struct */ #include +#include #include #include @@ -47,7 +48,7 @@ /* * This is used to lock changes in serial line configuration. */ -static DECLARE_MUTEX(port_sem); +static DEFINE_MUTEX(port_mutex); #define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) @@ -1472,7 +1473,7 @@ static struct uart_state *uart_get(struct uart_driver *drv, int line) { struct uart_state *state; - down(&port_sem); + mutex_lock(&port_mutex); state = drv->state + line; if (down_interruptible(&state->sem)) { state = ERR_PTR(-ERESTARTSYS); @@ -1509,7 +1510,7 @@ static struct uart_state *uart_get(struct uart_driver *drv, int line) } out: - up(&port_sem); + mutex_unlock(&port_mutex); return state; } @@ -2219,7 +2220,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) state = drv->state + port->line; - down(&port_sem); + mutex_lock(&port_mutex); if (state->port) { ret = -EINVAL; goto out; @@ -2255,7 +2256,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) register_console(port->cons); out: - up(&port_sem); + mutex_unlock(&port_mutex); return ret; } @@ -2279,7 +2280,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port) printk(KERN_ALERT "Removing wrong port: %p != %p\n", state->port, port); - down(&port_sem); + mutex_lock(&port_mutex); /* * Remove the devices from devfs @@ -2288,7 +2289,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port) uart_unconfigure_port(drv, state); state->port = NULL; - up(&port_sem); + mutex_unlock(&port_mutex); return 0; } diff --git a/trunk/drivers/serial/serial_txx9.c b/trunk/drivers/serial/serial_txx9.c index fdd1f1915a42..ee98a867bc6d 100644 --- a/trunk/drivers/serial/serial_txx9.c +++ b/trunk/drivers/serial/serial_txx9.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -1018,7 +1019,7 @@ static void serial_txx9_resume_port(int line) uart_resume_port(&serial_txx9_reg, &serial_txx9_ports[line].port); } -static DECLARE_MUTEX(serial_txx9_sem); +static DEFINE_MUTEX(serial_txx9_mutex); /** * serial_txx9_register_port - register a serial port @@ -1037,7 +1038,7 @@ static int __devinit serial_txx9_register_port(struct uart_port *port) struct uart_txx9_port *uart; int ret = -ENOSPC; - down(&serial_txx9_sem); + mutex_lock(&serial_txx9_mutex); for (i = 0; i < UART_NR; i++) { uart = &serial_txx9_ports[i]; if (uart->port.type == PORT_UNKNOWN) @@ -1058,7 +1059,7 @@ static int __devinit serial_txx9_register_port(struct uart_port *port) if (ret == 0) ret = uart->port.line; } - up(&serial_txx9_sem); + mutex_unlock(&serial_txx9_mutex); return ret; } @@ -1073,7 +1074,7 @@ static void __devexit serial_txx9_unregister_port(int line) { struct uart_txx9_port *uart = &serial_txx9_ports[line]; - down(&serial_txx9_sem); + mutex_lock(&serial_txx9_mutex); uart_remove_one_port(&serial_txx9_reg, &uart->port); uart->port.flags = 0; uart->port.type = PORT_UNKNOWN; @@ -1082,7 +1083,7 @@ static void __devexit serial_txx9_unregister_port(int line) uart->port.membase = 0; uart->port.dev = NULL; uart_add_one_port(&serial_txx9_reg, &uart->port); - up(&serial_txx9_sem); + mutex_unlock(&serial_txx9_mutex); } /* diff --git a/trunk/drivers/video/amifb.c b/trunk/drivers/video/amifb.c index 2c42a812655a..d549e215f3c5 100644 --- a/trunk/drivers/video/amifb.c +++ b/trunk/drivers/video/amifb.c @@ -590,8 +590,6 @@ static u_short maxfmode, chipset; #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 @@ -1166,8 +1164,8 @@ static void ami_update_display(void); 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 __user *data); -static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data); +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_cursorstate(struct fb_cursorstate *state); static int ami_set_cursorstate(struct fb_cursorstate *state); static void ami_set_sprite(void); @@ -2181,7 +2179,6 @@ static int amifb_ioctl(struct inode *inode, struct file *file, struct fb_var_cursorinfo var; struct fb_cursorstate state; } crsr; - void __user *argp = (void __user *)arg; int i; switch (cmd) { @@ -2189,32 +2186,33 @@ static int amifb_ioctl(struct inode *inode, struct file *file, i = ami_get_fix_cursorinfo(&crsr.fix); if (i) return i; - return copy_to_user(argp, &crsr.fix, + return copy_to_user((void *)arg, &crsr.fix, sizeof(crsr.fix)) ? -EFAULT : 0; case FBIOGET_VCURSORINFO: i = ami_get_var_cursorinfo(&crsr.var, - ((struct fb_var_cursorinfo __user *)arg)->data); + ((struct fb_var_cursorinfo *)arg)->data); if (i) return i; - return copy_to_user(argp, &crsr.var, + return copy_to_user((void *)arg, &crsr.var, sizeof(crsr.var)) ? -EFAULT : 0; case FBIOPUT_VCURSORINFO: - if (copy_from_user(&crsr.var, argp, sizeof(crsr.var))) + if (copy_from_user(&crsr.var, (void *)arg, + sizeof(crsr.var))) return -EFAULT; return ami_set_var_cursorinfo(&crsr.var, - ((struct fb_var_cursorinfo __user *)arg)->data); + ((struct fb_var_cursorinfo *)arg)->data); case FBIOGET_CURSORSTATE: i = ami_get_cursorstate(&crsr.state); if (i) return i; - return copy_to_user(argp, &crsr.state, + return copy_to_user((void *)arg, &crsr.state, sizeof(crsr.state)) ? -EFAULT : 0; case FBIOPUT_CURSORSTATE: - if (copy_from_user(&crsr.state, argp, + if (copy_from_user(&crsr.state, (void *)arg, sizeof(crsr.state))) return -EFAULT; return ami_set_cursorstate(&crsr.state); @@ -3327,7 +3325,7 @@ static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix) return 0; } -static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data) +static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data) { struct amifb_par *par = ¤tpar; register u_short *lspr, *sspr; @@ -3349,14 +3347,14 @@ static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user * var->yspot = par->crsr.spot_y; if (size > var->height*var->width) return -ENAMETOOLONG; - if (!access_ok(VERIFY_WRITE, data, size)) + if (!access_ok(VERIFY_WRITE, (void *)data, size)) return -EFAULT; delta = 1<crsr.fmode; lspr = lofsprite + (delta<<1); if (par->bplcon0 & BPC0_LACE) sspr = shfsprite + (delta<<1); else - sspr = NULL; + sspr = 0; for (height = (short)var->height-1; height >= 0; height--) { bits = 0; words = delta; datawords = 0; for (width = (short)var->width-1; width >= 0; width--) { @@ -3402,7 +3400,7 @@ static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user * return 0; } -static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data) +static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data) { struct amifb_par *par = ¤tpar; register u_short *lspr, *sspr; @@ -3429,7 +3427,7 @@ static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user * return -EINVAL; if (!var->height) return -EINVAL; - if (!access_ok(VERIFY_READ, data, var->width*var->height)) + if (!access_ok(VERIFY_READ, (void *)data, var->width*var->height)) return -EFAULT; delta = 1<height+2)< SPRITEMEMSIZE) return -EINVAL; memset(lspr, 0, (var->height+2)<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, data); + get_user(tdata, (char *)data); data++; #ifdef __mc68000__ asm volatile ( diff --git a/trunk/drivers/video/aty/atyfb_base.c b/trunk/drivers/video/aty/atyfb_base.c index ed81005cbdba..e370125e4fbc 100644 --- a/trunk/drivers/video/aty/atyfb_base.c +++ b/trunk/drivers/video/aty/atyfb_base.c @@ -3501,7 +3501,7 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi static int __devinit atyfb_atari_probe(void) { - struct atyfb_par *par; + struct aty_par *par; struct fb_info *info; int m64_num; u32 clock_r; diff --git a/trunk/drivers/video/macfb.c b/trunk/drivers/video/macfb.c index e6cbd9de944a..cfc748e94272 100644 --- a/trunk/drivers/video/macfb.c +++ b/trunk/drivers/video/macfb.c @@ -609,19 +609,18 @@ void __init macfb_setup(char *options) } } -static int __init macfb_init(void) +void __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 -ENODEV; + return; /* There can only be one internal video controller anyway so we're not too worried about this */ @@ -959,11 +958,11 @@ static int __init macfb_init(void) fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0); - err = register_framebuffer(&fb_info); - if (!err) - printk("fb%d: %s frame buffer device\n", - fb_info.node, fb_info.fix.id); - return err; + if (register_framebuffer(&fb_info) < 0) + return; + + printk("fb%d: %s frame buffer device\n", + fb_info.node, fb_info.fix.id); } module_init(macfb_init); diff --git a/trunk/drivers/zorro/proc.c b/trunk/drivers/zorro/proc.c index 7aa2d3de6d37..1a409c2c320c 100644 --- a/trunk/drivers/zorro/proc.c +++ b/trunk/drivers/zorro/proc.c @@ -45,7 +45,7 @@ proc_bus_zorro_lseek(struct file *file, loff_t off, int whence) } static ssize_t -proc_bus_zorro_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) +proc_bus_zorro_read(struct file *file, char *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/trunk/fs/compat_ioctl.c b/trunk/fs/compat_ioctl.c index 5dd0207ffd46..f0b7256b2f87 100644 --- a/trunk/fs/compat_ioctl.c +++ b/trunk/fs/compat_ioctl.c @@ -122,7 +122,6 @@ #include #include #include -#include /* Aiee. Someone does not find a difference between int and long */ #define EXT2_IOC32_GETFLAGS _IOR('f', 1, int) @@ -2736,20 +2735,6 @@ static int do_ncp_setprivatedata(unsigned int fd, unsigned int cmd, unsigned lon } #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) }, @@ -2977,20 +2962,6 @@ HANDLE_IOCTL(DMX_GET_EVENT, do_dmx_get_event) 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/trunk/fs/xfs/linux-2.6/xfs_aops.c b/trunk/fs/xfs/linux-2.6/xfs_aops.c index d1db8c17a74e..94d3cdfbf9b8 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_aops.c +++ b/trunk/fs/xfs/linux-2.6/xfs_aops.c @@ -40,10 +40,11 @@ #include "xfs_rw.h" #include "xfs_iomap.h" #include -#include #include 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 @@ -54,15 +55,17 @@ xfs_page_trace( 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 = page_offset(page); + loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT; int delalloc = -1, unmapped = -1, unwritten = -1; if (page_has_buffers(page)) xfs_count_page_state(page, &delalloc, &unmapped, &unwritten); - ip = xfs_vtoi(vp); + bdp = vn_bhv_lookup(VN_BHV_HEAD(vp), &xfs_vnodeops); + ip = XFS_BHVTOI(bdp); if (!ip->i_rwtrace) return; @@ -100,56 +103,15 @@ xfs_finish_ioend( 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. */ @@ -161,10 +123,21 @@ xfs_end_bio_unwritten( 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); } @@ -176,8 +149,7 @@ xfs_end_bio_unwritten( */ STATIC xfs_ioend_t * xfs_alloc_ioend( - struct inode *inode, - unsigned int type) + struct inode *inode) { xfs_ioend_t *ioend; @@ -190,25 +162,45 @@ xfs_alloc_ioend( */ 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; - 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); + INIT_WORK(&ioend->io_work, xfs_end_bio_unwritten, 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, @@ -226,260 +218,138 @@ xfs_map_blocks( return -error; } -STATIC inline int -xfs_iomap_valid( - xfs_iomap_t *iomapp, - loff_t offset) -{ - return offset >= iomapp->iomap_offset && - offset < iomapp->iomap_offset + iomapp->iomap_bsize; -} - /* - * BIO completion handler for buffered IO. + * Finds the corresponding mapping in block @map array of the + * given @offset within a @page. */ -STATIC int -xfs_end_bio( - struct bio *bio, - unsigned int bytes_done, - int error) -{ - xfs_ioend_t *ioend = bio->bi_private; - - if (bio->bi_size) - return 1; - - 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( +STATIC xfs_iomap_t * +xfs_offset_to_map( 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_iomap_t *iomapp, + unsigned long offset) { - xfs_ioend_t *ioend = *result; + loff_t full_offset; /* offset from start of file */ - if (!ioend || need_ioend || type != ioend->io_type) { - xfs_ioend_t *previous = *result; + ASSERT(offset < PAGE_CACHE_SIZE); - 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; - } + full_offset = page->index; /* NB: using 64bit number */ + full_offset <<= PAGE_CACHE_SHIFT; /* offset from file start */ + full_offset += offset; /* offset from page start */ - bh->b_private = NULL; - ioend->io_size += bh->b_size; + if (full_offset < iomapp->iomap_offset) + return NULL; + if (iomapp->iomap_offset + (iomapp->iomap_bsize -1) >= full_offset) + return iomapp; + return NULL; } STATIC void xfs_map_at_offset( + struct page *page, struct buffer_head *bh, - loff_t offset, + unsigned long 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); - sector_shift = block_bits - BBSHIFT; - bn = (iomapp->iomap_bn >> sector_shift) + - ((offset - iomapp->iomap_offset) >> block_bits); + delta = page->index; + delta <<= PAGE_CACHE_SHIFT; + delta += offset; + delta -= iomapp->iomap_offset; + delta >>= block_bits; - ASSERT(bn || (iomapp->iomap_flags & IOMAP_REALTIME)); + sector_shift = block_bits - BBSHIFT; + bn = iomapp->iomap_bn >> sector_shift; + bn += delta; + BUG_ON(!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->bt_bdev; + bh->b_bdev = iomapp->iomap_target->pbr_bdev; set_buffer_mapped(bh); clear_buffer_delay(bh); - clear_buffer_unwritten(bh); } /* - * Look for a page at index that is suitable for clustering. + * 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. */ STATIC unsigned int -xfs_probe_page( - struct page *page, - unsigned int pg_offset, - int mapped) +xfs_probe_unmapped_page( + struct address_space *mapping, + pgoff_t index, + unsigned int pg_offset) { + struct page *page; int ret = 0; - if (PageWriteback(page)) + page = find_trylock_page(mapping, index); + if (!page) return 0; + if (PageWriteback(page)) + goto out; if (page->mapping && PageDirty(page)) { if (page_has_buffers(page)) { @@ -487,101 +357,79 @@ xfs_probe_page( bh = head = page_buffers(page); do { - if (!buffer_uptodate(bh)) - break; - if (mapped != buffer_mapped(bh)) + if (buffer_mapped(bh) || !buffer_uptodate(bh)) break; ret += bh->b_size; if (ret >= pg_offset) break; } while ((bh = bh->b_this_page) != head); } else - ret = mapped ? 0 : PAGE_CACHE_SIZE; + ret = PAGE_CACHE_SIZE; } +out: + unlock_page(page); return ret; } -STATIC size_t -xfs_probe_cluster( +STATIC unsigned int +xfs_probe_unmapped_cluster( struct inode *inode, struct page *startpage, struct buffer_head *bh, - struct buffer_head *head, - int mapped) + struct buffer_head *head) { - struct pagevec pvec; pgoff_t tindex, tlast, tloff; - size_t total = 0; - int done = 0, i; + unsigned int pg_offset, len, total = 0; + struct address_space *mapping = inode->i_mapping; /* First sum forwards in this page */ do { - if (mapped != buffer_mapped(bh)) - return total; + if (buffer_mapped(bh)) + break; total += bh->b_size; } while ((bh = bh->b_this_page) != head); - /* 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; - } - + /* 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; total += len; - tindex++; } - - pagevec_release(&pvec); - cond_resched(); + if (tindex == tlast && + (pg_offset = i_size_read(inode) & (PAGE_CACHE_SIZE - 1))) { + total += xfs_probe_unmapped_page(mapping, + tindex, pg_offset); + } } - return total; } /* - * Test if a given page is suitable for writing as part of an unwritten - * or delayed allocate extent. + * 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. */ -STATIC int -xfs_is_delayed_page( - struct page *page, - unsigned int type) +STATIC struct page * +xfs_probe_delalloc_page( + struct inode *inode, + pgoff_t index) { + struct page *page; + + page = find_trylock_page(inode->i_mapping, index); + if (!page) + return NULL; if (PageWriteback(page)) - return 0; + goto out; if (page->mapping && page_has_buffers(page)) { struct buffer_head *bh, *head; @@ -589,156 +437,243 @@ xfs_is_delayed_page( bh = head = page_buffers(page); do { - 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 + if (buffer_unwritten(bh)) { + acceptable = 0; break; + } else if (buffer_delay(bh)) { + acceptable = 1; + } } while ((bh = bh->b_this_page) != head); if (acceptable) - return 1; + return page; + } + +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 int +STATIC void xfs_convert_page( struct inode *inode, struct page *page, - loff_t tindex, - xfs_iomap_t *mp, - xfs_ioend_t **ioendp, + xfs_iomap_t *iomapp, struct writeback_control *wbc, + void *private, int startio, int all_bh) { - struct buffer_head *bh, *head; - xfs_off_t end_offset; - unsigned long p_offset; - unsigned int type; + 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; int bbits = inode->i_blkbits; int len, page_dirty; - int count = 0, done = 0, uptodate = 1; - xfs_off_t offset = page_offset(page); - 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; + end_offset = (i_size_read(inode) & (PAGE_CACHE_SIZE - 1)); /* * 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, - i_size_read(inode)); - 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; + end_offset = max(end_offset, PAGE_CACHE_SIZE); + end_offset = roundup(end_offset, len); + page_dirty = end_offset / len; + offset = 0; bh = head = page_buffers(page); do { if (offset >= end_offset) break; - if (!buffer_uptodate(bh)) - uptodate = 0; - if (!(PageUptodate(page) || buffer_uptodate(bh))) { - done = 1; + if (!(PageUptodate(page) || buffer_uptodate(bh))) continue; - } - - 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 (buffer_mapped(bh) && all_bh && + !(buffer_unwritten(bh) || buffer_delay(bh))) { 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++; + bh_arr[index++] = bh; page_dirty--; - } else { - done = 1; } + continue; } - } while (offset += len, (bh = bh->b_this_page) != head); - - if (uptodate && bh == head) - SetPageUptodate(page); + tmp = xfs_offset_to_map(page, mp, offset); + if (!tmp) + continue; + ASSERT(!(tmp->iomap_flags & IOMAP_HOLE)); + ASSERT(!(tmp->iomap_flags & IOMAP_DELAY)); - 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; + /* 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); } } - xfs_start_page_writeback(page, wbc, !page_dirty, count); - } + 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); - return done; - fail_unlock_page: - unlock_page(page); - fail: - return 1; + if (startio && index) { + xfs_submit_page(page, wbc, bh_arr, index, 1, !page_dirty); + } else { + unlock_page(page); + } } /* @@ -750,31 +685,19 @@ xfs_cluster_write( 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 pagevec pvec; - int done = 0, i; + struct page *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)) + for (; tindex <= tlast; tindex++) { + page = xfs_probe_delalloc_page(inode, tindex); + if (!page) break; - - 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(); + xfs_convert_page(inode, page, iomapp, wbc, NULL, + startio, all_bh); } } @@ -805,22 +728,18 @@ xfs_page_state_convert( int startio, int unmapped) /* also implies page uptodate */ { - struct buffer_head *bh, *head; - xfs_iomap_t iomap; - xfs_ioend_t *ioend = NULL, *iohead = NULL; + struct buffer_head *bh_arr[MAX_BUF_PER_PAGE], *bh, *head; + xfs_iomap_t *iomp, iomap; loff_t offset; unsigned long p_offset = 0; - unsigned int type; __uint64_t end_offset; pgoff_t end_index, last_index, tlast; - ssize_t size, len; - int flags, err, iomap_valid = 0, uptodate = 1; - int page_dirty, count = 0, trylock_flag = 0; - int all_bh = unmapped; + int len, err, i, cnt = 0, uptodate = 1; + int flags; + int page_dirty; /* wait for other IO threads? */ - if (startio && (wbc->sync_mode == WB_SYNC_NONE && wbc->nonblocking)) - trylock_flag |= BMAPI_TRYLOCK; + flags = (startio && wbc->sync_mode != WB_SYNC_NONE) ? 0 : BMAPI_TRYLOCK; /* Is this page beyond the end of the file? */ offset = i_size_read(inode); @@ -835,173 +754,161 @@ xfs_page_state_convert( } } + 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 = min_t(unsigned long, end_offset & (PAGE_CACHE_SIZE - 1), - PAGE_CACHE_SIZE); - p_offset = p_offset ? roundup(p_offset, len) : PAGE_CACHE_SIZE; + p_offset = max(p_offset, PAGE_CACHE_SIZE); + p_offset = roundup(p_offset, len); 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) { - /* - * the iomap is actually still valid, but the ioend - * isn't. shouldn't happen too often. - */ - iomap_valid = 0; + if (!(PageUptodate(page) || buffer_uptodate(bh)) && !startio) continue; - } - if (iomap_valid) - iomap_valid = xfs_iomap_valid(&iomap, offset); + if (iomp) { + iomp = xfs_offset_to_map(page, &iomap, p_offset); + } /* * First case, map an unwritten extent and prepare for * extent state conversion transaction on completion. - * - * Second case, allocate space for a delalloc buffer. - * We can return EAGAIN here in the release page case. - * - * 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 (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 (!iomap_valid) { - if (type == IOMAP_NEW) { - size = xfs_probe_cluster(inode, - page, bh, head, 0); + 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 { - size = len; + set_bit(BH_Lock, &bh->b_state); } - - err = xfs_map_blocks(inode, offset, size, - &iomap, flags); - if (err) + 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; - iomap_valid = xfs_iomap_valid(&iomap, offset); + } + iomp = xfs_offset_to_map(page, &iomap, + p_offset); } - if (iomap_valid) { - xfs_map_at_offset(bh, offset, - inode->i_blkbits, &iomap); + if (iomp) { + xfs_map_at_offset(page, bh, p_offset, + inode->i_blkbits, iomp); if (startio) { - xfs_add_to_ioend(inode, bh, offset, - type, &ioend, - !iomap_valid); + bh_arr[cnt++] = bh; } 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)) { - iomap_valid = 0; - } - - if (!iohead) - iohead = ioend; - } while (offset += len, ((bh = bh->b_this_page) != head)); + 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--; + } + } + } + } while (offset += len, p_offset += len, + ((bh = bh->b_this_page) != head)); if (uptodate && bh == head) SetPageUptodate(page); - if (startio) - xfs_start_page_writeback(page, wbc, 1, count); + if (startio) { + xfs_submit_page(page, wbc, bh_arr, cnt, 0, !page_dirty); + } - if (ioend && iomap_valid) { - offset = (iomap.iomap_offset + iomap.iomap_bsize - 1) >> + if (iomp) { + offset = (iomp->iomap_offset + iomp->iomap_bsize - 1) >> PAGE_CACHE_SHIFT; tlast = min_t(pgoff_t, offset, last_index); - xfs_cluster_write(inode, page->index + 1, &iomap, &ioend, - wbc, startio, all_bh, tlast); + xfs_cluster_write(inode, page->index + 1, iomp, wbc, + startio, unmapped, tlast); } - if (iohead) - xfs_submit_ioend(iohead); - return page_dirty; error: - if (iohead) - xfs_cancel_ioend(iohead); + for (i = 0; i < cnt; i++) { + unlock_buffer(bh_arr[i]); + } /* * If it's delalloc and we have nowhere to put it, @@ -1009,8 +916,9 @@ xfs_page_state_convert( * us to try again. */ if (err != -EAGAIN) { - if (!unmapped) + if (!unmapped) { block_invalidatepage(page, 0); + } ClearPageUptodate(page); } return err; @@ -1074,7 +982,7 @@ __linvfs_get_block( } /* If this is a realtime file, data might be on a new device */ - bh_result->b_bdev = iomap.iomap_target->bt_bdev; + bh_result->b_bdev = iomap.iomap_target->pbr_bdev; /* If we previously allocated a block out beyond eof and * we are now coming back to use it then we will need to @@ -1186,10 +1094,10 @@ linvfs_direct_IO( if (error) return -error; - iocb->private = xfs_alloc_ioend(inode, IOMAP_UNWRITTEN); + iocb->private = xfs_alloc_ioend(inode); ret = blockdev_direct_IO_own_locking(rw, iocb, inode, - iomap.iomap_target->bt_bdev, + iomap.iomap_target->pbr_bdev, iov, offset, nr_segs, linvfs_get_blocks_direct, linvfs_end_io_direct); diff --git a/trunk/fs/xfs/linux-2.6/xfs_aops.h b/trunk/fs/xfs/linux-2.6/xfs_aops.h index 55339dd5a30d..4720758a9ade 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_aops.h +++ b/trunk/fs/xfs/linux-2.6/xfs_aops.h @@ -23,24 +23,14 @@ extern mempool_t *xfs_ioend_pool; 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/trunk/fs/xfs/linux-2.6/xfs_buf.c b/trunk/fs/xfs/linux-2.6/xfs_buf.c index e44b7c1a3a36..6fe21d2b8847 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_buf.c +++ b/trunk/fs/xfs/linux-2.6/xfs_buf.c @@ -31,77 +31,76 @@ #include #include "xfs_linux.h" -STATIC kmem_zone_t *xfs_buf_zone; -STATIC kmem_shaker_t xfs_buf_shake; -STATIC int xfsbufd(void *); +STATIC kmem_cache_t *pagebuf_zone; +STATIC kmem_shaker_t pagebuf_shake; STATIC int xfsbufd_wakeup(int, gfp_t); -STATIC void xfs_buf_delwri_queue(xfs_buf_t *, int); +STATIC void pagebuf_delwri_queue(xfs_buf_t *, int); STATIC struct workqueue_struct *xfslogd_workqueue; struct workqueue_struct *xfsdatad_workqueue; -#ifdef XFS_BUF_TRACE +#ifdef PAGEBUF_TRACE void -xfs_buf_trace( - xfs_buf_t *bp, +pagebuf_trace( + xfs_buf_t *pb, char *id, void *data, void *ra) { - 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, + 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, (void *)current, data, ra, - (void *)(unsigned long)((bp->b_file_offset>>32) & 0xffffffff), - (void *)(unsigned long)(bp->b_file_offset & 0xffffffff), - (void *)(unsigned long)bp->b_buffer_length, + (void *)(unsigned long)((pb->pb_file_offset>>32) & 0xffffffff), + (void *)(unsigned long)(pb->pb_file_offset & 0xffffffff), + (void *)(unsigned long)pb->pb_buffer_length, NULL, NULL, NULL, NULL, NULL); } -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)) +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)) #else -#define XB_TRACE(bp, id, data) do { } while (0) +#define PB_TRACE(pb, id, data) do { } while (0) #endif -#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) +#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) #else -# define XB_SET_OWNER(bp) do { } while (0) -# define XB_CLEAR_OWNER(bp) do { } while (0) -# define XB_GET_OWNER(bp) do { } while (0) +# define PB_SET_OWNER(pb) do { } while (0) +# define PB_CLEAR_OWNER(pb) do { } while (0) +# define PB_GET_OWNER(pb) do { } while (0) #endif -#define xb_to_gfp(flags) \ - ((((flags) & XBF_READ_AHEAD) ? __GFP_NORETRY : \ - ((flags) & XBF_DONT_BLOCK) ? GFP_NOFS : GFP_KERNEL) | __GFP_NOWARN) +#define pb_to_gfp(flags) \ + ((((flags) & PBF_READ_AHEAD) ? __GFP_NORETRY : \ + ((flags) & PBF_DONT_BLOCK) ? GFP_NOFS : GFP_KERNEL) | __GFP_NOWARN) -#define xb_to_km(flags) \ - (((flags) & XBF_DONT_BLOCK) ? KM_NOFS : KM_SLEEP) +#define pb_to_km(flags) \ + (((flags) & PBF_DONT_BLOCK) ? KM_NOFS : KM_SLEEP) -#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)); +#define pagebuf_allocate(flags) \ + kmem_zone_alloc(pagebuf_zone, pb_to_km(flags)) +#define pagebuf_deallocate(pb) \ + kmem_zone_free(pagebuf_zone, (pb)); /* - * 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) */ @@ -160,7 +159,7 @@ test_page_region( } /* - * Mapping of multi-page buffers into contiguous virtual space + * Mapping of multi-page buffers into contiguous virtual space */ typedef struct a_list { @@ -173,7 +172,7 @@ STATIC int as_list_len; 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( @@ -216,83 +215,83 @@ purge_addresses(void) } /* - * Internal xfs_buf_t object manipulation + * Internal pagebuf object manipulation */ STATIC void -_xfs_buf_initialize( - xfs_buf_t *bp, +_pagebuf_initialize( + xfs_buf_t *pb, xfs_buftarg_t *target, - xfs_off_t range_base, + loff_t range_base, size_t range_length, - xfs_buf_flags_t flags) + page_buf_flags_t flags) { /* - * We don't want certain flags to appear in b_flags. + * We don't want certain flags to appear in pb->pb_flags. */ - flags &= ~(XBF_LOCK|XBF_MAPPED|XBF_DONT_BLOCK|XBF_READ_AHEAD); - - 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; + flags &= ~(PBF_LOCK|PBF_MAPPED|PBF_DONT_BLOCK|PBF_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; /* * 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). */ - 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(xb_create); - XB_TRACE(bp, "initialize", target); + 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); + + XFS_STATS_INC(pb_create); + PB_TRACE(pb, "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 -_xfs_buf_get_pages( - xfs_buf_t *bp, +_pagebuf_get_pages( + xfs_buf_t *pb, int page_count, - xfs_buf_flags_t flags) + page_buf_flags_t flags) { /* Make sure that we have a page list */ - 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; + 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; } else { - bp->b_pages = kmem_alloc(sizeof(struct page *) * - page_count, xb_to_km(flags)); - if (bp->b_pages == NULL) + pb->pb_pages = kmem_alloc(sizeof(struct page *) * + page_count, pb_to_km(flags)); + if (pb->pb_pages == NULL) return -ENOMEM; } - memset(bp->b_pages, 0, sizeof(struct page *) * page_count); + memset(pb->pb_pages, 0, sizeof(struct page *) * page_count); } return 0; } /* - * Frees b_pages if it was allocated. + * Frees pb_pages if it was malloced. */ STATIC void -_xfs_buf_free_pages( +_pagebuf_free_pages( xfs_buf_t *bp) { - if (bp->b_pages != bp->b_page_array) { - kmem_free(bp->b_pages, - bp->b_page_count * sizeof(struct page *)); + if (bp->pb_pages != bp->pb_page_array) { + kmem_free(bp->pb_pages, + bp->pb_page_count * sizeof(struct page *)); } } @@ -300,79 +299,79 @@ _xfs_buf_free_pages( * Releases the specified buffer. * * The modification state of any associated pages is left unchanged. - * The buffer most not be on any hash - use xfs_buf_rele instead for + * The buffer most not be on any hash - use pagebuf_rele instead for * hashed and refcounted buffers */ void -xfs_buf_free( +pagebuf_free( xfs_buf_t *bp) { - XB_TRACE(bp, "free", 0); + PB_TRACE(bp, "free", 0); - ASSERT(list_empty(&bp->b_hash_list)); + ASSERT(list_empty(&bp->pb_hash_list)); - if (bp->b_flags & _XBF_PAGE_CACHE) { + if (bp->pb_flags & _PBF_PAGE_CACHE) { uint i; - if ((bp->b_flags & XBF_MAPPED) && (bp->b_page_count > 1)) - free_address(bp->b_addr - bp->b_offset); + if ((bp->pb_flags & PBF_MAPPED) && (bp->pb_page_count > 1)) + free_address(bp->pb_addr - bp->pb_offset); - 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) { + 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) { /* - * XXX(hch): bp->b_count_desired might be incorrect (see - * xfs_buf_associate_memory for details), but fortunately + * XXX(hch): bp->pb_count_desired might be incorrect (see + * pagebuf_associate_memory for details), but fortunately * the Linux version of kmem_free ignores the len argument.. */ - kmem_free(bp->b_addr, bp->b_count_desired); - _xfs_buf_free_pages(bp); + kmem_free(bp->pb_addr, bp->pb_count_desired); + _pagebuf_free_pages(bp); } - xfs_buf_deallocate(bp); + pagebuf_deallocate(bp); } /* * Finds all pages for buffer in question and builds it's page list. */ STATIC int -_xfs_buf_lookup_pages( +_pagebuf_lookup_pages( xfs_buf_t *bp, uint flags) { - struct address_space *mapping = bp->b_target->bt_mapping; - size_t blocksize = bp->b_target->bt_bsize; - size_t size = bp->b_count_desired; + struct address_space *mapping = bp->pb_target->pbr_mapping; + size_t blocksize = bp->pb_target->pbr_bsize; + size_t size = bp->pb_count_desired; size_t nbytes, offset; - gfp_t gfp_mask = xb_to_gfp(flags); + gfp_t gfp_mask = pb_to_gfp(flags); unsigned short page_count, i; pgoff_t first; - xfs_off_t end; + loff_t end; int error; - end = bp->b_file_offset + bp->b_buffer_length; - page_count = xfs_buf_btoc(end) - xfs_buf_btoct(bp->b_file_offset); + end = bp->pb_file_offset + bp->pb_buffer_length; + page_count = page_buf_btoc(end) - page_buf_btoct(bp->pb_file_offset); - error = _xfs_buf_get_pages(bp, page_count, flags); + error = _pagebuf_get_pages(bp, page_count, flags); if (unlikely(error)) return error; - bp->b_flags |= _XBF_PAGE_CACHE; + bp->pb_flags |= _PBF_PAGE_CACHE; - offset = bp->b_offset; - first = bp->b_file_offset >> PAGE_CACHE_SHIFT; + offset = bp->pb_offset; + first = bp->pb_file_offset >> PAGE_CACHE_SHIFT; - for (i = 0; i < bp->b_page_count; i++) { + for (i = 0; i < bp->pb_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 & XBF_READ_AHEAD) { - bp->b_page_count = i; - for (i = 0; i < bp->b_page_count; i++) - unlock_page(bp->b_pages[i]); + 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]); return -ENOMEM; } @@ -388,13 +387,13 @@ _xfs_buf_lookup_pages( "deadlock in %s (mode:0x%x)\n", __FUNCTION__, gfp_mask); - XFS_STATS_INC(xb_page_retries); + XFS_STATS_INC(pb_page_retries); xfsbufd_wakeup(0, gfp_mask); blk_congestion_wait(WRITE, HZ/50); goto retry; } - XFS_STATS_INC(xb_page_found); + XFS_STATS_INC(pb_page_found); nbytes = min_t(size_t, size, PAGE_CACHE_SIZE - offset); size -= nbytes; @@ -402,27 +401,27 @@ _xfs_buf_lookup_pages( if (!PageUptodate(page)) { page_count--; if (blocksize >= PAGE_CACHE_SIZE) { - if (flags & XBF_READ) - bp->b_locked = 1; + if (flags & PBF_READ) + bp->pb_locked = 1; } else if (!PagePrivate(page)) { if (test_page_region(page, offset, nbytes)) page_count++; } } - bp->b_pages[i] = page; + bp->pb_pages[i] = page; offset = 0; } - if (!bp->b_locked) { - for (i = 0; i < bp->b_page_count; i++) - unlock_page(bp->b_pages[i]); + if (!bp->pb_locked) { + for (i = 0; i < bp->pb_page_count; i++) + unlock_page(bp->pb_pages[i]); } - if (page_count == bp->b_page_count) - bp->b_flags |= XBF_DONE; + if (page_count == bp->pb_page_count) + bp->pb_flags |= PBF_DONE; - XB_TRACE(bp, "lookup_pages", (long)page_count); + PB_TRACE(bp, "lookup_pages", (long)page_count); return error; } @@ -430,23 +429,23 @@ _xfs_buf_lookup_pages( * Map buffer into kernel address-space if nessecary. */ STATIC int -_xfs_buf_map_pages( +_pagebuf_map_pages( xfs_buf_t *bp, uint flags) { /* A single page buffer is always mappable */ - 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 (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 (as_list_len > 64) purge_addresses(); - bp->b_addr = vmap(bp->b_pages, bp->b_page_count, - VM_MAP, PAGE_KERNEL); - if (unlikely(bp->b_addr == NULL)) + bp->pb_addr = vmap(bp->pb_pages, bp->pb_page_count, + VM_MAP, PAGE_KERNEL); + if (unlikely(bp->pb_addr == NULL)) return -ENOMEM; - bp->b_addr += bp->b_offset; - bp->b_flags |= XBF_MAPPED; + bp->pb_addr += bp->pb_offset; + bp->pb_flags |= PBF_MAPPED; } return 0; @@ -457,7 +456,9 @@ _xfs_buf_map_pages( */ /* - * Look up, and creates if absent, a lockable buffer for + * _pagebuf_find + * + * Looks 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, @@ -465,55 +466,55 @@ _xfs_buf_map_pages( * are unlocked. No I/O is implied by this call. */ xfs_buf_t * -_xfs_buf_find( +_pagebuf_find( xfs_buftarg_t *btp, /* block device target */ - xfs_off_t ioff, /* starting offset of range */ + loff_t ioff, /* starting offset of range */ size_t isize, /* length of range */ - xfs_buf_flags_t flags, - xfs_buf_t *new_bp) + page_buf_flags_t flags, /* PBF_TRYLOCK */ + xfs_buf_t *new_pb)/* newly allocated buffer */ { - xfs_off_t range_base; + loff_t range_base; size_t range_length; xfs_bufhash_t *hash; - xfs_buf_t *bp, *n; + xfs_buf_t *pb, *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->bt_sshift))); - ASSERT(!(range_base & (xfs_off_t)btp->bt_smask)); + ASSERT(!(range_length < (1 << btp->pbr_sshift))); + ASSERT(!(range_base & (loff_t)btp->pbr_smask)); hash = &btp->bt_hash[hash_long((unsigned long)ioff, btp->bt_hashshift)]; spin_lock(&hash->bh_lock); - 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) { + 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) { /* - * 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(&bp->b_hold); - list_move(&bp->b_hash_list, &hash->bh_list); + atomic_inc(&pb->pb_hold); + list_move(&pb->pb_hash_list, &hash->bh_list); goto found; } } /* No match found */ - if (new_bp) { - _xfs_buf_initialize(new_bp, btp, range_base, + if (new_pb) { + _pagebuf_initialize(new_pb, btp, range_base, range_length, flags); - new_bp->b_hash = hash; - list_add(&new_bp->b_hash_list, &hash->bh_list); + new_pb->pb_hash = hash; + list_add(&new_pb->pb_hash_list, &hash->bh_list); } else { - XFS_STATS_INC(xb_miss_locked); + XFS_STATS_INC(pb_miss_locked); } spin_unlock(&hash->bh_lock); - return new_bp; + return new_pb; found: spin_unlock(&hash->bh_lock); @@ -522,72 +523,74 @@ _xfs_buf_find( * if this does not work then we need to drop the * spinlock and do a hard attempt on the semaphore. */ - if (down_trylock(&bp->b_sema)) { - if (!(flags & XBF_TRYLOCK)) { + if (down_trylock(&pb->pb_sema)) { + if (!(flags & PBF_TRYLOCK)) { /* wait for buffer ownership */ - XB_TRACE(bp, "get_lock", 0); - xfs_buf_lock(bp); - XFS_STATS_INC(xb_get_locked_waited); + PB_TRACE(pb, "get_lock", 0); + pagebuf_lock(pb); + XFS_STATS_INC(pb_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 buffer at least overlaps our - * buffer and is locked, therefore our buffer - * either does not exist, or is this buffer. + * know that this pagebuf at least overlaps our + * pagebuf and is locked, therefore our buffer + * either does not exist, or is this buffer */ - xfs_buf_rele(bp); - XFS_STATS_INC(xb_busy_locked); - return NULL; + + pagebuf_rele(pb); + XFS_STATS_INC(pb_busy_locked); + return (NULL); } } else { /* trylock worked */ - XB_SET_OWNER(bp); + PB_SET_OWNER(pb); } - if (bp->b_flags & XBF_STALE) { - ASSERT((bp->b_flags & _XBF_DELWRI_Q) == 0); - bp->b_flags &= XBF_MAPPED; + if (pb->pb_flags & PBF_STALE) { + ASSERT((pb->pb_flags & _PBF_DELWRI_Q) == 0); + pb->pb_flags &= PBF_MAPPED; } - XB_TRACE(bp, "got_lock", 0); - XFS_STATS_INC(xb_get_locked); - return bp; + PB_TRACE(pb, "got_lock", 0); + XFS_STATS_INC(pb_get_locked); + return (pb); } /* - * Assembles a buffer covering the specified range. + * xfs_buf_get_flags 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( +xfs_buf_get_flags( /* allocate a buffer */ xfs_buftarg_t *target,/* target for buffer */ - xfs_off_t ioff, /* starting offset of range */ + loff_t ioff, /* starting offset of range */ size_t isize, /* length of range */ - xfs_buf_flags_t flags) + page_buf_flags_t flags) /* PBF_TRYLOCK */ { - xfs_buf_t *bp, *new_bp; + xfs_buf_t *pb, *new_pb; int error = 0, i; - new_bp = xfs_buf_allocate(flags); - if (unlikely(!new_bp)) + new_pb = pagebuf_allocate(flags); + if (unlikely(!new_pb)) return NULL; - bp = _xfs_buf_find(target, ioff, isize, flags, new_bp); - if (bp == new_bp) { - error = _xfs_buf_lookup_pages(bp, flags); + pb = _pagebuf_find(target, ioff, isize, flags, new_pb); + if (pb == new_pb) { + error = _pagebuf_lookup_pages(pb, flags); if (error) goto no_buffer; } else { - xfs_buf_deallocate(new_bp); - if (unlikely(bp == NULL)) + pagebuf_deallocate(new_pb); + if (unlikely(pb == NULL)) return NULL; } - for (i = 0; i < bp->b_page_count; i++) - mark_page_accessed(bp->b_pages[i]); + for (i = 0; i < pb->pb_page_count; i++) + mark_page_accessed(pb->pb_pages[i]); - if (!(bp->b_flags & XBF_MAPPED)) { - error = _xfs_buf_map_pages(bp, flags); + if (!(pb->pb_flags & PBF_MAPPED)) { + error = _pagebuf_map_pages(pb, flags); if (unlikely(error)) { printk(KERN_WARNING "%s: failed to map pages\n", __FUNCTION__); @@ -595,97 +598,97 @@ xfs_buf_get_flags( } } - XFS_STATS_INC(xb_get); + XFS_STATS_INC(pb_get); /* * Always fill in the block number now, the mapped cases can do * their own overlay of this later. */ - bp->b_bn = ioff; - bp->b_count_desired = bp->b_buffer_length; + pb->pb_bn = ioff; + pb->pb_count_desired = pb->pb_buffer_length; - XB_TRACE(bp, "get", (unsigned long)flags); - return bp; + PB_TRACE(pb, "get", (unsigned long)flags); + return pb; no_buffer: - if (flags & (XBF_LOCK | XBF_TRYLOCK)) - xfs_buf_unlock(bp); - xfs_buf_rele(bp); + if (flags & (PBF_LOCK | PBF_TRYLOCK)) + pagebuf_unlock(pb); + pagebuf_rele(pb); return NULL; } xfs_buf_t * xfs_buf_read_flags( xfs_buftarg_t *target, - xfs_off_t ioff, + loff_t ioff, size_t isize, - xfs_buf_flags_t flags) + page_buf_flags_t flags) { - xfs_buf_t *bp; - - flags |= XBF_READ; - - 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); + xfs_buf_t *pb; + + flags |= PBF_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); /* * Read ahead call which is already satisfied, * drop the buffer */ goto no_buffer; } else { - XB_TRACE(bp, "read_done", (unsigned long)flags); + PB_TRACE(pb, "read_done", (unsigned long)flags); /* We do not want read in the flags */ - bp->b_flags &= ~XBF_READ; + pb->pb_flags &= ~PBF_READ; } } - return bp; + return pb; no_buffer: - if (flags & (XBF_LOCK | XBF_TRYLOCK)) - xfs_buf_unlock(bp); - xfs_buf_rele(bp); + if (flags & (PBF_LOCK | PBF_TRYLOCK)) + pagebuf_unlock(pb); + pagebuf_rele(pb); 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 -xfs_buf_readahead( +pagebuf_readahead( xfs_buftarg_t *target, - xfs_off_t ioff, + loff_t ioff, size_t isize, - xfs_buf_flags_t flags) + page_buf_flags_t flags) { struct backing_dev_info *bdi; - bdi = target->bt_mapping->backing_dev_info; + bdi = target->pbr_mapping->backing_dev_info; if (bdi_read_congested(bdi)) return; - flags |= (XBF_TRYLOCK|XBF_ASYNC|XBF_READ_AHEAD); + flags |= (PBF_TRYLOCK|PBF_ASYNC|PBF_READ_AHEAD); xfs_buf_read_flags(target, ioff, isize, flags); } xfs_buf_t * -xfs_buf_get_empty( +pagebuf_get_empty( size_t len, xfs_buftarg_t *target) { - xfs_buf_t *bp; + xfs_buf_t *pb; - bp = xfs_buf_allocate(0); - if (bp) - _xfs_buf_initialize(bp, target, 0, len, 0); - return bp; + pb = pagebuf_allocate(0); + if (pb) + _pagebuf_initialize(pb, target, 0, len, 0); + return pb; } static inline struct page * @@ -701,8 +704,8 @@ mem_to_page( } int -xfs_buf_associate_memory( - xfs_buf_t *bp, +pagebuf_associate_memory( + xfs_buf_t *pb, void *mem, size_t len) { @@ -719,40 +722,40 @@ xfs_buf_associate_memory( page_count++; /* Free any previous set of page pointers */ - if (bp->b_pages) - _xfs_buf_free_pages(bp); + if (pb->pb_pages) + _pagebuf_free_pages(pb); - bp->b_pages = NULL; - bp->b_addr = mem; + pb->pb_pages = NULL; + pb->pb_addr = mem; - rval = _xfs_buf_get_pages(bp, page_count, 0); + rval = _pagebuf_get_pages(pb, page_count, 0); if (rval) return rval; - bp->b_offset = offset; + pb->pb_offset = offset; ptr = (size_t) mem & PAGE_CACHE_MASK; end = PAGE_CACHE_ALIGN((size_t) mem + len); end_cur = end; /* set up first page */ - bp->b_pages[0] = mem_to_page(mem); + pb->pb_pages[0] = mem_to_page(mem); ptr += PAGE_CACHE_SIZE; - bp->b_page_count = ++i; + pb->pb_page_count = ++i; while (ptr < end) { - bp->b_pages[i] = mem_to_page((void *)ptr); - bp->b_page_count = ++i; + pb->pb_pages[i] = mem_to_page((void *)ptr); + pb->pb_page_count = ++i; ptr += PAGE_CACHE_SIZE; } - bp->b_locked = 0; + pb->pb_locked = 0; - bp->b_count_desired = bp->b_buffer_length = len; - bp->b_flags |= XBF_MAPPED; + pb->pb_count_desired = pb->pb_buffer_length = len; + pb->pb_flags |= PBF_MAPPED; return 0; } xfs_buf_t * -xfs_buf_get_noaddr( +pagebuf_get_no_daddr( size_t len, xfs_buftarg_t *target) { @@ -761,10 +764,10 @@ xfs_buf_get_noaddr( void *data; int error; - bp = xfs_buf_allocate(0); + bp = pagebuf_allocate(0); if (unlikely(bp == NULL)) goto fail; - _xfs_buf_initialize(bp, target, 0, len, 0); + _pagebuf_initialize(bp, target, 0, len, 0); try_again: data = kmem_alloc(malloc_len, KM_SLEEP | KM_MAYFAIL); @@ -773,73 +776,78 @@ xfs_buf_get_noaddr( /* check whether alignment matches.. */ if ((__psunsigned_t)data != - ((__psunsigned_t)data & ~target->bt_smask)) { + ((__psunsigned_t)data & ~target->pbr_smask)) { /* .. else double the size and try again */ kmem_free(data, malloc_len); malloc_len <<= 1; goto try_again; } - error = xfs_buf_associate_memory(bp, data, len); + error = pagebuf_associate_memory(bp, data, len); if (error) goto fail_free_mem; - bp->b_flags |= _XBF_KMEM_ALLOC; + bp->pb_flags |= _PBF_KMEM_ALLOC; - xfs_buf_unlock(bp); + pagebuf_unlock(bp); - XB_TRACE(bp, "no_daddr", data); + PB_TRACE(bp, "no_daddr", data); return bp; fail_free_mem: kmem_free(data, malloc_len); fail_free_buf: - xfs_buf_free(bp); + pagebuf_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 -xfs_buf_hold( - xfs_buf_t *bp) +pagebuf_hold( + xfs_buf_t *pb) { - atomic_inc(&bp->b_hold); - XB_TRACE(bp, "hold", 0); + atomic_inc(&pb->pb_hold); + PB_TRACE(pb, "hold", 0); } /* - * Releases a hold on the specified buffer. If the - * the hold count is 1, calls xfs_buf_free. + * pagebuf_rele + * + * pagebuf_rele releases a hold on the specified buffer. If the + * the hold count is 1, pagebuf_rele calls pagebuf_free. */ void -xfs_buf_rele( - xfs_buf_t *bp) +pagebuf_rele( + xfs_buf_t *pb) { - xfs_bufhash_t *hash = bp->b_hash; + xfs_bufhash_t *hash = pb->pb_hash; - XB_TRACE(bp, "rele", bp->b_relse); + PB_TRACE(pb, "rele", pb->pb_relse); - if (atomic_dec_and_lock(&bp->b_hold, &hash->bh_lock)) { - if (bp->b_relse) { - atomic_inc(&bp->b_hold); + if (atomic_dec_and_lock(&pb->pb_hold, &hash->bh_lock)) { + if (pb->pb_relse) { + atomic_inc(&pb->pb_hold); spin_unlock(&hash->bh_lock); - (*(bp->b_relse)) (bp); - } else if (bp->b_flags & XBF_FS_MANAGED) { + (*(pb->pb_relse)) (pb); + } else if (pb->pb_flags & PBF_FS_MANAGED) { spin_unlock(&hash->bh_lock); } else { - ASSERT(!(bp->b_flags & (XBF_DELWRI|_XBF_DELWRI_Q))); - list_del_init(&bp->b_hash_list); + ASSERT(!(pb->pb_flags & (PBF_DELWRI|_PBF_DELWRI_Q))); + list_del_init(&pb->pb_hash_list); spin_unlock(&hash->bh_lock); - xfs_buf_free(bp); + pagebuf_free(pb); } } else { /* * Catch reference count leaks */ - ASSERT(atomic_read(&bp->b_hold) >= 0); + ASSERT(atomic_read(&pb->pb_hold) >= 0); } } @@ -855,122 +863,168 @@ xfs_buf_rele( */ /* - * 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. + * 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. */ int -xfs_buf_cond_lock( - xfs_buf_t *bp) +pagebuf_cond_lock( /* lock buffer, if not locked */ + /* returns -EBUSY if locked) */ + xfs_buf_t *pb) { int locked; - locked = down_trylock(&bp->b_sema) == 0; + locked = down_trylock(&pb->pb_sema) == 0; if (locked) { - XB_SET_OWNER(bp); + PB_SET_OWNER(pb); } - XB_TRACE(bp, "cond_lock", (long)locked); - return locked ? 0 : -EBUSY; + PB_TRACE(pb, "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 -xfs_buf_lock_value( - xfs_buf_t *bp) +pagebuf_lock_value( + xfs_buf_t *pb) { - return atomic_read(&bp->b_sema.count); + return(atomic_read(&pb->pb_sema.count)); } #endif /* - * 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. + * 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. */ -void -xfs_buf_lock( - xfs_buf_t *bp) +int +pagebuf_lock( + xfs_buf_t *pb) { - 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); + 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; } /* - * Releases the lock on the buffer object. + * 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). + * * 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 -xfs_buf_unlock( - xfs_buf_t *bp) +pagebuf_unlock( /* unlock buffer */ + xfs_buf_t *pb) /* buffer to unlock */ { - 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); + 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); } - XB_CLEAR_OWNER(bp); - up(&bp->b_sema); - XB_TRACE(bp, "unlock", 0); + PB_CLEAR_OWNER(pb); + up(&pb->pb_sema); + PB_TRACE(pb, "unlock", 0); } /* * Pinning Buffer Storage in Memory - * Ensure that no attempt to force a buffer to disk will succeed. + */ + +/* + * 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. */ void -xfs_buf_pin( - xfs_buf_t *bp) +pagebuf_pin( + xfs_buf_t *pb) { - atomic_inc(&bp->b_pin_count); - XB_TRACE(bp, "pin", (long)bp->b_pin_count.counter); + atomic_inc(&pb->pb_pin_count); + PB_TRACE(pb, "pin", (long)pb->pb_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 -xfs_buf_unpin( - xfs_buf_t *bp) +pagebuf_unpin( + xfs_buf_t *pb) { - 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); + 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); } int -xfs_buf_ispin( - xfs_buf_t *bp) +pagebuf_ispin( + xfs_buf_t *pb) { - return atomic_read(&bp->b_pin_count); + return atomic_read(&pb->pb_pin_count); } -STATIC void -xfs_buf_wait_unpin( - xfs_buf_t *bp) +/* + * 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) { DECLARE_WAITQUEUE (wait, current); - if (atomic_read(&bp->b_pin_count) == 0) + if (atomic_read(&pb->pb_pin_count) == 0) return; - add_wait_queue(&bp->b_waiters, &wait); + add_wait_queue(&pb->pb_waiters, &wait); for (;;) { set_current_state(TASK_UNINTERRUPTIBLE); - if (atomic_read(&bp->b_pin_count) == 0) + if (atomic_read(&pb->pb_pin_count) == 0) break; - if (atomic_read(&bp->b_io_remaining)) - blk_run_address_space(bp->b_target->bt_mapping); + if (atomic_read(&pb->pb_io_remaining)) + blk_run_address_space(pb->pb_target->pbr_mapping); schedule(); } - remove_wait_queue(&bp->b_waiters, &wait); + remove_wait_queue(&pb->pb_waiters, &wait); set_current_state(TASK_RUNNING); } @@ -978,216 +1032,241 @@ xfs_buf_wait_unpin( * 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 -xfs_buf_iodone_work( +pagebuf_iodone_work( void *v) { xfs_buf_t *bp = (xfs_buf_t *)v; - if (bp->b_iodone) - (*(bp->b_iodone))(bp); - else if (bp->b_flags & XBF_ASYNC) + if (bp->pb_iodone) + (*(bp->pb_iodone))(bp); + else if (bp->pb_flags & PBF_ASYNC) xfs_buf_relse(bp); } void -xfs_buf_ioend( - xfs_buf_t *bp, +pagebuf_iodone( + xfs_buf_t *pb, int schedule) { - bp->b_flags &= ~(XBF_READ | XBF_WRITE); - if (bp->b_error == 0) - bp->b_flags |= XBF_DONE; + pb->pb_flags &= ~(PBF_READ | PBF_WRITE); + if (pb->pb_error == 0) + pb->pb_flags |= PBF_DONE; - XB_TRACE(bp, "iodone", bp->b_iodone); + PB_TRACE(pb, "iodone", pb->pb_iodone); - if ((bp->b_iodone) || (bp->b_flags & XBF_ASYNC)) { + if ((pb->pb_iodone) || (pb->pb_flags & PBF_ASYNC)) { if (schedule) { - INIT_WORK(&bp->b_iodone_work, xfs_buf_iodone_work, bp); - queue_work(xfslogd_workqueue, &bp->b_iodone_work); + INIT_WORK(&pb->pb_iodone_work, pagebuf_iodone_work, pb); + queue_work(xfslogd_workqueue, &pb->pb_iodone_work); } else { - xfs_buf_iodone_work(bp); + pagebuf_iodone_work(pb); } } else { - up(&bp->b_iodonesema); + up(&pb->pb_iodonesema); } } +/* + * pagebuf_ioerror + * + * pagebuf_ioerror sets the error code for a buffer. + */ void -xfs_buf_ioerror( - xfs_buf_t *bp, - int error) +pagebuf_ioerror( /* mark/clear buffer error flag */ + xfs_buf_t *pb, /* buffer to mark */ + int error) /* error to store (0 if none) */ { ASSERT(error >= 0 && error <= 0xffff); - bp->b_error = (unsigned short)error; - XB_TRACE(bp, "ioerror", (unsigned long)error); + pb->pb_error = (unsigned short)error; + PB_TRACE(pb, "ioerror", (unsigned long)error); } /* - * Initiate I/O on a buffer, based on the flags supplied. - * The b_iodone routine in the buffer supplied will only be called + * 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 * 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 -xfs_buf_iostart( - xfs_buf_t *bp, - xfs_buf_flags_t flags) +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 */ { int status = 0; - XB_TRACE(bp, "iostart", (unsigned long)flags); + PB_TRACE(pb, "iostart", (unsigned long)flags); - 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); + 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); return status; } - 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); + 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); - BUG_ON(bp->b_bn == XFS_BUF_DADDR_NULL); + BUG_ON(pb->pb_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 & XBF_WRITE) ? - xfs_buf_iostrategy(bp) : xfs_buf_iorequest(bp); + status = (flags & PBF_WRITE) ? + pagebuf_iostrategy(pb) : pagebuf_iorequest(pb); /* 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 & XBF_ASYNC)) - status = xfs_buf_iowait(bp); + if (!status && !(flags & PBF_ASYNC)) + status = pagebuf_iowait(pb); return status; } +/* + * Helper routine for pagebuf_iorequest + */ + STATIC __inline__ int -_xfs_buf_iolocked( - xfs_buf_t *bp) +_pagebuf_iolocked( + xfs_buf_t *pb) { - ASSERT(bp->b_flags & (XBF_READ | XBF_WRITE)); - if (bp->b_flags & XBF_READ) - return bp->b_locked; + ASSERT(pb->pb_flags & (PBF_READ|PBF_WRITE)); + if (pb->pb_flags & PBF_READ) + return pb->pb_locked; return 0; } STATIC __inline__ void -_xfs_buf_ioend( - xfs_buf_t *bp, +_pagebuf_iodone( + xfs_buf_t *pb, int schedule) { - if (atomic_dec_and_test(&bp->b_io_remaining) == 1) { - bp->b_locked = 0; - xfs_buf_ioend(bp, schedule); + if (atomic_dec_and_test(&pb->pb_io_remaining) == 1) { + pb->pb_locked = 0; + pagebuf_iodone(pb, schedule); } } STATIC int -xfs_buf_bio_end_io( +bio_end_io_pagebuf( struct bio *bio, unsigned int bytes_done, int error) { - xfs_buf_t *bp = (xfs_buf_t *)bio->bi_private; - unsigned int blocksize = bp->b_target->bt_bsize; + xfs_buf_t *pb = (xfs_buf_t *)bio->bi_private; + unsigned int blocksize = pb->pb_target->pbr_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)) - bp->b_error = EIO; + pb->pb_error = EIO; do { struct page *page = bvec->bv_page; - if (unlikely(bp->b_error)) { - if (bp->b_flags & XBF_READ) + if (unlikely(pb->pb_error)) { + if (pb->pb_flags & PBF_READ) ClearPageUptodate(page); SetPageError(page); - } else if (blocksize >= PAGE_CACHE_SIZE) { + } else if (blocksize == PAGE_CACHE_SIZE) { SetPageUptodate(page); } else if (!PagePrivate(page) && - (bp->b_flags & _XBF_PAGE_CACHE)) { + (pb->pb_flags & _PBF_PAGE_CACHE)) { set_page_region(page, bvec->bv_offset, bvec->bv_len); } if (--bvec >= bio->bi_io_vec) prefetchw(&bvec->bv_page->flags); - if (_xfs_buf_iolocked(bp)) { + if (_pagebuf_iolocked(pb)) { unlock_page(page); } } while (bvec >= bio->bi_io_vec); - _xfs_buf_ioend(bp, 1); + _pagebuf_iodone(pb, 1); bio_put(bio); return 0; } STATIC void -_xfs_buf_ioapply( - xfs_buf_t *bp) +_pagebuf_ioapply( + xfs_buf_t *pb) { int i, rw, map_i, total_nr_pages, nr_pages; struct bio *bio; - 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); + 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); - total_nr_pages = bp->b_page_count; + total_nr_pages = pb->pb_page_count; map_i = 0; - if (bp->b_flags & _XBF_RUN_QUEUES) { - bp->b_flags &= ~_XBF_RUN_QUEUES; - rw = (bp->b_flags & XBF_READ) ? READ_SYNC : WRITE_SYNC; + if (pb->pb_flags & _PBF_RUN_QUEUES) { + pb->pb_flags &= ~_PBF_RUN_QUEUES; + rw = (pb->pb_flags & PBF_READ) ? READ_SYNC : WRITE_SYNC; } else { - rw = (bp->b_flags & XBF_READ) ? READ : WRITE; + rw = (pb->pb_flags & PBF_READ) ? READ : WRITE; } - if (bp->b_flags & XBF_ORDERED) { - ASSERT(!(bp->b_flags & XBF_READ)); + if (pb->pb_flags & PBF_ORDERED) { + ASSERT(!(pb->pb_flags & PBF_READ)); rw = WRITE_BARRIER; } - /* Special code path for reading a sub page size buffer in -- + /* Special code path for reading a sub page size pagebuf 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 is not smaller than the page size. + * filesystem block size and the page size are equal. */ - if ((bp->b_buffer_length < PAGE_CACHE_SIZE) && - (bp->b_flags & XBF_READ) && locking && - (blocksize >= PAGE_CACHE_SIZE)) { + if ((pb->pb_buffer_length < PAGE_CACHE_SIZE) && + (pb->pb_flags & PBF_READ) && locking && + (blocksize == PAGE_CACHE_SIZE)) { bio = bio_alloc(GFP_NOIO, 1); - bio->bi_bdev = bp->b_target->bt_bdev; + bio->bi_bdev = pb->pb_target->pbr_bdev; bio->bi_sector = sector - (offset >> BBSHIFT); - bio->bi_end_io = xfs_buf_bio_end_io; - bio->bi_private = bp; + bio->bi_end_io = bio_end_io_pagebuf; + bio->bi_private = pb; - bio_add_page(bio, bp->b_pages[0], PAGE_CACHE_SIZE, 0); + bio_add_page(bio, pb->pb_pages[0], PAGE_CACHE_SIZE, 0); size = 0; - atomic_inc(&bp->b_io_remaining); + atomic_inc(&pb->pb_io_remaining); goto submit_io; } /* Lock down the pages which we need to for the request */ - if (locking && (bp->b_flags & XBF_WRITE) && (bp->b_locked == 0)) { + if (locking && (pb->pb_flags & PBF_WRITE) && (pb->pb_locked == 0)) { for (i = 0; size; i++) { int nbytes = PAGE_CACHE_SIZE - offset; - struct page *page = bp->b_pages[i]; + struct page *page = pb->pb_pages[i]; if (nbytes > size) nbytes = size; @@ -1197,30 +1276,30 @@ _xfs_buf_ioapply( size -= nbytes; offset = 0; } - offset = bp->b_offset; - size = bp->b_count_desired; + offset = pb->pb_offset; + size = pb->pb_count_desired; } next_chunk: - atomic_inc(&bp->b_io_remaining); + atomic_inc(&pb->pb_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 = bp->b_target->bt_bdev; + bio->bi_bdev = pb->pb_target->pbr_bdev; bio->bi_sector = sector; - bio->bi_end_io = xfs_buf_bio_end_io; - bio->bi_private = bp; + bio->bi_end_io = bio_end_io_pagebuf; + bio->bi_private = pb; for (; size && nr_pages; nr_pages--, map_i++) { - int rbytes, nbytes = PAGE_CACHE_SIZE - offset; + int nbytes = PAGE_CACHE_SIZE - offset; if (nbytes > size) nbytes = size; - rbytes = bio_add_page(bio, bp->b_pages[map_i], nbytes, offset); - if (rbytes < nbytes) + if (bio_add_page(bio, pb->pb_pages[map_i], + nbytes, offset) < nbytes) break; offset = 0; @@ -1236,102 +1315,107 @@ _xfs_buf_ioapply( goto next_chunk; } else { bio_put(bio); - xfs_buf_ioerror(bp, EIO); + pagebuf_ioerror(pb, EIO); } } +/* + * pagebuf_iorequest -- the core I/O request routine. + */ int -xfs_buf_iorequest( - xfs_buf_t *bp) +pagebuf_iorequest( /* start real I/O */ + xfs_buf_t *pb) /* buffer to convey to device */ { - XB_TRACE(bp, "iorequest", 0); + PB_TRACE(pb, "iorequest", 0); - if (bp->b_flags & XBF_DELWRI) { - xfs_buf_delwri_queue(bp, 1); + if (pb->pb_flags & PBF_DELWRI) { + pagebuf_delwri_queue(pb, 1); return 0; } - if (bp->b_flags & XBF_WRITE) { - xfs_buf_wait_unpin(bp); + if (pb->pb_flags & PBF_WRITE) { + _pagebuf_wait_unpin(pb); } - xfs_buf_hold(bp); + pagebuf_hold(pb); /* 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 xfs_buf_ioend too early. + * all the I/O from calling pagebuf_iodone too early. */ - atomic_set(&bp->b_io_remaining, 1); - _xfs_buf_ioapply(bp); - _xfs_buf_ioend(bp, 0); + atomic_set(&pb->pb_io_remaining, 1); + _pagebuf_ioapply(pb); + _pagebuf_iodone(pb, 0); - xfs_buf_rele(bp); + pagebuf_rele(pb); return 0; } /* - * 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. + * 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. */ int -xfs_buf_iowait( - xfs_buf_t *bp) +pagebuf_iowait( + xfs_buf_t *pb) { - 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; + 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; } -xfs_caddr_t -xfs_buf_offset( - xfs_buf_t *bp, +caddr_t +pagebuf_offset( + xfs_buf_t *pb, size_t offset) { struct page *page; - if (bp->b_flags & XBF_MAPPED) - return XFS_BUF_PTR(bp) + offset; + offset += pb->pb_offset; - offset += bp->b_offset; - page = bp->b_pages[offset >> PAGE_CACHE_SHIFT]; - return (xfs_caddr_t)page_address(page) + (offset & (PAGE_CACHE_SIZE-1)); + page = pb->pb_pages[offset >> PAGE_CACHE_SHIFT]; + return (caddr_t) page_address(page) + (offset & (PAGE_CACHE_SIZE - 1)); } /* + * pagebuf_iomove + * * Move data into or out of a buffer. */ void -xfs_buf_iomove( - xfs_buf_t *bp, /* buffer to process */ +pagebuf_iomove( + xfs_buf_t *pb, /* buffer to process */ size_t boff, /* starting buffer offset */ size_t bsize, /* length to copy */ caddr_t data, /* data address */ - xfs_buf_rw_t mode) /* read/write/zero flag */ + page_buf_rw_t mode) /* read/write flag */ { size_t bend, cpoff, csize; struct page *page; bend = boff + bsize; while (boff < bend) { - page = bp->b_pages[xfs_buf_btoct(boff + bp->b_offset)]; - cpoff = xfs_buf_poff(boff + bp->b_offset); + page = pb->pb_pages[page_buf_btoct(boff + pb->pb_offset)]; + cpoff = page_buf_poff(boff + pb->pb_offset); csize = min_t(size_t, - PAGE_CACHE_SIZE-cpoff, bp->b_count_desired-boff); + PAGE_CACHE_SIZE-cpoff, pb->pb_count_desired-boff); ASSERT(((csize + cpoff) <= PAGE_CACHE_SIZE)); switch (mode) { - case XBRW_ZERO: + case PBRW_ZERO: memset(page_address(page) + cpoff, 0, csize); break; - case XBRW_READ: + case PBRW_READ: memcpy(data, page_address(page) + cpoff, csize); break; - case XBRW_WRITE: + case PBRW_WRITE: memcpy(page_address(page) + cpoff, data, csize); } @@ -1341,12 +1425,12 @@ xfs_buf_iomove( } /* - * Handling of buffer targets (buftargs). + * Handling of 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( @@ -1360,15 +1444,15 @@ xfs_wait_buftarg( hash = &btp->bt_hash[i]; again: spin_lock(&hash->bh_lock); - 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)) { + 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)) { spin_unlock(&hash->bh_lock); /* * Catch superblock reference count leaks * immediately */ - BUG_ON(bp->b_bn == 0); + BUG_ON(bp->pb_bn == 0); delay(100); goto again; } @@ -1378,9 +1462,9 @@ xfs_wait_buftarg( } /* - * 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( @@ -1403,34 +1487,11 @@ STATIC void xfs_free_bufhash( xfs_buftarg_t *btp) { - kmem_free(btp->bt_hash, (1<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, @@ -1438,16 +1499,9 @@ xfs_free_buftarg( { xfs_flush_buftarg(btp, 1); if (external) - xfs_blkdev_put(btp->bt_bdev); + xfs_blkdev_put(btp->pbr_bdev); xfs_free_bufhash(btp); - 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); - + iput(btp->pbr_mapping->host); kmem_free(btp, sizeof(*btp)); } @@ -1458,11 +1512,11 @@ xfs_setsize_buftarg_flags( unsigned int sectorsize, int verbose) { - btp->bt_bsize = blocksize; - btp->bt_sshift = ffs(sectorsize) - 1; - btp->bt_smask = sectorsize - 1; + btp->pbr_bsize = blocksize; + btp->pbr_sshift = ffs(sectorsize) - 1; + btp->pbr_smask = sectorsize - 1; - if (set_blocksize(btp->bt_bdev, sectorsize)) { + if (set_blocksize(btp->pbr_bdev, sectorsize)) { printk(KERN_WARNING "XFS: Cannot set_blocksize to %u on device %s\n", sectorsize, XFS_BUFTARG_NAME(btp)); @@ -1482,10 +1536,10 @@ xfs_setsize_buftarg_flags( } /* - * 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, @@ -1533,30 +1587,10 @@ xfs_mapping_buftarg( mapping->a_ops = &mapping_aops; mapping->backing_dev_info = bdi; mapping_set_gfp_mask(mapping, GFP_NOFS); - btp->bt_mapping = mapping; + btp->pbr_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, @@ -1566,14 +1600,12 @@ xfs_alloc_buftarg( btp = kmem_zalloc(sizeof(*btp), KM_SLEEP); - btp->bt_dev = bdev->bd_dev; - btp->bt_bdev = bdev; + btp->pbr_dev = bdev->bd_dev; + btp->pbr_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; @@ -1584,81 +1616,83 @@ xfs_alloc_buftarg( /* - * Delayed write buffer handling + * Pagebuf delayed write buffer handling */ + +STATIC LIST_HEAD(pbd_delwrite_queue); +STATIC DEFINE_SPINLOCK(pbd_delwrite_lock); + STATIC void -xfs_buf_delwri_queue( - xfs_buf_t *bp, +pagebuf_delwri_queue( + xfs_buf_t *pb, int unlock) { - struct list_head *dwq = &bp->b_target->bt_delwrite_queue; - spinlock_t *dwlk = &bp->b_target->bt_delwrite_lock; - - XB_TRACE(bp, "delwri_q", (long)unlock); - ASSERT((bp->b_flags&(XBF_DELWRI|XBF_ASYNC)) == (XBF_DELWRI|XBF_ASYNC)); + PB_TRACE(pb, "delwri_q", (long)unlock); + ASSERT((pb->pb_flags & (PBF_DELWRI|PBF_ASYNC)) == + (PBF_DELWRI|PBF_ASYNC)); - spin_lock(dwlk); + spin_lock(&pbd_delwrite_lock); /* If already in the queue, dequeue and place at tail */ - 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); + 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); } - bp->b_flags |= _XBF_DELWRI_Q; - list_add_tail(&bp->b_list, dwq); - bp->b_queuetime = jiffies; - spin_unlock(dwlk); + pb->pb_flags |= _PBF_DELWRI_Q; + list_add_tail(&pb->pb_list, &pbd_delwrite_queue); + pb->pb_queuetime = jiffies; + spin_unlock(&pbd_delwrite_lock); if (unlock) - xfs_buf_unlock(bp); + pagebuf_unlock(pb); } void -xfs_buf_delwri_dequeue( - xfs_buf_t *bp) +pagebuf_delwri_dequeue( + xfs_buf_t *pb) { - spinlock_t *dwlk = &bp->b_target->bt_delwrite_lock; int dequeued = 0; - 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); + 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); dequeued = 1; } - bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q); - spin_unlock(dwlk); + pb->pb_flags &= ~(PBF_DELWRI|_PBF_DELWRI_Q); + spin_unlock(&pbd_delwrite_lock); if (dequeued) - xfs_buf_rele(bp); + pagebuf_rele(pb); - XB_TRACE(bp, "delwri_dq", (long)dequeued); + PB_TRACE(pb, "delwri_dq", (long)dequeued); } STATIC void -xfs_buf_runall_queues( +pagebuf_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) { - 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); + if (xfsbufd_force_sleep) + return 0; + xfsbufd_force_flush = 1; + barrier(); + wake_up_process(xfsbufd_task); return 0; } @@ -1668,70 +1702,67 @@ xfsbufd( { struct list_head tmp; unsigned long age; - 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; + xfs_buftarg_t *target; + xfs_buf_t *pb, *n; current->flags |= PF_MEMALLOC; INIT_LIST_HEAD(&tmp); do { if (unlikely(freezing(current))) { - set_bit(XBT_FORCE_SLEEP, &target->bt_flags); + xfsbufd_force_sleep = 1; refrigerator(); } else { - clear_bit(XBT_FORCE_SLEEP, &target->bt_flags); + xfsbufd_force_sleep = 0; } schedule_timeout_interruptible( xfs_buf_timer_centisecs * msecs_to_jiffies(10)); age = xfs_buf_age_centisecs * msecs_to_jiffies(10); - 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 (!xfs_buf_ispin(bp) && !xfs_buf_cond_lock(bp)) { - if (!test_bit(XBT_FORCE_FLUSH, - &target->bt_flags) && + 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); + + if (!pagebuf_ispin(pb) && !pagebuf_cond_lock(pb)) { + if (!xfsbufd_force_flush && time_before(jiffies, - bp->b_queuetime + age)) { - xfs_buf_unlock(bp); + pb->pb_queuetime + age)) { + pagebuf_unlock(pb); break; } - bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q); - bp->b_flags |= XBF_WRITE; - list_move(&bp->b_list, &tmp); + pb->pb_flags &= ~(PBF_DELWRI|_PBF_DELWRI_Q); + pb->pb_flags |= PBF_WRITE; + list_move(&pb->pb_list, &tmp); } } - spin_unlock(dwlk); + spin_unlock(&pbd_delwrite_lock); while (!list_empty(&tmp)) { - bp = list_entry(tmp.next, xfs_buf_t, b_list); - ASSERT(target == bp->b_target); + pb = list_entry(tmp.next, xfs_buf_t, pb_list); + target = pb->pb_target; - list_del_init(&bp->b_list); - xfs_buf_iostrategy(bp); + list_del_init(&pb->pb_list); + pagebuf_iostrategy(pb); - blk_run_address_space(target->bt_mapping); + blk_run_address_space(target->pbr_mapping); } if (as_list_len > 0) purge_addresses(); - clear_bit(XBT_FORCE_FLUSH, &target->bt_flags); + xfsbufd_force_flush = 0; } 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( @@ -1739,72 +1770,73 @@ xfs_flush_buftarg( int wait) { struct list_head tmp; - xfs_buf_t *bp, *n; + xfs_buf_t *pb, *n; int pincount = 0; - struct list_head *dwq = &target->bt_delwrite_queue; - spinlock_t *dwlk = &target->bt_delwrite_lock; - xfs_buf_runall_queues(xfsdatad_workqueue); - xfs_buf_runall_queues(xfslogd_workqueue); + pagebuf_runall_queues(xfsdatad_workqueue); + pagebuf_runall_queues(xfslogd_workqueue); INIT_LIST_HEAD(&tmp); - 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)) { + 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)) { pincount++; continue; } - list_move(&bp->b_list, &tmp); + list_move(&pb->pb_list, &tmp); } - spin_unlock(dwlk); + spin_unlock(&pbd_delwrite_lock); /* * Dropped the delayed write list lock, now walk the temporary list */ - 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; + 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; if (wait) - bp->b_flags &= ~XBF_ASYNC; + pb->pb_flags &= ~PBF_ASYNC; else - list_del_init(&bp->b_list); + list_del_init(&pb->pb_list); - xfs_buf_iostrategy(bp); + pagebuf_iostrategy(pb); } /* * Remaining list items must be flushed before returning */ while (!list_empty(&tmp)) { - bp = list_entry(tmp.next, xfs_buf_t, b_list); + pb = list_entry(tmp.next, xfs_buf_t, pb_list); - list_del_init(&bp->b_list); - xfs_iowait(bp); - xfs_buf_relse(bp); + list_del_init(&pb->pb_list); + xfs_iowait(pb); + xfs_buf_relse(pb); } if (wait) - blk_run_address_space(target->bt_mapping); + blk_run_address_space(target->pbr_mapping); return pincount; } int __init -xfs_buf_init(void) +pagebuf_init(void) { int error = -ENOMEM; -#ifdef XFS_BUF_TRACE - xfs_buf_trace_buf = ktrace_alloc(XFS_BUF_TRACE_SIZE, KM_SLEEP); +#ifdef PAGEBUF_TRACE + pagebuf_trace_buf = ktrace_alloc(PAGEBUF_TRACE_SIZE, KM_SLEEP); #endif - xfs_buf_zone = kmem_zone_init(sizeof(xfs_buf_t), "xfs_buf"); - if (!xfs_buf_zone) + pagebuf_zone = kmem_zone_init(sizeof(xfs_buf_t), "xfs_buf"); + if (!pagebuf_zone) goto out_free_trace_buf; xfslogd_workqueue = create_workqueue("xfslogd"); @@ -1815,33 +1847,42 @@ xfs_buf_init(void) if (!xfsdatad_workqueue) goto out_destroy_xfslogd_workqueue; - xfs_buf_shake = kmem_shake_register(xfsbufd_wakeup); - if (!xfs_buf_shake) + xfsbufd_task = kthread_run(xfsbufd, NULL, "xfsbufd"); + if (IS_ERR(xfsbufd_task)) { + error = PTR_ERR(xfsbufd_task); 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(xfs_buf_zone); + kmem_zone_destroy(pagebuf_zone); out_free_trace_buf: -#ifdef XFS_BUF_TRACE - ktrace_free(xfs_buf_trace_buf); +#ifdef PAGEBUF_TRACE + ktrace_free(pagebuf_trace_buf); #endif return error; } void -xfs_buf_terminate(void) +pagebuf_terminate(void) { - kmem_shake_deregister(xfs_buf_shake); + kmem_shake_deregister(pagebuf_shake); + kthread_stop(xfsbufd_task); destroy_workqueue(xfsdatad_workqueue); destroy_workqueue(xfslogd_workqueue); - kmem_zone_destroy(xfs_buf_zone); -#ifdef XFS_BUF_TRACE - ktrace_free(xfs_buf_trace_buf); + kmem_zone_destroy(pagebuf_zone); +#ifdef PAGEBUF_TRACE + ktrace_free(pagebuf_trace_buf); #endif } diff --git a/trunk/fs/xfs/linux-2.6/xfs_buf.h b/trunk/fs/xfs/linux-2.6/xfs_buf.h index 4dd6592d5a4c..237a35b915d1 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_buf.h +++ b/trunk/fs/xfs/linux-2.6/xfs_buf.h @@ -32,47 +32,44 @@ * Base types */ -#define XFS_BUF_DADDR_NULL ((xfs_daddr_t) (-1LL)) - -#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 { - 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 { - 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 */ +#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) + +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 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 */ /* flags used only as arguments to access routines */ - 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 */ + 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 */ /* flags used only internally */ - _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; + _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; -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; @@ -80,350 +77,477 @@ typedef struct xfs_bufhash { } xfs_bufhash_t; typedef struct xfs_buftarg { - 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 */ + 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; + + /* 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 pagecache-based buffers - * - * This buffer structure is used by the pagecache buffer management routines - * to refer to an assembly of pages forming a logical buffer. + * xfs_buf_t: Buffer structure for page cache-based buffers * - * 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 + * 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 * 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 *); -#define XB_PAGES 2 +/* 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 typedef struct xfs_buf { - 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; + 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; #endif } xfs_buf_t; /* Finding and Reading Buffers */ -extern xfs_buf_t *_xfs_buf_find(xfs_buftarg_t *, xfs_off_t, size_t, - xfs_buf_flags_t, xfs_buf_t *); + +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 */ + #define xfs_incore(buftarg,blkno,len,lockit) \ - _xfs_buf_find(buftarg, blkno ,len, lockit, NULL) + _pagebuf_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), XBF_LOCK | XBF_MAPPED) + xfs_buf_get_flags((target), (blkno), (len), PBF_LOCK | PBF_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), XBF_LOCK | XBF_MAPPED) + xfs_buf_read_flags((target), (blkno), (len), PBF_LOCK | PBF_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 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); +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 */ /* Releasing Buffers */ -extern void xfs_buf_free(xfs_buf_t *); -extern void xfs_buf_rele(xfs_buf_t *); + +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 */ /* Locking and Unlocking Buffers */ -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 *); + +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 */ /* 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); - -static inline int xfs_buf_iostrategy(xfs_buf_t *bp) + +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) { - return bp->b_strat ? bp->b_strat(bp) : xfs_buf_iorequest(bp); + return pb->pb_strat ? pb->pb_strat(pb) : pagebuf_iorequest(pb); } -static inline int xfs_buf_geterror(xfs_buf_t *bp) +static inline int pagebuf_geterror(xfs_buf_t *pb) { - return bp ? bp->b_error : ENOMEM; + return pb ? pb->pb_error : ENOMEM; } /* Buffer Utility Routines */ -extern xfs_caddr_t xfs_buf_offset(xfs_buf_t *, size_t); + +extern caddr_t pagebuf_offset( /* pointer at offset in buffer */ + xfs_buf_t *, /* buffer to offset into */ + size_t); /* offset */ /* Pinning Buffer Storage in Memory */ -extern void xfs_buf_pin(xfs_buf_t *); -extern void xfs_buf_unpin(xfs_buf_t *); -extern int xfs_buf_ispin(xfs_buf_t *); + +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 */ /* Delayed Write Buffer Routines */ -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 void pagebuf_delwri_dequeue(xfs_buf_t *); -#ifdef XFS_BUF_TRACE -extern ktrace_t *xfs_buf_trace_buf; -extern void xfs_buf_trace(xfs_buf_t *, char *, void *, void *); -#else -#define xfs_buf_trace(bp,id,ptr,ra) do { } while (0) -#endif +/* Buffer Daemon Setup Routines */ -#define xfs_buf_target_name(target) \ - ({ char __b[BDEVNAME_SIZE]; bdevname((target)->bt_bdev, __b); __b; }) +extern int pagebuf_init(void); +extern void pagebuf_terminate(void); -#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 +#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 */ +#else +# define pagebuf_trace(pb, id, ptr, ra) do { } while (0) +#endif -#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 pagebuf_target_name(target) \ + ({ char __b[BDEVNAME_SIZE]; bdevname((target)->pbr_bdev, __b); __b; }) -#define BUF_BUSY XBF_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_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); \ +/* 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 PBF_TRYLOCK +#define XFS_INCORE_TRYLOCK PBF_TRYLOCK +#define XFS_BUF_LOCK PBF_LOCK +#define XFS_BUF_MAPPED PBF_MAPPED + +#define BUF_BUSY PBF_DONT_BLOCK + +#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); \ } while (0) -#define XFS_BUF_MANAGE XBF_FS_MANAGED -#define XFS_BUF_UNMANAGE(bp) ((bp)->b_flags &= ~XBF_FS_MANAGED) - -#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(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(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(bp) do { } while (0) -#define XFS_BUF_UNBUSY(bp) do { } while (0) -#define XFS_BUF_ISBUSY(bp) (1) - -#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(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(bp) do { } while (0) -#define XFS_BUF_UNSHUT(bp) do { } while (0) -#define XFS_BUF_ISSHUT(bp) (0) - -#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(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(bp) (0) -#define XFS_BUF_UNUNINITIAL(bp) (0) - -#define XFS_BUF_BP_ISMAPPED(bp) (1) - -#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(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_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_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) - -#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) +#define XFS_BUF_MANAGE PBF_FS_MANAGED +#define XFS_BUF_UNMANAGE(x) ((x)->pb_flags &= ~PBF_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_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_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_BUSY(x) do { } while (0) +#define XFS_BUF_UNBUSY(x) do { } while (0) +#define XFS_BUF_ISBUSY(x) (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_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_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_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_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_ISUNINITIAL(x) (0) +#define XFS_BUF_UNUNINITIAL(x) (0) + +#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_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_SET_BRELSE_FUNC(buf, value) \ + (buf)->pb_relse = (value) + +#define XFS_BUF_PTR(bp) (xfs_caddr_t)((bp)->pb_addr) + +static inline xfs_caddr_t xfs_buf_offset(xfs_buf_t *bp, size_t offset) +{ + if (bp->pb_flags & PBF_MAPPED) + return XFS_BUF_PTR(bp) + offset; + return (xfs_caddr_t) pagebuf_offset(bp, offset); +} + +#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) { - 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); + 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); } -static inline void xfs_buf_relse(xfs_buf_t *bp) +static inline void xfs_buf_relse(xfs_buf_t *bp) { - if (!bp->b_relse) - xfs_buf_unlock(bp); - xfs_buf_rele(bp); + if (!bp->pb_relse) + pagebuf_unlock(bp); + pagebuf_rele(bp); } -#define xfs_bpin(bp) xfs_buf_pin(bp) -#define xfs_bunpin(bp) xfs_buf_unpin(bp) +#define xfs_bpin(bp) pagebuf_pin(bp) +#define xfs_bunpin(bp) pagebuf_unpin(bp) #define xfs_buftrace(id, bp) \ - xfs_buf_trace(bp, id, NULL, (void *)__builtin_return_address(0)) + pagebuf_trace(bp, id, NULL, (void *)__builtin_return_address(0)) -#define xfs_biodone(bp) xfs_buf_ioend(bp, 0) +#define xfs_biodone(pb) \ + pagebuf_iodone(pb, 0) -#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_biomove(pb, off, len, data, rw) \ + pagebuf_iomove((pb), (off), (len), (data), \ + ((rw) == XFS_B_WRITE) ? PBRW_WRITE : PBRW_READ) -#define xfs_biozero(bp, off, len) \ - xfs_buf_iomove((bp), (off), (len), NULL, XBRW_ZERO) +#define xfs_biozero(pb, off, len) \ + pagebuf_iomove((pb), (off), (len), NULL, PBRW_ZERO) -static inline int XFS_bwrite(xfs_buf_t *bp) +static inline int XFS_bwrite(xfs_buf_t *pb) { - int iowait = (bp->b_flags & XBF_ASYNC) == 0; + int iowait = (pb->pb_flags & PBF_ASYNC) == 0; int error = 0; if (!iowait) - bp->b_flags |= _XBF_RUN_QUEUES; + pb->pb_flags |= _PBF_RUN_QUEUES; - xfs_buf_delwri_dequeue(bp); - xfs_buf_iostrategy(bp); + pagebuf_delwri_dequeue(pb); + pagebuf_iostrategy(pb); if (iowait) { - error = xfs_buf_iowait(bp); - xfs_buf_relse(bp); + error = pagebuf_iowait(pb); + xfs_buf_relse(pb); } return error; } -#define XFS_bdwrite(bp) xfs_buf_iostart(bp, XBF_DELWRI | XBF_ASYNC) +#define XFS_bdwrite(pb) \ + pagebuf_iostart(pb, PBF_DELWRI | PBF_ASYNC) static inline int xfs_bdwrite(void *mp, xfs_buf_t *bp) { - bp->b_strat = xfs_bdstrat_cb; - bp->b_fspriv3 = mp; - return xfs_buf_iostart(bp, XBF_DELWRI | XBF_ASYNC); + bp->pb_strat = xfs_bdstrat_cb; + bp->pb_fspriv3 = mp; + + return pagebuf_iostart(bp, PBF_DELWRI | PBF_ASYNC); } -#define XFS_bdstrat(bp) xfs_buf_iorequest(bp) +#define XFS_bdstrat(bp) pagebuf_iorequest(bp) -#define xfs_iowait(bp) xfs_buf_iowait(bp) +#define xfs_iowait(pb) pagebuf_iowait(pb) #define xfs_baread(target, rablkno, ralen) \ - xfs_buf_readahead((target), (rablkno), (ralen), XBF_DONT_BLOCK) + 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) /* * 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)->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) +#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) #endif /* __XFS_BUF_H__ */ diff --git a/trunk/fs/xfs/linux-2.6/xfs_file.c b/trunk/fs/xfs/linux-2.6/xfs_file.c index ced4404339c7..06111d0bbae4 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_file.c +++ b/trunk/fs/xfs/linux-2.6/xfs_file.c @@ -509,14 +509,16 @@ linvfs_open_exec( 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) { - ip = xfs_vtoi(vp); - if (!ip) { + bdp = vn_bhv_lookup(VN_BHV_HEAD(vp), &xfs_vnodeops); + if (!bdp) { 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/trunk/fs/xfs/linux-2.6/xfs_ioctl.c b/trunk/fs/xfs/linux-2.6/xfs_ioctl.c index 4db47790415c..21667ba6dcd5 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/trunk/fs/xfs/linux-2.6/xfs_ioctl.c @@ -146,10 +146,13 @@ xfs_find_handle( 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 */ - ip = xfs_vtoi(vp); + bhv = vn_bhv_lookup_unlocked(VN_BHV_HEAD(vp), &xfs_vnodeops); + ASSERT(bhv); + ip = XFS_BHVTOI(bhv); ASSERT(ip); lock_mode = xfs_ilock_map_shared(ip); @@ -748,8 +751,9 @@ xfs_ioctl( (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? mp->m_rtdev_targp : mp->m_ddev_targp; - da.d_mem = da.d_miniosz = 1 << target->bt_sshift; - da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1); + 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; if (copy_to_user(arg, &da, sizeof(da))) return -XFS_ERROR(EFAULT); diff --git a/trunk/fs/xfs/linux-2.6/xfs_iops.c b/trunk/fs/xfs/linux-2.6/xfs_iops.c index 4bd3d03b23ed..9b8ee3470ecc 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_iops.c +++ b/trunk/fs/xfs/linux-2.6/xfs_iops.c @@ -54,45 +54,10 @@ #include #include #include -#include #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 @@ -112,6 +77,23 @@ xfs_ichgtime( 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; @@ -148,6 +130,8 @@ xfs_ichgtime( * 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( @@ -157,12 +141,6 @@ xfs_ichgtime_fast( { 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. @@ -170,11 +148,26 @@ xfs_ichgtime_fast( 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; @@ -220,39 +213,6 @@ validate_fields( } } -/* - * 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). @@ -318,9 +278,6 @@ linvfs_mknod( break; } - if (!error) - error = linvfs_init_security(vp, dir); - if (default_acl) { if (!error) { error = _ACL_INHERIT(vp, &va, default_acl); @@ -337,6 +294,8 @@ linvfs_mknod( 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 @@ -547,7 +506,7 @@ linvfs_follow_link( ASSERT(dentry); ASSERT(nd); - link = (char *)kmalloc(MAXPATHLEN+1, GFP_KERNEL); + link = (char *)kmalloc(MAXNAMELEN+1, GFP_KERNEL); if (!link) { nd_set_link(nd, ERR_PTR(-ENOMEM)); return NULL; @@ -563,12 +522,12 @@ linvfs_follow_link( vp = LINVFS_GET_VP(dentry->d_inode); iov.iov_base = link; - iov.iov_len = MAXPATHLEN; + iov.iov_len = MAXNAMELEN; uio->uio_iov = &iov; uio->uio_offset = 0; uio->uio_segflg = UIO_SYSSPACE; - uio->uio_resid = MAXPATHLEN; + uio->uio_resid = MAXNAMELEN; uio->uio_iovcnt = 1; VOP_READLINK(vp, uio, 0, NULL, error); @@ -576,7 +535,7 @@ linvfs_follow_link( kfree(link); link = ERR_PTR(-error); } else { - link[MAXPATHLEN - uio->uio_resid] = '\0'; + link[MAXNAMELEN - uio->uio_resid] = '\0'; } kfree(uio); diff --git a/trunk/fs/xfs/linux-2.6/xfs_iops.h b/trunk/fs/xfs/linux-2.6/xfs_iops.h index 6899a6b4a50a..ee784b63acbf 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_iops.h +++ b/trunk/fs/xfs/linux-2.6/xfs_iops.h @@ -26,6 +26,11 @@ extern struct file_operations linvfs_file_operations; 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/trunk/fs/xfs/linux-2.6/xfs_linux.h b/trunk/fs/xfs/linux-2.6/xfs_linux.h index 67389b745526..d8e21ba0cccc 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_linux.h +++ b/trunk/fs/xfs/linux-2.6/xfs_linux.h @@ -110,6 +110,10 @@ * 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 @@ -228,7 +232,7 @@ BUFFER_FNS(PrivateStart, unwritten); #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_ddev_targp->bt_dev); \ + ({ u64 id = huge_encode_dev((mp)->m_dev); \ __kernel_fsid_t *fsid = &(statp)->f_fsid; \ (fsid->val[0] = (u32)id, fsid->val[1] = (u32)(id >> 32)); }) diff --git a/trunk/fs/xfs/linux-2.6/xfs_lrw.c b/trunk/fs/xfs/linux-2.6/xfs_lrw.c index e0ab45fbfebd..885dfafeabee 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_lrw.c +++ b/trunk/fs/xfs/linux-2.6/xfs_lrw.c @@ -233,8 +233,8 @@ xfs_read( xfs_buftarg_t *target = (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? mp->m_rtdev_targp : mp->m_ddev_targp; - if ((*offset & target->bt_smask) || - (size & target->bt_smask)) { + if ((*offset & target->pbr_smask) || + (size & target->pbr_smask)) { if (*offset == ip->i_d.di_size) { return (0); } @@ -281,6 +281,9 @@ xfs_read( 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); @@ -343,6 +346,9 @@ xfs_sendfile( 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; } @@ -356,6 +362,7 @@ STATIC int /* error (positive) */ xfs_zero_last_block( struct inode *ip, xfs_iocore_t *io, + xfs_off_t offset, xfs_fsize_t isize, xfs_fsize_t end_size) { @@ -364,16 +371,19 @@ xfs_zero_last_block( 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; - zero_offset = XFS_B_FSB_OFFSET(mp, isize); - if (zero_offset == 0) { + isize_fsb_offset = XFS_B_FSB_OFFSET(mp, isize); + if (isize_fsb_offset == 0) { /* * There are no extra bytes in the last block on disk to * zero, so return. @@ -403,8 +413,10 @@ xfs_zero_last_block( */ 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_len = mp->m_sb.sb_blocksize - zero_offset; + zero_offset = isize_fsb_offset; + zero_len = mp->m_sb.sb_blocksize - isize_fsb_offset; error = xfs_iozero(ip, loff + zero_offset, zero_len, end_size); @@ -435,17 +447,20 @@ xfs_zero_eof( 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; @@ -453,7 +468,7 @@ xfs_zero_eof( * 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, isize, end_size); + error = xfs_zero_last_block(ip, io, offset, isize, end_size); if (error) { ASSERT(ismrlocked(io->io_lock, MR_UPDATE)); ASSERT(ismrlocked(io->io_iolock, MR_UPDATE)); @@ -481,6 +496,8 @@ xfs_zero_eof( } 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; @@ -502,7 +519,10 @@ xfs_zero_eof( * that sits on a hole and sets the page as P_HOLE * and calls remapf if it is a mapped file. */ - start_zero_fsb = imap.br_startoff + imap.br_blockcount; + prev_zero_fsb = NULLFILEOFF; + prev_zero_count = 0; + start_zero_fsb = imap.br_startoff + + imap.br_blockcount; ASSERT(start_zero_fsb <= (end_zero_fsb + 1)); continue; } @@ -523,15 +543,17 @@ xfs_zero_eof( */ XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); - error = xfs_iozero(ip, - XFS_FSB_TO_B(mp, start_zero_fsb), - XFS_FSB_TO_B(mp, buf_len_fsb), - end_size); + 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); 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)); @@ -618,7 +640,7 @@ xfs_write( (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? mp->m_rtdev_targp : mp->m_ddev_targp; - if ((pos & target->bt_smask) || (count & target->bt_smask)) + if ((pos & target->pbr_smask) || (count & target->pbr_smask)) return XFS_ERROR(-EINVAL); if (!VN_CACHED(vp) && pos < i_size_read(inode)) @@ -809,10 +831,6 @@ xfs_write( 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) { @@ -938,7 +956,7 @@ xfs_bdstrat_cb(struct xfs_buf *bp) mp = XFS_BUF_FSPRIVATE3(bp, xfs_mount_t *); if (!XFS_FORCED_SHUTDOWN(mp)) { - xfs_buf_iorequest(bp); + pagebuf_iorequest(bp); return 0; } else { xfs_buftrace("XFS__BDSTRAT IOERROR", bp); @@ -991,7 +1009,7 @@ xfsbdstrat( * if (XFS_BUF_IS_GRIO(bp)) { */ - xfs_buf_iorequest(bp); + pagebuf_iorequest(bp); return 0; } diff --git a/trunk/fs/xfs/linux-2.6/xfs_stats.c b/trunk/fs/xfs/linux-2.6/xfs_stats.c index 8955720a2c6b..6c40a74be7c8 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_stats.c +++ b/trunk/fs/xfs/linux-2.6/xfs_stats.c @@ -34,7 +34,7 @@ xfs_read_xfsstats( __uint64_t xs_write_bytes = 0; __uint64_t xs_read_bytes = 0; - static const struct xstats_entry { + static struct xstats_entry { char *desc; int endpoint; } xstats[] = { diff --git a/trunk/fs/xfs/linux-2.6/xfs_stats.h b/trunk/fs/xfs/linux-2.6/xfs_stats.h index 8ba7a2fa6c1d..50027c4a5618 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_stats.h +++ b/trunk/fs/xfs/linux-2.6/xfs_stats.h @@ -109,15 +109,15 @@ struct xfsstats { __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 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; + __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; /* Extra precision counters */ __uint64_t xs_xstrat_bytes; __uint64_t xs_write_bytes; diff --git a/trunk/fs/xfs/linux-2.6/xfs_super.c b/trunk/fs/xfs/linux-2.6/xfs_super.c index f22e426d9e42..6116b5bf433e 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_super.c +++ b/trunk/fs/xfs/linux-2.6/xfs_super.c @@ -306,15 +306,13 @@ xfs_mountfs_check_barriers(xfs_mount_t *mp) 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->bt_bdev->bd_disk->queue->ordered == + if (mp->m_ddev_targp->pbr_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); @@ -322,7 +320,6 @@ xfs_mountfs_check_barriers(xfs_mount_t *mp) xfs_fs_cmn_err(CE_NOTE, mp, "Disabling barriers, trial barrier write failed"); mp->m_flags &= ~XFS_MOUNT_BARRIER; - return; } } @@ -330,7 +327,7 @@ void xfs_blkdev_issue_flush( xfs_buftarg_t *buftarg) { - blkdev_issue_flush(buftarg->bt_bdev, NULL); + blkdev_issue_flush(buftarg->pbr_bdev, NULL); } STATIC struct inode * @@ -579,7 +576,7 @@ xfssyncd( timeleft = schedule_timeout_interruptible(timeleft); /* swsusp */ try_to_freeze(); - if (kthread_should_stop() && list_empty(&vfsp->vfs_sync_list)) + if (kthread_should_stop()) break; spin_lock(&vfsp->vfs_sync_lock); @@ -969,9 +966,9 @@ init_xfs_fs( void ) if (error < 0) goto undo_zones; - error = xfs_buf_init(); + error = pagebuf_init(); if (error < 0) - goto undo_buffers; + goto undo_pagebuf; vn_init(); xfs_init(); @@ -985,9 +982,9 @@ init_xfs_fs( void ) return 0; undo_register: - xfs_buf_terminate(); + pagebuf_terminate(); -undo_buffers: +undo_pagebuf: linvfs_destroy_zones(); undo_zones: @@ -1001,7 +998,7 @@ exit_xfs_fs( void ) XFS_DM_EXIT(&xfs_fs_type); unregister_filesystem(&xfs_fs_type); xfs_cleanup(); - xfs_buf_terminate(); + pagebuf_terminate(); linvfs_destroy_zones(); ktrace_uninit(); } diff --git a/trunk/fs/xfs/linux-2.6/xfs_vnode.c b/trunk/fs/xfs/linux-2.6/xfs_vnode.c index 260dd8415dd7..e9bbcb4d6243 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_vnode.c +++ b/trunk/fs/xfs/linux-2.6/xfs_vnode.c @@ -106,6 +106,7 @@ vn_revalidate_core( 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/trunk/fs/xfs/linux-2.6/xfs_vnode.h b/trunk/fs/xfs/linux-2.6/xfs_vnode.h index 0fe2419461d6..f2bbb327c081 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_vnode.h +++ b/trunk/fs/xfs/linux-2.6/xfs_vnode.h @@ -565,25 +565,6 @@ static inline int VN_BAD(struct vnode *vp) return is_bad_inode(LINVFS_GET_IP(vp)); } -/* - * 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. */ diff --git a/trunk/fs/xfs/quota/xfs_dquot_item.c b/trunk/fs/xfs/quota/xfs_dquot_item.c index 2ec6b441849c..2f69822344e5 100644 --- a/trunk/fs/xfs/quota/xfs_dquot_item.c +++ b/trunk/fs/xfs/quota/xfs_dquot_item.c @@ -239,7 +239,7 @@ xfs_qm_dquot_logitem_pushbuf( * trying to duplicate our effort. */ ASSERT(qip->qli_pushbuf_flag != 0); - ASSERT(qip->qli_push_owner == current_pid()); + ASSERT(qip->qli_push_owner == get_thread_id()); /* * If flushlock isn't locked anymore, chances are that the @@ -333,7 +333,7 @@ xfs_qm_dquot_logitem_trylock( qip->qli_pushbuf_flag = 1; ASSERT(qip->qli_format.qlf_blkno == dqp->q_blkno); #ifdef DEBUG - qip->qli_push_owner = current_pid(); + qip->qli_push_owner = get_thread_id(); #endif /* * The dquot is left locked. diff --git a/trunk/fs/xfs/quota/xfs_qm.c b/trunk/fs/xfs/quota/xfs_qm.c index 7dcdd0640c32..bb6991a7a617 100644 --- a/trunk/fs/xfs/quota/xfs_qm.c +++ b/trunk/fs/xfs/quota/xfs_qm.c @@ -1392,12 +1392,11 @@ xfs_qm_qino_alloc( { 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, @@ -1407,9 +1406,8 @@ xfs_qm_qino_alloc( return (error); } memset(&zerocr, 0, sizeof(zerocr)); - memset(&zeroino, 0, sizeof(zeroino)); - if ((error = xfs_dir_ialloc(&tp, &zeroino, S_IFREG, 1, 0, + if ((error = xfs_dir_ialloc(&tp, mp->m_rootip, S_IFREG, 1, 0, &zerocr, 0, 1, ip, &committed))) { xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); @@ -1920,7 +1918,9 @@ xfs_qm_quotacheck( * at this point (because we intentionally didn't in dqget_noattach). */ if (error) { - xfs_qm_dqpurge_all(mp, XFS_QMOPT_QUOTALL | XFS_QMOPT_QUOTAOFF); + xfs_qm_dqpurge_all(mp, + XFS_QMOPT_UQUOTA|XFS_QMOPT_GQUOTA| + XFS_QMOPT_PQUOTA|XFS_QMOPT_QUOTAOFF); goto error_return; } /* @@ -2743,7 +2743,6 @@ xfs_qm_vop_dqattach_and_dqmod_newinode( 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); } @@ -2753,10 +2752,7 @@ xfs_qm_vop_dqattach_and_dqmod_newinode( xfs_dqunlock(gdqp); ASSERT(ip->i_gdquot == NULL); ip->i_gdquot = gdqp; - 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)); + ASSERT(ip->i_d.di_gid == be32_to_cpu(gdqp->q_core.d_id)); xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1); } } diff --git a/trunk/fs/xfs/support/debug.c b/trunk/fs/xfs/support/debug.c index b08b3d9345b7..bb6dc91ea261 100644 --- a/trunk/fs/xfs/support/debug.c +++ b/trunk/fs/xfs/support/debug.c @@ -27,11 +27,44 @@ static DEFINE_SPINLOCK(xfs_err_lock); /* 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 const char * const err_level[XFS_MAX_ERR_LEVEL+1] = +static char *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, ...) { @@ -57,6 +90,7 @@ cmn_err(register int level, char *fmt, ...) BUG(); } + void icmn_err(register int level, char *fmt, va_list ap) { @@ -75,27 +109,3 @@ icmn_err(register int level, char *fmt, va_list ap) 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/trunk/fs/xfs/support/debug.h b/trunk/fs/xfs/support/debug.h index e3bf58112e7e..aff558664c32 100644 --- a/trunk/fs/xfs/support/debug.h +++ b/trunk/fs/xfs/support/debug.h @@ -31,23 +31,24 @@ extern void icmn_err(int, char *, va_list) __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 STATIC +# define STATIC static +#endif -#ifndef DEBUG -# define ASSERT(expr) ((void)0) +#ifdef DEBUG +# define ASSERT(EX) ((EX) ? ((void)0) : assfail(#EX, __FILE__, __LINE__)) #else -# define ASSERT(expr) ASSERT_ALWAYS(expr) -extern unsigned long random(void); +# define ASSERT(x) ((void)0) #endif -#ifndef STATIC -# define STATIC static +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/trunk/fs/xfs/support/uuid.c b/trunk/fs/xfs/support/uuid.c index a3d565a67734..69ec4f540c3a 100644 --- a/trunk/fs/xfs/support/uuid.c +++ b/trunk/fs/xfs/support/uuid.c @@ -27,16 +27,6 @@ uuid_init(void) 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. * @@ -46,11 +36,16 @@ typedef struct { void uuid_getnodeuniq(uuid_t *uuid, int fsid [2]) { - xfs_uu_t *uup = (xfs_uu_t *)uuid; + char *uu = (char *)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] = (be16_to_cpu(uup->uu_clockseq) << 16) | - be16_to_cpu(uup->uu_timemid); - fsid[1] = be16_to_cpu(uup->uu_timelow); + 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); } void diff --git a/trunk/fs/xfs/xfs_arch.h b/trunk/fs/xfs/xfs_arch.h index c4836890b726..68e5051d8e24 100644 --- a/trunk/fs/xfs/xfs_arch.h +++ b/trunk/fs/xfs/xfs_arch.h @@ -40,22 +40,6 @@ #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? */ @@ -202,7 +186,7 @@ static inline void be64_add(__be64 *a, __s64 b) */ #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 { \ @@ -213,9 +197,9 @@ do { \ } 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/trunk/fs/xfs/xfs_attr_leaf.c b/trunk/fs/xfs/xfs_attr_leaf.c index fe91eac4e2a7..1c7421840c18 100644 --- a/trunk/fs/xfs/xfs_attr_leaf.c +++ b/trunk/fs/xfs/xfs_attr_leaf.c @@ -128,7 +128,7 @@ xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes) return (offset >= minforkoff) ? minforkoff : 0; } - if (!(mp->m_flags & XFS_MOUNT_ATTR2)) { + if (unlikely(mp->m_flags & XFS_MOUNT_COMPAT_ATTR)) { if (bytes <= XFS_IFORK_ASIZE(dp)) return mp->m_attroffset >> 3; return 0; @@ -157,7 +157,7 @@ xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp) { unsigned long s; - if ((mp->m_flags & XFS_MOUNT_ATTR2) && + if (!(mp->m_flags & XFS_MOUNT_COMPAT_ATTR) && !(XFS_SB_VERSION_HASATTR2(&mp->m_sb))) { s = XFS_SB_LOCK(mp); if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb)) { @@ -311,7 +311,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args) */ totsize -= size; if (totsize == sizeof(xfs_attr_sf_hdr_t) && !args->addname && - (mp->m_flags & XFS_MOUNT_ATTR2)) { + !(mp->m_flags & XFS_MOUNT_COMPAT_ATTR)) { /* * Last attribute now removed, revert to original * inode format making all literal area available @@ -330,7 +330,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args) 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_ATTR2)); + (mp->m_flags & XFS_MOUNT_COMPAT_ATTR)); 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 @@ xfs_attr_shortform_allfit(xfs_dabuf_t *bp, xfs_inode_t *dp) + name_loc->namelen + INT_GET(name_loc->valuelen, ARCH_CONVERT); } - if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) && + if (!(dp->i_mount->m_flags & XFS_MOUNT_COMPAT_ATTR) && (bytes == sizeof(struct xfs_attr_sf_hdr))) return(-1); return(xfs_attr_shortform_bytesfit(dp, bytes)); @@ -778,7 +778,7 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff) goto out; if (forkoff == -1) { - ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2); + ASSERT(!(dp->i_mount->m_flags & XFS_MOUNT_COMPAT_ATTR)); /* * Last attribute was removed, revert to original diff --git a/trunk/fs/xfs/xfs_attr_leaf.h b/trunk/fs/xfs/xfs_attr_leaf.h index 541e34109bb9..f6143ff251a0 100644 --- a/trunk/fs/xfs/xfs_attr_leaf.h +++ b/trunk/fs/xfs/xfs_attr_leaf.h @@ -63,7 +63,7 @@ struct xfs_trans; * 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 an "incomplete" bit in the leaf_entry. It shows that an + * We also store a "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,48 +72,42 @@ struct xfs_trans; */ #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 { - 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 */ + 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_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. @@ -156,8 +150,7 @@ xfs_attr_leaf_name_local(xfs_attr_leafblock_t *leafp, int idx) (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/trunk/fs/xfs/xfs_bmap.c b/trunk/fs/xfs/xfs_bmap.c index 70625e577c70..e415a4698e9c 100644 --- a/trunk/fs/xfs/xfs_bmap.c +++ b/trunk/fs/xfs/xfs_bmap.c @@ -2146,176 +2146,13 @@ xfs_bmap_add_extent_hole_real( 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 +STATIC int /* error */ xfs_bmap_alloc( xfs_bmalloca_t *ap) /* bmap alloc argument struct */ { @@ -2326,10 +2163,10 @@ xfs_bmap_alloc( xfs_mount_t *mp; /* mount point structure */ int nullfb; /* true if ap->firstblock isn't set */ int rt; /* true if inode is realtime */ - 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; +#ifdef __KERNEL__ + xfs_extlen_t prod=0; /* product factor for allocators */ + xfs_extlen_t ralen=0; /* realtime allocation length */ +#endif #define ISVALID(x,y) \ (rt ? \ @@ -2345,25 +2182,125 @@ xfs_bmap_alloc( 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) { - 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; - - 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); + 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 */ + /* + * 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); + } + 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, align) || ap->alen % align) + if (do_mod(ap->off, extsz) || ap->alen % extsz) prod = 1; /* * Set ralen to be the actual requested length in rtextents. @@ -2389,24 +2326,15 @@ xfs_bmap_alloc( 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. @@ -2670,12 +2598,11 @@ xfs_bmap_alloc( args.total = ap->total; args.minlen = ap->minlen; } - if (unlikely(ap->userdata && ap->ip->i_d.di_extsize && - (ap->ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE))) { + if (ap->ip->i_d.di_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 (unlikely(mp->m_sb.sb_blocksize >= NBPP)) { + } else if (mp->m_sb.sb_blocksize >= NBPP) { args.prod = 1; args.mod = 0; } else { @@ -3653,16 +3580,14 @@ xfs_bmap_search_extents( ep = xfs_bmap_do_search_extents(base, lastx, nextents, bno, eofp, lastxp, gotp, prevp); - rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip); - if (unlikely(!rt && !gotp->br_startblock && (*lastxp != NULLEXTNUM))) { + rt = ip->i_d.di_flags & XFS_DIFLAG_REALTIME; + if(!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, - (unsigned long long)gotp->br_startblock, - (unsigned long long)gotp->br_startoff, - (unsigned long long)gotp->br_blockcount, - gotp->br_state); + (ip->i_mount)->m_fsname,(long long)ip->i_ino, + gotp->br_startblock, gotp->br_startoff, + gotp->br_blockcount,gotp->br_state); } return ep; } @@ -3950,7 +3875,7 @@ xfs_bmap_add_attrfork( 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_ATTR2) + else if (!(mp->m_flags & XFS_MOUNT_COMPAT_ATTR)) version = 2; break; default: @@ -4098,13 +4023,13 @@ xfs_bmap_compute_maxlevels( */ if (whichfork == XFS_DATA_FORK) { maxleafents = MAXEXTNUM; - sz = (mp->m_flags & XFS_MOUNT_ATTR2) ? - XFS_BMDR_SPACE_CALC(MINDBTPTRS) : mp->m_attroffset; + sz = (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) ? + mp->m_attroffset : XFS_BMDR_SPACE_CALC(MINDBTPTRS); } else { maxleafents = MAXAEXTNUM; - sz = (mp->m_flags & XFS_MOUNT_ATTR2) ? - XFS_BMDR_SPACE_CALC(MINABTPTRS) : - mp->m_sb.sb_inodesize - mp->m_attroffset; + sz = (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) ? + mp->m_sb.sb_inodesize - mp->m_attroffset : + XFS_BMDR_SPACE_CALC(MINABTPTRS); } maxrootrecs = (int)XFS_BTREE_BLOCK_MAXRECS(sz, xfs_bmdr, 0); minleafrecs = mp->m_bmap_dmnr[0]; @@ -4493,8 +4418,8 @@ xfs_bmap_read_extents( num_recs = be16_to_cpu(block->bb_numrecs); if (unlikely(i + num_recs > room)) { ASSERT(i + num_recs <= room); - xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, - "corrupt dinode %Lu, (btree extents).", + xfs_fs_cmn_err(CE_WARN, ip->i_mount, + "corrupt dinode %Lu, (btree extents). Unmount and run xfs_repair.", (unsigned long long) ip->i_ino); XFS_ERROR_REPORT("xfs_bmap_read_extents(1)", XFS_ERRLEVEL_LOW, @@ -4665,7 +4590,6 @@ xfs_bmapi( 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 */ @@ -4719,7 +4643,7 @@ xfs_bmapi( } if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); - rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip); + rt = 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)); @@ -4730,7 +4654,6 @@ xfs_bmapi( 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; @@ -4825,25 +4748,15 @@ xfs_bmapi( } minlen = contig ? alen : 1; if (delay) { - xfs_extlen_t extsz; + xfs_extlen_t extsz = 0; /* Figure out the extent size, adjust alen */ if (rt) { if (!(extsz = ip->i_d.di_extsize)) extsz = 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) + alen = roundup(alen, extsz); extsz = alen / mp->m_sb.sb_rextsize; + } /* * Make a transaction-less quota reservation for @@ -4872,33 +4785,32 @@ xfs_bmapi( 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(mp, + if (error && rt) { + xfs_mod_incore_sb(ip->i_mount, XFS_SBS_FREXTENTS, extsz, rsvd); - else if (error) - xfs_mod_incore_sb(mp, + } else if (error) { + xfs_mod_incore_sb(ip->i_mount, XFS_SBS_FDBLOCKS, alen, rsvd); + } } if (error) { - if (XFS_IS_QUOTA_ON(mp)) + if (XFS_IS_QUOTA_ON(ip->i_mount)) /* unreserve the blocks now */ - (void) XFS_TRANS_UNRESERVE_QUOTA_NBLKS( mp, NULL, ip, (long)alen, 0, rt ? @@ -4937,7 +4849,6 @@ xfs_bmapi( bma.firstblock = *firstblock; bma.alen = alen; bma.off = aoff; - bma.conv = convert; bma.wasdel = wasdelay; bma.minlen = minlen; bma.low = flist->xbf_low; @@ -5359,7 +5270,8 @@ xfs_bunmapi( return 0; } XFS_STATS_INC(xs_blk_unmap); - isrt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip); + isrt = (whichfork == XFS_DATA_FORK) && + (ip->i_d.di_flags & XFS_DIFLAG_REALTIME); start = bno; bno = start + len - 1; ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, @@ -5531,7 +5443,7 @@ xfs_bunmapi( } if (wasdel) { ASSERT(STARTBLOCKVAL(del.br_startblock) > 0); - /* Update realtime/data freespace, unreserve quota */ + /* Update realtim/data freespace, unreserve quota */ if (isrt) { xfs_filblks_t rtexts; @@ -5539,14 +5451,14 @@ xfs_bunmapi( do_div(rtexts, mp->m_sb.sb_rextsize); xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, (int)rtexts, rsvd); - (void)XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, - NULL, ip, -((long)del.br_blockcount), 0, + 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); - (void)XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, - NULL, ip, -((long)del.br_blockcount), 0, + XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip, + -((long)del.br_blockcount), 0, XFS_QMOPT_RES_REGBLKS); } ip->i_delayed_blks -= del.br_blockcount; @@ -5740,9 +5652,7 @@ xfs_getbmap( ip->i_d.di_format != XFS_DINODE_FMT_LOCAL) return XFS_ERROR(EINVAL); if (whichfork == XFS_DATA_FORK) { - 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)){ + if (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC) { prealloced = 1; fixlen = XFS_MAXIOFFSET(mp); } else { diff --git a/trunk/fs/xfs/xfs_bmap.h b/trunk/fs/xfs/xfs_bmap.h index 12cc63dfc2c4..2e0717a01309 100644 --- a/trunk/fs/xfs/xfs_bmap.h +++ b/trunk/fs/xfs/xfs_bmap.h @@ -62,10 +62,6 @@ typedef struct xfs_bmap_free #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) @@ -105,8 +101,7 @@ typedef struct xfs_bmalloca { 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 conv; /* overwriting unwritten extents */ + char aeof; /* allocated space at eof */ } xfs_bmalloca_t; #ifdef __KERNEL__ diff --git a/trunk/fs/xfs/xfs_clnt.h b/trunk/fs/xfs/xfs_clnt.h index f57cc9ac875e..328a528b926d 100644 --- a/trunk/fs/xfs/xfs_clnt.h +++ b/trunk/fs/xfs/xfs_clnt.h @@ -57,7 +57,7 @@ struct xfs_mount_args { /* * XFS mount option flags -- args->flags1 */ -#define XFSMNT_ATTR2 0x00000001 /* allow ATTR2 EA format */ +#define XFSMNT_COMPAT_ATTR 0x00000001 /* do not use ATTR2 format */ #define XFSMNT_WSYNC 0x00000002 /* safe mode nfs mount * compatible */ #define XFSMNT_INO64 0x00000004 /* move inode numbers up diff --git a/trunk/fs/xfs/xfs_dfrag.c b/trunk/fs/xfs/xfs_dfrag.c index c6191d00ad27..070259a4254c 100644 --- a/trunk/fs/xfs/xfs_dfrag.c +++ b/trunk/fs/xfs/xfs_dfrag.c @@ -60,6 +60,8 @@ xfs_swapext( 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; @@ -88,10 +90,13 @@ xfs_swapext( goto error0; } - ip = xfs_vtoi(vp); - if (ip == NULL) { + bhp = VN_BHV_HEAD(vp); + bdp = vn_bhv_lookup(bhp, &xfs_vnodeops); + if (bdp == NULL) { error = XFS_ERROR(EBADF); goto error0; + } else { + ip = XFS_BHVTOI(bdp); } if (((tfp = fget((int)sxp->sx_fdtmp)) == NULL) || @@ -100,10 +105,13 @@ xfs_swapext( goto error0; } - tip = xfs_vtoi(tvp); - if (tip == NULL) { + tbhp = VN_BHV_HEAD(tvp); + tbdp = vn_bhv_lookup(tbhp, &xfs_vnodeops); + if (tbdp == NULL) { error = XFS_ERROR(EBADF); goto error0; + } else { + tip = XFS_BHVTOI(tbdp); } if (ip->i_mount != tip->i_mount) { diff --git a/trunk/fs/xfs/xfs_dinode.h b/trunk/fs/xfs/xfs_dinode.h index 79d0d9e1fbab..c5a0e537ff1a 100644 --- a/trunk/fs/xfs/xfs_dinode.h +++ b/trunk/fs/xfs/xfs_dinode.h @@ -199,16 +199,10 @@ typedef enum xfs_dinode_fmt #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) @@ -222,7 +216,6 @@ typedef enum xfs_dinode_fmt #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 ? \ @@ -230,13 +223,13 @@ typedef enum xfs_dinode_fmt 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)) /* @@ -253,10 +246,8 @@ typedef enum xfs_dinode_fmt #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_EXTSIZE_BIT 11 /* inode extent size allocator hint */ -#define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */ +#define XFS_DIFLAG_PROJINHERIT_BIT 9 /* create with parents projid */ +#define XFS_DIFLAG_NOSYMLINKS_BIT 10 /* disallow symlink creation */ #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) @@ -268,14 +259,11 @@ typedef enum xfs_dinode_fmt #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_EXTSIZE | \ - XFS_DIFLAG_EXTSZINHERIT) + XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS) #endif /* __XFS_DINODE_H__ */ diff --git a/trunk/fs/xfs/xfs_dir.c b/trunk/fs/xfs/xfs_dir.c index bb87d2a700a9..3dd30391f551 100644 --- a/trunk/fs/xfs/xfs_dir.c +++ b/trunk/fs/xfs/xfs_dir.c @@ -176,7 +176,7 @@ xfs_dir_mount(xfs_mount_t *mp) uint shortcount, leafcount, count; mp->m_dirversion = 1; - if (!(mp->m_flags & XFS_MOUNT_ATTR2)) { + if (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) { shortcount = (mp->m_attroffset - (uint)sizeof(xfs_dir_sf_hdr_t)) / (uint)sizeof(xfs_dir_sf_entry_t); diff --git a/trunk/fs/xfs/xfs_dir.h b/trunk/fs/xfs/xfs_dir.h index 8cc8afb9f6c0..488defe86ba6 100644 --- a/trunk/fs/xfs/xfs_dir.h +++ b/trunk/fs/xfs/xfs_dir.h @@ -135,8 +135,6 @@ void xfs_dir_startup(void); /* called exactly once */ ((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/trunk/fs/xfs/xfs_dir2.h b/trunk/fs/xfs/xfs_dir2.h index 3158f5dc431f..7e24ffeda9e1 100644 --- a/trunk/fs/xfs/xfs_dir2.h +++ b/trunk/fs/xfs/xfs_dir2.h @@ -72,6 +72,9 @@ typedef struct xfs_dir2_put_args { 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/trunk/fs/xfs/xfs_dir_leaf.h b/trunk/fs/xfs/xfs_dir_leaf.h index eb8cd9a4667f..ab6b09eef9ab 100644 --- a/trunk/fs/xfs/xfs_dir_leaf.h +++ b/trunk/fs/xfs/xfs_dir_leaf.h @@ -67,38 +67,34 @@ struct xfs_trans; */ #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 { - 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 */ + 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_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 @@ -130,10 +126,11 @@ typedef union { #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 */ @@ -141,8 +138,7 @@ typedef struct xfs_dir_put_args { 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/trunk/fs/xfs/xfs_error.c b/trunk/fs/xfs/xfs_error.c index 2a21c5024017..d7b6b5d16704 100644 --- a/trunk/fs/xfs/xfs_error.c +++ b/trunk/fs/xfs/xfs_error.c @@ -54,6 +54,7 @@ xfs_error_trap(int e) 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/trunk/fs/xfs/xfs_error.h b/trunk/fs/xfs/xfs_error.h index 26b8e709a569..06d8a8426c16 100644 --- a/trunk/fs/xfs/xfs_error.h +++ b/trunk/fs/xfs/xfs_error.h @@ -18,6 +18,9 @@ #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 */ @@ -179,11 +182,8 @@ extern int xfs_errortag_clearall_umount(int64_t fsid, char *fsname, int loud); 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/trunk/fs/xfs/xfs_fs.h b/trunk/fs/xfs/xfs_fs.h index 14010f1fa82f..ba096f80f48d 100644 --- a/trunk/fs/xfs/xfs_fs.h +++ b/trunk/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 Lesser General Public License - * as published by the Free Software Foundation. + * modify it under the terms of the GNU 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 Lesser General Public License for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public License + * You should have received a copy of the GNU 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,8 +65,6 @@ struct fsxattr { #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/trunk/fs/xfs/xfs_fsops.c b/trunk/fs/xfs/xfs_fsops.c index 163031c1e394..d1236d6f4045 100644 --- a/trunk/fs/xfs/xfs_fsops.c +++ b/trunk/fs/xfs/xfs_fsops.c @@ -540,32 +540,6 @@ xfs_reserve_blocks( 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/trunk/fs/xfs/xfs_fsops.h b/trunk/fs/xfs/xfs_fsops.h index 300d0c9d61ad..f32713f14f9a 100644 --- a/trunk/fs/xfs/xfs_fsops.h +++ b/trunk/fs/xfs/xfs_fsops.h @@ -25,6 +25,5 @@ extern int xfs_fs_counts(xfs_mount_t *mp, xfs_fsop_counts_t *cnt); 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/trunk/fs/xfs/xfs_iget.c b/trunk/fs/xfs/xfs_iget.c index 8e380a1fb79b..fc19eedbd11b 100644 --- a/trunk/fs/xfs/xfs_iget.c +++ b/trunk/fs/xfs/xfs_iget.c @@ -493,6 +493,7 @@ xfs_iget( retry: if ((inode = iget_locked(XFS_MTOVFS(mp)->vfs_super, ino))) { + bhv_desc_t *bdp; xfs_inode_t *ip; vp = LINVFS_GET_VP(inode); @@ -516,12 +517,14 @@ xfs_iget( * to wait for the inode to go away. */ if (is_bad_inode(inode) || - ((ip = xfs_vtoi(vp)) == NULL)) { + ((bdp = vn_bhv_lookup(VN_BHV_HEAD(vp), + &xfs_vnodeops)) == 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/trunk/fs/xfs/xfs_inode.c b/trunk/fs/xfs/xfs_inode.c index 1d7f5a7e063e..df0d4572d70a 100644 --- a/trunk/fs/xfs/xfs_inode.c +++ b/trunk/fs/xfs/xfs_inode.c @@ -404,8 +404,9 @@ xfs_iformat( 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_repair_cmn_err(CE_WARN, ip->i_mount, - "corrupt dinode %Lu, extent total = %d, nblocks = %Lu.", + xfs_fs_cmn_err(CE_WARN, ip->i_mount, + "corrupt dinode %Lu, extent total = %d, nblocks = %Lu." + " Unmount and run xfs_repair.", (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)), @@ -417,8 +418,9 @@ xfs_iformat( } if (unlikely(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT) > ip->i_mount->m_sb.sb_inodesize)) { - xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, - "corrupt dinode %Lu, forkoff = 0x%x.", + xfs_fs_cmn_err(CE_WARN, ip->i_mount, + "corrupt dinode %Lu, forkoff = 0x%x." + " Unmount and run xfs_repair.", (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, @@ -449,9 +451,8 @@ xfs_iformat( * no local regular files yet */ if (unlikely((INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & S_IFMT) == S_IFREG)) { - xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, - "corrupt inode %Lu " - "(local format for regular file).", + xfs_fs_cmn_err(CE_WARN, ip->i_mount, + "corrupt inode (local format for regular file) %Lu. Unmount and run xfs_repair.", (unsigned long long) ip->i_ino); XFS_CORRUPTION_ERROR("xfs_iformat(4)", XFS_ERRLEVEL_LOW, @@ -461,9 +462,8 @@ xfs_iformat( di_size = INT_GET(dip->di_core.di_size, ARCH_CONVERT); if (unlikely(di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) { - xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, - "corrupt inode %Lu " - "(bad size %Ld for local inode).", + xfs_fs_cmn_err(CE_WARN, ip->i_mount, + "corrupt inode %Lu (bad size %Ld for local inode). Unmount and run xfs_repair.", (unsigned long long) ip->i_ino, (long long) di_size); XFS_CORRUPTION_ERROR("xfs_iformat(5)", @@ -551,9 +551,8 @@ xfs_iformat_local( * kmem_alloc() or memcpy() below. */ if (unlikely(size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) { - xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, - "corrupt inode %Lu " - "(bad size %d for local fork, size = %d).", + 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.", (unsigned long long) ip->i_ino, size, XFS_DFORK_SIZE(dip, ip->i_mount, whichfork)); XFS_CORRUPTION_ERROR("xfs_iformat_local", XFS_ERRLEVEL_LOW, @@ -611,8 +610,8 @@ xfs_iformat_extents( * kmem_alloc() or memcpy() below. */ if (unlikely(size < 0 || size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) { - xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, - "corrupt inode %Lu ((a)extents = %d).", + xfs_fs_cmn_err(CE_WARN, ip->i_mount, + "corrupt inode %Lu ((a)extents = %d). Unmount and run xfs_repair.", (unsigned long long) ip->i_ino, nex); XFS_CORRUPTION_ERROR("xfs_iformat_extents(1)", XFS_ERRLEVEL_LOW, ip->i_mount, dip); @@ -693,8 +692,8 @@ xfs_iformat_btree( || 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_repair_cmn_err(CE_WARN, ip->i_mount, - "corrupt inode %Lu (btree).", + xfs_fs_cmn_err(CE_WARN, ip->i_mount, + "corrupt inode %Lu (btree). Unmount and run xfs_repair.", (unsigned long long) ip->i_ino); XFS_ERROR_REPORT("xfs_iformat_btree", XFS_ERRLEVEL_LOW, ip->i_mount); @@ -810,10 +809,6 @@ _xfs_dic2xflags( 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; @@ -1197,19 +1192,11 @@ xfs_ialloc( if ((mode & S_IFMT) == S_IFDIR) { if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) di_flags |= XFS_DIFLAG_RTINHERIT; - 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) { + } else { 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) @@ -1275,7 +1262,7 @@ xfs_isize_check( if ((ip->i_d.di_mode & S_IFMT) != S_IFREG) return; - if (ip->i_d.di_flags & (XFS_DIFLAG_REALTIME | XFS_DIFLAG_EXTSIZE)) + if ( ip->i_d.di_flags & XFS_DIFLAG_REALTIME ) return; nimaps = 2; @@ -1778,19 +1765,22 @@ xfs_igrow_start( 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, - ip->i_d.di_size, new_size); + error = xfs_zero_eof(XFS_ITOV(ip), &ip->i_iocore, new_size, isize, + new_size); return error; } @@ -3365,11 +3355,6 @@ xfs_iflush_int( 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/trunk/fs/xfs/xfs_inode.h b/trunk/fs/xfs/xfs_inode.h index 1cfbcf18ce86..124d30e6143b 100644 --- a/trunk/fs/xfs/xfs_inode.h +++ b/trunk/fs/xfs/xfs_inode.h @@ -436,10 +436,6 @@ void xfs_ichgtime(xfs_inode_t *, int); 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/trunk/fs/xfs/xfs_inode_item.c b/trunk/fs/xfs/xfs_inode_item.c index 36aa1fcb90a5..7f3363c621e1 100644 --- a/trunk/fs/xfs/xfs_inode_item.c +++ b/trunk/fs/xfs/xfs_inode_item.c @@ -271,11 +271,6 @@ xfs_inode_item_format( 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); @@ -608,7 +603,7 @@ xfs_inode_item_trylock( if (iip->ili_pushbuf_flag == 0) { iip->ili_pushbuf_flag = 1; #ifdef DEBUG - iip->ili_push_owner = current_pid(); + iip->ili_push_owner = get_thread_id(); #endif /* * Inode is left locked in shared mode. @@ -787,7 +782,7 @@ xfs_inode_item_pushbuf( * trying to duplicate our effort. */ ASSERT(iip->ili_pushbuf_flag != 0); - ASSERT(iip->ili_push_owner == current_pid()); + ASSERT(iip->ili_push_owner == get_thread_id()); /* * If flushlock isn't locked anymore, chances are that the diff --git a/trunk/fs/xfs/xfs_iomap.c b/trunk/fs/xfs/xfs_iomap.c index 788917f355c4..ca7afc83a893 100644 --- a/trunk/fs/xfs/xfs_iomap.c +++ b/trunk/fs/xfs/xfs_iomap.c @@ -262,7 +262,7 @@ xfs_iomap( 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); @@ -316,58 +316,6 @@ xfs_iomap( return XFS_ERROR(error); } -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, @@ -414,20 +362,19 @@ xfs_iomap_write_direct( xfs_iocore_t *io = &ip->i_iocore; xfs_fileoff_t offset_fsb; xfs_fileoff_t last_fsb; - xfs_filblks_t count_fsb, resaligned; + xfs_filblks_t count_fsb; 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; - uint qblocks, resblks, resrtextents; + xfs_filblks_t qblocks, resblks; int committed; - int error; + int resrtextents; /* * Make sure that the dquots are there. This doesn't hold @@ -437,52 +384,37 @@ xfs_iomap_write_direct( if (error) return XFS_ERROR(error); - 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; + 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); } - isize = ip->i_d.di_size; - if (io->io_new_size > isize) - isize = io->io_new_size; + /* + * Determine if reserving space on the data or realtime partition. + */ + if ((rt = XFS_IS_REALTIME_INODE(ip))) { + xfs_extlen_t extsz; - 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; + 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 { - if (found && (ret_imap->br_startblock == HOLESTARTBLOCK)) - last_fsb = MIN(last_fsb, (xfs_fileoff_t) - ret_imap->br_blockcount + - ret_imap->br_startoff); + resrtextents = 0; + resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, count_fsb); + quota_flag = XFS_QMOPT_RES_REGBLKS; } - 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 @@ -493,6 +425,7 @@ xfs_iomap_write_direct( 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 */ @@ -502,20 +435,20 @@ xfs_iomap_write_direct( if (error) goto error_out; - error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, - qblocks, 0, quota_flag); - if (error) + if (XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag)) { + error = (EDQUOT); goto error1; + } + bmapi_flag = XFS_BMAPI_WRITE; xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); xfs_trans_ihold(tp, ip); - bmapi_flag = XFS_BMAPI_WRITE; - if ((flags & BMAPI_DIRECT) && (offset < ip->i_d.di_size || extsz)) + if (!(flags & BMAPI_MMAP) && (offset < ip->i_d.di_size || rt)) bmapi_flag |= XFS_BMAPI_PREALLOC; /* - * Issue the xfs_bmapi() call to allocate the blocks + * Issue the bmapi() call to allocate the blocks */ XFS_BMAP_INIT(&free_list, &firstfsb); nimaps = 1; @@ -550,10 +483,8 @@ xfs_iomap_write_direct( "extent-state : %x \n", (ip->i_mount)->m_fsname, (long long)ip->i_ino, - (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->br_startblock, ret_imap->br_startoff, + ret_imap->br_blockcount,ret_imap->br_state); } return 0; @@ -569,63 +500,6 @@ xfs_iomap_write_direct( 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, @@ -639,15 +513,13 @@ xfs_iomap_write_delay( xfs_iocore_t *io = &ip->i_iocore; xfs_fileoff_t offset_fsb; xfs_fileoff_t last_fsb; - xfs_off_t aligned_offset; - xfs_fileoff_t ioalign; - xfs_fsblock_t firstblock; - xfs_extlen_t extsz; xfs_fsize_t isize; + xfs_fsblock_t firstblock; int nimaps; - xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS]; - int prealloc, fsynced = 0; int error; + xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS]; + int aeof; + int fsynced = 0; ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE) != 0); @@ -655,57 +527,152 @@ xfs_iomap_write_delay( * 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; + } - error = xfs_iomap_eof_want_preallocate(mp, io, isize, offset, count, - ioflag, imap, XFS_WRITE_IMAPS, &prealloc); - if (error) - return error; + 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; - if (prealloc) { + /* + * 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; aligned_offset = XFS_WRITEIO_ALIGN(mp, (offset + count - 1)); ioalign = XFS_B_TO_FSBT(mp, aligned_offset); - last_fsb = ioalign + mp->m_writeio_blocks; - } else { - last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count))); + last_fsb = ioalign + iosize; + aeof = 1; } +write_map: + nimaps = XFS_WRITE_IMAPS; + firstblock = NULLFSBLOCK; - if (prealloc || extsz) { - error = xfs_iomap_eof_align_last_fsb(mp, io, isize, extsz, - &last_fsb); - if (error) + /* + * 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; - nimaps = XFS_WRITE_IMAPS; - firstblock = NULLFSBLOCK; + 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); - if (error && (error != ENOSPC)) + /* + * This can be EDQUOT, if nimaps == 0 + */ + 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 - flush delalloc, and retry.. + * then we must have run out of space. */ if (nimaps == 0) { xfs_iomap_enter_trace(XFS_IOMAP_WRITE_NOSPACE, @@ -717,21 +684,17 @@ xfs_iomap_write_delay( goto retry; } - if (!(io->io_flags & XFS_IOCORE_RT) && !ret_imap->br_startblock) { + *ret_imap = imap[0]; + *nmaps = 1; + 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, - (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->br_startblock, ret_imap->br_startoff, + ret_imap->br_blockcount,ret_imap->br_state); } - - *ret_imap = imap[0]; - *nmaps = 1; - return 0; } @@ -857,21 +820,17 @@ xfs_iomap_write_allocate( */ 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, - (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); + imap[i].br_startblock, + imap[i].br_startoff, + imap[i].br_blockcount,imap[i].br_state); } if ((offset_fsb >= imap[i].br_startoff) && (offset_fsb < (imap[i].br_startoff + @@ -908,17 +867,17 @@ xfs_iomap_write_unwritten( { 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_fsblock_t firstfsb; - int nimaps; - xfs_trans_t *tp; - xfs_bmbt_irec_t imap; - xfs_bmap_free_t free_list; - uint resblks; + xfs_bmbt_irec_t imap; 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); @@ -927,9 +886,9 @@ xfs_iomap_write_unwritten( count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); count_fsb = (xfs_filblks_t)(count_fsb - offset_fsb); - resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0) << 1; - do { + nres = XFS_DIOSTRAT_SPACE_RES(mp, 0); + /* * set up a transaction to convert the range of extents * from unwritten to real. Do allocations in a loop until @@ -937,7 +896,7 @@ xfs_iomap_write_unwritten( */ tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE); - error = xfs_trans_reserve(tp, resblks, + error = xfs_trans_reserve(tp, nres, XFS_WRITE_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_WRITE_LOG_COUNT); @@ -956,7 +915,7 @@ xfs_iomap_write_unwritten( XFS_BMAP_INIT(&free_list, &firstfsb); nimaps = 1; error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, - XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb, + XFS_BMAPI_WRITE, &firstfsb, 1, &imap, &nimaps, &free_list); if (error) goto error_on_bmapi_transaction; @@ -970,17 +929,15 @@ xfs_iomap_write_unwritten( 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, - (unsigned long long)imap.br_startblock, - (unsigned long long)imap.br_startoff, - (unsigned long long)imap.br_blockcount, - imap.br_state); + imap.br_startblock,imap.br_startoff, + imap.br_blockcount,imap.br_state); } if ((numblks_fsb = imap.br_blockcount) == 0) { diff --git a/trunk/fs/xfs/xfs_itable.c b/trunk/fs/xfs/xfs_itable.c index c59450e1be40..f63646ead816 100644 --- a/trunk/fs/xfs/xfs_itable.c +++ b/trunk/fs/xfs/xfs_itable.c @@ -56,7 +56,6 @@ xfs_bulkstat_one_iget( { 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); @@ -73,7 +72,6 @@ xfs_bulkstat_one_iget( goto out_iput; } - vp = XFS_ITOV(ip); dic = &ip->i_d; /* xfs_iget returns the following without needing @@ -86,7 +84,8 @@ xfs_bulkstat_one_iget( buf->bs_uid = dic->di_uid; buf->bs_gid = dic->di_gid; buf->bs_size = dic->di_size; - vn_atime_to_bstime(vp, &buf->bs_atime); + buf->bs_atime.tv_sec = dic->di_atime.t_sec; + buf->bs_atime.tv_nsec = dic->di_atime.t_nsec; 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/trunk/fs/xfs/xfs_log.c b/trunk/fs/xfs/xfs_log.c index 3d9a36e77363..29af51275ca9 100644 --- a/trunk/fs/xfs/xfs_log.c +++ b/trunk/fs/xfs/xfs_log.c @@ -178,83 +178,6 @@ xlog_trace_iclog(xlog_in_core_t *iclog, uint state) #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: * @@ -505,7 +428,7 @@ xfs_log_mount(xfs_mount_t *mp, if (readonly) vfsp->vfs_flag &= ~VFS_RDONLY; - error = xlog_recover(mp->m_log); + error = xlog_recover(mp->m_log, readonly); if (readonly) vfsp->vfs_flag |= VFS_RDONLY; @@ -1397,7 +1320,8 @@ xlog_sync(xlog_t *log, /* move grant heads by roundoff in sync */ s = GRANT_LOCK(log); - xlog_grant_add_space(log, roundoff); + XLOG_GRANT_ADD_SPACE(log, roundoff, 'w'); + XLOG_GRANT_ADD_SPACE(log, roundoff, 'r'); GRANT_UNLOCK(log, s); /* put cycle number in every block */ @@ -1591,6 +1515,7 @@ xlog_state_finish_copy(xlog_t *log, * 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) { @@ -1680,11 +1605,11 @@ xlog_print_tic_res(xfs_mount_t *mp, xlog_ticket_t *ticket) 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, @@ -1693,6 +1618,9 @@ xlog_print_tic_res(xfs_mount_t *mp, xlog_ticket_t *ticket) ticket->t_res_arr[i].r_len); } } +#else +#define xlog_print_tic_res(mp, ticket) +#endif /* * Write some region out to in-core log @@ -2461,7 +2389,7 @@ xlog_grant_log_space(xlog_t *log, /* 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"); /* @@ -2494,7 +2422,7 @@ xlog_grant_log_space(xlog_t *log, 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); @@ -2511,10 +2439,11 @@ xlog_grant_log_space(xlog_t *log, 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); + XLOG_GRANT_ADD_SPACE(log, need_bytes, 'w'); + XLOG_GRANT_ADD_SPACE(log, need_bytes, 'r'); #ifdef DEBUG tail_lsn = log->l_tail_lsn; /* @@ -2535,7 +2464,7 @@ xlog_grant_log_space(xlog_t *log, 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 @@ -2604,7 +2533,7 @@ xlog_regrant_write_log_space(xlog_t *log, 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"); @@ -2636,7 +2565,7 @@ xlog_regrant_write_log_space(xlog_t *log, 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); @@ -2652,10 +2581,9 @@ xlog_regrant_write_log_space(xlog_t *log, 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); - /* we've got enough space */ - xlog_grant_add_space_write(log, need_bytes); + XLOG_GRANT_ADD_SPACE(log, need_bytes, 'w'); /* we've got enough space */ #ifdef DEBUG tail_lsn = log->l_tail_lsn; if (CYCLE_LSN(tail_lsn) != log->l_grant_write_cycle) { @@ -2672,7 +2600,7 @@ xlog_regrant_write_log_space(xlog_t *log, 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 @@ -2705,7 +2633,8 @@ xlog_regrant_reserve_log_space(xlog_t *log, ticket->t_cnt--; s = GRANT_LOCK(log); - xlog_grant_sub_space(log, ticket->t_curr_res); + XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'w'); + XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'r'); ticket->t_curr_res = ticket->t_unit_res; XLOG_TIC_RESET_RES(ticket); xlog_trace_loggrant(log, ticket, @@ -2718,7 +2647,7 @@ xlog_regrant_reserve_log_space(xlog_t *log, return; } - xlog_grant_add_space_reserve(log, ticket->t_unit_res); + XLOG_GRANT_ADD_SPACE(log, ticket->t_unit_res, 'r'); xlog_trace_loggrant(log, ticket, "xlog_regrant_reserve_log_space: exit"); xlog_verify_grant_head(log, 0); @@ -2754,7 +2683,8 @@ xlog_ungrant_log_space(xlog_t *log, s = GRANT_LOCK(log); xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: enter"); - xlog_grant_sub_space(log, ticket->t_curr_res); + XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'w'); + XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'r'); xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: sub current"); @@ -2763,7 +2693,8 @@ xlog_ungrant_log_space(xlog_t *log, */ 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); + 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_trace_loggrant(log, ticket, "xlog_ungrant_log_space: exit"); diff --git a/trunk/fs/xfs/xfs_log.h b/trunk/fs/xfs/xfs_log.h index 4b2ac88dbb83..f40d4391fcfc 100644 --- a/trunk/fs/xfs/xfs_log.h +++ b/trunk/fs/xfs/xfs_log.h @@ -96,6 +96,7 @@ static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2) /* 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 @@ -116,13 +117,21 @@ static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2) #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 */ - uint i_type; /* type of region */ +#if defined(XFS_LOG_RES_DEBUG) + uint i_type; /* type of region */ +#endif } xfs_log_iovec_t; typedef void* xfs_log_ticket_t; diff --git a/trunk/fs/xfs/xfs_log_priv.h b/trunk/fs/xfs/xfs_log_priv.h index 34bcbf50789c..4518b188ade6 100644 --- a/trunk/fs/xfs/xfs_log_priv.h +++ b/trunk/fs/xfs/xfs_log_priv.h @@ -253,6 +253,7 @@ typedef __uint32_t xlog_tid_t; /* 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) @@ -277,9 +278,15 @@ typedef __uint32_t xlog_tid_t; * we don't care about. */ typedef struct xlog_res { - uint r_len; /* region length :4 */ - uint r_type; /* region's transaction type :4 */ + uint r_len; + uint r_type; } 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 */ @@ -294,12 +301,14 @@ typedef struct xlog_ticket { 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 */ - xlog_res_t t_res_arr[XLOG_TIC_LEN_MAX]; /* array of res : 8 * 15 */ +#endif } xlog_ticket_t; #endif @@ -485,13 +494,71 @@ typedef struct log { #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); -extern int xlog_recover(xlog_t *log); + xfs_daddr_t *tail_blk, + int readonly); +extern int xlog_recover(xlog_t *log, int readonly); 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/trunk/fs/xfs/xfs_log_recover.c b/trunk/fs/xfs/xfs_log_recover.c index 7d46cbd6a07a..8ab7df768063 100644 --- a/trunk/fs/xfs/xfs_log_recover.c +++ b/trunk/fs/xfs/xfs_log_recover.c @@ -783,7 +783,8 @@ int xlog_find_tail( xlog_t *log, xfs_daddr_t *head_blk, - xfs_daddr_t *tail_blk) + xfs_daddr_t *tail_blk, + int readonly) { xlog_rec_header_t *rhead; xlog_op_header_t *op_head; @@ -2562,12 +2563,10 @@ xlog_recover_do_quotaoff_trans( /* * The logitem format's flag tells us if this was user quotaoff, - * group/project quotaoff or both. + * group 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; @@ -3891,13 +3890,14 @@ xlog_do_recover( */ int xlog_recover( - xlog_t *log) + xlog_t *log, + int readonly) { 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))) + if ((error = xlog_find_tail(log, &head_blk, &tail_blk, readonly))) return error; if (tail_blk != head_blk) { diff --git a/trunk/fs/xfs/xfs_mount.c b/trunk/fs/xfs/xfs_mount.c index 6088e14f84e3..303af86739bf 100644 --- a/trunk/fs/xfs/xfs_mount.c +++ b/trunk/fs/xfs/xfs_mount.c @@ -51,7 +51,7 @@ STATIC int xfs_uuid_mount(xfs_mount_t *); STATIC void xfs_uuid_unmount(xfs_mount_t *mp); STATIC void xfs_unmountfs_wait(xfs_mount_t *); -static const struct { +static struct { short offset; short type; /* 0 = integer * 1 = binary / string (no translation) @@ -1077,7 +1077,8 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) xfs_iflush_all(mp); - XFS_QM_DQPURGEALL(mp, XFS_QMOPT_QUOTALL | XFS_QMOPT_UMOUNTING); + XFS_QM_DQPURGEALL(mp, + XFS_QMOPT_UQUOTA | XFS_QMOPT_GQUOTA | XFS_QMOPT_UMOUNTING); /* * Flush out the log synchronously so that we know for sure diff --git a/trunk/fs/xfs/xfs_mount.h b/trunk/fs/xfs/xfs_mount.h index cd3cf9613a00..3432fd5a3986 100644 --- a/trunk/fs/xfs/xfs_mount.h +++ b/trunk/fs/xfs/xfs_mount.h @@ -308,6 +308,7 @@ typedef struct xfs_mount { 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 */ @@ -392,7 +393,7 @@ typedef struct xfs_mount { user */ #define XFS_MOUNT_NOALIGN (1ULL << 7) /* turn off stripe alignment allocations */ -#define XFS_MOUNT_ATTR2 (1ULL << 8) /* allow use of attr2 format */ +#define XFS_MOUNT_COMPAT_ATTR (1ULL << 8) /* do not use 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/trunk/fs/xfs/xfs_rename.c b/trunk/fs/xfs/xfs_rename.c index 81a05cfd77d2..4d4e8f4e768e 100644 --- a/trunk/fs/xfs/xfs_rename.c +++ b/trunk/fs/xfs/xfs_rename.c @@ -243,6 +243,7 @@ xfs_rename( 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; @@ -259,12 +260,14 @@ xfs_rename( * Find the XFS behavior descriptor for the target directory * vnode since it was not handed to us. */ - target_dp = xfs_vtoi(target_dir_vp); - if (target_dp == NULL) { + target_dir_bdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(target_dir_vp), + &xfs_vnodeops); + if (target_dir_bdp == 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/trunk/fs/xfs/xfs_rw.c b/trunk/fs/xfs/xfs_rw.c index a59c102cf214..c4b20872f07d 100644 --- a/trunk/fs/xfs/xfs_rw.c +++ b/trunk/fs/xfs/xfs_rw.c @@ -238,7 +238,6 @@ xfs_bioerror_relse( } return (EIO); } - /* * Prints out an ALERT message about I/O error. */ @@ -253,9 +252,11 @@ xfs_ioerror_alert( "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(XFS_BUF_TARGET(bp)), - (__uint64_t)blkno, func, - XFS_BUF_GETERROR(bp), XFS_BUF_COUNT(bp)); + XFS_BUFTARG_NAME(bp->pb_target), + (__uint64_t)blkno, + func, + XFS_BUF_GETERROR(bp), + XFS_BUF_COUNT(bp)); } /* diff --git a/trunk/fs/xfs/xfs_sb.h b/trunk/fs/xfs/xfs_sb.h index bf168a91ddb8..4a17d335f897 100644 --- a/trunk/fs/xfs/xfs_sb.h +++ b/trunk/fs/xfs/xfs_sb.h @@ -68,6 +68,18 @@ struct xfs_mount; (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 @@ -93,6 +105,11 @@ struct xfs_mount; (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/trunk/fs/xfs/xfs_trans.c b/trunk/fs/xfs/xfs_trans.c index d3d714e6b32a..279e043d7323 100644 --- a/trunk/fs/xfs/xfs_trans.c +++ b/trunk/fs/xfs/xfs_trans.c @@ -1014,7 +1014,6 @@ xfs_trans_cancel( 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 @@ -1027,10 +1026,9 @@ xfs_trans_cancel( * filesystem. This happens in paths where we detect * corruption and decide to give up. */ - 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); - } + if ((tp->t_flags & XFS_TRANS_DIRTY) && + !XFS_FORCED_SHUTDOWN(tp->t_mountp)) + xfs_force_shutdown(tp->t_mountp, XFS_CORRUPT_INCORE); #ifdef DEBUG if (!(flags & XFS_TRANS_ABORT)) { licp = &(tp->t_items); @@ -1042,7 +1040,7 @@ xfs_trans_cancel( } lip = lidp->lid_item; - if (!XFS_FORCED_SHUTDOWN(mp)) + if (!XFS_FORCED_SHUTDOWN(tp->t_mountp)) ASSERT(!(lip->li_type == XFS_LI_EFD)); } licp = licp->lic_next; @@ -1050,7 +1048,7 @@ xfs_trans_cancel( } #endif xfs_trans_unreserve_and_mod_sb(tp); - XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(mp, tp); + XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(tp->t_mountp, tp); if (tp->t_ticket) { if (flags & XFS_TRANS_RELEASE_LOG_RES) { @@ -1059,7 +1057,7 @@ xfs_trans_cancel( } else { log_flags = 0; } - xfs_log_done(mp, tp->t_ticket, NULL, log_flags); + xfs_log_done(tp->t_mountp, tp->t_ticket, NULL, log_flags); } /* mark this thread as no longer being in a transaction */ diff --git a/trunk/fs/xfs/xfs_trans.h b/trunk/fs/xfs/xfs_trans.h index d77901c07f63..a889963fdd14 100644 --- a/trunk/fs/xfs/xfs_trans.h +++ b/trunk/fs/xfs/xfs_trans.h @@ -973,6 +973,7 @@ void xfs_trans_bhold(xfs_trans_t *, struct xfs_buf *); 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/trunk/fs/xfs/xfs_utils.c b/trunk/fs/xfs/xfs_utils.c index 34654ec6ae10..fefe1d60377f 100644 --- a/trunk/fs/xfs/xfs_utils.c +++ b/trunk/fs/xfs/xfs_utils.c @@ -55,13 +55,16 @@ xfs_get_dir_entry( xfs_inode_t **ipp) { vnode_t *vp; + bhv_desc_t *bdp; vp = VNAME_TO_VNODE(dentry); - - *ipp = xfs_vtoi(vp); - if (!*ipp) + bdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(vp), &xfs_vnodeops); + if (!bdp) { + *ipp = NULL; return XFS_ERROR(ENOENT); + } VN_HOLD(vp); + *ipp = XFS_BHVTOI(bdp); return 0; } diff --git a/trunk/fs/xfs/xfs_vfsops.c b/trunk/fs/xfs/xfs_vfsops.c index b6ad370fab3d..7bdbd991ab1c 100644 --- a/trunk/fs/xfs/xfs_vfsops.c +++ b/trunk/fs/xfs/xfs_vfsops.c @@ -53,7 +53,6 @@ #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 *); @@ -291,8 +290,8 @@ xfs_start_flags( mp->m_flags |= XFS_MOUNT_IDELETE; if (ap->flags & XFSMNT_DIRSYNC) mp->m_flags |= XFS_MOUNT_DIRSYNC; - if (ap->flags & XFSMNT_ATTR2) - mp->m_flags |= XFS_MOUNT_ATTR2; + if (ap->flags & XFSMNT_COMPAT_ATTR) + mp->m_flags |= XFS_MOUNT_COMPAT_ATTR; if (ap->flags2 & XFSMNT2_COMPAT_IOSIZE) mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; @@ -313,8 +312,6 @@ xfs_start_flags( 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; } @@ -333,11 +330,10 @@ xfs_finish_flags( /* Fail a mount where the logbuf is smaller then the log stripe */ if (XFS_SB_VERSION_HASLOGV2(&mp->m_sb)) { - if ((ap->logbufsize <= 0) && + if ((ap->logbufsize == -1) && (mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE)) { mp->m_logbsize = mp->m_sb.sb_logsunit; - } else if (ap->logbufsize > 0 && - ap->logbufsize < mp->m_sb.sb_logsunit) { + } else if (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); @@ -351,10 +347,6 @@ xfs_finish_flags( } } - if (XFS_SB_VERSION_HASATTR2(&mp->m_sb)) { - mp->m_flags |= XFS_MOUNT_ATTR2; - } - /* * prohibit r/w mounts of read-only filesystems */ @@ -390,6 +382,10 @@ xfs_finish_flags( return XFS_ERROR(EINVAL); } + if (XFS_SB_VERSION_HASATTR2(&mp->m_sb)) { + mp->m_flags &= ~XFS_MOUNT_COMPAT_ATTR; + } + return 0; } @@ -508,13 +504,13 @@ xfs_mount( 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: @@ -659,11 +655,6 @@ xfs_mntupdate( 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; @@ -1643,7 +1634,6 @@ xfs_vget( #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 */ @@ -1690,6 +1680,7 @@ xfs_parseargs( 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 */ @@ -1815,8 +1806,6 @@ xfs_parseargs( 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)) { @@ -1826,9 +1815,9 @@ xfs_parseargs( } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) { args->flags2 |= XFSMNT2_COMPAT_IOSIZE; } else if (!strcmp(this_char, MNTOPT_ATTR2)) { - args->flags |= XFSMNT_ATTR2; + args->flags &= ~XFSMNT_COMPAT_ATTR; } else if (!strcmp(this_char, MNTOPT_NOATTR2)) { - args->flags &= ~XFSMNT_ATTR2; + args->flags |= XFSMNT_COMPAT_ATTR; } else if (!strcmp(this_char, "osyncisdsync")) { /* no-op, this is now the default */ printk("XFS: osyncisdsync is now the default, option is deprecated.\n"); @@ -1903,6 +1892,7 @@ xfs_showargs( { 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 } }; @@ -1924,28 +1914,33 @@ xfs_showargs( 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); @@ -1964,7 +1959,6 @@ xfs_freeze( /* 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/trunk/fs/xfs/xfs_vnodeops.c b/trunk/fs/xfs/xfs_vnodeops.c index 8076cc981e11..e92cacde02f5 100644 --- a/trunk/fs/xfs/xfs_vnodeops.c +++ b/trunk/fs/xfs/xfs_vnodeops.c @@ -185,7 +185,8 @@ xfs_getattr( break; } - vn_atime_to_timespec(vp, &vap->va_atime); + vap->va_atime.tv_sec = ip->i_d.di_atime.t_sec; + vap->va_atime.tv_nsec = ip->i_d.di_atime.t_nsec; 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; @@ -542,6 +543,24 @@ xfs_setattr( goto error_return; } + /* + * 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. */ @@ -804,17 +823,13 @@ xfs_setattr( di_flags |= XFS_DIFLAG_RTINHERIT; if (vap->va_xflags & XFS_XFLAG_NOSYMLINKS) di_flags |= XFS_DIFLAG_NOSYMLINKS; - if (vap->va_xflags & XFS_XFLAG_EXTSZINHERIT) - di_flags |= XFS_DIFLAG_EXTSZINHERIT; - } else if ((ip->i_d.di_mode & S_IFMT) == S_IFREG) { + } else { 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; } @@ -984,6 +999,10 @@ xfs_readlink( goto error_return; } + if (!(ioflags & IO_INVIS)) { + xfs_ichgtime(ip, XFS_ICHGTIME_ACC); + } + /* * See if the symlink is stored inline. */ @@ -1215,8 +1234,7 @@ xfs_inactive_free_eofblocks( xfs_iunlock(ip, XFS_ILOCK_SHARED); if (!error && (nimaps != 0) && - (imap.br_startblock != HOLESTARTBLOCK || - ip->i_delayed_blks)) { + (imap.br_startblock != HOLESTARTBLOCK)) { /* * Attach the dquots to the inode up front. */ @@ -1551,11 +1569,9 @@ xfs_release( 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_delayed_blks > 0)) && + ((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_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 */ @@ -1612,8 +1628,7 @@ xfs_inactive( * 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_delayed_blks > 0)) && + ((ip->i_d.di_size != 0) || (ip->i_d.di_nextents > 0)) && ((ip->i_d.di_mode & S_IFMT) == S_IFREG)); mp = ip->i_mount; @@ -1631,12 +1646,10 @@ xfs_inactive( 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_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)))) { + ((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))) { if ((error = xfs_inactive_free_eofblocks(mp, ip))) return (VN_INACTIVE_CACHE); /* Update linux inode block count after free above */ @@ -2580,6 +2593,7 @@ xfs_link( 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; @@ -2592,7 +2606,8 @@ xfs_link( if (VN_ISDIR(src_vp)) return XFS_ERROR(EPERM); - sip = xfs_vtoi(src_vp); + src_bdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(src_vp), &xfs_vnodeops); + sip = XFS_BHVTOI(src_bdp); tdp = XFS_BHVTOI(target_dir_bdp); mp = tdp->i_mount; if (XFS_FORCED_SHUTDOWN(mp)) @@ -3225,6 +3240,7 @@ xfs_readdir( 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); @@ -3235,7 +3251,11 @@ xfs_readdir( } 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; } @@ -3812,12 +3832,7 @@ xfs_reclaim( vn_iowait(vp); ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0); - - /* - * Make sure the atime in the XFS inode is correct before freeing the - * Linux inode. - */ - xfs_synchronize_atime(ip); + ASSERT(VN_CACHED(vp) == 0); /* If we have nothing to flush with this inode then complete the * teardown now, otherwise break the link between the xfs inode @@ -3987,36 +4002,42 @@ xfs_alloc_file_space( 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; - xfs_extlen_t extsz, temp; - xfs_fileoff_t startoffset_fsb; + int committed; + xfs_off_t count; + xfs_filblks_t datablocks; + int error; xfs_fsblock_t firstfsb; - int nimaps; - int bmapi_flag; - int quota_flag; + 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_fileoff_t startoffset_fsb; xfs_trans_t *tp; - xfs_bmbt_irec_t imaps[1], *imapp; - xfs_bmap_free_t free_list; - uint qblocks, resblks, resrtextents; - int committed; - int error; + int xfs_bmapi_flags; vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); + mp = ip->i_mount; if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); - 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; - } + /* + * 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; if ((error = XFS_QM_DQATTACH(mp, ip, 0))) return error; @@ -4027,8 +4048,8 @@ xfs_alloc_file_space( count = len; error = 0; imapp = &imaps[0]; - nimaps = 1; - bmapi_flag = XFS_BMAPI_WRITE | (alloc_type ? XFS_BMAPI_PREALLOC : 0); + reccount = 1; + xfs_bmapi_flags = 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); @@ -4049,51 +4070,43 @@ xfs_alloc_file_space( } /* - * 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) { - xfs_fileoff_t s, e; - /* - * Determine space reservations for data/realtime. + * determine if reserving space on + * the data or realtime partition. */ - if (unlikely(extsz)) { - s = startoffset_fsb; - 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 { - s = 0; - e = allocatesize_fsb; - } + if (rt) { + xfs_fileoff_t s, e; - 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; + 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; } else { - resrtextents = 0; - resblks = qblocks = \ - XFS_DIOSTRAT_SPACE_RES(mp, (uint)(e - s)); - quota_flag = XFS_QMOPT_RES_REGBLKS; + datablocks = allocatesize_fsb; + numrtextents = 0; } /* - * Allocate and setup the transaction. + * allocate and setup the transaction */ tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); - error = xfs_trans_reserve(tp, resblks, - XFS_WRITE_LOG_RES(mp), resrtextents, + resblks = XFS_DIOSTRAT_SPACE_RES(mp, datablocks); + error = xfs_trans_reserve(tp, + resblks, + XFS_WRITE_LOG_RES(mp), + numrtextents, XFS_TRANS_PERM_LOG_RES, XFS_WRITE_LOG_COUNT); + /* - * Check for running out of space + * check for running out of space */ if (error) { /* @@ -4104,8 +4117,8 @@ xfs_alloc_file_space( break; } xfs_ilock(ip, XFS_ILOCK_EXCL); - error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, - qblocks, 0, quota_flag); + error = XFS_TRANS_RESERVE_QUOTA(mp, tp, + ip->i_udquot, ip->i_gdquot, resblks, 0, 0); if (error) goto error1; @@ -4113,19 +4126,19 @@ xfs_alloc_file_space( xfs_trans_ihold(tp, ip); /* - * Issue the xfs_bmapi() call to allocate the blocks + * issue the bmapi() call to allocate the blocks */ XFS_BMAP_INIT(&free_list, &firstfsb); error = xfs_bmapi(tp, ip, startoffset_fsb, - allocatesize_fsb, bmapi_flag, - &firstfsb, 0, imapp, &nimaps, + allocatesize_fsb, xfs_bmapi_flags, + &firstfsb, 0, imapp, &reccount, &free_list); if (error) { goto error0; } /* - * Complete the transaction + * complete the transaction */ error = xfs_bmap_finish(&tp, &free_list, firstfsb, &committed); if (error) { @@ -4140,7 +4153,7 @@ xfs_alloc_file_space( allocated_fsb = imapp->br_blockcount; - if (nimaps == 0) { + if (reccount == 0) { error = XFS_ERROR(ENOSPC); break; } @@ -4163,11 +4176,9 @@ xfs_alloc_file_space( return error; -error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */ + error0: xfs_bmap_cancel(&free_list); - XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag); - -error1: /* Just cancel transaction */ + error1: xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); xfs_iunlock(ip, XFS_ILOCK_EXCL); goto dmapi_enospc_check; @@ -4412,8 +4423,8 @@ xfs_free_file_space( } xfs_ilock(ip, XFS_ILOCK_EXCL); error = XFS_TRANS_RESERVE_QUOTA(mp, tp, - ip->i_udquot, ip->i_gdquot, resblks, 0, - XFS_QMOPT_RES_REGBLKS); + ip->i_udquot, ip->i_gdquot, resblks, 0, rt ? + XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS); if (error) goto error1; diff --git a/trunk/include/asm-alpha/mmu_context.h b/trunk/include/asm-alpha/mmu_context.h index 6f92482cc96c..a714d0cdc204 100644 --- a/trunk/include/asm-alpha/mmu_context.h +++ b/trunk/include/asm-alpha/mmu_context.h @@ -156,7 +156,7 @@ ev5_switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm, /* 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. */ - task_thread_info(next)->pcb.asn = mmc & HARDWARE_ASN_MASK; + next->thread_info->pcb.asn = mmc & HARDWARE_ASN_MASK; } __EXTERN_INLINE void @@ -235,7 +235,7 @@ init_new_context(struct task_struct *tsk, struct mm_struct *mm) if (cpu_online(i)) mm->context[i] = 0; if (tsk != current) - task_thread_info(tsk)->pcb.ptbr + tsk->thread_info->pcb.ptbr = ((unsigned long)mm->pgd - IDENT_ADDR) >> PAGE_SHIFT; return 0; } @@ -249,7 +249,7 @@ destroy_context(struct mm_struct *mm) static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) { - task_thread_info(tsk)->pcb.ptbr + tsk->thread_info->pcb.ptbr = ((unsigned long)mm->pgd - IDENT_ADDR) >> PAGE_SHIFT; } diff --git a/trunk/include/asm-alpha/processor.h b/trunk/include/asm-alpha/processor.h index 425b7b6d28cb..bb1a7a3abb8b 100644 --- a/trunk/include/asm-alpha/processor.h +++ b/trunk/include/asm-alpha/processor.h @@ -52,10 +52,19 @@ extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); unsigned long get_wchan(struct task_struct *p); -#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc) +/* 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_ESP(tsk) \ - ((tsk) == current ? rdusp() : task_thread_info(tsk)->pcb.usp) + ((tsk) == current ? rdusp() : (tsk)->thread_info->pcb.usp) #define cpu_relax() barrier() diff --git a/trunk/include/asm-alpha/ptrace.h b/trunk/include/asm-alpha/ptrace.h index 9933b8b3612e..072375c135b4 100644 --- a/trunk/include/asm-alpha/ptrace.h +++ b/trunk/include/asm-alpha/ptrace.h @@ -75,10 +75,10 @@ struct switch_stack { #define profile_pc(regs) instruction_pointer(regs) extern void show_regs(struct pt_regs *); -#define task_pt_regs(task) \ - ((struct pt_regs *) (task_stack_page(task) + 2*PAGE_SIZE) - 1) +#define alpha_task_regs(task) \ + ((struct pt_regs *) ((long) (task)->thread_info + 2*PAGE_SIZE) - 1) -#define force_successful_syscall_return() (task_pt_regs(current)->r0 = 0) +#define force_successful_syscall_return() (alpha_task_regs(current)->r0 = 0) #endif diff --git a/trunk/include/asm-alpha/system.h b/trunk/include/asm-alpha/system.h index cc9c7e8cced5..050e86d12891 100644 --- a/trunk/include/asm-alpha/system.h +++ b/trunk/include/asm-alpha/system.h @@ -131,25 +131,15 @@ struct el_common_EV6_mcheck { 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(&task_thread_info(N)->pcb), (P)); \ - check_mmu_context(); \ +#define switch_to(P,N,L) \ + do { \ + (L) = alpha_switch_to(virt_to_phys(&(N)->thread_info->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/trunk/include/asm-alpha/thread_info.h b/trunk/include/asm-alpha/thread_info.h index 69ffd93f8e22..d51491ed00b8 100644 --- a/trunk/include/asm-alpha/thread_info.h +++ b/trunk/include/asm-alpha/thread_info.h @@ -54,6 +54,8 @@ register struct thread_info *__current_thread_info __asm__("$8"); #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/trunk/include/asm-arm/processor.h b/trunk/include/asm-arm/processor.h index 31290694648b..7d4118e09054 100644 --- a/trunk/include/asm-arm/processor.h +++ b/trunk/include/asm-arm/processor.h @@ -85,11 +85,9 @@ unsigned long get_wchan(struct task_struct *p); */ extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); -#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 +#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 /* * Prefetching support - only ARMv5. diff --git a/trunk/include/asm-arm/system.h b/trunk/include/asm-arm/system.h index eb2de8c10515..5621d61ebc07 100644 --- a/trunk/include/asm-arm/system.h +++ b/trunk/include/asm-arm/system.h @@ -168,19 +168,9 @@ extern struct task_struct *__switch_to(struct task_struct *, struct thread_info #define switch_to(prev,next,last) \ do { \ - last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \ + last = __switch_to(prev,prev->thread_info,next->thread_info); \ } 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. */ diff --git a/trunk/include/asm-arm/thread_info.h b/trunk/include/asm-arm/thread_info.h index 33a33cbb6329..7c98557b717f 100644 --- a/trunk/include/asm-arm/thread_info.h +++ b/trunk/include/asm-arm/thread_info.h @@ -96,10 +96,13 @@ static inline struct thread_info *current_thread_info(void) 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(task_thread_info(tsk)->cpu_context.pc))) + ((unsigned long)(pc_pointer((tsk)->thread_info->cpu_context.pc))) #define thread_saved_fp(tsk) \ - ((unsigned long)(task_thread_info(tsk)->cpu_context.fp)) + ((unsigned long)((tsk)->thread_info->cpu_context.fp)) extern void iwmmxt_task_disable(struct thread_info *); extern void iwmmxt_task_copy(struct thread_info *, void *); diff --git a/trunk/include/asm-arm26/system.h b/trunk/include/asm-arm26/system.h index ca4ccfc4b578..f23fac1938f3 100644 --- a/trunk/include/asm-arm26/system.h +++ b/trunk/include/asm-arm26/system.h @@ -111,19 +111,9 @@ extern struct task_struct *__switch_to(struct task_struct *, struct thread_info #define switch_to(prev,next,last) \ do { \ - last = __switch_to(prev,task_thread_info(prev),task_thread_info(next)); \ + last = __switch_to(prev,prev->thread_info,next->thread_info); \ } 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 */ diff --git a/trunk/include/asm-arm26/thread_info.h b/trunk/include/asm-arm26/thread_info.h index a65e58a0a767..aff3e5699c64 100644 --- a/trunk/include/asm-arm26/thread_info.h +++ b/trunk/include/asm-arm26/thread_info.h @@ -82,15 +82,18 @@ static inline struct thread_info *current_thread_info(void) /* 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 task_pt_regs(task) ((struct pt_regs *)(task_stack_page(task) + THREAD_SIZE - 8) - 1) +#define __get_user_regs(x) (((struct pt_regs *)((unsigned long)(x) + 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(task_thread_info(tsk)->cpu_context.pc))) + ((unsigned long)(pc_pointer((tsk)->thread_info->cpu_context.pc))) #define thread_saved_fp(tsk) \ - ((unsigned long)(task_thread_info(tsk)->cpu_context.fp)) + ((unsigned long)((tsk)->thread_info->cpu_context.fp)) #else /* !__ASSEMBLY__ */ diff --git a/trunk/include/asm-cris/arch-v10/processor.h b/trunk/include/asm-cris/arch-v10/processor.h index cc692c7a0660..e23df8dc96e8 100644 --- a/trunk/include/asm-cris/arch-v10/processor.h +++ b/trunk/include/asm-cris/arch-v10/processor.h @@ -40,7 +40,7 @@ struct thread_struct { #define KSTK_EIP(tsk) \ ({ \ unsigned long eip = 0; \ - unsigned long regs = (unsigned long)task_pt_regs(tsk); \ + unsigned long regs = (unsigned long)user_regs(tsk); \ if (regs > PAGE_SIZE && \ virt_addr_valid(regs)) \ eip = ((struct pt_regs *)regs)->irp; \ diff --git a/trunk/include/asm-cris/arch-v32/processor.h b/trunk/include/asm-cris/arch-v32/processor.h index 32bf2e538ced..8c939bf27987 100644 --- a/trunk/include/asm-cris/arch-v32/processor.h +++ b/trunk/include/asm-cris/arch-v32/processor.h @@ -36,7 +36,7 @@ struct thread_struct { #define KSTK_EIP(tsk) \ ({ \ unsigned long eip = 0; \ - unsigned long regs = (unsigned long)task_pt_regs(tsk); \ + unsigned long regs = (unsigned long)user_regs(tsk); \ if (regs > PAGE_SIZE && virt_addr_valid(regs)) \ eip = ((struct pt_regs *)regs)->erp; \ eip; \ diff --git a/trunk/include/asm-cris/processor.h b/trunk/include/asm-cris/processor.h index 961e2bceadbc..dce41009eeb0 100644 --- a/trunk/include/asm-cris/processor.h +++ b/trunk/include/asm-cris/processor.h @@ -45,8 +45,7 @@ struct task_struct; * Dito but for the currently running task */ -#define task_pt_regs(task) user_regs(task_thread_info(task)) -#define current_regs() task_pt_regs(current) +#define current_regs() user_regs(current->thread_info) static inline void prepare_to_copy(struct task_struct *tsk) { diff --git a/trunk/include/asm-cris/thread_info.h b/trunk/include/asm-cris/thread_info.h index 7ad853c3f74e..cef0140fc104 100644 --- a/trunk/include/asm-cris/thread_info.h +++ b/trunk/include/asm-cris/thread_info.h @@ -69,6 +69,8 @@ struct thread_info { /* 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/trunk/include/asm-frv/thread_info.h b/trunk/include/asm-frv/thread_info.h index a5576e02dd1d..60f6b2aee76d 100644 --- a/trunk/include/asm-frv/thread_info.h +++ b/trunk/include/asm-frv/thread_info.h @@ -110,6 +110,8 @@ register struct thread_info *__current_thread_info asm("gr15"); #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/trunk/include/asm-h8300/thread_info.h b/trunk/include/asm-h8300/thread_info.h index 45f09dc9caff..bfcc755c3bb1 100644 --- a/trunk/include/asm-h8300/thread_info.h +++ b/trunk/include/asm-h8300/thread_info.h @@ -69,6 +69,8 @@ static inline struct thread_info *current_thread_info(void) #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/trunk/include/asm-i386/i387.h b/trunk/include/asm-i386/i387.h index 152d0baa576a..6747006743f9 100644 --- a/trunk/include/asm-i386/i387.h +++ b/trunk/include/asm-i386/i387.h @@ -49,19 +49,19 @@ static inline void __save_init_fpu( struct task_struct *tsk ) X86_FEATURE_FXSR, "m" (tsk->thread.i387.fxsave) :"memory"); - task_thread_info(tsk)->status &= ~TS_USEDFPU; + tsk->thread_info->status &= ~TS_USEDFPU; } #define __unlazy_fpu( tsk ) do { \ - if (task_thread_info(tsk)->status & TS_USEDFPU) \ + if ((tsk)->thread_info->status & TS_USEDFPU) \ save_init_fpu( tsk ); \ } while (0) #define __clear_fpu( tsk ) \ do { \ - if (task_thread_info(tsk)->status & TS_USEDFPU) { \ + if ((tsk)->thread_info->status & TS_USEDFPU) { \ asm volatile("fnclex ; fwait"); \ - task_thread_info(tsk)->status &= ~TS_USEDFPU; \ + (tsk)->thread_info->status &= ~TS_USEDFPU; \ stts(); \ } \ } while (0) diff --git a/trunk/include/asm-i386/processor.h b/trunk/include/asm-i386/processor.h index feca5d961e2b..13ecf66b098c 100644 --- a/trunk/include/asm-i386/processor.h +++ b/trunk/include/asm-i386/processor.h @@ -561,20 +561,10 @@ unsigned long get_wchan(struct task_struct *p); (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_stack_page(task))-8); \ + __regs__ = (struct pt_regs *)KSTK_TOP((task)->thread_info); \ __regs__ - 1; \ }) diff --git a/trunk/include/asm-i386/system.h b/trunk/include/asm-i386/system.h index 36a92ed6a9d0..9c0593b7a94e 100644 --- a/trunk/include/asm-i386/system.h +++ b/trunk/include/asm-i386/system.h @@ -548,15 +548,6 @@ void enable_hlt(void); 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/trunk/include/asm-i386/thread_info.h b/trunk/include/asm-i386/thread_info.h index 2493e77e8c30..8fbf791651bf 100644 --- a/trunk/include/asm-i386/thread_info.h +++ b/trunk/include/asm-i386/thread_info.h @@ -111,6 +111,8 @@ register unsigned long current_stack_pointer asm("esp") __attribute_used__; #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/trunk/include/asm-i386/topology.h b/trunk/include/asm-i386/topology.h index d7e19eb344b7..0ec27c9e8e45 100644 --- a/trunk/include/asm-i386/topology.h +++ b/trunk/include/asm-i386/topology.h @@ -72,6 +72,7 @@ static inline int node_to_first_cpu(int node) .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/trunk/include/asm-ia64/compat.h b/trunk/include/asm-ia64/compat.h index c0b19106665c..aaf11f4e9169 100644 --- a/trunk/include/asm-ia64/compat.h +++ b/trunk/include/asm-ia64/compat.h @@ -192,7 +192,7 @@ compat_ptr (compat_uptr_t uptr) static __inline__ void __user * compat_alloc_user_space (long len) { - struct pt_regs *regs = task_pt_regs(current); + struct pt_regs *regs = ia64_task_regs(current); return (void __user *) (((regs->r12 & 0xffffffff) & -16) - len); } diff --git a/trunk/include/asm-ia64/processor.h b/trunk/include/asm-ia64/processor.h index 8c648bf72bbd..94e07e727395 100644 --- a/trunk/include/asm-ia64/processor.h +++ b/trunk/include/asm-ia64/processor.h @@ -352,7 +352,7 @@ extern unsigned long get_wchan (struct task_struct *p); /* Return instruction pointer of blocked task TSK. */ #define KSTK_EIP(tsk) \ ({ \ - struct pt_regs *_regs = task_pt_regs(tsk); \ + struct pt_regs *_regs = ia64_task_regs(tsk); \ _regs->cr_iip + ia64_psr(_regs)->ri; \ }) diff --git a/trunk/include/asm-ia64/ptrace.h b/trunk/include/asm-ia64/ptrace.h index 9471cdc3f4c0..2c703d6e0c86 100644 --- a/trunk/include/asm-ia64/ptrace.h +++ b/trunk/include/asm-ia64/ptrace.h @@ -248,7 +248,7 @@ struct switch_stack { }) /* given a pointer to a task_struct, return the user's pt_regs */ -# define task_pt_regs(t) (((struct pt_regs *) ((char *) (t) + IA64_STK_OFFSET)) - 1) +# define ia64_task_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 @@ struct switch_stack { * * On ia64, we can clear the user's pt_regs->r8 to force a successful syscall. */ -# define force_successful_syscall_return() (task_pt_regs(current)->r8 = 0) +# define force_successful_syscall_return() (ia64_task_regs(current)->r8 = 0) struct task_struct; /* forward decl */ struct unw_frame_info; /* forward decl */ diff --git a/trunk/include/asm-ia64/system.h b/trunk/include/asm-ia64/system.h index 80c5a234e259..635235fa1e32 100644 --- a/trunk/include/asm-ia64/system.h +++ b/trunk/include/asm-ia64/system.h @@ -219,14 +219,14 @@ extern void ia64_load_extra (struct task_struct *task); #define IA64_HAS_EXTRA_STATE(t) \ ((t)->thread.flags & (IA64_THREAD_DBG_VALID|IA64_THREAD_PM_VALID) \ - || IS_IA32_PROCESS(task_pt_regs(t)) || PERFMON_IS_SYSWIDE()) + || IS_IA32_PROCESS(ia64_task_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(task_pt_regs(next))->dfh = !ia64_is_local_fpu_owner(next); \ + ia64_psr(ia64_task_regs(next))->dfh = !ia64_is_local_fpu_owner(next); \ (last) = ia64_switch_to((next)); \ } while (0) @@ -238,8 +238,8 @@ extern void ia64_load_extra (struct task_struct *task); * the latest fph state from another CPU. In other words: eager save, lazy restore. */ # define switch_to(prev,next,last) do { \ - if (ia64_psr(task_pt_regs(prev))->mfh && ia64_is_local_fpu_owner(prev)) { \ - ia64_psr(task_pt_regs(prev))->mfh = 0; \ + if (ia64_psr(ia64_task_regs(prev))->mfh && ia64_is_local_fpu_owner(prev)) { \ + ia64_psr(ia64_task_regs(prev))->mfh = 0; \ (prev)->thread.flags |= IA64_THREAD_FPH_VALID; \ __ia64_save_fpu((prev)->thread.fph); \ } \ @@ -279,7 +279,6 @@ extern void ia64_load_extra (struct task_struct *task); #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/trunk/include/asm-ia64/thread_info.h b/trunk/include/asm-ia64/thread_info.h index 653bb7f9a753..171b2207bde4 100644 --- a/trunk/include/asm-ia64/thread_info.h +++ b/trunk/include/asm-ia64/thread_info.h @@ -57,20 +57,11 @@ struct thread_info { /* 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/trunk/include/asm-ia64/topology.h b/trunk/include/asm-ia64/topology.h index d8aae4da3978..f7c330467e7e 100644 --- a/trunk/include/asm-ia64/topology.h +++ b/trunk/include/asm-ia64/topology.h @@ -55,6 +55,7 @@ void build_cpu_to_node_map(void); .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, \ @@ -80,6 +81,7 @@ void build_cpu_to_node_map(void); .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/trunk/include/asm-m32r/ptrace.h b/trunk/include/asm-m32r/ptrace.h index 0d058b2d844e..55cd7ecfde43 100644 --- a/trunk/include/asm-m32r/ptrace.h +++ b/trunk/include/asm-m32r/ptrace.h @@ -163,9 +163,6 @@ extern void show_regs(struct pt_regs *); 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/trunk/include/asm-m32r/system.h b/trunk/include/asm-m32r/system.h index 06c12a037cba..dcf619a0a0b0 100644 --- a/trunk/include/asm-m32r/system.h +++ b/trunk/include/asm-m32r/system.h @@ -68,16 +68,6 @@ 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/trunk/include/asm-m32r/thread_info.h b/trunk/include/asm-m32r/thread_info.h index 22aff3222d22..0f589363f619 100644 --- a/trunk/include/asm-m32r/thread_info.h +++ b/trunk/include/asm-m32r/thread_info.h @@ -110,6 +110,8 @@ static inline struct thread_info *current_thread_info(void) #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/trunk/include/asm-m68k/amigahw.h b/trunk/include/asm-m68k/amigahw.h index a16fe4e5a28a..3ae5d8d55ba9 100644 --- a/trunk/include/asm-m68k/amigahw.h +++ b/trunk/include/asm-m68k/amigahw.h @@ -274,7 +274,7 @@ struct CIA { #define ZTWO_VADDR(x) (((unsigned long)(x))+zTwoBase) #define CUSTOM_PHYSADDR (0xdff000) -#define amiga_custom ((*(volatile struct CUSTOM *)(zTwoBase+CUSTOM_PHYSADDR))) +#define custom ((*(volatile struct CUSTOM *)(zTwoBase+CUSTOM_PHYSADDR))) #define CIAA_PHYSADDR (0xbfe001) #define CIAB_PHYSADDR (0xbfd000) @@ -294,12 +294,12 @@ static inline void amifb_video_off(void) { if (amiga_chipset == CS_ECS || amiga_chipset == CS_AGA) { /* program Denise/Lisa for a higher maximum play rate */ - amiga_custom.htotal = 113; /* 31 kHz */ - amiga_custom.vtotal = 223; /* 70 Hz */ - amiga_custom.beamcon0 = 0x4390; /* HARDDIS, VAR{BEAM,VSY,HSY,CSY}EN */ + custom.htotal = 113; /* 31 kHz */ + custom.vtotal = 223; /* 70 Hz */ + custom.beamcon0 = 0x4390; /* HARDDIS, VAR{BEAM,VSY,HSY,CSY}EN */ /* suspend the monitor */ - amiga_custom.hsstrt = amiga_custom.hsstop = 116; - amiga_custom.vsstrt = amiga_custom.vsstop = 226; + custom.hsstrt = custom.hsstop = 116; + custom.vsstrt = custom.vsstop = 226; amiga_audio_min_period = 57; } } diff --git a/trunk/include/asm-m68k/amigaints.h b/trunk/include/asm-m68k/amigaints.h index aa968d014bb6..2aff4cfbf7b3 100644 --- a/trunk/include/asm-m68k/amigaints.h +++ b/trunk/include/asm-m68k/amigaints.h @@ -109,6 +109,8 @@ 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/trunk/include/asm-m68k/checksum.h b/trunk/include/asm-m68k/checksum.h index 17280ef719f5..78860c20db01 100644 --- a/trunk/include/asm-m68k/checksum.h +++ b/trunk/include/asm-m68k/checksum.h @@ -25,7 +25,7 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) * better 64-bit) boundary */ -extern unsigned int csum_partial_copy_from_user(const unsigned char __user *src, +extern unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, int len, int sum, int *csum_err); diff --git a/trunk/include/asm-m68k/dsp56k.h b/trunk/include/asm-m68k/dsp56k.h index 2d8c0c9f794b..ab3dd33e23a1 100644 --- a/trunk/include/asm-m68k/dsp56k.h +++ b/trunk/include/asm-m68k/dsp56k.h @@ -13,7 +13,7 @@ /* Used for uploading DSP binary code */ struct dsp56k_upload { int len; - char __user *bin; + char *bin; }; /* For the DSP host flags */ diff --git a/trunk/include/asm-m68k/floppy.h b/trunk/include/asm-m68k/floppy.h index 63a05ed95c17..c6e708dd9f62 100644 --- a/trunk/include/asm-m68k/floppy.h +++ b/trunk/include/asm-m68k/floppy.h @@ -46,7 +46,7 @@ asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id, static int virtual_dma_count=0; static int virtual_dma_residue=0; -static char *virtual_dma_addr=NULL; +static char *virtual_dma_addr=0; static int virtual_dma_mode=0; static int doing_pdma=0; diff --git a/trunk/include/asm-m68k/hardirq.h b/trunk/include/asm-m68k/hardirq.h index 5e1c5826c83d..728318bf7f0e 100644 --- a/trunk/include/asm-m68k/hardirq.h +++ b/trunk/include/asm-m68k/hardirq.h @@ -14,4 +14,13 @@ typedef struct { #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/trunk/include/asm-m68k/io.h b/trunk/include/asm-m68k/io.h index dcfaa352d34c..6bb8b0d8f99d 100644 --- a/trunk/include/asm-m68k/io.h +++ b/trunk/include/asm-m68k/io.h @@ -24,7 +24,6 @@ #ifdef __KERNEL__ #include -#include #include #include @@ -121,68 +120,68 @@ extern int isa_sex; * be compiled in so the case statement will be optimised away */ -static inline u8 __iomem *isa_itb(unsigned long addr) +static inline u8 *isa_itb(unsigned long addr) { switch(ISA_TYPE) { #ifdef CONFIG_Q40 - case Q40_ISA: return (u8 __iomem *)Q40_ISA_IO_B(addr); + case Q40_ISA: return (u8 *)Q40_ISA_IO_B(addr); #endif #ifdef CONFIG_GG2 - case GG2_ISA: return (u8 __iomem *)GG2_ISA_IO_B(addr); + case GG2_ISA: return (u8 *)GG2_ISA_IO_B(addr); #endif #ifdef CONFIG_AMIGA_PCMCIA - case AG_ISA: return (u8 __iomem *)AG_ISA_IO_B(addr); + case AG_ISA: return (u8 *)AG_ISA_IO_B(addr); #endif - default: return NULL; /* avoid warnings, just in case */ + default: return 0; /* avoid warnings, just in case */ } } -static inline u16 __iomem *isa_itw(unsigned long addr) +static inline u16 *isa_itw(unsigned long addr) { switch(ISA_TYPE) { #ifdef CONFIG_Q40 - case Q40_ISA: return (u16 __iomem *)Q40_ISA_IO_W(addr); + case Q40_ISA: return (u16 *)Q40_ISA_IO_W(addr); #endif #ifdef CONFIG_GG2 - case GG2_ISA: return (u16 __iomem *)GG2_ISA_IO_W(addr); + case GG2_ISA: return (u16 *)GG2_ISA_IO_W(addr); #endif #ifdef CONFIG_AMIGA_PCMCIA - case AG_ISA: return (u16 __iomem *)AG_ISA_IO_W(addr); + case AG_ISA: return (u16 *)AG_ISA_IO_W(addr); #endif - default: return NULL; /* avoid warnings, just in case */ + default: return 0; /* avoid warnings, just in case */ } } -static inline u8 __iomem *isa_mtb(unsigned long addr) +static inline u8 *isa_mtb(unsigned long addr) { switch(ISA_TYPE) { #ifdef CONFIG_Q40 - case Q40_ISA: return (u8 __iomem *)Q40_ISA_MEM_B(addr); + case Q40_ISA: return (u8 *)Q40_ISA_MEM_B(addr); #endif #ifdef CONFIG_GG2 - case GG2_ISA: return (u8 __iomem *)GG2_ISA_MEM_B(addr); + case GG2_ISA: return (u8 *)GG2_ISA_MEM_B(addr); #endif #ifdef CONFIG_AMIGA_PCMCIA - case AG_ISA: return (u8 __iomem *)addr; + case AG_ISA: return (u8 *)addr; #endif - default: return NULL; /* avoid warnings, just in case */ + default: return 0; /* avoid warnings, just in case */ } } -static inline u16 __iomem *isa_mtw(unsigned long addr) +static inline u16 *isa_mtw(unsigned long addr) { switch(ISA_TYPE) { #ifdef CONFIG_Q40 - case Q40_ISA: return (u16 __iomem *)Q40_ISA_MEM_W(addr); + case Q40_ISA: return (u16 *)Q40_ISA_MEM_W(addr); #endif #ifdef CONFIG_GG2 - case GG2_ISA: return (u16 __iomem *)GG2_ISA_MEM_W(addr); + case GG2_ISA: return (u16 *)GG2_ISA_MEM_W(addr); #endif #ifdef CONFIG_AMIGA_PCMCIA - case AG_ISA: return (u16 __iomem *)addr; + case AG_ISA: return (u16 *)addr; #endif - default: return NULL; /* avoid warnings, just in case */ + default: return 0; /* avoid warnings, just in case */ } } @@ -327,20 +326,20 @@ static inline void isa_delay(void) #define mmiowb() -static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size) +static inline void *ioremap(unsigned long physaddr, unsigned long size) { return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); } -static inline void __iomem *ioremap_nocache(unsigned long physaddr, unsigned long size) +static inline void *ioremap_nocache(unsigned long physaddr, unsigned long size) { return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); } -static inline void __iomem *ioremap_writethrough(unsigned long physaddr, +static inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size) { return __ioremap(physaddr, size, IOMAP_WRITETHROUGH); } -static inline void __iomem *ioremap_fullcache(unsigned long physaddr, +static inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size) { return __ioremap(physaddr, size, IOMAP_FULL_CACHING); diff --git a/trunk/include/asm-m68k/irq.h b/trunk/include/asm-m68k/irq.h index 325c86f8512d..127ad190cf2d 100644 --- a/trunk/include/asm-m68k/irq.h +++ b/trunk/include/asm-m68k/irq.h @@ -22,15 +22,6 @@ #define NR_IRQS (24+SYS_IRQS) #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. diff --git a/trunk/include/asm-m68k/machdep.h b/trunk/include/asm-m68k/machdep.h index 7d3fee342369..a0dd5c47002c 100644 --- a/trunk/include/asm-m68k/machdep.h +++ b/trunk/include/asm-m68k/machdep.h @@ -34,6 +34,7 @@ extern void (*mach_power_off)( void ); 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/trunk/include/asm-m68k/raw_io.h b/trunk/include/asm-m68k/raw_io.h index 5439bcaa57c6..041f0a87b25d 100644 --- a/trunk/include/asm-m68k/raw_io.h +++ b/trunk/include/asm-m68k/raw_io.h @@ -19,9 +19,9 @@ #define IOMAP_NOCACHE_NONSER 2 #define IOMAP_WRITETHROUGH 3 -extern void iounmap(void __iomem *addr); +extern void iounmap(void *addr); -extern void __iomem *__ioremap(unsigned long physaddr, unsigned long size, +extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag); extern void __iounmap(void *addr, unsigned long size); @@ -30,21 +30,21 @@ extern void __iounmap(void *addr, unsigned long size); * two accesses to memory, which may be undesirable for some devices. */ #define in_8(addr) \ - ({ u8 __v = (*(__force volatile u8 *) (addr)); __v; }) + ({ u8 __v = (*(volatile u8 *) (addr)); __v; }) #define in_be16(addr) \ - ({ u16 __v = (*(__force volatile u16 *) (addr)); __v; }) + ({ u16 __v = (*(volatile u16 *) (addr)); __v; }) #define in_be32(addr) \ - ({ u32 __v = (*(__force volatile u32 *) (addr)); __v; }) + ({ u32 __v = (*(volatile u32 *) (addr)); __v; }) #define in_le16(addr) \ - ({ u16 __v = le16_to_cpu(*(__force volatile u16 *) (addr)); __v; }) + ({ u16 __v = le16_to_cpu(*(volatile u16 *) (addr)); __v; }) #define in_le32(addr) \ - ({ u32 __v = le32_to_cpu(*(__force volatile u32 *) (addr)); __v; }) + ({ u32 __v = le32_to_cpu(*(volatile u32 *) (addr)); __v; }) -#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 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 raw_inb in_8 #define raw_inw in_be16 @@ -54,7 +54,7 @@ extern void __iounmap(void *addr, unsigned long size); #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 __iomem *port, u8 *buf, unsigned int len) +static inline void raw_insb(volatile u8 *port, u8 *buf, unsigned int len) { unsigned int i; @@ -62,7 +62,7 @@ static inline void raw_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len *buf++ = in_8(port); } -static inline void raw_outsb(volatile u8 __iomem *port, const u8 *buf, +static inline void raw_outsb(volatile u8 *port, const u8 *buf, unsigned int len) { unsigned int i; @@ -71,7 +71,7 @@ static inline void raw_outsb(volatile u8 __iomem *port, const u8 *buf, out_8(port, *buf++); } -static inline void raw_insw(volatile u16 __iomem *port, u16 *buf, unsigned int nr) +static inline void raw_insw(volatile u16 *port, u16 *buf, unsigned int nr) { unsigned int tmp; @@ -110,7 +110,7 @@ static inline void raw_insw(volatile u16 __iomem *port, u16 *buf, unsigned int n } } -static inline void raw_outsw(volatile u16 __iomem *port, const u16 *buf, +static inline void raw_outsw(volatile u16 *port, const u16 *buf, unsigned int nr) { unsigned int tmp; @@ -150,7 +150,7 @@ static inline void raw_outsw(volatile u16 __iomem *port, const u16 *buf, } } -static inline void raw_insl(volatile u32 __iomem *port, u32 *buf, unsigned int nr) +static inline void raw_insl(volatile u32 *port, u32 *buf, unsigned int nr) { unsigned int tmp; @@ -189,7 +189,7 @@ static inline void raw_insl(volatile u32 __iomem *port, u32 *buf, unsigned int n } } -static inline void raw_outsl(volatile u32 __iomem *port, const u32 *buf, +static inline void raw_outsl(volatile u32 *port, const u32 *buf, unsigned int nr) { unsigned int tmp; @@ -230,7 +230,7 @@ static inline void raw_outsl(volatile u32 __iomem *port, const u32 *buf, } -static inline void raw_insw_swapw(volatile u16 __iomem *port, u16 *buf, +static inline void raw_insw_swapw(volatile u16 *port, u16 *buf, unsigned int nr) { if ((nr) % 8) @@ -283,7 +283,7 @@ static inline void raw_insw_swapw(volatile u16 __iomem *port, u16 *buf, : "d0", "a0", "a1", "d6"); } -static inline void raw_outsw_swapw(volatile u16 __iomem *port, const u16 *buf, +static inline void raw_outsw_swapw(volatile u16 *port, const u16 *buf, unsigned int nr) { if ((nr) % 8) diff --git a/trunk/include/asm-m68k/signal.h b/trunk/include/asm-m68k/signal.h index b7b7ea20caab..a0cdf9082372 100644 --- a/trunk/include/asm-m68k/signal.h +++ b/trunk/include/asm-m68k/signal.h @@ -144,7 +144,7 @@ struct sigaction { #endif /* __KERNEL__ */ typedef struct sigaltstack { - void __user *ss_sp; + void *ss_sp; int ss_flags; size_t ss_size; } stack_t; diff --git a/trunk/include/asm-m68k/sun3_pgtable.h b/trunk/include/asm-m68k/sun3_pgtable.h index 5156a28a18d8..e974bb072047 100644 --- a/trunk/include/asm-m68k/sun3_pgtable.h +++ b/trunk/include/asm-m68k/sun3_pgtable.h @@ -211,7 +211,7 @@ static inline unsigned long pte_to_pgoff(pte_t pte) return pte.pte & SUN3_PAGE_PGNUM_MASK; } -static inline pte_t pgoff_to_pte(unsigned off) +static inline pte_t pgoff_to_pte(inline unsigned off) { pte_t pte = { off + SUN3_PAGE_ACCESSED }; return pte; diff --git a/trunk/include/asm-m68k/sun3ints.h b/trunk/include/asm-m68k/sun3ints.h index bd038fccb64b..fd838eb14213 100644 --- a/trunk/include/asm-m68k/sun3ints.h +++ b/trunk/include/asm-m68k/sun3ints.h @@ -31,6 +31,7 @@ int sun3_request_irq(unsigned int irq, ); 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/trunk/include/asm-m68k/sun3xflop.h b/trunk/include/asm-m68k/sun3xflop.h index 98a9f79dab29..fda1eccf10aa 100644 --- a/trunk/include/asm-m68k/sun3xflop.h +++ b/trunk/include/asm-m68k/sun3xflop.h @@ -208,7 +208,7 @@ static int sun3xflop_request_irq(void) if(!once) { once = 1; - error = request_irq(FLOPPY_IRQ, sun3xflop_hardint, SA_INTERRUPT, "floppy", NULL); + error = request_irq(FLOPPY_IRQ, sun3xflop_hardint, SA_INTERRUPT, "floppy", 0); return ((error == 0) ? 0 : -1); } else return 0; } @@ -238,7 +238,7 @@ static int sun3xflop_init(void) *sun3x_fdc.fcr_r = 0; /* Success... */ - floppy_set_flags(NULL, 1, FD_BROKEN_DCL); // I don't know how to detect this. + floppy_set_flags(0, 1, FD_BROKEN_DCL); // I don't know how to detect this. allowed_drive_mask = 0x01; return (int) SUN3X_FDC; } diff --git a/trunk/include/asm-m68k/thread_info.h b/trunk/include/asm-m68k/thread_info.h index c4d622a57dfb..9532ca3c45cb 100644 --- a/trunk/include/asm-m68k/thread_info.h +++ b/trunk/include/asm-m68k/thread_info.h @@ -37,7 +37,6 @@ struct thread_info { #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/trunk/include/asm-m68k/uaccess.h b/trunk/include/asm-m68k/uaccess.h index 2ffd87b0a769..f5cedf19cf68 100644 --- a/trunk/include/asm-m68k/uaccess.h +++ b/trunk/include/asm-m68k/uaccess.h @@ -42,7 +42,6 @@ struct exception_table_entry ({ \ 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); \ @@ -92,7 +91,6 @@ __asm__ __volatile__ \ ({ \ 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"); \ @@ -107,7 +105,7 @@ __asm__ __volatile__ \ __gu_err = __constant_copy_from_user(&__gu_val, ptr, 8); \ break; \ default: \ - __gu_val = (typeof(*(ptr)))0; \ + __gu_val = 0; \ __gu_err = __get_user_bad(); \ break; \ } \ @@ -136,7 +134,7 @@ __asm__ __volatile__ \ : "m"(*(ptr)), "i" (-EFAULT), "0"(0)) static inline unsigned long -__generic_copy_from_user(void *to, const void __user *from, unsigned long n) +__generic_copy_from_user(void *to, const void *from, unsigned long n) { unsigned long tmp; __asm__ __volatile__ @@ -191,7 +189,7 @@ __generic_copy_from_user(void *to, const void __user *from, unsigned long n) } static inline unsigned long -__generic_copy_to_user(void __user *to, const void *from, unsigned long n) +__generic_copy_to_user(void *to, const void *from, unsigned long n) { unsigned long tmp; __asm__ __volatile__ @@ -266,7 +264,7 @@ __generic_copy_to_user(void __user *to, const void *from, unsigned long n) : "d0", "memory") static inline unsigned long -__constant_copy_from_user(void *to, const void __user *from, unsigned long n) +__constant_copy_from_user(void *to, const void *from, unsigned long n) { switch (n) { case 0: @@ -522,7 +520,7 @@ __constant_copy_from_user(void *to, const void __user *from, unsigned long n) #define __copy_from_user_inatomic __copy_from_user static inline unsigned long -__constant_copy_to_user(void __user *to, const void *from, unsigned long n) +__constant_copy_to_user(void *to, const void *from, unsigned long n) { switch (n) { case 0: @@ -768,7 +766,7 @@ __constant_copy_to_user(void __user *to, const void *from, unsigned long n) */ static inline long -strncpy_from_user(char *dst, const char __user *src, long count) +strncpy_from_user(char *dst, const char *src, long count) { long res; if (count == 0) return count; @@ -801,11 +799,11 @@ strncpy_from_user(char *dst, const char __user *src, long count) * * Return 0 on exception, a value greater than N if too long */ -static inline long strnlen_user(const char __user *src, long n) +static inline long strnlen_user(const char *src, long n) { long res; - res = -(unsigned long)src; + res = -(long)src; __asm__ __volatile__ ("1:\n" " tstl %2\n" @@ -844,7 +842,7 @@ static inline long strnlen_user(const char __user *src, long n) */ static inline unsigned long -clear_user(void __user *to, unsigned long n) +clear_user(void *to, unsigned long n) { __asm__ __volatile__ (" tstl %1\n" diff --git a/trunk/include/asm-m68k/zorro.h b/trunk/include/asm-m68k/zorro.h index 5ce97c22b582..cf816588bedb 100644 --- a/trunk/include/asm-m68k/zorro.h +++ b/trunk/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 __iomem *z_remap_nocache_ser(unsigned long physaddr, +static inline void *z_remap_nocache_ser(unsigned long physaddr, unsigned long size) { return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); } -static inline void __iomem *z_remap_nocache_nonser(unsigned long physaddr, +static inline void *z_remap_nocache_nonser(unsigned long physaddr, unsigned long size) { return __ioremap(physaddr, size, IOMAP_NOCACHE_NONSER); } -static inline void __iomem *z_remap_writethrough(unsigned long physaddr, +static inline void *z_remap_writethrough(unsigned long physaddr, unsigned long size) { return __ioremap(physaddr, size, IOMAP_WRITETHROUGH); } -static inline void __iomem *z_remap_fullcache(unsigned long physaddr, +static inline void *z_remap_fullcache(unsigned long physaddr, unsigned long size) { return __ioremap(physaddr, size, IOMAP_FULL_CACHING); diff --git a/trunk/include/asm-m68knommu/machdep.h b/trunk/include/asm-m68knommu/machdep.h index 27c90afd3339..5a9f9c297f79 100644 --- a/trunk/include/asm-m68knommu/machdep.h +++ b/trunk/include/asm-m68knommu/machdep.h @@ -38,6 +38,7 @@ extern void (*mach_power_off)( void ); 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/trunk/include/asm-m68knommu/thread_info.h b/trunk/include/asm-m68knommu/thread_info.h index b8f009edf2b2..7b9a3fa3af5d 100644 --- a/trunk/include/asm-m68knommu/thread_info.h +++ b/trunk/include/asm-m68knommu/thread_info.h @@ -75,6 +75,8 @@ static inline struct thread_info *current_thread_info(void) #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/trunk/include/asm-mips/mach-ip27/topology.h b/trunk/include/asm-mips/mach-ip27/topology.h index 59d26b52ba32..82141c711c33 100644 --- a/trunk/include/asm-mips/mach-ip27/topology.h +++ b/trunk/include/asm-mips/mach-ip27/topology.h @@ -27,6 +27,7 @@ extern unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES]; .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/trunk/include/asm-mips/processor.h b/trunk/include/asm-mips/processor.h index 39d2bd50fece..de53055a62ae 100644 --- a/trunk/include/asm-mips/processor.h +++ b/trunk/include/asm-mips/processor.h @@ -200,11 +200,11 @@ extern void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long unsigned long get_wchan(struct task_struct *p); -#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 __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 cpu_relax() barrier() diff --git a/trunk/include/asm-mips/system.h b/trunk/include/asm-mips/system.h index e8e5d4143377..330c4e497af3 100644 --- a/trunk/include/asm-mips/system.h +++ b/trunk/include/asm-mips/system.h @@ -159,21 +159,11 @@ struct task_struct; do { \ if (cpu_has_dsp) \ __save_dsp(prev); \ - (last) = resume(prev, next, task_thread_info(next)); \ + (last) = resume(prev, next, next->thread_info); \ 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/trunk/include/asm-mips/thread_info.h b/trunk/include/asm-mips/thread_info.h index 1612b3fe1080..e6c24472e03f 100644 --- a/trunk/include/asm-mips/thread_info.h +++ b/trunk/include/asm-mips/thread_info.h @@ -97,6 +97,8 @@ register struct thread_info *__current_thread_info __asm__("$28"); #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/trunk/include/asm-parisc/system.h b/trunk/include/asm-parisc/system.h index a5a973c0c07f..f3928d3a80cb 100644 --- a/trunk/include/asm-parisc/system.h +++ b/trunk/include/asm-parisc/system.h @@ -49,15 +49,6 @@ extern struct task_struct *_switch_to(struct task_struct *, struct task_struct * (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/trunk/include/asm-parisc/thread_info.h b/trunk/include/asm-parisc/thread_info.h index ac32f140b83a..57bbb76cb6c1 100644 --- a/trunk/include/asm-parisc/thread_info.h +++ b/trunk/include/asm-parisc/thread_info.h @@ -43,6 +43,9 @@ struct thread_info { #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/trunk/include/asm-powerpc/iommu.h b/trunk/include/asm-powerpc/iommu.h index d5677cbec200..8a8393e50774 100644 --- a/trunk/include/asm-powerpc/iommu.h +++ b/trunk/include/asm-powerpc/iommu.h @@ -64,6 +64,25 @@ extern void iommu_free_table(struct device_node *dn); #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/trunk/include/asm-powerpc/iseries/hv_call.h b/trunk/include/asm-powerpc/iseries/hv_call.h index 162d653ad51f..e9f831c9a5e5 100644 --- a/trunk/include/asm-powerpc/iseries/hv_call.h +++ b/trunk/include/asm-powerpc/iseries/hv_call.h @@ -1,4 +1,5 @@ /* + * HvCall.h * Copyright (C) 2001 Mike Corrigan IBM Corporation * * This program is free software; you can redistribute it and/or modify @@ -14,7 +15,8 @@ * 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/trunk/include/asm-powerpc/iseries/hv_call_event.h b/trunk/include/asm-powerpc/iseries/hv_call_event.h index 4cec4762076d..46763a30590a 100644 --- a/trunk/include/asm-powerpc/iseries/hv_call_event.h +++ b/trunk/include/asm-powerpc/iseries/hv_call_event.h @@ -1,4 +1,5 @@ /* + * HvCallEvent.h * Copyright (C) 2001 Mike Corrigan IBM Corporation * * This program is free software; you can redistribute it and/or modify @@ -14,7 +15,8 @@ * 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. */ @@ -31,9 +33,32 @@ typedef u8 HvLpEvent_Type; 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; @@ -67,8 +92,11 @@ static inline void HvCallEvent_setInterLpQueueIndex(u8 queueIndex) static inline void HvCallEvent_setLpEventStack(u8 queueIndex, char *eventStackAddr, u32 eventStackSize) { - HvCall3(HvCallEventSetLpEventStack, queueIndex, - virt_to_abs(eventStackAddr), eventStackSize); + u64 abs_addr; + + abs_addr = virt_to_abs(eventStackAddr); + HvCall3(HvCallEventSetLpEventStack, queueIndex, abs_addr, + eventStackSize); } static inline void HvCallEvent_setLpEventQueueInterruptProc(u8 queueIndex, @@ -80,7 +108,14 @@ static inline void HvCallEvent_setLpEventQueueInterruptProc(u8 queueIndex, static inline HvLpEvent_Rc HvCallEvent_signalLpEvent(struct HvLpEvent *event) { - return HvCall1(HvCallEventSignalLpEvent, virt_to_abs(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); } static inline HvLpEvent_Rc HvCallEvent_signalLpEventFast(HvLpIndex targetLp, @@ -92,21 +127,17 @@ static inline HvLpEvent_Rc HvCallEvent_signalLpEventFast(HvLpIndex targetLp, { /* Pack the misc bits into a single Dword to pass to PLIC */ union { - struct { - u8 ack_and_target; - u8 type; - u16 subtype; - HvLpInstanceId src_inst; - HvLpInstanceId target_inst; - } parms; + struct HvCallEvent_PackedParms parms; u64 dword; } packed; - - 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; + 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; return HvCall7(HvCallEventSignalLpEventParms, packed.dword, correlationToken, eventData1, eventData2, @@ -115,12 +146,18 @@ static inline HvLpEvent_Rc HvCallEvent_signalLpEventFast(HvLpIndex targetLp, static inline HvLpEvent_Rc HvCallEvent_ackLpEvent(struct HvLpEvent *event) { - return HvCall1(HvCallEventAckLpEvent, virt_to_abs(event)); + u64 abs_addr; + + abs_addr = virt_to_abs(event); + return HvCall1(HvCallEventAckLpEvent, abs_addr); } static inline HvLpEvent_Rc HvCallEvent_cancelLpEvent(struct HvLpEvent *event) { - return HvCall1(HvCallEventCancelLpEvent, virt_to_abs(event)); + u64 abs_addr; + + abs_addr = virt_to_abs(event); + return HvCall1(HvCallEventCancelLpEvent, abs_addr); } static inline HvLpInstanceId HvCallEvent_getSourceLpInstanceId( @@ -158,34 +195,59 @@ static inline HvLpDma_Rc HvCallEvent_dmaBufList(HvLpEvent_Type type, { /* Pack the misc bits into a single Dword to pass to PLIC */ union { - struct { - u8 flags; - HvLpIndex remote; - u8 type; - u8 reserved; - HvLpInstanceId local_inst; - HvLpInstanceId remote_inst; - } parms; + struct HvCallEvent_PackedDmaParms parms; u64 dword; } packed; - 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; + 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 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) { - return HvCall4(HvCallEventDmaToSp, virt_to_abs(local), remote, - length, dir); + u64 abs_addr; + + abs_addr = virt_to_abs(local); + return HvCall4(HvCallEventDmaToSp, abs_addr, remote, length, dir); } #endif /* _ASM_POWERPC_ISERIES_HV_CALL_EVENT_H */ diff --git a/trunk/include/asm-powerpc/iseries/hv_call_sc.h b/trunk/include/asm-powerpc/iseries/hv_call_sc.h index f5d210959250..dec7e9d9ab78 100644 --- a/trunk/include/asm-powerpc/iseries/hv_call_sc.h +++ b/trunk/include/asm-powerpc/iseries/hv_call_sc.h @@ -1,4 +1,5 @@ /* + * HvCallSc.h * Copyright (C) 2001 Mike Corrigan IBM Corporation * * This program is free software; you can redistribute it and/or modify diff --git a/trunk/include/asm-powerpc/iseries/hv_lp_config.h b/trunk/include/asm-powerpc/iseries/hv_lp_config.h index df8b20739719..bc00f036bca0 100644 --- a/trunk/include/asm-powerpc/iseries/hv_lp_config.h +++ b/trunk/include/asm-powerpc/iseries/hv_lp_config.h @@ -1,4 +1,5 @@ /* + * HvLpConfig.h * Copyright (C) 2001 Mike Corrigan IBM Corporation * * This program is free software; you can redistribute it and/or modify diff --git a/trunk/include/asm-powerpc/iseries/hv_lp_event.h b/trunk/include/asm-powerpc/iseries/hv_lp_event.h index 4065a4de4935..499ab1ad0185 100644 --- a/trunk/include/asm-powerpc/iseries/hv_lp_event.h +++ b/trunk/include/asm-powerpc/iseries/hv_lp_event.h @@ -1,4 +1,5 @@ /* + * HvLpEvent.h * Copyright (C) 2001 Mike Corrigan IBM Corporation * * This program is free software; you can redistribute it and/or modify @@ -31,8 +32,17 @@ * 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 { - u8 flags; /* Event flags x00-x00 */ + struct HvEventFlags xFlags; /* Event flags x00-x00 */ u8 xType; /* Type of message x01-x01 */ u16 xSubtype; /* Subtype for event x02-x03 */ u8 xSourceLp; /* Source LP x04-x04 */ @@ -116,11 +126,6 @@ extern int HvLpEvent_closePath(HvLpEvent_Type eventType, HvLpIndex lpIndex); #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 @@ -134,29 +139,4 @@ extern int HvLpEvent_closePath(HvLpEvent_Type eventType, HvLpIndex lpIndex); #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/trunk/include/asm-powerpc/iseries/hv_types.h b/trunk/include/asm-powerpc/iseries/hv_types.h index c3e6d2a1d1c3..c38f7e3d01dc 100644 --- a/trunk/include/asm-powerpc/iseries/hv_types.h +++ b/trunk/include/asm-powerpc/iseries/hv_types.h @@ -1,4 +1,5 @@ /* + * HvTypes.h * Copyright (C) 2001 Mike Corrigan IBM Corporation * * This program is free software; you can redistribute it and/or modify diff --git a/trunk/include/asm-powerpc/iseries/iseries_io.h b/trunk/include/asm-powerpc/iseries/iseries_io.h index 496aa852b617..56b2113ff0f5 100644 --- a/trunk/include/asm-powerpc/iseries/iseries_io.h +++ b/trunk/include/asm-powerpc/iseries/iseries_io.h @@ -6,7 +6,7 @@ #ifdef CONFIG_PPC_ISERIES #include /* - * Created by Allan Trautman on Thu Dec 28 2000. + * File iSeries_io.h 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,7 +32,6 @@ * 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); @@ -45,17 +44,6 @@ extern void iSeries_memcpy_toio(volatile void __iomem *dest, void *source, 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/trunk/include/asm-powerpc/iseries/it_exp_vpd_panel.h b/trunk/include/asm-powerpc/iseries/it_exp_vpd_panel.h index 304a609ae21a..66a17a230c52 100644 --- a/trunk/include/asm-powerpc/iseries/it_exp_vpd_panel.h +++ b/trunk/include/asm-powerpc/iseries/it_exp_vpd_panel.h @@ -1,4 +1,5 @@ /* + * ItExtVpdPanel.h * Copyright (C) 2002 Dave Boutcher IBM Corporation * * This program is free software; you can redistribute it and/or modify diff --git a/trunk/include/asm-powerpc/iseries/it_lp_naca.h b/trunk/include/asm-powerpc/iseries/it_lp_naca.h index 4fdcf052927f..c3ef1de45d82 100644 --- a/trunk/include/asm-powerpc/iseries/it_lp_naca.h +++ b/trunk/include/asm-powerpc/iseries/it_lp_naca.h @@ -1,4 +1,5 @@ /* + * ItLpNaca.h * Copyright (C) 2001 Mike Corrigan IBM Corporation * * This program is free software; you can redistribute it and/or modify @@ -36,13 +37,17 @@ struct ItLpNaca { 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; // Piranha or hardware x10-x10 - u8 xPirConsoleMode; // Piranha console indicator x11-x11 - u8 xPirDasdMode; // Piranha dasd indicator x12-x12 + 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 xRsvd1_0[5]; // Reserved for Piranha related x13-x17 - u8 flags; // flags, see below x18-x1F - u8 xSpVpdFormat; // VPD areas are in CSP format ... - u8 xIntProcRatio; // Ratio of int procs to procs ... + 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 xRsvd1_2[5]; // Reserved ... u16 xRsvd1_3; // Reserved x20-x21 u16 xPlicVrmIndex; // VRM index of PLIC x22-x23 @@ -72,9 +77,4 @@ struct ItLpNaca { 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/trunk/include/asm-powerpc/iseries/it_lp_queue.h b/trunk/include/asm-powerpc/iseries/it_lp_queue.h index b7c6fc12cce2..a60d03afbf95 100644 --- a/trunk/include/asm-powerpc/iseries/it_lp_queue.h +++ b/trunk/include/asm-powerpc/iseries/it_lp_queue.h @@ -1,4 +1,5 @@ /* + * ItLpQueue.h * Copyright (C) 2001 Mike Corrigan IBM Corporation * * This program is free software; you can redistribute it and/or modify diff --git a/trunk/include/asm-powerpc/iseries/it_lp_reg_save.h b/trunk/include/asm-powerpc/iseries/it_lp_reg_save.h index 5403b756f654..81824e1bb767 100644 --- a/trunk/include/asm-powerpc/iseries/it_lp_reg_save.h +++ b/trunk/include/asm-powerpc/iseries/it_lp_reg_save.h @@ -1,4 +1,5 @@ /* + * ItLpRegSave.h * Copyright (C) 2001 Mike Corrigan IBM Corporation * * This program is free software; you can redistribute it and/or modify @@ -82,4 +83,4 @@ struct ItLpRegSave { extern struct ItLpRegSave iseries_reg_save[]; -#endif /* _ASM_POWERPC_ISERIES_IT_LP_REG_SAVE_H */ +#endif /* _ITLPREGSAVE_H */ diff --git a/trunk/include/asm-powerpc/iseries/lpar_map.h b/trunk/include/asm-powerpc/iseries/lpar_map.h index 2ec384d66abb..84fc321615bf 100644 --- a/trunk/include/asm-powerpc/iseries/lpar_map.h +++ b/trunk/include/asm-powerpc/iseries/lpar_map.h @@ -1,4 +1,5 @@ /* + * LparMap.h * Copyright (C) 2001 Mike Corrigan IBM Corporation * * This program is free software; you can redistribute it and/or modify diff --git a/trunk/include/asm-powerpc/iseries/mf.h b/trunk/include/asm-powerpc/iseries/mf.h index 857e5202fc78..e7bd57a03fb1 100644 --- a/trunk/include/asm-powerpc/iseries/mf.h +++ b/trunk/include/asm-powerpc/iseries/mf.h @@ -1,4 +1,5 @@ /* + * mf.h * Copyright (C) 2001 Troy D. Armstrong IBM Corporation * Copyright (C) 2004 Stephen Rothwell IBM Corporation * diff --git a/trunk/include/asm-powerpc/iseries/vio.h b/trunk/include/asm-powerpc/iseries/vio.h index 72a97d37aac3..7e3a469420dd 100644 --- a/trunk/include/asm-powerpc/iseries/vio.h +++ b/trunk/include/asm-powerpc/iseries/vio.h @@ -1,4 +1,5 @@ /* -*- linux-c -*- + * drivers/char/vio.h * * iSeries Virtual I/O Message Path header * diff --git a/trunk/include/asm-powerpc/pci-bridge.h b/trunk/include/asm-powerpc/pci-bridge.h index 38de92d41a14..b0d816fe2e27 100644 --- a/trunk/include/asm-powerpc/pci-bridge.h +++ b/trunk/include/asm-powerpc/pci-bridge.h @@ -142,6 +142,8 @@ void pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus); 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/trunk/include/asm-powerpc/system.h b/trunk/include/asm-powerpc/system.h index 9b822afa7d0e..0c58e32a9570 100644 --- a/trunk/include/asm-powerpc/system.h +++ b/trunk/include/asm-powerpc/system.h @@ -133,14 +133,6 @@ extern int fix_alignment(struct pt_regs *); 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 @@ -183,16 +175,6 @@ struct thread_struct; 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/trunk/include/asm-powerpc/thread_info.h b/trunk/include/asm-powerpc/thread_info.h index 7e09d7cda933..ac1e80e6033e 100644 --- a/trunk/include/asm-powerpc/thread_info.h +++ b/trunk/include/asm-powerpc/thread_info.h @@ -89,6 +89,9 @@ struct thread_info { #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/trunk/include/asm-powerpc/topology.h b/trunk/include/asm-powerpc/topology.h index 1e19cd00af25..9f3d4da261c4 100644 --- a/trunk/include/asm-powerpc/topology.h +++ b/trunk/include/asm-powerpc/topology.h @@ -39,6 +39,7 @@ static inline int node_to_first_cpu(int node) .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/trunk/include/asm-ppc/system.h b/trunk/include/asm-ppc/system.h index fb49c0c49ea1..bd99cb53a19f 100644 --- a/trunk/include/asm-ppc/system.h +++ b/trunk/include/asm-ppc/system.h @@ -4,6 +4,7 @@ #ifndef __PPC_SYSTEM_H #define __PPC_SYSTEM_H +#include #include #include @@ -38,7 +39,7 @@ #ifdef CONFIG_SMP #define smp_mb() mb() #define smp_rmb() rmb() -#define smp_wmb() __asm__ __volatile__ ("eieio" : : : "memory") +#define smp_wmb() wmb() #define smp_read_barrier_depends() read_barrier_depends() #else #define smp_mb() barrier() @@ -73,7 +74,6 @@ extern void chrp_nvram_init(void); 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,14 +86,6 @@ extern int fix_alignment(struct pt_regs *); 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 @@ -131,16 +123,6 @@ extern struct task_struct *__switch_to(struct task_struct *, 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/trunk/include/asm-s390/elf.h b/trunk/include/asm-s390/elf.h index 710646e64f7d..372d51cccd53 100644 --- a/trunk/include/asm-s390/elf.h +++ b/trunk/include/asm-s390/elf.h @@ -163,7 +163,7 @@ static inline int dump_regs(struct pt_regs *ptregs, elf_gregset_t *regs) static inline int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) { - struct pt_regs *ptregs = task_pt_regs(tsk); + struct pt_regs *ptregs = __KSTK_PTREGS(tsk); memcpy(®s->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/trunk/include/asm-s390/processor.h b/trunk/include/asm-s390/processor.h index c5cbc4bd8414..4ec652ebb3b1 100644 --- a/trunk/include/asm-s390/processor.h +++ b/trunk/include/asm-s390/processor.h @@ -191,10 +191,10 @@ extern void show_registers(struct pt_regs *regs); extern void show_trace(struct task_struct *task, unsigned long *sp); unsigned long get_wchan(struct task_struct *p); -#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]) +#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]) /* * Give up the time slice of the virtual PU. diff --git a/trunk/include/asm-s390/system.h b/trunk/include/asm-s390/system.h index c7c3a9ad593f..864cae7e1fd6 100644 --- a/trunk/include/asm-s390/system.h +++ b/trunk/include/asm-s390/system.h @@ -104,16 +104,6 @@ static inline void restore_access_regs(unsigned int *acrs) 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/trunk/include/asm-s390/thread_info.h b/trunk/include/asm-s390/thread_info.h index f3797a52c4ea..6c18a3f24316 100644 --- a/trunk/include/asm-s390/thread_info.h +++ b/trunk/include/asm-s390/thread_info.h @@ -81,6 +81,8 @@ static inline struct thread_info *current_thread_info(void) #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/trunk/include/asm-sh/ptrace.h b/trunk/include/asm-sh/ptrace.h index 792fc35bd624..0f75e16a7415 100644 --- a/trunk/include/asm-sh/ptrace.h +++ b/trunk/include/asm-sh/ptrace.h @@ -91,16 +91,6 @@ struct pt_dspregs { #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/trunk/include/asm-sh/system.h b/trunk/include/asm-sh/system.h index bb0330499bdf..28a3c2d8bcd7 100644 --- a/trunk/include/asm-sh/system.h +++ b/trunk/include/asm-sh/system.h @@ -57,16 +57,6 @@ 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/trunk/include/asm-sh/thread_info.h b/trunk/include/asm-sh/thread_info.h index 85f0c11b4319..46080cefaff8 100644 --- a/trunk/include/asm-sh/thread_info.h +++ b/trunk/include/asm-sh/thread_info.h @@ -60,6 +60,8 @@ static inline struct thread_info *current_thread_info(void) #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/trunk/include/asm-sh64/thread_info.h b/trunk/include/asm-sh64/thread_info.h index 1f825cb163c3..10f024c6a2e3 100644 --- a/trunk/include/asm-sh64/thread_info.h +++ b/trunk/include/asm-sh64/thread_info.h @@ -66,6 +66,8 @@ static inline struct thread_info *current_thread_info(void) #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/trunk/include/asm-sparc/system.h b/trunk/include/asm-sparc/system.h index 58dd162927bb..1f6b71f9e1b6 100644 --- a/trunk/include/asm-sparc/system.h +++ b/trunk/include/asm-sparc/system.h @@ -155,7 +155,7 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr, "here:\n" \ : "=&r" (last) \ : "r" (&(current_set[hard_smp_processor_id()])), \ - "r" (task_thread_info(next)), \ + "r" ((next)->thread_info), \ "i" (TI_KPSR), \ "i" (TI_KSP), \ "i" (TI_TASK) \ @@ -165,16 +165,6 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr, "o0", "o1", "o2", "o3", "o7"); \ } 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. */ diff --git a/trunk/include/asm-sparc/thread_info.h b/trunk/include/asm-sparc/thread_info.h index 65f060b040ab..ff6ccb3d24c6 100644 --- a/trunk/include/asm-sparc/thread_info.h +++ b/trunk/include/asm-sparc/thread_info.h @@ -92,6 +92,9 @@ BTFIXUPDEF_CALL(struct thread_info *, alloc_thread_info, void) 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/trunk/include/asm-sparc64/elf.h b/trunk/include/asm-sparc64/elf.h index 69539a8ab833..91458118277e 100644 --- a/trunk/include/asm-sparc64/elf.h +++ b/trunk/include/asm-sparc64/elf.h @@ -119,7 +119,7 @@ typedef struct { #endif #define ELF_CORE_COPY_TASK_REGS(__tsk, __elf_regs) \ - ({ ELF_CORE_COPY_REGS((*(__elf_regs)), task_pt_regs(__tsk)); 1; }) + ({ ELF_CORE_COPY_REGS((*(__elf_regs)), (__tsk)->thread_info->kregs); 1; }) /* * This is used to ensure we don't load something for the wrong architecture. diff --git a/trunk/include/asm-sparc64/mmu_context.h b/trunk/include/asm-sparc64/mmu_context.h index 57ee7b306189..08ba72d7722c 100644 --- a/trunk/include/asm-sparc64/mmu_context.h +++ b/trunk/include/asm-sparc64/mmu_context.h @@ -60,7 +60,7 @@ do { \ register unsigned long pgd_cache asm("o4"); \ paddr = __pa((__mm)->pgd); \ pgd_cache = 0UL; \ - if (task_thread_info(__tsk)->flags & _TIF_32BIT) \ + if ((__tsk)->thread_info->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/trunk/include/asm-sparc64/processor.h b/trunk/include/asm-sparc64/processor.h index cd8d9b4c8658..3169f3e2237e 100644 --- a/trunk/include/asm-sparc64/processor.h +++ b/trunk/include/asm-sparc64/processor.h @@ -186,9 +186,8 @@ extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); extern unsigned long get_wchan(struct task_struct *task); -#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 KSTK_EIP(tsk) ((tsk)->thread_info->kregs->tpc) +#define KSTK_ESP(tsk) ((tsk)->thread_info->kregs->u_regs[UREG_FP]) #define cpu_relax() barrier() diff --git a/trunk/include/asm-sparc64/system.h b/trunk/include/asm-sparc64/system.h index af254e581834..309f1466b6fa 100644 --- a/trunk/include/asm-sparc64/system.h +++ b/trunk/include/asm-sparc64/system.h @@ -208,7 +208,7 @@ do { if (test_thread_flag(TIF_PERFCTR)) { \ /* 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(task_thread_info(next))[TI_FLAG_BYTE_CURRENT_DS]));\ + : : "r" (__thread_flag_byte_ptr(next->thread_info)[TI_FLAG_BYTE_CURRENT_DS]));\ __asm__ __volatile__( \ "mov %%g4, %%g7\n\t" \ "wrpr %%g0, 0x95, %%pstate\n\t" \ @@ -238,7 +238,7 @@ do { if (test_thread_flag(TIF_PERFCTR)) { \ "b,a ret_from_syscall\n\t" \ "1:\n\t" \ : "=&r" (last) \ - : "0" (task_thread_info(next)), \ + : "0" (next->thread_info), \ "i" (TI_WSTATE), "i" (TI_KSP), "i" (TI_NEW_CHILD), \ "i" (TI_CWP), "i" (TI_TASK) \ : "cc", \ @@ -253,16 +253,6 @@ do { if (test_thread_flag(TIF_PERFCTR)) { \ } \ } 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/trunk/include/asm-um/thread_info.h b/trunk/include/asm-um/thread_info.h index 705c71972c32..97267f059ef5 100644 --- a/trunk/include/asm-um/thread_info.h +++ b/trunk/include/asm-um/thread_info.h @@ -56,6 +56,9 @@ static inline struct thread_info *current_thread_info(void) ((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/trunk/include/asm-v850/processor.h b/trunk/include/asm-v850/processor.h index 2d31308935a0..98f929427d3d 100644 --- a/trunk/include/asm-v850/processor.h +++ b/trunk/include/asm-v850/processor.h @@ -98,10 +98,10 @@ unsigned long get_wchan (struct task_struct *p); /* Return some info about the user process TASK. */ -#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) +#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) /* Grotty old names for some. */ #define KSTK_EIP(task) task_pc (task) #define KSTK_ESP(task) task_sp (task) diff --git a/trunk/include/asm-v850/thread_info.h b/trunk/include/asm-v850/thread_info.h index 82b8f2846207..e4cfad94a553 100644 --- a/trunk/include/asm-v850/thread_info.h +++ b/trunk/include/asm-v850/thread_info.h @@ -58,6 +58,8 @@ struct thread_info { #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/trunk/include/asm-x86_64/compat.h b/trunk/include/asm-x86_64/compat.h index b37ab8218ef0..3863a7da372b 100644 --- a/trunk/include/asm-x86_64/compat.h +++ b/trunk/include/asm-x86_64/compat.h @@ -198,7 +198,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) static __inline__ void __user *compat_alloc_user_space(long len) { - struct pt_regs *regs = task_pt_regs(current); + struct pt_regs *regs = (void *)current->thread.rsp0 - sizeof(struct pt_regs); return (void __user *)regs->rsp - len; } diff --git a/trunk/include/asm-x86_64/i387.h b/trunk/include/asm-x86_64/i387.h index 876eb9a2fe78..57f7e1433849 100644 --- a/trunk/include/asm-x86_64/i387.h +++ b/trunk/include/asm-x86_64/i387.h @@ -30,7 +30,7 @@ extern int save_i387(struct _fpstate __user *buf); */ #define unlazy_fpu(tsk) do { \ - if (task_thread_info(tsk)->status & TS_USEDFPU) \ + if ((tsk)->thread_info->status & TS_USEDFPU) \ save_init_fpu(tsk); \ } while (0) @@ -46,9 +46,9 @@ static inline void tolerant_fwait(void) } #define clear_fpu(tsk) do { \ - if (task_thread_info(tsk)->status & TS_USEDFPU) { \ + if ((tsk)->thread_info->status & TS_USEDFPU) { \ tolerant_fwait(); \ - task_thread_info(tsk)->status &= ~TS_USEDFPU; \ + (tsk)->thread_info->status &= ~TS_USEDFPU; \ stts(); \ } \ } while (0) @@ -170,10 +170,10 @@ static inline void kernel_fpu_end(void) 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); - task_thread_info(tsk)->status &= ~TS_USEDFPU; + tsk->thread_info->status &= ~TS_USEDFPU; stts(); } diff --git a/trunk/include/asm-x86_64/processor.h b/trunk/include/asm-x86_64/processor.h index 87a282b1043a..394dd729752d 100644 --- a/trunk/include/asm-x86_64/processor.h +++ b/trunk/include/asm-x86_64/processor.h @@ -321,8 +321,8 @@ extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); #define thread_saved_pc(t) (*(unsigned long *)((t)->thread.rsp - 8)) extern unsigned long get_wchan(struct task_struct *p); -#define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.rsp0 - 1) -#define KSTK_EIP(tsk) (task_pt_regs(tsk)->rip) +#define KSTK_EIP(tsk) \ + (((struct pt_regs *)(tsk->thread.rsp0 - sizeof(struct pt_regs)))->rip) #define KSTK_ESP(tsk) -1 /* sorry. doesn't work for syscall. */ diff --git a/trunk/include/asm-x86_64/system.h b/trunk/include/asm-x86_64/system.h index 0eacbefb7dd0..38c1e8a69c9c 100644 --- a/trunk/include/asm-x86_64/system.h +++ b/trunk/include/asm-x86_64/system.h @@ -193,15 +193,6 @@ static inline void write_cr4(unsigned long val) #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/trunk/include/asm-x86_64/thread_info.h b/trunk/include/asm-x86_64/thread_info.h index 4ac0e0a36934..eb7c5fda1870 100644 --- a/trunk/include/asm-x86_64/thread_info.h +++ b/trunk/include/asm-x86_64/thread_info.h @@ -76,6 +76,8 @@ static inline struct thread_info *stack_thread_info(void) #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/trunk/include/asm-x86_64/topology.h b/trunk/include/asm-x86_64/topology.h index 2fa7f27381b4..7d82bc56b9fa 100644 --- a/trunk/include/asm-x86_64/topology.h +++ b/trunk/include/asm-x86_64/topology.h @@ -39,6 +39,7 @@ extern int __node_distance(int, int); .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/trunk/include/asm-xtensa/processor.h b/trunk/include/asm-xtensa/processor.h index d1d72ad36f08..9cab5e4298b9 100644 --- a/trunk/include/asm-xtensa/processor.h +++ b/trunk/include/asm-xtensa/processor.h @@ -184,12 +184,12 @@ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); #define release_segments(mm) do { } while(0) #define forget_segments() do { } while (0) -#define thread_saved_pc(tsk) (task_pt_regs(tsk)->pc) +#define thread_saved_pc(tsk) (xtensa_pt_regs(tsk)->pc) extern unsigned long get_wchan(struct task_struct *p); -#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc) -#define KSTK_ESP(tsk) (task_pt_regs(tsk)->areg[1]) +#define KSTK_EIP(tsk) (xtensa_pt_regs(tsk)->pc) +#define KSTK_ESP(tsk) (xtensa_pt_regs(tsk)->areg[1]) #define cpu_relax() do { } while (0) diff --git a/trunk/include/asm-xtensa/ptrace.h b/trunk/include/asm-xtensa/ptrace.h index a5ac71a5205c..aa4fd7fb3ce7 100644 --- a/trunk/include/asm-xtensa/ptrace.h +++ b/trunk/include/asm-xtensa/ptrace.h @@ -113,8 +113,8 @@ struct pt_regs { }; #ifdef __KERNEL__ -# define task_pt_regs(tsk) ((struct pt_regs*) \ - (task_stack_page(tsk) + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4) - 1) +# define xtensa_pt_regs(tsk) ((struct pt_regs*) \ + (((long)(tsk)->thread_info + 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/trunk/include/asm-xtensa/thread_info.h b/trunk/include/asm-xtensa/thread_info.h index 5ae34ab71597..af208d41fd82 100644 --- a/trunk/include/asm-xtensa/thread_info.h +++ b/trunk/include/asm-xtensa/thread_info.h @@ -93,6 +93,8 @@ static inline struct thread_info *current_thread_info(void) /* 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/trunk/include/linux/hrtimer.h b/trunk/include/linux/hrtimer.h index 089bfb1fa01a..cf5cfdf8d613 100644 --- a/trunk/include/linux/hrtimer.h +++ b/trunk/include/linux/hrtimer.h @@ -49,6 +49,8 @@ struct hrtimer_base; * struct hrtimer - the basic hrtimer structure * * @node: red black tree node for time ordered insertion + * @list: list head for easier access to the time ordered list, + * without walking the red black tree. * @expires: the absolute expiry time in the hrtimers internal * representation. The time is related to the clock on * which the timer is based. @@ -61,6 +63,7 @@ struct hrtimer_base; */ struct hrtimer { struct rb_node node; + struct list_head list; ktime_t expires; enum hrtimer_state state; int (*function)(void *); @@ -75,7 +78,7 @@ struct hrtimer { * to a base on another cpu. * @lock: lock protecting the base and associated timers * @active: red black tree root node for the active timers - * @first: pointer to the timer node which expires first + * @pending: list of pending timers for simple time ordered access * @resolution: the resolution of the clock, in nanoseconds * @get_time: function to retrieve the current time of the clock * @curr_timer: the timer which is executing a callback right now @@ -84,8 +87,8 @@ struct hrtimer_base { clockid_t index; spinlock_t lock; struct rb_root active; - struct rb_node *first; - ktime_t resolution; + struct list_head pending; + unsigned long resolution; ktime_t (*get_time)(void); struct hrtimer *curr_timer; }; @@ -122,7 +125,8 @@ static inline int hrtimer_active(const struct hrtimer *timer) } /* Forward a hrtimer so it expires after now: */ -extern unsigned long hrtimer_forward(struct hrtimer *timer, ktime_t interval); +extern unsigned long hrtimer_forward(struct hrtimer *timer, + const ktime_t interval); /* Precise sleep: */ extern long hrtimer_nanosleep(struct timespec *rqtp, diff --git a/trunk/include/linux/ide.h b/trunk/include/linux/ide.h index f2e1b5b22898..9a8c05dbe4f3 100644 --- a/trunk/include/linux/ide.h +++ b/trunk/include/linux/ide.h @@ -1002,6 +1002,7 @@ extern int noautodma; extern int ide_end_request (ide_drive_t *drive, int uptodate, int nrsecs); extern int __ide_end_request (ide_drive_t *drive, struct request *rq, int uptodate, int nrsecs); +extern void ide_softirq_done(struct request *rq); /* * This is used on exit from the driver to designate the next irq handler diff --git a/trunk/include/linux/ktime.h b/trunk/include/linux/ktime.h index 1bd6552cc341..222a047cc145 100644 --- a/trunk/include/linux/ktime.h +++ b/trunk/include/linux/ktime.h @@ -272,8 +272,8 @@ static inline u64 ktime_to_ns(const ktime_t kt) * idea of the (in)accuracy of timers. Timer values are rounded up to * this resolution values. */ -#define KTIME_REALTIME_RES (ktime_t){ .tv64 = TICK_NSEC } -#define KTIME_MONOTONIC_RES (ktime_t){ .tv64 = TICK_NSEC } +#define KTIME_REALTIME_RES (NSEC_PER_SEC/HZ) +#define KTIME_MONOTONIC_RES (NSEC_PER_SEC/HZ) /* Get the monotonic time in timespec format: */ extern void ktime_get_ts(struct timespec *ts); diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index a72e17135421..3b74c4bf2934 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -631,14 +631,7 @@ struct sched_domain { extern void partition_sched_domains(cpumask_t *partition1, cpumask_t *partition2); - -/* - * Maximum cache size the migration-costs auto-tuning code will - * search from: - */ -extern unsigned int max_cache_size; - -#endif /* CONFIG_SMP */ +#endif /* CONFIG_SMP */ struct io_context; /* See blkdev.h */ @@ -696,11 +689,8 @@ struct task_struct { int lock_depth; /* BKL lock depth */ -#if defined(CONFIG_SMP) - int last_waker_cpu; /* CPU that last woke this task up */ -#if defined(__ARCH_WANT_UNLOCKED_CTXSW) +#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW) int oncpu; -#endif #endif int prio, static_prio; struct list_head run_list; @@ -1240,7 +1230,6 @@ static inline void task_unlock(struct task_struct *p) #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/trunk/include/linux/topology.h b/trunk/include/linux/topology.h index 315a5163d6a0..3df1d474e5c5 100644 --- a/trunk/include/linux/topology.h +++ b/trunk/include/linux/topology.h @@ -86,6 +86,7 @@ .max_interval = 2, \ .busy_factor = 8, \ .imbalance_pct = 110, \ + .cache_hot_time = 0, \ .cache_nice_tries = 0, \ .per_cpu_gain = 25, \ .busy_idx = 0, \ @@ -116,6 +117,7 @@ .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/trunk/kernel/hrtimer.c b/trunk/kernel/hrtimer.c index 04ccab099e84..f073a2461faa 100644 --- a/trunk/kernel/hrtimer.c +++ b/trunk/kernel/hrtimer.c @@ -275,7 +275,7 @@ void unlock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags) * The number of overruns is added to the overrun field. */ unsigned long -hrtimer_forward(struct hrtimer *timer, ktime_t interval) +hrtimer_forward(struct hrtimer *timer, const ktime_t interval) { unsigned long orun = 1; ktime_t delta, now; @@ -287,9 +287,6 @@ hrtimer_forward(struct hrtimer *timer, ktime_t interval) if (delta.tv64 < 0) return 0; - if (interval.tv64 < timer->base->resolution.tv64) - interval.tv64 = timer->base->resolution.tv64; - if (unlikely(delta.tv64 >= interval.tv64)) { nsec_t incr = ktime_to_ns(interval); @@ -317,6 +314,7 @@ hrtimer_forward(struct hrtimer *timer, ktime_t interval) static void enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_base *base) { struct rb_node **link = &base->active.rb_node; + struct list_head *prev = &base->pending; struct rb_node *parent = NULL; struct hrtimer *entry; @@ -332,24 +330,23 @@ static void enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_base *base) */ if (timer->expires.tv64 < entry->expires.tv64) link = &(*link)->rb_left; - else + else { link = &(*link)->rb_right; + prev = &entry->list; + } } /* - * Insert the timer to the rbtree and check whether it - * replaces the first pending timer + * Insert the timer to the rbtree and to the sorted list: */ rb_link_node(&timer->node, parent, link); rb_insert_color(&timer->node, &base->active); + list_add(&timer->list, prev); timer->state = HRTIMER_PENDING; - - if (!base->first || timer->expires.tv64 < - rb_entry(base->first, struct hrtimer, node)->expires.tv64) - base->first = &timer->node; } + /* * __remove_hrtimer - internal function to remove a timer * @@ -358,11 +355,9 @@ static void enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_base *base) static void __remove_hrtimer(struct hrtimer *timer, struct hrtimer_base *base) { /* - * Remove the timer from the rbtree and replace the - * first entry pointer if necessary. + * Remove the timer from the sorted list and from the rbtree: */ - if (base->first == &timer->node) - base->first = rb_next(&timer->node); + list_del(&timer->list); rb_erase(&timer->node, &base->active); } @@ -521,8 +516,9 @@ int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp) { struct hrtimer_base *bases; + tp->tv_sec = 0; bases = per_cpu(hrtimer_bases, raw_smp_processor_id()); - *tp = ktime_to_timespec(bases[which_clock].resolution); + tp->tv_nsec = bases[which_clock].resolution; return 0; } @@ -533,17 +529,16 @@ int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp) static inline void run_hrtimer_queue(struct hrtimer_base *base) { ktime_t now = base->get_time(); - struct rb_node *node; spin_lock_irq(&base->lock); - while ((node = base->first)) { + while (!list_empty(&base->pending)) { struct hrtimer *timer; int (*fn)(void *); int restart; void *data; - timer = rb_entry(node, struct hrtimer, node); + timer = list_entry(base->pending.next, struct hrtimer, list); if (now.tv64 <= timer->expires.tv64) break; @@ -737,6 +732,7 @@ static void __devinit init_hrtimers_cpu(int cpu) for (i = 0; i < MAX_HRTIMER_BASES; i++) { spin_lock_init(&base->lock); + INIT_LIST_HEAD(&base->pending); base++; } } diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c index c9dec2aa1976..c0c60c926d5e 100644 --- a/trunk/kernel/sched.c +++ b/trunk/kernel/sched.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -1290,9 +1289,6 @@ static int try_to_wake_up(task_t *p, unsigned int state, int sync) } } - if (p->last_waker_cpu != this_cpu) - goto out_set_cpu; - if (unlikely(!cpu_isset(this_cpu, p->cpus_allowed))) goto out_set_cpu; @@ -1363,8 +1359,6 @@ static int try_to_wake_up(task_t *p, unsigned int state, int sync) cpu = task_cpu(p); } - p->last_waker_cpu = this_cpu; - out_activate: #endif /* CONFIG_SMP */ if (old_state == TASK_UNINTERRUPTIBLE) { @@ -1446,12 +1440,9 @@ void fastcall sched_fork(task_t *p, int clone_flags) #ifdef CONFIG_SCHEDSTATS memset(&p->sched_info, 0, sizeof(p->sched_info)); #endif -#if defined(CONFIG_SMP) - p->last_waker_cpu = cpu; -#if defined(__ARCH_WANT_UNLOCKED_CTXSW) +#if defined(CONFIG_SMP) && 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; @@ -5091,470 +5082,7 @@ static void init_sched_build_groups(struct sched_group groups[], cpumask_t span, #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 @@ -5920,10 +5448,6 @@ void build_sched_domains(const cpumask_t *cpu_map) #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/trunk/mm/mempolicy.c b/trunk/mm/mempolicy.c index b62cab575a84..1850d0aef4ac 100644 --- a/trunk/mm/mempolicy.c +++ b/trunk/mm/mempolicy.c @@ -208,8 +208,6 @@ static int check_pte_range(struct vm_area_struct *vma, pmd_t *pmd, 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; @@ -292,7 +290,7 @@ static inline int check_pgd_range(struct vm_area_struct *vma, static inline int vma_migratable(struct vm_area_struct *vma) { if (vma->vm_flags & ( - VM_LOCKED|VM_IO|VM_HUGETLB|VM_PFNMAP|VM_RESERVED)) + VM_LOCKED|VM_IO|VM_HUGETLB|VM_PFNMAP)) return 0; return 1; } diff --git a/trunk/mm/page_alloc.c b/trunk/mm/page_alloc.c index 8c960b469593..d41a0662d4da 100644 --- a/trunk/mm/page_alloc.c +++ b/trunk/mm/page_alloc.c @@ -1742,7 +1742,7 @@ void __devinit memmap_init_zone(unsigned long size, int nid, unsigned long zone, unsigned long end_pfn = start_pfn + size; unsigned long pfn; - for (pfn = start_pfn; pfn < end_pfn; pfn++) { + for (pfn = start_pfn; pfn < end_pfn; pfn++, page++) { if (!early_pfn_valid(pfn)) continue; page = pfn_to_page(pfn); diff --git a/trunk/mm/swap.c b/trunk/mm/swap.c index cbb48e721ab9..ee6d71ccfa56 100644 --- a/trunk/mm/swap.c +++ b/trunk/mm/swap.c @@ -384,8 +384,6 @@ unsigned pagevec_lookup(struct pagevec *pvec, struct address_space *mapping, 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/trunk/mm/tiny-shmem.c b/trunk/mm/tiny-shmem.c index f9d6a9cc91c4..cdc6d431972b 100644 --- a/trunk/mm/tiny-shmem.c +++ b/trunk/mm/tiny-shmem.c @@ -90,7 +90,7 @@ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags) file->f_mode = FMODE_WRITE | FMODE_READ; /* notify everyone as to the change of file size */ - error = do_truncate(dentry, size, 0, file); + error = do_truncate(dentry, size, file); if (error < 0) goto close_file; diff --git a/trunk/sound/oss/dmasound/dmasound.h b/trunk/sound/oss/dmasound/dmasound.h index a1b0b92af4b5..222014cafc1a 100644 --- a/trunk/sound/oss/dmasound/dmasound.h +++ b/trunk/sound/oss/dmasound/dmasound.h @@ -270,6 +270,7 @@ extern int dmasound_catchRadius; #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/trunk/sound/oss/dmasound/dmasound_atari.c b/trunk/sound/oss/dmasound/dmasound_atari.c index dc31373069a5..59eb53f89318 100644 --- a/trunk/sound/oss/dmasound/dmasound_atari.c +++ b/trunk/sound/oss/dmasound/dmasound_atari.c @@ -67,46 +67,46 @@ static int expand_data; /* Data for expanding */ * ++geert: split in even more functions (one per format) */ -static ssize_t ata_ct_law(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ct_law(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft); -static ssize_t ata_ct_s8(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ct_s8(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft); -static ssize_t ata_ct_u8(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ct_u8(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft); -static ssize_t ata_ct_s16be(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ct_s16be(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft); -static ssize_t ata_ct_u16be(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ct_u16be(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft); -static ssize_t ata_ct_s16le(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ct_s16le(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft); -static ssize_t ata_ct_u16le(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ct_u16le(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft); -static ssize_t ata_ctx_law(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ctx_law(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft); -static ssize_t ata_ctx_s8(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ctx_s8(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft); -static ssize_t ata_ctx_u8(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ctx_u8(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft); -static ssize_t ata_ctx_s16be(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ctx_s16be(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft); -static ssize_t ata_ctx_u16be(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ctx_u16be(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft); -static ssize_t ata_ctx_s16le(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ctx_s16le(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft); -static ssize_t ata_ctx_u16le(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ctx_u16le(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft); @@ -151,7 +151,7 @@ static int FalconStateInfo(char *buffer, size_t space); /*** Translations ************************************************************/ -static ssize_t ata_ct_law(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ct_law(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { @@ -176,7 +176,7 @@ static ssize_t ata_ct_law(const u_char __user *userPtr, size_t userCount, } -static ssize_t ata_ct_s8(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ct_s8(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { @@ -194,7 +194,7 @@ static ssize_t ata_ct_s8(const u_char __user *userPtr, size_t userCount, } -static ssize_t ata_ct_u8(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ct_u8(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { @@ -217,9 +217,8 @@ static ssize_t ata_ct_u8(const u_char __user *userPtr, size_t userCount, used = count*2; while (count > 0) { u_short data; - if (get_user(data, (u_short __user *)userPtr)) + if (get_user(data, ((u_short *)userPtr)++)) return -EFAULT; - userPtr += 2; *p++ = data ^ 0x8080; count--; } @@ -229,7 +228,7 @@ static ssize_t ata_ct_u8(const u_char __user *userPtr, size_t userCount, } -static ssize_t ata_ct_s16be(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ct_s16be(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { @@ -241,9 +240,8 @@ static ssize_t ata_ct_s16be(const u_char __user *userPtr, size_t userCount, used = count*2; while (count > 0) { u_short data; - if (get_user(data, (u_short __user *)userPtr)) + if (get_user(data, ((u_short *)userPtr)++)) return -EFAULT; - userPtr += 2; *p++ = data; *p++ = data; count--; @@ -261,7 +259,7 @@ static ssize_t ata_ct_s16be(const u_char __user *userPtr, size_t userCount, } -static ssize_t ata_ct_u16be(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ct_u16be(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { @@ -273,9 +271,8 @@ static ssize_t ata_ct_u16be(const u_char __user *userPtr, size_t userCount, used = count*2; while (count > 0) { u_short data; - if (get_user(data, (u_short __user *)userPtr)) + if (get_user(data, ((u_short *)userPtr)++)) return -EFAULT; - userPtr += 2; data ^= 0x8000; *p++ = data; *p++ = data; @@ -287,10 +284,9 @@ static ssize_t ata_ct_u16be(const u_char __user *userPtr, size_t userCount, count = min_t(unsigned long, userCount, frameLeft)>>2; used = count*4; while (count > 0) { - u_int data; - if (get_user(data, (u_int __user *)userPtr)) + u_long data; + if (get_user(data, ((u_int *)userPtr)++)) return -EFAULT; - userPtr += 4; *p++ = data ^ 0x80008000; count--; } @@ -300,7 +296,7 @@ static ssize_t ata_ct_u16be(const u_char __user *userPtr, size_t userCount, } -static ssize_t ata_ct_s16le(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ct_s16le(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { @@ -313,9 +309,8 @@ static ssize_t ata_ct_s16le(const u_char __user *userPtr, size_t userCount, used = count*2; while (count > 0) { u_short data; - if (get_user(data, (u_short __user *)userPtr)) + if (get_user(data, ((u_short *)userPtr)++)) return -EFAULT; - userPtr += 2; data = le2be16(data); *p++ = data; *p++ = data; @@ -328,9 +323,8 @@ static ssize_t ata_ct_s16le(const u_char __user *userPtr, size_t userCount, used = count*4; while (count > 0) { u_long data; - if (get_user(data, (u_int __user *)userPtr)) + if (get_user(data, ((u_int *)userPtr)++)) return -EFAULT; - userPtr += 4; data = le2be16dbl(data); *p++ = data; count--; @@ -341,7 +335,7 @@ static ssize_t ata_ct_s16le(const u_char __user *userPtr, size_t userCount, } -static ssize_t ata_ct_u16le(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ct_u16le(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { @@ -354,9 +348,8 @@ static ssize_t ata_ct_u16le(const u_char __user *userPtr, size_t userCount, used = count*2; while (count > 0) { u_short data; - if (get_user(data, (u_short __user *)userPtr)) + if (get_user(data, ((u_short *)userPtr)++)) return -EFAULT; - userPtr += 2; data = le2be16(data) ^ 0x8000; *p++ = data; *p++ = data; @@ -368,9 +361,8 @@ static ssize_t ata_ct_u16le(const u_char __user *userPtr, size_t userCount, used = count; while (count > 0) { u_long data; - if (get_user(data, (u_int __user *)userPtr)) + if (get_user(data, ((u_int *)userPtr)++)) return -EFAULT; - userPtr += 4; data = le2be16dbl(data) ^ 0x80008000; *p++ = data; count--; @@ -381,7 +373,7 @@ static ssize_t ata_ct_u16le(const u_char __user *userPtr, size_t userCount, } -static ssize_t ata_ctx_law(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ctx_law(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { @@ -443,7 +435,7 @@ static ssize_t ata_ctx_law(const u_char __user *userPtr, size_t userCount, } -static ssize_t ata_ctx_s8(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ctx_s8(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { @@ -478,9 +470,8 @@ static ssize_t ata_ctx_s8(const u_char __user *userPtr, size_t userCount, if (bal < 0) { if (userCount < 2) break; - if (get_user(data, (u_short __user *)userPtr)) + if (get_user(data, ((u_short *)userPtr)++)) return -EFAULT; - userPtr += 2; userCount -= 2; bal += hSpeed; } @@ -497,7 +488,7 @@ static ssize_t ata_ctx_s8(const u_char __user *userPtr, size_t userCount, } -static ssize_t ata_ctx_u8(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ctx_u8(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { @@ -533,9 +524,8 @@ static ssize_t ata_ctx_u8(const u_char __user *userPtr, size_t userCount, if (bal < 0) { if (userCount < 2) break; - if (get_user(data, (u_short __user *)userPtr)) + if (get_user(data, ((u_short *)userPtr)++)) return -EFAULT; - userPtr += 2; data ^= 0x8080; userCount -= 2; bal += hSpeed; @@ -553,7 +543,7 @@ static ssize_t ata_ctx_u8(const u_char __user *userPtr, size_t userCount, } -static ssize_t ata_ctx_s16be(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ctx_s16be(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { @@ -571,9 +561,8 @@ static ssize_t ata_ctx_s16be(const u_char __user *userPtr, size_t userCount, if (bal < 0) { if (userCount < 2) break; - if (get_user(data, (u_short __user *)userPtr)) + if (get_user(data, ((u_short *)userPtr)++)) return -EFAULT; - userPtr += 2; userCount -= 2; bal += hSpeed; } @@ -590,9 +579,8 @@ static ssize_t ata_ctx_s16be(const u_char __user *userPtr, size_t userCount, if (bal < 0) { if (userCount < 4) break; - if (get_user(data, (u_int __user *)userPtr)) + if (get_user(data, ((u_int *)userPtr)++)) return -EFAULT; - userPtr += 4; userCount -= 4; bal += hSpeed; } @@ -609,7 +597,7 @@ static ssize_t ata_ctx_s16be(const u_char __user *userPtr, size_t userCount, } -static ssize_t ata_ctx_u16be(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ctx_u16be(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { @@ -627,9 +615,8 @@ static ssize_t ata_ctx_u16be(const u_char __user *userPtr, size_t userCount, if (bal < 0) { if (userCount < 2) break; - if (get_user(data, (u_short __user *)userPtr)) + if (get_user(data, ((u_short *)userPtr)++)) return -EFAULT; - userPtr += 2; data ^= 0x8000; userCount -= 2; bal += hSpeed; @@ -647,9 +634,8 @@ static ssize_t ata_ctx_u16be(const u_char __user *userPtr, size_t userCount, if (bal < 0) { if (userCount < 4) break; - if (get_user(data, (u_int __user *)userPtr)) + if (get_user(data, ((u_int *)userPtr)++)) return -EFAULT; - userPtr += 4; data ^= 0x80008000; userCount -= 4; bal += hSpeed; @@ -667,7 +653,7 @@ static ssize_t ata_ctx_u16be(const u_char __user *userPtr, size_t userCount, } -static ssize_t ata_ctx_s16le(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ctx_s16le(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { @@ -685,9 +671,8 @@ static ssize_t ata_ctx_s16le(const u_char __user *userPtr, size_t userCount, if (bal < 0) { if (userCount < 2) break; - if (get_user(data, (u_short __user *)userPtr)) + if (get_user(data, ((u_short *)userPtr)++)) return -EFAULT; - userPtr += 2; data = le2be16(data); userCount -= 2; bal += hSpeed; @@ -705,9 +690,8 @@ static ssize_t ata_ctx_s16le(const u_char __user *userPtr, size_t userCount, if (bal < 0) { if (userCount < 4) break; - if (get_user(data, (u_int __user *)userPtr)) + if (get_user(data, ((u_int *)userPtr)++)) return -EFAULT; - userPtr += 4; data = le2be16dbl(data); userCount -= 4; bal += hSpeed; @@ -725,7 +709,7 @@ static ssize_t ata_ctx_s16le(const u_char __user *userPtr, size_t userCount, } -static ssize_t ata_ctx_u16le(const u_char __user *userPtr, size_t userCount, +static ssize_t ata_ctx_u16le(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { @@ -743,9 +727,8 @@ static ssize_t ata_ctx_u16le(const u_char __user *userPtr, size_t userCount, if (bal < 0) { if (userCount < 2) break; - if (get_user(data, (u_short __user *)userPtr)) + if (get_user(data, ((u_short *)userPtr)++)) return -EFAULT; - userPtr += 2; data = le2be16(data) ^ 0x8000; userCount -= 2; bal += hSpeed; @@ -763,9 +746,8 @@ static ssize_t ata_ctx_u16le(const u_char __user *userPtr, size_t userCount, if (bal < 0) { if (userCount < 4) break; - if (get_user(data, (u_int __user *)userPtr)) + if (get_user(data, ((u_int *)userPtr)++)) return -EFAULT; - userPtr += 4; data = le2be16dbl(data) ^ 0x80008000; userCount -= 4; bal += hSpeed; diff --git a/trunk/sound/oss/dmasound/dmasound_paula.c b/trunk/sound/oss/dmasound/dmasound_paula.c index 494070a3f870..d59f60b26410 100644 --- a/trunk/sound/oss/dmasound/dmasound_paula.c +++ b/trunk/sound/oss/dmasound/dmasound_paula.c @@ -34,7 +34,6 @@ #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) @@ -157,7 +156,7 @@ static int AmiStateInfo(char *buffer, size_t space); * Native format */ -static ssize_t ami_ct_s8(const u_char __user *userPtr, size_t userCount, +static ssize_t ami_ct_s8(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { ssize_t count, used; @@ -190,7 +189,7 @@ static ssize_t ami_ct_s8(const u_char __user *userPtr, size_t userCount, */ #define GENERATE_AMI_CT8(funcname, convsample) \ -static ssize_t funcname(const u_char __user *userPtr, size_t userCount, \ +static ssize_t funcname(const u_char *userPtr, size_t userCount, \ u_char frame[], ssize_t *frameUsed, \ ssize_t frameLeft) \ { \ @@ -241,11 +240,10 @@ GENERATE_AMI_CT8(ami_ct_u8, AMI_CT_U8) */ #define GENERATE_AMI_CT_16(funcname, convsample) \ -static ssize_t funcname(const u_char __user *userPtr, size_t userCount, \ +static ssize_t funcname(const u_char *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; \ \ @@ -255,7 +253,7 @@ static ssize_t funcname(const u_char __user *userPtr, size_t userCount, \ count = min_t(size_t, userCount, frameLeft)>>1 & ~1; \ used = count*2; \ while (count > 0) { \ - if (get_user(data, ptr++)) \ + if (get_user(data, ((u_short *)userPtr)++)) \ return -EFAULT; \ data = convsample(data); \ *high++ = data>>8; \ @@ -270,12 +268,12 @@ static ssize_t funcname(const u_char __user *userPtr, size_t userCount, \ count = min_t(size_t, userCount, frameLeft)>>2 & ~1; \ used = count*4; \ while (count > 0) { \ - if (get_user(data, ptr++)) \ + if (get_user(data, ((u_short *)userPtr)++)) \ return -EFAULT; \ data = convsample(data); \ *lefth++ = data>>8; \ *leftl++ = (data>>2) & 0x3f; \ - if (get_user(data, ptr++)) \ + if (get_user(data, ((u_short *)userPtr)++)) \ return -EFAULT; \ data = convsample(data); \ *righth++ = data>>8; \ diff --git a/trunk/sound/oss/dmasound/dmasound_q40.c b/trunk/sound/oss/dmasound/dmasound_q40.c index e2081f32b0c4..1ddaa6284b08 100644 --- a/trunk/sound/oss/dmasound/dmasound_q40.c +++ b/trunk/sound/oss/dmasound/dmasound_q40.c @@ -58,7 +58,7 @@ static void Q40Interrupt(void); /* userCount, frameUsed, frameLeft == byte counts */ -static ssize_t q40_ct_law(const u_char __user *userPtr, size_t userCount, +static ssize_t q40_ct_law(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { @@ -79,7 +79,7 @@ static ssize_t q40_ct_law(const u_char __user *userPtr, size_t userCount, } -static ssize_t q40_ct_s8(const u_char __user *userPtr, size_t userCount, +static ssize_t q40_ct_s8(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { @@ -98,7 +98,7 @@ static ssize_t q40_ct_s8(const u_char __user *userPtr, size_t userCount, return used; } -static ssize_t q40_ct_u8(const u_char __user *userPtr, size_t userCount, +static ssize_t q40_ct_u8(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { @@ -114,7 +114,7 @@ static ssize_t q40_ct_u8(const u_char __user *userPtr, size_t userCount, /* a bit too complicated to optimise right now ..*/ -static ssize_t q40_ctx_law(const u_char __user *userPtr, size_t userCount, +static ssize_t q40_ctx_law(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { @@ -152,7 +152,7 @@ static ssize_t q40_ctx_law(const u_char __user *userPtr, size_t userCount, } -static ssize_t q40_ctx_s8(const u_char __user *userPtr, size_t userCount, +static ssize_t q40_ctx_s8(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { @@ -189,7 +189,7 @@ static ssize_t q40_ctx_s8(const u_char __user *userPtr, size_t userCount, } -static ssize_t q40_ctx_u8(const u_char __user *userPtr, size_t userCount, +static ssize_t q40_ctx_u8(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { @@ -224,7 +224,7 @@ static ssize_t q40_ctx_u8(const u_char __user *userPtr, size_t userCount, } /* compressing versions */ -static ssize_t q40_ctc_law(const u_char __user *userPtr, size_t userCount, +static ssize_t q40_ctc_law(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { @@ -265,7 +265,7 @@ static ssize_t q40_ctc_law(const u_char __user *userPtr, size_t userCount, } -static ssize_t q40_ctc_s8(const u_char __user *userPtr, size_t userCount, +static ssize_t q40_ctc_s8(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { @@ -304,7 +304,7 @@ static ssize_t q40_ctc_s8(const u_char __user *userPtr, size_t userCount, } -static ssize_t q40_ctc_u8(const u_char __user *userPtr, size_t userCount, +static ssize_t q40_ctc_u8(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft) { diff --git a/trunk/sound/oss/dmasound/trans_16.c b/trunk/sound/oss/dmasound/trans_16.c index ca973ac2a30a..23562e947806 100644 --- a/trunk/sound/oss/dmasound/trans_16.c +++ b/trunk/sound/oss/dmasound/trans_16.c @@ -17,7 +17,6 @@ #include #include "dmasound.h" -extern int expand_bal; /* Balance factor for expanding (not volume!) */ static short dmasound_alaw2dma16[] ; static short dmasound_ulaw2dma16[] ;