kernel/fs: Use DoublyLinkedList for the unused vnodes list.

Avoids needing a nonstandard "offsetof", and inlines more methods.
No behavioral change intended.

Also rename "next" to "hash_next" for clarity, and remove an unused
"next" field from LockWaiter.
This commit is contained in:
Augustin Cavalier 2024-11-18 13:27:31 -05:00
parent a9b5f684f1
commit 2f37cef1e4
3 changed files with 11 additions and 15 deletions

View File

@ -24,14 +24,14 @@ typedef struct vnode Vnode;
struct vnode : fs_vnode, DoublyLinkedListLinkImpl<vnode> { struct vnode : fs_vnode, DoublyLinkedListLinkImpl<vnode> {
struct vnode* next; struct vnode* hash_next;
VMCache* cache; VMCache* cache;
struct fs_mount* mount; struct fs_mount* mount;
struct vnode* covered_by; struct vnode* covered_by;
struct vnode* covers; struct vnode* covers;
struct advisory_locking* advisory_locking; struct advisory_locking* advisory_locking;
struct file_descriptor* mandatory_locked_by; struct file_descriptor* mandatory_locked_by;
list_link unused_link; DoublyLinkedListLink<struct vnode> unused_link;
ino_t id; ino_t id;
dev_t device; dev_t device;
int32 ref_count; int32 ref_count;
@ -83,7 +83,6 @@ private:
static const uint32 kBucketCount = 32; static const uint32 kBucketCount = 32;
struct LockWaiter : DoublyLinkedListLinkImpl<LockWaiter> { struct LockWaiter : DoublyLinkedListLinkImpl<LockWaiter> {
LockWaiter* next;
Thread* thread; Thread* thread;
struct vnode* vnode; struct vnode* vnode;
}; };

View File

@ -29,7 +29,9 @@ const static uint32 kMaxUnusedVnodes = 8192;
Innermost lock. Must not be held when acquiring any other lock. Innermost lock. Must not be held when acquiring any other lock.
*/ */
static mutex sUnusedVnodesLock = MUTEX_INITIALIZER("unused vnodes"); static mutex sUnusedVnodesLock = MUTEX_INITIALIZER("unused vnodes");
static list sUnusedVnodeList; typedef DoublyLinkedList<Vnode, DoublyLinkedListMemberGetLink<Vnode, &Vnode::unused_link> >
UnusedVnodeList;
static UnusedVnodeList sUnusedVnodeList;
static uint32 sUnusedVnodes = 0; static uint32 sUnusedVnodes = 0;
static const int32 kMaxHotVnodes = 1024; static const int32 kMaxHotVnodes = 1024;
@ -56,7 +58,7 @@ flush_hot_vnodes_locked()
if (vnode->IsHot()) { if (vnode->IsHot()) {
if (vnode->IsUnused()) { if (vnode->IsUnused()) {
list_add_item(&sUnusedVnodeList, vnode); sUnusedVnodeList.Add(vnode);
sUnusedVnodes++; sUnusedVnodes++;
} }
vnode->SetHot(false); vnode->SetHot(false);
@ -146,7 +148,7 @@ vnode_used(Vnode* vnode)
if (!vnode->IsHot()) { if (!vnode->IsHot()) {
MutexLocker unusedLocker(sUnusedVnodesLock); MutexLocker unusedLocker(sUnusedVnodesLock);
list_remove_item(&sUnusedVnodeList, vnode); sUnusedVnodeList.Remove(vnode);
sUnusedVnodes--; sUnusedVnodes--;
} }
} }
@ -174,7 +176,7 @@ vnode_to_be_freed(Vnode* vnode)
} }
} else if (vnode->IsUnused()) { } else if (vnode->IsUnused()) {
MutexLocker unusedLocker(sUnusedVnodesLock); MutexLocker unusedLocker(sUnusedVnodesLock);
list_remove_item(&sUnusedVnodeList, vnode); sUnusedVnodeList.Remove(vnode);
sUnusedVnodes--; sUnusedVnodes--;
} }

View File

@ -291,7 +291,7 @@ struct VnodeHash {
ValueType*& GetLink(ValueType* value) const ValueType*& GetLink(ValueType* value) const
{ {
return value->next; return value->hash_next;
} }
}; };
@ -1319,8 +1319,7 @@ free_unused_vnodes(int32 level)
// get the first node // get the first node
MutexLocker unusedVnodesLocker(sUnusedVnodesLock); MutexLocker unusedVnodesLocker(sUnusedVnodesLock);
struct vnode* vnode = (struct vnode*)list_get_first_item( struct vnode* vnode = sUnusedVnodeList.First();
&sUnusedVnodeList);
unusedVnodesLocker.Unlock(); unusedVnodesLocker.Unlock();
if (vnode == NULL) if (vnode == NULL)
@ -1336,7 +1335,7 @@ free_unused_vnodes(int32 level)
// has been touched in the meantime, i.e. it is no longer the least // has been touched in the meantime, i.e. it is no longer the least
// recently used unused vnode and we rather don't free it. // recently used unused vnode and we rather don't free it.
unusedVnodesLocker.Lock(); unusedVnodesLocker.Lock();
if (vnode != list_get_first_item(&sUnusedVnodeList)) if (vnode != sUnusedVnodeList.First())
continue; continue;
unusedVnodesLocker.Unlock(); unusedVnodesLocker.Unlock();
@ -5262,10 +5261,6 @@ vfs_init(kernel_args* args)
if (sVnodeTable == NULL || sVnodeTable->Init(VNODE_HASH_TABLE_SIZE) != B_OK) if (sVnodeTable == NULL || sVnodeTable->Init(VNODE_HASH_TABLE_SIZE) != B_OK)
panic("vfs_init: error creating vnode hash table\n"); panic("vfs_init: error creating vnode hash table\n");
struct vnode dummy_vnode;
list_init_etc(&sUnusedVnodeList, offset_of_member(dummy_vnode, unused_link));
struct fs_mount dummyMount;
sMountsTable = new(std::nothrow) MountTable(); sMountsTable = new(std::nothrow) MountTable();
if (sMountsTable == NULL if (sMountsTable == NULL
|| sMountsTable->Init(MOUNTS_HASH_TABLE_SIZE) != B_OK) || sMountsTable->Init(MOUNTS_HASH_TABLE_SIZE) != B_OK)