aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r--fs/btrfs/file.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 1b7e51a9db0f..3088a1184483 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -41,6 +41,9 @@
41#include "compat.h" 41#include "compat.h"
42 42
43 43
44/* simple helper to fault in pages and copy. This should go away
45 * and be replaced with calls into generic code.
46 */
44static int noinline btrfs_copy_from_user(loff_t pos, int num_pages, 47static int noinline btrfs_copy_from_user(loff_t pos, int num_pages,
45 int write_bytes, 48 int write_bytes,
46 struct page **prepared_pages, 49 struct page **prepared_pages,
@@ -72,12 +75,19 @@ static int noinline btrfs_copy_from_user(loff_t pos, int num_pages,
72 return page_fault ? -EFAULT : 0; 75 return page_fault ? -EFAULT : 0;
73} 76}
74 77
78/*
79 * unlocks pages after btrfs_file_write is done with them
80 */
75static void noinline btrfs_drop_pages(struct page **pages, size_t num_pages) 81static void noinline btrfs_drop_pages(struct page **pages, size_t num_pages)
76{ 82{
77 size_t i; 83 size_t i;
78 for (i = 0; i < num_pages; i++) { 84 for (i = 0; i < num_pages; i++) {
79 if (!pages[i]) 85 if (!pages[i])
80 break; 86 break;
87 /* page checked is some magic around finding pages that
88 * have been modified without going through btrfs_set_page_dirty
89 * clear it here
90 */
81 ClearPageChecked(pages[i]); 91 ClearPageChecked(pages[i]);
82 unlock_page(pages[i]); 92 unlock_page(pages[i]);
83 mark_page_accessed(pages[i]); 93 mark_page_accessed(pages[i]);
@@ -85,6 +95,10 @@ static void noinline btrfs_drop_pages(struct page **pages, size_t num_pages)
85 } 95 }
86} 96}
87 97
98/* this does all the hard work for inserting an inline extent into
99 * the btree. Any existing inline extent is extended as required to make room,
100 * otherwise things are inserted as required into the btree
101 */
88static int noinline insert_inline_extent(struct btrfs_trans_handle *trans, 102static int noinline insert_inline_extent(struct btrfs_trans_handle *trans,
89 struct btrfs_root *root, struct inode *inode, 103 struct btrfs_root *root, struct inode *inode,
90 u64 offset, size_t size, 104 u64 offset, size_t size,
@@ -228,6 +242,14 @@ fail:
228 return err; 242 return err;
229} 243}
230 244
245/*
246 * after copy_from_user, pages need to be dirtied and we need to make
247 * sure holes are created between the current EOF and the start of
248 * any next extents (if required).
249 *
250 * this also makes the decision about creating an inline extent vs
251 * doing real data extents, marking pages dirty and delalloc as required.
252 */
231static int noinline dirty_and_release_pages(struct btrfs_trans_handle *trans, 253static int noinline dirty_and_release_pages(struct btrfs_trans_handle *trans,
232 struct btrfs_root *root, 254 struct btrfs_root *root,
233 struct file *file, 255 struct file *file,
@@ -362,6 +384,10 @@ out_unlock:
362 return err; 384 return err;
363} 385}
364 386
387/*
388 * this drops all the extents in the cache that intersect the range
389 * [start, end]. Existing extents are split as required.
390 */
365int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, 391int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
366 int skip_pinned) 392 int skip_pinned)
367{ 393{
@@ -536,6 +562,9 @@ out:
536 * If an extent intersects the range but is not entirely inside the range 562 * If an extent intersects the range but is not entirely inside the range
537 * it is either truncated or split. Anything entirely inside the range 563 * it is either truncated or split. Anything entirely inside the range
538 * is deleted from the tree. 564 * is deleted from the tree.
565 *
566 * inline_limit is used to tell this code which offsets in the file to keep
567 * if they contain inline extents.
539 */ 568 */
540int noinline btrfs_drop_extents(struct btrfs_trans_handle *trans, 569int noinline btrfs_drop_extents(struct btrfs_trans_handle *trans,
541 struct btrfs_root *root, struct inode *inode, 570 struct btrfs_root *root, struct inode *inode,
@@ -796,7 +825,9 @@ out:
796} 825}
797 826
798/* 827/*
799 * this gets pages into the page cache and locks them down 828 * this gets pages into the page cache and locks them down, it also properly
829 * waits for data=ordered extents to finish before allowing the pages to be
830 * modified.
800 */ 831 */
801static int noinline prepare_pages(struct btrfs_root *root, struct file *file, 832static int noinline prepare_pages(struct btrfs_root *root, struct file *file,
802 struct page **pages, size_t num_pages, 833 struct page **pages, size_t num_pages,
@@ -1034,6 +1065,17 @@ int btrfs_release_file(struct inode * inode, struct file * filp)
1034 return 0; 1065 return 0;
1035} 1066}
1036 1067
1068/*
1069 * fsync call for both files and directories. This logs the inode into
1070 * the tree log instead of forcing full commits whenever possible.
1071 *
1072 * It needs to call filemap_fdatawait so that all ordered extent updates are
1073 * in the metadata btree are up to date for copying to the log.
1074 *
1075 * It drops the inode mutex before doing the tree log commit. This is an
1076 * important optimization for directories because holding the mutex prevents
1077 * new operations on the dir while we write to disk.
1078 */
1037int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) 1079int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
1038{ 1080{
1039 struct inode *inode = dentry->d_inode; 1081 struct inode *inode = dentry->d_inode;