Skip to contentSkip to conversation

Btrfs: fix transaction leak during fsync call

PATCH Superseded Filipe David Borba Manana 1 participant 2 messages May 29, 2014 Btrfs file system

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Btrfs: fix transaction leak during fsync call

If btrfs_log_dentry_safe() returns an error, we set ret to 1 and fall through with the goal of committing the transaction. However, in the case where the inode doesn't need a full sync, we would call btrfs_wait_ordered_range() against the target range for our inode, and if it returned an error, we would return without commiting or ending the transaction, leaving the transaction open forever.

Since when btrfs_wait_ordered_range() doesn't return an error we commit the transaction, it doesn't make sense to make a call to btrfs_wait_ordered_range() because committing the transaction will wait for all ordered extents to complete anyway.

---
 fs/btrfs/file.c | 6 ------
 1 file changed, 6 deletions(-)
fs/btrfs/file.c +0 -6
index 8accf94..e0be468 100644
@@ -2022,12 +2022,6 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
 				goto out;
 			}
 		}
-		if (!full_sync) {
-			ret = btrfs_wait_ordered_range(inode, start,
-						       end - start + 1);
-			if (ret)
-				goto out;
-		}
 		ret = btrfs_commit_transaction(trans, root);
 	} else {
 		ret = btrfs_end_transaction(trans, root);
Signature · 1 line
1.9.1
#1 lore raw

PATCH v2 1/1 Btrfs: fix transaction leak during fsync call

If btrfs_log_dentry_safe() returns an error, we set ret to 1 and fall through with the goal of committing the transaction. However, in the case where the inode doesn't need a full sync, we would call btrfs_wait_ordered_range() against the target range for our inode, and if it returned an error, we would return without commiting or ending the transaction.

---

V2: Leave the call to btrfs_wait_ordered_range(), it's needed if
the fs is mounted with -o no_flushoncommit.

 fs/btrfs/file.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
fs/btrfs/file.c +3 -1
index e46bfaf..5a00597 100644
@@ -2025,8 +2025,10 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
 		if (!full_sync) {
 			ret = btrfs_wait_ordered_range(inode, start,
 						       end - start + 1);
-			if (ret)
+			if (ret) {
+				btrfs_end_transaction(trans, root);
 				goto out;
+			}
 		}
 		ret = btrfs_commit_transaction(trans, root);
 	} else {
Signature · 1 line
1.9.1