Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 520c8b16 authored by Miklos Szeredi's avatar Miklos Szeredi
Browse files

vfs: add renameat2 syscall



Add new renameat2 syscall, which is the same as renameat with an added
flags argument.

Pass flags to vfs_rename() and to i_op->rename() as well.

Signed-off-by: default avatarMiklos Szeredi <mszeredi@suse.cz>
Reviewed-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent bc27027a
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -47,6 +47,8 @@ prototypes:
	int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t);
	int (*rename) (struct inode *, struct dentry *,
			struct inode *, struct dentry *);
	int (*rename2) (struct inode *, struct dentry *,
			struct inode *, struct dentry *, unsigned int);
	int (*readlink) (struct dentry *, char __user *,int);
	void * (*follow_link) (struct dentry *, struct nameidata *);
	void (*put_link) (struct dentry *, struct nameidata *, void *);
@@ -78,6 +80,7 @@ mkdir: yes
unlink:		yes (both)
rmdir:		yes (both)	(see below)
rename:		yes (all)	(see below)
rename2:	yes (all)	(see below)
readlink:	no
follow_link:	no
put_link:	no
@@ -96,7 +99,8 @@ tmpfile: no

	Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on
victim.
	cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem.
	cross-directory ->rename() and rename2() has (per-superblock)
->s_vfs_rename_sem.

See Documentation/filesystems/directory-locking for more detailed discussion
of the locking scheme for directory operations.
+16 −0
Original line number Diff line number Diff line
@@ -347,6 +347,8 @@ struct inode_operations {
	int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t);
	int (*rename) (struct inode *, struct dentry *,
			struct inode *, struct dentry *);
	int (*rename2) (struct inode *, struct dentry *,
			struct inode *, struct dentry *, unsigned int);
	int (*readlink) (struct dentry *, char __user *,int);
        void * (*follow_link) (struct dentry *, struct nameidata *);
        void (*put_link) (struct dentry *, struct nameidata *, void *);
@@ -414,6 +416,20 @@ otherwise noted.
  rename: called by the rename(2) system call to rename the object to
	have the parent and name given by the second inode and dentry.

  rename2: this has an additional flags argument compared to rename.
	If no flags are supported by the filesystem then this method
	need not be implemented.  If some flags are supported then the
	filesystem must return -EINVAL for any unsupported or unknown
	flags.  Currently the following flags are implemented:
	(1) RENAME_NOREPLACE: this flag indicates that if the target
	of the rename exists the rename should fail with -EEXIST
	instead of replacing the target.  The VFS already checks for
	existence, so for local filesystems the RENAME_NOREPLACE
	implementation is equivalent to plain rename.
	(2) RENAME_EXCHANGE: exchange source and target.  Both must
	exist; this is checked by the VFS.  Unlike plain rename,
	source and target may be of different type.

  readlink: called by the readlink(2) system call. Only required if
	you want to support reading symbolic links

+1 −0
Original line number Diff line number Diff line
@@ -322,6 +322,7 @@
313	common	finit_module		sys_finit_module
314	common	sched_setattr		sys_sched_setattr
315	common	sched_getattr		sys_sched_getattr
316	common	renameat2		sys_renameat2

#
# x32-specific system call numbers start at 512 to avoid cache impact
+2 −2
Original line number Diff line number Diff line
@@ -105,8 +105,8 @@ static inline void ll_set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt,
#define ll_vfs_unlink(inode,entry,mnt)	  vfs_unlink(inode,entry)
#define ll_vfs_mknod(dir,entry,mnt,mode,dev)    vfs_mknod(dir,entry,mode,dev)
#define ll_security_inode_unlink(dir,entry,mnt) security_inode_unlink(dir,entry)
#define ll_vfs_rename(old,old_dir,mnt,new,new_dir,mnt1,delegated_inode) \
		vfs_rename(old,old_dir,new,new_dir,delegated_inode)
#define ll_vfs_rename(old, old_dir, mnt, new, new_dir, mnt1) \
		vfs_rename(old, old_dir, new, new_dir, NULL, 0)

#define cfs_bio_io_error(a,b)   bio_io_error((a))
#define cfs_bio_endio(a,b,c)    bio_endio((a),(c))
+1 −1
Original line number Diff line number Diff line
@@ -223,7 +223,7 @@ int lustre_rename(struct dentry *dir, struct vfsmount *mnt,
		GOTO(put_old, err = PTR_ERR(dchild_new));

	err = ll_vfs_rename(dir->d_inode, dchild_old, mnt,
			    dir->d_inode, dchild_new, mnt, NULL);
			    dir->d_inode, dchild_new, mnt);

	dput(dchild_new);
put_old:
Loading