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