mirror of
https://github.com/torvalds/linux.git
synced 2024-11-17 01:22:07 +00:00
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: Josef Bacik <josef@redhat.com>
This commit is contained in:
parent
018642a1f1
commit
22ee6985de
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -3038,21 +3038,6 @@ out:
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user