Linux 4.9: inode_operation rename now takes flags

In Linux 3.15 commit 520c8b16505236fc82daa352e6c5e73cd9870cff,
inode_operation rename2() was added.  It takes the same arguments as
rename(), with an added flags argument supporting the following values:

RENAME_NOREPLACE: if "new" name exists, fail with -EEXIST.  Without
this flag, the default behavior is to replace the "new" existing file.

RENAME_EXCHANGE: exchange source and target; both must exist.

OpenAFS never implemented a .rename2() routine because it was optional
when introduced at Linux v3.15.

In Linux 4.9-rc1 the following commits remove the last in-tree uses of
.rename() and converts .rename2() to .rename().
aadfa8019e81 vfs: add note about i_op->rename changes to porting
2773bf00aeb9 fs: rename "rename2" i_op to "rename"
18fc84dafaac vfs: remove unused i_op->rename
1cd66c93ba8c fs: make remaining filesystems use .rename2
e0e0be8a8355 libfs: support RENAME_NOREPLACE in simple_rename()
f03b8ad8d386 fs: support RENAME_NOREPLACE for local filesystems

With these changes, it is now mandatory for OpenAFS afs_linux_rename()
to accept a 5th flag argument.

Add an autoconfig test to determine the signature of .rename().  Use this
information to implement afs_linux_rename() with the appropriate number
of arguments.  Implement "toleration support" for the flags option by
treating a zero flag as a normal rename; if any flags are specified,
return -EINVAL to indicate the OpenAFS filesystem does not yet support
any flags.

Change-Id: I165d2b7956942446d97beda8504ac1ed5185a036
Reviewed-on: https://gerrit.openafs.org/12391
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
This commit is contained in:
Mark Vitale 2016-09-16 19:01:19 -04:00 committed by Benjamin Kaduk
parent 8e81b182e3
commit f21e3ef8ce
2 changed files with 16 additions and 1 deletions

View File

@ -917,6 +917,12 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*)
[#include <linux/fs.h>],
[void],
[struct inode *inode, void *link_data])
AC_CHECK_LINUX_OPERATION([inode_operations], [rename], [takes_flags],
[#include <linux/fs.h>],
[int],
[struct inode *oinode, struct dentry *odentry,
struct inode *ninode, struct dentry *ndentry,
unsigned int flags])
dnl Check for header files
AC_CHECK_LINUX_HEADER([config.h])

View File

@ -1808,7 +1808,11 @@ afs_linux_rmdir(struct inode *dip, struct dentry *dp)
static int
afs_linux_rename(struct inode *oldip, struct dentry *olddp,
struct inode *newip, struct dentry *newdp)
struct inode *newip, struct dentry *newdp
#ifdef HAVE_LINUX_INODE_OPERATIONS_RENAME_TAKES_FLAGS
, unsigned int flags
#endif
)
{
int code;
cred_t *credp = crref();
@ -1816,6 +1820,11 @@ afs_linux_rename(struct inode *oldip, struct dentry *olddp,
const char *newname = newdp->d_name.name;
struct dentry *rehash = NULL;
#ifdef HAVE_LINUX_INODE_OPERATIONS_RENAME_TAKES_FLAGS
if (flags)
return -EINVAL; /* no support for new flags yet */
#endif
/* Prevent any new references during rename operation. */
if (!d_unhashed(newdp)) {