bitops: protect variables in set_mask_bits() macro
authorMiklos Szeredi <mszeredi@redhat.com>
Mon, 15 Oct 2018 13:43:06 +0000 (15:43 +0200)
committerMiklos Szeredi <mszeredi@redhat.com>
Mon, 15 Oct 2018 13:43:06 +0000 (15:43 +0200)
Unprotected naming of local variables within the set_mask_bits() can easily
lead to using the wrong scope.

Noticed this when "set_mask_bits(&foo->bar, 0, mask)" behaved as no-op.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Fixes: 00a1a053ebe5 ("ext4: atomically set inode->i_flags in ext4_set_inode_flags()")
Cc: Theodore Ts'o <tytso@mit.edu>
include/linux/bitops.h

index 7ddb134..d18ee0e 100644 (file)
@@ -236,17 +236,17 @@ static __always_inline void __assign_bit(long nr, volatile unsigned long *addr,
 #ifdef __KERNEL__
 
 #ifndef set_mask_bits
-#define set_mask_bits(ptr, _mask, _bits)       \
+#define set_mask_bits(ptr, mask, bits) \
 ({                                                             \
-       const typeof(*ptr) mask = (_mask), bits = (_bits);      \
-       typeof(*ptr) old, new;                                  \
+       const typeof(*(ptr)) mask__ = (mask), bits__ = (bits);  \
+       typeof(*(ptr)) old__, new__;                            \
                                                                \
        do {                                                    \
-               old = READ_ONCE(*ptr);                  \
-               new = (old & ~mask) | bits;                     \
-       } while (cmpxchg(ptr, old, new) != old);                \
+               old__ = READ_ONCE(*(ptr));                      \
+               new__ = (old__ & ~mask__) | bits__;             \
+       } while (cmpxchg(ptr, old__, new__) != old__);          \
                                                                \
-       new;                                                    \
+       new__;                                                  \
 })
 #endif