3 static inline unsigned int
4 __ext2_global_slot_alloc(struct v_superblock* vsb, int type_sel,
5 struct ext2_gdesc** gd_out)
8 struct ext2_sbinfo* sb;
9 struct ext2_gdesc *pos;
10 struct llist_header *header;
16 header = &sb->free_list_sel[type_sel];
18 // we have used up all avaliable inodes/blocks
19 if (llist_empty(header))
22 if (type_sel == GDESC_INO_SEL) {
23 pos = list_entry(header->next, struct ext2_gdesc, free_grps_ino);
26 pos = list_entry(header->next, struct ext2_gdesc, free_grps_blk);
29 alloc = ext2gd_alloc_slot(pos, type_sel);
31 if (valid_bmp_slot(alloc)) {
41 ext2ino_alloc_slot(struct v_superblock* vsb, struct ext2_gdesc** gd_out)
43 return __ext2_global_slot_alloc(vsb, GDESC_INO_SEL, gd_out);
47 ext2db_alloc_slot(struct v_superblock* vsb, struct ext2_gdesc** gd_out)
49 return __ext2_global_slot_alloc(vsb, GDESC_BLK_SEL, gd_out);
53 ext2gd_alloc_slot(struct ext2_gdesc* gd, int type_sel)
56 struct ext2_sbinfo *sb;
62 bmp = &gd->bmps[type_sel];
63 alloc = ext2bmp_alloc_nolock(bmp);
69 if (!ext2bmp_check_free(bmp)) {
70 llist_delete(&gd->free_list_sel[type_sel]);
73 if (type_sel == GDESC_INO_SEL) {
74 gd->info->bg_free_ino_cnt--;
75 sb->raw->s_free_ino_cnt--;
77 gd->info->bg_free_blk_cnt--;
78 sb->raw->s_free_blk_cnt--;
81 ext2gd_schedule_sync(gd);
82 ext2sb_schedule_sync(sb);
90 ext2gd_free_slot(struct ext2_gdesc* gd, int type_sel, int slot)
92 struct llist_header *free_ent, *free_list;
93 struct ext2_sbinfo *sb;
97 ext2bmp_free_nolock(&gd->bmps[type_sel], slot);
100 free_ent = &gd->free_list_sel[slot];
101 free_list = &gd->sb->free_list_sel[slot];
102 if (llist_empty(free_ent)) {
103 llist_append(free_list, free_ent);
106 // FIXME might need arch-depedent impl for atomic operations
107 if (type_sel == GDESC_INO_SEL) {
108 gd->info->bg_free_ino_cnt++;
109 sb->raw->s_free_ino_cnt++;
111 gd->info->bg_free_blk_cnt++;
112 sb->raw->s_free_blk_cnt++;
115 ext2gd_schedule_sync(gd);
116 ext2sb_schedule_sync(sb);