mirror of
https://github.com/SerenityOS/serenity
synced 2024-07-21 18:15:58 +00:00
Kernel/FileSystem: Funnel calls to Inode::prepare_to_write_data method
Instead of requiring each FileSystem implementation to call this method when trying to write data, do the calls at 2 points to avoid further calls (or lack of them due to not remembering to use it) at other files and locations in the codebase.
This commit is contained in:
parent
38bf7863d0
commit
fcc0e4d538
|
@ -937,15 +937,12 @@ ErrorOr<void> Ext2FSInode::resize(u64 new_size)
|
||||||
|
|
||||||
ErrorOr<size_t> Ext2FSInode::write_bytes(off_t offset, size_t count, UserOrKernelBuffer const& data, OpenFileDescription* description)
|
ErrorOr<size_t> Ext2FSInode::write_bytes(off_t offset, size_t count, UserOrKernelBuffer const& data, OpenFileDescription* description)
|
||||||
{
|
{
|
||||||
|
VERIFY(m_inode_lock.is_locked());
|
||||||
VERIFY(offset >= 0);
|
VERIFY(offset >= 0);
|
||||||
|
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
MutexLocker inode_locker(m_inode_lock);
|
|
||||||
|
|
||||||
TRY(prepare_to_write_data());
|
|
||||||
|
|
||||||
if (is_symlink()) {
|
if (is_symlink()) {
|
||||||
VERIFY(offset == 0);
|
VERIFY(offset == 0);
|
||||||
if (max((size_t)(offset + count), (size_t)m_raw_inode.i_size) < max_inline_symlink_length) {
|
if (max((size_t)(offset + count), (size_t)m_raw_inode.i_size) < max_inline_symlink_length) {
|
||||||
|
|
|
@ -253,9 +253,7 @@ void Inode::did_delete_self()
|
||||||
|
|
||||||
ErrorOr<void> Inode::prepare_to_write_data()
|
ErrorOr<void> Inode::prepare_to_write_data()
|
||||||
{
|
{
|
||||||
// FIXME: It's a poor design that filesystems are expected to call this before writing out data.
|
VERIFY(m_inode_lock.is_locked());
|
||||||
// We should funnel everything through an interface at the VirtualFileSystem layer so this can happen from a single place.
|
|
||||||
MutexLocker locker(m_inode_lock);
|
|
||||||
if (fs().is_readonly())
|
if (fs().is_readonly())
|
||||||
return EROFS;
|
return EROFS;
|
||||||
auto metadata = this->metadata();
|
auto metadata = this->metadata();
|
||||||
|
|
|
@ -31,6 +31,7 @@ class Inode : public ListedRefCounted<Inode, LockType::Spinlock>
|
||||||
, public Weakable<Inode> {
|
, public Weakable<Inode> {
|
||||||
friend class VirtualFileSystem;
|
friend class VirtualFileSystem;
|
||||||
friend class FileSystem;
|
friend class FileSystem;
|
||||||
|
friend class InodeFile;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~Inode();
|
virtual ~Inode();
|
||||||
|
|
|
@ -42,7 +42,12 @@ ErrorOr<size_t> InodeFile::write(OpenFileDescription& description, u64 offset, U
|
||||||
if (Checked<off_t>::addition_would_overflow(offset, count))
|
if (Checked<off_t>::addition_would_overflow(offset, count))
|
||||||
return EOVERFLOW;
|
return EOVERFLOW;
|
||||||
|
|
||||||
auto nwritten = TRY(m_inode->write_bytes(offset, count, data, &description));
|
size_t nwritten = 0;
|
||||||
|
{
|
||||||
|
MutexLocker locker(m_inode->m_inode_lock);
|
||||||
|
TRY(m_inode->prepare_to_write_data());
|
||||||
|
nwritten = TRY(m_inode->write_bytes(offset, count, data, &description));
|
||||||
|
}
|
||||||
if (nwritten > 0) {
|
if (nwritten > 0) {
|
||||||
auto mtime_result = m_inode->set_mtime(kgettimeofday().to_truncated_seconds());
|
auto mtime_result = m_inode->set_mtime(kgettimeofday().to_truncated_seconds());
|
||||||
Thread::current()->did_file_write(nwritten);
|
Thread::current()->did_file_write(nwritten);
|
||||||
|
|
|
@ -108,12 +108,10 @@ ErrorOr<size_t> TmpFSInode::read_bytes(off_t offset, size_t size, UserOrKernelBu
|
||||||
|
|
||||||
ErrorOr<size_t> TmpFSInode::write_bytes(off_t offset, size_t size, UserOrKernelBuffer const& buffer, OpenFileDescription*)
|
ErrorOr<size_t> TmpFSInode::write_bytes(off_t offset, size_t size, UserOrKernelBuffer const& buffer, OpenFileDescription*)
|
||||||
{
|
{
|
||||||
MutexLocker locker(m_inode_lock);
|
VERIFY(m_inode_lock.is_locked());
|
||||||
VERIFY(!is_directory());
|
VERIFY(!is_directory());
|
||||||
VERIFY(offset >= 0);
|
VERIFY(offset >= 0);
|
||||||
|
|
||||||
TRY(prepare_to_write_data());
|
|
||||||
|
|
||||||
off_t old_size = m_metadata.size;
|
off_t old_size = m_metadata.size;
|
||||||
off_t new_size = m_metadata.size;
|
off_t new_size = m_metadata.size;
|
||||||
if (static_cast<off_t>(offset + size) > new_size)
|
if (static_cast<off_t>(offset + size) > new_size)
|
||||||
|
|
|
@ -693,6 +693,8 @@ ErrorOr<void> VirtualFileSystem::symlink(StringView target, StringView linkpath,
|
||||||
auto inode = TRY(parent_inode.create_child(basename, S_IFLNK | 0644, 0, current_process.euid(), current_process.egid()));
|
auto inode = TRY(parent_inode.create_child(basename, S_IFLNK | 0644, 0, current_process.euid(), current_process.egid()));
|
||||||
|
|
||||||
auto target_buffer = UserOrKernelBuffer::for_kernel_buffer(const_cast<u8*>((u8 const*)target.characters_without_null_termination()));
|
auto target_buffer = UserOrKernelBuffer::for_kernel_buffer(const_cast<u8*>((u8 const*)target.characters_without_null_termination()));
|
||||||
|
MutexLocker locker(inode->m_inode_lock);
|
||||||
|
TRY(inode->prepare_to_write_data());
|
||||||
TRY(inode->write_bytes(0, target.length(), target_buffer, nullptr));
|
TRY(inode->write_bytes(0, target.length(), target_buffer, nullptr));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue