diff options
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r-- | fs/btrfs/file.c | 44 |
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 | */ | ||
44 | static int noinline btrfs_copy_from_user(loff_t pos, int num_pages, | 47 | static 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 | */ | ||
75 | static void noinline btrfs_drop_pages(struct page **pages, size_t num_pages) | 81 | static 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 | */ | ||
88 | static int noinline insert_inline_extent(struct btrfs_trans_handle *trans, | 102 | static 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 | */ | ||
231 | static int noinline dirty_and_release_pages(struct btrfs_trans_handle *trans, | 253 | static 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 | */ | ||
365 | int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, | 391 | int 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 | */ |
540 | int noinline btrfs_drop_extents(struct btrfs_trans_handle *trans, | 569 | int 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 | */ |
801 | static int noinline prepare_pages(struct btrfs_root *root, struct file *file, | 832 | static 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 | */ | ||
1037 | int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | 1079 | int 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; |