@@ -16,6 +16,7 @@ LIBHFILES = libxfs.h \
hlist.h \
kmem.h \
list.h \
+ list_lru.h \
parent.h \
sema.h \
spinlock.h \
@@ -21,6 +21,7 @@
#include "spinlock.h"
#include "completion.h"
#include "sema.h"
+#include "list_lru.h"
#include "xfs_types.h"
#include "xfs_fs.h"
new file mode 100644
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 RedHat, Inc.
+ * All Rights Reserved.
+ */
+#ifndef __LIBXFS_LIST_LRU_H__
+#define __LIBXFS_LIST_LRU_H__
+
+/*
+ * This implements kernel compatible list_lru semantics that the buffer cache
+ * requires. It is not meant as a hugely scalable lru list like the kernel, but
+ * just what is needed for the buffer cache to function in userspace.
+ */
+struct list_lru {
+ struct list_head l_lru;
+ spinlock_t l_lock;
+ uint64_t l_count;
+};
+
+static inline bool
+list_lru_add(
+ struct list_lru *lru,
+ struct list_head *item)
+{
+ spin_lock(&lru->l_lock);
+ if (!list_empty(item)) {
+ spin_unlock(&(lru->l_lock));
+ return false;
+ }
+ list_add_tail(item, &lru->l_lru);
+ lru->l_count++;
+ spin_unlock(&(lru->l_lock));
+ return true;
+}
+
+static inline bool
+list_lru_del(
+ struct list_lru *lru,
+ struct list_head *item)
+{
+ spin_lock(&lru->l_lock);
+ if (list_empty(item)) {
+ spin_unlock(&(lru->l_lock));
+ return false;
+ }
+ list_del_init(item);
+ lru->l_count--;
+ spin_unlock(&(lru->l_lock));
+ return true;
+}
+
+static inline bool
+list_lru_init(
+ struct list_lru *lru)
+{
+ list_head_init(&lru->l_lru);
+ spin_lock_init(&lru->l_lock);
+ lru->l_count = 0;
+ return false;
+}
+
+static inline void
+list_lru_destroy(
+ struct list_lru *lru)
+{
+ return;
+}
+
+#endif /* __LIBXFS_LIST_LRU_H__ */
@@ -78,11 +78,16 @@ xfs_buftarg_alloc(
if (xfs_buftarg_setsize_early(btp))
goto error_free;
- if (percpu_counter_init(&btp->bt_io_count, 0, GFP_KERNEL))
+ if (list_lru_init(&btp->bt_lru))
goto error_free;
+ if (percpu_counter_init(&btp->bt_io_count, 0, GFP_KERNEL))
+ goto error_lru;
+
return btp;
+error_lru:
+ list_lru_destroy(&btp->bt_lru);
error_free:
free(btp);
return NULL;
@@ -72,6 +72,7 @@ struct xfs_buf {
struct list_head b_btc_list;
unsigned int b_state;
atomic_t b_lru_ref;
+ struct list_head b_lru;
};
bool xfs_verify_magic(struct xfs_buf *bp, __be32 dmagic);
@@ -51,6 +51,7 @@
#include "spinlock.h"
#include "completion.h"
#include "sema.h"
+#include "list_lru.h"
#include "xfs_types.h"
#include "xfs_arch.h"
@@ -41,6 +41,7 @@ struct xfs_buftarg {
uint32_t bt_io_count;
unsigned int flags;
+ struct list_lru bt_lru;
};
/* We purged a dirty buffer and lost a write. */