direct-io.hg
changeset 1000:9a40e3a9158f
bitkeeper revision 1.645.1.1 (3fd9f02bxWKGgV_bPDcD98xGu_WfmA)
Many files:
Update the VBD interface.
Many files:
Update the VBD interface.
author | kaf24@scramble.cl.cam.ac.uk |
---|---|
date | Fri Dec 12 16:43:23 2003 +0000 (2003-12-12) |
parents | 0edb87f619c4 |
children | 70a2962f5aeb |
files | tools/examples/createlinuxdom.py tools/examples/mynewdom.py tools/xc/lib/xc.h tools/xc/lib/xc_vbd.c tools/xc/py/Xc.c xen/drivers/block/xen_block.c xen/drivers/block/xen_vbd.c xen/include/hypervisor-ifs/vbd.h xen/include/xeno/vbd.h |
line diff
1.1 --- a/tools/examples/createlinuxdom.py Mon Dec 08 08:14:58 2003 +0000 1.2 +++ b/tools/examples/createlinuxdom.py Fri Dec 12 16:43:23 2003 +0000 1.3 @@ -77,11 +77,11 @@ if root_partn: 1.4 print "Error creating root VBD" 1.5 xc.domain_destroy ( dom=id ) 1.6 sys.exit() 1.7 - if xc.vbd_add_extent( dom=id, 1.8 - vbd=root_info[0], 1.9 - device=root_info[1], 1.10 - start_sector=root_info[2], 1.11 - nr_sectors=root_info[3] ): 1.12 + if xc.vbd_grow( dom=id, 1.13 + vbd=root_info[0], 1.14 + device=root_info[1], 1.15 + start_sector=root_info[2], 1.16 + nr_sectors=root_info[3] ): 1.17 print "Error populating root VBD" 1.18 xc.domain_destroy ( dom=id ) 1.19 sys.exit() 1.20 @@ -91,11 +91,11 @@ if usr_partn: 1.21 print "Error creating usr VBD" 1.22 xc.domain_destroy ( dom=id ) 1.23 sys.exit() 1.24 - if xc.vbd_add_extent( dom=id, 1.25 - vbd=usr_info[0], 1.26 - device=usr_info[1], 1.27 - start_sector=usr_info[2], 1.28 - nr_sectors=usr_info[3] ): 1.29 + if xc.vbd_grow( dom=id, 1.30 + vbd=usr_info[0], 1.31 + device=usr_info[1], 1.32 + start_sector=usr_info[2], 1.33 + nr_sectors=usr_info[3] ): 1.34 print "Error populating usr VBD" 1.35 xc.domain_destroy ( dom=id ) 1.36 sys.exit()
2.1 --- a/tools/examples/mynewdom.py Mon Dec 08 08:14:58 2003 +0000 2.2 +++ b/tools/examples/mynewdom.py Fri Dec 12 16:43:23 2003 +0000 2.3 @@ -83,11 +83,11 @@ if root_partn: 2.4 print "Error creating root VBD" 2.5 xc.domain_destroy ( dom=id ) 2.6 sys.exit() 2.7 - if xc.vbd_add_extent( dom=id, 2.8 - vbd=root_info[0], 2.9 - device=root_info[1], 2.10 - start_sector=root_info[2], 2.11 - nr_sectors=root_info[3] ): 2.12 + if xc.vbd_grow( dom=id, 2.13 + vbd=root_info[0], 2.14 + device=root_info[1], 2.15 + start_sector=root_info[2], 2.16 + nr_sectors=root_info[3] ): 2.17 print "Error populating root VBD" 2.18 xc.domain_destroy ( dom=id ) 2.19 sys.exit() 2.20 @@ -97,11 +97,11 @@ if usr_partn: 2.21 print "Error creating usr VBD" 2.22 xc.domain_destroy ( dom=id ) 2.23 sys.exit() 2.24 - if xc.vbd_add_extent( dom=id, 2.25 - vbd=usr_info[0], 2.26 - device=usr_info[1], 2.27 - start_sector=usr_info[2], 2.28 - nr_sectors=usr_info[3] ): 2.29 + if xc.vbd_grow( dom=id, 2.30 + vbd=usr_info[0], 2.31 + device=usr_info[1], 2.32 + start_sector=usr_info[2], 2.33 + nr_sectors=usr_info[3] ): 2.34 print "Error populating usr VBD" 2.35 xc.domain_destroy ( dom=id ) 2.36 sys.exit()
3.1 --- a/tools/xc/lib/xc.h Mon Dec 08 08:14:58 2003 +0000 3.2 +++ b/tools/xc/lib/xc.h Fri Dec 12 16:43:23 2003 +0000 3.3 @@ -34,6 +34,9 @@ int xc_domain_stop(int xc_handle, 3.4 int xc_domain_destroy(int xc_handle, 3.5 unsigned int domid, 3.6 int force); 3.7 +int xc_domain_pincpu(int xc_handle, 3.8 + unsigned int domid, 3.9 + int cpu); 3.10 int xc_domain_getinfo(int xc_handle, 3.11 unsigned int first_domid, 3.12 unsigned int max_doms, 3.13 @@ -93,6 +96,11 @@ typedef struct { 3.14 unsigned long nr_sectors; 3.15 } xc_vbd_t; 3.16 3.17 +typedef struct { 3.18 + unsigned short real_device; 3.19 + unsigned long start_sector; 3.20 + unsigned long nr_sectors; 3.21 +} xc_vbdextent_t; 3.22 3.23 int xc_vbd_create(int xc_handle, 3.24 unsigned int domid, 3.25 @@ -101,18 +109,24 @@ int xc_vbd_create(int xc_handle, 3.26 int xc_vbd_destroy(int xc_handle, 3.27 unsigned int domid, 3.28 unsigned short vbdid); 3.29 -int xc_vbd_add_extent(int xc_handle, 3.30 +int xc_vbd_grow(int xc_handle, 3.31 + unsigned int domid, 3.32 + unsigned short vbdid, 3.33 + xc_vbdextent_t *extent); 3.34 +int xc_vbd_shrink(int xc_handle, 3.35 + unsigned int domid, 3.36 + unsigned short vbdid); 3.37 +int xc_vbd_setextents(int xc_handle, 3.38 unsigned int domid, 3.39 unsigned short vbdid, 3.40 - unsigned short real_device, 3.41 - unsigned long start_sector, 3.42 - unsigned long nr_sectors); 3.43 -int xc_vbd_delete_extent(int xc_handle, 3.44 - unsigned int domid, 3.45 - unsigned short vbdid, 3.46 - unsigned short real_device, 3.47 - unsigned long start_sector, 3.48 - unsigned long nr_sectors); 3.49 + unsigned int nr_extents, 3.50 + xc_vbdextent_t *extents); 3.51 +int xc_vbd_getextents(int xc_handle, 3.52 + unsigned int domid, 3.53 + unsigned short vbdid, 3.54 + unsigned int max_extents, 3.55 + xc_vbdextent_t *extents, 3.56 + int *writeable); 3.57 int xc_vbd_probe(int xc_handle, 3.58 unsigned int domid, 3.59 unsigned int max_vbds,
4.1 --- a/tools/xc/lib/xc_vbd.c Mon Dec 08 08:14:58 2003 +0000 4.2 +++ b/tools/xc/lib/xc_vbd.c Fri Dec 12 16:43:23 2003 +0000 4.3 @@ -35,39 +35,126 @@ int xc_vbd_destroy(int xc_handle, 4.4 } 4.5 4.6 4.7 -int xc_vbd_add_extent(int xc_handle, 4.8 - unsigned int domid, 4.9 - unsigned short vbdid, 4.10 - unsigned short real_device, 4.11 - unsigned long start_sector, 4.12 - unsigned long nr_sectors) 4.13 +int xc_vbd_grow(int xc_handle, 4.14 + unsigned int domid, 4.15 + unsigned short vbdid, 4.16 + xc_vbdextent_t *extent) 4.17 { 4.18 block_io_op_t op; 4.19 - op.cmd = BLOCK_IO_OP_VBD_ADD; 4.20 - op.u.add_params.domain = domid; 4.21 - op.u.add_params.vdevice = vbdid; 4.22 - op.u.add_params.extent.device = real_device; 4.23 - op.u.add_params.extent.start_sector = start_sector; 4.24 - op.u.add_params.extent.nr_sectors = nr_sectors; 4.25 + op.cmd = BLOCK_IO_OP_VBD_GROW; 4.26 + op.u.grow_params.domain = domid; 4.27 + op.u.grow_params.vdevice = vbdid; 4.28 + op.u.grow_params.extent.device = extent->real_device; 4.29 + op.u.grow_params.extent.start_sector = extent->start_sector; 4.30 + op.u.grow_params.extent.nr_sectors = extent->nr_sectors; 4.31 + return do_block_io_op(xc_handle, &op); 4.32 +} 4.33 + 4.34 + 4.35 +int xc_vbd_shrink(int xc_handle, 4.36 + unsigned int domid, 4.37 + unsigned short vbdid) 4.38 +{ 4.39 + block_io_op_t op; 4.40 + op.cmd = BLOCK_IO_OP_VBD_SHRINK; 4.41 + op.u.shrink_params.domain = domid; 4.42 + op.u.shrink_params.vdevice = vbdid; 4.43 return do_block_io_op(xc_handle, &op); 4.44 } 4.45 4.46 4.47 -int xc_vbd_delete_extent(int xc_handle, 4.48 - unsigned int domid, 4.49 - unsigned short vbdid, 4.50 - unsigned short real_device, 4.51 - unsigned long start_sector, 4.52 - unsigned long nr_sectors) 4.53 +int xc_vbd_setextents(int xc_handle, 4.54 + unsigned int domid, 4.55 + unsigned short vbdid, 4.56 + unsigned int nr_extents, 4.57 + xc_vbdextent_t *extents) 4.58 { 4.59 - block_io_op_t op; 4.60 - op.cmd = BLOCK_IO_OP_VBD_REMOVE; 4.61 - op.u.add_params.domain = domid; 4.62 - op.u.add_params.vdevice = vbdid; 4.63 - op.u.add_params.extent.device = real_device; 4.64 - op.u.add_params.extent.start_sector = start_sector; 4.65 - op.u.add_params.extent.nr_sectors = nr_sectors; 4.66 - return do_block_io_op(xc_handle, &op); 4.67 + int i, rc; 4.68 + block_io_op_t op; 4.69 + xen_extent_t *real_extents = NULL; 4.70 + 4.71 + if ( nr_extents != 0 ) 4.72 + { 4.73 + real_extents = malloc(nr_extents * sizeof(xc_vbdextent_t)); 4.74 + if ( (real_extents == NULL) || 4.75 + (mlock(real_extents, nr_extents * sizeof(xc_vbdextent_t)) != 0) ) 4.76 + { 4.77 + if ( real_extents != NULL ) 4.78 + free(real_extents); 4.79 + return -ENOMEM; 4.80 + } 4.81 + 4.82 + for ( i = 0; i < nr_extents; i++ ) 4.83 + { 4.84 + real_extents[i].device = extents[i].real_device; 4.85 + real_extents[i].start_sector = extents[i].start_sector; 4.86 + real_extents[i].nr_sectors = extents[i].nr_sectors; 4.87 + } 4.88 + } 4.89 + 4.90 + op.cmd = BLOCK_IO_OP_VBD_SET_EXTENTS; 4.91 + op.u.setextents_params.domain = domid; 4.92 + op.u.setextents_params.vdevice = vbdid; 4.93 + op.u.setextents_params.nr_extents = nr_extents; 4.94 + op.u.setextents_params.extents = real_extents; 4.95 + rc = do_block_io_op(xc_handle, &op); 4.96 + 4.97 + if ( real_extents != NULL ) 4.98 + { 4.99 + (void)munlock(real_extents, nr_extents * sizeof(xc_vbdextent_t)); 4.100 + free(real_extents); 4.101 + } 4.102 + 4.103 + return rc; 4.104 +} 4.105 + 4.106 + 4.107 +int xc_vbd_getextents(int xc_handle, 4.108 + unsigned int domid, 4.109 + unsigned short vbdid, 4.110 + unsigned int max_extents, 4.111 + xc_vbdextent_t *extents, 4.112 + int *writeable) 4.113 +{ 4.114 + int i, rc; 4.115 + block_io_op_t op; 4.116 + xen_extent_t *real_extents = malloc(max_extents * sizeof(xc_vbdextent_t)); 4.117 + 4.118 + if ( (real_extents == NULL) || 4.119 + (mlock(real_extents, max_extents * sizeof(xc_vbdextent_t)) != 0) ) 4.120 + { 4.121 + if ( real_extents != NULL ) 4.122 + free(real_extents); 4.123 + return -ENOMEM; 4.124 + } 4.125 + 4.126 + op.cmd = BLOCK_IO_OP_VBD_INFO; 4.127 + op.u.info_params.domain = domid; 4.128 + op.u.info_params.vdevice = vbdid; 4.129 + op.u.info_params.maxextents = max_extents; 4.130 + op.u.info_params.extents = real_extents; 4.131 + rc = do_block_io_op(xc_handle, &op); 4.132 + 4.133 + (void)munlock(real_extents, max_extents * sizeof(xc_vbdextent_t)); 4.134 + 4.135 + if ( rc >= 0 ) 4.136 + { 4.137 + for ( i = 0; i < op.u.info_params.nextents; i++ ) 4.138 + { 4.139 + extents[i].real_device = real_extents[i].device; 4.140 + extents[i].start_sector = real_extents[i].start_sector; 4.141 + extents[i].nr_sectors = real_extents[i].nr_sectors; 4.142 + } 4.143 + 4.144 + if ( writeable != NULL ) 4.145 + *writeable = !!(op.u.info_params.mode & VBD_MODE_W); 4.146 + 4.147 + rc = op.u.info_params.nextents; 4.148 + } 4.149 + 4.150 + free(real_extents); 4.151 + 4.152 + return rc; 4.153 } 4.154 4.155
5.1 --- a/tools/xc/py/Xc.c Mon Dec 08 08:14:58 2003 +0000 5.2 +++ b/tools/xc/py/Xc.c Fri Dec 12 16:43:23 2003 +0000 5.3 @@ -387,52 +387,159 @@ static PyObject *pyxc_vbd_destroy(PyObje 5.4 return PyInt_FromLong(ret); 5.5 } 5.6 5.7 -static PyObject *pyxc_vbd_add_extent(PyObject *self, 5.8 - PyObject *args, 5.9 - PyObject *kwds) 5.10 +static PyObject *pyxc_vbd_grow(PyObject *self, 5.11 + PyObject *args, 5.12 + PyObject *kwds) 5.13 { 5.14 XcObject *xc = (XcObject *)self; 5.15 5.16 - unsigned int dom, vbd, device; 5.17 - unsigned long start_sector, nr_sectors; 5.18 - int ret; 5.19 + unsigned int dom, vbd; 5.20 + xc_vbdextent_t extent; 5.21 + int ret; 5.22 5.23 static char *kwd_list[] = { "dom", "vbd", "device", 5.24 "start_sector", "nr_sectors", NULL }; 5.25 5.26 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiill", kwd_list, 5.27 - &dom, &vbd, &device, 5.28 - &start_sector, &nr_sectors) ) 5.29 + &dom, &vbd, 5.30 + &extent.real_device, 5.31 + &extent.start_sector, 5.32 + &extent.nr_sectors) ) 5.33 return NULL; 5.34 5.35 - ret = xc_vbd_add_extent(xc->xc_handle, dom, vbd, device, 5.36 - start_sector, nr_sectors); 5.37 + ret = xc_vbd_grow(xc->xc_handle, dom, vbd, &extent); 5.38 + 5.39 + return PyInt_FromLong(ret); 5.40 +} 5.41 + 5.42 +static PyObject *pyxc_vbd_shrink(PyObject *self, 5.43 + PyObject *args, 5.44 + PyObject *kwds) 5.45 +{ 5.46 + XcObject *xc = (XcObject *)self; 5.47 + 5.48 + unsigned int dom, vbd; 5.49 + int ret; 5.50 + 5.51 + static char *kwd_list[] = { "dom", "vbd", NULL }; 5.52 + 5.53 + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list, 5.54 + &dom, &vbd) ) 5.55 + return NULL; 5.56 + 5.57 + ret = xc_vbd_shrink(xc->xc_handle, dom, vbd); 5.58 5.59 return PyInt_FromLong(ret); 5.60 } 5.61 5.62 -static PyObject *pyxc_vbd_delete_extent(PyObject *self, 5.63 - PyObject *args, 5.64 - PyObject *kwds) 5.65 +static PyObject *pyxc_vbd_setextents(PyObject *self, 5.66 + PyObject *args, 5.67 + PyObject *kwds) 5.68 { 5.69 XcObject *xc = (XcObject *)self; 5.70 + PyObject *list, *dict, *obj; 5.71 5.72 - unsigned int dom, vbd, device; 5.73 - unsigned long start_sector, nr_sectors; 5.74 - int ret; 5.75 + unsigned int dom, vbd; 5.76 + xc_vbdextent_t *extents = NULL; 5.77 + int ret, i, nr_extents; 5.78 + 5.79 + static char *kwd_list[] = { "dom", "vbd", "extents", NULL }; 5.80 + 5.81 + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iio", kwd_list, 5.82 + &dom, &vbd, &list) ) 5.83 + goto fail; 5.84 + 5.85 + if ( (nr_extents = PyList_Size(list)) < 0 ) 5.86 + goto fail; 5.87 + 5.88 + if ( nr_extents != 0 ) 5.89 + { 5.90 + extents = malloc(nr_extents * sizeof(xc_vbdextent_t)); 5.91 + if ( extents == NULL ) 5.92 + goto fail; 5.93 5.94 - static char *kwd_list[] = { "dom", "vbd", "device", 5.95 - "start_sector", "nr_sectors", NULL }; 5.96 + for ( i = 0; i < nr_extents; i++ ) 5.97 + { 5.98 + dict = PyList_GetItem(list, i); 5.99 + if ( !PyDict_Check(dict) ) 5.100 + goto fail; 5.101 + if ( ((obj = PyDict_GetItemString(dict, "device")) == NULL) || 5.102 + !PyInt_Check(obj) ) 5.103 + goto fail; 5.104 + extents[i].real_device = (unsigned short)PyInt_AsLong(obj); 5.105 + if ( ((obj = PyDict_GetItemString(dict,"start_sector")) == NULL) || 5.106 + !PyInt_Check(obj) ) 5.107 + goto fail; 5.108 + extents[i].start_sector = PyInt_AsLong(obj); 5.109 + if ( ((obj = PyDict_GetItemString(dict, "nr_sectors")) == NULL) || 5.110 + !PyInt_Check(obj) ) 5.111 + goto fail; 5.112 + extents[i].nr_sectors = PyInt_AsLong(obj); 5.113 + } 5.114 + } 5.115 5.116 - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiill", kwd_list, 5.117 - &dom, &vbd, &device, 5.118 - &start_sector, &nr_sectors) ) 5.119 + ret = xc_vbd_setextents(xc->xc_handle, dom, vbd, nr_extents, extents); 5.120 + 5.121 + if ( extents != NULL ) 5.122 + free(extents); 5.123 + 5.124 + return PyInt_FromLong(ret); 5.125 + 5.126 + fail: 5.127 + if ( extents != NULL ) 5.128 + free(extents); 5.129 + return NULL; 5.130 +} 5.131 + 5.132 +#define MAX_EXTENTS 1024 5.133 +static PyObject *pyxc_vbd_getextents(PyObject *self, 5.134 + PyObject *args, 5.135 + PyObject *kwds) 5.136 +{ 5.137 + XcObject *xc = (XcObject *)self; 5.138 + PyObject *list; 5.139 + 5.140 + unsigned int dom, vbd; 5.141 + xc_vbdextent_t *extents; 5.142 + int i, nr_extents, max_extents; 5.143 + 5.144 + static char *kwd_list[] = { "dom", "vbd", NULL }; 5.145 + 5.146 + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list, 5.147 + &dom, &vbd) ) 5.148 return NULL; 5.149 5.150 - ret = xc_vbd_delete_extent(xc->xc_handle, dom, vbd, device, 5.151 - start_sector, nr_sectors); 5.152 + extents = malloc(MAX_EXTENTS * sizeof(xc_vbdextent_t)); 5.153 + if ( extents == NULL ) 5.154 + max_extents = 0; 5.155 + else 5.156 + max_extents = MAX_EXTENTS; 5.157 + 5.158 + nr_extents = xc_vbd_getextents(xc->xc_handle, dom, vbd, max_extents, 5.159 + extents, NULL); 5.160 5.161 - return PyInt_FromLong(ret); 5.162 + if ( nr_extents <= 0 ) 5.163 + { 5.164 + list = PyList_New(0); 5.165 + } 5.166 + else 5.167 + { 5.168 + list = PyList_New(nr_extents); 5.169 + for ( i = 0; i < nr_extents; i++ ) 5.170 + { 5.171 + PyList_SetItem( 5.172 + list, i, 5.173 + Py_BuildValue("{s:i,s:l,s:l}", 5.174 + "device", extents[i].real_device, 5.175 + "start_sector", extents[i].start_sector, 5.176 + "nr_sectors", extents[i].nr_sectors)); 5.177 + } 5.178 + } 5.179 + 5.180 + if ( extents != NULL ) 5.181 + free(extents); 5.182 + 5.183 + return list; 5.184 } 5.185 5.186 static PyObject *pyxc_vbd_probe(PyObject *self, 5.187 @@ -647,10 +754,10 @@ static PyMethodDef pyxc_methods[] = { 5.188 " vbd [int]: Identifier of the VBD.\n\n" 5.189 "Returns: [int] 0 on success; -1 on error.\n" }, 5.190 5.191 - { "vbd_add_extent", 5.192 - (PyCFunction)pyxc_vbd_add_extent, 5.193 + { "vbd_grow", 5.194 + (PyCFunction)pyxc_vbd_grow, 5.195 METH_VARARGS | METH_KEYWORDS, "\n" 5.196 - "Add an extent to a virtual block device.\n" 5.197 + "Grow a virtual block device by appending a new extent.\n" 5.198 " dom [int]: Identifier of domain containing the VBD.\n" 5.199 " vbd [int]: Identifier of the VBD.\n" 5.200 " device [int]: Identifier of the real underlying block device.\n" 5.201 @@ -658,16 +765,36 @@ static PyMethodDef pyxc_methods[] = { 5.202 " nr_sectors [int]: Length, in sectors, of this extent.\n\n" 5.203 "Returns: [int] 0 on success; -1 on error.\n" }, 5.204 5.205 - { "vbd_delete_extent", 5.206 - (PyCFunction)pyxc_vbd_delete_extent, 5.207 + { "vbd_shrink", 5.208 + (PyCFunction)pyxc_vbd_shrink, 5.209 METH_VARARGS | METH_KEYWORDS, "\n" 5.210 - "Delete an extent from a virtual block device.\n" 5.211 + "Shrink a virtual block device by deleting its final extent.\n" 5.212 + " dom [int]: Identifier of domain containing the VBD.\n" 5.213 + " vbd [int]: Identifier of the VBD.\n\n" 5.214 + "Returns: [int] 0 on success; -1 on error.\n" }, 5.215 + 5.216 + { "vbd_setextents", 5.217 + (PyCFunction)pyxc_vbd_setextents, 5.218 + METH_VARARGS | METH_KEYWORDS, "\n" 5.219 + "Set all the extent information for a virtual block device.\n" 5.220 " dom [int]: Identifier of domain containing the VBD.\n" 5.221 " vbd [int]: Identifier of the VBD.\n" 5.222 + " extents [list of dicts]: Per-extent information.\n" 5.223 + " device [int]: Identifier of the real underlying block device.\n" 5.224 + " start_sector [int]: Real start sector of this extent.\n" 5.225 + " nr_sectors [int]: Length, in sectors, of this extent.\n\n" 5.226 + "Returns: [int] 0 on success; -1 on error.\n" }, 5.227 + 5.228 + { "vbd_getextents", 5.229 + (PyCFunction)pyxc_vbd_getextents, 5.230 + METH_VARARGS | METH_KEYWORDS, "\n" 5.231 + "Get info on all the extents in a virtual block device.\n" 5.232 + " dom [int]: Identifier of domain containing the VBD.\n" 5.233 + " vbd [int]: Identifier of the VBD.\n\n" 5.234 + "Returns: [list of dicts] per-extent information; empty on error.\n" 5.235 " device [int]: Identifier of the real underlying block device.\n" 5.236 - " start_sector [int]: Real start sector of the extent.\n" 5.237 - " nr_sectors [int]: Length, in sectors, of the extent.\n\n" 5.238 - "Returns: [int] 0 on success; -1 on error.\n" }, 5.239 + " start_sector [int]: Real start sector of this extent.\n" 5.240 + " nr_sectors [int]: Length, in sectors, of this extent.\n" }, 5.241 5.242 { "vbd_probe", 5.243 (PyCFunction)pyxc_vbd_probe,
6.1 --- a/xen/drivers/block/xen_block.c Mon Dec 08 08:14:58 2003 +0000 6.2 +++ b/xen/drivers/block/xen_block.c Fri Dec 12 16:43:23 2003 +0000 6.3 @@ -274,14 +274,19 @@ long do_block_io_op(block_io_op_t *u_blo 6.4 ret = vbd_create(&op.u.create_params); 6.5 break; 6.6 6.7 - case BLOCK_IO_OP_VBD_ADD: 6.8 - /* add an extent to a VBD */ 6.9 - ret = vbd_add(&op.u.add_params); 6.10 + case BLOCK_IO_OP_VBD_GROW: 6.11 + /* append an extent to a VBD */ 6.12 + ret = vbd_grow(&op.u.grow_params); 6.13 break; 6.14 6.15 - case BLOCK_IO_OP_VBD_REMOVE: 6.16 - /* remove an extent from a VBD */ 6.17 - ret = vbd_remove(&op.u.remove_params); 6.18 + case BLOCK_IO_OP_VBD_SHRINK: 6.19 + /* remove teh final extent from a VBD */ 6.20 + ret = vbd_shrink(&op.u.shrink_params); 6.21 + break; 6.22 + 6.23 + case BLOCK_IO_OP_VBD_SET_EXTENTS: 6.24 + /* a fresh extent list for the given VBD */ 6.25 + ret = vbd_setextents(&op.u.setextents_params); 6.26 break; 6.27 6.28 case BLOCK_IO_OP_VBD_DELETE:
7.1 --- a/xen/drivers/block/xen_vbd.c Mon Dec 08 08:14:58 2003 +0000 7.2 +++ b/xen/drivers/block/xen_vbd.c Fri Dec 12 16:43:23 2003 +0000 7.3 @@ -33,6 +33,7 @@ extern int scsi_probe_devices(xen_disk_i 7.4 /* XXX SMH: crappy 'hash function' .. fix when care. */ 7.5 #define HSH(_x) ((_x) & (VBD_HTAB_SZ - 1)) 7.6 7.7 + 7.8 /* 7.9 ** Create a new VBD; all this involves is adding an entry to the domain's 7.10 ** vbd hash table; caller must be privileged. 7.11 @@ -43,10 +44,10 @@ long vbd_create(vbd_create_t *create) 7.12 vbd_t *new_vbd, **pv; 7.13 long ret = 0; 7.14 7.15 - if( !IS_PRIV(current) ) 7.16 + if ( unlikely(!IS_PRIV(current)) ) 7.17 return -EPERM; 7.18 7.19 - if ( (p = find_domain_by_id(create->domain)) == NULL ) 7.20 + if ( unlikely((p = find_domain_by_id(create->domain)) == NULL) ) 7.21 { 7.22 DPRINTK("vbd_create attempted for non-existent domain %d\n", 7.23 create->domain); 7.24 @@ -59,7 +60,7 @@ long vbd_create(vbd_create_t *create) 7.25 *pv != NULL; 7.26 pv = &(*pv)->next ) 7.27 { 7.28 - if ( (*pv)->vdevice == create->vdevice ) 7.29 + if ( unlikely((*pv)->vdevice == create->vdevice) ) 7.30 { 7.31 DPRINTK("vbd_create attempted for already existing vbd\n"); 7.32 ret = -EINVAL; 7.33 @@ -69,10 +70,16 @@ long vbd_create(vbd_create_t *create) 7.34 break; 7.35 } 7.36 7.37 - new_vbd = kmalloc(sizeof(vbd_t), GFP_KERNEL); 7.38 + if ( unlikely((new_vbd = kmalloc(sizeof(vbd_t), GFP_KERNEL)) == NULL) ) 7.39 + { 7.40 + DPRINTK("vbd_create: out of memory\n"); 7.41 + ret = -ENOMEM; 7.42 + goto out; 7.43 + } 7.44 + 7.45 new_vbd->vdevice = create->vdevice; 7.46 new_vbd->mode = create->mode; 7.47 - new_vbd->extents = (xen_extent_le_t *)NULL; 7.48 + new_vbd->extents = NULL; 7.49 new_vbd->next = *pv; 7.50 7.51 *pv = new_vbd; 7.52 @@ -83,44 +90,48 @@ long vbd_create(vbd_create_t *create) 7.53 return ret; 7.54 } 7.55 7.56 -/* 7.57 -** Add an extent to an existing VBD; fails if the VBD doesn't exist. 7.58 -** Doesn't worry about overlapping extents (e.g. merging etc) for now. 7.59 -*/ 7.60 -long vbd_add(vbd_add_t *add) 7.61 + 7.62 +/* Grow a VBD by appending a new extent. Fails if the VBD doesn't exist. */ 7.63 +long vbd_grow(vbd_grow_t *grow) 7.64 { 7.65 struct task_struct *p; 7.66 xen_extent_le_t **px, *x; 7.67 vbd_t *v; 7.68 long ret = 0; 7.69 7.70 - if ( !IS_PRIV(current) ) 7.71 + if ( unlikely(!IS_PRIV(current)) ) 7.72 return -EPERM; 7.73 7.74 - if ( (p = find_domain_by_id(add->domain)) == NULL ) 7.75 + if ( unlikely((p = find_domain_by_id(grow->domain)) == NULL) ) 7.76 { 7.77 - DPRINTK("vbd_add attempted for non-existent domain %d\n", 7.78 - add->domain); 7.79 + DPRINTK("vbd_grow: attempted for non-existent domain %d\n", 7.80 + grow->domain); 7.81 return -EINVAL; 7.82 } 7.83 7.84 spin_lock(&p->vbd_lock); 7.85 7.86 - for ( v = p->vbdtab[HSH(add->vdevice)]; v != NULL; v = v->next ) 7.87 - if ( v->vdevice == add->vdevice ) 7.88 + for ( v = p->vbdtab[HSH(grow->vdevice)]; v != NULL; v = v->next ) 7.89 + if ( v->vdevice == grow->vdevice ) 7.90 break; 7.91 7.92 - if ( v == NULL ) 7.93 + if ( unlikely(v == NULL) ) 7.94 { 7.95 - DPRINTK("vbd_add; attempted to add extent to non-existent VBD.\n"); 7.96 + DPRINTK("vbd_grow: attempted to append extent to non-existent VBD.\n"); 7.97 ret = -EINVAL; 7.98 goto out; 7.99 } 7.100 7.101 - x = kmalloc(sizeof(xen_extent_le_t), GFP_KERNEL); 7.102 - x->extent.device = add->extent.device; 7.103 - x->extent.start_sector = add->extent.start_sector; 7.104 - x->extent.nr_sectors = add->extent.nr_sectors; 7.105 + if ( unlikely((x = kmalloc(sizeof(xen_extent_le_t), GFP_KERNEL)) == NULL) ) 7.106 + { 7.107 + DPRINTK("vbd_grow: out of memory\n"); 7.108 + ret = -ENOMEM; 7.109 + goto out; 7.110 + } 7.111 + 7.112 + x->extent.device = grow->extent.device; 7.113 + x->extent.start_sector = grow->extent.start_sector; 7.114 + x->extent.nr_sectors = grow->extent.nr_sectors; 7.115 x->next = (xen_extent_le_t *)NULL; 7.116 7.117 for ( px = &v->extents; *px != NULL; px = &(*px)->next ) 7.118 @@ -134,7 +145,8 @@ long vbd_add(vbd_add_t *add) 7.119 return ret; 7.120 } 7.121 7.122 -long vbd_remove(vbd_remove_t *remove) 7.123 + 7.124 +long vbd_shrink(vbd_shrink_t *shrink) 7.125 { 7.126 struct task_struct *p; 7.127 xen_extent_le_t **px, *x; 7.128 @@ -144,39 +156,31 @@ long vbd_remove(vbd_remove_t *remove) 7.129 if ( !IS_PRIV(current) ) 7.130 return -EPERM; 7.131 7.132 - if ( (p = find_domain_by_id(remove->domain)) == NULL ) 7.133 + if ( (p = find_domain_by_id(shrink->domain)) == NULL ) 7.134 { 7.135 - DPRINTK("vbd_remove attempted for non-existent domain %d\n", 7.136 - remove->domain); 7.137 + DPRINTK("vbd_shrink attempted for non-existent domain %d\n", 7.138 + shrink->domain); 7.139 return -EINVAL; 7.140 } 7.141 7.142 spin_lock(&p->vbd_lock); 7.143 7.144 - for ( v = p->vbdtab[HSH(remove->vdevice)]; v != NULL; v = v->next ) 7.145 - if ( v->vdevice == remove->vdevice ) 7.146 + for ( v = p->vbdtab[HSH(shrink->vdevice)]; v != NULL; v = v->next ) 7.147 + if ( v->vdevice == shrink->vdevice ) 7.148 break; 7.149 7.150 - if ( v == NULL ) 7.151 + if ( unlikely(v == NULL) || unlikely(v->extents == NULL) ) 7.152 { 7.153 - DPRINTK("vbd_remove; attempt to remove ext from non-existent VBD.\n"); 7.154 + DPRINTK("vbd_shrink: attempt to remove non-existent extent.\n"); 7.155 ret = -EINVAL; 7.156 goto out; 7.157 } 7.158 7.159 - for ( px = &v->extents; *px != NULL; px = &(*px)->next ) 7.160 - if ( (*px)->extent.start_sector == remove->extent.start_sector ) 7.161 - break; 7.162 - 7.163 - if ( ((x = *px) == NULL) || 7.164 - (x->extent.nr_sectors != remove->extent.nr_sectors) || 7.165 - (x->extent.device != remove->extent.device) ) 7.166 - { 7.167 - DPRINTK("vbd_remove: attempt to remove non-matching extent.\n"); 7.168 - ret = -EINVAL; 7.169 - goto out; 7.170 - } 7.171 + /* Find the last extent. We now know that there is at least one. */ 7.172 + for ( px = &v->extents; (*px)->next != NULL; px = &(*px)->next ) 7.173 + continue; 7.174 7.175 + x = *px; 7.176 *px = x->next; 7.177 kfree(x); 7.178 7.179 @@ -186,6 +190,92 @@ long vbd_remove(vbd_remove_t *remove) 7.180 return ret; 7.181 } 7.182 7.183 + 7.184 +long vbd_setextents(vbd_setextents_t *setextents) 7.185 +{ 7.186 + struct task_struct *p; 7.187 + xen_extent_t e; 7.188 + xen_extent_le_t *new_extents, *x, *t; 7.189 + vbd_t *v; 7.190 + int i; 7.191 + long ret = 0; 7.192 + 7.193 + if ( !IS_PRIV(current) ) 7.194 + return -EPERM; 7.195 + 7.196 + if ( (p = find_domain_by_id(setextents->domain)) == NULL ) 7.197 + { 7.198 + DPRINTK("vbd_setextents attempted for non-existent domain %d\n", 7.199 + setextents->domain); 7.200 + return -EINVAL; 7.201 + } 7.202 + 7.203 + spin_lock(&p->vbd_lock); 7.204 + 7.205 + for ( v = p->vbdtab[HSH(setextents->vdevice)]; v != NULL; v = v->next ) 7.206 + if ( v->vdevice == setextents->vdevice ) 7.207 + break; 7.208 + 7.209 + if ( unlikely(v == NULL) ) 7.210 + { 7.211 + DPRINTK("vbd_setextents: attempt to modify non-existent VBD.\n"); 7.212 + ret = -EINVAL; 7.213 + goto out; 7.214 + } 7.215 + 7.216 + /* Construct the new extent list. */ 7.217 + new_extents = NULL; 7.218 + for ( i = setextents->nr_extents; i >= 0; i++ ) 7.219 + { 7.220 + if ( unlikely(copy_from_user(&e, 7.221 + &setextents->extents[i], 7.222 + sizeof(e)) != 0) ) 7.223 + { 7.224 + DPRINTK("vbd_setextents: copy_from_user failed\n"); 7.225 + ret = -EFAULT; 7.226 + goto free_and_out; 7.227 + } 7.228 + 7.229 + if ( unlikely((x = kmalloc(sizeof(xen_extent_le_t), GFP_KERNEL)) 7.230 + == NULL) ) 7.231 + { 7.232 + DPRINTK("vbd_setextents: out of memory\n"); 7.233 + ret = -ENOMEM; 7.234 + goto free_and_out; 7.235 + } 7.236 + 7.237 + x->extent = e; 7.238 + x->next = new_extents; 7.239 + 7.240 + new_extents = x; 7.241 + } 7.242 + 7.243 + /* Delete the old extent list _after_ successfully creating the new. */ 7.244 + for ( x = v->extents; x != NULL; x = t ) 7.245 + { 7.246 + t = x->next; 7.247 + kfree(x); 7.248 + } 7.249 + 7.250 + /* Make the new list visible. */ 7.251 + v->extents = new_extents; 7.252 + 7.253 + out: 7.254 + spin_unlock(&p->vbd_lock); 7.255 + put_task_struct(p); 7.256 + return ret; 7.257 + 7.258 + free_and_out: 7.259 + /* Failed part-way through the new list. Delete all that we managed. */ 7.260 + for ( x = new_extents; x != NULL; x = t ) 7.261 + { 7.262 + t = x->next; 7.263 + kfree(x); 7.264 + } 7.265 + goto out; 7.266 +} 7.267 + 7.268 + 7.269 long vbd_delete(vbd_delete_t *delete) 7.270 { 7.271 struct task_struct *p; 7.272 @@ -442,6 +532,8 @@ long vbd_info(vbd_info_t *info) 7.273 extents = info->extents; 7.274 for ( x = v->extents; x != NULL; x = x->next ) 7.275 { 7.276 + if ( info->nextents == info->maxextents ) 7.277 + break; 7.278 if ( copy_to_user(extents, &x->extent, sizeof(xen_extent_t)) ) 7.279 { 7.280 DPRINTK("vbd_info: copy_to_user failed\n"); 7.281 @@ -449,7 +541,7 @@ long vbd_info(vbd_info_t *info) 7.282 goto out; 7.283 } 7.284 extents++; 7.285 - info->nextents++; 7.286 + info->nextents++; 7.287 } 7.288 7.289 out:
8.1 --- a/xen/include/hypervisor-ifs/vbd.h Mon Dec 08 08:14:58 2003 +0000 8.2 +++ b/xen/include/hypervisor-ifs/vbd.h Fri Dec 12 16:43:23 2003 +0000 8.3 @@ -6,25 +6,24 @@ 8.4 * Block I/O trap operations and associated structures. 8.5 */ 8.6 8.7 -#define BLOCK_IO_OP_SIGNAL 0 /* let xen know we have work to do */ 8.8 +#define BLOCK_IO_OP_SIGNAL 0 /* let xen know we have work to do */ 8.9 #define BLOCK_IO_OP_RESET 1 /* reset ring indexes on quiescent i/f */ 8.10 #define BLOCK_IO_OP_RING_ADDRESS 2 /* returns machine address of I/O ring */ 8.11 #define BLOCK_IO_OP_VBD_CREATE 3 /* create a new VBD for a given domain */ 8.12 -#define BLOCK_IO_OP_VBD_ADD 4 /* add an extent to a given VBD */ 8.13 -#define BLOCK_IO_OP_VBD_REMOVE 5 /* remove an extent from a given VBD */ 8.14 -#define BLOCK_IO_OP_VBD_DELETE 6 /* delete a VBD */ 8.15 -#define BLOCK_IO_OP_VBD_PROBE 7 /* query VBD information for a domain */ 8.16 -#define BLOCK_IO_OP_VBD_INFO 8 /* query info about a particular VBD */ 8.17 +#define BLOCK_IO_OP_VBD_GROW 4 /* append an extent to a given VBD */ 8.18 +#define BLOCK_IO_OP_VBD_SHRINK 5 /* remove last extent from a given VBD */ 8.19 +#define BLOCK_IO_OP_VBD_SET_EXTENTS 6 /* provide a fresh extent list for VBD */ 8.20 +#define BLOCK_IO_OP_VBD_DELETE 7 /* delete a VBD */ 8.21 +#define BLOCK_IO_OP_VBD_PROBE 8 /* query VBD information for a domain */ 8.22 +#define BLOCK_IO_OP_VBD_INFO 9 /* query info about a particular VBD */ 8.23 8.24 typedef struct _xen_extent { 8.25 u16 device; 8.26 - u16 unused; // pad 8.27 + u16 unused; 8.28 ulong start_sector; 8.29 ulong nr_sectors; 8.30 } xen_extent_t; 8.31 8.32 - 8.33 - 8.34 #define VBD_MODE_R 0x1 8.35 #define VBD_MODE_W 0x2 8.36 8.37 @@ -33,44 +32,49 @@ typedef struct _xen_extent { 8.38 8.39 8.40 typedef struct _vbd_create { 8.41 - unsigned domain; // create VBD for this domain 8.42 - u16 vdevice; // 16 bit id domain will refer to VBD as 8.43 - u16 mode; // OR of { VBD_MODE_R , VBD_MODE_W } 8.44 + unsigned domain; /* create VBD for this domain */ 8.45 + u16 vdevice; /* id by which dom will refer to VBD */ 8.46 + u16 mode; /* OR of { VBD_MODE_R , VBD_MODE_W } */ 8.47 } vbd_create_t; 8.48 8.49 -typedef struct _vbd_add { 8.50 - unsigned domain; // domain in question 8.51 - u16 vdevice; // 16 bit id domain refers to VBD as 8.52 - xen_extent_t extent; // the extent to add to this VBD 8.53 -} vbd_add_t; 8.54 +typedef struct _vbd_grow { 8.55 + unsigned domain; /* domain in question */ 8.56 + u16 vdevice; /* 16 bit id domain refers to VBD as */ 8.57 + xen_extent_t extent; /* the extent to add to this VBD */ 8.58 +} vbd_grow_t; 8.59 8.60 -typedef struct _vbd_remove { 8.61 - unsigned domain; // domain in question 8.62 - u16 vdevice; // 16 bit id domain refers to VBD as 8.63 - xen_extent_t extent; // the extent to remove from this VBD 8.64 -} vbd_remove_t; 8.65 +typedef struct _vbd_shrink { 8.66 + unsigned domain; /* domain in question */ 8.67 + u16 vdevice; /* 16 bit id domain refers to VBD as */ 8.68 +} vbd_shrink_t; 8.69 8.70 +typedef struct _vbd_setextents { 8.71 + unsigned domain; /* domain in question */ 8.72 + u16 vdevice; /* 16 bit id domain refers to VBD as */ 8.73 + u16 nr_extents; /* number of extents in the list */ 8.74 + xen_extent_t *extents; /* the extents to add to this VBD */ 8.75 +} vbd_setextents_t; 8.76 8.77 typedef struct _vbd_delete { 8.78 - unsigned domain; // domain in question 8.79 - u16 vdevice; // 16 bit id domain refers to VBD as 8.80 + unsigned domain; /* domain in question */ 8.81 + u16 vdevice; /* 16 bit id domain refers to VBD as */ 8.82 } vbd_delete_t; 8.83 8.84 #define VBD_PROBE_ALL 0xFFFFFFFF 8.85 typedef struct _vbd_probe { 8.86 - unsigned domain; // domain in question or VBD_PROBE_ALL 8.87 - xen_disk_info_t xdi; // where's our space for VBD/disk info 8.88 + unsigned domain; /* domain in question or VBD_PROBE_ALL */ 8.89 + xen_disk_info_t xdi; /* where's our space for VBD/disk info */ 8.90 } vbd_probe_t; 8.91 8.92 typedef struct _vbd_info { 8.93 /* IN variables */ 8.94 - unsigned domain; // domain in question 8.95 - u16 vdevice; // 16 bit id domain refers to VBD as 8.96 - u16 maxextents; // max no. of extents to return info for 8.97 - xen_extent_t *extents; // pointer to space for array of extents 8.98 + unsigned domain; /* domain in question */ 8.99 + u16 vdevice; /* 16 bit id domain refers to VBD as */ 8.100 + u16 maxextents; /* max # of extents to return info for */ 8.101 + xen_extent_t *extents; /* pointer to space for extent list */ 8.102 /* OUT variables */ 8.103 - u16 nextents; // no of extents in the above 8.104 - u16 mode; // VBD_MODE_{READONLY,READWRITE} 8.105 + u16 nextents; /* # extents in the above list */ 8.106 + u16 mode; /* VBD_MODE_{READONLY,READWRITE} */ 8.107 } vbd_info_t; 8.108 8.109 8.110 @@ -81,13 +85,14 @@ typedef struct block_io_op_st 8.111 { 8.112 /* no entry for BLOCK_IO_OP_SIGNAL */ 8.113 /* no entry for BLOCK_IO_OP_RESET */ 8.114 - unsigned long ring_mfn; 8.115 - vbd_create_t create_params; 8.116 - vbd_add_t add_params; 8.117 - vbd_remove_t remove_params; 8.118 - vbd_delete_t delete_params; 8.119 - vbd_probe_t probe_params; 8.120 - vbd_info_t info_params; 8.121 + unsigned long ring_mfn; 8.122 + vbd_create_t create_params; 8.123 + vbd_grow_t grow_params; 8.124 + vbd_shrink_t shrink_params; 8.125 + vbd_setextents_t setextents_params; 8.126 + vbd_delete_t delete_params; 8.127 + vbd_probe_t probe_params; 8.128 + vbd_info_t info_params; 8.129 } 8.130 u; 8.131 } block_io_op_t;
9.1 --- a/xen/include/xeno/vbd.h Mon Dec 08 08:14:58 2003 +0000 9.2 +++ b/xen/include/xeno/vbd.h Fri Dec 12 16:43:23 2003 +0000 9.3 @@ -1,8 +1,8 @@ 9.4 /* 9.5 ** include/xeno/vbd.h: 9.6 ** -- xen internal declarations + prototypes for virtual block devices 9.7 -** 9.8 */ 9.9 + 9.10 #ifndef __VBD_H__ 9.11 #define __VBD_H__ 9.12 9.13 @@ -11,8 +11,8 @@ 9.14 9.15 /* an entry in a list of xen_extent's */ 9.16 typedef struct _xen_extent_le { 9.17 - xen_extent_t extent; // an individual extent 9.18 - struct _xen_extent_le *next; // and a pointer to the next 9.19 + xen_extent_t extent; /* an individual extent */ 9.20 + struct _xen_extent_le *next; /* and a pointer to the next */ 9.21 } xen_extent_le_t; 9.22 9.23 9.24 @@ -22,17 +22,18 @@ typedef struct _xen_extent_le { 9.25 ** Each domain has a hash table to map from these to the relevant VBD. 9.26 */ 9.27 typedef struct _vbd { 9.28 - unsigned short vdevice; // what the domain refers to this vbd as 9.29 - unsigned short mode; // VBD_MODE_{READONLY,READWRITE} 9.30 - xen_extent_le_t *extents; // list of xen_extents making up this vbd 9.31 - struct _vbd *next; // for chaining in the hash table 9.32 + unsigned short vdevice; /* what the domain refers to this vbd as */ 9.33 + unsigned short mode; /* VBD_MODE_{READONLY,READWRITE} */ 9.34 + xen_extent_le_t *extents; /* list of xen_extents making up this vbd */ 9.35 + struct _vbd *next; /* for chaining in the hash table */ 9.36 } vbd_t; 9.37 9.38 -#define VBD_HTAB_SZ 16 // no. of entries in the vbd hash table. 9.39 +#define VBD_HTAB_SZ 16 /* # entries in the vbd hash table. */ 9.40 9.41 long vbd_create(vbd_create_t *create_params); 9.42 -long vbd_add(vbd_add_t *add_params); 9.43 -long vbd_remove(vbd_remove_t *remove_params); 9.44 +long vbd_grow(vbd_grow_t *grow_params); 9.45 +long vbd_shrink(vbd_shrink_t *shrink_params); 9.46 +long vbd_setextents(vbd_setextents_t *setextents_params); 9.47 long vbd_delete(vbd_delete_t *delete_params); 9.48 long vbd_probe(vbd_probe_t *probe_params); 9.49 long vbd_info(vbd_info_t *info_params); 9.50 @@ -50,5 +51,4 @@ typedef struct { 9.51 9.52 int vbd_translate(phys_seg_t *pseg, struct task_struct *p, int operation); 9.53 9.54 - 9.55 #endif /* __VBD_H__ */