aboutsummaryrefslogtreecommitdiff
path: root/sys/fs/ext2fs
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2011-02-08 13:02:25 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2011-02-08 13:02:25 +0000
commit73dd6d1f8fddfdd8949e89dfa698ce7287bc54df (patch)
treea5cb521f45c81cd75b73fe46dfe8c049efc8f47d /sys/fs/ext2fs
parente0e5b8b471f914d7045b5a700c488c7268928cf1 (diff)
downloadsrc-73dd6d1f8fddfdd8949e89dfa698ce7287bc54df.tar.gz
src-73dd6d1f8fddfdd8949e89dfa698ce7287bc54df.zip
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
Notes
Notes: svn path=/head/; revision=218438
Diffstat (limited to 'sys/fs/ext2fs')
-rw-r--r--sys/fs/ext2fs/ext2_alloc.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/sys/fs/ext2fs/ext2_alloc.c b/sys/fs/ext2fs/ext2_alloc.c
index baab4a5677d1..7abfe2b2bf09 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;