aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/file.c
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2008-06-10 10:07:39 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:03 -0400
commit6bf13c0cc833bf5ba013d6aa60379484bf48c4e6 (patch)
treeae2b54a1a26a89fece49f6b6d6dff8448efab542 /fs/btrfs/file.c
parenteba12c7bfcb4855fc757357e5e5b0b9a474499ba (diff)
Btrfs: transaction ioctls
These ioctls let a user application hold a transaction open while it performs a series of operations. A final ioctl does a sync on the fs (closing the current transaction). This is the main requirement for Ceph's OSD to be able to keep the data it's storing in a btrfs volume consistent, and AFAICS it works just fine. The application would do something like fd = ::open("some/file", O_RDONLY); ::ioctl(fd, BTRFS_IOC_TRANS_START); /* do a bunch of stuff */ ::ioctl(fd, BTRFS_IOC_TRANS_END); or just ::close(fd); And to ensure it commits to disk, ::ioctl(fd, BTRFS_IOC_SYNC); When a transaction is held open, the trans_handle is attached to the struct file (via private_data) so that it will get cleaned up if the process dies unexpectedly. A held transaction is also ended on fsync() to avoid a deadlock. A misbehaving application could also deliberately hold a transaction open, effectively locking up the FS, so it may make sense to restrict something like this to root or something. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r--fs/btrfs/file.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index c4fa4664a456..73c6d085bd90 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -978,9 +978,11 @@ out_nolock:
978 return num_written ? num_written : err; 978 return num_written ? num_written : err;
979} 979}
980 980
981static int btrfs_release_file (struct inode * inode, struct file * filp) 981int btrfs_release_file(struct inode * inode, struct file * filp)
982{ 982{
983 btrfs_del_ordered_inode(inode); 983 btrfs_del_ordered_inode(inode);
984 if (filp->private_data)
985 btrfs_ioctl_trans_end(filp);
984 return 0; 986 return 0;
985} 987}
986 988
@@ -1011,6 +1013,9 @@ static int btrfs_sync_file(struct file *file,
1011 /* 1013 /*
1012 * ok we haven't committed the transaction yet, lets do a commit 1014 * ok we haven't committed the transaction yet, lets do a commit
1013 */ 1015 */
1016 if (file->private_data)
1017 btrfs_ioctl_trans_end(file);
1018
1014 trans = btrfs_start_transaction(root, 1); 1019 trans = btrfs_start_transaction(root, 1);
1015 if (!trans) { 1020 if (!trans) {
1016 ret = -ENOMEM; 1021 ret = -ENOMEM;