• Arne Jansen's avatar
    btrfs: initial readahead code and prototypes · 7414a03f
    Arne Jansen authored
    This is the implementation for the generic read ahead framework.
    
    To trigger a readahead, btrfs_reada_add must be called. It will start
    a read ahead for the given range [start, end) on tree root. The returned
    handle can either be used to wait on the readahead to finish
    (btrfs_reada_wait), or to send it to the background (btrfs_reada_detach).
    
    The read ahead works as follows:
    On btrfs_reada_add, the root of the tree is inserted into a radix_tree.
    reada_start_machine will then search for extents to prefetch and trigger
    some reads. When a read finishes for a node, all contained node/leaf
    pointers that lie in the given range will also be enqueued. The reads will
    be triggered in sequential order, thus giving a big win over a naive
    enumeration. It will also make use of multi-device layouts. Each disk
    will have its on read pointer and all disks will by utilized in parallel.
    Also will no two disks read both sides of a mirror simultaneously, as this
    would waste seeking capacity. Instead both disks will read different parts
    of the filesystem.
    Any number of readaheads can be started in parallel. The read order will be
    determined globally, i.e. 2 parallel readaheads will normally finish faster
    than the 2 started one after another.
    
    Changes v2:
     - protect root->node by transaction instead of node_lock
     - fix missed branches:
        The readahead had a too simple check to determine if a branch from
        a node should be checked or not. It now also records the upper bound
        of each node to see if the requested RA range lies within.
     - use KERN_CONT to debug output, to avoid line breaks
     - defer reada_start_machine to worker to avoid deadlock
    
    Changes v3:
     - protect root->node by rcu
    
    Changes v5:
     - changed EIO-semantics of reada_tree_block_flagged
     - remove spin_lock from reada_control and make elems an atomic_t
     - remove unused read_total from reada_control
     - kill reada_key_cmp, use btrfs_comp_cpu_keys instead
     - use kref-style release functions where possible
     - return struct reada_control * instead of void * from btrfs_reada_add
    Signed-off-by: default avatarArne Jansen <sensille@gmx.net>
    7414a03f
reada.c 23.1 KB