summaryrefslogtreecommitdiffstats
path: root/fs/bcachefs/nocow_locking.h
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2022-12-14 20:52:11 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:09:52 -0400
commit350175bf9b0fe5da12a2fd8bfd453a49f038ceb4 (patch)
tree6118c2363f0ee7570b8d9ac6440b13217b8c322e /fs/bcachefs/nocow_locking.h
parentf3a37e76cade1469871c4309584ebbc358becf40 (diff)
downloadlinux-350175bf9b0fe5da12a2fd8bfd453a49f038ceb4.tar.gz
linux-350175bf9b0fe5da12a2fd8bfd453a49f038ceb4.tar.bz2
linux-350175bf9b0fe5da12a2fd8bfd453a49f038ceb4.zip
bcachefs: Improved nocow locking
This improves the nocow lock table so that hash table entries have multiple locks, and locks specify which bucket they're for - i.e. we can now resolve hash collisions. This is important because the allocator has to skip buckets that are locked in the nocow lock table, and previously hash collisions would cause it to spuriously skip unlocked buckets. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/nocow_locking.h')
-rw-r--r--fs/bcachefs/nocow_locking.h54
1 files changed, 24 insertions, 30 deletions
diff --git a/fs/bcachefs/nocow_locking.h b/fs/bcachefs/nocow_locking.h
index 2a7a9f44e88e..ff8e4af52edc 100644
--- a/fs/bcachefs/nocow_locking.h
+++ b/fs/bcachefs/nocow_locking.h
@@ -2,54 +2,48 @@
#ifndef _BCACHEFS_NOCOW_LOCKING_H
#define _BCACHEFS_NOCOW_LOCKING_H
-#include "bcachefs_format.h"
-#include "two_state_shared_lock.h"
+#include "bcachefs.h"
+#include "alloc_background.h"
+#include "nocow_locking_types.h"
#include <linux/hash.h>
-#define BUCKET_NOCOW_LOCKS_BITS 10
-#define BUCKET_NOCOW_LOCKS (1U << BUCKET_NOCOW_LOCKS_BITS)
-
-struct bucket_nocow_lock_table {
- two_state_lock_t l[BUCKET_NOCOW_LOCKS];
-};
-
-#define BUCKET_NOCOW_LOCK_UPDATE (1 << 0)
-
-static inline two_state_lock_t *bucket_nocow_lock(struct bucket_nocow_lock_table *t,
- struct bpos bucket)
+static inline struct nocow_lock_bucket *bucket_nocow_lock(struct bucket_nocow_lock_table *t,
+ u64 dev_bucket)
{
- u64 dev_bucket = bucket.inode << 56 | bucket.offset;
unsigned h = hash_64(dev_bucket, BUCKET_NOCOW_LOCKS_BITS);
return t->l + (h & (BUCKET_NOCOW_LOCKS - 1));
}
-static inline bool bch2_bucket_nocow_is_locked(struct bucket_nocow_lock_table *t,
- struct bpos bucket)
-{
- two_state_lock_t *l = bucket_nocow_lock(t, bucket);
+#define BUCKET_NOCOW_LOCK_UPDATE (1 << 0)
- return atomic_long_read(&l->v) != 0;
-}
+bool bch2_bucket_nocow_is_locked(struct bucket_nocow_lock_table *, struct bpos);
+void bch2_bucket_nocow_unlock(struct bucket_nocow_lock_table *, struct bpos, int);
+bool __bch2_bucket_nocow_trylock(struct nocow_lock_bucket *, u64, int);
+void __bch2_bucket_nocow_lock(struct bucket_nocow_lock_table *,
+ struct nocow_lock_bucket *, u64, int);
-static inline void bch2_bucket_nocow_unlock(struct bucket_nocow_lock_table *t,
- struct bpos bucket, int flags)
+static inline void bch2_bucket_nocow_lock(struct bucket_nocow_lock_table *t,
+ struct bpos bucket, int flags)
{
- two_state_lock_t *l = bucket_nocow_lock(t, bucket);
+ u64 dev_bucket = bucket_to_u64(bucket);
+ struct nocow_lock_bucket *l = bucket_nocow_lock(t, dev_bucket);
- bch2_two_state_unlock(l, flags & BUCKET_NOCOW_LOCK_UPDATE);
+ __bch2_bucket_nocow_lock(t, l, dev_bucket, flags);
}
-void __bch2_bucket_nocow_lock(struct bucket_nocow_lock_table *, two_state_lock_t *, int);
-
-static inline void bch2_bucket_nocow_lock(struct bucket_nocow_lock_table *t,
+static inline bool bch2_bucket_nocow_trylock(struct bucket_nocow_lock_table *t,
struct bpos bucket, int flags)
{
- two_state_lock_t *l = bucket_nocow_lock(t, bucket);
+ u64 dev_bucket = bucket_to_u64(bucket);
+ struct nocow_lock_bucket *l = bucket_nocow_lock(t, dev_bucket);
- if (!bch2_two_state_trylock(l, flags & BUCKET_NOCOW_LOCK_UPDATE))
- __bch2_bucket_nocow_lock(t, l, flags);
+ return __bch2_bucket_nocow_trylock(l, dev_bucket, flags);
}
+void bch2_nocow_locks_to_text(struct printbuf *, struct bucket_nocow_lock_table *);
+
+int bch2_fs_nocow_locking_init(struct bch_fs *);
+
#endif /* _BCACHEFS_NOCOW_LOCKING_H */