* Added a acquire_unreferenced_ref() to vm_store
* his has to be used by the page writer to make sure the vnode is still valid. * This should have been the final nail on the Luposian bug - I haven't tested it yet, but we'll certainly see :-) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22462 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
80f5469291
commit
c950f17a51
@ -219,19 +219,20 @@ struct vm_store {
|
||||
};
|
||||
|
||||
typedef struct vm_store_ops {
|
||||
void (*destroy)(struct vm_store *backing_store);
|
||||
status_t (*commit)(struct vm_store *backing_store, off_t size);
|
||||
bool (*has_page)(struct vm_store *backing_store, off_t offset);
|
||||
status_t (*read)(struct vm_store *backing_store, off_t offset,
|
||||
void (*destroy)(struct vm_store *backingStore);
|
||||
status_t (*commit)(struct vm_store *backingStore, off_t size);
|
||||
bool (*has_page)(struct vm_store *backingStore, off_t offset);
|
||||
status_t (*read)(struct vm_store *backingStore, off_t offset,
|
||||
const iovec *vecs, size_t count, size_t *_numBytes, bool mayBlock,
|
||||
bool fsReenter);
|
||||
status_t (*write)(struct vm_store *backing_store, off_t offset,
|
||||
status_t (*write)(struct vm_store *backingStore, off_t offset,
|
||||
const iovec *vecs, size_t count, size_t *_numBytes, bool mayBlock,
|
||||
bool fsReenter);
|
||||
status_t (*fault)(struct vm_store *backing_store,
|
||||
status_t (*fault)(struct vm_store *backingStore,
|
||||
struct vm_address_space *aspace, off_t offset);
|
||||
void (*acquire_ref)(struct vm_store *backing_store);
|
||||
void (*release_ref)(struct vm_store *backing_store);
|
||||
status_t (*acquire_unreferenced_ref)(struct vm_store *backingStore);
|
||||
void (*acquire_ref)(struct vm_store *backingStore);
|
||||
void (*release_ref)(struct vm_store *backingStore);
|
||||
} vm_store_ops;
|
||||
|
||||
#endif /* _KERNEL_VM_TYPES_H */
|
||||
|
11
src/system/kernel/cache/vnode_store.cpp
vendored
11
src/system/kernel/cache/vnode_store.cpp
vendored
@ -83,6 +83,15 @@ store_write(struct vm_store *_store, off_t offset, const iovec *vecs,
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
store_acquire_unreferenced_ref(struct vm_store *_store)
|
||||
{
|
||||
vnode_store *store = (vnode_store *)_store;
|
||||
struct vnode *vnode;
|
||||
return vfs_get_vnode(store->device, store->inode, &vnode);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
store_acquire_ref(struct vm_store *_store)
|
||||
{
|
||||
@ -106,6 +115,7 @@ static vm_store_ops sStoreOps = {
|
||||
&store_read,
|
||||
&store_write,
|
||||
NULL, /* fault */
|
||||
&store_acquire_unreferenced_ref,
|
||||
&store_acquire_ref,
|
||||
&store_release_ref
|
||||
};
|
||||
@ -128,6 +138,7 @@ vm_create_vnode_store(struct vnode *vnode)
|
||||
store->vnode = vnode;
|
||||
store->file_cache_ref = NULL;
|
||||
|
||||
vfs_vnode_to_node_ref(vnode, &store->device, &store->inode);
|
||||
return &store->vm;
|
||||
}
|
||||
|
||||
|
2
src/system/kernel/cache/vnode_store.h
vendored
2
src/system/kernel/cache/vnode_store.h
vendored
@ -12,6 +12,8 @@
|
||||
struct vnode_store {
|
||||
vm_store vm;
|
||||
struct vnode* vnode;
|
||||
dev_t device;
|
||||
ino_t inode;
|
||||
void* file_cache_ref;
|
||||
};
|
||||
|
||||
|
@ -665,6 +665,15 @@ page_writer(void* /*unused*/)
|
||||
if (!cacheLocker.IsLocked())
|
||||
continue;
|
||||
|
||||
vm_cache *cache = page->cache;
|
||||
if (cache->store->ops->acquire_unreferenced_ref != NULL) {
|
||||
// we need our own reference to the store, as it might
|
||||
// currently be destructed
|
||||
if (cache->store->ops->acquire_unreferenced_ref(cache->store)
|
||||
!= B_OK)
|
||||
continue;
|
||||
}
|
||||
|
||||
locker.Lock();
|
||||
remove_page_from_queue(&sModifiedPageQueue, page);
|
||||
page->state = PAGE_STATE_BUSY;
|
||||
@ -675,7 +684,7 @@ page_writer(void* /*unused*/)
|
||||
|
||||
//dprintf("write page %p, cache %p (%ld)\n", page, page->cache, page->cache->ref_count);
|
||||
vm_clear_map_flags(page, PAGE_MODIFIED);
|
||||
vm_cache_acquire_ref(page->cache);
|
||||
vm_cache_acquire_ref(cache);
|
||||
pages[numPages++] = page;
|
||||
}
|
||||
|
||||
@ -711,6 +720,8 @@ page_writer(void* /*unused*/)
|
||||
busyConditions[i].Unpublish();
|
||||
|
||||
mutex_unlock(&cache->lock);
|
||||
if (cache->store->ops->release_ref != NULL)
|
||||
cache->store->ops->release_ref(cache->store);
|
||||
vm_cache_release_ref(cache);
|
||||
}
|
||||
}
|
||||
|
@ -154,6 +154,7 @@ static vm_store_ops anonymous_ops = {
|
||||
&anonymous_read,
|
||||
&anonymous_write,
|
||||
&anonymous_fault,
|
||||
NULL, // acquire unreferenced ref
|
||||
NULL, // acquire ref
|
||||
NULL // release ref
|
||||
};
|
||||
|
@ -78,8 +78,9 @@ static vm_store_ops device_ops = {
|
||||
&device_read,
|
||||
&device_write,
|
||||
&device_fault,
|
||||
NULL,
|
||||
NULL
|
||||
NULL, // acquire unreferenced ref
|
||||
NULL, // acquire ref
|
||||
NULL // release ref
|
||||
};
|
||||
|
||||
|
||||
|
@ -67,8 +67,9 @@ static vm_store_ops null_ops = {
|
||||
&null_read,
|
||||
&null_write,
|
||||
&null_fault,
|
||||
NULL,
|
||||
NULL
|
||||
NULL, // acquire unreferenced ref
|
||||
NULL, // acquire ref
|
||||
NULL // release ref
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user