Skip to content

Commit 1740527

Browse files
author
Kent Overstreet
committed
bcachefs: bch2_sb_member_alloc()
refactoring Signed-off-by: Kent Overstreet <[email protected]>
1 parent 6b812f1 commit 1740527

File tree

3 files changed

+53
-46
lines changed

3 files changed

+53
-46
lines changed

fs/bcachefs/sb-members.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,3 +474,47 @@ unsigned bch2_sb_nr_devices(const struct bch_sb *sb)
474474
nr += bch2_member_exists((struct bch_sb *) sb, i);
475475
return nr;
476476
}
477+
478+
int bch2_sb_member_alloc(struct bch_fs *c)
479+
{
480+
unsigned dev_idx = c->sb.nr_devices;
481+
if (dev_idx < BCH_SB_MEMBERS_MAX)
482+
goto have_slot;
483+
484+
int best = -1;
485+
u64 best_last_mount = 0;
486+
for (dev_idx = 0; dev_idx < BCH_SB_MEMBERS_MAX; dev_idx++) {
487+
/* eventually BCH_SB_MEMBERS_MAX will be raised */
488+
if (dev_idx == BCH_SB_MEMBER_INVALID)
489+
continue;
490+
491+
struct bch_member m = bch2_sb_member_get(c->disk_sb.sb, dev_idx);
492+
if (bch2_member_alive(&m))
493+
continue;
494+
495+
u64 last_mount = le64_to_cpu(m.last_mount);
496+
if (best < 0 || last_mount < best_last_mount) {
497+
best = dev_idx;
498+
best_last_mount = last_mount;
499+
}
500+
}
501+
if (best >= 0) {
502+
dev_idx = best;
503+
goto have_slot;
504+
}
505+
506+
return -BCH_ERR_ENOSPC_sb_members;
507+
have_slot:
508+
unsigned nr_devices = max_t(unsigned, dev_idx + 1, c->sb.nr_devices);
509+
510+
struct bch_sb_field_members_v2 *mi = bch2_sb_field_get(c->disk_sb.sb, members_v2);
511+
unsigned u64s = DIV_ROUND_UP(sizeof(struct bch_sb_field_members_v2) +
512+
le16_to_cpu(mi->member_bytes) * nr_devices, sizeof(u64));
513+
514+
mi = bch2_sb_field_resize(&c->disk_sb, members_v2, u64s);
515+
if (!mi)
516+
return -BCH_ERR_ENOSPC_sb_members;
517+
518+
c->disk_sb.sb->nr_devices = nr_devices;
519+
return dev_idx;
520+
}

fs/bcachefs/sb-members.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,4 +354,6 @@ static inline bool bch2_dev_btree_bitmap_marked_sectors(struct bch_dev *ca, u64
354354
bool bch2_dev_btree_bitmap_marked(struct bch_fs *, struct bkey_s_c);
355355
void bch2_dev_btree_bitmap_mark(struct bch_fs *, struct bkey_s_c);
356356

357+
int bch2_sb_member_alloc(struct bch_fs *);
358+
357359
#endif /* _BCACHEFS_SB_MEMBERS_H */

fs/bcachefs/super.c

Lines changed: 7 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,9 +1703,6 @@ int bch2_dev_add(struct bch_fs *c, const char *path)
17031703
struct bch_opts opts = bch2_opts_empty();
17041704
struct bch_sb_handle sb;
17051705
struct bch_dev *ca = NULL;
1706-
struct bch_sb_field_members_v2 *mi;
1707-
struct bch_member dev_mi;
1708-
unsigned dev_idx, nr_devices, u64s;
17091706
struct printbuf errbuf = PRINTBUF;
17101707
struct printbuf label = PRINTBUF;
17111708
int ret;
@@ -1715,7 +1712,7 @@ int bch2_dev_add(struct bch_fs *c, const char *path)
17151712
if (ret)
17161713
goto err;
17171714

1718-
dev_mi = bch2_sb_member_get(sb.sb, sb.sb->dev_idx);
1715+
struct bch_member dev_mi = bch2_sb_member_get(sb.sb, sb.sb->dev_idx);
17191716

17201717
if (BCH_MEMBER_GROUP(&dev_mi)) {
17211718
bch2_disk_path_to_text_sb(&label, sb.sb, BCH_MEMBER_GROUP(&dev_mi) - 1);
@@ -1753,55 +1750,19 @@ int bch2_dev_add(struct bch_fs *c, const char *path)
17531750
goto err_unlock;
17541751

17551752
if (dynamic_fault("bcachefs:add:no_slot"))
1756-
goto no_slot;
1757-
1758-
if (c->sb.nr_devices < BCH_SB_MEMBERS_MAX) {
1759-
dev_idx = c->sb.nr_devices;
1760-
goto have_slot;
1761-
}
1762-
1763-
int best = -1;
1764-
u64 best_last_mount = 0;
1765-
for (dev_idx = 0; dev_idx < BCH_SB_MEMBERS_MAX; dev_idx++) {
1766-
struct bch_member m = bch2_sb_member_get(c->disk_sb.sb, dev_idx);
1767-
if (bch2_member_alive(&m))
1768-
continue;
1769-
1770-
u64 last_mount = le64_to_cpu(m.last_mount);
1771-
if (best < 0 || last_mount < best_last_mount) {
1772-
best = dev_idx;
1773-
best_last_mount = last_mount;
1774-
}
1775-
}
1776-
if (best >= 0) {
1777-
dev_idx = best;
1778-
goto have_slot;
1779-
}
1780-
no_slot:
1781-
ret = -BCH_ERR_ENOSPC_sb_members;
1782-
bch_err_msg(c, ret, "setting up new superblock");
1783-
goto err_unlock;
1784-
1785-
have_slot:
1786-
nr_devices = max_t(unsigned, dev_idx + 1, c->sb.nr_devices);
1787-
1788-
mi = bch2_sb_field_get(c->disk_sb.sb, members_v2);
1789-
u64s = DIV_ROUND_UP(sizeof(struct bch_sb_field_members_v2) +
1790-
le16_to_cpu(mi->member_bytes) * nr_devices, sizeof(u64));
1753+
goto err_unlock;
17911754

1792-
mi = bch2_sb_field_resize(&c->disk_sb, members_v2, u64s);
1793-
if (!mi) {
1794-
ret = -BCH_ERR_ENOSPC_sb_members;
1755+
ret = bch2_sb_member_alloc(c);
1756+
if (ret < 0) {
17951757
bch_err_msg(c, ret, "setting up new superblock");
17961758
goto err_unlock;
17971759
}
1798-
struct bch_member *m = bch2_members_v2_get_mut(c->disk_sb.sb, dev_idx);
1760+
unsigned dev_idx = ret;
17991761

18001762
/* success: */
18011763

1802-
*m = dev_mi;
1803-
m->last_mount = cpu_to_le64(ktime_get_real_seconds());
1804-
c->disk_sb.sb->nr_devices = nr_devices;
1764+
dev_mi.last_mount = cpu_to_le64(ktime_get_real_seconds());
1765+
*bch2_members_v2_get_mut(c->disk_sb.sb, dev_idx) = dev_mi;
18051766

18061767
ca->disk_sb.sb->dev_idx = dev_idx;
18071768
bch2_dev_attach(c, ca, dev_idx);

0 commit comments

Comments
 (0)