summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2022-09-18 17:10:33 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2022-10-03 23:54:26 -0400
commitab140ac5142494649f0b022d49b44077f7b93a34 (patch)
tree640f544675076170d05a5b9ce9358b6cf4f54bfa
parent96860718b7f6b4d2a84eaeb9d79240d9dd5cb2e9 (diff)
bcachefs: Add private error codes for ENOSPC
Continuing the saga of introducing private dedicated error codes for each error path, this patch converts ENOSPC to error codes that are subtypes of ENOSPC. We've recently had a test failure where we got -ENOSPC where we shouldn't have, and didn't have enough information to tell where it came from, so this patch will solve that problem. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/alloc_foreground.c4
-rw-r--r--fs/bcachefs/btree_update_leaf.c8
-rw-r--r--fs/bcachefs/buckets.c2
-rw-r--r--fs/bcachefs/disk_groups.c2
-rw-r--r--fs/bcachefs/ec.c4
-rw-r--r--fs/bcachefs/errcode.h14
-rw-r--r--fs/bcachefs/fs-io.c4
-rw-r--r--fs/bcachefs/inode.c2
-rw-r--r--fs/bcachefs/journal.c13
-rw-r--r--fs/bcachefs/journal_sb.c2
-rw-r--r--fs/bcachefs/quota.c2
-rw-r--r--fs/bcachefs/replicas.c16
-rw-r--r--fs/bcachefs/str_hash.h4
-rw-r--r--fs/bcachefs/subvolume.c4
-rw-r--r--fs/bcachefs/super-io.c2
-rw-r--r--fs/bcachefs/super.c6
16 files changed, 54 insertions, 35 deletions
diff --git a/fs/bcachefs/alloc_foreground.c b/fs/bcachefs/alloc_foreground.c
index dce227c54a7e..8d1c7797f25a 100644
--- a/fs/bcachefs/alloc_foreground.c
+++ b/fs/bcachefs/alloc_foreground.c
@@ -1223,7 +1223,9 @@ err:
if (bch2_err_matches(ret, BCH_ERR_open_buckets_empty) ||
bch2_err_matches(ret, BCH_ERR_freelist_empty))
- return cl ? ERR_PTR(-EAGAIN) : ERR_PTR(-ENOSPC);
+ return cl
+ ? ERR_PTR(-EAGAIN)
+ : ERR_PTR(-BCH_ERR_ENOSPC_bucket_alloc);
if (bch2_err_matches(ret, BCH_ERR_insufficient_devices))
return ERR_PTR(-EROFS);
diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c
index 5d6b189cabcc..3b3024177b40 100644
--- a/fs/bcachefs/btree_update_leaf.c
+++ b/fs/bcachefs/btree_update_leaf.c
@@ -1031,9 +1031,11 @@ int bch2_trans_commit_error(struct btree_trans *trans,
}
BUG_ON(bch2_err_matches(ret, BCH_ERR_transaction_restart) != !!trans->restarted);
- BUG_ON(ret == -ENOSPC &&
- !(trans->flags & BTREE_INSERT_NOWAIT) &&
- (trans->flags & BTREE_INSERT_NOFAIL));
+
+ bch2_fs_inconsistent_on(bch2_err_matches(ret, ENOSPC) &&
+ !(trans->flags & BTREE_INSERT_NOWAIT) &&
+ (trans->flags & BTREE_INSERT_NOFAIL), c,
+ "%s: incorrectly got %s\n", __func__, bch2_err_str(ret));
return ret;
}
diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c
index b4be2122c2d5..8af0dd022fda 100644
--- a/fs/bcachefs/buckets.c
+++ b/fs/bcachefs/buckets.c
@@ -1999,7 +1999,7 @@ recalculate:
ret = 0;
} else {
atomic64_set(&c->sectors_available, sectors_available);
- ret = -ENOSPC;
+ ret = -BCH_ERR_ENOSPC_disk_reservation;
}
mutex_unlock(&c->sectors_available_lock);
diff --git a/fs/bcachefs/disk_groups.c b/fs/bcachefs/disk_groups.c
index 5f405d38b3de..6b81f35861ac 100644
--- a/fs/bcachefs/disk_groups.c
+++ b/fs/bcachefs/disk_groups.c
@@ -276,7 +276,7 @@ static int __bch2_disk_group_add(struct bch_sb_handle *sb, unsigned parent,
groups = bch2_sb_resize_disk_groups(sb, u64s);
if (!groups)
- return -ENOSPC;
+ return -BCH_ERR_ENOSPC_disk_label_add;
nr_groups = disk_groups_nr(groups);
}
diff --git a/fs/bcachefs/ec.c b/fs/bcachefs/ec.c
index f33acf1af110..aa8301146382 100644
--- a/fs/bcachefs/ec.c
+++ b/fs/bcachefs/ec.c
@@ -731,7 +731,7 @@ static int ec_stripe_bkey_insert(struct btree_trans *trans,
continue;
}
- ret = -ENOSPC;
+ ret = -BCH_ERR_ENOSPC_stripe_create;
break;
}
@@ -1388,7 +1388,7 @@ static int __bch2_ec_stripe_head_reuse(struct bch_fs *c,
idx = get_existing_stripe(c, h);
if (idx < 0) {
bch_err(c, "failed to find an existing stripe");
- return -ENOSPC;
+ return -BCH_ERR_ENOSPC_stripe_reuse;
}
h->s->have_existing_stripe = true;
diff --git a/fs/bcachefs/errcode.h b/fs/bcachefs/errcode.h
index 6980416bb0b5..135d9eba6203 100644
--- a/fs/bcachefs/errcode.h
+++ b/fs/bcachefs/errcode.h
@@ -3,6 +3,20 @@
#define _BCACHEFS_ERRCODE_H
#define BCH_ERRCODES() \
+ x(ENOSPC, ENOSPC_disk_reservation) \
+ x(ENOSPC, ENOSPC_bucket_alloc) \
+ x(ENOSPC, ENOSPC_disk_label_add) \
+ x(ENOSPC, ENOSPC_stripe_create) \
+ x(ENOSPC, ENOSPC_stripe_reuse) \
+ x(ENOSPC, ENOSPC_inode_create) \
+ x(ENOSPC, ENOSPC_str_hash_create) \
+ x(ENOSPC, ENOSPC_snapshot_create) \
+ x(ENOSPC, ENOSPC_subvolume_create) \
+ x(ENOSPC, ENOSPC_sb) \
+ x(ENOSPC, ENOSPC_sb_journal) \
+ x(ENOSPC, ENOSPC_sb_quota) \
+ x(ENOSPC, ENOSPC_sb_replicas) \
+ x(ENOSPC, ENOSPC_sb_members) \
x(0, open_buckets_empty) \
x(0, freelist_empty) \
x(BCH_ERR_freelist_empty, no_buckets_found) \
diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c
index 0956b44776da..c99fc56fb7cf 100644
--- a/fs/bcachefs/fs-io.c
+++ b/fs/bcachefs/fs-io.c
@@ -3020,7 +3020,7 @@ bkey_err:
bch2_trans_unlock(&trans); /* lock ordering, before taking pagecache locks: */
mark_pagecache_reserved(inode, start_sector, iter.pos.offset);
- if (ret == -ENOSPC && (mode & FALLOC_FL_ZERO_RANGE)) {
+ if (bch2_err_matches(ret, ENOSPC) && (mode & FALLOC_FL_ZERO_RANGE)) {
struct quota_res quota_res = { 0 };
s64 i_sectors_delta = 0;
@@ -3071,7 +3071,7 @@ static long bchfs_fallocate(struct bch_inode_info *inode, int mode,
* so that the VFS cache i_size is consistent with the btree i_size:
*/
if (ret &&
- !(ret == -ENOSPC && (mode & FALLOC_FL_ZERO_RANGE)))
+ !(bch2_err_matches(ret, ENOSPC) && (mode & FALLOC_FL_ZERO_RANGE)))
return ret;
if (mode & FALLOC_FL_KEEP_SIZE && end > inode->v.i_size)
diff --git a/fs/bcachefs/inode.c b/fs/bcachefs/inode.c
index 083106006747..1f2782fc5a2d 100644
--- a/fs/bcachefs/inode.c
+++ b/fs/bcachefs/inode.c
@@ -567,7 +567,7 @@ again:
}
if (!ret && start == min)
- ret = -ENOSPC;
+ ret = -BCH_ERR_ENOSPC_inode_create;
if (ret) {
bch2_trans_iter_exit(trans, iter);
diff --git a/fs/bcachefs/journal.c b/fs/bcachefs/journal.c
index 3e8972c22b5c..ab594623341f 100644
--- a/fs/bcachefs/journal.c
+++ b/fs/bcachefs/journal.c
@@ -809,14 +809,16 @@ static int __bch2_set_nr_journal_buckets(struct bch_dev *ca, unsigned nr,
if (new_fs) {
bu[nr_got] = bch2_bucket_alloc_new_fs(ca);
if (bu[nr_got] < 0) {
- ret = -ENOSPC;
+ ret = -BCH_ERR_ENOSPC_bucket_alloc;
break;
}
} else {
ob[nr_got] = bch2_bucket_alloc(c, ca, RESERVE_none,
false, cl);
if (IS_ERR(ob[nr_got])) {
- ret = cl ? -EAGAIN : -ENOSPC;
+ ret = cl
+ ? -EAGAIN
+ : -BCH_ERR_ENOSPC_bucket_alloc;
break;
}
@@ -943,10 +945,11 @@ int bch2_set_nr_journal_buckets(struct bch_fs *c, struct bch_dev *ca,
* reservation to ensure we'll actually be able to allocate:
*/
- if (bch2_disk_reservation_get(c, &disk_res,
- bucket_to_sector(ca, nr - ja->nr), 1, 0)) {
+ ret = bch2_disk_reservation_get(c, &disk_res,
+ bucket_to_sector(ca, nr - ja->nr), 1, 0);
+ if (ret) {
mutex_unlock(&c->sb_lock);
- return -ENOSPC;
+ return ret;
}
ret = __bch2_set_nr_journal_buckets(ca, nr, false, &cl);
diff --git a/fs/bcachefs/journal_sb.c b/fs/bcachefs/journal_sb.c
index 001cecec1291..cfdbd92d2164 100644
--- a/fs/bcachefs/journal_sb.c
+++ b/fs/bcachefs/journal_sb.c
@@ -197,7 +197,7 @@ int bch2_journal_buckets_to_sb(struct bch_fs *c, struct bch_dev *ca)
j = bch2_sb_resize_journal_v2(&ca->disk_sb,
(sizeof(*j) + sizeof(j->d[0]) * nr) / sizeof(u64));
if (!j)
- return -ENOSPC;
+ return -BCH_ERR_ENOSPC_sb_journal;
bch2_sb_field_delete(&ca->disk_sb, BCH_SB_FIELD_journal);
diff --git a/fs/bcachefs/quota.c b/fs/bcachefs/quota.c
index 454c76e03be9..c12d715fb758 100644
--- a/fs/bcachefs/quota.c
+++ b/fs/bcachefs/quota.c
@@ -665,7 +665,7 @@ static int bch2_quota_set_info(struct super_block *sb, int type,
sb_quota = bch2_sb_resize_quota(&c->disk_sb,
sizeof(*sb_quota) / sizeof(u64));
if (!sb_quota)
- return -ENOSPC;
+ return -BCH_ERR_ENOSPC_sb_quota;
}
if (info->i_fieldmask & QC_SPC_TIMER)
diff --git a/fs/bcachefs/replicas.c b/fs/bcachefs/replicas.c
index 9cb47ba62bc3..fcf73d723035 100644
--- a/fs/bcachefs/replicas.c
+++ b/fs/bcachefs/replicas.c
@@ -478,7 +478,7 @@ int bch2_replicas_gc_end(struct bch_fs *c, int ret)
bch2_fs_usage_read_one(c, &c->usage_base->replicas[i])) {
n = cpu_replicas_add_entry(&c->replicas_gc, e);
if (!n.entries) {
- ret = -ENOSPC;
+ ret = -ENOMEM;
goto err;
}
@@ -487,10 +487,9 @@ int bch2_replicas_gc_end(struct bch_fs *c, int ret)
}
}
- if (bch2_cpu_replicas_to_sb_replicas(c, &c->replicas_gc)) {
- ret = -ENOSPC;
+ ret = bch2_cpu_replicas_to_sb_replicas(c, &c->replicas_gc);
+ if (ret)
goto err;
- }
ret = replicas_table_update(c, &c->replicas_gc);
err:
@@ -593,10 +592,9 @@ retry:
bch2_cpu_replicas_sort(&new);
- if (bch2_cpu_replicas_to_sb_replicas(c, &new)) {
- ret = -ENOSPC;
+ ret = bch2_cpu_replicas_to_sb_replicas(c, &new);
+ if (ret)
goto err;
- }
ret = replicas_table_update(c, &new);
err:
@@ -751,7 +749,7 @@ static int bch2_cpu_replicas_to_sb_replicas_v0(struct bch_fs *c,
sb_r = bch2_sb_resize_replicas_v0(&c->disk_sb,
DIV_ROUND_UP(bytes, sizeof(u64)));
if (!sb_r)
- return -ENOSPC;
+ return -BCH_ERR_ENOSPC_sb_replicas;
bch2_sb_field_delete(&c->disk_sb, BCH_SB_FIELD_replicas);
sb_r = bch2_sb_get_replicas_v0(c->disk_sb.sb);
@@ -796,7 +794,7 @@ static int bch2_cpu_replicas_to_sb_replicas(struct bch_fs *c,
sb_r = bch2_sb_resize_replicas(&c->disk_sb,
DIV_ROUND_UP(bytes, sizeof(u64)));
if (!sb_r)
- return -ENOSPC;
+ return -BCH_ERR_ENOSPC_sb_replicas;
bch2_sb_field_delete(&c->disk_sb, BCH_SB_FIELD_replicas_v0);
sb_r = bch2_sb_get_replicas(c->disk_sb.sb);
diff --git a/fs/bcachefs/str_hash.h b/fs/bcachefs/str_hash.h
index 560983df13f0..6178ae620ff1 100644
--- a/fs/bcachefs/str_hash.h
+++ b/fs/bcachefs/str_hash.h
@@ -207,7 +207,7 @@ bch2_hash_hole(struct btree_trans *trans,
return 0;
bch2_trans_iter_exit(trans, iter);
- return ret ?: -ENOSPC;
+ return ret ?: -BCH_ERR_ENOSPC_str_hash_create;
}
static __always_inline
@@ -277,7 +277,7 @@ int bch2_hash_set_snapshot(struct btree_trans *trans,
}
if (!ret)
- ret = -ENOSPC;
+ ret = -BCH_ERR_ENOSPC_str_hash_create;
out:
bch2_trans_iter_exit(trans, &slot);
bch2_trans_iter_exit(trans, &iter);
diff --git a/fs/bcachefs/subvolume.c b/fs/bcachefs/subvolume.c
index fb3f8e4074c7..8c98bacca290 100644
--- a/fs/bcachefs/subvolume.c
+++ b/fs/bcachefs/subvolume.c
@@ -517,7 +517,7 @@ int bch2_snapshot_node_create(struct btree_trans *trans, u32 parent,
goto err;
if (!k.k || !k.k->p.offset) {
- ret = -ENOSPC;
+ ret = -BCH_ERR_ENOSPC_snapshot_create;
goto err;
}
@@ -1031,7 +1031,7 @@ int bch2_subvolume_create(struct btree_trans *trans, u64 inode,
}
if (!ret)
- ret = -ENOSPC;
+ ret = -BCH_ERR_ENOSPC_subvolume_create;
goto err;
found_slot:
snapshot_subvols[0] = dst_iter.pos.offset;
diff --git a/fs/bcachefs/super-io.c b/fs/bcachefs/super-io.c
index c72632f67a5e..25cfb8aa0826 100644
--- a/fs/bcachefs/super-io.c
+++ b/fs/bcachefs/super-io.c
@@ -130,7 +130,7 @@ int bch2_sb_realloc(struct bch_sb_handle *sb, unsigned u64s)
if (new_bytes > max_bytes) {
pr_err("%pg: superblock too big: want %zu but have %llu",
sb->bdev, new_bytes, max_bytes);
- return -ENOSPC;
+ return -BCH_ERR_ENOSPC_sb;
}
}
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
index f0e7c116fb4f..3ee6545a8721 100644
--- a/fs/bcachefs/super.c
+++ b/fs/bcachefs/super.c
@@ -1592,7 +1592,7 @@ int bch2_dev_add(struct bch_fs *c, const char *path)
le32_to_cpu(mi->field.u64s) +
sizeof(dev_mi) / sizeof(u64))) {
bch_err(c, "device add error: new device superblock too small");
- ret = -ENOSPC;
+ ret = -BCH_ERR_ENOSPC_sb_members;
goto err_unlock;
}
@@ -1605,7 +1605,7 @@ int bch2_dev_add(struct bch_fs *c, const char *path)
goto have_slot;
no_slot:
bch_err(c, "device add error: already have maximum number of devices");
- ret = -ENOSPC;
+ ret = -BCH_ERR_ENOSPC_sb_members;
goto err_unlock;
have_slot:
@@ -1616,7 +1616,7 @@ have_slot:
mi = bch2_sb_resize_members(&c->disk_sb, u64s);
if (!mi) {
bch_err(c, "device add error: no room in superblock for member info");
- ret = -ENOSPC;
+ ret = -BCH_ERR_ENOSPC_sb_members;
goto err_unlock;
}