__ext2_global_slot_alloc(struct v_superblock* vsb, int type_sel,
struct ext2_gdesc** gd_out)
{
+ int alloc;
struct ext2_sbinfo* sb;
struct ext2_gdesc *pos;
struct llist_header *header;
+ alloc = ALLOC_FAIL;
sb = EXT2_SB(vsb);
+
+ ext2sb_lock(sb);
header = &sb->free_list_sel[type_sel];
+
+ // we have used up all avaliable inodes/blocks
+ if (llist_empty(header))
+ goto done;
if (type_sel == GDESC_INO_SEL) {
pos = list_entry(header->next, struct ext2_gdesc, free_grps_ino);
pos = list_entry(header->next, struct ext2_gdesc, free_grps_blk);
}
- int alloc = ext2gd_alloc_slot(pos, type_sel);
+ alloc = ext2gd_alloc_slot(pos, type_sel);
if (valid_bmp_slot(alloc)) {
*gd_out = pos;
}
+done:
+ ext2sb_unlock(sb);
return alloc;
}
struct ext2_bmp* bmp;
struct ext2_sbinfo *sb;
int alloc;
+
+ ext2gd_lock(gd);
sb = gd->sb;
bmp = &gd->bmps[type_sel];
- alloc = ext2bmp_alloc_one(bmp);
+ alloc = ext2bmp_alloc_nolock(bmp);
if (alloc < 0) {
- return alloc;
+ goto done;
}
if (!ext2bmp_check_free(bmp)) {
sb->raw->s_free_blk_cnt--;
}
- fsblock_dirty(gd->buf);
- fsblock_dirty(sb->buf);
+ ext2gd_schedule_sync(gd);
+ ext2sb_schedule_sync(sb);
+
+done:
+ ext2gd_unlock(gd);
return alloc;
}
struct llist_header *free_ent, *free_list;
struct ext2_sbinfo *sb;
- ext2bmp_free_one(&gd->bmps[type_sel], slot);
+ ext2gd_lock(gd);
+
+ ext2bmp_free_nolock(&gd->bmps[type_sel], slot);
sb = gd->sb;
free_ent = &gd->free_list_sel[slot];
llist_append(free_list, free_ent);
}
+ // FIXME might need arch-depedent impl for atomic operations
if (type_sel == GDESC_INO_SEL) {
gd->info->bg_free_ino_cnt++;
sb->raw->s_free_ino_cnt++;
sb->raw->s_free_blk_cnt++;
}
- fsblock_dirty(gd->buf);
- fsblock_dirty(sb->buf);
+ ext2gd_schedule_sync(gd);
+ ext2sb_schedule_sync(sb);
+
+ ext2gd_unlock(gd);
}
\ No newline at end of file