/*
 *   fs/cifs/fcntl.c
 *
 *   vfs operations that deal with the file control API
 *
 *   Copyright (C) International Business Machines  Corp., 2003,2004
 *   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/fcntl.h>
#include "cifsglob.h"
#include "cifsproto.h"
#include "cifs_unicode.h"
#include "cifs_debug.h"
#include "cifsfs.h"

static __u32 convert_to_cifs_notify_flags(unsigned long fcntl_notify_flags)
{
	__u32 cifs_ntfy_flags = 0;

	/* No way on Linux VFS to ask to monitor xattr
	changes (and no stream support either */
	if (fcntl_notify_flags & DN_ACCESS) {
		cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
	}
	if (fcntl_notify_flags & DN_MODIFY) {
		/* What does this mean on directories? */
		cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE |
			FILE_NOTIFY_CHANGE_SIZE;
	}
	if (fcntl_notify_flags & DN_CREATE) {
		cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_CREATION |
			FILE_NOTIFY_CHANGE_LAST_WRITE;
	}
	if (fcntl_notify_flags & DN_DELETE) {
		cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE;
	}
	if (fcntl_notify_flags & DN_RENAME) {
		/* BB review this - checking various server behaviors */
		cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_DIR_NAME |
			FILE_NOTIFY_CHANGE_FILE_NAME;
	}
	if (fcntl_notify_flags & DN_ATTRIB) {
		cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_SECURITY |
			FILE_NOTIFY_CHANGE_ATTRIBUTES;
	}
/*	if (fcntl_notify_flags & DN_MULTISHOT) {
		cifs_ntfy_flags |= ;
	} */ /* BB fixme - not sure how to handle this with CIFS yet */

	return cifs_ntfy_flags;
}

int cifs_dir_notify(struct file * file, unsigned long arg)
{
	int xid;
	int rc = -EINVAL;
	int oplock = FALSE;
	struct cifs_sb_info *cifs_sb;
	struct cifsTconInfo *pTcon;
	char *full_path = NULL;
	__u32 filter = FILE_NOTIFY_CHANGE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES;
	__u16 netfid;

	if (experimEnabled == 0)
		return 0;

	xid = GetXid();
	cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
	pTcon = cifs_sb->tcon;

	full_path = build_path_from_dentry(file->f_path.dentry);

	if (full_path == NULL) {
		rc = -ENOMEM;
	} else {
		cFYI(1, ("dir notify on file %s Arg 0x%lx", full_path, arg));
		rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN,
			GENERIC_READ | SYNCHRONIZE, 0 /* create options */,
			&netfid, &oplock, NULL, cifs_sb->local_nls,
			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
		/* BB fixme - add this handle to a notify handle list */
		if (rc) {
			cFYI(1, ("Could not open directory for notify"));
		} else {
			filter = convert_to_cifs_notify_flags(arg);
			if (filter != 0) {
				rc = CIFSSMBNotify(xid, pTcon,
					0 /* no subdirs */, netfid,
					filter, file, arg & DN_MULTISHOT,
					cifs_sb->local_nls);
			} else {
				rc = -EINVAL;
			}
			/* BB add code to close file eventually (at unmount
			it would close automatically but may be a way
			to do it easily when inode freed or when
			notify info is cleared/changed */
			cFYI(1, ("notify rc %d", rc));
		}
	}

	FreeXid(xid);
	return rc;
}
