18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * fs/hmdfs/inode.c
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include "hmdfs_device_view.h"
98c2ecf20Sopenharmony_ci#include "inode.h"
108c2ecf20Sopenharmony_ci#include "comm/connection.h"
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci/**
138c2ecf20Sopenharmony_ci * Rules to generate inode numbers:
148c2ecf20Sopenharmony_ci *
158c2ecf20Sopenharmony_ci * "/", "/device_view", "/merge_view", "/device_view/local", "/device_view/cid"
168c2ecf20Sopenharmony_ci * = DOMAIN {3} : dev_id {29} : HMDFS_ROOT {32}
178c2ecf20Sopenharmony_ci *
188c2ecf20Sopenharmony_ci * "/device_view/cid/xxx"
198c2ecf20Sopenharmony_ci * = DOMAIN {3} : dev_id {29} : hash(remote_ino){32}
208c2ecf20Sopenharmony_ci *
218c2ecf20Sopenharmony_ci * "/merge_view/xxx"
228c2ecf20Sopenharmony_ci * = DOMAIN {3} : lower's dev_id {29} : lower's ino_raw {32}
238c2ecf20Sopenharmony_ci */
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci#define BIT_WIDE_TOTAL 64
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci#define BIT_WIDE_DOMAIN 3
288c2ecf20Sopenharmony_ci#define BIT_WIDE_DEVID 29
298c2ecf20Sopenharmony_ci#define BIT_WIDE_INO_RAW 32
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_cienum DOMAIN {
328c2ecf20Sopenharmony_ci	DOMAIN_ROOT,
338c2ecf20Sopenharmony_ci	DOMAIN_DEVICE_LOCAL,
348c2ecf20Sopenharmony_ci	DOMAIN_DEVICE_REMOTE,
358c2ecf20Sopenharmony_ci	DOMAIN_DEVICE_CLOUD,
368c2ecf20Sopenharmony_ci	DOMAIN_MERGE_VIEW,
378c2ecf20Sopenharmony_ci	DOMAIN_CLOUD_MERGE_VIEW,
388c2ecf20Sopenharmony_ci	DOMAIN_INVALID,
398c2ecf20Sopenharmony_ci};
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ciunion hmdfs_ino {
428c2ecf20Sopenharmony_ci	const uint64_t ino_output;
438c2ecf20Sopenharmony_ci	struct {
448c2ecf20Sopenharmony_ci		uint64_t ino_raw : BIT_WIDE_INO_RAW;
458c2ecf20Sopenharmony_ci		uint64_t dev_id : BIT_WIDE_DEVID;
468c2ecf20Sopenharmony_ci		uint8_t domain : BIT_WIDE_DOMAIN;
478c2ecf20Sopenharmony_ci	};
488c2ecf20Sopenharmony_ci};
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_cistatic uint8_t read_ino_domain(uint64_t ino)
518c2ecf20Sopenharmony_ci{
528c2ecf20Sopenharmony_ci	union hmdfs_ino _ino = {
538c2ecf20Sopenharmony_ci		.ino_output = ino,
548c2ecf20Sopenharmony_ci	};
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	return _ino.domain;
578c2ecf20Sopenharmony_ci}
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_cistruct iget_args {
608c2ecf20Sopenharmony_ci	/* The lower inode of local/merge/root(part) inode */
618c2ecf20Sopenharmony_ci	struct inode *lo_i;
628c2ecf20Sopenharmony_ci	/* The peer of remote inode */
638c2ecf20Sopenharmony_ci	struct hmdfs_peer *peer;
648c2ecf20Sopenharmony_ci	/* The ino of remote inode */
658c2ecf20Sopenharmony_ci	uint64_t remote_ino;
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci	/* The recordId of cloud inode */
688c2ecf20Sopenharmony_ci	uint8_t *cloud_record_id;
698c2ecf20Sopenharmony_ci	uint8_t *reserved;
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	/* Returned inode's ino */
728c2ecf20Sopenharmony_ci	union hmdfs_ino ino;
738c2ecf20Sopenharmony_ci};
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci/**
768c2ecf20Sopenharmony_ci * iget_test - whether or not the inode with matched hashval is the one we are
778c2ecf20Sopenharmony_ci * looking for
788c2ecf20Sopenharmony_ci *
798c2ecf20Sopenharmony_ci * @inode: the local inode we found in inode cache with matched hashval
808c2ecf20Sopenharmony_ci * @data: struct iget_args
818c2ecf20Sopenharmony_ci */
828c2ecf20Sopenharmony_cistatic int iget_test(struct inode *inode, void *data)
838c2ecf20Sopenharmony_ci{
848c2ecf20Sopenharmony_ci	struct hmdfs_inode_info *hii = hmdfs_i(inode);
858c2ecf20Sopenharmony_ci	struct iget_args *ia = data;
868c2ecf20Sopenharmony_ci	int res = 0;
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci	WARN_ON(ia->ino.domain < DOMAIN_ROOT ||
898c2ecf20Sopenharmony_ci		ia->ino.domain >= DOMAIN_INVALID);
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci	if (read_ino_domain(inode->i_ino) == DOMAIN_ROOT)
928c2ecf20Sopenharmony_ci		return 1;
938c2ecf20Sopenharmony_ci	if (read_ino_domain(inode->i_ino) != ia->ino.domain)
948c2ecf20Sopenharmony_ci		return 0;
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci	switch (ia->ino.domain) {
978c2ecf20Sopenharmony_ci	case DOMAIN_MERGE_VIEW:
988c2ecf20Sopenharmony_ci	case DOMAIN_CLOUD_MERGE_VIEW:
998c2ecf20Sopenharmony_ci		res = (ia->lo_i == hii->lower_inode);
1008c2ecf20Sopenharmony_ci		break;
1018c2ecf20Sopenharmony_ci	case DOMAIN_DEVICE_LOCAL:
1028c2ecf20Sopenharmony_ci		res = (ia->lo_i == hii->lower_inode);
1038c2ecf20Sopenharmony_ci		break;
1048c2ecf20Sopenharmony_ci	case DOMAIN_DEVICE_REMOTE:
1058c2ecf20Sopenharmony_ci		res = (ia->peer == hii->conn &&
1068c2ecf20Sopenharmony_ci		       ia->remote_ino == hii->remote_ino);
1078c2ecf20Sopenharmony_ci		break;
1088c2ecf20Sopenharmony_ci	case DOMAIN_DEVICE_CLOUD:
1098c2ecf20Sopenharmony_ci		res = (ia->cloud_record_id &&
1108c2ecf20Sopenharmony_ci		       (memcmp(ia->cloud_record_id, hii->cloud_record_id,
1118c2ecf20Sopenharmony_ci			       CLOUD_RECORD_ID_LEN) == 0) &&
1128c2ecf20Sopenharmony_ci		       (ia->reserved[0] == hii->reserved[0]));
1138c2ecf20Sopenharmony_ci		break;
1148c2ecf20Sopenharmony_ci	}
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci	return res;
1178c2ecf20Sopenharmony_ci}
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci/**
1208c2ecf20Sopenharmony_ci * iget_set - initialize a inode with iget_args
1218c2ecf20Sopenharmony_ci *
1228c2ecf20Sopenharmony_ci * @sb: the superblock of current hmdfs instance
1238c2ecf20Sopenharmony_ci * @data: struct iget_args
1248c2ecf20Sopenharmony_ci */
1258c2ecf20Sopenharmony_cistatic int iget_set(struct inode *inode, void *data)
1268c2ecf20Sopenharmony_ci{
1278c2ecf20Sopenharmony_ci	struct hmdfs_inode_info *hii = hmdfs_i(inode);
1288c2ecf20Sopenharmony_ci	struct iget_args *ia = (struct iget_args *)data;
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci	inode->i_ino = ia->ino.ino_output;
1318c2ecf20Sopenharmony_ci	inode_inc_iversion(inode);
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci	hii->conn = ia->peer;
1348c2ecf20Sopenharmony_ci	hii->remote_ino = ia->remote_ino;
1358c2ecf20Sopenharmony_ci	hii->lower_inode = ia->lo_i;
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci	if (ia->cloud_record_id) {
1388c2ecf20Sopenharmony_ci		memcpy(hii->cloud_record_id, ia->cloud_record_id, CLOUD_RECORD_ID_LEN);
1398c2ecf20Sopenharmony_ci		memcpy(hii->reserved, ia->reserved, CLOUD_DENTRY_RESERVED_LENGTH);
1408c2ecf20Sopenharmony_ci	}
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ci	return 0;
1438c2ecf20Sopenharmony_ci}
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_cistatic uint64_t make_ino_raw_dev_local(uint64_t lo_ino)
1468c2ecf20Sopenharmony_ci{
1478c2ecf20Sopenharmony_ci	if (!(lo_ino >> BIT_WIDE_INO_RAW))
1488c2ecf20Sopenharmony_ci		return lo_ino;
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci	return lo_ino * GOLDEN_RATIO_64 >> BIT_WIDE_INO_RAW;
1518c2ecf20Sopenharmony_ci}
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_cistatic uint64_t make_ino_raw_dev_remote(uint64_t remote_ino)
1548c2ecf20Sopenharmony_ci{
1558c2ecf20Sopenharmony_ci	return hash_long(remote_ino, BIT_WIDE_INO_RAW);
1568c2ecf20Sopenharmony_ci}
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci/**
1598c2ecf20Sopenharmony_ci * hmdfs_iget5_locked_merge - obtain an inode for the merge-view
1608c2ecf20Sopenharmony_ci *
1618c2ecf20Sopenharmony_ci * @sb: superblock of current instance
1628c2ecf20Sopenharmony_ci * @fst_lo_i: the lower inode of it's first comrade
1638c2ecf20Sopenharmony_ci *
1648c2ecf20Sopenharmony_ci * Simply replace the lower's domain for a new ino.
1658c2ecf20Sopenharmony_ci */
1668c2ecf20Sopenharmony_cistruct inode *hmdfs_iget5_locked_merge(struct super_block *sb,
1678c2ecf20Sopenharmony_ci				       struct dentry *fst_lo_d)
1688c2ecf20Sopenharmony_ci{
1698c2ecf20Sopenharmony_ci	struct iget_args ia = {
1708c2ecf20Sopenharmony_ci		.lo_i = d_inode(fst_lo_d),
1718c2ecf20Sopenharmony_ci		.peer = NULL,
1728c2ecf20Sopenharmony_ci		.remote_ino = 0,
1738c2ecf20Sopenharmony_ci		.cloud_record_id = NULL,
1748c2ecf20Sopenharmony_ci		.ino.ino_output = 0,
1758c2ecf20Sopenharmony_ci	};
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_ci	if (unlikely(!d_inode(fst_lo_d))) {
1788c2ecf20Sopenharmony_ci		hmdfs_err("Received a invalid lower inode");
1798c2ecf20Sopenharmony_ci		return NULL;
1808c2ecf20Sopenharmony_ci	}
1818c2ecf20Sopenharmony_ci	if (unlikely(!hmdfs_d(fst_lo_d))) {
1828c2ecf20Sopenharmony_ci		hmdfs_err("Received a invalid fsdata");
1838c2ecf20Sopenharmony_ci		return NULL;
1848c2ecf20Sopenharmony_ci	}
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci	ia.ino.ino_raw = d_inode(fst_lo_d)->i_ino;
1878c2ecf20Sopenharmony_ci	ia.ino.dev_id = hmdfs_d(fst_lo_d)->device_id;
1888c2ecf20Sopenharmony_ci	ia.ino.domain = DOMAIN_MERGE_VIEW;
1898c2ecf20Sopenharmony_ci	return iget5_locked(sb, ia.ino.ino_output, iget_test, iget_set, &ia);
1908c2ecf20Sopenharmony_ci}
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_cistruct inode *hmdfs_iget5_locked_cloud_merge(struct super_block *sb,
1938c2ecf20Sopenharmony_ci					     struct dentry *fst_lo_d)
1948c2ecf20Sopenharmony_ci{
1958c2ecf20Sopenharmony_ci	struct iget_args ia = {
1968c2ecf20Sopenharmony_ci		.lo_i = d_inode(fst_lo_d),
1978c2ecf20Sopenharmony_ci		.peer = NULL,
1988c2ecf20Sopenharmony_ci		.remote_ino = 0,
1998c2ecf20Sopenharmony_ci		.cloud_record_id = NULL,
2008c2ecf20Sopenharmony_ci		.ino.ino_output = 0,
2018c2ecf20Sopenharmony_ci	};
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ci	if (unlikely(!d_inode(fst_lo_d))) {
2048c2ecf20Sopenharmony_ci		hmdfs_err("Received a invalid lower inode");
2058c2ecf20Sopenharmony_ci		return NULL;
2068c2ecf20Sopenharmony_ci	}
2078c2ecf20Sopenharmony_ci	if (unlikely(!hmdfs_d(fst_lo_d))) {
2088c2ecf20Sopenharmony_ci		hmdfs_err("Received a invalid fsdata");
2098c2ecf20Sopenharmony_ci		return NULL;
2108c2ecf20Sopenharmony_ci	}
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_ci	ia.ino.ino_raw = d_inode(fst_lo_d)->i_ino;
2138c2ecf20Sopenharmony_ci	ia.ino.dev_id = hmdfs_d(fst_lo_d)->device_id;
2148c2ecf20Sopenharmony_ci	ia.ino.domain = DOMAIN_CLOUD_MERGE_VIEW;
2158c2ecf20Sopenharmony_ci	return iget5_locked(sb, ia.ino.ino_output, iget_test, iget_set, &ia);
2168c2ecf20Sopenharmony_ci}
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ci/**
2198c2ecf20Sopenharmony_ci * hmdfs_iget5_locked_local - obtain an inode for the local-dev-view
2208c2ecf20Sopenharmony_ci *
2218c2ecf20Sopenharmony_ci * @sb: superblock of current instance
2228c2ecf20Sopenharmony_ci * @lo_i: the lower inode from local filesystem
2238c2ecf20Sopenharmony_ci *
2248c2ecf20Sopenharmony_ci * Hashing local inode's ino to generate our ino. We continue to compare the
2258c2ecf20Sopenharmony_ci * address of the lower_inode for uniqueness when collisions occurred.
2268c2ecf20Sopenharmony_ci */
2278c2ecf20Sopenharmony_cistruct inode *hmdfs_iget5_locked_local(struct super_block *sb,
2288c2ecf20Sopenharmony_ci				       struct inode *lo_i)
2298c2ecf20Sopenharmony_ci{
2308c2ecf20Sopenharmony_ci	struct iget_args ia = {
2318c2ecf20Sopenharmony_ci		.lo_i = lo_i,
2328c2ecf20Sopenharmony_ci		.peer = NULL,
2338c2ecf20Sopenharmony_ci		.remote_ino = 0,
2348c2ecf20Sopenharmony_ci		.cloud_record_id = NULL,
2358c2ecf20Sopenharmony_ci		.ino.ino_output = 0,
2368c2ecf20Sopenharmony_ci	};
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci	if (unlikely(!lo_i)) {
2398c2ecf20Sopenharmony_ci		hmdfs_err("Received a invalid lower inode");
2408c2ecf20Sopenharmony_ci		return NULL;
2418c2ecf20Sopenharmony_ci	}
2428c2ecf20Sopenharmony_ci	ia.ino.ino_raw = make_ino_raw_dev_local(lo_i->i_ino);
2438c2ecf20Sopenharmony_ci	ia.ino.dev_id = 0;
2448c2ecf20Sopenharmony_ci	ia.ino.domain = DOMAIN_DEVICE_LOCAL;
2458c2ecf20Sopenharmony_ci	return iget5_locked(sb, ia.ino.ino_output, iget_test, iget_set, &ia);
2468c2ecf20Sopenharmony_ci}
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_ci/**
2498c2ecf20Sopenharmony_ci * hmdfs_iget5_locked_remote - obtain an inode for the remote-dev-view
2508c2ecf20Sopenharmony_ci *
2518c2ecf20Sopenharmony_ci * @sb: superblock of current instance
2528c2ecf20Sopenharmony_ci * @peer: corresponding device node
2538c2ecf20Sopenharmony_ci * @remote_ino: remote inode's ino
2548c2ecf20Sopenharmony_ci *
2558c2ecf20Sopenharmony_ci * Hash remote ino for ino's 32bit~1bit.
2568c2ecf20Sopenharmony_ci *
2578c2ecf20Sopenharmony_ci * Note that currenly implementation assume the each remote inode has unique
2588c2ecf20Sopenharmony_ci * ino. Thus the combination of the peer's unique dev_id and the remote_ino
2598c2ecf20Sopenharmony_ci * is enough to determine a unique remote inode.
2608c2ecf20Sopenharmony_ci */
2618c2ecf20Sopenharmony_cistruct inode *hmdfs_iget5_locked_remote(struct super_block *sb,
2628c2ecf20Sopenharmony_ci					struct hmdfs_peer *peer,
2638c2ecf20Sopenharmony_ci					uint64_t remote_ino)
2648c2ecf20Sopenharmony_ci{
2658c2ecf20Sopenharmony_ci	struct iget_args ia = {
2668c2ecf20Sopenharmony_ci		.lo_i = NULL,
2678c2ecf20Sopenharmony_ci		.peer = peer,
2688c2ecf20Sopenharmony_ci		.remote_ino = remote_ino,
2698c2ecf20Sopenharmony_ci		.cloud_record_id = NULL,
2708c2ecf20Sopenharmony_ci		.ino.ino_output = 0,
2718c2ecf20Sopenharmony_ci	};
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_ci	if (unlikely(!peer)) {
2748c2ecf20Sopenharmony_ci		hmdfs_err("Received a invalid peer");
2758c2ecf20Sopenharmony_ci		return NULL;
2768c2ecf20Sopenharmony_ci	}
2778c2ecf20Sopenharmony_ci
2788c2ecf20Sopenharmony_ci	ia.ino.ino_raw = make_ino_raw_dev_remote(remote_ino);
2798c2ecf20Sopenharmony_ci	ia.ino.dev_id = peer->device_id;
2808c2ecf20Sopenharmony_ci	ia.ino.domain = DOMAIN_DEVICE_REMOTE;
2818c2ecf20Sopenharmony_ci	return iget5_locked(sb, ia.ino.ino_output, iget_test, iget_set, &ia);
2828c2ecf20Sopenharmony_ci}
2838c2ecf20Sopenharmony_ci
2848c2ecf20Sopenharmony_ci/**
2858c2ecf20Sopenharmony_ci * hmdfs_iget5_locked_cloud - obtain an inode for the cloud-dev-view
2868c2ecf20Sopenharmony_ci *
2878c2ecf20Sopenharmony_ci * @sb: superblock of current instance
2888c2ecf20Sopenharmony_ci * @peer: corresponding device node
2898c2ecf20Sopenharmony_ci * @cloud_id: cloud file record id
2908c2ecf20Sopenharmony_ci *
2918c2ecf20Sopenharmony_ci * Hash remote ino for ino's 32bit~1bit.
2928c2ecf20Sopenharmony_ci *
2938c2ecf20Sopenharmony_ci * Note that currenly implementation assume the each remote inode has unique
2948c2ecf20Sopenharmony_ci * ino. Thus the combination of the peer's unique dev_id and the remote_ino
2958c2ecf20Sopenharmony_ci * is enough to determine a unique remote inode.
2968c2ecf20Sopenharmony_ci */
2978c2ecf20Sopenharmony_cistruct inode *hmdfs_iget5_locked_cloud(struct super_block *sb,
2988c2ecf20Sopenharmony_ci				       struct hmdfs_peer *peer,
2998c2ecf20Sopenharmony_ci				       struct hmdfs_lookup_cloud_ret *res)
3008c2ecf20Sopenharmony_ci{
3018c2ecf20Sopenharmony_ci	struct iget_args ia = {
3028c2ecf20Sopenharmony_ci		.lo_i = NULL,
3038c2ecf20Sopenharmony_ci		.peer = peer,
3048c2ecf20Sopenharmony_ci		.remote_ino = 0,
3058c2ecf20Sopenharmony_ci		.cloud_record_id = res->record_id,
3068c2ecf20Sopenharmony_ci		.reserved = res->reserved,
3078c2ecf20Sopenharmony_ci		.ino.ino_output = 0,
3088c2ecf20Sopenharmony_ci	};
3098c2ecf20Sopenharmony_ci
3108c2ecf20Sopenharmony_ci	if (unlikely(!peer)) {
3118c2ecf20Sopenharmony_ci		hmdfs_err("Received a invalid peer");
3128c2ecf20Sopenharmony_ci		return NULL;
3138c2ecf20Sopenharmony_ci	}
3148c2ecf20Sopenharmony_ci
3158c2ecf20Sopenharmony_ci	ia.ino.ino_raw = make_ino_raw_cloud(res->record_id) + res->reserved[0];
3168c2ecf20Sopenharmony_ci	ia.ino.dev_id = peer->device_id;
3178c2ecf20Sopenharmony_ci	ia.ino.domain = DOMAIN_DEVICE_CLOUD;
3188c2ecf20Sopenharmony_ci	return iget5_locked(sb, ia.ino.ino_output, iget_test, iget_set, &ia);
3198c2ecf20Sopenharmony_ci}
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_cistruct inode *hmdfs_iget_locked_root(struct super_block *sb, uint64_t root_ino,
3228c2ecf20Sopenharmony_ci				     struct inode *lo_i,
3238c2ecf20Sopenharmony_ci				     struct hmdfs_peer *peer)
3248c2ecf20Sopenharmony_ci{
3258c2ecf20Sopenharmony_ci	struct iget_args ia = {
3268c2ecf20Sopenharmony_ci		.lo_i = lo_i,
3278c2ecf20Sopenharmony_ci		.peer = peer,
3288c2ecf20Sopenharmony_ci		.remote_ino = 0,
3298c2ecf20Sopenharmony_ci		.cloud_record_id = NULL,
3308c2ecf20Sopenharmony_ci		.ino.ino_raw = root_ino,
3318c2ecf20Sopenharmony_ci		.ino.dev_id = peer ? peer->device_id : 0,
3328c2ecf20Sopenharmony_ci		.ino.domain = DOMAIN_ROOT,
3338c2ecf20Sopenharmony_ci	};
3348c2ecf20Sopenharmony_ci
3358c2ecf20Sopenharmony_ci	if (unlikely(root_ino < 0 || root_ino >= HMDFS_ROOT_INVALID)) {
3368c2ecf20Sopenharmony_ci		hmdfs_err("Root %llu is invalid", root_ino);
3378c2ecf20Sopenharmony_ci		return NULL;
3388c2ecf20Sopenharmony_ci	}
3398c2ecf20Sopenharmony_ci	if (unlikely(root_ino == HMDFS_ROOT_DEV_REMOTE && !peer)) {
3408c2ecf20Sopenharmony_ci		hmdfs_err("Root %llu received a invalid peer", root_ino);
3418c2ecf20Sopenharmony_ci		return NULL;
3428c2ecf20Sopenharmony_ci	}
3438c2ecf20Sopenharmony_ci
3448c2ecf20Sopenharmony_ci	return iget5_locked(sb, ia.ino.ino_output, iget_test, iget_set, &ia);
3458c2ecf20Sopenharmony_ci}
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_ci
3488c2ecf20Sopenharmony_civoid hmdfs_update_upper_file(struct file *upper_file, struct file *lower_file)
3498c2ecf20Sopenharmony_ci{
3508c2ecf20Sopenharmony_ci	loff_t upper_size = i_size_read(upper_file->f_inode);
3518c2ecf20Sopenharmony_ci	loff_t lower_size = i_size_read(lower_file->f_inode);
3528c2ecf20Sopenharmony_ci
3538c2ecf20Sopenharmony_ci	if (upper_file->f_inode->i_mapping && upper_size != lower_size) {
3548c2ecf20Sopenharmony_ci		i_size_write(upper_file->f_inode, lower_size);
3558c2ecf20Sopenharmony_ci		truncate_inode_pages(upper_file->f_inode->i_mapping, 0);
3568c2ecf20Sopenharmony_ci	}
3578c2ecf20Sopenharmony_ci}