
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/module.h>
#include <linux/smp_lock.h>
#include <linux/namei.h>

struct export_operations export_op_default;

#define	CALL(ops,fun) ((ops->fun)?(ops->fun):export_op_default.fun)

#define dprintk(fmt, args...) do{}while(0)

/**
 * find_exported_dentry - helper routine to implement export_operations->decode_fh
 * @sb:		The &super_block identifying the filesystem
 * @obj:	An opaque identifier of the object to be found - passed to
 *		get_inode
 * @parent:	An optional opqaue identifier of the parent of the object.
 * @acceptable:	A function used to test possible &dentries to see if they are
 *		acceptable
 * @context:	A parameter to @acceptable so that it knows on what basis to
 *		judge.
 *
 * find_exported_dentry is the central helper routine to enable file systems
 * to provide the decode_fh() export_operation.  It's main task is to take
 * an &inode, find or create an appropriate &dentry structure, and possibly
 * splice this into the dcache in the correct place.
 *
 * The decode_fh() operation provided by the filesystem should call
 * find_exported_dentry() with the same parameters that it received except
 * that instead of the file handle fragment, pointers to opaque identifiers
 * for the object and optionally its parent are passed.  The default decode_fh
 * routine passes one pointer to the start of the filehandle fragment, and
 * one 8 bytes into the fragment.  It is expected that most filesystems will
 * take this approach, though the offset to the parent identifier may well be
 * different.
 *
 * find_exported_dentry() will call get_dentry to get an dentry pointer from
 * the file system.  If any &dentry in the d_alias list is acceptable, it will
 * be returned.  Otherwise find_exported_dentry() will attempt to splice a new
 * &dentry into the dcache using get_name() and get_parent() to find the
 * appropriate place.
 */

struct dentry *
find_exported_dentry(struct super_block *sb, void *obj, void *parent,
		     int (*acceptable)(void *context, struct dentry *de),
		     void *context)
{
	struct dentry *result = NULL;
	struct dentry *target_dir;
	int err;
	struct export_operations *nops = sb->s_export_op;
	struct list_head *le, *head;
	struct dentry *toput = NULL;
	int noprogress;


	/*
	 * Attempt to find the inode.
	 */
	result = CALL(sb->s_export_op,get_dentry)(sb,obj);
	err = -ESTALE;
	if (result == NULL)
		goto err_out;
	if (IS_ERR(result)) {
		err = PTR_ERR(result);
		goto err_out;
	}
	if (S_ISDIR(result->d_inode->i_mode) &&
	    (result->d_flags & DCACHE_DISCONNECTED)) {
		/* it is an unconnected directory, we must connect it */
		;
	} else {
		if (acceptable(context, result))
			return result;
		if (S_ISDIR(result->d_inode->i_mode)) {
			/* there is no other dentry, so fail */
			goto err_result;
		}
		/* try any other aliases */
		spin_lock(&dcache_lock);
		head = &result->d_inode->i_dentry;
		list_for_each(le, head) {
			struct dentry *dentry = list_entry(le, struct dentry, d_alias);
			dget_locked(dentry);
			spin_unlock(&dcache_lock);
			if (toput)
				dput(toput);
			toput = NULL;
			if (dentry != result &&
			    acceptable(context, dentry)) {
				dput(result);
				return dentry;
			}
			spin_lock(&dcache_lock);
			toput = dentry;
		}
		spin_unlock(&dcache_lock);
		if (toput)
			dput(toput);
	}			

	/* It's a directory, or we are required to confirm the file's
	 * location in the tree based on the parent information
 	 */
	dprintk("find_exported_dentry: need to look harder for %s/%d\n",sb->s_id,*(int*)obj);
	if (S_ISDIR(result->d_inode->i_mode))
		target_dir = dget(result);
	else {
		if (parent == NULL)
			goto err_result;

		target_dir = CALL(sb->s_export_op,get_dentry)(sb,parent);
		if (IS_ERR(target_dir))
			err = PTR_ERR(target_dir);
		if (target_dir == NULL || IS_ERR(target_dir))
			goto err_result;
	}
	/*
	 * Now we need to make sure that target_dir is properly connected.
	 * It may already be, as the flag isn't always updated when connection
	 * happens.
	 * So, we walk up parent links until we find a connected directory,
	 * or we run out of directories.  Then we find the parent, find
	 * the name of the child in that parent, and do a lookup.
	 * This should connect the child into the parent
	 * We then repeat.
	 */

	/* it is possible that a confused file system might not let us complete 
	 * the path to the root.  For example, if get_parent returns a directory
	 * in which we cannot find a name for the child.  While this implies a
	 * very sick filesystem we don't want it to cause knfsd to spin.  Hence
	 * the noprogress counter.  If we go through the loop 10 times (2 is
	 * probably enough) without getting anywhere, we just give up
	 */
	noprogress= 0;
	while (target_dir->d_flags & DCACHE_DISCONNECTED && noprogress++ < 10) {
		struct dentry *pd = target_dir;

		dget(pd);
		spin_lock(&pd->d_lock);
		while (!IS_ROOT(pd) &&
				(pd->d_parent->d_flags&DCACHE_DISCONNECTED)) {
			struct dentry *parent = pd->d_parent;

			dget(parent);
			spin_unlock(&pd->d_lock);
			dput(pd);
			pd = parent;
			spin_lock(&pd->d_lock);
		}
		spin_unlock(&pd->d_lock);

		if (!IS_ROOT(pd)) {
			/* must have found a connected parent - great */
			spin_lock(&pd->d_lock);
			pd->d_flags &= ~DCACHE_DISCONNECTED;
			spin_unlock(&pd->d_lock);
			noprogress = 0;
		} else if (pd == sb->s_root) {
			printk(KERN_ERR "export: Eeek filesystem root is not connected, impossible\n");
			spin_lock(&pd->d_lock);
			pd->d_flags &= ~DCACHE_DISCONNECTED;
			spin_unlock(&pd->d_lock);
			noprogress = 0;
		} else {
			/* we have hit the top of a disconnected path.  Try
			 * to find parent and connect
			 * note: racing with some other process renaming a
			 * directory isn't much of a problem here.  If someone
			 * renames the directory, it will end up properly
			 * connected, which is what we want
			 */
			struct dentry *ppd;
			struct dentry *npd;
			char nbuf[NAME_MAX+1];

			down(&pd->d_inode->i_sem);
			ppd = CALL(nops,get_parent)(pd);
			up(&pd->d_inode->i_sem);

			if (IS_ERR(ppd)) {
				err = PTR_ERR(ppd);
				dprintk("find_exported_dentry: get_parent of %ld failed, err %d\n",
					pd->d_inode->i_ino, err);
				dput(pd);
				break;
			}
			dprintk("find_exported_dentry: find name of %lu in %lu\n", pd->d_inode->i_ino, ppd->d_inode->i_ino);
			err = CALL(nops,get_name)(ppd, nbuf, pd);
			if (err) {
				dput(ppd);
				dput(pd);
				if (err == -ENOENT)
					/* some race between get_parent and
					 * get_name?  just try again
					 */
					continue;
				break;
			}
			dprintk("find_exported_dentry: found name: %s\n", nbuf);
			down(&ppd->d_inode->i_sem);
			npd = lookup_one_len(nbuf, ppd, strlen(nbuf));
			up(&ppd->d_inode->i_sem);
			if (IS_ERR(npd)) {
				err = PTR_ERR(npd);
				dprintk("find_exported_dentry: lookup failed: %d\n", err);
				dput(ppd);
				dput(pd);
				break;
			}
			/* we didn't really want npd, we really wanted
			 * a side-effect of the lookup.
			 * hopefully, npd == pd, though it isn't really
			 * a problem if it isn't
			 */
			if (npd == pd)
				noprogress = 0;
			else
				printk("find_exported_dentry: npd != pd\n");
			dput(npd);
			dput(ppd);
			if (IS_ROOT(pd)) {
				/* something went wrong, we have to give up */
				dput(pd);
				break;
			}
		}
		dput(pd);
	}

	if (target_dir->d_flags & DCACHE_DISCONNECTED) {
		/* something went wrong - oh-well */
		if (!err)
			err = -ESTALE;
		goto err_target;
	}
	/* if we weren't after a directory, have one more step to go */
	if (result != target_dir) {
		struct dentry *nresult;
		char nbuf[NAME_MAX+1];
		err = CALL(nops,get_name)(target_dir, nbuf, result);
		if (!err) {
			down(&target_dir->d_inode->i_sem);
			nresult = lookup_one_len(nbuf, target_dir, strlen(nbuf));
			up(&target_dir->d_inode->i_sem);
			if (!IS_ERR(nresult)) {
				if (nresult->d_inode) {
					dput(result);
					result = nresult;
				} else
					dput(nresult);
			}
		}
	}
	dput(target_dir);
	/* now result is properly connected, it is our best bet */
	if (acceptable(context, result))
		return result;
	/* one last try of the aliases.. */
	spin_lock(&dcache_lock);
	toput = NULL;
	head = &result->d_inode->i_dentry;
	list_for_each(le, head) {
		struct dentry *dentry = list_entry(le, struct dentry, d_alias);
		dget_locked(dentry);
		spin_unlock(&dcache_lock);
		if (toput) dput(toput);
		if (dentry != result &&
		    acceptable(context, dentry)) {
			dput(result);
			return dentry;
		}
		spin_lock(&dcache_lock);
		toput = dentry;
	}
	spin_unlock(&dcache_lock);
	if (toput)
		dput(toput);

	/* drat - I just cannot find anything acceptable */
	dput(result);
	/* It might be justifiable to return ESTALE here,
	 * but the filehandle at-least looks reasonable good
	 * and it just be a permission problem, so returning
	 * -EACCESS is safer
	 */
	return ERR_PTR(-EACCES);

 err_target:
	dput(target_dir);
 err_result:
	dput(result);
 err_out:
	return ERR_PTR(err);
}



static struct dentry *get_parent(struct dentry *child)
{
	/* get_parent cannot be supported generically, the locking
	 * is too icky.
	 * instead, we just return EACCES.  If server reboots or inodes
	 * get flushed, you lose
	 */
	return ERR_PTR(-EACCES);
}


struct getdents_callback {
	char *name;		/* name that was found. It already points to a
				   buffer NAME_MAX+1 is size */
	unsigned long ino;	/* the inum we are looking for */
	int found;		/* inode matched? */
	int sequence;		/* sequence counter */
};

/*
 * A rather strange filldir function to capture
 * the name matching the specified inode number.
 */
static int filldir_one(void * __buf, const char * name, int len,
			loff_t pos, ino_t ino, unsigned int d_type)
{
	struct getdents_callback *buf = __buf;
	int result = 0;

	buf->sequence++;
	if (buf->ino == ino) {
		memcpy(buf->name, name, len);
		buf->name[len] = '\0';
		buf->found = 1;
		result = -1;
	}
	return result;
}

/**
 * get_name - default export_operations->get_name function
 * @dentry: the directory in which to find a name
 * @name:   a pointer to a %NAME_MAX+1 char buffer to store the name
 * @child:  the dentry for the child directory.
 *
 * calls readdir on the parent until it finds an entry with
 * the same inode number as the child, and returns that.
 */
static int get_name(struct dentry *dentry, char *name,
			struct dentry *child)
{
	struct inode *dir = dentry->d_inode;
	int error;
	struct file *file;
	struct getdents_callback buffer;

	error = -ENOTDIR;
	if (!dir || !S_ISDIR(dir->i_mode))
		goto out;
	error = -EINVAL;
	if (!dir->i_fop)
		goto out;
	/*
	 * Open the directory ...
	 */
	file = dentry_open(dget(dentry), NULL, O_RDONLY);
	error = PTR_ERR(file);
	if (IS_ERR(file))
		goto out;

	error = -EINVAL;
	if (!file->f_op->readdir)
		goto out_close;

	buffer.name = name;
	buffer.ino = child->d_inode->i_ino;
	buffer.found = 0;
	buffer.sequence = 0;
	while (1) {
		int old_seq = buffer.sequence;

		error = vfs_readdir(file, filldir_one, &buffer);

		if (error < 0)
			break;

		error = 0;
		if (buffer.found)
			break;
		error = -ENOENT;
		if (old_seq == buffer.sequence)
			break;
	}

out_close:
	fput(file);
out:
	return error;
}


static struct dentry *export_iget(struct super_block *sb, unsigned long ino, __u32 generation)
{

	/* iget isn't really right if the inode is currently unallocated!!
	 * This should really all be done inside each filesystem
	 *
	 * ext2fs' read_inode has been strengthed to return a bad_inode if
	 * the inode had been deleted.
	 *
	 * Currently we don't know the generation for parent directory, so
	 * a generation of 0 means "accept any"
	 */
	struct inode *inode;
	struct dentry *result;
	if (ino == 0)
		return ERR_PTR(-ESTALE);
	inode = iget(sb, ino);
	if (inode == NULL)
		return ERR_PTR(-ENOMEM);
	if (is_bad_inode(inode)
	    || (generation && inode->i_generation != generation)
		) {
		/* we didn't find the right inode.. */
		dprintk("fh_verify: Inode %lu, Bad count: %d %d or version  %u %u\n",
			inode->i_ino,
			inode->i_nlink, atomic_read(&inode->i_count),
			inode->i_generation,
			generation);

		iput(inode);
		return ERR_PTR(-ESTALE);
	}
	/* now to find a dentry.
	 * If possible, get a well-connected one
	 */
	result = d_alloc_anon(inode);
	if (!result) {
		iput(inode);
		return ERR_PTR(-ENOMEM);
	}
	return result;
}


static struct dentry *get_object(struct super_block *sb, void *vobjp)
{
	__u32 *objp = vobjp;
	unsigned long ino = objp[0];
	__u32 generation = objp[1];

	return export_iget(sb, ino, generation);
}


/**
 * export_encode_fh - default export_operations->encode_fh function
 * @dentry:  the dentry to encode
 * @fh:      where to store the file handle fragment
 * @max_len: maximum length to store there
 * @connectable: whether to store parent information
 *
 * This default encode_fh function assumes that the 32 inode number
 * is suitable for locating an inode, and that the generation number
 * can be used to check that it is still valid.  It places them in the
 * filehandle fragment where export_decode_fh expects to find them.
 */
static int export_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
		   int connectable)
{
	struct inode * inode = dentry->d_inode;
	int len = *max_len;
	int type = 1;
	
	if (len < 2 || (connectable && len < 4))
		return 255;

	len = 2;
	fh[0] = inode->i_ino;
	fh[1] = inode->i_generation;
	if (connectable && !S_ISDIR(inode->i_mode)) {
		struct inode *parent;

		spin_lock(&dentry->d_lock);
		parent = dentry->d_parent->d_inode;
		fh[2] = parent->i_ino;
		fh[3] = parent->i_generation;
		spin_unlock(&dentry->d_lock);
		len = 4;
		type = 2;
	}
	*max_len = len;
	return type;
}


/**
 * export_decode_fh - default export_operations->decode_fh function
 * @sb:  The superblock
 * @fh:  pointer to the file handle fragment
 * @fh_len: length of file handle fragment
 * @acceptable: function for testing acceptability of dentrys
 * @context:   context for @acceptable
 *
 * This is the default decode_fh() function.
 * a fileid_type of 1 indicates that the filehandlefragment
 * just contains an object identifier understood by  get_dentry.
 * a fileid_type of 2 says that there is also a directory
 * identifier 8 bytes in to the filehandlefragement.
 */
static struct dentry *export_decode_fh(struct super_block *sb, __u32 *fh, int fh_len,
			      int fileid_type,
			 int (*acceptable)(void *context, struct dentry *de),
			 void *context)
{
	__u32 parent[2];
	parent[0] = parent[1] = 0;
	if (fh_len < 2 || fileid_type > 2)
		return NULL;
	if (fileid_type == 2) {
		if (fh_len > 2) parent[0] = fh[2];
		if (fh_len > 3) parent[1] = fh[3];
	}
	return find_exported_dentry(sb, fh, parent,
				   acceptable, context);
}

struct export_operations export_op_default = {
	.decode_fh	= export_decode_fh,
	.encode_fh	= export_encode_fh,

	.get_name	= get_name,
	.get_parent	= get_parent,
	.get_dentry	= get_object,
};

EXPORT_SYMBOL(export_op_default);
EXPORT_SYMBOL(find_exported_dentry);

MODULE_LICENSE("GPL");
