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

Commit 22ee6985 authored by Josef Bacik's avatar Josef Bacik
Browse files

Btrfs: check to see if the inode is in the log before fsyncing



We have this check down in the actual logging code, but this is after we
start a transaction and all that good stuff.  So move the helper
inode_in_log() out so we can call it in fsync() and avoid starting a
transaction altogether and just exit if we've already fsync()'ed this file
recently.  You would notice this issue if you fsync()'ed a file over and
over again until the transaction committed.  Thanks,

Signed-off-by: default avatarJosef Bacik <josef@redhat.com>
parent 018642a1
Loading
Loading
Loading
Loading
+13 −0
Original line number Original line Diff line number Diff line
@@ -199,4 +199,17 @@ static inline bool btrfs_is_free_space_inode(struct btrfs_root *root,
	return false;
	return false;
}
}


static inline int btrfs_inode_in_log(struct inode *inode, u64 generation)
{
	struct btrfs_root *root = BTRFS_I(inode)->root;
	int ret = 0;

	mutex_lock(&root->log_mutex);
	if (BTRFS_I(inode)->logged_trans == generation &&
	    BTRFS_I(inode)->last_sub_trans <= root->last_log_commit)
		ret = 1;
	mutex_unlock(&root->log_mutex);
	return ret;
}

#endif
#endif
+2 −1
Original line number Original line Diff line number Diff line
@@ -1552,7 +1552,8 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
	 * syncing
	 * syncing
	 */
	 */
	smp_mb();
	smp_mb();
	if (BTRFS_I(inode)->last_trans <=
	if (btrfs_inode_in_log(inode, root->fs_info->generation) ||
	    BTRFS_I(inode)->last_trans <=
	    root->fs_info->last_trans_committed) {
	    root->fs_info->last_trans_committed) {
		BTRFS_I(inode)->last_trans = 0;
		BTRFS_I(inode)->last_trans = 0;
		mutex_unlock(&inode->i_mutex);
		mutex_unlock(&inode->i_mutex);
+1 −16
Original line number Original line Diff line number Diff line
@@ -3038,21 +3038,6 @@ static noinline int check_parent_dirs_for_sync(struct btrfs_trans_handle *trans,
	return ret;
	return ret;
}
}


static int inode_in_log(struct btrfs_trans_handle *trans,
		 struct inode *inode)
{
	struct btrfs_root *root = BTRFS_I(inode)->root;
	int ret = 0;

	mutex_lock(&root->log_mutex);
	if (BTRFS_I(inode)->logged_trans == trans->transid &&
	    BTRFS_I(inode)->last_sub_trans <= root->last_log_commit)
		ret = 1;
	mutex_unlock(&root->log_mutex);
	return ret;
}


/*
/*
 * helper function around btrfs_log_inode to make sure newly created
 * helper function around btrfs_log_inode to make sure newly created
 * parent directories also end up in the log.  A minimal inode and backref
 * parent directories also end up in the log.  A minimal inode and backref
@@ -3093,7 +3078,7 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
	if (ret)
	if (ret)
		goto end_no_trans;
		goto end_no_trans;


	if (inode_in_log(trans, inode)) {
	if (btrfs_inode_in_log(inode, trans->transid)) {
		ret = BTRFS_NO_LOG_SYNC;
		ret = BTRFS_NO_LOG_SYNC;
		goto end_no_trans;
		goto end_no_trans;
	}
	}