diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.cpp b/src/add-ons/kernel/file_systems/bfs/Inode.cpp index 8583598eec..13aa38af7d 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Inode.cpp @@ -1498,7 +1498,7 @@ Inode::WriteAt(Transaction& transaction, off_t pos, const uint8* buffer, if (pos + length > Size()) { // let's grow the data stream to the size needed status_t status = SetFileSize(transaction, pos + length); - if (status < B_OK) { + if (status != B_OK) { *_length = 0; WriteLockInTransaction(transaction); RETURN_ERROR(status); @@ -1511,7 +1511,7 @@ Inode::WriteAt(Transaction& transaction, off_t pos, const uint8* buffer, // go into this transaction (we cannot wait until the file // is closed) status = WriteBack(transaction); - if (status < B_OK) { + if (status != B_OK) { WriteLockInTransaction(transaction); return status; } diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.h b/src/add-ons/kernel/file_systems/bfs/Inode.h index ea3bffb0ff..2beda03659 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.h +++ b/src/add-ons/kernel/file_systems/bfs/Inode.h @@ -19,7 +19,6 @@ class TreeIterator; class AttributeIterator; class Index; class InodeAllocator; -class InodeReadLocker; class NodeGetter; class Transaction; @@ -188,8 +187,6 @@ private: friend class AttributeIterator; friend class InodeAllocator; - friend class InodeReadLocker; - friend class Transaction; // small_data access methods status_t _MakeSpaceForSmallData(Transaction& transaction, @@ -253,7 +250,7 @@ class InodeReadLocker { public: InodeReadLocker(Inode* inode) : - fLock(&inode->fLock) + fLock(&inode->Lock()) { rw_lock_read_lock(fLock); } diff --git a/src/add-ons/kernel/file_systems/bfs/Journal.cpp b/src/add-ons/kernel/file_systems/bfs/Journal.cpp index 4882d08500..24ef97b88f 100644 --- a/src/add-ons/kernel/file_systems/bfs/Journal.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Journal.cpp @@ -1103,7 +1103,7 @@ Transaction::AddInode(Inode* inode) if (!GetVolume()->IsInitializing()) acquire_vnode(GetVolume()->FSVolume(), inode->ID()); - rw_lock_write_lock(&inode->fLock); + rw_lock_write_lock(&inode->Lock()); fLockedInodes.Add(inode); inode->Node().flags |= HOST_ENDIAN_TO_BFS_INT32(INODE_IN_TRANSACTION); } @@ -1117,7 +1117,7 @@ Transaction::RemoveInode(Inode* inode) inode->Node().flags &= ~HOST_ENDIAN_TO_BFS_INT32(INODE_IN_TRANSACTION); fLockedInodes.Remove(inode); - rw_lock_write_unlock(&inode->fLock); + rw_lock_write_unlock(&inode->Lock()); // See AddInode() why we do this here if ((inode->Flags() & INODE_DELETED) != 0) @@ -1133,7 +1133,7 @@ Transaction::_UnlockInodes() { while (Inode* inode = fLockedInodes.RemoveHead()) { inode->Node().flags &= ~HOST_ENDIAN_TO_BFS_INT32(INODE_IN_TRANSACTION); - rw_lock_write_unlock(&inode->fLock); + rw_lock_write_unlock(&inode->Lock()); // See AddInode() why we do this here if ((inode->Flags() & INODE_DELETED) != 0) diff --git a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp index 3b9f588d71..c96fca3fb7 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -755,8 +755,13 @@ bfs_write_stat(fs_volume* _volume, fs_vnode* _node, const struct stat* stat, return status; // fill the new blocks (if any) with zeros - if ((mask & B_STAT_SIZE_INSECURE) == 0) + if ((mask & B_STAT_SIZE_INSECURE) == 0) { + // We must not keep the inode locked during a write operation, + // or else we might deadlock. + rw_lock_write_unlock(&inode->Lock()); inode->FillGapWithZeros(oldSize, inode->Size()); + rw_lock_write_lock(&inode->Lock()); + } if (!inode->IsDeleted()) { Index index(volume);