~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to fs/btrfs/delayed-ref.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
281
281
}
282
282
 
283
283
/*
284
 
 * This checks to see if there are any delayed refs in the
285
 
 * btree for a given bytenr.  It returns one if it finds any
286
 
 * and zero otherwise.
287
 
 *
288
 
 * If it only finds a head node, it returns 0.
289
 
 *
290
 
 * The idea is to use this when deciding if you can safely delete an
291
 
 * extent from the extent allocation tree.  There may be a pending
292
 
 * ref in the rbtree that adds or removes references, so as long as this
293
 
 * returns one you need to leave the BTRFS_EXTENT_ITEM in the extent
294
 
 * allocation tree.
295
 
 */
296
 
int btrfs_delayed_ref_pending(struct btrfs_trans_handle *trans, u64 bytenr)
297
 
{
298
 
        struct btrfs_delayed_ref_node *ref;
299
 
        struct btrfs_delayed_ref_root *delayed_refs;
300
 
        struct rb_node *prev_node;
301
 
        int ret = 0;
302
 
 
303
 
        delayed_refs = &trans->transaction->delayed_refs;
304
 
        spin_lock(&delayed_refs->lock);
305
 
 
306
 
        ref = find_ref_head(&delayed_refs->root, bytenr, NULL);
307
 
        if (ref) {
308
 
                prev_node = rb_prev(&ref->rb_node);
309
 
                if (!prev_node)
310
 
                        goto out;
311
 
                ref = rb_entry(prev_node, struct btrfs_delayed_ref_node,
312
 
                               rb_node);
313
 
                if (ref->bytenr == bytenr)
314
 
                        ret = 1;
315
 
        }
316
 
out:
317
 
        spin_unlock(&delayed_refs->lock);
318
 
        return ret;
319
 
}
320
 
 
321
 
/*
322
284
 * helper function to update an extent delayed ref in the
323
285
 * rbtree.  existing and update must both have the same
324
286
 * bytenr and parent
483
445
        INIT_LIST_HEAD(&head_ref->cluster);
484
446
        mutex_init(&head_ref->mutex);
485
447
 
 
448
        trace_btrfs_delayed_ref_head(ref, head_ref, action);
 
449
 
486
450
        existing = tree_insert(&delayed_refs->root, &ref->rb_node);
487
451
 
488
452
        if (existing) {
537
501
        }
538
502
        full_ref->level = level;
539
503
 
 
504
        trace_btrfs_delayed_tree_ref(ref, full_ref, action);
 
505
 
540
506
        existing = tree_insert(&delayed_refs->root, &ref->rb_node);
541
507
 
542
508
        if (existing) {
591
557
        full_ref->objectid = owner;
592
558
        full_ref->offset = offset;
593
559
 
 
560
        trace_btrfs_delayed_data_ref(ref, full_ref, action);
 
561
 
594
562
        existing = tree_insert(&delayed_refs->root, &ref->rb_node);
595
563
 
596
564
        if (existing) {
741
709
                return btrfs_delayed_node_to_head(ref);
742
710
        return NULL;
743
711
}
744
 
 
745
 
/*
746
 
 * add a delayed ref to the tree.  This does all of the accounting required
747
 
 * to make sure the delayed ref is eventually processed before this
748
 
 * transaction commits.
749
 
 *
750
 
 * The main point of this call is to add and remove a backreference in a single
751
 
 * shot, taking the lock only once, and only searching for the head node once.
752
 
 *
753
 
 * It is the same as doing a ref add and delete in two separate calls.
754
 
 */
755
 
#if 0
756
 
int btrfs_update_delayed_ref(struct btrfs_trans_handle *trans,
757
 
                          u64 bytenr, u64 num_bytes, u64 orig_parent,
758
 
                          u64 parent, u64 orig_ref_root, u64 ref_root,
759
 
                          u64 orig_ref_generation, u64 ref_generation,
760
 
                          u64 owner_objectid, int pin)
761
 
{
762
 
        struct btrfs_delayed_ref *ref;
763
 
        struct btrfs_delayed_ref *old_ref;
764
 
        struct btrfs_delayed_ref_head *head_ref;
765
 
        struct btrfs_delayed_ref_root *delayed_refs;
766
 
        int ret;
767
 
 
768
 
        ref = kmalloc(sizeof(*ref), GFP_NOFS);
769
 
        if (!ref)
770
 
                return -ENOMEM;
771
 
 
772
 
        old_ref = kmalloc(sizeof(*old_ref), GFP_NOFS);
773
 
        if (!old_ref) {
774
 
                kfree(ref);
775
 
                return -ENOMEM;
776
 
        }
777
 
 
778
 
        /*
779
 
         * the parent = 0 case comes from cases where we don't actually
780
 
         * know the parent yet.  It will get updated later via a add/drop
781
 
         * pair.
782
 
         */
783
 
        if (parent == 0)
784
 
                parent = bytenr;
785
 
        if (orig_parent == 0)
786
 
                orig_parent = bytenr;
787
 
 
788
 
        head_ref = kmalloc(sizeof(*head_ref), GFP_NOFS);
789
 
        if (!head_ref) {
790
 
                kfree(ref);
791
 
                kfree(old_ref);
792
 
                return -ENOMEM;
793
 
        }
794
 
        delayed_refs = &trans->transaction->delayed_refs;
795
 
        spin_lock(&delayed_refs->lock);
796
 
 
797
 
        /*
798
 
         * insert both the head node and the new ref without dropping
799
 
         * the spin lock
800
 
         */
801
 
        ret = __btrfs_add_delayed_ref(trans, &head_ref->node, bytenr, num_bytes,
802
 
                                      (u64)-1, 0, 0, 0,
803
 
                                      BTRFS_UPDATE_DELAYED_HEAD, 0);
804
 
        BUG_ON(ret);
805
 
 
806
 
        ret = __btrfs_add_delayed_ref(trans, &ref->node, bytenr, num_bytes,
807
 
                                      parent, ref_root, ref_generation,
808
 
                                      owner_objectid, BTRFS_ADD_DELAYED_REF, 0);
809
 
        BUG_ON(ret);
810
 
 
811
 
        ret = __btrfs_add_delayed_ref(trans, &old_ref->node, bytenr, num_bytes,
812
 
                                      orig_parent, orig_ref_root,
813
 
                                      orig_ref_generation, owner_objectid,
814
 
                                      BTRFS_DROP_DELAYED_REF, pin);
815
 
        BUG_ON(ret);
816
 
        spin_unlock(&delayed_refs->lock);
817
 
        return 0;
818
 
}
819
 
#endif