Linux Audio

Check our new training course

Yocto / OpenEmbedded training

Mar 24-27, 2025, special US time zones
Register
Loading...
Note: File does not exist in v4.17.
   1/*
   2 *  inode.c
   3 *
   4 *  Copyright (C) 1995, 1996 by Volker Lendecke
   5 *  Modified for big endian by J.F. Chadima and David S. Miller
   6 *  Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache
   7 *  Modified 1998 Wolfram Pienkoss for NLS
   8 *  Modified 2000 Ben Harris, University of Cambridge for NFS NS meta-info
   9 *
  10 */
  11
  12#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  13
  14#include <linux/module.h>
  15
  16#include <asm/uaccess.h>
  17#include <asm/byteorder.h>
  18
  19#include <linux/time.h>
  20#include <linux/kernel.h>
  21#include <linux/mm.h>
  22#include <linux/string.h>
  23#include <linux/stat.h>
  24#include <linux/errno.h>
  25#include <linux/file.h>
  26#include <linux/fcntl.h>
  27#include <linux/slab.h>
  28#include <linux/vmalloc.h>
  29#include <linux/init.h>
  30#include <linux/vfs.h>
  31#include <linux/mount.h>
  32#include <linux/seq_file.h>
  33#include <linux/namei.h>
  34
  35#include <net/sock.h>
  36
  37#include "ncp_fs.h"
  38#include "getopt.h"
  39
  40#define NCP_DEFAULT_FILE_MODE 0600
  41#define NCP_DEFAULT_DIR_MODE 0700
  42#define NCP_DEFAULT_TIME_OUT 10
  43#define NCP_DEFAULT_RETRY_COUNT 20
  44
  45static void ncp_evict_inode(struct inode *);
  46static void ncp_put_super(struct super_block *);
  47static int  ncp_statfs(struct dentry *, struct kstatfs *);
  48static int  ncp_show_options(struct seq_file *, struct dentry *);
  49
  50static struct kmem_cache * ncp_inode_cachep;
  51
  52static struct inode *ncp_alloc_inode(struct super_block *sb)
  53{
  54	struct ncp_inode_info *ei;
  55	ei = (struct ncp_inode_info *)kmem_cache_alloc(ncp_inode_cachep, GFP_KERNEL);
  56	if (!ei)
  57		return NULL;
  58	return &ei->vfs_inode;
  59}
  60
  61static void ncp_i_callback(struct rcu_head *head)
  62{
  63	struct inode *inode = container_of(head, struct inode, i_rcu);
  64	kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode));
  65}
  66
  67static void ncp_destroy_inode(struct inode *inode)
  68{
  69	call_rcu(&inode->i_rcu, ncp_i_callback);
  70}
  71
  72static void init_once(void *foo)
  73{
  74	struct ncp_inode_info *ei = (struct ncp_inode_info *) foo;
  75
  76	mutex_init(&ei->open_mutex);
  77	inode_init_once(&ei->vfs_inode);
  78}
  79
  80static int init_inodecache(void)
  81{
  82	ncp_inode_cachep = kmem_cache_create("ncp_inode_cache",
  83					     sizeof(struct ncp_inode_info),
  84					     0, (SLAB_RECLAIM_ACCOUNT|
  85						SLAB_MEM_SPREAD),
  86					     init_once);
  87	if (ncp_inode_cachep == NULL)
  88		return -ENOMEM;
  89	return 0;
  90}
  91
  92static void destroy_inodecache(void)
  93{
  94	/*
  95	 * Make sure all delayed rcu free inodes are flushed before we
  96	 * destroy cache.
  97	 */
  98	rcu_barrier();
  99	kmem_cache_destroy(ncp_inode_cachep);
 100}
 101
 102static int ncp_remount(struct super_block *sb, int *flags, char* data)
 103{
 104	sync_filesystem(sb);
 105	*flags |= MS_NODIRATIME;
 106	return 0;
 107}
 108
 109static const struct super_operations ncp_sops =
 110{
 111	.alloc_inode	= ncp_alloc_inode,
 112	.destroy_inode	= ncp_destroy_inode,
 113	.drop_inode	= generic_delete_inode,
 114	.evict_inode	= ncp_evict_inode,
 115	.put_super	= ncp_put_super,
 116	.statfs		= ncp_statfs,
 117	.remount_fs	= ncp_remount,
 118	.show_options	= ncp_show_options,
 119};
 120
 121/*
 122 * Fill in the ncpfs-specific information in the inode.
 123 */
 124static void ncp_update_dirent(struct inode *inode, struct ncp_entry_info *nwinfo)
 125{
 126	NCP_FINFO(inode)->DosDirNum = nwinfo->i.DosDirNum;
 127	NCP_FINFO(inode)->dirEntNum = nwinfo->i.dirEntNum;
 128	NCP_FINFO(inode)->volNumber = nwinfo->volume;
 129}
 130
 131void ncp_update_inode(struct inode *inode, struct ncp_entry_info *nwinfo)
 132{
 133	ncp_update_dirent(inode, nwinfo);
 134	NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
 135	NCP_FINFO(inode)->access = nwinfo->access;
 136	memcpy(NCP_FINFO(inode)->file_handle, nwinfo->file_handle,
 137			sizeof(nwinfo->file_handle));
 138	ncp_dbg(1, "updated %s, volnum=%d, dirent=%u\n",
 139		nwinfo->i.entryName, NCP_FINFO(inode)->volNumber,
 140		NCP_FINFO(inode)->dirEntNum);
 141}
 142
 143static void ncp_update_dates(struct inode *inode, struct nw_info_struct *nwi)
 144{
 145	/* NFS namespace mode overrides others if it's set. */
 146	ncp_dbg(1, "(%s) nfs.mode=0%o\n", nwi->entryName, nwi->nfs.mode);
 147	if (nwi->nfs.mode) {
 148		/* XXX Security? */
 149		inode->i_mode = nwi->nfs.mode;
 150	}
 151
 152	inode->i_blocks = (i_size_read(inode) + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
 153
 154	inode->i_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate);
 155	inode->i_ctime.tv_sec = ncp_date_dos2unix(nwi->creationTime, nwi->creationDate);
 156	inode->i_atime.tv_sec = ncp_date_dos2unix(0, nwi->lastAccessDate);
 157	inode->i_atime.tv_nsec = 0;
 158	inode->i_mtime.tv_nsec = 0;
 159	inode->i_ctime.tv_nsec = 0;
 160}
 161
 162static void ncp_update_attrs(struct inode *inode, struct ncp_entry_info *nwinfo)
 163{
 164	struct nw_info_struct *nwi = &nwinfo->i;
 165	struct ncp_server *server = NCP_SERVER(inode);
 166
 167	if (nwi->attributes & aDIR) {
 168		inode->i_mode = server->m.dir_mode;
 169		/* for directories dataStreamSize seems to be some
 170		   Object ID ??? */
 171		i_size_write(inode, NCP_BLOCK_SIZE);
 172	} else {
 173		u32 size;
 174
 175		inode->i_mode = server->m.file_mode;
 176		size = le32_to_cpu(nwi->dataStreamSize);
 177		i_size_write(inode, size);
 178#ifdef CONFIG_NCPFS_EXTRAS
 179		if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS)) 
 180		 && (nwi->attributes & aSHARED)) {
 181			switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
 182				case aHIDDEN:
 183					if (server->m.flags & NCP_MOUNT_SYMLINKS) {
 184						if (/* (size >= NCP_MIN_SYMLINK_SIZE)
 185						 && */ (size <= NCP_MAX_SYMLINK_SIZE)) {
 186							inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
 187							NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK;
 188							break;
 189						}
 190					}
 191					/* FALLTHROUGH */
 192				case 0:
 193					if (server->m.flags & NCP_MOUNT_EXTRAS)
 194						inode->i_mode |= S_IRUGO;
 195					break;
 196				case aSYSTEM:
 197					if (server->m.flags & NCP_MOUNT_EXTRAS)
 198						inode->i_mode |= (inode->i_mode >> 2) & S_IXUGO;
 199					break;
 200				/* case aSYSTEM|aHIDDEN: */
 201				default:
 202					/* reserved combination */
 203					break;
 204			}
 205		}
 206#endif
 207	}
 208	if (nwi->attributes & aRONLY) inode->i_mode &= ~S_IWUGO;
 209}
 210
 211void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo)
 212{
 213	NCP_FINFO(inode)->flags = 0;
 214	if (!atomic_read(&NCP_FINFO(inode)->opened)) {
 215		NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
 216		ncp_update_attrs(inode, nwinfo);
 217	}
 218
 219	ncp_update_dates(inode, &nwinfo->i);
 220	ncp_update_dirent(inode, nwinfo);
 221}
 222
 223/*
 224 * Fill in the inode based on the ncp_entry_info structure.  Used only for brand new inodes.
 225 */
 226static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
 227{
 228	struct ncp_server *server = NCP_SERVER(inode);
 229
 230	NCP_FINFO(inode)->flags = 0;
 231	
 232	ncp_update_attrs(inode, nwinfo);
 233
 234	ncp_dbg(2, "inode->i_mode = %u\n", inode->i_mode);
 235
 236	set_nlink(inode, 1);
 237	inode->i_uid = server->m.uid;
 238	inode->i_gid = server->m.gid;
 239
 240	ncp_update_dates(inode, &nwinfo->i);
 241	ncp_update_inode(inode, nwinfo);
 242}
 243
 244#if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
 245static const struct inode_operations ncp_symlink_inode_operations = {
 246	.readlink	= generic_readlink,
 247	.follow_link	= page_follow_link_light,
 248	.put_link	= page_put_link,
 249	.setattr	= ncp_notify_change,
 250};
 251#endif
 252
 253/*
 254 * Get a new inode.
 255 */
 256struct inode * 
 257ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
 258{
 259	struct inode *inode;
 260
 261	if (info == NULL) {
 262		pr_err("%s: info is NULL\n", __func__);
 263		return NULL;
 264	}
 265
 266	inode = new_inode(sb);
 267	if (inode) {
 268		atomic_set(&NCP_FINFO(inode)->opened, info->opened);
 269
 270		inode->i_mapping->backing_dev_info = sb->s_bdi;
 271		inode->i_ino = info->ino;
 272		ncp_set_attr(inode, info);
 273		if (S_ISREG(inode->i_mode)) {
 274			inode->i_op = &ncp_file_inode_operations;
 275			inode->i_fop = &ncp_file_operations;
 276		} else if (S_ISDIR(inode->i_mode)) {
 277			inode->i_op = &ncp_dir_inode_operations;
 278			inode->i_fop = &ncp_dir_operations;
 279#ifdef CONFIG_NCPFS_NFS_NS
 280		} else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
 281			init_special_inode(inode, inode->i_mode,
 282				new_decode_dev(info->i.nfs.rdev));
 283#endif
 284#if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
 285		} else if (S_ISLNK(inode->i_mode)) {
 286			inode->i_op = &ncp_symlink_inode_operations;
 287			inode->i_data.a_ops = &ncp_symlink_aops;
 288#endif
 289		} else {
 290			make_bad_inode(inode);
 291		}
 292		insert_inode_hash(inode);
 293	} else
 294		pr_err("%s: iget failed!\n", __func__);
 295	return inode;
 296}
 297
 298static void
 299ncp_evict_inode(struct inode *inode)
 300{
 301	truncate_inode_pages_final(&inode->i_data);
 302	clear_inode(inode);
 303
 304	if (S_ISDIR(inode->i_mode)) {
 305		ncp_dbg(2, "put directory %ld\n", inode->i_ino);
 306	}
 307
 308	if (ncp_make_closed(inode) != 0) {
 309		/* We can't do anything but complain. */
 310		pr_err("%s: could not close\n", __func__);
 311	}
 312}
 313
 314static void ncp_stop_tasks(struct ncp_server *server) {
 315	struct sock* sk = server->ncp_sock->sk;
 316
 317	lock_sock(sk);
 318	sk->sk_error_report = server->error_report;
 319	sk->sk_data_ready   = server->data_ready;
 320	sk->sk_write_space  = server->write_space;
 321	release_sock(sk);
 322	del_timer_sync(&server->timeout_tm);
 323
 324	flush_work(&server->rcv.tq);
 325	if (sk->sk_socket->type == SOCK_STREAM)
 326		flush_work(&server->tx.tq);
 327	else
 328		flush_work(&server->timeout_tq);
 329}
 330
 331static int  ncp_show_options(struct seq_file *seq, struct dentry *root)
 332{
 333	struct ncp_server *server = NCP_SBP(root->d_sb);
 334	unsigned int tmp;
 335
 336	if (!uid_eq(server->m.uid, GLOBAL_ROOT_UID))
 337		seq_printf(seq, ",uid=%u",
 338			   from_kuid_munged(&init_user_ns, server->m.uid));
 339	if (!gid_eq(server->m.gid, GLOBAL_ROOT_GID))
 340		seq_printf(seq, ",gid=%u",
 341			   from_kgid_munged(&init_user_ns, server->m.gid));
 342	if (!uid_eq(server->m.mounted_uid, GLOBAL_ROOT_UID))
 343		seq_printf(seq, ",owner=%u",
 344			   from_kuid_munged(&init_user_ns, server->m.mounted_uid));
 345	tmp = server->m.file_mode & S_IALLUGO;
 346	if (tmp != NCP_DEFAULT_FILE_MODE)
 347		seq_printf(seq, ",mode=0%o", tmp);
 348	tmp = server->m.dir_mode & S_IALLUGO;
 349	if (tmp != NCP_DEFAULT_DIR_MODE)
 350		seq_printf(seq, ",dirmode=0%o", tmp);
 351	if (server->m.time_out != NCP_DEFAULT_TIME_OUT * HZ / 100) {
 352		tmp = server->m.time_out * 100 / HZ;
 353		seq_printf(seq, ",timeout=%u", tmp);
 354	}
 355	if (server->m.retry_count != NCP_DEFAULT_RETRY_COUNT)
 356		seq_printf(seq, ",retry=%u", server->m.retry_count);
 357	if (server->m.flags != 0)
 358		seq_printf(seq, ",flags=%lu", server->m.flags);
 359	if (server->m.wdog_pid != NULL)
 360		seq_printf(seq, ",wdogpid=%u", pid_vnr(server->m.wdog_pid));
 361
 362	return 0;
 363}
 364
 365static const struct ncp_option ncp_opts[] = {
 366	{ "uid",	OPT_INT,	'u' },
 367	{ "gid",	OPT_INT,	'g' },
 368	{ "owner",	OPT_INT,	'o' },
 369	{ "mode",	OPT_INT,	'm' },
 370	{ "dirmode",	OPT_INT,	'd' },
 371	{ "timeout",	OPT_INT,	't' },
 372	{ "retry",	OPT_INT,	'r' },
 373	{ "flags",	OPT_INT,	'f' },
 374	{ "wdogpid",	OPT_INT,	'w' },
 375	{ "ncpfd",	OPT_INT,	'n' },
 376	{ "infofd",	OPT_INT,	'i' },	/* v5 */
 377	{ "version",	OPT_INT,	'v' },
 378	{ NULL,		0,		0 } };
 379
 380static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) {
 381	int optval;
 382	char *optarg;
 383	unsigned long optint;
 384	int version = 0;
 385	int ret;
 386
 387	data->flags = 0;
 388	data->int_flags = 0;
 389	data->mounted_uid = GLOBAL_ROOT_UID;
 390	data->wdog_pid = NULL;
 391	data->ncp_fd = ~0;
 392	data->time_out = NCP_DEFAULT_TIME_OUT;
 393	data->retry_count = NCP_DEFAULT_RETRY_COUNT;
 394	data->uid = GLOBAL_ROOT_UID;
 395	data->gid = GLOBAL_ROOT_GID;
 396	data->file_mode = NCP_DEFAULT_FILE_MODE;
 397	data->dir_mode = NCP_DEFAULT_DIR_MODE;
 398	data->info_fd = -1;
 399	data->mounted_vol[0] = 0;
 400	
 401	while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 0) {
 402		ret = optval;
 403		if (ret < 0)
 404			goto err;
 405		switch (optval) {
 406			case 'u':
 407				data->uid = make_kuid(current_user_ns(), optint);
 408				if (!uid_valid(data->uid)) {
 409					ret = -EINVAL;
 410					goto err;
 411				}
 412				break;
 413			case 'g':
 414				data->gid = make_kgid(current_user_ns(), optint);
 415				if (!gid_valid(data->gid)) {
 416					ret = -EINVAL;
 417					goto err;
 418				}
 419				break;
 420			case 'o':
 421				data->mounted_uid = make_kuid(current_user_ns(), optint);
 422				if (!uid_valid(data->mounted_uid)) {
 423					ret = -EINVAL;
 424					goto err;
 425				}
 426				break;
 427			case 'm':
 428				data->file_mode = optint;
 429				break;
 430			case 'd':
 431				data->dir_mode = optint;
 432				break;
 433			case 't':
 434				data->time_out = optint;
 435				break;
 436			case 'r':
 437				data->retry_count = optint;
 438				break;
 439			case 'f':
 440				data->flags = optint;
 441				break;
 442			case 'w':
 443				data->wdog_pid = find_get_pid(optint);
 444				break;
 445			case 'n':
 446				data->ncp_fd = optint;
 447				break;
 448			case 'i':
 449				data->info_fd = optint;
 450				break;
 451			case 'v':
 452				ret = -ECHRNG;
 453				if (optint < NCP_MOUNT_VERSION_V4)
 454					goto err;
 455				if (optint > NCP_MOUNT_VERSION_V5)
 456					goto err;
 457				version = optint;
 458				break;
 459			
 460		}
 461	}
 462	return 0;
 463err:
 464	put_pid(data->wdog_pid);
 465	data->wdog_pid = NULL;
 466	return ret;
 467}
 468
 469static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
 470{
 471	struct ncp_mount_data_kernel data;
 472	struct ncp_server *server;
 473	struct inode *root_inode;
 474	struct socket *sock;
 475	int error;
 476	int default_bufsize;
 477#ifdef CONFIG_NCPFS_PACKET_SIGNING
 478	int options;
 479#endif
 480	struct ncp_entry_info finfo;
 481
 482	memset(&data, 0, sizeof(data));
 483	server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL);
 484	if (!server)
 485		return -ENOMEM;
 486	sb->s_fs_info = server;
 487
 488	error = -EFAULT;
 489	if (raw_data == NULL)
 490		goto out;
 491	switch (*(int*)raw_data) {
 492		case NCP_MOUNT_VERSION:
 493			{
 494				struct ncp_mount_data* md = (struct ncp_mount_data*)raw_data;
 495
 496				data.flags = md->flags;
 497				data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE;
 498				data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid);
 499				data.wdog_pid = find_get_pid(md->wdog_pid);
 500				data.ncp_fd = md->ncp_fd;
 501				data.time_out = md->time_out;
 502				data.retry_count = md->retry_count;
 503				data.uid = make_kuid(current_user_ns(), md->uid);
 504				data.gid = make_kgid(current_user_ns(), md->gid);
 505				data.file_mode = md->file_mode;
 506				data.dir_mode = md->dir_mode;
 507				data.info_fd = -1;
 508				memcpy(data.mounted_vol, md->mounted_vol,
 509					NCP_VOLNAME_LEN+1);
 510			}
 511			break;
 512		case NCP_MOUNT_VERSION_V4:
 513			{
 514				struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data;
 515
 516				data.flags = md->flags;
 517				data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid);
 518				data.wdog_pid = find_get_pid(md->wdog_pid);
 519				data.ncp_fd = md->ncp_fd;
 520				data.time_out = md->time_out;
 521				data.retry_count = md->retry_count;
 522				data.uid = make_kuid(current_user_ns(), md->uid);
 523				data.gid = make_kgid(current_user_ns(), md->gid);
 524				data.file_mode = md->file_mode;
 525				data.dir_mode = md->dir_mode;
 526				data.info_fd = -1;
 527			}
 528			break;
 529		default:
 530			error = -ECHRNG;
 531			if (memcmp(raw_data, "vers", 4) == 0) {
 532				error = ncp_parse_options(&data, raw_data);
 533			}
 534			if (error)
 535				goto out;
 536			break;
 537	}
 538	error = -EINVAL;
 539	if (!uid_valid(data.mounted_uid) || !uid_valid(data.uid) ||
 540	    !gid_valid(data.gid))
 541		goto out;
 542	sock = sockfd_lookup(data.ncp_fd, &error);
 543	if (!sock)
 544		goto out;
 545
 546	if (sock->type == SOCK_STREAM)
 547		default_bufsize = 0xF000;
 548	else
 549		default_bufsize = 1024;
 550
 551	sb->s_flags |= MS_NODIRATIME;	/* probably even noatime */
 552	sb->s_maxbytes = 0xFFFFFFFFU;
 553	sb->s_blocksize = 1024;	/* Eh...  Is this correct? */
 554	sb->s_blocksize_bits = 10;
 555	sb->s_magic = NCP_SUPER_MAGIC;
 556	sb->s_op = &ncp_sops;
 557	sb->s_d_op = &ncp_dentry_operations;
 558	sb->s_bdi = &server->bdi;
 559
 560	server = NCP_SBP(sb);
 561	memset(server, 0, sizeof(*server));
 562
 563	error = bdi_setup_and_register(&server->bdi, "ncpfs", BDI_CAP_MAP_COPY);
 564	if (error)
 565		goto out_fput;
 566
 567	server->ncp_sock = sock;
 568	
 569	if (data.info_fd != -1) {
 570		struct socket *info_sock = sockfd_lookup(data.info_fd, &error);
 571		if (!info_sock)
 572			goto out_bdi;
 573		server->info_sock = info_sock;
 574		error = -EBADFD;
 575		if (info_sock->type != SOCK_STREAM)
 576			goto out_fput2;
 577	}
 578
 579/*	server->lock = 0;	*/
 580	mutex_init(&server->mutex);
 581	server->packet = NULL;
 582/*	server->buffer_size = 0;	*/
 583/*	server->conn_status = 0;	*/
 584/*	server->root_dentry = NULL;	*/
 585/*	server->root_setuped = 0;	*/
 586	mutex_init(&server->root_setup_lock);
 587#ifdef CONFIG_NCPFS_PACKET_SIGNING
 588/*	server->sign_wanted = 0;	*/
 589/*	server->sign_active = 0;	*/
 590#endif
 591	init_rwsem(&server->auth_rwsem);
 592	server->auth.auth_type = NCP_AUTH_NONE;
 593/*	server->auth.object_name_len = 0;	*/
 594/*	server->auth.object_name = NULL;	*/
 595/*	server->auth.object_type = 0;		*/
 596/*	server->priv.len = 0;			*/
 597/*	server->priv.data = NULL;		*/
 598
 599	server->m = data;
 600	/* Although anything producing this is buggy, it happens
 601	   now because of PATH_MAX changes.. */
 602	if (server->m.time_out < 1) {
 603		server->m.time_out = 10;
 604		pr_info("You need to recompile your ncpfs utils..\n");
 605	}
 606	server->m.time_out = server->m.time_out * HZ / 100;
 607	server->m.file_mode = (server->m.file_mode & S_IRWXUGO) | S_IFREG;
 608	server->m.dir_mode = (server->m.dir_mode & S_IRWXUGO) | S_IFDIR;
 609
 610#ifdef CONFIG_NCPFS_NLS
 611	/* load the default NLS charsets */
 612	server->nls_vol = load_nls_default();
 613	server->nls_io = load_nls_default();
 614#endif /* CONFIG_NCPFS_NLS */
 615
 616	atomic_set(&server->dentry_ttl, 0);	/* no caching */
 617
 618	INIT_LIST_HEAD(&server->tx.requests);
 619	mutex_init(&server->rcv.creq_mutex);
 620	server->tx.creq		= NULL;
 621	server->rcv.creq	= NULL;
 622
 623	init_timer(&server->timeout_tm);
 624#undef NCP_PACKET_SIZE
 625#define NCP_PACKET_SIZE 131072
 626	error = -ENOMEM;
 627	server->packet_size = NCP_PACKET_SIZE;
 628	server->packet = vmalloc(NCP_PACKET_SIZE);
 629	if (server->packet == NULL)
 630		goto out_nls;
 631	server->txbuf = vmalloc(NCP_PACKET_SIZE);
 632	if (server->txbuf == NULL)
 633		goto out_packet;
 634	server->rxbuf = vmalloc(NCP_PACKET_SIZE);
 635	if (server->rxbuf == NULL)
 636		goto out_txbuf;
 637
 638	lock_sock(sock->sk);
 639	server->data_ready	= sock->sk->sk_data_ready;
 640	server->write_space	= sock->sk->sk_write_space;
 641	server->error_report	= sock->sk->sk_error_report;
 642	sock->sk->sk_user_data	= server;
 643	sock->sk->sk_data_ready	  = ncp_tcp_data_ready;
 644	sock->sk->sk_error_report = ncp_tcp_error_report;
 645	if (sock->type == SOCK_STREAM) {
 646		server->rcv.ptr = (unsigned char*)&server->rcv.buf;
 647		server->rcv.len = 10;
 648		server->rcv.state = 0;
 649		INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc);
 650		INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc);
 651		sock->sk->sk_write_space = ncp_tcp_write_space;
 652	} else {
 653		INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc);
 654		INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc);
 655		server->timeout_tm.data = (unsigned long)server;
 656		server->timeout_tm.function = ncpdgram_timeout_call;
 657	}
 658	release_sock(sock->sk);
 659
 660	ncp_lock_server(server);
 661	error = ncp_connect(server);
 662	ncp_unlock_server(server);
 663	if (error < 0)
 664		goto out_rxbuf;
 665	ncp_dbg(1, "NCP_SBP(sb) = %p\n", NCP_SBP(sb));
 666
 667	error = -EMSGSIZE;	/* -EREMOTESIDEINCOMPATIBLE */
 668#ifdef CONFIG_NCPFS_PACKET_SIGNING
 669	if (ncp_negotiate_size_and_options(server, default_bufsize,
 670		NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0)
 671	{
 672		if (options != NCP_DEFAULT_OPTIONS)
 673		{
 674			if (ncp_negotiate_size_and_options(server, 
 675				default_bufsize,
 676				options & 2, 
 677				&(server->buffer_size), &options) != 0)
 678				
 679			{
 680				goto out_disconnect;
 681			}
 682		}
 683		ncp_lock_server(server);
 684		if (options & 2)
 685			server->sign_wanted = 1;
 686		ncp_unlock_server(server);
 687	}
 688	else 
 689#endif	/* CONFIG_NCPFS_PACKET_SIGNING */
 690	if (ncp_negotiate_buffersize(server, default_bufsize,
 691  				     &(server->buffer_size)) != 0)
 692		goto out_disconnect;
 693	ncp_dbg(1, "bufsize = %d\n", server->buffer_size);
 694
 695	memset(&finfo, 0, sizeof(finfo));
 696	finfo.i.attributes	= aDIR;
 697	finfo.i.dataStreamSize	= 0;	/* ignored */
 698	finfo.i.dirEntNum	= 0;
 699	finfo.i.DosDirNum	= 0;
 700#ifdef CONFIG_NCPFS_SMALLDOS
 701	finfo.i.NSCreator	= NW_NS_DOS;
 702#endif
 703	finfo.volume		= NCP_NUMBER_OF_VOLUMES;
 704	/* set dates of mountpoint to Jan 1, 1986; 00:00 */
 705	finfo.i.creationTime	= finfo.i.modifyTime
 706				= cpu_to_le16(0x0000);
 707	finfo.i.creationDate	= finfo.i.modifyDate
 708				= finfo.i.lastAccessDate
 709				= cpu_to_le16(0x0C21);
 710	finfo.i.nameLen		= 0;
 711	finfo.i.entryName[0]	= '\0';
 712
 713	finfo.opened		= 0;
 714	finfo.ino		= 2;	/* tradition */
 715
 716	server->name_space[finfo.volume] = NW_NS_DOS;
 717
 718	error = -ENOMEM;
 719        root_inode = ncp_iget(sb, &finfo);
 720        if (!root_inode)
 721		goto out_disconnect;
 722	ncp_dbg(1, "root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
 723	sb->s_root = d_make_root(root_inode);
 724        if (!sb->s_root)
 725		goto out_disconnect;
 726	return 0;
 727
 728out_disconnect:
 729	ncp_lock_server(server);
 730	ncp_disconnect(server);
 731	ncp_unlock_server(server);
 732out_rxbuf:
 733	ncp_stop_tasks(server);
 734	vfree(server->rxbuf);
 735out_txbuf:
 736	vfree(server->txbuf);
 737out_packet:
 738	vfree(server->packet);
 739out_nls:
 740#ifdef CONFIG_NCPFS_NLS
 741	unload_nls(server->nls_io);
 742	unload_nls(server->nls_vol);
 743#endif
 744	mutex_destroy(&server->rcv.creq_mutex);
 745	mutex_destroy(&server->root_setup_lock);
 746	mutex_destroy(&server->mutex);
 747out_fput2:
 748	if (server->info_sock)
 749		sockfd_put(server->info_sock);
 750out_bdi:
 751	bdi_destroy(&server->bdi);
 752out_fput:
 753	sockfd_put(sock);
 754out:
 755	put_pid(data.wdog_pid);
 756	sb->s_fs_info = NULL;
 757	kfree(server);
 758	return error;
 759}
 760
 761static void delayed_free(struct rcu_head *p)
 762{
 763	struct ncp_server *server = container_of(p, struct ncp_server, rcu);
 764#ifdef CONFIG_NCPFS_NLS
 765	/* unload the NLS charsets */
 766	unload_nls(server->nls_vol);
 767	unload_nls(server->nls_io);
 768#endif /* CONFIG_NCPFS_NLS */
 769	kfree(server);
 770}
 771
 772static void ncp_put_super(struct super_block *sb)
 773{
 774	struct ncp_server *server = NCP_SBP(sb);
 775
 776	ncp_lock_server(server);
 777	ncp_disconnect(server);
 778	ncp_unlock_server(server);
 779
 780	ncp_stop_tasks(server);
 781
 782	mutex_destroy(&server->rcv.creq_mutex);
 783	mutex_destroy(&server->root_setup_lock);
 784	mutex_destroy(&server->mutex);
 785
 786	if (server->info_sock)
 787		sockfd_put(server->info_sock);
 788	sockfd_put(server->ncp_sock);
 789	kill_pid(server->m.wdog_pid, SIGTERM, 1);
 790	put_pid(server->m.wdog_pid);
 791
 792	bdi_destroy(&server->bdi);
 793	kfree(server->priv.data);
 794	kfree(server->auth.object_name);
 795	vfree(server->rxbuf);
 796	vfree(server->txbuf);
 797	vfree(server->packet);
 798	call_rcu(&server->rcu, delayed_free);
 799}
 800
 801static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
 802{
 803	struct dentry* d;
 804	struct inode* i;
 805	struct ncp_inode_info* ni;
 806	struct ncp_server* s;
 807	struct ncp_volume_info vi;
 808	struct super_block *sb = dentry->d_sb;
 809	int err;
 810	__u8 dh;
 811	
 812	d = sb->s_root;
 813	if (!d) {
 814		goto dflt;
 815	}
 816	i = d->d_inode;
 817	if (!i) {
 818		goto dflt;
 819	}
 820	ni = NCP_FINFO(i);
 821	if (!ni) {
 822		goto dflt;
 823	}
 824	s = NCP_SBP(sb);
 825	if (!s) {
 826		goto dflt;
 827	}
 828	if (!s->m.mounted_vol[0]) {
 829		goto dflt;
 830	}
 831
 832	err = ncp_dirhandle_alloc(s, ni->volNumber, ni->DosDirNum, &dh);
 833	if (err) {
 834		goto dflt;
 835	}
 836	err = ncp_get_directory_info(s, dh, &vi);
 837	ncp_dirhandle_free(s, dh);
 838	if (err) {
 839		goto dflt;
 840	}
 841	buf->f_type = NCP_SUPER_MAGIC;
 842	buf->f_bsize = vi.sectors_per_block * 512;
 843	buf->f_blocks = vi.total_blocks;
 844	buf->f_bfree = vi.free_blocks;
 845	buf->f_bavail = vi.free_blocks;
 846	buf->f_files = vi.total_dir_entries;
 847	buf->f_ffree = vi.available_dir_entries;
 848	buf->f_namelen = 12;
 849	return 0;
 850
 851	/* We cannot say how much disk space is left on a mounted
 852	   NetWare Server, because free space is distributed over
 853	   volumes, and the current user might have disk quotas. So
 854	   free space is not that simple to determine. Our decision
 855	   here is to err conservatively. */
 856
 857dflt:;
 858	buf->f_type = NCP_SUPER_MAGIC;
 859	buf->f_bsize = NCP_BLOCK_SIZE;
 860	buf->f_blocks = 0;
 861	buf->f_bfree = 0;
 862	buf->f_bavail = 0;
 863	buf->f_namelen = 12;
 864	return 0;
 865}
 866
 867int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
 868{
 869	struct inode *inode = dentry->d_inode;
 870	int result = 0;
 871	__le32 info_mask;
 872	struct nw_modify_dos_info info;
 873	struct ncp_server *server;
 874
 875	result = -EIO;
 876
 877	server = NCP_SERVER(inode);
 878	if (!server)	/* How this could happen? */
 879		goto out;
 880
 881	result = -EPERM;
 882	if (IS_DEADDIR(dentry->d_inode))
 883		goto out;
 884
 885	/* ageing the dentry to force validation */
 886	ncp_age_dentry(server, dentry);
 887
 888	result = inode_change_ok(inode, attr);
 889	if (result < 0)
 890		goto out;
 891
 892	result = -EPERM;
 893	if ((attr->ia_valid & ATTR_UID) && !uid_eq(attr->ia_uid, server->m.uid))
 894		goto out;
 895
 896	if ((attr->ia_valid & ATTR_GID) && !gid_eq(attr->ia_gid, server->m.gid))
 897		goto out;
 898
 899	if (((attr->ia_valid & ATTR_MODE) &&
 900	     (attr->ia_mode &
 901	      ~(S_IFREG | S_IFDIR | S_IRWXUGO))))
 902		goto out;
 903
 904	info_mask = 0;
 905	memset(&info, 0, sizeof(info));
 906
 907#if 1 
 908        if ((attr->ia_valid & ATTR_MODE) != 0)
 909        {
 910		umode_t newmode = attr->ia_mode;
 911
 912		info_mask |= DM_ATTRIBUTES;
 913
 914                if (S_ISDIR(inode->i_mode)) {
 915                	newmode &= server->m.dir_mode;
 916		} else {
 917#ifdef CONFIG_NCPFS_EXTRAS			
 918			if (server->m.flags & NCP_MOUNT_EXTRAS) {
 919				/* any non-default execute bit set */
 920				if (newmode & ~server->m.file_mode & S_IXUGO)
 921					info.attributes |= aSHARED | aSYSTEM;
 922				/* read for group/world and not in default file_mode */
 923				else if (newmode & ~server->m.file_mode & S_IRUGO)
 924					info.attributes |= aSHARED;
 925			} else
 926#endif
 927				newmode &= server->m.file_mode;			
 928                }
 929                if (newmode & S_IWUGO)
 930                	info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
 931                else
 932			info.attributes |=  (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
 933
 934#ifdef CONFIG_NCPFS_NFS_NS
 935		if (ncp_is_nfs_extras(server, NCP_FINFO(inode)->volNumber)) {
 936			result = ncp_modify_nfs_info(server,
 937						     NCP_FINFO(inode)->volNumber,
 938						     NCP_FINFO(inode)->dirEntNum,
 939						     attr->ia_mode, 0);
 940			if (result != 0)
 941				goto out;
 942			info.attributes &= ~(aSHARED | aSYSTEM);
 943			{
 944				/* mark partial success */
 945				struct iattr tmpattr;
 946				
 947				tmpattr.ia_valid = ATTR_MODE;
 948				tmpattr.ia_mode = attr->ia_mode;
 949
 950				setattr_copy(inode, &tmpattr);
 951				mark_inode_dirty(inode);
 952			}
 953		}
 954#endif
 955        }
 956#endif
 957
 958	/* Do SIZE before attributes, otherwise mtime together with size does not work...
 959	 */
 960	if ((attr->ia_valid & ATTR_SIZE) != 0) {
 961		int written;
 962
 963		ncp_dbg(1, "trying to change size to %llu\n", attr->ia_size);
 964
 965		if ((result = ncp_make_open(inode, O_WRONLY)) < 0) {
 966			result = -EACCES;
 967			goto out;
 968		}
 969		ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
 970			  attr->ia_size, 0, "", &written);
 971
 972		/* According to ndir, the changes only take effect after
 973		   closing the file */
 974		ncp_inode_close(inode);
 975		result = ncp_make_closed(inode);
 976		if (result)
 977			goto out;
 978
 979		if (attr->ia_size != i_size_read(inode)) {
 980			truncate_setsize(inode, attr->ia_size);
 981			mark_inode_dirty(inode);
 982		}
 983	}
 984	if ((attr->ia_valid & ATTR_CTIME) != 0) {
 985		info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE);
 986		ncp_date_unix2dos(attr->ia_ctime.tv_sec,
 987			     &info.creationTime, &info.creationDate);
 988	}
 989	if ((attr->ia_valid & ATTR_MTIME) != 0) {
 990		info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE);
 991		ncp_date_unix2dos(attr->ia_mtime.tv_sec,
 992				  &info.modifyTime, &info.modifyDate);
 993	}
 994	if ((attr->ia_valid & ATTR_ATIME) != 0) {
 995		__le16 dummy;
 996		info_mask |= (DM_LAST_ACCESS_DATE);
 997		ncp_date_unix2dos(attr->ia_atime.tv_sec,
 998				  &dummy, &info.lastAccessDate);
 999	}
1000	if (info_mask != 0) {
1001		result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
1002				      inode, info_mask, &info);
1003		if (result != 0) {
1004			if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
1005				/* NetWare seems not to allow this. I
1006				   do not know why. So, just tell the
1007				   user everything went fine. This is
1008				   a terrible hack, but I do not know
1009				   how to do this correctly. */
1010				result = 0;
1011			} else
1012				goto out;
1013		}
1014#ifdef CONFIG_NCPFS_STRONG		
1015		if ((!result) && (info_mask & DM_ATTRIBUTES))
1016			NCP_FINFO(inode)->nwattr = info.attributes;
1017#endif
1018	}
1019	if (result)
1020		goto out;
1021
1022	setattr_copy(inode, attr);
1023	mark_inode_dirty(inode);
1024
1025out:
1026	if (result > 0)
1027		result = -EACCES;
1028	return result;
1029}
1030
1031static struct dentry *ncp_mount(struct file_system_type *fs_type,
1032	int flags, const char *dev_name, void *data)
1033{
1034	return mount_nodev(fs_type, flags, data, ncp_fill_super);
1035}
1036
1037static struct file_system_type ncp_fs_type = {
1038	.owner		= THIS_MODULE,
1039	.name		= "ncpfs",
1040	.mount		= ncp_mount,
1041	.kill_sb	= kill_anon_super,
1042	.fs_flags	= FS_BINARY_MOUNTDATA,
1043};
1044MODULE_ALIAS_FS("ncpfs");
1045
1046static int __init init_ncp_fs(void)
1047{
1048	int err;
1049	ncp_dbg(1, "called\n");
1050
1051	err = init_inodecache();
1052	if (err)
1053		goto out1;
1054	err = register_filesystem(&ncp_fs_type);
1055	if (err)
1056		goto out;
1057	return 0;
1058out:
1059	destroy_inodecache();
1060out1:
1061	return err;
1062}
1063
1064static void __exit exit_ncp_fs(void)
1065{
1066	ncp_dbg(1, "called\n");
1067	unregister_filesystem(&ncp_fs_type);
1068	destroy_inodecache();
1069}
1070
1071module_init(init_ncp_fs)
1072module_exit(exit_ncp_fs)
1073MODULE_LICENSE("GPL");