-b64d9b7b192a641ef4ea036d6e465e8cfe82e83c
+259ff916050fb6a9ff742891fb8aa379924a187f
trans_for_each_path(trans, path) {
path->should_be_locked = false;
+ /*
+ * If the transaction wasn't restarted, we're presuming to be
+ * doing something new: dont keep iterators excpt the ones that
+ * are in use - except for the subvolumes btree:
+ */
+ if (!trans->restarted && path->btree_id != BTREE_ID_subvolumes)
+ path->preserve = false;
+
/*
* XXX: we probably shouldn't be doing this if the transaction
* was restarted, but currently we still overflow transaction
return -EINVAL;
}
-void bch2_sb_target_to_text(struct printbuf *out, struct bch_sb *sb, u64 v)
+void bch2_opt_target_to_text(struct printbuf *out,
+ struct bch_fs *c,
+ struct bch_sb *sb,
+ u64 v)
{
struct target t = target_decode(v);
case TARGET_NULL:
pr_buf(out, "none");
break;
- case TARGET_DEV: {
- struct bch_sb_field_members *mi = bch2_sb_get_members(sb);
- struct bch_member *m = mi->members + t.dev;
-
- if (bch2_dev_exists(sb, mi, t.dev)) {
- pr_buf(out, "Device ");
- pr_uuid(out, m->uuid.b);
- pr_buf(out, " (%u)", t.dev);
+ case TARGET_DEV:
+ if (c) {
+ struct bch_dev *ca;
+
+ rcu_read_lock();
+ ca = t.dev < c->sb.nr_devices
+ ? rcu_dereference(c->devs[t.dev])
+ : NULL;
+
+ if (ca && percpu_ref_tryget(&ca->io_ref)) {
+ char b[BDEVNAME_SIZE];
+
+ pr_buf(out, "/dev/%s",
+ bdevname(ca->disk_sb.bdev, b));
+ percpu_ref_put(&ca->io_ref);
+ } else if (ca) {
+ pr_buf(out, "offline device %u", t.dev);
+ } else {
+ pr_buf(out, "invalid device %u", t.dev);
+ }
+
+ rcu_read_unlock();
} else {
- pr_buf(out, "Bad device %u", t.dev);
+ struct bch_sb_field_members *mi = bch2_sb_get_members(sb);
+ struct bch_member *m = mi->members + t.dev;
+
+ if (bch2_dev_exists(sb, mi, t.dev)) {
+ pr_buf(out, "Device ");
+ pr_uuid(out, m->uuid.b);
+ pr_buf(out, " (%u)", t.dev);
+ } else {
+ pr_buf(out, "Bad device %u", t.dev);
+ }
}
-
break;
- }
case TARGET_GROUP:
- bch2_disk_path_to_text(out, sb, t.group);
- break;
- default:
- BUG();
- }
-}
-
-void bch2_opt_target_to_text(struct printbuf *out, struct bch_fs *c, u64 v)
-{
- struct target t = target_decode(v);
-
- switch (t.type) {
- case TARGET_NULL:
- pr_buf(out, "none");
- break;
- case TARGET_DEV: {
- struct bch_dev *ca;
-
- rcu_read_lock();
- ca = t.dev < c->sb.nr_devices
- ? rcu_dereference(c->devs[t.dev])
- : NULL;
-
- if (ca && percpu_ref_tryget(&ca->io_ref)) {
- char b[BDEVNAME_SIZE];
-
- pr_buf(out, "/dev/%s",
- bdevname(ca->disk_sb.bdev, b));
- percpu_ref_put(&ca->io_ref);
- } else if (ca) {
- pr_buf(out, "offline device %u", t.dev);
+ if (c) {
+ mutex_lock(&c->sb_lock);
+ bch2_disk_path_to_text(out, c->disk_sb.sb, t.group);
+ mutex_unlock(&c->sb_lock);
} else {
- pr_buf(out, "invalid device %u", t.dev);
+ bch2_disk_path_to_text(out, sb, t.group);
}
-
- rcu_read_unlock();
- break;
- }
- case TARGET_GROUP:
- mutex_lock(&c->sb_lock);
- bch2_disk_path_to_text(out, c->disk_sb.sb, t.group);
- mutex_unlock(&c->sb_lock);
break;
default:
BUG();
void bch2_disk_path_to_text(struct printbuf *, struct bch_sb *, unsigned);
-void bch2_sb_target_to_text(struct printbuf *, struct bch_sb *, u64);
-
int bch2_opt_target_parse(struct bch_fs *, const char *, u64 *);
-void bch2_opt_target_to_text(struct printbuf *, struct bch_fs *, u64);
+void bch2_opt_target_to_text(struct printbuf *, struct bch_fs *, struct bch_sb *, u64);
int bch2_sb_disk_groups_to_cpu(struct bch_fs *);
bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
SPOS(ei->v.i_ino, start, snapshot), 0);
- while ((k = bch2_btree_iter_peek(&iter)).k &&
+ while (!(ret = btree_trans_too_many_iters(&trans)) &&
+ (k = bch2_btree_iter_peek(&iter)).k &&
!(ret = bkey_err(k)) &&
bkey_cmp(iter.pos, end) < 0) {
enum btree_id data_btree = BTREE_ID_extents;
bch2_btree_iter_set_pos(&iter,
POS(iter.pos.inode, iter.pos.offset + sectors));
-
- if (btree_trans_too_many_iters(&trans))
- goto retry;
}
start = iter.pos.offset;
bch2_trans_iter_exit(&trans, &iter);
continue;
printbuf_reset(&buf);
- bch2_opt_to_text(&buf, c, opt, v,
+ bch2_opt_to_text(&buf, c, c->disk_sb.sb, opt, v,
OPT_SHOW_MOUNT_STYLE);
seq_putc(seq, ',');
seq_puts(seq, buf.buf);
return bch2_opt_validate(opt, msg, *res);
}
-void bch2_opt_to_text(struct printbuf *out, struct bch_fs *c,
+void bch2_opt_to_text(struct printbuf *out,
+ struct bch_fs *c, struct bch_sb *sb,
const struct bch_option *opt, u64 v,
unsigned flags)
{
pr_buf(out, opt->choices[v]);
break;
case BCH_OPT_FN:
- opt->to_text(out, c, v);
+ opt->to_text(out, c, sb, v);
break;
default:
BUG();
};
struct {
int (*parse)(struct bch_fs *, const char *, u64 *);
- void (*to_text)(struct printbuf *, struct bch_fs *, u64);
+ void (*to_text)(struct printbuf *, struct bch_fs *, struct bch_sb *, u64);
};
};
#define OPT_SHOW_FULL_LIST (1 << 0)
#define OPT_SHOW_MOUNT_STYLE (1 << 1)
-void bch2_opt_to_text(struct printbuf *, struct bch_fs *,
+void bch2_opt_to_text(struct printbuf *, struct bch_fs *, struct bch_sb *,
const struct bch_option *, u64, unsigned);
int bch2_opt_check_may_set(struct bch_fs *, int, u64);
pr_buf(out, "%s:", opt->attr.name);
pr_tab(out);
- bch2_opt_to_text(out, NULL, opt, v, OPT_HUMAN_READABLE|OPT_SHOW_FULL_LIST);
+ bch2_opt_to_text(out, NULL, sb, opt, v,
+ OPT_HUMAN_READABLE|OPT_SHOW_FULL_LIST);
pr_newline(out);
}
}
if (!first)
pr_buf(&p, ",");
first = false;
- bch2_opt_to_text(&p, c, opt, v, OPT_SHOW_MOUNT_STYLE);
+ bch2_opt_to_text(&p, c, c->disk_sb.sb, opt, v, OPT_SHOW_MOUNT_STYLE);
}
if (!p.pos)
int id = opt - bch2_opt_table;
u64 v = bch2_opt_get_by_id(&c->opts, id);
- bch2_opt_to_text(out, c, opt, v, OPT_SHOW_FULL_LIST);
+ bch2_opt_to_text(out, c, c->disk_sb.sb, opt, v, OPT_SHOW_FULL_LIST);
pr_char(out, '\n');
return 0;
return -ENODATA;
v = bch2_opt_get_by_id(&opts, id);
- bch2_opt_to_text(&out, c, opt, v, 0);
+ bch2_opt_to_text(&out, c, c->disk_sb.sb, opt, v, 0);
ret = out.pos;