|
@@ -2078,6 +2078,14 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
|
|
goto out;
|
|
goto out;
|
|
|
|
|
|
inode_lock(inode);
|
|
inode_lock(inode);
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * We take the dio_sem here because the tree log stuff can race with
|
|
|
|
+ * lockless dio writes and get an extent map logged for an extent we
|
|
|
|
+ * never waited on. We need it this high up for lockdep reasons.
|
|
|
|
+ */
|
|
|
|
+ down_write(&BTRFS_I(inode)->dio_sem);
|
|
|
|
+
|
|
atomic_inc(&root->log_batch);
|
|
atomic_inc(&root->log_batch);
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -2086,6 +2094,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
|
|
*/
|
|
*/
|
|
ret = btrfs_wait_ordered_range(inode, start, len);
|
|
ret = btrfs_wait_ordered_range(inode, start, len);
|
|
if (ret) {
|
|
if (ret) {
|
|
|
|
+ up_write(&BTRFS_I(inode)->dio_sem);
|
|
inode_unlock(inode);
|
|
inode_unlock(inode);
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
@@ -2109,6 +2118,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
|
|
* checked called fsync.
|
|
* checked called fsync.
|
|
*/
|
|
*/
|
|
ret = filemap_check_wb_err(inode->i_mapping, file->f_wb_err);
|
|
ret = filemap_check_wb_err(inode->i_mapping, file->f_wb_err);
|
|
|
|
+ up_write(&BTRFS_I(inode)->dio_sem);
|
|
inode_unlock(inode);
|
|
inode_unlock(inode);
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
@@ -2127,6 +2137,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
|
|
trans = btrfs_start_transaction(root, 0);
|
|
trans = btrfs_start_transaction(root, 0);
|
|
if (IS_ERR(trans)) {
|
|
if (IS_ERR(trans)) {
|
|
ret = PTR_ERR(trans);
|
|
ret = PTR_ERR(trans);
|
|
|
|
+ up_write(&BTRFS_I(inode)->dio_sem);
|
|
inode_unlock(inode);
|
|
inode_unlock(inode);
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
@@ -2148,6 +2159,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
|
|
* file again, but that will end up using the synchronization
|
|
* file again, but that will end up using the synchronization
|
|
* inside btrfs_sync_log to keep things safe.
|
|
* inside btrfs_sync_log to keep things safe.
|
|
*/
|
|
*/
|
|
|
|
+ up_write(&BTRFS_I(inode)->dio_sem);
|
|
inode_unlock(inode);
|
|
inode_unlock(inode);
|
|
|
|
|
|
/*
|
|
/*
|