/*
 *   Contains the CIFS DFS referral mounting routines used for handling
 *   traversal via DFS junction point
 *
 *   Copyright (c) 2007 Igor Mammedov
 *   Copyright (C) International Business Machines  Corp., 2008
 *   Author(s): Igor Mammedov (niallain@gmail.com)
 *		Steve French (sfrench@us.ibm.com)
 *   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; either version
 *   2 of the License, or (at your option) any later version.
 */

#include <linux/dcache.h>
#include <linux/mount.h>
#include <linux/namei.h>
#include <linux/vfs.h>
#include <linux/fs.h>
#include "cifsglob.h"
#include "cifsproto.h"
#include "cifsfs.h"
#include "dns_resolve.h"
#include "cifs_debug.h"

static LIST_HEAD(cifs_dfs_automount_list);

/*
 * DFS functions
*/

void dfs_shrink_umount_helper(struct vfsmount *vfsmnt)
{
	mark_mounts_for_expiry(&cifs_dfs_automount_list);
	mark_mounts_for_expiry(&cifs_dfs_automount_list);
}

/**
 * cifs_get_share_name	-	extracts share name from UNC
 * @node_name:	pointer to UNC string
 *
 * Extracts sharename form full UNC.
 * i.e. strips from UNC trailing path that is not part of share
 * name and fixup missing '\' in the begining of DFS node refferal
 * if neccessary.
 * Returns pointer to share name on success or NULL on error.
 * Caller is responsible for freeing returned string.
 */
static char *cifs_get_share_name(const char *node_name)
{
	int len;
	char *UNC;
	char *pSep;

	len = strlen(node_name);
	UNC = kmalloc(len+2 /*for term null and additional \ if it's missed */,
			 GFP_KERNEL);
	if (!UNC)
		return NULL;

	/* get share name and server name */
	if (node_name[1] != '\\') {
		UNC[0] = '\\';
		strncpy(UNC+1, node_name, len);
		len++;
		UNC[len] = 0;
	} else {
		strncpy(UNC, node_name, len);
		UNC[len] = 0;
	}

	/* find server name end */
	pSep = memchr(UNC+2, '\\', len-2);
	if (!pSep) {
		cERROR(1, ("%s: no server name end in node name: %s",
			__func__, node_name));
		kfree(UNC);
		return NULL;
	}

	/* find sharename end */
	pSep++;
	pSep = memchr(UNC+(pSep-UNC), '\\', len-(pSep-UNC));
	if (!pSep) {
		cERROR(1, ("%s:2 cant find share name in node name: %s",
			__func__, node_name));
		kfree(UNC);
		return NULL;
	}
	/* trim path up to sharename end
	 *          * now we have share name in UNC */
	*pSep = 0;

	return UNC;
}


/**
 * compose_mount_options	-	creates mount options for refferral
 * @sb_mountdata:	parent/root DFS mount options (template)
 * @ref_unc:		refferral server UNC
 * @devname:		pointer for saving device name
 *
 * creates mount options for submount based on template options sb_mountdata
 * and replacing unc,ip,prefixpath options with ones we've got form ref_unc.
 *
 * Returns: pointer to new mount options or ERR_PTR.
 * Caller is responcible for freeing retunrned value if it is not error.
 */
static char *compose_mount_options(const char *sb_mountdata,
				   const char *ref_unc,
				   char **devname)
{
	int rc;
	char *mountdata;
	int md_len;
	char *tkn_e;
	char *srvIP = NULL;
	char sep = ',';
	int off, noff;

	if (sb_mountdata == NULL)
		return ERR_PTR(-EINVAL);

	*devname = cifs_get_share_name(ref_unc);
	rc = dns_resolve_server_name_to_ip(*devname, &srvIP);
	if (rc != 0) {
		cERROR(1, ("%s: Failed to resolve server part of %s to IP",
			  __func__, *devname));
		mountdata = ERR_PTR(rc);
		goto compose_mount_options_out;
	}
	md_len = strlen(sb_mountdata) + strlen(srvIP) + strlen(ref_unc) + 3;
	mountdata = kzalloc(md_len+1, GFP_KERNEL);
	if (mountdata == NULL) {
		mountdata = ERR_PTR(-ENOMEM);
		goto compose_mount_options_out;
	}

	/* copy all options except of unc,ip,prefixpath */
	off = 0;
	if (strncmp(sb_mountdata, "sep=", 4) == 0) {
			sep = sb_mountdata[4];
			strncpy(mountdata, sb_mountdata, 5);
			off += 5;
	}
	while ((tkn_e = strchr(sb_mountdata+off, sep))) {
		noff = (tkn_e - (sb_mountdata+off)) + 1;
		if (strnicmp(sb_mountdata+off, "unc=", 4) == 0) {
			off += noff;
			continue;
		}
		if (strnicmp(sb_mountdata+off, "ip=", 3) == 0) {
			off += noff;
			continue;
		}
		if (strnicmp(sb_mountdata+off, "prefixpath=", 3) == 0) {
			off += noff;
			continue;
		}
		strncat(mountdata, sb_mountdata+off, noff);
		off += noff;
	}
	strcat(mountdata, sb_mountdata+off);
	mountdata[md_len] = '\0';

	/* copy new IP and ref share name */
	strcat(mountdata, ",ip=");
	strcat(mountdata, srvIP);
	strcat(mountdata, ",unc=");
	strcat(mountdata, *devname);

	/* find & copy prefixpath */
	tkn_e = strchr(ref_unc+2, '\\');
	if (tkn_e) {
		tkn_e = strchr(tkn_e+1, '\\');
		if (tkn_e) {
			strcat(mountdata, ",prefixpath=");
			strcat(mountdata, tkn_e);
		}
	}

	/*cFYI(1,("%s: parent mountdata: %s", __func__,sb_mountdata));*/
	/*cFYI(1, ("%s: submount mountdata: %s", __func__, mountdata ));*/

compose_mount_options_out:
	kfree(srvIP);
	return mountdata;
}


static struct vfsmount *cifs_dfs_do_refmount(const struct vfsmount *mnt_parent,
		struct dentry *dentry, char *ref_unc)
{
	struct cifs_sb_info *cifs_sb;
	struct vfsmount *mnt;
	char *mountdata;
	char *devname = NULL;

	cifs_sb = CIFS_SB(dentry->d_inode->i_sb);
	mountdata = compose_mount_options(cifs_sb->mountdata,
						ref_unc, &devname);

	if (IS_ERR(mountdata))
		return (struct vfsmount *)mountdata;

	mnt = vfs_kern_mount(&cifs_fs_type, 0, devname, mountdata);
	kfree(mountdata);
	kfree(devname);
	return mnt;

}

static char *build_full_dfs_path_from_dentry(struct dentry *dentry)
{
	char *full_path = NULL;
	char *search_path;
	char *tmp_path;
	size_t l_max_len;
	struct cifs_sb_info *cifs_sb;

	if (dentry->d_inode == NULL)
		return NULL;

	cifs_sb = CIFS_SB(dentry->d_inode->i_sb);

	if (cifs_sb->tcon == NULL)
		return NULL;

	search_path = build_path_from_dentry(dentry);
	if (search_path == NULL)
		return NULL;

	if (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS) {
		/* we should use full path name to correct working with DFS */
		l_max_len = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE+1) +
					strnlen(search_path, MAX_PATHCONF) + 1;
		tmp_path = kmalloc(l_max_len, GFP_KERNEL);
		if (tmp_path == NULL) {
			kfree(search_path);
			return NULL;
		}
		strncpy(tmp_path, cifs_sb->tcon->treeName, l_max_len);
		strcat(tmp_path, search_path);
		tmp_path[l_max_len-1] = 0;
		full_path = tmp_path;
		kfree(search_path);
	} else {
		full_path = search_path;
	}
	return full_path;
}

static int add_mount_helper(struct vfsmount *newmnt, struct nameidata *nd,
				struct list_head *mntlist)
{
	/* stolen from afs code */
	int err;

	mntget(newmnt);
	err = do_add_mount(newmnt, nd, nd->path.mnt->mnt_flags, mntlist);
	switch (err) {
	case 0:
		dput(nd->path.dentry);
		mntput(nd->path.mnt);
		nd->path.mnt = newmnt;
		nd->path.dentry = dget(newmnt->mnt_root);
		break;
	case -EBUSY:
		/* someone else made a mount here whilst we were busy */
		while (d_mountpoint(nd->path.dentry) &&
		       follow_down(&nd->path.mnt, &nd->path.dentry))
			;
		err = 0;
	default:
		mntput(newmnt);
		break;
	}
	return err;
}

static void dump_referral(const struct dfs_info3_param *ref)
{
	cFYI(1, ("DFS: ref path: %s", ref->path_name));
	cFYI(1, ("DFS: node path: %s", ref->node_name));
	cFYI(1, ("DFS: fl: %hd, srv_type: %hd", ref->flags, ref->server_type));
	cFYI(1, ("DFS: ref_flags: %hd, path_consumed: %hd", ref->ref_flag,
				ref->path_consumed));
}


static void*
cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
{
	struct dfs_info3_param *referrals = NULL;
	unsigned int num_referrals = 0;
	struct cifs_sb_info *cifs_sb;
	struct cifsSesInfo *ses;
	char *full_path = NULL;
	int xid, i;
	int rc = 0;
	struct vfsmount *mnt = ERR_PTR(-ENOENT);

	cFYI(1, ("in %s", __func__));
	BUG_ON(IS_ROOT(dentry));

	xid = GetXid();

	dput(nd->path.dentry);
	nd->path.dentry = dget(dentry);

	cifs_sb = CIFS_SB(dentry->d_inode->i_sb);
	ses = cifs_sb->tcon->ses;

	if (!ses) {
		rc = -EINVAL;
		goto out_err;
	}

	full_path = build_full_dfs_path_from_dentry(dentry);
	if (full_path == NULL) {
		rc = -ENOMEM;
		goto out_err;
	}

	rc = get_dfs_path(xid, ses , full_path, cifs_sb->local_nls,
		&num_referrals, &referrals,
		cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);

	for (i = 0; i < num_referrals; i++) {
		dump_referral(referrals+i);
		/* connect to a storage node */
		if (referrals[i].flags & DFSREF_STORAGE_SERVER) {
			int len;
			len = strlen(referrals[i].node_name);
			if (len < 2) {
				cERROR(1, ("%s: Net Address path too short: %s",
					__func__, referrals[i].node_name));
				rc = -EINVAL;
				goto out_err;
			}
			mnt = cifs_dfs_do_refmount(nd->path.mnt,
						nd->path.dentry,
						referrals[i].node_name);
			cFYI(1, ("%s: cifs_dfs_do_refmount:%s , mnt:%p",
					 __func__,
					referrals[i].node_name, mnt));

			/* complete mount procedure if we accured submount */
			if (!IS_ERR(mnt))
				break;
		}
	}

	/* we need it cause for() above could exit without valid submount */
	rc = PTR_ERR(mnt);
	if (IS_ERR(mnt))
		goto out_err;

	nd->path.mnt->mnt_flags |= MNT_SHRINKABLE;
	rc = add_mount_helper(mnt, nd, &cifs_dfs_automount_list);

out:
	FreeXid(xid);
	free_dfs_info_array(referrals, num_referrals);
	kfree(full_path);
	cFYI(1, ("leaving %s" , __func__));
	return ERR_PTR(rc);
out_err:
	path_put(&nd->path);
	goto out;
}

struct inode_operations cifs_dfs_referral_inode_operations = {
	.follow_link = cifs_dfs_follow_mountpoint,
};

