/*
 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write the Free Software Foundation,
 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <xfs/libxfs.h>
#include <xfs/xfs_log.h>
#include <xfs/xfs_log_priv.h>
#include "init.h"

#define BDSTRAT_SIZE	(256 * 1024)
#define min(x, y)	((x) < (y) ? (x) : (y))

#define IO_BCOMPARE_CHECK

void
libxfs_device_zero(dev_t dev, xfs_daddr_t start, uint len)
{
	xfs_off_t	start_offset, end_offset, offset;
	ssize_t		zsize, bytes;
	char		*z;
	int		fd;

	zsize = min(BDSTRAT_SIZE, BBTOB(len));
	if ((z = memalign(libxfs_device_alignment(), zsize)) == NULL) {
		fprintf(stderr,
			_("%s: %s can't memalign %d bytes: %s\n"),
			progname, __FUNCTION__, (int)zsize, strerror(errno));
		exit(1);
	}
	memset(z, 0, zsize);

	fd = libxfs_device_to_fd(dev);
	start_offset = LIBXFS_BBTOOFF64(start);

	if ((lseek64(fd, start_offset, SEEK_SET)) < 0) {
		fprintf(stderr, _("%s: %s seek to offset %llu failed: %s\n"),
			progname, __FUNCTION__,
			(unsigned long long)start_offset, strerror(errno));
		exit(1);
	}

	end_offset = LIBXFS_BBTOOFF64(start + len) - start_offset;
	for (offset = 0; offset < end_offset; ) {
		bytes = min((ssize_t)(end_offset - offset), zsize);
		if ((bytes = write(fd, z, bytes)) < 0) {
			fprintf(stderr, _("%s: %s write failed: %s\n"),
				progname, __FUNCTION__, strerror(errno));
			exit(1);
		} else if (bytes == 0) {
			fprintf(stderr, _("%s: %s not progressing?\n"),
				progname, __FUNCTION__);
			exit(1);
		}
		offset += bytes;
	}
	free(z);
}

static void unmount_record(void *p)
{
	xlog_op_header_t	*op = (xlog_op_header_t *)p;
	/* the data section must be 32 bit size aligned */
	struct {
	    __uint16_t magic;
	    __uint16_t pad1;
	    __uint32_t pad2; /* may as well make it 64 bits */
	} magic = { XLOG_UNMOUNT_TYPE, 0, 0 };

	memset(p, 0, BBSIZE);
	op->oh_tid = cpu_to_be32(1);
	op->oh_len = cpu_to_be32(sizeof(magic));
	op->oh_clientid = XFS_LOG;
	op->oh_flags = XLOG_UNMOUNT_TRANS;
	op->oh_res2 = 0;

	/* and the data for this op */
	memcpy((char *)p + sizeof(xlog_op_header_t), &magic, sizeof(magic));
}

static xfs_caddr_t next(xfs_caddr_t ptr, int offset, void *private)
{
	xfs_buf_t	*buf = (xfs_buf_t *)private;

	if (XFS_BUF_COUNT(buf) < (int)(ptr - XFS_BUF_PTR(buf)) + offset)
		abort();
	return ptr + offset;
}

int
libxfs_log_clear(
	dev_t			device,
	xfs_daddr_t		start,
	uint			length,
	uuid_t			*fs_uuid,
	int			version,
	int			sunit,
	int			fmt)
{
	xfs_buf_t		*bp;
	int			len;

	if (!device || !fs_uuid)
		return -EINVAL;

	/* first zero the log */
	libxfs_device_zero(device, start, length);

	/* then write a log record header */
	len = ((version == 2) && sunit) ? BTOBB(sunit) : 2;
	len = MAX(len, 2);
	bp = libxfs_getbufr(device, start, len);
	libxfs_log_header(XFS_BUF_PTR(bp),
			  fs_uuid, version, sunit, fmt, next, bp);
	bp->b_flags |= LIBXFS_B_DIRTY;
	libxfs_putbufr(bp);
	return 0;
}

int
libxfs_log_header(
	xfs_caddr_t		caddr,
	uuid_t			*fs_uuid,
	int			version,
	int			sunit,
	int			fmt,
	libxfs_get_block_t	*nextfunc,
	void			*private)
{
	xlog_rec_header_t	*head = (xlog_rec_header_t *)caddr;
	xfs_caddr_t		p = caddr;
	__be32			cycle_lsn;
	int			i, len;

	len = ((version == 2) && sunit) ? BTOBB(sunit) : 1;

	/* note that oh_tid actually contains the cycle number
	 * and the tid is stored in h_cycle_data[0] - that's the
	 * way things end up on disk.
	 */
	memset(p, 0, BBSIZE);
	head->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM);
	head->h_cycle = cpu_to_be32(1);
	head->h_version = cpu_to_be32(version);
	if (len != 1)
		head->h_len = cpu_to_be32(sunit - BBSIZE);
	else
		head->h_len = cpu_to_be32(20);
	head->h_chksum = cpu_to_be32(0);
	head->h_prev_block = cpu_to_be32(-1);
	head->h_num_logops = cpu_to_be32(1);
	head->h_cycle_data[0] = cpu_to_be32(0xb0c0d0d0);
	head->h_fmt = cpu_to_be32(fmt);
	head->h_size = cpu_to_be32(XLOG_HEADER_CYCLE_SIZE);

	head->h_lsn = cpu_to_be64(xlog_assign_lsn(1, 0));
	head->h_tail_lsn = cpu_to_be64(xlog_assign_lsn(1, 0));

	memcpy(&head->h_fs_uuid, fs_uuid, sizeof(uuid_t));

	len = MAX(len, 2);
	p = nextfunc(p, BBSIZE, private);
	unmount_record(p);

	cycle_lsn = CYCLE_LSN_DISK(head->h_lsn);
	for (i = 2; i < len; i++) {
		p = nextfunc(p, BBSIZE, private);
		memset(p, 0, BBSIZE);
		*(__be32 *)p = cycle_lsn;
	}

	return BBTOB(len);
}

/*
 * Simple I/O (buffer cache) interface
 */


#ifdef XFS_BUF_TRACING

#undef libxfs_readbuf
#undef libxfs_writebuf
#undef libxfs_getbuf
#undef libxfs_putbuf

xfs_buf_t 	*libxfs_readbuf(dev_t, xfs_daddr_t, int, int);
int		libxfs_writebuf(xfs_buf_t *, int);
xfs_buf_t 	*libxfs_getbuf(dev_t, xfs_daddr_t, int);
void		libxfs_putbuf (xfs_buf_t *);

xfs_buf_t *
libxfs_trace_readbuf(const char *func, const char *file, int line, dev_t dev, xfs_daddr_t blkno, int len, int flags)
{
	xfs_buf_t	*bp = libxfs_readbuf(dev, blkno, len, flags);

	bp->b_func = func;
	bp->b_file = file;
	bp->b_line = line;

	return bp;
}

int
libxfs_trace_writebuf(const char *func, const char *file, int line, xfs_buf_t *bp, int flags)
{
	bp->b_func = func;
	bp->b_file = file;
	bp->b_line = line;

	return libxfs_writebuf(bp, flags);
}

xfs_buf_t *
libxfs_trace_getbuf(const char *func, const char *file, int line, dev_t device, xfs_daddr_t blkno, int len)
{
	xfs_buf_t	*bp = libxfs_getbuf(device, blkno, len);

	bp->b_func = func;
	bp->b_file = file;
	bp->b_line = line;

	return bp;
}

void
libxfs_trace_putbuf(const char *func, const char *file, int line, xfs_buf_t *bp)
{
	bp->b_func = func;
	bp->b_file = file;
	bp->b_line = line;

	libxfs_putbuf(bp);
}


#endif


xfs_buf_t *
libxfs_getsb(xfs_mount_t *mp, int flags)
{
	return libxfs_readbuf(mp->m_dev, XFS_SB_DADDR,
				XFS_FSS_TO_BB(mp, 1), flags);
}

kmem_zone_t			*xfs_buf_zone;

static struct cache_mru		xfs_buf_freelist =
	{{&xfs_buf_freelist.cm_list, &xfs_buf_freelist.cm_list},
	 0, PTHREAD_MUTEX_INITIALIZER };

typedef struct {
	dev_t		device;
	xfs_daddr_t	blkno;
	unsigned int	bblen;
} xfs_bufkey_t;

static unsigned int
libxfs_bhash(cache_key_t key, unsigned int hashsize)
{
	return (((unsigned int)((xfs_bufkey_t *)key)->blkno) >> 5) % hashsize;
}

static int
libxfs_bcompare(struct cache_node *node, cache_key_t key)
{
	xfs_buf_t	*bp = (xfs_buf_t *)node;
	xfs_bufkey_t	*bkey = (xfs_bufkey_t *)key;

#ifdef IO_BCOMPARE_CHECK
	if (bp->b_dev == bkey->device &&
	    bp->b_blkno == bkey->blkno &&
	    bp->b_bcount != BBTOB(bkey->bblen))
		fprintf(stderr, "%lx: Badness in key lookup (length)\n"
			"bp=(bno %llu, len %u bytes) key=(bno %llu, len %u bytes)\n",
			pthread_self(),
			(unsigned long long)bp->b_blkno, (int)bp->b_bcount,
			(unsigned long long)bkey->blkno, BBTOB(bkey->bblen));
#endif

	return (bp->b_dev == bkey->device &&
		bp->b_blkno == bkey->blkno &&
		bp->b_bcount == BBTOB(bkey->bblen));
}

void
libxfs_bprint(xfs_buf_t *bp)
{
	fprintf(stderr, "Buffer 0x%p blkno=%llu bytes=%u flags=0x%x count=%u\n",
		bp, (unsigned long long)bp->b_blkno, (unsigned)bp->b_bcount,
		bp->b_flags, bp->b_node.cn_count);
}

static void
libxfs_initbuf(xfs_buf_t *bp, dev_t device, xfs_daddr_t bno, unsigned int bytes)
{
	bp->b_flags = 0;
	bp->b_blkno = bno;
	bp->b_bcount = bytes;
	bp->b_dev = device;
	if (!bp->b_addr)
		bp->b_addr = memalign(libxfs_device_alignment(), bytes);
	if (!bp->b_addr) {
		fprintf(stderr,
			_("%s: %s can't memalign %u bytes: %s\n"),
			progname, __FUNCTION__, bytes,
			strerror(errno));
		exit(1);
	}
#ifdef XFS_BUF_TRACING
	list_head_init(&bp->b_lock_list);
#endif
	pthread_mutex_init(&bp->b_lock, NULL);
}

xfs_buf_t *
libxfs_getbufr(dev_t device, xfs_daddr_t blkno, int bblen)
{
	xfs_buf_t	*bp;
	int		blen = BBTOB(bblen);

	/*
	 * first look for a buffer that can be used as-is,
	 * if one cannot be found, see if there is a buffer,
	 * and if so, free its buffer and set b_addr to NULL
	 * before calling libxfs_initbuf.
	 */
	pthread_mutex_lock(&xfs_buf_freelist.cm_mutex);
	if (!list_empty(&xfs_buf_freelist.cm_list)) {
		list_for_each_entry(bp, &xfs_buf_freelist.cm_list, b_node.cn_mru) {
			if (bp->b_bcount == blen) {
				list_del_init(&bp->b_node.cn_mru);
				break;
			}
		}
		if (&bp->b_node.cn_mru == &xfs_buf_freelist.cm_list) {
			bp = list_entry(xfs_buf_freelist.cm_list.next,
					xfs_buf_t, b_node.cn_mru);
			list_del_init(&bp->b_node.cn_mru);
			free(bp->b_addr);
			bp->b_addr = NULL;
		}
	} else
		bp = kmem_zone_zalloc(xfs_buf_zone, 0);
	pthread_mutex_unlock(&xfs_buf_freelist.cm_mutex);

	if (bp != NULL)
		libxfs_initbuf(bp, device, blkno, blen);
#ifdef IO_DEBUG
	printf("%lx: %s: allocated %u bytes buffer, key=%llu(%llu), %p\n",
		pthread_self(), __FUNCTION__, BBTOB(len),
		(long long)LIBXFS_BBTOOFF64(blkno), (long long)blkno, bp);
#endif

	return bp;
}


#ifdef XFS_BUF_TRACING
struct list_head	lock_buf_list = {&lock_buf_list, &lock_buf_list};
int			lock_buf_count = 0;
#endif

extern int     use_xfs_buf_lock;

xfs_buf_t *
libxfs_getbuf(dev_t device, xfs_daddr_t blkno, int len)
{
	xfs_buf_t	*bp;
	xfs_bufkey_t	key;
	int		miss;

	key.device = device;
	key.blkno = blkno;
	key.bblen = len;

	miss = cache_node_get(libxfs_bcache, &key, (struct cache_node **)&bp);
	if (bp) {
		if (use_xfs_buf_lock)
			pthread_mutex_lock(&bp->b_lock);
		cache_node_set_priority(libxfs_bcache, (struct cache_node *)bp,
			cache_node_get_priority((struct cache_node *)bp) -
						CACHE_PREFETCH_PRIORITY);
#ifdef XFS_BUF_TRACING
		pthread_mutex_lock(&libxfs_bcache->c_mutex);
		lock_buf_count++;
		list_add(&bp->b_lock_list, &lock_buf_list);
		pthread_mutex_unlock(&libxfs_bcache->c_mutex);
#endif
#ifdef IO_DEBUG
		printf("%lx %s: %s buffer %p for bno = %llu\n",
			pthread_self(), __FUNCTION__, miss ? "miss" : "hit",
			bp, (long long)LIBXFS_BBTOOFF64(blkno));
#endif
	}

	return bp;
}

void
libxfs_putbuf(xfs_buf_t *bp)
{
#ifdef XFS_BUF_TRACING
	pthread_mutex_lock(&libxfs_bcache->c_mutex);
	lock_buf_count--;
	ASSERT(lock_buf_count >= 0);
	list_del_init(&bp->b_lock_list);
	pthread_mutex_unlock(&libxfs_bcache->c_mutex);
#endif
	if (use_xfs_buf_lock)
		pthread_mutex_unlock(&bp->b_lock);
	cache_node_put(libxfs_bcache, (struct cache_node *)bp);
}

void
libxfs_purgebuf(xfs_buf_t *bp)
{
	xfs_bufkey_t	key;

	key.device = bp->b_dev;
	key.blkno = bp->b_blkno;
	key.bblen = bp->b_bcount >> BBSHIFT;

	cache_node_purge(libxfs_bcache, &key, (struct cache_node *)bp);
}

static struct cache_node *
libxfs_balloc(cache_key_t key)
{
	xfs_bufkey_t	*bufkey = (xfs_bufkey_t *)key;

	return (struct cache_node *)libxfs_getbufr(bufkey->device,
					bufkey->blkno, bufkey->bblen);
}

int
libxfs_readbufr(dev_t dev, xfs_daddr_t blkno, xfs_buf_t *bp, int len, int flags)
{
	int	fd = libxfs_device_to_fd(dev);
	int	bytes = BBTOB(len);

	ASSERT(BBTOB(len) <= bp->b_bcount);

	if (pread64(fd, bp->b_addr, bytes, LIBXFS_BBTOOFF64(blkno)) < 0) {
		fprintf(stderr, _("%s: read failed: %s\n"),
			progname, strerror(errno));
		if (flags & LIBXFS_EXIT_ON_FAILURE)
			exit(1);
		return errno;
	}
#ifdef IO_DEBUG
	printf("%lx: %s: read %u bytes, blkno=%llu(%llu), %p\n",
		pthread_self(), __FUNCTION__, bytes,
		(long long)LIBXFS_BBTOOFF64(blkno), (long long)blkno, bp);
#endif
	if (bp->b_dev == dev &&
	    bp->b_blkno == blkno &&
	    bp->b_bcount == bytes)
		bp->b_flags |= LIBXFS_B_UPTODATE;
	return 0;
}

xfs_buf_t *
libxfs_readbuf(dev_t dev, xfs_daddr_t blkno, int len, int flags)
{
	xfs_buf_t	*bp;
	int		error;

	bp = libxfs_getbuf(dev, blkno, len);
	if (bp && !(bp->b_flags & (LIBXFS_B_UPTODATE|LIBXFS_B_DIRTY))) {
		error = libxfs_readbufr(dev, blkno, bp, len, flags);
		if (error) {
			libxfs_putbuf(bp);
			return NULL;
		}
	}
	return bp;
}

int
libxfs_writebufr(xfs_buf_t *bp)
{
	int	sts;
	int	fd = libxfs_device_to_fd(bp->b_dev);

	sts = pwrite64(fd, bp->b_addr, bp->b_bcount, LIBXFS_BBTOOFF64(bp->b_blkno));
	if (sts < 0) {
		fprintf(stderr, _("%s: pwrite64 failed: %s\n"),
			progname, strerror(errno));
		if (bp->b_flags & LIBXFS_B_EXIT)
			exit(1);
		return errno;
	}
	else if (sts != bp->b_bcount) {
		fprintf(stderr, _("%s: error - wrote only %d of %d bytes\n"),
			progname, sts, bp->b_bcount);
		if (bp->b_flags & LIBXFS_B_EXIT)
			exit(1);
		return EIO;
	}
#ifdef IO_DEBUG
	printf("%lx: %s: wrote %u bytes, blkno=%llu(%llu), %p\n",
			pthread_self(), __FUNCTION__, bp->b_bcount,
			(long long)LIBXFS_BBTOOFF64(bp->b_blkno),
			(long long)bp->b_blkno, bp);
#endif
	bp->b_flags |= LIBXFS_B_UPTODATE;
	bp->b_flags &= ~(LIBXFS_B_DIRTY | LIBXFS_B_EXIT);
	return 0;
}

int
libxfs_writebuf_int(xfs_buf_t *bp, int flags)
{
	bp->b_flags |= (LIBXFS_B_DIRTY | flags);
	return 0;
}

int
libxfs_writebuf(xfs_buf_t *bp, int flags)
{
	bp->b_flags |= (LIBXFS_B_DIRTY | flags);
	libxfs_putbuf(bp);
	return 0;
}

void
libxfs_iomove(xfs_buf_t *bp, uint boff, int len, void *data, int flags)
{
#ifdef IO_DEBUG
	if (boff + len > bp->b_bcount) {
		printf("Badness, iomove out of range!\n"
			"bp=(bno %llu, bytes %u) range=(boff %u, bytes %u)\n",
			(long long)bp->b_blkno, bp->b_bcount, boff, len);
		abort();
	}
#endif
	switch (flags) {
	case LIBXFS_BZERO:
		memset(bp->b_addr + boff, 0, len);
		break;
	case LIBXFS_BREAD:
		memcpy(data, bp->b_addr + boff, len);
		break;
	case LIBXFS_BWRITE:
		memcpy(bp->b_addr + boff, data, len);
		break;
	}
}

static void
libxfs_brelse(struct cache_node *node)
{
	xfs_buf_t		*bp = (xfs_buf_t *)node;

	if (bp != NULL) {
		if (bp->b_flags & LIBXFS_B_DIRTY)
			libxfs_writebufr(bp);
		pthread_mutex_lock(&xfs_buf_freelist.cm_mutex);
		list_add(&bp->b_node.cn_mru, &xfs_buf_freelist.cm_list);
		pthread_mutex_unlock(&xfs_buf_freelist.cm_mutex);
	}
}

static unsigned int
libxfs_bulkrelse(
	struct cache 		*cache,
	struct list_head 	*list)
{
	xfs_buf_t		*bp;
	int			count = 0;

	if (list_empty(list))
		return 0 ;

	list_for_each_entry(bp, list, b_node.cn_mru) {
		if (bp->b_flags & LIBXFS_B_DIRTY)
			libxfs_writebufr(bp);
		count++;
	}

	pthread_mutex_lock(&xfs_buf_freelist.cm_mutex);
	__list_splice(list, &xfs_buf_freelist.cm_list);
	pthread_mutex_unlock(&xfs_buf_freelist.cm_mutex);

	return count;
}

static void
libxfs_bflush(struct cache_node *node)
{
	xfs_buf_t		*bp = (xfs_buf_t *)node;

	if ((bp != NULL) && (bp->b_flags & LIBXFS_B_DIRTY))
		libxfs_writebufr(bp);
}

void
libxfs_putbufr(xfs_buf_t *bp)
{
	libxfs_brelse((struct cache_node *)bp);
}


void
libxfs_bcache_purge(void)
{
	cache_purge(libxfs_bcache);
}

void
libxfs_bcache_flush(void)
{
	cache_flush(libxfs_bcache);
}

int
libxfs_bcache_overflowed(void)
{
	return cache_overflowed(libxfs_bcache);
}

struct cache_operations libxfs_bcache_operations = {
	/* .hash */	libxfs_bhash,
	/* .alloc */	libxfs_balloc,
	/* .flush */	libxfs_bflush,
	/* .relse */	libxfs_brelse,
	/* .compare */	libxfs_bcompare,
	/* .bulkrelse */libxfs_bulkrelse
};


/*
 * Inode cache interfaces
 */

extern kmem_zone_t	*xfs_ili_zone;
extern kmem_zone_t	*xfs_inode_zone;

static unsigned int
libxfs_ihash(cache_key_t key, unsigned int hashsize)
{
	return ((unsigned int)*(xfs_ino_t *)key) % hashsize;
}

static int
libxfs_icompare(struct cache_node *node, cache_key_t key)
{
	xfs_inode_t	*ip = (xfs_inode_t *)node;

	return (ip->i_ino == *(xfs_ino_t *)key);
}

int
libxfs_iget(xfs_mount_t *mp, xfs_trans_t *tp, xfs_ino_t ino, uint lock_flags,
		xfs_inode_t **ipp, xfs_daddr_t bno)
{
	xfs_inode_t	*ip;
	int		error = 0;

	if (cache_node_get(libxfs_icache, &ino, (struct cache_node **)&ip)) {
#ifdef INO_DEBUG
		fprintf(stderr, "%s: allocated inode, ino=%llu(%llu), %p\n",
			__FUNCTION__, (unsigned long long)ino, bno, ip);
#endif
		if ((error = libxfs_iread(mp, tp, ino, ip, bno))) {
			cache_node_purge(libxfs_icache, &ino,
					(struct cache_node *)ip);
			ip = NULL;
		}
	}
	*ipp = ip;
	return error;
}

void
libxfs_iput(xfs_inode_t *ip, uint lock_flags)
{
	cache_node_put(libxfs_icache, (struct cache_node *)ip);
}

static struct cache_node *
libxfs_ialloc(cache_key_t key)
{
	return kmem_zone_zalloc(xfs_inode_zone, 0);
}

static void
libxfs_idestroy(xfs_inode_t *ip)
{
	switch (ip->i_d.di_mode & S_IFMT) {
		case S_IFREG:
		case S_IFDIR:
		case S_IFLNK:
			libxfs_idestroy_fork(ip, XFS_DATA_FORK);
			break;
	}
	if (ip->i_afp)
		libxfs_idestroy_fork(ip, XFS_ATTR_FORK);
}

static void
libxfs_irelse(struct cache_node *node)
{
	xfs_inode_t	*ip = (xfs_inode_t *)node;

	if (ip != NULL) {
		if (ip->i_itemp)
			kmem_zone_free(xfs_ili_zone, ip->i_itemp);
		ip->i_itemp = NULL;
		libxfs_idestroy(ip);
		kmem_zone_free(xfs_inode_zone, ip);
		ip = NULL;
	}
}

void
libxfs_icache_purge(void)
{
	cache_purge(libxfs_icache);
}

struct cache_operations libxfs_icache_operations = {
	/* .hash */	libxfs_ihash,
	/* .alloc */	libxfs_ialloc,
	/* .flush */	NULL,
	/* .relse */	libxfs_irelse,
	/* .compare */	libxfs_icompare,
	/* .bulkrelse */ NULL
};
