Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 33345d01 authored by Li Zefan's avatar Li Zefan
Browse files

Btrfs: Always use 64bit inode number



There's a potential problem in 32bit system when we exhaust 32bit inode
numbers and start to allocate big inode numbers, because btrfs uses
inode->i_ino in many places.

So here we always use BTRFS_I(inode)->location.objectid, which is an
u64 variable.

There are 2 exceptions that BTRFS_I(inode)->location.objectid !=
inode->i_ino: the btree inode (0 vs 1) and empty subvol dirs (256 vs 2),
and inode->i_ino will be used in those cases.

Another reason to make this change is I'm going to use a special inode
to save free ino cache, and the inode number must be > (u64)-256.

Signed-off-by: default avatarLi Zefan <lizf@cn.fujitsu.com>
parent 0414efae
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -166,6 +166,15 @@ static inline struct btrfs_inode *BTRFS_I(struct inode *inode)
	return container_of(inode, struct btrfs_inode, vfs_inode);
}

static inline u64 btrfs_ino(struct inode *inode)
{
	u64 ino = BTRFS_I(inode)->location.objectid;

	if (ino <= BTRFS_FIRST_FREE_OBJECTID)
		ino = inode->i_ino;
	return ino;
}

static inline void btrfs_i_size_write(struct inode *inode, u64 size)
{
	i_size_write(inode, size);
+3 −2
Original line number Diff line number Diff line
@@ -125,9 +125,10 @@ static int check_compressed_csum(struct inode *inode,
		kunmap_atomic(kaddr, KM_USER0);

		if (csum != *cb_sum) {
			printk(KERN_INFO "btrfs csum failed ino %lu "
			printk(KERN_INFO "btrfs csum failed ino %llu "
			       "extent %llu csum %u "
			       "wanted %u mirror %d\n", inode->i_ino,
			       "wanted %u mirror %d\n",
			       (unsigned long long)btrfs_ino(inode),
			       (unsigned long long)disk_start,
			       csum, *cb_sum, cb->mirror_num);
			ret = -EIO;
+14 −11
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ static int btrfs_encode_fh(struct dentry *dentry, u32 *fh, int *max_len,
	len  = BTRFS_FID_SIZE_NON_CONNECTABLE;
	type = FILEID_BTRFS_WITHOUT_PARENT;

	fid->objectid = inode->i_ino;
	fid->objectid = btrfs_ino(inode);
	fid->root_objectid = BTRFS_I(inode)->root->objectid;
	fid->gen = inode->i_generation;

@@ -174,13 +174,13 @@ static struct dentry *btrfs_get_parent(struct dentry *child)
	if (!path)
		return ERR_PTR(-ENOMEM);

	if (dir->i_ino == BTRFS_FIRST_FREE_OBJECTID) {
	if (btrfs_ino(dir) == BTRFS_FIRST_FREE_OBJECTID) {
		key.objectid = root->root_key.objectid;
		key.type = BTRFS_ROOT_BACKREF_KEY;
		key.offset = (u64)-1;
		root = root->fs_info->tree_root;
	} else {
		key.objectid = dir->i_ino;
		key.objectid = btrfs_ino(dir);
		key.type = BTRFS_INODE_REF_KEY;
		key.offset = (u64)-1;
	}
@@ -240,6 +240,7 @@ static int btrfs_get_name(struct dentry *parent, char *name,
	struct btrfs_key key;
	int name_len;
	int ret;
	u64 ino;

	if (!dir || !inode)
		return -EINVAL;
@@ -247,19 +248,21 @@ static int btrfs_get_name(struct dentry *parent, char *name,
	if (!S_ISDIR(dir->i_mode))
		return -EINVAL;

	ino = btrfs_ino(inode);

	path = btrfs_alloc_path();
	if (!path)
		return -ENOMEM;
	path->leave_spinning = 1;

	if (inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) {
	if (ino == BTRFS_FIRST_FREE_OBJECTID) {
		key.objectid = BTRFS_I(inode)->root->root_key.objectid;
		key.type = BTRFS_ROOT_BACKREF_KEY;
		key.offset = (u64)-1;
		root = root->fs_info->tree_root;
	} else {
		key.objectid = inode->i_ino;
		key.offset = dir->i_ino;
		key.objectid = ino;
		key.offset = btrfs_ino(dir);
		key.type = BTRFS_INODE_REF_KEY;
	}

@@ -268,7 +271,7 @@ static int btrfs_get_name(struct dentry *parent, char *name,
		btrfs_free_path(path);
		return ret;
	} else if (ret > 0) {
		if (inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) {
		if (ino == BTRFS_FIRST_FREE_OBJECTID) {
			path->slots[0]--;
		} else {
			btrfs_free_path(path);
@@ -277,7 +280,7 @@ static int btrfs_get_name(struct dentry *parent, char *name,
	}
	leaf = path->nodes[0];

	if (inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) {
	if (ino == BTRFS_FIRST_FREE_OBJECTID) {
		rref = btrfs_item_ptr(leaf, path->slots[0],
				     struct btrfs_root_ref);
		name_ptr = (unsigned long)(rref + 1);
+5 −5
Original line number Diff line number Diff line
@@ -7009,8 +7009,8 @@ static noinline int get_new_locations(struct inode *reloc_inode,

	cur_pos = extent_key->objectid - offset;
	last_byte = extent_key->objectid + extent_key->offset;
	ret = btrfs_lookup_file_extent(NULL, root, path, reloc_inode->i_ino,
				       cur_pos, 0);
	ret = btrfs_lookup_file_extent(NULL, root, path,
				       btrfs_ino(reloc_inode), cur_pos, 0);
	if (ret < 0)
		goto out;
	if (ret > 0) {
@@ -7033,7 +7033,7 @@ static noinline int get_new_locations(struct inode *reloc_inode,
		btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
		if (found_key.offset != cur_pos ||
		    found_key.type != BTRFS_EXTENT_DATA_KEY ||
		    found_key.objectid != reloc_inode->i_ino)
		    found_key.objectid != btrfs_ino(reloc_inode))
			break;

		fi = btrfs_item_ptr(leaf, path->slots[0],
@@ -7179,7 +7179,7 @@ next:
				break;
		}

		if (inode && key.objectid != inode->i_ino) {
		if (inode && key.objectid != btrfs_ino(inode)) {
			BUG_ON(extent_locked);
			btrfs_release_path(root, path);
			mutex_unlock(&inode->i_mutex);
@@ -7488,7 +7488,7 @@ static noinline int invalidate_extent_cache(struct btrfs_root *root,
			continue;
		if (btrfs_file_extent_disk_bytenr(leaf, fi) == 0)
			continue;
		if (!inode || inode->i_ino != key.objectid) {
		if (!inode || btrfs_ino(inode) != key.objectid) {
			iput(inode);
			inode = btrfs_ilookup(target_root->fs_info->sb,
					      key.objectid, target_root, 1);
+2 −2
Original line number Diff line number Diff line
@@ -3030,7 +3030,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
	 * because there might be preallocation past i_size
	 */
	ret = btrfs_lookup_file_extent(NULL, BTRFS_I(inode)->root,
				       path, inode->i_ino, -1, 0);
				       path, btrfs_ino(inode), -1, 0);
	if (ret < 0) {
		btrfs_free_path(path);
		return ret;
@@ -3043,7 +3043,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
	found_type = btrfs_key_type(&found_key);

	/* No extents, but there might be delalloc bits */
	if (found_key.objectid != inode->i_ino ||
	if (found_key.objectid != btrfs_ino(inode) ||
	    found_type != BTRFS_EXTENT_DATA_KEY) {
		/* have to trust i_size as the end */
		last = (u64)-1;
Loading