On Fri, Sep 13, 2019 at 10:24:08AM +0200, Johannes Thumshirn wrote: > On 13/09/2019 01:55, 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; > > Would > flags && IS_ALIGNED(flags) > > Work as well? IS_ALIGNED() should be type-save due to the typeof(): > #define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0) > > Or maybe I'm missing something subtle?
Wouldn't that be flags && IS_ALIGNED(flags, flags) ? > Thanks, > Johannes > -- > Johannes Thumshirn SUSE Labs Filesystems > jthumsh...@suse.de +49 911 74053 689 > SUSE Software Solutions Germany GmbH > Maxfeldstr. 5 > 90409 Nürnberg > Germany > (HRB 247165, AG München) > Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850
signature.asc
Description: PGP signature