From: Lunaixsky Date: Sat, 3 May 2025 18:10:01 +0000 (+0100) Subject: add locks to the shared objects of ext2 fs X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/commitdiff_plain/130d1cf10ae76844c1dfe5002c741b82a53244a5?ds=sidebyside add locks to the shared objects of ext2 fs --- diff --git a/lunaix-os/kernel/fs/ext2/alloc.c b/lunaix-os/kernel/fs/ext2/alloc.c index 2996141..62dfb6b 100644 --- a/lunaix-os/kernel/fs/ext2/alloc.c +++ b/lunaix-os/kernel/fs/ext2/alloc.c @@ -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 diff --git a/lunaix-os/kernel/fs/ext2/dir.c b/lunaix-os/kernel/fs/ext2/dir.c index e09a17b..9058c8a 100644 --- a/lunaix-os/kernel/fs/ext2/dir.c +++ b/lunaix-os/kernel/fs/ext2/dir.c @@ -57,10 +57,11 @@ done: _ret: fsblock_put(prev_buf); ext2dr_itend(&iter); + return itstate_sel(&iter, errno); } -static size_t +static inline size_t __dirent_realsize(struct ext2b_dirent* dirent) { return sizeof(*dirent) - sizeof(dirent->name) + dirent->name_len; diff --git a/lunaix-os/kernel/fs/ext2/ext2.h b/lunaix-os/kernel/fs/ext2/ext2.h index 93996cd..8a6e852 100644 --- a/lunaix-os/kernel/fs/ext2/ext2.h +++ b/lunaix-os/kernel/fs/ext2/ext2.h @@ -6,6 +6,7 @@ #include #include #include +#include #ifdef CONFIG_EXT2_DEBUG_MSG # include @@ -209,6 +210,8 @@ struct ext2_sbinfo struct llist_header gds; GDESC_FREE_LISTS; }; + + mutex_t lock; }; #define EXT2_SB(vsb) (fsapi_impl_data(vsb, struct ext2_sbinfo)) @@ -241,6 +244,8 @@ struct ext2_gdesc struct ext2_sbinfo* sb; bbuf_t buf; bcobj_t cache_ref; + + mutex_t lock; }; /* @@ -298,6 +303,8 @@ struct ext2_inode // prefetched block for 1st order of indirection bbuf_t ind_ord1; char* symlink; + + // No lock required, it shares lock context with v_inode. }; #define EXT2_INO(v_inode) (fsapi_impl_data(v_inode, struct ext2_inode)) @@ -311,6 +318,8 @@ struct ext2_dnode { struct ext2_dnode_sub self; struct ext2_dnode_sub prev; + + // No lock required, it shares lock context with v_dnode. }; #define EXT2_DNO(v_dnode) (fsapi_impl_data(v_dnode, struct ext2_dnode)) @@ -344,7 +353,6 @@ struct ext2_iterator struct ext2_file { struct ext2_iterator iter; - struct ext2_inode* b_ino; }; #define EXT2_FILE(v_file) (fsapi_impl_data(v_file, struct ext2_file)) @@ -379,6 +387,27 @@ ext2_feature(struct v_superblock* vsb, unsigned int feat) return !!(EXT2_SB(vsb)->all_feature & feat); } +/* ************ Superblock ************ */ + +static inline void +ext2sb_schedule_sync(struct ext2_sbinfo* sb) +{ + fsblock_dirty(sb->buf); +} + +static inline void must_inline +ext2sb_lock(struct ext2_sbinfo* sb) +{ + mutex_lock(&sb->lock); +} + +static inline void must_inline +ext2sb_unlock(struct ext2_sbinfo* sb) +{ + mutex_unlock(&sb->lock); +} + + /* ************ Inodes ************ */ void @@ -413,6 +442,15 @@ ext2ino_linkto(struct ext2_inode* e_ino, struct ext2b_dirent* dirent) fsblock_dirty(e_ino->buf); } +static inline void +ext2ino_schedule_sync(struct ext2_inode* ino) +{ + fsblock_dirty(ino->buf); +} + + +/* ************* Data blocks ************* */ + #define DBIT_MODE_ISIZE 0 #define DBIT_MODE_BLOCK 1 @@ -497,14 +535,33 @@ void ext2gd_release_gdt(struct v_superblock* vsb); int -ext2gd_take(struct v_superblock* vsb, +ext2gd_take_at(struct v_superblock* vsb, unsigned int index, struct ext2_gdesc** out); +static inline struct ext2_gdesc* +ext2gd_take(struct ext2_gdesc* gd) { + bcache_refonce(gd->cache_ref); + + return gd; +} + static inline void ext2gd_put(struct ext2_gdesc* gd) { bcache_return(gd->cache_ref); } +static inline void must_inline +ext2gd_lock(struct ext2_gdesc* gd) +{ + mutex_lock(&gd->lock); +} + +static inline void must_inline +ext2gd_unlock(struct ext2_gdesc* gd) +{ + mutex_unlock(&gd->lock); +} + /* ************ Directory ************ */ @@ -610,23 +667,6 @@ ext2_get_symlink(struct v_inode *this, const char **path_out); int ext2_set_symlink(struct v_inode *this, const char *target); -/* *********** Bitmap *********** */ - -void -ext2bmp_init(struct ext2_bmp* e_bmp, bbuf_t bmp_buf, unsigned int nr_bits); - -bool -ext2bmp_check_free(struct ext2_bmp* e_bmp); - -int -ext2bmp_alloc_one(struct ext2_bmp* e_bmp); - -void -ext2bmp_free_one(struct ext2_bmp* e_bmp, unsigned int pos); - -void -ext2bmp_discard(struct ext2_bmp* e_bmp); - /* *********** Allocations *********** */ #define ALLOC_FAIL -1 @@ -667,6 +707,13 @@ ext2gd_free_block(struct ext2_gdesc* gd, int slot) ext2gd_free_slot(gd, GDESC_BLK_SEL, slot); } +static inline void +ext2gd_schedule_sync(struct ext2_gdesc* gd) +{ + fsblock_dirty(gd->buf); + fsblock_dirty(gd->ino_bmp.raw); + fsblock_dirty(gd->blk_bmp.raw); +} /** * @brief Allocate a free inode @@ -716,4 +763,26 @@ int ext2db_alloc_slot(struct v_superblock* vsb, struct ext2_gdesc** gd_out); +/* *********** Bitmap *********** */ + +void +ext2bmp_init(struct ext2_bmp* e_bmp, bbuf_t bmp_buf, unsigned int nr_bits); + +int +ext2bmp_alloc_nolock(struct ext2_bmp* e_bmp); + +void +ext2bmp_free_nolock(struct ext2_bmp* e_bmp, unsigned int pos); + +void +ext2bmp_discard_nolock(struct ext2_bmp* e_bmp); + +static inline bool +ext2bmp_check_free(struct ext2_bmp* e_bmp) +{ + assert(e_bmp->raw); + + return valid_bmp_slot(e_bmp->next_free); +} + #endif /* __LUNAIX_EXT2_H */ diff --git a/lunaix-os/kernel/fs/ext2/file.c b/lunaix-os/kernel/fs/ext2/file.c index d94371d..bd14785 100644 --- a/lunaix-os/kernel/fs/ext2/file.c +++ b/lunaix-os/kernel/fs/ext2/file.c @@ -12,7 +12,6 @@ ext2_open_inode(struct v_inode* inode, struct v_file* file) struct ext2_file* e_file; e_file = valloc(sizeof(*e_file)); - e_file->b_ino = EXT2_INO(inode); file->data = e_file; diff --git a/lunaix-os/kernel/fs/ext2/group.c b/lunaix-os/kernel/fs/ext2/group.c index 277d690..d11e510 100644 --- a/lunaix-os/kernel/fs/ext2/group.c +++ b/lunaix-os/kernel/fs/ext2/group.c @@ -126,7 +126,7 @@ __try_load_bitmap(struct v_superblock* vsb, } int -ext2gd_take(struct v_superblock* vsb, +ext2gd_take_at(struct v_superblock* vsb, unsigned int index, struct ext2_gdesc** out) { bbuf_t part, buf; @@ -169,6 +169,8 @@ ext2gd_take(struct v_superblock* vsb, .ino_base = index * ext2sb->raw->s_ino_per_grp }; + mutex_init(&gd->lock); + *out = gd; if (!ext2sb->read_only) { @@ -235,16 +237,8 @@ ext2bmp_init(struct ext2_bmp* e_bmp, bbuf_t bmp_buf, unsigned int nr_bits) __ext2bmp_update_next_free_cell(e_bmp); } -bool -ext2bmp_check_free(struct ext2_bmp* e_bmp) -{ - assert(e_bmp->raw); - - return valid_bmp_slot(e_bmp->next_free); -} - int -ext2bmp_alloc_one(struct ext2_bmp* e_bmp) +ext2bmp_alloc_nolock(struct ext2_bmp* e_bmp) { assert(e_bmp->raw); @@ -275,7 +269,7 @@ ext2bmp_alloc_one(struct ext2_bmp* e_bmp) } void -ext2bmp_free_one(struct ext2_bmp* e_bmp, unsigned int pos) +ext2bmp_free_nolock(struct ext2_bmp* e_bmp, unsigned int pos) { assert(e_bmp->raw); @@ -291,7 +285,7 @@ ext2bmp_free_one(struct ext2_bmp* e_bmp, unsigned int pos) } void -ext2bmp_discard(struct ext2_bmp* e_bmp) +ext2bmp_discard_nolock(struct ext2_bmp* e_bmp) { assert(e_bmp->raw); diff --git a/lunaix-os/kernel/fs/ext2/inode.c b/lunaix-os/kernel/fs/ext2/inode.c index b784b38..0956b1e 100644 --- a/lunaix-os/kernel/fs/ext2/inode.c +++ b/lunaix-os/kernel/fs/ext2/inode.c @@ -391,7 +391,7 @@ __get_group_desc(struct v_superblock* vsb, int ino, sb = EXT2_SB(vsb); blkgrp_id = to_fsblock_id(ino) / sb->raw->s_ino_per_grp; - return ext2gd_take(vsb, blkgrp_id, gd_out); + return ext2gd_take_at(vsb, blkgrp_id, gd_out); } static struct ext2b_inode* @@ -443,7 +443,7 @@ __create_inode(struct v_superblock* vsb, struct ext2_gdesc* gd, int ino_index) inode->btlb = vzalloc(sizeof(struct ext2_btlb)); inode->buf = ino_tab; inode->ino = b_inode; - inode->blk_grp = gd; + inode->blk_grp = ext2gd_take(gd); inode->isize = b_inode->i_size; if (ext2_feature(vsb, FEAT_LARGE_FILE)) { @@ -592,7 +592,7 @@ __free_block_at(struct v_superblock *vsb, unsigned int block_pos) sb = EXT2_SB(vsb); gd_index = block_pos / sb->raw->s_blk_per_grp; - if ((errno = ext2gd_take(vsb, gd_index, &gd))) { + if ((errno = ext2gd_take_at(vsb, gd_index, &gd))) { return errno; } diff --git a/lunaix-os/kernel/fs/ext2/mount.c b/lunaix-os/kernel/fs/ext2/mount.c index 05fbdce..0d328e7 100644 --- a/lunaix-os/kernel/fs/ext2/mount.c +++ b/lunaix-os/kernel/fs/ext2/mount.c @@ -170,6 +170,8 @@ ext2_mount(struct v_superblock* vsb, struct v_dnode* mnt) ext2sb->raw = rawsb; ext2sb->all_feature = __translate_feature(rawsb); + mutex_init(&ext2sb->lock); + fsapi_set_vsb_ops(vsb, &vsb_ops); fsapi_complete_vsb_setup(vsb, ext2sb); @@ -188,6 +190,9 @@ ext2_mount(struct v_superblock* vsb, struct v_dnode* mnt) ext2sb->raw = offset(blkbuf_data(buf), EXT2_BASE_BLKSZ); } + ext2sb->raw->s_mnt_cnt++; + ext2sb->raw->s_mtime = clock_unixtime(); + ext2sb->buf = buf; vfree(rawsb); return 0;