Deadlock between nfsd and snapshots.
Tor Egge
Tor.Egge at cvsup.no.freebsd.org
Wed Aug 23 20:06:56 UTC 2006
> I found some cases where i_flag, timestamps and probably other parts of the
> vnode seem to be accessed without any proper locks (maybe a refcount) :-(.
> See another (private) reply and below.
>
> I don't understand how the vnode interlock can help much for interoperation
> with code which uses vnode locks. Aren't these locks almost independent of
> each other, so if the vnode lock is already held then acquiring the vnode
> interlock wouldn't block? So to protect iflag with the interlock you
> would have to add the interlock to mounds of code that just uses the vnode
> lock now.
the vnode interlock is used to resolve between those holding a shared lock.
There are 4 locking protocols for the protection of i_flags and the
timestamps:
1. Previous locking protocol: Giant
2. Current locking protocol: vnode lock. This breaks down when processes
with a shared vnode lock perform changes (e.g. sets flags or timestamps).
3. Proposed locking protocol: exclusive vnode lock or shared
vnode lock plus the vnode interlock.
4. Alternate locking protocol: vnode interlock. Further code changes
might be needed for this to work properly, e.g. IN_MODIFIED might
have to be set before making changes to the inode instead of
aftewards.
> I understand this locking :-). ffs_sync() actually uses only uses the vnode
> interlock to access i_flag. I think this is intentionally quick and not
> quite right -- there is a comment a few lines before it saying that we depend
> on a mntvnode lock to keep things stable enough for a quick test. The scope
> of the comment is unclear. I think the quick test is only good enough for
> sync(2).
The correct unoptimized version of ffs_sync() would have the vnode lock before
checking i_flag.
When this loop executes as part of suspending the file system, MNTK_SUSPEND is
set. No code is executing within regions protected by vn_start_write() and new
calls to vn_start_write() will fail or block. Calls to
vn_start_secondary_write() might succeed but will then trigger a retry of the
whole vnode sync loop.
While not having the vnode lock when checking i_flag in ffs_sync() opens a
race, the conseqeuences are limited due to other locking and the restart.
- Tor Egge
More information about the freebsd-fs
mailing list