/*
 *  proc.c
 *
 *  Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
 *  Copyright (C) 1997 by Volker Lendecke
 *
 *  Please add a note about your changes to smbfs in the ChangeLog file.
 */

#include <linux/types.h>
#include <linux/capability.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/dcache.h>
#include <linux/nls.h>
#include <linux/smp_lock.h>
#include <linux/net.h>
#include <linux/vfs.h>
#include <net/sock.h>

#include <asm/string.h>
#include <asm/div64.h>

#include "smb_fs.h"
#include "smbno.h"
#include "smb_mount.h"
#include "smb_debug.h"
#include "proto.h"
#include "request.h"


/* Features. Undefine if they cause problems, this should perhaps be a
   config option. */
#define SMBFS_POSIX_UNLINK 1

/* Allow smb_retry to be interrupted. */
#define SMB_RETRY_INTR

#define SMB_VWV(packet)  ((packet) + SMB_HEADER_LEN)
#define SMB_CMD(packet)  (*(packet+8))
#define SMB_WCT(packet)  (*(packet+SMB_HEADER_LEN - 1))

#define SMB_DIRINFO_SIZE 43
#define SMB_STATUS_SIZE  21

#define SMB_ST_BLKSIZE	(PAGE_SIZE)
#define SMB_ST_BLKSHIFT	(PAGE_SHIFT)

static struct smb_ops smb_ops_core;
static struct smb_ops smb_ops_os2;
static struct smb_ops smb_ops_win95;
static struct smb_ops smb_ops_winNT;
static struct smb_ops smb_ops_unix;
static struct smb_ops smb_ops_null;

static void
smb_init_dirent(struct smb_sb_info *server, struct smb_fattr *fattr);
static void
smb_finish_dirent(struct smb_sb_info *server, struct smb_fattr *fattr);
static int
smb_proc_getattr_core(struct smb_sb_info *server, struct dentry *dir,
		      struct smb_fattr *fattr);
static int
smb_proc_getattr_ff(struct smb_sb_info *server, struct dentry *dentry,
		    struct smb_fattr *fattr);
static int
smb_proc_setattr_core(struct smb_sb_info *server, struct dentry *dentry,
		      u16 attr);
static int
smb_proc_setattr_ext(struct smb_sb_info *server,
		     struct inode *inode, struct smb_fattr *fattr);
static int
smb_proc_query_cifsunix(struct smb_sb_info *server);
static void
install_ops(struct smb_ops *dst, struct smb_ops *src);


static void
str_upper(char *name, int len)
{
	while (len--)
	{
		if (*name >= 'a' && *name <= 'z')
			*name -= ('a' - 'A');
		name++;
	}
}

#if 0
static void
str_lower(char *name, int len)
{
	while (len--)
	{
		if (*name >= 'A' && *name <= 'Z')
			*name += ('a' - 'A');
		name++;
	}
}
#endif

/* reverse a string inline. This is used by the dircache walking routines */
static void reverse_string(char *buf, int len)
{
	char c;
	char *end = buf+len-1;

	while(buf < end) {
		c = *buf;
		*(buf++) = *end;
		*(end--) = c;
	}
}

/* no conversion, just a wrapper for memcpy. */
static int convert_memcpy(unsigned char *output, int olen,
			  const unsigned char *input, int ilen,
			  struct nls_table *nls_from,
			  struct nls_table *nls_to)
{
	if (olen < ilen)
		return -ENAMETOOLONG;
	memcpy(output, input, ilen);
	return ilen;
}

static inline int write_char(unsigned char ch, char *output, int olen)
{
	if (olen < 4)
		return -ENAMETOOLONG;
	sprintf(output, ":x%02x", ch);
	return 4;
}

static inline int write_unichar(wchar_t ch, char *output, int olen)
{
	if (olen < 5)
		return -ENAMETOOLONG;
	sprintf(output, ":%04x", ch);
	return 5;
}

/* convert from one "codepage" to another (possibly being utf8). */
static int convert_cp(unsigned char *output, int olen,
		      const unsigned char *input, int ilen,
		      struct nls_table *nls_from,
		      struct nls_table *nls_to)
{
	int len = 0;
	int n;
	wchar_t ch;

	while (ilen > 0) {
		/* convert by changing to unicode and back to the new cp */
		n = nls_from->char2uni(input, ilen, &ch);
		if (n == -EINVAL) {
			ilen--;
			n = write_char(*input++, output, olen);
			if (n < 0)
				goto fail;
			output += n;
			olen -= n;
			len += n;
			continue;
		} else if (n < 0)
			goto fail;
		input += n;
		ilen -= n;

		n = nls_to->uni2char(ch, output, olen);
		if (n == -EINVAL)
			n = write_unichar(ch, output, olen);
		if (n < 0)
			goto fail;
		output += n;
		olen -= n;

		len += n;
	}
	return len;
fail:
	return n;
}

/* ----------------------------------------------------------- */

/*
 * nls_unicode
 *
 * This encodes/decodes little endian unicode format
 */

static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
	if (boundlen < 2)
		return -EINVAL;
	*out++ = uni & 0xff;
	*out++ = uni >> 8;
	return 2;
}

static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
{
	if (boundlen < 2)
		return -EINVAL;
	*uni = (rawstring[1] << 8) | rawstring[0];
	return 2;
}

static struct nls_table unicode_table = {
	.charset	= "unicode",
	.uni2char	= uni2char,
	.char2uni	= char2uni,
};

/* ----------------------------------------------------------- */

static int setcodepage(struct nls_table **p, char *name)
{
	struct nls_table *nls;

	if (!name || !*name) {
		nls = NULL;
	} else if ( (nls = load_nls(name)) == NULL) {
		printk (KERN_ERR "smbfs: failed to load nls '%s'\n", name);
		return -EINVAL;
	}

	/* if already set, unload the previous one. */
	if (*p && *p != &unicode_table)
		unload_nls(*p);
	*p = nls;

	return 0;
}

/* Handles all changes to codepage settings. */
int smb_setcodepage(struct smb_sb_info *server, struct smb_nls_codepage *cp)
{
	int n = 0;

	smb_lock_server(server);

	/* Don't load any nls_* at all, if no remote is requested */
	if (!*cp->remote_name)
		goto out;

	/* local */
	n = setcodepage(&server->local_nls, cp->local_name);
	if (n != 0)
		goto out;

	/* remote */
	if (!strcmp(cp->remote_name, "unicode")) {
		server->remote_nls = &unicode_table;
	} else {
		n = setcodepage(&server->remote_nls, cp->remote_name);
		if (n != 0)
			setcodepage(&server->local_nls, NULL);
	}

out:
	if (server->local_nls != NULL && server->remote_nls != NULL)
		server->ops->convert = convert_cp;
	else
		server->ops->convert = convert_memcpy;

	smb_unlock_server(server);
	return n;
}


/*****************************************************************************/
/*                                                                           */
/*  Encoding/Decoding section                                                */
/*                                                                           */
/*****************************************************************************/

static __u8 *
smb_encode_smb_length(__u8 * p, __u32 len)
{
	*p = 0;
	*(p+1) = 0;
	*(p+2) = (len & 0xFF00) >> 8;
	*(p+3) = (len & 0xFF);
	if (len > 0xFFFF)
	{
		*(p+1) = 1;
	}
	return p + 4;
}

/*
 * smb_build_path: build the path to entry and name storing it in buf.
 * The path returned will have the trailing '\0'.
 */
static int smb_build_path(struct smb_sb_info *server, unsigned char *buf,
			  int maxlen,
			  struct dentry *entry, struct qstr *name)
{
	unsigned char *path = buf;
	int len;
	int unicode = (server->mnt->flags & SMB_MOUNT_UNICODE) != 0;

	if (maxlen < (2<<unicode))
		return -ENAMETOOLONG;

	if (maxlen > SMB_MAXPATHLEN + 1)
		maxlen = SMB_MAXPATHLEN + 1;

	if (entry == NULL)
		goto test_name_and_out;

	/*
	 * If IS_ROOT, we have to do no walking at all.
	 */
	if (IS_ROOT(entry) && !name) {
		*path++ = '\\';
		if (unicode) *path++ = '\0';
		*path++ = '\0';
		if (unicode) *path++ = '\0';
		return path-buf;
	}

	/*
	 * Build the path string walking the tree backward from end to ROOT
	 * and store it in reversed order [see reverse_string()]
	 */
	dget(entry);
	while (!IS_ROOT(entry)) {
		struct dentry *parent;

		if (maxlen < (3<<unicode)) {
			dput(entry);
			return -ENAMETOOLONG;
		}

		spin_lock(&entry->d_lock);
		len = server->ops->convert(path, maxlen-2, 
				      entry->d_name.name, entry->d_name.len,
				      server->local_nls, server->remote_nls);
		if (len < 0) {
			spin_unlock(&entry->d_lock);
			dput(entry);
			return len;
		}
		reverse_string(path, len);
		path += len;
		if (unicode) {
			/* Note: reverse order */
			*path++ = '\0';
			maxlen--;
		}
		*path++ = '\\';
		maxlen -= len+1;
		spin_unlock(&entry->d_lock);

		parent = dget_parent(entry);
		dput(entry);
		entry = parent;
	}
	dput(entry);
	reverse_string(buf, path-buf);

	/* maxlen has space for at least one char */
test_name_and_out:
	if (name) {
		if (maxlen < (3<<unicode))
			return -ENAMETOOLONG;
		*path++ = '\\';
		if (unicode) {
			*path++ = '\0';
			maxlen--;
		}
		len = server->ops->convert(path, maxlen-2, 
				      name->name, name->len,
				      server->local_nls, server->remote_nls);
		if (len < 0)
			return len;
		path += len;
		maxlen -= len+1;
	}
	/* maxlen has space for at least one char */
	*path++ = '\0';
	if (unicode) *path++ = '\0';
	return path-buf;
}

static int smb_encode_path(struct smb_sb_info *server, char *buf, int maxlen,
			   struct dentry *dir, struct qstr *name)
{
	int result;

	result = smb_build_path(server, buf, maxlen, dir, name);
	if (result < 0)
		goto out;
	if (server->opt.protocol <= SMB_PROTOCOL_COREPLUS)
		str_upper(buf, result);
out:
	return result;
}

/* encode_path for non-trans2 request SMBs */
static int smb_simple_encode_path(struct smb_request *req, char **p,
				  struct dentry * entry, struct qstr * name)
{
	struct smb_sb_info *server = req->rq_server;
	char *s = *p;
	int res;
	int maxlen = ((char *)req->rq_buffer + req->rq_bufsize) - s;
	int unicode = (server->mnt->flags & SMB_MOUNT_UNICODE);

	if (!maxlen)
		return -ENAMETOOLONG;
	*s++ = 4;	/* ASCII data format */

	/*
	 * SMB Unicode strings must be 16bit aligned relative the start of the
	 * packet. If they are not they must be padded with 0.
	 */
	if (unicode) {
		int align = s - (char *)req->rq_buffer;
		if (!(align & 1)) {
			*s++ = '\0';
			maxlen--;
		}
	}

	res = smb_encode_path(server, s, maxlen-1, entry, name);
	if (res < 0)
		return res;
	*p = s + res;
	return 0;
}

/* The following are taken directly from msdos-fs */

/* Linear day numbers of the respective 1sts in non-leap years. */

static int day_n[] =
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0};
		  /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */


static time_t
utc2local(struct smb_sb_info *server, time_t time)
{
	return time - server->opt.serverzone*60;
}

static time_t
local2utc(struct smb_sb_info *server, time_t time)
{
	return time + server->opt.serverzone*60;
}

/* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */

static time_t
date_dos2unix(struct smb_sb_info *server, __u16 date, __u16 time)
{
	int month, year;
	time_t secs;

	/* first subtract and mask after that... Otherwise, if
	   date == 0, bad things happen */
	month = ((date >> 5) - 1) & 15;
	year = date >> 9;
	secs = (time & 31) * 2 + 60 * ((time >> 5) & 63) + (time >> 11) * 3600 + 86400 *
	    ((date & 31) - 1 + day_n[month] + (year / 4) + year * 365 - ((year & 3) == 0 &&
						   month < 2 ? 1 : 0) + 3653);
	/* days since 1.1.70 plus 80's leap day */
	return local2utc(server, secs);
}


/* Convert linear UNIX date to a MS-DOS time/date pair. */

static void
date_unix2dos(struct smb_sb_info *server,
	      int unix_date, __u16 *date, __u16 *time)
{
	int day, year, nl_day, month;

	unix_date = utc2local(server, unix_date);
	if (unix_date < 315532800)
		unix_date = 315532800;

	*time = (unix_date % 60) / 2 +
		(((unix_date / 60) % 60) << 5) +
		(((unix_date / 3600) % 24) << 11);

	day = unix_date / 86400 - 3652;
	year = day / 365;
	if ((year + 3) / 4 + 365 * year > day)
		year--;
	day -= (year + 3) / 4 + 365 * year;
	if (day == 59 && !(year & 3)) {
		nl_day = day;
		month = 2;
	} else {
		nl_day = (year & 3) || day <= 59 ? day : day - 1;
		for (month = 1; month < 12; month++)
			if (day_n[month] > nl_day)
				break;
	}
	*date = nl_day - day_n[month - 1] + 1 + (month << 5) + (year << 9);
}

/* The following are taken from fs/ntfs/util.c */

#define NTFS_TIME_OFFSET ((u64)(369*365 + 89) * 24 * 3600 * 10000000)

/*
 * Convert the NT UTC (based 1601-01-01, in hundred nanosecond units)
 * into Unix UTC (based 1970-01-01, in seconds).
 */
static struct timespec
smb_ntutc2unixutc(u64 ntutc)
{
	struct timespec ts;
	/* FIXME: what about the timezone difference? */
	/* Subtract the NTFS time offset, then convert to 1s intervals. */
	u64 t = ntutc - NTFS_TIME_OFFSET;
	ts.tv_nsec = do_div(t, 10000000) * 100;
	ts.tv_sec = t; 
	return ts;
}

/* Convert the Unix UTC into NT time */
static u64
smb_unixutc2ntutc(struct timespec ts)
{
	/* Note: timezone conversion is probably wrong. */
	/* return ((u64)utc2local(server, t)) * 10000000 + NTFS_TIME_OFFSET; */
	return ((u64)ts.tv_sec) * 10000000 + ts.tv_nsec/100 + NTFS_TIME_OFFSET;
}

#define MAX_FILE_MODE	6
static mode_t file_mode[] = {
	S_IFREG, S_IFDIR, S_IFLNK, S_IFCHR, S_IFBLK, S_IFIFO, S_IFSOCK
};

static int smb_filetype_to_mode(u32 filetype)
{
	if (filetype > MAX_FILE_MODE) {
		PARANOIA("Filetype out of range: %d\n", filetype);
		return S_IFREG;
	}
	return file_mode[filetype];
}

static u32 smb_filetype_from_mode(int mode)
{
	if (S_ISREG(mode))
		return UNIX_TYPE_FILE;
	if (S_ISDIR(mode))
		return UNIX_TYPE_DIR;
	if (S_ISLNK(mode))
		return UNIX_TYPE_SYMLINK;
	if (S_ISCHR(mode))
		return UNIX_TYPE_CHARDEV;
	if (S_ISBLK(mode))
		return UNIX_TYPE_BLKDEV;
	if (S_ISFIFO(mode))
		return UNIX_TYPE_FIFO;
	if (S_ISSOCK(mode))
		return UNIX_TYPE_SOCKET;
	return UNIX_TYPE_UNKNOWN;
}


/*****************************************************************************/
/*                                                                           */
/*  Support section.                                                         */
/*                                                                           */
/*****************************************************************************/

__u32
smb_len(__u8 * p)
{
	return ((*(p+1) & 0x1) << 16L) | (*(p+2) << 8L) | *(p+3);
}

static __u16
smb_bcc(__u8 * packet)
{
	int pos = SMB_HEADER_LEN + SMB_WCT(packet) * sizeof(__u16);
	return WVAL(packet, pos);
}

/* smb_valid_packet: We check if packet fulfills the basic
   requirements of a smb packet */

static int
smb_valid_packet(__u8 * packet)
{
	return (packet[4] == 0xff
		&& packet[5] == 'S'
		&& packet[6] == 'M'
		&& packet[7] == 'B'
		&& (smb_len(packet) + 4 == SMB_HEADER_LEN
		    + SMB_WCT(packet) * 2 + smb_bcc(packet)));
}

/* smb_verify: We check if we got the answer we expected, and if we
   got enough data. If bcc == -1, we don't care. */

static int
smb_verify(__u8 * packet, int command, int wct, int bcc)
{
	if (SMB_CMD(packet) != command)
		goto bad_command;
	if (SMB_WCT(packet) < wct)
		goto bad_wct;
	if (bcc != -1 && smb_bcc(packet) < bcc)
		goto bad_bcc;
	return 0;

bad_command:
	printk(KERN_ERR "smb_verify: command=%x, SMB_CMD=%x??\n",
	       command, SMB_CMD(packet));
	goto fail;
bad_wct:
	printk(KERN_ERR "smb_verify: command=%x, wct=%d, SMB_WCT=%d??\n",
	       command, wct, SMB_WCT(packet));
	goto fail;
bad_bcc:
	printk(KERN_ERR "smb_verify: command=%x, bcc=%d, SMB_BCC=%d??\n",
	       command, bcc, smb_bcc(packet));
fail:
	return -EIO;
}

/*
 * Returns the maximum read or write size for the "payload". Making all of the
 * packet fit within the negotiated max_xmit size.
 *
 * N.B. Since this value is usually computed before locking the server,
 * the server's packet size must never be decreased!
 */
static inline int
smb_get_xmitsize(struct smb_sb_info *server, int overhead)
{
	return server->opt.max_xmit - overhead;
}

/*
 * Calculate the maximum read size
 */
int
smb_get_rsize(struct smb_sb_info *server)
{
	/* readX has 12 parameters, read has 5 */
	int overhead = SMB_HEADER_LEN + 12 * sizeof(__u16) + 2 + 1 + 2;
	int size = smb_get_xmitsize(server, overhead);

	VERBOSE("xmit=%d, size=%d\n", server->opt.max_xmit, size);

	return size;
}

/*
 * Calculate the maximum write size
 */
int
smb_get_wsize(struct smb_sb_info *server)
{
	/* writeX has 14 parameters, write has 5 */
	int overhead = SMB_HEADER_LEN + 14 * sizeof(__u16) + 2 + 1 + 2;
	int size = smb_get_xmitsize(server, overhead);

	VERBOSE("xmit=%d, size=%d\n", server->opt.max_xmit, size);

	return size;
}

/*
 * Convert SMB error codes to -E... errno values.
 */
int
smb_errno(struct smb_request *req)
{
	int errcls = req->rq_rcls;
	int error  = req->rq_err;
	char *class = "Unknown";

	VERBOSE("errcls %d  code %d  from command 0x%x\n",
		errcls, error, SMB_CMD(req->rq_header));

	if (errcls == ERRDOS) {
		switch (error) {
		case ERRbadfunc:
			return -EINVAL;
		case ERRbadfile:
		case ERRbadpath:
			return -ENOENT;
		case ERRnofids:
			return -EMFILE;
		case ERRnoaccess:
			return -EACCES;
		case ERRbadfid:
			return -EBADF;
		case ERRbadmcb:
			return -EREMOTEIO;
		case ERRnomem:
			return -ENOMEM;
		case ERRbadmem:
			return -EFAULT;
		case ERRbadenv:
		case ERRbadformat:
			return -EREMOTEIO;
		case ERRbadaccess:
			return -EACCES;
		case ERRbaddata:
			return -E2BIG;
		case ERRbaddrive:
			return -ENXIO;
		case ERRremcd:
			return -EREMOTEIO;
		case ERRdiffdevice:
			return -EXDEV;
		case ERRnofiles:
			return -ENOENT;
		case ERRbadshare:
			return -ETXTBSY;
		case ERRlock:
			return -EDEADLK;
		case ERRfilexists:
			return -EEXIST;
		case ERROR_INVALID_PARAMETER:
			return -EINVAL;
		case ERROR_DISK_FULL:
			return -ENOSPC;
		case ERROR_INVALID_NAME:
			return -ENOENT;
		case ERROR_DIR_NOT_EMPTY:
			return -ENOTEMPTY;
		case ERROR_NOT_LOCKED:
                       return -ENOLCK;
		case ERROR_ALREADY_EXISTS:
			return -EEXIST;
		default:
			class = "ERRDOS";
			goto err_unknown;
		}
	} else if (errcls == ERRSRV) {
		switch (error) {
		/* N.B. This is wrong ... EIO ? */
		case ERRerror:
			return -ENFILE;
		case ERRbadpw:
			return -EINVAL;
		case ERRbadtype:
		case ERRtimeout:
			return -EIO;
		case ERRaccess:
			return -EACCES;
		/*
		 * This is a fatal error, as it means the "tree ID"
		 * for this connection is no longer valid. We map
		 * to a special error code and get a new connection.
		 */
		case ERRinvnid:
			return -EBADSLT;
		default:
			class = "ERRSRV";
			goto err_unknown;
		}
	} else if (errcls == ERRHRD) {
		switch (error) {
		case ERRnowrite:
			return -EROFS;
		case ERRbadunit:
			return -ENODEV;
		case ERRnotready:
			return -EUCLEAN;
		case ERRbadcmd:
		case ERRdata:
			return -EIO;
		case ERRbadreq:
			return -ERANGE;
		case ERRbadshare:
			return -ETXTBSY;
		case ERRlock:
			return -EDEADLK;
		case ERRdiskfull:
			return -ENOSPC;
		default:
			class = "ERRHRD";
			goto err_unknown;
		}
	} else if (errcls == ERRCMD) {
		class = "ERRCMD";
	} else if (errcls == SUCCESS) {
		return 0;	/* This is the only valid 0 return */
	}

err_unknown:
	printk(KERN_ERR "smb_errno: class %s, code %d from command 0x%x\n",
	       class, error, SMB_CMD(req->rq_header));
	return -EIO;
}

/* smb_request_ok: We expect the server to be locked. Then we do the
   request and check the answer completely. When smb_request_ok
   returns 0, you can be quite sure that everything went well. When
   the answer is <=0, the returned number is a valid unix errno. */

static int
smb_request_ok(struct smb_request *req, int command, int wct, int bcc)
{
	int result;

	req->rq_resp_wct = wct;
	req->rq_resp_bcc = bcc;

	result = smb_add_request(req);
	if (result != 0) {
		DEBUG1("smb_request failed\n");
		goto out;
	}

	if (smb_valid_packet(req->rq_header) != 0) {
		PARANOIA("invalid packet!\n");
		goto out;
	}

	result = smb_verify(req->rq_header, command, wct, bcc);

out:
	return result;
}

/*
 * This implements the NEWCONN ioctl. It installs the server pid,
 * sets server->state to CONN_VALID, and wakes up the waiting process.
 */
int
smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt)
{
	struct file *filp;
	struct sock *sk;
	int error;

	VERBOSE("fd=%d, pid=%d\n", opt->fd, current->pid);

	smb_lock_server(server);

	/*
	 * Make sure we don't already have a valid connection ...
	 */
	error = -EINVAL;
	if (server->state == CONN_VALID)
		goto out;

	error = -EACCES;
	if (current_uid() != server->mnt->mounted_uid &&
	    !capable(CAP_SYS_ADMIN))
		goto out;

	error = -EBADF;
	filp = fget(opt->fd);
	if (!filp)
		goto out;
	if (!smb_valid_socket(filp->f_path.dentry->d_inode))
		goto out_putf;

	server->sock_file = filp;
	server->conn_pid = get_pid(task_pid(current));
	server->opt = *opt;
	server->generation += 1;
	server->state = CONN_VALID;
	error = 0;

	if (server->conn_error) {
		/*
		 * conn_error is the returncode we originally decided to
		 * drop the old connection on. This message should be positive
		 * and not make people ask questions on why smbfs is printing
		 * error messages ...
		 */
		printk(KERN_INFO "SMB connection re-established (%d)\n",
		       server->conn_error);
		server->conn_error = 0;
	}

	/*
	 * Store the server in sock user_data (Only used by sunrpc)
	 */
	sk = SOCKET_I(filp->f_path.dentry->d_inode)->sk;
	sk->sk_user_data = server;

	/* chain into the data_ready callback */
	server->data_ready = xchg(&sk->sk_data_ready, smb_data_ready);

	/* check if we have an old smbmount that uses seconds for the 
	   serverzone */
	if (server->opt.serverzone > 12*60 || server->opt.serverzone < -12*60)
		server->opt.serverzone /= 60;

	/* now that we have an established connection we can detect the server
	   type and enable bug workarounds */
	if (server->opt.protocol < SMB_PROTOCOL_LANMAN2)
		install_ops(server->ops, &smb_ops_core);
	else if (server->opt.protocol == SMB_PROTOCOL_LANMAN2)
		install_ops(server->ops, &smb_ops_os2);
	else if (server->opt.protocol == SMB_PROTOCOL_NT1 &&
		 (server->opt.max_xmit < 0x1000) &&
		 !(server->opt.capabilities & SMB_CAP_NT_SMBS)) {
		/* FIXME: can we kill the WIN95 flag now? */
		server->mnt->flags |= SMB_MOUNT_WIN95;
		VERBOSE("detected WIN95 server\n");
		install_ops(server->ops, &smb_ops_win95);
	} else {
		/*
		 * Samba has max_xmit 65535
		 * NT4spX has max_xmit 4536 (or something like that)
		 * win2k has ...
		 */
		VERBOSE("detected NT1 (Samba, NT4/5) server\n");
		install_ops(server->ops, &smb_ops_winNT);
	}

	/* FIXME: the win9x code wants to modify these ... (seek/trunc bug) */
	if (server->mnt->flags & SMB_MOUNT_OLDATTR) {
		server->ops->getattr = smb_proc_getattr_core;
	} else if (server->mnt->flags & SMB_MOUNT_DIRATTR) {
		server->ops->getattr = smb_proc_getattr_ff;
	}

	/* Decode server capabilities */
	if (server->opt.capabilities & SMB_CAP_LARGE_FILES) {
		/* Should be ok to set this now, as no one can access the
		   mount until the connection has been established. */
		SB_of(server)->s_maxbytes = ~0ULL >> 1;
		VERBOSE("LFS enabled\n");
	}
	if (server->opt.capabilities & SMB_CAP_UNICODE) {
		server->mnt->flags |= SMB_MOUNT_UNICODE;
		VERBOSE("Unicode enabled\n");
	} else {
		server->mnt->flags &= ~SMB_MOUNT_UNICODE;
	}
#if 0
	/* flags we may test for other patches ... */
	if (server->opt.capabilities & SMB_CAP_LARGE_READX) {
		VERBOSE("Large reads enabled\n");
	}
	if (server->opt.capabilities & SMB_CAP_LARGE_WRITEX) {
		VERBOSE("Large writes enabled\n");
	}
#endif
	if (server->opt.capabilities & SMB_CAP_UNIX) {
		struct inode *inode;
		VERBOSE("Using UNIX CIFS extensions\n");
		install_ops(server->ops, &smb_ops_unix);
		inode = SB_of(server)->s_root->d_inode;
		if (inode)
			inode->i_op = &smb_dir_inode_operations_unix;
	}

	VERBOSE("protocol=%d, max_xmit=%d, pid=%d capabilities=0x%x\n",
		server->opt.protocol, server->opt.max_xmit,
		pid_nr(server->conn_pid), server->opt.capabilities);

	/* FIXME: this really should be done by smbmount. */
	if (server->opt.max_xmit > SMB_MAX_PACKET_SIZE) {
		server->opt.max_xmit = SMB_MAX_PACKET_SIZE;
	}

	smb_unlock_server(server);
	smbiod_wake_up();
	if (server->opt.capabilities & SMB_CAP_UNIX)
		smb_proc_query_cifsunix(server);

	server->conn_complete++;
	wake_up_interruptible_all(&server->conn_wq);
	return error;

out:
	smb_unlock_server(server);
	smbiod_wake_up();
	return error;

out_putf:
	fput(filp);
	goto out;
}

/* smb_setup_header: We completely set up the packet. You only have to
   insert the command-specific fields */

__u8 *
smb_setup_header(struct smb_request *req, __u8 command, __u16 wct, __u16 bcc)
{
	__u32 xmit_len = SMB_HEADER_LEN + wct * sizeof(__u16) + bcc + 2;
	__u8 *p = req->rq_header;
	struct smb_sb_info *server = req->rq_server;

	p = smb_encode_smb_length(p, xmit_len - 4);

	*p++ = 0xff;
	*p++ = 'S';
	*p++ = 'M';
	*p++ = 'B';
	*p++ = command;

	memset(p, '\0', 19);
	p += 19;
	p += 8;

	if (server->opt.protocol > SMB_PROTOCOL_CORE) {
		int flags = SMB_FLAGS_CASELESS_PATHNAMES;
		int flags2 = SMB_FLAGS2_LONG_PATH_COMPONENTS |
			SMB_FLAGS2_EXTENDED_ATTRIBUTES;	/* EA? not really ... */

		*(req->rq_header + smb_flg) = flags;
		if (server->mnt->flags & SMB_MOUNT_UNICODE)
			flags2 |= SMB_FLAGS2_UNICODE_STRINGS;
		WSET(req->rq_header, smb_flg2, flags2);
	}
	*p++ = wct;		/* wct */
	p += 2 * wct;
	WSET(p, 0, bcc);

	/* Include the header in the data to send */
	req->rq_iovlen = 1;
	req->rq_iov[0].iov_base = req->rq_header;
	req->rq_iov[0].iov_len  = xmit_len - bcc;

	return req->rq_buffer;
}

static void
smb_setup_bcc(struct smb_request *req, __u8 *p)
{
	u16 bcc = p - req->rq_buffer;
	u8 *pbcc = req->rq_header + SMB_HEADER_LEN + 2*SMB_WCT(req->rq_header);

	WSET(pbcc, 0, bcc);

	smb_encode_smb_length(req->rq_header, SMB_HEADER_LEN + 
			      2*SMB_WCT(req->rq_header) - 2 + bcc);

	/* Include the "bytes" in the data to send */
	req->rq_iovlen = 2;
	req->rq_iov[1].iov_base = req->rq_buffer;
	req->rq_iov[1].iov_len  = bcc;
}

static int
smb_proc_seek(struct smb_sb_info *server, __u16 fileid,
	      __u16 mode, off_t offset)
{
	int result;
	struct smb_request *req;

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, 0)))
		goto out;

	smb_setup_header(req, SMBlseek, 4, 0);
	WSET(req->rq_header, smb_vwv0, fileid);
	WSET(req->rq_header, smb_vwv1, mode);
	DSET(req->rq_header, smb_vwv2, offset);
	req->rq_flags |= SMB_REQ_NORETRY;

	result = smb_request_ok(req, SMBlseek, 2, 0);
	if (result < 0) {
		result = 0;
		goto out_free;
	}

	result = DVAL(req->rq_header, smb_vwv0);
out_free:
	smb_rput(req);
out:
	return result;
}

static int
smb_proc_open(struct smb_sb_info *server, struct dentry *dentry, int wish)
{
	struct inode *ino = dentry->d_inode;
	struct smb_inode_info *ei = SMB_I(ino);
	int mode, read_write = 0x42, read_only = 0x40;
	int res;
	char *p;
	struct smb_request *req;

	/*
	 * Attempt to open r/w, unless there are no write privileges.
	 */
	mode = read_write;
	if (!(ino->i_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
		mode = read_only;
#if 0
	/* FIXME: why is this code not in? below we fix it so that a caller
	   wanting RO doesn't get RW. smb_revalidate_inode does some 
	   optimization based on access mode. tail -f needs it to be correct.

	   We must open rw since we don't do the open if called a second time
	   with different 'wish'. Is that not supported by smb servers? */
	if (!(wish & (O_WRONLY | O_RDWR)))
		mode = read_only;
#endif

	res = -ENOMEM;
	if (! (req = smb_alloc_request(server, PAGE_SIZE)))
		goto out;

      retry:
	p = smb_setup_header(req, SMBopen, 2, 0);
	WSET(req->rq_header, smb_vwv0, mode);
	WSET(req->rq_header, smb_vwv1, aSYSTEM | aHIDDEN | aDIR);
	res = smb_simple_encode_path(req, &p, dentry, NULL);
	if (res < 0)
		goto out_free;
	smb_setup_bcc(req, p);

	res = smb_request_ok(req, SMBopen, 7, 0);
	if (res != 0) {
		if (mode == read_write &&
		    (res == -EACCES || res == -ETXTBSY || res == -EROFS))
		{
			VERBOSE("%s/%s R/W failed, error=%d, retrying R/O\n",
				DENTRY_PATH(dentry), res);
			mode = read_only;
			req->rq_flags = 0;
			goto retry;
		}
		goto out_free;
	}
	/* We should now have data in vwv[0..6]. */

	ei->fileid = WVAL(req->rq_header, smb_vwv0);
	ei->attr   = WVAL(req->rq_header, smb_vwv1);
	/* smb_vwv2 has mtime */
	/* smb_vwv4 has size  */
	ei->access = (WVAL(req->rq_header, smb_vwv6) & SMB_ACCMASK);
	ei->open = server->generation;

out_free:
	smb_rput(req);
out:
	return res;
}

/*
 * Make sure the file is open, and check that the access
 * is compatible with the desired access.
 */
int
smb_open(struct dentry *dentry, int wish)
{
	struct inode *inode = dentry->d_inode;
	int result;
	__u16 access;

	result = -ENOENT;
	if (!inode) {
		printk(KERN_ERR "smb_open: no inode for dentry %s/%s\n",
		       DENTRY_PATH(dentry));
		goto out;
	}

	if (!smb_is_open(inode)) {
		struct smb_sb_info *server = server_from_inode(inode);
		result = 0;
		if (!smb_is_open(inode))
			result = smb_proc_open(server, dentry, wish);
		if (result)
			goto out;
		/*
		 * A successful open means the path is still valid ...
		 */
		smb_renew_times(dentry);
	}

	/*
	 * Check whether the access is compatible with the desired mode.
	 */
	result = 0;
	access = SMB_I(inode)->access;
	if (access != wish && access != SMB_O_RDWR) {
		PARANOIA("%s/%s access denied, access=%x, wish=%x\n",
			 DENTRY_PATH(dentry), access, wish);
		result = -EACCES;
	}
out:
	return result;
}

static int 
smb_proc_close(struct smb_sb_info *server, __u16 fileid, __u32 mtime)
{
	struct smb_request *req;
	int result = -ENOMEM;

	if (! (req = smb_alloc_request(server, 0)))
		goto out;

	smb_setup_header(req, SMBclose, 3, 0);
	WSET(req->rq_header, smb_vwv0, fileid);
	DSET(req->rq_header, smb_vwv1, utc2local(server, mtime));
	req->rq_flags |= SMB_REQ_NORETRY;
	result = smb_request_ok(req, SMBclose, 0, 0);

	smb_rput(req);
out:
	return result;
}

/*
 * Win NT 4.0 has an apparent bug in that it fails to update the
 * modify time when writing to a file. As a workaround, we update
 * both modify and access time locally, and post the times to the
 * server when closing the file.
 */
static int 
smb_proc_close_inode(struct smb_sb_info *server, struct inode * ino)
{
	struct smb_inode_info *ei = SMB_I(ino);
	int result = 0;
	if (smb_is_open(ino))
	{
		/*
		 * We clear the open flag in advance, in case another
 		 * process observes the value while we block below.
		 */
		ei->open = 0;

		/*
		 * Kludge alert: SMB timestamps are accurate only to
		 * two seconds ... round the times to avoid needless
		 * cache invalidations!
		 */
		if (ino->i_mtime.tv_sec & 1) { 
			ino->i_mtime.tv_sec--;
			ino->i_mtime.tv_nsec = 0; 
		}
		if (ino->i_atime.tv_sec & 1) {
			ino->i_atime.tv_sec--;
			ino->i_atime.tv_nsec = 0;
		}
		/*
		 * If the file is open with write permissions,
		 * update the time stamps to sync mtime and atime.
		 */
		if ((server->opt.capabilities & SMB_CAP_UNIX) == 0 &&
		    (server->opt.protocol >= SMB_PROTOCOL_LANMAN2) &&
		    !(ei->access == SMB_O_RDONLY))
		{
			struct smb_fattr fattr;
			smb_get_inode_attr(ino, &fattr);
			smb_proc_setattr_ext(server, ino, &fattr);
		}

		result = smb_proc_close(server, ei->fileid, ino->i_mtime.tv_sec);
		/*
		 * Force a revalidation after closing ... some servers
		 * don't post the size until the file has been closed.
		 */
		if (server->opt.protocol < SMB_PROTOCOL_NT1)
			ei->oldmtime = 0;
		ei->closed = jiffies;
	}
	return result;
}

int
smb_close(struct inode *ino)
{
	int result = 0;

	if (smb_is_open(ino)) {
		struct smb_sb_info *server = server_from_inode(ino);
		result = smb_proc_close_inode(server, ino);
	}
	return result;
}

/*
 * This is used to close a file following a failed instantiate.
 * Since we don't have an inode, we can't use any of the above.
 */
int
smb_close_fileid(struct dentry *dentry, __u16 fileid)
{
	struct smb_sb_info *server = server_from_dentry(dentry);
	int result;

	result = smb_proc_close(server, fileid, get_seconds());
	return result;
}

/* In smb_proc_read and smb_proc_write we do not retry, because the
   file-id would not be valid after a reconnection. */

static void
smb_proc_read_data(struct smb_request *req)
{
	req->rq_iov[0].iov_base = req->rq_buffer;
	req->rq_iov[0].iov_len  = 3;

	req->rq_iov[1].iov_base = req->rq_page;
	req->rq_iov[1].iov_len  = req->rq_rsize;
	req->rq_iovlen = 2;

	req->rq_rlen = smb_len(req->rq_header) + 4 - req->rq_bytes_recvd;
}

static int
smb_proc_read(struct inode *inode, loff_t offset, int count, char *data)
{
	struct smb_sb_info *server = server_from_inode(inode);
	__u16 returned_count, data_len;
	unsigned char *buf;
	int result;
	struct smb_request *req;
	u8 rbuf[4];

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, 0)))
		goto out;

	smb_setup_header(req, SMBread, 5, 0);
	buf = req->rq_header;
	WSET(buf, smb_vwv0, SMB_I(inode)->fileid);
	WSET(buf, smb_vwv1, count);
	DSET(buf, smb_vwv2, offset);
	WSET(buf, smb_vwv4, 0);

	req->rq_page = data;
	req->rq_rsize = count;
	req->rq_callback = smb_proc_read_data;
	req->rq_buffer = rbuf;
	req->rq_flags |= SMB_REQ_NORETRY | SMB_REQ_STATIC;

	result = smb_request_ok(req, SMBread, 5, -1);
	if (result < 0)
		goto out_free;
	returned_count = WVAL(req->rq_header, smb_vwv0);

	data_len = WVAL(rbuf, 1);

	if (returned_count != data_len) {
		printk(KERN_NOTICE "smb_proc_read: returned != data_len\n");
		printk(KERN_NOTICE "smb_proc_read: ret_c=%d, data_len=%d\n",
		       returned_count, data_len);
	}
	result = data_len;

out_free:
	smb_rput(req);
out:
	VERBOSE("ino=%ld, fileid=%d, count=%d, result=%d\n",
		inode->i_ino, SMB_I(inode)->fileid, count, result);
	return result;
}

static int
smb_proc_write(struct inode *inode, loff_t offset, int count, const char *data)
{
	struct smb_sb_info *server = server_from_inode(inode);
	int result;
	u16 fileid = SMB_I(inode)->fileid;
	u8 buf[4];
	struct smb_request *req;

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, 0)))
		goto out;

	VERBOSE("ino=%ld, fileid=%d, count=%d@%Ld\n",
		inode->i_ino, fileid, count, offset);

	smb_setup_header(req, SMBwrite, 5, count + 3);
	WSET(req->rq_header, smb_vwv0, fileid);
	WSET(req->rq_header, smb_vwv1, count);
	DSET(req->rq_header, smb_vwv2, offset);
	WSET(req->rq_header, smb_vwv4, 0);

	buf[0] = 1;
	WSET(buf, 1, count);	/* yes, again ... */
	req->rq_iov[1].iov_base = buf;
	req->rq_iov[1].iov_len = 3;
	req->rq_iov[2].iov_base = (char *) data;
	req->rq_iov[2].iov_len = count;
	req->rq_iovlen = 3;
	req->rq_flags |= SMB_REQ_NORETRY;

	result = smb_request_ok(req, SMBwrite, 1, 0);
	if (result >= 0)
		result = WVAL(req->rq_header, smb_vwv0);

	smb_rput(req);
out:
	return result;
}

/*
 * In smb_proc_readX and smb_proc_writeX we do not retry, because the
 * file-id would not be valid after a reconnection.
 */

#define SMB_READX_MAX_PAD      64
static void
smb_proc_readX_data(struct smb_request *req)
{
	/* header length, excluding the netbios length (-4) */
	int hdrlen = SMB_HEADER_LEN + req->rq_resp_wct*2 - 2;
	int data_off = WVAL(req->rq_header, smb_vwv6);

	/*
	 * Some genius made the padding to the data bytes arbitrary.
	 * So we must first calculate the amount of padding used by the server.
	 */
	data_off -= hdrlen;
	if (data_off > SMB_READX_MAX_PAD || data_off < 0) {
		PARANOIA("offset is larger than SMB_READX_MAX_PAD or negative!\n");
		PARANOIA("%d > %d || %d < 0\n", data_off, SMB_READX_MAX_PAD, data_off);
		req->rq_rlen = req->rq_bufsize + 1;
		return;
	}
	req->rq_iov[0].iov_base = req->rq_buffer;
	req->rq_iov[0].iov_len  = data_off;

	req->rq_iov[1].iov_base = req->rq_page;
	req->rq_iov[1].iov_len  = req->rq_rsize;
	req->rq_iovlen = 2;

	req->rq_rlen = smb_len(req->rq_header) + 4 - req->rq_bytes_recvd;
}

static int
smb_proc_readX(struct inode *inode, loff_t offset, int count, char *data)
{
	struct smb_sb_info *server = server_from_inode(inode);
	unsigned char *buf;
	int result;
	struct smb_request *req;
	static char pad[SMB_READX_MAX_PAD];

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, 0)))
		goto out;

	smb_setup_header(req, SMBreadX, 12, 0);
	buf = req->rq_header;
	WSET(buf, smb_vwv0, 0x00ff);
	WSET(buf, smb_vwv1, 0);
	WSET(buf, smb_vwv2, SMB_I(inode)->fileid);
	DSET(buf, smb_vwv3, (u32)offset);               /* low 32 bits */
	WSET(buf, smb_vwv5, count);
	WSET(buf, smb_vwv6, 0);
	DSET(buf, smb_vwv7, 0);
	WSET(buf, smb_vwv9, 0);
	DSET(buf, smb_vwv10, (u32)(offset >> 32));      /* high 32 bits */
	WSET(buf, smb_vwv11, 0);

	req->rq_page = data;
	req->rq_rsize = count;
	req->rq_callback = smb_proc_readX_data;
	req->rq_buffer = pad;
	req->rq_bufsize = SMB_READX_MAX_PAD;
	req->rq_flags |= SMB_REQ_STATIC | SMB_REQ_NORETRY;

	result = smb_request_ok(req, SMBreadX, 12, -1);
	if (result < 0)
		goto out_free;
	result = WVAL(req->rq_header, smb_vwv5);

out_free:
	smb_rput(req);
out:
	VERBOSE("ino=%ld, fileid=%d, count=%d, result=%d\n",
		inode->i_ino, SMB_I(inode)->fileid, count, result);
	return result;
}

static int
smb_proc_writeX(struct inode *inode, loff_t offset, int count, const char *data)
{
	struct smb_sb_info *server = server_from_inode(inode);
	int result;
	u8 *p;
	static u8 pad[4];
	struct smb_request *req;

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, 0)))
		goto out;

	VERBOSE("ino=%ld, fileid=%d, count=%d@%Ld\n",
		inode->i_ino, SMB_I(inode)->fileid, count, offset);

	p = smb_setup_header(req, SMBwriteX, 14, count + 1);
	WSET(req->rq_header, smb_vwv0, 0x00ff);
	WSET(req->rq_header, smb_vwv1, 0);
	WSET(req->rq_header, smb_vwv2, SMB_I(inode)->fileid);
	DSET(req->rq_header, smb_vwv3, (u32)offset);	/* low 32 bits */
	DSET(req->rq_header, smb_vwv5, 0);
	WSET(req->rq_header, smb_vwv7, 0);		/* write mode */
	WSET(req->rq_header, smb_vwv8, 0);
	WSET(req->rq_header, smb_vwv9, 0);
	WSET(req->rq_header, smb_vwv10, count);		/* data length */
	WSET(req->rq_header, smb_vwv11, smb_vwv12 + 2 + 1);
	DSET(req->rq_header, smb_vwv12, (u32)(offset >> 32));

	req->rq_iov[1].iov_base = pad;
	req->rq_iov[1].iov_len = 1;
	req->rq_iov[2].iov_base = (char *) data;
	req->rq_iov[2].iov_len = count;
	req->rq_iovlen = 3;
	req->rq_flags |= SMB_REQ_NORETRY;

	result = smb_request_ok(req, SMBwriteX, 6, 0);
 	if (result >= 0)
		result = WVAL(req->rq_header, smb_vwv2);

	smb_rput(req);
out:
	return result;
}

int
smb_proc_create(struct dentry *dentry, __u16 attr, time_t ctime, __u16 *fileid)
{
	struct smb_sb_info *server = server_from_dentry(dentry);
	char *p;
	int result;
	struct smb_request *req;

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, PAGE_SIZE)))
		goto out;

	p = smb_setup_header(req, SMBcreate, 3, 0);
	WSET(req->rq_header, smb_vwv0, attr);
	DSET(req->rq_header, smb_vwv1, utc2local(server, ctime));
	result = smb_simple_encode_path(req, &p, dentry, NULL);
	if (result < 0)
		goto out_free;
	smb_setup_bcc(req, p);

	result = smb_request_ok(req, SMBcreate, 1, 0);
	if (result < 0)
		goto out_free;

	*fileid = WVAL(req->rq_header, smb_vwv0);
	result = 0;

out_free:
	smb_rput(req);
out:
	return result;
}

int
smb_proc_mv(struct dentry *old_dentry, struct dentry *new_dentry)
{
	struct smb_sb_info *server = server_from_dentry(old_dentry);
	char *p;
	int result;
	struct smb_request *req;

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, PAGE_SIZE)))
		goto out;

	p = smb_setup_header(req, SMBmv, 1, 0);
	WSET(req->rq_header, smb_vwv0, aSYSTEM | aHIDDEN | aDIR);
	result = smb_simple_encode_path(req, &p, old_dentry, NULL);
	if (result < 0)
		goto out_free;
	result = smb_simple_encode_path(req, &p, new_dentry, NULL);
	if (result < 0)
		goto out_free;
	smb_setup_bcc(req, p);

	if ((result = smb_request_ok(req, SMBmv, 0, 0)) < 0)
		goto out_free;
	result = 0;

out_free:
	smb_rput(req);
out:
	return result;
}

/*
 * Code common to mkdir and rmdir.
 */
static int
smb_proc_generic_command(struct dentry *dentry, __u8 command)
{
	struct smb_sb_info *server = server_from_dentry(dentry);
	char *p;
	int result;
	struct smb_request *req;

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, PAGE_SIZE)))
		goto out;

	p = smb_setup_header(req, command, 0, 0);
	result = smb_simple_encode_path(req, &p, dentry, NULL);
	if (result < 0)
		goto out_free;
	smb_setup_bcc(req, p);

	result = smb_request_ok(req, command, 0, 0);
	if (result < 0)
		goto out_free;
	result = 0;

out_free:
	smb_rput(req);
out:
	return result;
}

int
smb_proc_mkdir(struct dentry *dentry)
{
	return smb_proc_generic_command(dentry, SMBmkdir);
}

int
smb_proc_rmdir(struct dentry *dentry)
{
	return smb_proc_generic_command(dentry, SMBrmdir);
}

#if SMBFS_POSIX_UNLINK
/*
 * Removes readonly attribute from a file. Used by unlink to give posix
 * semantics.
 */
static int
smb_set_rw(struct dentry *dentry,struct smb_sb_info *server)
{
	int result;
	struct smb_fattr fattr;

	/* FIXME: cifsUE should allow removing a readonly file. */

	/* first get current attribute */
	smb_init_dirent(server, &fattr);
	result = server->ops->getattr(server, dentry, &fattr);
	smb_finish_dirent(server, &fattr);
	if (result < 0)
		return result;

	/* if RONLY attribute is set, remove it */
	if (fattr.attr & aRONLY) {  /* read only attribute is set */
		fattr.attr &= ~aRONLY;
		result = smb_proc_setattr_core(server, dentry, fattr.attr);
	}
	return result;
}
#endif

int
smb_proc_unlink(struct dentry *dentry)
{
	struct smb_sb_info *server = server_from_dentry(dentry);
	int flag = 0;
	char *p;
	int result;
	struct smb_request *req;

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, PAGE_SIZE)))
		goto out;

      retry:
	p = smb_setup_header(req, SMBunlink, 1, 0);
	WSET(req->rq_header, smb_vwv0, aSYSTEM | aHIDDEN);
	result = smb_simple_encode_path(req, &p, dentry, NULL);
	if (result < 0)
		goto out_free;
	smb_setup_bcc(req, p);

	if ((result = smb_request_ok(req, SMBunlink, 0, 0)) < 0) {
#if SMBFS_POSIX_UNLINK
		if (result == -EACCES && !flag) {
			/* Posix semantics is for the read-only state
			   of a file to be ignored in unlink(). In the
			   SMB world a unlink() is refused on a
			   read-only file. To make things easier for
			   unix users we try to override the files
			   permission if the unlink fails with the
			   right error.
			   This introduces a race condition that could
			   lead to a file being written by someone who
			   shouldn't have access, but as far as I can
			   tell that is unavoidable */

			/* remove RONLY attribute and try again */
			result = smb_set_rw(dentry,server);
			if (result == 0) {
				flag = 1;
				req->rq_flags = 0;
				goto retry;
			}
		}
#endif
		goto out_free;
	}
	result = 0;

out_free:
	smb_rput(req);
out:
	return result;
}

int
smb_proc_flush(struct smb_sb_info *server, __u16 fileid)
{
	int result;
	struct smb_request *req;

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, 0)))
		goto out;

	smb_setup_header(req, SMBflush, 1, 0);
	WSET(req->rq_header, smb_vwv0, fileid);
	req->rq_flags |= SMB_REQ_NORETRY;
	result = smb_request_ok(req, SMBflush, 0, 0);

	smb_rput(req);
out:
	return result;
}

static int
smb_proc_trunc32(struct inode *inode, loff_t length)
{
	/*
	 * Writing 0bytes is old-SMB magic for truncating files.
	 * MAX_NON_LFS should prevent this from being called with a too
	 * large offset.
	 */
	return smb_proc_write(inode, length, 0, NULL);
}

static int
smb_proc_trunc64(struct inode *inode, loff_t length)
{
	struct smb_sb_info *server = server_from_inode(inode);
	int result;
	char *param;
	char *data;
	struct smb_request *req;

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, 14)))
		goto out;

	param = req->rq_buffer;
	data = req->rq_buffer + 6;

	/* FIXME: must we also set allocation size? winNT seems to do that */
	WSET(param, 0, SMB_I(inode)->fileid);
	WSET(param, 2, SMB_SET_FILE_END_OF_FILE_INFO);
	WSET(param, 4, 0);
	LSET(data, 0, length);

	req->rq_trans2_command = TRANSACT2_SETFILEINFO;
	req->rq_ldata = 8;
	req->rq_data  = data;
	req->rq_lparm = 6;
	req->rq_parm  = param;
	req->rq_flags |= SMB_REQ_NORETRY;
	result = smb_add_request(req);
	if (result < 0)
		goto out_free;

	result = 0;
	if (req->rq_rcls != 0)
		result = smb_errno(req);

out_free:
	smb_rput(req);
out:
	return result;
}

static int
smb_proc_trunc95(struct inode *inode, loff_t length)
{
	struct smb_sb_info *server = server_from_inode(inode);
	int result = smb_proc_trunc32(inode, length);
 
	/*
	 * win9x doesn't appear to update the size immediately.
	 * It will return the old file size after the truncate,
	 * confusing smbfs. So we force an update.
	 *
	 * FIXME: is this still necessary?
	 */
	smb_proc_flush(server, SMB_I(inode)->fileid);
	return result;
}

static void
smb_init_dirent(struct smb_sb_info *server, struct smb_fattr *fattr)
{
	memset(fattr, 0, sizeof(*fattr));

	fattr->f_nlink = 1;
	fattr->f_uid = server->mnt->uid;
	fattr->f_gid = server->mnt->gid;
	fattr->f_unix = 0;
}

static void
smb_finish_dirent(struct smb_sb_info *server, struct smb_fattr *fattr)
{
	if (fattr->f_unix)
		return;

	fattr->f_mode = server->mnt->file_mode;
	if (fattr->attr & aDIR) {
		fattr->f_mode = server->mnt->dir_mode;
		fattr->f_size = SMB_ST_BLKSIZE;
	}
	/* Check the read-only flag */
	if (fattr->attr & aRONLY)
		fattr->f_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);

	/* How many 512 byte blocks do we need for this file? */
	fattr->f_blocks = 0;
	if (fattr->f_size != 0)
		fattr->f_blocks = 1 + ((fattr->f_size-1) >> 9);
	return;
}

void
smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr,
		     struct super_block *sb)
{
	smb_init_dirent(server, fattr);
	fattr->attr = aDIR;
	fattr->f_ino = 2; /* traditional root inode number */
	fattr->f_mtime = current_fs_time(sb);
	smb_finish_dirent(server, fattr);
}

/*
 * Decode a dirent for old protocols
 *
 * qname is filled with the decoded, and possibly translated, name.
 * fattr receives decoded attributes
 *
 * Bugs Noted:
 * (1) Pathworks servers may pad the name with extra spaces.
 */
static char *
smb_decode_short_dirent(struct smb_sb_info *server, char *p,
			struct qstr *qname, struct smb_fattr *fattr,
			unsigned char *name_buf)
{
	int len;

	/*
	 * SMB doesn't have a concept of inode numbers ...
	 */
	smb_init_dirent(server, fattr);
	fattr->f_ino = 0;	/* FIXME: do we need this? */

	p += SMB_STATUS_SIZE;	/* reserved (search_status) */
	fattr->attr = *p;
	fattr->f_mtime.tv_sec = date_dos2unix(server, WVAL(p, 3), WVAL(p, 1));
	fattr->f_mtime.tv_nsec = 0;
	fattr->f_size = DVAL(p, 5);
	fattr->f_ctime = fattr->f_mtime;
	fattr->f_atime = fattr->f_mtime;
	qname->name = p + 9;
	len = strnlen(qname->name, 12);

	/*
	 * Trim trailing blanks for Pathworks servers
	 */
	while (len > 2 && qname->name[len-1] == ' ')
		len--;

	smb_finish_dirent(server, fattr);

#if 0
	/* FIXME: These only work for ascii chars, and recent smbmount doesn't
	   allow the flag to be set anyway. It kills const. Remove? */
	switch (server->opt.case_handling) {
	case SMB_CASE_UPPER:
		str_upper(entry->name, len);
		break;
	case SMB_CASE_LOWER:
		str_lower(entry->name, len);
		break;
	default:
		break;
	}
#endif

	qname->len = 0;
	len = server->ops->convert(name_buf, SMB_MAXNAMELEN,
				   qname->name, len,
				   server->remote_nls, server->local_nls);
	if (len > 0) {
		qname->len = len;
		qname->name = name_buf;
		DEBUG1("len=%d, name=%.*s\n",qname->len,qname->len,qname->name);
	}

	return p + 22;
}

/*
 * This routine is used to read in directory entries from the network.
 * Note that it is for short directory name seeks, i.e.: protocol <
 * SMB_PROTOCOL_LANMAN2
 */
static int
smb_proc_readdir_short(struct file *filp, void *dirent, filldir_t filldir,
		       struct smb_cache_control *ctl)
{
	struct dentry *dir = filp->f_path.dentry;
	struct smb_sb_info *server = server_from_dentry(dir);
	struct qstr qname;
	struct smb_fattr fattr;
	char *p;
	int result;
	int i, first, entries_seen, entries;
	int entries_asked = (server->opt.max_xmit - 100) / SMB_DIRINFO_SIZE;
	__u16 bcc;
	__u16 count;
	char status[SMB_STATUS_SIZE];
	static struct qstr mask = {
		.name	= "*.*",
		.len	= 3,
	};
	unsigned char *last_status;
	struct smb_request *req;
	unsigned char *name_buf;

	VERBOSE("%s/%s\n", DENTRY_PATH(dir));

	lock_kernel();

	result = -ENOMEM;
	if (! (name_buf = kmalloc(SMB_MAXNAMELEN, GFP_KERNEL)))
		goto out;

	first = 1;
	entries = 0;
	entries_seen = 2; /* implicit . and .. */

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, server->opt.max_xmit)))
		goto out_name;

	while (1) {
		p = smb_setup_header(req, SMBsearch, 2, 0);
		WSET(req->rq_header, smb_vwv0, entries_asked);
		WSET(req->rq_header, smb_vwv1, aDIR);
		if (first == 1) {
			result = smb_simple_encode_path(req, &p, dir, &mask);
			if (result < 0)
				goto out_free;
			if (p + 3 > (char *)req->rq_buffer + req->rq_bufsize) {
				result = -ENAMETOOLONG;
				goto out_free;
			}
			*p++ = 5;
			WSET(p, 0, 0);
			p += 2;
			first = 0;
		} else {
			if (p + 5 + SMB_STATUS_SIZE >
			    (char *)req->rq_buffer + req->rq_bufsize) {
				result = -ENAMETOOLONG;
				goto out_free;
			}
				
			*p++ = 4;
			*p++ = 0;
			*p++ = 5;
			WSET(p, 0, SMB_STATUS_SIZE);
			p += 2;
			memcpy(p, status, SMB_STATUS_SIZE);
			p += SMB_STATUS_SIZE;
		}

		smb_setup_bcc(req, p);

		result = smb_request_ok(req, SMBsearch, 1, -1);
		if (result < 0) {
			if ((req->rq_rcls == ERRDOS) && 
			    (req->rq_err  == ERRnofiles))
				break;
			goto out_free;
		}
		count = WVAL(req->rq_header, smb_vwv0);
		if (count <= 0)
			break;

		result = -EIO;
		bcc = smb_bcc(req->rq_header);
		if (bcc != count * SMB_DIRINFO_SIZE + 3)
			goto out_free;
		p = req->rq_buffer + 3;


		/* Make sure the response fits in the buffer. Fixed sized 
		   entries means we don't have to check in the decode loop. */

		last_status = req->rq_buffer + 3 + (count-1) * SMB_DIRINFO_SIZE;

		if (last_status + SMB_DIRINFO_SIZE >=
		    req->rq_buffer + req->rq_bufsize) {
			printk(KERN_ERR "smb_proc_readdir_short: "
			       "last dir entry outside buffer! "
			       "%d@%p  %d@%p\n", SMB_DIRINFO_SIZE, last_status,
			       req->rq_bufsize, req->rq_buffer);
			goto out_free;
		}

		/* Read the last entry into the status field. */
		memcpy(status, last_status, SMB_STATUS_SIZE);


		/* Now we are ready to parse smb directory entries. */

		for (i = 0; i < count; i++) {
			p = smb_decode_short_dirent(server, p, 
						    &qname, &fattr, name_buf);
			if (qname.len == 0)
				continue;

			if (entries_seen == 2 && qname.name[0] == '.') {
				if (qname.len == 1)
					continue;
				if (qname.name[1] == '.' && qname.len == 2)
					continue;
			}
			if (!smb_fill_cache(filp, dirent, filldir, ctl, 
					    &qname, &fattr))
				;	/* stop reading? */
			entries_seen++;
		}
	}
	result = entries;

out_free:
	smb_rput(req);
out_name:
	kfree(name_buf);
out:
	unlock_kernel();
	return result;
}

static void smb_decode_unix_basic(struct smb_fattr *fattr, struct smb_sb_info *server, char *p)
{
	u64 size, disk_bytes;

	/* FIXME: verify nls support. all is sent as utf8? */

	fattr->f_unix = 1;
	fattr->f_mode = 0;

	/* FIXME: use the uniqueID from the remote instead? */
	/* 0 L file size in bytes */
	/* 8 L file size on disk in bytes (block count) */
	/* 40 L uid */
	/* 48 L gid */
	/* 56 W file type */
	/* 60 L devmajor */
	/* 68 L devminor */
	/* 76 L unique ID (inode) */
	/* 84 L permissions */
	/* 92 L link count */

	size = LVAL(p, 0);
	disk_bytes = LVAL(p, 8);

	/*
	 * Some samba versions round up on-disk byte usage
	 * to 1MB boundaries, making it useless. When seeing
	 * that, use the size instead.
	 */
	if (!(disk_bytes & 0xfffff))
		disk_bytes = size+511;

	fattr->f_size = size;
	fattr->f_blocks = disk_bytes >> 9;
	fattr->f_ctime = smb_ntutc2unixutc(LVAL(p, 16));
	fattr->f_atime = smb_ntutc2unixutc(LVAL(p, 24));
	fattr->f_mtime = smb_ntutc2unixutc(LVAL(p, 32));

	if (server->mnt->flags & SMB_MOUNT_UID)
		fattr->f_uid = server->mnt->uid;
	else
		fattr->f_uid = LVAL(p, 40);

	if (server->mnt->flags & SMB_MOUNT_GID)
		fattr->f_gid = server->mnt->gid;
	else
		fattr->f_gid = LVAL(p, 48);

	fattr->f_mode |= smb_filetype_to_mode(WVAL(p, 56));

	if (S_ISBLK(fattr->f_mode) || S_ISCHR(fattr->f_mode)) {
		__u64 major = LVAL(p, 60);
		__u64 minor = LVAL(p, 68);

		fattr->f_rdev = MKDEV(major & 0xffffffff, minor & 0xffffffff);
		if (MAJOR(fattr->f_rdev) != (major & 0xffffffff) ||
	    	MINOR(fattr->f_rdev) != (minor & 0xffffffff))
			fattr->f_rdev = 0;
	}

	fattr->f_mode |= LVAL(p, 84);

	if ( (server->mnt->flags & SMB_MOUNT_DMODE) &&
	     (S_ISDIR(fattr->f_mode)) )
		fattr->f_mode = (server->mnt->dir_mode & S_IRWXUGO) | S_IFDIR;
	else if ( (server->mnt->flags & SMB_MOUNT_FMODE) &&
	          !(S_ISDIR(fattr->f_mode)) )
		fattr->f_mode = (server->mnt->file_mode & S_IRWXUGO) |
				(fattr->f_mode & S_IFMT);

}

/*
 * Interpret a long filename structure using the specified info level:
 *   level 1 for anything below NT1 protocol
 *   level 260 for NT1 protocol
 *
 * qname is filled with the decoded, and possibly translated, name
 * fattr receives decoded attributes.
 *
 * Bugs Noted:
 * (1) Win NT 4.0 appends a null byte to names and counts it in the length!
 */
static char *
smb_decode_long_dirent(struct smb_sb_info *server, char *p, int level,
		       struct qstr *qname, struct smb_fattr *fattr,
		       unsigned char *name_buf)
{
	char *result;
	unsigned int len = 0;
	int n;
	__u16 date, time;
	int unicode = (server->mnt->flags & SMB_MOUNT_UNICODE);

	/*
	 * SMB doesn't have a concept of inode numbers ...
	 */
	smb_init_dirent(server, fattr);
	fattr->f_ino = 0;	/* FIXME: do we need this? */

	switch (level) {
	case 1:
		len = *((unsigned char *) p + 22);
		qname->name = p + 23;
		result = p + 24 + len;

		date = WVAL(p, 0);
		time = WVAL(p, 2);
		fattr->f_ctime.tv_sec = date_dos2unix(server, date, time);
		fattr->f_ctime.tv_nsec = 0;

		date = WVAL(p, 4);
		time = WVAL(p, 6);
		fattr->f_atime.tv_sec = date_dos2unix(server, date, time);
		fattr->f_atime.tv_nsec = 0;

		date = WVAL(p, 8);
		time = WVAL(p, 10);
		fattr->f_mtime.tv_sec = date_dos2unix(server, date, time);
		fattr->f_mtime.tv_nsec = 0;
		fattr->f_size = DVAL(p, 12);
		/* ULONG allocation size */
		fattr->attr = WVAL(p, 20);

		VERBOSE("info 1 at %p, len=%d, name=%.*s\n",
			p, len, len, qname->name);
		break;
	case 260:
		result = p + WVAL(p, 0);
		len = DVAL(p, 60);
		if (len > 255) len = 255;
		/* NT4 null terminates, unless we are using unicode ... */
		qname->name = p + 94;
		if (!unicode && len && qname->name[len-1] == '\0')
			len--;

		fattr->f_ctime = smb_ntutc2unixutc(LVAL(p, 8));
		fattr->f_atime = smb_ntutc2unixutc(LVAL(p, 16));
		fattr->f_mtime = smb_ntutc2unixutc(LVAL(p, 24));
		/* change time (32) */
		fattr->f_size = LVAL(p, 40);
		/* alloc size (48) */
		fattr->attr = DVAL(p, 56);

		VERBOSE("info 260 at %p, len=%d, name=%.*s\n",
			p, len, len, qname->name);
		break;
	case SMB_FIND_FILE_UNIX:
		result = p + WVAL(p, 0);
		qname->name = p + 108;

		len = strlen(qname->name);
		/* FIXME: should we check the length?? */

		p += 8;
		smb_decode_unix_basic(fattr, server, p);
		VERBOSE("info SMB_FIND_FILE_UNIX at %p, len=%d, name=%.*s\n",
			p, len, len, qname->name);
		break;
	default:
		PARANOIA("Unknown info level %d\n", level);
		result = p + WVAL(p, 0);
		goto out;
	}

	smb_finish_dirent(server, fattr);

#if 0
	/* FIXME: These only work for ascii chars, and recent smbmount doesn't
	   allow the flag to be set anyway. Remove? */
	switch (server->opt.case_handling) {
	case SMB_CASE_UPPER:
		str_upper(qname->name, len);
		break;
	case SMB_CASE_LOWER:
		str_lower(qname->name, len);
		break;
	default:
		break;
	}
#endif

	qname->len = 0;
	n = server->ops->convert(name_buf, SMB_MAXNAMELEN,
				 qname->name, len,
				 server->remote_nls, server->local_nls);
	if (n > 0) {
		qname->len = n;
		qname->name = name_buf;
	}

out:
	return result;
}

/* findfirst/findnext flags */
#define SMB_CLOSE_AFTER_FIRST (1<<0)
#define SMB_CLOSE_IF_END (1<<1)
#define SMB_REQUIRE_RESUME_KEY (1<<2)
#define SMB_CONTINUE_BIT (1<<3)

/*
 * Note: samba-2.0.7 (at least) has a very similar routine, cli_list, in
 * source/libsmb/clilist.c. When looking for smb bugs in the readdir code,
 * go there for advise.
 *
 * Bugs Noted:
 * (1) When using Info Level 1 Win NT 4.0 truncates directory listings 
 * for certain patterns of names and/or lengths. The breakage pattern
 * is completely reproducible and can be toggled by the creation of a
 * single file. (E.g. echo hi >foo breaks, rm -f foo works.)
 */
static int
smb_proc_readdir_long(struct file *filp, void *dirent, filldir_t filldir,
		      struct smb_cache_control *ctl)
{
	struct dentry *dir = filp->f_path.dentry;
	struct smb_sb_info *server = server_from_dentry(dir);
	struct qstr qname;
	struct smb_fattr fattr;

	unsigned char *p, *lastname;
	char *mask, *param;
	__u16 command;
	int first, entries_seen;

	/* Both NT and OS/2 accept info level 1 (but see note below). */
	int info_level = 260;
	const int max_matches = 512;

	unsigned int ff_searchcount = 0;
	unsigned int ff_eos = 0;
	unsigned int ff_lastname = 0;
	unsigned int ff_dir_handle = 0;
	unsigned int loop_count = 0;
	unsigned int mask_len, i;
	int result;
	struct smb_request *req;
	unsigned char *name_buf;
	static struct qstr star = {
		.name	= "*",
		.len	= 1,
	};

	lock_kernel();

	/*
	 * We always prefer unix style. Use info level 1 for older
	 * servers that don't do 260.
	 */
	if (server->opt.capabilities & SMB_CAP_UNIX)
		info_level = SMB_FIND_FILE_UNIX;
	else if (server->opt.protocol < SMB_PROTOCOL_NT1)
		info_level = 1;

	result = -ENOMEM;
	if (! (name_buf = kmalloc(SMB_MAXNAMELEN+2, GFP_KERNEL)))
		goto out;
	if (! (req = smb_alloc_request(server, server->opt.max_xmit)))
		goto out_name;
	param = req->rq_buffer;

	/*
	 * Encode the initial path
	 */
	mask = param + 12;

	result = smb_encode_path(server, mask, SMB_MAXPATHLEN+1, dir, &star);
	if (result <= 0)
		goto out_free;
	mask_len = result - 1;	/* mask_len is strlen, not #bytes */
	result = 0;
	first = 1;
	VERBOSE("starting mask_len=%d, mask=%s\n", mask_len, mask);

	entries_seen = 2;
	ff_eos = 0;

	while (ff_eos == 0) {
		loop_count += 1;
		if (loop_count > 10) {
			printk(KERN_WARNING "smb_proc_readdir_long: "
			       "Looping in FIND_NEXT??\n");
			result = -EIO;
			break;
		}

		if (first != 0) {
			command = TRANSACT2_FINDFIRST;
			WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);
			WSET(param, 2, max_matches);	/* max count */
			WSET(param, 4, SMB_CLOSE_IF_END);
			WSET(param, 6, info_level);
			DSET(param, 8, 0);
		} else {
			command = TRANSACT2_FINDNEXT;

			VERBOSE("handle=0x%X, lastname=%d, mask=%.*s\n",
				ff_dir_handle, ff_lastname, mask_len, mask);

			WSET(param, 0, ff_dir_handle);	/* search handle */
			WSET(param, 2, max_matches);	/* max count */
			WSET(param, 4, info_level);
			DSET(param, 6, 0);
			WSET(param, 10, SMB_CONTINUE_BIT|SMB_CLOSE_IF_END);
		}

		req->rq_trans2_command = command;
		req->rq_ldata = 0;
		req->rq_data  = NULL;
		req->rq_lparm = 12 + mask_len + 1;
		req->rq_parm  = param;
		req->rq_flags = 0;
		result = smb_add_request(req);
		if (result < 0) {
			PARANOIA("error=%d, breaking\n", result);
			break;
		}

		if (req->rq_rcls == ERRSRV && req->rq_err == ERRerror) {
			/* a damn Win95 bug - sometimes it clags if you 
			   ask it too fast */
			schedule_timeout_interruptible(msecs_to_jiffies(200));
			continue;
                }

		if (req->rq_rcls != 0) {
			result = smb_errno(req);
			PARANOIA("name=%s, result=%d, rcls=%d, err=%d\n",
				 mask, result, req->rq_rcls, req->rq_err);
			break;
		}

		/* parse out some important return info */
		if (first != 0) {
			ff_dir_handle = WVAL(req->rq_parm, 0);
			ff_searchcount = WVAL(req->rq_parm, 2);
			ff_eos = WVAL(req->rq_parm, 4);
			ff_lastname = WVAL(req->rq_parm, 8);
		} else {
			ff_searchcount = WVAL(req->rq_parm, 0);
			ff_eos = WVAL(req->rq_parm, 2);
			ff_lastname = WVAL(req->rq_parm, 6);
		}

		if (ff_searchcount == 0)
			break;

		/* Now we are ready to parse smb directory entries. */

		/* point to the data bytes */
		p = req->rq_data;
		for (i = 0; i < ff_searchcount; i++) {
			/* make sure we stay within the buffer */
			if (p >= req->rq_data + req->rq_ldata) {
				printk(KERN_ERR "smb_proc_readdir_long: "
				       "dirent pointer outside buffer! "
				       "%p  %d@%p\n",
				       p, req->rq_ldata, req->rq_data);
				result = -EIO; /* always a comm. error? */
				goto out_free;
			}

			p = smb_decode_long_dirent(server, p, info_level,
						   &qname, &fattr, name_buf);

			/* ignore . and .. from the server */
			if (entries_seen == 2 && qname.name[0] == '.') {
				if (qname.len == 1)
					continue;
				if (qname.name[1] == '.' && qname.len == 2)
					continue;
			}

			if (!smb_fill_cache(filp, dirent, filldir, ctl, 
					    &qname, &fattr))
				;	/* stop reading? */
			entries_seen++;
		}

		VERBOSE("received %d entries, eos=%d\n", ff_searchcount,ff_eos);

		/*
		 * We might need the lastname for continuations.
		 *
		 * Note that some servers (win95?) point to the filename and
		 * others (NT4, Samba using NT1) to the dir entry. We assume
		 * here that those who do not point to a filename do not need
		 * this info to continue the listing.
		 *
		 * OS/2 needs this and talks infolevel 1.
		 * NetApps want lastname with infolevel 260.
		 * win2k want lastname with infolevel 260, and points to
		 *       the record not to the name.
		 * Samba+CifsUnixExt doesn't need lastname.
		 *
		 * Both are happy if we return the data they point to. So we do.
		 * (FIXME: above is not true with win2k)
		 */
		mask_len = 0;
		if (info_level != SMB_FIND_FILE_UNIX &&
		    ff_lastname > 0 && ff_lastname < req->rq_ldata) {
			lastname = req->rq_data + ff_lastname;

			switch (info_level) {
			case 260:
				mask_len = req->rq_ldata - ff_lastname;
				break;
			case 1:
				/* lastname points to a length byte */
				mask_len = *lastname++;
				if (ff_lastname + 1 + mask_len > req->rq_ldata)
					mask_len = req->rq_ldata - ff_lastname - 1;
				break;
			}

			/*
			 * Update the mask string for the next message.
			 */
			if (mask_len > 255)
				mask_len = 255;
			if (mask_len)
				strncpy(mask, lastname, mask_len);
		}
		mask_len = strnlen(mask, mask_len);
		VERBOSE("new mask, len=%d@%d of %d, mask=%.*s\n",
			mask_len, ff_lastname, req->rq_ldata, mask_len, mask);

		first = 0;
		loop_count = 0;
	}

out_free:
	smb_rput(req);
out_name:
	kfree(name_buf);
out:
	unlock_kernel();
	return result;
}

/*
 * This version uses the trans2 TRANSACT2_FINDFIRST message 
 * to get the attribute data.
 *
 * Bugs Noted:
 */
static int
smb_proc_getattr_ff(struct smb_sb_info *server, struct dentry *dentry,
			struct smb_fattr *fattr)
{
	char *param, *mask;
	__u16 date, time;
	int mask_len, result;
	struct smb_request *req;

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, PAGE_SIZE)))
		goto out;
	param = req->rq_buffer;
	mask = param + 12;

	mask_len = smb_encode_path(server, mask, SMB_MAXPATHLEN+1, dentry,NULL);
	if (mask_len < 0) {
		result = mask_len;
		goto out_free;
	}
	VERBOSE("name=%s, len=%d\n", mask, mask_len);
	WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);
	WSET(param, 2, 1);	/* max count */
	WSET(param, 4, 1);	/* close after this call */
	WSET(param, 6, 1);	/* info_level */
	DSET(param, 8, 0);

	req->rq_trans2_command = TRANSACT2_FINDFIRST;
	req->rq_ldata = 0;
	req->rq_data  = NULL;
	req->rq_lparm = 12 + mask_len;
	req->rq_parm  = param;
	req->rq_flags = 0;
	result = smb_add_request(req);
	if (result < 0)
		goto out_free;
	if (req->rq_rcls != 0) {
		result = smb_errno(req);
#ifdef SMBFS_PARANOIA
		if (result != -ENOENT)
			PARANOIA("error for %s, rcls=%d, err=%d\n",
				 mask, req->rq_rcls, req->rq_err);
#endif
		goto out_free;
	}
	/* Make sure we got enough data ... */
	result = -EINVAL;
	if (req->rq_ldata < 22 || WVAL(req->rq_parm, 2) != 1) {
		PARANOIA("bad result for %s, len=%d, count=%d\n",
			 mask, req->rq_ldata, WVAL(req->rq_parm, 2));
		goto out_free;
	}

	/*
	 * Decode the response into the fattr ...
	 */
	date = WVAL(req->rq_data, 0);
	time = WVAL(req->rq_data, 2);
	fattr->f_ctime.tv_sec = date_dos2unix(server, date, time);
	fattr->f_ctime.tv_nsec = 0;

	date = WVAL(req->rq_data, 4);
	time = WVAL(req->rq_data, 6);
	fattr->f_atime.tv_sec = date_dos2unix(server, date, time);
	fattr->f_atime.tv_nsec = 0;

	date = WVAL(req->rq_data, 8);
	time = WVAL(req->rq_data, 10);
	fattr->f_mtime.tv_sec = date_dos2unix(server, date, time);
	fattr->f_mtime.tv_nsec = 0;
	VERBOSE("name=%s, date=%x, time=%x, mtime=%ld\n",
		mask, date, time, fattr->f_mtime.tv_sec);
	fattr->f_size = DVAL(req->rq_data, 12);
	/* ULONG allocation size */
	fattr->attr = WVAL(req->rq_data, 20);
	result = 0;

out_free:
	smb_rput(req);
out:
	return result;
}

static int
smb_proc_getattr_core(struct smb_sb_info *server, struct dentry *dir,
		      struct smb_fattr *fattr)
{
	int result;
	char *p;
	struct smb_request *req;

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, PAGE_SIZE)))
		goto out;

	p = smb_setup_header(req, SMBgetatr, 0, 0);
	result = smb_simple_encode_path(req, &p, dir, NULL);
	if (result < 0)
 		goto out_free;
	smb_setup_bcc(req, p);

	if ((result = smb_request_ok(req, SMBgetatr, 10, 0)) < 0)
		goto out_free;
	fattr->attr    = WVAL(req->rq_header, smb_vwv0);
	fattr->f_mtime.tv_sec = local2utc(server, DVAL(req->rq_header, smb_vwv1));
	fattr->f_mtime.tv_nsec = 0;
	fattr->f_size  = DVAL(req->rq_header, smb_vwv3);
	fattr->f_ctime = fattr->f_mtime; 
	fattr->f_atime = fattr->f_mtime; 
#ifdef SMBFS_DEBUG_TIMESTAMP
	printk("getattr_core: %s/%s, mtime=%ld\n",
	       DENTRY_PATH(dir), fattr->f_mtime);
#endif
	result = 0;

out_free:
	smb_rput(req);
out:
	return result;
}

/*
 * Bugs Noted:
 * (1) Win 95 swaps the date and time fields in the standard info level.
 */
static int
smb_proc_getattr_trans2(struct smb_sb_info *server, struct dentry *dir,
			struct smb_request *req, int infolevel)
{
	char *p, *param;
	int result;

	param = req->rq_buffer;
	WSET(param, 0, infolevel);
	DSET(param, 2, 0);
	result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, dir, NULL);
	if (result < 0)
		goto out;
	p = param + 6 + result;

	req->rq_trans2_command = TRANSACT2_QPATHINFO;
	req->rq_ldata = 0;
	req->rq_data  = NULL;
	req->rq_lparm = p - param;
	req->rq_parm  = param;
	req->rq_flags = 0;
	result = smb_add_request(req);
	if (result < 0)
		goto out;
	if (req->rq_rcls != 0) {
		VERBOSE("for %s: result=%d, rcls=%d, err=%d\n",
			&param[6], result, req->rq_rcls, req->rq_err);
		result = smb_errno(req);
		goto out;
	}
	result = -ENOENT;
	if (req->rq_ldata < 22) {
		PARANOIA("not enough data for %s, len=%d\n",
			 &param[6], req->rq_ldata);
		goto out;
	}

	result = 0;
out:
	return result;
}

static int
smb_proc_getattr_trans2_std(struct smb_sb_info *server, struct dentry *dir,
			    struct smb_fattr *attr)
{
	u16 date, time;
	int off_date = 0, off_time = 2;
	int result;
	struct smb_request *req;

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, PAGE_SIZE)))
		goto out;

	result = smb_proc_getattr_trans2(server, dir, req, SMB_INFO_STANDARD);
	if (result < 0)
		goto out_free;

	/*
	 * Kludge alert: Win 95 swaps the date and time field,
	 * contrary to the CIFS docs and Win NT practice.
	 */
	if (server->mnt->flags & SMB_MOUNT_WIN95) {
		off_date = 2;
		off_time = 0;
	}
	date = WVAL(req->rq_data, off_date);
	time = WVAL(req->rq_data, off_time);
	attr->f_ctime.tv_sec = date_dos2unix(server, date, time);
	attr->f_ctime.tv_nsec = 0;

	date = WVAL(req->rq_data, 4 + off_date);
	time = WVAL(req->rq_data, 4 + off_time);
	attr->f_atime.tv_sec = date_dos2unix(server, date, time);
	attr->f_atime.tv_nsec = 0;

	date = WVAL(req->rq_data, 8 + off_date);
	time = WVAL(req->rq_data, 8 + off_time);
	attr->f_mtime.tv_sec = date_dos2unix(server, date, time);
	attr->f_mtime.tv_nsec = 0;
#ifdef SMBFS_DEBUG_TIMESTAMP
	printk(KERN_DEBUG "getattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n",
	       DENTRY_PATH(dir), date, time, attr->f_mtime);
#endif
	attr->f_size = DVAL(req->rq_data, 12);
	attr->attr = WVAL(req->rq_data, 20);

out_free:
	smb_rput(req);
out:
	return result;
}

static int
smb_proc_getattr_trans2_all(struct smb_sb_info *server, struct dentry *dir,
			    struct smb_fattr *attr)
{
	struct smb_request *req;
	int result;

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, PAGE_SIZE)))
		goto out;

	result = smb_proc_getattr_trans2(server, dir, req,
					 SMB_QUERY_FILE_ALL_INFO);
	if (result < 0)
		goto out_free;

	attr->f_ctime = smb_ntutc2unixutc(LVAL(req->rq_data, 0));
	attr->f_atime = smb_ntutc2unixutc(LVAL(req->rq_data, 8));
	attr->f_mtime = smb_ntutc2unixutc(LVAL(req->rq_data, 16));
	/* change (24) */
	attr->attr = WVAL(req->rq_data, 32);
	/* pad? (34) */
	/* allocated size (40) */
	attr->f_size = LVAL(req->rq_data, 48);

out_free:
	smb_rput(req);
out:
	return result;
}

static int
smb_proc_getattr_unix(struct smb_sb_info *server, struct dentry *dir,
		      struct smb_fattr *attr)
{
	struct smb_request *req;
	int result;

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, PAGE_SIZE)))
		goto out;

	result = smb_proc_getattr_trans2(server, dir, req,
					 SMB_QUERY_FILE_UNIX_BASIC);
	if (result < 0)
		goto out_free;

	smb_decode_unix_basic(attr, server, req->rq_data);

out_free:
	smb_rput(req);
out:
	return result;
}

static int
smb_proc_getattr_95(struct smb_sb_info *server, struct dentry *dir,
		    struct smb_fattr *attr)
{
	struct inode *inode = dir->d_inode;
	int result;

	/* FIXME: why not use the "all" version? */
	result = smb_proc_getattr_trans2_std(server, dir, attr);
	if (result < 0)
		goto out;

	/*
	 * None of the getattr versions here can make win9x return the right
	 * filesize if there are changes made to an open file.
	 * A seek-to-end does return the right size, but we only need to do
	 * that on files we have written.
	 */
	if (inode && SMB_I(inode)->flags & SMB_F_LOCALWRITE &&
	    smb_is_open(inode))
	{
		__u16 fileid = SMB_I(inode)->fileid;
		attr->f_size = smb_proc_seek(server, fileid, 2, 0);
	}

out:
	return result;
}

static int
smb_proc_ops_wait(struct smb_sb_info *server)
{
	int result;

	result = wait_event_interruptible_timeout(server->conn_wq,
				server->conn_complete, 30*HZ);

	if (!result || signal_pending(current))
		return -EIO;

	return 0;
}

static int
smb_proc_getattr_null(struct smb_sb_info *server, struct dentry *dir,
			  struct smb_fattr *fattr)
{
	int result;

	if (smb_proc_ops_wait(server) < 0)
		return -EIO;

	smb_init_dirent(server, fattr);
	result = server->ops->getattr(server, dir, fattr);
	smb_finish_dirent(server, fattr);

	return result;
}

static int
smb_proc_readdir_null(struct file *filp, void *dirent, filldir_t filldir,
		      struct smb_cache_control *ctl)
{
	struct smb_sb_info *server = server_from_dentry(filp->f_path.dentry);

	if (smb_proc_ops_wait(server) < 0)
		return -EIO;

	return server->ops->readdir(filp, dirent, filldir, ctl);
}

int
smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr)
{
	struct smb_sb_info *server = server_from_dentry(dir);
	int result;

	smb_init_dirent(server, fattr);
	result = server->ops->getattr(server, dir, fattr);
	smb_finish_dirent(server, fattr);

	return result;
}


/*
 * Because of bugs in the core protocol, we use this only to set
 * attributes. See smb_proc_settime() below for timestamp handling.
 *
 * Bugs Noted:
 * (1) If mtime is non-zero, both Win 3.1 and Win 95 fail
 * with an undocumented error (ERRDOS code 50). Setting
 * mtime to 0 allows the attributes to be set.
 * (2) The extra parameters following the name string aren't
 * in the CIFS docs, but seem to be necessary for operation.
 */
static int
smb_proc_setattr_core(struct smb_sb_info *server, struct dentry *dentry,
		      __u16 attr)
{
	char *p;
	int result;
	struct smb_request *req;

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, PAGE_SIZE)))
		goto out;

	p = smb_setup_header(req, SMBsetatr, 8, 0);
	WSET(req->rq_header, smb_vwv0, attr);
	DSET(req->rq_header, smb_vwv1, 0); /* mtime */
	WSET(req->rq_header, smb_vwv3, 0); /* reserved values */
	WSET(req->rq_header, smb_vwv4, 0);
	WSET(req->rq_header, smb_vwv5, 0);
	WSET(req->rq_header, smb_vwv6, 0);
	WSET(req->rq_header, smb_vwv7, 0);
	result = smb_simple_encode_path(req, &p, dentry, NULL);
	if (result < 0)
		goto out_free;
	if (p + 2 > (char *)req->rq_buffer + req->rq_bufsize) {
		result = -ENAMETOOLONG;
		goto out_free;
	}
	*p++ = 4;
	*p++ = 0;
	smb_setup_bcc(req, p);

	result = smb_request_ok(req, SMBsetatr, 0, 0);
	if (result < 0)
		goto out_free;
	result = 0;

out_free:
	smb_rput(req);
out:
	return result;
}

/*
 * Because of bugs in the trans2 setattr messages, we must set
 * attributes and timestamps separately. The core SMBsetatr
 * message seems to be the only reliable way to set attributes.
 */
int
smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr)
{
	struct smb_sb_info *server = server_from_dentry(dir);
	int result;

	VERBOSE("setting %s/%s, open=%d\n", 
		DENTRY_PATH(dir), smb_is_open(dir->d_inode));
	result = smb_proc_setattr_core(server, dir, fattr->attr);
	return result;
}

/*
 * Sets the timestamps for an file open with write permissions.
 */
static int
smb_proc_setattr_ext(struct smb_sb_info *server,
		      struct inode *inode, struct smb_fattr *fattr)
{
	__u16 date, time;
	int result;
	struct smb_request *req;

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, 0)))
		goto out;

	smb_setup_header(req, SMBsetattrE, 7, 0);
	WSET(req->rq_header, smb_vwv0, SMB_I(inode)->fileid);
	/* We don't change the creation time */
	WSET(req->rq_header, smb_vwv1, 0);
	WSET(req->rq_header, smb_vwv2, 0);
	date_unix2dos(server, fattr->f_atime.tv_sec, &date, &time);
	WSET(req->rq_header, smb_vwv3, date);
	WSET(req->rq_header, smb_vwv4, time);
	date_unix2dos(server, fattr->f_mtime.tv_sec, &date, &time);
	WSET(req->rq_header, smb_vwv5, date);
	WSET(req->rq_header, smb_vwv6, time);
#ifdef SMBFS_DEBUG_TIMESTAMP
	printk(KERN_DEBUG "smb_proc_setattr_ext: date=%d, time=%d, mtime=%ld\n",
	       date, time, fattr->f_mtime);
#endif

	req->rq_flags |= SMB_REQ_NORETRY;
	result = smb_request_ok(req, SMBsetattrE, 0, 0);
	if (result < 0)
		goto out_free;
	result = 0;
out_free:
	smb_rput(req);
out:
	return result;
}

/*
 * Bugs Noted:
 * (1) The TRANSACT2_SETPATHINFO message under Win NT 4.0 doesn't
 * set the file's attribute flags.
 */
static int
smb_proc_setattr_trans2(struct smb_sb_info *server,
			struct dentry *dir, struct smb_fattr *fattr)
{
	__u16 date, time;
	char *p, *param;
	int result;
	char data[26];
	struct smb_request *req;

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, PAGE_SIZE)))
		goto out;
	param = req->rq_buffer;

	WSET(param, 0, 1);	/* Info level SMB_INFO_STANDARD */
	DSET(param, 2, 0);
	result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, dir, NULL);
	if (result < 0)
		goto out_free;
	p = param + 6 + result;

	WSET(data, 0, 0); /* creation time */
	WSET(data, 2, 0);
	date_unix2dos(server, fattr->f_atime.tv_sec, &date, &time);
	WSET(data, 4, date);
	WSET(data, 6, time);
	date_unix2dos(server, fattr->f_mtime.tv_sec, &date, &time);
	WSET(data, 8, date);
	WSET(data, 10, time);
#ifdef SMBFS_DEBUG_TIMESTAMP
	printk(KERN_DEBUG "setattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n", 
	       DENTRY_PATH(dir), date, time, fattr->f_mtime);
#endif
	DSET(data, 12, 0); /* size */
	DSET(data, 16, 0); /* blksize */
	WSET(data, 20, 0); /* attr */
	DSET(data, 22, 0); /* ULONG EA size */

	req->rq_trans2_command = TRANSACT2_SETPATHINFO;
	req->rq_ldata = 26;
	req->rq_data  = data;
	req->rq_lparm = p - param;
	req->rq_parm  = param;
	req->rq_flags = 0;
	result = smb_add_request(req);
	if (result < 0)
		goto out_free;
	result = 0;
	if (req->rq_rcls != 0)
		result = smb_errno(req);

out_free:
	smb_rput(req);
out:
	return result;
}

/*
 * ATTR_MODE      0x001
 * ATTR_UID       0x002
 * ATTR_GID       0x004
 * ATTR_SIZE      0x008
 * ATTR_ATIME     0x010
 * ATTR_MTIME     0x020
 * ATTR_CTIME     0x040
 * ATTR_ATIME_SET 0x080
 * ATTR_MTIME_SET 0x100
 * ATTR_FORCE     0x200	
 * ATTR_ATTR_FLAG 0x400
 *
 * major/minor should only be set by mknod.
 */
int
smb_proc_setattr_unix(struct dentry *d, struct iattr *attr,
		      unsigned int major, unsigned int minor)
{
	struct smb_sb_info *server = server_from_dentry(d);
	u64 nttime;
	char *p, *param;
	int result;
	char data[100];
	struct smb_request *req;

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, PAGE_SIZE)))
		goto out;
	param = req->rq_buffer;

	DEBUG1("valid flags = 0x%04x\n", attr->ia_valid);

	WSET(param, 0, SMB_SET_FILE_UNIX_BASIC);
	DSET(param, 2, 0);
	result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, d, NULL);
	if (result < 0)
		goto out_free;
	p = param + 6 + result;

	/* 0 L file size in bytes */
	/* 8 L file size on disk in bytes (block count) */
	/* 40 L uid */
	/* 48 L gid */
	/* 56 W file type enum */
	/* 60 L devmajor */
	/* 68 L devminor */
	/* 76 L unique ID (inode) */
	/* 84 L permissions */
	/* 92 L link count */
	LSET(data, 0, SMB_SIZE_NO_CHANGE);
	LSET(data, 8, SMB_SIZE_NO_CHANGE);
	LSET(data, 16, SMB_TIME_NO_CHANGE);
	LSET(data, 24, SMB_TIME_NO_CHANGE);
	LSET(data, 32, SMB_TIME_NO_CHANGE);
	LSET(data, 40, SMB_UID_NO_CHANGE);
	LSET(data, 48, SMB_GID_NO_CHANGE);
	DSET(data, 56, smb_filetype_from_mode(attr->ia_mode));
	LSET(data, 60, major);
	LSET(data, 68, minor);
	LSET(data, 76, 0);
	LSET(data, 84, SMB_MODE_NO_CHANGE);
	LSET(data, 92, 0);

	if (attr->ia_valid & ATTR_SIZE) {
		LSET(data, 0, attr->ia_size);
		LSET(data, 8, 0); /* can't set anyway */
	}

	/*
	 * FIXME: check the conversion function it the correct one
	 *
	 * we can't set ctime but we might as well pass this to the server
	 * and let it ignore it.
	 */
	if (attr->ia_valid & ATTR_CTIME) {
		nttime = smb_unixutc2ntutc(attr->ia_ctime);
		LSET(data, 16, nttime);
	}
	if (attr->ia_valid & ATTR_ATIME) {
		nttime = smb_unixutc2ntutc(attr->ia_atime);
		LSET(data, 24, nttime);
	}
	if (attr->ia_valid & ATTR_MTIME) {
		nttime = smb_unixutc2ntutc(attr->ia_mtime);
		LSET(data, 32, nttime);
	}
	
	if (attr->ia_valid & ATTR_UID) {
		LSET(data, 40, attr->ia_uid);
	}
	if (attr->ia_valid & ATTR_GID) {
		LSET(data, 48, attr->ia_gid); 
	}
	
	if (attr->ia_valid & ATTR_MODE) {
		LSET(data, 84, attr->ia_mode);
	}

	req->rq_trans2_command = TRANSACT2_SETPATHINFO;
	req->rq_ldata = 100;
	req->rq_data  = data;
	req->rq_lparm = p - param;
	req->rq_parm  = param;
	req->rq_flags = 0;
	result = smb_add_request(req);

out_free:
	smb_rput(req);
out:
	return result;
}


/*
 * Set the modify and access timestamps for a file.
 *
 * Incredibly enough, in all of SMB there is no message to allow
 * setting both attributes and timestamps at once. 
 *
 * Bugs Noted:
 * (1) Win 95 doesn't support the TRANSACT2_SETFILEINFO message 
 * with info level 1 (INFO_STANDARD).
 * (2) Win 95 seems not to support setting directory timestamps.
 * (3) Under the core protocol apparently the only way to set the
 * timestamp is to open and close the file.
 */
int
smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr)
{
	struct smb_sb_info *server = server_from_dentry(dentry);
	struct inode *inode = dentry->d_inode;
	int result;

	VERBOSE("setting %s/%s, open=%d\n",
		DENTRY_PATH(dentry), smb_is_open(inode));

	/* setting the time on a Win95 server fails (tridge) */
	if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2 && 
	    !(server->mnt->flags & SMB_MOUNT_WIN95)) {
		if (smb_is_open(inode) && SMB_I(inode)->access != SMB_O_RDONLY)
			result = smb_proc_setattr_ext(server, inode, fattr);
		else
			result = smb_proc_setattr_trans2(server, dentry, fattr);
	} else {
		/*
		 * Fail silently on directories ... timestamp can't be set?
		 */
		result = 0;
		if (S_ISREG(inode->i_mode)) {
			/*
			 * Set the mtime by opening and closing the file.
			 * Note that the file is opened read-only, but this
			 * still allows us to set the date (tridge)
			 */
			result = -EACCES;
			if (!smb_is_open(inode))
				smb_proc_open(server, dentry, SMB_O_RDONLY);
			if (smb_is_open(inode)) {
				inode->i_mtime = fattr->f_mtime;
				result = smb_proc_close_inode(server, inode);
			}
		}
	}

	return result;
}

int
smb_proc_dskattr(struct dentry *dentry, struct kstatfs *attr)
{
	struct smb_sb_info *server = SMB_SB(dentry->d_sb);
	int result;
	char *p;
	long unit;
	struct smb_request *req;

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, 0)))
		goto out;

	smb_setup_header(req, SMBdskattr, 0, 0);
	if ((result = smb_request_ok(req, SMBdskattr, 5, 0)) < 0)
		goto out_free;
	p = SMB_VWV(req->rq_header);
	unit = (WVAL(p, 2) * WVAL(p, 4)) >> SMB_ST_BLKSHIFT;
	attr->f_blocks = WVAL(p, 0) * unit;
	attr->f_bsize  = SMB_ST_BLKSIZE;
	attr->f_bavail = attr->f_bfree = WVAL(p, 6) * unit;
	result = 0;

out_free:
	smb_rput(req);
out:
	return result;
}

int
smb_proc_read_link(struct smb_sb_info *server, struct dentry *d,
		   char *buffer, int len)
{
	char *p, *param;
	int result;
	struct smb_request *req;

	DEBUG1("readlink of %s/%s\n", DENTRY_PATH(d));

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, PAGE_SIZE)))
		goto out;
	param = req->rq_buffer;

	WSET(param, 0, SMB_QUERY_FILE_UNIX_LINK);
	DSET(param, 2, 0);
	result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, d, NULL);
	if (result < 0)
		goto out_free;
	p = param + 6 + result;

	req->rq_trans2_command = TRANSACT2_QPATHINFO;
	req->rq_ldata = 0;
	req->rq_data  = NULL;
	req->rq_lparm = p - param;
	req->rq_parm  = param;
	req->rq_flags = 0;
	result = smb_add_request(req);
	if (result < 0)
		goto out_free;
	DEBUG1("for %s: result=%d, rcls=%d, err=%d\n",
		&param[6], result, req->rq_rcls, req->rq_err);

	/* copy data up to the \0 or buffer length */
	result = len;
	if (req->rq_ldata < len)
		result = req->rq_ldata;
	strncpy(buffer, req->rq_data, result);

out_free:
	smb_rput(req);
out:
	return result;
}


/*
 * Create a symlink object called dentry which points to oldpath.
 * Samba does not permit dangling links but returns a suitable error message.
 */
int
smb_proc_symlink(struct smb_sb_info *server, struct dentry *d,
		 const char *oldpath)
{
	char *p, *param;
	int result;
	struct smb_request *req;

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, PAGE_SIZE)))
		goto out;
	param = req->rq_buffer;

	WSET(param, 0, SMB_SET_FILE_UNIX_LINK);
	DSET(param, 2, 0);
	result = smb_encode_path(server, param + 6, SMB_MAXPATHLEN+1, d, NULL);
	if (result < 0)
		goto out_free;
	p = param + 6 + result;

	req->rq_trans2_command = TRANSACT2_SETPATHINFO;
	req->rq_ldata = strlen(oldpath) + 1;
	req->rq_data  = (char *) oldpath;
	req->rq_lparm = p - param;
	req->rq_parm  = param;
	req->rq_flags = 0;
	result = smb_add_request(req);
	if (result < 0)
		goto out_free;

	DEBUG1("for %s: result=%d, rcls=%d, err=%d\n",
		&param[6], result, req->rq_rcls, req->rq_err);
	result = 0;

out_free:
	smb_rput(req);
out:
	return result;
}

/*
 * Create a hard link object called new_dentry which points to dentry.
 */
int
smb_proc_link(struct smb_sb_info *server, struct dentry *dentry,
	      struct dentry *new_dentry)
{
	char *p, *param;
	int result;
	struct smb_request *req;

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, PAGE_SIZE)))
		goto out;
	param = req->rq_buffer;

	WSET(param, 0, SMB_SET_FILE_UNIX_HLINK);
	DSET(param, 2, 0);
	result = smb_encode_path(server, param + 6, SMB_MAXPATHLEN+1,
				 new_dentry, NULL);
	if (result < 0)
		goto out_free;
	p = param + 6 + result;

	/* Grr, pointless separation of parameters and data ... */
	req->rq_data = p;
	req->rq_ldata = smb_encode_path(server, p, SMB_MAXPATHLEN+1,
					dentry, NULL);

	req->rq_trans2_command = TRANSACT2_SETPATHINFO;
	req->rq_lparm = p - param;
	req->rq_parm  = param;
	req->rq_flags = 0;
	result = smb_add_request(req);
	if (result < 0)
		goto out_free;

	DEBUG1("for %s: result=%d, rcls=%d, err=%d\n",
	       &param[6], result, req->rq_rcls, req->rq_err);
	result = 0;

out_free:
	smb_rput(req);
out:
	return result;
}

static int
smb_proc_query_cifsunix(struct smb_sb_info *server)
{
	int result;
	int major, minor;
	u64 caps;
	char param[2];
	struct smb_request *req;

	result = -ENOMEM;
	if (! (req = smb_alloc_request(server, 100)))
		goto out;

	WSET(param, 0, SMB_QUERY_CIFS_UNIX_INFO);

	req->rq_trans2_command = TRANSACT2_QFSINFO;
	req->rq_ldata = 0;
	req->rq_data  = NULL;
	req->rq_lparm = 2;
	req->rq_parm  = param;
	req->rq_flags = 0;
	result = smb_add_request(req);
	if (result < 0)
		goto out_free;

	if (req->rq_ldata < 12) {
		PARANOIA("Not enough data\n");
		goto out_free;
	}
	major = WVAL(req->rq_data, 0);
	minor = WVAL(req->rq_data, 2);

	DEBUG1("Server implements CIFS Extensions for UNIX systems v%d.%d\n",
	       major, minor);
	/* FIXME: verify that we are ok with this major/minor? */

	caps = LVAL(req->rq_data, 4);
	DEBUG1("Server capabilities 0x%016llx\n", caps);

out_free:
	smb_rput(req);
out:
	return result;
}


static void
install_ops(struct smb_ops *dst, struct smb_ops *src)
{
	memcpy(dst, src, sizeof(void *) * SMB_OPS_NUM_STATIC);
}

/* < LANMAN2 */
static struct smb_ops smb_ops_core =
{
	.read		= smb_proc_read,
	.write		= smb_proc_write,
	.readdir	= smb_proc_readdir_short,
	.getattr	= smb_proc_getattr_core,
	.truncate	= smb_proc_trunc32,
};

/* LANMAN2, OS/2, others? */
static struct smb_ops smb_ops_os2 =
{
	.read		= smb_proc_read,
	.write		= smb_proc_write,
	.readdir	= smb_proc_readdir_long,
	.getattr	= smb_proc_getattr_trans2_std,
	.truncate	= smb_proc_trunc32,
};

/* Win95, and possibly some NetApp versions too */
static struct smb_ops smb_ops_win95 =
{
	.read		= smb_proc_read,    /* does not support 12word readX */
	.write		= smb_proc_write,
	.readdir	= smb_proc_readdir_long,
	.getattr	= smb_proc_getattr_95,
	.truncate	= smb_proc_trunc95,
};

/* Samba, NT4 and NT5 */
static struct smb_ops smb_ops_winNT =
{
	.read		= smb_proc_readX,
	.write		= smb_proc_writeX,
	.readdir	= smb_proc_readdir_long,
	.getattr	= smb_proc_getattr_trans2_all,
	.truncate	= smb_proc_trunc64,
};

/* Samba w/ unix extensions. Others? */
static struct smb_ops smb_ops_unix =
{
	.read		= smb_proc_readX,
	.write		= smb_proc_writeX,
	.readdir	= smb_proc_readdir_long,
	.getattr	= smb_proc_getattr_unix,
	/* FIXME: core/ext/time setattr needs to be cleaned up! */
	/* .setattr	= smb_proc_setattr_unix, */
	.truncate	= smb_proc_trunc64,
};

/* Place holder until real ops are in place */
static struct smb_ops smb_ops_null =
{
	.readdir	= smb_proc_readdir_null,
	.getattr	= smb_proc_getattr_null,
};

void smb_install_null_ops(struct smb_ops *ops)
{
	install_ops(ops, &smb_ops_null);
}
