ext2: Add some necessary mutexes around block and inode allocation
This commit is contained in:
parent
b48326cd23
commit
d2fe9c19d7
@ -15,6 +15,7 @@
|
|||||||
#include <kernel/spinlock.h>
|
#include <kernel/spinlock.h>
|
||||||
#include <kernel/tokenize.h>
|
#include <kernel/tokenize.h>
|
||||||
#include <kernel/module.h>
|
#include <kernel/module.h>
|
||||||
|
#include <kernel/mutex.h>
|
||||||
|
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
@ -202,6 +203,8 @@ typedef struct {
|
|||||||
uint8_t * cache_data;
|
uint8_t * cache_data;
|
||||||
|
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
|
sched_mutex_t * mutex;
|
||||||
} ext2_fs_t;
|
} ext2_fs_t;
|
||||||
|
|
||||||
#define EXT2_FLAG_READWRITE 0x0002
|
#define EXT2_FLAG_READWRITE 0x0002
|
||||||
@ -502,6 +505,8 @@ static size_t allocate_block(ext2_fs_t * this) {
|
|||||||
size_t group = 0;
|
size_t group = 0;
|
||||||
uint8_t * bg_buffer = malloc(this->block_size);
|
uint8_t * bg_buffer = malloc(this->block_size);
|
||||||
|
|
||||||
|
mutex_acquire(this->mutex);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < BGDS; ++i) {
|
for (unsigned int i = 0; i < BGDS; ++i) {
|
||||||
if (BGD[i].free_blocks_count > 0) {
|
if (BGD[i].free_blocks_count > 0) {
|
||||||
read_block(this, BGD[i].block_bitmap, (uint8_t *)bg_buffer);
|
read_block(this, BGD[i].block_bitmap, (uint8_t *)bg_buffer);
|
||||||
@ -515,6 +520,7 @@ static size_t allocate_block(ext2_fs_t * this) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!block_no) {
|
if (!block_no) {
|
||||||
|
mutex_release(this->mutex);
|
||||||
debug_print(CRITICAL, "No available blocks, disk is out of space!");
|
debug_print(CRITICAL, "No available blocks, disk is out of space!");
|
||||||
free(bg_buffer);
|
free(bg_buffer);
|
||||||
return 0;
|
return 0;
|
||||||
@ -536,6 +542,8 @@ static size_t allocate_block(ext2_fs_t * this) {
|
|||||||
memset(bg_buffer, 0x00, this->block_size);
|
memset(bg_buffer, 0x00, this->block_size);
|
||||||
write_block(this, block_no, bg_buffer);
|
write_block(this, block_no, bg_buffer);
|
||||||
|
|
||||||
|
mutex_release(this->mutex);
|
||||||
|
|
||||||
free(bg_buffer);
|
free(bg_buffer);
|
||||||
|
|
||||||
return block_no;
|
return block_no;
|
||||||
@ -603,6 +611,7 @@ static unsigned int inode_write_block(ext2_fs_t * this, ext2_inodetable_t * inod
|
|||||||
|
|
||||||
debug_print(WARNING, "clearing and allocating up to required blocks (block=%d, %d)", block, inode->blocks);
|
debug_print(WARNING, "clearing and allocating up to required blocks (block=%d, %d)", block, inode->blocks);
|
||||||
char * empty = NULL;
|
char * empty = NULL;
|
||||||
|
|
||||||
while (block >= inode->blocks / (this->block_size / 512)) {
|
while (block >= inode->blocks / (this->block_size / 512)) {
|
||||||
allocate_inode_block(this, inode, inode_no, inode->blocks / (this->block_size / 512));
|
allocate_inode_block(this, inode, inode_no, inode->blocks / (this->block_size / 512));
|
||||||
refresh_inode(this, inode, inode_no);
|
refresh_inode(this, inode, inode_no);
|
||||||
@ -751,6 +760,8 @@ static unsigned int allocate_inode(ext2_fs_t * this) {
|
|||||||
uint32_t group = 0;
|
uint32_t group = 0;
|
||||||
uint8_t * bg_buffer = malloc(this->block_size);
|
uint8_t * bg_buffer = malloc(this->block_size);
|
||||||
|
|
||||||
|
mutex_acquire(this->mutex);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < BGDS; ++i) {
|
for (unsigned int i = 0; i < BGDS; ++i) {
|
||||||
if (BGD[i].free_inodes_count > 0) {
|
if (BGD[i].free_inodes_count > 0) {
|
||||||
debug_print(NOTICE, "Group %d has %d free inodes.", i, BGD[i].free_inodes_count);
|
debug_print(NOTICE, "Group %d has %d free inodes.", i, BGD[i].free_inodes_count);
|
||||||
@ -764,6 +775,7 @@ static unsigned int allocate_inode(ext2_fs_t * this) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!node_no) {
|
if (!node_no) {
|
||||||
|
mutex_release(this->mutex);
|
||||||
debug_print(ERROR, "Ran out of inodes!");
|
debug_print(ERROR, "Ran out of inodes!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -781,6 +793,8 @@ static unsigned int allocate_inode(ext2_fs_t * this) {
|
|||||||
SB->free_inodes_count--;
|
SB->free_inodes_count--;
|
||||||
rewrite_superblock(this);
|
rewrite_superblock(this);
|
||||||
|
|
||||||
|
mutex_release(this->mutex);
|
||||||
|
|
||||||
return node_no;
|
return node_no;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1097,17 +1111,32 @@ static int unlink_ext2(fs_node_t * node, char * name) {
|
|||||||
dir_offset += d_ent->rec_len;
|
dir_offset += d_ent->rec_len;
|
||||||
total_offset += d_ent->rec_len;
|
total_offset += d_ent->rec_len;
|
||||||
}
|
}
|
||||||
free(inode);
|
|
||||||
if (!direntry) {
|
if (!direntry) {
|
||||||
|
free(inode);
|
||||||
free(block);
|
free(block);
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int new_inode = direntry->inode;
|
||||||
direntry->inode = 0;
|
direntry->inode = 0;
|
||||||
|
|
||||||
inode_write_block(this, inode, node->inode, block_nr, block);
|
inode_write_block(this, inode, node->inode, block_nr, block);
|
||||||
|
free(inode);
|
||||||
free(block);
|
free(block);
|
||||||
|
|
||||||
|
inode = read_inode(this, new_inode);
|
||||||
|
|
||||||
|
if (inode->links_count == 1) {
|
||||||
|
dprintf("ext2: TODO: unlinking '%s' (inode=%u) which now has no links; should delete\n",
|
||||||
|
name, new_inode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inode->links_count > 0) {
|
||||||
|
inode->links_count--;
|
||||||
|
write_inode(this, inode, new_inode);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(inode);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1539,6 +1568,8 @@ static fs_node_t * mount_ext2(fs_node_t * block_device, int flags) {
|
|||||||
/* We need to keep an owned refcount to this device if it was something we opened... */
|
/* We need to keep an owned refcount to this device if it was something we opened... */
|
||||||
//vfs_lock(this->block_device);
|
//vfs_lock(this->block_device);
|
||||||
|
|
||||||
|
this->mutex = mutex_init("ext2 fs");
|
||||||
|
|
||||||
SB = malloc(this->block_size);
|
SB = malloc(this->block_size);
|
||||||
|
|
||||||
debug_print(INFO, "Reading superblock...");
|
debug_print(INFO, "Reading superblock...");
|
||||||
|
Loading…
Reference in New Issue
Block a user