diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2010-02-22 07:48:51 -0500 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2010-02-22 07:48:51 -0500 |
commit | f11cbd74c5ff3614f6390b4de67a6ffdc614c378 (patch) | |
tree | 6a30920ade9eeaac5bf6d6263b5d09712e882eb0 /fs/btrfs | |
parent | 429c42c9d246f5bda868495c09974312a0177328 (diff) | |
parent | aea187c46f7d03ce985e55eb1398d0776a15b928 (diff) |
Merge branch 'master' into for-2.6.34
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/acl.c | 13 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 1 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 13 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 40 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 3 | ||||
-rw-r--r-- | fs/btrfs/extent_map.c | 14 | ||||
-rw-r--r-- | fs/btrfs/file.c | 104 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 72 | ||||
-rw-r--r-- | fs/btrfs/ordered-data.c | 2 | ||||
-rw-r--r-- | fs/btrfs/relocation.c | 7 | ||||
-rw-r--r-- | fs/btrfs/super.c | 9 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 17 |
12 files changed, 176 insertions, 119 deletions
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index 2e9e69987a82..6df6d6ed74fd 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c | |||
@@ -112,12 +112,14 @@ static int btrfs_set_acl(struct btrfs_trans_handle *trans, | |||
112 | switch (type) { | 112 | switch (type) { |
113 | case ACL_TYPE_ACCESS: | 113 | case ACL_TYPE_ACCESS: |
114 | mode = inode->i_mode; | 114 | mode = inode->i_mode; |
115 | ret = posix_acl_equiv_mode(acl, &mode); | ||
116 | if (ret < 0) | ||
117 | return ret; | ||
118 | ret = 0; | ||
119 | inode->i_mode = mode; | ||
120 | name = POSIX_ACL_XATTR_ACCESS; | 115 | name = POSIX_ACL_XATTR_ACCESS; |
116 | if (acl) { | ||
117 | ret = posix_acl_equiv_mode(acl, &mode); | ||
118 | if (ret < 0) | ||
119 | return ret; | ||
120 | inode->i_mode = mode; | ||
121 | } | ||
122 | ret = 0; | ||
121 | break; | 123 | break; |
122 | case ACL_TYPE_DEFAULT: | 124 | case ACL_TYPE_DEFAULT: |
123 | if (!S_ISDIR(inode->i_mode)) | 125 | if (!S_ISDIR(inode->i_mode)) |
@@ -242,6 +244,7 @@ int btrfs_init_acl(struct btrfs_trans_handle *trans, | |||
242 | ACL_TYPE_ACCESS); | 244 | ACL_TYPE_ACCESS); |
243 | } | 245 | } |
244 | } | 246 | } |
247 | posix_acl_release(clone); | ||
245 | } | 248 | } |
246 | failed: | 249 | failed: |
247 | posix_acl_release(acl); | 250 | posix_acl_release(acl); |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 9f806dd04c27..2aa8ec6a0981 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -1161,6 +1161,7 @@ struct btrfs_root { | |||
1161 | #define BTRFS_MOUNT_SSD_SPREAD (1 << 8) | 1161 | #define BTRFS_MOUNT_SSD_SPREAD (1 << 8) |
1162 | #define BTRFS_MOUNT_NOSSD (1 << 9) | 1162 | #define BTRFS_MOUNT_NOSSD (1 << 9) |
1163 | #define BTRFS_MOUNT_DISCARD (1 << 10) | 1163 | #define BTRFS_MOUNT_DISCARD (1 << 10) |
1164 | #define BTRFS_MOUNT_FORCE_COMPRESS (1 << 11) | ||
1164 | 1165 | ||
1165 | #define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt) | 1166 | #define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt) |
1166 | #define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt) | 1167 | #define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt) |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 009e3bd18f23..2b59201b955c 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -1982,7 +1982,12 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1982 | 1982 | ||
1983 | if (!(sb->s_flags & MS_RDONLY)) { | 1983 | if (!(sb->s_flags & MS_RDONLY)) { |
1984 | ret = btrfs_recover_relocation(tree_root); | 1984 | ret = btrfs_recover_relocation(tree_root); |
1985 | BUG_ON(ret); | 1985 | if (ret < 0) { |
1986 | printk(KERN_WARNING | ||
1987 | "btrfs: failed to recover relocation\n"); | ||
1988 | err = -EINVAL; | ||
1989 | goto fail_trans_kthread; | ||
1990 | } | ||
1986 | } | 1991 | } |
1987 | 1992 | ||
1988 | location.objectid = BTRFS_FS_TREE_OBJECTID; | 1993 | location.objectid = BTRFS_FS_TREE_OBJECTID; |
@@ -1993,6 +1998,12 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1993 | if (!fs_info->fs_root) | 1998 | if (!fs_info->fs_root) |
1994 | goto fail_trans_kthread; | 1999 | goto fail_trans_kthread; |
1995 | 2000 | ||
2001 | if (!(sb->s_flags & MS_RDONLY)) { | ||
2002 | down_read(&fs_info->cleanup_work_sem); | ||
2003 | btrfs_orphan_cleanup(fs_info->fs_root); | ||
2004 | up_read(&fs_info->cleanup_work_sem); | ||
2005 | } | ||
2006 | |||
1996 | return tree_root; | 2007 | return tree_root; |
1997 | 2008 | ||
1998 | fail_trans_kthread: | 2009 | fail_trans_kthread: |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 56e50137d0e6..559f72489b3b 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -83,6 +83,17 @@ static int block_group_bits(struct btrfs_block_group_cache *cache, u64 bits) | |||
83 | return (cache->flags & bits) == bits; | 83 | return (cache->flags & bits) == bits; |
84 | } | 84 | } |
85 | 85 | ||
86 | void btrfs_get_block_group(struct btrfs_block_group_cache *cache) | ||
87 | { | ||
88 | atomic_inc(&cache->count); | ||
89 | } | ||
90 | |||
91 | void btrfs_put_block_group(struct btrfs_block_group_cache *cache) | ||
92 | { | ||
93 | if (atomic_dec_and_test(&cache->count)) | ||
94 | kfree(cache); | ||
95 | } | ||
96 | |||
86 | /* | 97 | /* |
87 | * this adds the block group to the fs_info rb tree for the block group | 98 | * this adds the block group to the fs_info rb tree for the block group |
88 | * cache | 99 | * cache |
@@ -156,7 +167,7 @@ block_group_cache_tree_search(struct btrfs_fs_info *info, u64 bytenr, | |||
156 | } | 167 | } |
157 | } | 168 | } |
158 | if (ret) | 169 | if (ret) |
159 | atomic_inc(&ret->count); | 170 | btrfs_get_block_group(ret); |
160 | spin_unlock(&info->block_group_cache_lock); | 171 | spin_unlock(&info->block_group_cache_lock); |
161 | 172 | ||
162 | return ret; | 173 | return ret; |
@@ -407,6 +418,8 @@ err: | |||
407 | 418 | ||
408 | put_caching_control(caching_ctl); | 419 | put_caching_control(caching_ctl); |
409 | atomic_dec(&block_group->space_info->caching_threads); | 420 | atomic_dec(&block_group->space_info->caching_threads); |
421 | btrfs_put_block_group(block_group); | ||
422 | |||
410 | return 0; | 423 | return 0; |
411 | } | 424 | } |
412 | 425 | ||
@@ -447,6 +460,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache) | |||
447 | up_write(&fs_info->extent_commit_sem); | 460 | up_write(&fs_info->extent_commit_sem); |
448 | 461 | ||
449 | atomic_inc(&cache->space_info->caching_threads); | 462 | atomic_inc(&cache->space_info->caching_threads); |
463 | btrfs_get_block_group(cache); | ||
450 | 464 | ||
451 | tsk = kthread_run(caching_kthread, cache, "btrfs-cache-%llu\n", | 465 | tsk = kthread_run(caching_kthread, cache, "btrfs-cache-%llu\n", |
452 | cache->key.objectid); | 466 | cache->key.objectid); |
@@ -486,12 +500,6 @@ struct btrfs_block_group_cache *btrfs_lookup_block_group( | |||
486 | return cache; | 500 | return cache; |
487 | } | 501 | } |
488 | 502 | ||
489 | void btrfs_put_block_group(struct btrfs_block_group_cache *cache) | ||
490 | { | ||
491 | if (atomic_dec_and_test(&cache->count)) | ||
492 | kfree(cache); | ||
493 | } | ||
494 | |||
495 | static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info, | 503 | static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info, |
496 | u64 flags) | 504 | u64 flags) |
497 | { | 505 | { |
@@ -2582,7 +2590,7 @@ next_block_group(struct btrfs_root *root, | |||
2582 | if (node) { | 2590 | if (node) { |
2583 | cache = rb_entry(node, struct btrfs_block_group_cache, | 2591 | cache = rb_entry(node, struct btrfs_block_group_cache, |
2584 | cache_node); | 2592 | cache_node); |
2585 | atomic_inc(&cache->count); | 2593 | btrfs_get_block_group(cache); |
2586 | } else | 2594 | } else |
2587 | cache = NULL; | 2595 | cache = NULL; |
2588 | spin_unlock(&root->fs_info->block_group_cache_lock); | 2596 | spin_unlock(&root->fs_info->block_group_cache_lock); |
@@ -4227,7 +4235,7 @@ search: | |||
4227 | u64 offset; | 4235 | u64 offset; |
4228 | int cached; | 4236 | int cached; |
4229 | 4237 | ||
4230 | atomic_inc(&block_group->count); | 4238 | btrfs_get_block_group(block_group); |
4231 | search_start = block_group->key.objectid; | 4239 | search_start = block_group->key.objectid; |
4232 | 4240 | ||
4233 | have_block_group: | 4241 | have_block_group: |
@@ -4315,7 +4323,7 @@ have_block_group: | |||
4315 | 4323 | ||
4316 | btrfs_put_block_group(block_group); | 4324 | btrfs_put_block_group(block_group); |
4317 | block_group = last_ptr->block_group; | 4325 | block_group = last_ptr->block_group; |
4318 | atomic_inc(&block_group->count); | 4326 | btrfs_get_block_group(block_group); |
4319 | spin_unlock(&last_ptr->lock); | 4327 | spin_unlock(&last_ptr->lock); |
4320 | spin_unlock(&last_ptr->refill_lock); | 4328 | spin_unlock(&last_ptr->refill_lock); |
4321 | 4329 | ||
@@ -5394,10 +5402,6 @@ static noinline int walk_down_tree(struct btrfs_trans_handle *trans, | |||
5394 | int ret; | 5402 | int ret; |
5395 | 5403 | ||
5396 | while (level >= 0) { | 5404 | while (level >= 0) { |
5397 | if (path->slots[level] >= | ||
5398 | btrfs_header_nritems(path->nodes[level])) | ||
5399 | break; | ||
5400 | |||
5401 | ret = walk_down_proc(trans, root, path, wc, lookup_info); | 5405 | ret = walk_down_proc(trans, root, path, wc, lookup_info); |
5402 | if (ret > 0) | 5406 | if (ret > 0) |
5403 | break; | 5407 | break; |
@@ -5405,6 +5409,10 @@ static noinline int walk_down_tree(struct btrfs_trans_handle *trans, | |||
5405 | if (level == 0) | 5409 | if (level == 0) |
5406 | break; | 5410 | break; |
5407 | 5411 | ||
5412 | if (path->slots[level] >= | ||
5413 | btrfs_header_nritems(path->nodes[level])) | ||
5414 | break; | ||
5415 | |||
5408 | ret = do_walk_down(trans, root, path, wc, &lookup_info); | 5416 | ret = do_walk_down(trans, root, path, wc, &lookup_info); |
5409 | if (ret > 0) { | 5417 | if (ret > 0) { |
5410 | path->slots[level]++; | 5418 | path->slots[level]++; |
@@ -7395,9 +7403,7 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info) | |||
7395 | wait_block_group_cache_done(block_group); | 7403 | wait_block_group_cache_done(block_group); |
7396 | 7404 | ||
7397 | btrfs_remove_free_space_cache(block_group); | 7405 | btrfs_remove_free_space_cache(block_group); |
7398 | 7406 | btrfs_put_block_group(block_group); | |
7399 | WARN_ON(atomic_read(&block_group->count) != 1); | ||
7400 | kfree(block_group); | ||
7401 | 7407 | ||
7402 | spin_lock(&info->block_group_cache_lock); | 7408 | spin_lock(&info->block_group_cache_lock); |
7403 | } | 7409 | } |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 96577e8bf9fd..b177ed319612 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -3165,10 +3165,9 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, | |||
3165 | spin_unlock(&tree->buffer_lock); | 3165 | spin_unlock(&tree->buffer_lock); |
3166 | goto free_eb; | 3166 | goto free_eb; |
3167 | } | 3167 | } |
3168 | spin_unlock(&tree->buffer_lock); | ||
3169 | |||
3170 | /* add one reference for the tree */ | 3168 | /* add one reference for the tree */ |
3171 | atomic_inc(&eb->refs); | 3169 | atomic_inc(&eb->refs); |
3170 | spin_unlock(&tree->buffer_lock); | ||
3172 | return eb; | 3171 | return eb; |
3173 | 3172 | ||
3174 | free_eb: | 3173 | free_eb: |
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 46bea0f4dc7b..428fcac45f90 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c | |||
@@ -155,20 +155,6 @@ static struct rb_node *__tree_search(struct rb_root *root, u64 offset, | |||
155 | return NULL; | 155 | return NULL; |
156 | } | 156 | } |
157 | 157 | ||
158 | /* | ||
159 | * look for an offset in the tree, and if it can't be found, return | ||
160 | * the first offset we can find smaller than 'offset'. | ||
161 | */ | ||
162 | static inline struct rb_node *tree_search(struct rb_root *root, u64 offset) | ||
163 | { | ||
164 | struct rb_node *prev; | ||
165 | struct rb_node *ret; | ||
166 | ret = __tree_search(root, offset, &prev, NULL); | ||
167 | if (!ret) | ||
168 | return prev; | ||
169 | return ret; | ||
170 | } | ||
171 | |||
172 | /* check to see if two extent_map structs are adjacent and safe to merge */ | 158 | /* check to see if two extent_map structs are adjacent and safe to merge */ |
173 | static int mergable_maps(struct extent_map *prev, struct extent_map *next) | 159 | static int mergable_maps(struct extent_map *prev, struct extent_map *next) |
174 | { | 160 | { |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index feaa13b105d9..6ed434ac037f 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -506,7 +506,8 @@ next_slot: | |||
506 | } | 506 | } |
507 | 507 | ||
508 | static int extent_mergeable(struct extent_buffer *leaf, int slot, | 508 | static int extent_mergeable(struct extent_buffer *leaf, int slot, |
509 | u64 objectid, u64 bytenr, u64 *start, u64 *end) | 509 | u64 objectid, u64 bytenr, u64 orig_offset, |
510 | u64 *start, u64 *end) | ||
510 | { | 511 | { |
511 | struct btrfs_file_extent_item *fi; | 512 | struct btrfs_file_extent_item *fi; |
512 | struct btrfs_key key; | 513 | struct btrfs_key key; |
@@ -522,6 +523,7 @@ static int extent_mergeable(struct extent_buffer *leaf, int slot, | |||
522 | fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); | 523 | fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); |
523 | if (btrfs_file_extent_type(leaf, fi) != BTRFS_FILE_EXTENT_REG || | 524 | if (btrfs_file_extent_type(leaf, fi) != BTRFS_FILE_EXTENT_REG || |
524 | btrfs_file_extent_disk_bytenr(leaf, fi) != bytenr || | 525 | btrfs_file_extent_disk_bytenr(leaf, fi) != bytenr || |
526 | btrfs_file_extent_offset(leaf, fi) != key.offset - orig_offset || | ||
525 | btrfs_file_extent_compression(leaf, fi) || | 527 | btrfs_file_extent_compression(leaf, fi) || |
526 | btrfs_file_extent_encryption(leaf, fi) || | 528 | btrfs_file_extent_encryption(leaf, fi) || |
527 | btrfs_file_extent_other_encoding(leaf, fi)) | 529 | btrfs_file_extent_other_encoding(leaf, fi)) |
@@ -561,6 +563,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, | |||
561 | u64 split; | 563 | u64 split; |
562 | int del_nr = 0; | 564 | int del_nr = 0; |
563 | int del_slot = 0; | 565 | int del_slot = 0; |
566 | int recow; | ||
564 | int ret; | 567 | int ret; |
565 | 568 | ||
566 | btrfs_drop_extent_cache(inode, start, end - 1, 0); | 569 | btrfs_drop_extent_cache(inode, start, end - 1, 0); |
@@ -568,6 +571,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, | |||
568 | path = btrfs_alloc_path(); | 571 | path = btrfs_alloc_path(); |
569 | BUG_ON(!path); | 572 | BUG_ON(!path); |
570 | again: | 573 | again: |
574 | recow = 0; | ||
571 | split = start; | 575 | split = start; |
572 | key.objectid = inode->i_ino; | 576 | key.objectid = inode->i_ino; |
573 | key.type = BTRFS_EXTENT_DATA_KEY; | 577 | key.type = BTRFS_EXTENT_DATA_KEY; |
@@ -591,12 +595,60 @@ again: | |||
591 | bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); | 595 | bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); |
592 | num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi); | 596 | num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi); |
593 | orig_offset = key.offset - btrfs_file_extent_offset(leaf, fi); | 597 | orig_offset = key.offset - btrfs_file_extent_offset(leaf, fi); |
598 | memcpy(&new_key, &key, sizeof(new_key)); | ||
599 | |||
600 | if (start == key.offset && end < extent_end) { | ||
601 | other_start = 0; | ||
602 | other_end = start; | ||
603 | if (extent_mergeable(leaf, path->slots[0] - 1, | ||
604 | inode->i_ino, bytenr, orig_offset, | ||
605 | &other_start, &other_end)) { | ||
606 | new_key.offset = end; | ||
607 | btrfs_set_item_key_safe(trans, root, path, &new_key); | ||
608 | fi = btrfs_item_ptr(leaf, path->slots[0], | ||
609 | struct btrfs_file_extent_item); | ||
610 | btrfs_set_file_extent_num_bytes(leaf, fi, | ||
611 | extent_end - end); | ||
612 | btrfs_set_file_extent_offset(leaf, fi, | ||
613 | end - orig_offset); | ||
614 | fi = btrfs_item_ptr(leaf, path->slots[0] - 1, | ||
615 | struct btrfs_file_extent_item); | ||
616 | btrfs_set_file_extent_num_bytes(leaf, fi, | ||
617 | end - other_start); | ||
618 | btrfs_mark_buffer_dirty(leaf); | ||
619 | goto out; | ||
620 | } | ||
621 | } | ||
622 | |||
623 | if (start > key.offset && end == extent_end) { | ||
624 | other_start = end; | ||
625 | other_end = 0; | ||
626 | if (extent_mergeable(leaf, path->slots[0] + 1, | ||
627 | inode->i_ino, bytenr, orig_offset, | ||
628 | &other_start, &other_end)) { | ||
629 | fi = btrfs_item_ptr(leaf, path->slots[0], | ||
630 | struct btrfs_file_extent_item); | ||
631 | btrfs_set_file_extent_num_bytes(leaf, fi, | ||
632 | start - key.offset); | ||
633 | path->slots[0]++; | ||
634 | new_key.offset = start; | ||
635 | btrfs_set_item_key_safe(trans, root, path, &new_key); | ||
636 | |||
637 | fi = btrfs_item_ptr(leaf, path->slots[0], | ||
638 | struct btrfs_file_extent_item); | ||
639 | btrfs_set_file_extent_num_bytes(leaf, fi, | ||
640 | other_end - start); | ||
641 | btrfs_set_file_extent_offset(leaf, fi, | ||
642 | start - orig_offset); | ||
643 | btrfs_mark_buffer_dirty(leaf); | ||
644 | goto out; | ||
645 | } | ||
646 | } | ||
594 | 647 | ||
595 | while (start > key.offset || end < extent_end) { | 648 | while (start > key.offset || end < extent_end) { |
596 | if (key.offset == start) | 649 | if (key.offset == start) |
597 | split = end; | 650 | split = end; |
598 | 651 | ||
599 | memcpy(&new_key, &key, sizeof(new_key)); | ||
600 | new_key.offset = split; | 652 | new_key.offset = split; |
601 | ret = btrfs_duplicate_item(trans, root, path, &new_key); | 653 | ret = btrfs_duplicate_item(trans, root, path, &new_key); |
602 | if (ret == -EAGAIN) { | 654 | if (ret == -EAGAIN) { |
@@ -631,15 +683,18 @@ again: | |||
631 | path->slots[0]--; | 683 | path->slots[0]--; |
632 | extent_end = end; | 684 | extent_end = end; |
633 | } | 685 | } |
686 | recow = 1; | ||
634 | } | 687 | } |
635 | 688 | ||
636 | fi = btrfs_item_ptr(leaf, path->slots[0], | ||
637 | struct btrfs_file_extent_item); | ||
638 | |||
639 | other_start = end; | 689 | other_start = end; |
640 | other_end = 0; | 690 | other_end = 0; |
641 | if (extent_mergeable(leaf, path->slots[0] + 1, inode->i_ino, | 691 | if (extent_mergeable(leaf, path->slots[0] + 1, |
642 | bytenr, &other_start, &other_end)) { | 692 | inode->i_ino, bytenr, orig_offset, |
693 | &other_start, &other_end)) { | ||
694 | if (recow) { | ||
695 | btrfs_release_path(root, path); | ||
696 | goto again; | ||
697 | } | ||
643 | extent_end = other_end; | 698 | extent_end = other_end; |
644 | del_slot = path->slots[0] + 1; | 699 | del_slot = path->slots[0] + 1; |
645 | del_nr++; | 700 | del_nr++; |
@@ -650,8 +705,13 @@ again: | |||
650 | } | 705 | } |
651 | other_start = 0; | 706 | other_start = 0; |
652 | other_end = start; | 707 | other_end = start; |
653 | if (extent_mergeable(leaf, path->slots[0] - 1, inode->i_ino, | 708 | if (extent_mergeable(leaf, path->slots[0] - 1, |
654 | bytenr, &other_start, &other_end)) { | 709 | inode->i_ino, bytenr, orig_offset, |
710 | &other_start, &other_end)) { | ||
711 | if (recow) { | ||
712 | btrfs_release_path(root, path); | ||
713 | goto again; | ||
714 | } | ||
655 | key.offset = other_start; | 715 | key.offset = other_start; |
656 | del_slot = path->slots[0]; | 716 | del_slot = path->slots[0]; |
657 | del_nr++; | 717 | del_nr++; |
@@ -661,21 +721,23 @@ again: | |||
661 | BUG_ON(ret); | 721 | BUG_ON(ret); |
662 | } | 722 | } |
663 | if (del_nr == 0) { | 723 | if (del_nr == 0) { |
724 | fi = btrfs_item_ptr(leaf, path->slots[0], | ||
725 | struct btrfs_file_extent_item); | ||
664 | btrfs_set_file_extent_type(leaf, fi, | 726 | btrfs_set_file_extent_type(leaf, fi, |
665 | BTRFS_FILE_EXTENT_REG); | 727 | BTRFS_FILE_EXTENT_REG); |
666 | btrfs_mark_buffer_dirty(leaf); | 728 | btrfs_mark_buffer_dirty(leaf); |
667 | goto out; | 729 | } else { |
668 | } | 730 | fi = btrfs_item_ptr(leaf, del_slot - 1, |
669 | 731 | struct btrfs_file_extent_item); | |
670 | fi = btrfs_item_ptr(leaf, del_slot - 1, | 732 | btrfs_set_file_extent_type(leaf, fi, |
671 | struct btrfs_file_extent_item); | 733 | BTRFS_FILE_EXTENT_REG); |
672 | btrfs_set_file_extent_type(leaf, fi, BTRFS_FILE_EXTENT_REG); | 734 | btrfs_set_file_extent_num_bytes(leaf, fi, |
673 | btrfs_set_file_extent_num_bytes(leaf, fi, | 735 | extent_end - key.offset); |
674 | extent_end - key.offset); | 736 | btrfs_mark_buffer_dirty(leaf); |
675 | btrfs_mark_buffer_dirty(leaf); | ||
676 | 737 | ||
677 | ret = btrfs_del_items(trans, root, path, del_slot, del_nr); | 738 | ret = btrfs_del_items(trans, root, path, del_slot, del_nr); |
678 | BUG_ON(ret); | 739 | BUG_ON(ret); |
740 | } | ||
679 | out: | 741 | out: |
680 | btrfs_free_path(path); | 742 | btrfs_free_path(path); |
681 | return 0; | 743 | return 0; |
@@ -1073,7 +1135,7 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
1073 | } | 1135 | } |
1074 | mutex_lock(&dentry->d_inode->i_mutex); | 1136 | mutex_lock(&dentry->d_inode->i_mutex); |
1075 | out: | 1137 | out: |
1076 | return ret > 0 ? EIO : ret; | 1138 | return ret > 0 ? -EIO : ret; |
1077 | } | 1139 | } |
1078 | 1140 | ||
1079 | static const struct vm_operations_struct btrfs_file_vm_ops = { | 1141 | static const struct vm_operations_struct btrfs_file_vm_ops = { |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 5440bab23635..4deb280f8969 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -483,7 +483,8 @@ again: | |||
483 | nr_pages_ret = 0; | 483 | nr_pages_ret = 0; |
484 | 484 | ||
485 | /* flag the file so we don't compress in the future */ | 485 | /* flag the file so we don't compress in the future */ |
486 | BTRFS_I(inode)->flags |= BTRFS_INODE_NOCOMPRESS; | 486 | if (!btrfs_test_opt(root, FORCE_COMPRESS)) |
487 | BTRFS_I(inode)->flags |= BTRFS_INODE_NOCOMPRESS; | ||
487 | } | 488 | } |
488 | if (will_compress) { | 489 | if (will_compress) { |
489 | *num_added += 1; | 490 | *num_added += 1; |
@@ -1680,24 +1681,6 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, | |||
1680 | * before we start the transaction. It limits the amount of btree | 1681 | * before we start the transaction. It limits the amount of btree |
1681 | * reads required while inside the transaction. | 1682 | * reads required while inside the transaction. |
1682 | */ | 1683 | */ |
1683 | static noinline void reada_csum(struct btrfs_root *root, | ||
1684 | struct btrfs_path *path, | ||
1685 | struct btrfs_ordered_extent *ordered_extent) | ||
1686 | { | ||
1687 | struct btrfs_ordered_sum *sum; | ||
1688 | u64 bytenr; | ||
1689 | |||
1690 | sum = list_entry(ordered_extent->list.next, struct btrfs_ordered_sum, | ||
1691 | list); | ||
1692 | bytenr = sum->sums[0].bytenr; | ||
1693 | |||
1694 | /* | ||
1695 | * we don't care about the results, the point of this search is | ||
1696 | * just to get the btree leaves into ram | ||
1697 | */ | ||
1698 | btrfs_lookup_csum(NULL, root->fs_info->csum_root, path, bytenr, 0); | ||
1699 | } | ||
1700 | |||
1701 | /* as ordered data IO finishes, this gets called so we can finish | 1684 | /* as ordered data IO finishes, this gets called so we can finish |
1702 | * an ordered extent if the range of bytes in the file it covers are | 1685 | * an ordered extent if the range of bytes in the file it covers are |
1703 | * fully written. | 1686 | * fully written. |
@@ -1708,7 +1691,6 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
1708 | struct btrfs_trans_handle *trans; | 1691 | struct btrfs_trans_handle *trans; |
1709 | struct btrfs_ordered_extent *ordered_extent = NULL; | 1692 | struct btrfs_ordered_extent *ordered_extent = NULL; |
1710 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | 1693 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
1711 | struct btrfs_path *path; | ||
1712 | int compressed = 0; | 1694 | int compressed = 0; |
1713 | int ret; | 1695 | int ret; |
1714 | 1696 | ||
@@ -1716,32 +1698,9 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
1716 | if (!ret) | 1698 | if (!ret) |
1717 | return 0; | 1699 | return 0; |
1718 | 1700 | ||
1719 | /* | 1701 | ordered_extent = btrfs_lookup_ordered_extent(inode, start); |
1720 | * before we join the transaction, try to do some of our IO. | ||
1721 | * This will limit the amount of IO that we have to do with | ||
1722 | * the transaction running. We're unlikely to need to do any | ||
1723 | * IO if the file extents are new, the disk_i_size checks | ||
1724 | * covers the most common case. | ||
1725 | */ | ||
1726 | if (start < BTRFS_I(inode)->disk_i_size) { | ||
1727 | path = btrfs_alloc_path(); | ||
1728 | if (path) { | ||
1729 | ret = btrfs_lookup_file_extent(NULL, root, path, | ||
1730 | inode->i_ino, | ||
1731 | start, 0); | ||
1732 | ordered_extent = btrfs_lookup_ordered_extent(inode, | ||
1733 | start); | ||
1734 | if (!list_empty(&ordered_extent->list)) { | ||
1735 | btrfs_release_path(root, path); | ||
1736 | reada_csum(root, path, ordered_extent); | ||
1737 | } | ||
1738 | btrfs_free_path(path); | ||
1739 | } | ||
1740 | } | ||
1741 | |||
1742 | if (!ordered_extent) | ||
1743 | ordered_extent = btrfs_lookup_ordered_extent(inode, start); | ||
1744 | BUG_ON(!ordered_extent); | 1702 | BUG_ON(!ordered_extent); |
1703 | |||
1745 | if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) { | 1704 | if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) { |
1746 | BUG_ON(!list_empty(&ordered_extent->list)); | 1705 | BUG_ON(!list_empty(&ordered_extent->list)); |
1747 | ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent); | 1706 | ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent); |
@@ -3995,7 +3954,11 @@ skip: | |||
3995 | 3954 | ||
3996 | /* Reached end of directory/root. Bump pos past the last item. */ | 3955 | /* Reached end of directory/root. Bump pos past the last item. */ |
3997 | if (key_type == BTRFS_DIR_INDEX_KEY) | 3956 | if (key_type == BTRFS_DIR_INDEX_KEY) |
3998 | filp->f_pos = INT_LIMIT(off_t); | 3957 | /* |
3958 | * 32-bit glibc will use getdents64, but then strtol - | ||
3959 | * so the last number we can serve is this. | ||
3960 | */ | ||
3961 | filp->f_pos = 0x7fffffff; | ||
3999 | else | 3962 | else |
4000 | filp->f_pos++; | 3963 | filp->f_pos++; |
4001 | nopos: | 3964 | nopos: |
@@ -5789,7 +5752,7 @@ out_fail: | |||
5789 | } | 5752 | } |
5790 | 5753 | ||
5791 | static int prealloc_file_range(struct inode *inode, u64 start, u64 end, | 5754 | static int prealloc_file_range(struct inode *inode, u64 start, u64 end, |
5792 | u64 alloc_hint, int mode) | 5755 | u64 alloc_hint, int mode, loff_t actual_len) |
5793 | { | 5756 | { |
5794 | struct btrfs_trans_handle *trans; | 5757 | struct btrfs_trans_handle *trans; |
5795 | struct btrfs_root *root = BTRFS_I(inode)->root; | 5758 | struct btrfs_root *root = BTRFS_I(inode)->root; |
@@ -5798,6 +5761,7 @@ static int prealloc_file_range(struct inode *inode, u64 start, u64 end, | |||
5798 | u64 cur_offset = start; | 5761 | u64 cur_offset = start; |
5799 | u64 num_bytes = end - start; | 5762 | u64 num_bytes = end - start; |
5800 | int ret = 0; | 5763 | int ret = 0; |
5764 | u64 i_size; | ||
5801 | 5765 | ||
5802 | while (num_bytes > 0) { | 5766 | while (num_bytes > 0) { |
5803 | alloc_size = min(num_bytes, root->fs_info->max_extent); | 5767 | alloc_size = min(num_bytes, root->fs_info->max_extent); |
@@ -5835,9 +5799,15 @@ static int prealloc_file_range(struct inode *inode, u64 start, u64 end, | |||
5835 | inode->i_ctime = CURRENT_TIME; | 5799 | inode->i_ctime = CURRENT_TIME; |
5836 | BTRFS_I(inode)->flags |= BTRFS_INODE_PREALLOC; | 5800 | BTRFS_I(inode)->flags |= BTRFS_INODE_PREALLOC; |
5837 | if (!(mode & FALLOC_FL_KEEP_SIZE) && | 5801 | if (!(mode & FALLOC_FL_KEEP_SIZE) && |
5838 | cur_offset > inode->i_size) { | 5802 | (actual_len > inode->i_size) && |
5839 | i_size_write(inode, cur_offset); | 5803 | (cur_offset > inode->i_size)) { |
5840 | btrfs_ordered_update_i_size(inode, cur_offset, NULL); | 5804 | |
5805 | if (cur_offset > actual_len) | ||
5806 | i_size = actual_len; | ||
5807 | else | ||
5808 | i_size = cur_offset; | ||
5809 | i_size_write(inode, i_size); | ||
5810 | btrfs_ordered_update_i_size(inode, i_size, NULL); | ||
5841 | } | 5811 | } |
5842 | 5812 | ||
5843 | ret = btrfs_update_inode(trans, root, inode); | 5813 | ret = btrfs_update_inode(trans, root, inode); |
@@ -5930,7 +5900,7 @@ static long btrfs_fallocate(struct inode *inode, int mode, | |||
5930 | !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { | 5900 | !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { |
5931 | ret = prealloc_file_range(inode, | 5901 | ret = prealloc_file_range(inode, |
5932 | cur_offset, last_byte, | 5902 | cur_offset, last_byte, |
5933 | alloc_hint, mode); | 5903 | alloc_hint, mode, offset+len); |
5934 | if (ret < 0) { | 5904 | if (ret < 0) { |
5935 | free_extent_map(em); | 5905 | free_extent_map(em); |
5936 | break; | 5906 | break; |
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index b10a49d4bc6a..5c2a9e78a949 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c | |||
@@ -626,6 +626,8 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, | |||
626 | 626 | ||
627 | if (ordered) | 627 | if (ordered) |
628 | offset = entry_end(ordered); | 628 | offset = entry_end(ordered); |
629 | else | ||
630 | offset = ALIGN(offset, BTRFS_I(inode)->root->sectorsize); | ||
629 | 631 | ||
630 | mutex_lock(&tree->mutex); | 632 | mutex_lock(&tree->mutex); |
631 | disk_i_size = BTRFS_I(inode)->disk_i_size; | 633 | disk_i_size = BTRFS_I(inode)->disk_i_size; |
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index a9728680eca8..ab7ab5318745 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
@@ -3281,8 +3281,10 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc) | |||
3281 | return -ENOMEM; | 3281 | return -ENOMEM; |
3282 | 3282 | ||
3283 | path = btrfs_alloc_path(); | 3283 | path = btrfs_alloc_path(); |
3284 | if (!path) | 3284 | if (!path) { |
3285 | kfree(cluster); | ||
3285 | return -ENOMEM; | 3286 | return -ENOMEM; |
3287 | } | ||
3286 | 3288 | ||
3287 | rc->extents_found = 0; | 3289 | rc->extents_found = 0; |
3288 | rc->extents_skipped = 0; | 3290 | rc->extents_skipped = 0; |
@@ -3762,7 +3764,8 @@ out: | |||
3762 | BTRFS_DATA_RELOC_TREE_OBJECTID); | 3764 | BTRFS_DATA_RELOC_TREE_OBJECTID); |
3763 | if (IS_ERR(fs_root)) | 3765 | if (IS_ERR(fs_root)) |
3764 | err = PTR_ERR(fs_root); | 3766 | err = PTR_ERR(fs_root); |
3765 | btrfs_orphan_cleanup(fs_root); | 3767 | else |
3768 | btrfs_orphan_cleanup(fs_root); | ||
3766 | } | 3769 | } |
3767 | return err; | 3770 | return err; |
3768 | } | 3771 | } |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 3f9b45704fcd..8a1ea6e64575 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -66,7 +66,8 @@ enum { | |||
66 | Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow, | 66 | Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow, |
67 | Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, | 67 | Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, |
68 | Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, | 68 | Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, |
69 | Opt_compress, Opt_notreelog, Opt_ratio, Opt_flushoncommit, | 69 | Opt_compress, Opt_compress_force, Opt_notreelog, Opt_ratio, |
70 | Opt_flushoncommit, | ||
70 | Opt_discard, Opt_err, | 71 | Opt_discard, Opt_err, |
71 | }; | 72 | }; |
72 | 73 | ||
@@ -82,6 +83,7 @@ static match_table_t tokens = { | |||
82 | {Opt_alloc_start, "alloc_start=%s"}, | 83 | {Opt_alloc_start, "alloc_start=%s"}, |
83 | {Opt_thread_pool, "thread_pool=%d"}, | 84 | {Opt_thread_pool, "thread_pool=%d"}, |
84 | {Opt_compress, "compress"}, | 85 | {Opt_compress, "compress"}, |
86 | {Opt_compress_force, "compress-force"}, | ||
85 | {Opt_ssd, "ssd"}, | 87 | {Opt_ssd, "ssd"}, |
86 | {Opt_ssd_spread, "ssd_spread"}, | 88 | {Opt_ssd_spread, "ssd_spread"}, |
87 | {Opt_nossd, "nossd"}, | 89 | {Opt_nossd, "nossd"}, |
@@ -173,6 +175,11 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
173 | printk(KERN_INFO "btrfs: use compression\n"); | 175 | printk(KERN_INFO "btrfs: use compression\n"); |
174 | btrfs_set_opt(info->mount_opt, COMPRESS); | 176 | btrfs_set_opt(info->mount_opt, COMPRESS); |
175 | break; | 177 | break; |
178 | case Opt_compress_force: | ||
179 | printk(KERN_INFO "btrfs: forcing compression\n"); | ||
180 | btrfs_set_opt(info->mount_opt, FORCE_COMPRESS); | ||
181 | btrfs_set_opt(info->mount_opt, COMPRESS); | ||
182 | break; | ||
176 | case Opt_ssd: | 183 | case Opt_ssd: |
177 | printk(KERN_INFO "btrfs: use ssd allocation scheme\n"); | 184 | printk(KERN_INFO "btrfs: use ssd allocation scheme\n"); |
178 | btrfs_set_opt(info->mount_opt, SSD); | 185 | btrfs_set_opt(info->mount_opt, SSD); |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 198cff28766d..41ecbb2347f2 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -1135,7 +1135,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
1135 | root->fs_info->avail_metadata_alloc_bits; | 1135 | root->fs_info->avail_metadata_alloc_bits; |
1136 | 1136 | ||
1137 | if ((all_avail & BTRFS_BLOCK_GROUP_RAID10) && | 1137 | if ((all_avail & BTRFS_BLOCK_GROUP_RAID10) && |
1138 | root->fs_info->fs_devices->rw_devices <= 4) { | 1138 | root->fs_info->fs_devices->num_devices <= 4) { |
1139 | printk(KERN_ERR "btrfs: unable to go below four devices " | 1139 | printk(KERN_ERR "btrfs: unable to go below four devices " |
1140 | "on raid10\n"); | 1140 | "on raid10\n"); |
1141 | ret = -EINVAL; | 1141 | ret = -EINVAL; |
@@ -1143,7 +1143,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
1143 | } | 1143 | } |
1144 | 1144 | ||
1145 | if ((all_avail & BTRFS_BLOCK_GROUP_RAID1) && | 1145 | if ((all_avail & BTRFS_BLOCK_GROUP_RAID1) && |
1146 | root->fs_info->fs_devices->rw_devices <= 2) { | 1146 | root->fs_info->fs_devices->num_devices <= 2) { |
1147 | printk(KERN_ERR "btrfs: unable to go below two " | 1147 | printk(KERN_ERR "btrfs: unable to go below two " |
1148 | "devices on raid1\n"); | 1148 | "devices on raid1\n"); |
1149 | ret = -EINVAL; | 1149 | ret = -EINVAL; |
@@ -1434,8 +1434,8 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
1434 | return -EINVAL; | 1434 | return -EINVAL; |
1435 | 1435 | ||
1436 | bdev = open_bdev_exclusive(device_path, 0, root->fs_info->bdev_holder); | 1436 | bdev = open_bdev_exclusive(device_path, 0, root->fs_info->bdev_holder); |
1437 | if (!bdev) | 1437 | if (IS_ERR(bdev)) |
1438 | return -EIO; | 1438 | return PTR_ERR(bdev); |
1439 | 1439 | ||
1440 | if (root->fs_info->fs_devices->seeding) { | 1440 | if (root->fs_info->fs_devices->seeding) { |
1441 | seeding_dev = 1; | 1441 | seeding_dev = 1; |
@@ -2538,6 +2538,11 @@ int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset) | |||
2538 | if (!em) | 2538 | if (!em) |
2539 | return 1; | 2539 | return 1; |
2540 | 2540 | ||
2541 | if (btrfs_test_opt(root, DEGRADED)) { | ||
2542 | free_extent_map(em); | ||
2543 | return 0; | ||
2544 | } | ||
2545 | |||
2541 | map = (struct map_lookup *)em->bdev; | 2546 | map = (struct map_lookup *)em->bdev; |
2542 | for (i = 0; i < map->num_stripes; i++) { | 2547 | for (i = 0; i < map->num_stripes; i++) { |
2543 | if (!map->stripes[i].dev->writeable) { | 2548 | if (!map->stripes[i].dev->writeable) { |
@@ -2649,8 +2654,10 @@ again: | |||
2649 | em = lookup_extent_mapping(em_tree, logical, *length); | 2654 | em = lookup_extent_mapping(em_tree, logical, *length); |
2650 | read_unlock(&em_tree->lock); | 2655 | read_unlock(&em_tree->lock); |
2651 | 2656 | ||
2652 | if (!em && unplug_page) | 2657 | if (!em && unplug_page) { |
2658 | kfree(multi); | ||
2653 | return 0; | 2659 | return 0; |
2660 | } | ||
2654 | 2661 | ||
2655 | if (!em) { | 2662 | if (!em) { |
2656 | printk(KERN_CRIT "unable to find logical %llu len %llu\n", | 2663 | printk(KERN_CRIT "unable to find logical %llu len %llu\n", |