summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorChris Mason2007-12-18 02:14:04 +0100
committerChris Mason2008-09-25 17:03:58 +0200
commitc59f8951d48c5eb000926935f3ab063d8181d1ee (patch)
treeddf1e3ecb8a03fc30add98ee263c23eb6d382621 /fs/btrfs/inode.c
parentBtrfs: Fix extent_map and extent_state leaks by flushing lrus on FS unmount (diff)
downloadkernel-qcow2-linux-c59f8951d48c5eb000926935f3ab063d8181d1ee.tar.gz
kernel-qcow2-linux-c59f8951d48c5eb000926935f3ab063d8181d1ee.tar.xz
kernel-qcow2-linux-c59f8951d48c5eb000926935f3ab063d8181d1ee.zip
Btrfs: Add mount option to enforce a max extent size
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 91f3fc43e2a9..686dd03f34f2 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -78,6 +78,7 @@ static int cow_file_range(struct inode *inode, u64 start, u64 end)
struct btrfs_trans_handle *trans;
u64 alloc_hint = 0;
u64 num_bytes;
+ u64 cur_alloc_size;
u64 blocksize = root->sectorsize;
struct btrfs_key ins;
int ret;
@@ -94,17 +95,24 @@ static int cow_file_range(struct inode *inode, u64 start, u64 end)
if (alloc_hint == EXTENT_MAP_INLINE)
goto out;
- ret = btrfs_alloc_extent(trans, root, num_bytes,
- root->root_key.objectid, trans->transid,
- inode->i_ino, start, 0,
- alloc_hint, (u64)-1, &ins, 1);
- if (ret) {
- WARN_ON(1);
- goto out;
+ while(num_bytes > 0) {
+ cur_alloc_size = min(num_bytes, root->fs_info->max_extent);
+ ret = btrfs_alloc_extent(trans, root, cur_alloc_size,
+ root->root_key.objectid,
+ trans->transid,
+ inode->i_ino, start, 0,
+ alloc_hint, (u64)-1, &ins, 1);
+ if (ret) {
+ WARN_ON(1);
+ goto out;
+ }
+ ret = btrfs_insert_file_extent(trans, root, inode->i_ino,
+ start, ins.objectid, ins.offset,
+ ins.offset);
+ num_bytes -= cur_alloc_size;
+ alloc_hint = ins.objectid + ins.offset;
+ start += cur_alloc_size;
}
- ret = btrfs_insert_file_extent(trans, root, inode->i_ino,
- start, ins.objectid, ins.offset,
- ins.offset);
out:
btrfs_end_transaction(trans, root);
return ret;