diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.cpp b/src/add-ons/kernel/file_systems/bfs/Inode.cpp index b3c8071fbb..9aa81714f0 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Inode.cpp @@ -1,6 +1,6 @@ /* Inode - inode access functions * - * Copyright 2001-2004, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2001-2005, Axel Dörfler, axeld@pinc-software.de. * This file may be used under the terms of the MIT License. */ @@ -1840,7 +1840,8 @@ Inode::NeedsTrimming() { // We never trim preallocated index blocks to make them grow as smooth as possible. // There are only few indices anyway, so this doesn't hurt - if (IsIndex()) + // Also, if an inode is already in deleted state, we don't bother trimming it + if (IsIndex() || IsDeleted()) return false; off_t roundedSize = (Size() + fVolume->BlockSize() - 1) & ~(fVolume->BlockSize() - 1); @@ -2054,7 +2055,7 @@ Inode::Remove(Transaction &transaction, const char *name, off_t *_id, bool isDir // Deleted inodes won't be visible in queries anyway. } - if ((inode->Mode() & (S_FILE | S_SYMLINK)) != 0) { + if (inode->IsFile() || inode->IsSymLink()) { if (inode->IsFile()) index.RemoveSize(transaction, inode); index.RemoveLastModified(transaction, inode); diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.h b/src/add-ons/kernel/file_systems/bfs/Inode.h index 3908d73851..8240c7ed73 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.h +++ b/src/add-ons/kernel/file_systems/bfs/Inode.h @@ -1,6 +1,6 @@ /* Inode - inode access functions * - * Copyright 2001-2004, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2001-2005, Axel Dörfler, axeld@pinc-software.de. * This file may be used under the terms of the MIT License. */ #ifndef INODE_H @@ -75,6 +75,8 @@ class Inode { bool HasUserAccessableStream() const { return S_ISREG(Mode()); } // currently only files can be accessed with bfs_read()/bfs_write() + bool IsDeleted() const { return (Flags() & INODE_DELETED) != 0; } + mode_t Mode() const { return fNode.Mode(); } uint32 Type() const { return fNode.Type(); } int32 Flags() const { return fNode.Flags(); } 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 a38e36041d..237e9a87a1 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -698,11 +698,13 @@ bfs_write_stat(void *_ns, void *_node, const struct stat *stat, uint32 mask) // fill the new blocks (if any) with zeros inode->FillGapWithZeros(inode->OldSize(), inode->Size()); - Index index(volume); - index.UpdateSize(transaction, inode); + if (!inode->IsDeleted()) { + Index index(volume); + index.UpdateSize(transaction, inode); - if ((mask & FS_WRITE_STAT_MTIME) == 0) - index.UpdateLastModified(transaction, inode); + if ((mask & FS_WRITE_STAT_MTIME) == 0) + index.UpdateLastModified(transaction, inode); + } } } @@ -717,10 +719,12 @@ bfs_write_stat(void *_ns, void *_node, const struct stat *stat, uint32 mask) node.gid = HOST_ENDIAN_TO_BFS_INT32(stat->st_gid); if (mask & FS_WRITE_STAT_MTIME) { - // Index::UpdateLastModified() will set the new time in the inode - Index index(volume); - index.UpdateLastModified(transaction, inode, - (bigtime_t)stat->st_mtime << INODE_TIME_SHIFT); + if (!inode->IsDeleted()) { + // Index::UpdateLastModified() will set the new time in the inode + Index index(volume); + index.UpdateLastModified(transaction, inode, + (bigtime_t)stat->st_mtime << INODE_TIME_SHIFT); + } } if (mask & FS_WRITE_STAT_CRTIME) { node.create_time = HOST_ENDIAN_TO_BFS_INT64((bigtime_t)stat->st_crtime << INODE_TIME_SHIFT); @@ -1182,7 +1186,7 @@ bfs_write(void *_ns, void *_node, void *_cookie, off_t pos, const void *buffer, if (status == B_OK) { // periodically notify if the file size has changed // ToDo: should we better test for a change in the last_modified time only? - if (cookie->last_size != inode->Size() + if (!inode->IsDeleted() && cookie->last_size != inode->Size() && system_time() > cookie->last_notification + INODE_NOTIFICATION_INTERVAL) { notify_listener(B_STAT_CHANGED, volume->ID(), 0, 0, inode->ID(), NULL); cookie->last_size = inode->Size(); @@ -1224,8 +1228,11 @@ bfs_free_cookie(void *_ns, void *_node, void *_cookie) bool needsTrimming = inode->NeedsTrimming(); - if (cookie->open_mode & O_RWMASK - && (needsTrimming || inode->OldLastModified() != inode->LastModified())) { + if ((cookie->open_mode & O_RWMASK) != 0 + && !inode->IsDeleted() + && (needsTrimming + || inode->OldLastModified() != inode->LastModified() + || inode->OldSize() != inode->Size())) { #ifdef UNSAFE_GET_VNODE RecursiveLocker locker(volume->Lock()); #endif @@ -1243,7 +1250,8 @@ bfs_free_cookie(void *_ns, void *_node, void *_cookie) status = inode->TrimPreallocation(transaction); if (status < B_OK) FATAL(("Could not trim preallocated blocks!")); - + } + if (needsTrimming || inode->OldSize() != inode->Size()) { index.UpdateSize(transaction, inode); changed = true; }