ext4: make sure group number is bumped after a inode allocation race
When we try to allocate an inode, and there is a race between two CPU's trying to grab the same inode, _and_ this inode is the last free inode in the block group, make sure the group number is bumped before we continue searching the rest of the block groups. Otherwise, we end up searching the current block group twice, and we end up skipping searching the last block group. So in the unlikely situation where almost all of the inodes are allocated, it's possible that we will return ENOSPC even though there might be free inodes in that last block group. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Cc: stable@vger.kernel.org
This commit is contained in:
parent
3b2f64d00c
commit
a34eb50374
|
@ -734,11 +734,8 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
|
|||
ino = ext4_find_next_zero_bit((unsigned long *)
|
||||
inode_bitmap_bh->b_data,
|
||||
EXT4_INODES_PER_GROUP(sb), ino);
|
||||
if (ino >= EXT4_INODES_PER_GROUP(sb)) {
|
||||
if (++group == ngroups)
|
||||
group = 0;
|
||||
continue;
|
||||
}
|
||||
if (ino >= EXT4_INODES_PER_GROUP(sb))
|
||||
goto next_group;
|
||||
if (group == 0 && (ino+1) < EXT4_FIRST_INO(sb)) {
|
||||
ext4_error(sb, "reserved inode found cleared - "
|
||||
"inode=%lu", ino + 1);
|
||||
|
@ -769,6 +766,9 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
|
|||
goto got; /* we grabbed the inode! */
|
||||
if (ino < EXT4_INODES_PER_GROUP(sb))
|
||||
goto repeat_in_this_group;
|
||||
next_group:
|
||||
if (++group == ngroups)
|
||||
group = 0;
|
||||
}
|
||||
err = -ENOSPC;
|
||||
goto out;
|
||||
|
|
Loading…
Reference in New Issue