diff options
author | kib <kib@FreeBSD.org> | 2008-08-28 09:19:50 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2008-08-28 09:19:50 +0000 |
commit | 8ccd4bd3a18f0d73c17c7096b561febf5d6f93d8 (patch) | |
tree | db8640622e3c52b26ebefb4423a8434f37ff751c /sys/ufs/ffs | |
parent | 2a5baa49d2b2d537072a458d7e86c120a59acc67 (diff) | |
download | FreeBSD-src-8ccd4bd3a18f0d73c17c7096b561febf5d6f93d8.zip FreeBSD-src-8ccd4bd3a18f0d73c17c7096b561febf5d6f93d8.tar.gz |
In ffs_valloc(), ffs_vget() may fail because insmntque() refused to
insert new vnode into the mount vnode list. Then, for the SU-enabled
mount, ffs_vfree could create freefile dependency. This dependency can
hang around forever since inode is not marked as IN_MODIFIED and
correspondingly inodeblock may be not marked as dirty.
After ffs_vget() fails, retry with FFSV_FORCEINSMQ, mark the inode as
modified, and vput() it immediately. Take care of the dup alloc.
Tested by: pho
Reviewed by: tegge
MFC after: 1 month
Diffstat (limited to 'sys/ufs/ffs')
-rw-r--r-- | sys/ufs/ffs/ffs_alloc.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c index 2c9fdd6..a72137e 100644 --- a/sys/ufs/ffs/ffs_alloc.c +++ b/sys/ufs/ffs/ffs_alloc.c @@ -921,7 +921,7 @@ ffs_valloc(pvp, mode, cred, vpp) struct timespec ts; struct ufsmount *ump; ino_t ino, ipref; - int cg, error; + int cg, error, error1; static struct timeval lastfail; static int curfail; @@ -958,11 +958,21 @@ ffs_valloc(pvp, mode, cred, vpp) goto noinodes; error = ffs_vget(pvp->v_mount, ino, LK_EXCLUSIVE, vpp); if (error) { + error1 = ffs_vgetf(pvp->v_mount, ino, LK_EXCLUSIVE, vpp, + FFSV_FORCEINSMQ); ffs_vfree(pvp, ino, mode); + if (error1 == 0) { + ip = VTOI(*vpp); + if (ip->i_mode) + goto dup_alloc; + ip->i_flag |= IN_MODIFIED; + vput(*vpp); + } return (error); } ip = VTOI(*vpp); if (ip->i_mode) { +dup_alloc: printf("mode = 0%o, inum = %lu, fs = %s\n", ip->i_mode, (u_long)ip->i_number, fs->fs_fsmnt); panic("ffs_valloc: dup alloc"); |