Skip to content

Commit

Permalink
renameat2: add EL7 compatibility handling
Browse files Browse the repository at this point in the history
EL7 has .rename2 op upper in the inode_operations_wrapper, so let's add
a wrapping ifdef to dir inode_operations and ifdef the ops assignment
too.

Configure test lives in kernel-rename.m4 for now, as rename2/EL7 case is
the only reason why we need it - for now, until support for tmpfile is
needed. then it would me more logical to move this check to a separate
file.

Signed-off-by: Pavel Snajdr <snajpa@snajpa.net>
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
  • Loading branch information
snajpa authored and cyphar committed Jun 9, 2021
1 parent 54f00e0 commit 43f2844
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 0 deletions.
27 changes: 27 additions & 0 deletions config/kernel-rename.m4
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,24 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME], [
};
],[])
dnl #
dnl # EL7 compatibility
dnl #
dnl # EL7 has backported renameat2 support, but it's done by defining a
dnl # separate iops wrapper structure that takes the .renameat2 function.
dnl #
ZFS_LINUX_TEST_SRC([dir_inode_operations_wrapper_rename2], [
#include <linux/fs.h>
int rename2_fn(struct inode *sip, struct dentry *sdp,
struct inode *tip, struct dentry *tdp,
unsigned int flags) { return 0; }
static const struct inode_operations_wrapper
iops __attribute__ ((unused)) = {
.rename2 = rename2_fn,
};
],[])
dnl #
dnl # 5.12 API change,
dnl #
Expand Down Expand Up @@ -78,6 +96,15 @@ AC_DEFUN([ZFS_AC_KERNEL_RENAME], [
[iops->rename() wants flags])
],[
AC_MSG_RESULT(no)
AC_MSG_CHECKING([whether struct inode_operations_wrapper takes .rename2()])
ZFS_LINUX_TEST_RESULT([dir_inode_operations_wrapper_rename2], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_RENAME2_OPERATIONS_WRAPPER, 1,
[struct inode_operations_wrapper takes .rename2()])
],[
AC_MSG_RESULT(no)
])
])
])
])
Expand Down
4 changes: 4 additions & 0 deletions include/os/linux/zfs/sys/zpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ extern void zpl_vap_init(vattr_t *vap, struct inode *dir,
umode_t mode, cred_t *cr);

extern const struct inode_operations zpl_inode_operations;
#ifdef HAVE_RENAME2_OPERATIONS_WRAPPER
extern const struct inode_operations_wrapper zpl_dir_inode_operations;
#else
extern const struct inode_operations zpl_dir_inode_operations;
#endif
extern const struct inode_operations zpl_symlink_inode_operations;
extern const struct inode_operations zpl_special_inode_operations;

Expand Down
5 changes: 5 additions & 0 deletions module/os/linux/zfs/zfs_znode.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,12 @@ zfs_inode_set_ops(zfsvfs_t *zfsvfs, struct inode *ip)
break;

case S_IFDIR:
#ifdef HAVE_RENAME2_OPERATIONS_WRAPPER
ip->i_flags |= S_IOPS_WRAPPER;
ip->i_op = &zpl_dir_inode_operations.ops;
#else
ip->i_op = &zpl_dir_inode_operations;
#endif
ip->i_fop = &zpl_dir_file_operations;
ITOZ(ip)->z_zn_prefetch = B_TRUE;
break;
Expand Down
9 changes: 9 additions & 0 deletions module/os/linux/zfs/zpl_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,12 @@ const struct inode_operations zpl_inode_operations = {
#endif /* CONFIG_FS_POSIX_ACL */
};

#ifdef HAVE_RENAME2_OPERATIONS_WRAPPER
const struct inode_operations_wrapper zpl_dir_inode_operations = {
.ops = {
#else
const struct inode_operations zpl_dir_inode_operations = {
#endif
.create = zpl_create,
.lookup = zpl_lookup,
.link = zpl_link,
Expand Down Expand Up @@ -725,6 +730,10 @@ const struct inode_operations zpl_dir_inode_operations = {
#endif /* HAVE_SET_ACL */
.get_acl = zpl_get_acl,
#endif /* CONFIG_FS_POSIX_ACL */
#ifdef HAVE_RENAME2_OPERATIONS_WRAPPER
},
.rename2 = zpl_rename2,
#endif
};

const struct inode_operations zpl_symlink_inode_operations = {
Expand Down

0 comments on commit 43f2844

Please sign in to comment.