k.k->p, bkey_start_pos(&insert->k)) ?:
                        bch2_insert_snapshot_whiteouts(trans, m->btree_id,
                                                k.k->p, insert->k.p) ?:
-                       bch2_bkey_set_needs_rebalance(c, insert,
-                                                     op->opts.background_target,
-                                                     op->opts.background_compression) ?:
+                       bch2_bkey_set_needs_rebalance(c, insert, &op->opts) ?:
                        bch2_trans_update(trans, &iter, insert,
                                BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE) ?:
                        bch2_trans_commit(trans, &op->res,
                BCH_WRITE_DATA_ENCODED|
                BCH_WRITE_MOVE|
                m->data_opts.write_flags;
-       m->op.compression_opt   = io_opts.background_compression ?: io_opts.compression;
+       m->op.compression_opt   = background_compression(io_opts);
        m->op.watermark         = m->data_opts.btree_insert_flags & BCH_WATERMARK_MASK;
 
        bkey_for_each_ptr(ptrs, ptr)
 
 }
 
 int bch2_bkey_set_needs_rebalance(struct bch_fs *c, struct bkey_i *_k,
-                                 unsigned target, unsigned compression)
+                                 struct bch_io_opts *opts)
 {
        struct bkey_s k = bkey_i_to_s(_k);
        struct bch_extent_rebalance *r;
+       unsigned target = opts->background_target;
+       unsigned compression = background_compression(*opts);
        bool needs_rebalance;
 
        if (!bkey_extent_is_direct_data(k.k))
 
 bool bch2_bkey_needs_rebalance(struct bch_fs *, struct bkey_s_c);
 
 int bch2_bkey_set_needs_rebalance(struct bch_fs *, struct bkey_i *,
-                                 unsigned, unsigned);
+                                 struct bch_io_opts *);
 
 /* Generic extent code: */
 
 
 
                op->v.pos = cpu_to_le64(insert ? bkey_start_offset(&delete.k) : delete.k.p.offset);
 
-               ret =   bch2_bkey_set_needs_rebalance(c, copy,
-                                       opts.background_target,
-                                       opts.background_compression) ?:
+               ret =   bch2_bkey_set_needs_rebalance(c, copy, &opts) ?:
                        bch2_btree_insert_trans(trans, BTREE_ID_extents, &delete, 0) ?:
                        bch2_btree_insert_trans(trans, BTREE_ID_extents, copy, 0) ?:
                        bch2_logged_op_update(trans, &op->k_i) ?:
 
                                     bkey_start_pos(&sk.k->k),
                                     BTREE_ITER_SLOTS|BTREE_ITER_INTENT);
 
-               ret =   bch2_bkey_set_needs_rebalance(c, sk.k,
-                                       op->opts.background_target,
-                                       op->opts.background_compression) ?:
+               ret =   bch2_bkey_set_needs_rebalance(c, sk.k, &op->opts) ?:
                        bch2_extent_update(trans, inum, &iter, sk.k,
                                        &op->res,
                                        op->new_i_size, &op->i_sectors_delta,
 
 
        prt_str(out, "compression: ");
        prt_tab(out);
-       bch2_compression_opt_to_text(out, io_opts->background_compression ?: io_opts->compression);
+       bch2_compression_opt_to_text(out, background_compression(*io_opts));
        prt_newline(out);
 
        prt_str(out, "extra replicas: ");
 
 #undef x
 };
 
+static inline unsigned background_compression(struct bch_io_opts opts)
+{
+       return opts.background_compression ?: opts.compression;
+}
+
 struct bch_io_opts bch2_opts_to_inode_opts(struct bch_opts);
 bool bch2_opt_is_inode_opt(enum bch_opt_id);
 
 
 
        if (k.k->p.inode) {
                target          = io_opts->background_target;
-               compression     = io_opts->background_compression ?: io_opts->compression;
+               compression     = background_compression(*io_opts);
        } else {
                const struct bch_extent_rebalance *r = bch2_bkey_rebalance_opts(k);
 
                target          = r ? r->target : io_opts->background_target;
-               compression     = r ? r->compression :
-                       (io_opts->background_compression ?: io_opts->compression);
+               compression     = r ? r->compression : background_compression(*io_opts);
        }
 
        data_opts->rewrite_ptrs         = bch2_bkey_ptrs_need_rebalance(c, k, target, compression);
 
                                min(src_k.k->p.offset - src_want.offset,
                                    dst_end.offset - dst_iter.pos.offset));
 
-               ret =   bch2_bkey_set_needs_rebalance(c, new_dst.k,
-                                       opts.background_target,
-                                       opts.background_compression) ?:
+               ret =   bch2_bkey_set_needs_rebalance(c, new_dst.k, &opts) ?:
                        bch2_extent_update(trans, dst_inum, &dst_iter,
                                        new_dst.k, &disk_res,
                                        new_i_size, i_sectors_delta,
 
        bch2_opt_set_sb(c, opt, v);
        bch2_opt_set_by_id(&c->opts, id, v);
 
-       if ((id == Opt_background_target ||
-            id == Opt_background_compression) && v)
+       if (v &&
+           (id == Opt_background_target ||
+            id == Opt_background_compression ||
+            (id == Opt_compression && !c->opts.background_compression)))
                bch2_set_rebalance_needs_scan(c, 0);
 
        ret = size;
 
        mutex_unlock(&inode->ei_update_lock);
 
        if (value &&
-           (opt_id == Opt_background_compression ||
-            opt_id == Opt_background_target))
+           (opt_id == Opt_background_target ||
+            opt_id == Opt_background_compression ||
+            (opt_id == Opt_compression && !inode_opt_get(c, &inode->ei_inode, background_compression))))
                bch2_set_rebalance_needs_scan(c, inode->ei_inode.bi_inum);
 
        return bch2_err_class(ret);