Second Extended Filesystem (ext2) and other improvements (#33)
[lunaix-os.git] / lunaix-os / kernel / fs / ext2 / alloc.c
1 #include "ext2.h"
2
3 static inline unsigned int
4 __ext2_global_slot_alloc(struct v_superblock* vsb, int type_sel, 
5                          struct ext2_gdesc** gd_out)
6 {
7     struct ext2_sbinfo* sb;
8     struct ext2_gdesc *pos;
9     struct llist_header *header;
10     
11     sb = EXT2_SB(vsb);
12     header = &sb->free_list_sel[type_sel];
13     
14     if (type_sel == GDESC_INO_SEL) {
15         pos = list_entry(header->next, struct ext2_gdesc, free_grps_ino);
16     } 
17     else {
18         pos = list_entry(header->next, struct ext2_gdesc, free_grps_blk);
19     }
20
21     int alloc = ext2gd_alloc_slot(pos, type_sel);
22
23     if (valid_bmp_slot(alloc)) {
24         *gd_out = pos;
25     }
26
27     return alloc;
28 }
29
30 int
31 ext2ino_alloc_slot(struct v_superblock* vsb, struct ext2_gdesc** gd_out)
32 {
33     return __ext2_global_slot_alloc(vsb, GDESC_INO_SEL, gd_out);
34 }
35
36 int
37 ext2db_alloc_slot(struct v_superblock* vsb, struct ext2_gdesc** gd_out)
38 {
39     return __ext2_global_slot_alloc(vsb, GDESC_BLK_SEL, gd_out);
40 }
41
42 int
43 ext2gd_alloc_slot(struct ext2_gdesc* gd, int type_sel) 
44 {
45     struct ext2_bmp* bmp;
46     struct ext2_sbinfo *sb;
47     int alloc;
48     
49     sb = gd->sb;
50     bmp = &gd->bmps[type_sel];
51     alloc = ext2bmp_alloc_one(bmp);
52     
53     if (alloc < 0) {
54         return alloc;
55     }
56
57     if (!ext2bmp_check_free(bmp)) {
58         llist_delete(&gd->free_list_sel[type_sel]);
59     }
60
61     if (type_sel == GDESC_INO_SEL) {
62         gd->info->bg_free_ino_cnt--;
63         sb->raw->s_free_ino_cnt--;
64     } else {
65         gd->info->bg_free_blk_cnt--;
66         sb->raw->s_free_blk_cnt--;
67     }
68
69     fsblock_dirty(gd->buf);
70     fsblock_dirty(sb->buf);
71     return alloc;
72 }
73
74 void
75 ext2gd_free_slot(struct ext2_gdesc* gd, int type_sel, int slot)
76 {
77     struct llist_header *free_ent, *free_list;
78     struct ext2_sbinfo *sb;
79
80     ext2bmp_free_one(&gd->bmps[type_sel], slot);
81
82     sb = gd->sb;
83     free_ent  = &gd->free_list_sel[slot];
84     free_list = &gd->sb->free_list_sel[slot];
85     if (llist_empty(free_ent)) {
86         llist_append(free_list, free_ent);
87     }
88
89     if (type_sel == GDESC_INO_SEL) {
90         gd->info->bg_free_ino_cnt++;
91         sb->raw->s_free_ino_cnt++;
92     } else {
93         gd->info->bg_free_blk_cnt++;
94         sb->raw->s_free_blk_cnt++;
95     }
96
97     fsblock_dirty(gd->buf);
98     fsblock_dirty(sb->buf);
99 }