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

Commit 75caeecd authored by Maxim Patlasov's avatar Maxim Patlasov Committed by Miklos Szeredi
Browse files

fuse: update mtime on open(O_TRUNC) in atomic_o_trunc mode



In case of fc->atomic_o_trunc is set, fuse does nothing in
fuse_do_setattr() while handling open(O_TRUNC). Hence, i_mtime must be
updated explicitly in fuse_finish_open(). The patch also adds extra locking
encompassing open(O_TRUNC) operation to avoid races between the truncation
and updating i_mtime.

Signed-off-by: default avatarMaxim Patlasov <MPatlasov@parallels.com>
Signed-off-by: default avatarMiklos Szeredi <mszeredi@suse.cz>
parent 009dd694
Loading
Loading
Loading
Loading
+14 −4
Original line number Original line Diff line number Diff line
@@ -223,6 +223,8 @@ void fuse_finish_open(struct inode *inode, struct file *file)
		i_size_write(inode, 0);
		i_size_write(inode, 0);
		spin_unlock(&fc->lock);
		spin_unlock(&fc->lock);
		fuse_invalidate_attr(inode);
		fuse_invalidate_attr(inode);
		if (fc->writeback_cache)
			file_update_time(file);
	}
	}
	if ((file->f_mode & FMODE_WRITE) && fc->writeback_cache)
	if ((file->f_mode & FMODE_WRITE) && fc->writeback_cache)
		fuse_link_write_file(file);
		fuse_link_write_file(file);
@@ -232,18 +234,26 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir)
{
{
	struct fuse_conn *fc = get_fuse_conn(inode);
	struct fuse_conn *fc = get_fuse_conn(inode);
	int err;
	int err;
	bool lock_inode = (file->f_flags & O_TRUNC) &&
			  fc->atomic_o_trunc &&
			  fc->writeback_cache;


	err = generic_file_open(inode, file);
	err = generic_file_open(inode, file);
	if (err)
	if (err)
		return err;
		return err;


	if (lock_inode)
		mutex_lock(&inode->i_mutex);

	err = fuse_do_open(fc, get_node_id(inode), file, isdir);
	err = fuse_do_open(fc, get_node_id(inode), file, isdir);
	if (err)
		return err;


	if (!err)
		fuse_finish_open(inode, file);
		fuse_finish_open(inode, file);


	return 0;
	if (lock_inode)
		mutex_unlock(&inode->i_mutex);

	return err;
}
}


static void fuse_prepare_release(struct fuse_file *ff, int flags, int opcode)
static void fuse_prepare_release(struct fuse_file *ff, int flags, int opcode)