diff -uprN -X linux-2.6.18-rc1.orig/Documentation/dontdiff linux-2.6.18-rc1.orig/arch/i386/Kconfig linux-2.6.18-rc1.unsorted_groups/arch/i386/Kconfig --- linux-2.6.18-rc1.orig/arch/i386/Kconfig 2006-07-07 13:12:20.000000000 +1200 +++ linux-2.6.18-rc1.unsorted_groups/arch/i386/Kconfig 2006-07-07 11:46:34.000000000 +1200 @@ -258,6 +258,7 @@ config SCHED_MC increased overhead in some places. If unsure say N here. source "kernel/Kconfig.preempt" +source "kernel/Kconfig.unsortedgroups" config X86_UP_APIC bool "Local APIC support on uniprocessors" diff -uprN -X linux-2.6.18-rc1.orig/Documentation/dontdiff linux-2.6.18-rc1.orig/arch/mips/Kconfig linux-2.6.18-rc1.unsorted_groups/arch/mips/Kconfig --- linux-2.6.18-rc1.orig/arch/mips/Kconfig 2006-07-07 13:12:22.000000000 +1200 +++ linux-2.6.18-rc1.unsorted_groups/arch/mips/Kconfig 2006-07-07 11:46:34.000000000 +1200 @@ -1820,6 +1820,7 @@ config HZ default 1024 if HZ_1024 source "kernel/Kconfig.preempt" +source "kernel/Kconfig.unsortedgroups" config RTC_DS1742 bool "DS1742 BRAM/RTC support" diff -uprN -X linux-2.6.18-rc1.orig/Documentation/dontdiff linux-2.6.18-rc1.orig/arch/parisc/Kconfig linux-2.6.18-rc1.unsorted_groups/arch/parisc/Kconfig --- linux-2.6.18-rc1.orig/arch/parisc/Kconfig 2006-07-07 13:12:23.000000000 +1200 +++ linux-2.6.18-rc1.unsorted_groups/arch/parisc/Kconfig 2006-07-07 11:46:34.000000000 +1200 @@ -220,6 +220,7 @@ config NODES_SHIFT source "kernel/Kconfig.preempt" source "kernel/Kconfig.hz" source "mm/Kconfig" +source "kernel/Kconfig.unsortedgroups" config COMPAT def_bool y diff -uprN -X linux-2.6.18-rc1.orig/Documentation/dontdiff linux-2.6.18-rc1.orig/arch/powerpc/Kconfig linux-2.6.18-rc1.unsorted_groups/arch/powerpc/Kconfig --- linux-2.6.18-rc1.orig/arch/powerpc/Kconfig 2006-07-07 13:12:23.000000000 +1200 +++ linux-2.6.18-rc1.unsorted_groups/arch/powerpc/Kconfig 2006-07-07 11:46:34.000000000 +1200 @@ -593,6 +593,7 @@ config HIGHMEM source kernel/Kconfig.hz source kernel/Kconfig.preempt source "fs/Kconfig.binfmt" +source "kernel/Kconfig.unsortedgroups" # We optimistically allocate largepages from the VM, so make the limit # large enough (16MB). This badly named config option is actually diff -uprN -X linux-2.6.18-rc1.orig/Documentation/dontdiff linux-2.6.18-rc1.orig/arch/x86_64/Kconfig linux-2.6.18-rc1.unsorted_groups/arch/x86_64/Kconfig --- linux-2.6.18-rc1.orig/arch/x86_64/Kconfig 2006-07-07 13:12:26.000000000 +1200 +++ linux-2.6.18-rc1.unsorted_groups/arch/x86_64/Kconfig 2006-07-07 11:46:34.000000000 +1200 @@ -273,6 +273,8 @@ config SCHED_MC increased overhead in some places. If unsure say N here. source "kernel/Kconfig.preempt" +source "kernel/Kconfig.unsortedgroups" + config NUMA bool "Non Uniform Memory Access (NUMA) Support" diff -uprN -X linux-2.6.18-rc1.orig/Documentation/dontdiff linux-2.6.18-rc1.orig/kernel/Kconfig.unsortedgroups linux-2.6.18-rc1.unsorted_groups/kernel/Kconfig.unsortedgroups --- linux-2.6.18-rc1.orig/kernel/Kconfig.unsortedgroups 1970-01-01 12:00:00.000000000 +1200 +++ linux-2.6.18-rc1.unsorted_groups/kernel/Kconfig.unsortedgroups 2006-07-07 11:46:34.000000000 +1200 @@ -0,0 +1,16 @@ +# +# Groups order +# +config USE_UNSORTED_SUPPLEMENTAL_GROUPS + bool "Use unsorted supplemental groups" + help + + If you need to use setgroups(2) to order a process's supplemental group list so that you can + choose which 16 groups are sent during a NFSv2 or NFSv3 AUTH_UNIX (the default authentication protocol) + transaction you need to say Y here. + + If you do not have users with more than 16 groups who need to access NFS you don't need this. + + Do not set this option if you are going to have users in thousands of secondary groups. The default + kernel implementation sorts the groups and then binary searches them for membership. This option forces + the search to be linear. diff -uprN -X linux-2.6.18-rc1.orig/Documentation/dontdiff linux-2.6.18-rc1.orig/kernel/sys.c linux-2.6.18-rc1.unsorted_groups/kernel/sys.c --- linux-2.6.18-rc1.orig/kernel/sys.c 2006-07-07 13:12:44.000000000 +1200 +++ linux-2.6.18-rc1.unsorted_groups/kernel/sys.c 2006-07-11 14:45:08.007916000 +1200 @@ -1535,14 +1535,22 @@ static void groups_sort(struct group_inf } } -/* a simple bsearch */ +/* if USE_UNSORTED_SUPPLEMENTAL_GROUPS is set this is a linear search. If not it's a binary search */ int groups_search(struct group_info *group_info, gid_t grp) { - unsigned int left, right; if (!group_info) return 0; +#ifdef USE_UNSORTED_SUPPLEMENTAL_GROUPS + unsigned int i; + + for (i=0; i < group_info->ngroups; i++) + if (GROUP_AT(group_info,i) == grp) + return 1; +#else + unsigned int left, right; + left = 0; right = group_info->ngroups; while (left < right) { @@ -1555,6 +1563,7 @@ int groups_search(struct group_info *gro else return 1; } +#endif return 0; } @@ -1568,7 +1577,10 @@ int set_current_groups(struct group_info if (retval) return retval; +#ifndef USE_UNSORTED_SUPPLEMENTAL_GROUPS groups_sort(group_info); +#endif + get_group_info(group_info); task_lock(current);