aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/ctree.h1
-rw-r--r--fs/btrfs/disk-io.c1
-rw-r--r--fs/btrfs/inode.c28
-rw-r--r--fs/btrfs/super.c46
4 files changed, 65 insertions, 11 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index b51b021fff85..32b24460ec82 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -322,6 +322,7 @@ struct btrfs_fs_info {
322 u64 generation; 322 u64 generation;
323 u64 last_trans_committed; 323 u64 last_trans_committed;
324 unsigned long mount_opt; 324 unsigned long mount_opt;
325 u64 max_extent;
325 struct btrfs_transaction *running_transaction; 326 struct btrfs_transaction *running_transaction;
326 struct btrfs_super_block super_copy; 327 struct btrfs_super_block super_copy;
327 struct extent_buffer *sb_buffer; 328 struct extent_buffer *sb_buffer;
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 278564178993..7213012c27d5 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -569,6 +569,7 @@ struct btrfs_root *open_ctree(struct super_block *sb)
569 fs_info->extent_root = extent_root; 569 fs_info->extent_root = extent_root;
570 fs_info->sb = sb; 570 fs_info->sb = sb;
571 fs_info->mount_opt = 0; 571 fs_info->mount_opt = 0;
572 fs_info->max_extent = (u64)-1;
572 fs_info->btree_inode = new_inode(sb); 573 fs_info->btree_inode = new_inode(sb);
573 fs_info->btree_inode->i_ino = 1; 574 fs_info->btree_inode->i_ino = 1;
574 fs_info->btree_inode->i_nlink = 1; 575 fs_info->btree_inode->i_nlink = 1;
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)
78 struct btrfs_trans_handle *trans; 78 struct btrfs_trans_handle *trans;
79 u64 alloc_hint = 0; 79 u64 alloc_hint = 0;
80 u64 num_bytes; 80 u64 num_bytes;
81 u64 cur_alloc_size;
81 u64 blocksize = root->sectorsize; 82 u64 blocksize = root->sectorsize;
82 struct btrfs_key ins; 83 struct btrfs_key ins;
83 int ret; 84 int ret;
@@ -94,17 +95,24 @@ static int cow_file_range(struct inode *inode, u64 start, u64 end)
94 if (alloc_hint == EXTENT_MAP_INLINE) 95 if (alloc_hint == EXTENT_MAP_INLINE)
95 goto out; 96 goto out;
96 97
97 ret = btrfs_alloc_extent(trans, root, num_bytes, 98 while(num_bytes > 0) {
98 root->root_key.objectid, trans->transid, 99 cur_alloc_size = min(num_bytes, root->fs_info->max_extent);
99 inode->i_ino, start, 0, 100 ret = btrfs_alloc_extent(trans, root, cur_alloc_size,
100 alloc_hint, (u64)-1, &ins, 1); 101 root->root_key.objectid,
101 if (ret) { 102 trans->transid,
102 WARN_ON(1); 103 inode->i_ino, start, 0,
103 goto out; 104 alloc_hint, (u64)-1, &ins, 1);
105 if (ret) {
106 WARN_ON(1);
107 goto out;
108 }
109 ret = btrfs_insert_file_extent(trans, root, inode->i_ino,
110 start, ins.objectid, ins.offset,
111 ins.offset);
112 num_bytes -= cur_alloc_size;
113 alloc_hint = ins.objectid + ins.offset;
114 start += cur_alloc_size;
104 } 115 }
105 ret = btrfs_insert_file_extent(trans, root, inode->i_ino,
106 start, ins.objectid, ins.offset,
107 ins.offset);
108out: 116out:
109 btrfs_end_transaction(trans, root); 117 btrfs_end_transaction(trans, root);
110 return ret; 118 return ret;
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 2116728d1f98..b7323914bf5a 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -34,6 +34,7 @@
34#include <linux/statfs.h> 34#include <linux/statfs.h>
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 "ctree.h" 38#include "ctree.h"
38#include "disk-io.h" 39#include "disk-io.h"
39#include "transaction.h" 40#include "transaction.h"
@@ -61,16 +62,42 @@ static void btrfs_put_super (struct super_block * sb)
61} 62}
62 63
63enum { 64enum {
64 Opt_subvol, Opt_nodatasum, Opt_nodatacow, Opt_err, 65 Opt_subvol, Opt_nodatasum, Opt_nodatacow, Opt_max_extent, Opt_err,
65}; 66};
66 67
67static match_table_t tokens = { 68static match_table_t tokens = {
68 {Opt_subvol, "subvol=%s"}, 69 {Opt_subvol, "subvol=%s"},
69 {Opt_nodatasum, "nodatasum"}, 70 {Opt_nodatasum, "nodatasum"},
70 {Opt_nodatacow, "nodatacow"}, 71 {Opt_nodatacow, "nodatacow"},
72 {Opt_max_extent, "max_extent=%s"},
71 {Opt_err, NULL} 73 {Opt_err, NULL}
72}; 74};
73 75
76static unsigned long parse_size(char *str)
77{
78 unsigned long res;
79 int mult = 1;
80 char *end;
81 char last;
82
83 res = simple_strtoul(str, &end, 10);
84
85 last = end[0];
86 if (isalpha(last)) {
87 last = tolower(last);
88 switch (last) {
89 case 'g':
90 mult *= 1024;
91 case 'm':
92 mult *= 1024;
93 case 'k':
94 mult *= 1024;
95 }
96 res = res * mult;
97 }
98 return res;
99}
100
74static int parse_options (char * options, 101static int parse_options (char * options,
75 struct btrfs_root *root, 102 struct btrfs_root *root,
76 char **subvol_name) 103 char **subvol_name)
@@ -118,6 +145,21 @@ static int parse_options (char * options,
118 btrfs_set_opt(info->mount_opt, NODATASUM); 145 btrfs_set_opt(info->mount_opt, NODATASUM);
119 } 146 }
120 break; 147 break;
148 case Opt_max_extent:
149 if (info) {
150 char *num = match_strdup(&args[0]);
151 if (num) {
152 info->max_extent = parse_size(num);
153 kfree(num);
154
155 info->max_extent = max_t(u64,
156 info->max_extent,
157 root->sectorsize);
158 printk("btrfs: max_extent at %Lu\n",
159 info->max_extent);
160 }
161 }
162 break;
121 default: 163 default:
122 break; 164 break;
123 } 165 }
@@ -329,6 +371,8 @@ static int btrfs_get_sb(struct file_system_type *fs_type,
329 ret = btrfs_get_sb_bdev(fs_type, flags, dev_name, data, 371 ret = btrfs_get_sb_bdev(fs_type, flags, dev_name, data,
330 btrfs_fill_super, mnt, 372 btrfs_fill_super, mnt,
331 subvol_name ? subvol_name : "default"); 373 subvol_name ? subvol_name : "default");
374 if (subvol_name)
375 kfree(subvol_name);
332 return ret; 376 return ret;
333} 377}
334 378