Reduce probability for a deadlock that can occur when a snapshot inode is
updated by a process holding the snapshot lock. Another process updating a different inode in the same inodeblock will do copy on write checks and lock in the opposite direction. The snapshot code force a copy on write of these blocks manually (cf. start of expunge_ufs[12]) and these inode blocks are later put on snapblklist. This partial fix is to 'drain' the relevant ffs_copyonwrite() operation after installing new snapblklist. This is not a 100% solution since a failed block allocation can cause implicit fsync() which might deadlock before the new snapblklist has been installed.
This commit is contained in:
parent
1448da0d3a
commit
ddad01d50f
@ -681,6 +681,17 @@ ffs_snapshot(mp, snapfile)
|
||||
VI_UNLOCK(devvp);
|
||||
if (space != NULL)
|
||||
FREE(space, M_UFSMNT);
|
||||
/*
|
||||
* If another process is currently writing the buffer containing
|
||||
* the inode for this snapshot then a deadlock can occur. Drop
|
||||
* the snapshot lock until the buffer has been written.
|
||||
*/
|
||||
VOP_UNLOCK(vp, 0, td);
|
||||
(void) bread(ip->i_devvp,
|
||||
fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
|
||||
(int) fs->fs_bsize, NOCRED, &nbp);
|
||||
brelse(nbp);
|
||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
done:
|
||||
FREE(copy_fs->fs_csp, M_UFSMNT);
|
||||
bawrite(sbp);
|
||||
|
Loading…
Reference in New Issue
Block a user