LE64_BITMASK(BCH_SB_CSUM_ERR_RETRY_NR, struct bch_sb, flags[6], 14, 20);
 LE64_BITMASK(BCH_SB_DEGRADED_ACTION,   struct bch_sb, flags[6], 20, 22);
 LE64_BITMASK(BCH_SB_CASEFOLD,          struct bch_sb, flags[6], 22, 23);
+LE64_BITMASK(BCH_SB_REBALANCE_AC_ONLY, struct bch_sb, flags[6], 23, 24);
 
 static inline __u64 BCH_SB_COMPRESSION_TYPE(const struct bch_sb *sb)
 {
 
          BCH2_NO_SB_OPT,                       true,                   \
          NULL,         "Enable rebalance: disable for debugging, or to\n"\
                        "quiet the system when doing performance testing\n")\
+       x(rebalance_on_ac_only,         u8,                             \
+         OPT_FS|OPT_MOUNT|OPT_RUNTIME,                                 \
+         OPT_BOOL(),                                                   \
+         BCH_SB_REBALANCE_AC_ONLY,             false,                  \
+         NULL,         "Enable rebalance while on mains power only\n") \
        x(no_data_io,                   u8,                             \
          OPT_MOUNT,                                                    \
          OPT_BOOL(),                                                   \
 
        bch2_kthread_io_clock_wait(clock, r->wait_iotime_end, MAX_SCHEDULE_TIMEOUT);
 }
 
+static bool bch2_rebalance_enabled(struct bch_fs *c)
+{
+       return c->opts.rebalance_enabled &&
+               !(c->opts.rebalance_on_ac_only &&
+                 c->rebalance.on_battery);
+}
+
 static int do_rebalance(struct moving_context *ctxt)
 {
        struct btree_trans *trans = ctxt->trans;
                             BTREE_ITER_all_snapshots);
 
        while (!bch2_move_ratelimit(ctxt)) {
-               if (!c->opts.rebalance_enabled) {
+               if (!bch2_rebalance_enabled(c)) {
                        bch2_moving_ctxt_flush_all(ctxt);
-                       kthread_wait_freezable(c->opts.rebalance_enabled ||
+                       kthread_wait_freezable(bch2_rebalance_enabled(c) ||
                                               kthread_should_stop());
                }
 
        return 0;
 }
 
-void bch2_fs_rebalance_init(struct bch_fs *c)
+#ifdef CONFIG_POWER_SUPPLY
+#include <linux/power_supply.h>
+
+static int bch2_rebalance_power_notifier(struct notifier_block *nb,
+                                        unsigned long event, void *data)
+{
+       struct bch_fs *c = container_of(nb, struct bch_fs, rebalance.power_notifier);
+
+       c->rebalance.on_battery = !power_supply_is_system_supplied();
+       bch2_rebalance_wakeup(c);
+       return NOTIFY_OK;
+}
+#endif
+
+void bch2_fs_rebalance_exit(struct bch_fs *c)
 {
-       bch2_pd_controller_init(&c->rebalance.pd);
+#ifdef CONFIG_POWER_SUPPLY
+       power_supply_unreg_notifier(&c->rebalance.power_notifier);
+#endif
+}
+
+int bch2_fs_rebalance_init(struct bch_fs *c)
+{
+       struct bch_fs_rebalance *r = &c->rebalance;
+
+       bch2_pd_controller_init(&r->pd);
+
+#ifdef CONFIG_POWER_SUPPLY
+       r->power_notifier.notifier_call = bch2_rebalance_power_notifier;
+       int ret = power_supply_reg_notifier(&r->power_notifier);
+       if (ret)
+               return ret;
+
+       r->on_battery = !power_supply_is_system_supplied();
+#endif
+       return 0;
 }
 
 static int check_rebalance_work_one(struct btree_trans *trans,
 
 
 void bch2_rebalance_stop(struct bch_fs *);
 int bch2_rebalance_start(struct bch_fs *);
-void bch2_fs_rebalance_init(struct bch_fs *);
+
+void bch2_fs_rebalance_exit(struct bch_fs *);
+int bch2_fs_rebalance_init(struct bch_fs *);
 
 int bch2_check_rebalance_work(struct bch_fs *);
 
 
        struct bbpos                    scan_start;
        struct bbpos                    scan_end;
        struct bch_move_stats           scan_stats;
+
+       bool                            on_battery;
+#ifdef CONFIG_POWER_SUPPLY
+       struct notifier_block           power_notifier;
+#endif
 };
 
 #endif /* _BCACHEFS_REBALANCE_TYPES_H */
 
        bch2_fs_snapshots_exit(c);
        bch2_fs_sb_errors_exit(c);
        bch2_fs_replicas_exit(c);
+       bch2_fs_rebalance_exit(c);
        bch2_fs_quota_exit(c);
        bch2_fs_nocow_locking_exit(c);
        bch2_fs_journal_exit(&c->journal);
        bch2_fs_move_init(c);
        bch2_fs_nocow_locking_init_early(c);
        bch2_fs_quota_init(c);
-       bch2_fs_rebalance_init(c);
        bch2_fs_sb_errors_init_early(c);
        bch2_fs_snapshots_init_early(c);
        bch2_fs_subvolumes_init_early(c);
            bch2_fs_fsio_init(c) ?:
            bch2_fs_fs_io_direct_init(c) ?:
            bch2_fs_io_read_init(c) ?:
+           bch2_fs_rebalance_init(c) ?:
            bch2_fs_sb_errors_init(c) ?:
            bch2_fs_vfs_init(c);
        if (ret)