summaryrefslogtreecommitdiff
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-10-15 16:18:25 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:03:56 -0400
commit3326d1b07c0cb6a2ff5b835b7a2cffa54124d074 (patch)
tree16db275e3e8edb35e46fdd9f9a0f3a1c377ada5f /fs/btrfs/inode.c
parent4dc119046d0d8501afa4346472917fb05586ad9c (diff)
downloadlwn-3326d1b07c0cb6a2ff5b835b7a2cffa54124d074.tar.gz
lwn-3326d1b07c0cb6a2ff5b835b7a2cffa54124d074.zip
Btrfs: Allow tails larger than one page
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index d6b3a55ed8e0..84f496c838c9 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -87,7 +87,7 @@ static int run_delalloc_range(struct inode *inode, u64 start, u64 end)
BUG_ON(!trans);
num_bytes = (end - start + blocksize) & ~(blocksize - 1);
ret = btrfs_drop_extents(trans, root, inode,
- start, start + num_bytes, &alloc_hint);
+ start, start + num_bytes, start, &alloc_hint);
ret = btrfs_alloc_extent(trans, root, inode->i_ino, num_bytes, 0,
alloc_hint, (u64)-1, &ins, 1);
@@ -776,7 +776,8 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
trans = btrfs_start_transaction(root, 1);
btrfs_set_trans_block_group(trans, inode);
err = btrfs_drop_extents(trans, root, inode,
- pos, pos + hole_size, &alloc_hint);
+ pos, pos + hole_size, pos,
+ &alloc_hint);
err = btrfs_insert_file_extent(trans, root, inode->i_ino,
pos, 0, 0, hole_size);
@@ -1581,7 +1582,9 @@ again:
} else if (found_type == BTRFS_FILE_EXTENT_INLINE) {
unsigned long ptr;
char *map;
- u32 size;
+ size_t size;
+ size_t extent_offset;
+ size_t copy_size;
size = btrfs_file_extent_inline_len(leaf, btrfs_item_nr(leaf,
path->slots[0]));
@@ -1600,26 +1603,31 @@ again:
goto not_found_em;
}
+ extent_offset = (page->index << PAGE_CACHE_SHIFT) -
+ extent_start;
+ ptr = btrfs_file_extent_inline_start(item) + extent_offset;
+ map = kmap(page);
+ copy_size = min(PAGE_CACHE_SIZE - page_offset,
+ size - extent_offset);
+
em->block_start = EXTENT_MAP_INLINE;
em->block_end = EXTENT_MAP_INLINE;
- em->start = extent_start;
- em->end = extent_end;
+ em->start = extent_start + extent_offset;
+ em->end = (em->start + copy_size -1) |
+ ((u64)root->sectorsize -1);
if (!page) {
goto insert;
}
- ptr = btrfs_file_extent_inline_start(item);
- map = kmap(page);
- read_extent_buffer(leaf, map + page_offset, ptr, size);
+ read_extent_buffer(leaf, map + page_offset, ptr, copy_size);
/*
- memset(map + page_offset + size, 0,
- root->sectorsize - (page_offset + size));
+ memset(map + page_offset + copy_size, 0,
+ PAGE_CACHE_SIZE - copy_size - page_offset);
*/
flush_dcache_page(page);
kunmap(page);
- set_extent_uptodate(em_tree, extent_start,
- extent_end, GFP_NOFS);
+ set_extent_uptodate(em_tree, em->start, em->end, GFP_NOFS);
goto insert;
} else {
printk("unkknown found_type %d\n", found_type);