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 <n.borisov.lkml@gmail.com>
Signed-off-by: Chunwei Chen <david.chen@osnexus.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #4928
This commit is contained in:
Nikolay Borisov 2016-08-03 20:19:04 +03:00 committed by Brian Behlendorf
parent cf2731e65b
commit 938cfeb0f2
3 changed files with 39 additions and 0 deletions

View File

@ -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)
])
])

View File

@ -8,6 +8,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
ZFS_AC_KERNEL_CONFIG ZFS_AC_KERNEL_CONFIG
ZFS_AC_KERNEL_DECLARE_EVENT_CLASS ZFS_AC_KERNEL_DECLARE_EVENT_CLASS
ZFS_AC_KERNEL_CURRENT_BIO_TAIL ZFS_AC_KERNEL_CURRENT_BIO_TAIL
ZFS_AC_KERNEL_SUPER_USER_NS
ZFS_AC_KERNEL_SUBMIT_BIO ZFS_AC_KERNEL_SUBMIT_BIO
ZFS_AC_KERNEL_BDEV_BLOCK_DEVICE_OPERATIONS ZFS_AC_KERNEL_BDEV_BLOCK_DEVICE_OPERATIONS
ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID

View File

@ -356,7 +356,11 @@ static inline struct inode *file_inode(const struct file *f)
#ifdef HAVE_KUID_HELPERS #ifdef HAVE_KUID_HELPERS
static inline uid_t zfs_uid_read_impl(struct inode *ip) 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)); return (from_kuid(kcred->user_ns, ip->i_uid));
#endif
} }
static inline uid_t zfs_uid_read(struct inode *ip) 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) 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)); return (from_kgid(kcred->user_ns, ip->i_gid));
#endif
} }
static inline gid_t zfs_gid_read(struct inode *ip) 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) 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); ip->i_uid = make_kuid(kcred->user_ns, uid);
#endif
} }
static inline void zfs_gid_write(struct inode *ip, gid_t gid) 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); ip->i_gid = make_kgid(kcred->user_ns, gid);
#endif
} }
#else #else
static inline uid_t zfs_uid_read(struct inode *ip) static inline uid_t zfs_uid_read(struct inode *ip)
{ {