Automatic merge of rsync://rsync.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 8bfcb37..bf397a9 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -85,6 +85,7 @@
config ARCH_CLPS7500
bool "Cirrus-CL-PS7500FE"
select TIMER_ACORN
+ select ISA
config ARCH_CLPS711X
bool "CLPS711x/EP721x-based"
@@ -96,6 +97,7 @@
config ARCH_EBSA110
bool "EBSA-110"
+ select ISA
help
This is an evaluation board for the StrongARM processor available
from Digital. It has limited hardware on-board, including an onboard
@@ -120,13 +122,16 @@
config ARCH_IOP3XX
bool "IOP3xx-based"
+ select PCI
config ARCH_IXP4XX
bool "IXP4xx-based"
select DMABOUNCE
+ select PCI
config ARCH_IXP2000
bool "IXP2400/2800-based"
+ select PCI
config ARCH_L7200
bool "LinkUp-L7200"
@@ -155,6 +160,8 @@
config ARCH_SA1100
bool "SA1100-based"
+ select ISA
+ select DISCONTIGMEM
config ARCH_S3C2410
bool "Samsung S3C2410"
@@ -165,6 +172,9 @@
config ARCH_SHARK
bool "Shark"
+ select ISA
+ select ISA_DMA
+ select PCI
config ARCH_LH7A40X
bool "Sharp LH7A40X"
@@ -252,8 +262,6 @@
config ISA
bool
- depends on FOOTBRIDGE_HOST || ARCH_SHARK || ARCH_CLPS7500 || ARCH_EBSA110 || ARCH_CDB89712 || ARCH_EDB7211 || ARCH_SA1100 || ARCH_MX1ADS
- default y
help
Find out whether you have ISA slots on your motherboard. ISA is the
name of a bus system, i.e. the way the CPU talks to the other stuff
@@ -263,8 +271,6 @@
config ISA_DMA
bool
- depends on FOOTBRIDGE_HOST || ARCH_SHARK
- default y
config ISA_DMA_API
bool
@@ -272,7 +278,6 @@
config PCI
bool "PCI support" if ARCH_INTEGRATOR_AP
- default y if ARCH_SHARK || FOOTBRIDGE_HOST || ARCH_IOP3XX || ARCH_IXP4XX || ARCH_IXP2000
help
Find out whether you have a PCI motherboard. PCI is the name of a
bus system, i.e. the way the CPU talks to the other stuff inside
@@ -300,7 +305,7 @@
config SMP
bool "Symmetric Multi-Processing (EXPERIMENTAL)"
- depends on EXPERIMENTAL && n
+ depends on EXPERIMENTAL #&& n
help
This enables support for systems with more than one CPU. If you have
a system with only one CPU, like most personal computers, say N. If
@@ -340,8 +345,7 @@
config DISCONTIGMEM
bool
- depends on ARCH_EDB7211 || ARCH_SA1100 || (ARCH_LH7A40X && !LH7A40X_CONTIGMEM)
- default y
+ default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM)
help
Say Y to support efficient handling of discontiguous physical memory,
for architectures which are either NUMA (Non-Uniform Memory Access)
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 080df90..4eb3615 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -17,8 +17,8 @@
#include <asm/glue.h>
#include <asm/vfpmacros.h>
-#include <asm/hardware.h> @ should be moved into entry-macro.S
-#include <asm/arch/irqs.h> @ should be moved into entry-macro.S
+#include <asm/hardware.h> /* should be moved into entry-macro.S */
+#include <asm/arch/irqs.h> /* should be moved into entry-macro.S */
#include <asm/arch/entry-macro.S>
#include "entry-header.S"
@@ -505,9 +505,9 @@
mra r4, r5, acc0
stmia ip, {r4, r5}
#endif
-#ifdef CONFIG_HAS_TLS_REG
+#if defined(CONFIG_HAS_TLS_REG)
mcr p15, 0, r3, c13, c0, 3 @ set TLS register
-#else
+#elif !defined(CONFIG_TLS_REG_EMUL)
mov r4, #0xffff0fff
str r3, [r4, #-15] @ TLS val at 0xffff0ff0
#endif
@@ -690,11 +690,7 @@
__kuser_get_tls: @ 0xffff0fe0
-#ifndef CONFIG_HAS_TLS_REG
-
-#ifdef CONFIG_SMP /* sanity check */
-#error "CONFIG_SMP without CONFIG_HAS_TLS_REG is wrong"
-#endif
+#if !defined(CONFIG_HAS_TLS_REG) && !defined(CONFIG_TLS_REG_EMUL)
ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0
mov pc, lr
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 171b3e8..4733877 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -19,6 +19,7 @@
#include <asm/procinfo.h>
#include <asm/ptrace.h>
#include <asm/constants.h>
+#include <asm/thread_info.h>
#include <asm/system.h>
#define PROCINFO_MMUFLAGS 8
@@ -131,7 +132,7 @@
.long processor_id @ r4
.long __machine_arch_type @ r5
.long cr_alignment @ r6
- .long init_thread_union+8192 @ sp
+ .long init_thread_union + THREAD_START_SP @ sp
/*
* The following fragment of code is executed with the MMU on, and uses
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 26eacd3..8f146a4 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -256,8 +256,6 @@
static unsigned int nr_thread_info;
#define EXTRA_TASK_STRUCT 4
-#define ll_alloc_task_struct() ((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
-#define ll_free_task_struct(p) free_pages((unsigned long)(p),1)
struct thread_info *alloc_thread_info(struct task_struct *task)
{
@@ -274,17 +272,16 @@
}
if (!thread)
- thread = ll_alloc_task_struct();
+ thread = (struct thread_info *)
+ __get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER);
-#ifdef CONFIG_MAGIC_SYSRQ
+#ifdef CONFIG_DEBUG_STACK_USAGE
/*
* The stack must be cleared if you want SYSRQ-T to
* give sensible stack usage information
*/
- if (thread) {
- char *p = (char *)thread;
- memzero(p+KERNEL_STACK_SIZE, KERNEL_STACK_SIZE);
- }
+ if (thread)
+ memzero(thread, THREAD_SIZE);
#endif
return thread;
}
@@ -297,7 +294,7 @@
thread_info_head = p;
nr_thread_info += 1;
} else
- ll_free_task_struct(thread);
+ free_pages((unsigned long)thread, THREAD_SIZE_ORDER);
}
/*
@@ -350,7 +347,7 @@
struct thread_info *thread = p->thread_info;
struct pt_regs *childregs;
- childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_SIZE - 8)) - 1;
+ childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_START_SP)) - 1;
*childregs = *regs;
childregs->ARM_r0 = 0;
childregs->ARM_sp = stack_start;
@@ -447,15 +444,17 @@
unsigned long get_wchan(struct task_struct *p)
{
unsigned long fp, lr;
- unsigned long stack_page;
+ unsigned long stack_start, stack_end;
int count = 0;
if (!p || p == current || p->state == TASK_RUNNING)
return 0;
- stack_page = 4096 + (unsigned long)p->thread_info;
+ stack_start = (unsigned long)(p->thread_info + 1);
+ stack_end = ((unsigned long)p->thread_info) + THREAD_SIZE;
+
fp = thread_saved_fp(p);
do {
- if (fp < stack_page || fp > 4092+stack_page)
+ if (fp < stack_start || fp > stack_end)
return 0;
lr = pc_pointer (((unsigned long *)fp)[-1]);
if (!in_sched_functions(lr))
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index ef32577..f897ce2 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -302,7 +302,7 @@
"b ret_to_user"
:
: "r" (current_thread_info()),
- "Ir" (THREAD_SIZE - 8 - sizeof(regs)),
+ "Ir" (THREAD_START_SP - sizeof(regs)),
"r" (®s),
"Ir" (sizeof(regs))
: "r0", "r1", "r2", "r3", "ip", "memory");
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 3a001fe..14df16b 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -218,7 +218,8 @@
tsk->comm, tsk->pid, tsk->thread_info + 1);
if (!user_mode(regs) || in_interrupt()) {
- dump_mem("Stack: ", regs->ARM_sp, 8192+(unsigned long)tsk->thread_info);
+ dump_mem("Stack: ", regs->ARM_sp,
+ THREAD_SIZE + (unsigned long)tsk->thread_info);
dump_backtrace(regs, tsk);
dump_instr(regs);
}
@@ -450,9 +451,9 @@
case NR(set_tls):
thread->tp_value = regs->ARM_r0;
-#ifdef CONFIG_HAS_TLS_REG
+#if defined(CONFIG_HAS_TLS_REG)
asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) );
-#else
+#elif !defined(CONFIG_TLS_REG_EMUL)
/*
* User space must never try to access this directly.
* Expect your app to break eventually if you do so.
@@ -497,11 +498,14 @@
return 0;
}
-#if defined(CONFIG_CPU_32v6) && !defined(CONFIG_HAS_TLS_REG)
+#ifdef CONFIG_TLS_REG_EMUL
/*
* We might be running on an ARMv6+ processor which should have the TLS
- * register, but for some reason we can't use it and have to emulate it.
+ * register but for some reason we can't use it, or maybe an SMP system
+ * using a pre-ARMv6 processor (there are apparently a few prototypes like
+ * that in existence) and therefore access to that register must be
+ * emulated.
*/
static int get_tp_trap(struct pt_regs *regs, unsigned int instr)
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index a39c6a4..ad2d66c 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -5,6 +5,7 @@
#include <asm-generic/vmlinux.lds.h>
#include <linux/config.h>
+#include <asm/thread_info.h>
OUTPUT_ARCH(arm)
ENTRY(stext)
@@ -103,7 +104,7 @@
__data_loc = ALIGN(4); /* location in binary */
. = DATAADDR;
#else
- . = ALIGN(8192);
+ . = ALIGN(THREAD_SIZE);
__data_loc = .;
#endif
diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig
index f6e6763..45c930c 100644
--- a/arch/arm/mach-clps711x/Kconfig
+++ b/arch/arm/mach-clps711x/Kconfig
@@ -10,6 +10,7 @@
config ARCH_CDB89712
bool "CDB89712"
+ select ISA
help
This is an evaluation board from Cirrus for the CS89712 processor.
The board includes 2 serial ports, Ethernet, IRDA, and expansion
@@ -26,6 +27,8 @@
config ARCH_EDB7211
bool "EDB7211"
+ select ISA
+ select DISCONTIGMEM
help
Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211
evaluation board.
diff --git a/arch/arm/mach-footbridge/Kconfig b/arch/arm/mach-footbridge/Kconfig
index 1090c68..324d9ed 100644
--- a/arch/arm/mach-footbridge/Kconfig
+++ b/arch/arm/mach-footbridge/Kconfig
@@ -5,6 +5,9 @@
config ARCH_CATS
bool "CATS"
select FOOTBRIDGE_HOST
+ select ISA
+ select ISA_DMA
+ select PCI
help
Say Y here if you intend to run this kernel on the CATS.
@@ -13,6 +16,9 @@
config ARCH_PERSONAL_SERVER
bool "Compaq Personal Server"
select FOOTBRIDGE_HOST
+ select ISA
+ select ISA_DMA
+ select PCI
---help---
Say Y here if you intend to run this kernel on the Compaq
Personal Server.
@@ -42,6 +48,9 @@
bool "EBSA285 (host mode)"
select ARCH_EBSA285
select FOOTBRIDGE_HOST
+ select ISA
+ select ISA_DMA
+ select PCI
help
Say Y here if you intend to run this kernel on the EBSA285 card
in host ("central function") mode.
@@ -51,6 +60,9 @@
config ARCH_NETWINDER
bool "NetWinder"
select FOOTBRIDGE_HOST
+ select ISA
+ select ISA_DMA
+ select PCI
help
Say Y here if you intend to run this kernel on the Rebel.COM
NetWinder. Information about this machine can be found at:
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index ec85813..cddd194 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -4,6 +4,7 @@
config ARCH_MX1ADS
bool "mx1ads"
depends on ARCH_IMX
+ select ISA
help
Say Y here if you are using the Motorola MX1ADS board
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 27892e3..c4fc6be 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -410,17 +410,23 @@
help
Say Y here to disable branch prediction. If unsure, say N.
+config TLS_REG_EMUL
+ bool
+ default y if (SMP || CPU_32v6) && (CPU_32v5 || CPU_32v4 || CPU_32v3)
+ help
+ We might be running on an ARMv6+ processor which should have the TLS
+ register but for some reason we can't use it, or maybe an SMP system
+ using a pre-ARMv6 processor (there are apparently a few prototypes
+ like that in existence) and therefore access to that register must
+ be emulated.
+
config HAS_TLS_REG
bool
- depends on CPU_32v6 && !CPU_32v5 && !CPU_32v4 && !CPU_32v3
- default y
+ depends on CPU_32v6
+ default y if !TLS_REG_EMUL
help
This selects support for the CP15 thread register.
- It is defined to be available on ARMv6 or later. However
- if the kernel is configured to support multiple CPUs including
- a pre-ARMv6 processors, or if a given ARMv6 processor doesn't
- implement the thread register for some reason, then access to
- this register from user space must be trapped and emulated.
- If user space is relying on the __kuser_get_tls code then
- there should not be any impact.
+ It is defined to be available on ARMv6 or later. If a particular
+ ARMv6 or later CPU doesn't support it then it must omc;ide "select
+ TLS_REG_EMUL" along with its other caracteristics.
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index 554e4a1..d3ff783 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -49,7 +49,7 @@
EXTRA_CFLAGS += -DXFS_LOG_TRACE
EXTRA_CFLAGS += -DXFS_RW_TRACE
EXTRA_CFLAGS += -DPAGEBUF_TRACE
- # EXTRA_CFLAGS += -DXFS_VNODE_TRACE
+ EXTRA_CFLAGS += -DXFS_VNODE_TRACE
endif
obj-$(CONFIG_XFS_FS) += xfs.o
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 76a8475..9278e9a 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -558,7 +558,8 @@
int i;
BUG_ON(PageWriteback(page));
- set_page_writeback(page);
+ if (bh_count)
+ set_page_writeback(page);
if (clear_dirty)
clear_page_dirty(page);
unlock_page(page);
@@ -578,9 +579,6 @@
if (probed_page && clear_dirty)
wbc->nr_to_write--; /* Wrote an "extra" page */
- } else {
- end_page_writeback(page);
- wbc->pages_skipped++; /* We didn't write this page */
}
}
@@ -602,21 +600,26 @@
{
struct buffer_head *bh_arr[MAX_BUF_PER_PAGE], *bh, *head;
xfs_iomap_t *mp = iomapp, *tmp;
- unsigned long end, offset;
- pgoff_t end_index;
- int i = 0, index = 0;
+ unsigned long offset, end_offset;
+ int index = 0;
int bbits = inode->i_blkbits;
+ int len, page_dirty;
- end_index = i_size_read(inode) >> PAGE_CACHE_SHIFT;
- if (page->index < end_index) {
- end = PAGE_CACHE_SIZE;
- } else {
- end = i_size_read(inode) & (PAGE_CACHE_SIZE-1);
- }
+ 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.
+ */
+ len = 1 << inode->i_blkbits;
+ 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 {
- offset = i << bbits;
- if (offset >= end)
+ if (offset >= end_offset)
break;
if (!(PageUptodate(page) || buffer_uptodate(bh)))
continue;
@@ -625,6 +628,7 @@
if (startio) {
lock_buffer(bh);
bh_arr[index++] = bh;
+ page_dirty--;
}
continue;
}
@@ -657,10 +661,11 @@
unlock_buffer(bh);
mark_buffer_dirty(bh);
}
- } while (i++, (bh = bh->b_this_page) != head);
+ page_dirty--;
+ } while (offset += len, (bh = bh->b_this_page) != head);
- if (startio) {
- xfs_submit_page(page, wbc, bh_arr, index, 1, index == i);
+ if (startio && index) {
+ xfs_submit_page(page, wbc, bh_arr, index, 1, !page_dirty);
} else {
unlock_page(page);
}
@@ -725,8 +730,11 @@
__uint64_t end_offset;
pgoff_t end_index, last_index, tlast;
int len, err, i, cnt = 0, uptodate = 1;
- int flags = startio ? 0 : BMAPI_TRYLOCK;
- int page_dirty, delalloc = 0;
+ int flags;
+ int page_dirty;
+
+ /* wait for other IO threads? */
+ 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);
@@ -740,19 +748,22 @@
}
}
- offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
end_offset = min_t(unsigned long long,
- offset + PAGE_CACHE_SIZE, i_size_read(inode));
-
- bh = head = page_buffers(page);
- iomp = NULL;
+ (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 and
- * is decrememted as we move each into a cleanable state.
+ * page_dirty is initially a count of buffers on the page before
+ * EOF and is decrememted as we move each into a cleanable state.
*/
- len = bh->b_size;
- page_dirty = PAGE_CACHE_SIZE / len;
+ len = 1 << inode->i_blkbits;
+ 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);
do {
if (offset >= end_offset)
@@ -804,7 +815,6 @@
*/
} else if (buffer_delay(bh)) {
if (!iomp) {
- delalloc = 1;
err = xfs_map_blocks(inode, offset, len, &iomap,
BMAPI_ALLOCATE | flags);
if (err) {
@@ -875,14 +885,15 @@
if (uptodate && bh == head)
SetPageUptodate(page);
- if (startio)
- xfs_submit_page(page, wbc, bh_arr, cnt, 0, 1);
+ if (startio) {
+ WARN_ON(page_dirty);
+ xfs_submit_page(page, wbc, bh_arr, cnt, 0, !page_dirty);
+ }
if (iomp) {
- tlast = (iomp->iomap_offset + iomp->iomap_bsize - 1) >>
+ offset = (iomp->iomap_offset + iomp->iomap_bsize - 1) >>
PAGE_CACHE_SHIFT;
- if (delalloc && (tlast > last_index))
- tlast = last_index;
+ tlast = min_t(pgoff_t, offset, last_index);
xfs_cluster_write(inode, page->index + 1, iomp, wbc,
startio, unmapped, tlast);
}
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index 23e0eb6..997963e 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -1746,13 +1746,15 @@
STATIC struct task_struct *pagebuf_daemon_task;
STATIC int pagebuf_daemon_active;
STATIC int force_flush;
-
+STATIC int force_sleep;
STATIC int
pagebuf_daemon_wakeup(
int priority,
unsigned int mask)
{
+ if (force_sleep)
+ return 0;
force_flush = 1;
barrier();
wake_up_process(pagebuf_daemon_task);
@@ -1778,7 +1780,12 @@
INIT_LIST_HEAD(&tmp);
do {
- try_to_freeze(PF_FREEZE);
+ if (unlikely(current->flags & PF_FREEZE)) {
+ force_sleep = 1;
+ refrigerator(PF_FREEZE);
+ } else {
+ force_sleep = 0;
+ }
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout((xfs_buf_timer_centisecs * HZ) / 100);
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 9f057a4..d0d412a 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -515,10 +515,49 @@
}
#endif /* HAVE_FOP_OPEN_EXEC */
+/*
+ * Temporary workaround to the AIO direct IO write problem.
+ * This code can go and we can revert to do_sync_write once
+ * the writepage(s) rework is merged.
+ */
+STATIC ssize_t
+linvfs_write(
+ struct file *filp,
+ const char __user *buf,
+ size_t len,
+ loff_t *ppos)
+{
+ struct kiocb kiocb;
+ ssize_t ret;
+
+ init_sync_kiocb(&kiocb, filp);
+ kiocb.ki_pos = *ppos;
+ ret = __linvfs_write(&kiocb, buf, 0, len, kiocb.ki_pos);
+ *ppos = kiocb.ki_pos;
+ return ret;
+}
+STATIC ssize_t
+linvfs_write_invis(
+ struct file *filp,
+ const char __user *buf,
+ size_t len,
+ loff_t *ppos)
+{
+ struct kiocb kiocb;
+ ssize_t ret;
+
+ init_sync_kiocb(&kiocb, filp);
+ kiocb.ki_pos = *ppos;
+ ret = __linvfs_write(&kiocb, buf, IO_INVIS, len, kiocb.ki_pos);
+ *ppos = kiocb.ki_pos;
+ return ret;
+}
+
+
struct file_operations linvfs_file_operations = {
.llseek = generic_file_llseek,
.read = do_sync_read,
- .write = do_sync_write,
+ .write = linvfs_write,
.readv = linvfs_readv,
.writev = linvfs_writev,
.aio_read = linvfs_aio_read,
@@ -540,7 +579,7 @@
struct file_operations linvfs_invis_file_operations = {
.llseek = generic_file_llseek,
.read = do_sync_read,
- .write = do_sync_write,
+ .write = linvfs_write_invis,
.readv = linvfs_readv_invis,
.writev = linvfs_writev_invis,
.aio_read = linvfs_aio_read_invis,
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index ff145fd..aa9daae 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -683,6 +683,9 @@
(xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
mp->m_rtdev_targp : mp->m_ddev_targp;
+ if (ioflags & IO_ISAIO)
+ return XFS_ERROR(-ENOSYS);
+
if ((pos & target->pbr_smask) || (count & target->pbr_smask))
return XFS_ERROR(-EINVAL);
diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c
index 849c61c..a832d16 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.c
+++ b/fs/xfs/linux-2.6/xfs_vnode.c
@@ -156,7 +156,6 @@
#ifdef XFS_VNODE_TRACE
vp->v_trace = ktrace_alloc(VNODE_TRACE_SIZE, KM_SLEEP);
- printk("Allocated VNODE_TRACE at 0x%p\n", vp->v_trace);
#endif /* XFS_VNODE_TRACE */
vn_trace_exit(vp, "vn_initialize", (inst_t *)__return_address);
@@ -424,13 +423,13 @@
* Vnode tracing code.
*/
void
-vn_trace_entry(vnode_t *vp, char *func, inst_t *ra)
+vn_trace_entry(vnode_t *vp, const char *func, inst_t *ra)
{
KTRACE_ENTER(vp, VNODE_KTRACE_ENTRY, func, 0, ra);
}
void
-vn_trace_exit(vnode_t *vp, char *func, inst_t *ra)
+vn_trace_exit(vnode_t *vp, const char *func, inst_t *ra)
{
KTRACE_ENTER(vp, VNODE_KTRACE_EXIT, func, 0, ra);
}
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index da76c1f..00466c3 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -86,10 +86,11 @@
vnumber_t v_number; /* in-core vnode number */
vn_bhv_head_t v_bh; /* behavior head */
spinlock_t v_lock; /* VN_LOCK/VN_UNLOCK */
- struct inode v_inode; /* Linux inode */
#ifdef XFS_VNODE_TRACE
struct ktrace *v_trace; /* trace header structure */
#endif
+ struct inode v_inode; /* Linux inode */
+ /* inode MUST be last */
} vnode_t;
#define v_fbhv v_bh.bh_first /* first behavior */
@@ -409,7 +410,7 @@
int va_mask; /* bit-mask of attributes present */
enum vtype va_type; /* vnode type (for create) */
mode_t va_mode; /* file access mode and type */
- nlink_t va_nlink; /* number of references to file */
+ xfs_nlink_t va_nlink; /* number of references to file */
uid_t va_uid; /* owner user id */
gid_t va_gid; /* owner group id */
xfs_ino_t va_nodeid; /* file id */
@@ -625,6 +626,7 @@
#define ATTR_DMI 0x08 /* invocation from a DMI function */
#define ATTR_LAZY 0x80 /* set/get attributes lazily */
#define ATTR_NONBLOCK 0x100 /* return EAGAIN if operation would block */
+#define ATTR_NOLOCK 0x200 /* Don't grab any conflicting locks */
/*
* Flags to VOP_FSYNC and VOP_RECLAIM.
@@ -646,8 +648,8 @@
#define VNODE_KTRACE_REF 4
#define VNODE_KTRACE_RELE 5
-extern void vn_trace_entry(struct vnode *, char *, inst_t *);
-extern void vn_trace_exit(struct vnode *, char *, inst_t *);
+extern void vn_trace_entry(struct vnode *, const char *, inst_t *);
+extern void vn_trace_exit(struct vnode *, const char *, inst_t *);
extern void vn_trace_hold(struct vnode *, char *, int, inst_t *);
extern void vn_trace_ref(struct vnode *, char *, int, inst_t *);
extern void vn_trace_rele(struct vnode *, char *, int, inst_t *);
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index 08d551a..63abdc2 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -182,7 +182,7 @@
if (VN_CACHED(tvp) != 0)
xfs_inval_cached_pages(XFS_ITOV(tip), &(tip->i_iocore),
- (loff_t)0, 0, 0);
+ (xfs_off_t)0, 0, 0);
/* Verify O_DIRECT for ftmp */
if (VN_CACHED(tvp) != 0) {
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index 3a0ba1d..d3da000 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -136,6 +136,40 @@
}
/*
+ * Try to move an inode to the front of its hash list if possible
+ * (and if its not there already). Called right after obtaining
+ * the list version number and then dropping the read_lock on the
+ * hash list in question (which is done right after looking up the
+ * inode in question...).
+ */
+STATIC void
+xfs_ihash_promote(
+ xfs_ihash_t *ih,
+ xfs_inode_t *ip,
+ ulong version)
+{
+ xfs_inode_t *iq;
+
+ if ((ip->i_prevp != &ih->ih_next) && write_trylock(&ih->ih_lock)) {
+ if (likely(version == ih->ih_version)) {
+ /* remove from list */
+ if ((iq = ip->i_next)) {
+ iq->i_prevp = ip->i_prevp;
+ }
+ *ip->i_prevp = iq;
+
+ /* insert at list head */
+ iq = ih->ih_next;
+ iq->i_prevp = &ip->i_next;
+ ip->i_next = iq;
+ ip->i_prevp = &ih->ih_next;
+ ih->ih_next = ip;
+ }
+ write_unlock(&ih->ih_lock);
+ }
+}
+
+/*
* Look up an inode by number in the given file system.
* The inode is looked up in the hash table for the file system
* represented by the mount point parameter mp. Each bucket of
@@ -229,7 +263,9 @@
XFS_STATS_INC(xs_ig_found);
ip->i_flags &= ~XFS_IRECLAIMABLE;
+ version = ih->ih_version;
read_unlock(&ih->ih_lock);
+ xfs_ihash_promote(ih, ip, version);
XFS_MOUNT_ILOCK(mp);
list_del_init(&ip->i_reclaim);
@@ -259,8 +295,15 @@
inode_vp, vp);
}
+ /*
+ * Inode cache hit: if ip is not at the front of
+ * its hash chain, move it there now.
+ * Do this with the lock held for update, but
+ * do statistics after releasing the lock.
+ */
+ version = ih->ih_version;
read_unlock(&ih->ih_lock);
-
+ xfs_ihash_promote(ih, ip, version);
XFS_STATS_INC(xs_ig_found);
finish_inode:
@@ -547,6 +590,7 @@
{
xfs_ihash_t *ih;
xfs_inode_t *ip;
+ ulong version;
ih = XFS_IHASH(mp, ino);
read_lock(&ih->ih_lock);
@@ -554,11 +598,15 @@
if (ip->i_ino == ino) {
/*
* If we find it and tp matches, return it.
+ * Also move it to the front of the hash list
+ * if we find it and it is not already there.
* Otherwise break from the loop and return
* NULL.
*/
if (ip->i_transp == tp) {
+ version = ih->ih_version;
read_unlock(&ih->ih_lock);
+ xfs_ihash_promote(ih, ip, version);
return (ip);
}
break;
@@ -685,6 +733,7 @@
iq->i_prevp = ip->i_prevp;
}
*ip->i_prevp = iq;
+ ih->ih_version++;
write_unlock(&ih->ih_lock);
/*
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 43c632a..bc8c8c7 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1130,7 +1130,7 @@
xfs_trans_t *tp,
xfs_inode_t *pip,
mode_t mode,
- nlink_t nlink,
+ xfs_nlink_t nlink,
xfs_dev_t rdev,
cred_t *cr,
xfs_prid_t prid,
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index a53b1cc..37e1c31 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -495,9 +495,9 @@
int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
xfs_inode_t **, xfs_daddr_t);
int xfs_iread_extents(struct xfs_trans *, xfs_inode_t *, int);
-int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, nlink_t,
- xfs_dev_t, struct cred *, xfs_prid_t, int,
- struct xfs_buf **, boolean_t *, xfs_inode_t **);
+int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t,
+ xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t,
+ int, struct xfs_buf **, boolean_t *, xfs_inode_t **);
void xfs_xlate_dinode_core(xfs_caddr_t, struct xfs_dinode_core *,
int);
uint xfs_ip2xflags(struct xfs_inode *);
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 3826e8f..991f8a6 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -308,7 +308,8 @@
break;
}
- error = XFS_IOMAP_WRITE_ALLOCATE(mp, io, &imap, &nimaps);
+ error = XFS_IOMAP_WRITE_ALLOCATE(mp, io, offset, count,
+ &imap, &nimaps);
break;
case BMAPI_UNWRITTEN:
lockmode = 0;
@@ -365,7 +366,7 @@
int
xfs_iomap_write_direct(
xfs_inode_t *ip,
- loff_t offset,
+ xfs_off_t offset,
size_t count,
int flags,
xfs_bmbt_irec_t *ret_imap,
@@ -541,7 +542,7 @@
int
xfs_iomap_write_delay(
xfs_inode_t *ip,
- loff_t offset,
+ xfs_off_t offset,
size_t count,
int ioflag,
xfs_bmbt_irec_t *ret_imap,
@@ -746,6 +747,8 @@
int
xfs_iomap_write_allocate(
xfs_inode_t *ip,
+ xfs_off_t offset,
+ size_t count,
xfs_bmbt_irec_t *map,
int *retmap)
{
@@ -770,9 +773,9 @@
if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
return XFS_ERROR(error);
- offset_fsb = map->br_startoff;
+ offset_fsb = XFS_B_TO_FSBT(mp, offset);
count_fsb = map->br_blockcount;
- map_start_fsb = offset_fsb;
+ map_start_fsb = map->br_startoff;
XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb));
@@ -868,9 +871,9 @@
imap[i].br_startoff,
imap[i].br_blockcount,imap[i].br_state);
}
- if ((map->br_startoff >= imap[i].br_startoff) &&
- (map->br_startoff < (imap[i].br_startoff +
- imap[i].br_blockcount))) {
+ if ((offset_fsb >= imap[i].br_startoff) &&
+ (offset_fsb < (imap[i].br_startoff +
+ imap[i].br_blockcount))) {
*map = imap[i];
*retmap = 1;
XFS_STATS_INC(xs_xstrat_quick);
@@ -883,9 +886,8 @@
* file, just surrounding data, try again.
*/
nimaps--;
- offset_fsb = imap[nimaps].br_startoff +
- imap[nimaps].br_blockcount;
- map_start_fsb = offset_fsb;
+ map_start_fsb = imap[nimaps].br_startoff +
+ imap[nimaps].br_blockcount;
}
trans_cancel:
@@ -899,7 +901,7 @@
int
xfs_iomap_write_unwritten(
xfs_inode_t *ip,
- loff_t offset,
+ xfs_off_t offset,
size_t count)
{
xfs_mount_t *mp = ip->i_mount;
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h
index 31c9108..4daaa52 100644
--- a/fs/xfs/xfs_iomap.h
+++ b/fs/xfs/xfs_iomap.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003,2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2003-2005 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -29,9 +29,6 @@
*
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
-
-
-
#ifndef __XFS_IOMAP_H__
#define __XFS_IOMAP_H__
@@ -56,7 +53,7 @@
BMAPI_UNWRITTEN = (1 << 3), /* unwritten extents to real extents */
/* modifiers */
BMAPI_IGNSTATE = (1 << 4), /* ignore unwritten state on read */
- BMAPI_DIRECT = (1 << 5), /* direct instead of buffered write */
+ BMAPI_DIRECT = (1 << 5), /* direct instead of buffered write */
BMAPI_MMAP = (1 << 6), /* allocate for mmap write */
BMAPI_SYNC = (1 << 7), /* sync write to flush delalloc space */
BMAPI_TRYLOCK = (1 << 8), /* non-blocking request */
@@ -67,13 +64,13 @@
/*
* xfs_iomap_t: File system I/O map
*
- * The iomap_bn field is expressed in 512-byte blocks, and is where the
+ * The iomap_bn field is expressed in 512-byte blocks, and is where the
* mapping starts on disk.
*
* The iomap_offset, iomap_bsize and iomap_delta fields are in bytes.
* iomap_offset is the offset of the mapping in the file itself.
- * iomap_bsize is the size of the mapping, iomap_delta is the
- * desired data's offset into the mapping, given the offset supplied
+ * iomap_bsize is the size of the mapping, iomap_delta is the
+ * desired data's offset into the mapping, given the offset supplied
* to the file I/O map routine.
*
* When a request is made to read beyond the logical end of the object,
@@ -84,8 +81,8 @@
typedef struct xfs_iomap {
xfs_daddr_t iomap_bn; /* first 512b blk of mapping */
xfs_buftarg_t *iomap_target;
- loff_t iomap_offset; /* offset of mapping, bytes */
- loff_t iomap_bsize; /* size of mapping, bytes */
+ xfs_off_t iomap_offset; /* offset of mapping, bytes */
+ xfs_off_t iomap_bsize; /* size of mapping, bytes */
size_t iomap_delta; /* offset into mapping, bytes */
iomap_flags_t iomap_flags;
} xfs_iomap_t;
@@ -96,12 +93,12 @@
extern int xfs_iomap(struct xfs_iocore *, xfs_off_t, ssize_t, int,
struct xfs_iomap *, int *);
-extern int xfs_iomap_write_direct(struct xfs_inode *, loff_t, size_t,
+extern int xfs_iomap_write_direct(struct xfs_inode *, xfs_off_t, size_t,
int, struct xfs_bmbt_irec *, int *, int);
-extern int xfs_iomap_write_delay(struct xfs_inode *, loff_t, size_t, int,
+extern int xfs_iomap_write_delay(struct xfs_inode *, xfs_off_t, size_t, int,
struct xfs_bmbt_irec *, int *);
-extern int xfs_iomap_write_allocate(struct xfs_inode *,
+extern int xfs_iomap_write_allocate(struct xfs_inode *, xfs_off_t, size_t,
struct xfs_bmbt_irec *, int *);
-extern int xfs_iomap_write_unwritten(struct xfs_inode *, loff_t, size_t);
+extern int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, size_t);
#endif /* __XFS_IOMAP_H__*/
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index b57423c..2ec967d 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -301,6 +301,15 @@
}
/*
+ * Version 1 directory format has never worked on Linux.
+ */
+ if (unlikely(!XFS_SB_VERSION_HASDIRV2(sbp))) {
+ cmn_err(CE_WARN,
+ "XFS: Attempted to mount file system using version 1 directory format");
+ return XFS_ERROR(ENOSYS);
+ }
+
+ /*
* Until this is fixed only page-sized or smaller data blocks work.
*/
if (unlikely(sbp->sb_blocksize > PAGE_SIZE)) {
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 5fc6201..30dd08f 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -210,15 +210,16 @@
struct xfs_bmap_free *);
typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *);
typedef int (*xfs_iomap_write_direct_t)(
- void *, loff_t, size_t, int,
+ void *, xfs_off_t, size_t, int,
struct xfs_bmbt_irec *, int *, int);
typedef int (*xfs_iomap_write_delay_t)(
- void *, loff_t, size_t, int,
+ void *, xfs_off_t, size_t, int,
struct xfs_bmbt_irec *, int *);
typedef int (*xfs_iomap_write_allocate_t)(
- void *, struct xfs_bmbt_irec *, int *);
+ void *, xfs_off_t, size_t,
+ struct xfs_bmbt_irec *, int *);
typedef int (*xfs_iomap_write_unwritten_t)(
- void *, loff_t, size_t);
+ void *, xfs_off_t, size_t);
typedef uint (*xfs_lck_map_shared_t)(void *);
typedef void (*xfs_lock_t)(void *, uint);
typedef void (*xfs_lock_demote_t)(void *, uint);
@@ -258,9 +259,9 @@
#define XFS_IOMAP_WRITE_DELAY(mp, io, offset, count, flags, mval, nmap) \
(*(mp)->m_io_ops.xfs_iomap_write_delay) \
((io)->io_obj, offset, count, flags, mval, nmap)
-#define XFS_IOMAP_WRITE_ALLOCATE(mp, io, mval, nmap) \
+#define XFS_IOMAP_WRITE_ALLOCATE(mp, io, offset, count, mval, nmap) \
(*(mp)->m_io_ops.xfs_iomap_write_allocate) \
- ((io)->io_obj, mval, nmap)
+ ((io)->io_obj, offset, count, mval, nmap)
#define XFS_IOMAP_WRITE_UNWRITTEN(mp, io, offset, count) \
(*(mp)->m_io_ops.xfs_iomap_write_unwritten) \
((io)->io_obj, offset, count)
@@ -428,10 +429,10 @@
#define XFS_WRITEIO_LOG_LARGE 16
/*
- * Max and min values for UIO and mount-option defined I/O sizes;
- * min value can't be less than a page. Currently unused.
+ * Max and min values for mount-option defined I/O
+ * preallocation sizes.
*/
-#define XFS_MAX_IO_LOG 16 /* 64K */
+#define XFS_MAX_IO_LOG 30 /* 1G */
#define XFS_MIN_IO_LOG PAGE_SHIFT
/*
diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h
index 04609d2..e4bf711 100644
--- a/fs/xfs/xfs_types.h
+++ b/fs/xfs/xfs_types.h
@@ -63,6 +63,7 @@
typedef __s64 xfs_daddr_t; /* <disk address> type */
typedef char * xfs_caddr_t; /* <core address> type */
typedef __u32 xfs_dev_t;
+typedef __u32 xfs_nlink_t;
/* __psint_t is the same size as a pointer */
#if (BITS_PER_LONG == 32)
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
index 816b945..d1f8146 100644
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -147,7 +147,7 @@
xfs_inode_t *dp, /* directory within whose allocate
the inode. */
mode_t mode,
- nlink_t nlink,
+ xfs_nlink_t nlink,
xfs_dev_t rdev,
cred_t *credp,
prid_t prid, /* project id */
diff --git a/fs/xfs/xfs_utils.h b/fs/xfs/xfs_utils.h
index e1ed6a5..01d98b4 100644
--- a/fs/xfs/xfs_utils.h
+++ b/fs/xfs/xfs_utils.h
@@ -42,7 +42,7 @@
extern int xfs_dir_lookup_int (bhv_desc_t *, uint, vname_t *, xfs_ino_t *,
xfs_inode_t **);
extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *);
-extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, nlink_t,
+extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t,
xfs_dev_t, cred_t *, prid_t, int,
xfs_inode_t **, int *);
extern int xfs_droplink (xfs_trans_t *, xfs_inode_t *);
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index 00aae9c..b537366 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -1649,6 +1649,7 @@
#define MNTOPT_SWIDTH "swidth" /* data volume stripe width */
#define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */
#define MNTOPT_MTPT "mtpt" /* filesystem mount point */
+#define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */
#define MNTOPT_IHASHSIZE "ihashsize" /* size of inode hash table */
#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */
#define MNTOPT_NOLOGFLUSH "nologflush" /* don't hard flush on log writes */
@@ -1657,6 +1658,28 @@
#define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */
#define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */
+STATIC unsigned long
+suffix_strtoul(const char *cp, char **endp, unsigned int base)
+{
+ int last, shift_left_factor = 0;
+ char *value = (char *)cp;
+
+ last = strlen(value) - 1;
+ if (value[last] == 'K' || value[last] == 'k') {
+ shift_left_factor = 10;
+ value[last] = '\0';
+ }
+ if (value[last] == 'M' || value[last] == 'm') {
+ shift_left_factor = 20;
+ value[last] = '\0';
+ }
+ if (value[last] == 'G' || value[last] == 'g') {
+ shift_left_factor = 30;
+ value[last] = '\0';
+ }
+
+ return simple_strtoul(cp, endp, base) << shift_left_factor;
+}
int
xfs_parseargs(
@@ -1688,60 +1711,60 @@
if (!strcmp(this_char, MNTOPT_LOGBUFS)) {
if (!value || !*value) {
printk("XFS: %s option requires an argument\n",
- MNTOPT_LOGBUFS);
+ this_char);
return EINVAL;
}
args->logbufs = simple_strtoul(value, &eov, 10);
} else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) {
- int last, in_kilobytes = 0;
-
if (!value || !*value) {
printk("XFS: %s option requires an argument\n",
- MNTOPT_LOGBSIZE);
+ this_char);
return EINVAL;
}
- last = strlen(value) - 1;
- if (value[last] == 'K' || value[last] == 'k') {
- in_kilobytes = 1;
- value[last] = '\0';
- }
- args->logbufsize = simple_strtoul(value, &eov, 10);
- if (in_kilobytes)
- args->logbufsize <<= 10;
+ args->logbufsize = suffix_strtoul(value, &eov, 10);
} else if (!strcmp(this_char, MNTOPT_LOGDEV)) {
if (!value || !*value) {
printk("XFS: %s option requires an argument\n",
- MNTOPT_LOGDEV);
+ this_char);
return EINVAL;
}
strncpy(args->logname, value, MAXNAMELEN);
} else if (!strcmp(this_char, MNTOPT_MTPT)) {
if (!value || !*value) {
printk("XFS: %s option requires an argument\n",
- MNTOPT_MTPT);
+ this_char);
return EINVAL;
}
strncpy(args->mtpt, value, MAXNAMELEN);
} else if (!strcmp(this_char, MNTOPT_RTDEV)) {
if (!value || !*value) {
printk("XFS: %s option requires an argument\n",
- MNTOPT_RTDEV);
+ this_char);
return EINVAL;
}
strncpy(args->rtname, value, MAXNAMELEN);
} else if (!strcmp(this_char, MNTOPT_BIOSIZE)) {
if (!value || !*value) {
printk("XFS: %s option requires an argument\n",
- MNTOPT_BIOSIZE);
+ this_char);
return EINVAL;
}
iosize = simple_strtoul(value, &eov, 10);
args->flags |= XFSMNT_IOSIZE;
args->iosizelog = (uint8_t) iosize;
+ } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) {
+ if (!value || !*value) {
+ printk("XFS: %s option requires an argument\n",
+ this_char);
+ return EINVAL;
+ }
+ iosize = suffix_strtoul(value, &eov, 10);
+ args->flags |= XFSMNT_IOSIZE;
+ args->iosizelog = ffs(iosize) - 1;
} else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) {
if (!value || !*value) {
printk("XFS: %s option requires an argument\n",
- this_char);
+ this_char);
return EINVAL;
}
args->flags |= XFSMNT_IHASHSIZE;
@@ -1756,7 +1779,7 @@
args->flags |= XFSMNT_INO64;
#if !XFS_BIG_INUMS
printk("XFS: %s option not allowed on this system\n",
- MNTOPT_INO64);
+ this_char);
return EINVAL;
#endif
} else if (!strcmp(this_char, MNTOPT_NOALIGN)) {
@@ -1766,14 +1789,14 @@
} else if (!strcmp(this_char, MNTOPT_SUNIT)) {
if (!value || !*value) {
printk("XFS: %s option requires an argument\n",
- MNTOPT_SUNIT);
+ this_char);
return EINVAL;
}
dsunit = simple_strtoul(value, &eov, 10);
} else if (!strcmp(this_char, MNTOPT_SWIDTH)) {
if (!value || !*value) {
printk("XFS: %s option requires an argument\n",
- MNTOPT_SWIDTH);
+ this_char);
return EINVAL;
}
dswidth = simple_strtoul(value, &eov, 10);
@@ -1781,7 +1804,7 @@
args->flags &= ~XFSMNT_32BITINODES;
#if !XFS_BIG_INUMS
printk("XFS: %s option not allowed on this system\n",
- MNTOPT_64BITINODE);
+ this_char);
return EINVAL;
#endif
} else if (!strcmp(this_char, MNTOPT_NOUUID)) {
@@ -1877,7 +1900,7 @@
seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", mp->m_ihsize);
if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
- seq_printf(m, "," MNTOPT_BIOSIZE "=%d", mp->m_writeio_log);
+ seq_printf(m, "," MNTOPT_ALLOCSIZE "=%d", 1<<mp->m_writeio_log);
if (mp->m_logbufs > 0)
seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs);
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 7009296..25a5266 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -305,7 +305,7 @@
int mandlock_before, mandlock_after;
struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2;
int file_owner;
- int need_iolock = (flags & ATTR_DMI) == 0;
+ int need_iolock = 1;
vp = BHV_TO_VNODE(bdp);
vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
@@ -384,6 +384,9 @@
*/
tp = NULL;
lock_flags = XFS_ILOCK_EXCL;
+ ASSERT(flags & ATTR_NOLOCK ? flags & ATTR_DMI : 1);
+ if (flags & ATTR_NOLOCK)
+ need_iolock = 0;
if (!(mask & XFS_AT_SIZE)) {
if ((mask != (XFS_AT_CTIME|XFS_AT_ATIME|XFS_AT_MTIME)) ||
(mp->m_flags & XFS_MOUNT_WSYNC)) {
@@ -4320,7 +4323,7 @@
int rt;
xfs_fileoff_t startoffset_fsb;
xfs_trans_t *tp;
- int need_iolock = (attr_flags & ATTR_DMI) == 0;
+ int need_iolock = 1;
vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address);
mp = ip->i_mount;
@@ -4348,8 +4351,12 @@
return(error);
}
+ ASSERT(attr_flags & ATTR_NOLOCK ? attr_flags & ATTR_DMI : 1);
+ if (attr_flags & ATTR_NOLOCK)
+ need_iolock = 0;
if (need_iolock)
xfs_ilock(ip, XFS_IOLOCK_EXCL);
+
rounding = MAX((__uint8_t)(1 << mp->m_sb.sb_blocklog),
(__uint8_t)NBPP);
ilen = len + (offset & (rounding - 1));
diff --git a/include/asm-arm/arch-imx/imxfb.h b/include/asm-arm/arch-imx/imxfb.h
new file mode 100644
index 0000000..2346d45
--- /dev/null
+++ b/include/asm-arm/arch-imx/imxfb.h
@@ -0,0 +1,35 @@
+/*
+ * This structure describes the machine which we are running on.
+ */
+struct imxfb_mach_info {
+ u_long pixclock;
+
+ u_short xres;
+ u_short yres;
+
+ u_char bpp;
+ u_char hsync_len;
+ u_char left_margin;
+ u_char right_margin;
+
+ u_char vsync_len;
+ u_char upper_margin;
+ u_char lower_margin;
+ u_char sync;
+
+ u_int cmap_greyscale:1,
+ cmap_inverse:1,
+ cmap_static:1,
+ unused:29;
+
+ u_int pcr;
+ u_int pwmr;
+ u_int lscr1;
+
+ u_char * fixed_screen_cpu;
+ dma_addr_t fixed_screen_dma;
+
+ void (*lcd_power)(int);
+ void (*backlight_power)(int);
+};
+void set_imx_fb_info(struct imxfb_mach_info *hard_imx_fb_info);
diff --git a/include/asm-arm/processor.h b/include/asm-arm/processor.h
index 4a98459..7d4118e 100644
--- a/include/asm-arm/processor.h
+++ b/include/asm-arm/processor.h
@@ -23,8 +23,6 @@
#include <asm/procinfo.h>
#include <asm/types.h>
-#define KERNEL_STACK_SIZE PAGE_SIZE
-
union debug_insn {
u32 arm;
u16 thumb;
@@ -87,8 +85,9 @@
*/
extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)->thread_info))[1019])
-#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)->thread_info))[1017])
+#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/include/asm-arm/thread_info.h b/include/asm-arm/thread_info.h
index a61618f..66c585c 100644
--- a/include/asm-arm/thread_info.h
+++ b/include/asm-arm/thread_info.h
@@ -14,6 +14,10 @@
#include <asm/fpstate.h>
+#define THREAD_SIZE_ORDER 1
+#define THREAD_SIZE 8192
+#define THREAD_START_SP (THREAD_SIZE - 8)
+
#ifndef __ASSEMBLY__
struct task_struct;
@@ -77,8 +81,6 @@
#define init_thread_info (init_thread_union.thread_info)
#define init_stack (init_thread_union.stack)
-#define THREAD_SIZE 8192
-
/*
* how to get the thread information struct from C
*/
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 5a5ddc4..09abb89 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -2,7 +2,7 @@
# Kernel configuration targets
# These targets are used from top-level makefile
-.PHONY: oldconfig xconfig gconfig menuconfig config silentoldconfig
+.PHONY: oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config
xconfig: $(obj)/qconf
$< arch/$(ARCH)/Kconfig
@@ -23,6 +23,13 @@
silentoldconfig: $(obj)/conf
$< -s arch/$(ARCH)/Kconfig
+update-po-config: $(obj)/kxgettext
+ xgettext --default-domain=linux \
+ --add-comments --keyword=_ --keyword=N_ \
+ --files-from=scripts/kconfig/POTFILES.in \
+ -o scripts/kconfig/linux.pot
+ scripts/kconfig/kxgettext arch/$(ARCH)/Kconfig >> scripts/kconfig/linux.pot
+
.PHONY: randconfig allyesconfig allnoconfig allmodconfig defconfig
randconfig: $(obj)/conf
@@ -72,9 +79,10 @@
# Based on GTK which needs to be installed to compile it
# object files used by all kconfig flavours
-hostprogs-y := conf mconf qconf gconf
+hostprogs-y := conf mconf qconf gconf kxgettext
conf-objs := conf.o zconf.tab.o
mconf-objs := mconf.o zconf.tab.o
+kxgettext-objs := kxgettext.o zconf.tab.o
ifeq ($(MAKECMDGOALS),xconfig)
qconf-target := 1
@@ -107,7 +115,7 @@
HOSTCFLAGS_gconf.o = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --cflags` \
-D LKC_DIRECT_LINK
-$(obj)/conf.o $(obj)/mconf.o $(obj)/qconf.o $(obj)/gconf.o: $(obj)/zconf.tab.h
+$(obj)/conf.o $(obj)/mconf.o $(obj)/qconf.o $(obj)/gconf.o $(obj)/kxgettext: $(obj)/zconf.tab.h
$(obj)/zconf.tab.h: $(src)/zconf.tab.h_shipped
$(obj)/zconf.tab.c: $(src)/zconf.tab.c_shipped
diff --git a/scripts/kconfig/POTFILES.in b/scripts/kconfig/POTFILES.in
new file mode 100644
index 0000000..cc94e46
--- /dev/null
+++ b/scripts/kconfig/POTFILES.in
@@ -0,0 +1,5 @@
+scripts/kconfig/mconf.c
+scripts/kconfig/conf.c
+scripts/kconfig/confdata.c
+scripts/kconfig/gconf.c
+scripts/kconfig/qconf.cc
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index a494d1a..70e7264 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -34,7 +34,7 @@
static signed char line[128];
static struct menu *rootEntry;
-static char nohelp_text[] = "Sorry, no help available for this option yet.\n";
+static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n");
static void strip(signed char *str)
{
@@ -56,9 +56,9 @@
static void check_stdin(void)
{
if (!valid_stdin && input_mode == ask_silent) {
- printf("aborted!\n\n");
- printf("Console input/output is redirected. ");
- printf("Run 'make oldconfig' to update configuration.\n\n");
+ printf(_("aborted!\n\n"));
+ printf(_("Console input/output is redirected. "));
+ printf(_("Run 'make oldconfig' to update configuration.\n\n"));
exit(1);
}
}
@@ -470,7 +470,7 @@
if (sym) {
if (sym_is_changable(sym) && !sym_has_value(sym)) {
if (!conf_cnt++)
- printf("*\n* Restart config...\n*\n");
+ printf(_("*\n* Restart config...\n*\n"));
rootEntry = menu_get_parent_menu(menu);
conf(rootEntry);
}
@@ -504,7 +504,7 @@
input_mode = set_default;
defconfig_file = av[i++];
if (!defconfig_file) {
- printf("%s: No default config file specified\n",
+ printf(_("%s: No default config file specified\n"),
av[0]);
exit(1);
}
@@ -530,7 +530,7 @@
}
name = av[i];
if (!name) {
- printf("%s: Kconfig file missing\n", av[0]);
+ printf(_("%s: Kconfig file missing\n"), av[0]);
}
conf_parse(name);
//zconfdump(stdout);
@@ -547,12 +547,12 @@
break;
case ask_silent:
if (stat(".config", &tmpstat)) {
- printf("***\n"
+ printf(_("***\n"
"*** You have not yet configured your kernel!\n"
"***\n"
"*** Please run some configurator (e.g. \"make oldconfig\" or\n"
"*** \"make menuconfig\" or \"make xconfig\").\n"
- "***\n");
+ "***\n"));
exit(1);
}
case ask_all:
@@ -576,7 +576,7 @@
check_conf(&rootmenu);
} while (conf_cnt);
if (conf_write(NULL)) {
- fprintf(stderr, "\n*** Error during writing of the kernel configuration.\n\n");
+ fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
return 1;
}
return 0;
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 1e82ae3..2755c45 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -88,9 +88,9 @@
name = conf_expand_value(name);
in = zconf_fopen(name);
if (in) {
- printf("#\n"
- "# using defaults found in %s\n"
- "#\n", name);
+ printf(_("#\n"
+ "# using defaults found in %s\n"
+ "#\n"), name);
break;
}
}
@@ -312,11 +312,11 @@
if (env && *env)
use_timestamp = 0;
- fprintf(out, "#\n"
- "# Automatically generated make config: don't edit\n"
- "# Linux kernel version: %s\n"
- "%s%s"
- "#\n",
+ fprintf(out, _("#\n"
+ "# Automatically generated make config: don't edit\n"
+ "# Linux kernel version: %s\n"
+ "%s%s"
+ "#\n"),
sym_get_string_value(sym),
use_timestamp ? "# " : "",
use_timestamp ? ctime(&now) : "");
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c
index 6fdbe6e..ad6b120 100644
--- a/scripts/kconfig/gconf.c
+++ b/scripts/kconfig/gconf.c
@@ -41,7 +41,7 @@
static gboolean config_changed = FALSE;
static char nohelp_text[] =
- "Sorry, no help available for this option yet.\n";
+ N_("Sorry, no help available for this option yet.\n");
GtkWidget *main_wnd = NULL;
GtkWidget *tree1_w = NULL; // left frame
@@ -193,7 +193,7 @@
xml = glade_xml_new(glade_file, "window1", NULL);
if (!xml)
- g_error("GUI loading failed !\n");
+ g_error(_("GUI loading failed !\n"));
glade_xml_signal_autoconnect(xml);
main_wnd = glade_xml_get_widget(xml, "window1");
@@ -275,7 +275,7 @@
/*"style", PANGO_STYLE_OBLIQUE, */
NULL);
- sprintf(title, "Linux Kernel v%s Configuration",
+ sprintf(title, _("Linux Kernel v%s Configuration"),
getenv("KERNELRELEASE"));
gtk_window_set_title(GTK_WINDOW(main_wnd), title);
@@ -325,7 +325,7 @@
column = gtk_tree_view_column_new();
gtk_tree_view_append_column(view, column);
- gtk_tree_view_column_set_title(column, "Options");
+ gtk_tree_view_column_set_title(column, _("Options"));
renderer = gtk_cell_renderer_toggle_new();
gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
@@ -370,7 +370,7 @@
column = gtk_tree_view_column_new();
gtk_tree_view_append_column(view, column);
- gtk_tree_view_column_set_title(column, "Options");
+ gtk_tree_view_column_set_title(column, _("Options"));
renderer = gtk_cell_renderer_pixbuf_new();
gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
@@ -401,7 +401,7 @@
renderer = gtk_cell_renderer_text_new();
gtk_tree_view_insert_column_with_attributes(view, -1,
- "Name", renderer,
+ _("Name"), renderer,
"text", COL_NAME,
"foreground-gdk",
COL_COLOR, NULL);
@@ -425,7 +425,7 @@
COL_COLOR, NULL);
renderer = gtk_cell_renderer_text_new();
gtk_tree_view_insert_column_with_attributes(view, -1,
- "Value", renderer,
+ _("Value"), renderer,
"text", COL_VALUE,
"editable",
COL_EDIT,
@@ -466,15 +466,15 @@
GtkTextIter start, end;
const char *prompt = menu_get_prompt(menu);
gchar *name;
- const char *help = nohelp_text;
+ const char *help = _(nohelp_text);
if (!menu->sym)
help = "";
else if (menu->sym->help)
- help = menu->sym->help;
+ help = _(menu->sym->help);
if (menu->sym && menu->sym->name)
- name = g_strdup_printf(menu->sym->name);
+ name = g_strdup_printf(_(menu->sym->name));
else
name = g_strdup("");
@@ -530,7 +530,7 @@
if (config_changed == FALSE)
return FALSE;
- dialog = gtk_dialog_new_with_buttons("Warning !",
+ dialog = gtk_dialog_new_with_buttons(_("Warning !"),
GTK_WINDOW(main_wnd),
(GtkDialogFlags)
(GTK_DIALOG_MODAL |
@@ -544,7 +544,7 @@
gtk_dialog_set_default_response(GTK_DIALOG(dialog),
GTK_RESPONSE_CANCEL);
- label = gtk_label_new("\nSave configuration ?\n");
+ label = gtk_label_new(_("\nSave configuration ?\n"));
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
gtk_widget_show(label);
@@ -604,7 +604,7 @@
(user_data));
if (conf_read(fn))
- text_insert_msg("Error", "Unable to load configuration !");
+ text_insert_msg(_("Error"), _("Unable to load configuration !"));
else
display_tree(&rootmenu);
}
@@ -613,7 +613,7 @@
{
GtkWidget *fs;
- fs = gtk_file_selection_new("Load file...");
+ fs = gtk_file_selection_new(_("Load file..."));
g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
"clicked",
G_CALLBACK(load_filename), (gpointer) fs);
@@ -632,7 +632,7 @@
void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data)
{
if (conf_write(NULL))
- text_insert_msg("Error", "Unable to save configuration !");
+ text_insert_msg(_("Error"), _("Unable to save configuration !"));
config_changed = FALSE;
}
@@ -647,7 +647,7 @@
(user_data));
if (conf_write(fn))
- text_insert_msg("Error", "Unable to save configuration !");
+ text_insert_msg(_("Error"), _("Unable to save configuration !"));
gtk_widget_destroy(GTK_WIDGET(user_data));
}
@@ -656,7 +656,7 @@
{
GtkWidget *fs;
- fs = gtk_file_selection_new("Save file as...");
+ fs = gtk_file_selection_new(_("Save file as..."));
g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
"clicked",
G_CALLBACK(store_filename), (gpointer) fs);
@@ -740,7 +740,7 @@
void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
{
GtkWidget *dialog;
- const gchar *intro_text =
+ const gchar *intro_text = _(
"Welcome to gkc, the GTK+ graphical kernel configuration tool\n"
"for Linux.\n"
"For each option, a blank box indicates the feature is disabled, a\n"
@@ -756,7 +756,7 @@
"option.\n"
"\n"
"Toggling Show Debug Info under the Options menu will show \n"
- "the dependencies, which you can then match by examining other options.";
+ "the dependencies, which you can then match by examining other options.");
dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -773,8 +773,8 @@
{
GtkWidget *dialog;
const gchar *about_text =
- "gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n"
- "Based on the source code from Roman Zippel.\n";
+ _("gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n"
+ "Based on the source code from Roman Zippel.\n");
dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -791,9 +791,9 @@
{
GtkWidget *dialog;
const gchar *license_text =
- "gkc is released under the terms of the GNU GPL v2.\n"
- "For more information, please see the source code or\n"
- "visit http://www.fsf.org/licenses/licenses.html\n";
+ _("gkc is released under the terms of the GNU GPL v2.\n"
+ "For more information, please see the source code or\n"
+ "visit http://www.fsf.org/licenses/licenses.html\n");
dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -1579,6 +1579,10 @@
kconfig_load();
#endif
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ bind_textdomain_codeset(PACKAGE, "UTF-8");
+ textdomain(PACKAGE);
+
/* GTK stuffs */
gtk_set_locale();
gtk_init(&ac, &av);
diff --git a/scripts/kconfig/kxgettext.c b/scripts/kconfig/kxgettext.c
new file mode 100644
index 0000000..1c88d7c
--- /dev/null
+++ b/scripts/kconfig/kxgettext.c
@@ -0,0 +1,221 @@
+/*
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2005
+ *
+ * Released under the terms of the GNU GPL v2.0
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+static char *escape(const char* text, char *bf, int len)
+{
+ char *bfp = bf;
+ int multiline = strchr(text, '\n') != NULL;
+
+ *bfp++ = '"';
+ --len;
+
+ if (multiline) {
+ *bfp++ = '"';
+ *bfp++ = '\n';
+ *bfp++ = '"';
+ len -= 3;
+ }
+
+ while (*text != '\0' && len > 1) {
+ if (*text == '"')
+ *bfp++ = '\\';
+ else if (*text == '\n') {
+ *bfp++ = '\\';
+ *bfp++ = 'n';
+ *bfp++ = '"';
+ *bfp++ = '\n';
+ *bfp++ = '"';
+ len -= 5;
+ ++text;
+ goto next;
+ }
+ *bfp++ = *text++;
+next:
+ --len;
+ }
+
+ if (multiline)
+ bfp -= 3;
+
+ *bfp++ = '"';
+ *bfp = '\0';
+
+ return bf;
+}
+
+struct file_line {
+ struct file_line *next;
+ char* file;
+ int lineno;
+};
+
+static struct file_line *file_line__new(char *file, int lineno)
+{
+ struct file_line *self = malloc(sizeof(*self));
+
+ if (self == NULL)
+ goto out;
+
+ self->file = file;
+ self->lineno = lineno;
+ self->next = NULL;
+out:
+ return self;
+}
+
+struct message {
+ const char *msg;
+ const char *option;
+ struct message *next;
+ struct file_line *files;
+};
+
+static struct message *message__list;
+
+static struct message *message__new(const char *msg, char *option, char *file, int lineno)
+{
+ struct message *self = malloc(sizeof(*self));
+
+ if (self == NULL)
+ goto out;
+
+ self->files = file_line__new(file, lineno);
+ if (self->files == NULL)
+ goto out_fail;
+
+ self->msg = strdup(msg);
+ if (self->msg == NULL)
+ goto out_fail_msg;
+
+ self->option = option;
+ self->next = NULL;
+out:
+ return self;
+out_fail_msg:
+ free(self->files);
+out_fail:
+ free(self);
+ self = NULL;
+ goto out;
+}
+
+static struct message *mesage__find(const char *msg)
+{
+ struct message *m = message__list;
+
+ while (m != NULL) {
+ if (strcmp(m->msg, msg) == 0)
+ break;
+ m = m->next;
+ }
+
+ return m;
+}
+
+static int message__add_file_line(struct message *self, char *file, int lineno)
+{
+ int rc = -1;
+ struct file_line *fl = file_line__new(file, lineno);
+
+ if (fl == NULL)
+ goto out;
+
+ fl->next = self->files;
+ self->files = fl;
+ rc = 0;
+out:
+ return rc;
+}
+
+static int message__add(const char *msg, char *option, char *file, int lineno)
+{
+ int rc = 0;
+ char bf[16384];
+ char *escaped = escape(msg, bf, sizeof(bf));
+ struct message *m = mesage__find(escaped);
+
+ if (m != NULL)
+ rc = message__add_file_line(m, file, lineno);
+ else {
+ m = message__new(escaped, option, file, lineno);
+
+ if (m != NULL) {
+ m->next = message__list;
+ message__list = m;
+ } else
+ rc = -1;
+ }
+ return rc;
+}
+
+void menu_build_message_list(struct menu *menu)
+{
+ struct menu *child;
+
+ message__add(menu_get_prompt(menu), NULL,
+ menu->file == NULL ? "Root Menu" : menu->file->name,
+ menu->lineno);
+
+ if (menu->sym != NULL && menu->sym->help != NULL)
+ message__add(menu->sym->help, menu->sym->name,
+ menu->file == NULL ? "Root Menu" : menu->file->name,
+ menu->lineno);
+
+ for (child = menu->list; child != NULL; child = child->next)
+ if (child->prompt != NULL)
+ menu_build_message_list(child);
+}
+
+static void message__print_file_lineno(struct message *self)
+{
+ struct file_line *fl = self->files;
+
+ printf("\n#: %s:%d", fl->file, fl->lineno);
+ fl = fl->next;
+
+ while (fl != NULL) {
+ printf(", %s:%d", fl->file, fl->lineno);
+ fl = fl->next;
+ }
+
+ if (self->option != NULL)
+ printf(", %s:00000", self->option);
+
+ putchar('\n');
+}
+
+static void message__print_gettext_msgid_msgstr(struct message *self)
+{
+ message__print_file_lineno(self);
+
+ printf("msgid %s\n"
+ "msgstr \"\"\n", self->msg);
+}
+
+void menu__xgettext(void)
+{
+ struct message *m = message__list;
+
+ while (m != NULL) {
+ message__print_gettext_msgid_msgstr(m);
+ m = m->next;
+ }
+}
+
+int main(int ac, char **av)
+{
+ conf_parse(av[1]);
+
+ menu_build_message_list(menu_get_root_menu(NULL));
+ menu__xgettext();
+ return 0;
+}
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index b8a67fc..8b84c42 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -8,6 +8,8 @@
#include "expr.h"
+#include <libintl.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -23,6 +25,12 @@
#define SRCTREE "srctree"
+#define PACKAGE "linux"
+#define LOCALEDIR "/usr/share/locale"
+
+#define _(text) gettext(text)
+#define N_(text) (text)
+
int zconfparse(void);
void zconfdump(FILE *out);
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 730d316..e5db10c 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -4,6 +4,8 @@
*
* Introduced single menu mode (show all sub-menus in one large tree).
* 2002-11-06 Petr Baudis <pasky@ucw.cz>
+ *
+ * i18n, 2005, Arnaldo Carvalho de Melo <acme@conectiva.com.br>
*/
#include <sys/ioctl.h>
@@ -23,7 +25,7 @@
#include "lkc.h"
static char menu_backtitle[128];
-static const char mconf_readme[] =
+static const char mconf_readme[] = N_(
"Overview\n"
"--------\n"
"Some kernel features may be built directly into the kernel.\n"
@@ -156,39 +158,39 @@
"\n"
"Note that this mode can eventually be a little more CPU expensive\n"
"(especially with a larger number of unrolled categories) than the\n"
-"default mode.\n",
-menu_instructions[] =
+"default mode.\n"),
+menu_instructions[] = N_(
"Arrow keys navigate the menu. "
"<Enter> selects submenus --->. "
"Highlighted letters are hotkeys. "
"Pressing <Y> includes, <N> excludes, <M> modularizes features. "
"Press <Esc><Esc> to exit, <?> for Help, </> for Search. "
- "Legend: [*] built-in [ ] excluded <M> module < > module capable",
-radiolist_instructions[] =
+ "Legend: [*] built-in [ ] excluded <M> module < > module capable"),
+radiolist_instructions[] = N_(
"Use the arrow keys to navigate this window or "
"press the hotkey of the item you wish to select "
"followed by the <SPACE BAR>. "
- "Press <?> for additional information about this option.",
-inputbox_instructions_int[] =
+ "Press <?> for additional information about this option."),
+inputbox_instructions_int[] = N_(
"Please enter a decimal value. "
"Fractions will not be accepted. "
- "Use the <TAB> key to move from the input field to the buttons below it.",
-inputbox_instructions_hex[] =
+ "Use the <TAB> key to move from the input field to the buttons below it."),
+inputbox_instructions_hex[] = N_(
"Please enter a hexadecimal value. "
- "Use the <TAB> key to move from the input field to the buttons below it.",
-inputbox_instructions_string[] =
+ "Use the <TAB> key to move from the input field to the buttons below it."),
+inputbox_instructions_string[] = N_(
"Please enter a string value. "
- "Use the <TAB> key to move from the input field to the buttons below it.",
-setmod_text[] =
+ "Use the <TAB> key to move from the input field to the buttons below it."),
+setmod_text[] = N_(
"This feature depends on another which has been configured as a module.\n"
- "As a result, this feature will be built as a module.",
-nohelp_text[] =
- "There is no help available for this kernel option.\n",
-load_config_text[] =
+ "As a result, this feature will be built as a module."),
+nohelp_text[] = N_(
+ "There is no help available for this kernel option.\n"),
+load_config_text[] = N_(
"Enter the name of the configuration file you wish to load. "
"Accept the name shown to restore the configuration you "
- "last retrieved. Leave blank to abort.",
-load_config_help[] =
+ "last retrieved. Leave blank to abort."),
+load_config_help[] = N_(
"\n"
"For various reasons, one may wish to keep several different kernel\n"
"configurations available on a single machine.\n"
@@ -198,11 +200,11 @@
"to modify that configuration.\n"
"\n"
"If you are uncertain, then you have probably never used alternate\n"
- "configuration files. You should therefor leave this blank to abort.\n",
-save_config_text[] =
+ "configuration files. You should therefor leave this blank to abort.\n"),
+save_config_text[] = N_(
"Enter a filename to which this configuration should be saved "
- "as an alternate. Leave blank to abort.",
-save_config_help[] =
+ "as an alternate. Leave blank to abort."),
+save_config_help[] = N_(
"\n"
"For various reasons, one may wish to keep different kernel\n"
"configurations available on a single machine.\n"
@@ -212,8 +214,8 @@
"configuration options you have selected at that time.\n"
"\n"
"If you are uncertain what all this means then you should probably\n"
- "leave this blank.\n",
-search_help[] =
+ "leave this blank.\n"),
+search_help[] = N_(
"\n"
"Search for CONFIG_ symbols and display their relations.\n"
"Example: search for \"^FOO\"\n"
@@ -250,7 +252,7 @@
"Examples: USB => find all CONFIG_ symbols containing USB\n"
" ^USB => find all CONFIG_ symbols starting with USB\n"
" USB$ => find all CONFIG_ symbols ending with USB\n"
- "\n";
+ "\n");
static signed char buf[4096], *bufptr = buf;
static signed char input_buf[4096];
@@ -305,8 +307,8 @@
}
if (rows < 19 || cols < 80) {
- fprintf(stderr, "Your display is too small to run Menuconfig!\n");
- fprintf(stderr, "It must be at least 19 lines by 80 columns.\n");
+ fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));
+ fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n"));
exit(1);
}
@@ -526,9 +528,9 @@
again:
cprint_init();
cprint("--title");
- cprint("Search Configuration Parameter");
+ cprint(_("Search Configuration Parameter"));
cprint("--inputbox");
- cprint("Enter Keyword");
+ cprint(_("Enter Keyword"));
cprint("10");
cprint("75");
cprint("");
@@ -539,7 +541,7 @@
case 0:
break;
case 1:
- show_helptext("Search Configuration", search_help);
+ show_helptext(_("Search Configuration"), search_help);
goto again;
default:
return;
@@ -548,7 +550,7 @@
sym_arr = sym_re_search(input_buf);
res = get_relations_str(sym_arr);
free(sym_arr);
- show_textbox("Search Results", str_get(&res), 0, 0);
+ show_textbox(_("Search Results"), str_get(&res), 0, 0);
str_free(&res);
}
@@ -721,9 +723,9 @@
while (1) {
cprint_init();
cprint("--title");
- cprint("%s", prompt ? prompt : "Main Menu");
+ cprint("%s", prompt ? prompt : _("Main Menu"));
cprint("--menu");
- cprint(menu_instructions);
+ cprint(_(menu_instructions));
cprint("%d", rows);
cprint("%d", cols);
cprint("%d", rows - 10);
@@ -736,9 +738,9 @@
cprint(":");
cprint("--- ");
cprint("L");
- cprint(" Load an Alternate Configuration File");
+ cprint(_(" Load an Alternate Configuration File"));
cprint("S");
- cprint(" Save Configuration to an Alternate File");
+ cprint(_(" Save Configuration to an Alternate File"));
}
stat = exec_conf();
if (stat < 0)
@@ -793,7 +795,7 @@
if (sym)
show_help(submenu);
else
- show_helptext("README", mconf_readme);
+ show_helptext("README", _(mconf_readme));
break;
case 3:
if (type == 't') {
@@ -849,7 +851,7 @@
{
if (sym->name) {
str_printf(&help, "CONFIG_%s:\n\n", sym->name);
- str_append(&help, sym->help);
+ str_append(&help, _(sym->help));
str_append(&help, "\n");
}
} else {
@@ -886,9 +888,9 @@
while (1) {
cprint_init();
cprint("--title");
- cprint("%s", prompt ? prompt : "Main Menu");
+ cprint("%s", prompt ? prompt : _("Main Menu"));
cprint("--radiolist");
- cprint(radiolist_instructions);
+ cprint(_(radiolist_instructions));
cprint("15");
cprint("70");
cprint("6");
@@ -935,17 +937,17 @@
while (1) {
cprint_init();
cprint("--title");
- cprint("%s", prompt ? prompt : "Main Menu");
+ cprint("%s", prompt ? prompt : _("Main Menu"));
cprint("--inputbox");
switch (sym_get_type(menu->sym)) {
case S_INT:
- cprint(inputbox_instructions_int);
+ cprint(_(inputbox_instructions_int));
break;
case S_HEX:
- cprint(inputbox_instructions_hex);
+ cprint(_(inputbox_instructions_hex));
break;
case S_STRING:
- cprint(inputbox_instructions_string);
+ cprint(_(inputbox_instructions_string));
break;
default:
/* panic? */;
@@ -958,7 +960,7 @@
case 0:
if (sym_set_string_value(menu->sym, input_buf))
return;
- show_textbox(NULL, "You have made an invalid entry.", 5, 43);
+ show_textbox(NULL, _("You have made an invalid entry."), 5, 43);
break;
case 1:
show_help(menu);
@@ -987,10 +989,10 @@
return;
if (!conf_read(input_buf))
return;
- show_textbox(NULL, "File does not exist!", 5, 38);
+ show_textbox(NULL, _("File does not exist!"), 5, 38);
break;
case 1:
- show_helptext("Load Alternate Configuration", load_config_help);
+ show_helptext(_("Load Alternate Configuration"), load_config_help);
break;
case 255:
return;
@@ -1016,10 +1018,10 @@
return;
if (!conf_write(input_buf))
return;
- show_textbox(NULL, "Can't create file! Probably a nonexistent directory.", 5, 60);
+ show_textbox(NULL, _("Can't create file! Probably a nonexistent directory."), 5, 60);
break;
case 1:
- show_helptext("Save Alternate Configuration", save_config_help);
+ show_helptext(_("Save Alternate Configuration"), save_config_help);
break;
case 255:
return;
@@ -1040,12 +1042,16 @@
char *mode;
int stat;
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
conf_parse(av[1]);
conf_read(NULL);
sym = sym_lookup("KERNELRELEASE", 0);
sym_calc_value(sym);
- sprintf(menu_backtitle, "Linux Kernel v%s Configuration",
+ sprintf(menu_backtitle, _("Linux Kernel v%s Configuration"),
sym_get_string_value(sym));
mode = getenv("MENUCONFIG_MODE");
@@ -1062,7 +1068,7 @@
do {
cprint_init();
cprint("--yesno");
- cprint("Do you wish to save your new kernel configuration?");
+ cprint(_("Do you wish to save your new kernel configuration?"));
cprint("5");
cprint("60");
stat = exec_conf();
@@ -1070,20 +1076,20 @@
if (stat == 0) {
if (conf_write(NULL)) {
- fprintf(stderr, "\n\n"
+ fprintf(stderr, _("\n\n"
"Error during writing of the kernel configuration.\n"
"Your kernel configuration changes were NOT saved."
- "\n\n");
+ "\n\n"));
return 1;
}
- printf("\n\n"
+ printf(_("\n\n"
"*** End of Linux kernel configuration.\n"
"*** Execute 'make' to build the kernel or try 'make help'."
- "\n\n");
+ "\n\n"));
} else {
- fprintf(stderr, "\n\n"
+ fprintf(stderr, _("\n\n"
"Your kernel configuration changes were NOT saved."
- "\n\n");
+ "\n\n"));
}
return 0;
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 0c13156..8c59b21 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -365,9 +365,9 @@
const char *menu_get_prompt(struct menu *menu)
{
if (menu->prompt)
- return menu->prompt->text;
+ return _(menu->prompt->text);
else if (menu->sym)
- return menu->sym->name;
+ return _(menu->sym->name);
return NULL;
}
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index 0cdbf9d..4590cd3 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -26,8 +26,23 @@
#include "qconf.moc"
#include "images.c"
+#ifdef _
+# undef _
+# define _ qgettext
+#endif
+
static QApplication *configApp;
+static inline QString qgettext(const char* str)
+{
+ return QString::fromLocal8Bit(gettext(str));
+}
+
+static inline QString qgettext(const QString& str)
+{
+ return QString::fromLocal8Bit(gettext(str.latin1()));
+}
+
ConfigSettings::ConfigSettings()
: showAll(false), showName(false), showRange(false), showData(false)
{
@@ -177,7 +192,7 @@
sym = menu->sym;
prop = menu->prompt;
- prompt = menu_get_prompt(menu);
+ prompt = QString::fromLocal8Bit(menu_get_prompt(menu));
if (prop) switch (prop->type) {
case P_MENU:
@@ -203,7 +218,7 @@
if (!sym)
goto set_prompt;
- setText(nameColIdx, sym->name);
+ setText(nameColIdx, QString::fromLocal8Bit(sym->name));
type = sym_get_type(sym);
switch (type) {
@@ -213,9 +228,9 @@
if (!sym_is_changable(sym) && !list->showAll) {
setPixmap(promptColIdx, 0);
- setText(noColIdx, 0);
- setText(modColIdx, 0);
- setText(yesColIdx, 0);
+ setText(noColIdx, QString::null);
+ setText(modColIdx, QString::null);
+ setText(yesColIdx, QString::null);
break;
}
expr = sym_get_tristate_value(sym);
@@ -257,6 +272,7 @@
const char* data;
data = sym_get_string_value(sym);
+
#if QT_VERSION >= 300
int i = list->mapIdx(dataColIdx);
if (i >= 0)
@@ -264,9 +280,9 @@
#endif
setText(dataColIdx, data);
if (type == S_STRING)
- prompt.sprintf("%s: %s", prompt.latin1(), data);
+ prompt = QString("%1: %2").arg(prompt).arg(data);
else
- prompt.sprintf("(%s) %s", data, prompt.latin1());
+ prompt = QString("(%2) %1").arg(prompt).arg(data);
break;
}
if (!sym_has_value(sym) && visible)
@@ -343,9 +359,9 @@
{
item = i;
if (sym_get_string_value(item->menu->sym))
- setText(sym_get_string_value(item->menu->sym));
+ setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
else
- setText(0);
+ setText(QString::null);
Parent::show();
setFocus();
}
@@ -961,7 +977,7 @@
delete configSettings;
}
-static QString print_filter(const char *str)
+static QString print_filter(const QString &str)
{
QRegExp re("[<>&\"\\n]");
QString res = str;
@@ -994,7 +1010,7 @@
static void expr_print_help(void *data, const char *str)
{
- ((QString*)data)->append(print_filter(str));
+ reinterpret_cast<QString*>(data)->append(print_filter(str));
}
/*
@@ -1009,7 +1025,7 @@
if (item)
menu = ((ConfigItem*)item)->menu;
if (!menu) {
- helpText->setText(NULL);
+ helpText->setText(QString::null);
return;
}
@@ -1019,16 +1035,16 @@
if (sym) {
if (menu->prompt) {
head += "<big><b>";
- head += print_filter(menu->prompt->text);
+ head += print_filter(_(menu->prompt->text));
head += "</b></big>";
if (sym->name) {
head += " (";
- head += print_filter(sym->name);
+ head += print_filter(_(sym->name));
head += ")";
}
} else if (sym->name) {
head += "<big><b>";
- head += print_filter(sym->name);
+ head += print_filter(_(sym->name));
head += "</b></big>";
}
head += "<br><br>";
@@ -1049,7 +1065,7 @@
case P_PROMPT:
case P_MENU:
debug += "prompt: ";
- debug += print_filter(prop->text);
+ debug += print_filter(_(prop->text));
debug += "<br>";
break;
case P_DEFAULT:
@@ -1088,10 +1104,10 @@
debug += "<br>";
}
- help = print_filter(sym->help);
+ help = print_filter(_(sym->help));
} else if (menu->prompt) {
head += "<big><b>";
- head += print_filter(menu->prompt->text);
+ head += print_filter(_(menu->prompt->text));
head += "</b></big><br><br>";
if (showDebug) {
if (menu->prompt->visible.expr) {
@@ -1111,7 +1127,7 @@
QString s = QFileDialog::getOpenFileName(".config", NULL, this);
if (s.isNull())
return;
- if (conf_read(s.latin1()))
+ if (conf_read(QFile::encodeName(s)))
QMessageBox::information(this, "qconf", "Unable to load configuration!");
ConfigView::updateListAll();
}
@@ -1127,7 +1143,7 @@
QString s = QFileDialog::getSaveFileName(".config", NULL, this);
if (s.isNull())
return;
- if (conf_write(s.latin1()))
+ if (conf_write(QFile::encodeName(s)))
QMessageBox::information(this, "qconf", "Unable to save configuration!");
}
@@ -1372,6 +1388,9 @@
ConfigMainWindow* v;
const char *name;
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
#ifndef LKC_DIRECT_LINK
kconfig_load();
#endif