summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChunwei Chen <[email protected]>2016-10-18 17:30:41 -0700
committerBrian Behlendorf <[email protected]>2016-10-20 09:33:28 -0700
commitae7eda1dde8aebc298a013254dcd90f7fa42171a (patch)
tree56167dff16e601f6255616467f310ca23fc74b02
parent87063d7dc392cb710c70dba49021d6e4ec8961a9 (diff)
Linux 4.9 compat: group_info changes
In Linux 4.9, torvalds/linux@81243ea, group_info changed from 2d array via ->blocks to 1d array via ->gid. We change the spl cred functions accordingly. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Chunwei Chen <[email protected]> Closes #581
-rw-r--r--config/spl-build.m423
-rw-r--r--include/sys/cred.h5
-rw-r--r--module/spl/spl-cred.c10
-rw-r--r--module/splat/splat-cred.c5
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