direct-io.hg
changeset 939:cfd9961afd8b
bitkeeper revision 1.596.1.1 (3fb282f5lerTApG4SkcCvGEWh9vYBg)
VBD fixes + improvements
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 + if( argc != 3) { 2.20 + fprintf(stderr, "Usage: xi_vbd_info domain device\n"); 2.21 + return 1; 2.22 + } 2.23 + 2.24 + domain = atoi(argv[1]); 2.25 + vdevice = atoi(argv[2]); 2.26 + 2.27 + extents = malloc(XEA_SIZE); // convenience 2.28 + 2.29 + op.cmd = BLOCK_IO_OP_VBD_INFO; 2.30 + op.u.info_params.domain = domain; 2.31 + op.u.info_params.vdevice = vdevice; 2.32 + op.u.info_params.maxextents = MAX_EXTENTS; 2.33 + op.u.info_params.extents = extents; 2.34 + op.u.info_params.nextents = 0; 2.35 + op.u.info_params.mode = 0; 2.36 2.37 - // XXX SMH: writeme 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;