diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-12-18 16:15:09 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:03:58 -0400 |
commit | 6da6abae027e2dbc59bca5f4168b0760f25068c7 (patch) | |
tree | a1e9c70c930e8b01baead984b706042067148788 | |
parent | c59f8951d48c5eb000926935f3ab063d8181d1ee (diff) |
Btrfs: Back port to 2.6.18-el kernels
Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r-- | fs/btrfs/ctree.h | 13 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 5 | ||||
-rw-r--r-- | fs/btrfs/extent_map.c | 168 | ||||
-rw-r--r-- | fs/btrfs/file.c | 15 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 21 | ||||
-rw-r--r-- | fs/btrfs/super.c | 1 | ||||
-rw-r--r-- | fs/btrfs/sysfs.c | 23 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 8 | ||||
-rw-r--r-- | fs/btrfs/transaction.h | 5 |
9 files changed, 239 insertions, 20 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 32b24460ec82..2559f5d5d00a 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #ifndef __BTRFS__ | 19 | #ifndef __BTRFS__ |
20 | #define __BTRFS__ | 20 | #define __BTRFS__ |
21 | 21 | ||
22 | #include <linux/version.h> | ||
22 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
23 | #include <linux/highmem.h> | 24 | #include <linux/highmem.h> |
24 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
@@ -334,7 +335,11 @@ struct btrfs_fs_info { | |||
334 | struct list_head trans_list; | 335 | struct list_head trans_list; |
335 | struct list_head hashers; | 336 | struct list_head hashers; |
336 | struct list_head dead_roots; | 337 | struct list_head dead_roots; |
338 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) | ||
339 | struct work_struct trans_work; | ||
340 | #else | ||
337 | struct delayed_work trans_work; | 341 | struct delayed_work trans_work; |
342 | #endif | ||
338 | struct kobject super_kobj; | 343 | struct kobject super_kobj; |
339 | struct completion kobj_unregister; | 344 | struct completion kobj_unregister; |
340 | int do_barriers; | 345 | int do_barriers; |
@@ -916,6 +921,14 @@ static inline u32 btrfs_level_size(struct btrfs_root *root, int level) { | |||
916 | ((unsigned long)(btrfs_leaf_data(leaf) + \ | 921 | ((unsigned long)(btrfs_leaf_data(leaf) + \ |
917 | btrfs_item_offset_nr(leaf, slot))) | 922 | btrfs_item_offset_nr(leaf, slot))) |
918 | 923 | ||
924 | static inline struct dentry *fdentry(struct file *file) { | ||
925 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) | ||
926 | return file->f_dentry; | ||
927 | #else | ||
928 | return file->f_path.dentry; | ||
929 | #endif | ||
930 | } | ||
931 | |||
919 | /* extent-tree.c */ | 932 | /* extent-tree.c */ |
920 | u32 btrfs_count_snapshots_in_path(struct btrfs_root *root, | 933 | u32 btrfs_count_snapshots_in_path(struct btrfs_root *root, |
921 | struct btrfs_path *count_path, | 934 | struct btrfs_path *count_path, |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 7213012c27d5..ebb2db624fdd 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -593,8 +593,11 @@ struct btrfs_root *open_ctree(struct super_block *sb) | |||
593 | fs_info->do_barriers = 1; | 593 | fs_info->do_barriers = 1; |
594 | fs_info->closing = 0; | 594 | fs_info->closing = 0; |
595 | fs_info->total_pinned = 0; | 595 | fs_info->total_pinned = 0; |
596 | 596 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) | |
597 | INIT_WORK(&fs_info->trans_work, btrfs_transaction_cleaner, fs_info); | ||
598 | #else | ||
597 | INIT_DELAYED_WORK(&fs_info->trans_work, btrfs_transaction_cleaner); | 599 | INIT_DELAYED_WORK(&fs_info->trans_work, btrfs_transaction_cleaner); |
600 | #endif | ||
598 | BTRFS_I(fs_info->btree_inode)->root = tree_root; | 601 | BTRFS_I(fs_info->btree_inode)->root = tree_root; |
599 | memset(&BTRFS_I(fs_info->btree_inode)->location, 0, | 602 | memset(&BTRFS_I(fs_info->btree_inode)->location, 0, |
600 | sizeof(struct btrfs_key)); | 603 | sizeof(struct btrfs_key)); |
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 8326a18413ff..0d1e59a86e49 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c | |||
@@ -1585,8 +1585,18 @@ extent_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs, | |||
1585 | 1585 | ||
1586 | static int submit_one_bio(int rw, struct bio *bio) | 1586 | static int submit_one_bio(int rw, struct bio *bio) |
1587 | { | 1587 | { |
1588 | u64 maxsector; | ||
1588 | int ret = 0; | 1589 | int ret = 0; |
1590 | |||
1589 | bio_get(bio); | 1591 | bio_get(bio); |
1592 | |||
1593 | maxsector = bio->bi_bdev->bd_inode->i_size >> 9; | ||
1594 | if (maxsector < bio->bi_sector) { | ||
1595 | printk("sector too large max %Lu got %llu\n", maxsector, | ||
1596 | (unsigned long long)bio->bi_sector); | ||
1597 | WARN_ON(1); | ||
1598 | } | ||
1599 | |||
1590 | submit_bio(rw, bio); | 1600 | submit_bio(rw, bio); |
1591 | if (bio_flagged(bio, BIO_EOPNOTSUPP)) | 1601 | if (bio_flagged(bio, BIO_EOPNOTSUPP)) |
1592 | ret = -EOPNOTSUPP; | 1602 | ret = -EOPNOTSUPP; |
@@ -1678,8 +1688,12 @@ static int __extent_read_full_page(struct extent_map_tree *tree, | |||
1678 | 1688 | ||
1679 | while (cur <= end) { | 1689 | while (cur <= end) { |
1680 | if (cur >= last_byte) { | 1690 | if (cur >= last_byte) { |
1691 | char *userpage; | ||
1681 | iosize = PAGE_CACHE_SIZE - page_offset; | 1692 | iosize = PAGE_CACHE_SIZE - page_offset; |
1682 | zero_user_page(page, page_offset, iosize, KM_USER0); | 1693 | userpage = kmap_atomic(page, KM_USER0); |
1694 | memset(userpage + page_offset, 0, iosize); | ||
1695 | flush_dcache_page(page); | ||
1696 | kunmap_atomic(userpage, KM_USER0); | ||
1683 | set_extent_uptodate(tree, cur, cur + iosize - 1, | 1697 | set_extent_uptodate(tree, cur, cur + iosize - 1, |
1684 | GFP_NOFS); | 1698 | GFP_NOFS); |
1685 | unlock_extent(tree, cur, cur + iosize - 1, GFP_NOFS); | 1699 | unlock_extent(tree, cur, cur + iosize - 1, GFP_NOFS); |
@@ -1707,7 +1721,12 @@ static int __extent_read_full_page(struct extent_map_tree *tree, | |||
1707 | 1721 | ||
1708 | /* we've found a hole, just zero and go on */ | 1722 | /* we've found a hole, just zero and go on */ |
1709 | if (block_start == EXTENT_MAP_HOLE) { | 1723 | if (block_start == EXTENT_MAP_HOLE) { |
1710 | zero_user_page(page, page_offset, iosize, KM_USER0); | 1724 | char *userpage; |
1725 | userpage = kmap_atomic(page, KM_USER0); | ||
1726 | memset(userpage + page_offset, 0, iosize); | ||
1727 | flush_dcache_page(page); | ||
1728 | kunmap_atomic(userpage, KM_USER0); | ||
1729 | |||
1711 | set_extent_uptodate(tree, cur, cur + iosize - 1, | 1730 | set_extent_uptodate(tree, cur, cur + iosize - 1, |
1712 | GFP_NOFS); | 1731 | GFP_NOFS); |
1713 | unlock_extent(tree, cur, cur + iosize - 1, GFP_NOFS); | 1732 | unlock_extent(tree, cur, cur + iosize - 1, GFP_NOFS); |
@@ -1804,9 +1823,14 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, | |||
1804 | } | 1823 | } |
1805 | 1824 | ||
1806 | if (page->index == end_index) { | 1825 | if (page->index == end_index) { |
1826 | char *userpage; | ||
1827 | |||
1807 | size_t offset = i_size & (PAGE_CACHE_SIZE - 1); | 1828 | size_t offset = i_size & (PAGE_CACHE_SIZE - 1); |
1808 | zero_user_page(page, offset, | 1829 | |
1809 | PAGE_CACHE_SIZE - offset, KM_USER0); | 1830 | userpage = kmap_atomic(page, KM_USER0); |
1831 | memset(userpage + offset, 0, PAGE_CACHE_SIZE - offset); | ||
1832 | flush_dcache_page(page); | ||
1833 | kunmap_atomic(userpage, KM_USER0); | ||
1810 | } | 1834 | } |
1811 | 1835 | ||
1812 | set_page_extent_mapped(page); | 1836 | set_page_extent_mapped(page); |
@@ -1921,6 +1945,129 @@ done: | |||
1921 | return 0; | 1945 | return 0; |
1922 | } | 1946 | } |
1923 | 1947 | ||
1948 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) | ||
1949 | |||
1950 | /* Taken directly from 2.6.23 for 2.6.18 back port */ | ||
1951 | typedef int (*writepage_t)(struct page *page, struct writeback_control *wbc, | ||
1952 | void *data); | ||
1953 | |||
1954 | /** | ||
1955 | * write_cache_pages - walk the list of dirty pages of the given address space | ||
1956 | * and write all of them. | ||
1957 | * @mapping: address space structure to write | ||
1958 | * @wbc: subtract the number of written pages from *@wbc->nr_to_write | ||
1959 | * @writepage: function called for each page | ||
1960 | * @data: data passed to writepage function | ||
1961 | * | ||
1962 | * If a page is already under I/O, write_cache_pages() skips it, even | ||
1963 | * if it's dirty. This is desirable behaviour for memory-cleaning writeback, | ||
1964 | * but it is INCORRECT for data-integrity system calls such as fsync(). fsync() | ||
1965 | * and msync() need to guarantee that all the data which was dirty at the time | ||
1966 | * the call was made get new I/O started against them. If wbc->sync_mode is | ||
1967 | * WB_SYNC_ALL then we were called for data integrity and we must wait for | ||
1968 | * existing IO to complete. | ||
1969 | */ | ||
1970 | static int write_cache_pages(struct address_space *mapping, | ||
1971 | struct writeback_control *wbc, writepage_t writepage, | ||
1972 | void *data) | ||
1973 | { | ||
1974 | struct backing_dev_info *bdi = mapping->backing_dev_info; | ||
1975 | int ret = 0; | ||
1976 | int done = 0; | ||
1977 | struct pagevec pvec; | ||
1978 | int nr_pages; | ||
1979 | pgoff_t index; | ||
1980 | pgoff_t end; /* Inclusive */ | ||
1981 | int scanned = 0; | ||
1982 | int range_whole = 0; | ||
1983 | |||
1984 | if (wbc->nonblocking && bdi_write_congested(bdi)) { | ||
1985 | wbc->encountered_congestion = 1; | ||
1986 | return 0; | ||
1987 | } | ||
1988 | |||
1989 | pagevec_init(&pvec, 0); | ||
1990 | if (wbc->range_cyclic) { | ||
1991 | index = mapping->writeback_index; /* Start from prev offset */ | ||
1992 | end = -1; | ||
1993 | } else { | ||
1994 | index = wbc->range_start >> PAGE_CACHE_SHIFT; | ||
1995 | end = wbc->range_end >> PAGE_CACHE_SHIFT; | ||
1996 | if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) | ||
1997 | range_whole = 1; | ||
1998 | scanned = 1; | ||
1999 | } | ||
2000 | retry: | ||
2001 | while (!done && (index <= end) && | ||
2002 | (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, | ||
2003 | PAGECACHE_TAG_DIRTY, | ||
2004 | min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) { | ||
2005 | unsigned i; | ||
2006 | |||
2007 | scanned = 1; | ||
2008 | for (i = 0; i < nr_pages; i++) { | ||
2009 | struct page *page = pvec.pages[i]; | ||
2010 | |||
2011 | /* | ||
2012 | * At this point we hold neither mapping->tree_lock nor | ||
2013 | * lock on the page itself: the page may be truncated or | ||
2014 | * invalidated (changing page->mapping to NULL), or even | ||
2015 | * swizzled back from swapper_space to tmpfs file | ||
2016 | * mapping | ||
2017 | */ | ||
2018 | lock_page(page); | ||
2019 | |||
2020 | if (unlikely(page->mapping != mapping)) { | ||
2021 | unlock_page(page); | ||
2022 | continue; | ||
2023 | } | ||
2024 | |||
2025 | if (!wbc->range_cyclic && page->index > end) { | ||
2026 | done = 1; | ||
2027 | unlock_page(page); | ||
2028 | continue; | ||
2029 | } | ||
2030 | |||
2031 | if (wbc->sync_mode != WB_SYNC_NONE) | ||
2032 | wait_on_page_writeback(page); | ||
2033 | |||
2034 | if (PageWriteback(page) || | ||
2035 | !clear_page_dirty_for_io(page)) { | ||
2036 | unlock_page(page); | ||
2037 | continue; | ||
2038 | } | ||
2039 | |||
2040 | ret = (*writepage)(page, wbc, data); | ||
2041 | |||
2042 | if (unlikely(ret == AOP_WRITEPAGE_ACTIVATE)) { | ||
2043 | unlock_page(page); | ||
2044 | ret = 0; | ||
2045 | } | ||
2046 | if (ret || (--(wbc->nr_to_write) <= 0)) | ||
2047 | done = 1; | ||
2048 | if (wbc->nonblocking && bdi_write_congested(bdi)) { | ||
2049 | wbc->encountered_congestion = 1; | ||
2050 | done = 1; | ||
2051 | } | ||
2052 | } | ||
2053 | pagevec_release(&pvec); | ||
2054 | cond_resched(); | ||
2055 | } | ||
2056 | if (!scanned && !done) { | ||
2057 | /* | ||
2058 | * We hit the last page and there is more work to be done: wrap | ||
2059 | * back to the start of the file | ||
2060 | */ | ||
2061 | scanned = 1; | ||
2062 | index = 0; | ||
2063 | goto retry; | ||
2064 | } | ||
2065 | if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) | ||
2066 | mapping->writeback_index = index; | ||
2067 | return ret; | ||
2068 | } | ||
2069 | #endif | ||
2070 | |||
1924 | int extent_write_full_page(struct extent_map_tree *tree, struct page *page, | 2071 | int extent_write_full_page(struct extent_map_tree *tree, struct page *page, |
1925 | get_extent_t *get_extent, | 2072 | get_extent_t *get_extent, |
1926 | struct writeback_control *wbc) | 2073 | struct writeback_control *wbc) |
@@ -1945,18 +2092,20 @@ int extent_write_full_page(struct extent_map_tree *tree, struct page *page, | |||
1945 | ret = __extent_writepage(page, wbc, &epd); | 2092 | ret = __extent_writepage(page, wbc, &epd); |
1946 | 2093 | ||
1947 | write_cache_pages(mapping, &wbc_writepages, __extent_writepage, &epd); | 2094 | write_cache_pages(mapping, &wbc_writepages, __extent_writepage, &epd); |
1948 | if (epd.bio) | 2095 | if (epd.bio) { |
1949 | submit_one_bio(WRITE, epd.bio); | 2096 | submit_one_bio(WRITE, epd.bio); |
2097 | } | ||
1950 | return ret; | 2098 | return ret; |
1951 | } | 2099 | } |
1952 | EXPORT_SYMBOL(extent_write_full_page); | 2100 | EXPORT_SYMBOL(extent_write_full_page); |
1953 | 2101 | ||
2102 | |||
1954 | int extent_writepages(struct extent_map_tree *tree, | 2103 | int extent_writepages(struct extent_map_tree *tree, |
1955 | struct address_space *mapping, | 2104 | struct address_space *mapping, |
1956 | get_extent_t *get_extent, | 2105 | get_extent_t *get_extent, |
1957 | struct writeback_control *wbc) | 2106 | struct writeback_control *wbc) |
1958 | { | 2107 | { |
1959 | int ret; | 2108 | int ret = 0; |
1960 | struct extent_page_data epd = { | 2109 | struct extent_page_data epd = { |
1961 | .bio = NULL, | 2110 | .bio = NULL, |
1962 | .tree = tree, | 2111 | .tree = tree, |
@@ -1964,8 +2113,9 @@ int extent_writepages(struct extent_map_tree *tree, | |||
1964 | }; | 2113 | }; |
1965 | 2114 | ||
1966 | ret = write_cache_pages(mapping, wbc, __extent_writepage, &epd); | 2115 | ret = write_cache_pages(mapping, wbc, __extent_writepage, &epd); |
1967 | if (epd.bio) | 2116 | if (epd.bio) { |
1968 | submit_one_bio(WRITE, epd.bio); | 2117 | submit_one_bio(WRITE, epd.bio); |
2118 | } | ||
1969 | return ret; | 2119 | return ret; |
1970 | } | 2120 | } |
1971 | EXPORT_SYMBOL(extent_writepages); | 2121 | EXPORT_SYMBOL(extent_writepages); |
@@ -2106,7 +2256,9 @@ int extent_prepare_write(struct extent_map_tree *tree, | |||
2106 | flush_dcache_page(page); | 2256 | flush_dcache_page(page); |
2107 | kunmap_atomic(kaddr, KM_USER0); | 2257 | kunmap_atomic(kaddr, KM_USER0); |
2108 | } | 2258 | } |
2109 | if (!isnew && !PageUptodate(page) && | 2259 | if ((em->block_start != EXTENT_MAP_HOLE && |
2260 | em->block_start != EXTENT_MAP_INLINE) && | ||
2261 | !isnew && !PageUptodate(page) && | ||
2110 | (block_off_end > to || block_off_start < from) && | 2262 | (block_off_end > to || block_off_start < from) && |
2111 | !test_range_bit(tree, block_start, cur_end, | 2263 | !test_range_bit(tree, block_start, cur_end, |
2112 | EXTENT_UPTODATE, 1)) { | 2264 | EXTENT_UPTODATE, 1)) { |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 62fcd79d8ab3..461b09663fed 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -231,7 +231,7 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans, | |||
231 | { | 231 | { |
232 | int err = 0; | 232 | int err = 0; |
233 | int i; | 233 | int i; |
234 | struct inode *inode = file->f_path.dentry->d_inode; | 234 | struct inode *inode = fdentry(file)->d_inode; |
235 | struct extent_map *em; | 235 | struct extent_map *em; |
236 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; | 236 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; |
237 | u64 hint_byte; | 237 | u64 hint_byte; |
@@ -652,7 +652,7 @@ static int prepare_pages(struct btrfs_root *root, | |||
652 | { | 652 | { |
653 | int i; | 653 | int i; |
654 | unsigned long index = pos >> PAGE_CACHE_SHIFT; | 654 | unsigned long index = pos >> PAGE_CACHE_SHIFT; |
655 | struct inode *inode = file->f_path.dentry->d_inode; | 655 | struct inode *inode = fdentry(file)->d_inode; |
656 | int err = 0; | 656 | int err = 0; |
657 | u64 start_pos; | 657 | u64 start_pos; |
658 | 658 | ||
@@ -666,7 +666,11 @@ static int prepare_pages(struct btrfs_root *root, | |||
666 | err = -ENOMEM; | 666 | err = -ENOMEM; |
667 | BUG_ON(1); | 667 | BUG_ON(1); |
668 | } | 668 | } |
669 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) | ||
670 | ClearPageDirty(pages[i]); | ||
671 | #else | ||
669 | cancel_dirty_page(pages[i], PAGE_CACHE_SIZE); | 672 | cancel_dirty_page(pages[i], PAGE_CACHE_SIZE); |
673 | #endif | ||
670 | wait_on_page_writeback(pages[i]); | 674 | wait_on_page_writeback(pages[i]); |
671 | set_page_extent_mapped(pages[i]); | 675 | set_page_extent_mapped(pages[i]); |
672 | WARN_ON(!PageLocked(pages[i])); | 676 | WARN_ON(!PageLocked(pages[i])); |
@@ -682,7 +686,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
682 | ssize_t num_written = 0; | 686 | ssize_t num_written = 0; |
683 | ssize_t err = 0; | 687 | ssize_t err = 0; |
684 | int ret = 0; | 688 | int ret = 0; |
685 | struct inode *inode = file->f_path.dentry->d_inode; | 689 | struct inode *inode = fdentry(file)->d_inode; |
686 | struct btrfs_root *root = BTRFS_I(inode)->root; | 690 | struct btrfs_root *root = BTRFS_I(inode)->root; |
687 | struct page **pages = NULL; | 691 | struct page **pages = NULL; |
688 | int nrptrs; | 692 | int nrptrs; |
@@ -707,7 +711,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
707 | goto out; | 711 | goto out; |
708 | if (count == 0) | 712 | if (count == 0) |
709 | goto out; | 713 | goto out; |
710 | err = remove_suid(file->f_path.dentry); | 714 | err = remove_suid(fdentry(file)); |
711 | if (err) | 715 | if (err) |
712 | goto out; | 716 | goto out; |
713 | file_update_time(file); | 717 | file_update_time(file); |
@@ -862,6 +866,9 @@ struct file_operations btrfs_file_operations = { | |||
862 | .read = do_sync_read, | 866 | .read = do_sync_read, |
863 | .aio_read = generic_file_aio_read, | 867 | .aio_read = generic_file_aio_read, |
864 | .splice_read = generic_file_splice_read, | 868 | .splice_read = generic_file_splice_read, |
869 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) | ||
870 | .sendfile = generic_file_sendfile, | ||
871 | #endif | ||
865 | .write = btrfs_file_write, | 872 | .write = btrfs_file_write, |
866 | .mmap = btrfs_file_mmap, | 873 | .mmap = btrfs_file_mmap, |
867 | .open = generic_file_open, | 874 | .open = generic_file_open, |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 686dd03f34f2..6a7d9160df27 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -532,7 +532,11 @@ err: | |||
532 | dir->i_size -= name_len * 2; | 532 | dir->i_size -= name_len * 2; |
533 | dir->i_mtime = dir->i_ctime = CURRENT_TIME; | 533 | dir->i_mtime = dir->i_ctime = CURRENT_TIME; |
534 | btrfs_update_inode(trans, root, dir); | 534 | btrfs_update_inode(trans, root, dir); |
535 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) | ||
536 | dentry->d_inode->i_nlink--; | ||
537 | #else | ||
535 | drop_nlink(dentry->d_inode); | 538 | drop_nlink(dentry->d_inode); |
539 | #endif | ||
536 | ret = btrfs_update_inode(trans, root, dentry->d_inode); | 540 | ret = btrfs_update_inode(trans, root, dentry->d_inode); |
537 | dir->i_sb->s_dirt = 1; | 541 | dir->i_sb->s_dirt = 1; |
538 | } | 542 | } |
@@ -1139,7 +1143,7 @@ static unsigned char btrfs_filetype_table[] = { | |||
1139 | 1143 | ||
1140 | static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | 1144 | static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir) |
1141 | { | 1145 | { |
1142 | struct inode *inode = filp->f_path.dentry->d_inode; | 1146 | struct inode *inode = filp->f_dentry->d_inode; |
1143 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1147 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1144 | struct btrfs_item *item; | 1148 | struct btrfs_item *item; |
1145 | struct btrfs_dir_item *di; | 1149 | struct btrfs_dir_item *di; |
@@ -1554,7 +1558,11 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
1554 | if (inode->i_nlink == 0) | 1558 | if (inode->i_nlink == 0) |
1555 | return -ENOENT; | 1559 | return -ENOENT; |
1556 | 1560 | ||
1561 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) | ||
1562 | inode->i_nlink++; | ||
1563 | #else | ||
1557 | inc_nlink(inode); | 1564 | inc_nlink(inode); |
1565 | #endif | ||
1558 | mutex_lock(&root->fs_info->fs_mutex); | 1566 | mutex_lock(&root->fs_info->fs_mutex); |
1559 | trans = btrfs_start_transaction(root, 1); | 1567 | trans = btrfs_start_transaction(root, 1); |
1560 | 1568 | ||
@@ -1825,6 +1833,9 @@ insert: | |||
1825 | if (ret == -EEXIST) { | 1833 | if (ret == -EEXIST) { |
1826 | free_extent_map(em); | 1834 | free_extent_map(em); |
1827 | em = NULL; | 1835 | em = NULL; |
1836 | if (0 && failed_insert == 1) { | ||
1837 | btrfs_drop_extent_cache(inode, start, end); | ||
1838 | } | ||
1828 | failed_insert++; | 1839 | failed_insert++; |
1829 | if (failed_insert > 5) { | 1840 | if (failed_insert > 5) { |
1830 | printk("failing to insert %Lu %Lu\n", start, end); | 1841 | printk("failing to insert %Lu %Lu\n", start, end); |
@@ -1942,7 +1953,7 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset) | |||
1942 | */ | 1953 | */ |
1943 | int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page) | 1954 | int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page) |
1944 | { | 1955 | { |
1945 | struct inode *inode = vma->vm_file->f_path.dentry->d_inode; | 1956 | struct inode *inode = fdentry(vma->vm_file)->d_inode; |
1946 | unsigned long end; | 1957 | unsigned long end; |
1947 | loff_t size; | 1958 | loff_t size; |
1948 | int ret = -EINVAL; | 1959 | int ret = -EINVAL; |
@@ -2243,7 +2254,7 @@ static unsigned long force_ra(struct address_space *mapping, | |||
2243 | } | 2254 | } |
2244 | 2255 | ||
2245 | int btrfs_defrag_file(struct file *file) { | 2256 | int btrfs_defrag_file(struct file *file) { |
2246 | struct inode *inode = file->f_path.dentry->d_inode; | 2257 | struct inode *inode = fdentry(file)->d_inode; |
2247 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; | 2258 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; |
2248 | struct page *page; | 2259 | struct page *page; |
2249 | unsigned long last_index; | 2260 | unsigned long last_index; |
@@ -2329,7 +2340,7 @@ static int btrfs_ioctl_snap_create(struct btrfs_root *root, void __user *arg) | |||
2329 | 2340 | ||
2330 | static int btrfs_ioctl_defrag(struct file *file) | 2341 | static int btrfs_ioctl_defrag(struct file *file) |
2331 | { | 2342 | { |
2332 | struct inode *inode = file->f_path.dentry->d_inode; | 2343 | struct inode *inode = fdentry(file)->d_inode; |
2333 | struct btrfs_root *root = BTRFS_I(inode)->root; | 2344 | struct btrfs_root *root = BTRFS_I(inode)->root; |
2334 | 2345 | ||
2335 | switch (inode->i_mode & S_IFMT) { | 2346 | switch (inode->i_mode & S_IFMT) { |
@@ -2350,7 +2361,7 @@ static int btrfs_ioctl_defrag(struct file *file) | |||
2350 | long btrfs_ioctl(struct file *file, unsigned int | 2361 | long btrfs_ioctl(struct file *file, unsigned int |
2351 | cmd, unsigned long arg) | 2362 | cmd, unsigned long arg) |
2352 | { | 2363 | { |
2353 | struct btrfs_root *root = BTRFS_I(file->f_path.dentry->d_inode)->root; | 2364 | struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; |
2354 | 2365 | ||
2355 | switch (cmd) { | 2366 | switch (cmd) { |
2356 | case BTRFS_IOC_SNAP_CREATE: | 2367 | case BTRFS_IOC_SNAP_CREATE: |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index b7323914bf5a..7cab680418a1 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/compat.h> | 35 | #include <linux/compat.h> |
36 | #include <linux/parser.h> | 36 | #include <linux/parser.h> |
37 | #include <linux/ctype.h> | 37 | #include <linux/ctype.h> |
38 | #include <linux/namei.h> | ||
38 | #include "ctree.h" | 39 | #include "ctree.h" |
39 | #include "disk-io.h" | 40 | #include "disk-io.h" |
40 | #include "transaction.h" | 41 | #include "transaction.h" |
diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c index 1671c731800e..cd673ca9bb98 100644 --- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c | |||
@@ -189,12 +189,29 @@ static struct kset btrfs_kset; | |||
189 | int btrfs_sysfs_add_super(struct btrfs_fs_info *fs) | 189 | int btrfs_sysfs_add_super(struct btrfs_fs_info *fs) |
190 | { | 190 | { |
191 | int error; | 191 | int error; |
192 | char *name; | ||
193 | char c; | ||
194 | int len = strlen(fs->sb->s_id) + 1; | ||
195 | int i; | ||
196 | |||
197 | name = kmalloc(len, GFP_NOFS); | ||
198 | if (!name) { | ||
199 | error = -ENOMEM; | ||
200 | goto fail; | ||
201 | } | ||
202 | |||
203 | for (i = 0; i < len; i++) { | ||
204 | c = fs->sb->s_id[i]; | ||
205 | if (c == '/' || c == '\\') | ||
206 | c = '!'; | ||
207 | name[i] = c; | ||
208 | } | ||
209 | name[len] = '\0'; | ||
192 | 210 | ||
193 | fs->super_kobj.kset = &btrfs_kset; | 211 | fs->super_kobj.kset = &btrfs_kset; |
194 | fs->super_kobj.ktype = &btrfs_super_ktype; | 212 | fs->super_kobj.ktype = &btrfs_super_ktype; |
195 | 213 | ||
196 | error = kobject_set_name(&fs->super_kobj, "%s", | 214 | error = kobject_set_name(&fs->super_kobj, "%s", name); |
197 | fs->sb->s_id); | ||
198 | if (error) | 215 | if (error) |
199 | goto fail; | 216 | goto fail; |
200 | 217 | ||
@@ -202,9 +219,11 @@ int btrfs_sysfs_add_super(struct btrfs_fs_info *fs) | |||
202 | if (error) | 219 | if (error) |
203 | goto fail; | 220 | goto fail; |
204 | 221 | ||
222 | kfree(name); | ||
205 | return 0; | 223 | return 0; |
206 | 224 | ||
207 | fail: | 225 | fail: |
226 | kfree(name); | ||
208 | printk(KERN_ERR "btrfs: sysfs creation for super failed\n"); | 227 | printk(KERN_ERR "btrfs: sysfs creation for super failed\n"); |
209 | return error; | 228 | return error; |
210 | } | 229 | } |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 0229e69bd2ff..1ad611b9f61b 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -614,12 +614,20 @@ int btrfs_clean_old_snapshots(struct btrfs_root *root) | |||
614 | } | 614 | } |
615 | return 0; | 615 | return 0; |
616 | } | 616 | } |
617 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) | ||
618 | void btrfs_transaction_cleaner(void *p) | ||
619 | #else | ||
617 | void btrfs_transaction_cleaner(struct work_struct *work) | 620 | void btrfs_transaction_cleaner(struct work_struct *work) |
621 | #endif | ||
618 | { | 622 | { |
623 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) | ||
624 | struct btrfs_fs_info *fs_info = p; | ||
625 | #else | ||
619 | struct btrfs_fs_info *fs_info = container_of(work, | 626 | struct btrfs_fs_info *fs_info = container_of(work, |
620 | struct btrfs_fs_info, | 627 | struct btrfs_fs_info, |
621 | trans_work.work); | 628 | trans_work.work); |
622 | 629 | ||
630 | #endif | ||
623 | struct btrfs_root *root = fs_info->tree_root; | 631 | struct btrfs_root *root = fs_info->tree_root; |
624 | struct btrfs_transaction *cur; | 632 | struct btrfs_transaction *cur; |
625 | struct btrfs_trans_handle *trans; | 633 | struct btrfs_trans_handle *trans; |
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h index ae39fcfc169a..eef840bca91e 100644 --- a/fs/btrfs/transaction.h +++ b/fs/btrfs/transaction.h | |||
@@ -73,7 +73,12 @@ int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, | |||
73 | int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans, | 73 | int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans, |
74 | struct btrfs_root *root); | 74 | struct btrfs_root *root); |
75 | 75 | ||
76 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) | ||
77 | void btrfs_transaction_cleaner(void *p); | ||
78 | #else | ||
76 | void btrfs_transaction_cleaner(struct work_struct *work); | 79 | void btrfs_transaction_cleaner(struct work_struct *work); |
80 | #endif | ||
81 | |||
77 | void btrfs_transaction_flush_work(struct btrfs_root *root); | 82 | void btrfs_transaction_flush_work(struct btrfs_root *root); |
78 | void btrfs_transaction_queue_work(struct btrfs_root *root, int delay); | 83 | void btrfs_transaction_queue_work(struct btrfs_root *root, int delay); |
79 | void btrfs_init_transaction_sys(void); | 84 | void btrfs_init_transaction_sys(void); |