diff options
| -rw-r--r-- | fs/btrfs/compression.c | 15 | ||||
| -rw-r--r-- | fs/btrfs/ctree.h | 6 | ||||
| -rw-r--r-- | fs/btrfs/disk-io.c | 38 | ||||
| -rw-r--r-- | fs/btrfs/export.c | 76 | ||||
| -rw-r--r-- | fs/btrfs/extent-tree.c | 2 | ||||
| -rw-r--r-- | fs/btrfs/extent_io.c | 77 | ||||
| -rw-r--r-- | fs/btrfs/extent_io.h | 3 | ||||
| -rw-r--r-- | fs/btrfs/file.c | 7 | ||||
| -rw-r--r-- | fs/btrfs/inode.c | 294 | ||||
| -rw-r--r-- | fs/btrfs/ioctl.c | 31 | ||||
| -rw-r--r-- | fs/btrfs/ordered-data.c | 67 | ||||
| -rw-r--r-- | fs/btrfs/ordered-data.h | 3 | ||||
| -rw-r--r-- | fs/btrfs/super.c | 41 | ||||
| -rw-r--r-- | fs/btrfs/transaction.c | 5 | ||||
| -rw-r--r-- | fs/btrfs/tree-log.c | 21 |
15 files changed, 572 insertions, 114 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 7845d1f7d1d9..b50bc4bd5c56 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c | |||
| @@ -91,23 +91,10 @@ static inline int compressed_bio_size(struct btrfs_root *root, | |||
| 91 | static struct bio *compressed_bio_alloc(struct block_device *bdev, | 91 | static struct bio *compressed_bio_alloc(struct block_device *bdev, |
| 92 | u64 first_byte, gfp_t gfp_flags) | 92 | u64 first_byte, gfp_t gfp_flags) |
| 93 | { | 93 | { |
| 94 | struct bio *bio; | ||
| 95 | int nr_vecs; | 94 | int nr_vecs; |
| 96 | 95 | ||
| 97 | nr_vecs = bio_get_nr_vecs(bdev); | 96 | nr_vecs = bio_get_nr_vecs(bdev); |
| 98 | bio = bio_alloc(gfp_flags, nr_vecs); | 97 | return btrfs_bio_alloc(bdev, first_byte >> 9, nr_vecs, gfp_flags); |
| 99 | |||
| 100 | if (bio == NULL && (current->flags & PF_MEMALLOC)) { | ||
| 101 | while (!bio && (nr_vecs /= 2)) | ||
| 102 | bio = bio_alloc(gfp_flags, nr_vecs); | ||
| 103 | } | ||
| 104 | |||
| 105 | if (bio) { | ||
| 106 | bio->bi_size = 0; | ||
| 107 | bio->bi_bdev = bdev; | ||
| 108 | bio->bi_sector = first_byte >> 9; | ||
| 109 | } | ||
| 110 | return bio; | ||
| 111 | } | 98 | } |
| 112 | 99 | ||
| 113 | static int check_compressed_csum(struct inode *inode, | 100 | static int check_compressed_csum(struct inode *inode, |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 8db9234f6b41..af52f6d7a4d8 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
| @@ -808,9 +808,9 @@ struct btrfs_block_group_cache { | |||
| 808 | int extents_thresh; | 808 | int extents_thresh; |
| 809 | int free_extents; | 809 | int free_extents; |
| 810 | int total_bitmaps; | 810 | int total_bitmaps; |
| 811 | int ro:1; | 811 | unsigned int ro:1; |
| 812 | int dirty:1; | 812 | unsigned int dirty:1; |
| 813 | int iref:1; | 813 | unsigned int iref:1; |
| 814 | 814 | ||
| 815 | int disk_cache_state; | 815 | int disk_cache_state; |
| 816 | 816 | ||
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index fb827d0d7181..c547cca26a26 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/freezer.h> | 28 | #include <linux/freezer.h> |
| 29 | #include <linux/crc32c.h> | 29 | #include <linux/crc32c.h> |
| 30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
| 31 | #include <linux/migrate.h> | ||
| 31 | #include "compat.h" | 32 | #include "compat.h" |
| 32 | #include "ctree.h" | 33 | #include "ctree.h" |
| 33 | #include "disk-io.h" | 34 | #include "disk-io.h" |
| @@ -355,6 +356,8 @@ static int csum_dirty_buffer(struct btrfs_root *root, struct page *page) | |||
| 355 | ret = btree_read_extent_buffer_pages(root, eb, start + PAGE_CACHE_SIZE, | 356 | ret = btree_read_extent_buffer_pages(root, eb, start + PAGE_CACHE_SIZE, |
| 356 | btrfs_header_generation(eb)); | 357 | btrfs_header_generation(eb)); |
| 357 | BUG_ON(ret); | 358 | BUG_ON(ret); |
| 359 | WARN_ON(!btrfs_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN)); | ||
| 360 | |||
| 358 | found_start = btrfs_header_bytenr(eb); | 361 | found_start = btrfs_header_bytenr(eb); |
| 359 | if (found_start != start) { | 362 | if (found_start != start) { |
| 360 | WARN_ON(1); | 363 | WARN_ON(1); |
| @@ -693,6 +696,29 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, | |||
| 693 | __btree_submit_bio_done); | 696 | __btree_submit_bio_done); |
| 694 | } | 697 | } |
| 695 | 698 | ||
| 699 | static int btree_migratepage(struct address_space *mapping, | ||
| 700 | struct page *newpage, struct page *page) | ||
| 701 | { | ||
| 702 | /* | ||
| 703 | * we can't safely write a btree page from here, | ||
| 704 | * we haven't done the locking hook | ||
| 705 | */ | ||
| 706 | if (PageDirty(page)) | ||
| 707 | return -EAGAIN; | ||
| 708 | /* | ||
| 709 | * Buffers may be managed in a filesystem specific way. | ||
| 710 | * We must have no buffers or drop them. | ||
| 711 | */ | ||
| 712 | if (page_has_private(page) && | ||
| 713 | !try_to_release_page(page, GFP_KERNEL)) | ||
| 714 | return -EAGAIN; | ||
| 715 | #ifdef CONFIG_MIGRATION | ||
| 716 | return migrate_page(mapping, newpage, page); | ||
| 717 | #else | ||
| 718 | return -ENOSYS; | ||
| 719 | #endif | ||
| 720 | } | ||
| 721 | |||
| 696 | static int btree_writepage(struct page *page, struct writeback_control *wbc) | 722 | static int btree_writepage(struct page *page, struct writeback_control *wbc) |
| 697 | { | 723 | { |
| 698 | struct extent_io_tree *tree; | 724 | struct extent_io_tree *tree; |
| @@ -707,8 +733,7 @@ static int btree_writepage(struct page *page, struct writeback_control *wbc) | |||
| 707 | } | 733 | } |
| 708 | 734 | ||
| 709 | redirty_page_for_writepage(wbc, page); | 735 | redirty_page_for_writepage(wbc, page); |
| 710 | eb = btrfs_find_tree_block(root, page_offset(page), | 736 | eb = btrfs_find_tree_block(root, page_offset(page), PAGE_CACHE_SIZE); |
| 711 | PAGE_CACHE_SIZE); | ||
| 712 | WARN_ON(!eb); | 737 | WARN_ON(!eb); |
| 713 | 738 | ||
| 714 | was_dirty = test_and_set_bit(EXTENT_BUFFER_DIRTY, &eb->bflags); | 739 | was_dirty = test_and_set_bit(EXTENT_BUFFER_DIRTY, &eb->bflags); |
| @@ -799,6 +824,9 @@ static const struct address_space_operations btree_aops = { | |||
| 799 | .releasepage = btree_releasepage, | 824 | .releasepage = btree_releasepage, |
| 800 | .invalidatepage = btree_invalidatepage, | 825 | .invalidatepage = btree_invalidatepage, |
| 801 | .sync_page = block_sync_page, | 826 | .sync_page = block_sync_page, |
| 827 | #ifdef CONFIG_MIGRATION | ||
| 828 | .migratepage = btree_migratepage, | ||
| 829 | #endif | ||
| 802 | }; | 830 | }; |
| 803 | 831 | ||
| 804 | int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize, | 832 | int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize, |
| @@ -1538,10 +1566,8 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1538 | GFP_NOFS); | 1566 | GFP_NOFS); |
| 1539 | struct btrfs_root *csum_root = kzalloc(sizeof(struct btrfs_root), | 1567 | struct btrfs_root *csum_root = kzalloc(sizeof(struct btrfs_root), |
| 1540 | GFP_NOFS); | 1568 | GFP_NOFS); |
| 1541 | struct btrfs_root *tree_root = kzalloc(sizeof(struct btrfs_root), | 1569 | struct btrfs_root *tree_root = btrfs_sb(sb); |
| 1542 | GFP_NOFS); | 1570 | struct btrfs_fs_info *fs_info = tree_root->fs_info; |
| 1543 | struct btrfs_fs_info *fs_info = kzalloc(sizeof(*fs_info), | ||
| 1544 | GFP_NOFS); | ||
| 1545 | struct btrfs_root *chunk_root = kzalloc(sizeof(struct btrfs_root), | 1571 | struct btrfs_root *chunk_root = kzalloc(sizeof(struct btrfs_root), |
| 1546 | GFP_NOFS); | 1572 | GFP_NOFS); |
| 1547 | struct btrfs_root *dev_root = kzalloc(sizeof(struct btrfs_root), | 1573 | struct btrfs_root *dev_root = kzalloc(sizeof(struct btrfs_root), |
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c index 951ef09b82f4..6f0444473594 100644 --- a/fs/btrfs/export.c +++ b/fs/btrfs/export.c | |||
| @@ -232,9 +232,85 @@ fail: | |||
| 232 | return ERR_PTR(ret); | 232 | return ERR_PTR(ret); |
| 233 | } | 233 | } |
| 234 | 234 | ||
| 235 | static int btrfs_get_name(struct dentry *parent, char *name, | ||
| 236 | struct dentry *child) | ||
| 237 | { | ||
| 238 | struct inode *inode = child->d_inode; | ||
| 239 | struct inode *dir = parent->d_inode; | ||
| 240 | struct btrfs_path *path; | ||
| 241 | struct btrfs_root *root = BTRFS_I(dir)->root; | ||
| 242 | struct btrfs_inode_ref *iref; | ||
| 243 | struct btrfs_root_ref *rref; | ||
| 244 | struct extent_buffer *leaf; | ||
| 245 | unsigned long name_ptr; | ||
| 246 | struct btrfs_key key; | ||
| 247 | int name_len; | ||
| 248 | int ret; | ||
| 249 | |||
| 250 | if (!dir || !inode) | ||
| 251 | return -EINVAL; | ||
| 252 | |||
| 253 | if (!S_ISDIR(dir->i_mode)) | ||
| 254 | return -EINVAL; | ||
| 255 | |||
| 256 | path = btrfs_alloc_path(); | ||
| 257 | if (!path) | ||
| 258 | return -ENOMEM; | ||
| 259 | path->leave_spinning = 1; | ||
| 260 | |||
| 261 | if (inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) { | ||
| 262 | key.objectid = BTRFS_I(inode)->root->root_key.objectid; | ||
| 263 | key.type = BTRFS_ROOT_BACKREF_KEY; | ||
| 264 | key.offset = (u64)-1; | ||
| 265 | root = root->fs_info->tree_root; | ||
| 266 | } else { | ||
| 267 | key.objectid = inode->i_ino; | ||
| 268 | key.offset = dir->i_ino; | ||
