diff options
-rw-r--r-- | drivers/block/xen-blkback/blkback.c | 31 | ||||
-rw-r--r-- | drivers/block/xen-blkback/common.h | 25 | ||||
-rw-r--r-- | include/xen/interface/io/blkif.h | 10 |
3 files changed, 62 insertions, 4 deletions
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 6d1cc3df2ac6..1a0faf6370ca 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c | |||
@@ -679,6 +679,16 @@ static int dispatch_discard_io(struct xen_blkif *blkif, | |||
679 | return err; | 679 | return err; |
680 | } | 680 | } |
681 | 681 | ||
682 | static int dispatch_other_io(struct xen_blkif *blkif, | ||
683 | struct blkif_request *req, | ||
684 | struct pending_req *pending_req) | ||
685 | { | ||
686 | free_req(pending_req); | ||
687 | make_response(blkif, req->u.other.id, req->operation, | ||
688 | BLKIF_RSP_EOPNOTSUPP); | ||
689 | return -EIO; | ||
690 | } | ||
691 | |||
682 | static void xen_blk_drain_io(struct xen_blkif *blkif) | 692 | static void xen_blk_drain_io(struct xen_blkif *blkif) |
683 | { | 693 | { |
684 | atomic_set(&blkif->drain, 1); | 694 | atomic_set(&blkif->drain, 1); |
@@ -800,17 +810,30 @@ __do_block_io_op(struct xen_blkif *blkif) | |||
800 | 810 | ||
801 | /* Apply all sanity checks to /private copy/ of request. */ | 811 | /* Apply all sanity checks to /private copy/ of request. */ |
802 | barrier(); | 812 | barrier(); |
803 | if (unlikely(req.operation == BLKIF_OP_DISCARD)) { | 813 | |
814 | switch (req.operation) { | ||
815 | case BLKIF_OP_READ: | ||
816 | case BLKIF_OP_WRITE: | ||
817 | case BLKIF_OP_WRITE_BARRIER: | ||
818 | case BLKIF_OP_FLUSH_DISKCACHE: | ||
819 | if (dispatch_rw_block_io(blkif, &req, pending_req)) | ||
820 | goto done; | ||
821 | break; | ||
822 | case BLKIF_OP_DISCARD: | ||
804 | free_req(pending_req); | 823 | free_req(pending_req); |
805 | if (dispatch_discard_io(blkif, &req)) | 824 | if (dispatch_discard_io(blkif, &req)) |
806 | break; | 825 | goto done; |
807 | } else if (dispatch_rw_block_io(blkif, &req, pending_req)) | 826 | break; |
827 | default: | ||
828 | if (dispatch_other_io(blkif, &req, pending_req)) | ||
829 | goto done; | ||
808 | break; | 830 | break; |
831 | } | ||
809 | 832 | ||
810 | /* Yield point for this unbounded loop. */ | 833 | /* Yield point for this unbounded loop. */ |
811 | cond_resched(); | 834 | cond_resched(); |
812 | } | 835 | } |
813 | 836 | done: | |
814 | return more_to_do; | 837 | return more_to_do; |
815 | } | 838 | } |
816 | 839 | ||
diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h index 6072390c7f57..195278ae993d 100644 --- a/drivers/block/xen-blkback/common.h +++ b/drivers/block/xen-blkback/common.h | |||
@@ -77,11 +77,18 @@ struct blkif_x86_32_request_discard { | |||
77 | uint64_t nr_sectors; | 77 | uint64_t nr_sectors; |
78 | } __attribute__((__packed__)); | 78 | } __attribute__((__packed__)); |
79 | 79 | ||
80 | struct blkif_x86_32_request_other { | ||
81 | uint8_t _pad1; | ||
82 | blkif_vdev_t _pad2; | ||
83 | uint64_t id; /* private guest value, echoed in resp */ | ||
84 | } __attribute__((__packed__)); | ||
85 | |||
80 | struct blkif_x86_32_request { | 86 | struct blkif_x86_32_request { |
81 | uint8_t operation; /* BLKIF_OP_??? */ | 87 | uint8_t operation; /* BLKIF_OP_??? */ |
82 | union { | 88 | union { |
83 | struct blkif_x86_32_request_rw rw; | 89 | struct blkif_x86_32_request_rw rw; |
84 | struct blkif_x86_32_request_discard discard; | 90 | struct blkif_x86_32_request_discard discard; |
91 | struct blkif_x86_32_request_other other; | ||
85 | } u; | 92 | } u; |
86 | } __attribute__((__packed__)); | 93 | } __attribute__((__packed__)); |
87 | 94 | ||
@@ -113,11 +120,19 @@ struct blkif_x86_64_request_discard { | |||
113 | uint64_t nr_sectors; | 120 | uint64_t nr_sectors; |
114 | } __attribute__((__packed__)); | 121 | } __attribute__((__packed__)); |
115 | 122 | ||
123 | struct blkif_x86_64_request_other { | ||
124 | uint8_t _pad1; | ||
125 | blkif_vdev_t _pad2; | ||
126 | uint32_t _pad3; /* offsetof(blkif_..,u.discard.id)==8 */ | ||
127 | uint64_t id; /* private guest value, echoed in resp */ | ||
128 | } __attribute__((__packed__)); | ||
129 | |||
116 | struct blkif_x86_64_request { | 130 | struct blkif_x86_64_request { |
117 | uint8_t operation; /* BLKIF_OP_??? */ | 131 | uint8_t operation; /* BLKIF_OP_??? */ |
118 | union { | 132 | union { |
119 | struct blkif_x86_64_request_rw rw; | 133 | struct blkif_x86_64_request_rw rw; |
120 | struct blkif_x86_64_request_discard discard; | 134 | struct blkif_x86_64_request_discard discard; |
135 | struct blkif_x86_64_request_other other; | ||
121 | } u; | 136 | } u; |
122 | } __attribute__((__packed__)); | 137 | } __attribute__((__packed__)); |
123 | 138 | ||
@@ -278,6 +293,11 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst, | |||
278 | dst->u.discard.nr_sectors = src->u.discard.nr_sectors; | 293 | dst->u.discard.nr_sectors = src->u.discard.nr_sectors; |
279 | break; | 294 | break; |
280 | default: | 295 | default: |
296 | /* | ||
297 | * Don't know how to translate this op. Only get the | ||
298 | * ID so failure can be reported to the frontend. | ||
299 | */ | ||
300 | dst->u.other.id = src->u.other.id; | ||
281 | break; | 301 | break; |
282 | } | 302 | } |
283 | } | 303 | } |
@@ -309,6 +329,11 @@ static inline void blkif_get_x86_64_req(struct blkif_request *dst, | |||
309 | dst->u.discard.nr_sectors = src->u.discard.nr_sectors; | 329 | dst->u.discard.nr_sectors = src->u.discard.nr_sectors; |
310 | break; | 330 | break; |
311 | default: | 331 | default: |
332 | /* | ||
333 | * Don't know how to translate this op. Only get the | ||
334 | * ID so failure can be reported to the frontend. | ||
335 | */ | ||
336 | dst->u.other.id = src->u.other.id; | ||
312 | break; | 337 | break; |
313 | } | 338 | } |
314 | } | 339 | } |
diff --git a/include/xen/interface/io/blkif.h b/include/xen/interface/io/blkif.h index 01c3d62436ef..ffd4652de91c 100644 --- a/include/xen/interface/io/blkif.h +++ b/include/xen/interface/io/blkif.h | |||
@@ -138,11 +138,21 @@ struct blkif_request_discard { | |||
138 | uint8_t _pad3; | 138 | uint8_t _pad3; |
139 | } __attribute__((__packed__)); | 139 | } __attribute__((__packed__)); |
140 | 140 | ||
141 | struct blkif_request_other { | ||
142 | uint8_t _pad1; | ||
143 | blkif_vdev_t _pad2; /* only for read/write requests */ | ||
144 | #ifdef CONFIG_X86_64 | ||
145 | uint32_t _pad3; /* offsetof(blkif_req..,u.other.id)==8*/ | ||
146 | #endif | ||
147 | uint64_t id; /* private guest value, echoed in resp */ | ||
148 | } __attribute__((__packed__)); | ||
149 | |||
141 | struct blkif_request { | 150 | struct blkif_request { |
142 | uint8_t operation; /* BLKIF_OP_??? */ | 151 | uint8_t operation; /* BLKIF_OP_??? */ |
143 | union { | 152 | union { |
144 | struct blkif_request_rw rw; | 153 | struct blkif_request_rw rw; |
145 | struct blkif_request_discard discard; | 154 | struct blkif_request_discard discard; |
155 | struct blkif_request_other other; | ||
146 | } u; | 156 | } u; |
147 | } __attribute__((__packed__)); | 157 | } __attribute__((__packed__)); |
148 | 158 | ||