From: Brian Behlendorf Date: Thu, 4 Mar 2010 20:14:56 +0000 (-0800) Subject: Linux 2.6.32 compat, proc_handler() API change X-Git-Tag: zfs-0.8.0-rc1~152^2~624 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3977f8370f8caf57600deff6795894410f0e715e;p=zfs Linux 2.6.32 compat, proc_handler() API change As of linux-2.6.32 the 'struct file *filp' argument was dropped from the proc_handle() prototype. It was apparently unused _almost_ everywhere in the kernel and this was simply cleanup. I've added a new SPL_AC_5ARGS_PROC_HANDLER autoconf check for this and the proper compat macros to correctly define the prototypes and some helper functions. It's not pretty but API compat changes rarely are. --- diff --git a/config/spl-build.m4 b/config/spl-build.m4 index 9fa7bc811..e2e2112e7 100644 --- a/config/spl-build.m4 +++ b/config/spl-build.m4 @@ -72,6 +72,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [ SPL_AC_CRED_STRUCT SPL_AC_GROUPS_SEARCH SPL_AC_PUT_TASK_STRUCT + SPL_AC_5ARGS_PROC_HANDLER ]) AC_DEFUN([SPL_AC_MODULE_SYMVERS], [ @@ -1371,3 +1372,22 @@ AC_DEFUN([SPL_AC_PUT_TASK_STRUCT], [ [__put_task_struct() is available])], []) ]) + +dnl # +dnl # 2.6.32 API change, +dnl # Unused 'struct file *' removed from prototype. +dnl # +AC_DEFUN([SPL_AC_5ARGS_PROC_HANDLER], [ + AC_MSG_CHECKING([whether proc_handler() wants 5 args]) + SPL_LINUX_TRY_COMPILE([ + #include + ],[ + proc_dostring(NULL, 0, NULL, NULL, NULL); + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_5ARGS_PROC_HANDLER, 1, + [proc_handler() wants 5 args]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/configure b/configure index 192a08442..99c064d43 100755 --- a/configure +++ b/configure @@ -22231,6 +22231,71 @@ _ACEOF fi + + echo "$as_me:$LINENO: checking whether proc_handler() wants 5 args" >&5 +echo $ECHO_N "checking whether proc_handler() wants 5 args... $ECHO_C" >&6 + + +cat >conftest.c <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + + #include + +int +main (void) +{ + + proc_dostring(NULL, 0, NULL, NULL, NULL); + + ; + return 0; +} + +_ACEOF + + + rm -Rf build && mkdir -p build + echo "obj-m := conftest.o" >build/Makefile + if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +cat >>confdefs.h <<\_ACEOF +#define HAVE_5ARGS_PROC_HANDLER 1 +_ACEOF + + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + + + +fi + + rm -Rf build + + + ;; user) ;; all) @@ -25513,6 +25578,71 @@ _ACEOF + echo "$as_me:$LINENO: checking whether proc_handler() wants 5 args" >&5 +echo $ECHO_N "checking whether proc_handler() wants 5 args... $ECHO_C" >&6 + + +cat >conftest.c <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + + #include + +int +main (void) +{ + + proc_dostring(NULL, 0, NULL, NULL, NULL); + + ; + return 0; +} + +_ACEOF + + + rm -Rf build && mkdir -p build + echo "obj-m := conftest.o" >build/Makefile + if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +cat >>confdefs.h <<\_ACEOF +#define HAVE_5ARGS_PROC_HANDLER 1 +_ACEOF + + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + + + +fi + + rm -Rf build + + + + ;; srpm) ;; *) diff --git a/include/linux/sysctl_compat.h b/include/linux/sysctl_compat.h new file mode 100644 index 000000000..ecc5d1999 --- /dev/null +++ b/include/linux/sysctl_compat.h @@ -0,0 +1,72 @@ +#ifndef _SPL_SYSCTL_COMPAT_H +#define _SPL_SYSCTL_COMPAT_H + +#include + +/* proc_handler() / proc_do* API changes + * 2.6.x - 2.6.31: 6 args, prototype includes 'struct file *' + * 2.6.32 - 2.6.y: 5 args, removed unused 'struct file *' from prototype + * + * Generic SPL_PROC_HANDLER() macro should be used for correct prototypes. + * It will define the following function arguments which can and should be + * used with the spl_proc_* helper macros. + * + * struct ctl_table *table, + * int write, + * struct file *filp [2.6.31 and earlier kernels], + * void __user *buffer, + * size_t *lenp, + * loff_t *ppos, + */ +#ifdef HAVE_5ARGS_PROC_HANDLER + +#define SPL_PROC_HANDLER(proc_handler) \ +static int \ +proc_handler(struct ctl_table *table, int write, \ + void __user *buffer, size_t *lenp, loff_t *ppos) + +#define spl_proc_dostring(table, write, filp, buffer, lenp, ppos) \ + proc_dostring(table, write, buffer, lenp, ppos) +#define spl_proc_dointvec(table, write, filp, buffer, lenp, ppos) \ + proc_dointvec(table, write, buffer, lenp, ppos) +#define spl_proc_dointvec_minmax(table, write, filp, buffer, lenp, ppos) \ + proc_dointvec_minmax(table, write, buffer, lenp, ppos) +#define spl_proc_dointvec_jiffies(table, write, filp, buffer, lenp, ppos) \ + proc_dointvec_jiffies(table, write, buffer, lenp, ppos) +#define spl_proc_dointvec_userhz_jiffies(table,write,filp,buffer,lenp,ppos) \ + proc_dointvec_userhz_jiffies(table, write, buffer, lenp, ppos) +#define spl_proc_dointvec_ms_jiffies(table,write,filp,buffer,lenp,ppos) \ + proc_dointvec_ms_jiffies(table, write, buffer, lenp, ppos) +#define spl_proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos) \ + proc_doulongvec_minmax(table, write, buffer, lenp, ppos) +#define spl_proc_doulongvec_ms_jiffies_minmax(table,write,filp,buffer,lenp,ppos) \ + proc_doulongvec_ms_jiffies_minmax(table, write, buffer, lenp, ppos) + +#else /* HAVE_5ARGS_PROC_HANDLER */ + +#define SPL_PROC_HANDLER(proc_handler) \ +static int \ +proc_handler(struct ctl_table *table, int write, struct file *filp, \ + void __user *buffer, size_t *lenp, loff_t *ppos) + +#define spl_proc_dostring(table, write, filp, buffer, lenp, ppos) \ + proc_dostring(table, write, filp, buffer, lenp, ppos) +#define spl_proc_dointvec(table, write, filp, buffer, lenp, ppos) \ + proc_dointvec(table, write, filp, buffer, lenp, ppos) +#define spl_proc_dointvec_minmax(table, write, filp, buffer, lenp, ppos) \ + proc_dointvec_minmax(table, write, filp, buffer, lenp, ppos) +#define spl_proc_dointvec_jiffies(table, write, filp, buffer, lenp, ppos) \ + proc_dointvec_jiffies(table, write, filp, buffer, lenp, ppos) +#define spl_proc_dointvec_userhz_jiffies(table,write,filp,buffer,lenp,ppos) \ + proc_dointvec_userhz_jiffies(table, write, filp, buffer, lenp, ppos) +#define spl_proc_dointvec_ms_jiffies(table, write, filp, buffer, lenp, ppos) \ + proc_dointvec_ms_jiffies(table, write, filp, buffer, lenp, ppos) +#define spl_proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos) \ + proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos) +#define spl_proc_doulongvec_ms_jiffies_minmax(table,write,filp,buffer,lenp,ppos) \ + proc_doulongvec_ms_jiffies_minmax(table,write,filp,buffer,lenp,ppos) + + +#endif /* HAVE_5ARGS_PROC_HANDLER */ + +#endif /* _SPL_SYSCTL_COMPAT_H */ diff --git a/include/sys/types.h b/include/sys/types.h index 89cf115c0..407a1b0c5 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -19,6 +19,7 @@ extern "C" { #include #include #include +#include #ifndef HAVE_UINTPTR_T typedef unsigned long uintptr_t; diff --git a/module/spl/spl-proc.c b/module/spl/spl-proc.c index 6458186ee..6db4664da 100644 --- a/module/spl/spl-proc.c +++ b/module/spl/spl-proc.c @@ -203,9 +203,7 @@ proc_copyout_string(char *ubuffer, int ubuffer_size, return size; } -static int -proc_dobitmasks(struct ctl_table *table, int write, struct file *filp, - void __user *buffer, size_t *lenp, loff_t *ppos) +SPL_PROC_HANDLER(proc_dobitmasks) { unsigned long *mask = table->data; int is_subsys = (mask == &spl_debug_subsys) ? 1 : 0; @@ -246,9 +244,7 @@ proc_dobitmasks(struct ctl_table *table, int write, struct file *filp, RETURN(rc); } -static int -proc_debug_mb(struct ctl_table *table, int write, struct file *filp, - void __user *buffer, size_t *lenp, loff_t *ppos) +SPL_PROC_HANDLER(proc_debug_mb) { char str[32]; int rc, len; @@ -266,7 +262,7 @@ proc_debug_mb(struct ctl_table *table, int write, struct file *filp, if (*ppos >= len) rc = 0; else - rc = proc_copyout_string(buffer, *lenp, str + *ppos, "\n"); + rc = proc_copyout_string(buffer,*lenp,str+*ppos,"\n"); if (rc >= 0) { *lenp = rc; @@ -277,9 +273,7 @@ proc_debug_mb(struct ctl_table *table, int write, struct file *filp, RETURN(rc); } -static int -proc_dump_kernel(struct ctl_table *table, int write, struct file *filp, - void __user *buffer, size_t *lenp, loff_t *ppos) +SPL_PROC_HANDLER(proc_dump_kernel) { ENTRY; @@ -293,9 +287,7 @@ proc_dump_kernel(struct ctl_table *table, int write, struct file *filp, RETURN(0); } -static int -proc_force_bug(struct ctl_table *table, int write, struct file *filp, - void __user *buffer, size_t *lenp, loff_t *ppos) +SPL_PROC_HANDLER(proc_force_bug) { ENTRY; @@ -310,9 +302,7 @@ proc_force_bug(struct ctl_table *table, int write, struct file *filp, RETURN(0); } -static int -proc_console_max_delay_cs(struct ctl_table *table, int write, struct file *filp, - void __user *buffer, size_t *lenp, loff_t *ppos) +SPL_PROC_HANDLER(proc_console_max_delay_cs) { int rc, max_delay_cs; struct ctl_table dummy = *table; @@ -324,7 +314,7 @@ proc_console_max_delay_cs(struct ctl_table *table, int write, struct file *filp, if (write) { max_delay_cs = 0; - rc = proc_dointvec(&dummy, write, filp, buffer, lenp, ppos); + rc = spl_proc_dointvec(&dummy,write,filp,buffer,lenp,ppos); if (rc < 0) RETURN(rc); @@ -338,15 +328,13 @@ proc_console_max_delay_cs(struct ctl_table *table, int write, struct file *filp, spl_console_max_delay = d; } else { max_delay_cs = (spl_console_max_delay * 100) / HZ; - rc = proc_dointvec(&dummy, write, filp, buffer, lenp, ppos); + rc = spl_proc_dointvec(&dummy,write,filp,buffer,lenp,ppos); } RETURN(rc); } -static int -proc_console_min_delay_cs(struct ctl_table *table, int write, struct file *filp, - void __user *buffer, size_t *lenp, loff_t *ppos) +SPL_PROC_HANDLER(proc_console_min_delay_cs) { int rc, min_delay_cs; struct ctl_table dummy = *table; @@ -358,7 +346,7 @@ proc_console_min_delay_cs(struct ctl_table *table, int write, struct file *filp, if (write) { min_delay_cs = 0; - rc = proc_dointvec(&dummy, write, filp, buffer, lenp, ppos); + rc = spl_proc_dointvec(&dummy,write,filp,buffer,lenp,ppos); if (rc < 0) RETURN(rc); @@ -372,15 +360,13 @@ proc_console_min_delay_cs(struct ctl_table *table, int write, struct file *filp, spl_console_min_delay = d; } else { min_delay_cs = (spl_console_min_delay * 100) / HZ; - rc = proc_dointvec(&dummy, write, filp, buffer, lenp, ppos); + rc = spl_proc_dointvec(&dummy,write,filp,buffer,lenp,ppos); } RETURN(rc); } -static int -proc_console_backoff(struct ctl_table *table, int write, struct file *filp, - void __user *buffer, size_t *lenp, loff_t *ppos) +SPL_PROC_HANDLER(proc_console_backoff) { int rc, backoff; struct ctl_table dummy = *table; @@ -391,7 +377,7 @@ proc_console_backoff(struct ctl_table *table, int write, struct file *filp, if (write) { backoff = 0; - rc = proc_dointvec(&dummy, write, filp, buffer, lenp, ppos); + rc = spl_proc_dointvec(&dummy,write,filp,buffer,lenp,ppos); if (rc < 0) RETURN(rc); @@ -401,16 +387,14 @@ proc_console_backoff(struct ctl_table *table, int write, struct file *filp, spl_console_backoff = backoff; } else { backoff = spl_console_backoff; - rc = proc_dointvec(&dummy, write, filp, buffer, lenp, ppos); + rc = spl_proc_dointvec(&dummy,write,filp,buffer,lenp,ppos); } RETURN(rc); } #ifdef DEBUG_KMEM -static int -proc_domemused(struct ctl_table *table, int write, struct file *filp, - void __user *buffer, size_t *lenp, loff_t *ppos) +SPL_PROC_HANDLER(proc_domemused) { int rc = 0; unsigned long min = 0, max = ~0, val; @@ -430,17 +414,15 @@ proc_domemused(struct ctl_table *table, int write, struct file *filp, # else val = atomic_read((atomic_t *)table->data); # endif /* HAVE_ATOMIC64_T */ - rc = proc_doulongvec_minmax(&dummy, write, filp, - buffer, lenp, ppos); + rc = spl_proc_doulongvec_minmax(&dummy, write, filp, + buffer, lenp, ppos); } RETURN(rc); } #endif /* DEBUG_KMEM */ -static int -proc_dohostid(struct ctl_table *table, int write, struct file *filp, - void __user *buffer, size_t *lenp, loff_t *ppos) +SPL_PROC_HANDLER(proc_dohostid) { int len, rc = 0; int32_t val; @@ -448,7 +430,7 @@ proc_dohostid(struct ctl_table *table, int write, struct file *filp, ENTRY; if (write) { - /* We can't use proc_doulongvec_minmax() in the write + /* We can't use spl_proc_doulongvec_minmax() in the write * case hear because hostid while a hex value has no * leading 0x which confuses the helper function. */ rc = proc_copyin_string(str, sizeof(str), buffer, *lenp); @@ -469,7 +451,7 @@ proc_dohostid(struct ctl_table *table, int write, struct file *filp, if (*ppos >= len) rc = 0; else - rc = proc_copyout_string(buffer, *lenp, str + *ppos, "\n"); + rc = proc_copyout_string(buffer,*lenp,str+*ppos,"\n"); if (rc >= 0) { *lenp = rc; @@ -481,10 +463,8 @@ proc_dohostid(struct ctl_table *table, int write, struct file *filp, } #ifndef HAVE_KALLSYMS_LOOKUP_NAME -static int -proc_dokallsyms_lookup_name(struct ctl_table *table, int write, - struct file *filp, void __user *buffer, - size_t *lenp, loff_t *ppos) { +SPL_PROC_HANDLER(proc_dokallsyms_lookup_name) +{ int len, rc = 0; char *end, str[32]; ENTRY; @@ -494,7 +474,7 @@ proc_dokallsyms_lookup_name(struct ctl_table *table, int write, if (spl_kallsyms_lookup_name_fn != SYMBOL_POISON) RETURN(-EEXIST); - /* We can't use proc_doulongvec_minmax() in the write + /* We can't use spl_proc_doulongvec_minmax() in the write * case hear because the address while a hex value has no * leading 0x which confuses the helper function. */ rc = proc_copyin_string(str, sizeof(str), buffer, *lenp); @@ -525,9 +505,7 @@ proc_dokallsyms_lookup_name(struct ctl_table *table, int write, } #endif /* HAVE_KALLSYMS_LOOKUP_NAME */ -static int -proc_doavailrmem(struct ctl_table *table, int write, struct file *filp, - void __user *buffer, size_t *lenp, loff_t *ppos) +SPL_PROC_HANDLER(proc_doavailrmem) { int len, rc = 0; char str[32]; @@ -536,11 +514,12 @@ proc_doavailrmem(struct ctl_table *table, int write, struct file *filp, if (write) { *ppos += *lenp; } else { - len = snprintf(str, sizeof(str), "%lu", (unsigned long)availrmem); + len = snprintf(str, sizeof(str), "%lu", + (unsigned long)availrmem); if (*ppos >= len) rc = 0; else - rc = proc_copyout_string(buffer, *lenp, str + *ppos, "\n"); + rc = proc_copyout_string(buffer,*lenp,str+*ppos,"\n"); if (rc >= 0) { *lenp = rc; @@ -551,9 +530,7 @@ proc_doavailrmem(struct ctl_table *table, int write, struct file *filp, RETURN(rc); } -static int -proc_dofreemem(struct ctl_table *table, int write, struct file *filp, - void __user *buffer, size_t *lenp, loff_t *ppos) +SPL_PROC_HANDLER(proc_dofreemem) { int len, rc = 0; char str[32]; @@ -566,7 +543,7 @@ proc_dofreemem(struct ctl_table *table, int write, struct file *filp, if (*ppos >= len) rc = 0; else - rc = proc_copyout_string(buffer, *lenp, str + *ppos, "\n"); + rc = proc_copyout_string(buffer,*lenp,str+*ppos,"\n"); if (rc >= 0) { *lenp = rc; @@ -648,7 +625,7 @@ slab_seq_next(struct seq_file *f, void *p, loff_t *pos) ++*pos; RETURN((skc->skc_list.next == &spl_kmem_cache_list) ? - NULL : list_entry(skc->skc_list.next, spl_kmem_cache_t, skc_list)); + NULL : list_entry(skc->skc_list.next,spl_kmem_cache_t,skc_list)); } static void diff --git a/spl_config.h.in b/spl_config.h.in index 06e5766f1..a820bccbb 100644 --- a/spl_config.h.in +++ b/spl_config.h.in @@ -30,6 +30,9 @@ /* device_create wants 5 args */ #undef HAVE_5ARGS_DEVICE_CREATE +/* proc_handler() wants 5 args */ +#undef HAVE_5ARGS_PROC_HANDLER + /* kernel defines atomic64_cmpxchg */ #undef HAVE_ATOMIC64_CMPXCHG