summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikolay Borisov <[email protected]>2016-08-03 20:19:04 +0300
committerBrian Behlendorf <[email protected]>2016-08-08 10:47:22 -0700
commit938cfeb0f27303721081223816d4f251ffeb1767 (patch)
tree601e6d10fd24c402c51333d16f2d64f9bf0bf349
parentcf2731e65b2015988b2cae7970886279e11b013f (diff)
Linux 4.8 compat: new s_user_ns member of struct super_block
Kernel 4.8 paved the way to enabling mounting a file system inside a non-init user namespace. To facilitate this a s_user_ns member was added holding the userns in which the filesystem's instance was mounted. This enables doing the uid/gid translation relative to this particular username space and not the default init_user_ns. Signed-off-by: Nikolay Borisov <[email protected]> Signed-off-by: Chunwei Chen <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Closes #4928
-rw-r--r--config/kernel-super-userns.m421
-rw-r--r--config/kernel.m41
-rw-r--r--include/linux/vfs_compat.h17
3 files changed, 39 insertions, 0 deletions
diff --git a/config/kernel-super-userns.m4 b/config/kernel-super-userns.m4
new file mode 100644
index 000000000..de94ad967
--- /dev/null
+++ b/config/kernel-super-userns.m4
@@ -0,0 +1,21 @@
+dnl #
+dnl # 4.8 API change
+dnl # struct user_namespace was added to struct super_block as
+dnl # super->s_user_ns member
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SUPER_USER_NS], [
+ AC_MSG_CHECKING([whether super_block->s_user_ns exists])
+ ZFS_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+ #include <linux/user_namespace.h>
+ ],[
+ struct super_block super;
+ super.s_user_ns = (struct user_namespace *)NULL;
+ ],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_SUPER_USER_NS, 1,
+ [super_block->s_user_ns exists])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+])
diff --git a/config/kernel.m4 b/config/kernel.m4
index 7edafee0f..2fa04706b 100644
--- a/config/kernel.m4
+++ b/config/kernel.m4
@@ -8,6 +8,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
ZFS_AC_KERNEL_CONFIG
ZFS_AC_KERNEL_DECLARE_EVENT_CLASS
ZFS_AC_KERNEL_CURRENT_BIO_TAIL
+ ZFS_AC_KERNEL_SUPER_USER_NS
ZFS_AC_KERNEL_SUBMIT_BIO
ZFS_AC_KERNEL_BDEV_BLOCK_DEVICE_OPERATIONS
ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
diff --git a/include/linux/vfs_compat.h b/include/linux/vfs_compat.h
index 97220c2fe..fa12ba95a 100644
--- a/include/linux/vfs_compat.h
+++ b/include/linux/vfs_compat.h
@@ -356,7 +356,11 @@ static inline struct inode *file_inode(const struct file *f)
#ifdef HAVE_KUID_HELPERS
static inline uid_t zfs_uid_read_impl(struct inode *ip)
{
+#ifdef HAVE_SUPER_USER_NS
+ return (from_kuid(ip->i_sb->s_user_ns, ip->i_uid));
+#else
return (from_kuid(kcred->user_ns, ip->i_uid));
+#endif
}
static inline uid_t zfs_uid_read(struct inode *ip)
@@ -366,7 +370,11 @@ static inline uid_t zfs_uid_read(struct inode *ip)
static inline gid_t zfs_gid_read_impl(struct inode *ip)
{
+#ifdef HAVE_SUPER_USER_NS
+ return (from_kgid(ip->i_sb->s_user_ns, ip->i_gid));
+#else
return (from_kgid(kcred->user_ns, ip->i_gid));
+#endif
}
static inline gid_t zfs_gid_read(struct inode *ip)
@@ -376,13 +384,22 @@ static inline gid_t zfs_gid_read(struct inode *ip)
static inline void zfs_uid_write(struct inode *ip, uid_t uid)
{
+#ifdef HAVE_SUPER_USER_NS
+ ip->i_uid = make_kuid(ip->i_sb->s_user_ns, uid);
+#else
ip->i_uid = make_kuid(kcred->user_ns, uid);
+#endif
}
static inline void zfs_gid_write(struct inode *ip, gid_t gid)
{
+#ifdef HAVE_SUPER_USER_NS
+ ip->i_gid = make_kgid(ip->i_sb->s_user_ns, gid);
+#else
ip->i_gid = make_kgid(kcred->user_ns, gid);
+#endif
}
+
#else
static inline uid_t zfs_uid_read(struct inode *ip)
{