ia64/xen-unstable

changeset 2071:027b642fff57

bitkeeper revision 1.1141 (41100bacOlxYcQPdke8d6QszHxObgQ)

Finish merging the 2.4/2.6 blkdev backend drivers.
author kaf24@scramble.cl.cam.ac.uk
date Tue Aug 03 22:03:24 2004 +0000 (2004-08-03)
parents dd8e4c63f93c
children 14ad99d6f689
files .rootkeys linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/backend/common.h linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/backend/main.c linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/backend/vbd.c linux-2.4.26-xen-sparse/mkbuildtree linux-2.6.7-xen-sparse/drivers/xen/blkback/blkback.c linux-2.6.7-xen-sparse/drivers/xen/blkback/common.h linux-2.6.7-xen-sparse/drivers/xen/blkback/vbd.c
line diff
     1.1 --- a/.rootkeys	Tue Aug 03 20:23:21 2004 +0000
     1.2 +++ b/.rootkeys	Tue Aug 03 22:03:24 2004 +0000
     1.3 @@ -51,9 +51,6 @@ 3e6377f5xwPfYZkPHPrDbEq1PRN7uQ linux-2.4
     1.4  3e6377f8Me8IqtvEhb70XFgOvqQH7A linux-2.4.26-xen-sparse/arch/xen/drivers/balloon/balloon.c
     1.5  4083dc16z0jvZEH4PiVDbDRreaNp6w linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/Makefile
     1.6  4083dc16KQus88a4U3uCV6qVCA6_8Q linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/backend/Makefile
     1.7 -4087cf0dPeHOvzmZAazvwLslKEF93A linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/backend/common.h
     1.8 -4087cf0dkVF3I19gpT1cNubeJgQr7g linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/backend/main.c
     1.9 -4087cf0dlv1Dw4MAbeRStPPG8IvPPg linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/backend/vbd.c
    1.10  4075806dI5kfeMD5RV-DA0PYoThx_w linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/frontend/Makefile
    1.11  4075806d4-j7vN0Mn0bklI1cRUX1vQ linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/frontend/common.h
    1.12  4075806d3fJqqDC1pYYPTZPc575iKg linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/frontend/main.c
     2.1 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/backend/common.h	Tue Aug 03 20:23:21 2004 +0000
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,111 +0,0 @@
     2.4 -/******************************************************************************
     2.5 - * arch/xen/drivers/blkif/backend/common.h
     2.6 - */
     2.7 -
     2.8 -#ifndef __BLKIF__BACKEND__COMMON_H__
     2.9 -#define __BLKIF__BACKEND__COMMON_H__
    2.10 -
    2.11 -#include <linux/config.h>
    2.12 -#include <linux/module.h>
    2.13 -#include <linux/rbtree.h>
    2.14 -#include <linux/interrupt.h>
    2.15 -#include <linux/slab.h>
    2.16 -#include <linux/blkdev.h>
    2.17 -#include <asm/ctrl_if.h>
    2.18 -#include <asm/io.h>
    2.19 -#include <asm-xen/hypervisor-ifs/io/blkif.h>
    2.20 -
    2.21 -#if 0
    2.22 -#define ASSERT(_p) \
    2.23 -    if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
    2.24 -    __LINE__, __FILE__); *(int*)0=0; }
    2.25 -#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
    2.26 -                           __FILE__ , __LINE__ , ## _a )
    2.27 -#else
    2.28 -#define ASSERT(_p) ((void)0)
    2.29 -#define DPRINTK(_f, _a...) ((void)0)
    2.30 -#endif
    2.31 -
    2.32 -#define PRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
    2.33 -                           __FILE__ , __LINE__ , ## _a )
    2.34 -
    2.35 -typedef struct blkif_st {
    2.36 -    /* Unique identifier for this interface. */
    2.37 -    domid_t          domid;
    2.38 -    unsigned int     handle;
    2.39 -    /* Physical parameters of the comms window. */
    2.40 -    unsigned long    shmem_frame;
    2.41 -    unsigned int     evtchn;
    2.42 -    int              irq;
    2.43 -    /* Comms information. */
    2.44 -    blkif_ring_t    *blk_ring_base; /* ioremap()'ed ptr to shmem_frame. */
    2.45 -    BLKIF_RING_IDX     blk_req_cons;  /* Request consumer. */
    2.46 -    BLKIF_RING_IDX     blk_resp_prod; /* Private version of resp. producer. */
    2.47 -    /* VBDs attached to this interface. */
    2.48 -    rb_root_t        vbd_rb;        /* Mapping from 16-bit vdevices to VBDs. */
    2.49 -    spinlock_t       vbd_lock;      /* Protects VBD mapping. */
    2.50 -    /* Private fields. */
    2.51 -    enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
    2.52 -    /*
    2.53 -     * DISCONNECT response is deferred until pending requests are ack'ed.
    2.54 -     * We therefore need to store the id from the original request.
    2.55 -     */
    2.56 -    u8               disconnect_rspid;
    2.57 -    struct blkif_st *hash_next;
    2.58 -    struct list_head blkdev_list;
    2.59 -    spinlock_t       blk_ring_lock;
    2.60 -    atomic_t         refcnt;
    2.61 -} blkif_t;
    2.62 -
    2.63 -void blkif_create(blkif_be_create_t *create);
    2.64 -void blkif_destroy(blkif_be_destroy_t *destroy);
    2.65 -void blkif_connect(blkif_be_connect_t *connect);
    2.66 -int  blkif_disconnect(blkif_be_disconnect_t *disconnect, u8 rsp_id);
    2.67 -void __blkif_disconnect_complete(blkif_t *blkif);
    2.68 -blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle);
    2.69 -#define blkif_get(_b) (atomic_inc(&(_b)->refcnt))
    2.70 -#define blkif_put(_b)                             \
    2.71 -    do {                                          \
    2.72 -        if ( atomic_dec_and_test(&(_b)->refcnt) ) \
    2.73 -            __blkif_disconnect_complete(_b);      \
    2.74 -    } while (0)
    2.75 -
    2.76 -/* An entry in a list of xen_extents. */
    2.77 -typedef struct _blkif_extent_le { 
    2.78 -    blkif_extent_t extent;               /* an individual extent */
    2.79 -    struct _blkif_extent_le *next;       /* and a pointer to the next */ 
    2.80 -} blkif_extent_le_t; 
    2.81 -
    2.82 -typedef struct _vbd { 
    2.83 -    blkif_vdev_t       vdevice;   /* what the domain refers to this vbd as */
    2.84 -    unsigned char      readonly;  /* Non-zero -> read-only */
    2.85 -    unsigned char      type;      /* VDISK_TYPE_xxx */
    2.86 -    blkif_extent_le_t *extents;   /* list of xen_extents making up this vbd */
    2.87 -    rb_node_t          rb;        /* for linking into R-B tree lookup struct */
    2.88 -} vbd_t; 
    2.89 -
    2.90 -void vbd_create(blkif_be_vbd_create_t *create); 
    2.91 -void vbd_grow(blkif_be_vbd_grow_t *grow); 
    2.92 -void vbd_shrink(blkif_be_vbd_shrink_t *shrink);
    2.93 -void vbd_destroy(blkif_be_vbd_destroy_t *delete); 
    2.94 -int vbd_probe(blkif_t *blkif, vdisk_t *vbd_info, int max_vbds);
    2.95 -void destroy_all_vbds(blkif_t *blkif);
    2.96 -
    2.97 -/* Describes a [partial] disk extent (part of a block io request) */
    2.98 -typedef struct {
    2.99 -    unsigned short dev;
   2.100 -    unsigned short nr_sects;
   2.101 -    unsigned long  buffer;
   2.102 -    blkif_sector_t sector_number;
   2.103 -} phys_seg_t;
   2.104 -
   2.105 -int vbd_translate(phys_seg_t *pseg, blkif_t *blkif, int operation); 
   2.106 -
   2.107 -void blkif_interface_init(void);
   2.108 -void blkif_ctrlif_init(void);
   2.109 -
   2.110 -void blkif_deschedule(blkif_t *blkif);
   2.111 -
   2.112 -void blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);
   2.113 -
   2.114 -#endif /* __BLKIF__BACKEND__COMMON_H__ */
     3.1 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/backend/main.c	Tue Aug 03 20:23:21 2004 +0000
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,536 +0,0 @@
     3.4 -/******************************************************************************
     3.5 - * arch/xen/drivers/blkif/backend/main.c
     3.6 - * 
     3.7 - * Back-end of the driver for virtual block devices. This portion of the
     3.8 - * driver exports a 'unified' block-device interface that can be accessed
     3.9 - * by any operating system that implements a compatible front end. A 
    3.10 - * reference front-end implementation can be found in:
    3.11 - *  arch/xen/drivers/blkif/frontend
    3.12 - * 
    3.13 - * Copyright (c) 2003-2004, Keir Fraser & Steve Hand
    3.14 - */
    3.15 -
    3.16 -#include "common.h"
    3.17 -
    3.18 -/*
    3.19 - * These are rather arbitrary. They are fairly large because adjacent requests
    3.20 - * pulled from a communication ring are quite likely to end up being part of
    3.21 - * the same scatter/gather request at the disc.
    3.22 - * 
    3.23 - * ** TRY INCREASING 'MAX_PENDING_REQS' IF WRITE SPEEDS SEEM TOO LOW **
    3.24 - * This will increase the chances of being able to write whole tracks.
    3.25 - * 64 should be enough to keep us competitive with Linux.
    3.26 - */
    3.27 -#define MAX_PENDING_REQS 64
    3.28 -#define BATCH_PER_DOMAIN 16
    3.29 -
    3.30 -/*
    3.31 - * NB. We place a page of padding between each buffer page to avoid incorrect
    3.32 - * merging of requests by the IDE and SCSI merging routines. Otherwise, two
    3.33 - * adjacent buffers in a scatter-gather request would have adjacent page
    3.34 - * numbers: since the merge routines don't realise that this is in *pseudophys*
    3.35 - * space, not real space, they may collapse the s-g elements!
    3.36 - */
    3.37 -static unsigned long mmap_vstart;
    3.38 -#define MMAP_PAGES_PER_REQUEST \
    3.39 -    (2 * (BLKIF_MAX_SEGMENTS_PER_REQUEST + 1))
    3.40 -#define MMAP_PAGES             \
    3.41 -    (MAX_PENDING_REQS * MMAP_PAGES_PER_REQUEST)
    3.42 -#define MMAP_VADDR(_req,_seg)                        \
    3.43 -    (mmap_vstart +                                   \
    3.44 -     ((_req) * MMAP_PAGES_PER_REQUEST * PAGE_SIZE) + \
    3.45 -     ((_seg) * 2 * PAGE_SIZE))
    3.46 -
    3.47 -/*
    3.48 - * Each outstanding request that we've passed to the lower device layers has a 
    3.49 - * 'pending_req' allocated to it. Each buffer_head that completes decrements 
    3.50 - * the pendcnt towards zero. When it hits zero, the specified domain has a 
    3.51 - * response queued for it, with the saved 'id' passed back.
    3.52 - */
    3.53 -typedef struct {
    3.54 -    blkif_t       *blkif;
    3.55 -    unsigned long  id;
    3.56 -    int            nr_pages;
    3.57 -    atomic_t       pendcnt;
    3.58 -    unsigned short operation;
    3.59 -    int            status;
    3.60 -} pending_req_t;
    3.61 -
    3.62 -/*
    3.63 - * We can't allocate pending_req's in order, since they may complete out of 
    3.64 - * order. We therefore maintain an allocation ring. This ring also indicates 
    3.65 - * when enough work has been passed down -- at that point the allocation ring 
    3.66 - * will be empty.
    3.67 - */
    3.68 -static pending_req_t pending_reqs[MAX_PENDING_REQS];
    3.69 -static unsigned char pending_ring[MAX_PENDING_REQS];
    3.70 -static spinlock_t pend_prod_lock = SPIN_LOCK_UNLOCKED;
    3.71 -/* NB. We use a different index type to differentiate from shared blk rings. */
    3.72 -typedef unsigned int PEND_RING_IDX;
    3.73 -#define MASK_PEND_IDX(_i) ((_i)&(MAX_PENDING_REQS-1))
    3.74 -static PEND_RING_IDX pending_prod, pending_cons;
    3.75 -#define NR_PENDING_REQS (MAX_PENDING_REQS - pending_prod + pending_cons)
    3.76 -
    3.77 -static kmem_cache_t *buffer_head_cachep;
    3.78 -
    3.79 -static int do_block_io_op(blkif_t *blkif, int max_to_do);
    3.80 -static void dispatch_probe(blkif_t *blkif, blkif_request_t *req);
    3.81 -static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req);
    3.82 -static void make_response(blkif_t *blkif, unsigned long id, 
    3.83 -                          unsigned short op, int st);
    3.84 -
    3.85 -static void fast_flush_area(int idx, int nr_pages)
    3.86 -{
    3.87 -    multicall_entry_t mcl[MMAP_PAGES_PER_REQUEST];
    3.88 -    int               i;
    3.89 -
    3.90 -    for ( i = 0; i < nr_pages; i++ )
    3.91 -    {
    3.92 -        mcl[i].op = __HYPERVISOR_update_va_mapping;
    3.93 -        mcl[i].args[0] = MMAP_VADDR(idx, i) >> PAGE_SHIFT;
    3.94 -        mcl[i].args[1] = 0;
    3.95 -        mcl[i].args[2] = 0;
    3.96 -    }
    3.97 -
    3.98 -    mcl[nr_pages-1].args[2] = UVMF_FLUSH_TLB;
    3.99 -    if ( unlikely(HYPERVISOR_multicall(mcl, nr_pages) != 0) )
   3.100 -        BUG();
   3.101 -}
   3.102 -
   3.103 -
   3.104 -/******************************************************************
   3.105 - * BLOCK-DEVICE SCHEDULER LIST MAINTENANCE
   3.106 - */
   3.107 -
   3.108 -static struct list_head io_schedule_list;
   3.109 -static spinlock_t io_schedule_list_lock;
   3.110 -
   3.111 -static int __on_blkdev_list(blkif_t *blkif)
   3.112 -{
   3.113 -    return blkif->blkdev_list.next != NULL;
   3.114 -}
   3.115 -
   3.116 -static void remove_from_blkdev_list(blkif_t *blkif)
   3.117 -{
   3.118 -    unsigned long flags;
   3.119 -    if ( !__on_blkdev_list(blkif) ) return;
   3.120 -    spin_lock_irqsave(&io_schedule_list_lock, flags);
   3.121 -    if ( __on_blkdev_list(blkif) )
   3.122 -    {
   3.123 -        list_del(&blkif->blkdev_list);
   3.124 -        blkif->blkdev_list.next = NULL;
   3.125 -        blkif_put(blkif);
   3.126 -    }
   3.127 -    spin_unlock_irqrestore(&io_schedule_list_lock, flags);
   3.128 -}
   3.129 -
   3.130 -static void add_to_blkdev_list_tail(blkif_t *blkif)
   3.131 -{
   3.132 -    unsigned long flags;
   3.133 -    if ( __on_blkdev_list(blkif) ) return;
   3.134 -    spin_lock_irqsave(&io_schedule_list_lock, flags);
   3.135 -    if ( !__on_blkdev_list(blkif) && (blkif->status == CONNECTED) )
   3.136 -    {
   3.137 -        list_add_tail(&blkif->blkdev_list, &io_schedule_list);
   3.138 -        blkif_get(blkif);
   3.139 -    }
   3.140 -    spin_unlock_irqrestore(&io_schedule_list_lock, flags);
   3.141 -}
   3.142 -
   3.143 -
   3.144 -/******************************************************************
   3.145 - * SCHEDULER FUNCTIONS
   3.146 - */
   3.147 -
   3.148 -static DECLARE_WAIT_QUEUE_HEAD(io_schedule_wait);
   3.149 -
   3.150 -static int io_schedule(void *arg)
   3.151 -{
   3.152 -    DECLARE_WAITQUEUE(wq, current);
   3.153 -
   3.154 -    blkif_t          *blkif;
   3.155 -    struct list_head *ent;
   3.156 -
   3.157 -    for ( ; ; )
   3.158 -    {
   3.159 -        /* Wait for work to do. */
   3.160 -        add_wait_queue(&io_schedule_wait, &wq);
   3.161 -        set_current_state(TASK_INTERRUPTIBLE);
   3.162 -        if ( (NR_PENDING_REQS == MAX_PENDING_REQS) || 
   3.163 -             list_empty(&io_schedule_list) )
   3.164 -            schedule();
   3.165 -        __set_current_state(TASK_RUNNING);
   3.166 -        remove_wait_queue(&io_schedule_wait, &wq);
   3.167 -
   3.168 -        /* Queue up a batch of requests. */
   3.169 -        while ( (NR_PENDING_REQS < MAX_PENDING_REQS) &&
   3.170 -                !list_empty(&io_schedule_list) )
   3.171 -        {
   3.172 -            ent = io_schedule_list.next;
   3.173 -            blkif = list_entry(ent, blkif_t, blkdev_list);
   3.174 -            blkif_get(blkif);
   3.175 -            remove_from_blkdev_list(blkif);
   3.176 -            if ( do_block_io_op(blkif, BATCH_PER_DOMAIN) )
   3.177 -                add_to_blkdev_list_tail(blkif);
   3.178 -            blkif_put(blkif);
   3.179 -        }
   3.180 -        
   3.181 -        /* Push the batch through to disc. */
   3.182 -        run_task_queue(&tq_disk);
   3.183 -    }
   3.184 -}
   3.185 -
   3.186 -static void maybe_trigger_io_schedule(void)
   3.187 -{
   3.188 -    /*
   3.189 -     * Needed so that two processes, who together make the following predicate
   3.190 -     * true, don't both read stale values and evaluate the predicate
   3.191 -     * incorrectly. Incredibly unlikely to stall the scheduler on x86, but...
   3.192 -     */
   3.193 -    smp_mb();
   3.194 -
   3.195 -    if ( (NR_PENDING_REQS < (MAX_PENDING_REQS/2)) &&
   3.196 -         !list_empty(&io_schedule_list) )
   3.197 -        wake_up(&io_schedule_wait);
   3.198 -}
   3.199 -
   3.200 -
   3.201 -
   3.202 -/******************************************************************
   3.203 - * COMPLETION CALLBACK -- Called as bh->b_end_io()
   3.204 - */
   3.205 -
   3.206 -static void __end_block_io_op(pending_req_t *pending_req, int uptodate)
   3.207 -{
   3.208 -    unsigned long flags;
   3.209 -
   3.210 -    /* An error fails the entire request. */
   3.211 -    if ( !uptodate )
   3.212 -    {
   3.213 -        DPRINTK("Buffer not up-to-date at end of operation\n");
   3.214 -        pending_req->status = BLKIF_RSP_ERROR;
   3.215 -    }
   3.216 -
   3.217 -    if ( atomic_dec_and_test(&pending_req->pendcnt) )
   3.218 -    {
   3.219 -        int pending_idx = pending_req - pending_reqs;
   3.220 -        fast_flush_area(pending_idx, pending_req->nr_pages);
   3.221 -        make_response(pending_req->blkif, pending_req->id,
   3.222 -                      pending_req->operation, pending_req->status);
   3.223 -        blkif_put(pending_req->blkif);
   3.224 -        spin_lock_irqsave(&pend_prod_lock, flags);
   3.225 -        pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
   3.226 -        spin_unlock_irqrestore(&pend_prod_lock, flags);
   3.227 -        maybe_trigger_io_schedule();
   3.228 -    }
   3.229 -}
   3.230 -
   3.231 -static void end_block_io_op(struct buffer_head *bh, int uptodate)
   3.232 -{
   3.233 -    __end_block_io_op(bh->b_private, uptodate);
   3.234 -    kmem_cache_free(buffer_head_cachep, bh);
   3.235 -}
   3.236 -
   3.237 -
   3.238 -
   3.239 -/******************************************************************************
   3.240 - * NOTIFICATION FROM GUEST OS.
   3.241 - */
   3.242 -
   3.243 -void blkif_be_int(int irq, void *dev_id, struct pt_regs *regs)
   3.244 -{
   3.245 -    blkif_t *blkif = dev_id;
   3.246 -    add_to_blkdev_list_tail(blkif);
   3.247 -    maybe_trigger_io_schedule();
   3.248 -}
   3.249 -
   3.250 -
   3.251 -
   3.252 -/******************************************************************
   3.253 - * DOWNWARD CALLS -- These interface with the block-device layer proper.
   3.254 - */
   3.255 -
   3.256 -static int do_block_io_op(blkif_t *blkif, int max_to_do)
   3.257 -{
   3.258 -    blkif_ring_t *blk_ring = blkif->blk_ring_base;
   3.259 -    blkif_request_t *req;
   3.260 -    BLKIF_RING_IDX i;
   3.261 -    int more_to_do = 0;
   3.262 -
   3.263 -    /* Take items off the comms ring, taking care not to overflow. */
   3.264 -    for ( i = blkif->blk_req_cons; 
   3.265 -          (i != blk_ring->req_prod) && ((i-blkif->blk_resp_prod) != 
   3.266 -                                        BLKIF_RING_SIZE);
   3.267 -          i++ )
   3.268 -    {
   3.269 -        if ( (max_to_do-- == 0) || (NR_PENDING_REQS == MAX_PENDING_REQS) )
   3.270 -        {
   3.271 -            more_to_do = 1;
   3.272 -            break;
   3.273 -        }
   3.274 -        
   3.275 -        req = &blk_ring->ring[MASK_BLKIF_IDX(i)].req;
   3.276 -        switch ( req->operation )
   3.277 -        {
   3.278 -        case BLKIF_OP_READ:
   3.279 -        case BLKIF_OP_WRITE:
   3.280 -            dispatch_rw_block_io(blkif, req);
   3.281 -            break;
   3.282 -
   3.283 -        case BLKIF_OP_PROBE:
   3.284 -            dispatch_probe(blkif, req);
   3.285 -            break;
   3.286 -
   3.287 -        default:
   3.288 -            DPRINTK("error: unknown block io operation [%d]\n",
   3.289 -                    blk_ring->ring[i].req.operation);
   3.290 -            make_response(blkif, blk_ring->ring[i].req.id, 
   3.291 -                          blk_ring->ring[i].req.operation, BLKIF_RSP_ERROR);
   3.292 -            break;
   3.293 -        }
   3.294 -    }
   3.295 -
   3.296 -    blkif->blk_req_cons = i;
   3.297 -    return more_to_do;
   3.298 -}
   3.299 -
   3.300 -static void dispatch_probe(blkif_t *blkif, blkif_request_t *req)
   3.301 -{
   3.302 -    int rsp = BLKIF_RSP_ERROR;
   3.303 -    int pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
   3.304 -
   3.305 -    /* We expect one buffer only. */
   3.306 -    if ( unlikely(req->nr_segments != 1) )
   3.307 -        goto out;
   3.308 -
   3.309 -    /* Make sure the buffer is page-sized. */
   3.310 -    if ( (blkif_first_sect(req->frame_and_sects[0]) != 0) ||
   3.311 -         (blkif_last_sect(req->frame_and_sects[0]) != 7) )
   3.312 -        goto out;
   3.313 -
   3.314 -    if ( HYPERVISOR_update_va_mapping_otherdomain(
   3.315 -        MMAP_VADDR(pending_idx, 0) >> PAGE_SHIFT,
   3.316 -        (pte_t) { (req->frame_and_sects[0] & PAGE_MASK) | __PAGE_KERNEL },
   3.317 -        0, blkif->domid) )
   3.318 -        goto out;
   3.319 -
   3.320 -    rsp = vbd_probe(blkif, (vdisk_t *)MMAP_VADDR(pending_idx, 0), 
   3.321 -                    PAGE_SIZE / sizeof(vdisk_t));
   3.322 -
   3.323 - out:
   3.324 -    fast_flush_area(pending_idx, 1);
   3.325 -    make_response(blkif, req->id, req->operation, rsp);
   3.326 -}
   3.327 -
   3.328 -static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req)
   3.329 -{
   3.330 -    extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]); 
   3.331 -    struct buffer_head *bh;
   3.332 -    int operation = (req->operation == BLKIF_OP_WRITE) ? WRITE : READ;
   3.333 -    short nr_sects;
   3.334 -    unsigned long buffer, fas;
   3.335 -    int i, tot_sects, pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
   3.336 -    pending_req_t *pending_req;
   3.337 -    unsigned long  remap_prot;
   3.338 -    multicall_entry_t mcl[MMAP_PAGES_PER_REQUEST];
   3.339 -
   3.340 -    /* We map virtual scatter/gather segments to physical segments. */
   3.341 -    int new_segs, nr_psegs = 0;
   3.342 -    phys_seg_t phys_seg[BLKIF_MAX_SEGMENTS_PER_REQUEST + 1];
   3.343 -
   3.344 -    /* Check that number of segments is sane. */
   3.345 -    if ( unlikely(req->nr_segments == 0) || 
   3.346 -         unlikely(req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST) )
   3.347 -    {
   3.348 -        DPRINTK("Bad number of segments in request (%d)\n", req->nr_segments);
   3.349 -        goto bad_descriptor;
   3.350 -    }
   3.351 -
   3.352 -    /*
   3.353 -     * Check each address/size pair is sane, and convert into a
   3.354 -     * physical device and block offset. Note that if the offset and size
   3.355 -     * crosses a virtual extent boundary, we may end up with more
   3.356 -     * physical scatter/gather segments than virtual segments.
   3.357 -     */
   3.358 -    for ( i = tot_sects = 0; i < req->nr_segments; i++, tot_sects += nr_sects )
   3.359 -    {
   3.360 -        fas      = req->frame_and_sects[i];
   3.361 -        buffer   = (fas & PAGE_MASK) | (blkif_first_sect(fas) << 9);
   3.362 -        nr_sects = blkif_last_sect(fas) - blkif_first_sect(fas) + 1;
   3.363 -
   3.364 -        if ( nr_sects <= 0 )
   3.365 -            goto bad_descriptor;
   3.366 -
   3.367 -        phys_seg[nr_psegs].dev           = req->device;
   3.368 -        phys_seg[nr_psegs].sector_number = req->sector_number + tot_sects;
   3.369 -        phys_seg[nr_psegs].buffer        = buffer;
   3.370 -        phys_seg[nr_psegs].nr_sects      = nr_sects;
   3.371 -
   3.372 -        /* Translate the request into the relevant 'physical device' */
   3.373 -        new_segs = vbd_translate(&phys_seg[nr_psegs], blkif, operation);
   3.374 -        if ( new_segs < 0 )
   3.375 -        { 
   3.376 -            DPRINTK("access denied: %s of [%llu,%llu] on dev=%04x\n", 
   3.377 -                    operation == READ ? "read" : "write", 
   3.378 -                    req->sector_number + tot_sects, 
   3.379 -                    req->sector_number + tot_sects + nr_sects, 
   3.380 -                    req->device); 
   3.381 -            goto bad_descriptor;
   3.382 -        }
   3.383 -  
   3.384 -        nr_psegs += new_segs;
   3.385 -        ASSERT(nr_psegs <= (BLKIF_MAX_SEGMENTS_PER_REQUEST+1));
   3.386 -    }
   3.387 -
   3.388 -    /* Nonsensical zero-sized request? */
   3.389 -    if ( unlikely(nr_psegs == 0) )
   3.390 -        goto bad_descriptor;
   3.391 -
   3.392 -    if ( operation == READ )
   3.393 -        remap_prot = _PAGE_PRESENT|_PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_RW;
   3.394 -    else
   3.395 -        remap_prot = _PAGE_PRESENT|_PAGE_DIRTY|_PAGE_ACCESSED;
   3.396 -
   3.397 -    for ( i = 0; i < nr_psegs; i++ )
   3.398 -    {
   3.399 -        mcl[i].op = __HYPERVISOR_update_va_mapping_otherdomain;
   3.400 -        mcl[i].args[0] = MMAP_VADDR(pending_idx, i) >> PAGE_SHIFT;
   3.401 -        mcl[i].args[1] = (phys_seg[i].buffer & PAGE_MASK) | remap_prot;
   3.402 -        mcl[i].args[2] = 0;
   3.403 -        mcl[i].args[3] = blkif->domid;
   3.404 -
   3.405 -        phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx, i))>>PAGE_SHIFT] =
   3.406 -            phys_seg[i].buffer >> PAGE_SHIFT;
   3.407 -    }
   3.408 -
   3.409 -    if ( unlikely(HYPERVISOR_multicall(mcl, nr_psegs) != 0) )
   3.410 -        BUG();
   3.411 -
   3.412 -    for ( i = 0; i < nr_psegs; i++ )
   3.413 -    {
   3.414 -        if ( unlikely(mcl[i].args[5] != 0) )
   3.415 -        {
   3.416 -            DPRINTK("invalid buffer -- could not remap it\n");
   3.417 -            fast_flush_area(pending_idx, nr_psegs);
   3.418 -            goto bad_descriptor;
   3.419 -        }
   3.420 -    }
   3.421 -
   3.422 -    pending_req = &pending_reqs[pending_idx];
   3.423 -    pending_req->blkif     = blkif;
   3.424 -    pending_req->id        = req->id;
   3.425 -    pending_req->operation = operation;
   3.426 -    pending_req->status    = BLKIF_RSP_OKAY;
   3.427 -    pending_req->nr_pages  = nr_psegs;
   3.428 -    atomic_set(&pending_req->pendcnt, nr_psegs);
   3.429 -    pending_cons++;
   3.430 -
   3.431 -    blkif_get(blkif);
   3.432 -
   3.433 -    /* Now we pass each segment down to the real blkdev layer. */
   3.434 -    for ( i = 0; i < nr_psegs; i++ )
   3.435 -    {
   3.436 -        bh = kmem_cache_alloc(buffer_head_cachep, GFP_ATOMIC);
   3.437 -        if ( unlikely(bh == NULL) )
   3.438 -        {
   3.439 -            __end_block_io_op(pending_req, 0);
   3.440 -            continue;
   3.441 -        }
   3.442 -        memset(bh, 0, sizeof (struct buffer_head));
   3.443 -
   3.444 -        init_waitqueue_head(&bh->b_wait);
   3.445 -        bh->b_size          = phys_seg[i].nr_sects << 9;
   3.446 -        bh->b_dev           = phys_seg[i].dev;
   3.447 -        bh->b_rdev          = phys_seg[i].dev;
   3.448 -        bh->b_rsector       = (unsigned long)phys_seg[i].sector_number;
   3.449 -        bh->b_data          = (char *)MMAP_VADDR(pending_idx, i) +
   3.450 -            (phys_seg[i].buffer & ~PAGE_MASK);
   3.451 -        bh->b_page          = virt_to_page(MMAP_VADDR(pending_idx, i));
   3.452 -        bh->b_end_io        = end_block_io_op;
   3.453 -        bh->b_private       = pending_req;
   3.454 -
   3.455 -        bh->b_state = (1 << BH_Mapped) | (1 << BH_Lock) | 
   3.456 -            (1 << BH_Req) | (1 << BH_Launder);
   3.457 -        if ( operation == WRITE )
   3.458 -            bh->b_state |= (1 << BH_JBD) | (1 << BH_Req) | (1 << BH_Uptodate);
   3.459 -
   3.460 -        atomic_set(&bh->b_count, 1);
   3.461 -
   3.462 -        /* Dispatch a single request. We'll flush it to disc later. */
   3.463 -        generic_make_request(operation, bh);
   3.464 -    }
   3.465 -
   3.466 -    return;
   3.467 -
   3.468 - bad_descriptor:
   3.469 -    make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR);
   3.470 -} 
   3.471 -
   3.472 -
   3.473 -
   3.474 -/******************************************************************
   3.475 - * MISCELLANEOUS SETUP / TEARDOWN / DEBUGGING
   3.476 - */
   3.477 -
   3.478 -
   3.479 -static void make_response(blkif_t *blkif, unsigned long id, 
   3.480 -                          unsigned short op, int st)
   3.481 -{
   3.482 -    blkif_response_t *resp;
   3.483 -    unsigned long     flags;
   3.484 -
   3.485 -    /* Place on the response ring for the relevant domain. */ 
   3.486 -    spin_lock_irqsave(&blkif->blk_ring_lock, flags);
   3.487 -    resp = &blkif->blk_ring_base->
   3.488 -        ring[MASK_BLKIF_IDX(blkif->blk_resp_prod)].resp;
   3.489 -    resp->id        = id;
   3.490 -    resp->operation = op;
   3.491 -    resp->status    = st;
   3.492 -    wmb();
   3.493 -    blkif->blk_ring_base->resp_prod = ++blkif->blk_resp_prod;
   3.494 -    spin_unlock_irqrestore(&blkif->blk_ring_lock, flags);
   3.495 -
   3.496 -    /* Kick the relevant domain. */
   3.497 -    notify_via_evtchn(blkif->evtchn);
   3.498 -}
   3.499 -
   3.500 -void blkif_deschedule(blkif_t *blkif)
   3.501 -{
   3.502 -    remove_from_blkdev_list(blkif);
   3.503 -}
   3.504 -
   3.505 -static int __init blkif_init(void)
   3.506 -{
   3.507 -    int i;
   3.508 -
   3.509 -    if ( !(start_info.flags & SIF_INITDOMAIN)
   3.510 -	 && !(start_info.flags & SIF_BLK_BE_DOMAIN) )
   3.511 -        return 0;
   3.512 -
   3.513 -    blkif_interface_init();
   3.514 -
   3.515 -    if ( (mmap_vstart = allocate_empty_lowmem_region(MMAP_PAGES)) == 0 )
   3.516 -        BUG();
   3.517 -
   3.518 -    pending_cons = 0;
   3.519 -    pending_prod = MAX_PENDING_REQS;
   3.520 -    memset(pending_reqs, 0, sizeof(pending_reqs));
   3.521 -    for ( i = 0; i < MAX_PENDING_REQS; i++ )
   3.522 -        pending_ring[i] = i;
   3.523 -    
   3.524 -    spin_lock_init(&io_schedule_list_lock);
   3.525 -    INIT_LIST_HEAD(&io_schedule_list);
   3.526 -
   3.527 -    if ( kernel_thread(io_schedule, 0, CLONE_FS | CLONE_FILES) < 0 )
   3.528 -        BUG();
   3.529 -
   3.530 -    buffer_head_cachep = kmem_cache_create(
   3.531 -        "buffer_head_cache", sizeof(struct buffer_head),
   3.532 -        0, SLAB_HWCACHE_ALIGN, NULL, NULL);
   3.533 -
   3.534 -    blkif_ctrlif_init();
   3.535 -
   3.536 -    return 0;
   3.537 -}
   3.538 -
   3.539 -__initcall(blkif_init);
     4.1 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/backend/vbd.c	Tue Aug 03 20:23:21 2004 +0000
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,474 +0,0 @@
     4.4 -/******************************************************************************
     4.5 - * arch/xen/drivers/blkif/backend/vbd.c
     4.6 - * 
     4.7 - * Routines for managing virtual block devices (VBDs).
     4.8 - * 
     4.9 - * Copyright (c) 2003-2004, Keir Fraser & Steve Hand
    4.10 - */
    4.11 -
    4.12 -#include "common.h"
    4.13 -
    4.14 -void vbd_create(blkif_be_vbd_create_t *create) 
    4.15 -{
    4.16 -    vbd_t       *vbd; 
    4.17 -    rb_node_t  **rb_p, *rb_parent = NULL;
    4.18 -    blkif_t     *blkif;
    4.19 -    blkif_vdev_t vdevice = create->vdevice;
    4.20 -
    4.21 -    blkif = blkif_find_by_handle(create->domid, create->blkif_handle);
    4.22 -    if ( unlikely(blkif == NULL) )
    4.23 -    {
    4.24 -        PRINTK("vbd_create attempted for non-existent blkif (%u,%u)\n", 
    4.25 -                create->domid, create->blkif_handle); 
    4.26 -        create->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
    4.27 -        return;
    4.28 -    }
    4.29 -
    4.30 -    spin_lock(&blkif->vbd_lock);
    4.31 -
    4.32 -    rb_p = &blkif->vbd_rb.rb_node;
    4.33 -    while ( *rb_p != NULL )
    4.34 -    {
    4.35 -        rb_parent = *rb_p;
    4.36 -        vbd = rb_entry(rb_parent, vbd_t, rb);
    4.37 -        if ( vdevice < vbd->vdevice )
    4.38 -        {
    4.39 -            rb_p = &rb_parent->rb_left;
    4.40 -        }
    4.41 -        else if ( vdevice > vbd->vdevice )
    4.42 -        {
    4.43 -            rb_p = &rb_parent->rb_right;
    4.44 -        }
    4.45 -        else
    4.46 -        {
    4.47 -            PRINTK("vbd_create attempted for already existing vbd\n");
    4.48 -            create->status = BLKIF_BE_STATUS_VBD_EXISTS;
    4.49 -            goto out;
    4.50 -        }
    4.51 -    }
    4.52 -
    4.53 -    if ( unlikely((vbd = kmalloc(sizeof(vbd_t), GFP_KERNEL)) == NULL) )
    4.54 -    {
    4.55 -        PRINTK("vbd_create: out of memory\n");
    4.56 -        create->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
    4.57 -        goto out;
    4.58 -    }
    4.59 -
    4.60 -    vbd->vdevice  = vdevice; 
    4.61 -    vbd->readonly = create->readonly;
    4.62 -    vbd->type     = VDISK_TYPE_DISK | VDISK_FLAG_VIRT;
    4.63 -    vbd->extents  = NULL; 
    4.64 -
    4.65 -    rb_link_node(&vbd->rb, rb_parent, rb_p);
    4.66 -    rb_insert_color(&vbd->rb, &blkif->vbd_rb);
    4.67 -
    4.68 -    DPRINTK("Successful creation of vdev=%04x (dom=%u)\n",
    4.69 -            vdevice, create->domid);
    4.70 -    create->status = BLKIF_BE_STATUS_OKAY;
    4.71 -
    4.72 - out:
    4.73 -    spin_unlock(&blkif->vbd_lock);
    4.74 -}
    4.75 -
    4.76 -
    4.77 -/* Grow a VBD by appending a new extent. Fails if the VBD doesn't exist. */
    4.78 -void vbd_grow(blkif_be_vbd_grow_t *grow) 
    4.79 -{
    4.80 -    blkif_t            *blkif;
    4.81 -    blkif_extent_le_t **px, *x; 
    4.82 -    vbd_t              *vbd = NULL;
    4.83 -    rb_node_t          *rb;
    4.84 -    blkif_vdev_t        vdevice = grow->vdevice;
    4.85 -    unsigned long       sz;
    4.86 -    
    4.87 -
    4.88 -    blkif = blkif_find_by_handle(grow->domid, grow->blkif_handle);
    4.89 -    if ( unlikely(blkif == NULL) )
    4.90 -    {
    4.91 -        PRINTK("vbd_grow attempted for non-existent blkif (%u,%u)\n", 
    4.92 -                grow->domid, grow->blkif_handle); 
    4.93 -        grow->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
    4.94 -        return;
    4.95 -    }
    4.96 -
    4.97 -    spin_lock(&blkif->vbd_lock);
    4.98 -
    4.99 -    rb = blkif->vbd_rb.rb_node;
   4.100 -    while ( rb != NULL )
   4.101 -    {
   4.102 -        vbd = rb_entry(rb, vbd_t, rb);
   4.103 -        if ( vdevice < vbd->vdevice )
   4.104 -            rb = rb->rb_left;
   4.105 -        else if ( vdevice > vbd->vdevice )
   4.106 -            rb = rb->rb_right;
   4.107 -        else
   4.108 -            break;
   4.109 -    }
   4.110 -
   4.111 -    if ( unlikely(vbd == NULL) || unlikely(vbd->vdevice != vdevice) )
   4.112 -    {
   4.113 -        PRINTK("vbd_grow: attempted to append extent to non-existent VBD.\n");
   4.114 -        grow->status = BLKIF_BE_STATUS_VBD_NOT_FOUND;
   4.115 -        goto out;
   4.116 -    } 
   4.117 -
   4.118 -    if ( unlikely((x = kmalloc(sizeof(blkif_extent_le_t), 
   4.119 -                               GFP_KERNEL)) == NULL) )
   4.120 -    {
   4.121 -        PRINTK("vbd_grow: out of memory\n");
   4.122 -        grow->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
   4.123 -        goto out;
   4.124 -    }
   4.125 -    
   4.126 -    x->extent.device        = grow->extent.device; 
   4.127 -    x->extent.sector_start  = grow->extent.sector_start; 
   4.128 -    x->extent.sector_length = grow->extent.sector_length; 
   4.129 -    x->next                 = (blkif_extent_le_t *)NULL; 
   4.130 -    
   4.131 -    if( !blk_size[MAJOR(x->extent.device)] )
   4.132 -    {
   4.133 -        PRINTK("vbd_grow: device %08x doesn't exist.\n", x->extent.device);
   4.134 -	grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
   4.135 -	goto out;
   4.136 -    }
   4.137 -    
   4.138 -    /* convert blocks (1KB) to sectors */
   4.139 -    sz = blk_size[MAJOR(x->extent.device)][MINOR(x->extent.device)] * 2;    
   4.140 -    
   4.141 -    if ( sz == 0 )
   4.142 -    {
   4.143 -        PRINTK("vbd_grow: device %08x zero size!\n", x->extent.device);
   4.144 -	grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
   4.145 -	goto out;
   4.146 -    }
   4.147 -
   4.148 -    if ( x->extent.sector_start > 0 )
   4.149 -    {
   4.150 -        PRINTK("vbd_grow: device %08x start not zero!\n", x->extent.device);
   4.151 -	grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
   4.152 -	goto out;
   4.153 -    }
   4.154 -    
   4.155 -    /*
   4.156 -     * NB. This test assumes sector_start == 0, which is always the case
   4.157 -     * in Xen 1.3. In fact the whole grow/shrink interface could do with
   4.158 -     * some simplification.
   4.159 -     */
   4.160 -    if ( x->extent.sector_length > sz )
   4.161 -        x->extent.sector_length = sz;
   4.162 -    
   4.163 -    DPRINTK("vbd_grow: requested_len %llu actual_len %lu\n", 
   4.164 -            x->extent.sector_length, sz);
   4.165 -
   4.166 -    for ( px = &vbd->extents; *px != NULL; px = &(*px)->next ) 
   4.167 -        continue;
   4.168 -    
   4.169 -    *px = x;
   4.170 -
   4.171 -    DPRINTK("Successful grow of vdev=%04x (dom=%u)\n",
   4.172 -            vdevice, grow->domid);
   4.173 -    
   4.174 -    grow->status = BLKIF_BE_STATUS_OKAY;
   4.175 -
   4.176 - out:
   4.177 -    spin_unlock(&blkif->vbd_lock);
   4.178 -}
   4.179 -
   4.180 -
   4.181 -void vbd_shrink(blkif_be_vbd_shrink_t *shrink)
   4.182 -{
   4.183 -    blkif_t            *blkif;
   4.184 -    blkif_extent_le_t **px, *x; 
   4.185 -    vbd_t              *vbd = NULL;
   4.186 -    rb_node_t          *rb;
   4.187 -    blkif_vdev_t        vdevice = shrink->vdevice;
   4.188 -
   4.189 -    blkif = blkif_find_by_handle(shrink->domid, shrink->blkif_handle);
   4.190 -    if ( unlikely(blkif == NULL) )
   4.191 -    {
   4.192 -        DPRINTK("vbd_shrink attempted for non-existent blkif (%u,%u)\n", 
   4.193 -                shrink->domid, shrink->blkif_handle); 
   4.194 -        shrink->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
   4.195 -        return;
   4.196 -    }
   4.197 -
   4.198 -    spin_lock(&blkif->vbd_lock);
   4.199 -
   4.200 -    rb = blkif->vbd_rb.rb_node;
   4.201 -    while ( rb != NULL )
   4.202 -    {
   4.203 -        vbd = rb_entry(rb, vbd_t, rb);
   4.204 -        if ( vdevice < vbd->vdevice )
   4.205 -            rb = rb->rb_left;
   4.206 -        else if ( vdevice > vbd->vdevice )
   4.207 -            rb = rb->rb_right;
   4.208 -        else
   4.209 -            break;
   4.210 -    }
   4.211 -
   4.212 -    if ( unlikely(vbd == NULL) || unlikely(vbd->vdevice != vdevice) )
   4.213 -    {
   4.214 -        shrink->status = BLKIF_BE_STATUS_VBD_NOT_FOUND;
   4.215 -        goto out;
   4.216 -    }
   4.217 -
   4.218 -    if ( unlikely(vbd->extents == NULL) )
   4.219 -    {
   4.220 -        shrink->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
   4.221 -        goto out;
   4.222 -    }
   4.223 -
   4.224 -    /* Find the last extent. We now know that there is at least one. */
   4.225 -    for ( px = &vbd->extents; (*px)->next != NULL; px = &(*px)->next )
   4.226 -        continue;
   4.227 -
   4.228 -    x   = *px;
   4.229 -    *px = x->next;
   4.230 -    kfree(x);
   4.231 -
   4.232 -    shrink->status = BLKIF_BE_STATUS_OKAY;
   4.233 -
   4.234 - out:
   4.235 -    spin_unlock(&blkif->vbd_lock);
   4.236 -}
   4.237 -
   4.238 -
   4.239 -void vbd_destroy(blkif_be_vbd_destroy_t *destroy) 
   4.240 -{
   4.241 -    blkif_t           *blkif;
   4.242 -    vbd_t             *vbd;
   4.243 -    rb_node_t         *rb;
   4.244 -    blkif_extent_le_t *x, *t;
   4.245 -    blkif_vdev_t       vdevice = destroy->vdevice;
   4.246 -
   4.247 -    blkif = blkif_find_by_handle(destroy->domid, destroy->blkif_handle);
   4.248 -    if ( unlikely(blkif == NULL) )
   4.249 -    {
   4.250 -        PRINTK("vbd_destroy attempted for non-existent blkif (%u,%u)\n", 
   4.251 -                destroy->domid, destroy->blkif_handle); 
   4.252 -        destroy->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
   4.253 -        return;
   4.254 -    }
   4.255 -
   4.256 -    spin_lock(&blkif->vbd_lock);
   4.257 -
   4.258 -    rb = blkif->vbd_rb.rb_node;
   4.259 -    while ( rb != NULL )
   4.260 -    {
   4.261 -        vbd = rb_entry(rb, vbd_t, rb);
   4.262 -        if ( vdevice < vbd->vdevice )
   4.263 -            rb = rb->rb_left;
   4.264 -        else if ( vdevice > vbd->vdevice )
   4.265 -            rb = rb->rb_right;
   4.266 -        else
   4.267 -            goto found;
   4.268 -    }
   4.269 -
   4.270 -    destroy->status = BLKIF_BE_STATUS_VBD_NOT_FOUND;
   4.271 -    goto out;
   4.272 -
   4.273 - found:
   4.274 -    rb_erase(rb, &blkif->vbd_rb);
   4.275 -    x = vbd->extents;
   4.276 -    kfree(vbd);
   4.277 -
   4.278 -    while ( x != NULL )
   4.279 -    {
   4.280 -        t = x->next;
   4.281 -        kfree(x);
   4.282 -        x = t;
   4.283 -    }
   4.284 -    
   4.285 - out:
   4.286 -    spin_unlock(&blkif->vbd_lock);
   4.287 -}
   4.288 -
   4.289 -
   4.290 -void destroy_all_vbds(blkif_t *blkif)
   4.291 -{
   4.292 -    vbd_t *vbd;
   4.293 -    rb_node_t *rb;
   4.294 -    blkif_extent_le_t *x, *t;
   4.295 -
   4.296 -    spin_lock(&blkif->vbd_lock);
   4.297 -
   4.298 -    while ( (rb = blkif->vbd_rb.rb_node) != NULL )
   4.299 -    {
   4.300 -        vbd = rb_entry(rb, vbd_t, rb);
   4.301 -
   4.302 -        rb_erase(rb, &blkif->vbd_rb);
   4.303 -        x = vbd->extents;
   4.304 -        kfree(vbd);
   4.305 -        
   4.306 -        while ( x != NULL )
   4.307 -        {
   4.308 -            t = x->next;
   4.309 -            kfree(x);
   4.310 -            x = t;
   4.311 -        }          
   4.312 -    }
   4.313 -
   4.314 -    spin_unlock(&blkif->vbd_lock);
   4.315 -}
   4.316 -
   4.317 -
   4.318 -static int vbd_probe_single(blkif_t *blkif, vdisk_t *vbd_info, vbd_t *vbd)
   4.319 -{
   4.320 -    blkif_extent_le_t *x; 
   4.321 -
   4.322 -    vbd_info->device = vbd->vdevice; 
   4.323 -    vbd_info->info   = vbd->type;
   4.324 -    if ( vbd->readonly )
   4.325 -        vbd_info->info |= VDISK_FLAG_RO; 
   4.326 -    vbd_info->capacity = 0ULL;
   4.327 -    for ( x = vbd->extents; x != NULL; x = x->next )
   4.328 -        vbd_info->capacity += x->extent.sector_length; 
   4.329 -        
   4.330 -    return 0;
   4.331 -}
   4.332 -
   4.333 -
   4.334 -int vbd_probe(blkif_t *blkif, vdisk_t *vbd_info, int max_vbds)
   4.335 -{
   4.336 -    int rc = 0, nr_vbds = 0;
   4.337 -    rb_node_t *rb;
   4.338 -
   4.339 -    spin_lock(&blkif->vbd_lock);
   4.340 -
   4.341 -    if ( (rb = blkif->vbd_rb.rb_node) == NULL )
   4.342 -        goto out;
   4.343 -
   4.344 - new_subtree:
   4.345 -    /* STEP 1. Find least node (it'll be left-most). */
   4.346 -    while ( rb->rb_left != NULL )
   4.347 -        rb = rb->rb_left;
   4.348 -
   4.349 -    for ( ; ; )
   4.350 -    {
   4.351 -        /* STEP 2. Dealt with left subtree. Now process current node. */
   4.352 -        if ( (rc = vbd_probe_single(blkif, &vbd_info[nr_vbds], 
   4.353 -                                    rb_entry(rb, vbd_t, rb))) != 0 )
   4.354 -            goto out;
   4.355 -        if ( ++nr_vbds == max_vbds )
   4.356 -            goto out;
   4.357 -
   4.358 -        /* STEP 3. Process right subtree, if any. */
   4.359 -        if ( rb->rb_right != NULL )
   4.360 -        {
   4.361 -            rb = rb->rb_right;
   4.362 -            goto new_subtree;
   4.363 -        }
   4.364 -
   4.365 -        /* STEP 4. Done both subtrees. Head back through ancesstors. */
   4.366 -        for ( ; ; ) 
   4.367 -        {
   4.368 -            /* We're done when we get back to the root node. */
   4.369 -            if ( rb->rb_parent == NULL )
   4.370 -                goto out;
   4.371 -            /* If we are left of parent, then parent is next to process. */
   4.372 -            if ( rb->rb_parent->rb_left == rb )
   4.373 -                break;
   4.374 -            /* If we are right of parent, then we climb to grandparent. */
   4.375 -            rb = rb->rb_parent;
   4.376 -        }
   4.377 -
   4.378 -        rb = rb->rb_parent;
   4.379 -    }
   4.380 -
   4.381 - out:
   4.382 -    spin_unlock(&blkif->vbd_lock);
   4.383 -    return (rc == 0) ? nr_vbds : rc;  
   4.384 -}
   4.385 -
   4.386 -
   4.387 -int vbd_translate(phys_seg_t *pseg, blkif_t *blkif, int operation)
   4.388 -{
   4.389 -    blkif_extent_le_t *x; 
   4.390 -    vbd_t             *vbd;
   4.391 -    rb_node_t         *rb;
   4.392 -    blkif_sector_t     sec_off;
   4.393 -    unsigned long      nr_secs;
   4.394 -
   4.395 -    spin_lock(&blkif->vbd_lock);
   4.396 -
   4.397 -    rb = blkif->vbd_rb.rb_node;
   4.398 -    while ( rb != NULL )
   4.399 -    {
   4.400 -        vbd = rb_entry(rb, vbd_t, rb);
   4.401 -        if ( pseg->dev < vbd->vdevice )
   4.402 -            rb = rb->rb_left;
   4.403 -        else if ( pseg->dev > vbd->vdevice )
   4.404 -            rb = rb->rb_right;
   4.405 -        else
   4.406 -            goto found;
   4.407 -    }
   4.408 -
   4.409 -    DPRINTK("vbd_translate; domain %u attempted to access "
   4.410 -            "non-existent VBD.\n", blkif->domid);
   4.411 -
   4.412 -    spin_unlock(&blkif->vbd_lock);
   4.413 -    return -ENODEV; 
   4.414 -
   4.415 - found:
   4.416 -
   4.417 -    if ( (operation == WRITE) && vbd->readonly )
   4.418 -    {
   4.419 -        spin_unlock(&blkif->vbd_lock);
   4.420 -        return -EACCES; 
   4.421 -    }
   4.422 -
   4.423 -    /*
   4.424 -     * Now iterate through the list of blkif_extents, working out which should 
   4.425 -     * be used to perform the translation.
   4.426 -     */
   4.427 -    sec_off = pseg->sector_number; 
   4.428 -    nr_secs = pseg->nr_sects;
   4.429 -    for ( x = vbd->extents; x != NULL; x = x->next )
   4.430 -    { 
   4.431 -        if ( sec_off < x->extent.sector_length )
   4.432 -        {
   4.433 -            pseg->dev = x->extent.device; 
   4.434 -            pseg->sector_number = x->extent.sector_start + sec_off;
   4.435 -            if ( unlikely((sec_off + nr_secs) > x->extent.sector_length) )
   4.436 -                goto overrun;
   4.437 -            spin_unlock(&p->vbd_lock);
   4.438 -            return 1;
   4.439 -        } 
   4.440 -        sec_off -= x->extent.sector_length; 
   4.441 -    }
   4.442 -
   4.443 -    DPRINTK("vbd_translate: end of vbd.\n");
   4.444 -    spin_unlock(&blkif->vbd_lock);
   4.445 -    return -EACCES; 
   4.446 -
   4.447 -    /*
   4.448 -     * Here we deal with overrun onto the following extent. We don't deal with 
   4.449 -     * overrun of more than one boundary since each request is restricted to 
   4.450 -     * 2^9 512-byte sectors, so it should be trivial for control software to 
   4.451 -     * ensure that extents are large enough to prevent excessive overrun.
   4.452 -     */
   4.453 - overrun:
   4.454 -
   4.455 -    /* Adjust length of first chunk to run to end of first extent. */
   4.456 -    pseg[0].nr_sects = x->extent.sector_length - sec_off;
   4.457 -
   4.458 -    /* Set second chunk buffer and length to start where first chunk ended. */
   4.459 -    pseg[1].buffer   = pseg[0].buffer + (pseg[0].nr_sects << 9);
   4.460 -    pseg[1].nr_sects = nr_secs - pseg[0].nr_sects;
   4.461 -
   4.462 -    /* Now move to the next extent. Check it exists and is long enough! */
   4.463 -    if ( unlikely((x = x->next) == NULL) || 
   4.464 -         unlikely(x->extent.sector_length < pseg[1].nr_sects) )
   4.465 -    {
   4.466 -        DPRINTK("vbd_translate: multiple overruns or end of vbd.\n");
   4.467 -        spin_unlock(&p->vbd_lock);
   4.468 -        return -EACCES;
   4.469 -    }
   4.470 -
   4.471 -    /* Store the real device and start sector for the second chunk. */
   4.472 -    pseg[1].dev           = x->extent.device;
   4.473 -    pseg[1].sector_number = x->extent.sector_start;
   4.474 -    
   4.475 -    spin_unlock(&blkif->vbd_lock);
   4.476 -    return 2;
   4.477 -}
     5.1 --- a/linux-2.4.26-xen-sparse/mkbuildtree	Tue Aug 03 20:23:21 2004 +0000
     5.2 +++ b/linux-2.4.26-xen-sparse/mkbuildtree	Tue Aug 03 22:03:24 2004 +0000
     5.3 @@ -259,5 +259,8 @@ ln -sf ../../../../../${LINUX_26}/driver
     5.4  ln -sf ../../../../../${LINUX_26}/drivers/xen/netback/netback.c main.c
     5.5  
     5.6  cd ${AD}/arch/xen/drivers/blkif/backend
     5.7 +ln -sf ../../../../../${LINUX_26}/drivers/xen/blkback/common.h
     5.8 +ln -sf ../../../../../${LINUX_26}/drivers/xen/blkback/blkback.c main.c
     5.9  ln -sf ../../../../../${LINUX_26}/drivers/xen/blkback/control.c
    5.10  ln -sf ../../../../../${LINUX_26}/drivers/xen/blkback/interface.c
    5.11 +ln -sf ../../../../../${LINUX_26}/drivers/xen/blkback/vbd.c
     6.1 --- a/linux-2.6.7-xen-sparse/drivers/xen/blkback/blkback.c	Tue Aug 03 20:23:21 2004 +0000
     6.2 +++ b/linux-2.6.7-xen-sparse/drivers/xen/blkback/blkback.c	Tue Aug 03 22:03:24 2004 +0000
     6.3 @@ -71,7 +71,7 @@ typedef unsigned int PEND_RING_IDX;
     6.4  static PEND_RING_IDX pending_prod, pending_cons;
     6.5  #define NR_PENDING_REQS (MAX_PENDING_REQS - pending_prod + pending_cons)
     6.6  
     6.7 -#if 0
     6.8 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
     6.9  static kmem_cache_t *buffer_head_cachep;
    6.10  #endif
    6.11  
    6.12 @@ -176,8 +176,8 @@ static int blkio_schedule(void *arg)
    6.13                  add_to_blkdev_list_tail(blkif);
    6.14              blkif_put(blkif);
    6.15          }
    6.16 -        
    6.17 -#if 0				/* XXXcl tq */
    6.18 +
    6.19 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
    6.20          /* Push the batch through to disc. */
    6.21          run_task_queue(&tq_disk);
    6.22  #endif
    6.23 @@ -229,18 +229,21 @@ static void __end_block_io_op(pending_re
    6.24      }
    6.25  }
    6.26  
    6.27 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
    6.28 +static void end_block_io_op(struct buffer_head *bh, int uptodate)
    6.29 +{
    6.30 +    __end_block_io_op(bh->b_private, uptodate);
    6.31 +    kmem_cache_free(buffer_head_cachep, bh);
    6.32 +}
    6.33 +#else
    6.34  static int end_block_io_op(struct bio *bio, unsigned int done, int error)
    6.35  {
    6.36 -    if (done || error)		/* XXXcl */
    6.37 -	__end_block_io_op(bio->bi_private, done);
    6.38 -#if 0
    6.39 -    kmem_cache_free(buffer_head_cachep, bh);
    6.40 -#else
    6.41 +    if ( done || error )
    6.42 +        __end_block_io_op(bio->bi_private, (done && !error));
    6.43      bio_put(bio);
    6.44 -#endif
    6.45      return error;
    6.46  }
    6.47 -
    6.48 +#endif
    6.49  
    6.50  
    6.51  /******************************************************************************
    6.52 @@ -336,15 +339,10 @@ static void dispatch_probe(blkif_t *blki
    6.53  static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req)
    6.54  {
    6.55      extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]); 
    6.56 -#if 0
    6.57 -    struct buffer_head *bh;
    6.58 -#else
    6.59 -    struct bio *bio;
    6.60 -#endif
    6.61      int operation = (req->operation == BLKIF_OP_WRITE) ? WRITE : READ;
    6.62      short nr_sects;
    6.63      unsigned long buffer, fas;
    6.64 -    int i, j, tot_sects, pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
    6.65 +    int i, tot_sects, pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
    6.66      pending_req_t *pending_req;
    6.67      unsigned long  remap_prot;
    6.68      multicall_entry_t mcl[MMAP_PAGES_PER_REQUEST];
    6.69 @@ -376,7 +374,7 @@ static void dispatch_rw_block_io(blkif_t
    6.70          if ( nr_sects <= 0 )
    6.71              goto bad_descriptor;
    6.72  
    6.73 -        phys_seg[nr_psegs].ps_device     = req->device;
    6.74 +        phys_seg[nr_psegs].dev           = req->device;
    6.75          phys_seg[nr_psegs].sector_number = req->sector_number + tot_sects;
    6.76          phys_seg[nr_psegs].buffer        = buffer;
    6.77          phys_seg[nr_psegs].nr_sects      = nr_sects;
    6.78 @@ -443,15 +441,18 @@ static void dispatch_rw_block_io(blkif_t
    6.79      blkif_get(blkif);
    6.80  
    6.81      /* Now we pass each segment down to the real blkdev layer. */
    6.82 -#if 0
    6.83 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
    6.84      for ( i = 0; i < nr_psegs; i++ )
    6.85      {
    6.86 +        struct buffer_head *bh;
    6.87 +
    6.88          bh = kmem_cache_alloc(buffer_head_cachep, GFP_ATOMIC);
    6.89          if ( unlikely(bh == NULL) )
    6.90          {
    6.91              __end_block_io_op(pending_req, 0);
    6.92 -            continue;		/* XXXcl continue!? */
    6.93 +            continue;
    6.94          }
    6.95 +
    6.96          memset(bh, 0, sizeof (struct buffer_head));
    6.97  
    6.98          init_waitqueue_head(&bh->b_wait);
    6.99 @@ -478,35 +479,31 @@ static void dispatch_rw_block_io(blkif_t
   6.100  #else
   6.101      for ( i = 0; i < nr_psegs; i++ )
   6.102      {
   6.103 -	int nr_iovecs = PFN_UP(phys_seg[i].nr_sects << 9);
   6.104 -	ASSERT(nr_iovecs == 1);
   6.105 -	bio = bio_alloc(GFP_ATOMIC, nr_iovecs);
   6.106 -	if ( unlikely(bio == NULL) )
   6.107 -	{
   6.108 -	    __end_block_io_op(pending_req, 0);
   6.109 -	    break;
   6.110 -	}
   6.111 -	bio->bi_bdev = phys_seg[i].ps_bdev;
   6.112 -	bio->bi_private = pending_req;
   6.113 -	bio->bi_end_io = end_block_io_op;
   6.114 -	bio->bi_sector = phys_seg[i].sector_number;
   6.115 -	bio->bi_rw = operation;
   6.116 +        struct bio *bio;
   6.117 +        struct bio_vec *bv;
   6.118 +
   6.119 +        bio = bio_alloc(GFP_ATOMIC, 1);
   6.120 +        if ( unlikely(bio == NULL) )
   6.121 +        {
   6.122 +            __end_block_io_op(pending_req, 0);
   6.123 +            continue;
   6.124 +        }
   6.125  
   6.126 -	bio->bi_size = 0;
   6.127 -
   6.128 -	for ( j = 0; j < nr_iovecs; j++ )
   6.129 -	{
   6.130 -	    struct bio_vec *bv = bio_iovec_idx(bio, j);
   6.131 +        bio->bi_bdev    = phys_seg[i].bdev;
   6.132 +        bio->bi_private = pending_req;
   6.133 +        bio->bi_end_io  = end_block_io_op;
   6.134 +        bio->bi_sector  = phys_seg[i].sector_number;
   6.135 +        bio->bi_rw      = operation;
   6.136  
   6.137 -	    bv->bv_page = virt_to_page(MMAP_VADDR(pending_idx, i));
   6.138 -	    bv->bv_len = phys_seg[i].nr_sects << 9;
   6.139 -	    bv->bv_offset = phys_seg[i].buffer & ~PAGE_MASK;
   6.140 +        bv = bio_iovec_idx(bio, 0);
   6.141 +        bv->bv_page   = virt_to_page(MMAP_VADDR(pending_idx, i));
   6.142 +        bv->bv_len    = phys_seg[i].nr_sects << 9;
   6.143 +        bv->bv_offset = phys_seg[i].buffer & ~PAGE_MASK;
   6.144  
   6.145 -	    bio->bi_size =+ bv->bv_len;
   6.146 -	    bio->bi_vcnt++;
   6.147 -	}
   6.148 +        bio->bi_size    = bv->bv_len;
   6.149 +        bio->bi_vcnt++;
   6.150  
   6.151 -	submit_bio(operation, bio);
   6.152 +        submit_bio(operation, bio);
   6.153      }
   6.154  #endif
   6.155  
   6.156 @@ -553,8 +550,8 @@ static int __init blkif_init(void)
   6.157  {
   6.158      int i;
   6.159  
   6.160 -    if ( !(start_info.flags & SIF_INITDOMAIN)
   6.161 -	 && !(start_info.flags & SIF_BLK_BE_DOMAIN) )
   6.162 +    if ( !(start_info.flags & SIF_INITDOMAIN) &&
   6.163 +         !(start_info.flags & SIF_BLK_BE_DOMAIN) )
   6.164          return 0;
   6.165  
   6.166      blkif_interface_init();
   6.167 @@ -574,7 +571,7 @@ static int __init blkif_init(void)
   6.168      if ( kernel_thread(blkio_schedule, 0, CLONE_FS | CLONE_FILES) < 0 )
   6.169          BUG();
   6.170  
   6.171 -#if 0
   6.172 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
   6.173      buffer_head_cachep = kmem_cache_create(
   6.174          "buffer_head_cache", sizeof(struct buffer_head),
   6.175          0, SLAB_HWCACHE_ALIGN, NULL, NULL);
     7.1 --- a/linux-2.6.7-xen-sparse/drivers/xen/blkback/common.h	Tue Aug 03 20:23:21 2004 +0000
     7.2 +++ b/linux-2.6.7-xen-sparse/drivers/xen/blkback/common.h	Tue Aug 03 22:03:24 2004 +0000
     7.3 @@ -1,6 +1,3 @@
     7.4 -/******************************************************************************
     7.5 - * arch/xen/drivers/blkif/backend/common.h
     7.6 - */
     7.7  
     7.8  #ifndef __BLKIF__BACKEND__COMMON_H__
     7.9  #define __BLKIF__BACKEND__COMMON_H__
    7.10 @@ -30,8 +27,12 @@
    7.11  #define DPRINTK(_f, _a...) ((void)0)
    7.12  #endif
    7.13  
    7.14 -#define PRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
    7.15 -                           __FILE__ , __LINE__ , ## _a )
    7.16 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
    7.17 +typedef struct rb_root rb_root_t;
    7.18 +typedef struct rb_node rb_node_t;
    7.19 +#else
    7.20 +struct block_device;
    7.21 +#endif
    7.22  
    7.23  typedef struct blkif_st {
    7.24      /* Unique identifier for this interface. */
    7.25 @@ -46,7 +47,7 @@ typedef struct blkif_st {
    7.26      BLKIF_RING_IDX     blk_req_cons;  /* Request consumer. */
    7.27      BLKIF_RING_IDX     blk_resp_prod; /* Private version of resp. producer. */
    7.28      /* VBDs attached to this interface. */
    7.29 -    struct rb_root   vbd_rb;        /* Mapping from 16-bit vdevices to VBDs. */
    7.30 +    rb_root_t        vbd_rb;        /* Mapping from 16-bit vdevices to VBDs. */
    7.31      spinlock_t       vbd_lock;      /* Protects VBD mapping. */
    7.32      /* Private fields. */
    7.33      enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
    7.34 @@ -86,7 +87,7 @@ typedef struct _vbd {
    7.35      unsigned char      readonly;  /* Non-zero -> read-only */
    7.36      unsigned char      type;      /* VDISK_TYPE_xxx */
    7.37      blkif_extent_le_t *extents;   /* list of xen_extents making up this vbd */
    7.38 -    struct rb_node     rb;        /* for linking into R-B tree lookup struct */
    7.39 +    rb_node_t          rb;        /* for linking into R-B tree lookup struct */
    7.40  } vbd_t; 
    7.41  
    7.42  void vbd_create(blkif_be_vbd_create_t *create); 
    7.43 @@ -98,16 +99,12 @@ void destroy_all_vbds(blkif_t *blkif);
    7.44  
    7.45  /* Describes a [partial] disk extent (part of a block io request) */
    7.46  typedef struct {
    7.47 -    union {
    7.48 -	unsigned short dev;
    7.49 -	struct block_device *bdev;
    7.50 -    } _dev;
    7.51 -    unsigned short nr_sects;
    7.52 -    unsigned long  buffer;
    7.53 -    blkif_sector_t sector_number;
    7.54 +    unsigned short       dev;
    7.55 +    unsigned short       nr_sects;
    7.56 +    struct block_device *bdev;
    7.57 +    unsigned long        buffer;
    7.58 +    blkif_sector_t       sector_number;
    7.59  } phys_seg_t;
    7.60 -#define ps_device _dev.dev
    7.61 -#define ps_bdev _dev.bdev
    7.62  
    7.63  int vbd_translate(phys_seg_t *pseg, blkif_t *blkif, int operation); 
    7.64  
     8.1 --- a/linux-2.6.7-xen-sparse/drivers/xen/blkback/vbd.c	Tue Aug 03 20:23:21 2004 +0000
     8.2 +++ b/linux-2.6.7-xen-sparse/drivers/xen/blkback/vbd.c	Tue Aug 03 22:03:24 2004 +0000
     8.3 @@ -1,31 +1,32 @@
     8.4  /******************************************************************************
     8.5 - * arch/xen/drivers/blkif/backend/vbd.c
     8.6 + * blkback/vbd.c
     8.7   * 
     8.8   * Routines for managing virtual block devices (VBDs).
     8.9   * 
    8.10 + * NOTE: vbd_lock protects updates to the rb_tree against concurrent lookups 
    8.11 + * in vbd_translate.  All other lookups are implicitly protected because the 
    8.12 + * only caller (the control message dispatch routine) serializes the calls.
    8.13 + * 
    8.14   * Copyright (c) 2003-2004, Keir Fraser & Steve Hand
    8.15   */
    8.16  
    8.17  #include "common.h"
    8.18  
    8.19 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
    8.20  static dev_t vbd_map_devnum(blkif_pdev_t);
    8.21 -
    8.22 -/* vbd_lock: protects updates to the rb_tree against concurrent
    8.23 - * lookups in vbd_translate.  All other lookups are implicitly
    8.24 - * protected because the only caller (the control message dispatch
    8.25 - * routine) serializes the calls. */
    8.26 +#endif
    8.27  
    8.28  void vbd_create(blkif_be_vbd_create_t *create) 
    8.29  {
    8.30      vbd_t       *vbd; 
    8.31 -    struct rb_node **rb_p, *rb_parent = NULL;
    8.32 +    rb_node_t  **rb_p, *rb_parent = NULL;
    8.33      blkif_t     *blkif;
    8.34      blkif_vdev_t vdevice = create->vdevice;
    8.35  
    8.36      blkif = blkif_find_by_handle(create->domid, create->blkif_handle);
    8.37      if ( unlikely(blkif == NULL) )
    8.38      {
    8.39 -        PRINTK("vbd_create attempted for non-existent blkif (%u,%u)\n", 
    8.40 +        DPRINTK("vbd_create attempted for non-existent blkif (%u,%u)\n", 
    8.41                  create->domid, create->blkif_handle); 
    8.42          create->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
    8.43          return;
    8.44 @@ -46,7 +47,7 @@ void vbd_create(blkif_be_vbd_create_t *c
    8.45          }
    8.46          else
    8.47          {
    8.48 -            PRINTK("vbd_create attempted for already existing vbd\n");
    8.49 +            DPRINTK("vbd_create attempted for already existing vbd\n");
    8.50              create->status = BLKIF_BE_STATUS_VBD_EXISTS;
    8.51              return;
    8.52          }
    8.53 @@ -54,7 +55,7 @@ void vbd_create(blkif_be_vbd_create_t *c
    8.54  
    8.55      if ( unlikely((vbd = kmalloc(sizeof(vbd_t), GFP_KERNEL)) == NULL) )
    8.56      {
    8.57 -        PRINTK("vbd_create: out of memory\n");
    8.58 +        DPRINTK("vbd_create: out of memory\n");
    8.59          create->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
    8.60          return;
    8.61      }
    8.62 @@ -81,15 +82,14 @@ void vbd_grow(blkif_be_vbd_grow_t *grow)
    8.63      blkif_t            *blkif;
    8.64      blkif_extent_le_t **px, *x; 
    8.65      vbd_t              *vbd = NULL;
    8.66 -    struct rb_node     *rb;
    8.67 +    rb_node_t          *rb;
    8.68      blkif_vdev_t        vdevice = grow->vdevice;
    8.69      unsigned long       sz;
    8.70  
    8.71 -
    8.72      blkif = blkif_find_by_handle(grow->domid, grow->blkif_handle);
    8.73      if ( unlikely(blkif == NULL) )
    8.74      {
    8.75 -        PRINTK("vbd_grow attempted for non-existent blkif (%u,%u)\n", 
    8.76 +        DPRINTK("vbd_grow attempted for non-existent blkif (%u,%u)\n", 
    8.77                  grow->domid, grow->blkif_handle); 
    8.78          grow->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
    8.79          return;
    8.80 @@ -109,22 +109,22 @@ void vbd_grow(blkif_be_vbd_grow_t *grow)
    8.81  
    8.82      if ( unlikely(vbd == NULL) || unlikely(vbd->vdevice != vdevice) )
    8.83      {
    8.84 -        PRINTK("vbd_grow: attempted to append extent to non-existent VBD.\n");
    8.85 +        DPRINTK("vbd_grow: attempted to append extent to non-existent VBD.\n");
    8.86          grow->status = BLKIF_BE_STATUS_VBD_NOT_FOUND;
    8.87          return;
    8.88      } 
    8.89  
    8.90      if ( grow->extent.sector_start > 0 )
    8.91      {
    8.92 -        PRINTK("vbd_grow: device %08x start not zero!\n", grow->extent.device);
    8.93 -	grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
    8.94 -	return;
    8.95 +        DPRINTK("vbd_grow: dev %08x start not zero.\n", grow->extent.device);
    8.96 +        grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
    8.97 +        return;
    8.98      }
    8.99  
   8.100      if ( unlikely((x = kmalloc(sizeof(blkif_extent_le_t), 
   8.101                                 GFP_KERNEL)) == NULL) )
   8.102      {
   8.103 -        PRINTK("vbd_grow: out of memory\n");
   8.104 +        DPRINTK("vbd_grow: out of memory\n");
   8.105          grow->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
   8.106          return;
   8.107      }
   8.108 @@ -134,28 +134,45 @@ void vbd_grow(blkif_be_vbd_grow_t *grow)
   8.109      x->extent.sector_length = grow->extent.sector_length;
   8.110      x->next                 = (blkif_extent_le_t *)NULL;
   8.111  
   8.112 -#if 01
   8.113 -    /* XXXcl see comments at top of open_by_devnum */
   8.114 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   8.115      x->bdev = open_by_devnum(vbd_map_devnum(x->extent.device),
   8.116 -			     vbd->readonly ? FMODE_READ : FMODE_WRITE);
   8.117 -    if (IS_ERR(x->bdev)) {
   8.118 -	PRINTK("vbd_grow: device %08x doesn't exist.\n", x->extent.device);
   8.119 -	grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
   8.120 -	goto out;
   8.121 +                             vbd->readonly ? FMODE_READ : FMODE_WRITE);
   8.122 +    if ( IS_ERR(x->bdev) )
   8.123 +    {
   8.124 +        DPRINTK("vbd_grow: device %08x doesn't exist.\n", x->extent.device);
   8.125 +        grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
   8.126 +        goto out;
   8.127      }
   8.128      /* XXXcl maybe bd_claim? */
   8.129  
   8.130 -    if( x->bdev->bd_disk == NULL || x->bdev->bd_part == NULL )
   8.131 +    if ( (x->bdev->bd_disk == NULL) || (x->bdev->bd_part == NULL) )
   8.132      {
   8.133 -        PRINTK("vbd_grow: device %08x doesn't exist.\n", x->extent.device);
   8.134 -	grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
   8.135 -	blkdev_put(x->bdev);
   8.136 -	goto out;
   8.137 +        DPRINTK("vbd_grow: device %08x doesn't exist.\n", x->extent.device);
   8.138 +        grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
   8.139 +        blkdev_put(x->bdev);
   8.140 +        goto out;
   8.141      }
   8.142 -#endif
   8.143     
   8.144      /* get size in sectors */
   8.145      sz = x->bdev->bd_part->nr_sects;
   8.146 +#else
   8.147 +    if( !blk_size[MAJOR(x->extent.device)] )
   8.148 +    {
   8.149 +        DPRINTK("vbd_grow: device %08x doesn't exist.\n", x->extent.device);
   8.150 +        grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
   8.151 +        goto out;
   8.152 +    }
   8.153 +    
   8.154 +    /* convert blocks (1KB) to sectors */
   8.155 +    sz = blk_size[MAJOR(x->extent.device)][MINOR(x->extent.device)] * 2;    
   8.156 +    
   8.157 +    if ( sz == 0 )
   8.158 +    {
   8.159 +        DPRINTK("vbd_grow: device %08x zero size!\n", x->extent.device);
   8.160 +        grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
   8.161 +        goto out;
   8.162 +    }
   8.163 +#endif
   8.164  
   8.165      /*
   8.166       * NB. This test assumes sector_start == 0, which is always the case
   8.167 @@ -171,7 +188,7 @@ void vbd_grow(blkif_be_vbd_grow_t *grow)
   8.168      for ( px = &vbd->extents; *px != NULL; px = &(*px)->next ) 
   8.169          continue;
   8.170      
   8.171 -    *px = x;
   8.172 +    *px = x; /* ATOMIC: no need for vbd_lock. */
   8.173  
   8.174      DPRINTK("Successful grow of vdev=%04x (dom=%u)\n",
   8.175              vdevice, grow->domid);
   8.176 @@ -189,7 +206,7 @@ void vbd_shrink(blkif_be_vbd_shrink_t *s
   8.177      blkif_t            *blkif;
   8.178      blkif_extent_le_t **px, *x; 
   8.179      vbd_t              *vbd = NULL;
   8.180 -    struct rb_node     *rb;
   8.181 +    rb_node_t          *rb;
   8.182      blkif_vdev_t        vdevice = shrink->vdevice;
   8.183  
   8.184      blkif = blkif_find_by_handle(shrink->domid, shrink->blkif_handle);
   8.185 @@ -216,13 +233,13 @@ void vbd_shrink(blkif_be_vbd_shrink_t *s
   8.186      if ( unlikely(vbd == NULL) || unlikely(vbd->vdevice != vdevice) )
   8.187      {
   8.188          shrink->status = BLKIF_BE_STATUS_VBD_NOT_FOUND;
   8.189 -	return;
   8.190 +        return;
   8.191      }
   8.192  
   8.193      if ( unlikely(vbd->extents == NULL) )
   8.194      {
   8.195          shrink->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
   8.196 -	return;
   8.197 +        return;
   8.198      }
   8.199  
   8.200      /* Find the last extent. We now know that there is at least one. */
   8.201 @@ -230,9 +247,11 @@ void vbd_shrink(blkif_be_vbd_shrink_t *s
   8.202          continue;
   8.203  
   8.204      x   = *px;
   8.205 -    *px = x->next;
   8.206 +    *px = x->next; /* ATOMIC: no need for vbd_lock. */
   8.207  
   8.208 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   8.209      blkdev_put(x->bdev);
   8.210 +#endif
   8.211      kfree(x);
   8.212  
   8.213      shrink->status = BLKIF_BE_STATUS_OKAY;
   8.214 @@ -243,14 +262,14 @@ void vbd_destroy(blkif_be_vbd_destroy_t 
   8.215  {
   8.216      blkif_t           *blkif;
   8.217      vbd_t             *vbd;
   8.218 -    struct rb_node    *rb;
   8.219 +    rb_node_t         *rb;
   8.220      blkif_extent_le_t *x, *t;
   8.221      blkif_vdev_t       vdevice = destroy->vdevice;
   8.222  
   8.223      blkif = blkif_find_by_handle(destroy->domid, destroy->blkif_handle);
   8.224      if ( unlikely(blkif == NULL) )
   8.225      {
   8.226 -        PRINTK("vbd_destroy attempted for non-existent blkif (%u,%u)\n", 
   8.227 +        DPRINTK("vbd_destroy attempted for non-existent blkif (%u,%u)\n", 
   8.228                  destroy->domid, destroy->blkif_handle); 
   8.229          destroy->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
   8.230          return;
   8.231 @@ -290,8 +309,8 @@ void vbd_destroy(blkif_be_vbd_destroy_t 
   8.232  
   8.233  void destroy_all_vbds(blkif_t *blkif)
   8.234  {
   8.235 -    vbd_t *vbd;
   8.236 -    struct rb_node *rb;
   8.237 +    vbd_t             *vbd;
   8.238 +    rb_node_t         *rb;
   8.239      blkif_extent_le_t *x, *t;
   8.240  
   8.241      spin_lock(&blkif->vbd_lock);
   8.242 @@ -334,8 +353,8 @@ static int vbd_probe_single(blkif_t *blk
   8.243  
   8.244  int vbd_probe(blkif_t *blkif, vdisk_t *vbd_info, int max_vbds)
   8.245  {
   8.246 -    int rc = 0, nr_vbds = 0;
   8.247 -    struct rb_node *rb;
   8.248 +    int        rc = 0, nr_vbds = 0;
   8.249 +    rb_node_t *rb;
   8.250  
   8.251      spin_lock(&blkif->vbd_lock);
   8.252  
   8.253 @@ -389,7 +408,7 @@ int vbd_translate(phys_seg_t *pseg, blki
   8.254  {
   8.255      blkif_extent_le_t *x; 
   8.256      vbd_t             *vbd;
   8.257 -    struct rb_node    *rb;
   8.258 +    rb_node_t         *rb;
   8.259      blkif_sector_t     sec_off;
   8.260      unsigned long      nr_secs;
   8.261  
   8.262 @@ -400,9 +419,9 @@ int vbd_translate(phys_seg_t *pseg, blki
   8.263      while ( rb != NULL )
   8.264      {
   8.265          vbd = rb_entry(rb, vbd_t, rb);
   8.266 -        if ( pseg->ps_device < vbd->vdevice )
   8.267 +        if ( pseg->dev < vbd->vdevice )
   8.268              rb = rb->rb_left;
   8.269 -        else if ( pseg->ps_device > vbd->vdevice )
   8.270 +        else if ( pseg->dev > vbd->vdevice )
   8.271              rb = rb->rb_right;
   8.272          else
   8.273              goto found;
   8.274 @@ -432,11 +451,8 @@ int vbd_translate(phys_seg_t *pseg, blki
   8.275      { 
   8.276          if ( sec_off < x->extent.sector_length )
   8.277          {
   8.278 -#if 0
   8.279 -            pseg->ps_device = x->extent.device;
   8.280 -#else
   8.281 -	    pseg->ps_bdev = x->bdev;
   8.282 -#endif
   8.283 +            pseg->dev  = x->extent.device;
   8.284 +            pseg->bdev = x->bdev;
   8.285              pseg->sector_number = x->extent.sector_start + sec_off;
   8.286              if ( unlikely((sec_off + nr_secs) > x->extent.sector_length) )
   8.287                  goto overrun;
   8.288 @@ -475,19 +491,19 @@ int vbd_translate(phys_seg_t *pseg, blki
   8.289      }
   8.290  
   8.291      /* Store the real device and start sector for the second chunk. */
   8.292 -#if 0
   8.293 -    pseg[1].ps_device     = x->extent.device;
   8.294 -#else
   8.295 -    pseg->ps_bdev         = x->bdev;
   8.296 -#endif
   8.297 +    pseg[1].dev           = x->extent.device;
   8.298 +    pseg[1].bdev          = x->bdev;
   8.299      pseg[1].sector_number = x->extent.sector_start;
   8.300      
   8.301      spin_unlock(&blkif->vbd_lock);
   8.302      return 2;
   8.303  }
   8.304  
   8.305 -#define MAJOR_XEN(dev)	((dev)>>8)
   8.306 -#define MINOR_XEN(dev)	((dev) & 0xff)
   8.307 +
   8.308 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   8.309 +
   8.310 +#define MAJOR_XEN(dev) ((dev)>>8)
   8.311 +#define MINOR_XEN(dev) ((dev) & 0xff)
   8.312  
   8.313  #ifndef FANCY_REMAPPING
   8.314  static dev_t vbd_map_devnum(blkif_pdev_t cookie)
   8.315 @@ -498,25 +514,25 @@ static dev_t vbd_map_devnum(blkif_pdev_t
   8.316      return MKDEV(major, minor);
   8.317  }
   8.318  #else
   8.319 -#define	XEN_IDE0_MAJOR IDE0_MAJOR
   8.320 -#define	XEN_IDE1_MAJOR IDE1_MAJOR
   8.321 -#define	XEN_IDE2_MAJOR IDE2_MAJOR
   8.322 -#define	XEN_IDE3_MAJOR IDE3_MAJOR
   8.323 -#define	XEN_IDE4_MAJOR IDE4_MAJOR
   8.324 -#define	XEN_IDE5_MAJOR IDE5_MAJOR
   8.325 -#define	XEN_IDE6_MAJOR IDE6_MAJOR
   8.326 -#define	XEN_IDE7_MAJOR IDE7_MAJOR
   8.327 -#define	XEN_IDE8_MAJOR IDE8_MAJOR
   8.328 -#define	XEN_IDE9_MAJOR IDE9_MAJOR
   8.329 -#define	XEN_SCSI_DISK0_MAJOR SCSI_DISK0_MAJOR
   8.330 -#define	XEN_SCSI_DISK1_MAJOR SCSI_DISK1_MAJOR
   8.331 -#define	XEN_SCSI_DISK2_MAJOR SCSI_DISK2_MAJOR
   8.332 -#define	XEN_SCSI_DISK3_MAJOR SCSI_DISK3_MAJOR
   8.333 -#define	XEN_SCSI_DISK4_MAJOR SCSI_DISK4_MAJOR
   8.334 -#define	XEN_SCSI_DISK5_MAJOR SCSI_DISK5_MAJOR
   8.335 -#define	XEN_SCSI_DISK6_MAJOR SCSI_DISK6_MAJOR
   8.336 -#define	XEN_SCSI_DISK7_MAJOR SCSI_DISK7_MAJOR
   8.337 -#define	XEN_SCSI_CDROM_MAJOR SCSI_CDROM_MAJOR
   8.338 +#define XEN_IDE0_MAJOR IDE0_MAJOR
   8.339 +#define XEN_IDE1_MAJOR IDE1_MAJOR
   8.340 +#define XEN_IDE2_MAJOR IDE2_MAJOR
   8.341 +#define XEN_IDE3_MAJOR IDE3_MAJOR
   8.342 +#define XEN_IDE4_MAJOR IDE4_MAJOR
   8.343 +#define XEN_IDE5_MAJOR IDE5_MAJOR
   8.344 +#define XEN_IDE6_MAJOR IDE6_MAJOR
   8.345 +#define XEN_IDE7_MAJOR IDE7_MAJOR
   8.346 +#define XEN_IDE8_MAJOR IDE8_MAJOR
   8.347 +#define XEN_IDE9_MAJOR IDE9_MAJOR
   8.348 +#define XEN_SCSI_DISK0_MAJOR SCSI_DISK0_MAJOR
   8.349 +#define XEN_SCSI_DISK1_MAJOR SCSI_DISK1_MAJOR
   8.350 +#define XEN_SCSI_DISK2_MAJOR SCSI_DISK2_MAJOR
   8.351 +#define XEN_SCSI_DISK3_MAJOR SCSI_DISK3_MAJOR
   8.352 +#define XEN_SCSI_DISK4_MAJOR SCSI_DISK4_MAJOR
   8.353 +#define XEN_SCSI_DISK5_MAJOR SCSI_DISK5_MAJOR
   8.354 +#define XEN_SCSI_DISK6_MAJOR SCSI_DISK6_MAJOR
   8.355 +#define XEN_SCSI_DISK7_MAJOR SCSI_DISK7_MAJOR
   8.356 +#define XEN_SCSI_CDROM_MAJOR SCSI_CDROM_MAJOR
   8.357  
   8.358  static dev_t vbd_map_devnum(blkif_pdev_t cookie)
   8.359  {
   8.360 @@ -537,8 +553,8 @@ static dev_t vbd_map_devnum(blkif_pdev_t
   8.361      case XEN_IDE9_MAJOR: new_major = IDE9_MAJOR; break;
   8.362      case XEN_SCSI_DISK0_MAJOR: new_major = SCSI_DISK0_MAJOR; break;
   8.363      case XEN_SCSI_DISK1_MAJOR ... XEN_SCSI_DISK7_MAJOR:
   8.364 -	new_major = SCSI_DISK1_MAJOR + major - XEN_SCSI_DISK1_MAJOR;
   8.365 -	break;
   8.366 +        new_major = SCSI_DISK1_MAJOR + major - XEN_SCSI_DISK1_MAJOR;
   8.367 +        break;
   8.368      case XEN_SCSI_CDROM_MAJOR: new_major = SCSI_CDROM_MAJOR; break;
   8.369      default: new_major = 0; break;
   8.370      }
   8.371 @@ -546,3 +562,5 @@ static dev_t vbd_map_devnum(blkif_pdev_t
   8.372      return MKDEV(new_major, minor);
   8.373  }
   8.374  #endif
   8.375 +
   8.376 +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION_CODE(2,6,0) */