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>
This commit is contained in:
Kent Overstreet 2022-09-18 17:10:33 -04:00
parent 5c1ef830f6
commit 098ef98d5b
16 changed files with 55 additions and 36 deletions

View file

@ -1246,7 +1246,9 @@ int bch2_alloc_sectors_start_trans(struct btree_trans *trans,
if (bch2_err_matches(ret, BCH_ERR_open_buckets_empty) ||
bch2_err_matches(ret, BCH_ERR_freelist_empty))
return cl ? -EAGAIN : -ENOSPC;
return cl
? -EAGAIN
: -BCH_ERR_ENOSPC_bucket_alloc;
if (bch2_err_matches(ret, BCH_ERR_insufficient_devices))
return -EROFS;

View file

@ -1037,9 +1037,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;
}

View file

@ -1991,7 +1991,7 @@ int __bch2_disk_reservation_add(struct bch_fs *c, struct disk_reservation *res,
ret = 0;
} else {
atomic64_set(&c->sectors_available, sectors_available);
ret = -ENOSPC;
ret = -BCH_ERR_ENOSPC_disk_reservation;
}
mutex_unlock(&c->sectors_available_lock);

View file

@ -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);
}

View file

@ -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;

View file

@ -2,7 +2,21 @@
#ifndef _BCACHEFS_ERRCODE_H
#define _BCACHEFS_ERRCODE_H
#define BCH_ERRCODES() \
#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) \

View file

@ -3031,7 +3031,7 @@ static int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
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;
@ -3082,7 +3082,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)

View file

@ -552,7 +552,7 @@ int bch2_inode_create(struct btree_trans *trans,
goto found_slot;
if (!ret && start == min)
ret = -ENOSPC;
ret = -BCH_ERR_ENOSPC_inode_create;
if (ret) {
bch2_trans_iter_exit(trans, iter);

View file

@ -808,14 +808,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;
}
@ -942,10 +944,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);

View file

@ -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);

View file

@ -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)

View file

@ -485,7 +485,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;
}
@ -494,10 +494,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:
@ -600,10 +599,9 @@ int bch2_replicas_gc2(struct bch_fs *c)
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:
@ -758,7 +756,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);
@ -803,7 +801,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);

View file

@ -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);

View file

@ -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;

View file

@ -132,7 +132,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;
}
}

View file

@ -1584,7 +1584,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;
}
@ -1597,7 +1597,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:
@ -1608,7 +1608,7 @@ int bch2_dev_add(struct bch_fs *c, const char *path)
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;
}