btrfs: add optimized btrfs_ino() version for 64 bits systems
authorFilipe Manana <fdmanana@suse.com>
Mon, 11 Jul 2022 14:22:50 +0000 (15:22 +0100)
committerDavid Sterba <dsterba@suse.com>
Mon, 25 Jul 2022 15:45:41 +0000 (17:45 +0200)
Currently btrfs_ino() tries to use first the objectid of the inode's
location key. This is to avoid truncation of the inode number on 32 bits
platforms because the i_ino field of struct inode has the unsigned long
type, while the objectid is a 64 bits unsigned type (u64) on every system.
This logic was added in commit 33345d01522f81 ("Btrfs: Always use 64bit
inode number").

However if we are running on a 64 bits system, we can always directly
return the i_ino value from struct inode, which eliminates the need for
he special if statement that tests for a location key type of
BTRFS_ROOT_ITEM_KEY - in which case i_ino may not have the same value as
the objectid in the inode's location objectid, it may have a value of
BTRFS_EMPTY_SUBVOL_DIR_OBJECTID, for the case of snapshots of trees with
subvolumes/snapshots inside them.

So add a special version for 64 bits system that directly returns i_ino
of struct inode. This eliminates one branch and reduces the overall code
size, since btrfs_ino() is an inline function that is extensively used.

Before:

$ size fs/btrfs/btrfs.ko
   text    data     bss     dec     hex filename
1617487  189240   29032 1835759  1c02ef fs/btrfs/btrfs.ko

After:

$ size fs/btrfs/btrfs.ko
   text    data     bss     dec     hex filename
1612028  189180   29032 1830240  1bed60 fs/btrfs/btrfs.ko

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/btrfs_inode.h
fs/btrfs/tests/btrfs-tests.c

index a18f90f..b160b8e 100644 (file)
@@ -279,6 +279,12 @@ static inline void btrfs_insert_inode_hash(struct inode *inode)
        __insert_inode_hash(inode, h);
 }
 
+#if BITS_PER_LONG == 32
+
+/*
+ * On 32 bit systems the i_ino of struct inode is 32 bits (unsigned long), so
+ * we use the inode's location objectid which is a u64 to avoid truncation.
+ */
 static inline u64 btrfs_ino(const struct btrfs_inode *inode)
 {
        u64 ino = inode->location.objectid;
@@ -289,6 +295,15 @@ static inline u64 btrfs_ino(const struct btrfs_inode *inode)
        return ino;
 }
 
+#else
+
+static inline u64 btrfs_ino(const struct btrfs_inode *inode)
+{
+       return inode->vfs_inode.i_ino;
+}
+
+#endif
+
 static inline void btrfs_i_size_write(struct btrfs_inode *inode, u64 size)
 {
        i_size_write(&inode->vfs_inode, size);
index d8e56ed..cc9377c 100644 (file)
@@ -59,6 +59,7 @@ struct inode *btrfs_new_test_inode(void)
                return NULL;
 
        inode->i_mode = S_IFREG;
+       inode->i_ino = BTRFS_FIRST_FREE_OBJECTID;
        BTRFS_I(inode)->location.type = BTRFS_INODE_ITEM_KEY;
        BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID;
        BTRFS_I(inode)->location.offset = 0;