Commit 7a7bc214 authored by Filipe Manana's avatar Filipe Manana Committed by David Sterba

btrfs: remove objectid from struct btrfs_inode on 64 bits platforms

On 64 bits platforms we don't really need to have a dedicated member (the
objectid field) for the inode's number since we store in the VFS inode's
i_ino member, which is an unsigned long and this type is 64 bits wide on
64 bits platforms. We only need that field in case we are on a 32 bits
platform because the unsigned long type is 32 bits wide on such platforms
See commit 33345d01 ("Btrfs: Always use 64bit inode number") regarding
this 64/32 bits detail.

The objectid field of struct btrfs_inode is also used to store the ID of
a root for directories that are stubs for unreferenced roots. In such
cases the inode is a directory and has the BTRFS_INODE_ROOT_STUB runtime
flag set.

So in order to reduce the size of btrfs_inode structure on 64 bits
platforms we can remove the objectid member and use the VFS inode's i_ino
member instead whenever we need to get the inode number. In case the inode
is a root stub (BTRFS_INODE_ROOT_STUB set) we can use the member
last_reflink_trans to store the ID of the unreferenced root, since such
inode is a directory and reflinks can't be done against directories.

So remove the objectid fields for 64 bits platforms and alias the
last_reflink_trans field with a name of ref_root_id in a union.
On a release kernel config, this reduces the size of struct btrfs_inode
from 1040 bytes down to 1032 bytes.
Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 068fc8f9
...@@ -129,15 +129,14 @@ struct btrfs_inode { ...@@ -129,15 +129,14 @@ struct btrfs_inode {
/* which subvolume this inode belongs to */ /* which subvolume this inode belongs to */
struct btrfs_root *root; struct btrfs_root *root;
#if BITS_PER_LONG == 32
/* /*
* This is either: * The objectid of the corresponding BTRFS_INODE_ITEM_KEY.
* * On 64 bits platforms we can get it from vfs_inode.i_ino, which is an
* 1) The objectid of the corresponding BTRFS_INODE_ITEM_KEY; * unsigned long and therefore 64 bits on such platforms.
*
* 2) In case this a root stub inode (BTRFS_INODE_ROOT_STUB flag set),
* the ID of that root.
*/ */
u64 objectid; u64 objectid;
#endif
/* Cached value of inode property 'compression'. */ /* Cached value of inode property 'compression'. */
u8 prop_compress; u8 prop_compress;
...@@ -301,17 +300,26 @@ struct btrfs_inode { ...@@ -301,17 +300,26 @@ struct btrfs_inode {
*/ */
u64 last_unlink_trans; u64 last_unlink_trans;
union {
/* /*
* The id/generation of the last transaction where this inode was * The id/generation of the last transaction where this inode
* either the source or the destination of a clone/dedupe operation. * was either the source or the destination of a clone/dedupe
* Used when logging an inode to know if there are shared extents that * operation. Used when logging an inode to know if there are
* need special care when logging checksum items, to avoid duplicate * shared extents that need special care when logging checksum
* checksum items in a log (which can lead to a corruption where we end * items, to avoid duplicate checksum items in a log (which can
* up with missing checksum ranges after log replay). * lead to a corruption where we end up with missing checksum
* Protected by the vfs inode lock. * ranges after log replay). Protected by the VFS inode lock.
* Used for regular files only.
*/ */
u64 last_reflink_trans; u64 last_reflink_trans;
/*
* In case this a root stub inode (BTRFS_INODE_ROOT_STUB flag set),
* the ID of that root.
*/
u64 ref_root_id;
};
/* Backwards incompatible flags, lower half of inode_item::flags */ /* Backwards incompatible flags, lower half of inode_item::flags */
u32 flags; u32 flags;
/* Read-only compatibility flags, upper half of inode_item::flags */ /* Read-only compatibility flags, upper half of inode_item::flags */
...@@ -387,11 +395,19 @@ static inline u64 btrfs_ino(const struct btrfs_inode *inode) ...@@ -387,11 +395,19 @@ static inline u64 btrfs_ino(const struct btrfs_inode *inode)
static inline void btrfs_get_inode_key(const struct btrfs_inode *inode, static inline void btrfs_get_inode_key(const struct btrfs_inode *inode,
struct btrfs_key *key) struct btrfs_key *key)
{ {
key->objectid = inode->objectid; key->objectid = btrfs_ino(inode);
key->type = BTRFS_INODE_ITEM_KEY; key->type = BTRFS_INODE_ITEM_KEY;
key->offset = 0; key->offset = 0;
} }
static inline void btrfs_set_inode_number(struct btrfs_inode *inode, u64 ino)
{
#if BITS_PER_LONG == 32
inode->objectid = ino;
#endif
inode->vfs_inode.i_ino = ino;
}
static inline void btrfs_i_size_write(struct btrfs_inode *inode, u64 size) static inline void btrfs_i_size_write(struct btrfs_inode *inode, u64 size)
{ {
i_size_write(&inode->vfs_inode, size); i_size_write(&inode->vfs_inode, size);
......
...@@ -1928,7 +1928,7 @@ static int btrfs_init_btree_inode(struct super_block *sb) ...@@ -1928,7 +1928,7 @@ static int btrfs_init_btree_inode(struct super_block *sb)
if (!inode) if (!inode)
return -ENOMEM; return -ENOMEM;
inode->i_ino = BTRFS_BTREE_INODE_OBJECTID; btrfs_set_inode_number(BTRFS_I(inode), BTRFS_BTREE_INODE_OBJECTID);
set_nlink(inode, 1); set_nlink(inode, 1);
/* /*
* we set the i_size on the btree inode to the max possible int. * we set the i_size on the btree inode to the max possible int.
...@@ -1944,7 +1944,6 @@ static int btrfs_init_btree_inode(struct super_block *sb) ...@@ -1944,7 +1944,6 @@ static int btrfs_init_btree_inode(struct super_block *sb)
extent_map_tree_init(&BTRFS_I(inode)->extent_tree); extent_map_tree_init(&BTRFS_I(inode)->extent_tree);
BTRFS_I(inode)->root = btrfs_grab_root(fs_info->tree_root); BTRFS_I(inode)->root = btrfs_grab_root(fs_info->tree_root);
BTRFS_I(inode)->objectid = BTRFS_BTREE_INODE_OBJECTID;
set_bit(BTRFS_INODE_DUMMY, &BTRFS_I(inode)->runtime_flags); set_bit(BTRFS_INODE_DUMMY, &BTRFS_I(inode)->runtime_flags);
__insert_inode_hash(inode, hash); __insert_inode_hash(inode, hash);
fs_info->btree_inode = inode; fs_info->btree_inode = inode;
......
...@@ -40,7 +40,7 @@ static int btrfs_encode_fh(struct inode *inode, u32 *fh, int *max_len, ...@@ -40,7 +40,7 @@ static int btrfs_encode_fh(struct inode *inode, u32 *fh, int *max_len,
if (parent) { if (parent) {
u64 parent_root_id; u64 parent_root_id;
fid->parent_objectid = BTRFS_I(parent)->objectid; fid->parent_objectid = btrfs_ino(BTRFS_I(parent));
fid->parent_gen = parent->i_generation; fid->parent_gen = parent->i_generation;
parent_root_id = btrfs_root_id(BTRFS_I(parent)->root); parent_root_id = btrfs_root_id(BTRFS_I(parent)->root);
......
...@@ -4340,7 +4340,7 @@ static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, ...@@ -4340,7 +4340,7 @@ static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans,
if (btrfs_ino(inode) == BTRFS_FIRST_FREE_OBJECTID) { if (btrfs_ino(inode) == BTRFS_FIRST_FREE_OBJECTID) {
objectid = btrfs_root_id(inode->root); objectid = btrfs_root_id(inode->root);
} else if (btrfs_ino(inode) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) { } else if (btrfs_ino(inode) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) {
objectid = inode->objectid; objectid = inode->ref_root_id;
} else { } else {
WARN_ON(1); WARN_ON(1);
fscrypt_free_filename(&fname); fscrypt_free_filename(&fname);
...@@ -5581,8 +5581,7 @@ static int btrfs_init_locked_inode(struct inode *inode, void *p) ...@@ -5581,8 +5581,7 @@ static int btrfs_init_locked_inode(struct inode *inode, void *p)
{ {
struct btrfs_iget_args *args = p; struct btrfs_iget_args *args = p;
inode->i_ino = args->ino; btrfs_set_inode_number(BTRFS_I(inode), args->ino);
BTRFS_I(inode)->objectid = args->ino;
BTRFS_I(inode)->root = btrfs_grab_root(args->root); BTRFS_I(inode)->root = btrfs_grab_root(args->root);
if (args->root && args->root == args->root->fs_info->tree_root && if (args->root && args->root == args->root->fs_info->tree_root &&
...@@ -5596,7 +5595,7 @@ static int btrfs_find_actor(struct inode *inode, void *opaque) ...@@ -5596,7 +5595,7 @@ static int btrfs_find_actor(struct inode *inode, void *opaque)
{ {
struct btrfs_iget_args *args = opaque; struct btrfs_iget_args *args = opaque;
return args->ino == BTRFS_I(inode)->objectid && return args->ino == btrfs_ino(BTRFS_I(inode)) &&
args->root == BTRFS_I(inode)->root; args->root == BTRFS_I(inode)->root;
} }
...@@ -5673,11 +5672,11 @@ static struct inode *new_simple_dir(struct inode *dir, ...@@ -5673,11 +5672,11 @@ static struct inode *new_simple_dir(struct inode *dir,
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
BTRFS_I(inode)->root = btrfs_grab_root(root); BTRFS_I(inode)->root = btrfs_grab_root(root);
BTRFS_I(inode)->objectid = key->objectid; BTRFS_I(inode)->ref_root_id = key->objectid;
set_bit(BTRFS_INODE_ROOT_STUB, &BTRFS_I(inode)->runtime_flags); set_bit(BTRFS_INODE_ROOT_STUB, &BTRFS_I(inode)->runtime_flags);
set_bit(BTRFS_INODE_DUMMY, &BTRFS_I(inode)->runtime_flags); set_bit(BTRFS_INODE_DUMMY, &BTRFS_I(inode)->runtime_flags);
inode->i_ino = BTRFS_EMPTY_SUBVOL_DIR_OBJECTID; btrfs_set_inode_number(BTRFS_I(inode), BTRFS_EMPTY_SUBVOL_DIR_OBJECTID);
/* /*
* We only need lookup, the rest is read-only and there's no inode * We only need lookup, the rest is read-only and there's no inode
* associated with the dentry * associated with the dentry
...@@ -6150,7 +6149,7 @@ static int btrfs_insert_inode_locked(struct inode *inode) ...@@ -6150,7 +6149,7 @@ static int btrfs_insert_inode_locked(struct inode *inode)
{ {
struct btrfs_iget_args args; struct btrfs_iget_args args;
args.ino = BTRFS_I(inode)->objectid; args.ino = btrfs_ino(BTRFS_I(inode));
args.root = BTRFS_I(inode)->root; args.root = BTRFS_I(inode)->root;
return insert_inode_locked4(inode, return insert_inode_locked4(inode,
...@@ -6282,7 +6281,7 @@ int btrfs_create_new_inode(struct btrfs_trans_handle *trans, ...@@ -6282,7 +6281,7 @@ int btrfs_create_new_inode(struct btrfs_trans_handle *trans,
ret = btrfs_get_free_objectid(root, &objectid); ret = btrfs_get_free_objectid(root, &objectid);
if (ret) if (ret)
goto out; goto out;
inode->i_ino = objectid; btrfs_set_inode_number(BTRFS_I(inode), objectid);
ret = xa_reserve(&root->inodes, objectid, GFP_NOFS); ret = xa_reserve(&root->inodes, objectid, GFP_NOFS);
if (ret) if (ret)
...@@ -6332,8 +6331,6 @@ int btrfs_create_new_inode(struct btrfs_trans_handle *trans, ...@@ -6332,8 +6331,6 @@ int btrfs_create_new_inode(struct btrfs_trans_handle *trans,
BTRFS_INODE_NODATASUM; BTRFS_INODE_NODATASUM;
} }
BTRFS_I(inode)->objectid = objectid;
ret = btrfs_insert_inode_locked(inode); ret = btrfs_insert_inode_locked(inode);
if (ret < 0) { if (ret < 0) {
if (!args->orphan) if (!args->orphan)
......
...@@ -1918,7 +1918,7 @@ static int btrfs_search_path_in_tree_user(struct mnt_idmap *idmap, ...@@ -1918,7 +1918,7 @@ static int btrfs_search_path_in_tree_user(struct mnt_idmap *idmap,
{ {
struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info; struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info;
struct super_block *sb = inode->i_sb; struct super_block *sb = inode->i_sb;
u64 upper_limit = BTRFS_I(inode)->objectid; u64 upper_limit = btrfs_ino(BTRFS_I(inode));
u64 treeid = btrfs_root_id(BTRFS_I(inode)->root); u64 treeid = btrfs_root_id(BTRFS_I(inode)->root);
u64 dirid = args->dirid; u64 dirid = args->dirid;
unsigned long item_off; unsigned long item_off;
...@@ -2140,7 +2140,7 @@ static int btrfs_ioctl_ino_lookup_user(struct file *file, void __user *argp) ...@@ -2140,7 +2140,7 @@ static int btrfs_ioctl_ino_lookup_user(struct file *file, void __user *argp)
inode = file_inode(file); inode = file_inode(file);
if (args->dirid == BTRFS_FIRST_FREE_OBJECTID && if (args->dirid == BTRFS_FIRST_FREE_OBJECTID &&
BTRFS_I(inode)->objectid != BTRFS_FIRST_FREE_OBJECTID) { btrfs_ino(BTRFS_I(inode)) != BTRFS_FIRST_FREE_OBJECTID) {
/* /*
* The subvolume does not exist under fd with which this is * The subvolume does not exist under fd with which this is
* called * called
......
...@@ -61,8 +61,7 @@ struct inode *btrfs_new_test_inode(void) ...@@ -61,8 +61,7 @@ struct inode *btrfs_new_test_inode(void)
return NULL; return NULL;
inode->i_mode = S_IFREG; inode->i_mode = S_IFREG;
inode->i_ino = BTRFS_FIRST_FREE_OBJECTID; btrfs_set_inode_number(BTRFS_I(inode), BTRFS_FIRST_FREE_OBJECTID);
BTRFS_I(inode)->objectid = BTRFS_FIRST_FREE_OBJECTID;
inode_init_owner(&nop_mnt_idmap, inode, NULL, S_IFREG); inode_init_owner(&nop_mnt_idmap, inode, NULL, S_IFREG);
return inode; return inode;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment