// SPDX-License-Identifier: GPL-2.0+
#include "internal.h"

int erofs_read_inode_from_disk(struct erofs_inode *vi)
{
	int ret, ifmt;
	char buf[sizeof(struct erofs_inode_extended)];
	struct erofs_inode_compact *dic;
	struct erofs_inode_extended *die;
	const erofs_off_t inode_loc = iloc(vi->nid);

	ret = erofs_dev_read(0, buf, inode_loc, sizeof(*dic));
	if (ret < 0)
		return -EIO;

	dic = (struct erofs_inode_compact *)buf;
	ifmt = le16_to_cpu(dic->i_format);

	vi->datalayout = erofs_inode_datalayout(ifmt);
	if (vi->datalayout >= EROFS_INODE_DATALAYOUT_MAX) {
		erofs_err("unsupported datalayout %u of nid %llu",
			  vi->datalayout, vi->nid | 0ULL);
		return -EOPNOTSUPP;
	}
	switch (erofs_inode_version(ifmt)) {
	case EROFS_INODE_LAYOUT_EXTENDED:
		vi->inode_isize = sizeof(struct erofs_inode_extended);

		ret = erofs_dev_read(0, buf + sizeof(*dic), inode_loc + sizeof(*dic),
				     sizeof(*die) - sizeof(*dic));
		if (ret < 0)
			return -EIO;

		die = (struct erofs_inode_extended *)buf;
		vi->xattr_isize = erofs_xattr_ibody_size(die->i_xattr_icount);
		vi->i_mode = le16_to_cpu(die->i_mode);

		switch (vi->i_mode & S_IFMT) {
		case S_IFREG:
		case S_IFDIR:
		case S_IFLNK:
			vi->u.i_blkaddr = le32_to_cpu(die->i_u.raw_blkaddr);
			break;
		case S_IFCHR:
		case S_IFBLK:
			vi->u.i_rdev = 0;
			break;
		case S_IFIFO:
		case S_IFSOCK:
			vi->u.i_rdev = 0;
			break;
		default:
			goto bogusimode;
		}

		vi->i_uid = le32_to_cpu(die->i_uid);
		vi->i_gid = le32_to_cpu(die->i_gid);
		vi->i_nlink = le32_to_cpu(die->i_nlink);

		vi->i_ctime = le64_to_cpu(die->i_ctime);
		vi->i_ctime_nsec = le64_to_cpu(die->i_ctime_nsec);
		vi->i_size = le64_to_cpu(die->i_size);
		if (vi->datalayout == EROFS_INODE_CHUNK_BASED)
			/* fill chunked inode summary info */
			vi->u.chunkformat = le16_to_cpu(die->i_u.c.format);
		break;
	case EROFS_INODE_LAYOUT_COMPACT:
		vi->inode_isize = sizeof(struct erofs_inode_compact);
		vi->xattr_isize = erofs_xattr_ibody_size(dic->i_xattr_icount);
		vi->i_mode = le16_to_cpu(dic->i_mode);

		switch (vi->i_mode & S_IFMT) {
		case S_IFREG:
		case S_IFDIR:
		case S_IFLNK:
			vi->u.i_blkaddr = le32_to_cpu(dic->i_u.raw_blkaddr);
			break;
		case S_IFCHR:
		case S_IFBLK:
			vi->u.i_rdev = 0;
			break;
		case S_IFIFO:
		case S_IFSOCK:
			vi->u.i_rdev = 0;
			break;
		default:
			goto bogusimode;
		}

		vi->i_uid = le16_to_cpu(dic->i_uid);
		vi->i_gid = le16_to_cpu(dic->i_gid);
		vi->i_nlink = le16_to_cpu(dic->i_nlink);

		vi->i_ctime = sbi.build_time;
		vi->i_ctime_nsec = sbi.build_time_nsec;

		vi->i_size = le32_to_cpu(dic->i_size);
		if (vi->datalayout == EROFS_INODE_CHUNK_BASED)
			vi->u.chunkformat = le16_to_cpu(dic->i_u.c.format);
		break;
	default:
		erofs_err("unsupported on-disk inode version %u of nid %llu",
			  erofs_inode_version(ifmt), vi->nid | 0ULL);
		return -EOPNOTSUPP;
	}

	vi->flags = 0;
	if (vi->datalayout == EROFS_INODE_CHUNK_BASED) {
		if (vi->u.chunkformat & ~EROFS_CHUNK_FORMAT_ALL) {
			erofs_err("unsupported chunk format %x of nid %llu",
				  vi->u.chunkformat, vi->nid | 0ULL);
			return -EOPNOTSUPP;
		}
		vi->u.chunkbits = LOG_BLOCK_SIZE +
			(vi->u.chunkformat & EROFS_CHUNK_FORMAT_BLKBITS_MASK);
	} else if (erofs_inode_is_data_compressed(vi->datalayout))
		return -EOPNOTSUPP;
	return 0;
bogusimode:
	erofs_err("bogus i_mode (%o) @ nid %llu", vi->i_mode, vi->nid | 0ULL);
	return -EFSCORRUPTED;
}

struct erofs_dirent *find_target_dirent(erofs_nid_t pnid,
					void *dentry_blk,
					const char *name, unsigned int len,
					unsigned int nameoff,
					unsigned int maxsize)
{
	struct erofs_dirent *de = dentry_blk;
	const struct erofs_dirent *end = dentry_blk + nameoff;

	while (de < end) {
		const char *de_name;
		unsigned int de_namelen;

		nameoff = le16_to_cpu(de->nameoff);
		de_name = (char *)dentry_blk + nameoff;

		/* the last dirent in the block? */
		if (de + 1 >= end)
			de_namelen = strnlen(de_name, maxsize - nameoff);
		else
			de_namelen = le16_to_cpu(de[1].nameoff) - nameoff;

		/* a corrupted entry is found */
		if (nameoff + de_namelen > maxsize ||
		    de_namelen > EROFS_NAME_LEN) {
			erofs_err("bogus dirent @ nid %llu", pnid | 0ULL);
			DBG_BUGON(1);
			return ERR_PTR(-EFSCORRUPTED);
		}

		if (len == de_namelen && !memcmp(de_name, name, de_namelen))
			return de;
		++de;
	}
	return NULL;
}

struct nameidata {
	erofs_nid_t	nid;
	unsigned int	ftype;
};

int erofs_namei(struct nameidata *nd,
		const char *name, unsigned int len)
{
	erofs_nid_t nid = nd->nid;
	int ret;
	char buf[EROFS_BLKSIZ];
	struct erofs_inode vi = { .nid = nid };
	erofs_off_t offset;

	ret = erofs_read_inode_from_disk(&vi);
	if (ret)
		return ret;

	offset = 0;
	while (offset < vi.i_size) {
		erofs_off_t maxsize = min_t(erofs_off_t,
					    vi.i_size - offset, EROFS_BLKSIZ);
		struct erofs_dirent *de = (void *)buf;
		unsigned int nameoff;

		ret = erofs_pread(&vi, buf, maxsize, offset);
		if (ret)
			return ret;

		nameoff = le16_to_cpu(de->nameoff);
		if (nameoff < sizeof(struct erofs_dirent) ||
		    nameoff >= PAGE_SIZE) {
			erofs_err("invalid de[0].nameoff %u @ nid %llu",
				  nameoff, nid | 0ULL);
			return -EFSCORRUPTED;
		}

		de = find_target_dirent(nid, buf, name, len,
					nameoff, maxsize);
		if (IS_ERR(de))
			return PTR_ERR(de);

		if (de) {
			nd->nid = le64_to_cpu(de->nid);
			return 0;
		}
		offset += maxsize;
	}
	return -ENOENT;
}

static int link_path_walk(const char *name, struct nameidata *nd)
{
	nd->nid = sbi.root_nid;

	while (*name == '/')
		name++;

	/* At this point we know we have a real path component. */
	while (*name != '\0') {
		const char *p = name;
		int ret;

		do {
			++p;
		} while (*p != '\0' && *p != '/');

		DBG_BUGON(p <= name);
		ret = erofs_namei(nd, name, p - name);
		if (ret)
			return ret;

		name = p;
		/* Skip until no more slashes. */
		for (name = p; *name == '/'; ++name)
			;
	}
	return 0;
}

int erofs_ilookup(const char *path, struct erofs_inode *vi)
{
	int ret;
	struct nameidata nd;

	ret = link_path_walk(path, &nd);
	if (ret)
		return ret;

	vi->nid = nd.nid;
	return erofs_read_inode_from_disk(vi);
}
