diff options
author | kib <kib@FreeBSD.org> | 2007-06-22 13:22:37 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2007-06-22 13:22:37 +0000 |
commit | 2f486f25b672cff71428e86c7369dbc7ed9d21a5 (patch) | |
tree | 9b4d2ba0b5040919a7c5e7db8282c7ce8cd9012c /sys | |
parent | 35e07e1a73d48b9ab13a630c8e5447aeb4e222f5 (diff) | |
download | FreeBSD-src-2f486f25b672cff71428e86c7369dbc7ed9d21a5.zip FreeBSD-src-2f486f25b672cff71428e86c7369dbc7ed9d21a5.tar.gz |
Fix livelock that could occur when snapshoting UFS with quotas, where
some quota limit was exceeded. Sequence of UFS_VALLOC()/UFS_VFREE()
call there could cause inodeblock to have both freefile and inodedep
dependencies without any inode in the block being marked for write.
Then, softdep_check_suspend() would return EAGAIN forewer.
Force write of inodeblock with allocated freefile softdependency by
setting IN_MODIFIED flag in softdep_freefile and unconditionally calling
UFS_UPDATE() in ufs_reclaim.
Reported by: kris
Debug help and tested by: Peter Holm
Approved by: re (kensmith)
MFC after: 3 weeks
Diffstat (limited to 'sys')
-rw-r--r-- | sys/ufs/ffs/ffs_softdep.c | 1 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_inode.c | 5 |
2 files changed, 3 insertions, 3 deletions
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index 058d693..94368fd 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -2603,6 +2603,7 @@ softdep_freefile(pvp, ino, mode) } WORKLIST_INSERT(&inodedep->id_inowait, &freefile->fx_list); FREE_LOCK(&lk); + ip->i_flag |= IN_MODIFIED; } /* diff --git a/sys/ufs/ufs/ufs_inode.c b/sys/ufs/ufs/ufs_inode.c index 86b1608..57ede1e 100644 --- a/sys/ufs/ufs/ufs_inode.c +++ b/sys/ufs/ufs/ufs_inode.c @@ -194,10 +194,9 @@ ufs_reclaim(ap) * Destroy the vm object and flush associated pages. */ vnode_destroy_vobject(vp); - if (ip->i_flag & IN_LAZYMOD) { + if (ip->i_flag & IN_LAZYMOD) ip->i_flag |= IN_MODIFIED; - UFS_UPDATE(vp, 0); - } + UFS_UPDATE(vp, 0); /* * Remove the inode from its hash chain. */ |