diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-12-17 20:14:01 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:03:58 -0400 |
commit | be20aa9dbadc8c06283784ee12bbc0d97dea3418 (patch) | |
tree | 52bd8b7e21b36d10dbb48f8b163eea992c9cfd4a /fs/btrfs/ctree.c | |
parent | b6cda9bcb4df7544c67fc3548a53bc1607d59f46 (diff) |
Btrfs: Add mount option to turn off data cow
A number of workloads do not require copy on write data or checksumming.
mount -o nodatasum to disable checksums and -o nodatacow to disable
both copy on write and checksumming.
In nodatacow mode, copy on write is still performed when a given extent
is under snapshot.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r-- | fs/btrfs/ctree.c | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index fd8233e05cf4..585f279d1112 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -70,7 +70,58 @@ void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p) | |||
70 | memset(p, 0, sizeof(*p)); | 70 | memset(p, 0, sizeof(*p)); |
71 | } | 71 | } |
72 | 72 | ||
73 | static int __btrfs_cow_block(struct btrfs_trans_handle *trans, | 73 | int btrfs_copy_root(struct btrfs_trans_handle *trans, |
74 | struct btrfs_root *root, | ||
75 | struct extent_buffer *buf, | ||
76 | struct extent_buffer **cow_ret, u64 new_root_objectid) | ||
77 | { | ||
78 | struct extent_buffer *cow; | ||
79 | u32 nritems; | ||
80 | int ret = 0; | ||
81 | int level; | ||
82 | struct btrfs_key first_key; | ||
83 | struct btrfs_root new_root; | ||
84 | |||
85 | memcpy(&new_root, root, sizeof(new_root)); | ||
86 | new_root.root_key.objectid = new_root_objectid; | ||
87 | |||
88 | WARN_ON(root->ref_cows && trans->transid != | ||
89 | root->fs_info->running_transaction->transid); | ||
90 | WARN_ON(root->ref_cows && trans->transid != root->last_trans); | ||
91 | |||
92 | level = btrfs_header_level(buf); | ||
93 | nritems = btrfs_header_nritems(buf); | ||
94 | if (nritems) { | ||
95 | if (level == 0) | ||
96 | btrfs_item_key_to_cpu(buf, &first_key, 0); | ||
97 | else | ||
98 | btrfs_node_key_to_cpu(buf, &first_key, 0); | ||
99 | } else { | ||
100 | first_key.objectid = 0; | ||
101 | } | ||
102 | cow = __btrfs_alloc_free_block(trans, &new_root, buf->len, | ||
103 | new_root_objectid, | ||
104 | trans->transid, first_key.objectid, | ||
105 | level, buf->start, 0); | ||
106 | if (IS_ERR(cow)) | ||
107 | return PTR_ERR(cow); | ||
108 | |||
109 | copy_extent_buffer(cow, buf, 0, 0, cow->len); | ||
110 | btrfs_set_header_bytenr(cow, cow->start); | ||
111 | btrfs_set_header_generation(cow, trans->transid); | ||
112 | btrfs_set_header_owner(cow, new_root_objectid); | ||
113 | |||
114 | WARN_ON(btrfs_header_generation(buf) > trans->transid); | ||
115 | ret = btrfs_inc_ref(trans, &new_root, buf); | ||
116 | if (ret) | ||
117 | return ret; | ||
118 | |||
119 | btrfs_mark_buffer_dirty(cow); | ||
120 | *cow_ret = cow; | ||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | int __btrfs_cow_block(struct btrfs_trans_handle *trans, | ||
74 | struct btrfs_root *root, | 125 | struct btrfs_root *root, |
75 | struct extent_buffer *buf, | 126 | struct extent_buffer *buf, |
76 | struct extent_buffer *parent, int parent_slot, | 127 | struct extent_buffer *parent, int parent_slot, |