aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-11-01 11:28:41 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:03:57 -0400
commit179e29e488cc74f1e9bd67bc45f70b832740e9ec (patch)
treeaa055d77b8d3f2b4bc59b1bb8a5b98ec0b223fb5 /fs/btrfs/ctree.c
parent35ebb934bd7fcc7ca991b155b7980c3c4ff9f1a5 (diff)
Btrfs: Fix a number of inline extent problems that Yan Zheng reported.
The fixes do a number of things: 1) Most btrfs_drop_extent callers will try to leave the inline extents in place. It can truncate bytes off the beginning of the inline extent if required. 2) writepage can now update the inline extent, allowing mmap writes to go directly into the inline extent. 3) btrfs_truncate_in_transaction truncates inline extents 4) extent_map.c fixed to not merge inline extent mappings and hole mappings together Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r--fs/btrfs/ctree.c52
1 files changed, 46 insertions, 6 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 516b90224a1b..eef9c92f86d5 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -1930,7 +1930,7 @@ again:
1930int btrfs_truncate_item(struct btrfs_trans_handle *trans, 1930int btrfs_truncate_item(struct btrfs_trans_handle *trans,
1931 struct btrfs_root *root, 1931 struct btrfs_root *root,
1932 struct btrfs_path *path, 1932 struct btrfs_path *path,
1933 u32 new_size) 1933 u32 new_size, int from_end)
1934{ 1934{
1935 int ret = 0; 1935 int ret = 0;
1936 int slot; 1936 int slot;
@@ -1946,13 +1946,17 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans,
1946 1946
1947 slot_orig = path->slots[0]; 1947 slot_orig = path->slots[0];
1948 leaf = path->nodes[0]; 1948 leaf = path->nodes[0];
1949 slot = path->slots[0];
1950
1951 old_size = btrfs_item_size_nr(leaf, slot);
1952 if (old_size == new_size)
1953 return 0;
1949 1954
1950 nritems = btrfs_header_nritems(leaf); 1955 nritems = btrfs_header_nritems(leaf);
1951 data_end = leaf_data_end(root, leaf); 1956 data_end = leaf_data_end(root, leaf);
1952 1957
1953 slot = path->slots[0];
1954 old_data_start = btrfs_item_offset_nr(leaf, slot); 1958 old_data_start = btrfs_item_offset_nr(leaf, slot);
1955 old_size = btrfs_item_size_nr(leaf, slot); BUG_ON(old_size <= new_size); 1959
1956 size_diff = old_size - new_size; 1960 size_diff = old_size - new_size;
1957 1961
1958 BUG_ON(slot < 0); 1962 BUG_ON(slot < 0);
@@ -1984,9 +1988,45 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans,
1984 } 1988 }
1985 1989
1986 /* shift the data */ 1990 /* shift the data */
1987 memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + 1991 if (from_end) {
1988 data_end + size_diff, btrfs_leaf_data(leaf) + 1992 memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) +
1989 data_end, old_data_start + new_size - data_end); 1993 data_end + size_diff, btrfs_leaf_data(leaf) +
1994 data_end, old_data_start + new_size - data_end);
1995 } else {
1996 struct btrfs_disk_key disk_key;
1997 u64 offset;
1998
1999 btrfs_item_key(leaf, &disk_key, slot);
2000
2001 if (btrfs_disk_key_type(&disk_key) == BTRFS_EXTENT_DATA_KEY) {
2002 unsigned long ptr;
2003 struct btrfs_file_extent_item *fi;
2004
2005 fi = btrfs_item_ptr(leaf, slot,
2006 struct btrfs_file_extent_item);
2007 fi = (struct btrfs_file_extent_item *)(
2008 (unsigned long)fi - size_diff);
2009
2010 if (btrfs_file_extent_type(leaf, fi) ==
2011 BTRFS_FILE_EXTENT_INLINE) {
2012 ptr = btrfs_item_ptr_offset(leaf, slot);
2013 memmove_extent_buffer(leaf, ptr,
2014 (unsigned long)fi,
2015 offsetof(struct btrfs_file_extent_item,
2016 disk_bytenr));
2017 }
2018 }
2019
2020 memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) +
2021 data_end + size_diff, btrfs_leaf_data(leaf) +
2022 data_end, old_data_start - data_end);
2023
2024 offset = btrfs_disk_key_offset(&disk_key);
2025 btrfs_set_disk_key_offset(&disk_key, offset + size_diff);
2026 btrfs_set_item_key(leaf, &disk_key, slot);
2027 if (slot == 0)
2028 fixup_low_keys(trans, root, path, &disk_key, 1);
2029 }
1990 2030
1991 item = btrfs_item_nr(leaf, slot); 2031 item = btrfs_item_nr(leaf, slot);
1992 btrfs_set_item_size(leaf, item, new_size); 2032 btrfs_set_item_size(leaf, item, new_size);