From: Kent Overstreet
> Sent: 14 February 2024 01:17
> 
> bcachefs bugs should go to the bcachefs mailing list; I assume this is
> just a case where we need min_t instead of min, if so I'll fix it
> shortly

You should pretty much never use min_t() - it contains casts that are just
waiting to cause grief.

I'm sure a bug got raised on clang so it outputting the source of the
_Static_assert() when there is a message.
That just makes the error message worse.

Hacking at the error message, it comes from (expanded by min()):

min(replicas_want, ({
    do {
        __attribute__((__noreturn__))
            extern void __compiletime_assert_578(void)
            __attribute__((__error__("Unsupported access size for 
{READ,WRITE}_ONCE().")));
        if (...)
            __compiletime_assert_578();
    } while (0);
    ({
        typeof(&(c->opts.metadata_replicas_required)) __x = 
&(c->opts.metadata_replicas_required);
        int atomic = 1;
        union {
            typeof( _Generic((*__x),
                char: (char)0,
                unsigned char: (unsigned char)0,
                signed char: (signed char)0,
                unsigned short: (unsigned short)0,
                signed short: (signed short)0,
                unsigned int: (unsigned int)0,
                signed int: (signed int)0,
                unsigned long: (unsigned long)0,
                signed long: (signed long)0,
                unsigned long long: (unsigned long long)0,
                signed long long: (signed long long)0,
                default: (*__x))) __val;
            char __c[1];
        } __u;
        switch (sizeof(c->opts.metadata_replicas_required)) {
        case 1: asm volatile("..." : "=r" (*(__u8 *)__u.__c) : "Q" (*__x) : 
"memory");
            break;
        case 2: asm volatile("..." : "=r" (*(__u16 *)__u.__c) : "Q" (*__x) : 
"memory");
            break;
        case 4: asm volatile("..." : "=r" (*(__u32 *)__u.__c) : "Q" (*__x) : 
"memory");
            break;
        case 8: asm volatile("..." : "=r" (*(__u64 *)__u.__c) : "Q" (*__x) : 
"memory");
            break;
        default:
            atomic = 0;
        }
        atomic ? (typeof(*__x))__u.__val : (*(volatile typeof(__x))__x);
    });
}))

So I suspect it is min(replicas_want, READ_ONCE(replices_required)).
I think replicas_want is unsigned (int) and replicas_required u8.

> 
> On Tue, Feb 13, 2024 at 02:56:40PM -0700, Nathan Chancellor wrote:
> > Hi all,
> >
> > I am not really sure where to go with this, so I figured I would loop
> > some people in and see if we can figure out what is going on here.
> >
> > After commit 67a8e7de7ef0 ("bcachefs: Clamp replicas_required to
> > replicas") in linux-next, I see a massive error occur when building for
> > ARCH=arm64 with both CONFIG_BCACHEFS_FS and CONFIG_LTO enabled, which is
> > important because arm64 defines its own __READ_ONCE() with LTO enabled.
> > The error appears to be related to the minmax.h changes that went into
> > 6.7; I think it is specifically around commit d03eba99f5bf ("minmax:
> > allow min()/max()/clamp() if the arguments have the same signedness.").
> >
> > As far as I can tell, replicas_want and the metadata_replicas_required
> > member in struct bch_opts should have the same signedness, unless the
> > __READ_ONCE() macro is messing something up, which is kind of hard to
> > tell at this point...

The last line of that READ_ONCE() expansion looks dubious to me.
The result type is independent of 'atomic' and I suspect ?: counts
as an arithmetic operation and u8 gets promoted to int.

That would fail the old min() as well as the new one.
Is this code new? I can see it online in 6.8.4-rc4.

        David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, 
UK
Registration No: 1397386 (Wales)


Reply via email to