mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Refactor extfs dirty pattern to BeginWrite then FinishWrite pattern.
This commit is contained in:
parent
34a832dbf3
commit
de21e9c8e2
11 changed files with 142 additions and 74 deletions
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************
|
||||
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2013.
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2013, 2014, 2015.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
|
@ -82,7 +82,11 @@ void Block::Sync()
|
|||
pwriteall(device->fd, block_data, device->block_size, file_offset);
|
||||
}
|
||||
|
||||
void Block::Dirty()
|
||||
void Block::BeginWrite()
|
||||
{
|
||||
}
|
||||
|
||||
void Block::FinishWrite()
|
||||
{
|
||||
if ( !dirty )
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************
|
||||
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2013.
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2013, 2014, 2015.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
|
@ -48,7 +48,8 @@ public:
|
|||
void Refer();
|
||||
void Unref();
|
||||
void Sync();
|
||||
void Dirty();
|
||||
void BeginWrite();
|
||||
void FinishWrite();
|
||||
void Use();
|
||||
void Unlink();
|
||||
void Prelink();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************
|
||||
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2013.
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2013, 2014, 2015.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
|
@ -96,22 +96,25 @@ uint32_t BlockGroup::AllocateBlock()
|
|||
for ( ; block_bitmap_chunk_i < num_bits; block_bitmap_chunk_i++ )
|
||||
if ( !checkbit(chunk_bits, block_bitmap_chunk_i) )
|
||||
{
|
||||
block_bitmap_chunk->BeginWrite();
|
||||
setbit(chunk_bits, block_bitmap_chunk_i);
|
||||
block_bitmap_chunk->Dirty();
|
||||
block_bitmap_chunk->FinishWrite();
|
||||
BeginWrite();
|
||||
data->bg_free_blocks_count--;
|
||||
Dirty();
|
||||
FinishWrite();
|
||||
filesystem->BeginWrite();
|
||||
filesystem->sb->s_free_blocks_count--;
|
||||
filesystem->Dirty();
|
||||
filesystem->FinishWrite();
|
||||
uint32_t group_block_id = chunk_offset + block_bitmap_chunk_i++;
|
||||
uint32_t block_id = first_block_id + group_block_id;
|
||||
return block_id;
|
||||
}
|
||||
block_bitmap_chunk->Sync();
|
||||
block_bitmap_chunk->Unref();
|
||||
block_bitmap_chunk = NULL;
|
||||
}
|
||||
BeginWrite();
|
||||
data->bg_free_blocks_count = 0;
|
||||
Dirty();
|
||||
FinishWrite();
|
||||
return errno = ENOSPC, 0;
|
||||
}
|
||||
|
||||
|
@ -138,22 +141,25 @@ uint32_t BlockGroup::AllocateInode()
|
|||
for ( ; inode_bitmap_chunk_i < num_bits; inode_bitmap_chunk_i++ )
|
||||
if ( !checkbit(chunk_bits, inode_bitmap_chunk_i) )
|
||||
{
|
||||
inode_bitmap_chunk->BeginWrite();
|
||||
setbit(chunk_bits, inode_bitmap_chunk_i);
|
||||
inode_bitmap_chunk->Dirty();
|
||||
inode_bitmap_chunk->FinishWrite();
|
||||
BeginWrite();
|
||||
data->bg_free_inodes_count--;
|
||||
Dirty();
|
||||
FinishWrite();
|
||||
filesystem->BeginWrite();
|
||||
filesystem->sb->s_free_inodes_count--;
|
||||
filesystem->Dirty();
|
||||
filesystem->FinishWrite();
|
||||
uint32_t group_inode_id = chunk_offset + inode_bitmap_chunk_i++;
|
||||
uint32_t inode_id = first_inode_id + group_inode_id;
|
||||
return inode_id;
|
||||
}
|
||||
inode_bitmap_chunk->Sync();
|
||||
inode_bitmap_chunk->Unref();
|
||||
inode_bitmap_chunk = NULL;
|
||||
}
|
||||
BeginWrite();
|
||||
data->bg_free_inodes_count = 0;
|
||||
Dirty();
|
||||
FinishWrite();
|
||||
return errno = ENOSPC, 0;
|
||||
}
|
||||
|
||||
|
@ -166,7 +172,6 @@ void BlockGroup::FreeBlock(uint32_t block_id)
|
|||
if ( !block_bitmap_chunk || chunk_id != block_alloc_chunk )
|
||||
{
|
||||
if ( block_bitmap_chunk )
|
||||
block_bitmap_chunk->Sync(),
|
||||
block_bitmap_chunk->Unref();
|
||||
block_alloc_chunk = chunk_id;
|
||||
uint32_t block_id = data->bg_block_bitmap + block_alloc_chunk;
|
||||
|
@ -174,13 +179,16 @@ void BlockGroup::FreeBlock(uint32_t block_id)
|
|||
block_bitmap_chunk_i = 0;
|
||||
}
|
||||
|
||||
block_bitmap_chunk->BeginWrite();
|
||||
uint8_t* chunk_bits = block_bitmap_chunk->block_data;
|
||||
clearbit(chunk_bits, chunk_bit);
|
||||
block_bitmap_chunk->Dirty();
|
||||
block_bitmap_chunk->FinishWrite();
|
||||
BeginWrite();
|
||||
data->bg_free_blocks_count++;
|
||||
Dirty();
|
||||
FinishWrite();
|
||||
filesystem->BeginWrite();
|
||||
filesystem->sb->s_free_blocks_count++;
|
||||
filesystem->Dirty();
|
||||
filesystem->FinishWrite();
|
||||
}
|
||||
|
||||
void BlockGroup::FreeInode(uint32_t inode_id)
|
||||
|
@ -192,7 +200,6 @@ void BlockGroup::FreeInode(uint32_t inode_id)
|
|||
if ( !inode_bitmap_chunk || chunk_id != inode_alloc_chunk )
|
||||
{
|
||||
if ( inode_bitmap_chunk )
|
||||
inode_bitmap_chunk->Sync(),
|
||||
inode_bitmap_chunk->Unref();
|
||||
inode_alloc_chunk = chunk_id;
|
||||
uint32_t block_id = data->bg_inode_bitmap + inode_alloc_chunk;
|
||||
|
@ -200,13 +207,16 @@ void BlockGroup::FreeInode(uint32_t inode_id)
|
|||
inode_bitmap_chunk_i = 0;
|
||||
}
|
||||
|
||||
inode_bitmap_chunk->BeginWrite();
|
||||
uint8_t* chunk_bits = inode_bitmap_chunk->block_data;
|
||||
clearbit(chunk_bits, chunk_bit);
|
||||
inode_bitmap_chunk->Dirty();
|
||||
inode_bitmap_chunk->FinishWrite();
|
||||
BeginWrite();
|
||||
data->bg_free_inodes_count++;
|
||||
Dirty();
|
||||
FinishWrite();
|
||||
filesystem->BeginWrite();
|
||||
filesystem->sb->s_free_inodes_count++;
|
||||
filesystem->Dirty();
|
||||
filesystem->FinishWrite();
|
||||
}
|
||||
|
||||
void BlockGroup::Refer()
|
||||
|
@ -223,15 +233,22 @@ void BlockGroup::Sync()
|
|||
{
|
||||
if ( block_bitmap_chunk )
|
||||
block_bitmap_chunk->Sync();
|
||||
if ( inode_bitmap_chunk )
|
||||
inode_bitmap_chunk->Sync();
|
||||
if ( dirty )
|
||||
data_block->Sync();
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
void BlockGroup::Dirty()
|
||||
void BlockGroup::BeginWrite()
|
||||
{
|
||||
data_block->BeginWrite();
|
||||
}
|
||||
|
||||
void BlockGroup::FinishWrite()
|
||||
{
|
||||
dirty = true;
|
||||
data_block->Dirty();
|
||||
data_block->FinishWrite();
|
||||
Use();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************
|
||||
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2013.
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2013, 2014, 2015.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
|
@ -60,7 +60,8 @@ public:
|
|||
void Refer();
|
||||
void Unref();
|
||||
void Sync();
|
||||
void Dirty();
|
||||
void BeginWrite();
|
||||
void FinishWrite();
|
||||
void Use();
|
||||
void Unlink();
|
||||
void Prelink();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************
|
||||
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2013.
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2013, 2014, 2015.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
|
@ -70,15 +70,17 @@ Block* Device::GetBlockZeroed(uint32_t block_id)
|
|||
{
|
||||
if ( Block* block = GetCachedBlock(block_id) )
|
||||
{
|
||||
block->BeginWrite();
|
||||
memset(block->block_data, 0, block_size);
|
||||
block->Dirty();
|
||||
block->FinishWrite();
|
||||
return block;
|
||||
}
|
||||
Block* block = new Block(this, block_id);
|
||||
block->block_data = new uint8_t[block_size];
|
||||
memset(block->block_data, 0, block_size);
|
||||
block->Prelink();
|
||||
block->Dirty();
|
||||
block->BeginWrite();
|
||||
block->FinishWrite();
|
||||
return block;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************
|
||||
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2013.
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2013, 2014.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
|
|
|
@ -305,9 +305,10 @@ void HandleUTimens(int chl, struct fsm_req_utimens* msg, Filesystem* fs)
|
|||
if ( fs->num_inodes <= msg->ino ) { RespondError(chl, EBADF); return; }
|
||||
Inode* inode = fs->GetInode((uint32_t) msg->ino);
|
||||
if ( !inode ) { RespondError(chl, errno); return; }
|
||||
inode->BeginWrite();
|
||||
inode->data->i_atime = msg->times[0].tv_sec;
|
||||
inode->data->i_mtime = msg->times[1].tv_sec;
|
||||
inode->Dirty();
|
||||
inode->FinishWrite();
|
||||
inode->Unref();
|
||||
RespondSuccess(chl);
|
||||
}
|
||||
|
@ -1177,7 +1178,6 @@ int ext2_fuse_readdir(const char* /*path*/, void* buf, fuse_fill_dir_t filler,
|
|||
if ( block )
|
||||
block->Unref();
|
||||
|
||||
inode->Sync();
|
||||
inode->Unref();
|
||||
return 0;
|
||||
}
|
||||
|
@ -1192,9 +1192,10 @@ int ext2_fuse_utimens(const char* path, const struct timespec tv[2])
|
|||
Inode* inode = ext2_fuse_resolve_path(path);
|
||||
if ( !inode )
|
||||
return -errno;
|
||||
inode->BeginWrite();
|
||||
inode->data->i_atime = tv[0].tv_sec;
|
||||
inode->data->i_mtime = tv[1].tv_sec;
|
||||
inode->Dirty();
|
||||
inode->FinishWrite();
|
||||
inode->Unref();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************
|
||||
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2013.
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2013, 2014, 2015.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
|
@ -64,10 +64,11 @@ Filesystem::Filesystem(Device* device)
|
|||
clock_gettime(CLOCK_MONOTONIC, &now_monotonic);
|
||||
mtime_realtime = now_realtime.tv_sec;
|
||||
mtime_monotonic = now_monotonic.tv_sec;
|
||||
BeginWrite();
|
||||
sb->s_mtime = mtime_realtime;
|
||||
sb->s_mnt_count++;
|
||||
sb->s_state = EXT2_ERROR_FS;
|
||||
Dirty();
|
||||
FinishWrite();
|
||||
Sync();
|
||||
}
|
||||
|
||||
|
@ -79,16 +80,22 @@ Filesystem::~Filesystem()
|
|||
for ( size_t i = 0; i < num_groups; i++ )
|
||||
delete block_groups[i];
|
||||
delete[] block_groups;
|
||||
BeginWrite();
|
||||
sb->s_state = EXT2_VALID_FS;
|
||||
Dirty();
|
||||
FinishWrite();
|
||||
Sync();
|
||||
sb_block->Unref();
|
||||
}
|
||||
|
||||
void Filesystem::Dirty()
|
||||
void Filesystem::BeginWrite()
|
||||
{
|
||||
sb_block->BeginWrite();
|
||||
}
|
||||
|
||||
void Filesystem::FinishWrite()
|
||||
{
|
||||
dirty = true;
|
||||
sb_block->Dirty();
|
||||
sb_block->FinishWrite();
|
||||
}
|
||||
|
||||
void Filesystem::Sync()
|
||||
|
@ -185,8 +192,9 @@ uint32_t Filesystem::AllocateBlock(BlockGroup* preferred)
|
|||
// rebuild all these values upon filesystem mount instead so we know
|
||||
// this can't happen. That also allows us to make the linked list
|
||||
// requested above.
|
||||
BeginWrite();
|
||||
sb->s_free_blocks_count--;
|
||||
Dirty();
|
||||
FinishWrite();
|
||||
return errno = ENOSPC, 0;
|
||||
}
|
||||
|
||||
|
@ -206,8 +214,9 @@ uint32_t Filesystem::AllocateInode(BlockGroup* preferred)
|
|||
// rebuild all these values upon filesystem mount instead so we know
|
||||
// this can't happen. That also allows us to make the linked list
|
||||
// requested above.
|
||||
BeginWrite();
|
||||
sb->s_free_inodes_count--;
|
||||
Dirty();
|
||||
FinishWrite();
|
||||
return errno = ENOSPC, 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************
|
||||
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2013.
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2013, 2014, 2015.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
|
@ -60,7 +60,8 @@ public:
|
|||
uint32_t AllocateInode(BlockGroup* preferred = NULL);
|
||||
void FreeBlock(uint32_t block_id);
|
||||
void FreeInode(uint32_t inode_id);
|
||||
void Dirty();
|
||||
void BeginWrite();
|
||||
void FinishWrite();
|
||||
void Sync();
|
||||
|
||||
};
|
||||
|
|
|
@ -82,9 +82,10 @@ uint32_t Inode::Mode()
|
|||
|
||||
void Inode::SetMode(uint32_t mode)
|
||||
{
|
||||
BeginWrite();
|
||||
// TODO: Use i_mode_high.
|
||||
data->i_mode = (uint16_t) mode;
|
||||
Dirty();
|
||||
FinishWrite();
|
||||
}
|
||||
|
||||
uint32_t Inode::UserId()
|
||||
|
@ -95,9 +96,10 @@ uint32_t Inode::UserId()
|
|||
|
||||
void Inode::SetUserId(uint32_t user)
|
||||
{
|
||||
BeginWrite();
|
||||
// TODO: Use i_uid_high.
|
||||
data->i_uid = (uint16_t) user;
|
||||
Dirty();
|
||||
FinishWrite();
|
||||
}
|
||||
|
||||
uint32_t Inode::GroupId()
|
||||
|
@ -108,9 +110,10 @@ uint32_t Inode::GroupId()
|
|||
|
||||
void Inode::SetGroupId(uint32_t group)
|
||||
{
|
||||
BeginWrite();
|
||||
// TODO: Use i_gid_high.
|
||||
data->i_gid = (uint16_t) group;
|
||||
Dirty();
|
||||
FinishWrite();
|
||||
}
|
||||
|
||||
uint64_t Inode::Size()
|
||||
|
@ -150,24 +153,28 @@ void Inode::SetSize(uint64_t new_size)
|
|||
actual_blocks += divup(logical_blocks - max_singly, ENTRIES * ENTRIES);
|
||||
if ( max_doubly <= logical_blocks )
|
||||
actual_blocks += divup(logical_blocks - max_doubly, ENTRIES * ENTRIES * ENTRIES);
|
||||
data->i_blocks = (actual_blocks * filesystem->block_size) / 512;
|
||||
|
||||
BeginWrite();
|
||||
data->i_blocks = (actual_blocks * filesystem->block_size) / 512;
|
||||
if ( EXT2_S_ISREG(data->i_mode) && largefile )
|
||||
data->i_dir_acl = upper;
|
||||
Dirty();
|
||||
FinishWrite();
|
||||
|
||||
Modified();
|
||||
}
|
||||
|
||||
void Inode::Linked()
|
||||
{
|
||||
BeginWrite();
|
||||
data->i_links_count++;
|
||||
Dirty();
|
||||
FinishWrite();
|
||||
}
|
||||
|
||||
void Inode::Unlinked()
|
||||
{
|
||||
BeginWrite();
|
||||
data->i_links_count--;
|
||||
Dirty();
|
||||
FinishWrite();
|
||||
}
|
||||
|
||||
Block* Inode::GetBlockFromTable(Block* table, uint32_t index)
|
||||
|
@ -182,8 +189,9 @@ Block* Inode::GetBlockFromTable(Block* table, uint32_t index)
|
|||
if ( block_id )
|
||||
{
|
||||
Block* block = filesystem->device->GetBlockZeroed(block_id);
|
||||
table->BeginWrite();
|
||||
((uint32_t*) table->block_data)[index] = block_id;
|
||||
table->Dirty();
|
||||
table->FinishWrite();
|
||||
return block;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -276,6 +284,7 @@ bool Inode::FreeIndirect(uint64_t from, uint64_t offset, uint32_t block_id,
|
|||
Block* block = filesystem->device->GetBlock(block_id);
|
||||
uint32_t* table = (uint32_t*) block->block_data;
|
||||
bool any_children = false;
|
||||
bool begun_writing = false;
|
||||
for ( uint64_t i = 0; i < ENTRIES; i++ )
|
||||
{
|
||||
if ( !table[i] )
|
||||
|
@ -290,9 +299,15 @@ bool Inode::FreeIndirect(uint64_t from, uint64_t offset, uint32_t block_id,
|
|||
continue;
|
||||
}
|
||||
filesystem->FreeBlock(table[i]);
|
||||
if ( !begun_writing )
|
||||
{
|
||||
block->BeginWrite();
|
||||
begun_writing = true;
|
||||
}
|
||||
table[i] = 0;
|
||||
block->Dirty();
|
||||
}
|
||||
if ( begun_writing )
|
||||
block->FinishWrite();
|
||||
return any_children;
|
||||
}
|
||||
|
||||
|
@ -319,8 +334,9 @@ void Inode::Truncate(uint64_t new_size)
|
|||
{
|
||||
Block* partial_block = GetBlock(new_num_blocks-1);
|
||||
uint8_t* data = partial_block->block_data;
|
||||
partial_block->BeginWrite();
|
||||
memset(data + partial, 0, filesystem->block_size - partial);
|
||||
partial_block->Dirty();
|
||||
partial_block->FinishWrite();
|
||||
}
|
||||
|
||||
const uint64_t ENTRIES = filesystem->block_size / sizeof(uint32_t);
|
||||
|
@ -333,6 +349,8 @@ void Inode::Truncate(uint64_t new_size)
|
|||
uint64_t max_doubly = max_singly + block_doubly;
|
||||
uint64_t max_triply = max_doubly + block_triply;
|
||||
|
||||
BeginWrite();
|
||||
|
||||
for ( uint64_t i = new_num_blocks; i < old_num_blocks && i < 12; i++ )
|
||||
{
|
||||
filesystem->FreeBlock(data->i_block[i]);
|
||||
|
@ -359,7 +377,7 @@ void Inode::Truncate(uint64_t new_size)
|
|||
|
||||
(void) max_triply;
|
||||
|
||||
Dirty();
|
||||
FinishWrite();
|
||||
}
|
||||
|
||||
Inode* Inode::Open(const char* elem, int flags, mode_t mode)
|
||||
|
@ -520,6 +538,8 @@ bool Inode::Link(const char* elem, Inode* dest, bool directories)
|
|||
if ( !block && !(block = GetBlock(block_id = hole_block_id)) )
|
||||
return NULL;
|
||||
|
||||
block->BeginWrite();
|
||||
|
||||
uint8_t* block_data = block->block_data + hole_block_offset;
|
||||
struct ext_dirent* entry = (struct ext_dirent*) block_data;
|
||||
|
||||
|
@ -528,7 +548,6 @@ bool Inode::Link(const char* elem, Inode* dest, bool directories)
|
|||
{
|
||||
entry->reclen = roundup(sizeof(struct ext_dirent) + entry->name_len, (size_t) 4);
|
||||
assert(entry->reclen);
|
||||
// Block marked dirty below.
|
||||
block_data += entry->reclen;
|
||||
entry = (struct ext_dirent*) block_data;
|
||||
}
|
||||
|
@ -544,7 +563,7 @@ bool Inode::Link(const char* elem, Inode* dest, bool directories)
|
|||
|
||||
assert(entry->reclen);
|
||||
|
||||
block->Dirty();
|
||||
block->FinishWrite();
|
||||
|
||||
dest->Linked();
|
||||
|
||||
|
@ -610,6 +629,9 @@ Inode* Inode::Unlink(const char* elem, bool directories, bool force)
|
|||
}
|
||||
|
||||
inode->Unlinked();
|
||||
|
||||
block->BeginWrite();
|
||||
|
||||
entry->inode = 0;
|
||||
entry->name_len = 0;
|
||||
entry->file_type = 0;
|
||||
|
@ -628,7 +650,6 @@ Inode* Inode::Unlink(const char* elem, bool directories, bool force)
|
|||
strncpy(entry->name + entry->name_len, "",
|
||||
entry->reclen - sizeof(struct ext_dirent) - entry->name_len);
|
||||
assert(entry->reclen);
|
||||
block->Dirty();
|
||||
|
||||
// If the entire block is empty, we'll need to remove it.
|
||||
if ( !entry->name[0] && entry->reclen == block_size )
|
||||
|
@ -641,12 +662,13 @@ Inode* Inode::Unlink(const char* elem, bool directories, bool force)
|
|||
{
|
||||
Block* last_block = GetBlock(num_blocks-1);
|
||||
memcpy(block->block_data, last_block->block_data, block_size);
|
||||
block->Dirty();
|
||||
last_block->Unref();
|
||||
}
|
||||
Truncate(filesize - block_size);
|
||||
}
|
||||
|
||||
block->FinishWrite();
|
||||
|
||||
block->Unref();
|
||||
|
||||
return inode;
|
||||
|
@ -733,8 +755,9 @@ ssize_t Inode::WriteAt(const uint8_t* buf, size_t s_count, off_t o_offset)
|
|||
if ( !block )
|
||||
return sofar ? sofar : -1;
|
||||
size_t amount = count - sofar < block_left ? count - sofar : block_left;
|
||||
block->BeginWrite();
|
||||
memcpy(block->block_data + block_offset, buf + sofar, amount);
|
||||
block->Dirty();
|
||||
block->FinishWrite();
|
||||
sofar += amount;
|
||||
offset += amount;
|
||||
block->Unref();
|
||||
|
@ -835,8 +858,9 @@ Inode* Inode::CreateDirectory(const char* path, mode_t mode)
|
|||
uint32_t group_id = (result->inode_id - 1) / filesystem->sb->s_inodes_per_group;
|
||||
assert(group_id < filesystem->num_groups);
|
||||
BlockGroup* block_group = filesystem->GetBlockGroup(group_id);
|
||||
block_group->BeginWrite();
|
||||
block_group->data->bg_used_dirs_count++;
|
||||
block_group->Dirty();
|
||||
block_group->FinishWrite();
|
||||
block_group->Unref();
|
||||
|
||||
struct timespec now;
|
||||
|
@ -886,8 +910,9 @@ bool Inode::RemoveDirectory(const char* path)
|
|||
uint32_t group_id = (result->inode_id - 1) / filesystem->sb->s_inodes_per_group;
|
||||
assert(group_id < filesystem->num_groups);
|
||||
BlockGroup* block_group = filesystem->GetBlockGroup(group_id);
|
||||
block_group->BeginWrite();
|
||||
block_group->data->bg_used_dirs_count--;
|
||||
block_group->Dirty();
|
||||
block_group->FinishWrite();
|
||||
block_group->Unref();
|
||||
|
||||
result->Unref();
|
||||
|
@ -939,13 +964,14 @@ void Inode::Delete()
|
|||
Truncate(0);
|
||||
|
||||
uint32_t deleted_inode_id = inode_id;
|
||||
memset(data, 0, sizeof(*data));
|
||||
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_REALTIME, &now);
|
||||
data->i_dtime = now.tv_sec;
|
||||
Dirty();
|
||||
|
||||
delete this;
|
||||
BeginWrite();
|
||||
memset(data, 0, sizeof(*data));
|
||||
data->i_dtime = now.tv_sec;
|
||||
FinishWrite();
|
||||
|
||||
filesystem->FreeInode(deleted_inode_id);
|
||||
}
|
||||
|
@ -962,8 +988,7 @@ void Inode::Unref()
|
|||
{
|
||||
if ( !data->i_links_count )
|
||||
Delete();
|
||||
else
|
||||
delete this;
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -979,8 +1004,7 @@ void Inode::RemoteUnref()
|
|||
{
|
||||
if ( !data->i_links_count )
|
||||
Delete();
|
||||
else
|
||||
delete this;
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -988,11 +1012,17 @@ void Inode::Modified()
|
|||
{
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_REALTIME, &now);
|
||||
BeginWrite();
|
||||
data->i_mtime = now.tv_sec;
|
||||
Dirty();
|
||||
FinishWrite();
|
||||
}
|
||||
|
||||
void Inode::Dirty()
|
||||
void Inode::BeginWrite()
|
||||
{
|
||||
data_block->BeginWrite();
|
||||
}
|
||||
|
||||
void Inode::FinishWrite()
|
||||
{
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_REALTIME, &now);
|
||||
|
@ -1006,7 +1036,7 @@ void Inode::Dirty()
|
|||
next_dirty->prev_dirty = this;
|
||||
filesystem->dirty_inode = this;
|
||||
}
|
||||
data_block->Dirty();
|
||||
data_block->FinishWrite();
|
||||
Use();
|
||||
}
|
||||
|
||||
|
@ -1015,6 +1045,7 @@ void Inode::Sync()
|
|||
if ( !dirty )
|
||||
return;
|
||||
data_block->Sync();
|
||||
// TODO: The inode contents needs to be sync'd as well!
|
||||
(prev_dirty ? prev_dirty->next_dirty : filesystem->dirty_inode) = next_dirty;
|
||||
if ( next_dirty )
|
||||
next_dirty->prev_dirty = prev_dirty;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************
|
||||
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2013.
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2013, 2014, 2015.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
|
@ -76,7 +76,8 @@ public:
|
|||
void RemoteRefer();
|
||||
void RemoteUnref();
|
||||
void Sync();
|
||||
void Dirty();
|
||||
void BeginWrite();
|
||||
void FinishWrite();
|
||||
void Modified();
|
||||
void Use();
|
||||
void Unlink();
|
||||
|
|
Loading…
Add table
Reference in a new issue