From: Thomas Veerman Date: Sat, 24 Aug 2013 10:23:41 +0000 (+0200) Subject: VFS: set w_task only when needed X-Git-Tag: v3.3.0~616 X-Git-Url: http://zhaoyanbai.com/repos/?a=commitdiff_plain;h=7d02ecdbb4a138f349e05f8bdcf5ad9e6685b25e;p=minix.git VFS: set w_task only when needed It was always set, but not always cleared, when talking to asynchronous drivers. This could cause erratic behavior upon a driver crash. Normally, a worker thread's w_task field is set when it's about to communicate with a driver or FS. Then upon receiving a reply we can do sanity checks (that the thread we want to wake up was actually waiting for a reply). Also, when a driver/FS crashes, we can identify which worker threads were talking to the crashed endpoint and handle the error gracefully. Asynchronous drivers are a bit special, though. In most cases, the sender of the request is not interested in the reply (the sender was suspended and only wants to know whether the request was successfully caried out or not). However, the open request is special, as the reply carries information needed by the sender. This is the only request where a worker thread actually yields and waits for the result. This is also the only case where we're interested in setting w_task for asynchronous drivers. Change-Id: Ia1ce2747937df376122b5e13b6a069de27fcc379 --- diff --git a/servers/vfs/device.c b/servers/vfs/device.c index f0647bad3..2e285a6f9 100644 --- a/servers/vfs/device.c +++ b/servers/vfs/device.c @@ -558,7 +558,9 @@ int gen_opcl( if (op == DEV_OPEN && dp->dmap_style == STYLE_DEVA) { fp->fp_task = dp->dmap_driver; + self->w_task = dp->dmap_driver; worker_wait(); + self->w_task = NONE; } if (is_bdev) @@ -769,7 +771,6 @@ int asyn_io(endpoint_t drv_e, message *mess_ptr) assert(!IS_BDEV_RQ(mess_ptr->m_type)); self->w_drv_sendrec = mess_ptr; /* Remember where result should be stored */ - self->w_task = drv_e; r = asynsend3(drv_e, mess_ptr, AMF_NOREPLY); @@ -892,7 +893,9 @@ int clone_opcl( if (op == DEV_OPEN && dev_style_asyn(dp->dmap_style)) { /* Wait for reply when driver is asynchronous */ fp->fp_task = dp->dmap_driver; + self->w_task = dp->dmap_driver; worker_wait(); + self->w_task = NONE; } if (op == DEV_OPEN && dev_mess.REP_STATUS >= 0) { @@ -1069,7 +1072,6 @@ void open_reply(void) } *wp->w_drv_sendrec = job_m_in; wp->w_drv_sendrec = NULL; - wp->w_task = NONE; worker_signal(wp); /* Continue open */ }