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: Li Zefan <lizf@cn.fujitsu.com>
This commit is contained in:
@@ -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,11 +280,11 @@ static int btrfs_get_name(struct dentry *parent, char *name,
|
||||
}
|
||||
leaf = path->nodes[0];
|
||||
|
||||
if (inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) {
|
||||
rref = btrfs_item_ptr(leaf, path->slots[0],
|
||||
if (ino == BTRFS_FIRST_FREE_OBJECTID) {
|
||||
rref = btrfs_item_ptr(leaf, path->slots[0],
|
||||
struct btrfs_root_ref);
|
||||
name_ptr = (unsigned long)(rref + 1);
|
||||
name_len = btrfs_root_ref_name_len(leaf, rref);
|
||||
name_ptr = (unsigned long)(rref + 1);
|
||||
name_len = btrfs_root_ref_name_len(leaf, rref);
|
||||
} else {
|
||||
iref = btrfs_item_ptr(leaf, path->slots[0],
|
||||
struct btrfs_inode_ref);
|
||||
|
Reference in New Issue
Block a user