]> bbs.cooldavid.org Git - net-next-2.6.git/blame - fs/btrfs/file.c
btrfs_get_extent should treat inline extents as though they hold a whole block
[net-next-2.6.git] / fs / btrfs / file.c
CommitLineData
6cbd5570
CM
1/*
2 * Copyright (C) 2007 Oracle. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License v2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public
14 * License along with this program; if not, write to the
15 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 * Boston, MA 021110-1307, USA.
17 */
18
39279cc3
CM
19#include <linux/buffer_head.h>
20#include <linux/fs.h>
21#include <linux/pagemap.h>
22#include <linux/highmem.h>
23#include <linux/time.h>
24#include <linux/init.h>
25#include <linux/string.h>
26#include <linux/smp_lock.h>
27#include <linux/backing-dev.h>
28#include <linux/mpage.h>
29#include <linux/swap.h>
30#include <linux/writeback.h>
31#include <linux/statfs.h>
32#include <linux/compat.h>
92fee66d 33#include <linux/version.h>
39279cc3
CM
34#include "ctree.h"
35#include "disk-io.h"
36#include "transaction.h"
37#include "btrfs_inode.h"
38#include "ioctl.h"
39#include "print-tree.h"
40
41
42static int btrfs_copy_from_user(loff_t pos, int num_pages, int write_bytes,
43 struct page **prepared_pages,
44 const char __user * buf)
45{
46 long page_fault = 0;
47 int i;
48 int offset = pos & (PAGE_CACHE_SIZE - 1);
49
50 for (i = 0; i < num_pages && write_bytes > 0; i++, offset = 0) {
51 size_t count = min_t(size_t,
52 PAGE_CACHE_SIZE - offset, write_bytes);
53 struct page *page = prepared_pages[i];
54 fault_in_pages_readable(buf, count);
55
56 /* Copy data from userspace to the current page */
57 kmap(page);
58 page_fault = __copy_from_user(page_address(page) + offset,
59 buf, count);
60 /* Flush processor's dcache for this page */
61 flush_dcache_page(page);
62 kunmap(page);
63 buf += count;
64 write_bytes -= count;
65
66 if (page_fault)
67 break;
68 }
69 return page_fault ? -EFAULT : 0;
70}
71
72static void btrfs_drop_pages(struct page **pages, size_t num_pages)
73{
74 size_t i;
75 for (i = 0; i < num_pages; i++) {
76 if (!pages[i])
77 break;
78 unlock_page(pages[i]);
79 mark_page_accessed(pages[i]);
80 page_cache_release(pages[i]);
81 }
82}
83
a52d9a80
CM
84static int insert_inline_extent(struct btrfs_trans_handle *trans,
85 struct btrfs_root *root, struct inode *inode,
54aa1f4d 86 u64 offset, ssize_t size,
a52d9a80 87 struct page *page, size_t page_offset)
54aa1f4d
CM
88{
89 struct btrfs_key key;
90 struct btrfs_path *path;
91 char *ptr, *kaddr;
54aa1f4d
CM
92 struct btrfs_file_extent_item *ei;
93 u32 datasize;
94 int err = 0;
95 int ret;
96
97 path = btrfs_alloc_path();
98 if (!path)
99 return -ENOMEM;
100
54aa1f4d
CM
101 btrfs_set_trans_block_group(trans, inode);
102
103 key.objectid = inode->i_ino;
104 key.offset = offset;
105 key.flags = 0;
106 btrfs_set_key_type(&key, BTRFS_EXTENT_DATA_KEY);
107 BUG_ON(size >= PAGE_CACHE_SIZE);
108 datasize = btrfs_file_extent_calc_inline_size(size);
109
110 ret = btrfs_insert_empty_item(trans, root, path, &key,
111 datasize);
112 if (ret) {
113 err = ret;
114 goto fail;
115 }
116 ei = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]),
117 path->slots[0], struct btrfs_file_extent_item);
118 btrfs_set_file_extent_generation(ei, trans->transid);
119 btrfs_set_file_extent_type(ei,
120 BTRFS_FILE_EXTENT_INLINE);
121 ptr = btrfs_file_extent_inline_start(ei);
122
a52d9a80 123 kaddr = kmap_atomic(page, KM_USER0);
54aa1f4d 124 btrfs_memcpy(root, path->nodes[0]->b_data,
a52d9a80 125 ptr, kaddr + page_offset, size);
54aa1f4d 126 kunmap_atomic(kaddr, KM_USER0);
ccd467d6 127 btrfs_mark_buffer_dirty(path->nodes[0]);
54aa1f4d
CM
128fail:
129 btrfs_free_path(path);
54aa1f4d
CM
130 return err;
131}
132
39279cc3
CM
133static int dirty_and_release_pages(struct btrfs_trans_handle *trans,
134 struct btrfs_root *root,
135 struct file *file,
136 struct page **pages,
137 size_t num_pages,
138 loff_t pos,
139 size_t write_bytes)
140{
39279cc3 141 int err = 0;
a52d9a80 142 int i;
39279cc3 143 struct inode *inode = file->f_path.dentry->d_inode;
a52d9a80
CM
144 struct extent_map *em;
145 struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
a52d9a80
CM
146 u64 hint_block;
147 u64 num_blocks;
148 u64 start_pos;
149 u64 end_of_last_block;
150 u64 end_pos = pos + write_bytes;
151 loff_t isize = i_size_read(inode);
39279cc3 152
a52d9a80
CM
153 em = alloc_extent_map(GFP_NOFS);
154 if (!em)
155 return -ENOMEM;
39279cc3 156
a52d9a80 157 em->bdev = inode->i_sb->s_bdev;
39279cc3 158
a52d9a80
CM
159 start_pos = pos & ~((u64)root->blocksize - 1);
160 num_blocks = (write_bytes + pos - start_pos + root->blocksize - 1) >>
161 inode->i_blkbits;
39279cc3 162
011410bd 163 down_read(&BTRFS_I(inode)->root->snap_sem);
a52d9a80 164 end_of_last_block = start_pos + (num_blocks << inode->i_blkbits) - 1;
b888db2b 165 lock_extent(em_tree, start_pos, end_of_last_block, GFP_NOFS);
a52d9a80
CM
166 mutex_lock(&root->fs_info->fs_mutex);
167 trans = btrfs_start_transaction(root, 1);
168 if (!trans) {
169 err = -ENOMEM;
170 goto out_unlock;
171 }
172 btrfs_set_trans_block_group(trans, inode);
173 inode->i_blocks += num_blocks << 3;
174 hint_block = 0;
175
176 if ((end_of_last_block & 4095) == 0) {
9433063b 177 printk("strange end of last %Lu %zu %Lu\n", start_pos, write_bytes, end_of_last_block);
a52d9a80
CM
178 }
179 set_extent_uptodate(em_tree, start_pos, end_of_last_block, GFP_NOFS);
180
181 /* FIXME...EIEIO, ENOSPC and more */
182
a52d9a80
CM
183 /* insert any holes we need to create */
184 if (inode->i_size < start_pos) {
185 u64 last_pos_in_file;
186 u64 hole_size;
187 u64 mask = root->blocksize - 1;
188 last_pos_in_file = (isize + mask) & ~mask;
189 hole_size = (start_pos - last_pos_in_file + mask) & ~mask;
2bf5a725 190
a52d9a80 191 if (last_pos_in_file < start_pos) {
2bf5a725
CM
192 err = btrfs_drop_extents(trans, root, inode,
193 last_pos_in_file,
194 last_pos_in_file + hole_size,
195 &hint_block);
196 if (err)
197 goto failed;
198
199 hole_size >>= inode->i_blkbits;
a52d9a80
CM
200 err = btrfs_insert_file_extent(trans, root,
201 inode->i_ino,
202 last_pos_in_file,
203 0, 0, hole_size);
204 }
205 if (err)
39279cc3 206 goto failed;
a52d9a80
CM
207 }
208
209 /*
210 * either allocate an extent for the new bytes or setup the key
211 * to show we are doing inline data in the extent
212 */
213 if (isize >= PAGE_CACHE_SIZE || pos + write_bytes < inode->i_size ||
214 pos + write_bytes - start_pos > BTRFS_MAX_INLINE_DATA_SIZE(root)) {
b888db2b 215 u64 last_end;
a52d9a80
CM
216 for (i = 0; i < num_pages; i++) {
217 struct page *p = pages[i];
218 SetPageUptodate(p);
b888db2b 219 set_page_dirty(p);
39279cc3 220 }
b888db2b
CM
221 last_end = pages[num_pages -1]->index << PAGE_CACHE_SHIFT;
222 last_end += PAGE_CACHE_SIZE - 1;
223 set_extent_delalloc(em_tree, start_pos, end_of_last_block,
224 GFP_NOFS);
a52d9a80
CM
225 } else {
226 struct page *p = pages[0];
b888db2b
CM
227 /* step one, delete the existing extents in this range */
228 /* FIXME blocksize != pagesize */
2bf5a725
CM
229 err = btrfs_drop_extents(trans, root, inode, start_pos,
230 (pos + write_bytes + root->blocksize -1) &
231 ~((u64)root->blocksize - 1), &hint_block);
232 if (err)
233 goto failed;
b888db2b 234
a52d9a80
CM
235 err = insert_inline_extent(trans, root, inode, start_pos,
236 end_pos - start_pos, p, 0);
237 BUG_ON(err);
238 em->start = start_pos;
6af858b2 239 em->end = end_pos - 1;
a52d9a80
CM
240 em->block_start = EXTENT_MAP_INLINE;
241 em->block_end = EXTENT_MAP_INLINE;
242 add_extent_mapping(em_tree, em);
243 }
244 if (end_pos > isize) {
245 i_size_write(inode, end_pos);
246 btrfs_update_inode(trans, root, inode);
39279cc3
CM
247 }
248failed:
a52d9a80
CM
249 err = btrfs_end_transaction(trans, root);
250out_unlock:
251 mutex_unlock(&root->fs_info->fs_mutex);
b888db2b 252 unlock_extent(em_tree, start_pos, end_of_last_block, GFP_NOFS);
a52d9a80 253 free_extent_map(em);
011410bd 254 up_read(&BTRFS_I(inode)->root->snap_sem);
39279cc3
CM
255 return err;
256}
257
a52d9a80
CM
258int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end)
259{
260 struct extent_map *em;
261 struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
262
263 while(1) {
264 em = lookup_extent_mapping(em_tree, start, end);
265 if (!em)
266 break;
267 remove_extent_mapping(em_tree, em);
268 /* once for us */
269 free_extent_map(em);
270 /* once for the tree*/
271 free_extent_map(em);
272 }
273 return 0;
274}
275
39279cc3
CM
276/*
277 * this is very complex, but the basic idea is to drop all extents
278 * in the range start - end. hint_block is filled in with a block number
279 * that would be a good hint to the block allocator for this file.
280 *
281 * If an extent intersects the range but is not entirely inside the range
282 * it is either truncated or split. Anything entirely inside the range
283 * is deleted from the tree.
284 */
285int btrfs_drop_extents(struct btrfs_trans_handle *trans,
286 struct btrfs_root *root, struct inode *inode,
287 u64 start, u64 end, u64 *hint_block)
288{
289 int ret;
290 struct btrfs_key key;
291 struct btrfs_leaf *leaf;
292 int slot;
293 struct btrfs_file_extent_item *extent;
294 u64 extent_end = 0;
295 int keep;
296 struct btrfs_file_extent_item old;
297 struct btrfs_path *path;
298 u64 search_start = start;
299 int bookend;
300 int found_type;
301 int found_extent;
302 int found_inline;
ccd467d6 303 int recow;
39279cc3 304
a52d9a80
CM
305 btrfs_drop_extent_cache(inode, start, end - 1);
306
39279cc3
CM
307 path = btrfs_alloc_path();
308 if (!path)
309 return -ENOMEM;
310 while(1) {
ccd467d6 311 recow = 0;
39279cc3
CM
312 btrfs_release_path(root, path);
313 ret = btrfs_lookup_file_extent(trans, root, path, inode->i_ino,
314 search_start, -1);
315 if (ret < 0)
316 goto out;
317 if (ret > 0) {
318 if (path->slots[0] == 0) {
319 ret = 0;
320 goto out;
321 }
322 path->slots[0]--;
323 }
8c2383c3 324next_slot:
39279cc3
CM
325 keep = 0;
326 bookend = 0;
327 found_extent = 0;
328 found_inline = 0;
329 extent = NULL;
330 leaf = btrfs_buffer_leaf(path->nodes[0]);
331 slot = path->slots[0];
8c2383c3 332 ret = 0;
39279cc3
CM
333 btrfs_disk_key_to_cpu(&key, &leaf->items[slot].key);
334 if (key.offset >= end || key.objectid != inode->i_ino) {
39279cc3
CM
335 goto out;
336 }
8c2383c3 337 if (btrfs_key_type(&key) > BTRFS_EXTENT_DATA_KEY) {
39279cc3
CM
338 goto out;
339 }
ccd467d6
CM
340 if (recow) {
341 search_start = key.offset;
342 continue;
343 }
8c2383c3
CM
344 if (btrfs_key_type(&key) == BTRFS_EXTENT_DATA_KEY) {
345 extent = btrfs_item_ptr(leaf, slot,
346 struct btrfs_file_extent_item);
347 found_type = btrfs_file_extent_type(extent);
348 if (found_type == BTRFS_FILE_EXTENT_REG) {
349 extent_end = key.offset +
350 (btrfs_file_extent_num_blocks(extent) <<
351 inode->i_blkbits);
352 found_extent = 1;
353 } else if (found_type == BTRFS_FILE_EXTENT_INLINE) {
354 found_inline = 1;
355 extent_end = key.offset +
356 btrfs_file_extent_inline_len(leaf->items +
357 slot);
358 }
359 } else {
360 extent_end = search_start;
39279cc3
CM
361 }
362
363 /* we found nothing we can drop */
8c2383c3
CM
364 if ((!found_extent && !found_inline) ||
365 search_start >= extent_end) {
366 int nextret;
367 u32 nritems;
368 nritems = btrfs_header_nritems(
369 btrfs_buffer_header(path->nodes[0]));
370 if (slot >= nritems - 1) {
371 nextret = btrfs_next_leaf(root, path);
372 if (nextret)
373 goto out;
ccd467d6 374 recow = 1;
8c2383c3
CM
375 } else {
376 path->slots[0]++;
377 }
378 goto next_slot;
39279cc3
CM
379 }
380
381 /* FIXME, there's only one inline extent allowed right now */
382 if (found_inline) {
383 u64 mask = root->blocksize - 1;
384 search_start = (extent_end + mask) & ~mask;
385 } else
386 search_start = extent_end;
387
388 if (end < extent_end && end >= key.offset) {
389 if (found_extent) {
390 u64 disk_blocknr =
391 btrfs_file_extent_disk_blocknr(extent);
392 u64 disk_num_blocks =
393 btrfs_file_extent_disk_num_blocks(extent);
394 memcpy(&old, extent, sizeof(old));
395 if (disk_blocknr != 0) {
396 ret = btrfs_inc_extent_ref(trans, root,
397 disk_blocknr, disk_num_blocks);
398 BUG_ON(ret);
399 }
400 }
401 WARN_ON(found_inline);
402 bookend = 1;
403 }
39279cc3
CM
404 /* truncate existing extent */
405 if (start > key.offset) {
406 u64 new_num;
407 u64 old_num;
408 keep = 1;
409 WARN_ON(start & (root->blocksize - 1));
410 if (found_extent) {
411 new_num = (start - key.offset) >>
412 inode->i_blkbits;
413 old_num = btrfs_file_extent_num_blocks(extent);
414 *hint_block =
415 btrfs_file_extent_disk_blocknr(extent);
416 if (btrfs_file_extent_disk_blocknr(extent)) {
417 inode->i_blocks -=
418 (old_num - new_num) << 3;
419 }
420 btrfs_set_file_extent_num_blocks(extent,
421 new_num);
ccd467d6 422 btrfs_mark_buffer_dirty(path->nodes[0]);
39279cc3
CM
423 } else {
424 WARN_ON(1);
425 }
426 }
427 /* delete the entire extent */
428 if (!keep) {
429 u64 disk_blocknr = 0;
430 u64 disk_num_blocks = 0;
431 u64 extent_num_blocks = 0;
432 if (found_extent) {
433 disk_blocknr =
434 btrfs_file_extent_disk_blocknr(extent);
435 disk_num_blocks =
436 btrfs_file_extent_disk_num_blocks(extent);
437 extent_num_blocks =
438 btrfs_file_extent_num_blocks(extent);
439 *hint_block =
440 btrfs_file_extent_disk_blocknr(extent);
441 }
442 ret = btrfs_del_item(trans, root, path);
54aa1f4d 443 /* TODO update progress marker and return */
39279cc3
CM
444 BUG_ON(ret);
445 btrfs_release_path(root, path);
446 extent = NULL;
447 if (found_extent && disk_blocknr != 0) {
448 inode->i_blocks -= extent_num_blocks << 3;
449 ret = btrfs_free_extent(trans, root,
450 disk_blocknr,
451 disk_num_blocks, 0);
452 }
453
454 BUG_ON(ret);
455 if (!bookend && search_start >= end) {
456 ret = 0;
457 goto out;
458 }
459 if (!bookend)
460 continue;
461 }
462 /* create bookend, splitting the extent in two */
463 if (bookend && found_extent) {
464 struct btrfs_key ins;
465 ins.objectid = inode->i_ino;
466 ins.offset = end;
467 ins.flags = 0;
468 btrfs_set_key_type(&ins, BTRFS_EXTENT_DATA_KEY);
39279cc3
CM
469 btrfs_release_path(root, path);
470 ret = btrfs_insert_empty_item(trans, root, path, &ins,
471 sizeof(*extent));
8c2383c3
CM
472
473 if (ret) {
474 btrfs_print_leaf(root, btrfs_buffer_leaf(path->nodes[0]));
2bf5a725 475 printk("got %d on inserting %Lu %u %Lu start %Lu end %Lu found %Lu %Lu keep was %d\n", ret , ins.objectid, ins.flags, ins.offset, start, end, key.offset, extent_end, keep);
8c2383c3 476 }
39279cc3
CM
477 BUG_ON(ret);
478 extent = btrfs_item_ptr(
479 btrfs_buffer_leaf(path->nodes[0]),
480 path->slots[0],
481 struct btrfs_file_extent_item);
482 btrfs_set_file_extent_disk_blocknr(extent,
483 btrfs_file_extent_disk_blocknr(&old));
484 btrfs_set_file_extent_disk_num_blocks(extent,
485 btrfs_file_extent_disk_num_blocks(&old));
486
487 btrfs_set_file_extent_offset(extent,
488 btrfs_file_extent_offset(&old) +
489 ((end - key.offset) >> inode->i_blkbits));
490 WARN_ON(btrfs_file_extent_num_blocks(&old) <
491 (extent_end - end) >> inode->i_blkbits);
492 btrfs_set_file_extent_num_blocks(extent,
493 (extent_end - end) >> inode->i_blkbits);
494
495 btrfs_set_file_extent_type(extent,
496 BTRFS_FILE_EXTENT_REG);
497 btrfs_set_file_extent_generation(extent,
498 btrfs_file_extent_generation(&old));
499 btrfs_mark_buffer_dirty(path->nodes[0]);
500 if (btrfs_file_extent_disk_blocknr(&old) != 0) {
501 inode->i_blocks +=
502 btrfs_file_extent_num_blocks(extent) << 3;
503 }
504 ret = 0;
505 goto out;
506 }
507 }
508out:
509 btrfs_free_path(path);
510 return ret;
511}
512
513/*
514 * this gets pages into the page cache and locks them down
515 */
516static int prepare_pages(struct btrfs_root *root,
517 struct file *file,
518 struct page **pages,
519 size_t num_pages,
520 loff_t pos,
521 unsigned long first_index,
522 unsigned long last_index,
8c2383c3 523 size_t write_bytes)
39279cc3
CM
524{
525 int i;
526 unsigned long index = pos >> PAGE_CACHE_SHIFT;
527 struct inode *inode = file->f_path.dentry->d_inode;
39279cc3 528 int err = 0;
8c2383c3 529 u64 num_blocks;
8c2383c3 530 u64 start_pos;
8c2383c3 531
b888db2b 532 start_pos = pos & ~((u64)root->blocksize - 1);
8c2383c3
CM
533 num_blocks = (write_bytes + pos - start_pos + root->blocksize - 1) >>
534 inode->i_blkbits;
39279cc3
CM
535
536 memset(pages, 0, num_pages * sizeof(struct page *));
537
538 for (i = 0; i < num_pages; i++) {
539 pages[i] = grab_cache_page(inode->i_mapping, index + i);
540 if (!pages[i]) {
541 err = -ENOMEM;
a52d9a80 542 BUG_ON(1);
39279cc3 543 }
ccd467d6
CM
544 cancel_dirty_page(pages[i], PAGE_CACHE_SIZE);
545 wait_on_page_writeback(pages[i]);
b3cfa35a 546 set_page_extent_mapped(pages[i]);
b888db2b 547 WARN_ON(!PageLocked(pages[i]));
39279cc3
CM
548 }
549 return 0;
39279cc3
CM
550}
551
552static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
553 size_t count, loff_t *ppos)
554{
555 loff_t pos;
556 size_t num_written = 0;
557 int err = 0;
558 int ret = 0;
559 struct inode *inode = file->f_path.dentry->d_inode;
560 struct btrfs_root *root = BTRFS_I(inode)->root;
8c2383c3
CM
561 struct page **pages = NULL;
562 int nrptrs;
39279cc3
CM
563 struct page *pinned[2];
564 unsigned long first_index;
565 unsigned long last_index;
8c2383c3
CM
566
567 nrptrs = min((count + PAGE_CACHE_SIZE - 1) / PAGE_CACHE_SIZE,
568 PAGE_CACHE_SIZE / (sizeof(struct page *)));
39279cc3
CM
569 pinned[0] = NULL;
570 pinned[1] = NULL;
571 if (file->f_flags & O_DIRECT)
572 return -EINVAL;
573 pos = *ppos;
574 vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
575 current->backing_dev_info = inode->i_mapping->backing_dev_info;
576 err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode));
577 if (err)
578 goto out;
579 if (count == 0)
580 goto out;
581 err = remove_suid(file->f_path.dentry);
582 if (err)
583 goto out;
584 file_update_time(file);
585
8c2383c3 586 pages = kmalloc(nrptrs * sizeof(struct page *), GFP_KERNEL);
39279cc3
CM
587
588 mutex_lock(&inode->i_mutex);
589 first_index = pos >> PAGE_CACHE_SHIFT;
590 last_index = (pos + count) >> PAGE_CACHE_SHIFT;
591
592 /*
593 * there are lots of better ways to do this, but this code
594 * makes sure the first and last page in the file range are
595 * up to date and ready for cow
596 */
597 if ((pos & (PAGE_CACHE_SIZE - 1))) {
598 pinned[0] = grab_cache_page(inode->i_mapping, first_index);
599 if (!PageUptodate(pinned[0])) {
9ebefb18 600 ret = btrfs_readpage(NULL, pinned[0]);
39279cc3
CM
601 BUG_ON(ret);
602 wait_on_page_locked(pinned[0]);
603 } else {
604 unlock_page(pinned[0]);
605 }
606 }
607 if ((pos + count) & (PAGE_CACHE_SIZE - 1)) {
608 pinned[1] = grab_cache_page(inode->i_mapping, last_index);
609 if (!PageUptodate(pinned[1])) {
9ebefb18 610 ret = btrfs_readpage(NULL, pinned[1]);
39279cc3
CM
611 BUG_ON(ret);
612 wait_on_page_locked(pinned[1]);
613 } else {
614 unlock_page(pinned[1]);
615 }
616 }
617
39279cc3
CM
618 while(count > 0) {
619 size_t offset = pos & (PAGE_CACHE_SIZE - 1);
11bd143f
CM
620 size_t write_bytes = min(count, nrptrs *
621 (size_t)PAGE_CACHE_SIZE -
8c2383c3 622 offset);
39279cc3
CM
623 size_t num_pages = (write_bytes + PAGE_CACHE_SIZE - 1) >>
624 PAGE_CACHE_SHIFT;
625
8c2383c3 626 WARN_ON(num_pages > nrptrs);
39279cc3
CM
627 memset(pages, 0, sizeof(pages));
628 ret = prepare_pages(root, file, pages, num_pages,
629 pos, first_index, last_index,
8c2383c3 630 write_bytes);
54aa1f4d
CM
631 if (ret)
632 goto out;
39279cc3 633
39279cc3
CM
634 ret = btrfs_copy_from_user(pos, num_pages,
635 write_bytes, pages, buf);
54aa1f4d
CM
636 if (ret) {
637 btrfs_drop_pages(pages, num_pages);
638 goto out;
639 }
39279cc3
CM
640
641 ret = dirty_and_release_pages(NULL, root, file, pages,
642 num_pages, pos, write_bytes);
39279cc3 643 btrfs_drop_pages(pages, num_pages);
54aa1f4d
CM
644 if (ret)
645 goto out;
39279cc3
CM
646
647 buf += write_bytes;
648 count -= write_bytes;
649 pos += write_bytes;
650 num_written += write_bytes;
651
8c2383c3 652 balance_dirty_pages_ratelimited_nr(inode->i_mapping, num_pages);
d3c2fdcf 653 btrfs_btree_balance_dirty(root, 1);
39279cc3
CM
654 cond_resched();
655 }
39279cc3
CM
656 mutex_unlock(&inode->i_mutex);
657out:
8c2383c3 658 kfree(pages);
39279cc3
CM
659 if (pinned[0])
660 page_cache_release(pinned[0]);
661 if (pinned[1])
662 page_cache_release(pinned[1]);
663 *ppos = pos;
664 current->backing_dev_info = NULL;
39279cc3
CM
665 return num_written ? num_written : err;
666}
667
39279cc3
CM
668static int btrfs_sync_file(struct file *file,
669 struct dentry *dentry, int datasync)
670{
671 struct inode *inode = dentry->d_inode;
672 struct btrfs_root *root = BTRFS_I(inode)->root;
15ee9bc7 673 int ret = 0;
39279cc3
CM
674 struct btrfs_trans_handle *trans;
675
676 /*
15ee9bc7
JB
677 * check the transaction that last modified this inode
678 * and see if its already been committed
39279cc3
CM
679 */
680 mutex_lock(&root->fs_info->fs_mutex);
15ee9bc7
JB
681 if (!BTRFS_I(inode)->last_trans)
682 goto out;
683 mutex_lock(&root->fs_info->trans_mutex);
684 if (BTRFS_I(inode)->last_trans <=
685 root->fs_info->last_trans_committed) {
686 BTRFS_I(inode)->last_trans = 0;
687 mutex_unlock(&root->fs_info->trans_mutex);
688 goto out;
689 }
690 mutex_unlock(&root->fs_info->trans_mutex);
691
692 /*
a52d9a80
CM
693 * ok we haven't committed the transaction yet, lets do a commit
694 */
39279cc3
CM
695 trans = btrfs_start_transaction(root, 1);
696 if (!trans) {
697 ret = -ENOMEM;
698 goto out;
699 }
700 ret = btrfs_commit_transaction(trans, root);
39279cc3 701out:
15ee9bc7 702 mutex_unlock(&root->fs_info->fs_mutex);
39279cc3
CM
703 return ret > 0 ? EIO : ret;
704}
705
9ebefb18 706static struct vm_operations_struct btrfs_file_vm_ops = {
92fee66d
CM
707#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
708 .nopage = filemap_nopage,
709 .populate = filemap_populate,
710#else
711 .fault = filemap_fault,
712#endif
9ebefb18
CM
713 .page_mkwrite = btrfs_page_mkwrite,
714};
715
716static int btrfs_file_mmap(struct file *filp, struct vm_area_struct *vma)
717{
718 vma->vm_ops = &btrfs_file_vm_ops;
719 file_accessed(filp);
720 return 0;
721}
722
39279cc3
CM
723struct file_operations btrfs_file_operations = {
724 .llseek = generic_file_llseek,
725 .read = do_sync_read,
9ebefb18 726 .aio_read = generic_file_aio_read,
39279cc3 727 .write = btrfs_file_write,
9ebefb18 728 .mmap = btrfs_file_mmap,
39279cc3 729 .open = generic_file_open,
39279cc3 730 .fsync = btrfs_sync_file,
34287aa3 731 .unlocked_ioctl = btrfs_ioctl,
39279cc3 732#ifdef CONFIG_COMPAT
34287aa3 733 .compat_ioctl = btrfs_ioctl,
39279cc3
CM
734#endif
735};
736