Well, so my called strictly blocking IO (do and wait till get result before returning from the syscall) only applies on read(). For write(), I agree, kernel may perfer defer the actual write to the physical device so our driver better supports this. ---------------------------------------- > From: oneukum@xxxxxxx > To: unicorn_wang@xxxxxxxxxxx > CC: linux-usb@xxxxxxxxxxxxxxx > Subject: Re: question on skel_read func of usb_skeleton.c > Date: Fri, 12 Jul 2013 15:38:04 +0200 > > On Friday 12 July 2013 13:09:23 WangChen wrote: >> Oliver, my understanding is the limit_sem will only cause write() to sleep and wait for other IOs to finish when there are alreay WRITES_IN_FLIGHT URBs are on going. I see code line 509: sema_init(&dev->limit_sem, WRITES_IN_FLIGHT); >> My understanding of Blocking IO should block every write() when corresponding URBs is not finished, am I right? > > Quoting from the man page of close(): > > NOTES > Not checking the return value of close() is a common but nevertheless serious programming error. It is quite possible that errors on a previous write(2) operation are first reported at the final close(). Not checking the return value when closing the file > may lead to silent loss of data. This can especially be observed with NFS and with disk quota. > > A successful close does not guarantee that the data has been successfully saved to disk, as the kernel defers writes. It is not common for a file system to flush the buffers when the stream is closed. If you need to be sure that the data is physically > stored use fsync(2). (It will depend on the disk hardware at this point.) > > It is probably unwise to close file descriptors while they may be in use by system calls in other threads in the same process. Since a file descriptor may be reused, there are some obscure race conditions that may cause unintended side effects. > > > The logic for doing this is implemented in: > > static int skel_flush(struct file *file, fl_owner_t id) > { > struct usb_skel *dev; > int res; > > dev = file->private_data; > if (dev == NULL) > return -ENODEV; > > /* wait for io to stop */ > mutex_lock(&dev->io_mutex); > skel_draw_down(dev); > > /* read out errors, leave subsequent opens a clean slate */ > spin_lock_irq(&dev->err_lock); > res = dev->errors ? (dev->errors == -EPIPE ? -EPIPE : -EIO) : 0; > dev->errors = 0; > spin_unlock_irq(&dev->err_lock); > > mutex_unlock(&dev->io_mutex); > > return res; > } > > Regards > Oliver > ےôè؛{.nا+‰·ں®‰†+%ٹثے±éف¶¥ٹwے؛{.nا+‰·¥ٹ{±ë)ي…وèw*jg¬±¨¶‰ڑژٹف¢jے¾«G«éے¢¸¢·¦j:+v‰¨ٹwèjطm¶ںےّ¯ù®w¥ٹàf£¢·hڑڈâْے†ظ¥