1 /* Filter driver - lowest layer - disk driver management */
11 int problem
; /* one of BD_* */
12 int error
; /* one of E*, only relevant if problem>0 */
17 /* State variables. */
18 static endpoint_t self_ep
;
19 static asynmsg_t amsgtable
[2];
21 static int size_known
= 0;
22 static u64_t disk_size
;
24 static int problem_stats
[BD_LAST
] = { 0 };
26 /*===========================================================================*
28 *===========================================================================*/
29 static int driver_open(int which
)
31 /* Perform an open or close operation on the driver. This is
32 * unfinished code: we should never be doing a blocking sendrec() to
37 struct partition part
;
41 msg
.m_type
= DEV_OPEN
;
42 msg
.DEVICE
= driver
[which
].minor
;
43 msg
.IO_ENDPT
= self_ep
;
44 r
= sendrec(driver
[which
].endpt
, &msg
);
47 /* Should we restart the driver now? */
48 printf("Filter: driver_open: sendrec returned %d\n", r
);
53 if(msg
.m_type
!= TASK_REPLY
|| msg
.REP_STATUS
!= OK
) {
54 printf("Filter: driver_open: sendrec returned %d, %d\n",
55 msg
.m_type
, msg
.REP_STATUS
);
60 /* Take the opportunity to retrieve the hard disk size. */
61 gid
= cpf_grant_direct(driver
[which
].endpt
,
62 (vir_bytes
) &part
, sizeof(part
), CPF_WRITE
);
64 panic(__FILE__
, "invalid grant", gid
);
66 msg
.m_type
= DEV_IOCTL_S
;
67 msg
.REQUEST
= DIOCGETP
;
68 msg
.DEVICE
= driver
[which
].minor
;
69 msg
.IO_ENDPT
= self_ep
;
70 msg
.IO_GRANT
= (char *) gid
;
72 r
= sendrec(driver
[which
].endpt
, &msg
);
76 if (r
!= OK
|| msg
.m_type
!= TASK_REPLY
|| msg
.REP_STATUS
!= OK
) {
77 /* Not sure what to do here, either. */
78 printf("Filter: ioctl(DIOCGETP) returned (%d, %d)\n",
85 disk_size
= part
.size
;
87 sectors
= div64u(disk_size
, SECTOR_SIZE
);
88 if(cmp64(mul64u(sectors
, SECTOR_SIZE
), disk_size
)) {
89 printf("Filter: partition too large\n");
94 printf("Filter: partition size: 0x%s / %lu sectors\n",
95 print64(disk_size
), sectors
);
98 if(cmp64(disk_size
, part
.size
)) {
99 printf("Filter: partition size mismatch (%s != %s)\n",
100 print64(part
.size
), print64(disk_size
));
109 /*===========================================================================*
111 *===========================================================================*/
112 static int driver_close(int which
)
117 msg
.m_type
= DEV_CLOSE
;
118 msg
.DEVICE
= driver
[which
].minor
;
119 msg
.IO_ENDPT
= self_ep
;
120 r
= sendrec(driver
[which
].endpt
, &msg
);
123 /* Should we restart the driver now? */
124 printf("Filter: driver_close: sendrec returned %d\n", r
);
129 if(msg
.m_type
!= TASK_REPLY
|| msg
.REP_STATUS
!= OK
) {
130 printf("Filter: driver_close: sendrec returned %d, %d\n",
131 msg
.m_type
, msg
.REP_STATUS
);
139 /*===========================================================================*
141 *===========================================================================*/
142 void driver_init(void)
144 /* Initialize the driver layer. */
147 self_ep
= getprocnr();
149 memset(driver
, 0, sizeof(driver
));
151 /* Endpoints unknown. */
152 driver
[DRIVER_MAIN
].endpt
= NONE
;
153 driver
[DRIVER_BACKUP
].endpt
= NONE
;
155 /* Get disk driver's and this proc's endpoint. */
156 driver
[DRIVER_MAIN
].label
= MAIN_LABEL
;
157 driver
[DRIVER_MAIN
].minor
= MAIN_MINOR
;
159 r
= ds_retrieve_label_num(driver
[DRIVER_MAIN
].label
,
160 (u32_t
*) &driver
[DRIVER_MAIN
].endpt
);
162 printf("Filter: failed to get main disk driver's endpoint: "
164 bad_driver(DRIVER_MAIN
, BD_DEAD
, EFAULT
);
165 check_driver(DRIVER_MAIN
);
167 else if (driver_open(DRIVER_MAIN
) != OK
) {
168 panic(__FILE__
, "unhandled driver_open failure", NO_NUM
);
172 driver
[DRIVER_BACKUP
].label
= BACKUP_LABEL
;
173 driver
[DRIVER_BACKUP
].minor
= BACKUP_MINOR
;
175 if(!strcmp(driver
[DRIVER_MAIN
].label
,
176 driver
[DRIVER_BACKUP
].label
)) {
177 panic(__FILE__
, "same driver: not tested", NO_NUM
);
180 r
= ds_retrieve_label_num(driver
[DRIVER_BACKUP
].label
,
181 (u32_t
*) &driver
[DRIVER_BACKUP
].endpt
);
183 printf("Filter: failed to get backup disk driver's "
184 "endpoint: %d\n", r
);
185 bad_driver(DRIVER_BACKUP
, BD_DEAD
, EFAULT
);
186 check_driver(DRIVER_BACKUP
);
188 else if (driver_open(DRIVER_BACKUP
) != OK
) {
189 panic(__FILE__
, "unhandled driver_open failure",
195 /*===========================================================================*
197 *===========================================================================*/
198 void driver_shutdown(void)
203 printf("Filter: %u driver deaths, %u protocol errors, "
204 "%u data errors\n", problem_stats
[BD_DEAD
],
205 problem_stats
[BD_PROTO
], problem_stats
[BD_DATA
]);
208 if(driver_close(DRIVER_MAIN
) != OK
)
209 printf("Filter: DEV_CLOSE failed on shutdown (1)\n");
212 if(driver_close(DRIVER_BACKUP
) != OK
)
213 printf("Filter: DEV_CLOSE failed on shutdown (2)\n");
216 /*===========================================================================*
218 *===========================================================================*/
219 u64_t
get_raw_size(void)
221 /* Return the size of the raw disks as used by the filter driver.
227 /*===========================================================================*
229 *===========================================================================*/
230 void reset_kills(void)
232 /* Reset kill and retry statistics. */
233 driver
[DRIVER_MAIN
].kills
= 0;
234 driver
[DRIVER_MAIN
].retries
= 0;
235 driver
[DRIVER_BACKUP
].kills
= 0;
236 driver
[DRIVER_BACKUP
].retries
= 0;
239 /*===========================================================================*
241 *===========================================================================*/
242 int bad_driver(int which
, int type
, int error
)
244 /* A disk driver has died or produced an error. Mark it so that we can
245 * deal with it later, and return RET_REDO to indicate that the
246 * current operation is to be retried. Also store an error code to
247 * return to the user if the situation is unrecoverable.
249 driver
[which
].problem
= type
;
250 driver
[which
].error
= error
;
255 /*===========================================================================*
257 *===========================================================================*/
258 static int new_driver_ep(int which
)
260 /* See if a new driver instance has already been started for the given
261 * driver, by retrieving its entry from DS.
266 r
= ds_retrieve_label_num(driver
[which
].label
, (u32_t
*) &endpt
);
269 printf("Filter: DS query for %s failed\n",
270 driver
[which
].label
);
275 if (endpt
== driver
[which
].endpt
) {
277 printf("Filter: same endpoint for %s\n", driver
[which
].label
);
283 printf("Filter: new enpdoint for %s: %d -> %d\n", driver
[which
].label
,
284 driver
[which
].endpt
, endpt
);
287 driver
[which
].endpt
= endpt
;
292 /*===========================================================================*
294 *===========================================================================*/
295 static int check_problem(int which
, int problem
, int retries
, int *tell_rs
)
297 /* A problem has occurred with a driver. Update statistics, and decide
298 * what to do. If EAGAIN is returned, the driver should be restarted;
299 * any other result will be passed up.
303 printf("Filter: check_driver processing driver %d, problem %d\n",
307 problem_stats
[problem
]++;
309 if(new_driver_ep(which
)) {
311 printf("Filter: check_problem: noticed a new driver\n");
314 if(driver_open(which
) == OK
) {
316 printf("Filter: open OK -> no recovery\n");
321 printf("Filter: open not OK -> recovery\n");
324 problem_stats
[problem
]++;
328 /* If the driver has died, we always need to restart it. If it has
329 * been giving problems, we first retry the request, up to N times,
330 * after which we kill and restart the driver. We restart the driver
331 * up to M times, after which we remove the driver from the mirror
332 * configuration. If we are not set up to do mirroring, we can only
333 * do one thing, and that is continue to limp along with the bad
339 driver
[which
].retries
++;
342 printf("Filter: disk driver %d has had "
343 "%d/%d retry attempts, %d/%d kills\n", which
,
344 driver
[which
].retries
, NR_RETRIES
,
345 driver
[which
].kills
, NR_RESTARTS
);
348 if (driver
[which
].retries
< NR_RETRIES
) {
351 printf("Filter: not restarting; retrying "
352 "(retries %d/%d, kills %d/%d)\n",
353 driver
[which
].retries
, NR_RETRIES
,
354 driver
[which
].kills
, NR_RESTARTS
);
359 printf("Filter: restarting (retries %d/%d, "
360 "kills %d/%d, internal retry %d)\n",
361 driver
[which
].retries
, NR_RETRIES
,
362 driver
[which
].kills
, NR_RESTARTS
, retries
);
367 printf("Filter: disk driver %d has reached error "
368 "threshold, restarting driver\n", which
);
375 /* Can't kill that which is already dead.. */
380 panic(__FILE__
, "invalid problem", problem
);
383 /* At this point, the driver will be restarted. */
384 driver
[which
].retries
= 0;
385 driver
[which
].kills
++;
387 if (driver
[which
].kills
< NR_RESTARTS
)
390 /* We've reached the maximum number of restarts for this driver. */
392 printf("Filter: kill threshold reached, disabling mirroring\n");
396 if (which
== DRIVER_MAIN
) {
397 driver
[DRIVER_MAIN
] = driver
[DRIVER_BACKUP
];
399 /* This is not necessary. */
400 strcpy(MAIN_LABEL
, BACKUP_LABEL
);
401 MAIN_MINOR
= BACKUP_MINOR
;
404 driver
[DRIVER_BACKUP
].endpt
= NONE
;
409 /* We tried, we really did. But now we give up. Tell the user.
411 printf("Filter: kill threshold reached, returning error\n");
413 if (driver
[which
].error
== EAGAIN
) return EIO
;
415 return driver
[which
].error
;
419 /*===========================================================================*
421 *===========================================================================*/
422 static void restart_driver(int which
, int tell_rs
)
424 /* Restart the given driver. Block until the new instance is up.
431 /* Tell RS to refresh or restart the driver */
432 msg
.m_type
= RS_REFRESH
;
433 msg
.RS_CMD_ADDR
= driver
[which
].label
;
434 msg
.RS_CMD_LEN
= strlen(driver
[which
].label
);
437 printf("Filter: asking RS to refresh %s..\n",
438 driver
[which
].label
);
441 r
= sendrec(RS_PROC_NR
, &msg
);
443 if (r
!= OK
|| msg
.m_type
!= OK
)
444 panic(__FILE__
, "RS request failed", r
);
447 printf("Filter: RS call succeeded\n");
451 /* Wait until the new driver instance is up, and get its endpoint. */
453 printf("Filter: endpoint update driver %d; old endpoint %d\n",
454 which
, driver
[which
].endpt
);
461 r
= ds_retrieve_label_num(driver
[which
].label
,
466 printf("Filter: DS request failed (%d)\n", r
);
467 else if (endpt
== driver
[which
].endpt
)
468 printf("Filter: DS returned same endpoint\n");
470 printf("Filter: DS request OK, new endpoint\n");
472 } while (r
!= OK
|| endpt
== driver
[which
].endpt
);
474 driver
[which
].endpt
= endpt
;
477 /*===========================================================================*
479 *===========================================================================*/
480 int check_driver(int which
)
482 /* See if the given driver has been troublesome, and if so, deal with
485 int problem
, tell_rs
;
488 problem
= driver
[which
].problem
;
490 if (problem
== BD_NONE
)
496 printf("Filter: check_driver: retry number %d\n",
502 driver
[which
].problem
= BD_NONE
;
504 /* Decide what to do: continue operation, restart the driver,
505 * or return an error.
507 r
= check_problem(which
, problem
, retries
, &tell_rs
);
511 /* Restarting the driver it is. First tell RS (if necessary),
512 * then wait for the new driver instance to come up.
514 restart_driver(which
, tell_rs
);
516 /* Finally, open the device on the new driver */
517 } while (driver_open(which
) != OK
);
520 printf("Filter: check_driver restarted driver %d, endpoint %d\n",
521 which
, driver
[which
].endpt
);
527 /*===========================================================================*
529 *===========================================================================*/
530 static int flt_senda(message
*mess
, int which
)
532 /* Send a message to one driver. Can only return OK at the moment. */
536 /* Fill in the last bits of the message. */
537 mess
->DEVICE
= driver
[which
].minor
;
538 mess
->IO_ENDPT
= self_ep
;
540 /* Send the message asynchronously. */
541 amp
= &amsgtable
[which
];
542 amp
->dst
= driver
[which
].endpt
;
544 amp
->flags
= AMF_VALID
;
545 r
= senda(amsgtable
, 2);
548 panic(__FILE__
, "senda returned error", r
);
553 /*===========================================================================*
555 *===========================================================================*/
556 static int check_senda(int which
)
558 /* Check whether an earlier senda resulted in an error indicating the
559 * message never got delivered. Only in that case can we reliably say
560 * that the driver died. Return BD_DEAD in this case, and BD_PROTO
565 amp
= &amsgtable
[which
];
567 if ((amp
->flags
& AMF_DONE
) &&
568 (amp
->result
== EDEADSRCDST
|| amp
->result
== EDSTDIED
)) {
576 /*===========================================================================*
578 *===========================================================================*/
579 static int flt_receive(message
*mess
, int which
)
581 /* Receive a message from one or either driver, unless a timeout
582 * occurs. Can only return OK or RET_REDO.
587 r
= sef_receive(ANY
, mess
);
589 panic(__FILE__
, "sef_receive returned error", r
);
591 if(mess
->m_source
== CLOCK
&& is_notify(mess
->m_type
)) {
592 if (mess
->NOTIFY_TIMESTAMP
< flt_alarm(-1)) {
594 printf("Filter: SKIPPING old alarm "
601 printf("Filter: timeout waiting for disk driver %d "
605 /* If we're waiting for either driver,
609 bad_driver(DRIVER_MAIN
,
610 check_senda(DRIVER_MAIN
), EFAULT
);
612 return bad_driver(DRIVER_BACKUP
,
613 check_senda(DRIVER_BACKUP
), EFAULT
);
616 /* Otherwise, just report the one not replying as dead.
618 return bad_driver(which
, check_senda(which
), EFAULT
);
621 if (mess
->m_source
!= driver
[DRIVER_MAIN
].endpt
&&
622 mess
->m_source
!= driver
[DRIVER_BACKUP
].endpt
) {
624 printf("Filter: got STRAY message %d from %d\n",
625 mess
->m_type
, mess
->m_source
);
631 /* We are waiting for a reply from one specific driver. */
633 /* If the message source is that driver, good. */
634 if (mess
->m_source
== driver
[which
].endpt
)
637 /* This should probably be treated as a real protocol
638 * error. We do not abort any receives (not even paired
639 * receives) except because of timeouts. Getting here
640 * means a driver replied at least the timeout period
641 * later than expected, which should be enough reason
642 * to kill it really. The other explanation is that it
643 * is actually violating the protocol and sending bogus
647 printf("Filter: got UNEXPECTED reply from %d\n",
654 /* We got a message from one of the drivers, and we didn't
655 * care which one we wanted to receive from. A-OK.
663 /*===========================================================================*
665 *===========================================================================*/
666 static int flt_sendrec(message
*mess
, int which
)
670 r
= flt_senda(mess
, which
);
674 if(check_senda(which
) == BD_DEAD
) {
675 return bad_driver(which
, BD_DEAD
, EFAULT
);
679 flt_alarm(DRIVER_TIMEOUT
);
681 r
= flt_receive(mess
, which
);
683 /* Clear the alarm. */
688 /*===========================================================================*
690 *===========================================================================*/
691 static int do_sendrec_both(message
*m1
, message
*m2
)
693 /* If USEE_MIRROR is set, call flt_sendrec() to both drivers.
694 * Otherwise, only call flt_sendrec() to the main driver.
695 * This function will only return either OK or RET_REDO.
700 /* If the two disks use the same driver, call flt_sendrec() twice
701 * sequentially. Such a setup is not very useful though.
703 if (!strcmp(driver
[DRIVER_MAIN
].label
, driver
[DRIVER_BACKUP
].label
)) {
704 if ((r
= flt_sendrec(m1
, DRIVER_MAIN
)) != OK
) return r
;
705 return flt_sendrec(m2
, DRIVER_BACKUP
);
708 /* If the two disks use different drivers, call flt_senda()
709 * twice, and then flt_receive(), and distinguish the return
710 * messages by means of m_source.
712 if ((r
= flt_senda(m1
, DRIVER_MAIN
)) != OK
) return r
;
713 if ((r
= flt_senda(m2
, DRIVER_BACKUP
)) != OK
) return r
;
716 flt_alarm(DRIVER_TIMEOUT
);
718 /* The message received by the 1st flt_receive() may not be
721 if ((r
= flt_receive(&ma
, -1)) != OK
) {
726 if (ma
.m_source
== driver
[DRIVER_MAIN
].endpt
) {
727 which
= DRIVER_BACKUP
;
728 } else if (ma
.m_source
== driver
[DRIVER_BACKUP
].endpt
) {
731 panic(__FILE__
, "message from unexpected source",
735 r
= flt_receive(&mb
, which
);
737 /* Clear the alarm. */
743 if (ma
.m_source
== driver
[DRIVER_MAIN
].endpt
) {
754 /*===========================================================================*
756 *===========================================================================*/
757 static int do_sendrec_one(message
*m1
, message
*m2
)
759 /* Only talk to the main driver. If something goes wrong, it will
760 * be fixed elsewhere.
761 * This function will only return either OK or RET_REDO.
764 return flt_sendrec(m1
, DRIVER_MAIN
);
767 /*===========================================================================*
769 *===========================================================================*/
770 static int paired_sendrec(message
*m1
, message
*m2
, int both
)
772 /* Sendrec with the disk driver. If the disk driver is down, and was
773 * restarted, redo the request, until the driver works fine, or can't
774 * be restarted again.
779 printf("paired_sendrec(%d) - <%d,%x:%x,%d> - %x,%x\n",
780 both
, m1
->m_type
, m1
->HIGHPOS
, m1
->POSITION
, m1
->COUNT
,
781 m1
->IO_GRANT
, m2
->IO_GRANT
);
785 r
= do_sendrec_both(m1
, m2
);
787 r
= do_sendrec_one(m1
, m2
);
791 printf("paired_sendrec about to return %d\n", r
);
797 /*===========================================================================*
799 *===========================================================================*/
800 static int single_grant(endpoint_t endpt
, vir_bytes buf
, int access
,
801 cp_grant_id_t
*gid
, iovec_s_t vector
[NR_IOREQS
], size_t *sizep
)
803 /* Create grants for a vectored request to a single driver.
811 /* Split up the request into chunks, if requested. This makes no
812 * difference at all, except that this works around a weird performance
813 * bug with large DMA PRDs on some machines.
815 if (CHUNK_SIZE
> 0) chunk
= CHUNK_SIZE
;
818 /* Fill in the vector, creating a grant for each item. */
819 for (count
= 0; size
> 0 && count
< NR_IOREQS
; count
++) {
820 /* The last chunk will contain all the remaining data. */
821 if (chunk
> size
|| count
== NR_IOREQS
- 1)
824 grant
= cpf_grant_direct(endpt
, buf
, chunk
, access
);
825 if (!GRANT_VALID(grant
))
826 panic(__FILE__
, "invalid grant", grant
);
828 vector
[count
].iov_grant
= grant
;
829 vector
[count
].iov_size
= chunk
;
835 /* Then create a grant for the vector itself. */
836 *gid
= cpf_grant_direct(endpt
, (vir_bytes
) vector
,
837 sizeof(vector
[0]) * count
, CPF_READ
| CPF_WRITE
);
839 if (!GRANT_VALID(*gid
))
840 panic(__FILE__
, "invalid grant", *gid
);
845 /*===========================================================================*
847 *===========================================================================*/
848 static int paired_grant(char *buf1
, char *buf2
, int request
,
849 cp_grant_id_t
*gids
, iovec_s_t vectors
[2][NR_IOREQS
], size_t *sizes
,
852 /* Create memory grants, either to one or to both drivers.
857 access
= (request
== FLT_WRITE
) ? CPF_READ
: CPF_WRITE
;
859 if(driver
[DRIVER_MAIN
].endpt
> 0) {
860 count
= single_grant(driver
[DRIVER_MAIN
].endpt
,
861 (vir_bytes
) buf1
, access
, &gids
[0], vectors
[0],
866 if(driver
[DRIVER_BACKUP
].endpt
> 0) {
867 count
= single_grant(driver
[DRIVER_BACKUP
].endpt
,
868 (vir_bytes
) buf2
, access
, &gids
[1],
869 vectors
[1], &sizes
[1]);
875 /*===========================================================================*
877 *===========================================================================*/
878 PRIVATE
void single_revoke(cp_grant_id_t gid
, iovec_s_t vector
[NR_IOREQS
],
879 size_t *sizep
, int count
)
881 /* Revoke all grants associated with a request to a single driver.
882 * Modify the given size to reflect the actual I/O performed.
886 /* Revoke the grants for all the elements of the vector. */
887 for (i
= 0; i
< count
; i
++) {
888 cpf_revoke(vector
[i
].iov_grant
);
889 *sizep
-= vector
[i
].iov_size
;
892 /* Then revoke the grant for the vector itself. */
896 /*===========================================================================*
898 *===========================================================================*/
899 static void paired_revoke(cp_grant_id_t
*gids
, iovec_s_t vectors
[2][NR_IOREQS
],
900 size_t *sizes
, int count
, int both
)
902 /* Revoke grants to drivers for a single request.
905 single_revoke(gids
[0], vectors
[0], &sizes
[0], count
);
908 single_revoke(gids
[1], vectors
[1], &sizes
[1], count
);
911 /*===========================================================================*
913 *===========================================================================*/
914 int read_write(u64_t pos
, char *bufa
, char *bufb
, size_t *sizep
, int request
)
916 iovec_s_t vectors
[2][NR_IOREQS
];
918 cp_grant_id_t gids
[2];
922 gids
[0] = gids
[1] = GRANT_INVALID
;
923 sizes
[0] = sizes
[1] = *sizep
;
925 /* Send two requests only if mirroring is enabled and the given request
926 * is either FLT_READ2 or FLT_WRITE.
928 both
= (USE_MIRROR
&& request
!= FLT_READ
);
930 count
= paired_grant(bufa
, bufb
, request
, gids
, vectors
, sizes
, both
);
932 m1
.m_type
= (request
== FLT_WRITE
) ? DEV_SCATTER_S
: DEV_GATHER_S
;
934 m1
.POSITION
= ex64lo(pos
);
935 m1
.HIGHPOS
= ex64hi(pos
);
939 m1
.IO_GRANT
= (char *) gids
[0];
940 m2
.IO_GRANT
= (char *) gids
[1];
942 r
= paired_sendrec(&m1
, &m2
, both
);
944 paired_revoke(gids
, vectors
, sizes
, count
, both
);
949 printf("Filter: paired_sendrec returned %d\n", r
);
954 if (m1
.m_type
!= TASK_REPLY
|| m1
.REP_STATUS
!= OK
) {
955 printf("Filter: unexpected/invalid reply from main driver: "
956 "(%x, %d)\n", m1
.m_type
, m1
.REP_STATUS
);
958 return bad_driver(DRIVER_MAIN
, BD_PROTO
,
959 (m1
.m_type
== TASK_REPLY
) ? m1
.REP_STATUS
: EFAULT
);
962 if (sizes
[0] != *sizep
) {
963 printf("Filter: truncated reply from main driver\n");
965 /* If the driver returned a value *larger* than we requested,
966 * OR if we did NOT exceed the disk size, then we should
967 * report the driver for acting strangely!
969 if (sizes
[0] < 0 || sizes
[0] > *sizep
||
970 cmp64(add64u(pos
, sizes
[0]), disk_size
) < 0)
971 return bad_driver(DRIVER_MAIN
, BD_PROTO
, EFAULT
);
973 /* Return the actual size. */
978 if (m2
.m_type
!= TASK_REPLY
|| m2
.REP_STATUS
!= OK
) {
979 printf("Filter: unexpected/invalid reply from "
980 "backup driver (%x, %d)\n",
981 m2
.m_type
, m2
.REP_STATUS
);
983 return bad_driver(DRIVER_BACKUP
, BD_PROTO
,
984 m2
.m_type
== TASK_REPLY
? m2
.REP_STATUS
:
987 if (sizes
[1] != *sizep
) {
988 printf("Filter: truncated reply from backup driver\n");
991 if (sizes
[1] < 0 || sizes
[1] > *sizep
||
992 cmp64(add64u(pos
, sizes
[1]), disk_size
) < 0)
993 return bad_driver(DRIVER_BACKUP
, BD_PROTO
,
996 /* Return the actual size. */
997 if (*sizep
>= sizes
[1])