aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-09-10 19:58:16 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-09-10 19:58:16 -0400
commit86479a04eef8f304a13aeb8b64bcc8e506a68268 (patch)
treecda7e66d469bcdc2f41144ea91405aeb96d1f777 /fs/btrfs/inode.c
parent8e21528f87854314792aaef4d279bc9e5a9be997 (diff)
Add support for defragging files via btrfsctl -d. Avoid OOM on extent tree
defrag. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c93
1 files changed, 81 insertions, 12 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 64710fa77d01..6b3e4404dc6a 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -1904,6 +1904,70 @@ fail:
1904 return ret; 1904 return ret;
1905} 1905}
1906 1906
1907static unsigned long force_ra(struct address_space *mapping,
1908 struct file_ra_state *ra, struct file *file,
1909 pgoff_t offset, pgoff_t last_index)
1910{
1911 pgoff_t req_size;
1912
1913#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
1914 req_size = last_index - offset + 1;
1915 offset = page_cache_readahead(mapping, ra, file, offset, req_size);
1916 return offset;
1917#else
1918 req_size = min(last_index - offset + 1, (pgoff_t)128);
1919 page_cache_sync_readahead(mapping, ra, file, offset, req_size);
1920 return offset + req_size;
1921#endif
1922}
1923
1924int btrfs_defrag_file(struct file *file) {
1925 struct inode *inode = file->f_path.dentry->d_inode;
1926 struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
1927 struct page *page;
1928 unsigned long last_index;
1929 unsigned long ra_index = 0;
1930 u64 page_start;
1931 u64 page_end;
1932 unsigned long i;
1933
1934 mutex_lock(&inode->i_mutex);
1935 last_index = inode->i_size >> PAGE_CACHE_SHIFT;
1936 for (i = 0; i <= last_index; i++) {
1937 if (i == ra_index) {
1938 ra_index = force_ra(inode->i_mapping, &file->f_ra,
1939 file, ra_index, last_index);
1940 }
1941 page = grab_cache_page(inode->i_mapping, i);
1942 if (!page)
1943 goto out_unlock;
1944 if (!PageUptodate(page)) {
1945 btrfs_readpage(NULL, page);
1946 lock_page(page);
1947 if (!PageUptodate(page)) {
1948 unlock_page(page);
1949 page_cache_release(page);
1950 goto out_unlock;
1951 }
1952 }
1953 page_start = page->index << PAGE_CACHE_SHIFT;
1954 page_end = page_start + PAGE_CACHE_SIZE - 1;
1955
1956 lock_extent(em_tree, page_start, page_end, GFP_NOFS);
1957 set_extent_delalloc(em_tree, page_start,
1958 page_end, GFP_NOFS);
1959 unlock_extent(em_tree, page_start, page_end, GFP_NOFS);
1960 set_page_dirty(page);
1961 unlock_page(page);
1962 page_cache_release(page);
1963 balance_dirty_pages_ratelimited_nr(inode->i_mapping, 1);
1964 }
1965
1966out_unlock:
1967 mutex_unlock(&inode->i_mutex);
1968 return 0;
1969}
1970
1907int btrfs_ioctl(struct inode *inode, struct file *filp, unsigned int 1971int btrfs_ioctl(struct inode *inode, struct file *filp, unsigned int
1908 cmd, unsigned long arg) 1972 cmd, unsigned long arg)
1909{ 1973{
@@ -1948,10 +2012,14 @@ int btrfs_ioctl(struct inode *inode, struct file *filp, unsigned int
1948 break; 2012 break;
1949 2013
1950 case BTRFS_IOC_DEFRAG: 2014 case BTRFS_IOC_DEFRAG:
1951 mutex_lock(&root->fs_info->fs_mutex); 2015 if (S_ISDIR(inode->i_mode)) {
1952 btrfs_defrag_root(root, 0); 2016 mutex_lock(&root->fs_info->fs_mutex);
1953 btrfs_defrag_root(root->fs_info->extent_root, 0); 2017 btrfs_defrag_root(root, 0);
1954 mutex_unlock(&root->fs_info->fs_mutex); 2018 btrfs_defrag_root(root->fs_info->extent_root, 0);
2019 mutex_unlock(&root->fs_info->fs_mutex);
2020 } else if (S_ISREG(inode->i_mode)) {
2021 btrfs_defrag_file(filp);
2022 }
1955 ret = 0; 2023 ret = 0;
1956 break; 2024 break;
1957 default: 2025 default:
@@ -2018,7 +2086,7 @@ void btrfs_destroy_cachep(void)
2018 kmem_cache_destroy(btrfs_path_cachep); 2086 kmem_cache_destroy(btrfs_path_cachep);
2019} 2087}
2020 2088
2021static struct kmem_cache *cache_create(const char *name, size_t size, 2089struct kmem_cache *btrfs_cache_create(const char *name, size_t size,
2022 unsigned long extra_flags, 2090 unsigned long extra_flags,
2023 void (*ctor)(void *, struct kmem_cache *, 2091 void (*ctor)(void *, struct kmem_cache *,
2024 unsigned long)) 2092 unsigned long))
@@ -2033,27 +2101,28 @@ static struct kmem_cache *cache_create(const char *name, size_t size,
2033 2101
2034int btrfs_init_cachep(void) 2102int btrfs_init_cachep(void)
2035{ 2103{
2036 btrfs_inode_cachep = cache_create("btrfs_inode_cache", 2104 btrfs_inode_cachep = btrfs_cache_create("btrfs_inode_cache",
2037 sizeof(struct btrfs_inode), 2105 sizeof(struct btrfs_inode),
2038 0, init_once); 2106 0, init_once);
2039 if (!btrfs_inode_cachep) 2107 if (!btrfs_inode_cachep)
2040 goto fail; 2108 goto fail;
2041 btrfs_trans_handle_cachep = cache_create("btrfs_trans_handle_cache", 2109 btrfs_trans_handle_cachep =
2042 sizeof(struct btrfs_trans_handle), 2110 btrfs_cache_create("btrfs_trans_handle_cache",
2043 0, NULL); 2111 sizeof(struct btrfs_trans_handle),
2112 0, NULL);
2044 if (!btrfs_trans_handle_cachep) 2113 if (!btrfs_trans_handle_cachep)
2045 goto fail; 2114 goto fail;
2046 btrfs_transaction_cachep = cache_create("btrfs_transaction_cache", 2115 btrfs_transaction_cachep = btrfs_cache_create("btrfs_transaction_cache",
2047 sizeof(struct btrfs_transaction), 2116 sizeof(struct btrfs_transaction),
2048 0, NULL); 2117 0, NULL);
2049 if (!btrfs_transaction_cachep) 2118 if (!btrfs_transaction_cachep)
2050 goto fail; 2119 goto fail;
2051 btrfs_path_cachep = cache_create("btrfs_path_cache", 2120 btrfs_path_cachep = btrfs_cache_create("btrfs_path_cache",
2052 sizeof(struct btrfs_transaction), 2121 sizeof(struct btrfs_transaction),
2053 0, NULL); 2122 0, NULL);
2054 if (!btrfs_path_cachep) 2123 if (!btrfs_path_cachep)
2055 goto fail; 2124 goto fail;
2056 btrfs_bit_radix_cachep = cache_create("btrfs_radix", 256, 2125 btrfs_bit_radix_cachep = btrfs_cache_create("btrfs_radix", 256,
2057 SLAB_DESTROY_BY_RCU, NULL); 2126 SLAB_DESTROY_BY_RCU, NULL);
2058 if (!btrfs_bit_radix_cachep) 2127 if (!btrfs_bit_radix_cachep)
2059 goto fail; 2128 goto fail;