diff --git a/config/kernel-kuid-helpers.m4 b/config/kernel-kuid-helpers.m4 new file mode 100644 index 000000000..60713b9d3 --- /dev/null +++ b/config/kernel-kuid-helpers.m4 @@ -0,0 +1,22 @@ +dnl # +dnl # 3.5 API change, +dnl # Since usernamespaces were introduced in kernel version 3.5, it +dnl # became necessary to go through one more level of indirection +dnl # when dealing with uid/gid - namely the kuid type. +dnl # +dnl # +AC_DEFUN([ZFS_AC_KERNEL_KUID_HELPERS], [ + AC_MSG_CHECKING([whether i_(uid|gid)_(read|write) exist]) + ZFS_LINUX_TRY_COMPILE([ + #include + ],[ + struct inode *ip = NULL; + (void) i_uid_read(ip); + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_KUID_HELPERS, 1, + [i_(uid|gid)_(read|write) exist]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel.m4 b/config/kernel.m4 index 086cd0b05..c9b24cbe8 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -92,6 +92,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ ZFS_AC_KERNEL_MAKE_REQUEST_FN ZFS_AC_KERNEL_GENERIC_IO_ACCT ZFS_AC_KERNEL_FPU + ZFS_AC_KERNEL_KUID_HELPERS AS_IF([test "$LINUX_OBJ" != "$LINUX"], [ KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ" diff --git a/include/linux/vfs_compat.h b/include/linux/vfs_compat.h index bcec1146a..97220c2fe 100644 --- a/include/linux/vfs_compat.h +++ b/include/linux/vfs_compat.h @@ -28,6 +28,7 @@ #define _ZFS_VFS_H #include +#include #include /* @@ -352,6 +353,58 @@ static inline struct inode *file_inode(const struct file *f) } #endif /* HAVE_FILE_INODE */ +#ifdef HAVE_KUID_HELPERS +static inline uid_t zfs_uid_read_impl(struct inode *ip) +{ + return (from_kuid(kcred->user_ns, ip->i_uid)); +} + +static inline uid_t zfs_uid_read(struct inode *ip) +{ + return (zfs_uid_read_impl(ip)); +} + +static inline gid_t zfs_gid_read_impl(struct inode *ip) +{ + return (from_kgid(kcred->user_ns, ip->i_gid)); +} + +static inline gid_t zfs_gid_read(struct inode *ip) +{ + return (zfs_gid_read_impl(ip)); +} + +static inline void zfs_uid_write(struct inode *ip, uid_t uid) +{ + ip->i_uid = make_kuid(kcred->user_ns, uid); +} + +static inline void zfs_gid_write(struct inode *ip, gid_t gid) +{ + ip->i_gid = make_kgid(kcred->user_ns, gid); +} +#else +static inline uid_t zfs_uid_read(struct inode *ip) +{ + return (ip->i_uid); +} + +static inline gid_t zfs_gid_read(struct inode *ip) +{ + return (ip->i_gid); +} + +static inline void zfs_uid_write(struct inode *ip, uid_t uid) +{ + ip->i_uid = uid; +} + +static inline void zfs_gid_write(struct inode *ip, gid_t gid) +{ + ip->i_gid = gid; +} +#endif + /* * 2.6.38 API change */