add locks to the shared objects of ext2 fs
[lunaix-os.git] / lunaix-os / kernel / fs / ext2 / alloc.c
index 29961410ff24b4d55030906ecc0ef5266be818a9..62dfb6b92bb657103fb5ca124f670df75c9cab5d 100644 (file)
@@ -4,12 +4,20 @@ static inline unsigned int
 __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);
@@ -18,12 +26,14 @@ __ext2_global_slot_alloc(struct v_superblock* vsb, int type_sel,
         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;
 }
 
@@ -45,13 +55,15 @@ ext2gd_alloc_slot(struct ext2_gdesc* gd, int type_sel)
     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)) {
@@ -66,8 +78,11 @@ ext2gd_alloc_slot(struct ext2_gdesc* gd, int type_sel)
         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;
 }
 
@@ -77,7 +92,9 @@ ext2gd_free_slot(struct ext2_gdesc* gd, int type_sel, int slot)
     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];
@@ -86,6 +103,7 @@ ext2gd_free_slot(struct ext2_gdesc* gd, int type_sel, int 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++;
@@ -94,6 +112,8 @@ ext2gd_free_slot(struct ext2_gdesc* gd, int type_sel, int slot)
         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