summaryrefslogtreecommitdiff
path: root/fs/bcachefs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/bcachefs')
-rw-r--r--fs/bcachefs/btree_iter.c49
-rw-r--r--fs/bcachefs/btree_locking.c8
-rw-r--r--fs/bcachefs/btree_locking.h9
-rw-r--r--fs/bcachefs/darray.h1
-rw-r--r--fs/bcachefs/fs.c16
5 files changed, 64 insertions, 19 deletions
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
index f1f4efc94589..401cfd727a12 100644
--- a/fs/bcachefs/btree_iter.c
+++ b/fs/bcachefs/btree_iter.c
@@ -2913,6 +2913,8 @@ unsigned bch2_trans_get_fn_idx(const char *fn)
return i;
}
+static struct lock_class_key key;
+
struct btree_trans *__bch2_trans_get(struct bch_fs *c, unsigned fn_idx)
__acquires(&c->btree_trans_barrier)
{
@@ -2976,8 +2978,8 @@ got_trans:
trans->paths_allocated[0] = 1;
- static struct lock_class_key lockdep_key;
- lockdep_init_map(&trans->dep_map, "bcachefs_btree", &lockdep_key, 0);
+ //lockdep_init_map(&trans->dep_map, "bcachefs_btree", &key, 0);
+ lockdep_init_map_wait(&trans->dep_map, "bcachefs_btree", &key, 0, LD_WAIT_SLEEP);
if (fn_idx < BCH_TRANSACTIONS_NR) {
trans->fn = bch2_btree_transaction_fns[fn_idx];
@@ -3226,6 +3228,10 @@ void bch2_fs_btree_iter_init_early(struct bch_fs *c)
seqmutex_init(&c->btree_trans_lock);
}
+#include <linux/delay.h>
+
+static DEFINE_MUTEX(test_mutex);
+
int bch2_fs_btree_iter_init(struct bch_fs *c)
{
int ret;
@@ -3242,15 +3248,46 @@ int bch2_fs_btree_iter_init(struct bch_fs *c)
if (ret)
return ret;
-#ifdef CONFIG_LOCKDEP
+ struct btree_trans *trans;
+#if 0
fs_reclaim_acquire(GFP_KERNEL);
- struct btree_trans *trans = bch2_trans_get(c);
- lock_acquire_exclusive(&trans->dep_map, 0, 0, NULL, _THIS_IP_);
+ mutex_lock(&test_mutex);
+ mutex_unlock(&test_mutex);
+ fs_reclaim_release(GFP_KERNEL);
+
+ mutex_lock(&test_mutex);
+ fs_reclaim_acquire(GFP_KERNEL);
+ fs_reclaim_release(GFP_KERNEL);
+ mutex_unlock(&test_mutex);
+
+ mutex_lock(&test_mutex);
+ trans = bch2_trans_get(c);
+ lock_map_acquire(&trans->dep_map);
trans->locks_held = true;
bch2_trans_put(trans);
- fs_reclaim_release(GFP_KERNEL);
+ mutex_unlock(&test_mutex);
+ trans = bch2_trans_get(c);
+ lock_map_acquire(&trans->dep_map);
+ trans->locks_held = true;
+ mutex_lock(&test_mutex);
+ mutex_unlock(&test_mutex);
+ bch2_trans_put(trans);
#endif
+ fs_reclaim_acquire(GFP_KERNEL);
+ trans = bch2_trans_get(c);
+ lock_map_acquire(&trans->dep_map);
+ trans->locks_held = true;
+ bch2_trans_put(trans);
+ fs_reclaim_release(GFP_KERNEL);
+
+ trans = bch2_trans_get(c);
+ lock_map_acquire(&trans->dep_map);
+ trans->locks_held = true;
+ fs_reclaim_acquire(GFP_KERNEL);
+ fs_reclaim_release(GFP_KERNEL);
+ bch2_trans_put(trans);
+
c->btree_trans_barrier_initialized = true;
return 0;
diff --git a/fs/bcachefs/btree_locking.c b/fs/bcachefs/btree_locking.c
index a5ae421073d0..707ef5872b6c 100644
--- a/fs/bcachefs/btree_locking.c
+++ b/fs/bcachefs/btree_locking.c
@@ -629,6 +629,12 @@ __flatten
bool bch2_btree_path_relock_norestart(struct btree_trans *trans,
struct btree_path *path, unsigned long trace_ip)
{
+#ifdef CONFIG_LOCKDEP
+ if (!trans->locks_held) {
+ lock_map_acquire(&trans->dep_map);
+ trans->locks_held = true;
+ }
+#endif
struct get_locks_fail f;
return btree_path_get_locks(trans, path, false, &f);
@@ -805,7 +811,7 @@ void bch2_trans_unlock(struct btree_trans *trans)
#ifdef CONFIG_LOCKDEP
if (trans->locks_held) {
- lock_release(&trans->dep_map, _THIS_IP_);
+ lock_map_release(&trans->dep_map);
trans->locks_held = false;
}
#endif
diff --git a/fs/bcachefs/btree_locking.h b/fs/bcachefs/btree_locking.h
index 962fa8f5cf0b..5d9b5f9e3e3b 100644
--- a/fs/bcachefs/btree_locking.h
+++ b/fs/bcachefs/btree_locking.h
@@ -204,7 +204,7 @@ static inline int __btree_node_lock_nopath(struct btree_trans *trans,
{
#ifdef CONFIG_LOCKDEP
if (!trans->locks_held) {
- lock_acquire_exclusive(&trans->dep_map, 0, 0, NULL, ip);
+ lock_map_acquire(&trans->dep_map);
trans->locks_held = true;
}
#endif
@@ -271,6 +271,13 @@ static inline int btree_node_lock(struct btree_trans *trans,
EBUG_ON(level >= BTREE_MAX_DEPTH);
+#ifdef CONFIG_LOCKDEP
+ if (!trans->locks_held) {
+ lock_map_acquire(&trans->dep_map);
+ trans->locks_held = true;
+ }
+#endif
+
if (likely(six_trylock_type(&b->lock, type)) ||
btree_node_lock_increment(trans, b, level, (enum btree_node_locked_type) type) ||
!(ret = btree_node_lock_nopath(trans, b, type, btree_path_ip_allocated(path)))) {
diff --git a/fs/bcachefs/darray.h b/fs/bcachefs/darray.h
index e3aba5b61d19..e43987987047 100644
--- a/fs/bcachefs/darray.h
+++ b/fs/bcachefs/darray.h
@@ -17,6 +17,7 @@ struct { \
}
typedef DARRAY(void) darray_void;
+typedef DARRAY(char *) darray_string;
int __bch2_darray_resize(darray_void *, size_t, size_t, gfp_t);
diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c
index bc280a0a957d..e006807bc260 100644
--- a/fs/bcachefs/fs.c
+++ b/fs/bcachefs/fs.c
@@ -1596,26 +1596,20 @@ static struct bch_fs *bch2_path_to_fs(const char *path)
return c ?: ERR_PTR(-ENOENT);
}
-static char **split_devs(const char *_dev_name, unsigned *nr)
+static darray_string bch2_split_devs(const char *_dev_name, unsigned *nr)
{
char *dev_name = NULL, **devs = NULL, *s;
size_t i = 0, nr_devs = 0;
+ DARRAY(
- dev_name = kstrdup(_dev_name, GFP_KERNEL);
+ char *dev_name = kstrdup(_dev_name, GFP_KERNEL), *s = dev_name;
if (!dev_name)
return NULL;
- for (s = dev_name; s; s = strchr(s + 1, ':'))
- nr_devs++;
+ while ((s = strsep(&dev_name, ":"))) {
- devs = kcalloc(nr_devs + 1, sizeof(const char *), GFP_KERNEL);
- if (!devs) {
- kfree(dev_name);
- return NULL;
- }
-
- while ((s = strsep(&dev_name, ":")))
devs[i++] = s;
+ }
*nr = nr_devs;
return devs;