From 4cecfec664c9451137c592bb8d43ed0ea071b329 Mon Sep 17 00:00:00 2001 From: jhb Date: Tue, 8 Feb 2011 13:02:25 +0000 Subject: After reading a bitmap block for i-nodes or blocks, recheck the count of free i-nodes or blocks to handle a race where another thread might have allocated the last i-node or block while we were waiting for the buffer. Tested by: dougb --- sys/fs/ext2fs/ext2_alloc.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/sys/fs/ext2fs/ext2_alloc.c b/sys/fs/ext2fs/ext2_alloc.c index baab4a5..7abfe2b 100644 --- a/sys/fs/ext2fs/ext2_alloc.c +++ b/sys/fs/ext2fs/ext2_alloc.c @@ -650,6 +650,15 @@ ext2_alloccg(struct inode *ip, int cg, daddr_t bpref, int size) EXT2_LOCK(ump); return (0); } + if (fs->e2fs_gd[cg].ext2bgd_nbfree == 0) { + /* + * Another thread allocated the last block in this + * group while we were waiting for the buffer. + */ + brelse(bp); + EXT2_LOCK(ump); + return (0); + } bbp = (char *)bp->b_data; if (dtog(fs, bpref) != cg) @@ -776,6 +785,15 @@ ext2_nodealloccg(struct inode *ip, int cg, daddr_t ipref, int mode) EXT2_LOCK(ump); return (0); } + if (fs->e2fs_gd[cg].ext2bgd_nifree == 0) { + /* + * Another thread allocated the last i-node in this + * group while we were waiting for the buffer. + */ + brelse(bp); + EXT2_LOCK(ump); + return (0); + } ibp = (char *)bp->b_data; if (ipref) { ipref %= fs->e2fs->e2fs_ipg; -- cgit v1.1