* 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 {
|
typedef struct vm_store_ops {
|
||||||
void (*destroy)(struct vm_store *backing_store);
|
void (*destroy)(struct vm_store *backingStore);
|
||||||
status_t (*commit)(struct vm_store *backing_store, off_t size);
|
status_t (*commit)(struct vm_store *backingStore, off_t size);
|
||||||
bool (*has_page)(struct vm_store *backing_store, off_t offset);
|
bool (*has_page)(struct vm_store *backingStore, off_t offset);
|
||||||
status_t (*read)(struct vm_store *backing_store, off_t offset,
|
status_t (*read)(struct vm_store *backingStore, off_t offset,
|
||||||
const iovec *vecs, size_t count, size_t *_numBytes, bool mayBlock,
|
const iovec *vecs, size_t count, size_t *_numBytes, bool mayBlock,
|
||||||
bool fsReenter);
|
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,
|
const iovec *vecs, size_t count, size_t *_numBytes, bool mayBlock,
|
||||||
bool fsReenter);
|
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);
|
struct vm_address_space *aspace, off_t offset);
|
||||||
void (*acquire_ref)(struct vm_store *backing_store);
|
status_t (*acquire_unreferenced_ref)(struct vm_store *backingStore);
|
||||||
void (*release_ref)(struct vm_store *backing_store);
|
void (*acquire_ref)(struct vm_store *backingStore);
|
||||||
|
void (*release_ref)(struct vm_store *backingStore);
|
||||||
} vm_store_ops;
|
} vm_store_ops;
|
||||||
|
|
||||||
#endif /* _KERNEL_VM_TYPES_H */
|
#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
|
static void
|
||||||
store_acquire_ref(struct vm_store *_store)
|
store_acquire_ref(struct vm_store *_store)
|
||||||
{
|
{
|
||||||
@ -106,6 +115,7 @@ static vm_store_ops sStoreOps = {
|
|||||||
&store_read,
|
&store_read,
|
||||||
&store_write,
|
&store_write,
|
||||||
NULL, /* fault */
|
NULL, /* fault */
|
||||||
|
&store_acquire_unreferenced_ref,
|
||||||
&store_acquire_ref,
|
&store_acquire_ref,
|
||||||
&store_release_ref
|
&store_release_ref
|
||||||
};
|
};
|
||||||
@ -128,6 +138,7 @@ vm_create_vnode_store(struct vnode *vnode)
|
|||||||
store->vnode = vnode;
|
store->vnode = vnode;
|
||||||
store->file_cache_ref = NULL;
|
store->file_cache_ref = NULL;
|
||||||
|
|
||||||
|
vfs_vnode_to_node_ref(vnode, &store->device, &store->inode);
|
||||||
return &store->vm;
|
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 {
|
struct vnode_store {
|
||||||
vm_store vm;
|
vm_store vm;
|
||||||
struct vnode* vnode;
|
struct vnode* vnode;
|
||||||
|
dev_t device;
|
||||||
|
ino_t inode;
|
||||||
void* file_cache_ref;
|
void* file_cache_ref;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -665,6 +665,15 @@ page_writer(void* /*unused*/)
|
|||||||
if (!cacheLocker.IsLocked())
|
if (!cacheLocker.IsLocked())
|
||||||
continue;
|
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();
|
locker.Lock();
|
||||||
remove_page_from_queue(&sModifiedPageQueue, page);
|
remove_page_from_queue(&sModifiedPageQueue, page);
|
||||||
page->state = PAGE_STATE_BUSY;
|
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);
|
//dprintf("write page %p, cache %p (%ld)\n", page, page->cache, page->cache->ref_count);
|
||||||
vm_clear_map_flags(page, PAGE_MODIFIED);
|
vm_clear_map_flags(page, PAGE_MODIFIED);
|
||||||
vm_cache_acquire_ref(page->cache);
|
vm_cache_acquire_ref(cache);
|
||||||
pages[numPages++] = page;
|
pages[numPages++] = page;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -711,6 +720,8 @@ page_writer(void* /*unused*/)
|
|||||||
busyConditions[i].Unpublish();
|
busyConditions[i].Unpublish();
|
||||||
|
|
||||||
mutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
|
if (cache->store->ops->release_ref != NULL)
|
||||||
|
cache->store->ops->release_ref(cache->store);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,6 +154,7 @@ static vm_store_ops anonymous_ops = {
|
|||||||
&anonymous_read,
|
&anonymous_read,
|
||||||
&anonymous_write,
|
&anonymous_write,
|
||||||
&anonymous_fault,
|
&anonymous_fault,
|
||||||
|
NULL, // acquire unreferenced ref
|
||||||
NULL, // acquire ref
|
NULL, // acquire ref
|
||||||
NULL // release ref
|
NULL // release ref
|
||||||
};
|
};
|
||||||
|
@ -78,8 +78,9 @@ static vm_store_ops device_ops = {
|
|||||||
&device_read,
|
&device_read,
|
||||||
&device_write,
|
&device_write,
|
||||||
&device_fault,
|
&device_fault,
|
||||||
NULL,
|
NULL, // acquire unreferenced ref
|
||||||
NULL
|
NULL, // acquire ref
|
||||||
|
NULL // release ref
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,8 +67,9 @@ static vm_store_ops null_ops = {
|
|||||||
&null_read,
|
&null_read,
|
||||||
&null_write,
|
&null_write,
|
||||||
&null_fault,
|
&null_fault,
|
||||||
NULL,
|
NULL, // acquire unreferenced ref
|
||||||
NULL
|
NULL, // acquire ref
|
||||||
|
NULL // release ref
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user