On Mon, Sep 23, 2019 at 05:14:04PM +0200, David Sterba wrote: > On Thu, Sep 12, 2019 at 07:55:01PM -0400, Zygo Blaxell wrote: > > Currently, the command: > > > > btrfs balance start -dconvert=single,soft . > > > > on a Raspberry Pi produces the following kernel message: > > > > BTRFS error (device mmcblk0p2): balance: invalid convert data profile > > single > > > > This fails because we use is_power_of_2(unsigned long) to validate > > the new data profile, the constant for 'single' profile uses bit 48, > > and there are only 32 bits in a long on ARM. > > > > Fix by open-coding the check using u64 variables. > > > > Tested by completing the original balance command on several Raspberry > > Pis. > > > > Signed-off-by: Zygo Blaxell <ce3g8...@umail.furryterror.org> > > --- > > fs/btrfs/volumes.c | 6 +++++- > > 1 file changed, 5 insertions(+), 1 deletion(-) > > > > diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c > > index 88a323a453d8..252c6049c6b7 100644 > > --- a/fs/btrfs/volumes.c > > +++ b/fs/btrfs/volumes.c > > @@ -3906,7 +3906,11 @@ static int alloc_profile_is_valid(u64 flags, int > > extended) > > return !extended; /* "0" is valid for usual profiles */ > > > > /* true if exactly one bit set */ > > - return is_power_of_2(flags); > > + /* > > + * Don't use is_power_of_2(unsigned long) because it won't work > > + * for the single profile (1ULL << 48) on 32-bit CPUs. > > + */ > > + return flags != 0 && (flags & (flags - 1)) == 0; > > I'd rather not open code it again. Based on the discussion, we need a > separate helper that takes u64 and possibly has the "value has exactly > one bit set" semantics from the beginnin. We now have a file for such > helpers (fs/btrfs/misc.h). > > There would a few more users of the new helper (now done using the > is_power_of_2 helper), that would improve readability.
I'll apply the patch as-is so it can go to stable and do the helper and other cleanups myself.