/*
 *	fs/bfs/dir.c
 *	BFS directory operations.
 *	Copyright (C) 1999,2000  Tigran Aivazian <tigran@veritas.com>
 *      Made endianness-clean by Andrew Stribblehill <ads@wompom.org> 2005
 */

#include <linux/time.h>
#include <linux/string.h>
#include <linux/fs.h>
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include <linux/sched.h>
#include "bfs.h"

#undef DEBUG

#ifdef DEBUG
#define dprintf(x...)	printf(x)
#else
#define dprintf(x...)
#endif

static int bfs_add_entry(struct inode * dir, const unsigned char * name, int namelen, int ino);
static struct buffer_head * bfs_find_entry(struct inode * dir, 
	const unsigned char * name, int namelen, struct bfs_dirent ** res_dir);

static int bfs_readdir(struct file * f, void * dirent, filldir_t filldir)
{
	struct inode * dir = f->f_dentry->d_inode;
	struct buffer_head * bh;
	struct bfs_dirent * de;
	unsigned int offset;
	int block;

	lock_kernel();

	if (f->f_pos & (BFS_DIRENT_SIZE-1)) {
		printf("Bad f_pos=%08lx for %s:%08lx\n", (unsigned long)f->f_pos, 
			dir->i_sb->s_id, dir->i_ino);
		unlock_kernel();
		return -EBADF;
	}

	while (f->f_pos < dir->i_size) {
		offset = f->f_pos & (BFS_BSIZE-1);
		block = BFS_I(dir)->i_sblock + (f->f_pos >> BFS_BSIZE_BITS);
		bh = sb_bread(dir->i_sb, block);
		if (!bh) {
			f->f_pos += BFS_BSIZE - offset;
			continue;
		}
		do {
			de = (struct bfs_dirent *)(bh->b_data + offset);
			if (de->ino) {
				int size = strnlen(de->name, BFS_NAMELEN);
				if (filldir(dirent, de->name, size, f->f_pos, le16_to_cpu(de->ino), DT_UNKNOWN) < 0) {
					brelse(bh);
					unlock_kernel();
					return 0;
				}
			}
			offset += BFS_DIRENT_SIZE;
			f->f_pos += BFS_DIRENT_SIZE;
		} while (offset < BFS_BSIZE && f->f_pos < dir->i_size);
		brelse(bh);
	}

	unlock_kernel();
	return 0;	
}

struct file_operations bfs_dir_operations = {
	.read		= generic_read_dir,
	.readdir	= bfs_readdir,
	.fsync		= file_fsync,
};

extern void dump_imap(const char *, struct super_block *);

static int bfs_create(struct inode * dir, struct dentry * dentry, int mode,
		struct nameidata *nd)
{
	int err;
	struct inode * inode;
	struct super_block * s = dir->i_sb;
	struct bfs_sb_info * info = BFS_SB(s);
	unsigned long ino;

	inode = new_inode(s);
	if (!inode)
		return -ENOSPC;
	lock_kernel();
	ino = find_first_zero_bit(info->si_imap, info->si_lasti);
	if (ino > info->si_lasti) {
		unlock_kernel();
		iput(inode);
		return -ENOSPC;
	}
	set_bit(ino, info->si_imap);	
	info->si_freei--;
	inode->i_uid = current->fsuid;
	inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
	inode->i_blocks = inode->i_blksize = 0;
	inode->i_op = &bfs_file_inops;
	inode->i_fop = &bfs_file_operations;
	inode->i_mapping->a_ops = &bfs_aops;
	inode->i_mode = mode;
	inode->i_ino = ino;
	BFS_I(inode)->i_dsk_ino = cpu_to_le16(ino);
	BFS_I(inode)->i_sblock = 0;
	BFS_I(inode)->i_eblock = 0;
	insert_inode_hash(inode);
        mark_inode_dirty(inode);
	dump_imap("create",s);

	err = bfs_add_entry(dir, dentry->d_name.name, dentry->d_name.len, inode->i_ino);
	if (err) {
		inode->i_nlink--;
		mark_inode_dirty(inode);
		iput(inode);
		unlock_kernel();
		return err;
	}
	unlock_kernel();
	d_instantiate(dentry, inode);
	return 0;
}

static struct dentry * bfs_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
{
	struct inode * inode = NULL;
	struct buffer_head * bh;
	struct bfs_dirent * de;

	if (dentry->d_name.len > BFS_NAMELEN)
		return ERR_PTR(-ENAMETOOLONG);

	lock_kernel();
	bh = bfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de);
	if (bh) {
		unsigned long ino = (unsigned long)le16_to_cpu(de->ino);
		brelse(bh);
		inode = iget(dir->i_sb, ino);
		if (!inode) {
			unlock_kernel();
			return ERR_PTR(-EACCES);
		}
	}
	unlock_kernel();
	d_add(dentry, inode);
	return NULL;
}

static int bfs_link(struct dentry * old, struct inode * dir, struct dentry * new)
{
	struct inode * inode = old->d_inode;
	int err;

	lock_kernel();
	err = bfs_add_entry(dir, new->d_name.name, new->d_name.len, inode->i_ino);
	if (err) {
		unlock_kernel();
		return err;
	}
	inode->i_nlink++;
	inode->i_ctime = CURRENT_TIME_SEC;
	mark_inode_dirty(inode);
	atomic_inc(&inode->i_count);
	d_instantiate(new, inode);
	unlock_kernel();
	return 0;
}


static int bfs_unlink(struct inode * dir, struct dentry * dentry)
{
	int error = -ENOENT;
	struct inode * inode;
	struct buffer_head * bh;
	struct bfs_dirent * de;

	inode = dentry->d_inode;
	lock_kernel();
	bh = bfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de);
	if (!bh || le16_to_cpu(de->ino) != inode->i_ino)
		goto out_brelse;

	if (!inode->i_nlink) {
		printf("unlinking non-existent file %s:%lu (nlink=%d)\n", inode->i_sb->s_id, 
				inode->i_ino, inode->i_nlink);
		inode->i_nlink = 1;
	}
	de->ino = 0;
	mark_buffer_dirty(bh);
	dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
	mark_inode_dirty(dir);
	inode->i_nlink--;
	inode->i_ctime = dir->i_ctime;
	mark_inode_dirty(inode);
	error = 0;

out_brelse:
	brelse(bh);
	unlock_kernel();
	return error;
}

static int bfs_rename(struct inode * old_dir, struct dentry * old_dentry, 
			struct inode * new_dir, struct dentry * new_dentry)
{
	struct inode * old_inode, * new_inode;
	struct buffer_head * old_bh, * new_bh;
	struct bfs_dirent * old_de, * new_de;		
	int error = -ENOENT;

	old_bh = new_bh = NULL;
	old_inode = old_dentry->d_inode;
	if (S_ISDIR(old_inode->i_mode))
		return -EINVAL;

	lock_kernel();
	old_bh = bfs_find_entry(old_dir, 
				old_dentry->d_name.name, 
				old_dentry->d_name.len, &old_de);

	if (!old_bh || le16_to_cpu(old_de->ino) != old_inode->i_ino)
		goto end_rename;

	error = -EPERM;
	new_inode = new_dentry->d_inode;
	new_bh = bfs_find_entry(new_dir, 
				new_dentry->d_name.name, 
				new_dentry->d_name.len, &new_de);

	if (new_bh && !new_inode) {
		brelse(new_bh);
		new_bh = NULL;
	}
	if (!new_bh) {
		error = bfs_add_entry(new_dir, 
					new_dentry->d_name.name,
			 		new_dentry->d_name.len, old_inode->i_ino);
		if (error)
			goto end_rename;
	}
	old_de->ino = 0;
	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC;
	mark_inode_dirty(old_dir);
	if (new_inode) {
		new_inode->i_nlink--;
		new_inode->i_ctime = CURRENT_TIME_SEC;
		mark_inode_dirty(new_inode);
	}
	mark_buffer_dirty(old_bh);
	error = 0;

end_rename:
	unlock_kernel();
	brelse(old_bh);
	brelse(new_bh);
	return error;
}

struct inode_operations bfs_dir_inops = {
	.create			= bfs_create,
	.lookup			= bfs_lookup,
	.link			= bfs_link,
	.unlink			= bfs_unlink,
	.rename			= bfs_rename,
};

static int bfs_add_entry(struct inode * dir, const unsigned char * name, int namelen, int ino)
{
	struct buffer_head * bh;
	struct bfs_dirent * de;
	int block, sblock, eblock, off, eoff;
	int i;

	dprintf("name=%s, namelen=%d\n", name, namelen);

	if (!namelen)
		return -ENOENT;
	if (namelen > BFS_NAMELEN)
		return -ENAMETOOLONG;

	sblock = BFS_I(dir)->i_sblock;
	eblock = BFS_I(dir)->i_eblock;
	eoff = dir->i_size % BFS_BSIZE;
	for (block=sblock; block<=eblock; block++) {
		bh = sb_bread(dir->i_sb, block);
		if(!bh) 
			return -ENOSPC;
		for (off=0; off<BFS_BSIZE; off+=BFS_DIRENT_SIZE) {
			de = (struct bfs_dirent *)(bh->b_data + off);
			if (block==eblock && off>=eoff) {
				/* Do not read/interpret the garbage in the end of eblock. */
				de->ino = 0;
			}
			if (!de->ino) {
				if ((block-sblock)*BFS_BSIZE + off >= dir->i_size) {
					dir->i_size += BFS_DIRENT_SIZE;
					dir->i_ctime = CURRENT_TIME_SEC;
				}
				dir->i_mtime = CURRENT_TIME_SEC;
				mark_inode_dirty(dir);
				de->ino = cpu_to_le16((u16)ino);
				for (i=0; i<BFS_NAMELEN; i++)
					de->name[i] = (i < namelen) ? name[i] : 0;
				mark_buffer_dirty(bh);
				brelse(bh);
				return 0;
			}
		}
		brelse(bh);
	}
	return -ENOSPC;
}

static inline int bfs_namecmp(int len, const unsigned char * name, const char * buffer)
{
	if (len < BFS_NAMELEN && buffer[len])
		return 0;
	return !memcmp(name, buffer, len);
}

static struct buffer_head * bfs_find_entry(struct inode * dir, 
	const unsigned char * name, int namelen, struct bfs_dirent ** res_dir)
{
	unsigned long block, offset;
	struct buffer_head * bh;
	struct bfs_dirent * de;

	*res_dir = NULL;
	if (namelen > BFS_NAMELEN)
		return NULL;
	bh = NULL;
	block = offset = 0;
	while (block * BFS_BSIZE + offset < dir->i_size) {
		if (!bh) {
			bh = sb_bread(dir->i_sb, BFS_I(dir)->i_sblock + block);
			if (!bh) {
				block++;
				continue;
			}
		}
		de = (struct bfs_dirent *)(bh->b_data + offset);
		offset += BFS_DIRENT_SIZE;
		if (le16_to_cpu(de->ino) && bfs_namecmp(namelen, name, de->name)) {
			*res_dir = de;
			return bh;
		}
		if (offset < bh->b_size)
			continue;
		brelse(bh);
		bh = NULL;
		offset = 0;
		block++;
	}
	brelse(bh);
	return NULL;
}
