Chris Johns commented: https://gitlab.rtems.org/rtems/rtos/rtems/-/issues/5201#note_123181 # Reason This behavior is also present on `6-freebsd-14` and `7-freebsd-14` and I suspect `main` (FreeBSD 15). The reason is an `fd` IOP is held when referenced by `kqueue` event sets. The `kqueue` `fd` is also held at the same time resulting in a deadlock because RTEMS's `libio` extended the errors `close` returns. If you attempt to close an `fd` while being held `EBUSY` is returned. The approach is a little naive performing the check at the `libio` layer rather than letting the file system decide. You cannot call close on either the event `fd` or `kqueue` to unblock the call. The close `EBUSY` check was added then the reference counting change was made. My guess is the implementation simplifies the free logic for an `iop`. We cannot change the current implementation without checking all users and possibly breaking them. # LibIO The proper fix is to clean up `libio`. There are other issues around the referencing counting in `libio`. The base design is good and sound with lock-less atomic access to the IOP flags giving good performance however it does not deal with more complex `fd` relationships such as FreeBSD's `kqueue` and the event `fd`'s with close. The IOP flags use the open bit in the IOP as a reference to say a user has the `fd`. The reference counts indicate if the IOP is held in `libio` or a file system call however the real count is plus one for the open state. # Solution The solution is to let `close` call the close handler if references to the `iop` are held. The default behavior is to return `EBADF` if a reference is held. It is what we have now. There is too much work to audit and check all the existing file systems and users of these handler interfaces to know handling close with reference held is OK. A file system that can support close with held references can set an `iop` flag called `LIBIO_FLAGS_CLOSE_BUSY` in open and `close` checks for the flag and does raise error if set. This approach complicates when the `iop` can be freed as the free is currently done in `close` as there are no held references. Adding checks to free the `iop` to all handler paths is not great because it complicates that code and a case might be missed. FreeBSD's descriptor code has a reference for the `fd` allocation and implements standard reference counting logic for a shared resource. If the hold count drops to zero the resource is freed. Adding the free to the `iop` drop can work. -- View it on GitLab: https://gitlab.rtems.org/rtems/rtos/rtems/-/issues/5201#note_123181 You're receiving this email because of your account on gitlab.rtems.org.
_______________________________________________ bugs mailing list bugs@rtems.org http://lists.rtems.org/mailman/listinfo/bugs