]> granicus.if.org Git - zfs/blob - config/spl-build.m4
Move vendor check to spl-build.m4
[zfs] / config / spl-build.m4
1 ###############################################################################
2 # Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
3 # Copyright (C) 2007 The Regents of the University of California.
4 # Written by Brian Behlendorf <behlendorf1@llnl.gov>.
5 ###############################################################################
6 # SPL_AC_CONFIG_KERNEL: Default SPL kernel configuration.
7 ###############################################################################
8
9 AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
10         SPL_AC_KERNEL
11
12         dnl # -Wall -fno-strict-aliasing -Wstrict-prototypes and other
13         dnl # compiler options are added by the kernel build system.
14         abs_srcdir=`readlink -f ${srcdir}`
15         KERNELCPPFLAGS="$KERNELCPPFLAGS -Wstrict-prototypes"
16         KERNELCPPFLAGS="$KERNELCPPFLAGS -I${abs_srcdir}/include"
17         KERNELCPPFLAGS="$KERNELCPPFLAGS -include ${abs_srcdir}/spl_config.h"
18
19         if test "${LINUX_OBJ}" != "${LINUX}"; then
20                 KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ"
21         fi
22
23         AC_SUBST(KERNELMAKE_PARAMS)
24         AC_SUBST(KERNELCPPFLAGS)
25
26         SPL_AC_DEBUG
27         SPL_AC_DEBUG_KMEM
28         SPL_AC_DEBUG_KMEM_TRACKING
29         SPL_AC_ATOMIC_SPINLOCK
30         SPL_AC_TYPE_ATOMIC64_CMPXCHG
31         SPL_AC_TYPE_ATOMIC64_XCHG
32         SPL_AC_TYPE_UINTPTR_T
33         SPL_AC_3ARGS_INIT_WORK
34         SPL_AC_2ARGS_REGISTER_SYSCTL
35         SPL_AC_SET_SHRINKER
36         SPL_AC_PATH_IN_NAMEIDATA
37         SPL_AC_TASK_CURR
38         SPL_AC_CTL_UNNUMBERED
39         SPL_AC_CTL_NAME
40         SPL_AC_FLS64
41         SPL_AC_DEVICE_CREATE
42         SPL_AC_5ARGS_DEVICE_CREATE
43         SPL_AC_CLASS_DEVICE_CREATE
44         SPL_AC_SET_NORMALIZED_TIMESPEC_EXPORT
45         SPL_AC_SET_NORMALIZED_TIMESPEC_INLINE
46         SPL_AC_TIMESPEC_SUB
47         SPL_AC_INIT_UTSNAME
48         SPL_AC_FDTABLE_HEADER
49         SPL_AC_FILES_FDTABLE
50         SPL_AC_UACCESS_HEADER
51         SPL_AC_KMALLOC_NODE
52         SPL_AC_MONOTONIC_CLOCK
53         SPL_AC_INODE_I_MUTEX
54         SPL_AC_MUTEX_OWNER
55         SPL_AC_MUTEX_LOCK_NESTED
56         SPL_AC_3ARGS_ON_EACH_CPU
57         SPL_AC_KALLSYMS_LOOKUP_NAME
58         SPL_AC_GET_VMALLOC_INFO
59         SPL_AC_PGDAT_HELPERS
60         SPL_AC_FIRST_ONLINE_PGDAT
61         SPL_AC_NEXT_ONLINE_PGDAT
62         SPL_AC_NEXT_ZONE
63         SPL_AC_PGDAT_LIST
64         SPL_AC_GLOBAL_PAGE_STATE
65         SPL_AC_ZONE_STAT_ITEM_FREE
66         SPL_AC_ZONE_STAT_ITEM_INACTIVE
67         SPL_AC_ZONE_STAT_ITEM_ACTIVE
68         SPL_AC_GET_ZONE_COUNTS
69         SPL_AC_USER_PATH_DIR
70         SPL_AC_SET_FS_PWD
71         SPL_AC_2ARGS_SET_FS_PWD
72         SPL_AC_2ARGS_VFS_UNLINK
73         SPL_AC_4ARGS_VFS_RENAME
74         SPL_AC_CRED_STRUCT
75         SPL_AC_GROUPS_SEARCH
76         SPL_AC_PUT_TASK_STRUCT
77         SPL_AC_5ARGS_PROC_HANDLER
78         SPL_AC_KVASPRINTF
79         SPL_AC_3ARGS_FILE_FSYNC
80         SPL_AC_EXPORTED_RWSEM_IS_LOCKED
81 ])
82
83 AC_DEFUN([SPL_AC_MODULE_SYMVERS], [
84         modpost=$LINUX/scripts/Makefile.modpost
85         AC_MSG_CHECKING([kernel file name for module symbols])
86         if test -f "$modpost"; then
87                 if grep -q Modules.symvers $modpost; then
88                         LINUX_SYMBOLS=Modules.symvers
89                 else
90                         LINUX_SYMBOLS=Module.symvers
91                 fi
92         else
93                 LINUX_SYMBOLS=NONE
94         fi
95         AC_MSG_RESULT($LINUX_SYMBOLS)
96         AC_SUBST(LINUX_SYMBOLS)
97 ])
98
99 AC_DEFUN([SPL_AC_KERNEL], [
100         AC_ARG_WITH([linux],
101                 AS_HELP_STRING([--with-linux=PATH],
102                 [Path to kernel source]),
103                 [kernelsrc="$withval"])
104
105         AC_ARG_WITH([linux-obj],
106                 AS_HELP_STRING([--with-linux-obj=PATH],
107                 [Path to kernel build objects]),
108                 [kernelbuild="$withval"])
109
110         AC_MSG_CHECKING([kernel source directory])
111         if test -z "$kernelsrc"; then
112                 headersdir="/lib/modules/$(uname -r)/build"
113                 if test -e "$headersdir"; then
114                         sourcelink=$(readlink -f "$headersdir")
115                 else
116                         sourcelink=$(ls -1d /usr/src/kernels/* \
117                                      /usr/src/linux-* \
118                                      2>/dev/null | grep -v obj | tail -1)
119                 fi
120
121                 if test -n "$sourcelink" && test -e ${sourcelink}; then
122                         kernelsrc=`readlink -f ${sourcelink}`
123                 else
124                         AC_MSG_RESULT([Not found])
125                         AC_MSG_ERROR([
126         *** Please make sure the kernel devel package for your distribution
127         *** is installed then try again.  If that fails you can specify the
128         *** location of the kernel source with the '--with-linux=PATH' option.])
129                 fi
130         else
131                 if test "$kernelsrc" = "NONE"; then
132                         kernsrcver=NONE
133                 fi
134         fi
135
136         AC_MSG_RESULT([$kernelsrc])
137         AC_MSG_CHECKING([kernel build directory])
138         if test -z "$kernelbuild"; then
139                 if test -d ${kernelsrc}-obj/${target_cpu}/${target_cpu}; then
140                         kernelbuild=${kernelsrc}-obj/${target_cpu}/${target_cpu}
141                 elif test -d ${kernelsrc}-obj/${target_cpu}/default; then
142                         kernelbuild=${kernelsrc}-obj/${target_cpu}/default
143                 elif test -d `dirname ${kernelsrc}`/build-${target_cpu}; then
144                         kernelbuild=`dirname ${kernelsrc}`/build-${target_cpu}
145                 else
146                         kernelbuild=${kernelsrc}
147                 fi
148         fi
149         AC_MSG_RESULT([$kernelbuild])
150
151         AC_MSG_CHECKING([kernel source version])
152         utsrelease1=$kernelbuild/include/linux/version.h
153         utsrelease2=$kernelbuild/include/linux/utsrelease.h
154         utsrelease3=$kernelbuild/include/generated/utsrelease.h
155         if test -r $utsrelease1 && fgrep -q UTS_RELEASE $utsrelease1; then
156                 utsrelease=linux/version.h
157         elif test -r $utsrelease2 && fgrep -q UTS_RELEASE $utsrelease2; then
158                 utsrelease=linux/utsrelease.h
159         elif test -r $utsrelease3 && fgrep -q UTS_RELEASE $utsrelease3; then
160                 utsrelease=generated/utsrelease.h
161         fi
162
163         if test "$utsrelease"; then
164                 kernsrcver=`(echo "#include <$utsrelease>";
165                              echo "kernsrcver=UTS_RELEASE") | 
166                              cpp -I $kernelbuild/include |
167                              grep "^kernsrcver=" | cut -d \" -f 2`
168
169                 if test -z "$kernsrcver"; then
170                         AC_MSG_RESULT([Not found])
171                         AC_MSG_ERROR([*** Cannot determine kernel version.])
172                 fi
173         else
174                 AC_MSG_RESULT([Not found])
175                 AC_MSG_ERROR([*** Cannot find UTS_RELEASE definition.])
176         fi
177
178         AC_MSG_RESULT([$kernsrcver])
179
180         LINUX=${kernelsrc}
181         LINUX_OBJ=${kernelbuild}
182         LINUX_VERSION=${kernsrcver}
183
184         AC_SUBST(LINUX)
185         AC_SUBST(LINUX_OBJ)
186         AC_SUBST(LINUX_VERSION)
187
188         SPL_AC_MODULE_SYMVERS
189 ])
190
191 dnl #
192 dnl # Explicitly check for gawk, we require it for the the usermode
193 dnl # helper.  For some reason the standard awk command does not
194 dnl # behave correctly when invoked from the usermode helper.
195 dnl #
196 AC_DEFUN([SPL_AC_GAWK], [
197         AS_IF([test "x$AWK" != xgawk], [
198                 AC_MSG_ERROR([
199         *** Required util gawk missing.  Please install the required
200         *** gawk package for your distribution and try again.])
201         ])
202 ])
203
204 dnl #
205 dnl # Default SPL user configuration
206 dnl #
207 AC_DEFUN([SPL_AC_CONFIG_USER], [
208         SPL_AC_GAWK
209 ])
210
211 dnl #
212 dnl # Check for rpm+rpmbuild to build RPM packages.  If these tools
213 dnl # are missing it is non-fatal but you will not be able to build
214 dnl # RPM packages and will be warned if you try too.
215 dnl #
216 AC_DEFUN([SPL_AC_RPM], [
217         RPM=rpm
218         RPMBUILD=rpmbuild
219
220         AC_MSG_CHECKING([whether $RPM is available])
221         AS_IF([tmp=$($RPM --version 2>/dev/null)], [
222                 RPM_VERSION=$(echo $tmp | $AWK '/RPM/ { print $[3] }')
223                 HAVE_RPM=yes
224                 AC_MSG_RESULT([$HAVE_RPM ($RPM_VERSION)])
225         ],[
226                 HAVE_RPM=no
227                 AC_MSG_RESULT([$HAVE_RPM])
228         ])
229
230         AC_MSG_CHECKING([whether $RPMBUILD is available])
231         AS_IF([tmp=$($RPMBUILD --version 2>/dev/null)], [
232                 RPMBUILD_VERSION=$(echo $tmp | $AWK '/RPM/ { print $[3] }')
233                 HAVE_RPMBUILD=yes
234                 AC_MSG_RESULT([$HAVE_RPMBUILD ($RPMBUILD_VERSION)])
235         ],[
236                 HAVE_RPMBUILD=no
237                 AC_MSG_RESULT([$HAVE_RPMBUILD])
238         ])
239
240         AC_SUBST(HAVE_RPM)
241         AC_SUBST(RPM)
242         AC_SUBST(RPM_VERSION)
243
244         AC_SUBST(HAVE_RPMBUILD)
245         AC_SUBST(RPMBUILD)
246         AC_SUBST(RPMBUILD_VERSION)
247 ])
248
249 dnl #
250 dnl # Check for dpkg+dpkg-buildpackage to build DEB packages.  If these
251 dnl # tools are missing it is non-fatal but you will not be able to build
252 dnl # DEB packages and will be warned if you try too.
253 dnl #
254 AC_DEFUN([SPL_AC_DPKG], [
255         DPKG=dpkg
256         DPKGBUILD=dpkg-buildpackage
257
258         AC_MSG_CHECKING([whether $DPKG is available])
259         AS_IF([tmp=$($DPKG --version 2>/dev/null)], [
260                 DPKG_VERSION=$(echo $tmp | $AWK '/Debian/ { print $[7] }')
261                 HAVE_DPKG=yes
262                 AC_MSG_RESULT([$HAVE_DPKG ($DPKG_VERSION)])
263         ],[
264                 HAVE_DPKG=no
265                 AC_MSG_RESULT([$HAVE_DPKG])
266         ])
267
268         AC_MSG_CHECKING([whether $DPKGBUILD is available])
269         AS_IF([tmp=$($DPKGBUILD --version 2>/dev/null)], [
270                 DPKGBUILD_VERSION=$(echo $tmp | \
271                     $AWK '/Debian/ { print $[4] }' | cut -f-4 -d'.')
272                 HAVE_DPKGBUILD=yes
273                 AC_MSG_RESULT([$HAVE_DPKGBUILD ($DPKGBUILD_VERSION)])
274         ],[
275                 HAVE_DPKGBUILD=no
276                 AC_MSG_RESULT([$HAVE_DPKGBUILD])
277         ])
278
279         AC_SUBST(HAVE_DPKG)
280         AC_SUBST(DPKG)
281         AC_SUBST(DPKG_VERSION)
282
283         AC_SUBST(HAVE_DPKGBUILD)
284         AC_SUBST(DPKGBUILD)
285         AC_SUBST(DPKGBUILD_VERSION)
286 ])
287
288 dnl #
289 dnl # Until native packaging for various different packing systems
290 dnl # can be added the least we can do is attempt to use alien to
291 dnl # convert the RPM packages to the needed package type.  This is
292 dnl # a hack but so far it has worked reasonable well.
293 dnl #
294 AC_DEFUN([SPL_AC_ALIEN], [
295         ALIEN=alien
296
297         AC_MSG_CHECKING([whether $ALIEN is available])
298         AS_IF([tmp=$($ALIEN --version 2>/dev/null)], [
299                 ALIEN_VERSION=$(echo $tmp | $AWK '{ print $[3] }')
300                 HAVE_ALIEN=yes
301                 AC_MSG_RESULT([$HAVE_ALIEN ($ALIEN_VERSION)])
302         ],[
303                 HAVE_ALIEN=no
304                 AC_MSG_RESULT([$HAVE_ALIEN])
305         ])
306
307         AC_SUBST(HAVE_ALIEN)
308         AC_SUBST(ALIEN)
309         AC_SUBST(ALIEN_VERSION)
310 ])
311
312 dnl #
313 dnl # Using the VENDOR tag from config.guess set the default
314 dnl # package type for 'make pkg': (rpm | deb | tgz)
315 dnl #
316 AC_DEFUN([SPL_AC_DEFAULT_PACKAGE], [
317         AC_MSG_CHECKING([linux distribution])
318         if test -f /etc/redhat-release ; then
319                 VENDOR=redhat ;
320         elif test -f /etc/fedora-release ; then
321                 VENDOR=fedora ;
322         elif test -f /etc/lsb-release ; then
323                 VENDOR=ubuntu ;
324         elif test -f /etc/debian_version ; then
325                 VENDOR=debian ;
326         elif test -f /etc/SuSE-release ; then
327                 VENDOR=sles ;
328         elif test -f /etc/slackware-version ; then
329                 VENDOR=slackware ;
330         elif test -f /etc/gentoo-release ; then
331                 VENDOR=gentoo ;
332         else
333                 VENDOR= ;
334         fi
335         AC_MSG_RESULT([$VENDOR])
336         AC_SUBST(VENDOR)
337
338         AC_MSG_CHECKING([default package type])
339         case "$VENDOR" in
340                 fedora)     DEFAULT_PACKAGE=rpm ;;
341                 redhat)     DEFAULT_PACKAGE=rpm ;;
342                 sles)       DEFAULT_PACKAGE=rpm ;;
343                 ubuntu)     DEFAULT_PACKAGE=deb ;;
344                 debian)     DEFAULT_PACKAGE=deb ;;
345                 slackware)  DEFAULT_PACKAGE=tgz ;;
346                 *)          DEFAULT_PACKAGE=rpm ;;
347         esac
348
349         AC_MSG_RESULT([$DEFAULT_PACKAGE])
350         AC_SUBST(DEFAULT_PACKAGE)
351 ])
352
353 dnl #
354 dnl # Default SPL user configuration
355 dnl #
356 AC_DEFUN([SPL_AC_PACKAGE], [
357         SPL_AC_RPM
358         SPL_AC_DPKG
359         SPL_AC_ALIEN
360         SPL_AC_DEFAULT_PACKAGE
361 ])
362
363 AC_DEFUN([SPL_AC_LICENSE], [
364         AC_MSG_CHECKING([spl license])
365         LICENSE=GPL
366         AC_MSG_RESULT([$LICENSE])
367         KERNELCPPFLAGS="${KERNELCPPFLAGS} -DHAVE_GPL_ONLY_SYMBOLS"
368         AC_SUBST(LICENSE)
369 ])
370
371 AC_DEFUN([SPL_AC_CONFIG], [
372         SPL_CONFIG=all
373         AC_ARG_WITH([config],
374                 AS_HELP_STRING([--with-config=CONFIG],
375                 [Config file 'kernel|user|all|srpm']),
376                 [SPL_CONFIG="$withval"])
377
378         AC_MSG_CHECKING([spl config])
379         AC_MSG_RESULT([$SPL_CONFIG]);
380         AC_SUBST(SPL_CONFIG)
381
382         case "$SPL_CONFIG" in
383                 kernel) SPL_AC_CONFIG_KERNEL ;;
384                 user)   SPL_AC_CONFIG_USER   ;;
385                 all)    SPL_AC_CONFIG_KERNEL
386                         SPL_AC_CONFIG_USER   ;;
387                 srpm)                        ;;
388                 *)
389                 AC_MSG_RESULT([Error!])
390                 AC_MSG_ERROR([Bad value "$SPL_CONFIG" for --with-config,
391                               user kernel|user|all|srpm]) ;;
392         esac
393
394         AM_CONDITIONAL([CONFIG_USER],
395                        [test "$SPL_CONFIG" = user] ||
396                        [test "$SPL_CONFIG" = all])
397         AM_CONDITIONAL([CONFIG_KERNEL],
398                        [test "$SPL_CONFIG" = kernel] ||
399                        [test "$SPL_CONFIG" = all])
400 ])
401
402 dnl #
403 dnl # Enable if the SPL should be compiled with internal debugging enabled.
404 dnl # By default this support is disabled.
405 dnl #
406 AC_DEFUN([SPL_AC_DEBUG], [
407         AC_MSG_CHECKING([whether debugging is enabled])
408         AC_ARG_ENABLE([debug],
409                 [AS_HELP_STRING([--enable-debug],
410                 [Enable generic debug support @<:@default=no@:>@])],
411                 [],
412                 [enable_debug=no])
413
414         AS_IF([test "x$enable_debug" = xyes],
415         [
416                 KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG -Werror"
417                 DEBUG_CFLAGS="-DDEBUG -Werror"
418         ],
419         [
420                 KERNELCPPFLAGS="${KERNELCPPFLAGS} -DNDEBUG"
421                 DEBUG_CFLAGS="-DNDEBUG"
422         ])
423
424         AC_SUBST(DEBUG_CFLAGS)
425         AC_MSG_RESULT([$enable_debug])
426 ])
427
428 dnl #
429 dnl # Enabled by default it provides a minimal level of memory tracking.
430 dnl # A total count of bytes allocated is kept for each alloc and free.
431 dnl # Then at module unload time a report to the console will be printed
432 dnl # if memory was leaked.  Additionally, /proc/spl/kmem/slab will exist
433 dnl # and provide an easy way to inspect the kmem based slab.
434 dnl #
435 AC_DEFUN([SPL_AC_DEBUG_KMEM], [
436         AC_ARG_ENABLE([debug-kmem],
437                 [AS_HELP_STRING([--enable-debug-kmem],
438                 [Enable basic kmem accounting @<:@default=yes@:>@])],
439                 [],
440                 [enable_debug_kmem=yes])
441
442         AS_IF([test "x$enable_debug_kmem" = xyes],
443                 [AC_DEFINE([DEBUG_KMEM], [1],
444                 [Define to 1 to enable basic kmem accounting])
445                 KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_KMEM"])
446
447         AC_MSG_CHECKING([whether basic kmem accounting is enabled])
448         AC_MSG_RESULT([$enable_debug_kmem])
449 ])
450
451 dnl #
452 dnl # Disabled by default it provides detailed memory tracking.  This
453 dnl # feature also requires --enable-debug-kmem to be set.  When enabled
454 dnl # not only will total bytes be tracked but also the location of every
455 dnl # alloc and free.  When the SPL module is unloaded a list of all leaked
456 dnl # addresses and where they were allocated will be dumped to the console.
457 dnl # Enabling this feature has a significant impact on performance but it
458 dnl # makes finding memory leaks pretty straight forward.
459 dnl #
460 AC_DEFUN([SPL_AC_DEBUG_KMEM_TRACKING], [
461         AC_ARG_ENABLE([debug-kmem-tracking],
462                 [AS_HELP_STRING([--enable-debug-kmem-tracking],
463                 [Enable detailed kmem tracking  @<:@default=no@:>@])],
464                 [],
465                 [enable_debug_kmem_tracking=no])
466
467         AS_IF([test "x$enable_debug_kmem_tracking" = xyes],
468                 [AC_DEFINE([DEBUG_KMEM_TRACKING], [1],
469                 [Define to 1 to enable detailed kmem tracking])
470                 KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_KMEM_TRACKING"])
471
472         AC_MSG_CHECKING([whether detailed kmem tracking is enabled])
473         AC_MSG_RESULT([$enable_debug_kmem_tracking])
474 ])
475
476 dnl #
477 dnl # SPL_LINUX_CONFTEST
478 dnl #
479 AC_DEFUN([SPL_LINUX_CONFTEST], [
480 cat confdefs.h - <<_ACEOF >conftest.c
481 $1
482 _ACEOF
483 ])
484
485 dnl #
486 dnl # SPL_LANG_PROGRAM(C)([PROLOGUE], [BODY])
487 dnl #
488 m4_define([SPL_LANG_PROGRAM], [
489 $1
490 int
491 main (void)
492 {
493 dnl Do *not* indent the following line: there may be CPP directives.
494 dnl Don't move the `;' right after for the same reason.
495 $2
496   ;
497   return 0;
498 }
499 ])
500
501 dnl #
502 dnl # SPL_LINUX_COMPILE_IFELSE / like AC_COMPILE_IFELSE
503 dnl #
504 AC_DEFUN([SPL_LINUX_COMPILE_IFELSE], [
505         m4_ifvaln([$1], [SPL_LINUX_CONFTEST([$1])])
506         rm -Rf build && mkdir -p build
507         echo "obj-m := conftest.o" >build/Makefile
508         AS_IF(
509                 [AC_TRY_COMMAND(cp conftest.c build && make [$2] -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build) >/dev/null && AC_TRY_COMMAND([$3])],
510                 [$4],
511                 [_AC_MSG_LOG_CONFTEST m4_ifvaln([$5],[$5])]
512         )
513         rm -Rf build
514 ])
515
516 dnl #
517 dnl # SPL_LINUX_TRY_COMPILE like AC_TRY_COMPILE
518 dnl #
519 AC_DEFUN([SPL_LINUX_TRY_COMPILE],
520         [SPL_LINUX_COMPILE_IFELSE(
521         [AC_LANG_SOURCE([SPL_LANG_PROGRAM([[$1]], [[$2]])])],
522         [modules],
523         [test -s build/conftest.o],
524         [$3], [$4])
525 ])
526
527 dnl #
528 dnl # SPL_LINUX_CONFIG
529 dnl #
530 AC_DEFUN([SPL_LINUX_CONFIG],
531         [AC_MSG_CHECKING([whether Linux was built with CONFIG_$1])
532         SPL_LINUX_TRY_COMPILE([
533                 #ifndef AUTOCONF_INCLUDED
534                 #include <linux/config.h>
535                 #endif
536         ],[
537                 #ifndef CONFIG_$1
538                 #error CONFIG_$1 not #defined
539                 #endif
540         ],[
541                 AC_MSG_RESULT([yes])
542                 $2
543         ],[
544                 AC_MSG_RESULT([no])
545                 $3
546         ])
547 ])
548
549 dnl #
550 dnl # SPL_CHECK_SYMBOL_EXPORT
551 dnl # check symbol exported or not
552 dnl #
553 AC_DEFUN([SPL_CHECK_SYMBOL_EXPORT],
554         [AC_MSG_CHECKING([whether symbol $1 is exported])
555         grep -q -E '[[[:space:]]]$1[[[:space:]]]' \
556                 $LINUX_OBJ/Module*.symvers 2>/dev/null
557         rc=$?
558         if test $rc -ne 0; then
559                 export=0
560                 for file in $2; do
561                         grep -q -E "EXPORT_SYMBOL.*($1)" \
562                                 "$LINUX_OBJ/$file" 2>/dev/null
563                         rc=$?
564                         if test $rc -eq 0; then
565                                 export=1
566                                 break;
567                         fi
568                 done
569                 if test $export -eq 0; then
570                         AC_MSG_RESULT([no])
571                         $4
572                 else
573                         AC_MSG_RESULT([yes])
574                         $3
575                 fi
576         else
577                 AC_MSG_RESULT([yes])
578                 $3
579         fi
580 ])
581
582 dnl #
583 dnl # SPL_CHECK_HEADER
584 dnl # check whether header exists and define HAVE_$2_HEADER
585 dnl #
586 AC_DEFUN([SPL_CHECK_HEADER],
587         [AC_MSG_CHECKING([whether header $1 exists])
588         SPL_LINUX_TRY_COMPILE([
589                 #include <$1>
590         ],[
591                 return 0;
592         ],[
593                 AC_DEFINE(HAVE_$2_HEADER, 1, [$1 exists])
594                 AC_MSG_RESULT(yes)
595                 $3
596         ],[
597                 AC_MSG_RESULT(no)
598                 $4
599         ])
600 ])
601
602 dnl #
603 dnl # Use the atomic implemenation based on global spinlocks.  This
604 dnl # should only be needed by 32-bit kernels which do not provide
605 dnl # the atomic64_* API.  It may be optionally enabled as a fallback
606 dnl # if problems are observed with the direct mapping to the native
607 dnl # Linux atomic operations.  You may not disable atomic spinlocks
608 dnl # if you kernel does not an atomic64_* API.
609 dnl #
610 AC_DEFUN([SPL_AC_ATOMIC_SPINLOCK], [
611         AC_ARG_ENABLE([atomic-spinlocks],
612                 [AS_HELP_STRING([--enable-atomic-spinlocks],
613                 [Atomic types use spinlocks @<:@default=check@:>@])],
614                 [],
615                 [enable_atomic_spinlocks=check])
616
617         SPL_LINUX_TRY_COMPILE([
618                 #include <asm/atomic.h>
619         ],[
620                 atomic64_t *ptr;
621         ],[
622                 have_atomic64_t=yes
623                 AC_DEFINE(HAVE_ATOMIC64_T, 1,
624                         [kernel defines atomic64_t])
625         ],[
626                 have_atomic64_t=no
627         ])
628
629         AS_IF([test "x$enable_atomic_spinlocks" = xcheck], [
630                 AS_IF([test "x$have_atomic64_t" = xyes], [
631                         enable_atomic_spinlocks=no
632                 ],[
633                         enable_atomic_spinlocks=yes
634                 ])
635         ])
636
637         AS_IF([test "x$enable_atomic_spinlocks" = xyes], [
638                 AC_DEFINE([ATOMIC_SPINLOCK], [1],
639                         [Atomic types use spinlocks])
640         ],[
641                 AS_IF([test "x$have_atomic64_t" = xno], [
642                         AC_MSG_FAILURE(
643                         [--disable-atomic-spinlocks given but required atomic64 support is unavailable])
644                 ])
645         ])
646
647         AC_MSG_CHECKING([whether atomic types use spinlocks])
648         AC_MSG_RESULT([$enable_atomic_spinlocks])
649
650         AC_MSG_CHECKING([whether kernel defines atomic64_t])
651         AC_MSG_RESULT([$have_atomic64_t])
652 ])
653
654 dnl #
655 dnl # 2.6.24 API change,
656 dnl # check if atomic64_cmpxchg is defined
657 dnl #
658 AC_DEFUN([SPL_AC_TYPE_ATOMIC64_CMPXCHG],
659         [AC_MSG_CHECKING([whether kernel defines atomic64_cmpxchg])
660         SPL_LINUX_TRY_COMPILE([
661                 #include <asm/atomic.h>
662                 #include <asm/system.h>
663         ],[
664                 atomic64_cmpxchg((atomic64_t *)NULL, 0, 0);
665         ],[
666                 AC_MSG_RESULT([yes])
667                 AC_DEFINE(HAVE_ATOMIC64_CMPXCHG, 1,
668                           [kernel defines atomic64_cmpxchg])
669         ],[
670                 AC_MSG_RESULT([no])
671         ])
672 ])
673
674 dnl #
675 dnl # 2.6.24 API change,
676 dnl # check if atomic64_xchg is defined
677 dnl #
678 AC_DEFUN([SPL_AC_TYPE_ATOMIC64_XCHG],
679         [AC_MSG_CHECKING([whether kernel defines atomic64_xchg])
680         SPL_LINUX_TRY_COMPILE([
681                 #include <asm/atomic.h>
682         ],[
683                 atomic64_xchg((atomic64_t *)NULL, 0);
684         ],[
685                 AC_MSG_RESULT([yes])
686                 AC_DEFINE(HAVE_ATOMIC64_XCHG, 1,
687                           [kernel defines atomic64_xchg])
688         ],[
689                 AC_MSG_RESULT([no])
690         ])
691 ])
692
693 dnl #
694 dnl # 2.6.24 API change,
695 dnl # check if uintptr_t typedef is defined
696 dnl #
697 AC_DEFUN([SPL_AC_TYPE_UINTPTR_T],
698         [AC_MSG_CHECKING([whether kernel defines uintptr_t])
699         SPL_LINUX_TRY_COMPILE([
700                 #include <linux/types.h>
701         ],[
702                 uintptr_t *ptr;
703         ],[
704                 AC_MSG_RESULT([yes])
705                 AC_DEFINE(HAVE_UINTPTR_T, 1,
706                           [kernel defines uintptr_t])
707         ],[
708                 AC_MSG_RESULT([no])
709         ])
710 ])
711
712 dnl #
713 dnl # 2.6.20 API change,
714 dnl # INIT_WORK use 2 args and not store data inside
715 dnl #
716 AC_DEFUN([SPL_AC_3ARGS_INIT_WORK],
717         [AC_MSG_CHECKING([whether INIT_WORK wants 3 args])
718         SPL_LINUX_TRY_COMPILE([
719                 #include <linux/workqueue.h>
720         ],[
721                 struct work_struct work;
722                 INIT_WORK(&work, NULL, NULL);
723         ],[
724                 AC_MSG_RESULT(yes)
725                 AC_DEFINE(HAVE_3ARGS_INIT_WORK, 1,
726                           [INIT_WORK wants 3 args])
727         ],[
728                 AC_MSG_RESULT(no)
729         ])
730 ])
731
732 dnl #
733 dnl # 2.6.21 API change,
734 dnl # 'register_sysctl_table' use only one argument instead of two
735 dnl #
736 AC_DEFUN([SPL_AC_2ARGS_REGISTER_SYSCTL],
737         [AC_MSG_CHECKING([whether register_sysctl_table() wants 2 args])
738         SPL_LINUX_TRY_COMPILE([
739                 #include <linux/sysctl.h>
740         ],[
741                 return register_sysctl_table(NULL,0);
742         ],[
743                 AC_MSG_RESULT(yes)
744                 AC_DEFINE(HAVE_2ARGS_REGISTER_SYSCTL, 1,
745                           [register_sysctl_table() wants 2 args])
746         ],[
747                 AC_MSG_RESULT(no)
748         ])
749 ])
750
751 dnl #
752 dnl # 2.6.23 API change
753 dnl # Old set_shrinker API replaced with register_shrinker
754 dnl #
755 AC_DEFUN([SPL_AC_SET_SHRINKER], [
756         AC_MSG_CHECKING([whether set_shrinker() available])
757         SPL_LINUX_TRY_COMPILE([
758                 #include <linux/mm.h>
759         ],[
760                 return set_shrinker(DEFAULT_SEEKS, NULL);
761         ],[
762                 AC_MSG_RESULT([yes])
763                 AC_DEFINE(HAVE_SET_SHRINKER, 1,
764                           [set_shrinker() available])
765         ],[
766                 AC_MSG_RESULT([no])
767         ])
768 ])
769
770 dnl #
771 dnl # 2.6.25 API change,
772 dnl # struct path entry added to struct nameidata
773 dnl #
774 AC_DEFUN([SPL_AC_PATH_IN_NAMEIDATA],
775         [AC_MSG_CHECKING([whether struct path used in struct nameidata])
776         SPL_LINUX_TRY_COMPILE([
777                 #include <linux/namei.h>
778         ],[
779                 struct nameidata nd;
780
781                 nd.path.mnt = NULL;
782                 nd.path.dentry = NULL;
783         ],[
784                 AC_MSG_RESULT(yes)
785                 AC_DEFINE(HAVE_PATH_IN_NAMEIDATA, 1,
786                           [struct path used in struct nameidata])
787         ],[
788                 AC_MSG_RESULT(no)
789         ])
790 ])
791
792 dnl #
793 dnl # Custom SPL patch may export this system it is not required
794 dnl #
795 AC_DEFUN([SPL_AC_TASK_CURR], [
796         SPL_CHECK_SYMBOL_EXPORT([task_curr], [kernel/sched.c],
797                 [AC_DEFINE(HAVE_TASK_CURR, 1, [task_curr() exported])],
798                 [])
799 ])
800
801 dnl #
802 dnl # 2.6.19 API change,
803 dnl # Use CTL_UNNUMBERED when binary sysctl is not required
804 dnl #
805 AC_DEFUN([SPL_AC_CTL_UNNUMBERED],
806         [AC_MSG_CHECKING([whether unnumbered sysctl support exists])
807         SPL_LINUX_TRY_COMPILE([
808                 #include <linux/sysctl.h>
809         ],[
810                 #ifndef CTL_UNNUMBERED
811                 #error CTL_UNNUMBERED undefined
812                 #endif
813         ],[
814                 AC_MSG_RESULT(yes)
815                 AC_DEFINE(HAVE_CTL_UNNUMBERED, 1,
816                           [unnumbered sysctl support exists])
817         ],[
818                 AC_MSG_RESULT(no)
819         ])
820 ])
821
822 dnl #
823 dnl # 2.6.33 API change,
824 dnl # Removed .ctl_name from struct ctl_table.
825 dnl #
826 AC_DEFUN([SPL_AC_CTL_NAME], [
827         AC_MSG_CHECKING([whether struct ctl_table has ctl_name])
828         SPL_LINUX_TRY_COMPILE([
829                 #include <linux/sysctl.h>
830         ],[
831                 struct ctl_table ctl;
832                 ctl.ctl_name = 0;
833         ],[
834                 AC_MSG_RESULT(yes)
835                 AC_DEFINE(HAVE_CTL_NAME, 1, [struct ctl_table has ctl_name])
836         ],[
837                 AC_MSG_RESULT(no)
838         ])
839 ])
840
841 dnl #
842 dnl # 2.6.16 API change.
843 dnl # Check if 'fls64()' is available
844 dnl #
845 AC_DEFUN([SPL_AC_FLS64],
846         [AC_MSG_CHECKING([whether fls64() is available])
847         SPL_LINUX_TRY_COMPILE([
848                 #include <linux/bitops.h>
849         ],[
850                 return fls64(0);
851         ],[
852                 AC_MSG_RESULT(yes)
853                 AC_DEFINE(HAVE_FLS64, 1, [fls64() is available])
854         ],[
855                 AC_MSG_RESULT(no)
856         ])
857 ])
858
859 dnl #
860 dnl # 2.6.18 API change, check whether device_create() is available.
861 dnl # Device_create() was introduced in 2.6.18 and depricated 
862 dnl # class_device_create() which was fully removed in 2.6.26.
863 dnl #
864 AC_DEFUN([SPL_AC_DEVICE_CREATE], [
865         SPL_CHECK_SYMBOL_EXPORT(
866                 [device_create],
867                 [drivers/base/core.c],
868                 [AC_DEFINE(HAVE_DEVICE_CREATE, 1,
869                 [device_create() is available])],
870                 [])
871 ])
872
873 dnl #
874 dnl # 2.6.27 API change,
875 dnl # device_create() uses 5 args, new 'drvdata' argument.
876 dnl #
877 AC_DEFUN([SPL_AC_5ARGS_DEVICE_CREATE], [
878         AC_MSG_CHECKING([whether device_create() wants 5 args])
879         tmp_flags="$EXTRA_KCFLAGS"
880         EXTRA_KCFLAGS="-Werror"
881         SPL_LINUX_TRY_COMPILE([
882                 #include <linux/device.h>
883         ],[
884                 device_create(NULL, NULL, 0, NULL, "%d", 1);
885         ],[
886                 AC_MSG_RESULT(yes)
887                 AC_DEFINE(HAVE_5ARGS_DEVICE_CREATE, 1,
888                           [device_create wants 5 args])
889         ],[
890                 AC_MSG_RESULT(no)
891         ])
892         EXTRA_KCFLAGS="$tmp_flags"
893 ])
894
895 dnl #
896 dnl # 2.6.13 API change, check whether class_device_create() is available.
897 dnl # Class_device_create() was introduced in 2.6.13 and depricated
898 dnl # class_simple_device_add() which was fully removed in 2.6.13.
899 dnl #
900 AC_DEFUN([SPL_AC_CLASS_DEVICE_CREATE], [
901         SPL_CHECK_SYMBOL_EXPORT(
902                 [class_device_create],
903                 [drivers/base/class.c],
904                 [AC_DEFINE(HAVE_CLASS_DEVICE_CREATE, 1,
905                 [class_device_create() is available])],
906                 [])
907 ])
908
909 dnl #
910 dnl # 2.6.26 API change, set_normalized_timespec() is exported.
911 dnl #
912 AC_DEFUN([SPL_AC_SET_NORMALIZED_TIMESPEC_EXPORT], [
913         SPL_CHECK_SYMBOL_EXPORT(
914                 [set_normalized_timespec],
915                 [kernel/time.c],
916                 [AC_DEFINE(HAVE_SET_NORMALIZED_TIMESPEC_EXPORT, 1,
917                 [set_normalized_timespec() is available as export])],
918                 [])
919 ])
920
921 dnl #
922 dnl # 2.6.16 API change, set_normalize_timespec() moved to time.c
923 dnl # previously it was available in time.h as an inline.
924 dnl #
925 AC_DEFUN([SPL_AC_SET_NORMALIZED_TIMESPEC_INLINE], [
926         AC_MSG_CHECKING([whether set_normalized_timespec() is an inline])
927         SPL_LINUX_TRY_COMPILE([
928                 #include <linux/time.h>
929                 void set_normalized_timespec(struct timespec *ts,
930                                              time_t sec, long nsec) { }
931         ],
932         [],
933         [
934                 AC_MSG_RESULT(no)
935         ],[
936                 AC_MSG_RESULT(yes)
937                 AC_DEFINE(HAVE_SET_NORMALIZED_TIMESPEC_INLINE, 1,
938                           [set_normalized_timespec() is available as inline])
939         ])
940 ])
941
942 dnl #
943 dnl # 2.6.18 API change,
944 dnl # timespec_sub() inline function available in linux/time.h
945 dnl #
946 AC_DEFUN([SPL_AC_TIMESPEC_SUB], [
947         AC_MSG_CHECKING([whether timespec_sub() is available])
948         SPL_LINUX_TRY_COMPILE([
949                 #include <linux/time.h>
950         ],[
951                 struct timespec a, b, c = { 0 };
952                 c = timespec_sub(a, b);
953         ],[
954                 AC_MSG_RESULT(yes)
955                 AC_DEFINE(HAVE_TIMESPEC_SUB, 1, [timespec_sub() is available])
956         ],[
957                 AC_MSG_RESULT(no)
958         ])
959 ])
960
961 dnl #
962 dnl # 2.6.19 API change,
963 dnl # check if init_utsname() is available in linux/utsname.h
964 dnl #
965 AC_DEFUN([SPL_AC_INIT_UTSNAME], [
966         AC_MSG_CHECKING([whether init_utsname() is available])
967         SPL_LINUX_TRY_COMPILE([
968                 #include <linux/utsname.h>
969         ],[
970                 struct new_utsname *a = init_utsname();
971         ],[
972                 AC_MSG_RESULT(yes)
973                 AC_DEFINE(HAVE_INIT_UTSNAME, 1, [init_utsname() is available])
974         ],[
975                 AC_MSG_RESULT(no)
976         ])
977 ])
978
979 dnl #
980 dnl # 2.6.26 API change,
981 dnl # definition of struct fdtable relocated to linux/fdtable.h
982 dnl #
983 AC_DEFUN([SPL_AC_FDTABLE_HEADER], [
984         SPL_CHECK_HEADER([linux/fdtable.h], [FDTABLE], [], [])
985 ])
986
987 dnl #
988 dnl # 2.6.14 API change,
989 dnl # check whether 'files_fdtable()' exists
990 dnl #
991 AC_DEFUN([SPL_AC_FILES_FDTABLE], [
992         AC_MSG_CHECKING([whether files_fdtable() is available])
993         SPL_LINUX_TRY_COMPILE([
994                 #include <linux/sched.h>
995                 #include <linux/file.h>
996                 #ifdef HAVE_FDTABLE_HEADER
997                 #include <linux/fdtable.h>
998                 #endif
999         ],[
1000                 struct files_struct *files = current->files;
1001                 struct fdtable *fdt = files_fdtable(files);
1002         ],[
1003                 AC_MSG_RESULT(yes)
1004                 AC_DEFINE(HAVE_FILES_FDTABLE, 1, [files_fdtable() is available])
1005         ],[
1006                 AC_MSG_RESULT(no)
1007         ])
1008 ])
1009
1010 dnl #
1011 dnl # 2.6.18 API change,
1012 dnl # added linux/uaccess.h
1013 dnl #
1014 AC_DEFUN([SPL_AC_UACCESS_HEADER], [
1015         SPL_CHECK_HEADER([linux/uaccess.h], [UACCESS], [], [])
1016 ])
1017
1018 dnl #
1019 dnl # 2.6.12 API change,
1020 dnl # check whether 'kmalloc_node()' is available.
1021 dnl #
1022 AC_DEFUN([SPL_AC_KMALLOC_NODE], [
1023         AC_MSG_CHECKING([whether kmalloc_node() is available])
1024         SPL_LINUX_TRY_COMPILE([
1025                 #include <linux/slab.h>
1026         ],[
1027                 void *a = kmalloc_node(1, GFP_KERNEL, 0);
1028         ],[
1029                 AC_MSG_RESULT(yes)
1030                 AC_DEFINE(HAVE_KMALLOC_NODE, 1, [kmalloc_node() is available])
1031         ],[
1032                 AC_MSG_RESULT(no)
1033         ])
1034 ])
1035
1036 dnl #
1037 dnl # 2.6.9 API change,
1038 dnl # check whether 'monotonic_clock()' is available it may
1039 dnl # be available for some archs but not others.
1040 dnl #
1041 AC_DEFUN([SPL_AC_MONOTONIC_CLOCK], [
1042         SPL_CHECK_SYMBOL_EXPORT(
1043                 [monotonic_clock],
1044                 [],
1045                 [AC_DEFINE(HAVE_MONOTONIC_CLOCK, 1,
1046                 [monotonic_clock() is available])],
1047                 [])
1048 ])
1049
1050 dnl #
1051 dnl # 2.6.16 API change,
1052 dnl # check whether 'struct inode' has i_mutex
1053 dnl #
1054 AC_DEFUN([SPL_AC_INODE_I_MUTEX], [
1055         AC_MSG_CHECKING([whether struct inode has i_mutex])
1056         SPL_LINUX_TRY_COMPILE([
1057                 #include <linux/fs.h>
1058                 #include <linux/mutex.h>
1059         ],[
1060                 struct inode i;
1061                 mutex_init(&i.i_mutex);
1062         ],[
1063                 AC_MSG_RESULT(yes)
1064                 AC_DEFINE(HAVE_INODE_I_MUTEX, 1, [struct inode has i_mutex])
1065         ],[
1066                 AC_MSG_RESULT(no)
1067         ])
1068 ])
1069
1070 dnl #
1071 dnl # 2.6.29 API change,
1072 dnl # Adaptive mutexs introduced.
1073 dnl #
1074 AC_DEFUN([SPL_AC_MUTEX_OWNER], [
1075         AC_MSG_CHECKING([whether struct mutex has owner])
1076         SPL_LINUX_TRY_COMPILE([
1077                 #include <linux/mutex.h>
1078         ],[
1079                 struct mutex mtx;
1080                 mtx.owner = NULL;
1081         ],[
1082                 AC_MSG_RESULT(yes)
1083                 AC_DEFINE(HAVE_MUTEX_OWNER, 1, [struct mutex has owner])
1084         ],[
1085                 AC_MSG_RESULT(no)
1086         ])
1087 ])
1088
1089 dnl #
1090 dnl # 2.6.18 API change,
1091 dnl # First introduced 'mutex_lock_nested()' in include/linux/mutex.h,
1092 dnl # as part of the mutex validator.  Fallback to using 'mutex_lock()' 
1093 dnl # if the mutex validator is disabled or otherwise unavailable.
1094 dnl #
1095 AC_DEFUN([SPL_AC_MUTEX_LOCK_NESTED], [
1096         AC_MSG_CHECKING([whether mutex_lock_nested() is available])
1097         SPL_LINUX_TRY_COMPILE([
1098                 #include <linux/mutex.h>
1099         ],[
1100                 struct mutex mutex;
1101                 mutex_init(&mutex);
1102                 mutex_lock_nested(&mutex, 0);
1103         ],[
1104                 AC_MSG_RESULT(yes)
1105                 AC_DEFINE(HAVE_MUTEX_LOCK_NESTED, 1,
1106                 [mutex_lock_nested() is available])
1107         ],[
1108                 AC_MSG_RESULT(no)
1109         ])
1110 ])
1111
1112 dnl #
1113 dnl # 2.6.27 API change,
1114 dnl # on_each_cpu() uses 3 args, no 'retry' argument
1115 dnl #
1116 AC_DEFUN([SPL_AC_3ARGS_ON_EACH_CPU], [
1117         AC_MSG_CHECKING([whether on_each_cpu() wants 3 args])
1118         SPL_LINUX_TRY_COMPILE([
1119                 #include <linux/smp.h>
1120         ],[
1121                 on_each_cpu(NULL, NULL, 0);
1122         ],[
1123                 AC_MSG_RESULT(yes)
1124                 AC_DEFINE(HAVE_3ARGS_ON_EACH_CPU, 1,
1125                           [on_each_cpu wants 3 args])
1126         ],[
1127                 AC_MSG_RESULT(no)
1128         ])
1129 ])
1130
1131 dnl #
1132 dnl # 2.6.18 API change,
1133 dnl # kallsyms_lookup_name no longer exported
1134 dnl #
1135 AC_DEFUN([SPL_AC_KALLSYMS_LOOKUP_NAME], [
1136         SPL_CHECK_SYMBOL_EXPORT(
1137                 [kallsyms_lookup_name],
1138                 [],
1139                 [AC_DEFINE(HAVE_KALLSYMS_LOOKUP_NAME, 1,
1140                 [kallsyms_lookup_name() is available])],
1141                 [])
1142 ])
1143
1144 dnl #
1145 dnl # Proposed API change,
1146 dnl # This symbol is not available in stock kernels.  You may build a
1147 dnl # custom kernel with the *-spl-export-symbols.patch which will export
1148 dnl # these symbols for use.  If your already rolling a custom kernel for
1149 dnl # your environment this is recommended.
1150 dnl #
1151 AC_DEFUN([SPL_AC_GET_VMALLOC_INFO], [
1152         SPL_CHECK_SYMBOL_EXPORT(
1153                 [get_vmalloc_info],
1154                 [],
1155                 [AC_DEFINE(HAVE_GET_VMALLOC_INFO, 1,
1156                 [get_vmalloc_info() is available])],
1157                 [])
1158 ])
1159
1160 dnl #
1161 dnl # 2.6.17 API change
1162 dnl # The helper functions first_online_pgdat(), next_online_pgdat(), and
1163 dnl # next_zone() are introduced to simplify for_each_zone().  These symbols
1164 dnl # were exported in 2.6.17 for use by modules which was consistent with
1165 dnl # the previous implementation of for_each_zone().  From 2.6.18 - 2.6.19
1166 dnl # the symbols were exported as 'unused', and by 2.6.20 they exports
1167 dnl # were dropped entirely leaving modules no way to directly iterate over
1168 dnl # the zone list.  Because we need access to the zone helpers we check
1169 dnl # if the kernel contains the old or new implementation.  Then we check
1170 dnl # to see if the symbols we need for each version are available.  If they
1171 dnl # are not, dynamically aquire the addresses with kallsyms_lookup_name().
1172 dnl #
1173 AC_DEFUN([SPL_AC_PGDAT_HELPERS], [
1174         AC_MSG_CHECKING([whether symbol *_pgdat exist])
1175         grep -q -E 'first_online_pgdat' $LINUX/include/linux/mmzone.h 2>/dev/null
1176         rc=$?
1177         if test $rc -eq 0; then
1178                 AC_MSG_RESULT([yes])
1179                 AC_DEFINE(HAVE_PGDAT_HELPERS, 1, [pgdat helpers are available])
1180         else
1181                 AC_MSG_RESULT([no])
1182         fi
1183 ])
1184
1185 dnl #
1186 dnl # Proposed API change,
1187 dnl # This symbol is not available in stock kernels.  You may build a
1188 dnl # custom kernel with the *-spl-export-symbols.patch which will export
1189 dnl # these symbols for use.  If your already rolling a custom kernel for
1190 dnl # your environment this is recommended.
1191 dnl #
1192 AC_DEFUN([SPL_AC_FIRST_ONLINE_PGDAT], [
1193         SPL_CHECK_SYMBOL_EXPORT(
1194                 [first_online_pgdat],
1195                 [],
1196                 [AC_DEFINE(HAVE_FIRST_ONLINE_PGDAT, 1,
1197                 [first_online_pgdat() is available])],
1198                 [])
1199 ])
1200
1201 dnl #
1202 dnl # Proposed API change,
1203 dnl # This symbol is not available in stock kernels.  You may build a
1204 dnl # custom kernel with the *-spl-export-symbols.patch which will export
1205 dnl # these symbols for use.  If your already rolling a custom kernel for
1206 dnl # your environment this is recommended.
1207 dnl #
1208 AC_DEFUN([SPL_AC_NEXT_ONLINE_PGDAT], [
1209         SPL_CHECK_SYMBOL_EXPORT(
1210                 [next_online_pgdat],
1211                 [],
1212                 [AC_DEFINE(HAVE_NEXT_ONLINE_PGDAT, 1,
1213                 [next_online_pgdat() is available])],
1214                 [])
1215 ])
1216
1217 dnl #
1218 dnl # Proposed API change,
1219 dnl # This symbol is not available in stock kernels.  You may build a
1220 dnl # custom kernel with the *-spl-export-symbols.patch which will export
1221 dnl # these symbols for use.  If your already rolling a custom kernel for
1222 dnl # your environment this is recommended.
1223 dnl #
1224 AC_DEFUN([SPL_AC_NEXT_ZONE], [
1225         SPL_CHECK_SYMBOL_EXPORT(
1226                 [next_zone],
1227                 [],
1228                 [AC_DEFINE(HAVE_NEXT_ZONE, 1,
1229                 [next_zone() is available])],
1230                 [])
1231 ])
1232
1233 dnl #
1234 dnl # 2.6.17 API change,
1235 dnl # See SPL_AC_PGDAT_HELPERS for details.
1236 dnl #
1237 AC_DEFUN([SPL_AC_PGDAT_LIST], [
1238         SPL_CHECK_SYMBOL_EXPORT(
1239                 [pgdat_list],
1240                 [],
1241                 [AC_DEFINE(HAVE_PGDAT_LIST, 1,
1242                 [pgdat_list is available])],
1243                 [])
1244 ])
1245
1246 dnl #
1247 dnl # 2.6.18 API change,
1248 dnl # First introduced global_page_state() support as an inline.
1249 dnl #
1250 AC_DEFUN([SPL_AC_GLOBAL_PAGE_STATE], [
1251         AC_MSG_CHECKING([whether global_page_state() is available])
1252         SPL_LINUX_TRY_COMPILE([
1253                 #include <linux/mm.h>
1254         ],[
1255                 unsigned long state;
1256                 state = global_page_state(0);
1257         ],[
1258                 AC_MSG_RESULT(yes)
1259                 AC_DEFINE(HAVE_GLOBAL_PAGE_STATE, 1,
1260                           [global_page_state() is available])
1261         ],[
1262                 AC_MSG_RESULT(no)
1263         ])
1264 ])
1265
1266 dnl #
1267 dnl # 2.6.21 API change (plus subsequent naming convention changes),
1268 dnl # Public global zone stats now include a free page count.  However
1269 dnl # the enumerated names of the counters have changed since this API
1270 dnl # was introduced.  We need to deduce the corrent name to use.  This
1271 dnl # replaces the priviate get_zone_counts() interface.
1272 dnl #
1273 dnl # NR_FREE_PAGES was available from 2.6.21 to current kernels, which
1274 dnl # is 2.6.30 as of when this was written.
1275 dnl #
1276 AC_DEFUN([SPL_AC_ZONE_STAT_ITEM_FREE], [
1277         AC_MSG_CHECKING([whether page state NR_FREE_PAGES is available])
1278         SPL_LINUX_TRY_COMPILE([
1279                 #include <linux/mm.h>
1280         ],[
1281                 enum zone_stat_item zsi;
1282                 zsi = NR_FREE_PAGES;
1283         ],[
1284                 AC_MSG_RESULT(yes)
1285                 AC_DEFINE(HAVE_ZONE_STAT_ITEM_NR_FREE_PAGES, 1,
1286                           [Page state NR_FREE_PAGES is available])
1287         ],[
1288                 AC_MSG_RESULT(no)
1289         ])
1290 ])
1291
1292 dnl #
1293 dnl # 2.6.21 API change (plus subsequent naming convention changes),
1294 dnl # Public global zone stats now include an inactive page count.  However
1295 dnl # the enumerated names of the counters have changed since this API
1296 dnl # was introduced.  We need to deduce the corrent name to use.  This
1297 dnl # replaces the priviate get_zone_counts() interface.
1298 dnl #
1299 dnl # NR_INACTIVE was available from 2.6.21 to 2.6.27 and included both
1300 dnl # anonymous and file inactive pages.  As of 2.6.28 it was split in
1301 dnl # to NR_INACTIVE_ANON and NR_INACTIVE_FILE.
1302 dnl #
1303 AC_DEFUN([SPL_AC_ZONE_STAT_ITEM_INACTIVE], [
1304         AC_MSG_CHECKING([whether page state NR_INACTIVE is available])
1305         SPL_LINUX_TRY_COMPILE([
1306                 #include <linux/mm.h>
1307         ],[
1308                 enum zone_stat_item zsi;
1309                 zsi = NR_INACTIVE;
1310         ],[
1311                 AC_MSG_RESULT(yes)
1312                 AC_DEFINE(HAVE_ZONE_STAT_ITEM_NR_INACTIVE, 1,
1313                           [Page state NR_INACTIVE is available])
1314         ],[
1315                 AC_MSG_RESULT(no)
1316         ])
1317
1318         AC_MSG_CHECKING([whether page state NR_INACTIVE_ANON is available])
1319         SPL_LINUX_TRY_COMPILE([
1320                 #include <linux/mm.h>
1321         ],[
1322                 enum zone_stat_item zsi;
1323                 zsi = NR_INACTIVE_ANON;
1324         ],[
1325                 AC_MSG_RESULT(yes)
1326                 AC_DEFINE(HAVE_ZONE_STAT_ITEM_NR_INACTIVE_ANON, 1,
1327                           [Page state NR_INACTIVE_ANON is available])
1328         ],[
1329                 AC_MSG_RESULT(no)
1330         ])
1331
1332         AC_MSG_CHECKING([whether page state NR_INACTIVE_FILE is available])
1333         SPL_LINUX_TRY_COMPILE([
1334                 #include <linux/mm.h>
1335         ],[
1336                 enum zone_stat_item zsi;
1337                 zsi = NR_INACTIVE_FILE;
1338         ],[
1339                 AC_MSG_RESULT(yes)
1340                 AC_DEFINE(HAVE_ZONE_STAT_ITEM_NR_INACTIVE_FILE, 1,
1341                           [Page state NR_INACTIVE_FILE is available])
1342         ],[
1343                 AC_MSG_RESULT(no)
1344         ])
1345 ])
1346
1347 dnl #
1348 dnl # 2.6.21 API change (plus subsequent naming convention changes),
1349 dnl # Public global zone stats now include an active page count.  However
1350 dnl # the enumerated names of the counters have changed since this API
1351 dnl # was introduced.  We need to deduce the corrent name to use.  This
1352 dnl # replaces the priviate get_zone_counts() interface.
1353 dnl #
1354 dnl # NR_ACTIVE was available from 2.6.21 to 2.6.27 and included both
1355 dnl # anonymous and file active pages.  As of 2.6.28 it was split in
1356 dnl # to NR_ACTIVE_ANON and NR_ACTIVE_FILE.
1357 dnl #
1358 AC_DEFUN([SPL_AC_ZONE_STAT_ITEM_ACTIVE], [
1359         AC_MSG_CHECKING([whether page state NR_ACTIVE is available])
1360         SPL_LINUX_TRY_COMPILE([
1361                 #include <linux/mm.h>
1362         ],[
1363                 enum zone_stat_item zsi;
1364                 zsi = NR_ACTIVE;
1365         ],[
1366                 AC_MSG_RESULT(yes)
1367                 AC_DEFINE(HAVE_ZONE_STAT_ITEM_NR_ACTIVE, 1,
1368                           [Page state NR_ACTIVE is available])
1369         ],[
1370                 AC_MSG_RESULT(no)
1371         ])
1372
1373         AC_MSG_CHECKING([whether page state NR_ACTIVE_ANON is available])
1374         SPL_LINUX_TRY_COMPILE([
1375                 #include <linux/mm.h>
1376         ],[
1377                 enum zone_stat_item zsi;
1378                 zsi = NR_ACTIVE_ANON;
1379         ],[
1380                 AC_MSG_RESULT(yes)
1381                 AC_DEFINE(HAVE_ZONE_STAT_ITEM_NR_ACTIVE_ANON, 1,
1382                           [Page state NR_ACTIVE_ANON is available])
1383         ],[
1384                 AC_MSG_RESULT(no)
1385         ])
1386
1387         AC_MSG_CHECKING([whether page state NR_ACTIVE_FILE is available])
1388         SPL_LINUX_TRY_COMPILE([
1389                 #include <linux/mm.h>
1390         ],[
1391                 enum zone_stat_item zsi;
1392                 zsi = NR_ACTIVE_FILE;
1393         ],[
1394                 AC_MSG_RESULT(yes)
1395                 AC_DEFINE(HAVE_ZONE_STAT_ITEM_NR_ACTIVE_FILE, 1,
1396                           [Page state NR_ACTIVE_FILE is available])
1397         ],[
1398                 AC_MSG_RESULT(no)
1399         ])
1400 ])
1401
1402 dnl #
1403 dnl # Proposed API change for legacy kernels.
1404 dnl # This symbol is not available in older kernels.  For kernels post
1405 dnl # 2.6.21 the global_page_state() API is used to get free/inactive/active
1406 dnl # page state information.  This symbol is only used in legacy kernels
1407 dnl # any only as a last resort.
1408 dnl
1409 AC_DEFUN([SPL_AC_GET_ZONE_COUNTS], [
1410         AC_MSG_CHECKING([whether symbol get_zone_counts is needed])
1411         SPL_LINUX_TRY_COMPILE([
1412         ],[
1413                 #if !defined(HAVE_ZONE_STAT_ITEM_NR_FREE_PAGES)
1414                 #error "global_page_state needs NR_FREE_PAGES"
1415                 #endif
1416
1417                 #if !defined(HAVE_ZONE_STAT_ITEM_NR_ACTIVE) && \
1418                     !defined(HAVE_ZONE_STAT_ITEM_NR_ACTIVE_ANON) && \
1419                     !defined(HAVE_ZONE_STAT_ITEM_NR_ACTIVE_FILE)
1420                 #error "global_page_state needs NR_ACTIVE*"
1421                 #endif
1422
1423                 #if !defined(HAVE_ZONE_STAT_ITEM_NR_INACTIVE) && \
1424                     !defined(HAVE_ZONE_STAT_ITEM_NR_INACTIVE_ANON) && \
1425                     !defined(HAVE_ZONE_STAT_ITEM_NR_INACTIVE_FILE)
1426                 #error "global_page_state needs NR_INACTIVE*"
1427                 #endif
1428         ],[
1429                 AC_MSG_RESULT(no)
1430         ],[
1431                 AC_MSG_RESULT(yes)
1432                 AC_DEFINE(NEED_GET_ZONE_COUNTS, 1,
1433                           [get_zone_counts() is needed])
1434
1435                 SPL_CHECK_SYMBOL_EXPORT(
1436                         [get_zone_counts],
1437                         [],
1438                         [AC_DEFINE(HAVE_GET_ZONE_COUNTS, 1,
1439                         [get_zone_counts() is available])],
1440                         [])
1441         ])
1442 ])
1443
1444 dnl #
1445 dnl # 2.6.27 API change,
1446 dnl # The user_path_dir() replaces __user_walk()
1447 dnl #
1448 AC_DEFUN([SPL_AC_USER_PATH_DIR], [
1449         SPL_CHECK_SYMBOL_EXPORT(
1450                 [user_path_at],
1451                 [],
1452                 [AC_DEFINE(HAVE_USER_PATH_DIR, 1,
1453                 [user_path_dir() is available])],
1454                 [])
1455 ])
1456
1457 dnl #
1458 dnl # Symbol available in RHEL kernels not in stock kernels.
1459 dnl #
1460 AC_DEFUN([SPL_AC_SET_FS_PWD], [
1461         SPL_CHECK_SYMBOL_EXPORT(
1462                 [set_fs_pwd],
1463                 [],
1464                 [AC_DEFINE(HAVE_SET_FS_PWD, 1,
1465                 [set_fs_pwd() is available])],
1466                 [])
1467 ])
1468
1469 dnl #
1470 dnl # 2.6.25 API change,
1471 dnl # Simplied API by replacing mnt+dentry args with a single path arg.
1472 dnl #
1473 AC_DEFUN([SPL_AC_2ARGS_SET_FS_PWD],
1474         [AC_MSG_CHECKING([whether set_fs_pwd() wants 2 args])
1475         SPL_LINUX_TRY_COMPILE([
1476                 #include <linux/sched.h>
1477                 #include <linux/fs_struct.h>
1478         ],[
1479                 set_fs_pwd(NULL, NULL);
1480         ],[
1481                 AC_MSG_RESULT(yes)
1482                 AC_DEFINE(HAVE_2ARGS_SET_FS_PWD, 1,
1483                           [set_fs_pwd() wants 2 args])
1484         ],[
1485                 AC_MSG_RESULT(no)
1486         ])
1487 ])
1488
1489 dnl #
1490 dnl # SLES API change, never adopted in mainline,
1491 dnl # Third 'struct vfsmount *' argument removed.
1492 dnl #
1493 AC_DEFUN([SPL_AC_2ARGS_VFS_UNLINK],
1494         [AC_MSG_CHECKING([whether vfs_unlink() wants 2 args])
1495         SPL_LINUX_TRY_COMPILE([
1496                 #include <linux/fs.h>
1497         ],[
1498                 vfs_unlink(NULL, NULL);
1499         ],[
1500                 AC_MSG_RESULT(yes)
1501                 AC_DEFINE(HAVE_2ARGS_VFS_UNLINK, 1,
1502                           [vfs_unlink() wants 2 args])
1503         ],[
1504                 AC_MSG_RESULT(no)
1505         ])
1506 ])
1507
1508 dnl #
1509 dnl # SLES API change, never adopted in mainline,
1510 dnl # Third and sixth 'struct vfsmount *' argument removed.
1511 dnl #
1512 AC_DEFUN([SPL_AC_4ARGS_VFS_RENAME],
1513         [AC_MSG_CHECKING([whether vfs_rename() wants 4 args])
1514         SPL_LINUX_TRY_COMPILE([
1515                 #include <linux/fs.h>
1516         ],[
1517                 vfs_rename(NULL, NULL, NULL, NULL);
1518         ],[
1519                 AC_MSG_RESULT(yes)
1520                 AC_DEFINE(HAVE_4ARGS_VFS_RENAME, 1,
1521                           [vfs_rename() wants 4 args])
1522         ],[
1523                 AC_MSG_RESULT(no)
1524         ])
1525 ])
1526
1527 dnl #
1528 dnl # 2.6.29 API change,
1529 dnl # check whether 'struct cred' exists
1530 dnl #
1531 AC_DEFUN([SPL_AC_CRED_STRUCT], [
1532         AC_MSG_CHECKING([whether struct cred exists])
1533         SPL_LINUX_TRY_COMPILE([
1534                 #include <linux/cred.h>
1535         ],[
1536                 struct cred *cr;
1537                 cr  = NULL;
1538         ],[
1539                 AC_MSG_RESULT(yes)
1540                 AC_DEFINE(HAVE_CRED_STRUCT, 1, [struct cred exists])
1541         ],[
1542                 AC_MSG_RESULT(no)
1543         ])
1544 ])
1545
1546 dnl #
1547 dnl # Custom SPL patch may export this symbol.
1548 dnl #
1549 AC_DEFUN([SPL_AC_GROUPS_SEARCH], [
1550         SPL_CHECK_SYMBOL_EXPORT(
1551                 [groups_search],
1552                 [],
1553                 [AC_DEFINE(HAVE_GROUPS_SEARCH, 1,
1554                 [groups_search() is available])],
1555                 [])
1556 ])
1557
1558 dnl #
1559 dnl # 2.6.x API change,
1560 dnl # __put_task_struct() was exported in RHEL5 but unavailable elsewhere.
1561 dnl #
1562 AC_DEFUN([SPL_AC_PUT_TASK_STRUCT], [
1563         SPL_CHECK_SYMBOL_EXPORT(
1564                 [__put_task_struct],
1565                 [],
1566                 [AC_DEFINE(HAVE_PUT_TASK_STRUCT, 1,
1567                 [__put_task_struct() is available])],
1568                 [])
1569 ])
1570
1571 dnl #
1572 dnl # 2.6.32 API change,
1573 dnl # Unused 'struct file *' removed from prototype.
1574 dnl #
1575 AC_DEFUN([SPL_AC_5ARGS_PROC_HANDLER], [
1576         AC_MSG_CHECKING([whether proc_handler() wants 5 args])
1577         SPL_LINUX_TRY_COMPILE([
1578                 #include <linux/sysctl.h>
1579         ],[
1580                 proc_dostring(NULL, 0, NULL, NULL, NULL);
1581         ],[
1582                 AC_MSG_RESULT(yes)
1583                 AC_DEFINE(HAVE_5ARGS_PROC_HANDLER, 1,
1584                           [proc_handler() wants 5 args])
1585         ],[
1586                 AC_MSG_RESULT(no)
1587         ])
1588 ])
1589
1590 dnl #
1591 dnl # 2.6.x API change,
1592 dnl # kvasprintf() function added.
1593 dnl #
1594 AC_DEFUN([SPL_AC_KVASPRINTF], [
1595         SPL_CHECK_SYMBOL_EXPORT(
1596                 [kvasprintf],
1597                 [],
1598                 [AC_DEFINE(HAVE_KVASPRINTF, 1,
1599                 [kvasprintf() is available])],
1600                 [])
1601 ])
1602
1603 dnl #
1604 dnl # 2.6.35 API change,
1605 dnl # Unused 'struct dentry *' removed from prototype.
1606 dnl #
1607 AC_DEFUN([SPL_AC_3ARGS_FILE_FSYNC], [
1608         AC_MSG_CHECKING([whether file_fsync() wants 3 args])
1609         SPL_LINUX_TRY_COMPILE([
1610                 #include <linux/buffer_head.h>
1611         ],[
1612                 file_fsync(NULL, NULL, 0);
1613         ],[
1614                 AC_MSG_RESULT(yes)
1615                 AC_DEFINE(HAVE_3ARGS_FILE_FSYNC, 1,
1616                           [file_fsync() wants 3 args])
1617         ],[
1618                 AC_MSG_RESULT(no)
1619         ])
1620 ])
1621
1622 dnl #
1623 dnl # 2.6.33 API change. Also backported in RHEL5 as of 2.6.18-190.el5.
1624 dnl # Earlier versions of rwsem_is_locked() were inline and had a race
1625 dnl # condition.  The fixed version is exported as a symbol.  The race
1626 dnl # condition is fixed by acquiring sem->wait_lock, so we must not
1627 dnl # call that version while holding sem->wait_lock.
1628 dnl #
1629 AC_DEFUN([SPL_AC_EXPORTED_RWSEM_IS_LOCKED], [
1630         SPL_CHECK_SYMBOL_EXPORT(
1631                 [rwsem_is_locked],
1632                 [lib/rwsem-spinlock.c],
1633                 [AC_DEFINE(RWSEM_IS_LOCKED_TAKES_WAIT_LOCK, 1,
1634                 [rwsem_is_locked() acquires sem->wait_lock])],
1635                 [])
1636 ])