Fix mkfs buddy initialization

mkfs was starting setting free blk bits from 0 instead of from
the blkno offset of the first free block.  This resulted in
the highest order above a used blkno being marked free.  Freeing
that blkno would set its lowest order blkno.  Now that blkno can be
allocated from two orders.  That, eventually, can lead to blocks
being doubly allocated and users trampling on each other.

While auditing the code to chase this bug down I also noticed that
write_buddy_blocks() was using a min() that makes no sense at all.  Here
'blk' is inclusive, the modulo math works on its own.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2016-11-17 15:43:23 -08:00
parent 932b0776d1
commit c3f122a5f1
+4 -3
View File
@@ -232,8 +232,7 @@ static int write_buddy_blocks(int fd, struct scoutfs_super_block *super,
last = SCOUTFS_BUDDY_ORDER0_BITS - 1;
} else {
first = 0;
last = min(blk % SCOUTFS_BUDDY_ORDER0_BITS,
SCOUTFS_BUDDY_ORDER0_BITS);
last = blk % SCOUTFS_BUDDY_ORDER0_BITS;
}
/* write the leaf block */
@@ -396,7 +395,9 @@ static int write_new_fs(char *path, int fd)
super->free_blocks = cpu_to_le64(total_blocks - blkno);
/* write left-most buddy block and all full parents, not root */
ret = write_buddy_blocks(fd, super, &binf, buf, 0, 1, &free_orders);
ret = write_buddy_blocks(fd, super, &binf, buf,
blkno - first_blkno(super),
1, &free_orders);
if (ret)
goto out;