summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config/kernel-rename.m425
-rw-r--r--config/kernel.m41
-rw-r--r--module/zfs/zpl_ctldir.c23
-rw-r--r--module/zfs/zpl_inode.c21
4 files changed, 65 insertions, 5 deletions
diff --git a/config/kernel-rename.m4 b/config/kernel-rename.m4
new file mode 100644
index 000000000..9f894fb4d
--- /dev/null
+++ b/config/kernel-rename.m4
@@ -0,0 +1,25 @@
+dnl #
+dnl # 4.9 API change,
+dnl # iops->rename2() merged into iops->rename(), and iops->rename() now wants
+dnl # flags.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_RENAME_WANTS_FLAGS], [
+ AC_MSG_CHECKING([whether iops->rename() wants flags])
+ ZFS_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+ int rename_fn(struct inode *sip, struct dentry *sdp,
+ struct inode *tip, struct dentry *tdp,
+ unsigned int flags) { return 0; }
+
+ static const struct inode_operations
+ iops __attribute__ ((unused)) = {
+ .rename = rename_fn,
+ };
+ ],[
+ ],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_RENAME_WANTS_FLAGS, 1, [iops->rename() wants flags])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+])
diff --git a/config/kernel.m4 b/config/kernel.m4
index cdefff5f1..9405ae6f9 100644
--- a/config/kernel.m4
+++ b/config/kernel.m4
@@ -99,6 +99,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
ZFS_AC_KERNEL_FOLLOW_DOWN_ONE
ZFS_AC_KERNEL_MAKE_REQUEST_FN
ZFS_AC_KERNEL_GENERIC_IO_ACCT
+ ZFS_AC_KERNEL_RENAME_WANTS_FLAGS
AS_IF([test "$LINUX_OBJ" != "$LINUX"], [
KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ"
diff --git a/module/zfs/zpl_ctldir.c b/module/zfs/zpl_ctldir.c
index 069834eae..d691f670b 100644
--- a/module/zfs/zpl_ctldir.c
+++ b/module/zfs/zpl_ctldir.c
@@ -301,13 +301,17 @@ zpl_snapdir_readdir(struct file *filp, void *dirent, filldir_t filldir)
}
#endif /* HAVE_VFS_ITERATE */
-int
-zpl_snapdir_rename(struct inode *sdip, struct dentry *sdentry,
- struct inode *tdip, struct dentry *tdentry)
+static int
+zpl_snapdir_rename2(struct inode *sdip, struct dentry *sdentry,
+ struct inode *tdip, struct dentry *tdentry, unsigned int flags)
{
cred_t *cr = CRED();
int error;
+ /* We probably don't want to support renameat2(2) in ctldir */
+ if (flags)
+ return (-EINVAL);
+
crhold(cr);
error = -zfsctl_snapdir_rename(sdip, dname(sdentry),
tdip, dname(tdentry), cr, 0);
@@ -317,6 +321,15 @@ zpl_snapdir_rename(struct inode *sdip, struct dentry *sdentry,
return (error);
}
+#ifndef HAVE_RENAME_WANTS_FLAGS
+static int
+zpl_snapdir_rename(struct inode *sdip, struct dentry *sdentry,
+ struct inode *tdip, struct dentry *tdentry)
+{
+ return (zpl_snapdir_rename2(sdip, sdentry, tdip, tdentry, 0));
+}
+#endif
+
static int
zpl_snapdir_rmdir(struct inode *dip, struct dentry *dentry)
{
@@ -405,7 +418,11 @@ const struct file_operations zpl_fops_snapdir = {
const struct inode_operations zpl_ops_snapdir = {
.lookup = zpl_snapdir_lookup,
.getattr = zpl_snapdir_getattr,
+#ifdef HAVE_RENAME_WANTS_FLAGS
+ .rename = zpl_snapdir_rename2,
+#else
.rename = zpl_snapdir_rename,
+#endif
.rmdir = zpl_snapdir_rmdir,
.mkdir = zpl_snapdir_mkdir,
};
diff --git a/module/zfs/zpl_inode.c b/module/zfs/zpl_inode.c
index d5d37345d..d8490ffcc 100644
--- a/module/zfs/zpl_inode.c
+++ b/module/zfs/zpl_inode.c
@@ -353,13 +353,17 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
}
static int
-zpl_rename(struct inode *sdip, struct dentry *sdentry,
- struct inode *tdip, struct dentry *tdentry)
+zpl_rename2(struct inode *sdip, struct dentry *sdentry,
+ struct inode *tdip, struct dentry *tdentry, unsigned int flags)
{
cred_t *cr = CRED();
int error;
fstrans_cookie_t cookie;
+ /* We don't have renameat2(2) support */
+ if (flags)
+ return (-EINVAL);
+
crhold(cr);
cookie = spl_fstrans_mark();
error = -zfs_rename(sdip, dname(sdentry), tdip, dname(tdentry), cr, 0);
@@ -370,6 +374,15 @@ zpl_rename(struct inode *sdip, struct dentry *sdentry,
return (error);
}
+#ifndef HAVE_RENAME_WANTS_FLAGS
+static int
+zpl_rename(struct inode *sdip, struct dentry *sdentry,
+ struct inode *tdip, struct dentry *tdentry)
+{
+ return (zpl_rename2(sdip, sdentry, tdip, tdentry, 0));
+}
+#endif
+
static int
zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
{
@@ -678,7 +691,11 @@ const struct inode_operations zpl_dir_inode_operations = {
.mkdir = zpl_mkdir,
.rmdir = zpl_rmdir,
.mknod = zpl_mknod,
+#ifdef HAVE_RENAME_WANTS_FLAGS
+ .rename = zpl_rename2,
+#else
.rename = zpl_rename,
+#endif
.setattr = zpl_setattr,
.getattr = zpl_getattr,
.setxattr = generic_setxattr,