aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/i386/kernel/ptrace.c19
-rw-r--r--arch/ia64/kernel/ptrace.c21
-rw-r--r--arch/mips/kernel/ptrace.c38
-rw-r--r--arch/ppc64/kernel/ptrace.c15
-rw-r--r--arch/s390/kernel/ptrace.c21
-rw-r--r--arch/um/kernel/ptrace.c21
-rw-r--r--arch/x86_64/kernel/ptrace.c21
-rw-r--r--drivers/base/bus.c5
-rw-r--r--drivers/base/core.c2
-rw-r--r--fs/namei.c20
-rw-r--r--fs/proc/base.c2
-rw-r--r--fs/xfs/Makefile2
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c81
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c11
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c43
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c3
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.c5
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h10
-rw-r--r--fs/xfs/xfs_dfrag.c2
-rw-r--r--fs/xfs/xfs_iget.c51
-rw-r--r--fs/xfs/xfs_inode.c2
-rw-r--r--fs/xfs/xfs_inode.h6
-rw-r--r--fs/xfs/xfs_iomap.c26
-rw-r--r--fs/xfs/xfs_iomap.h25
-rw-r--r--fs/xfs/xfs_mount.c9
-rw-r--r--fs/xfs/xfs_mount.h19
-rw-r--r--fs/xfs/xfs_types.h1
-rw-r--r--fs/xfs/xfs_utils.c2
-rw-r--r--fs/xfs/xfs_utils.h2
-rw-r--r--fs/xfs/xfs_vfsops.c67
-rw-r--r--fs/xfs/xfs_vnodeops.c11
-rw-r--r--include/asm-um/ptrace-i386.h2
-rw-r--r--include/asm-um/ptrace-x86_64.h2
-rw-r--r--include/asm-um/thread_info.h4
-rw-r--r--include/linux/audit.h64
-rw-r--r--include/linux/netlink.h1
-rw-r--r--init/Kconfig2
-rw-r--r--kernel/audit.c93
-rw-r--r--kernel/auditsc.c47
-rw-r--r--net/netlink/af_netlink.c3
-rw-r--r--scripts/kconfig/Makefile14
-rw-r--r--scripts/kconfig/POTFILES.in5
-rw-r--r--scripts/kconfig/conf.c20
-rw-r--r--scripts/kconfig/confdata.c16
-rw-r--r--scripts/kconfig/gconf.c52
-rw-r--r--scripts/kconfig/kxgettext.c221
-rw-r--r--scripts/kconfig/lkc.h8
-rw-r--r--scripts/kconfig/mconf.c120
-rw-r--r--scripts/kconfig/menu.c4
-rw-r--r--scripts/kconfig/qconf.cc59
50 files changed, 931 insertions, 369 deletions
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index e8c965ce86eb..e34f651fa13c 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -683,24 +683,18 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit)
683 /* do the secure computing check first */ 683 /* do the secure computing check first */
684 secure_computing(regs->orig_eax); 684 secure_computing(regs->orig_eax);
685 685
686 if (unlikely(current->audit_context)) { 686 if (unlikely(current->audit_context) && entryexit)
687 if (!entryexit) 687 audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax);
688 audit_syscall_entry(current, regs->orig_eax,
689 regs->ebx, regs->ecx,
690 regs->edx, regs->esi);
691 else
692 audit_syscall_exit(current, regs->eax);
693 }
694 688
695 if (!(current->ptrace & PT_PTRACED)) 689 if (!(current->ptrace & PT_PTRACED))
696 return; 690 goto out;
697 691
698 /* Fake a debug trap */ 692 /* Fake a debug trap */
699 if (test_thread_flag(TIF_SINGLESTEP)) 693 if (test_thread_flag(TIF_SINGLESTEP))
700 send_sigtrap(current, regs, 0); 694 send_sigtrap(current, regs, 0);
701 695
702 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 696 if (!test_thread_flag(TIF_SYSCALL_TRACE))
703 return; 697 goto out;
704 698
705 /* the 0x80 provides a way for the tracing parent to distinguish 699 /* the 0x80 provides a way for the tracing parent to distinguish
706 between a syscall stop and SIGTRAP delivery */ 700 between a syscall stop and SIGTRAP delivery */
@@ -715,4 +709,9 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit)
715 send_sig(current->exit_code, current, 1); 709 send_sig(current->exit_code, current, 1);
716 current->exit_code = 0; 710 current->exit_code = 0;
717 } 711 }
712 out:
713 if (unlikely(current->audit_context) && !entryexit)
714 audit_syscall_entry(current, AUDIT_ARCH_I386, regs->orig_eax,
715 regs->ebx, regs->ecx, regs->edx, regs->esi);
716
718} 717}
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index c253fd5914fc..907464ee7273 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -1596,20 +1596,25 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3,
1596 long arg4, long arg5, long arg6, long arg7, 1596 long arg4, long arg5, long arg6, long arg7,
1597 struct pt_regs regs) 1597 struct pt_regs regs)
1598{ 1598{
1599 long syscall; 1599 if (test_thread_flag(TIF_SYSCALL_TRACE)
1600 && (current->ptrace & PT_PTRACED))
1601 syscall_trace();
1600 1602
1601 if (unlikely(current->audit_context)) { 1603 if (unlikely(current->audit_context)) {
1602 if (IS_IA32_PROCESS(&regs)) 1604 long syscall;
1605 int arch;
1606
1607 if (IS_IA32_PROCESS(&regs)) {
1603 syscall = regs.r1; 1608 syscall = regs.r1;
1604 else 1609 arch = AUDIT_ARCH_I386;
1610 } else {
1605 syscall = regs.r15; 1611 syscall = regs.r15;
1612 arch = AUDIT_ARCH_IA64;
1613 }
1606 1614
1607 audit_syscall_entry(current, syscall, arg0, arg1, arg2, arg3); 1615 audit_syscall_entry(current, arch, syscall, arg0, arg1, arg2, arg3);
1608 } 1616 }
1609 1617
1610 if (test_thread_flag(TIF_SYSCALL_TRACE)
1611 && (current->ptrace & PT_PTRACED))
1612 syscall_trace();
1613} 1618}
1614 1619
1615/* "asmlinkage" so the input arguments are preserved... */ 1620/* "asmlinkage" so the input arguments are preserved... */
@@ -1620,7 +1625,7 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
1620 struct pt_regs regs) 1625 struct pt_regs regs)
1621{ 1626{
1622 if (unlikely(current->audit_context)) 1627 if (unlikely(current->audit_context))
1623 audit_syscall_exit(current, regs.r8); 1628 audit_syscall_exit(current, AUDITSC_RESULT(regs.r10), regs.r8);
1624 1629
1625 if (test_thread_flag(TIF_SYSCALL_TRACE) 1630 if (test_thread_flag(TIF_SYSCALL_TRACE)
1626 && (current->ptrace & PT_PTRACED)) 1631 && (current->ptrace & PT_PTRACED))
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index a2f899c2f4d4..92e70ca3bff9 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -301,25 +301,38 @@ out:
301 return ret; 301 return ret;
302} 302}
303 303
304static inline int audit_arch(void)
305{
306#ifdef CONFIG_CPU_LITTLE_ENDIAN
307#ifdef CONFIG_MIPS64
308 if (!(current->thread.mflags & MF_32BIT_REGS))
309 return AUDIT_ARCH_MIPSEL64;
310#endif /* MIPS64 */
311 return AUDIT_ARCH_MIPSEL;
312
313#else /* big endian... */
314#ifdef CONFIG_MIPS64
315 if (!(current->thread.mflags & MF_32BIT_REGS))
316 return AUDIT_ARCH_MIPS64;
317#endif /* MIPS64 */
318 return AUDIT_ARCH_MIPS;
319
320#endif /* endian */
321}
322
304/* 323/*
305 * Notification of system call entry/exit 324 * Notification of system call entry/exit
306 * - triggered by current->work.syscall_trace 325 * - triggered by current->work.syscall_trace
307 */ 326 */
308asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) 327asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
309{ 328{
310 if (unlikely(current->audit_context)) { 329 if (unlikely(current->audit_context) && entryexit)
311 if (!entryexit) 330 audit_syscall_exit(current, AUDITSC_RESULT(regs->regs[2]), regs->regs[2]);
312 audit_syscall_entry(current, regs->regs[2],
313 regs->regs[4], regs->regs[5],
314 regs->regs[6], regs->regs[7]);
315 else
316 audit_syscall_exit(current, regs->regs[2]);
317 }
318 331
319 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 332 if (!test_thread_flag(TIF_SYSCALL_TRACE))
320 return; 333 goto out;
321 if (!(current->ptrace & PT_PTRACED)) 334 if (!(current->ptrace & PT_PTRACED))
322 return; 335 goto out;
323 336
324 /* The 0x80 provides a way for the tracing parent to distinguish 337 /* The 0x80 provides a way for the tracing parent to distinguish
325 between a syscall stop and SIGTRAP delivery */ 338 between a syscall stop and SIGTRAP delivery */
@@ -335,4 +348,9 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
335 send_sig(current->exit_code, current, 1); 348 send_sig(current->exit_code, current, 1);
336 current->exit_code = 0; 349 current->exit_code = 0;
337 } 350 }
351 out:
352 if (unlikely(current->audit_context) && !entryexit)
353 audit_syscall_entry(current, audit_arch(), regs->regs[2],
354 regs->regs[4], regs->regs[5],
355 regs->regs[6], regs->regs[7]);
338} 356}
diff --git a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c
index 5a846324ca8c..9f8c6087ae56 100644
--- a/arch/ppc64/kernel/ptrace.c
+++ b/arch/ppc64/kernel/ptrace.c
@@ -305,14 +305,17 @@ static void do_syscall_trace(void)
305 305
306void do_syscall_trace_enter(struct pt_regs *regs) 306void do_syscall_trace_enter(struct pt_regs *regs)
307{ 307{
308 if (test_thread_flag(TIF_SYSCALL_TRACE)
309 && (current->ptrace & PT_PTRACED))
310 do_syscall_trace();
311
308 if (unlikely(current->audit_context)) 312 if (unlikely(current->audit_context))
309 audit_syscall_entry(current, regs->gpr[0], 313 audit_syscall_entry(current,
314 test_thread_flag(TIF_32BIT)?AUDIT_ARCH_PPC:AUDIT_ARCH_PPC64,
315 regs->gpr[0],
310 regs->gpr[3], regs->gpr[4], 316 regs->gpr[3], regs->gpr[4],
311 regs->gpr[5], regs->gpr[6]); 317 regs->gpr[5], regs->gpr[6]);
312 318
313 if (test_thread_flag(TIF_SYSCALL_TRACE)
314 && (current->ptrace & PT_PTRACED))
315 do_syscall_trace();
316} 319}
317 320
318void do_syscall_trace_leave(struct pt_regs *regs) 321void do_syscall_trace_leave(struct pt_regs *regs)
@@ -320,7 +323,9 @@ void do_syscall_trace_leave(struct pt_regs *regs)
320 secure_computing(regs->gpr[0]); 323 secure_computing(regs->gpr[0]);
321 324
322 if (unlikely(current->audit_context)) 325 if (unlikely(current->audit_context))
323 audit_syscall_exit(current, regs->result); 326 audit_syscall_exit(current,
327 (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
328 regs->result);
324 329
325 if ((test_thread_flag(TIF_SYSCALL_TRACE) 330 if ((test_thread_flag(TIF_SYSCALL_TRACE)
326 || test_thread_flag(TIF_SINGLESTEP)) 331 || test_thread_flag(TIF_SINGLESTEP))
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 9f0d73e3f5f7..26889366929a 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -712,18 +712,13 @@ out:
712asmlinkage void 712asmlinkage void
713syscall_trace(struct pt_regs *regs, int entryexit) 713syscall_trace(struct pt_regs *regs, int entryexit)
714{ 714{
715 if (unlikely(current->audit_context)) { 715 if (unlikely(current->audit_context) && entryexit)
716 if (!entryexit) 716 audit_syscall_exit(current, AUDITSC_RESULT(regs->gprs[2]), regs->gprs[2]);
717 audit_syscall_entry(current, regs->gprs[2], 717
718 regs->orig_gpr2, regs->gprs[3],
719 regs->gprs[4], regs->gprs[5]);
720 else
721 audit_syscall_exit(current, regs->gprs[2]);
722 }
723 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 718 if (!test_thread_flag(TIF_SYSCALL_TRACE))
724 return; 719 goto out;
725 if (!(current->ptrace & PT_PTRACED)) 720 if (!(current->ptrace & PT_PTRACED))
726 return; 721 goto out;
727 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) 722 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
728 ? 0x80 : 0)); 723 ? 0x80 : 0));
729 724
@@ -736,4 +731,10 @@ syscall_trace(struct pt_regs *regs, int entryexit)
736 send_sig(current->exit_code, current, 1); 731 send_sig(current->exit_code, current, 1);
737 current->exit_code = 0; 732 current->exit_code = 0;
738 } 733 }
734 out:
735 if (unlikely(current->audit_context) && !entryexit)
736 audit_syscall_entry(current,
737 test_thread_flag(TIF_31BIT)?AUDIT_ARCH_S390:AUDIT_ARCH_S390X,
738 regs->gprs[2], regs->orig_gpr2, regs->gprs[3],
739 regs->gprs[4], regs->gprs[5]);
739} 740}
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index e50e60ff5d27..959b2d2490df 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -337,15 +337,18 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit)
337 337
338 if (unlikely(current->audit_context)) { 338 if (unlikely(current->audit_context)) {
339 if (!entryexit) 339 if (!entryexit)
340 audit_syscall_entry(current, 340 audit_syscall_entry(current,
341 UPT_SYSCALL_NR(&regs->regs), 341 HOST_AUDIT_ARCH,
342 UPT_SYSCALL_ARG1(&regs->regs), 342 UPT_SYSCALL_NR(regs),
343 UPT_SYSCALL_ARG2(&regs->regs), 343 UPT_SYSCALL_ARG1(regs),
344 UPT_SYSCALL_ARG3(&regs->regs), 344 UPT_SYSCALL_ARG2(regs),
345 UPT_SYSCALL_ARG4(&regs->regs)); 345 UPT_SYSCALL_ARG3(regs),
346 else 346 UPT_SYSCALL_ARG4(regs));
347 audit_syscall_exit(current, 347 else {
348 UPT_SYSCALL_RET(&regs->regs)); 348 int res = UPT_SYSCALL_RET(regs);
349 audit_syscall_exit(current, AUDITSC_RESULT(res),
350 res);
351 }
349 } 352 }
350 353
351 /* Fake a debug trap */ 354 /* Fake a debug trap */
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
index c64b9c97c745..e26e86bb56fe 100644
--- a/arch/x86_64/kernel/ptrace.c
+++ b/arch/x86_64/kernel/ptrace.c
@@ -635,20 +635,29 @@ asmlinkage void syscall_trace_enter(struct pt_regs *regs)
635 /* do the secure computing check first */ 635 /* do the secure computing check first */
636 secure_computing(regs->orig_rax); 636 secure_computing(regs->orig_rax);
637 637
638 if (unlikely(current->audit_context))
639 audit_syscall_entry(current, regs->orig_rax,
640 regs->rdi, regs->rsi,
641 regs->rdx, regs->r10);
642
643 if (test_thread_flag(TIF_SYSCALL_TRACE) 638 if (test_thread_flag(TIF_SYSCALL_TRACE)
644 && (current->ptrace & PT_PTRACED)) 639 && (current->ptrace & PT_PTRACED))
645 syscall_trace(regs); 640 syscall_trace(regs);
641
642 if (unlikely(current->audit_context)) {
643 if (test_thread_flag(TIF_IA32)) {
644 audit_syscall_entry(current, AUDIT_ARCH_I386,
645 regs->orig_rax,
646 regs->rbx, regs->rcx,
647 regs->rdx, regs->rsi);
648 } else {
649 audit_syscall_entry(current, AUDIT_ARCH_X86_64,
650 regs->orig_rax,
651 regs->rdi, regs->rsi,
652 regs->rdx, regs->r10);
653 }
654 }
646} 655}
647 656
648asmlinkage void syscall_trace_leave(struct pt_regs *regs) 657asmlinkage void syscall_trace_leave(struct pt_regs *regs)
649{ 658{
650 if (unlikely(current->audit_context)) 659 if (unlikely(current->audit_context))
651 audit_syscall_exit(current, regs->rax); 660 audit_syscall_exit(current, AUDITSC_RESULT(regs->rax), regs->rax);
652 661
653 if ((test_thread_flag(TIF_SYSCALL_TRACE) 662 if ((test_thread_flag(TIF_SYSCALL_TRACE)
654 || test_thread_flag(TIF_SINGLESTEP)) 663 || test_thread_flag(TIF_SINGLESTEP))
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index f4fa27315fb4..2b3902c867da 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -405,9 +405,8 @@ void device_release_driver(struct device * dev)
405 405
406static void driver_detach(struct device_driver * drv) 406static void driver_detach(struct device_driver * drv)
407{ 407{
408 struct list_head * entry, * next; 408 while (!list_empty(&drv->devices)) {
409 list_for_each_safe(entry, next, &drv->devices) { 409 struct device * dev = container_of(drv->devices.next, struct device, driver_list);
410 struct device * dev = container_of(entry, struct device, driver_list);
411 device_release_driver(dev); 410 device_release_driver(dev);
412 } 411 }
413} 412}
diff --git a/drivers/base/core.c b/drivers/base/core.c
index a7cedd8cefe5..268a9c8d168b 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -139,7 +139,7 @@ static int dev_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
139 buffer = &buffer[length]; 139 buffer = &buffer[length];
140 buffer_size -= length; 140 buffer_size -= length;
141 141
142 if (dev->bus->hotplug) { 142 if (dev->bus && dev->bus->hotplug) {
143 /* have the bus specific function add its stuff */ 143 /* have the bus specific function add its stuff */
144 retval = dev->bus->hotplug (dev, envp, num_envp, buffer, buffer_size); 144 retval = dev->bus->hotplug (dev, envp, num_envp, buffer, buffer_size);
145 if (retval) { 145 if (retval) {
diff --git a/fs/namei.c b/fs/namei.c
index 9e4aef2a1a21..0f76fd75591b 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -686,11 +686,11 @@ fail:
686 686
687/* 687/*
688 * Name resolution. 688 * Name resolution.
689 * This is the basic name resolution function, turning a pathname into
690 * the final dentry. We expect 'base' to be positive and a directory.
689 * 691 *
690 * This is the basic name resolution function, turning a pathname 692 * Returns 0 and nd will have valid dentry and mnt on success.
691 * into the final dentry. 693 * Returns error and drops reference to input namei data on failure.
692 *
693 * We expect 'base' to be positive and a directory.
694 */ 694 */
695static fastcall int __link_path_walk(const char * name, struct nameidata *nd) 695static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
696{ 696{
@@ -929,8 +929,10 @@ int fastcall path_walk(const char * name, struct nameidata *nd)
929 return link_path_walk(name, nd); 929 return link_path_walk(name, nd);
930} 930}
931 931
932/* SMP-safe */ 932/*
933/* returns 1 if everything is done */ 933 * SMP-safe: Returns 1 and nd will have valid dentry and mnt, if
934 * everything is done. Returns 0 and drops input nd, if lookup failed;
935 */
934static int __emul_lookup_dentry(const char *name, struct nameidata *nd) 936static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
935{ 937{
936 if (path_walk(name, nd)) 938 if (path_walk(name, nd))
@@ -994,9 +996,10 @@ set_it:
994 } 996 }
995} 997}
996 998
999/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
997int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata *nd) 1000int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata *nd)
998{ 1001{
999 int retval; 1002 int retval = 0;
1000 1003
1001 nd->last_type = LAST_ROOT; /* if there are only slashes... */ 1004 nd->last_type = LAST_ROOT; /* if there are only slashes... */
1002 nd->flags = flags; 1005 nd->flags = flags;
@@ -1009,7 +1012,7 @@ int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata
1009 nd->dentry = dget(current->fs->altroot); 1012 nd->dentry = dget(current->fs->altroot);
1010 read_unlock(&current->fs->lock); 1013 read_unlock(&current->fs->lock);
1011 if (__emul_lookup_dentry(name,nd)) 1014 if (__emul_lookup_dentry(name,nd))
1012 return 0; 1015 goto out; /* found in altroot */
1013 read_lock(&current->fs->lock); 1016 read_lock(&current->fs->lock);
1014 } 1017 }
1015 nd->mnt = mntget(current->fs->rootmnt); 1018 nd->mnt = mntget(current->fs->rootmnt);
@@ -1021,6 +1024,7 @@ int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata
1021 read_unlock(&current->fs->lock); 1024 read_unlock(&current->fs->lock);
1022 current->total_link_count = 0; 1025 current->total_link_count = 0;
1023 retval = link_path_walk(name, nd); 1026 retval = link_path_walk(name, nd);
1027out:
1024 if (unlikely(current->audit_context 1028 if (unlikely(current->audit_context
1025 && nd && nd->dentry && nd->dentry->d_inode)) 1029 && nd && nd->dentry && nd->dentry->d_inode))
1026 audit_inode(name, nd->dentry->d_inode); 1030 audit_inode(name, nd->dentry->d_inode);
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 07cafdf74ef2..e31903aadd96 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -820,7 +820,7 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
820 goto out_free_page; 820 goto out_free_page;
821 821
822 } 822 }
823 length = audit_set_loginuid(task->audit_context, loginuid); 823 length = audit_set_loginuid(task, loginuid);
824 if (likely(length == 0)) 824 if (likely(length == 0))
825 length = count; 825 length = count;
826 826
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index 554e4a18c152..d3ff78354638 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -49,7 +49,7 @@ ifeq ($(CONFIG_XFS_TRACE),y)
49 EXTRA_CFLAGS += -DXFS_LOG_TRACE 49 EXTRA_CFLAGS += -DXFS_LOG_TRACE
50 EXTRA_CFLAGS += -DXFS_RW_TRACE 50 EXTRA_CFLAGS += -DXFS_RW_TRACE
51 EXTRA_CFLAGS += -DPAGEBUF_TRACE 51 EXTRA_CFLAGS += -DPAGEBUF_TRACE
52 # EXTRA_CFLAGS += -DXFS_VNODE_TRACE 52 EXTRA_CFLAGS += -DXFS_VNODE_TRACE
53endif 53endif
54 54
55obj-$(CONFIG_XFS_FS) += xfs.o 55obj-$(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 76a84758073a..9278e9aba9ba 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -558,7 +558,8 @@ xfs_submit_page(
558 int i; 558 int i;
559 559
560 BUG_ON(PageWriteback(page)); 560 BUG_ON(PageWriteback(page));
561 set_page_writeback(page); 561 if (bh_count)
562 set_page_writeback(page);
562 if (clear_dirty) 563 if (clear_dirty)
563 clear_page_dirty(page); 564 clear_page_dirty(page);
564 unlock_page(page); 565 unlock_page(page);
@@ -578,9 +579,6 @@ xfs_submit_page(
578 579
579 if (probed_page && clear_dirty) 580 if (probed_page && clear_dirty)
580 wbc->nr_to_write--; /* Wrote an "extra" page */ 581 wbc->nr_to_write--; /* Wrote an "extra" page */
581 } else {
582 end_page_writeback(page);
583 wbc->pages_skipped++; /* We didn't write this page */
584 } 582 }
585} 583}
586 584
@@ -602,21 +600,26 @@ xfs_convert_page(
602{ 600{
603 struct buffer_head *bh_arr[MAX_BUF_PER_PAGE], *bh, *head; 601 struct buffer_head *bh_arr[MAX_BUF_PER_PAGE], *bh, *head;
604 xfs_iomap_t *mp = iomapp, *tmp; 602 xfs_iomap_t *mp = iomapp, *tmp;
605 unsigned long end, offset; 603 unsigned long offset, end_offset;
606 pgoff_t end_index; 604 int index = 0;
607 int i = 0, index = 0;
608 int bbits = inode->i_blkbits; 605 int bbits = inode->i_blkbits;
606 int len, page_dirty;
609 607
610 end_index = i_size_read(inode) >> PAGE_CACHE_SHIFT; 608 end_offset = (i_size_read(inode) & (PAGE_CACHE_SIZE - 1));
611 if (page->index < end_index) { 609
612 end = PAGE_CACHE_SIZE; 610 /*
613 } else { 611 * page_dirty is initially a count of buffers on the page before
614 end = i_size_read(inode) & (PAGE_CACHE_SIZE-1); 612 * EOF and is decrememted as we move each into a cleanable state.
615 } 613 */
614 len = 1 << inode->i_blkbits;
615 end_offset = max(end_offset, PAGE_CACHE_SIZE);
616 end_offset = roundup(end_offset, len);
617 page_dirty = end_offset / len;
618
619 offset = 0;
616 bh = head = page_buffers(page); 620 bh = head = page_buffers(page);
617 do { 621 do {
618 offset = i << bbits; 622 if (offset >= end_offset)
619 if (offset >= end)
620 break; 623 break;
621 if (!(PageUptodate(page) || buffer_uptodate(bh))) 624 if (!(PageUptodate(page) || buffer_uptodate(bh)))
622 continue; 625 continue;
@@ -625,6 +628,7 @@ xfs_convert_page(
625 if (startio) { 628 if (startio) {
626 lock_buffer(bh); 629 lock_buffer(bh);
627 bh_arr[index++] = bh; 630 bh_arr[index++] = bh;
631 page_dirty--;
628 } 632 }
629 continue; 633 continue;
630 } 634 }
@@ -657,10 +661,11 @@ xfs_convert_page(
657 unlock_buffer(bh); 661 unlock_buffer(bh);
658 mark_buffer_dirty(bh); 662 mark_buffer_dirty(bh);
659 } 663 }
660 } while (i++, (bh = bh->b_this_page) != head); 664 page_dirty--;
665 } while (offset += len, (bh = bh->b_this_page) != head);
661 666
662 if (startio) { 667 if (startio && index) {
663 xfs_submit_page(page, wbc, bh_arr, index, 1, index == i); 668 xfs_submit_page(page, wbc, bh_arr, index, 1, !page_dirty);
664 } else { 669 } else {
665 unlock_page(page); 670 unlock_page(page);
666 } 671 }
@@ -725,8 +730,11 @@ xfs_page_state_convert(
725 __uint64_t end_offset; 730 __uint64_t end_offset;
726 pgoff_t end_index, last_index, tlast; 731 pgoff_t end_index, last_index, tlast;
727 int len, err, i, cnt = 0, uptodate = 1; 732 int len, err, i, cnt = 0, uptodate = 1;
728 int flags = startio ? 0 : BMAPI_TRYLOCK; 733 int flags;
729 int page_dirty, delalloc = 0; 734 int page_dirty;
735
736 /* wait for other IO threads? */
737 flags = (startio && wbc->sync_mode != WB_SYNC_NONE) ? 0 : BMAPI_TRYLOCK;
730 738
731 /* Is this page beyond the end of the file? */ 739 /* Is this page beyond the end of the file? */
732 offset = i_size_read(inode); 740 offset = i_size_read(inode);
@@ -740,19 +748,22 @@ xfs_page_state_convert(
740 } 748 }
741 } 749 }
742 750
743 offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
744 end_offset = min_t(unsigned long long, 751 end_offset = min_t(unsigned long long,
745 offset + PAGE_CACHE_SIZE, i_size_read(inode)); 752 (loff_t)(page->index + 1) << PAGE_CACHE_SHIFT, offset);
746 753 offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
747 bh = head = page_buffers(page);
748 iomp = NULL;
749 754
750 /* 755 /*
751 * page_dirty is initially a count of buffers on the page and 756 * page_dirty is initially a count of buffers on the page before
752 * is decrememted as we move each into a cleanable state. 757 * EOF and is decrememted as we move each into a cleanable state.
753 */ 758 */
754 len = bh->b_size; 759 len = 1 << inode->i_blkbits;
755 page_dirty = PAGE_CACHE_SIZE / len; 760 p_offset = max(p_offset, PAGE_CACHE_SIZE);
761 p_offset = roundup(p_offset, len);
762 page_dirty = p_offset / len;
763
764 iomp = NULL;
765 p_offset = 0;
766 bh = head = page_buffers(page);
756 767
757 do { 768 do {
758 if (offset >= end_offset) 769 if (offset >= end_offset)
@@ -804,7 +815,6 @@ xfs_page_state_convert(
804 */ 815 */
805 } else if (buffer_delay(bh)) { 816 } else if (buffer_delay(bh)) {
806 if (!iomp) { 817 if (!iomp) {
807 delalloc = 1;
808 err = xfs_map_blocks(inode, offset, len, &iomap, 818 err = xfs_map_blocks(inode, offset, len, &iomap,
809 BMAPI_ALLOCATE | flags); 819 BMAPI_ALLOCATE | flags);
810 if (err) { 820 if (err) {
@@ -875,14 +885,15 @@ xfs_page_state_convert(
875 if (uptodate && bh == head) 885 if (uptodate && bh == head)
876 SetPageUptodate(page); 886 SetPageUptodate(page);
877 887
878 if (startio) 888 if (startio) {
879 xfs_submit_page(page, wbc, bh_arr, cnt, 0, 1); 889 WARN_ON(page_dirty);
890 xfs_submit_page(page, wbc, bh_arr, cnt, 0, !page_dirty);
891 }
880 892
881 if (iomp) { 893 if (iomp) {
882 tlast = (iomp->iomap_offset + iomp->iomap_bsize - 1) >> 894 offset = (iomp->iomap_offset + iomp->iomap_bsize - 1) >>
883 PAGE_CACHE_SHIFT; 895 PAGE_CACHE_SHIFT;
884 if (delalloc && (tlast > last_index)) 896 tlast = min_t(pgoff_t, offset, last_index);
885 tlast = last_index;
886 xfs_cluster_write(inode, page->index + 1, iomp, wbc, 897 xfs_cluster_write(inode, page->index + 1, iomp, wbc,
887 startio, unmapped, tlast); 898 startio, unmapped, tlast);
888 } 899 }
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index 23e0eb67fc25..997963e53622 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -1746,13 +1746,15 @@ STATIC DECLARE_COMPLETION(pagebuf_daemon_done);
1746STATIC struct task_struct *pagebuf_daemon_task; 1746STATIC struct task_struct *pagebuf_daemon_task;
1747STATIC int pagebuf_daemon_active; 1747STATIC int pagebuf_daemon_active;
1748STATIC int force_flush; 1748STATIC int force_flush;
1749 1749STATIC int force_sleep;
1750 1750
1751STATIC int 1751STATIC int
1752pagebuf_daemon_wakeup( 1752pagebuf_daemon_wakeup(
1753 int priority, 1753 int priority,
1754 unsigned int mask) 1754 unsigned int mask)
1755{ 1755{
1756 if (force_sleep)
1757 return 0;
1756 force_flush = 1; 1758 force_flush = 1;
1757 barrier(); 1759 barrier();
1758 wake_up_process(pagebuf_daemon_task); 1760 wake_up_process(pagebuf_daemon_task);
@@ -1778,7 +1780,12 @@ pagebuf_daemon(
1778 1780
1779 INIT_LIST_HEAD(&tmp); 1781 INIT_LIST_HEAD(&tmp);
1780 do { 1782 do {
1781 try_to_freeze(PF_FREEZE); 1783 if (unlikely(current->flags & PF_FREEZE)) {
1784 force_sleep = 1;
1785 refrigerator(PF_FREEZE);
1786 } else {
1787 force_sleep = 0;
1788 }
1782 1789
1783 set_current_state(TASK_INTERRUPTIBLE); 1790 set_current_state(TASK_INTERRUPTIBLE);
1784 schedule_timeout((xfs_buf_timer_centisecs * HZ) / 100); 1791 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 9f057a4a5b06..d0d412afd261 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -515,10 +515,49 @@ open_exec_out:
515} 515}
516#endif /* HAVE_FOP_OPEN_EXEC */ 516#endif /* HAVE_FOP_OPEN_EXEC */
517 517
518/*
519 * Temporary workaround to the AIO direct IO write problem.
520 * This code can go and we can revert to do_sync_write once
521 * the writepage(s) rework is merged.
522 */
523STATIC ssize_t
524linvfs_write(
525 struct file *filp,
526 const char __user *buf,
527 size_t len,
528 loff_t *ppos)
529{
530 struct kiocb kiocb;
531 ssize_t ret;
532
533 init_sync_kiocb(&kiocb, filp);
534 kiocb.ki_pos = *ppos;
535 ret = __linvfs_write(&kiocb, buf, 0, len, kiocb.ki_pos);
536 *ppos = kiocb.ki_pos;
537 return ret;
538}
539STATIC ssize_t
540linvfs_write_invis(
541 struct file *filp,
542 const char __user *buf,
543 size_t len,
544 loff_t *ppos)
545{
546 struct kiocb kiocb;
547 ssize_t ret;
548
549 init_sync_kiocb(&kiocb, filp);
550 kiocb.ki_pos = *ppos;
551 ret = __linvfs_write(&kiocb, buf, IO_INVIS, len, kiocb.ki_pos);
552 *ppos = kiocb.ki_pos;
553 return ret;
554}
555
556
518struct file_operations linvfs_file_operations = { 557struct file_operations linvfs_file_operations = {
519 .llseek = generic_file_llseek, 558 .llseek = generic_file_llseek,
520 .read = do_sync_read, 559 .read = do_sync_read,
521 .write = do_sync_write, 560 .write = linvfs_write,
522 .readv = linvfs_readv, 561 .readv = linvfs_readv,
523 .writev = linvfs_writev, 562 .writev = linvfs_writev,
524 .aio_read = linvfs_aio_read, 563 .aio_read = linvfs_aio_read,
@@ -540,7 +579,7 @@ struct file_operations linvfs_file_operations = {
540struct file_operations linvfs_invis_file_operations = { 579struct file_operations linvfs_invis_file_operations = {
541 .llseek = generic_file_llseek, 580 .llseek = generic_file_llseek,
542 .read = do_sync_read, 581 .read = do_sync_read,
543 .write = do_sync_write, 582 .write = linvfs_write_invis,
544 .readv = linvfs_readv_invis, 583 .readv = linvfs_readv_invis,
545 .writev = linvfs_writev_invis, 584 .writev = linvfs_writev_invis,
546 .aio_read = linvfs_aio_read_invis, 585 .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 ff145fd0d1a4..aa9daaea6c34 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -683,6 +683,9 @@ xfs_write(
683 (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? 683 (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
684 mp->m_rtdev_targp : mp->m_ddev_targp; 684 mp->m_rtdev_targp : mp->m_ddev_targp;
685 685
686 if (ioflags & IO_ISAIO)
687 return XFS_ERROR(-ENOSYS);
688
686 if ((pos & target->pbr_smask) || (count & target->pbr_smask)) 689 if ((pos & target->pbr_smask) || (count & target->pbr_smask))
687 return XFS_ERROR(-EINVAL); 690 return XFS_ERROR(-EINVAL);
688 691
diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c
index 849c61c74f3c..a832d165f24f 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.c
+++ b/fs/xfs/linux-2.6/xfs_vnode.c
@@ -156,7 +156,6 @@ vn_initialize(
156 156
157#ifdef XFS_VNODE_TRACE 157#ifdef XFS_VNODE_TRACE
158 vp->v_trace = ktrace_alloc(VNODE_TRACE_SIZE, KM_SLEEP); 158 vp->v_trace = ktrace_alloc(VNODE_TRACE_SIZE, KM_SLEEP);
159 printk("Allocated VNODE_TRACE at 0x%p\n", vp->v_trace);
160#endif /* XFS_VNODE_TRACE */ 159#endif /* XFS_VNODE_TRACE */
161 160
162 vn_trace_exit(vp, "vn_initialize", (inst_t *)__return_address); 161 vn_trace_exit(vp, "vn_initialize", (inst_t *)__return_address);
@@ -424,13 +423,13 @@ vn_remove(
424 * Vnode tracing code. 423 * Vnode tracing code.
425 */ 424 */
426void 425void
427vn_trace_entry(vnode_t *vp, char *func, inst_t *ra) 426vn_trace_entry(vnode_t *vp, const char *func, inst_t *ra)
428{ 427{
429 KTRACE_ENTER(vp, VNODE_KTRACE_ENTRY, func, 0, ra); 428 KTRACE_ENTER(vp, VNODE_KTRACE_ENTRY, func, 0, ra);
430} 429}
431 430
432void 431void
433vn_trace_exit(vnode_t *vp, char *func, inst_t *ra) 432vn_trace_exit(vnode_t *vp, const char *func, inst_t *ra)
434{ 433{
435 KTRACE_ENTER(vp, VNODE_KTRACE_EXIT, func, 0, ra); 434 KTRACE_ENTER(vp, VNODE_KTRACE_EXIT, func, 0, ra);
436} 435}
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index da76c1f1e11c..00466c3194ac 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -86,10 +86,11 @@ typedef struct vnode {
86 vnumber_t v_number; /* in-core vnode number */ 86 vnumber_t v_number; /* in-core vnode number */
87 vn_bhv_head_t v_bh; /* behavior head */ 87 vn_bhv_head_t v_bh; /* behavior head */
88 spinlock_t v_lock; /* VN_LOCK/VN_UNLOCK */ 88 spinlock_t v_lock; /* VN_LOCK/VN_UNLOCK */
89 struct inode v_inode; /* Linux inode */
90#ifdef XFS_VNODE_TRACE 89#ifdef XFS_VNODE_TRACE
91 struct ktrace *v_trace; /* trace header structure */ 90 struct ktrace *v_trace; /* trace header structure */
92#endif 91#endif
92 struct inode v_inode; /* Linux inode */
93 /* inode MUST be last */
93} vnode_t; 94} vnode_t;
94 95
95#define v_fbhv v_bh.bh_first /* first behavior */ 96#define v_fbhv v_bh.bh_first /* first behavior */
@@ -409,7 +410,7 @@ typedef struct vattr {
409 int va_mask; /* bit-mask of attributes present */ 410 int va_mask; /* bit-mask of attributes present */
410 enum vtype va_type; /* vnode type (for create) */ 411 enum vtype va_type; /* vnode type (for create) */
411 mode_t va_mode; /* file access mode and type */ 412 mode_t va_mode; /* file access mode and type */
412 nlink_t va_nlink; /* number of references to file */ 413 xfs_nlink_t va_nlink; /* number of references to file */
413 uid_t va_uid; /* owner user id */ 414 uid_t va_uid; /* owner user id */
414 gid_t va_gid; /* owner group id */ 415 gid_t va_gid; /* owner group id */
415 xfs_ino_t va_nodeid; /* file id */ 416 xfs_ino_t va_nodeid; /* file id */
@@ -625,6 +626,7 @@ static inline int VN_BAD(struct vnode *vp)
625#define ATTR_DMI 0x08 /* invocation from a DMI function */ 626#define ATTR_DMI 0x08 /* invocation from a DMI function */
626#define ATTR_LAZY 0x80 /* set/get attributes lazily */ 627#define ATTR_LAZY 0x80 /* set/get attributes lazily */
627#define ATTR_NONBLOCK 0x100 /* return EAGAIN if operation would block */ 628#define ATTR_NONBLOCK 0x100 /* return EAGAIN if operation would block */
629#define ATTR_NOLOCK 0x200 /* Don't grab any conflicting locks */
628 630
629/* 631/*
630 * Flags to VOP_FSYNC and VOP_RECLAIM. 632 * Flags to VOP_FSYNC and VOP_RECLAIM.
@@ -646,8 +648,8 @@ static inline int VN_BAD(struct vnode *vp)
646#define VNODE_KTRACE_REF 4 648#define VNODE_KTRACE_REF 4
647#define VNODE_KTRACE_RELE 5 649#define VNODE_KTRACE_RELE 5
648 650
649extern void vn_trace_entry(struct vnode *, char *, inst_t *); 651extern void vn_trace_entry(struct vnode *, const char *, inst_t *);
650extern void vn_trace_exit(struct vnode *, char *, inst_t *); 652extern void vn_trace_exit(struct vnode *, const char *, inst_t *);
651extern void vn_trace_hold(struct vnode *, char *, int, inst_t *); 653extern void vn_trace_hold(struct vnode *, char *, int, inst_t *);
652extern void vn_trace_ref(struct vnode *, char *, int, inst_t *); 654extern void vn_trace_ref(struct vnode *, char *, int, inst_t *);
653extern void vn_trace_rele(struct vnode *, char *, int, inst_t *); 655extern 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 08d551a17347..63abdc2ac7f4 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -182,7 +182,7 @@ xfs_swapext(
182 182
183 if (VN_CACHED(tvp) != 0) 183 if (VN_CACHED(tvp) != 0)
184 xfs_inval_cached_pages(XFS_ITOV(tip), &(tip->i_iocore), 184 xfs_inval_cached_pages(XFS_ITOV(tip), &(tip->i_iocore),
185 (loff_t)0, 0, 0); 185 (xfs_off_t)0, 0, 0);
186 186
187 /* Verify O_DIRECT for ftmp */ 187 /* Verify O_DIRECT for ftmp */
188 if (VN_CACHED(tvp) != 0) { 188 if (VN_CACHED(tvp) != 0) {
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index 3a0ba1dfd0e8..d3da00045f26 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -136,6 +136,40 @@ xfs_chash_free(xfs_mount_t *mp)
136} 136}
137 137
138/* 138/*
139 * Try to move an inode to the front of its hash list if possible
140 * (and if its not there already). Called right after obtaining
141 * the list version number and then dropping the read_lock on the
142 * hash list in question (which is done right after looking up the
143 * inode in question...).
144 */
145STATIC void
146xfs_ihash_promote(
147 xfs_ihash_t *ih,
148 xfs_inode_t *ip,
149 ulong version)
150{
151 xfs_inode_t *iq;
152
153 if ((ip->i_prevp != &ih->ih_next) && write_trylock(&ih->ih_lock)) {
154 if (likely(version == ih->ih_version)) {
155 /* remove from list */
156 if ((iq = ip->i_next)) {
157 iq->i_prevp = ip->i_prevp;
158 }
159 *ip->i_prevp = iq;
160
161 /* insert at list head */
162 iq = ih->ih_next;
163 iq->i_prevp = &ip->i_next;
164 ip->i_next = iq;
165 ip->i_prevp = &ih->ih_next;
166 ih->ih_next = ip;
167 }
168 write_unlock(&ih->ih_lock);
169 }
170}
171
172/*
139 * Look up an inode by number in the given file system. 173 * Look up an inode by number in the given file system.
140 * The inode is looked up in the hash table for the file system 174 * The inode is looked up in the hash table for the file system
141 * represented by the mount point parameter mp. Each bucket of 175 * represented by the mount point parameter mp. Each bucket of
@@ -229,7 +263,9 @@ again:
229 XFS_STATS_INC(xs_ig_found); 263 XFS_STATS_INC(xs_ig_found);
230 264
231 ip->i_flags &= ~XFS_IRECLAIMABLE; 265 ip->i_flags &= ~XFS_IRECLAIMABLE;
266 version = ih->ih_version;
232 read_unlock(&ih->ih_lock); 267 read_unlock(&ih->ih_lock);
268 xfs_ihash_promote(ih, ip, version);
233 269
234 XFS_MOUNT_ILOCK(mp); 270 XFS_MOUNT_ILOCK(mp);
235 list_del_init(&ip->i_reclaim); 271 list_del_init(&ip->i_reclaim);
@@ -259,8 +295,15 @@ again:
259 inode_vp, vp); 295 inode_vp, vp);
260 } 296 }
261 297
298 /*
299 * Inode cache hit: if ip is not at the front of
300 * its hash chain, move it there now.
301 * Do this with the lock held for update, but
302 * do statistics after releasing the lock.
303 */
304 version = ih->ih_version;
262 read_unlock(&ih->ih_lock); 305 read_unlock(&ih->ih_lock);
263 306 xfs_ihash_promote(ih, ip, version);
264 XFS_STATS_INC(xs_ig_found); 307 XFS_STATS_INC(xs_ig_found);
265 308
266finish_inode: 309finish_inode:
@@ -547,6 +590,7 @@ xfs_inode_incore(xfs_mount_t *mp,
547{ 590{
548 xfs_ihash_t *ih; 591 xfs_ihash_t *ih;
549 xfs_inode_t *ip; 592 xfs_inode_t *ip;
593 ulong version;
550 594
551 ih = XFS_IHASH(mp, ino); 595 ih = XFS_IHASH(mp, ino);
552 read_lock(&ih->ih_lock); 596 read_lock(&ih->ih_lock);
@@ -554,11 +598,15 @@ xfs_inode_incore(xfs_mount_t *mp,
554 if (ip->i_ino == ino) { 598 if (ip->i_ino == ino) {
555 /* 599 /*
556 * If we find it and tp matches, return it. 600 * If we find it and tp matches, return it.
601 * Also move it to the front of the hash list
602 * if we find it and it is not already there.
557 * Otherwise break from the loop and return 603 * Otherwise break from the loop and return
558 * NULL. 604 * NULL.
559 */ 605 */
560 if (ip->i_transp == tp) { 606 if (ip->i_transp == tp) {
607 version = ih->ih_version;
561 read_unlock(&ih->ih_lock); 608 read_unlock(&ih->ih_lock);
609 xfs_ihash_promote(ih, ip, version);
562 return (ip); 610 return (ip);
563 } 611 }
564 break; 612 break;
@@ -685,6 +733,7 @@ xfs_iextract(
685 iq->i_prevp = ip->i_prevp; 733 iq->i_prevp = ip->i_prevp;
686 } 734 }
687 *ip->i_prevp = iq; 735 *ip->i_prevp = iq;
736 ih->ih_version++;
688 write_unlock(&ih->ih_lock); 737 write_unlock(&ih->ih_lock);
689 738
690 /* 739 /*
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 43c632ab86ad..bc8c8c7f9039 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1130,7 +1130,7 @@ xfs_ialloc(
1130 xfs_trans_t *tp, 1130 xfs_trans_t *tp,
1131 xfs_inode_t *pip, 1131 xfs_inode_t *pip,
1132 mode_t mode, 1132 mode_t mode,
1133 nlink_t nlink, 1133 xfs_nlink_t nlink,
1134 xfs_dev_t rdev, 1134 xfs_dev_t rdev,
1135 cred_t *cr, 1135 cred_t *cr,
1136 xfs_prid_t prid, 1136 xfs_prid_t prid,
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index a53b1ccf6070..37e1c316f3b6 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -495,9 +495,9 @@ int xfs_itobp(struct xfs_mount *, struct xfs_trans *,
495int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, 495int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
496 xfs_inode_t **, xfs_daddr_t); 496 xfs_inode_t **, xfs_daddr_t);
497int xfs_iread_extents(struct xfs_trans *, xfs_inode_t *, int); 497int xfs_iread_extents(struct xfs_trans *, xfs_inode_t *, int);
498int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, nlink_t, 498int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t,
499 xfs_dev_t, struct cred *, xfs_prid_t, int, 499 xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t,
500 struct xfs_buf **, boolean_t *, xfs_inode_t **); 500 int, struct xfs_buf **, boolean_t *, xfs_inode_t **);
501void xfs_xlate_dinode_core(xfs_caddr_t, struct xfs_dinode_core *, 501void xfs_xlate_dinode_core(xfs_caddr_t, struct xfs_dinode_core *,
502 int); 502 int);
503uint xfs_ip2xflags(struct xfs_inode *); 503uint xfs_ip2xflags(struct xfs_inode *);
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 3826e8f0e28a..991f8a61f7c4 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -308,7 +308,8 @@ phase2:
308 break; 308 break;
309 } 309 }
310 310
311 error = XFS_IOMAP_WRITE_ALLOCATE(mp, io, &imap, &nimaps); 311 error = XFS_IOMAP_WRITE_ALLOCATE(mp, io, offset, count,
312 &imap, &nimaps);
312 break; 313 break;
313 case BMAPI_UNWRITTEN: 314 case BMAPI_UNWRITTEN:
314 lockmode = 0; 315 lockmode = 0;
@@ -365,7 +366,7 @@ xfs_flush_space(
365int 366int
366xfs_iomap_write_direct( 367xfs_iomap_write_direct(
367 xfs_inode_t *ip, 368 xfs_inode_t *ip,
368 loff_t offset, 369 xfs_off_t offset,
369 size_t count, 370 size_t count,
370 int flags, 371 int flags,
371 xfs_bmbt_irec_t *ret_imap, 372 xfs_bmbt_irec_t *ret_imap,
@@ -541,7 +542,7 @@ error_out:
541int 542int
542xfs_iomap_write_delay( 543xfs_iomap_write_delay(
543 xfs_inode_t *ip, 544 xfs_inode_t *ip,
544 loff_t offset, 545 xfs_off_t offset,
545 size_t count, 546 size_t count,
546 int ioflag, 547 int ioflag,
547 xfs_bmbt_irec_t *ret_imap, 548 xfs_bmbt_irec_t *ret_imap,
@@ -746,6 +747,8 @@ write_map:
746int 747int
747xfs_iomap_write_allocate( 748xfs_iomap_write_allocate(
748 xfs_inode_t *ip, 749 xfs_inode_t *ip,
750 xfs_off_t offset,
751 size_t count,
749 xfs_bmbt_irec_t *map, 752 xfs_bmbt_irec_t *map,
750 int *retmap) 753 int *retmap)
751{ 754{
@@ -770,9 +773,9 @@ xfs_iomap_write_allocate(
770 if ((error = XFS_QM_DQATTACH(mp, ip, 0))) 773 if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
771 return XFS_ERROR(error); 774 return XFS_ERROR(error);
772 775
773 offset_fsb = map->br_startoff; 776 offset_fsb = XFS_B_TO_FSBT(mp, offset);
774 count_fsb = map->br_blockcount; 777 count_fsb = map->br_blockcount;
775 map_start_fsb = offset_fsb; 778 map_start_fsb = map->br_startoff;
776 779
777 XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb)); 780 XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb));
778 781
@@ -868,9 +871,9 @@ xfs_iomap_write_allocate(
868 imap[i].br_startoff, 871 imap[i].br_startoff,
869 imap[i].br_blockcount,imap[i].br_state); 872 imap[i].br_blockcount,imap[i].br_state);
870 } 873 }
871 if ((map->br_startoff >= imap[i].br_startoff) && 874 if ((offset_fsb >= imap[i].br_startoff) &&
872 (map->br_startoff < (imap[i].br_startoff + 875 (offset_fsb < (imap[i].br_startoff +
873 imap[i].br_blockcount))) { 876 imap[i].br_blockcount))) {
874 *map = imap[i]; 877 *map = imap[i];
875 *retmap = 1; 878 *retmap = 1;
876 XFS_STATS_INC(xs_xstrat_quick); 879 XFS_STATS_INC(xs_xstrat_quick);
@@ -883,9 +886,8 @@ xfs_iomap_write_allocate(
883 * file, just surrounding data, try again. 886 * file, just surrounding data, try again.
884 */ 887 */
885 nimaps--; 888 nimaps--;
886 offset_fsb = imap[nimaps].br_startoff + 889 map_start_fsb = imap[nimaps].br_startoff +
887 imap[nimaps].br_blockcount; 890 imap[nimaps].br_blockcount;
888 map_start_fsb = offset_fsb;
889 } 891 }
890 892
891trans_cancel: 893trans_cancel:
@@ -899,7 +901,7 @@ error0:
899int 901int
900xfs_iomap_write_unwritten( 902xfs_iomap_write_unwritten(
901 xfs_inode_t *ip, 903 xfs_inode_t *ip,
902 loff_t offset, 904 xfs_off_t offset,
903 size_t count) 905 size_t count)
904{ 906{
905 xfs_mount_t *mp = ip->i_mount; 907 xfs_mount_t *mp = ip->i_mount;
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h
index 31c91087cb33..4daaa5212102 100644
--- a/fs/xfs/xfs_iomap.h
+++ b/fs/xfs/xfs_iomap.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2003,2004 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 2003-2005 Silicon Graphics, Inc. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as 5 * under the terms of version 2 of the GNU General Public License as
@@ -29,9 +29,6 @@
29 * 29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ 30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */ 31 */
32
33
34
35#ifndef __XFS_IOMAP_H__ 32#ifndef __XFS_IOMAP_H__
36#define __XFS_IOMAP_H__ 33#define __XFS_IOMAP_H__
37 34
@@ -56,7 +53,7 @@ typedef enum {
56 BMAPI_UNWRITTEN = (1 << 3), /* unwritten extents to real extents */ 53 BMAPI_UNWRITTEN = (1 << 3), /* unwritten extents to real extents */
57 /* modifiers */ 54 /* modifiers */
58 BMAPI_IGNSTATE = (1 << 4), /* ignore unwritten state on read */ 55 BMAPI_IGNSTATE = (1 << 4), /* ignore unwritten state on read */
59 BMAPI_DIRECT = (1 << 5), /* direct instead of buffered write */ 56 BMAPI_DIRECT = (1 << 5), /* direct instead of buffered write */
60 BMAPI_MMAP = (1 << 6), /* allocate for mmap write */ 57 BMAPI_MMAP = (1 << 6), /* allocate for mmap write */
61 BMAPI_SYNC = (1 << 7), /* sync write to flush delalloc space */ 58 BMAPI_SYNC = (1 << 7), /* sync write to flush delalloc space */
62 BMAPI_TRYLOCK = (1 << 8), /* non-blocking request */ 59 BMAPI_TRYLOCK = (1 << 8), /* non-blocking request */
@@ -67,13 +64,13 @@ typedef enum {
67/* 64/*
68 * xfs_iomap_t: File system I/O map 65 * xfs_iomap_t: File system I/O map
69 * 66 *
70 * The iomap_bn field is expressed in 512-byte blocks, and is where the 67 * The iomap_bn field is expressed in 512-byte blocks, and is where the
71 * mapping starts on disk. 68 * mapping starts on disk.
72 * 69 *
73 * The iomap_offset, iomap_bsize and iomap_delta fields are in bytes. 70 * The iomap_offset, iomap_bsize and iomap_delta fields are in bytes.
74 * iomap_offset is the offset of the mapping in the file itself. 71 * iomap_offset is the offset of the mapping in the file itself.
75 * iomap_bsize is the size of the mapping, iomap_delta is the 72 * iomap_bsize is the size of the mapping, iomap_delta is the
76 * desired data's offset into the mapping, given the offset supplied 73 * desired data's offset into the mapping, given the offset supplied
77 * to the file I/O map routine. 74 * to the file I/O map routine.
78 * 75 *
79 * When a request is made to read beyond the logical end of the object, 76 * When a request is made to read beyond the logical end of the object,
@@ -84,8 +81,8 @@ typedef enum {
84typedef struct xfs_iomap { 81typedef struct xfs_iomap {
85 xfs_daddr_t iomap_bn; /* first 512b blk of mapping */ 82 xfs_daddr_t iomap_bn; /* first 512b blk of mapping */
86 xfs_buftarg_t *iomap_target; 83 xfs_buftarg_t *iomap_target;
87 loff_t iomap_offset; /* offset of mapping, bytes */ 84 xfs_off_t iomap_offset; /* offset of mapping, bytes */
88 loff_t iomap_bsize; /* size of mapping, bytes */ 85 xfs_off_t iomap_bsize; /* size of mapping, bytes */
89 size_t iomap_delta; /* offset into mapping, bytes */ 86 size_t iomap_delta; /* offset into mapping, bytes */
90 iomap_flags_t iomap_flags; 87 iomap_flags_t iomap_flags;
91} xfs_iomap_t; 88} xfs_iomap_t;
@@ -96,12 +93,12 @@ struct xfs_bmbt_irec;
96 93
97extern int xfs_iomap(struct xfs_iocore *, xfs_off_t, ssize_t, int, 94extern int xfs_iomap(struct xfs_iocore *, xfs_off_t, ssize_t, int,
98 struct xfs_iomap *, int *); 95 struct xfs_iomap *, int *);
99extern int xfs_iomap_write_direct(struct xfs_inode *, loff_t, size_t, 96extern int xfs_iomap_write_direct(struct xfs_inode *, xfs_off_t, size_t,
100 int, struct xfs_bmbt_irec *, int *, int); 97 int, struct xfs_bmbt_irec *, int *, int);
101extern int xfs_iomap_write_delay(struct xfs_inode *, loff_t, size_t, int, 98extern int xfs_iomap_write_delay(struct xfs_inode *, xfs_off_t, size_t, int,
102 struct xfs_bmbt_irec *, int *); 99 struct xfs_bmbt_irec *, int *);
103extern int xfs_iomap_write_allocate(struct xfs_inode *, 100extern int xfs_iomap_write_allocate(struct xfs_inode *, xfs_off_t, size_t,
104 struct xfs_bmbt_irec *, int *); 101 struct xfs_bmbt_irec *, int *);
105extern int xfs_iomap_write_unwritten(struct xfs_inode *, loff_t, size_t); 102extern int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, size_t);
106 103
107#endif /* __XFS_IOMAP_H__*/ 104#endif /* __XFS_IOMAP_H__*/
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index b57423caef9b..2ec967d93e5a 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -301,6 +301,15 @@ xfs_mount_validate_sb(
301 } 301 }
302 302
303 /* 303 /*
304 * Version 1 directory format has never worked on Linux.
305 */
306 if (unlikely(!XFS_SB_VERSION_HASDIRV2(sbp))) {
307 cmn_err(CE_WARN,
308 "XFS: Attempted to mount file system using version 1 directory format");
309 return XFS_ERROR(ENOSYS);
310 }
311
312 /*
304 * Until this is fixed only page-sized or smaller data blocks work. 313 * Until this is fixed only page-sized or smaller data blocks work.
305 */ 314 */
306 if (unlikely(sbp->sb_blocksize > PAGE_SIZE)) { 315 if (unlikely(sbp->sb_blocksize > PAGE_SIZE)) {
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 5fc6201dd8e2..30dd08fb9f57 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -210,15 +210,16 @@ typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *,
210 struct xfs_bmap_free *); 210 struct xfs_bmap_free *);
211typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *); 211typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *);
212typedef int (*xfs_iomap_write_direct_t)( 212typedef int (*xfs_iomap_write_direct_t)(
213 void *, loff_t, size_t, int, 213 void *, xfs_off_t, size_t, int,
214 struct xfs_bmbt_irec *, int *, int); 214 struct xfs_bmbt_irec *, int *, int);
215typedef int (*xfs_iomap_write_delay_t)( 215typedef int (*xfs_iomap_write_delay_t)(
216 void *, loff_t, size_t, int, 216 void *, xfs_off_t, size_t, int,
217 struct xfs_bmbt_irec *, int *); 217 struct xfs_bmbt_irec *, int *);
218typedef int (*xfs_iomap_write_allocate_t)( 218typedef int (*xfs_iomap_write_allocate_t)(
219 void *, struct xfs_bmbt_irec *, int *); 219 void *, xfs_off_t, size_t,
220 struct xfs_bmbt_irec *, int *);
220typedef int (*xfs_iomap_write_unwritten_t)( 221typedef int (*xfs_iomap_write_unwritten_t)(
221 void *, loff_t, size_t); 222 void *, xfs_off_t, size_t);
222typedef uint (*xfs_lck_map_shared_t)(void *); 223typedef uint (*xfs_lck_map_shared_t)(void *);
223typedef void (*xfs_lock_t)(void *, uint); 224typedef void (*xfs_lock_t)(void *, uint);
224typedef void (*xfs_lock_demote_t)(void *, uint); 225typedef void (*xfs_lock_demote_t)(void *, uint);
@@ -258,9 +259,9 @@ typedef struct xfs_ioops {
258#define XFS_IOMAP_WRITE_DELAY(mp, io, offset, count, flags, mval, nmap) \ 259#define XFS_IOMAP_WRITE_DELAY(mp, io, offset, count, flags, mval, nmap) \
259 (*(mp)->m_io_ops.xfs_iomap_write_delay) \ 260 (*(mp)->m_io_ops.xfs_iomap_write_delay) \
260 ((io)->io_obj, offset, count, flags, mval, nmap) 261 ((io)->io_obj, offset, count, flags, mval, nmap)
261#define XFS_IOMAP_WRITE_ALLOCATE(mp, io, mval, nmap) \ 262#define XFS_IOMAP_WRITE_ALLOCATE(mp, io, offset, count, mval, nmap) \
262 (*(mp)->m_io_ops.xfs_iomap_write_allocate) \ 263 (*(mp)->m_io_ops.xfs_iomap_write_allocate) \
263 ((io)->io_obj, mval, nmap) 264 ((io)->io_obj, offset, count, mval, nmap)
264#define XFS_IOMAP_WRITE_UNWRITTEN(mp, io, offset, count) \ 265#define XFS_IOMAP_WRITE_UNWRITTEN(mp, io, offset, count) \
265 (*(mp)->m_io_ops.xfs_iomap_write_unwritten) \ 266 (*(mp)->m_io_ops.xfs_iomap_write_unwritten) \
266 ((io)->io_obj, offset, count) 267 ((io)->io_obj, offset, count)
@@ -428,10 +429,10 @@ typedef struct xfs_mount {
428#define XFS_WRITEIO_LOG_LARGE 16 429#define XFS_WRITEIO_LOG_LARGE 16
429 430
430/* 431/*
431 * Max and min values for UIO and mount-option defined I/O sizes; 432 * Max and min values for mount-option defined I/O
432 * min value can't be less than a page. Currently unused. 433 * preallocation sizes.
433 */ 434 */
434#define XFS_MAX_IO_LOG 16 /* 64K */ 435#define XFS_MAX_IO_LOG 30 /* 1G */
435#define XFS_MIN_IO_LOG PAGE_SHIFT 436#define XFS_MIN_IO_LOG PAGE_SHIFT
436 437
437/* 438/*
diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h
index 04609d27ea51..e4bf711e48ff 100644
--- a/fs/xfs/xfs_types.h
+++ b/fs/xfs/xfs_types.h
@@ -63,6 +63,7 @@ typedef __u64 xfs_ino_t; /* <inode> type */
63typedef __s64 xfs_daddr_t; /* <disk address> type */ 63typedef __s64 xfs_daddr_t; /* <disk address> type */
64typedef char * xfs_caddr_t; /* <core address> type */ 64typedef char * xfs_caddr_t; /* <core address> type */
65typedef __u32 xfs_dev_t; 65typedef __u32 xfs_dev_t;
66typedef __u32 xfs_nlink_t;
66 67
67/* __psint_t is the same size as a pointer */ 68/* __psint_t is the same size as a pointer */
68#if (BITS_PER_LONG == 32) 69#if (BITS_PER_LONG == 32)
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
index 816b945fa0ea..d1f8146a06ea 100644
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -147,7 +147,7 @@ xfs_dir_ialloc(
147 xfs_inode_t *dp, /* directory within whose allocate 147 xfs_inode_t *dp, /* directory within whose allocate
148 the inode. */ 148 the inode. */
149 mode_t mode, 149 mode_t mode,
150 nlink_t nlink, 150 xfs_nlink_t nlink,
151 xfs_dev_t rdev, 151 xfs_dev_t rdev,
152 cred_t *credp, 152 cred_t *credp,
153 prid_t prid, /* project id */ 153 prid_t prid, /* project id */
diff --git a/fs/xfs/xfs_utils.h b/fs/xfs/xfs_utils.h
index e1ed6a588000..01d98b4b7af7 100644
--- a/fs/xfs/xfs_utils.h
+++ b/fs/xfs/xfs_utils.h
@@ -42,7 +42,7 @@ extern int xfs_get_dir_entry (vname_t *, xfs_inode_t **);
42extern int xfs_dir_lookup_int (bhv_desc_t *, uint, vname_t *, xfs_ino_t *, 42extern int xfs_dir_lookup_int (bhv_desc_t *, uint, vname_t *, xfs_ino_t *,
43 xfs_inode_t **); 43 xfs_inode_t **);
44extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *); 44extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *);
45extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, nlink_t, 45extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t,
46 xfs_dev_t, cred_t *, prid_t, int, 46 xfs_dev_t, cred_t *, prid_t, int,
47 xfs_inode_t **, int *); 47 xfs_inode_t **, int *);
48extern int xfs_droplink (xfs_trans_t *, xfs_inode_t *); 48extern int xfs_droplink (xfs_trans_t *, xfs_inode_t *);
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index 00aae9c6a904..b53736650100 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -1649,6 +1649,7 @@ xfs_vget(
1649#define MNTOPT_SWIDTH "swidth" /* data volume stripe width */ 1649#define MNTOPT_SWIDTH "swidth" /* data volume stripe width */
1650#define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */ 1650#define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */
1651#define MNTOPT_MTPT "mtpt" /* filesystem mount point */ 1651#define MNTOPT_MTPT "mtpt" /* filesystem mount point */
1652#define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */
1652#define MNTOPT_IHASHSIZE "ihashsize" /* size of inode hash table */ 1653#define MNTOPT_IHASHSIZE "ihashsize" /* size of inode hash table */
1653#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */ 1654#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */
1654#define MNTOPT_NOLOGFLUSH "nologflush" /* don't hard flush on log writes */ 1655#define MNTOPT_NOLOGFLUSH "nologflush" /* don't hard flush on log writes */
@@ -1657,6 +1658,28 @@ xfs_vget(
1657#define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */ 1658#define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */
1658#define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */ 1659#define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */
1659 1660
1661STATIC unsigned long
1662suffix_strtoul(const char *cp, char **endp, unsigned int base)
1663{
1664 int last, shift_left_factor = 0;
1665 char *value = (char *)cp;
1666
1667 last = strlen(value) - 1;
1668 if (value[last] == 'K' || value[last] == 'k') {
1669 shift_left_factor = 10;
1670 value[last] = '\0';
1671 }
1672 if (value[last] == 'M' || value[last] == 'm') {
1673 shift_left_factor = 20;
1674 value[last] = '\0';
1675 }
1676 if (value[last] == 'G' || value[last] == 'g') {
1677 shift_left_factor = 30;
1678 value[last] = '\0';
1679 }
1680
1681 return simple_strtoul(cp, endp, base) << shift_left_factor;
1682}
1660 1683
1661int 1684int
1662xfs_parseargs( 1685xfs_parseargs(
@@ -1688,60 +1711,60 @@ xfs_parseargs(
1688 if (!strcmp(this_char, MNTOPT_LOGBUFS)) { 1711 if (!strcmp(this_char, MNTOPT_LOGBUFS)) {
1689 if (!value || !*value) { 1712 if (!value || !*value) {
1690 printk("XFS: %s option requires an argument\n", 1713 printk("XFS: %s option requires an argument\n",
1691 MNTOPT_LOGBUFS); 1714 this_char);
1692 return EINVAL; 1715 return EINVAL;
1693 } 1716 }
1694 args->logbufs = simple_strtoul(value, &eov, 10); 1717 args->logbufs = simple_strtoul(value, &eov, 10);
1695 } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) { 1718 } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) {
1696 int last, in_kilobytes = 0;
1697
1698 if (!value || !*value) { 1719 if (!value || !*value) {
1699 printk("XFS: %s option requires an argument\n", 1720 printk("XFS: %s option requires an argument\n",
1700 MNTOPT_LOGBSIZE); 1721 this_char);
1701 return EINVAL; 1722 return EINVAL;
1702 } 1723 }
1703 last = strlen(value) - 1; 1724 args->logbufsize = suffix_strtoul(value, &eov, 10);
1704 if (value[last] == 'K' || value[last] == 'k') {
1705 in_kilobytes = 1;
1706 value[last] = '\0';
1707 }
1708 args->logbufsize = simple_strtoul(value, &eov, 10);
1709 if (in_kilobytes)
1710 args->logbufsize <<= 10;
1711 } else if (!strcmp(this_char, MNTOPT_LOGDEV)) { 1725 } else if (!strcmp(this_char, MNTOPT_LOGDEV)) {
1712 if (!value || !*value) { 1726 if (!value || !*value) {
1713 printk("XFS: %s option requires an argument\n", 1727 printk("XFS: %s option requires an argument\n",
1714 MNTOPT_LOGDEV); 1728 this_char);
1715 return EINVAL; 1729 return EINVAL;
1716 } 1730 }
1717 strncpy(args->logname, value, MAXNAMELEN); 1731 strncpy(args->logname, value, MAXNAMELEN);
1718 } else if (!strcmp(this_char, MNTOPT_MTPT)) { 1732 } else if (!strcmp(this_char, MNTOPT_MTPT)) {
1719 if (!value || !*value) { 1733 if (!value || !*value) {
1720 printk("XFS: %s option requires an argument\n", 1734 printk("XFS: %s option requires an argument\n",
1721 MNTOPT_MTPT); 1735 this_char);
1722 return EINVAL; 1736 return EINVAL;
1723 } 1737 }
1724 strncpy(args->mtpt, value, MAXNAMELEN); 1738 strncpy(args->mtpt, value, MAXNAMELEN);
1725 } else if (!strcmp(this_char, MNTOPT_RTDEV)) { 1739 } else if (!strcmp(this_char, MNTOPT_RTDEV)) {
1726 if (!value || !*value) { 1740 if (!value || !*value) {
1727 printk("XFS: %s option requires an argument\n", 1741 printk("XFS: %s option requires an argument\n",
1728 MNTOPT_RTDEV); 1742 this_char);
1729 return EINVAL; 1743 return EINVAL;
1730 } 1744 }
1731 strncpy(args->rtname, value, MAXNAMELEN); 1745 strncpy(args->rtname, value, MAXNAMELEN);
1732 } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) { 1746 } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) {
1733 if (!value || !*value) { 1747 if (!value || !*value) {
1734 printk("XFS: %s option requires an argument\n", 1748 printk("XFS: %s option requires an argument\n",
1735 MNTOPT_BIOSIZE); 1749 this_char);
1736 return EINVAL; 1750 return EINVAL;
1737 } 1751 }
1738 iosize = simple_strtoul(value, &eov, 10); 1752 iosize = simple_strtoul(value, &eov, 10);
1739 args->flags |= XFSMNT_IOSIZE; 1753 args->flags |= XFSMNT_IOSIZE;
1740 args->iosizelog = (uint8_t) iosize; 1754 args->iosizelog = (uint8_t) iosize;
1755 } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) {
1756 if (!value || !*value) {
1757 printk("XFS: %s option requires an argument\n",
1758 this_char);
1759 return EINVAL;
1760 }
1761 iosize = suffix_strtoul(value, &eov, 10);
1762 args->flags |= XFSMNT_IOSIZE;
1763 args->iosizelog = ffs(iosize) - 1;
1741 } else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) { 1764 } else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) {
1742 if (!value || !*value) { 1765 if (!value || !*value) {
1743 printk("XFS: %s option requires an argument\n", 1766 printk("XFS: %s option requires an argument\n",
1744 this_char); 1767 this_char);
1745 return EINVAL; 1768 return EINVAL;
1746 } 1769 }
1747 args->flags |= XFSMNT_IHASHSIZE; 1770 args->flags |= XFSMNT_IHASHSIZE;
@@ -1756,7 +1779,7 @@ xfs_parseargs(
1756 args->flags |= XFSMNT_INO64; 1779 args->flags |= XFSMNT_INO64;
1757#if !XFS_BIG_INUMS 1780#if !XFS_BIG_INUMS
1758 printk("XFS: %s option not allowed on this system\n", 1781 printk("XFS: %s option not allowed on this system\n",
1759 MNTOPT_INO64); 1782 this_char);
1760 return EINVAL; 1783 return EINVAL;
1761#endif 1784#endif
1762 } else if (!strcmp(this_char, MNTOPT_NOALIGN)) { 1785 } else if (!strcmp(this_char, MNTOPT_NOALIGN)) {
@@ -1766,14 +1789,14 @@ xfs_parseargs(
1766 } else if (!strcmp(this_char, MNTOPT_SUNIT)) { 1789 } else if (!strcmp(this_char, MNTOPT_SUNIT)) {
1767 if (!value || !*value) { 1790 if (!value || !*value) {
1768 printk("XFS: %s option requires an argument\n", 1791 printk("XFS: %s option requires an argument\n",
1769 MNTOPT_SUNIT); 1792 this_char);
1770 return EINVAL; 1793 return EINVAL;
1771 } 1794 }
1772 dsunit = simple_strtoul(value, &eov, 10); 1795 dsunit = simple_strtoul(value, &eov, 10);
1773 } else if (!strcmp(this_char, MNTOPT_SWIDTH)) { 1796 } else if (!strcmp(this_char, MNTOPT_SWIDTH)) {
1774 if (!value || !*value) { 1797 if (!value || !*value) {
1775 printk("XFS: %s option requires an argument\n", 1798 printk("XFS: %s option requires an argument\n",
1776 MNTOPT_SWIDTH); 1799 this_char);
1777 return EINVAL; 1800 return EINVAL;
1778 } 1801 }
1779 dswidth = simple_strtoul(value, &eov, 10); 1802 dswidth = simple_strtoul(value, &eov, 10);
@@ -1781,7 +1804,7 @@ xfs_parseargs(
1781 args->flags &= ~XFSMNT_32BITINODES; 1804 args->flags &= ~XFSMNT_32BITINODES;
1782#if !XFS_BIG_INUMS 1805#if !XFS_BIG_INUMS
1783 printk("XFS: %s option not allowed on this system\n", 1806 printk("XFS: %s option not allowed on this system\n",
1784 MNTOPT_64BITINODE); 1807 this_char);
1785 return EINVAL; 1808 return EINVAL;
1786#endif 1809#endif
1787 } else if (!strcmp(this_char, MNTOPT_NOUUID)) { 1810 } else if (!strcmp(this_char, MNTOPT_NOUUID)) {
@@ -1877,7 +1900,7 @@ xfs_showargs(
1877 seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", mp->m_ihsize); 1900 seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", mp->m_ihsize);
1878 1901
1879 if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) 1902 if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
1880 seq_printf(m, "," MNTOPT_BIOSIZE "=%d", mp->m_writeio_log); 1903 seq_printf(m, "," MNTOPT_ALLOCSIZE "=%d", 1<<mp->m_writeio_log);
1881 1904
1882 if (mp->m_logbufs > 0) 1905 if (mp->m_logbufs > 0)
1883 seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs); 1906 seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs);
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 70092963ca9e..25a526629b12 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -305,7 +305,7 @@ xfs_setattr(
305 int mandlock_before, mandlock_after; 305 int mandlock_before, mandlock_after;
306 struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; 306 struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2;
307 int file_owner; 307 int file_owner;
308 int need_iolock = (flags & ATTR_DMI) == 0; 308 int need_iolock = 1;
309 309
310 vp = BHV_TO_VNODE(bdp); 310 vp = BHV_TO_VNODE(bdp);
311 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 311 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
@@ -384,6 +384,9 @@ xfs_setattr(
384 */ 384 */
385 tp = NULL; 385 tp = NULL;
386 lock_flags = XFS_ILOCK_EXCL; 386 lock_flags = XFS_ILOCK_EXCL;
387 ASSERT(flags & ATTR_NOLOCK ? flags & ATTR_DMI : 1);
388 if (flags & ATTR_NOLOCK)
389 need_iolock = 0;
387 if (!(mask & XFS_AT_SIZE)) { 390 if (!(mask & XFS_AT_SIZE)) {
388 if ((mask != (XFS_AT_CTIME|XFS_AT_ATIME|XFS_AT_MTIME)) || 391 if ((mask != (XFS_AT_CTIME|XFS_AT_ATIME|XFS_AT_MTIME)) ||
389 (mp->m_flags & XFS_MOUNT_WSYNC)) { 392 (mp->m_flags & XFS_MOUNT_WSYNC)) {
@@ -4320,7 +4323,7 @@ xfs_free_file_space(
4320 int rt; 4323 int rt;
4321 xfs_fileoff_t startoffset_fsb; 4324 xfs_fileoff_t startoffset_fsb;
4322 xfs_trans_t *tp; 4325 xfs_trans_t *tp;
4323 int need_iolock = (attr_flags & ATTR_DMI) == 0; 4326 int need_iolock = 1;
4324 4327
4325 vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); 4328 vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address);
4326 mp = ip->i_mount; 4329 mp = ip->i_mount;
@@ -4348,8 +4351,12 @@ xfs_free_file_space(
4348 return(error); 4351 return(error);
4349 } 4352 }
4350 4353
4354 ASSERT(attr_flags & ATTR_NOLOCK ? attr_flags & ATTR_DMI : 1);
4355 if (attr_flags & ATTR_NOLOCK)
4356 need_iolock = 0;
4351 if (need_iolock) 4357 if (need_iolock)
4352 xfs_ilock(ip, XFS_IOLOCK_EXCL); 4358 xfs_ilock(ip, XFS_IOLOCK_EXCL);
4359
4353 rounding = MAX((__uint8_t)(1 << mp->m_sb.sb_blocklog), 4360 rounding = MAX((__uint8_t)(1 << mp->m_sb.sb_blocklog),
4354 (__uint8_t)NBPP); 4361 (__uint8_t)NBPP);
4355 ilen = len + (offset & (rounding - 1)); 4362 ilen = len + (offset & (rounding - 1));
diff --git a/include/asm-um/ptrace-i386.h b/include/asm-um/ptrace-i386.h
index 9e47590ec293..04222f35c43e 100644
--- a/include/asm-um/ptrace-i386.h
+++ b/include/asm-um/ptrace-i386.h
@@ -6,6 +6,8 @@
6#ifndef __UM_PTRACE_I386_H 6#ifndef __UM_PTRACE_I386_H
7#define __UM_PTRACE_I386_H 7#define __UM_PTRACE_I386_H
8 8
9#define HOST_AUDIT_ARCH AUDIT_ARCH_I386
10
9#include "sysdep/ptrace.h" 11#include "sysdep/ptrace.h"
10#include "asm/ptrace-generic.h" 12#include "asm/ptrace-generic.h"
11 13
diff --git a/include/asm-um/ptrace-x86_64.h b/include/asm-um/ptrace-x86_64.h
index c34be39b78b2..be51219a8ffe 100644
--- a/include/asm-um/ptrace-x86_64.h
+++ b/include/asm-um/ptrace-x86_64.h
@@ -14,6 +14,8 @@
14#include "asm/ptrace-generic.h" 14#include "asm/ptrace-generic.h"
15#undef signal_fault 15#undef signal_fault
16 16
17#define HOST_AUDIT_ARCH AUDIT_ARCH_X86_64
18
17void signal_fault(struct pt_regs_subarch *regs, void *frame, char *where); 19void signal_fault(struct pt_regs_subarch *regs, void *frame, char *where);
18 20
19#define FS_BASE (21 * sizeof(unsigned long)) 21#define FS_BASE (21 * sizeof(unsigned long))
diff --git a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h
index bffb577bc54e..a10ea155907e 100644
--- a/include/asm-um/thread_info.h
+++ b/include/asm-um/thread_info.h
@@ -72,12 +72,14 @@ static inline struct thread_info *current_thread_info(void)
72 */ 72 */
73#define TIF_RESTART_BLOCK 4 73#define TIF_RESTART_BLOCK 4
74#define TIF_MEMDIE 5 74#define TIF_MEMDIE 5
75#define TIF_SYSCALL_AUDIT 6
75 76
76#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) 77#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
77#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) 78#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
78#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) 79#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
79#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) 80#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
80#define _TIF_RESTART_BLOCK (1 << TIF_RESTART_BLOCK) 81#define _TIF_MEMDIE (1 << TIF_MEMDIE)
82#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
81 83
82#endif 84#endif
83 85
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 3628f7cfb178..19f04b049798 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -1,4 +1,4 @@
1/* audit.h -- Auditing support -*- linux-c -*- 1/* audit.h -- Auditing support
2 * 2 *
3 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina. 3 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
4 * All Rights Reserved. 4 * All Rights Reserved.
@@ -24,6 +24,9 @@
24#ifndef _LINUX_AUDIT_H_ 24#ifndef _LINUX_AUDIT_H_
25#define _LINUX_AUDIT_H_ 25#define _LINUX_AUDIT_H_
26 26
27#include <linux/sched.h>
28#include <linux/elf.h>
29
27/* Request and reply types */ 30/* Request and reply types */
28#define AUDIT_GET 1000 /* Get status */ 31#define AUDIT_GET 1000 /* Get status */
29#define AUDIT_SET 1001 /* Set status (enable/disable/auditd) */ 32#define AUDIT_SET 1001 /* Set status (enable/disable/auditd) */
@@ -67,6 +70,7 @@
67#define AUDIT_FSGID 8 70#define AUDIT_FSGID 8
68#define AUDIT_LOGINUID 9 71#define AUDIT_LOGINUID 9
69#define AUDIT_PERS 10 72#define AUDIT_PERS 10
73#define AUDIT_ARCH 11
70 74
71 /* These are ONLY useful when checking 75 /* These are ONLY useful when checking
72 * at syscall exit time (AUDIT_AT_EXIT). */ 76 * at syscall exit time (AUDIT_AT_EXIT). */
@@ -96,6 +100,38 @@
96#define AUDIT_FAIL_PRINTK 1 100#define AUDIT_FAIL_PRINTK 1
97#define AUDIT_FAIL_PANIC 2 101#define AUDIT_FAIL_PANIC 2
98 102
103/* distinguish syscall tables */
104#define __AUDIT_ARCH_64BIT 0x80000000
105#define __AUDIT_ARCH_LE 0x40000000
106#define AUDIT_ARCH_ALPHA (EM_ALPHA|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
107#define AUDIT_ARCH_ARM (EM_ARM|__AUDIT_ARCH_LE)
108#define AUDIT_ARCH_ARMEB (EM_ARM)
109#define AUDIT_ARCH_CRIS (EM_CRIS|__AUDIT_ARCH_LE)
110#define AUDIT_ARCH_FRV (EM_FRV)
111#define AUDIT_ARCH_H8300 (EM_H8_300)
112#define AUDIT_ARCH_I386 (EM_386|__AUDIT_ARCH_LE)
113#define AUDIT_ARCH_IA64 (EM_IA_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
114#define AUDIT_ARCH_M32R (EM_M32R)
115#define AUDIT_ARCH_M68K (EM_68K)
116#define AUDIT_ARCH_MIPS (EM_MIPS)
117#define AUDIT_ARCH_MIPSEL (EM_MIPS|__AUDIT_ARCH_LE)
118#define AUDIT_ARCH_MIPS64 (EM_MIPS|__AUDIT_ARCH_64BIT)
119#define AUDIT_ARCH_MIPSEL64 (EM_MIPS|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
120#define AUDIT_ARCH_PARISC (EM_PARISC)
121#define AUDIT_ARCH_PARISC64 (EM_PARISC|__AUDIT_ARCH_64BIT)
122#define AUDIT_ARCH_PPC (EM_PPC)
123#define AUDIT_ARCH_PPC64 (EM_PPC64|__AUDIT_ARCH_64BIT)
124#define AUDIT_ARCH_S390 (EM_S390)
125#define AUDIT_ARCH_S390X (EM_S390|__AUDIT_ARCH_64BIT)
126#define AUDIT_ARCH_SH (EM_SH)
127#define AUDIT_ARCH_SHEL (EM_SH|__AUDIT_ARCH_LE)
128#define AUDIT_ARCH_SH64 (EM_SH|__AUDIT_ARCH_64BIT)
129#define AUDIT_ARCH_SHEL64 (EM_SH|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
130#define AUDIT_ARCH_SPARC (EM_SPARC)
131#define AUDIT_ARCH_SPARC64 (EM_SPARC64|__AUDIT_ARCH_64BIT)
132#define AUDIT_ARCH_V850 (EM_V850|__AUDIT_ARCH_LE)
133#define AUDIT_ARCH_X86_64 (EM_X86_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
134
99#ifndef __KERNEL__ 135#ifndef __KERNEL__
100struct audit_message { 136struct audit_message {
101 struct nlmsghdr nlh; 137 struct nlmsghdr nlh;
@@ -129,32 +165,36 @@ struct audit_buffer;
129struct audit_context; 165struct audit_context;
130struct inode; 166struct inode;
131 167
168#define AUDITSC_INVALID 0
169#define AUDITSC_SUCCESS 1
170#define AUDITSC_FAILURE 2
171#define AUDITSC_RESULT(x) ( ((long)(x))<0?AUDITSC_FAILURE:AUDITSC_SUCCESS )
132#ifdef CONFIG_AUDITSYSCALL 172#ifdef CONFIG_AUDITSYSCALL
133/* These are defined in auditsc.c */ 173/* These are defined in auditsc.c */
134 /* Public API */ 174 /* Public API */
135extern int audit_alloc(struct task_struct *task); 175extern int audit_alloc(struct task_struct *task);
136extern void audit_free(struct task_struct *task); 176extern void audit_free(struct task_struct *task);
137extern void audit_syscall_entry(struct task_struct *task, 177extern void audit_syscall_entry(struct task_struct *task, int arch,
138 int major, unsigned long a0, unsigned long a1, 178 int major, unsigned long a0, unsigned long a1,
139 unsigned long a2, unsigned long a3); 179 unsigned long a2, unsigned long a3);
140extern void audit_syscall_exit(struct task_struct *task, int return_code); 180extern void audit_syscall_exit(struct task_struct *task, int failed, long return_code);
141extern void audit_getname(const char *name); 181extern void audit_getname(const char *name);
142extern void audit_putname(const char *name); 182extern void audit_putname(const char *name);
143extern void audit_inode(const char *name, const struct inode *inode); 183extern void audit_inode(const char *name, const struct inode *inode);
144 184
145 /* Private API (for audit.c only) */ 185 /* Private API (for audit.c only) */
146extern int audit_receive_filter(int type, int pid, int uid, int seq, 186extern int audit_receive_filter(int type, int pid, int uid, int seq,
147 void *data); 187 void *data, uid_t loginuid);
148extern void audit_get_stamp(struct audit_context *ctx, 188extern void audit_get_stamp(struct audit_context *ctx,
149 struct timespec *t, int *serial); 189 struct timespec *t, unsigned int *serial);
150extern int audit_set_loginuid(struct audit_context *ctx, uid_t loginuid); 190extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid);
151extern uid_t audit_get_loginuid(struct audit_context *ctx); 191extern uid_t audit_get_loginuid(struct audit_context *ctx);
152extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode); 192extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
153#else 193#else
154#define audit_alloc(t) ({ 0; }) 194#define audit_alloc(t) ({ 0; })
155#define audit_free(t) do { ; } while (0) 195#define audit_free(t) do { ; } while (0)
156#define audit_syscall_entry(t,a,b,c,d,e) do { ; } while (0) 196#define audit_syscall_entry(t,ta,a,b,c,d,e) do { ; } while (0)
157#define audit_syscall_exit(t,r) do { ; } while (0) 197#define audit_syscall_exit(t,f,r) do { ; } while (0)
158#define audit_getname(n) do { ; } while (0) 198#define audit_getname(n) do { ; } while (0)
159#define audit_putname(n) do { ; } while (0) 199#define audit_putname(n) do { ; } while (0)
160#define audit_inode(n,i) do { ; } while (0) 200#define audit_inode(n,i) do { ; } while (0)
@@ -174,11 +214,15 @@ extern void audit_log_format(struct audit_buffer *ab,
174 const char *fmt, ...) 214 const char *fmt, ...)
175 __attribute__((format(printf,2,3))); 215 __attribute__((format(printf,2,3)));
176extern void audit_log_end(struct audit_buffer *ab); 216extern void audit_log_end(struct audit_buffer *ab);
217extern void audit_log_hex(struct audit_buffer *ab,
218 const unsigned char *buf,
219 size_t len);
220extern void audit_log_untrustedstring(struct audit_buffer *ab,
221 const char *string);
177extern void audit_log_d_path(struct audit_buffer *ab, 222extern void audit_log_d_path(struct audit_buffer *ab,
178 const char *prefix, 223 const char *prefix,
179 struct dentry *dentry, 224 struct dentry *dentry,
180 struct vfsmount *vfsmnt); 225 struct vfsmount *vfsmnt);
181
182 /* Private API (for auditsc.c only) */ 226 /* Private API (for auditsc.c only) */
183extern void audit_send_reply(int pid, int seq, int type, 227extern void audit_send_reply(int pid, int seq, int type,
184 int done, int multi, 228 int done, int multi,
@@ -190,6 +234,8 @@ extern void audit_log_lost(const char *message);
190#define audit_log_vformat(b,f,a) do { ; } while (0) 234#define audit_log_vformat(b,f,a) do { ; } while (0)
191#define audit_log_format(b,f,...) do { ; } while (0) 235#define audit_log_format(b,f,...) do { ; } while (0)
192#define audit_log_end(b) do { ; } while (0) 236#define audit_log_end(b) do { ; } while (0)
237#define audit_log_hex(a,b,l) do { ; } while (0)
238#define audit_log_untrustedstring(a,s) do { ; } while (0)
193#define audit_log_d_path(b,p,d,v) do { ; } while (0) 239#define audit_log_d_path(b,p,d,v) do { ; } while (0)
194#endif 240#endif
195#endif 241#endif
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index f731abdc1a29..b2738ac8bc99 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -110,6 +110,7 @@ struct netlink_skb_parms
110 __u32 dst_pid; 110 __u32 dst_pid;
111 __u32 dst_groups; 111 __u32 dst_groups;
112 kernel_cap_t eff_cap; 112 kernel_cap_t eff_cap;
113 __u32 loginuid; /* Login (audit) uid */
113}; 114};
114 115
115#define NETLINK_CB(skb) (*(struct netlink_skb_parms*)&((skb)->cb)) 116#define NETLINK_CB(skb) (*(struct netlink_skb_parms*)&((skb)->cb))
diff --git a/init/Kconfig b/init/Kconfig
index 40d286d1d118..d920baed109a 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -173,7 +173,7 @@ config AUDIT
173 173
174config AUDITSYSCALL 174config AUDITSYSCALL
175 bool "Enable system-call auditing support" 175 bool "Enable system-call auditing support"
176 depends on AUDIT && (X86 || PPC64 || ARCH_S390 || IA64) 176 depends on AUDIT && (X86 || PPC64 || ARCH_S390 || IA64 || UML)
177 default y if SECURITY_SELINUX 177 default y if SECURITY_SELINUX
178 help 178 help
179 Enable low-overhead system-call auditing infrastructure that 179 Enable low-overhead system-call auditing infrastructure that
diff --git a/kernel/audit.c b/kernel/audit.c
index ac26d4d960d3..9c4f1af0c794 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1,4 +1,4 @@
1/* audit.c -- Auditing support -*- linux-c -*- 1/* audit.c -- Auditing support
2 * Gateway between the kernel (e.g., selinux) and the user-space audit daemon. 2 * Gateway between the kernel (e.g., selinux) and the user-space audit daemon.
3 * System-call specific features have moved to auditsc.c 3 * System-call specific features have moved to auditsc.c
4 * 4 *
@@ -38,7 +38,7 @@
38 * 6) Support low-overhead kernel-based filtering to minimize the 38 * 6) Support low-overhead kernel-based filtering to minimize the
39 * information that must be passed to user-space. 39 * information that must be passed to user-space.
40 * 40 *
41 * Example user-space utilities: http://people.redhat.com/faith/audit/ 41 * Example user-space utilities: http://people.redhat.com/sgrubb/audit/
42 */ 42 */
43 43
44#include <linux/init.h> 44#include <linux/init.h>
@@ -142,7 +142,6 @@ struct audit_buffer {
142 int total; 142 int total;
143 int type; 143 int type;
144 int pid; 144 int pid;
145 int count; /* Times requeued */
146}; 145};
147 146
148void audit_set_type(struct audit_buffer *ab, int type) 147void audit_set_type(struct audit_buffer *ab, int type)
@@ -239,36 +238,36 @@ void audit_log_lost(const char *message)
239 238
240} 239}
241 240
242static int audit_set_rate_limit(int limit) 241static int audit_set_rate_limit(int limit, uid_t loginuid)
243{ 242{
244 int old = audit_rate_limit; 243 int old = audit_rate_limit;
245 audit_rate_limit = limit; 244 audit_rate_limit = limit;
246 audit_log(current->audit_context, "audit_rate_limit=%d old=%d", 245 audit_log(NULL, "audit_rate_limit=%d old=%d by auid %u",
247 audit_rate_limit, old); 246 audit_rate_limit, old, loginuid);
248 return old; 247 return old;
249} 248}
250 249
251static int audit_set_backlog_limit(int limit) 250static int audit_set_backlog_limit(int limit, uid_t loginuid)
252{ 251{
253 int old = audit_backlog_limit; 252 int old = audit_backlog_limit;
254 audit_backlog_limit = limit; 253 audit_backlog_limit = limit;
255 audit_log(current->audit_context, "audit_backlog_limit=%d old=%d", 254 audit_log(NULL, "audit_backlog_limit=%d old=%d by auid %u",
256 audit_backlog_limit, old); 255 audit_backlog_limit, old, loginuid);
257 return old; 256 return old;
258} 257}
259 258
260static int audit_set_enabled(int state) 259static int audit_set_enabled(int state, uid_t loginuid)
261{ 260{
262 int old = audit_enabled; 261 int old = audit_enabled;
263 if (state != 0 && state != 1) 262 if (state != 0 && state != 1)
264 return -EINVAL; 263 return -EINVAL;
265 audit_enabled = state; 264 audit_enabled = state;
266 audit_log(current->audit_context, "audit_enabled=%d old=%d", 265 audit_log(NULL, "audit_enabled=%d old=%d by auid %u",
267 audit_enabled, old); 266 audit_enabled, old, loginuid);
268 return old; 267 return old;
269} 268}
270 269
271static int audit_set_failure(int state) 270static int audit_set_failure(int state, uid_t loginuid)
272{ 271{
273 int old = audit_failure; 272 int old = audit_failure;
274 if (state != AUDIT_FAIL_SILENT 273 if (state != AUDIT_FAIL_SILENT
@@ -276,8 +275,8 @@ static int audit_set_failure(int state)
276 && state != AUDIT_FAIL_PANIC) 275 && state != AUDIT_FAIL_PANIC)
277 return -EINVAL; 276 return -EINVAL;
278 audit_failure = state; 277 audit_failure = state;
279 audit_log(current->audit_context, "audit_failure=%d old=%d", 278 audit_log(NULL, "audit_failure=%d old=%d by auid %u",
280 audit_failure, old); 279 audit_failure, old, loginuid);
281 return old; 280 return old;
282} 281}
283 282
@@ -344,6 +343,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
344 int err; 343 int err;
345 struct audit_buffer *ab; 344 struct audit_buffer *ab;
346 u16 msg_type = nlh->nlmsg_type; 345 u16 msg_type = nlh->nlmsg_type;
346 uid_t loginuid; /* loginuid of sender */
347 347
348 err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type); 348 err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type);
349 if (err) 349 if (err)
@@ -351,6 +351,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
351 351
352 pid = NETLINK_CREDS(skb)->pid; 352 pid = NETLINK_CREDS(skb)->pid;
353 uid = NETLINK_CREDS(skb)->uid; 353 uid = NETLINK_CREDS(skb)->uid;
354 loginuid = NETLINK_CB(skb).loginuid;
354 seq = nlh->nlmsg_seq; 355 seq = nlh->nlmsg_seq;
355 data = NLMSG_DATA(nlh); 356 data = NLMSG_DATA(nlh);
356 357
@@ -371,34 +372,36 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
371 return -EINVAL; 372 return -EINVAL;
372 status_get = (struct audit_status *)data; 373 status_get = (struct audit_status *)data;
373 if (status_get->mask & AUDIT_STATUS_ENABLED) { 374 if (status_get->mask & AUDIT_STATUS_ENABLED) {
374 err = audit_set_enabled(status_get->enabled); 375 err = audit_set_enabled(status_get->enabled, loginuid);
375 if (err < 0) return err; 376 if (err < 0) return err;
376 } 377 }
377 if (status_get->mask & AUDIT_STATUS_FAILURE) { 378 if (status_get->mask & AUDIT_STATUS_FAILURE) {
378 err = audit_set_failure(status_get->failure); 379 err = audit_set_failure(status_get->failure, loginuid);
379 if (err < 0) return err; 380 if (err < 0) return err;
380 } 381 }
381 if (status_get->mask & AUDIT_STATUS_PID) { 382 if (status_get->mask & AUDIT_STATUS_PID) {
382 int old = audit_pid; 383 int old = audit_pid;
383 audit_pid = status_get->pid; 384 audit_pid = status_get->pid;
384 audit_log(current->audit_context, 385 audit_log(NULL, "audit_pid=%d old=%d by auid %u",
385 "audit_pid=%d old=%d", audit_pid, old); 386 audit_pid, old, loginuid);
386 } 387 }
387 if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) 388 if (status_get->mask & AUDIT_STATUS_RATE_LIMIT)
388 audit_set_rate_limit(status_get->rate_limit); 389 audit_set_rate_limit(status_get->rate_limit, loginuid);
389 if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) 390 if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT)
390 audit_set_backlog_limit(status_get->backlog_limit); 391 audit_set_backlog_limit(status_get->backlog_limit,
392 loginuid);
391 break; 393 break;
392 case AUDIT_USER: 394 case AUDIT_USER:
393 ab = audit_log_start(NULL); 395 ab = audit_log_start(NULL);
394 if (!ab) 396 if (!ab)
395 break; /* audit_panic has been called */ 397 break; /* audit_panic has been called */
396 audit_log_format(ab, 398 audit_log_format(ab,
397 "user pid=%d uid=%d length=%d msg='%.1024s'", 399 "user pid=%d uid=%d length=%d loginuid=%u"
400 " msg='%.1024s'",
398 pid, uid, 401 pid, uid,
399 (int)(nlh->nlmsg_len 402 (int)(nlh->nlmsg_len
400 - ((char *)data - (char *)nlh)), 403 - ((char *)data - (char *)nlh)),
401 (char *)data); 404 loginuid, (char *)data);
402 ab->type = AUDIT_USER; 405 ab->type = AUDIT_USER;
403 ab->pid = pid; 406 ab->pid = pid;
404 audit_log_end(ab); 407 audit_log_end(ab);
@@ -411,7 +414,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
411 case AUDIT_LIST: 414 case AUDIT_LIST:
412#ifdef CONFIG_AUDITSYSCALL 415#ifdef CONFIG_AUDITSYSCALL
413 err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, 416 err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid,
414 uid, seq, data); 417 uid, seq, data, loginuid);
415#else 418#else
416 err = -EOPNOTSUPP; 419 err = -EOPNOTSUPP;
417#endif 420#endif
@@ -480,7 +483,7 @@ static void audit_log_move(struct audit_buffer *ab)
480 if (ab->len == 0) 483 if (ab->len == 0)
481 return; 484 return;
482 485
483 skb = skb_peek(&ab->sklist); 486 skb = skb_peek_tail(&ab->sklist);
484 if (!skb || skb_tailroom(skb) <= ab->len + extra) { 487 if (!skb || skb_tailroom(skb) <= ab->len + extra) {
485 skb = alloc_skb(2 * ab->len + extra, GFP_ATOMIC); 488 skb = alloc_skb(2 * ab->len + extra, GFP_ATOMIC);
486 if (!skb) { 489 if (!skb) {
@@ -519,9 +522,9 @@ static inline int audit_log_drain(struct audit_buffer *ab)
519 retval = netlink_unicast(audit_sock, skb, audit_pid, 522 retval = netlink_unicast(audit_sock, skb, audit_pid,
520 MSG_DONTWAIT); 523 MSG_DONTWAIT);
521 } 524 }
522 if (retval == -EAGAIN && ab->count < 5) { 525 if (retval == -EAGAIN &&
523 ++ab->count; 526 (atomic_read(&audit_backlog)) < audit_backlog_limit) {
524 skb_queue_tail(&ab->sklist, skb); 527 skb_queue_head(&ab->sklist, skb);
525 audit_log_end_irq(ab); 528 audit_log_end_irq(ab);
526 return 1; 529 return 1;
527 } 530 }
@@ -537,8 +540,8 @@ static inline int audit_log_drain(struct audit_buffer *ab)
537 if (!audit_pid) { /* No daemon */ 540 if (!audit_pid) { /* No daemon */
538 int offset = ab->nlh ? NLMSG_SPACE(0) : 0; 541 int offset = ab->nlh ? NLMSG_SPACE(0) : 0;
539 int len = skb->len - offset; 542 int len = skb->len - offset;
540 printk(KERN_ERR "%*.*s\n", 543 skb->data[offset + len] = '\0';
541 len, len, skb->data + offset); 544 printk(KERN_ERR "%s\n", skb->data + offset);
542 } 545 }
543 kfree_skb(skb); 546 kfree_skb(skb);
544 ab->nlh = NULL; 547 ab->nlh = NULL;
@@ -617,7 +620,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx)
617 struct audit_buffer *ab = NULL; 620 struct audit_buffer *ab = NULL;
618 unsigned long flags; 621 unsigned long flags;
619 struct timespec t; 622 struct timespec t;
620 int serial = 0; 623 unsigned int serial;
621 624
622 if (!audit_initialized) 625 if (!audit_initialized)
623 return NULL; 626 return NULL;
@@ -659,15 +662,16 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx)
659 ab->total = 0; 662 ab->total = 0;
660 ab->type = AUDIT_KERNEL; 663 ab->type = AUDIT_KERNEL;
661 ab->pid = 0; 664 ab->pid = 0;
662 ab->count = 0;
663 665
664#ifdef CONFIG_AUDITSYSCALL 666#ifdef CONFIG_AUDITSYSCALL
665 if (ab->ctx) 667 if (ab->ctx)
666 audit_get_stamp(ab->ctx, &t, &serial); 668 audit_get_stamp(ab->ctx, &t, &serial);
667 else 669 else
668#endif 670#endif
671 {
669 t = CURRENT_TIME; 672 t = CURRENT_TIME;
670 673 serial = 0;
674 }
671 audit_log_format(ab, "audit(%lu.%03lu:%u): ", 675 audit_log_format(ab, "audit(%lu.%03lu:%u): ",
672 t.tv_sec, t.tv_nsec/1000000, serial); 676 t.tv_sec, t.tv_nsec/1000000, serial);
673 return ab; 677 return ab;
@@ -717,6 +721,29 @@ void audit_log_format(struct audit_buffer *ab, const char *fmt, ...)
717 va_end(args); 721 va_end(args);
718} 722}
719 723
724void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, size_t len)
725{
726 int i;
727
728 for (i=0; i<len; i++)
729 audit_log_format(ab, "%02x", buf[i]);
730}
731
732void audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
733{
734 const unsigned char *p = string;
735
736 while (*p) {
737 if (*p == '"' || *p == ' ' || *p < 0x20 || *p > 0x7f) {
738 audit_log_hex(ab, string, strlen(string));
739 return;
740 }
741 p++;
742 }
743 audit_log_format(ab, "\"%s\"", string);
744}
745
746
720/* This is a helper-function to print the d_path without using a static 747/* This is a helper-function to print the d_path without using a static
721 * buffer or allocating another buffer in addition to the one in 748 * buffer or allocating another buffer in addition to the one in
722 * audit_buffer. */ 749 * audit_buffer. */
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 6f1931381bc9..37b3ac94bc47 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1,4 +1,4 @@
1/* auditsc.c -- System-call auditing support -*- linux-c -*- 1/* auditsc.c -- System-call auditing support
2 * Handles all system-call specific auditing features. 2 * Handles all system-call specific auditing features.
3 * 3 *
4 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina. 4 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
@@ -123,7 +123,7 @@ struct audit_context {
123 int major; /* syscall number */ 123 int major; /* syscall number */
124 unsigned long argv[4]; /* syscall arguments */ 124 unsigned long argv[4]; /* syscall arguments */
125 int return_valid; /* return code is valid */ 125 int return_valid; /* return code is valid */
126 int return_code;/* syscall return code */ 126 long return_code;/* syscall return code */
127 int auditable; /* 1 if record should be written */ 127 int auditable; /* 1 if record should be written */
128 int name_count; 128 int name_count;
129 struct audit_names names[AUDIT_NAMES]; 129 struct audit_names names[AUDIT_NAMES];
@@ -135,6 +135,7 @@ struct audit_context {
135 uid_t uid, euid, suid, fsuid; 135 uid_t uid, euid, suid, fsuid;
136 gid_t gid, egid, sgid, fsgid; 136 gid_t gid, egid, sgid, fsgid;
137 unsigned long personality; 137 unsigned long personality;
138 int arch;
138 139
139#if AUDIT_DEBUG 140#if AUDIT_DEBUG
140 int put_count; 141 int put_count;
@@ -250,7 +251,8 @@ static int audit_copy_rule(struct audit_rule *d, struct audit_rule *s)
250 return 0; 251 return 0;
251} 252}
252 253
253int audit_receive_filter(int type, int pid, int uid, int seq, void *data) 254int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
255 uid_t loginuid)
254{ 256{
255 u32 flags; 257 u32 flags;
256 struct audit_entry *entry; 258 struct audit_entry *entry;
@@ -285,6 +287,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data)
285 err = audit_add_rule(entry, &audit_entlist); 287 err = audit_add_rule(entry, &audit_entlist);
286 if (!err && (flags & AUDIT_AT_EXIT)) 288 if (!err && (flags & AUDIT_AT_EXIT))
287 err = audit_add_rule(entry, &audit_extlist); 289 err = audit_add_rule(entry, &audit_extlist);
290 audit_log(NULL, "auid %u added an audit rule\n", loginuid);
288 break; 291 break;
289 case AUDIT_DEL: 292 case AUDIT_DEL:
290 flags =((struct audit_rule *)data)->flags; 293 flags =((struct audit_rule *)data)->flags;
@@ -294,6 +297,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data)
294 err = audit_del_rule(data, &audit_entlist); 297 err = audit_del_rule(data, &audit_entlist);
295 if (!err && (flags & AUDIT_AT_EXIT)) 298 if (!err && (flags & AUDIT_AT_EXIT))
296 err = audit_del_rule(data, &audit_extlist); 299 err = audit_del_rule(data, &audit_extlist);
300 audit_log(NULL, "auid %u removed an audit rule\n", loginuid);
297 break; 301 break;
298 default: 302 default:
299 return -EINVAL; 303 return -EINVAL;
@@ -348,6 +352,10 @@ static int audit_filter_rules(struct task_struct *tsk,
348 case AUDIT_PERS: 352 case AUDIT_PERS:
349 result = (tsk->personality == value); 353 result = (tsk->personality == value);
350 break; 354 break;
355 case AUDIT_ARCH:
356 if (ctx)
357 result = (ctx->arch == value);
358 break;
351 359
352 case AUDIT_EXIT: 360 case AUDIT_EXIT:
353 if (ctx && ctx->return_valid) 361 if (ctx && ctx->return_valid)
@@ -355,7 +363,7 @@ static int audit_filter_rules(struct task_struct *tsk,
355 break; 363 break;
356 case AUDIT_SUCCESS: 364 case AUDIT_SUCCESS:
357 if (ctx && ctx->return_valid) 365 if (ctx && ctx->return_valid)
358 result = (ctx->return_code >= 0); 366 result = (ctx->return_valid == AUDITSC_SUCCESS);
359 break; 367 break;
360 case AUDIT_DEVMAJOR: 368 case AUDIT_DEVMAJOR:
361 if (ctx) { 369 if (ctx) {
@@ -648,8 +656,11 @@ static void audit_log_exit(struct audit_context *context)
648 audit_log_format(ab, "syscall=%d", context->major); 656 audit_log_format(ab, "syscall=%d", context->major);
649 if (context->personality != PER_LINUX) 657 if (context->personality != PER_LINUX)
650 audit_log_format(ab, " per=%lx", context->personality); 658 audit_log_format(ab, " per=%lx", context->personality);
659 audit_log_format(ab, " arch=%x", context->arch);
651 if (context->return_valid) 660 if (context->return_valid)
652 audit_log_format(ab, " exit=%d", context->return_code); 661 audit_log_format(ab, " success=%s exit=%ld",
662 (context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
663 context->return_code);
653 audit_log_format(ab, 664 audit_log_format(ab,
654 " a0=%lx a1=%lx a2=%lx a3=%lx items=%d" 665 " a0=%lx a1=%lx a2=%lx a3=%lx items=%d"
655 " pid=%d loginuid=%d uid=%d gid=%d" 666 " pid=%d loginuid=%d uid=%d gid=%d"
@@ -696,9 +707,10 @@ static void audit_log_exit(struct audit_context *context)
696 if (!ab) 707 if (!ab)
697 continue; /* audit_panic has been called */ 708 continue; /* audit_panic has been called */
698 audit_log_format(ab, "item=%d", i); 709 audit_log_format(ab, "item=%d", i);
699 if (context->names[i].name) 710 if (context->names[i].name) {
700 audit_log_format(ab, " name=%s", 711 audit_log_format(ab, " name=");
701 context->names[i].name); 712 audit_log_untrustedstring(ab, context->names[i].name);
713 }
702 if (context->names[i].ino != (unsigned long)-1) 714 if (context->names[i].ino != (unsigned long)-1)
703 audit_log_format(ab, " inode=%lu dev=%02x:%02x mode=%#o" 715 audit_log_format(ab, " inode=%lu dev=%02x:%02x mode=%#o"
704 " uid=%d gid=%d rdev=%02x:%02x", 716 " uid=%d gid=%d rdev=%02x:%02x",
@@ -772,7 +784,7 @@ static inline unsigned int audit_serial(void)
772 * then the record will be written at syscall exit time (otherwise, it 784 * then the record will be written at syscall exit time (otherwise, it
773 * will only be written if another part of the kernel requests that it 785 * will only be written if another part of the kernel requests that it
774 * be written). */ 786 * be written). */
775void audit_syscall_entry(struct task_struct *tsk, int major, 787void audit_syscall_entry(struct task_struct *tsk, int arch, int major,
776 unsigned long a1, unsigned long a2, 788 unsigned long a1, unsigned long a2,
777 unsigned long a3, unsigned long a4) 789 unsigned long a3, unsigned long a4)
778{ 790{
@@ -826,6 +838,7 @@ void audit_syscall_entry(struct task_struct *tsk, int major,
826 if (!audit_enabled) 838 if (!audit_enabled)
827 return; 839 return;
828 840
841 context->arch = arch;
829 context->major = major; 842 context->major = major;
830 context->argv[0] = a1; 843 context->argv[0] = a1;
831 context->argv[1] = a2; 844 context->argv[1] = a2;
@@ -849,13 +862,13 @@ void audit_syscall_entry(struct task_struct *tsk, int major,
849 * filtering, or because some other part of the kernel write an audit 862 * filtering, or because some other part of the kernel write an audit
850 * message), then write out the syscall information. In call cases, 863 * message), then write out the syscall information. In call cases,
851 * free the names stored from getname(). */ 864 * free the names stored from getname(). */
852void audit_syscall_exit(struct task_struct *tsk, int return_code) 865void audit_syscall_exit(struct task_struct *tsk, int valid, long return_code)
853{ 866{
854 struct audit_context *context; 867 struct audit_context *context;
855 868
856 get_task_struct(tsk); 869 get_task_struct(tsk);
857 task_lock(tsk); 870 task_lock(tsk);
858 context = audit_get_context(tsk, 1, return_code); 871 context = audit_get_context(tsk, valid, return_code);
859 task_unlock(tsk); 872 task_unlock(tsk);
860 873
861 /* Not having a context here is ok, since the parent may have 874 /* Not having a context here is ok, since the parent may have
@@ -868,6 +881,7 @@ void audit_syscall_exit(struct task_struct *tsk, int return_code)
868 881
869 context->in_syscall = 0; 882 context->in_syscall = 0;
870 context->auditable = 0; 883 context->auditable = 0;
884
871 if (context->previous) { 885 if (context->previous) {
872 struct audit_context *new_context = context->previous; 886 struct audit_context *new_context = context->previous;
873 context->previous = NULL; 887 context->previous = NULL;
@@ -981,7 +995,7 @@ void audit_inode(const char *name, const struct inode *inode)
981} 995}
982 996
983void audit_get_stamp(struct audit_context *ctx, 997void audit_get_stamp(struct audit_context *ctx,
984 struct timespec *t, int *serial) 998 struct timespec *t, unsigned int *serial)
985{ 999{
986 if (ctx) { 1000 if (ctx) {
987 t->tv_sec = ctx->ctime.tv_sec; 1001 t->tv_sec = ctx->ctime.tv_sec;
@@ -996,20 +1010,21 @@ void audit_get_stamp(struct audit_context *ctx,
996 1010
997extern int audit_set_type(struct audit_buffer *ab, int type); 1011extern int audit_set_type(struct audit_buffer *ab, int type);
998 1012
999int audit_set_loginuid(struct audit_context *ctx, uid_t loginuid) 1013int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
1000{ 1014{
1001 if (ctx) { 1015 if (task->audit_context) {
1002 struct audit_buffer *ab; 1016 struct audit_buffer *ab;
1003 1017
1004 ab = audit_log_start(NULL); 1018 ab = audit_log_start(NULL);
1005 if (ab) { 1019 if (ab) {
1006 audit_log_format(ab, "login pid=%d uid=%u " 1020 audit_log_format(ab, "login pid=%d uid=%u "
1007 "old loginuid=%u new loginuid=%u", 1021 "old loginuid=%u new loginuid=%u",
1008 ctx->pid, ctx->uid, ctx->loginuid, loginuid); 1022 task->pid, task->uid,
1023 task->audit_context->loginuid, loginuid);
1009 audit_set_type(ab, AUDIT_LOGIN); 1024 audit_set_type(ab, AUDIT_LOGIN);
1010 audit_log_end(ab); 1025 audit_log_end(ab);
1011 } 1026 }
1012 ctx->loginuid = loginuid; 1027 task->audit_context->loginuid = loginuid;
1013 } 1028 }
1014 return 0; 1029 return 0;
1015} 1030}
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 4ee392066148..733bf52cef3e 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -49,6 +49,8 @@
49#include <linux/bitops.h> 49#include <linux/bitops.h>
50#include <linux/mm.h> 50#include <linux/mm.h>
51#include <linux/types.h> 51#include <linux/types.h>
52#include <linux/audit.h>
53
52#include <net/sock.h> 54#include <net/sock.h>
53#include <net/scm.h> 55#include <net/scm.h>
54 56
@@ -904,6 +906,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
904 NETLINK_CB(skb).groups = nlk->groups; 906 NETLINK_CB(skb).groups = nlk->groups;
905 NETLINK_CB(skb).dst_pid = dst_pid; 907 NETLINK_CB(skb).dst_pid = dst_pid;
906 NETLINK_CB(skb).dst_groups = dst_groups; 908 NETLINK_CB(skb).dst_groups = dst_groups;
909 NETLINK_CB(skb).loginuid = audit_get_loginuid(current->audit_context);
907 memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); 910 memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
908 911
909 /* What can I do? Netlink is asynchronous, so that 912 /* What can I do? Netlink is asynchronous, so that
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 5a5ddc40f36c..09abb891d11f 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -2,7 +2,7 @@
2# Kernel configuration targets 2# Kernel configuration targets
3# These targets are used from top-level makefile 3# These targets are used from top-level makefile
4 4
5.PHONY: oldconfig xconfig gconfig menuconfig config silentoldconfig 5.PHONY: oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config
6 6
7xconfig: $(obj)/qconf 7xconfig: $(obj)/qconf
8 $< arch/$(ARCH)/Kconfig 8 $< arch/$(ARCH)/Kconfig
@@ -23,6 +23,13 @@ oldconfig: $(obj)/conf
23silentoldconfig: $(obj)/conf 23silentoldconfig: $(obj)/conf
24 $< -s arch/$(ARCH)/Kconfig 24 $< -s arch/$(ARCH)/Kconfig
25 25
26update-po-config: $(obj)/kxgettext
27 xgettext --default-domain=linux \
28 --add-comments --keyword=_ --keyword=N_ \
29 --files-from=scripts/kconfig/POTFILES.in \
30 -o scripts/kconfig/linux.pot
31 scripts/kconfig/kxgettext arch/$(ARCH)/Kconfig >> scripts/kconfig/linux.pot
32
26.PHONY: randconfig allyesconfig allnoconfig allmodconfig defconfig 33.PHONY: randconfig allyesconfig allnoconfig allmodconfig defconfig
27 34
28randconfig: $(obj)/conf 35randconfig: $(obj)/conf
@@ -72,9 +79,10 @@ help:
72# Based on GTK which needs to be installed to compile it 79# Based on GTK which needs to be installed to compile it
73# object files used by all kconfig flavours 80# object files used by all kconfig flavours
74 81
75hostprogs-y := conf mconf qconf gconf 82hostprogs-y := conf mconf qconf gconf kxgettext
76conf-objs := conf.o zconf.tab.o 83conf-objs := conf.o zconf.tab.o
77mconf-objs := mconf.o zconf.tab.o 84mconf-objs := mconf.o zconf.tab.o
85kxgettext-objs := kxgettext.o zconf.tab.o
78 86
79ifeq ($(MAKECMDGOALS),xconfig) 87ifeq ($(MAKECMDGOALS),xconfig)
80 qconf-target := 1 88 qconf-target := 1
@@ -107,7 +115,7 @@ HOSTLOADLIBES_gconf = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --libs`
107HOSTCFLAGS_gconf.o = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --cflags` \ 115HOSTCFLAGS_gconf.o = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --cflags` \
108 -D LKC_DIRECT_LINK 116 -D LKC_DIRECT_LINK
109 117
110$(obj)/conf.o $(obj)/mconf.o $(obj)/qconf.o $(obj)/gconf.o: $(obj)/zconf.tab.h 118$(obj)/conf.o $(obj)/mconf.o $(obj)/qconf.o $(obj)/gconf.o $(obj)/kxgettext: $(obj)/zconf.tab.h
111 119
112$(obj)/zconf.tab.h: $(src)/zconf.tab.h_shipped 120$(obj)/zconf.tab.h: $(src)/zconf.tab.h_shipped
113$(obj)/zconf.tab.c: $(src)/zconf.tab.c_shipped 121$(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 000000000000..cc94e46a79e8
--- /dev/null
+++ b/scripts/kconfig/POTFILES.in
@@ -0,0 +1,5 @@
1scripts/kconfig/mconf.c
2scripts/kconfig/conf.c
3scripts/kconfig/confdata.c
4scripts/kconfig/gconf.c
5scripts/kconfig/qconf.cc
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index a494d1aeb9f9..70e7264c6942 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -34,7 +34,7 @@ static int conf_cnt;
34static signed char line[128]; 34static signed char line[128];
35static struct menu *rootEntry; 35static struct menu *rootEntry;
36 36
37static char nohelp_text[] = "Sorry, no help available for this option yet.\n"; 37static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n");
38 38
39static void strip(signed char *str) 39static void strip(signed char *str)
40{ 40{
@@ -56,9 +56,9 @@ static void strip(signed char *str)
56static void check_stdin(void) 56static void check_stdin(void)
57{ 57{
58 if (!valid_stdin && input_mode == ask_silent) { 58 if (!valid_stdin && input_mode == ask_silent) {
59 printf("aborted!\n\n"); 59 printf(_("aborted!\n\n"));
60 printf("Console input/output is redirected. "); 60 printf(_("Console input/output is redirected. "));
61 printf("Run 'make oldconfig' to update configuration.\n\n"); 61 printf(_("Run 'make oldconfig' to update configuration.\n\n"));
62 exit(1); 62 exit(1);
63 } 63 }
64} 64}
@@ -470,7 +470,7 @@ static void check_conf(struct menu *menu)
470 if (sym) { 470 if (sym) {
471 if (sym_is_changable(sym) && !sym_has_value(sym)) { 471 if (sym_is_changable(sym) && !sym_has_value(sym)) {
472 if (!conf_cnt++) 472 if (!conf_cnt++)
473 printf("*\n* Restart config...\n*\n"); 473 printf(_("*\n* Restart config...\n*\n"));
474 rootEntry = menu_get_parent_menu(menu); 474 rootEntry = menu_get_parent_menu(menu);
475 conf(rootEntry); 475 conf(rootEntry);
476 } 476 }
@@ -504,7 +504,7 @@ int main(int ac, char **av)
504 input_mode = set_default; 504 input_mode = set_default;
505 defconfig_file = av[i++]; 505 defconfig_file = av[i++];
506 if (!defconfig_file) { 506 if (!defconfig_file) {
507 printf("%s: No default config file specified\n", 507 printf(_("%s: No default config file specified\n"),
508 av[0]); 508 av[0]);
509 exit(1); 509 exit(1);
510 } 510 }
@@ -530,7 +530,7 @@ int main(int ac, char **av)
530 } 530 }
531 name = av[i]; 531 name = av[i];
532 if (!name) { 532 if (!name) {
533 printf("%s: Kconfig file missing\n", av[0]); 533 printf(_("%s: Kconfig file missing\n"), av[0]);
534 } 534 }
535 conf_parse(name); 535 conf_parse(name);
536 //zconfdump(stdout); 536 //zconfdump(stdout);
@@ -547,12 +547,12 @@ int main(int ac, char **av)
547 break; 547 break;
548 case ask_silent: 548 case ask_silent:
549 if (stat(".config", &tmpstat)) { 549 if (stat(".config", &tmpstat)) {
550 printf("***\n" 550 printf(_("***\n"
551 "*** You have not yet configured your kernel!\n" 551 "*** You have not yet configured your kernel!\n"
552 "***\n" 552 "***\n"
553 "*** Please run some configurator (e.g. \"make oldconfig\" or\n" 553 "*** Please run some configurator (e.g. \"make oldconfig\" or\n"
554 "*** \"make menuconfig\" or \"make xconfig\").\n" 554 "*** \"make menuconfig\" or \"make xconfig\").\n"
555 "***\n"); 555 "***\n"));
556 exit(1); 556 exit(1);
557 } 557 }
558 case ask_all: 558 case ask_all:
@@ -576,7 +576,7 @@ int main(int ac, char **av)
576 check_conf(&rootmenu); 576 check_conf(&rootmenu);
577 } while (conf_cnt); 577 } while (conf_cnt);
578 if (conf_write(NULL)) { 578 if (conf_write(NULL)) {
579 fprintf(stderr, "\n*** Error during writing of the kernel configuration.\n\n"); 579 fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
580 return 1; 580 return 1;
581 } 581 }
582 return 0; 582 return 0;
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 1e82ae390a69..2755c459d780 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -88,9 +88,9 @@ int conf_read(const char *name)
88 name = conf_expand_value(name); 88 name = conf_expand_value(name);
89 in = zconf_fopen(name); 89 in = zconf_fopen(name);
90 if (in) { 90 if (in) {
91 printf("#\n" 91 printf(_("#\n"
92 "# using defaults found in %s\n" 92 "# using defaults found in %s\n"
93 "#\n", name); 93 "#\n"), name);
94 break; 94 break;
95 } 95 }
96 } 96 }
@@ -312,11 +312,11 @@ int conf_write(const char *name)
312 if (env && *env) 312 if (env && *env)
313 use_timestamp = 0; 313 use_timestamp = 0;
314 314
315 fprintf(out, "#\n" 315 fprintf(out, _("#\n"
316 "# Automatically generated make config: don't edit\n" 316 "# Automatically generated make config: don't edit\n"
317 "# Linux kernel version: %s\n" 317 "# Linux kernel version: %s\n"
318 "%s%s" 318 "%s%s"
319 "#\n", 319 "#\n"),
320 sym_get_string_value(sym), 320 sym_get_string_value(sym),
321 use_timestamp ? "# " : "", 321 use_timestamp ? "# " : "",
322 use_timestamp ? ctime(&now) : ""); 322 use_timestamp ? ctime(&now) : "");
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c
index 6fdbe6e3ce0d..ad6b12043874 100644
--- a/scripts/kconfig/gconf.c
+++ b/scripts/kconfig/gconf.c
@@ -41,7 +41,7 @@ static gboolean resizeable = FALSE;
41static gboolean config_changed = FALSE; 41static gboolean config_changed = FALSE;
42 42
43static char nohelp_text[] = 43static char nohelp_text[] =
44 "Sorry, no help available for this option yet.\n"; 44 N_("Sorry, no help available for this option yet.\n");
45 45
46GtkWidget *main_wnd = NULL; 46GtkWidget *main_wnd = NULL;
47GtkWidget *tree1_w = NULL; // left frame 47GtkWidget *tree1_w = NULL; // left frame
@@ -193,7 +193,7 @@ void init_main_window(const gchar * glade_file)
193 193
194 xml = glade_xml_new(glade_file, "window1", NULL); 194 xml = glade_xml_new(glade_file, "window1", NULL);
195 if (!xml) 195 if (!xml)
196 g_error("GUI loading failed !\n"); 196 g_error(_("GUI loading failed !\n"));
197 glade_xml_signal_autoconnect(xml); 197 glade_xml_signal_autoconnect(xml);
198 198
199 main_wnd = glade_xml_get_widget(xml, "window1"); 199 main_wnd = glade_xml_get_widget(xml, "window1");
@@ -275,7 +275,7 @@ void init_main_window(const gchar * glade_file)
275 /*"style", PANGO_STYLE_OBLIQUE, */ 275 /*"style", PANGO_STYLE_OBLIQUE, */
276 NULL); 276 NULL);
277 277
278 sprintf(title, "Linux Kernel v%s Configuration", 278 sprintf(title, _("Linux Kernel v%s Configuration"),
279 getenv("KERNELRELEASE")); 279 getenv("KERNELRELEASE"));
280 gtk_window_set_title(GTK_WINDOW(main_wnd), title); 280 gtk_window_set_title(GTK_WINDOW(main_wnd), title);
281 281
@@ -325,7 +325,7 @@ void init_left_tree(void)
325 325
326 column = gtk_tree_view_column_new(); 326 column = gtk_tree_view_column_new();
327 gtk_tree_view_append_column(view, column); 327 gtk_tree_view_append_column(view, column);
328 gtk_tree_view_column_set_title(column, "Options"); 328 gtk_tree_view_column_set_title(column, _("Options"));
329 329
330 renderer = gtk_cell_renderer_toggle_new(); 330 renderer = gtk_cell_renderer_toggle_new();
331 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), 331 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
@@ -370,7 +370,7 @@ void init_right_tree(void)
370 370
371 column = gtk_tree_view_column_new(); 371 column = gtk_tree_view_column_new();
372 gtk_tree_view_append_column(view, column); 372 gtk_tree_view_append_column(view, column);
373 gtk_tree_view_column_set_title(column, "Options"); 373 gtk_tree_view_column_set_title(column, _("Options"));
374 374
375 renderer = gtk_cell_renderer_pixbuf_new(); 375 renderer = gtk_cell_renderer_pixbuf_new();
376 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), 376 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
@@ -401,7 +401,7 @@ void init_right_tree(void)
401 401
402 renderer = gtk_cell_renderer_text_new(); 402 renderer = gtk_cell_renderer_text_new();
403 gtk_tree_view_insert_column_with_attributes(view, -1, 403 gtk_tree_view_insert_column_with_attributes(view, -1,
404 "Name", renderer, 404 _("Name"), renderer,
405 "text", COL_NAME, 405 "text", COL_NAME,
406 "foreground-gdk", 406 "foreground-gdk",
407 COL_COLOR, NULL); 407 COL_COLOR, NULL);
@@ -425,7 +425,7 @@ void init_right_tree(void)
425 COL_COLOR, NULL); 425 COL_COLOR, NULL);
426 renderer = gtk_cell_renderer_text_new(); 426 renderer = gtk_cell_renderer_text_new();
427 gtk_tree_view_insert_column_with_attributes(view, -1, 427 gtk_tree_view_insert_column_with_attributes(view, -1,
428 "Value", renderer, 428 _("Value"), renderer,
429 "text", COL_VALUE, 429 "text", COL_VALUE,
430 "editable", 430 "editable",
431 COL_EDIT, 431 COL_EDIT,
@@ -466,15 +466,15 @@ static void text_insert_help(struct menu *menu)
466 GtkTextIter start, end; 466 GtkTextIter start, end;
467 const char *prompt = menu_get_prompt(menu); 467 const char *prompt = menu_get_prompt(menu);
468 gchar *name; 468 gchar *name;
469 const char *help = nohelp_text; 469 const char *help = _(nohelp_text);
470 470
471 if (!menu->sym) 471 if (!menu->sym)
472 help = ""; 472 help = "";
473 else if (menu->sym->help) 473 else if (menu->sym->help)
474 help = menu->sym->help; 474 help = _(menu->sym->help);
475 475
476 if (menu->sym && menu->sym->name) 476 if (menu->sym && menu->sym->name)
477 name = g_strdup_printf(menu->sym->name); 477 name = g_strdup_printf(_(menu->sym->name));
478 else 478 else
479 name = g_strdup(""); 479 name = g_strdup("");
480 480
@@ -530,7 +530,7 @@ gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event,
530 if (config_changed == FALSE) 530 if (config_changed == FALSE)
531 return FALSE; 531 return FALSE;
532 532
533 dialog = gtk_dialog_new_with_buttons("Warning !", 533 dialog = gtk_dialog_new_with_buttons(_("Warning !"),
534 GTK_WINDOW(main_wnd), 534 GTK_WINDOW(main_wnd),
535 (GtkDialogFlags) 535 (GtkDialogFlags)
536 (GTK_DIALOG_MODAL | 536 (GTK_DIALOG_MODAL |
@@ -544,7 +544,7 @@ gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event,
544 gtk_dialog_set_default_response(GTK_DIALOG(dialog), 544 gtk_dialog_set_default_response(GTK_DIALOG(dialog),
545 GTK_RESPONSE_CANCEL); 545 GTK_RESPONSE_CANCEL);
546 546
547 label = gtk_label_new("\nSave configuration ?\n"); 547 label = gtk_label_new(_("\nSave configuration ?\n"));
548 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label); 548 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
549 gtk_widget_show(label); 549 gtk_widget_show(label);
550 550
@@ -604,7 +604,7 @@ load_filename(GtkFileSelection * file_selector, gpointer user_data)
604 (user_data)); 604 (user_data));
605 605
606 if (conf_read(fn)) 606 if (conf_read(fn))
607 text_insert_msg("Error", "Unable to load configuration !"); 607 text_insert_msg(_("Error"), _("Unable to load configuration !"));
608 else 608 else
609 display_tree(&rootmenu); 609 display_tree(&rootmenu);
610} 610}
@@ -613,7 +613,7 @@ void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data)
613{ 613{
614 GtkWidget *fs; 614 GtkWidget *fs;
615 615
616 fs = gtk_file_selection_new("Load file..."); 616 fs = gtk_file_selection_new(_("Load file..."));
617 g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), 617 g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
618 "clicked", 618 "clicked",
619 G_CALLBACK(load_filename), (gpointer) fs); 619 G_CALLBACK(load_filename), (gpointer) fs);
@@ -632,7 +632,7 @@ void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data)
632void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data) 632void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data)
633{ 633{
634 if (conf_write(NULL)) 634 if (conf_write(NULL))
635 text_insert_msg("Error", "Unable to save configuration !"); 635 text_insert_msg(_("Error"), _("Unable to save configuration !"));
636 636
637 config_changed = FALSE; 637 config_changed = FALSE;
638} 638}
@@ -647,7 +647,7 @@ store_filename(GtkFileSelection * file_selector, gpointer user_data)
647 (user_data)); 647 (user_data));
648 648
649 if (conf_write(fn)) 649 if (conf_write(fn))
650 text_insert_msg("Error", "Unable to save configuration !"); 650 text_insert_msg(_("Error"), _("Unable to save configuration !"));
651 651
652 gtk_widget_destroy(GTK_WIDGET(user_data)); 652 gtk_widget_destroy(GTK_WIDGET(user_data));
653} 653}
@@ -656,7 +656,7 @@ void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data)
656{ 656{
657 GtkWidget *fs; 657 GtkWidget *fs;
658 658
659 fs = gtk_file_selection_new("Save file as..."); 659 fs = gtk_file_selection_new(_("Save file as..."));
660 g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), 660 g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
661 "clicked", 661 "clicked",
662 G_CALLBACK(store_filename), (gpointer) fs); 662 G_CALLBACK(store_filename), (gpointer) fs);
@@ -740,7 +740,7 @@ on_show_debug_info1_activate(GtkMenuItem * menuitem, gpointer user_data)
740void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) 740void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
741{ 741{
742 GtkWidget *dialog; 742 GtkWidget *dialog;
743 const gchar *intro_text = 743 const gchar *intro_text = _(
744 "Welcome to gkc, the GTK+ graphical kernel configuration tool\n" 744 "Welcome to gkc, the GTK+ graphical kernel configuration tool\n"
745 "for Linux.\n" 745 "for Linux.\n"
746 "For each option, a blank box indicates the feature is disabled, a\n" 746 "For each option, a blank box indicates the feature is disabled, a\n"
@@ -756,7 +756,7 @@ void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
756 "option.\n" 756 "option.\n"
757 "\n" 757 "\n"
758 "Toggling Show Debug Info under the Options menu will show \n" 758 "Toggling Show Debug Info under the Options menu will show \n"
759 "the dependencies, which you can then match by examining other options."; 759 "the dependencies, which you can then match by examining other options.");
760 760
761 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), 761 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
762 GTK_DIALOG_DESTROY_WITH_PARENT, 762 GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -773,8 +773,8 @@ void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data)
773{ 773{
774 GtkWidget *dialog; 774 GtkWidget *dialog;
775 const gchar *about_text = 775 const gchar *about_text =
776 "gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n" 776 _("gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n"
777 "Based on the source code from Roman Zippel.\n"; 777 "Based on the source code from Roman Zippel.\n");
778 778
779 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), 779 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
780 GTK_DIALOG_DESTROY_WITH_PARENT, 780 GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -791,9 +791,9 @@ void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data)
791{ 791{
792 GtkWidget *dialog; 792 GtkWidget *dialog;
793 const gchar *license_text = 793 const gchar *license_text =
794 "gkc is released under the terms of the GNU GPL v2.\n" 794 _("gkc is released under the terms of the GNU GPL v2.\n"
795 "For more information, please see the source code or\n" 795 "For more information, please see the source code or\n"
796 "visit http://www.fsf.org/licenses/licenses.html\n"; 796 "visit http://www.fsf.org/licenses/licenses.html\n");
797 797
798 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), 798 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
799 GTK_DIALOG_DESTROY_WITH_PARENT, 799 GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -1579,6 +1579,10 @@ int main(int ac, char *av[])
1579 kconfig_load(); 1579 kconfig_load();
1580#endif 1580#endif
1581 1581
1582 bindtextdomain(PACKAGE, LOCALEDIR);
1583 bind_textdomain_codeset(PACKAGE, "UTF-8");
1584 textdomain(PACKAGE);
1585
1582 /* GTK stuffs */ 1586 /* GTK stuffs */
1583 gtk_set_locale(); 1587 gtk_set_locale();
1584 gtk_init(&ac, &av); 1588 gtk_init(&ac, &av);
diff --git a/scripts/kconfig/kxgettext.c b/scripts/kconfig/kxgettext.c
new file mode 100644
index 000000000000..1c88d7c6d5a7
--- /dev/null
+++ b/scripts/kconfig/kxgettext.c
@@ -0,0 +1,221 @@
1/*
2 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2005
3 *
4 * Released under the terms of the GNU GPL v2.0
5 */
6
7#include <stdlib.h>
8#include <string.h>
9
10#define LKC_DIRECT_LINK
11#include "lkc.h"
12
13static char *escape(const char* text, char *bf, int len)
14{
15 char *bfp = bf;
16 int multiline = strchr(text, '\n') != NULL;
17
18 *bfp++ = '"';
19 --len;
20
21 if (multiline) {
22 *bfp++ = '"';
23 *bfp++ = '\n';
24 *bfp++ = '"';
25 len -= 3;
26 }
27
28 while (*text != '\0' && len > 1) {
29 if (*text == '"')
30 *bfp++ = '\\';
31 else if (*text == '\n') {
32 *bfp++ = '\\';
33 *bfp++ = 'n';
34 *bfp++ = '"';
35 *bfp++ = '\n';
36 *bfp++ = '"';
37 len -= 5;
38 ++text;
39 goto next;
40 }
41 *bfp++ = *text++;
42next:
43 --len;
44 }
45
46 if (multiline)
47 bfp -= 3;
48
49 *bfp++ = '"';
50 *bfp = '\0';
51
52 return bf;
53}
54
55struct file_line {
56 struct file_line *next;
57 char* file;
58 int lineno;
59};
60
61static struct file_line *file_line__new(char *file, int lineno)
62{
63 struct file_line *self = malloc(sizeof(*self));
64
65 if (self == NULL)
66 goto out;
67
68 self->file = file;
69 self->lineno = lineno;
70 self->next = NULL;
71out:
72 return self;
73}
74
75struct message {
76 const char *msg;
77 const char *option;
78 struct message *next;
79 struct file_line *files;
80};
81
82static struct message *message__list;
83
84static struct message *message__new(const char *msg, char *option, char *file, int lineno)
85{
86 struct message *self = malloc(sizeof(*self));
87
88 if (self == NULL)
89 goto out;
90
91 self->files = file_line__new(file, lineno);
92 if (self->files == NULL)
93 goto out_fail;
94
95 self->msg = strdup(msg);
96 if (self->msg == NULL)
97 goto out_fail_msg;
98
99 self->option = option;
100 self->next = NULL;
101out:
102 return self;
103out_fail_msg:
104 free(self->files);
105out_fail:
106 free(self);
107 self = NULL;
108 goto out;
109}
110
111static struct message *mesage__find(const char *msg)
112{
113 struct message *m = message__list;
114
115 while (m != NULL) {
116 if (strcmp(m->msg, msg) == 0)
117 break;
118 m = m->next;
119 }
120
121 return m;
122}
123
124static int message__add_file_line(struct message *self, char *file, int lineno)
125{
126 int rc = -1;
127 struct file_line *fl = file_line__new(file, lineno);
128
129 if (fl == NULL)
130 goto out;
131
132 fl->next = self->files;
133 self->files = fl;
134 rc = 0;
135out:
136 return rc;
137}
138
139static int message__add(const char *msg, char *option, char *file, int lineno)
140{
141 int rc = 0;
142 char bf[16384];
143 char *escaped = escape(msg, bf, sizeof(bf));
144 struct message *m = mesage__find(escaped);
145
146 if (m != NULL)
147 rc = message__add_file_line(m, file, lineno);
148 else {
149 m = message__new(escaped, option, file, lineno);
150
151 if (m != NULL) {
152 m->next = message__list;
153 message__list = m;
154 } else
155 rc = -1;
156 }
157 return rc;
158}
159
160void menu_build_message_list(struct menu *menu)
161{
162 struct menu *child;
163
164 message__add(menu_get_prompt(menu), NULL,
165 menu->file == NULL ? "Root Menu" : menu->file->name,
166 menu->lineno);
167
168 if (menu->sym != NULL && menu->sym->help != NULL)
169 message__add(menu->sym->help, menu->sym->name,
170 menu->file == NULL ? "Root Menu" : menu->file->name,
171 menu->lineno);
172
173 for (child = menu->list; child != NULL; child = child->next)
174 if (child->prompt != NULL)
175 menu_build_message_list(child);
176}
177
178static void message__print_file_lineno(struct message *self)
179{
180 struct file_line *fl = self->files;
181
182 printf("\n#: %s:%d", fl->file, fl->lineno);
183 fl = fl->next;
184
185 while (fl != NULL) {
186 printf(", %s:%d", fl->file, fl->lineno);
187 fl = fl->next;
188 }
189
190 if (self->option != NULL)
191 printf(", %s:00000", self->option);
192
193 putchar('\n');
194}
195
196static void message__print_gettext_msgid_msgstr(struct message *self)
197{
198 message__print_file_lineno(self);
199
200 printf("msgid %s\n"
201 "msgstr \"\"\n", self->msg);
202}
203
204void menu__xgettext(void)
205{
206 struct message *m = message__list;
207
208 while (m != NULL) {
209 message__print_gettext_msgid_msgstr(m);
210 m = m->next;
211 }
212}
213
214int main(int ac, char **av)
215{
216 conf_parse(av[1]);
217
218 menu_build_message_list(menu_get_root_menu(NULL));
219 menu__xgettext();
220 return 0;
221}
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index b8a67fc9d647..8b84c42b49b5 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -8,6 +8,8 @@
8 8
9#include "expr.h" 9#include "expr.h"
10 10
11#include <libintl.h>
12
11#ifdef __cplusplus 13#ifdef __cplusplus
12extern "C" { 14extern "C" {
13#endif 15#endif
@@ -23,6 +25,12 @@ extern "C" {
23 25
24#define SRCTREE "srctree" 26#define SRCTREE "srctree"
25 27
28#define PACKAGE "linux"
29#define LOCALEDIR "/usr/share/locale"
30
31#define _(text) gettext(text)
32#define N_(text) (text)
33
26int zconfparse(void); 34int zconfparse(void);
27void zconfdump(FILE *out); 35void zconfdump(FILE *out);
28 36
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 730d316fe7fe..e5db10ca9564 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -4,6 +4,8 @@
4 * 4 *
5 * Introduced single menu mode (show all sub-menus in one large tree). 5 * Introduced single menu mode (show all sub-menus in one large tree).
6 * 2002-11-06 Petr Baudis <pasky@ucw.cz> 6 * 2002-11-06 Petr Baudis <pasky@ucw.cz>
7 *
8 * i18n, 2005, Arnaldo Carvalho de Melo <acme@conectiva.com.br>
7 */ 9 */
8 10
9#include <sys/ioctl.h> 11#include <sys/ioctl.h>
@@ -23,7 +25,7 @@
23#include "lkc.h" 25#include "lkc.h"
24 26
25static char menu_backtitle[128]; 27static char menu_backtitle[128];
26static const char mconf_readme[] = 28static const char mconf_readme[] = N_(
27"Overview\n" 29"Overview\n"
28"--------\n" 30"--------\n"
29"Some kernel features may be built directly into the kernel.\n" 31"Some kernel features may be built directly into the kernel.\n"
@@ -156,39 +158,39 @@ static const char mconf_readme[] =
156"\n" 158"\n"
157"Note that this mode can eventually be a little more CPU expensive\n" 159"Note that this mode can eventually be a little more CPU expensive\n"
158"(especially with a larger number of unrolled categories) than the\n" 160"(especially with a larger number of unrolled categories) than the\n"
159"default mode.\n", 161"default mode.\n"),
160menu_instructions[] = 162menu_instructions[] = N_(
161 "Arrow keys navigate the menu. " 163 "Arrow keys navigate the menu. "
162 "<Enter> selects submenus --->. " 164 "<Enter> selects submenus --->. "
163 "Highlighted letters are hotkeys. " 165 "Highlighted letters are hotkeys. "
164 "Pressing <Y> includes, <N> excludes, <M> modularizes features. " 166 "Pressing <Y> includes, <N> excludes, <M> modularizes features. "
165 "Press <Esc><Esc> to exit, <?> for Help, </> for Search. " 167 "Press <Esc><Esc> to exit, <?> for Help, </> for Search. "
166 "Legend: [*] built-in [ ] excluded <M> module < > module capable", 168 "Legend: [*] built-in [ ] excluded <M> module < > module capable"),
167radiolist_instructions[] = 169radiolist_instructions[] = N_(
168 "Use the arrow keys to navigate this window or " 170 "Use the arrow keys to navigate this window or "
169 "press the hotkey of the item you wish to select " 171 "press the hotkey of the item you wish to select "
170 "followed by the <SPACE BAR>. " 172 "followed by the <SPACE BAR>. "
171 "Press <?> for additional information about this option.", 173 "Press <?> for additional information about this option."),
172inputbox_instructions_int[] = 174inputbox_instructions_int[] = N_(
173 "Please enter a decimal value. " 175 "Please enter a decimal value. "
174 "Fractions will not be accepted. " 176 "Fractions will not be accepted. "
175 "Use the <TAB> key to move from the input field to the buttons below it.", 177 "Use the <TAB> key to move from the input field to the buttons below it."),
176inputbox_instructions_hex[] = 178inputbox_instructions_hex[] = N_(
177 "Please enter a hexadecimal value. " 179 "Please enter a hexadecimal value. "
178 "Use the <TAB> key to move from the input field to the buttons below it.", 180 "Use the <TAB> key to move from the input field to the buttons below it."),
179inputbox_instructions_string[] = 181inputbox_instructions_string[] = N_(
180 "Please enter a string value. " 182 "Please enter a string value. "
181 "Use the <TAB> key to move from the input field to the buttons below it.", 183 "Use the <TAB> key to move from the input field to the buttons below it."),
182setmod_text[] = 184setmod_text[] = N_(
183 "This feature depends on another which has been configured as a module.\n" 185 "This feature depends on another which has been configured as a module.\n"
184 "As a result, this feature will be built as a module.", 186 "As a result, this feature will be built as a module."),
185nohelp_text[] = 187nohelp_text[] = N_(
186 "There is no help available for this kernel option.\n", 188 "There is no help available for this kernel option.\n"),
187load_config_text[] = 189load_config_text[] = N_(
188 "Enter the name of the configuration file you wish to load. " 190 "Enter the name of the configuration file you wish to load. "
189 "Accept the name shown to restore the configuration you " 191 "Accept the name shown to restore the configuration you "
190 "last retrieved. Leave blank to abort.", 192 "last retrieved. Leave blank to abort."),
191load_config_help[] = 193load_config_help[] = N_(
192 "\n" 194 "\n"
193 "For various reasons, one may wish to keep several different kernel\n" 195 "For various reasons, one may wish to keep several different kernel\n"
194 "configurations available on a single machine.\n" 196 "configurations available on a single machine.\n"
@@ -198,11 +200,11 @@ load_config_help[] =
198 "to modify that configuration.\n" 200 "to modify that configuration.\n"
199 "\n" 201 "\n"
200 "If you are uncertain, then you have probably never used alternate\n" 202 "If you are uncertain, then you have probably never used alternate\n"
201 "configuration files. You should therefor leave this blank to abort.\n", 203 "configuration files. You should therefor leave this blank to abort.\n"),
202save_config_text[] = 204save_config_text[] = N_(
203 "Enter a filename to which this configuration should be saved " 205 "Enter a filename to which this configuration should be saved "
204 "as an alternate. Leave blank to abort.", 206 "as an alternate. Leave blank to abort."),
205save_config_help[] = 207save_config_help[] = N_(
206 "\n" 208 "\n"
207 "For various reasons, one may wish to keep different kernel\n" 209 "For various reasons, one may wish to keep different kernel\n"
208 "configurations available on a single machine.\n" 210 "configurations available on a single machine.\n"
@@ -212,8 +214,8 @@ save_config_help[] =
212 "configuration options you have selected at that time.\n" 214 "configuration options you have selected at that time.\n"
213 "\n" 215 "\n"
214 "If you are uncertain what all this means then you should probably\n" 216 "If you are uncertain what all this means then you should probably\n"
215 "leave this blank.\n", 217 "leave this blank.\n"),
216search_help[] = 218search_help[] = N_(
217 "\n" 219 "\n"
218 "Search for CONFIG_ symbols and display their relations.\n" 220 "Search for CONFIG_ symbols and display their relations.\n"
219 "Example: search for \"^FOO\"\n" 221 "Example: search for \"^FOO\"\n"
@@ -250,7 +252,7 @@ search_help[] =
250 "Examples: USB => find all CONFIG_ symbols containing USB\n" 252 "Examples: USB => find all CONFIG_ symbols containing USB\n"
251 " ^USB => find all CONFIG_ symbols starting with USB\n" 253 " ^USB => find all CONFIG_ symbols starting with USB\n"
252 " USB$ => find all CONFIG_ symbols ending with USB\n" 254 " USB$ => find all CONFIG_ symbols ending with USB\n"
253 "\n"; 255 "\n");
254 256
255static signed char buf[4096], *bufptr = buf; 257static signed char buf[4096], *bufptr = buf;
256static signed char input_buf[4096]; 258static signed char input_buf[4096];
@@ -305,8 +307,8 @@ static void init_wsize(void)
305 } 307 }
306 308
307 if (rows < 19 || cols < 80) { 309 if (rows < 19 || cols < 80) {
308 fprintf(stderr, "Your display is too small to run Menuconfig!\n"); 310 fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));
309 fprintf(stderr, "It must be at least 19 lines by 80 columns.\n"); 311 fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n"));
310 exit(1); 312 exit(1);
311 } 313 }
312 314
@@ -526,9 +528,9 @@ static void search_conf(void)
526again: 528again:
527 cprint_init(); 529 cprint_init();
528 cprint("--title"); 530 cprint("--title");
529 cprint("Search Configuration Parameter"); 531 cprint(_("Search Configuration Parameter"));
530 cprint("--inputbox"); 532 cprint("--inputbox");
531 cprint("Enter Keyword"); 533 cprint(_("Enter Keyword"));
532 cprint("10"); 534 cprint("10");
533 cprint("75"); 535 cprint("75");
534 cprint(""); 536 cprint("");
@@ -539,7 +541,7 @@ again:
539 case 0: 541 case 0:
540 break; 542 break;
541 case 1: 543 case 1:
542 show_helptext("Search Configuration", search_help); 544 show_helptext(_("Search Configuration"), search_help);
543 goto again; 545 goto again;
544 default: 546 default:
545 return; 547 return;
@@ -548,7 +550,7 @@ again:
548 sym_arr = sym_re_search(input_buf); 550 sym_arr = sym_re_search(input_buf);
549 res = get_relations_str(sym_arr); 551 res = get_relations_str(sym_arr);
550 free(sym_arr); 552 free(sym_arr);
551 show_textbox("Search Results", str_get(&res), 0, 0); 553 show_textbox(_("Search Results"), str_get(&res), 0, 0);
552 str_free(&res); 554 str_free(&res);
553} 555}
554 556
@@ -721,9 +723,9 @@ static void conf(struct menu *menu)
721 while (1) { 723 while (1) {
722 cprint_init(); 724 cprint_init();
723 cprint("--title"); 725 cprint("--title");
724 cprint("%s", prompt ? prompt : "Main Menu"); 726 cprint("%s", prompt ? prompt : _("Main Menu"));
725 cprint("--menu"); 727 cprint("--menu");
726 cprint(menu_instructions); 728 cprint(_(menu_instructions));
727 cprint("%d", rows); 729 cprint("%d", rows);
728 cprint("%d", cols); 730 cprint("%d", cols);
729 cprint("%d", rows - 10); 731 cprint("%d", rows - 10);
@@ -736,9 +738,9 @@ static void conf(struct menu *menu)
736 cprint(":"); 738 cprint(":");
737 cprint("--- "); 739 cprint("--- ");
738 cprint("L"); 740 cprint("L");
739 cprint(" Load an Alternate Configuration File"); 741 cprint(_(" Load an Alternate Configuration File"));
740 cprint("S"); 742 cprint("S");
741 cprint(" Save Configuration to an Alternate File"); 743 cprint(_(" Save Configuration to an Alternate File"));
742 } 744 }
743 stat = exec_conf(); 745 stat = exec_conf();
744 if (stat < 0) 746 if (stat < 0)
@@ -793,7 +795,7 @@ static void conf(struct menu *menu)
793 if (sym) 795 if (sym)
794 show_help(submenu); 796 show_help(submenu);
795 else 797 else
796 show_helptext("README", mconf_readme); 798 show_helptext("README", _(mconf_readme));
797 break; 799 break;
798 case 3: 800 case 3:
799 if (type == 't') { 801 if (type == 't') {
@@ -849,7 +851,7 @@ static void show_help(struct menu *menu)
849 { 851 {
850 if (sym->name) { 852 if (sym->name) {
851 str_printf(&help, "CONFIG_%s:\n\n", sym->name); 853 str_printf(&help, "CONFIG_%s:\n\n", sym->name);
852 str_append(&help, sym->help); 854 str_append(&help, _(sym->help));
853 str_append(&help, "\n"); 855 str_append(&help, "\n");
854 } 856 }
855 } else { 857 } else {
@@ -886,9 +888,9 @@ static void conf_choice(struct menu *menu)
886 while (1) { 888 while (1) {
887 cprint_init(); 889 cprint_init();
888 cprint("--title"); 890 cprint("--title");
889 cprint("%s", prompt ? prompt : "Main Menu"); 891 cprint("%s", prompt ? prompt : _("Main Menu"));
890 cprint("--radiolist"); 892 cprint("--radiolist");
891 cprint(radiolist_instructions); 893 cprint(_(radiolist_instructions));
892 cprint("15"); 894 cprint("15");
893 cprint("70"); 895 cprint("70");
894 cprint("6"); 896 cprint("6");
@@ -935,17 +937,17 @@ static void conf_string(struct menu *menu)
935 while (1) { 937 while (1) {
936 cprint_init(); 938 cprint_init();
937 cprint("--title"); 939 cprint("--title");
938 cprint("%s", prompt ? prompt : "Main Menu"); 940 cprint("%s", prompt ? prompt : _("Main Menu"));
939 cprint("--inputbox"); 941 cprint("--inputbox");
940 switch (sym_get_type(menu->sym)) { 942 switch (sym_get_type(menu->sym)) {
941 case S_INT: 943 case S_INT:
942 cprint(inputbox_instructions_int); 944 cprint(_(inputbox_instructions_int));
943 break; 945 break;
944 case S_HEX: 946 case S_HEX:
945 cprint(inputbox_instructions_hex); 947 cprint(_(inputbox_instructions_hex));
946 break; 948 break;
947 case S_STRING: 949 case S_STRING:
948 cprint(inputbox_instructions_string); 950 cprint(_(inputbox_instructions_string));
949 break; 951 break;
950 default: 952 default:
951 /* panic? */; 953 /* panic? */;
@@ -958,7 +960,7 @@ static void conf_string(struct menu *menu)
958 case 0: 960 case 0:
959 if (sym_set_string_value(menu->sym, input_buf)) 961 if (sym_set_string_value(menu->sym, input_buf))
960 return; 962 return;
961 show_textbox(NULL, "You have made an invalid entry.", 5, 43); 963 show_textbox(NULL, _("You have made an invalid entry."), 5, 43);
962 break; 964 break;
963 case 1: 965 case 1:
964 show_help(menu); 966 show_help(menu);
@@ -987,10 +989,10 @@ static void conf_load(void)
987 return; 989 return;
988 if (!conf_read(input_buf)) 990 if (!conf_read(input_buf))
989 return; 991 return;
990 show_textbox(NULL, "File does not exist!", 5, 38); 992 show_textbox(NULL, _("File does not exist!"), 5, 38);
991 break; 993 break;
992 case 1: 994 case 1:
993 show_helptext("Load Alternate Configuration", load_config_help); 995 show_helptext(_("Load Alternate Configuration"), load_config_help);
994 break; 996 break;
995 case 255: 997 case 255:
996 return; 998 return;
@@ -1016,10 +1018,10 @@ static void conf_save(void)
1016 return; 1018 return;
1017 if (!conf_write(input_buf)) 1019 if (!conf_write(input_buf))
1018 return; 1020 return;
1019 show_textbox(NULL, "Can't create file! Probably a nonexistent directory.", 5, 60); 1021 show_textbox(NULL, _("Can't create file! Probably a nonexistent directory."), 5, 60);
1020 break; 1022 break;
1021 case 1: 1023 case 1:
1022 show_helptext("Save Alternate Configuration", save_config_help); 1024 show_helptext(_("Save Alternate Configuration"), save_config_help);
1023 break; 1025 break;
1024 case 255: 1026 case 255:
1025 return; 1027 return;
@@ -1040,12 +1042,16 @@ int main(int ac, char **av)
1040 char *mode; 1042 char *mode;
1041 int stat; 1043 int stat;
1042 1044
1045 setlocale(LC_ALL, "");
1046 bindtextdomain(PACKAGE, LOCALEDIR);
1047 textdomain(PACKAGE);
1048
1043 conf_parse(av[1]); 1049 conf_parse(av[1]);
1044 conf_read(NULL); 1050 conf_read(NULL);
1045 1051
1046 sym = sym_lookup("KERNELRELEASE", 0); 1052 sym = sym_lookup("KERNELRELEASE", 0);
1047 sym_calc_value(sym); 1053 sym_calc_value(sym);
1048 sprintf(menu_backtitle, "Linux Kernel v%s Configuration", 1054 sprintf(menu_backtitle, _("Linux Kernel v%s Configuration"),
1049 sym_get_string_value(sym)); 1055 sym_get_string_value(sym));
1050 1056
1051 mode = getenv("MENUCONFIG_MODE"); 1057 mode = getenv("MENUCONFIG_MODE");
@@ -1062,7 +1068,7 @@ int main(int ac, char **av)
1062 do { 1068 do {
1063 cprint_init(); 1069 cprint_init();
1064 cprint("--yesno"); 1070 cprint("--yesno");
1065 cprint("Do you wish to save your new kernel configuration?"); 1071 cprint(_("Do you wish to save your new kernel configuration?"));
1066 cprint("5"); 1072 cprint("5");
1067 cprint("60"); 1073 cprint("60");
1068 stat = exec_conf(); 1074 stat = exec_conf();
@@ -1070,20 +1076,20 @@ int main(int ac, char **av)
1070 1076
1071 if (stat == 0) { 1077 if (stat == 0) {
1072 if (conf_write(NULL)) { 1078 if (conf_write(NULL)) {
1073 fprintf(stderr, "\n\n" 1079 fprintf(stderr, _("\n\n"
1074 "Error during writing of the kernel configuration.\n" 1080 "Error during writing of the kernel configuration.\n"
1075 "Your kernel configuration changes were NOT saved." 1081 "Your kernel configuration changes were NOT saved."
1076 "\n\n"); 1082 "\n\n"));
1077 return 1; 1083 return 1;
1078 } 1084 }
1079 printf("\n\n" 1085 printf(_("\n\n"
1080 "*** End of Linux kernel configuration.\n" 1086 "*** End of Linux kernel configuration.\n"
1081 "*** Execute 'make' to build the kernel or try 'make help'." 1087 "*** Execute 'make' to build the kernel or try 'make help'."
1082 "\n\n"); 1088 "\n\n"));
1083 } else { 1089 } else {
1084 fprintf(stderr, "\n\n" 1090 fprintf(stderr, _("\n\n"
1085 "Your kernel configuration changes were NOT saved." 1091 "Your kernel configuration changes were NOT saved."
1086 "\n\n"); 1092 "\n\n"));
1087 } 1093 }
1088 1094
1089 return 0; 1095 return 0;
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 0c13156f3344..8c59b212722d 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -365,9 +365,9 @@ bool menu_is_visible(struct menu *menu)
365const char *menu_get_prompt(struct menu *menu) 365const char *menu_get_prompt(struct menu *menu)
366{ 366{
367 if (menu->prompt) 367 if (menu->prompt)
368 return menu->prompt->text; 368 return _(menu->prompt->text);
369 else if (menu->sym) 369 else if (menu->sym)
370 return menu->sym->name; 370 return _(menu->sym->name);
371 return NULL; 371 return NULL;
372} 372}
373 373
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index 0cdbf9dbbd51..4590cd31623f 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -26,8 +26,23 @@
26#include "qconf.moc" 26#include "qconf.moc"
27#include "images.c" 27#include "images.c"
28 28
29#ifdef _
30# undef _
31# define _ qgettext
32#endif
33
29static QApplication *configApp; 34static QApplication *configApp;
30 35
36static inline QString qgettext(const char* str)
37{
38 return QString::fromLocal8Bit(gettext(str));
39}
40
41static inline QString qgettext(const QString& str)
42{
43 return QString::fromLocal8Bit(gettext(str.latin1()));
44}
45
31ConfigSettings::ConfigSettings() 46ConfigSettings::ConfigSettings()
32 : showAll(false), showName(false), showRange(false), showData(false) 47 : showAll(false), showName(false), showRange(false), showData(false)
33{ 48{
@@ -177,7 +192,7 @@ void ConfigItem::updateMenu(void)
177 192
178 sym = menu->sym; 193 sym = menu->sym;
179 prop = menu->prompt; 194 prop = menu->prompt;
180 prompt = menu_get_prompt(menu); 195 prompt = QString::fromLocal8Bit(menu_get_prompt(menu));
181 196
182 if (prop) switch (prop->type) { 197 if (prop) switch (prop->type) {
183 case P_MENU: 198 case P_MENU:
@@ -203,7 +218,7 @@ void ConfigItem::updateMenu(void)
203 if (!sym) 218 if (!sym)
204 goto set_prompt; 219 goto set_prompt;
205 220
206 setText(nameColIdx, sym->name); 221 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
207 222
208 type = sym_get_type(sym); 223 type = sym_get_type(sym);
209 switch (type) { 224 switch (type) {
@@ -213,9 +228,9 @@ void ConfigItem::updateMenu(void)
213 228
214 if (!sym_is_changable(sym) && !list->showAll) { 229 if (!sym_is_changable(sym) && !list->showAll) {
215 setPixmap(promptColIdx, 0); 230 setPixmap(promptColIdx, 0);
216 setText(noColIdx, 0); 231 setText(noColIdx, QString::null);
217 setText(modColIdx, 0); 232 setText(modColIdx, QString::null);
218 setText(yesColIdx, 0); 233 setText(yesColIdx, QString::null);
219 break; 234 break;
220 } 235 }
221 expr = sym_get_tristate_value(sym); 236 expr = sym_get_tristate_value(sym);
@@ -257,6 +272,7 @@ void ConfigItem::updateMenu(void)
257 const char* data; 272 const char* data;
258 273
259 data = sym_get_string_value(sym); 274 data = sym_get_string_value(sym);
275
260#if QT_VERSION >= 300 276#if QT_VERSION >= 300
261 int i = list->mapIdx(dataColIdx); 277 int i = list->mapIdx(dataColIdx);
262 if (i >= 0) 278 if (i >= 0)
@@ -264,9 +280,9 @@ void ConfigItem::updateMenu(void)
264#endif 280#endif
265 setText(dataColIdx, data); 281 setText(dataColIdx, data);
266 if (type == S_STRING) 282 if (type == S_STRING)
267 prompt.sprintf("%s: %s", prompt.latin1(), data); 283 prompt = QString("%1: %2").arg(prompt).arg(data);
268 else 284 else
269 prompt.sprintf("(%s) %s", data, prompt.latin1()); 285 prompt = QString("(%2) %1").arg(prompt).arg(data);
270 break; 286 break;
271 } 287 }
272 if (!sym_has_value(sym) && visible) 288 if (!sym_has_value(sym) && visible)
@@ -343,9 +359,9 @@ void ConfigLineEdit::show(ConfigItem* i)
343{ 359{
344 item = i; 360 item = i;
345 if (sym_get_string_value(item->menu->sym)) 361 if (sym_get_string_value(item->menu->sym))
346 setText(sym_get_string_value(item->menu->sym)); 362 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
347 else 363 else
348 setText(0); 364 setText(QString::null);
349 Parent::show(); 365 Parent::show();
350 setFocus(); 366 setFocus();
351} 367}
@@ -961,7 +977,7 @@ ConfigMainWindow::ConfigMainWindow(void)
961 delete configSettings; 977 delete configSettings;
962} 978}
963 979
964static QString print_filter(const char *str) 980static QString print_filter(const QString &str)
965{ 981{
966 QRegExp re("[<>&\"\\n]"); 982 QRegExp re("[<>&\"\\n]");
967 QString res = str; 983 QString res = str;
@@ -994,7 +1010,7 @@ static QString print_filter(const char *str)
994 1010
995static void expr_print_help(void *data, const char *str) 1011static void expr_print_help(void *data, const char *str)
996{ 1012{
997 ((QString*)data)->append(print_filter(str)); 1013 reinterpret_cast<QString*>(data)->append(print_filter(str));
998} 1014}
999 1015
1000/* 1016/*
@@ -1009,7 +1025,7 @@ void ConfigMainWindow::setHelp(QListViewItem* item)
1009 if (item) 1025 if (item)
1010 menu = ((ConfigItem*)item)->menu; 1026 menu = ((ConfigItem*)item)->menu;
1011 if (!menu) { 1027 if (!menu) {
1012 helpText->setText(NULL); 1028 helpText->setText(QString::null);
1013 return; 1029 return;
1014 } 1030 }
1015 1031
@@ -1019,16 +1035,16 @@ void ConfigMainWindow::setHelp(QListViewItem* item)
1019 if (sym) { 1035 if (sym) {
1020 if (menu->prompt) { 1036 if (menu->prompt) {
1021 head += "<big><b>"; 1037 head += "<big><b>";
1022 head += print_filter(menu->prompt->text); 1038 head += print_filter(_(menu->prompt->text));
1023 head += "</b></big>"; 1039 head += "</b></big>";
1024 if (sym->name) { 1040 if (sym->name) {
1025 head += " ("; 1041 head += " (";
1026 head += print_filter(sym->name); 1042 head += print_filter(_(sym->name));
1027 head += ")"; 1043 head += ")";
1028 } 1044 }
1029 } else if (sym->name) { 1045 } else if (sym->name) {
1030 head += "<big><b>"; 1046 head += "<big><b>";
1031 head += print_filter(sym->name); 1047 head += print_filter(_(sym->name));
1032 head += "</b></big>"; 1048 head += "</b></big>";
1033 } 1049 }
1034 head += "<br><br>"; 1050 head += "<br><br>";
@@ -1049,7 +1065,7 @@ void ConfigMainWindow::setHelp(QListViewItem* item)
1049 case P_PROMPT: 1065 case P_PROMPT:
1050 case P_MENU: 1066 case P_MENU:
1051 debug += "prompt: "; 1067 debug += "prompt: ";
1052 debug += print_filter(prop->text); 1068 debug += print_filter(_(prop->text));
1053 debug += "<br>"; 1069 debug += "<br>";
1054 break; 1070 break;
1055 case P_DEFAULT: 1071 case P_DEFAULT:
@@ -1088,10 +1104,10 @@ void ConfigMainWindow::setHelp(QListViewItem* item)
1088 debug += "<br>"; 1104 debug += "<br>";
1089 } 1105 }
1090 1106
1091 help = print_filter(sym->help); 1107 help = print_filter(_(sym->help));
1092 } else if (menu->prompt) { 1108 } else if (menu->prompt) {
1093 head += "<big><b>"; 1109 head += "<big><b>";
1094 head += print_filter(menu->prompt->text); 1110 head += print_filter(_(menu->prompt->text));
1095 head += "</b></big><br><br>"; 1111 head += "</b></big><br><br>";
1096 if (showDebug) { 1112 if (showDebug) {
1097 if (menu->prompt->visible.expr) { 1113 if (menu->prompt->visible.expr) {
@@ -1111,7 +1127,7 @@ void ConfigMainWindow::loadConfig(void)
1111 QString s = QFileDialog::getOpenFileName(".config", NULL, this); 1127 QString s = QFileDialog::getOpenFileName(".config", NULL, this);
1112 if (s.isNull()) 1128 if (s.isNull())
1113 return; 1129 return;
1114 if (conf_read(s.latin1())) 1130 if (conf_read(QFile::encodeName(s)))
1115 QMessageBox::information(this, "qconf", "Unable to load configuration!"); 1131 QMessageBox::information(this, "qconf", "Unable to load configuration!");
1116 ConfigView::updateListAll(); 1132 ConfigView::updateListAll();
1117} 1133}
@@ -1127,7 +1143,7 @@ void ConfigMainWindow::saveConfigAs(void)
1127 QString s = QFileDialog::getSaveFileName(".config", NULL, this); 1143 QString s = QFileDialog::getSaveFileName(".config", NULL, this);
1128 if (s.isNull()) 1144 if (s.isNull())
1129 return; 1145 return;
1130 if (conf_write(s.latin1())) 1146 if (conf_write(QFile::encodeName(s)))
1131 QMessageBox::information(this, "qconf", "Unable to save configuration!"); 1147 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1132} 1148}
1133 1149
@@ -1372,6 +1388,9 @@ int main(int ac, char** av)
1372 ConfigMainWindow* v; 1388 ConfigMainWindow* v;
1373 const char *name; 1389 const char *name;
1374 1390
1391 bindtextdomain(PACKAGE, LOCALEDIR);
1392 textdomain(PACKAGE);
1393
1375#ifndef LKC_DIRECT_LINK 1394#ifndef LKC_DIRECT_LINK
1376 kconfig_load(); 1395 kconfig_load();
1377#endif 1396#endif