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

Commit f4e0c30c authored by Al Viro's avatar Al Viro
Browse files

allow the temp files created by open() to be linked to



O_TMPFILE | O_CREAT => linkat() with AT_SYMLINK_FOLLOW and /proc/self/fd/<n>
as oldpath (i.e. flink()) will create a link
O_TMPFILE | O_CREAT | O_EXCL => ENOENT on attempt to link those guys

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 60545d0d
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -333,8 +333,10 @@ EXPORT_SYMBOL(set_nlink);
 */
void inc_nlink(struct inode *inode)
{
	if (WARN_ON(inode->i_nlink == 0))
	if (unlikely(inode->i_nlink == 0)) {
		WARN_ON(!(inode->i_state & I_LINKABLE));
		atomic_long_dec(&inode->i_sb->s_remove_count);
	}

	inode->__i_nlink++;
}
+14 −2
Original line number Diff line number Diff line
@@ -2948,8 +2948,14 @@ static int do_tmpfile(int dfd, struct filename *pathname,
	if (error)
		goto out2;
	error = open_check_o_direct(file);
	if (error)
	if (error) {
		fput(file);
	} else if (!(op->open_flag & O_EXCL)) {
		struct inode *inode = file_inode(file);
		spin_lock(&inode->i_lock);
		inode->i_state |= I_LINKABLE;
		spin_unlock(&inode->i_lock);
	}
out2:
	mnt_drop_write(nd->path.mnt);
out:
@@ -3628,12 +3634,18 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de

	mutex_lock(&inode->i_mutex);
	/* Make sure we don't allow creating hardlink to an unlinked file */
	if (inode->i_nlink == 0)
	if (inode->i_nlink == 0 && !(inode->i_state & I_LINKABLE))
		error =  -ENOENT;
	else if (max_links && inode->i_nlink >= max_links)
		error = -EMLINK;
	else
		error = dir->i_op->link(old_dentry, dir, new_dentry);

	if (!error && (inode->i_state & I_LINKABLE)) {
		spin_lock(&inode->i_lock);
		inode->i_state &= ~I_LINKABLE;
		spin_unlock(&inode->i_lock);
	}
	mutex_unlock(&inode->i_mutex);
	if (!error)
		fsnotify_link(dir, inode, new_dentry);
+1 −0
Original line number Diff line number Diff line
@@ -1744,6 +1744,7 @@ struct super_operations {
#define I_REFERENCED		(1 << 8)
#define __I_DIO_WAKEUP		9
#define I_DIO_WAKEUP		(1 << I_DIO_WAKEUP)
#define I_LINKABLE		(1 << 10)

#define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)