From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu [18.9.28.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B26CD3DD523 for ; Mon, 4 May 2026 23:33:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=18.9.28.11 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777937607; cv=none; b=ZlmBPVuKASQMkSJ1akvnlXqNwgZLVkNae/JaPKOKevpx30OfUQE+SwaRMrFpx0vhGAXPeCwuj6t8UuCrhMYy/h+NGklzWsF63NQd6FaI/9TOpZ9AcZLRq56swCxIF35npatZpez2ARHbRbaI9Nhcv0Uz7mzuB94VK26zlIKMMz8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777937607; c=relaxed/simple; bh=CXaF5EAvyOZyokUnBHAipvVsnKS4iKx/juNre6U/nk4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PWY3W1yq+s9BaWdtrpgrI2Y+avPXP1NBwywJf9isn5Vlz14sBnWOPwPotvrIbENP4F8FcSDAPJwf5kYurL0DWpkNBxuqtYfEG6Vni5sKnh2rfD8hLTfMkvPdTCJFTg7H8VPM2Ex2qcO4TmhgILfYAARJxQXHdJdhyyswR974P/E= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=mit.edu; spf=pass smtp.mailfrom=mit.edu; dkim=pass (2048-bit key) header.d=mit.edu header.i=@mit.edu header.b=BY2lEkmq; arc=none smtp.client-ip=18.9.28.11 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=mit.edu Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=mit.edu Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=mit.edu header.i=@mit.edu header.b="BY2lEkmq" Received: from trampoline.thunk.org (pool-173-48-114-3.bstnma.fios.verizon.net [173.48.114.3]) (authenticated bits=0) (User authenticated as tytso@ATHENA.MIT.EDU) by outgoing.mit.edu (8.14.7/8.12.4) with ESMTP id 644NX8ZE019536 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 4 May 2026 19:33:09 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mit.edu; s=outgoing; t=1777937589; bh=OwCzUzBIBGdQyLiD5S3JambIs+FlgtXeteDfGew+v3Q=; h=From:Subject:Date:Message-ID:MIME-Version; b=BY2lEkmqDtwAbyZvtwm95MVZbugBIzCMoF//gHb0jNcjDfXPWxrOy2UlJREOUzRgr rdzDU9qme+U7pEn7RC5NPRpd6wDBjbWnl3woxoa5qOn/IlBsi3Ze4PhvnKXkl3KUZL gcMomY/T9001Iyuz3jgmzCTGYMClWeGGOhMc7vcP+yJI/p1g1xtCH1rOCCsnHMRMsh gkJ5y/yNkJdDjNMOT8P4v1ympYEdQEZ22GnHTNT/4LJJIwWCO39hyIQBbep7/aN91E dEwJzvfRdl05iEOZaX9oaSFyu92LU7MykO0AsyQ7qgR8+MzhDexmqzV3EWguWqeLVg Zv4ZE+3YRoBhg== Received: by trampoline.thunk.org (Postfix, from userid 15806) id EE0DC2E00CC; Mon, 04 May 2026 19:33:07 -0400 (EDT) From: "Theodore Ts'o" To: Ext4 Developers List Cc: "Darrick J. Wong" , "Theodore Ts'o" Subject: [PATCH 1/7] libsupport: drop xbitops.h and define fls() if necessary Date: Mon, 4 May 2026 19:32:55 -0400 Message-ID: <20260504233301.2345652-2-tytso@mit.edu> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260504233301.2345652-1-tytso@mit.edu> References: <20260504233301.2345652-1-tytso@mit.edu> Precedence: bulk X-Mailing-List: linux-ext4@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit The new cache.c file doesn't actually need most of the functions in xbitops.h. It only needs fls(), and on some systems, like MacOS and *BSD systems, fls() is defined already. The other functions in xbitops.h are massively non-portable and break on non-Linux systems, especially MacOS. So define fls() if it's needed (on Linux), and drop xbitops.h. Fixes: 30b3c80ed6bc ("libsupport: add a cache") Signed-off-by: Theodore Ts'o --- configure | 6 ++ configure.ac | 1 + fuse4fs/Makefile.in | 18 +++--- lib/config.h.in | 3 + lib/support/Makefile.in | 2 +- lib/support/cache.c | 33 ++++++++++- lib/support/xbitops.h | 128 ---------------------------------------- 7 files changed, 51 insertions(+), 140 deletions(-) delete mode 100644 lib/support/xbitops.h diff --git a/configure b/configure index a97794121..a1a270e63 100755 --- a/configure +++ b/configure @@ -13677,6 +13677,12 @@ if test "x$ac_cv_func_fdatasync" = xyes then : printf "%s\n" "#define HAVE_FDATASYNC 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "fls" "ac_cv_func_fls" +if test "x$ac_cv_func_fls" = xyes +then : + printf "%s\n" "#define HAVE_FLS 1" >>confdefs.h + fi ac_fn_c_check_func "$LINENO" "fstat64" "ac_cv_func_fstat64" if test "x$ac_cv_func_fstat64" = xyes diff --git a/configure.ac b/configure.ac index b62553e3d..abce79594 100644 --- a/configure.ac +++ b/configure.ac @@ -1233,6 +1233,7 @@ AC_CHECK_FUNCS(m4_flatten([ fchown fcntl fdatasync + fls fstat64 fsync ftruncate64 diff --git a/fuse4fs/Makefile.in b/fuse4fs/Makefile.in index 9f3547c27..cecee2b25 100644 --- a/fuse4fs/Makefile.in +++ b/fuse4fs/Makefile.in @@ -134,7 +134,7 @@ distclean: clean $(RM) -f .depend Makefile $(srcdir)/TAGS $(srcdir)/Makefile.in.old # +++ Dependency line eater +++ -# +# # Makefile dependencies follow. This must be the last section in # the Makefile.in file # @@ -145,9 +145,10 @@ fuse4fs.o: $(srcdir)/fuse4fs.c $(top_builddir)/lib/config.h \ $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \ $(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/hashmap.h \ $(top_srcdir)/lib/ext2fs/bitops.h $(top_srcdir)/lib/ext2fs/ext2fsP.h \ - $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/version.h \ - $(top_srcdir)/lib/e2p/e2p.h $(top_srcdir)/lib/support/cache.h \ - $(top_srcdir)/lib/support/list.h $(top_srcdir)/lib/support/xbitops.h + $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/support/bthread.h \ + $(top_srcdir)/lib/support/thread.h $(top_srcdir)/lib/support/list.h \ + $(top_srcdir)/lib/support/cache.h $(top_srcdir)/version.h \ + $(top_srcdir)/lib/e2p/e2p.h journal.o: $(srcdir)/../debugfs/journal.c $(top_builddir)/lib/config.h \ $(top_builddir)/lib/dirpaths.h $(srcdir)/../debugfs/journal.h \ $(top_srcdir)/e2fsck/jfs_user.h $(top_srcdir)/e2fsck/e2fsck.h \ @@ -161,8 +162,7 @@ journal.o: $(srcdir)/../debugfs/journal.c $(top_builddir)/lib/config.h \ $(top_srcdir)/lib/support/dqblk_v2.h \ $(top_srcdir)/lib/support/quotaio_tree.h \ $(top_srcdir)/lib/ext2fs/fast_commit.h $(top_srcdir)/lib/ext2fs/jfs_compat.h \ - $(top_srcdir)/lib/support/list.h $(top_srcdir)/lib/ext2fs/compiler.h \ - $(top_srcdir)/lib/ext2fs/kernel-jbd.h + $(top_srcdir)/lib/support/list.h $(top_srcdir)/lib/ext2fs/kernel-jbd.h revoke.o: $(srcdir)/../e2fsck/revoke.c $(srcdir)/../e2fsck/jfs_user.h \ $(top_builddir)/lib/config.h $(top_builddir)/lib/dirpaths.h \ $(srcdir)/../e2fsck/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \ @@ -175,8 +175,7 @@ revoke.o: $(srcdir)/../e2fsck/revoke.c $(srcdir)/../e2fsck/jfs_user.h \ $(top_srcdir)/lib/support/dqblk_v2.h \ $(top_srcdir)/lib/support/quotaio_tree.h \ $(top_srcdir)/lib/ext2fs/fast_commit.h $(top_srcdir)/lib/ext2fs/jfs_compat.h \ - $(top_srcdir)/lib/support/list.h $(top_srcdir)/lib/ext2fs/compiler.h \ - $(top_srcdir)/lib/ext2fs/kernel-jbd.h + $(top_srcdir)/lib/support/list.h $(top_srcdir)/lib/ext2fs/kernel-jbd.h recovery.o: $(srcdir)/../e2fsck/recovery.c $(srcdir)/../e2fsck/jfs_user.h \ $(top_builddir)/lib/config.h $(top_builddir)/lib/dirpaths.h \ $(srcdir)/../e2fsck/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \ @@ -189,5 +188,4 @@ recovery.o: $(srcdir)/../e2fsck/recovery.c $(srcdir)/../e2fsck/jfs_user.h \ $(top_srcdir)/lib/support/dqblk_v2.h \ $(top_srcdir)/lib/support/quotaio_tree.h \ $(top_srcdir)/lib/ext2fs/fast_commit.h $(top_srcdir)/lib/ext2fs/jfs_compat.h \ - $(top_srcdir)/lib/support/list.h $(top_srcdir)/lib/ext2fs/compiler.h \ - $(top_srcdir)/lib/ext2fs/kernel-jbd.h + $(top_srcdir)/lib/support/list.h $(top_srcdir)/lib/ext2fs/kernel-jbd.h diff --git a/lib/config.h.in b/lib/config.h.in index fd2520396..abba5e2c6 100644 --- a/lib/config.h.in +++ b/lib/config.h.in @@ -124,6 +124,9 @@ /* Define to 1 if you have the 'fdatasync' function. */ #undef HAVE_FDATASYNC +/* Define to 1 if you have the 'fls' function. */ +#undef HAVE_FLS + /* Define to 1 if fsmap_sizeof() is declared in linux/fsmap.h */ #undef HAVE_FSMAP_SIZEOF diff --git a/lib/support/Makefile.in b/lib/support/Makefile.in index 6ff1c81d0..d20d6a984 100644 --- a/lib/support/Makefile.in +++ b/lib/support/Makefile.in @@ -199,4 +199,4 @@ dict.o: $(srcdir)/dict.c $(top_builddir)/lib/config.h \ devname.o: $(srcdir)/devname.c $(top_builddir)/lib/config.h \ $(top_builddir)/lib/dirpaths.h $(srcdir)/devname.h $(srcdir)/nls-enable.h cache.o: $(srcdir)/cache.c $(top_builddir)/lib/config.h \ - $(srcdir)/cache.h $(srcdir)/list.h $(srcdir)/xbitops.h + $(top_builddir)/lib/dirpaths.h $(srcdir)/list.h $(srcdir)/cache.h diff --git a/lib/support/cache.c b/lib/support/cache.c index 3a9e276f1..f9669e3fc 100644 --- a/lib/support/cache.c +++ b/lib/support/cache.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -14,9 +15,9 @@ #include #include +#include "config.h" #include "list.h" #include "cache.h" -#include "xbitops.h" #undef CACHE_DEBUG /* #define CACHE_DEBUG 1 */ @@ -32,6 +33,36 @@ # define ASSERT(x) do { } while (0) #endif +#ifndef HAVE_FLS +static inline int fls(int x) +{ + int r = 32; + + if (!x) + return 0; + if (!(x & 0xffff0000u)) { + x = (x & 0xffffu) << 16; + r -= 16; + } + if (!(x & 0xff000000u)) { + x = (x & 0xffffffu) << 8; + r -= 8; + } + if (!(x & 0xf0000000u)) { + x = (x & 0xfffffffu) << 4; + r -= 4; + } + if (!(x & 0xc0000000u)) { + x = (x & 0x3fffffffu) << 2; + r -= 2; + } + if (!(x & 0x80000000u)) { + r -= 1; + } + return r; +} +#endif + static unsigned int cache_generic_bulkrelse(struct cache *, struct list_head *); int diff --git a/lib/support/xbitops.h b/lib/support/xbitops.h deleted file mode 100644 index 78a8f2a85..000000000 --- a/lib/support/xbitops.h +++ /dev/null @@ -1,128 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#ifndef __BITOPS_H__ -#define __BITOPS_H__ - -/* - * fls: find last bit set. - */ - -static inline int fls(int x) -{ - int r = 32; - - if (!x) - return 0; - if (!(x & 0xffff0000u)) { - x = (x & 0xffffu) << 16; - r -= 16; - } - if (!(x & 0xff000000u)) { - x = (x & 0xffffffu) << 8; - r -= 8; - } - if (!(x & 0xf0000000u)) { - x = (x & 0xfffffffu) << 4; - r -= 4; - } - if (!(x & 0xc0000000u)) { - x = (x & 0x3fffffffu) << 2; - r -= 2; - } - if (!(x & 0x80000000u)) { - r -= 1; - } - return r; -} - -static inline int fls64(uint64_t x) -{ - uint32_t h = x >> 32; - if (h) - return fls(h) + 32; - return fls(x); -} - -static inline unsigned fls_long(unsigned long l) -{ - if (sizeof(l) == 4) - return fls(l); - return fls64(l); -} - -/* - * ffz: find first zero bit. - * Result is undefined if no zero bit exists. - */ -#define ffz(x) ffs(~(x)) - -/* - * XFS bit manipulation routines. Repeated here so that some programs - * don't have to link in all of libxfs just to have bit manipulation. - */ - -/* - * masks with n high/low bits set, 64-bit values - */ -static inline uint64_t mask64hi(int n) -{ - return (uint64_t)-1 << (64 - (n)); -} -static inline uint32_t mask32lo(int n) -{ - return ((uint32_t)1 << (n)) - 1; -} -static inline uint64_t mask64lo(int n) -{ - return ((uint64_t)1 << (n)) - 1; -} - -/* Get high bit set out of 32-bit argument, -1 if none set */ -static inline int highbit32(uint32_t v) -{ - return fls(v) - 1; -} - -/* Get high bit set out of 64-bit argument, -1 if none set */ -static inline int highbit64(uint64_t v) -{ - return fls64(v) - 1; -} - -/* Get low bit set out of 32-bit argument, -1 if none set */ -static inline int lowbit32(uint32_t v) -{ - return ffs(v) - 1; -} - -/* Get low bit set out of 64-bit argument, -1 if none set */ -static inline int lowbit64(uint64_t v) -{ - uint32_t w = (uint32_t)v; - int n = 0; - - if (w) { /* lower bits */ - n = ffs(w); - } else { /* upper bits */ - w = (uint32_t)(v >> 32); - if (w) { - n = ffs(w); - if (n) - n += 32; - } - } - return n - 1; -} - -/** - * __rounddown_pow_of_two() - round down to nearest power of two - * @n: value to round down - */ -static inline __attribute__((const)) -unsigned long __rounddown_pow_of_two(unsigned long n) -{ - return 1UL << (fls_long(n) - 1); -} - -#define rounddown_pow_of_two(n) __rounddown_pow_of_two(n) - -#endif -- 2.53.0