// SPDX-License-Identifier: GPL-2.0-only
/*
 * directory.c
 *
 * PURPOSE
 *	Directory related functions
 *
 */

#include "udfdecl.h"
#include "udf_i.h"

#include <linux/fs.h>
#include <linux/string.h>
#include <linux/bio.h>
#include <linux/crc-itu-t.h>
#include <linux/iversion.h>

static int udf_verify_fi(struct udf_fileident_iter *iter)
{
	unsigned int len;

	if (iter->fi.descTag.tagIdent != cpu_to_le16(TAG_IDENT_FID)) {
		udf_err(iter->dir->i_sb,
			"directory (ino %llu) has entry at pos %llu with incorrect tag %x\n",
			iter->dir->i_ino, (unsigned long long)iter->pos,
			le16_to_cpu(iter->fi.descTag.tagIdent));
		return -EFSCORRUPTED;
	}
	len = udf_dir_entry_len(&iter->fi);
	if (le16_to_cpu(iter->fi.lengthOfImpUse) & 3) {
		udf_err(iter->dir->i_sb,
			"directory (ino %llu) has entry at pos %llu with unaligned length of impUse field\n",
			iter->dir->i_ino, (unsigned long long)iter->pos);
		return -EFSCORRUPTED;
	}
	/*
	 * This is in fact allowed by the spec due to long impUse field but
	 * we don't support it. If there is real media with this large impUse
	 * field, support can be added.
	 */
	if (len > 1 << iter->dir->i_blkbits) {
		udf_err(iter->dir->i_sb,
			"directory (ino %llu) has too big (%u) entry at pos %llu\n",
			iter->dir->i_ino, len, (unsigned long long)iter->pos);
		return -EFSCORRUPTED;
	}
	if (iter->pos + len > iter->dir->i_size) {
		udf_err(iter->dir->i_sb,
			"directory (ino %llu) has entry past directory size at pos %llu\n",
			iter->dir->i_ino, (unsigned long long)iter->pos);
		return -EFSCORRUPTED;
	}
	if (udf_dir_entry_len(&iter->fi) !=
	    sizeof(struct tag) + le16_to_cpu(iter->fi.descTag.descCRCLength)) {
		udf_err(iter->dir->i_sb,
			"directory (ino %llu) has entry where CRC length (%u) does not match entry length (%u)\n",
			iter->dir->i_ino,
			(unsigned)le16_to_cpu(iter->fi.descTag.descCRCLength),
			(unsigned)(udf_dir_entry_len(&iter->fi) -
							sizeof(struct tag)));
		return -EFSCORRUPTED;
	}
	return 0;
}

static int udf_copy_fi(struct udf_fileident_iter *iter)
{
	struct udf_inode_info *iinfo = UDF_I(iter->dir);
	u32 blksize = 1 << iter->dir->i_blkbits;
	u32 off, len, nameoff;
	int err;

	/* Skip copying when we are at EOF */
	if (iter->pos >= iter->dir->i_size) {
		iter->name = NULL;
		return 0;
	}
	if (iter->dir->i_size < iter->pos + sizeof(struct fileIdentDesc)) {
		udf_err(iter->dir->i_sb,
			"directory (ino %llu) has entry straddling EOF\n",
			iter->dir->i_ino);
		return -EFSCORRUPTED;
	}
	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
		memcpy(&iter->fi, iinfo->i_data + iinfo->i_lenEAttr + iter->pos,
		       sizeof(struct fileIdentDesc));
		err = udf_verify_fi(iter);
		if (err < 0)
			return err;
		iter->name = iinfo->i_data + iinfo->i_lenEAttr + iter->pos +
			sizeof(struct fileIdentDesc) +
			le16_to_cpu(iter->fi.lengthOfImpUse);
		return 0;
	}

	off = iter->pos & (blksize - 1);
	len = min_t(u32, sizeof(struct fileIdentDesc), blksize - off);
	memcpy(&iter->fi, iter->bh[0]->b_data + off, len);
	if (len < sizeof(struct fileIdentDesc))
		memcpy((char *)(&iter->fi) + len, iter->bh[1]->b_data,
		       sizeof(struct fileIdentDesc) - len);
	err = udf_verify_fi(iter);
	if (err < 0)
		return err;

	/* Handle directory entry name */
	nameoff = off + sizeof(struct fileIdentDesc) +
				le16_to_cpu(iter->fi.lengthOfImpUse);
	if (off + udf_dir_entry_len(&iter->fi) <= blksize) {
		iter->name = iter->bh[0]->b_data + nameoff;
	} else if (nameoff >= blksize) {
		iter->name = iter->bh[1]->b_data + (nameoff - blksize);
	} else {
		iter->name = iter->namebuf;
		len = blksize - nameoff;
		memcpy(iter->name, iter->bh[0]->b_data + nameoff, len);
		memcpy(iter->name + len, iter->bh[1]->b_data,
		       iter->fi.lengthFileIdent - len);
	}
	return 0;
}

/* Readahead 8k once we are at 8k boundary */
static void udf_readahead_dir(struct udf_fileident_iter *iter)
{
	unsigned int ralen = 16 >> (iter->dir->i_blkbits - 9);
	struct buffer_head *tmp, *bha[16];
	int i, num;
	udf_pblk_t blk;

	if (iter->loffset & (ralen - 1))
		return;

	if (iter->loffset + ralen > (iter->elen >> iter->dir->i_blkbits))
		ralen = (iter->elen >> iter->dir->i_blkbits) - iter->loffset;
	num = 0;
	for (i = 0; i < ralen; i++) {
		blk = udf_get_lb_pblock(iter->dir->i_sb, &iter->eloc,
					iter->loffset + i);
		tmp = sb_getblk(iter->dir->i_sb, blk);
		if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp))
			bha[num++] = tmp;
		else
			brelse(tmp);
	}
	if (num) {
		bh_readahead_batch(num, bha, REQ_RAHEAD);
		for (i = 0; i < num; i++)
			brelse(bha[i]);
	}
}

static struct buffer_head *udf_fiiter_bread_blk(struct udf_fileident_iter *iter)
{
	udf_pblk_t blk;

	udf_readahead_dir(iter);
	blk = udf_get_lb_pblock(iter->dir->i_sb, &iter->eloc, iter->loffset);
	return sb_bread(iter->dir->i_sb, blk);
}

/*
 * Updates loffset to point to next directory block; eloc, elen & epos are
 * updated if we need to traverse to the next extent as well.
 */
static int udf_fiiter_advance_blk(struct udf_fileident_iter *iter)
{
	int8_t etype = -1;
	int err = 0;

	iter->loffset++;
	if (iter->loffset < DIV_ROUND_UP(iter->elen, 1<<iter->dir->i_blkbits))
		return 0;

	iter->loffset = 0;
	err = udf_next_aext(iter->dir, &iter->epos, &iter->eloc,
			    &iter->elen, &etype, 1);
	if (err < 0)
		return err;
	else if (err == 0 || etype != (EXT_RECORDED_ALLOCATED >> 30)) {
		if (iter->pos == iter->dir->i_size) {
			iter->elen = 0;
			return 0;
		}
		udf_err(iter->dir->i_sb,
			"extent after position %llu not allocated in directory (ino %llu)\n",
			(unsigned long long)iter->pos, iter->dir->i_ino);
		return -EFSCORRUPTED;
	}
	return 0;
}

static int udf_fiiter_load_bhs(struct udf_fileident_iter *iter)
{
	int blksize = 1 << iter->dir->i_blkbits;
	int off = iter->pos & (blksize - 1);
	int err;
	struct fileIdentDesc *fi;

	/* Is there any further extent we can map from? */
	if (!iter->bh[0] && iter->elen) {
		iter->bh[0] = udf_fiiter_bread_blk(iter);
		if (!iter->bh[0]) {
			err = -ENOMEM;
			goto out_brelse;
		}
		if (!buffer_uptodate(iter->bh[0])) {
			err = -EIO;
			goto out_brelse;
		}
	}
	/* There's no next block so we are done */
	if (iter->pos >= iter->dir->i_size)
		return 0;
	/* Need to fetch next block as well? */
	if (off + sizeof(struct fileIdentDesc) > blksize)
		goto fetch_next;
	fi = (struct fileIdentDesc *)(iter->bh[0]->b_data + off);
	/* Need to fetch next block to get name? */
	if (off + udf_dir_entry_len(fi) > blksize) {
fetch_next:
		err = udf_fiiter_advance_blk(iter);
		if (err)
			goto out_brelse;
		iter->bh[1] = udf_fiiter_bread_blk(iter);
		if (!iter->bh[1]) {
			err = -ENOMEM;
			goto out_brelse;
		}
		if (!buffer_uptodate(iter->bh[1])) {
			err = -EIO;
			goto out_brelse;
		}
	}
	return 0;
out_brelse:
	brelse(iter->bh[0]);
	brelse(iter->bh[1]);
	iter->bh[0] = iter->bh[1] = NULL;
	return err;
}

int udf_fiiter_init(struct udf_fileident_iter *iter, struct inode *dir,
		    loff_t pos)
{
	struct udf_inode_info *iinfo = UDF_I(dir);
	int err = 0;
	int8_t etype;

	iter->dir = dir;
	iter->bh[0] = iter->bh[1] = NULL;
	iter->pos = pos;
	iter->elen = 0;
	iter->epos.bh = NULL;
	iter->name = NULL;
	/*
	 * When directory is verified, we don't expect directory iteration to
	 * fail and it can be difficult to undo without corrupting filesystem.
	 * So just do not allow memory allocation failures here.
	 */
	iter->namebuf = kmalloc(UDF_NAME_LEN_CS0, GFP_KERNEL | __GFP_NOFAIL);

	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
		err = udf_copy_fi(iter);
		goto out;
	}

	err = inode_bmap(dir, iter->pos >> dir->i_blkbits, &iter->epos,
			 &iter->eloc, &iter->elen, &iter->loffset, &etype);
	if (err <= 0 || etype != (EXT_RECORDED_ALLOCATED >> 30)) {
		if (pos == dir->i_size)
			return 0;
		udf_err(dir->i_sb,
			"position %llu not allocated in directory (ino %llu)\n",
			(unsigned long long)pos, dir->i_ino);
		err = -EFSCORRUPTED;
		goto out;
	}
	err = udf_fiiter_load_bhs(iter);
	if (err < 0)
		goto out;
	err = udf_copy_fi(iter);
out:
	if (err < 0)
		udf_fiiter_release(iter);
	return err;
}

int udf_fiiter_advance(struct udf_fileident_iter *iter)
{
	unsigned int oldoff, len;
	int blksize = 1 << iter->dir->i_blkbits;
	int err;

	oldoff = iter->pos & (blksize - 1);
	len = udf_dir_entry_len(&iter->fi);
	iter->pos += len;
	if (UDF_I(iter->dir)->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
		if (oldoff + len >= blksize) {
			brelse(iter->bh[0]);
			iter->bh[0] = NULL;
			/* Next block already loaded? */
			if (iter->bh[1]) {
				iter->bh[0] = iter->bh[1];
				iter->bh[1] = NULL;
			} else {
				err = udf_fiiter_advance_blk(iter);
				if (err < 0)
					return err;
			}
		}
		err = udf_fiiter_load_bhs(iter);
		if (err < 0)
			return err;
	}
	return udf_copy_fi(iter);
}

void udf_fiiter_release(struct udf_fileident_iter *iter)
{
	iter->dir = NULL;
	brelse(iter->bh[0]);
	brelse(iter->bh[1]);
	iter->bh[0] = iter->bh[1] = NULL;
	kfree(iter->namebuf);
	iter->namebuf = NULL;
}

static void udf_copy_to_bufs(void *buf1, int len1, void *buf2, int len2,
			     int off, void *src, int len)
{
	int copy;

	if (off >= len1) {
		off -= len1;
	} else {
		copy = min(off + len, len1) - off;
		memcpy(buf1 + off, src, copy);
		src += copy;
		len -= copy;
		off = 0;
	}
	if (len > 0) {
		if (WARN_ON_ONCE(off + len > len2 || !buf2))
			return;
		memcpy(buf2 + off, src, len);
	}
}

static uint16_t udf_crc_fi_bufs(void *buf1, int len1, void *buf2, int len2,
				int off, int len)
{
	int copy;
	uint16_t crc = 0;

	if (off >= len1) {
		off -= len1;
	} else {
		copy = min(off + len, len1) - off;
		crc = crc_itu_t(crc, buf1 + off, copy);
		len -= copy;
		off = 0;
	}
	if (len > 0) {
		if (WARN_ON_ONCE(off + len > len2 || !buf2))
			return 0;
		crc = crc_itu_t(crc, buf2 + off, len);
	}
	return crc;
}

static void udf_copy_fi_to_bufs(char *buf1, int len1, char *buf2, int len2,
				int off, struct fileIdentDesc *fi,
				uint8_t *impuse, uint8_t *name)
{
	uint16_t crc;
	int fioff = off;
	int crcoff = off + sizeof(struct tag);
	unsigned int crclen = udf_dir_entry_len(fi) - sizeof(struct tag);
	char zeros[UDF_NAME_PAD] = {};
	int endoff = off + udf_dir_entry_len(fi);

	udf_copy_to_bufs(buf1, len1, buf2, len2, off, fi,
			 sizeof(struct fileIdentDesc));
	off += sizeof(struct fileIdentDesc);
	if (impuse)
		udf_copy_to_bufs(buf1, len1, buf2, len2, off, impuse,
				 le16_to_cpu(fi->lengthOfImpUse));
	off += le16_to_cpu(fi->lengthOfImpUse);
	if (name) {
		udf_copy_to_bufs(buf1, len1, buf2, len2, off, name,
				 fi->lengthFileIdent);
		off += fi->lengthFileIdent;
		udf_copy_to_bufs(buf1, len1, buf2, len2, off, zeros,
				 endoff - off);
	}

	crc = udf_crc_fi_bufs(buf1, len1, buf2, len2, crcoff, crclen);
	fi->descTag.descCRC = cpu_to_le16(crc);
	fi->descTag.descCRCLength = cpu_to_le16(crclen);
	fi->descTag.tagChecksum = udf_tag_checksum(&fi->descTag);

	udf_copy_to_bufs(buf1, len1, buf2, len2, fioff, fi, sizeof(struct tag));
}

void udf_fiiter_write_fi(struct udf_fileident_iter *iter, uint8_t *impuse)
{
	struct udf_inode_info *iinfo = UDF_I(iter->dir);
	void *buf1, *buf2 = NULL;
	int len1, len2 = 0, off;
	int blksize = 1 << iter->dir->i_blkbits;

	off = iter->pos & (blksize - 1);
	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
		buf1 = iinfo->i_data + iinfo->i_lenEAttr;
		len1 = iter->dir->i_size;
	} else {
		buf1 = iter->bh[0]->b_data;
		len1 = blksize;
		if (iter->bh[1]) {
			buf2 = iter->bh[1]->b_data;
			len2 = blksize;
		}
	}

	udf_copy_fi_to_bufs(buf1, len1, buf2, len2, off, &iter->fi, impuse,
			    iter->name == iter->namebuf ? iter->name : NULL);

	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
		mark_inode_dirty(iter->dir);
	} else {
		mmb_mark_buffer_dirty(iter->bh[0], &iinfo->i_metadata_bhs);
		if (iter->bh[1])
			mmb_mark_buffer_dirty(iter->bh[1],
					      &iinfo->i_metadata_bhs);
	}
	inode_inc_iversion(iter->dir);
}

void udf_fiiter_update_elen(struct udf_fileident_iter *iter, uint32_t new_elen)
{
	struct udf_inode_info *iinfo = UDF_I(iter->dir);
	int diff = new_elen - iter->elen;

	/* Skip update when we already went past the last extent */
	if (!iter->elen)
		return;
	iter->elen = new_elen;
	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
		iter->epos.offset -= sizeof(struct short_ad);
	else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
		iter->epos.offset -= sizeof(struct long_ad);
	udf_write_aext(iter->dir, &iter->epos, &iter->eloc, iter->elen, 1);
	iinfo->i_lenExtents += diff;
	mark_inode_dirty(iter->dir);
}

/* Append new block to directory. @iter is expected to point at EOF */
int udf_fiiter_append_blk(struct udf_fileident_iter *iter)
{
	struct udf_inode_info *iinfo = UDF_I(iter->dir);
	int blksize = 1 << iter->dir->i_blkbits;
	struct buffer_head *bh;
	sector_t block;
	uint32_t old_elen = iter->elen;
	int err;
	int8_t etype;

	if (WARN_ON_ONCE(iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB))
		return -EINVAL;

	/* Round up last extent in the file */
	udf_fiiter_update_elen(iter, ALIGN(iter->elen, blksize));

	/* Allocate new block and refresh mapping information */
	block = iinfo->i_lenExtents >> iter->dir->i_blkbits;
	bh = udf_bread(iter->dir, block, 1, &err);
	if (!bh) {
		udf_fiiter_update_elen(iter, old_elen);
		return err;
	}
	err = inode_bmap(iter->dir, block, &iter->epos, &iter->eloc, &iter->elen,
		   &iter->loffset, &etype);
	if (err <= 0 || etype != (EXT_RECORDED_ALLOCATED >> 30)) {
		udf_err(iter->dir->i_sb,
			"block %llu not allocated in directory (ino %llu)\n",
			(unsigned long long)block, iter->dir->i_ino);
		return -EFSCORRUPTED;
	}
	if (!(iter->pos & (blksize - 1))) {
		brelse(iter->bh[0]);
		iter->bh[0] = bh;
	} else {
		iter->bh[1] = bh;
	}
	return 0;
}

struct short_ad *udf_get_fileshortad(uint8_t *ptr, int maxoffset, uint32_t *offset,
			      int inc)
{
	struct short_ad *sa;

	if ((!ptr) || (!offset)) {
		pr_err("%s: invalidparms\n", __func__);
		return NULL;
	}

	if ((*offset + sizeof(struct short_ad)) > maxoffset)
		return NULL;
	else {
		sa = (struct short_ad *)ptr;
		if (sa->extLength == 0)
			return NULL;
	}

	if (inc)
		*offset += sizeof(struct short_ad);
	return sa;
}

struct long_ad *udf_get_filelongad(uint8_t *ptr, int maxoffset, uint32_t *offset, int inc)
{
	struct long_ad *la;

	if ((!ptr) || (!offset)) {
		pr_err("%s: invalidparms\n", __func__);
		return NULL;
	}

	if ((*offset + sizeof(struct long_ad)) > maxoffset)
		return NULL;
	else {
		la = (struct long_ad *)ptr;
		if (la->extLength == 0)
			return NULL;
	}

	if (inc)
		*offset += sizeof(struct long_ad);
	return la;
}
