/*
 *   fs/cifs/dir.c
 *
 *   vfs operations that deal with dentries
 *
 *   Copyright (C) International Business Machines  Corp., 2002,2009
 *   Author(s): Steve French (sfrench@us.ibm.com)
 *
 *   This library is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published
 *   by the Free Software Foundation; either version 2.1 of the License, or
 *   (at your option) any later version.
 *
 *   This library is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
 *   the GNU Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public License
 *   along with this library; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
#include <linux/fs.h>
#include <linux/stat.h>
#include <linux/slab.h>
#include <linux/namei.h>
#include "cifsfs.h"
#include "cifspdu.h"
#include "cifsglob.h"
#include "cifsproto.h"
#include "cifs_debug.h"
#include "cifs_fs_sb.h"

static void
renew_parental_timestamps(struct dentry *direntry)
{
	/* BB check if there is a way to get the kernel to do this or if we
	   really need this */
	do {
		direntry->d_time = jiffies;
		direntry = direntry->d_parent;
	} while (!IS_ROOT(direntry));
}

/* Note: caller must free return buffer */
char *
build_path_from_dentry(struct dentry *direntry)
{
	struct dentry *temp;
	int namelen;
	int pplen;
	int dfsplen;
	char *full_path;
	char dirsep;
	struct cifs_sb_info *cifs_sb;

	if (direntry == NULL)
		return NULL;  /* not much we can do if dentry is freed and
		we need to reopen the file after it was closed implicitly
		when the server crashed */

	cifs_sb = CIFS_SB(direntry->d_sb);
	dirsep = CIFS_DIR_SEP(cifs_sb);
	pplen = cifs_sb->prepathlen;
	if (cifs_sb->tcon && (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS))
		dfsplen = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE + 1);
	else
		dfsplen = 0;
cifs_bp_rename_retry:
	namelen = pplen + dfsplen;
	for (temp = direntry; !IS_ROOT(temp);) {
		namelen += (1 + temp->d_name.len);
		temp = temp->d_parent;
		if (temp == NULL) {
			cERROR(1, ("corrupt dentry"));
			return NULL;
		}
	}

	full_path = kmalloc(namelen+1, GFP_KERNEL);
	if (full_path == NULL)
		return full_path;
	full_path[namelen] = 0;	/* trailing null */
	for (temp = direntry; !IS_ROOT(temp);) {
		namelen -= 1 + temp->d_name.len;
		if (namelen < 0) {
			break;
		} else {
			full_path[namelen] = dirsep;
			strncpy(full_path + namelen + 1, temp->d_name.name,
				temp->d_name.len);
			cFYI(0, ("name: %s", full_path + namelen));
		}
		temp = temp->d_parent;
		if (temp == NULL) {
			cERROR(1, ("corrupt dentry"));
			kfree(full_path);
			return NULL;
		}
	}
	if (namelen != pplen + dfsplen) {
		cERROR(1,
		       ("did not end path lookup where expected namelen is %d",
			namelen));
		/* presumably this is only possible if racing with a rename
		of one of the parent directories  (we can not lock the dentries
		above us to prevent this, but retrying should be harmless) */
		kfree(full_path);
		goto cifs_bp_rename_retry;
	}
	/* DIR_SEP already set for byte  0 / vs \ but not for
	   subsequent slashes in prepath which currently must
	   be entered the right way - not sure if there is an alternative
	   since the '\' is a valid posix character so we can not switch
	   those safely to '/' if any are found in the middle of the prepath */
	/* BB test paths to Windows with '/' in the midst of prepath */

	if (dfsplen) {
		strncpy(full_path, cifs_sb->tcon->treeName, dfsplen);
		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
			int i;
			for (i = 0; i < dfsplen; i++) {
				if (full_path[i] == '\\')
					full_path[i] = '/';
			}
		}
	}
	strncpy(full_path + dfsplen, CIFS_SB(direntry->d_sb)->prepath, pplen);
	return full_path;
}

static void
cifs_fill_fileinfo(struct inode *newinode, __u16 fileHandle,
			struct cifsTconInfo *tcon, bool write_only)
{
	int oplock = 0;
	struct cifsFileInfo *pCifsFile;
	struct cifsInodeInfo *pCifsInode;

	pCifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);

	if (pCifsFile == NULL)
		return;

	if (oplockEnabled)
		oplock = REQ_OPLOCK;

	pCifsFile->netfid = fileHandle;
	pCifsFile->pid = current->tgid;
	pCifsFile->pInode = newinode;
	pCifsFile->invalidHandle = false;
	pCifsFile->closePend = false;
	mutex_init(&pCifsFile->fh_mutex);
	mutex_init(&pCifsFile->lock_mutex);
	INIT_LIST_HEAD(&pCifsFile->llist);
	atomic_set(&pCifsFile->wrtPending, 0);

	/* set the following in open now
			pCifsFile->pfile = file; */
	write_lock(&GlobalSMBSeslock);
	list_add(&pCifsFile->tlist, &tcon->openFileList);
	pCifsInode = CIFS_I(newinode);
	if (pCifsInode) {
		/* if readable file instance put first in list*/
		if (write_only)
			list_add_tail(&pCifsFile->flist,
				      &pCifsInode->openFileList);
		else
			list_add(&pCifsFile->flist, &pCifsInode->openFileList);

		if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
			pCifsInode->clientCanCacheAll = true;
			pCifsInode->clientCanCacheRead = true;
			cFYI(1, ("Exclusive Oplock inode %p", newinode));
		} else if ((oplock & 0xF) == OPLOCK_READ)
				pCifsInode->clientCanCacheRead = true;
	}
	write_unlock(&GlobalSMBSeslock);
}

int cifs_posix_open(char *full_path, struct inode **pinode,
		    struct super_block *sb, int mode, int oflags,
		    int *poplock, __u16 *pnetfid, int xid)
{
	int rc;
	__u32 oplock;
	bool write_only = false;
	FILE_UNIX_BASIC_INFO *presp_data;
	__u32 posix_flags = 0;
	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);

	cFYI(1, ("posix open %s", full_path));

	presp_data = kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
	if (presp_data == NULL)
		return -ENOMEM;

/* So far cifs posix extensions can only map the following flags.
   There are other valid fmode oflags such as FMODE_LSEEK, FMODE_PREAD, but
   so far we do not seem to need them, and we can treat them as local only */
	if ((oflags & (FMODE_READ | FMODE_WRITE)) ==
		(FMODE_READ | FMODE_WRITE))
		posix_flags = SMB_O_RDWR;
	else if (oflags & FMODE_READ)
		posix_flags = SMB_O_RDONLY;
	else if (oflags & FMODE_WRITE)
		posix_flags = SMB_O_WRONLY;
	if (oflags & O_CREAT)
		posix_flags |= SMB_O_CREAT;
	if (oflags & O_EXCL)
		posix_flags |= SMB_O_EXCL;
	if (oflags & O_TRUNC)
		posix_flags |= SMB_O_TRUNC;
	if (oflags & O_APPEND)
		posix_flags |= SMB_O_APPEND;
	if (oflags & O_SYNC)
		posix_flags |= SMB_O_SYNC;
	if (oflags & O_DIRECTORY)
		posix_flags |= SMB_O_DIRECTORY;
	if (oflags & O_NOFOLLOW)
		posix_flags |= SMB_O_NOFOLLOW;
	if (oflags & O_DIRECT)
		posix_flags |= SMB_O_DIRECT;

	if (!(oflags & FMODE_READ))
		write_only = true;

	mode &= ~current_umask();
	rc = CIFSPOSIXCreate(xid, cifs_sb->tcon, posix_flags, mode,
			pnetfid, presp_data, &oplock, full_path,
			cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
					CIFS_MOUNT_MAP_SPECIAL_CHR);
	if (rc)
		goto posix_open_ret;

	if (presp_data->Type == cpu_to_le32(-1))
		goto posix_open_ret; /* open ok, caller does qpathinfo */

	/* get new inode and set it up */
	if (!pinode)
		goto posix_open_ret; /* caller does not need info */

	if (*pinode == NULL) {
		__u64 unique_id = le64_to_cpu(presp_data->UniqueId);
		*pinode = cifs_new_inode(sb, &unique_id);
	}
	/* else an inode was passed in. Update its info, don't create one */

	/* We do not need to close the file if new_inode fails since
	   the caller will retry qpathinfo as long as inode is null */
	if (*pinode == NULL)
		goto posix_open_ret;

	posix_fill_in_inode(*pinode, presp_data, 1);

	cifs_fill_fileinfo(*pinode, *pnetfid, cifs_sb->tcon, write_only);

posix_open_ret:
	kfree(presp_data);
	return rc;
}

static void setup_cifs_dentry(struct cifsTconInfo *tcon,
			      struct dentry *direntry,
			      struct inode *newinode)
{
	if (tcon->nocase)
		direntry->d_op = &cifs_ci_dentry_ops;
	else
		direntry->d_op = &cifs_dentry_ops;
	d_instantiate(direntry, newinode);
}

/* Inode operations in similar order to how they appear in Linux file fs.h */

int
cifs_create(struct inode *inode, struct dentry *direntry, int mode,
		struct nameidata *nd)
{
	int rc = -ENOENT;
	int xid;
	int create_options = CREATE_NOT_DIR;
	int oplock = 0;
	int oflags;
	bool posix_create = false;
	/*
	 * BB below access is probably too much for mknod to request
	 *    but we have to do query and setpathinfo so requesting
	 *    less could fail (unless we want to request getatr and setatr
	 *    permissions (only).  At least for POSIX we do not have to
	 *    request so much.
	 */
	int desiredAccess = GENERIC_READ | GENERIC_WRITE;
	__u16 fileHandle;
	struct cifs_sb_info *cifs_sb;
	struct cifsTconInfo *tcon;
	char *full_path = NULL;
	FILE_ALL_INFO *buf = NULL;
	struct inode *newinode = NULL;
	int disposition = FILE_OVERWRITE_IF;
	bool write_only = false;

	xid = GetXid();

	cifs_sb = CIFS_SB(inode->i_sb);
	tcon = cifs_sb->tcon;

	full_path = build_path_from_dentry(direntry);
	if (full_path == NULL) {
		FreeXid(xid);
		return -ENOMEM;
	}

	if (oplockEnabled)
		oplock = REQ_OPLOCK;

	if (nd && (nd->flags & LOOKUP_OPEN))
		oflags = nd->intent.open.flags;
	else
		oflags = FMODE_READ;

	if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
	    (CIFS_UNIX_POSIX_PATH_OPS_CAP &
			le64_to_cpu(tcon->fsUnixInfo.Capability))) {
		rc = cifs_posix_open(full_path, &newinode, inode->i_sb,
				     mode, oflags, &oplock, &fileHandle, xid);
		/* EIO could indicate that (posix open) operation is not
		   supported, despite what server claimed in capability
		   negotation.  EREMOTE indicates DFS junction, which is not
		   handled in posix open */

		if (rc == 0) {
			posix_create = true;
			if (newinode == NULL) /* query inode info */
				goto cifs_create_get_file_info;
			else /* success, no need to query */
				goto cifs_create_set_dentry;
		} else if ((rc != -EIO) && (rc != -EREMOTE) &&
			 (rc != -EOPNOTSUPP) && (rc != -EINVAL))
			goto cifs_create_out;
		/* else fallthrough to retry, using older open call, this is
		   case where server does not support this SMB level, and
		   falsely claims capability (also get here for DFS case
		   which should be rare for path not covered on files) */
	}

	if (nd && (nd->flags & LOOKUP_OPEN)) {
		/* if the file is going to stay open, then we
		   need to set the desired access properly */
		desiredAccess = 0;
		if (oflags & FMODE_READ)
			desiredAccess |= GENERIC_READ; /* is this too little? */
		if (oflags & FMODE_WRITE) {
			desiredAccess |= GENERIC_WRITE;
			if (!(oflags & FMODE_READ))
				write_only = true;
		}

		if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
			disposition = FILE_CREATE;
		else if ((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
			disposition = FILE_OVERWRITE_IF;
		else if ((oflags & O_CREAT) == O_CREAT)
			disposition = FILE_OPEN_IF;
		else
			cFYI(1, ("Create flag not set in create function"));
	}

	/* BB add processing to set equivalent of mode - e.g. via CreateX with
	   ACLs */

	buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
	if (buf == NULL) {
		kfree(full_path);
		FreeXid(xid);
		return -ENOMEM;
	}

	/*
	 * if we're not using unix extensions, see if we need to set
	 * ATTR_READONLY on the create call
	 */
	if (!tcon->unix_ext && (mode & S_IWUGO) == 0)
		create_options |= CREATE_OPTION_READONLY;

	if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS)
		rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
			 desiredAccess, create_options,
			 &fileHandle, &oplock, buf, cifs_sb->local_nls,
			 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
	else
		rc = -EIO; /* no NT SMB support fall into legacy open below */

	if (rc == -EIO) {
		/* old server, retry the open legacy style */
		rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
			desiredAccess, create_options,
			&fileHandle, &oplock, buf, cifs_sb->local_nls,
			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
	}
	if (rc) {
		cFYI(1, ("cifs_create returned 0x%x", rc));
		goto cifs_create_out;
	}

	/* If Open reported that we actually created a file
	   then we now have to set the mode if possible */
	if ((tcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) {
		struct cifs_unix_set_info_args args = {
				.mode	= mode,
				.ctime	= NO_CHANGE_64,
				.atime	= NO_CHANGE_64,
				.mtime	= NO_CHANGE_64,
				.device	= 0,
		};

		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
			args.uid = (__u64) current_fsuid();
			if (inode->i_mode & S_ISGID)
				args.gid = (__u64) inode->i_gid;
			else
				args.gid = (__u64) current_fsgid();
		} else {
			args.uid = NO_CHANGE_64;
			args.gid = NO_CHANGE_64;
		}
		CIFSSMBUnixSetInfo(xid, tcon, full_path, &args,
			cifs_sb->local_nls,
			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
	} else {
		/* BB implement mode setting via Windows security
		   descriptors e.g. */
		/* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/

		/* Could set r/o dos attribute if mode & 0222 == 0 */
	}

cifs_create_get_file_info:
	/* server might mask mode so we have to query for it */
	if (tcon->unix_ext)
		rc = cifs_get_inode_info_unix(&newinode, full_path,
					      inode->i_sb, xid);
	else {
		rc = cifs_get_inode_info(&newinode, full_path, buf,
					 inode->i_sb, xid, &fileHandle);
		if (newinode) {
			if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
				newinode->i_mode = mode;
			if ((oplock & CIFS_CREATE_ACTION) &&
			    (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) {
				newinode->i_uid = current_fsuid();
				if (inode->i_mode & S_ISGID)
					newinode->i_gid = inode->i_gid;
				else
					newinode->i_gid = current_fsgid();
			}
		}
	}

cifs_create_set_dentry:
	if (rc == 0)
		setup_cifs_dentry(tcon, direntry, newinode);
	else
		cFYI(1, ("Create worked, get_inode_info failed rc = %d", rc));

	/* nfsd case - nfs srv does not set nd */
	if ((nd == NULL) || (!(nd->flags & LOOKUP_OPEN))) {
		/* mknod case - do not leave file open */
		CIFSSMBClose(xid, tcon, fileHandle);
	} else if (!(posix_create) && (newinode)) {
			cifs_fill_fileinfo(newinode, fileHandle,
					cifs_sb->tcon, write_only);
	}
cifs_create_out:
	kfree(buf);
	kfree(full_path);
	FreeXid(xid);
	return rc;
}

int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
		dev_t device_number)
{
	int rc = -EPERM;
	int xid;
	struct cifs_sb_info *cifs_sb;
	struct cifsTconInfo *pTcon;
	char *full_path = NULL;
	struct inode *newinode = NULL;

	if (!old_valid_dev(device_number))
		return -EINVAL;

	xid = GetXid();

	cifs_sb = CIFS_SB(inode->i_sb);
	pTcon = cifs_sb->tcon;

	full_path = build_path_from_dentry(direntry);
	if (full_path == NULL)
		rc = -ENOMEM;
	else if (pTcon->unix_ext) {
		struct cifs_unix_set_info_args args = {
			.mode	= mode & ~current_umask(),
			.ctime	= NO_CHANGE_64,
			.atime	= NO_CHANGE_64,
			.mtime	= NO_CHANGE_64,
			.device	= device_number,
		};
		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
			args.uid = (__u64) current_fsuid();
			args.gid = (__u64) current_fsgid();
		} else {
			args.uid = NO_CHANGE_64;
			args.gid = NO_CHANGE_64;
		}
		rc = CIFSSMBUnixSetInfo(xid, pTcon, full_path,
			&args, cifs_sb->local_nls,
			cifs_sb->mnt_cifs_flags &
				CIFS_MOUNT_MAP_SPECIAL_CHR);

		if (!rc) {
			rc = cifs_get_inode_info_unix(&newinode, full_path,
						inode->i_sb, xid);
			if (pTcon->nocase)
				direntry->d_op = &cifs_ci_dentry_ops;
			else
				direntry->d_op = &cifs_dentry_ops;
			if (rc == 0)
				d_instantiate(direntry, newinode);
		}
	} else {
		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
			int oplock = 0;
			u16 fileHandle;
			FILE_ALL_INFO *buf;

			cFYI(1, ("sfu compat create special file"));

			buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
			if (buf == NULL) {
				kfree(full_path);
				FreeXid(xid);
				return -ENOMEM;
			}

			rc = CIFSSMBOpen(xid, pTcon, full_path,
					 FILE_CREATE, /* fail if exists */
					 GENERIC_WRITE /* BB would
					  WRITE_OWNER | WRITE_DAC be better? */,
					 /* Create a file and set the
					    file attribute to SYSTEM */
					 CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
					 &fileHandle, &oplock, buf,
					 cifs_sb->local_nls,
					 cifs_sb->mnt_cifs_flags &
					    CIFS_MOUNT_MAP_SPECIAL_CHR);

			/* BB FIXME - add handling for backlevel servers
			   which need legacy open and check for all
			   calls to SMBOpen for fallback to SMBLeagcyOpen */
			if (!rc) {
				/* BB Do not bother to decode buf since no
				   local inode yet to put timestamps in,
				   but we can reuse it safely */
				unsigned int bytes_written;
				struct win_dev *pdev;
				pdev = (struct win_dev *)buf;
				if (S_ISCHR(mode)) {
					memcpy(pdev->type, "IntxCHR", 8);
					pdev->major =
					      cpu_to_le64(MAJOR(device_number));
					pdev->minor =
					      cpu_to_le64(MINOR(device_number));
					rc = CIFSSMBWrite(xid, pTcon,
						fileHandle,
						sizeof(struct win_dev),
						0, &bytes_written, (char *)pdev,
						NULL, 0);
				} else if (S_ISBLK(mode)) {
					memcpy(pdev->type, "IntxBLK", 8);
					pdev->major =
					      cpu_to_le64(MAJOR(device_number));
					pdev->minor =
					      cpu_to_le64(MINOR(device_number));
					rc = CIFSSMBWrite(xid, pTcon,
						fileHandle,
						sizeof(struct win_dev),
						0, &bytes_written, (char *)pdev,
						NULL, 0);
				} /* else if(S_ISFIFO */
				CIFSSMBClose(xid, pTcon, fileHandle);
				d_drop(direntry);
			}
			kfree(buf);
			/* add code here to set EAs */
		}
	}

	kfree(full_path);
	FreeXid(xid);
	return rc;
}

struct dentry *
cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
	    struct nameidata *nd)
{
	int xid;
	int rc = 0; /* to get around spurious gcc warning, set to zero here */
	int oplock = 0;
	__u16 fileHandle = 0;
	bool posix_open = false;
	struct cifs_sb_info *cifs_sb;
	struct cifsTconInfo *pTcon;
	struct inode *newInode = NULL;
	char *full_path = NULL;
	struct file *filp;

	xid = GetXid();

	cFYI(1, ("parent inode = 0x%p name is: %s and dentry = 0x%p",
	      parent_dir_inode, direntry->d_name.name, direntry));

	/* check whether path exists */

	cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
	pTcon = cifs_sb->tcon;

	/*
	 * Don't allow the separator character in a path component.
	 * The VFS will not allow "/", but "\" is allowed by posix.
	 */
	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
		int i;
		for (i = 0; i < direntry->d_name.len; i++)
			if (direntry->d_name.name[i] == '\\') {
				cFYI(1, ("Invalid file name"));
				FreeXid(xid);
				return ERR_PTR(-EINVAL);
			}
	}

	/* can not grab the rename sem here since it would
	deadlock in the cases (beginning of sys_rename itself)
	in which we already have the sb rename sem */
	full_path = build_path_from_dentry(direntry);
	if (full_path == NULL) {
		FreeXid(xid);
		return ERR_PTR(-ENOMEM);
	}

	if (direntry->d_inode != NULL) {
		cFYI(1, ("non-NULL inode in lookup"));
	} else {
		cFYI(1, ("NULL inode in lookup"));
	}
	cFYI(1, ("Full path: %s inode = 0x%p", full_path, direntry->d_inode));

	/* Posix open is only called (at lookup time) for file create now.
	 * For opens (rather than creates), because we do not know if it
	 * is a file or directory yet, and current Samba no longer allows
	 * us to do posix open on dirs, we could end up wasting an open call
	 * on what turns out to be a dir. For file opens, we wait to call posix
	 * open till cifs_open.  It could be added here (lookup) in the future
	 * but the performance tradeoff of the extra network request when EISDIR
	 * or EACCES is returned would have to be weighed against the 50%
	 * reduction in network traffic in the other paths.
	 */
	if (pTcon->unix_ext) {
		if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) &&
		     (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
		     (nd->intent.open.flags & O_CREAT)) {
			rc = cifs_posix_open(full_path, &newInode,
					parent_dir_inode->i_sb,
					nd->intent.open.create_mode,
					nd->intent.open.flags, &oplock,
					&fileHandle, xid);
			/*
			 * The check below works around a bug in POSIX
			 * open in samba versions 3.3.1 and earlier where
			 * open could incorrectly fail with invalid parameter.
			 * If either that or op not supported returned, follow
			 * the normal lookup.
			 */
			if ((rc == 0) || (rc == -ENOENT))
				posix_open = true;
			else if ((rc == -EINVAL) || (rc != -EOPNOTSUPP))
				pTcon->broken_posix_open = true;
		}
		if (!posix_open)
			rc = cifs_get_inode_info_unix(&newInode, full_path,
						parent_dir_inode->i_sb, xid);
	} else
		rc = cifs_get_inode_info(&newInode, full_path, NULL,
				parent_dir_inode->i_sb, xid, NULL);

	if ((rc == 0) && (newInode != NULL)) {
		if (pTcon->nocase)
			direntry->d_op = &cifs_ci_dentry_ops;
		else
			direntry->d_op = &cifs_dentry_ops;
		d_add(direntry, newInode);
		if (posix_open)
			filp = lookup_instantiate_filp(nd, direntry, NULL);
		/* since paths are not looked up by component - the parent
		   directories are presumed to be good here */
		renew_parental_timestamps(direntry);

	} else if (rc == -ENOENT) {
		rc = 0;
		direntry->d_time = jiffies;
		if (pTcon->nocase)
			direntry->d_op = &cifs_ci_dentry_ops;
		else
			direntry->d_op = &cifs_dentry_ops;
		d_add(direntry, NULL);
	/*	if it was once a directory (but how can we tell?) we could do
		shrink_dcache_parent(direntry); */
	} else if (rc != -EACCES) {
		cERROR(1, ("Unexpected lookup error %d", rc));
		/* We special case check for Access Denied - since that
		is a common return code */
	}

	kfree(full_path);
	FreeXid(xid);
	return ERR_PTR(rc);
}

static int
cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
{
	int isValid = 1;

	if (direntry->d_inode) {
		if (cifs_revalidate(direntry))
			return 0;
	} else {
		cFYI(1, ("neg dentry 0x%p name = %s",
			 direntry, direntry->d_name.name));
		if (time_after(jiffies, direntry->d_time + HZ) ||
			!lookupCacheEnabled) {
			d_drop(direntry);
			isValid = 0;
		}
	}

	return isValid;
}

/* static int cifs_d_delete(struct dentry *direntry)
{
	int rc = 0;

	cFYI(1, ("In cifs d_delete, name = %s", direntry->d_name.name));

	return rc;
}     */

const struct dentry_operations cifs_dentry_ops = {
	.d_revalidate = cifs_d_revalidate,
/* d_delete:       cifs_d_delete,      */ /* not needed except for debugging */
};

static int cifs_ci_hash(struct dentry *dentry, struct qstr *q)
{
	struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls;
	unsigned long hash;
	int i;

	hash = init_name_hash();
	for (i = 0; i < q->len; i++)
		hash = partial_name_hash(nls_tolower(codepage, q->name[i]),
					 hash);
	q->hash = end_name_hash(hash);

	return 0;
}

static int cifs_ci_compare(struct dentry *dentry, struct qstr *a,
			   struct qstr *b)
{
	struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls;

	if ((a->len == b->len) &&
	    (nls_strnicmp(codepage, a->name, b->name, a->len) == 0)) {
		/*
		 * To preserve case, don't let an existing negative dentry's
		 * case take precedence.  If a is not a negative dentry, this
		 * should have no side effects
		 */
		memcpy((void *)a->name, b->name, a->len);
		return 0;
	}
	return 1;
}

const struct dentry_operations cifs_ci_dentry_ops = {
	.d_revalidate = cifs_d_revalidate,
	.d_hash = cifs_ci_hash,
	.d_compare = cifs_ci_compare,
};
