Opened 13 years ago
Closed 13 years ago
#374 closed defect (fixed)
Hang while unmounting dirty MFS
Reported by: | Jakub Jermář | Owned by: | Jakub Jermář |
---|---|---|---|
Priority: | major | Milestone: | 0.5.0 |
Component: | helenos/lib/c | Version: | mainline |
Keywords: | Cc: | ||
Blocker for: | Depends on: | ||
See also: |
Description
The following leads to a possibly infinity active loop in file_bd:
/ # cd /tmp /tmp # mfile -s 300k img /tmp # file_bd img fd0 ... /tmp # mkmfs fd0 ... /tmp # mfs ... /tmp # mount mfs /data fd0 /tmp # touch /data/a /tmp # unmount /data
After the unmount command, the file system will appear hung. Looking at threads from kconsole reveals that file_bd is busy all the time. Using the btrace command shows that it loops somewhere inside fwrite().
Change History (2)
comment:1 by , 13 years ago
Component: | helenos/fs/mfs → helenos/uspace/libc |
---|---|
Owner: | set to |
comment:2 by , 13 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Fixed in mainline,1226.
bytes_used
is computed as the distance between head and tail, buf_free
is the distance of the head from the end of the buffer (tail is not used). fwrite()
relies on _fflushbuf()
to reset head and tail pointers.
When doing a read()
of size equal to buffer size, first head is moved to the end of the buffer when the buffer is filled. Then tail is moved to the end of the buffer when the data is copied out to the client. Thus we have bytes_used == 0
since head ==
tail. We have buf_free == 0
since head is at the end of the buffer. _fflusbuf()
didn't do anything when bytes_used == 0
, hence the infinite loop.
When bytes_used == 0
_fflush()
needs to reset the head and tail pointers to the beginning of the buffer just like in the general case.
In this scenario, the while loop in fwrite() seems to be infinite because
buf_free
evaluates to zero:Because of this,
now
evaluates to zero too:The function is thus not making any forward progress:
_fflushbuf()
does not change the configuration either: