diff options
-rw-r--r-- | config/spl-build.m4 | 23 | ||||
-rw-r--r-- | include/sys/cred.h | 5 | ||||
-rw-r--r-- | module/spl/spl-cred.c | 10 | ||||
-rw-r--r-- | module/splat/splat-cred.c | 5 |
4 files changed, 41 insertions, 2 deletions
diff --git a/config/spl-build.m4 b/config/spl-build.m4 index 94e692a8b..7e2e7a0a9 100644 --- a/config/spl-build.m4 +++ b/config/spl-build.m4 @@ -49,6 +49,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [ SPL_AC_WAIT_ON_BIT SPL_AC_MUTEX_OWNER SPL_AC_INODE_LOCK + SPL_AC_GROUP_INFO_GID ]) AC_DEFUN([SPL_AC_MODULE_SYMVERS], [ @@ -1574,3 +1575,25 @@ AC_DEFUN([SPL_AC_INODE_LOCK], [ ]) EXTRA_KCFLAGS="$tmp_flags" ]) + +dnl # +dnl # 4.9 API change +dnl # group_info changed from 2d array via >blocks to 1d array via ->gid +dnl # +AC_DEFUN([SPL_AC_GROUP_INFO_GID], [ + AC_MSG_CHECKING([whether group_info->gid exists]) + tmp_flags="$EXTRA_KCFLAGS" + EXTRA_KCFLAGS="-Werror" + SPL_LINUX_TRY_COMPILE([ + #include <linux/cred.h> + ],[ + struct group_info *gi = groups_alloc(1); + gi->gid[0] = KGIDT_INIT(0); + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_GROUP_INFO_GID, 1, [group_info->gid exists]) + ],[ + AC_MSG_RESULT(no) + ]) + EXTRA_KCFLAGS="$tmp_flags" +]) diff --git a/include/sys/cred.h b/include/sys/cred.h index 58f7aafda..2ad7115e0 100644 --- a/include/sys/cred.h +++ b/include/sys/cred.h @@ -34,6 +34,11 @@ typedef struct cred cred_t; #define kcred ((cred_t *)(init_task.cred)) #define CRED() ((cred_t *)current_cred()) +/* Linux 4.9 API change, GROUP_AT was removed */ +#ifndef GROUP_AT +#define GROUP_AT(gi, i) ((gi)->gid[i]) +#endif + #ifdef HAVE_KUIDGID_T #define KUID_TO_SUID(x) (__kuid_val(x)) diff --git a/module/spl/spl-cred.c b/module/spl/spl-cred.c index d046f9513..1d486c1f0 100644 --- a/module/spl/spl-cred.c +++ b/module/spl/spl-cred.c @@ -85,7 +85,9 @@ crgetngroups(const cred_t *cr) gi = cr->group_info; rc = gi->ngroups; +#ifndef HAVE_GROUP_INFO_GID /* + * For Linux <= 4.8, * crgetgroups will only returns gi->blocks[0], which contains only * the first NGROUPS_PER_BLOCK groups. */ @@ -93,12 +95,16 @@ crgetngroups(const cred_t *cr) WARN_ON_ONCE(1); rc = NGROUPS_PER_BLOCK; } +#endif return rc; } /* * Return an array of supplemental gids. The returned address is safe * to use as long as the caller has taken a reference with crhold(). + * + * Linux 4.9 API change, group_info changed from 2d array via ->blocks to 1d + * array via ->gid. */ gid_t * crgetgroups(const cred_t *cr) @@ -107,8 +113,12 @@ crgetgroups(const cred_t *cr) gid_t *gids = NULL; gi = cr->group_info; +#ifdef HAVE_GROUP_INFO_GID + gids = KGIDP_TO_SGIDP(gi->gid); +#else if (gi->nblocks > 0) gids = KGIDP_TO_SGIDP(gi->blocks[0]); +#endif return gids; } diff --git a/module/splat/splat-cred.c b/module/splat/splat-cred.c index e3d1c4eee..f6b70ce34 100644 --- a/module/splat/splat-cred.c +++ b/module/splat/splat-cred.c @@ -166,6 +166,7 @@ splat_cred_test2(struct file *file, void *arg) return 0; } /* splat_cred_test2() */ +#define SPLAT_NGROUPS 32 /* * Verify the groupmember() works correctly by constructing an interesting * CRED() and checking that the expected gids are part of it. @@ -188,7 +189,7 @@ splat_cred_test3(struct file *file, void *arg) * 1:(NGROUPS_MAX-1). Gid 0 is explicitly avoided so we can reliably * test for its absence in the test cases. */ - gi = groups_alloc(NGROUPS_SMALL); + gi = groups_alloc(SPLAT_NGROUPS); if (gi == NULL) { splat_vprint(file, SPLAT_CRED_TEST3_NAME, "Failed create " "group_info for known gids: %d\n", -ENOMEM); @@ -196,7 +197,7 @@ splat_cred_test3(struct file *file, void *arg) goto show_groups; } - for (i = 0, tmp_gid = known_gid; i < NGROUPS_SMALL; i++) { + for (i = 0, tmp_gid = known_gid; i < SPLAT_NGROUPS; i++) { splat_vprint(file, SPLAT_CRED_TEST3_NAME, "Adding gid %d " "to current CRED() (%d/%d)\n", tmp_gid, i, gi->ngroups); #ifdef HAVE_KUIDGID_T |