#include <linux/fs.h>
#include <linux/buffer_head.h>
#include "omfs.h"

#define POLY 0x1021

/*
 * crc-ccitt with MSB first (i.e., backwards), so we can't use the
 * kernel table as-is.
 */
static u16 omfs_crc(u16 crc, unsigned char *buf, int count)
{
	int i, j;
	for (i=0; i<count; i++) {
		crc ^= buf[i] << 8;
		for (j = 0; j < 8; j++)
			crc = (crc << 1) ^ ((crc & 0x8000) ? POLY : 0);
	}
	return crc;
}

/*
 * Update the header checksums for a dirty inode based on its contents.
 * Caller is expected to hold the buffer head underlying oi and mark it
 * dirty.
 */
int omfs_update_checksums(struct omfs_inode *oi, struct super_block *sb,
		ino_t ino)
{
	int ret=0;
	int xor, i, ofs=0, count;
	u16 crc=0;
	unsigned char *ptr = (unsigned char *) oi;

	count = be32_to_cpu(oi->i_head.h_body_size);
	ofs = sizeof(struct omfs_header);

	crc = omfs_crc(crc, ptr + ofs, count);
	oi->i_head.h_crc = cpu_to_be16(crc);

	xor = ptr[0];
	for (i=1; i<OMFS_XOR_COUNT; i++)
		xor ^= ptr[i];

	oi->i_head.h_check_xor = xor;

	return ret;
}


