diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-27 13:43:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-27 13:43:44 -0400 |
commit | 105a048a4f35f7a74c7cc20b36dd83658b6ec232 (patch) | |
tree | 043b1110cda0042ba35d8aae59382bb094d0af3f /fs/btrfs/delayed-ref.c | |
parent | 00b9b0af5887fed54e899e3b7f5c2ccf5e739def (diff) | |
parent | 9aeead73782c4b8e2a91def36dbf95db28605c95 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
* git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable: (27 commits)
Btrfs: add more error checking to btrfs_dirty_inode
Btrfs: allow unaligned DIO
Btrfs: drop verbose enospc printk
Btrfs: Fix block generation verification race
Btrfs: fix preallocation and nodatacow checks in O_DIRECT
Btrfs: avoid ENOSPC errors in btrfs_dirty_inode
Btrfs: move O_DIRECT space reservation to btrfs_direct_IO
Btrfs: rework O_DIRECT enospc handling
Btrfs: use async helpers for DIO write checksumming
Btrfs: don't walk around with task->state != TASK_RUNNING
Btrfs: do aio_write instead of write
Btrfs: add basic DIO read/write support
direct-io: do not merge logically non-contiguous requests
direct-io: add a hook for the fs to provide its own submit_bio function
fs: allow short direct-io reads to be completed via buffered IO
Btrfs: Metadata ENOSPC handling for balance
Btrfs: Pre-allocate space for data relocation
Btrfs: Metadata ENOSPC handling for tree log
Btrfs: Metadata reservation for orphan inodes
Btrfs: Introduce global metadata reservation
...
Diffstat (limited to 'fs/btrfs/delayed-ref.c')
-rw-r--r-- | fs/btrfs/delayed-ref.c | 101 |
1 files changed, 0 insertions, 101 deletions
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c index 902ce507c4e3..e807b143b857 100644 --- a/fs/btrfs/delayed-ref.c +++ b/fs/btrfs/delayed-ref.c | |||
@@ -319,107 +319,6 @@ out: | |||
319 | } | 319 | } |
320 | 320 | ||
321 | /* | 321 | /* |
322 | * helper function to lookup reference count and flags of extent. | ||
323 | * | ||
324 | * the head node for delayed ref is used to store the sum of all the | ||
325 | * reference count modifications queued up in the rbtree. the head | ||
326 | * node may also store the extent flags to set. This way you can check | ||
327 | * to see what the reference count and extent flags would be if all of | ||
328 | * the delayed refs are not processed. | ||
329 | */ | ||
330 | int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, | ||
331 | struct btrfs_root *root, u64 bytenr, | ||
332 | u64 num_bytes, u64 *refs, u64 *flags) | ||
333 | { | ||
334 | struct btrfs_delayed_ref_node *ref; | ||
335 | struct btrfs_delayed_ref_head *head; | ||
336 | struct btrfs_delayed_ref_root *delayed_refs; | ||
337 | struct btrfs_path *path; | ||
338 | struct btrfs_extent_item *ei; | ||
339 | struct extent_buffer *leaf; | ||
340 | struct btrfs_key key; | ||
341 | u32 item_size; | ||
342 | u64 num_refs; | ||
343 | u64 extent_flags; | ||
344 | int ret; | ||
345 | |||
346 | path = btrfs_alloc_path(); | ||
347 | if (!path) | ||
348 | return -ENOMEM; | ||
349 | |||
350 | key.objectid = bytenr; | ||
351 | key.type = BTRFS_EXTENT_ITEM_KEY; | ||
352 | key.offset = num_bytes; | ||
353 | delayed_refs = &trans->transaction->delayed_refs; | ||
354 | again: | ||
355 | ret = btrfs_search_slot(trans, root->fs_info->extent_root, | ||
356 | &key, path, 0, 0); | ||
357 | if (ret < 0) | ||
358 | goto out; | ||
359 | |||
360 | if (ret == 0) { | ||
361 | leaf = path->nodes[0]; | ||
362 | item_size = btrfs_item_size_nr(leaf, path->slots[0]); | ||
363 | if (item_size >= sizeof(*ei)) { | ||
364 | ei = btrfs_item_ptr(leaf, path->slots[0], | ||
365 | struct btrfs_extent_item); | ||
366 | num_refs = btrfs_extent_refs(leaf, ei); | ||
367 | extent_flags = btrfs_extent_flags(leaf, ei); | ||
368 | } else { | ||
369 | #ifdef BTRFS_COMPAT_EXTENT_TREE_V0 | ||
370 | struct btrfs_extent_item_v0 *ei0; | ||
371 | BUG_ON(item_size != sizeof(*ei0)); | ||
372 | ei0 = btrfs_item_ptr(leaf, path->slots[0], | ||
373 | struct btrfs_extent_item_v0); | ||
374 | num_refs = btrfs_extent_refs_v0(leaf, ei0); | ||
375 | /* FIXME: this isn't correct for data */ | ||
376 | extent_flags = BTRFS_BLOCK_FLAG_FULL_BACKREF; | ||
377 | #else | ||
378 | BUG(); | ||
379 | #endif | ||
380 | } | ||
381 | BUG_ON(num_refs == 0); | ||
382 | } else { | ||
383 | num_refs = 0; | ||
384 | extent_flags = 0; | ||
385 | ret = 0; | ||
386 | } | ||
387 | |||
388 | spin_lock(&delayed_refs->lock); | ||
389 | ref = find_ref_head(&delayed_refs->root, bytenr, NULL); | ||
390 | if (ref) { | ||
391 | head = btrfs_delayed_node_to_head(ref); | ||
392 | if (!mutex_trylock(&head->mutex)) { | ||
393 | atomic_inc(&ref->refs); | ||
394 | spin_unlock(&delayed_refs->lock); | ||
395 | |||
396 | btrfs_release_path(root->fs_info->extent_root, path); | ||
397 | |||
398 | mutex_lock(&head->mutex); | ||
399 | mutex_unlock(&head->mutex); | ||
400 | btrfs_put_delayed_ref(ref); | ||
401 | goto again; | ||
402 | } | ||
403 | if (head->extent_op && head->extent_op->update_flags) | ||
404 | extent_flags |= head->extent_op->flags_to_set; | ||
405 | else | ||
406 | BUG_ON(num_refs == 0); | ||
407 | |||
408 | num_refs += ref->ref_mod; | ||
409 | mutex_unlock(&head->mutex); | ||
410 | } | ||
411 | WARN_ON(num_refs == 0); | ||
412 | if (refs) | ||
413 | *refs = num_refs; | ||
414 | if (flags) | ||
415 | *flags = extent_flags; | ||
416 | out: | ||
417 | spin_unlock(&delayed_refs->lock); | ||
418 | btrfs_free_path(path); | ||
419 | return ret; | ||
420 | } | ||
421 | |||
422 | /* | ||
423 | * helper function to update an extent delayed ref in the | 322 | * helper function to update an extent delayed ref in the |
424 | * rbtree. existing and update must both have the same | 323 | * rbtree. existing and update must both have the same |
425 | * bytenr and parent | 324 | * bytenr and parent |