diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-04-10 10:23:21 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:01 -0400 |
commit | 16432985920f3c45af82da214e2498f3e2f9066b (patch) | |
tree | ce05f57eefb1a6f5952c53205ec8a07e93d03b3c /fs/btrfs/file.c | |
parent | 85d824c4a407ba8dbd897f4e05bbe21bf24cc071 (diff) |
Btrfs: Add O_DIRECT read and write (writes == buffered + cache flush)
This adds basic O_DIRECT read and write support. In the write case, we
just do a normal buffered write followed by a cache flush. O_DIRECT +
O_SYNC are required to trigger metadata syncs.
In the read case, there is a basic btrfs_get_block call for use by
the generic O_DIRECT code. This does honor multi-volume mapping rules
but it skips all checksumming.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r-- | fs/btrfs/file.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 5fa450452f9b..5b9386452218 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -796,8 +796,6 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
796 | PAGE_CACHE_SIZE / (sizeof(struct page *))); | 796 | PAGE_CACHE_SIZE / (sizeof(struct page *))); |
797 | pinned[0] = NULL; | 797 | pinned[0] = NULL; |
798 | pinned[1] = NULL; | 798 | pinned[1] = NULL; |
799 | if (file->f_flags & O_DIRECT) | ||
800 | return -EINVAL; | ||
801 | 799 | ||
802 | pos = *ppos; | 800 | pos = *ppos; |
803 | start_pos = pos; | 801 | start_pos = pos; |
@@ -909,6 +907,15 @@ out_nolock: | |||
909 | start_pos, num_written); | 907 | start_pos, num_written); |
910 | if (err < 0) | 908 | if (err < 0) |
911 | num_written = err; | 909 | num_written = err; |
910 | } else if (num_written > 0 && (file->f_flags & O_DIRECT)) { | ||
911 | do_sync_mapping_range(inode->i_mapping, start_pos, | ||
912 | start_pos + num_written - 1, | ||
913 | SYNC_FILE_RANGE_WRITE | | ||
914 | SYNC_FILE_RANGE_WAIT_AFTER); | ||
915 | |||
916 | invalidate_mapping_pages(inode->i_mapping, | ||
917 | start_pos >> PAGE_CACHE_SHIFT, | ||
918 | (start_pos + num_written - 1) >> PAGE_CACHE_SHIFT); | ||
912 | } | 919 | } |
913 | current->backing_dev_info = NULL; | 920 | current->backing_dev_info = NULL; |
914 | return num_written ? num_written : err; | 921 | return num_written ? num_written : err; |