aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ordered-data.c
diff options
context:
space:
mode:
authorYan Zheng <zheng.yan@oracle.com>2008-08-05 13:05:02 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:06 -0400
commit7ea394f1192bee1af67ea4762c88ef4b7b0487a8 (patch)
treee2c593d054d802bc71e86508a5b7523ff80cc1ea /fs/btrfs/ordered-data.c
parent00e4e6b33a0f78aab4b788d6d31c884fd8bf88da (diff)
Btrfs: Fix nodatacow for the new data=ordered mode
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ordered-data.c')
-rw-r--r--fs/btrfs/ordered-data.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index db200e6baf7..da6d43eb41d 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -152,7 +152,7 @@ static inline struct rb_node *tree_search(struct btrfs_ordered_inode_tree *tree,
152 * inserted. 152 * inserted.
153 */ 153 */
154int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, 154int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
155 u64 start, u64 len) 155 u64 start, u64 len, int nocow)
156{ 156{
157 struct btrfs_ordered_inode_tree *tree; 157 struct btrfs_ordered_inode_tree *tree;
158 struct rb_node *node; 158 struct rb_node *node;
@@ -168,6 +168,8 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
168 entry->start = start; 168 entry->start = start;
169 entry->len = len; 169 entry->len = len;
170 entry->inode = inode; 170 entry->inode = inode;
171 if (nocow)
172 set_bit(BTRFS_ORDERED_NOCOW, &entry->flags);
171 173
172 /* one ref for the tree */ 174 /* one ref for the tree */
173 atomic_set(&entry->refs, 1); 175 atomic_set(&entry->refs, 1);
@@ -303,10 +305,11 @@ int btrfs_remove_ordered_extent(struct inode *inode,
303 return 0; 305 return 0;
304} 306}
305 307
306int btrfs_wait_ordered_extents(struct btrfs_root *root) 308int btrfs_wait_ordered_extents(struct btrfs_root *root, int nocow_only)
307{ 309{
308 struct list_head splice; 310 struct list_head splice;
309 struct list_head *cur; 311 struct list_head *cur;
312 struct list_head *tmp;
310 struct btrfs_ordered_extent *ordered; 313 struct btrfs_ordered_extent *ordered;
311 struct inode *inode; 314 struct inode *inode;
312 315
@@ -314,10 +317,16 @@ int btrfs_wait_ordered_extents(struct btrfs_root *root)
314 317
315 spin_lock(&root->fs_info->ordered_extent_lock); 318 spin_lock(&root->fs_info->ordered_extent_lock);
316 list_splice_init(&root->fs_info->ordered_extents, &splice); 319 list_splice_init(&root->fs_info->ordered_extents, &splice);
317 while(!list_empty(&splice)) { 320 list_for_each_safe(cur, tmp, &splice) {
318 cur = splice.next; 321 cur = splice.next;
319 ordered = list_entry(cur, struct btrfs_ordered_extent, 322 ordered = list_entry(cur, struct btrfs_ordered_extent,
320 root_extent_list); 323 root_extent_list);
324 if (nocow_only &&
325 !test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags)) {
326 cond_resched_lock(&root->fs_info->ordered_extent_lock);
327 continue;
328 }
329
321 list_del_init(&ordered->root_extent_list); 330 list_del_init(&ordered->root_extent_list);
322 atomic_inc(&ordered->refs); 331 atomic_inc(&ordered->refs);
323 inode = ordered->inode; 332 inode = ordered->inode;
@@ -338,6 +347,7 @@ int btrfs_wait_ordered_extents(struct btrfs_root *root)
338 347
339 spin_lock(&root->fs_info->ordered_extent_lock); 348 spin_lock(&root->fs_info->ordered_extent_lock);
340 } 349 }
350 list_splice_init(&splice, &root->fs_info->ordered_extents);
341 spin_unlock(&root->fs_info->ordered_extent_lock); 351 spin_unlock(&root->fs_info->ordered_extent_lock);
342 return 0; 352 return 0;
343} 353}