ia64/xen-unstable

changeset 939:cfd9961afd8b

bitkeeper revision 1.596.1.1 (3fb282f5lerTApG4SkcCvGEWh9vYBg)

VBD fixes + improvements
author smh22@labyrinth.cl.cam.ac.uk
date Wed Nov 12 18:59:01 2003 +0000 (2003-11-12)
parents 464dff9c4e15
children 72b0ba1bfefb
files BitKeeper/etc/ignore tools/internal/xi_vbd_info.c tools/internal/xi_vbd_list.c xen/drivers/block/xen_block.c xen/drivers/block/xen_vbd.c xen/include/hypervisor-ifs/vbd.h xenolinux-2.4.22-sparse/arch/xeno/drivers/block/xl_block.c
line diff
     1.1 --- a/BitKeeper/etc/ignore	Wed Nov 12 14:46:39 2003 +0000
     1.2 +++ b/BitKeeper/etc/ignore	Wed Nov 12 18:59:01 2003 +0000
     1.3 @@ -488,3 +488,7 @@ tools/internal/xi_vbd_create
     1.4  tools/internal/xi_vbd_info
     1.5  tools/internal/xi_vbd_list
     1.6  xen/drivers/scsi/BusLogic.o
     1.7 +tools/misc/xen_netwatch
     1.8 +xen/drivers/scsi/scsi_obsolete.o
     1.9 +xen/xen
    1.10 +xen/xen.gz
     2.1 --- a/tools/internal/xi_vbd_info.c	Wed Nov 12 14:46:39 2003 +0000
     2.2 +++ b/tools/internal/xi_vbd_info.c	Wed Nov 12 18:59:01 2003 +0000
     2.3 @@ -2,12 +2,62 @@
     2.4  #define _GNU_SOURCE
     2.5  #include "dom0_defs.h"
     2.6  
     2.7 +#define MAX_EXTENTS 32 
     2.8 +#define XEA_SIZE    (MAX_EXTENTS * sizeof(xen_extent_t))
     2.9  
    2.10  int main(int argc, char *argv[])
    2.11  {
    2.12 -//    block_io_op_t op; 
    2.13 +    block_io_op_t op; 
    2.14 +    unsigned int domain; 
    2.15 +    unsigned short vdevice; 
    2.16 +    xen_extent_t *extents; 
    2.17 +    int i, nextents, ret; 
    2.18  
    2.19 -    // XXX SMH: writeme
    2.20 +    if( argc != 3) { 
    2.21 +	fprintf(stderr, "Usage: xi_vbd_info domain device\n"); 
    2.22 +	return 1; 
    2.23 +    } 
    2.24 +    
    2.25 +    domain  = atoi(argv[1]); 
    2.26 +    vdevice = atoi(argv[2]); 
    2.27 +
    2.28 +    extents = malloc(XEA_SIZE); // convenience 
    2.29 +
    2.30 +    op.cmd = BLOCK_IO_OP_VBD_INFO; 
    2.31 +    op.u.info_params.domain     = domain; 
    2.32 +    op.u.info_params.vdevice    = vdevice; 
    2.33 +    op.u.info_params.maxextents = MAX_EXTENTS; 
    2.34 +    op.u.info_params.extents    = extents; 
    2.35 +    op.u.info_params.nextents   = 0; 
    2.36 +    op.u.info_params.mode       = 0; 
    2.37 +
    2.38 +    if(mlock(extents, XEA_SIZE) != 0) { 
    2.39 +        PERROR("Could not lock memory for Xen hypercall");
    2.40 +	return -1; 
    2.41 +    }
    2.42 +
    2.43 +    ret = do_block_io_op(&op);
    2.44 +
    2.45 +    (void)munlock(extents, XEA_SIZE); 
    2.46 +
    2.47 +    if(ret < 0) {
    2.48 +	fprintf(stderr, "error %d attempting to query VBD %04x for dom %d\n", 
    2.49 +		ret, vdevice, domain);
    2.50 +    } else { 
    2.51 +
    2.52 +	nextents = op.u.info_params.nextents; 
    2.53 +	fprintf(stderr, "Domain %d VBD %04x (mode %s) total of %d extents:\n", 
    2.54 +		domain, vdevice, op.u.info_params.mode == 1 ? "read-only" 
    2.55 +		: "read/write", nextents); 
    2.56 +
    2.57 +	for(i = 0; i < nextents; i++) { 
    2.58 +	    fprintf(stderr, "extent %02d: dev %04x start %ld length %ld\n", 
    2.59 +		    i, extents[i].device, extents[i].start_sector, 
    2.60 +		    extents[i].nr_sectors); 
    2.61 +	} 
    2.62 +		    
    2.63 +    }
    2.64 +
    2.65  
    2.66      return 0;
    2.67  }
     3.1 --- a/tools/internal/xi_vbd_list.c	Wed Nov 12 14:46:39 2003 +0000
     3.2 +++ b/tools/internal/xi_vbd_list.c	Wed Nov 12 18:59:01 2003 +0000
     3.3 @@ -47,19 +47,19 @@ int main(int argc, char *argv[])
     3.4  
     3.5      ret = do_block_io_op(&op);
     3.6  
     3.7 -    if(ret < 0) 
     3.8 -	fprintf(stderr, "error %d attempting to probe VBDs\n", ret);
     3.9 -
    3.10      (void)munlock(xdi->disks, XDA_SIZE); 
    3.11  
    3.12 -    for(i = 0; i < xdi->count; i++) { 
    3.13 -	fprintf(stderr, 
    3.14 -		"Domain %02d %cBD: [R/%c] device %04x capacity %ldkB\n", 
    3.15 -		xdi->disks[i].domain, XD_VIRTUAL(xdi->disks[i].info) ? 'V' : 
    3.16 -		'P', XD_READONLY(xdi->disks[i].info) ? 'O' : 'W', 
    3.17 -		xdi->disks[i].device,  xdi->disks[i].capacity >> 1); 
    3.18 +
    3.19 +    if(ret < 0) {
    3.20 +	fprintf(stderr, "error %d attempting to probe VBDs\n", ret);
    3.21 +    } else {
    3.22 +	for(i = 0; i < xdi->count; i++)
    3.23 +	    fprintf(stderr, 
    3.24 +		    "Domain %02d %cBD: [R/%c] device %04x capacity %ldkB\n", 
    3.25 +		    xdi->disks[i].domain, XD_VIRTUAL(xdi->disks[i].info) ? 
    3.26 +		    'V' : 'P', XD_READONLY(xdi->disks[i].info) ? 'O' : 'W', 
    3.27 +		    xdi->disks[i].device,  xdi->disks[i].capacity >> 1); 
    3.28      }
    3.29 -
    3.30 -
    3.31 +    
    3.32      return ret;
    3.33  }
     4.1 --- a/xen/drivers/block/xen_block.c	Wed Nov 12 14:46:39 2003 +0000
     4.2 +++ b/xen/drivers/block/xen_block.c	Wed Nov 12 18:59:01 2003 +0000
     4.3 @@ -269,6 +269,8 @@ long do_block_io_op(block_io_op_t *u_blo
     4.4      case BLOCK_IO_OP_VBD_INFO: 
     4.5  	/* query information about a particular VBD */
     4.6  	ret = vbd_info(&op.u.info_params); 
     4.7 +	if(ret == 0)
     4.8 +	    copy_to_user(u_block_io_op, &op, sizeof(op)); 
     4.9  	break; 
    4.10  
    4.11      default: 
     5.1 --- a/xen/drivers/block/xen_vbd.c	Wed Nov 12 14:46:39 2003 +0000
     5.2 +++ b/xen/drivers/block/xen_vbd.c	Wed Nov 12 18:59:01 2003 +0000
     5.3 @@ -121,6 +121,7 @@ long vbd_add(vbd_add_t *add_params)
     5.4      } 
     5.5  
     5.6      put_task_struct(p);
     5.7 +
     5.8      return 0; 
     5.9  }
    5.10  
    5.11 @@ -201,7 +202,8 @@ static int vbd_probe_devices(xen_disk_in
    5.12  long vbd_probe(vbd_probe_t *probe_params) 
    5.13  {
    5.14      struct task_struct *p = NULL; 
    5.15 -    int ret;  
    5.16 +    short putp = 0; 
    5.17 +    int ret = 0;  
    5.18  
    5.19      if(probe_params->domain) { 
    5.20  
    5.21 @@ -212,13 +214,14 @@ long vbd_probe(vbd_probe_t *probe_params
    5.22  	if(probe_params->domain != VBD_PROBE_ALL) { 
    5.23  
    5.24  	    p = find_domain_by_id(probe_params->domain);
    5.25 -	
    5.26 +	    
    5.27  	    if (!p) { 
    5.28  		printk("vbd_probe attempted for non-existent domain %d\n", 
    5.29  		       probe_params->domain); 
    5.30  		return -EINVAL; 
    5.31  	    }
    5.32  
    5.33 +	    putp = 1; 
    5.34  	}
    5.35  
    5.36      } else 
    5.37 @@ -231,11 +234,11 @@ long vbd_probe(vbd_probe_t *probe_params
    5.38  	/* privileged domains always get access to the 'real' devices */
    5.39  	if((ret = ide_probe_devices(&probe_params->xdi))) {
    5.40  	    printk("vbd_probe: error %d in probing ide devices\n", ret); 
    5.41 -	    return ret; 
    5.42 +	    goto out; 
    5.43  	}
    5.44  	if((ret = scsi_probe_devices(&probe_params->xdi))) { 
    5.45  	    printk("vbd_probe: error %d in probing scsi devices\n", ret); 
    5.46 -	    return ret; 
    5.47 +	    goto out; 
    5.48  	}
    5.49      } 
    5.50      
    5.51 @@ -253,7 +256,7 @@ long vbd_probe(vbd_probe_t *probe_params
    5.52  		    printk("vbd_probe: error %d in probing virtual devices\n",
    5.53  			   ret); 
    5.54  		    read_unlock_irqrestore(&tasklist_lock, flags);
    5.55 -		    return ret; 
    5.56 +		    goto out; 
    5.57  		}
    5.58  	    }
    5.59  	}
    5.60 @@ -265,18 +268,66 @@ long vbd_probe(vbd_probe_t *probe_params
    5.61  	/* probe for disks and VBDs for just 'p' */
    5.62  	if((ret = vbd_probe_devices(&probe_params->xdi, p))) { 
    5.63  	    printk("vbd_probe: error %d in probing virtual devices\n", ret); 
    5.64 -	    return ret; 
    5.65 +	    goto out; 
    5.66  	}
    5.67  
    5.68      }
    5.69  
    5.70 + out: 
    5.71 +    if(putp) 
    5.72 +	put_task_struct(p); 
    5.73  
    5.74 -    return 0; 
    5.75 +    return ret; 
    5.76  }
    5.77  
    5.78  long vbd_info(vbd_info_t *info_params) 
    5.79  {
    5.80 -    return -ENOSYS; 
    5.81 +    struct task_struct *p = NULL; 
    5.82 +    xen_extent_le_t *x; 
    5.83 +    xen_extent_t *extents; 
    5.84 +    vbd_t *v; 
    5.85 +    int h, ret = 0;  
    5.86 +   
    5.87 +    if(info_params->domain != current->domain && !IS_PRIV(current))
    5.88 +	return -EPERM; 
    5.89 +
    5.90 +    p = find_domain_by_id(info_params->domain);
    5.91 +    
    5.92 +    if (!p) { 
    5.93 +	printk("vbd_info attempted for non-existent domain %d\n", 
    5.94 +	       info_params->domain); 
    5.95 +	return -EINVAL; 
    5.96 +    }
    5.97 +
    5.98 +    h = HSH(info_params->vdevice); 
    5.99 +
   5.100 +    for(v = p->vbdtab[h]; v; v = v->next) 
   5.101 +	if(v->vdevice == info_params->vdevice)
   5.102 +	    break; 
   5.103 +
   5.104 +    if(!v) {
   5.105 +	printk("vbd_info attempted on non-existent VBD.\n"); 
   5.106 +	ret = -EINVAL; 
   5.107 +	goto out; 
   5.108 +    }
   5.109 +
   5.110 +    info_params->mode     = v->mode; 
   5.111 +    info_params->nextents = 0; 
   5.112 +
   5.113 +    extents = info_params->extents; // convenience 
   5.114 +
   5.115 +    for(x = v->extents; x; x = x->next) {
   5.116 +	if((ret = copy_to_user(extents++, &x->extent, 
   5.117 +			       sizeof(xen_extent_t))) < 0) {
   5.118 +	    printk("vbd_info: copy_to_user failed [rc=%d]\n", ret); 
   5.119 +	    goto out; 
   5.120 +	} 
   5.121 +	info_params->nextents++; 
   5.122 +    }
   5.123 +
   5.124 + out: 
   5.125 +    put_task_struct(p); 
   5.126 +    return ret; 
   5.127  }
   5.128  
   5.129  
     6.1 --- a/xen/include/hypervisor-ifs/vbd.h	Wed Nov 12 14:46:39 2003 +0000
     6.2 +++ b/xen/include/hypervisor-ifs/vbd.h	Wed Nov 12 18:59:01 2003 +0000
     6.3 @@ -63,10 +63,14 @@ typedef struct _vbd_probe {
     6.4  } vbd_probe_t; 
     6.5  
     6.6  typedef struct _vbd_info { 
     6.7 +    /* IN variables  */
     6.8      unsigned      domain;             // domain in question 
     6.9      u16           vdevice;            // 16 bit id domain refers to VBD as 
    6.10 -    u16           nextents;           // max no. of extents to return info for
    6.11 -    xen_extent_t *extents;            // pointer to space for list of extents
    6.12 +    u16           maxextents;         // max no. of extents to return info for
    6.13 +    xen_extent_t *extents;            // pointer to space for array of extents
    6.14 +    /* OUT variables */
    6.15 +    u16           nextents;           // no of extents in the above  
    6.16 +    u16           mode;               // VBD_MODE_{READONLY,READWRITE}
    6.17  } vbd_info_t; 
    6.18  
    6.19  
     7.1 --- a/xenolinux-2.4.22-sparse/arch/xeno/drivers/block/xl_block.c	Wed Nov 12 14:46:39 2003 +0000
     7.2 +++ b/xenolinux-2.4.22-sparse/arch/xeno/drivers/block/xl_block.c	Wed Nov 12 18:59:01 2003 +0000
     7.3 @@ -26,11 +26,6 @@ static unsigned int req_prod;  /* Privat
     7.4  #define XDI_MAX 64 
     7.5  static xen_disk_info_t xlblk_disk_info; /* information about our disks/VBDs */
     7.6  
     7.7 -#if 0
     7.8 -static int xlblk_control_msg_pending;
     7.9 -#endif
    7.10 -
    7.11 -
    7.12  /* We plug the I/O ring if the driver is suspended or if the ring is full. */
    7.13  #define RING_PLUGGED ((BLK_RING_INC(req_prod) == resp_cons) || \
    7.14                        (state != STATE_ACTIVE))
    7.15 @@ -71,7 +66,14 @@ static inline xl_disk_t *xldev_to_xldisk
    7.16  
    7.17  int xenolinux_block_open(struct inode *inode, struct file *filep)
    7.18  {
    7.19 +    short xldev = inode->i_rdev; 
    7.20 +    struct gendisk *gd = xldev_to_gendisk(xldev);
    7.21      xl_disk_t *disk = xldev_to_xldisk(inode->i_rdev);
    7.22 +
    7.23 +    /* Don't allow open if device doesn't exist :-) */
    7.24 +    if(!gd->part[MINOR(xldev)].nr_sects) 
    7.25 +	return -ENXIO; // no such device 
    7.26 +
    7.27      disk->usage++;
    7.28      DPRINTK("xenolinux_block_open\n");
    7.29      return 0;
    7.30 @@ -253,18 +255,18 @@ static int hypervisor_request(unsigned l
    7.31  
    7.32      switch ( operation )
    7.33      {
    7.34 -#if 0
    7.35 -    case XEN_BLOCK_PROBE:
    7.36 -        if ( RING_PLUGGED ) return 1;
    7.37 -	sector_number = 0;
    7.38 -        DISABLE_SCATTERGATHER();
    7.39 -        break;
    7.40 -#endif
    7.41  
    7.42      case XEN_BLOCK_READ:
    7.43      case XEN_BLOCK_WRITE:
    7.44 +
    7.45 +	/* Get the appropriate gendisk */
    7.46  	gd = xldev_to_gendisk(device); 
    7.47 +
    7.48 +	/* Update the sector_number we'll pass down as appropriate; note 
    7.49 +	   that we could sanity check that resulting sector will be in 
    7.50 +	   this partition, but this will happen in xen anyhow */
    7.51  	sector_number += gd->part[MINOR(device)].start_sect;
    7.52 +
    7.53          if ( (sg_operation == operation) &&
    7.54               (sg_dev == device) &&
    7.55               (sg_next_sect == sector_number) )
    7.56 @@ -349,12 +351,13 @@ void do_xlblk_request(request_queue_t *r
    7.57                  (rw == READ) ? XEN_BLOCK_READ : XEN_BLOCK_WRITE, 
    7.58                  bh->b_data, bh->b_rsector, bh->b_size>>9, bh->b_rdev);
    7.59  
    7.60 -            if ( full )
    7.61 -            {
    7.62 -                bh->b_reqnext = next_bh;
    7.63 -                pending_queues[nr_pending++] = rq;
    7.64 -                if ( nr_pending >= MAX_PENDING ) BUG();
    7.65 -                goto out;
    7.66 +	    if(full) { 
    7.67 +
    7.68 +		bh->b_reqnext = next_bh;
    7.69 +		pending_queues[nr_pending++] = rq;
    7.70 +		if ( nr_pending >= MAX_PENDING ) BUG();
    7.71 +		goto out; 
    7.72 +
    7.73              }
    7.74  
    7.75              queued++;
    7.76 @@ -438,12 +441,6 @@ static void xlblk_response_int(int irq, 
    7.77              }
    7.78  	    break;
    7.79  	    
    7.80 -#if 0
    7.81 -        case XEN_BLOCK_PROBE:
    7.82 -            xlblk_control_msg_pending = bret->status;
    7.83 -            break;
    7.84 -#endif
    7.85 -	  
    7.86          default:
    7.87              BUG();
    7.88  	}
    7.89 @@ -457,40 +454,11 @@ static void xlblk_response_int(int irq, 
    7.90  }
    7.91  
    7.92  
    7.93 -#if 0
    7.94 -/* Send a synchronous message to Xen. */
    7.95 -int xenolinux_control_msg(int operation, char *buffer, int size)
    7.96 -{
    7.97 -    unsigned long flags;
    7.98 -    char *aligned_buf;
    7.99 -
   7.100 -    /* We copy from an aligned buffer, as interface needs sector alignment. */
   7.101 -    aligned_buf = (char *)get_free_page(GFP_KERNEL);
   7.102 -    if ( aligned_buf == NULL ) BUG();
   7.103 -    memcpy(aligned_buf, buffer, size);
   7.104 -
   7.105 -    xlblk_control_msg_pending = 2;
   7.106 -    spin_lock_irqsave(&io_request_lock, flags);
   7.107 -    /* Note that size gets rounded up to a sector-sized boundary. */
   7.108 -    if ( hypervisor_request(0, operation, aligned_buf, 0, (size+511)/512, 0) )
   7.109 -        return -EAGAIN;
   7.110 -    signal_requests_to_xen();
   7.111 -    spin_unlock_irqrestore(&io_request_lock, flags);
   7.112 -    while ( xlblk_control_msg_pending == 2 ) barrier();
   7.113 -
   7.114 -    memcpy(buffer, aligned_buf, size);
   7.115 -    free_page((unsigned long)aligned_buf);
   7.116 -    
   7.117 -    return xlblk_control_msg_pending ? -EINVAL : 0;
   7.118 -}
   7.119 -#endif
   7.120 -
   7.121  
   7.122  static void reset_xlblk_interface(void)
   7.123  {
   7.124      block_io_op_t op; 
   7.125  
   7.126 -//    xlblk_control_msg_pending = 0;
   7.127      nr_pending = 0;
   7.128  
   7.129      op.cmd = BLOCK_IO_OP_RESET;