From 36bf05cac9e3cb1fa038b3341801fe675c729e41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 7 Jul 2008 12:53:53 +0000 Subject: [PATCH] * Added a lock to FileMap - since the map is retrieved lazily, and file systems like BFS only hold a read lock when reading the map, accessing the file map wasn't safe. * Made FileMap::Free() private, and renamed it to _Free(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26295 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/cache/file_map.cpp | 43 +++++++++++++++++++--------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/src/system/kernel/cache/file_map.cpp b/src/system/kernel/cache/file_map.cpp index 5d8264d2be..d1299e1834 100644 --- a/src/system/kernel/cache/file_map.cpp +++ b/src/system/kernel/cache/file_map.cpp @@ -62,7 +62,6 @@ public: void Invalidate(off_t offset, off_t size); void SetSize(off_t size); - void Free(); status_t Translate(off_t offset, size_t size, file_io_vec* vecs, size_t* _count); @@ -78,11 +77,14 @@ private: status_t _MakeSpace(size_t count); status_t _Add(file_io_vec* vecs, size_t vecCount, off_t& lastOffset); + void _InvalidateAfter(off_t offset); + void _Free(); union { file_extent fDirect[CACHED_FILE_EXTENTS]; file_extent_array fIndirect; }; + mutex fLock; size_t fCount; struct vnode* fVnode; off_t fSize; @@ -98,6 +100,7 @@ static mutex sLock; FileMap::FileMap(struct vnode* vnode, off_t size) { + mutex_init(&fLock, "file map"); fCount = 0; fVnode = vnode; fSize = size; @@ -111,7 +114,8 @@ FileMap::FileMap(struct vnode* vnode, off_t size) FileMap::~FileMap() { - Free(); + _Free(); + mutex_destroy(&fLock); #ifdef DEBUG_FILE_MAP MutexLocker _(sLock); @@ -260,17 +264,9 @@ FileMap::_Add(file_io_vec* vecs, size_t vecCount, off_t& lastOffset) } -/*! Invalidates or removes the specified part of the file map. -*/ void -FileMap::Invalidate(off_t offset, off_t size) +FileMap::_InvalidateAfter(off_t offset) { - // TODO: honour size, we currently always remove everything after "offset" - if (offset == 0) { - Free(); - return; - } - uint32 index; file_extent* extent = _FindExtent(offset, &index); if (extent != NULL) { @@ -282,18 +278,37 @@ FileMap::Invalidate(off_t offset, off_t size) } +/*! Invalidates or removes the specified part of the file map. +*/ +void +FileMap::Invalidate(off_t offset, off_t size) +{ + MutexLocker _(fLock); + + // TODO: honour size, we currently always remove everything after "offset" + if (offset == 0) { + _Free(); + return; + } + + _InvalidateAfter(offset); +} + + void FileMap::SetSize(off_t size) { + MutexLocker _(fLock); + if (size < fSize) - Invalidate(size, fSize - size); + _InvalidateAfter(size); fSize = size; } void -FileMap::Free() +FileMap::_Free() { if (fCount > CACHED_FILE_EXTENTS) free(fIndirect.array); @@ -305,6 +320,8 @@ FileMap::Free() status_t FileMap::Translate(off_t offset, size_t size, file_io_vec* vecs, size_t* _count) { + MutexLocker _(fLock); + size_t maxVecs = *_count; status_t status = B_OK;