Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
   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|SLAB_ACCOUNT),
  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	.get_link	= page_get_link,
 248	.setattr	= ncp_notify_change,
 249};
 250#endif
 251
 252/*
 253 * Get a new inode.
 254 */
 255struct inode * 
 256ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
 257{
 258	struct inode *inode;
 259
 260	if (info == NULL) {
 261		pr_err("%s: info is NULL\n", __func__);
 262		return NULL;
 263	}
 264
 265	inode = new_inode(sb);
 266	if (inode) {
 267		atomic_set(&NCP_FINFO(inode)->opened, info->opened);
 268
 269		inode->i_ino = info->ino;
 270		ncp_set_attr(inode, info);
 271		if (S_ISREG(inode->i_mode)) {
 272			inode->i_op = &ncp_file_inode_operations;
 273			inode->i_fop = &ncp_file_operations;
 274		} else if (S_ISDIR(inode->i_mode)) {
 275			inode->i_op = &ncp_dir_inode_operations;
 276			inode->i_fop = &ncp_dir_operations;
 277#ifdef CONFIG_NCPFS_NFS_NS
 278		} else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
 279			init_special_inode(inode, inode->i_mode,
 280				new_decode_dev(info->i.nfs.rdev));
 281#endif
 282#if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
 283		} else if (S_ISLNK(inode->i_mode)) {
 284			inode->i_op = &ncp_symlink_inode_operations;
 285			inode_nohighmem(inode);
 286			inode->i_data.a_ops = &ncp_symlink_aops;
 287#endif
 288		} else {
 289			make_bad_inode(inode);
 290		}
 291		insert_inode_hash(inode);
 292	} else
 293		pr_err("%s: iget failed!\n", __func__);
 294	return inode;
 295}
 296
 297static void
 298ncp_evict_inode(struct inode *inode)
 299{
 300	truncate_inode_pages_final(&inode->i_data);
 301	clear_inode(inode);
 302
 303	if (S_ISDIR(inode->i_mode)) {
 304		ncp_dbg(2, "put directory %ld\n", inode->i_ino);
 305	}
 306
 307	if (ncp_make_closed(inode) != 0) {
 308		/* We can't do anything but complain. */
 309		pr_err("%s: could not close\n", __func__);
 310	}
 311}
 312
 313static void ncp_stop_tasks(struct ncp_server *server) {
 314	struct sock* sk = server->ncp_sock->sk;
 315
 316	lock_sock(sk);
 317	sk->sk_error_report = server->error_report;
 318	sk->sk_data_ready   = server->data_ready;
 319	sk->sk_write_space  = server->write_space;
 320	release_sock(sk);
 321	del_timer_sync(&server->timeout_tm);
 322
 323	flush_work(&server->rcv.tq);
 324	if (sk->sk_socket->type == SOCK_STREAM)
 325		flush_work(&server->tx.tq);
 326	else
 327		flush_work(&server->timeout_tq);
 328}
 329
 330static int  ncp_show_options(struct seq_file *seq, struct dentry *root)
 331{
 332	struct ncp_server *server = NCP_SBP(root->d_sb);
 333	unsigned int tmp;
 334
 335	if (!uid_eq(server->m.uid, GLOBAL_ROOT_UID))
 336		seq_printf(seq, ",uid=%u",
 337			   from_kuid_munged(&init_user_ns, server->m.uid));
 338	if (!gid_eq(server->m.gid, GLOBAL_ROOT_GID))
 339		seq_printf(seq, ",gid=%u",
 340			   from_kgid_munged(&init_user_ns, server->m.gid));
 341	if (!uid_eq(server->m.mounted_uid, GLOBAL_ROOT_UID))
 342		seq_printf(seq, ",owner=%u",
 343			   from_kuid_munged(&init_user_ns, server->m.mounted_uid));
 344	tmp = server->m.file_mode & S_IALLUGO;
 345	if (tmp != NCP_DEFAULT_FILE_MODE)
 346		seq_printf(seq, ",mode=0%o", tmp);
 347	tmp = server->m.dir_mode & S_IALLUGO;
 348	if (tmp != NCP_DEFAULT_DIR_MODE)
 349		seq_printf(seq, ",dirmode=0%o", tmp);
 350	if (server->m.time_out != NCP_DEFAULT_TIME_OUT * HZ / 100) {
 351		tmp = server->m.time_out * 100 / HZ;
 352		seq_printf(seq, ",timeout=%u", tmp);
 353	}
 354	if (server->m.retry_count != NCP_DEFAULT_RETRY_COUNT)
 355		seq_printf(seq, ",retry=%u", server->m.retry_count);
 356	if (server->m.flags != 0)
 357		seq_printf(seq, ",flags=%lu", server->m.flags);
 358	if (server->m.wdog_pid != NULL)
 359		seq_printf(seq, ",wdogpid=%u", pid_vnr(server->m.wdog_pid));
 360
 361	return 0;
 362}
 363
 364static const struct ncp_option ncp_opts[] = {
 365	{ "uid",	OPT_INT,	'u' },
 366	{ "gid",	OPT_INT,	'g' },
 367	{ "owner",	OPT_INT,	'o' },
 368	{ "mode",	OPT_INT,	'm' },
 369	{ "dirmode",	OPT_INT,	'd' },
 370	{ "timeout",	OPT_INT,	't' },
 371	{ "retry",	OPT_INT,	'r' },
 372	{ "flags",	OPT_INT,	'f' },
 373	{ "wdogpid",	OPT_INT,	'w' },
 374	{ "ncpfd",	OPT_INT,	'n' },
 375	{ "infofd",	OPT_INT,	'i' },	/* v5 */
 376	{ "version",	OPT_INT,	'v' },
 377	{ NULL,		0,		0 } };
 378
 379static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) {
 380	int optval;
 381	char *optarg;
 382	unsigned long optint;
 383	int version = 0;
 384	int ret;
 385
 386	data->flags = 0;
 387	data->int_flags = 0;
 388	data->mounted_uid = GLOBAL_ROOT_UID;
 389	data->wdog_pid = NULL;
 390	data->ncp_fd = ~0;
 391	data->time_out = NCP_DEFAULT_TIME_OUT;
 392	data->retry_count = NCP_DEFAULT_RETRY_COUNT;
 393	data->uid = GLOBAL_ROOT_UID;
 394	data->gid = GLOBAL_ROOT_GID;
 395	data->file_mode = NCP_DEFAULT_FILE_MODE;
 396	data->dir_mode = NCP_DEFAULT_DIR_MODE;
 397	data->info_fd = -1;
 398	data->mounted_vol[0] = 0;
 399	
 400	while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 0) {
 401		ret = optval;
 402		if (ret < 0)
 403			goto err;
 404		switch (optval) {
 405			case 'u':
 406				data->uid = make_kuid(current_user_ns(), optint);
 407				if (!uid_valid(data->uid)) {
 408					ret = -EINVAL;
 409					goto err;
 410				}
 411				break;
 412			case 'g':
 413				data->gid = make_kgid(current_user_ns(), optint);
 414				if (!gid_valid(data->gid)) {
 415					ret = -EINVAL;
 416					goto err;
 417				}
 418				break;
 419			case 'o':
 420				data->mounted_uid = make_kuid(current_user_ns(), optint);
 421				if (!uid_valid(data->mounted_uid)) {
 422					ret = -EINVAL;
 423					goto err;
 424				}
 425				break;
 426			case 'm':
 427				data->file_mode = optint;
 428				break;
 429			case 'd':
 430				data->dir_mode = optint;
 431				break;
 432			case 't':
 433				data->time_out = optint;
 434				break;
 435			case 'r':
 436				data->retry_count = optint;
 437				break;
 438			case 'f':
 439				data->flags = optint;
 440				break;
 441			case 'w':
 442				data->wdog_pid = find_get_pid(optint);
 443				break;
 444			case 'n':
 445				data->ncp_fd = optint;
 446				break;
 447			case 'i':
 448				data->info_fd = optint;
 449				break;
 450			case 'v':
 451				ret = -ECHRNG;
 452				if (optint < NCP_MOUNT_VERSION_V4)
 453					goto err;
 454				if (optint > NCP_MOUNT_VERSION_V5)
 455					goto err;
 456				version = optint;
 457				break;
 458			
 459		}
 460	}
 461	return 0;
 462err:
 463	put_pid(data->wdog_pid);
 464	data->wdog_pid = NULL;
 465	return ret;
 466}
 467
 468static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
 469{
 470	struct ncp_mount_data_kernel data;
 471	struct ncp_server *server;
 472	struct inode *root_inode;
 473	struct socket *sock;
 474	int error;
 475	int default_bufsize;
 476#ifdef CONFIG_NCPFS_PACKET_SIGNING
 477	int options;
 478#endif
 479	struct ncp_entry_info finfo;
 480
 481	memset(&data, 0, sizeof(data));
 482	server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL);
 483	if (!server)
 484		return -ENOMEM;
 485	sb->s_fs_info = server;
 486
 487	error = -EFAULT;
 488	if (raw_data == NULL)
 489		goto out;
 490	switch (*(int*)raw_data) {
 491		case NCP_MOUNT_VERSION:
 492			{
 493				struct ncp_mount_data* md = (struct ncp_mount_data*)raw_data;
 494
 495				data.flags = md->flags;
 496				data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE;
 497				data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid);
 498				data.wdog_pid = find_get_pid(md->wdog_pid);
 499				data.ncp_fd = md->ncp_fd;
 500				data.time_out = md->time_out;
 501				data.retry_count = md->retry_count;
 502				data.uid = make_kuid(current_user_ns(), md->uid);
 503				data.gid = make_kgid(current_user_ns(), md->gid);
 504				data.file_mode = md->file_mode;
 505				data.dir_mode = md->dir_mode;
 506				data.info_fd = -1;
 507				memcpy(data.mounted_vol, md->mounted_vol,
 508					NCP_VOLNAME_LEN+1);
 509			}
 510			break;
 511		case NCP_MOUNT_VERSION_V4:
 512			{
 513				struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data;
 514
 515				data.flags = md->flags;
 516				data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid);
 517				data.wdog_pid = find_get_pid(md->wdog_pid);
 518				data.ncp_fd = md->ncp_fd;
 519				data.time_out = md->time_out;
 520				data.retry_count = md->retry_count;
 521				data.uid = make_kuid(current_user_ns(), md->uid);
 522				data.gid = make_kgid(current_user_ns(), md->gid);
 523				data.file_mode = md->file_mode;
 524				data.dir_mode = md->dir_mode;
 525				data.info_fd = -1;
 526			}
 527			break;
 528		default:
 529			error = -ECHRNG;
 530			if (memcmp(raw_data, "vers", 4) == 0) {
 531				error = ncp_parse_options(&data, raw_data);
 532			}
 533			if (error)
 534				goto out;
 535			break;
 536	}
 537	error = -EINVAL;
 538	if (!uid_valid(data.mounted_uid) || !uid_valid(data.uid) ||
 539	    !gid_valid(data.gid))
 540		goto out;
 541	sock = sockfd_lookup(data.ncp_fd, &error);
 542	if (!sock)
 543		goto out;
 544
 545	if (sock->type == SOCK_STREAM)
 546		default_bufsize = 0xF000;
 547	else
 548		default_bufsize = 1024;
 549
 550	sb->s_flags |= MS_NODIRATIME;	/* probably even noatime */
 551	sb->s_maxbytes = 0xFFFFFFFFU;
 552	sb->s_blocksize = 1024;	/* Eh...  Is this correct? */
 553	sb->s_blocksize_bits = 10;
 554	sb->s_magic = NCP_SUPER_MAGIC;
 555	sb->s_op = &ncp_sops;
 556	sb->s_d_op = &ncp_dentry_operations;
 557	sb->s_bdi = &server->bdi;
 558
 559	server = NCP_SBP(sb);
 560	memset(server, 0, sizeof(*server));
 561
 562	error = bdi_setup_and_register(&server->bdi, "ncpfs");
 563	if (error)
 564		goto out_fput;
 565
 566	server->ncp_sock = sock;
 567	
 568	if (data.info_fd != -1) {
 569		struct socket *info_sock = sockfd_lookup(data.info_fd, &error);
 570		if (!info_sock)
 571			goto out_bdi;
 572		server->info_sock = info_sock;
 573		error = -EBADFD;
 574		if (info_sock->type != SOCK_STREAM)
 575			goto out_fput2;
 576	}
 577
 578/*	server->lock = 0;	*/
 579	mutex_init(&server->mutex);
 580	server->packet = NULL;
 581/*	server->buffer_size = 0;	*/
 582/*	server->conn_status = 0;	*/
 583/*	server->root_dentry = NULL;	*/
 584/*	server->root_setuped = 0;	*/
 585	mutex_init(&server->root_setup_lock);
 586#ifdef CONFIG_NCPFS_PACKET_SIGNING
 587/*	server->sign_wanted = 0;	*/
 588/*	server->sign_active = 0;	*/
 589#endif
 590	init_rwsem(&server->auth_rwsem);
 591	server->auth.auth_type = NCP_AUTH_NONE;
 592/*	server->auth.object_name_len = 0;	*/
 593/*	server->auth.object_name = NULL;	*/
 594/*	server->auth.object_type = 0;		*/
 595/*	server->priv.len = 0;			*/
 596/*	server->priv.data = NULL;		*/
 597
 598	server->m = data;
 599	/* Although anything producing this is buggy, it happens
 600	   now because of PATH_MAX changes.. */
 601	if (server->m.time_out < 1) {
 602		server->m.time_out = 10;
 603		pr_info("You need to recompile your ncpfs utils..\n");
 604	}
 605	server->m.time_out = server->m.time_out * HZ / 100;
 606	server->m.file_mode = (server->m.file_mode & S_IRWXUGO) | S_IFREG;
 607	server->m.dir_mode = (server->m.dir_mode & S_IRWXUGO) | S_IFDIR;
 608
 609#ifdef CONFIG_NCPFS_NLS
 610	/* load the default NLS charsets */
 611	server->nls_vol = load_nls_default();
 612	server->nls_io = load_nls_default();
 613#endif /* CONFIG_NCPFS_NLS */
 614
 615	atomic_set(&server->dentry_ttl, 0);	/* no caching */
 616
 617	INIT_LIST_HEAD(&server->tx.requests);
 618	mutex_init(&server->rcv.creq_mutex);
 619	server->tx.creq		= NULL;
 620	server->rcv.creq	= NULL;
 621
 622	init_timer(&server->timeout_tm);
 623#undef NCP_PACKET_SIZE
 624#define NCP_PACKET_SIZE 131072
 625	error = -ENOMEM;
 626	server->packet_size = NCP_PACKET_SIZE;
 627	server->packet = vmalloc(NCP_PACKET_SIZE);
 628	if (server->packet == NULL)
 629		goto out_nls;
 630	server->txbuf = vmalloc(NCP_PACKET_SIZE);
 631	if (server->txbuf == NULL)
 632		goto out_packet;
 633	server->rxbuf = vmalloc(NCP_PACKET_SIZE);
 634	if (server->rxbuf == NULL)
 635		goto out_txbuf;
 636
 637	lock_sock(sock->sk);
 638	server->data_ready	= sock->sk->sk_data_ready;
 639	server->write_space	= sock->sk->sk_write_space;
 640	server->error_report	= sock->sk->sk_error_report;
 641	sock->sk->sk_user_data	= server;
 642	sock->sk->sk_data_ready	  = ncp_tcp_data_ready;
 643	sock->sk->sk_error_report = ncp_tcp_error_report;
 644	if (sock->type == SOCK_STREAM) {
 645		server->rcv.ptr = (unsigned char*)&server->rcv.buf;
 646		server->rcv.len = 10;
 647		server->rcv.state = 0;
 648		INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc);
 649		INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc);
 650		sock->sk->sk_write_space = ncp_tcp_write_space;
 651	} else {
 652		INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc);
 653		INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc);
 654		server->timeout_tm.data = (unsigned long)server;
 655		server->timeout_tm.function = ncpdgram_timeout_call;
 656	}
 657	release_sock(sock->sk);
 658
 659	ncp_lock_server(server);
 660	error = ncp_connect(server);
 661	ncp_unlock_server(server);
 662	if (error < 0)
 663		goto out_rxbuf;
 664	ncp_dbg(1, "NCP_SBP(sb) = %p\n", NCP_SBP(sb));
 665
 666	error = -EMSGSIZE;	/* -EREMOTESIDEINCOMPATIBLE */
 667#ifdef CONFIG_NCPFS_PACKET_SIGNING
 668	if (ncp_negotiate_size_and_options(server, default_bufsize,
 669		NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0)
 670	{
 671		if (options != NCP_DEFAULT_OPTIONS)
 672		{
 673			if (ncp_negotiate_size_and_options(server, 
 674				default_bufsize,
 675				options & 2, 
 676				&(server->buffer_size), &options) != 0)
 677				
 678			{
 679				goto out_disconnect;
 680			}
 681		}
 682		ncp_lock_server(server);
 683		if (options & 2)
 684			server->sign_wanted = 1;
 685		ncp_unlock_server(server);
 686	}
 687	else 
 688#endif	/* CONFIG_NCPFS_PACKET_SIGNING */
 689	if (ncp_negotiate_buffersize(server, default_bufsize,
 690  				     &(server->buffer_size)) != 0)
 691		goto out_disconnect;
 692	ncp_dbg(1, "bufsize = %d\n", server->buffer_size);
 693
 694	memset(&finfo, 0, sizeof(finfo));
 695	finfo.i.attributes	= aDIR;
 696	finfo.i.dataStreamSize	= 0;	/* ignored */
 697	finfo.i.dirEntNum	= 0;
 698	finfo.i.DosDirNum	= 0;
 699#ifdef CONFIG_NCPFS_SMALLDOS
 700	finfo.i.NSCreator	= NW_NS_DOS;
 701#endif
 702	finfo.volume		= NCP_NUMBER_OF_VOLUMES;
 703	/* set dates of mountpoint to Jan 1, 1986; 00:00 */
 704	finfo.i.creationTime	= finfo.i.modifyTime
 705				= cpu_to_le16(0x0000);
 706	finfo.i.creationDate	= finfo.i.modifyDate
 707				= finfo.i.lastAccessDate
 708				= cpu_to_le16(0x0C21);
 709	finfo.i.nameLen		= 0;
 710	finfo.i.entryName[0]	= '\0';
 711
 712	finfo.opened		= 0;
 713	finfo.ino		= 2;	/* tradition */
 714
 715	server->name_space[finfo.volume] = NW_NS_DOS;
 716
 717	error = -ENOMEM;
 718        root_inode = ncp_iget(sb, &finfo);
 719        if (!root_inode)
 720		goto out_disconnect;
 721	ncp_dbg(1, "root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
 722	sb->s_root = d_make_root(root_inode);
 723        if (!sb->s_root)
 724		goto out_disconnect;
 725	return 0;
 726
 727out_disconnect:
 728	ncp_lock_server(server);
 729	ncp_disconnect(server);
 730	ncp_unlock_server(server);
 731out_rxbuf:
 732	ncp_stop_tasks(server);
 733	vfree(server->rxbuf);
 734out_txbuf:
 735	vfree(server->txbuf);
 736out_packet:
 737	vfree(server->packet);
 738out_nls:
 739#ifdef CONFIG_NCPFS_NLS
 740	unload_nls(server->nls_io);
 741	unload_nls(server->nls_vol);
 742#endif
 743	mutex_destroy(&server->rcv.creq_mutex);
 744	mutex_destroy(&server->root_setup_lock);
 745	mutex_destroy(&server->mutex);
 746out_fput2:
 747	if (server->info_sock)
 748		sockfd_put(server->info_sock);
 749out_bdi:
 750	bdi_destroy(&server->bdi);
 751out_fput:
 752	sockfd_put(sock);
 753out:
 754	put_pid(data.wdog_pid);
 755	sb->s_fs_info = NULL;
 756	kfree(server);
 757	return error;
 758}
 759
 760static void delayed_free(struct rcu_head *p)
 761{
 762	struct ncp_server *server = container_of(p, struct ncp_server, rcu);
 763#ifdef CONFIG_NCPFS_NLS
 764	/* unload the NLS charsets */
 765	unload_nls(server->nls_vol);
 766	unload_nls(server->nls_io);
 767#endif /* CONFIG_NCPFS_NLS */
 768	kfree(server);
 769}
 770
 771static void ncp_put_super(struct super_block *sb)
 772{
 773	struct ncp_server *server = NCP_SBP(sb);
 774
 775	ncp_lock_server(server);
 776	ncp_disconnect(server);
 777	ncp_unlock_server(server);
 778
 779	ncp_stop_tasks(server);
 780
 781	mutex_destroy(&server->rcv.creq_mutex);
 782	mutex_destroy(&server->root_setup_lock);
 783	mutex_destroy(&server->mutex);
 784
 785	if (server->info_sock)
 786		sockfd_put(server->info_sock);
 787	sockfd_put(server->ncp_sock);
 788	kill_pid(server->m.wdog_pid, SIGTERM, 1);
 789	put_pid(server->m.wdog_pid);
 790
 791	bdi_destroy(&server->bdi);
 792	kfree(server->priv.data);
 793	kfree(server->auth.object_name);
 794	vfree(server->rxbuf);
 795	vfree(server->txbuf);
 796	vfree(server->packet);
 797	call_rcu(&server->rcu, delayed_free);
 798}
 799
 800static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
 801{
 802	struct dentry* d;
 803	struct inode* i;
 804	struct ncp_inode_info* ni;
 805	struct ncp_server* s;
 806	struct ncp_volume_info vi;
 807	struct super_block *sb = dentry->d_sb;
 808	int err;
 809	__u8 dh;
 810	
 811	d = sb->s_root;
 812	if (!d) {
 813		goto dflt;
 814	}
 815	i = d_inode(d);
 816	if (!i) {
 817		goto dflt;
 818	}
 819	ni = NCP_FINFO(i);
 820	if (!ni) {
 821		goto dflt;
 822	}
 823	s = NCP_SBP(sb);
 824	if (!s) {
 825		goto dflt;
 826	}
 827	if (!s->m.mounted_vol[0]) {
 828		goto dflt;
 829	}
 830
 831	err = ncp_dirhandle_alloc(s, ni->volNumber, ni->DosDirNum, &dh);
 832	if (err) {
 833		goto dflt;
 834	}
 835	err = ncp_get_directory_info(s, dh, &vi);
 836	ncp_dirhandle_free(s, dh);
 837	if (err) {
 838		goto dflt;
 839	}
 840	buf->f_type = NCP_SUPER_MAGIC;
 841	buf->f_bsize = vi.sectors_per_block * 512;
 842	buf->f_blocks = vi.total_blocks;
 843	buf->f_bfree = vi.free_blocks;
 844	buf->f_bavail = vi.free_blocks;
 845	buf->f_files = vi.total_dir_entries;
 846	buf->f_ffree = vi.available_dir_entries;
 847	buf->f_namelen = 12;
 848	return 0;
 849
 850	/* We cannot say how much disk space is left on a mounted
 851	   NetWare Server, because free space is distributed over
 852	   volumes, and the current user might have disk quotas. So
 853	   free space is not that simple to determine. Our decision
 854	   here is to err conservatively. */
 855
 856dflt:;
 857	buf->f_type = NCP_SUPER_MAGIC;
 858	buf->f_bsize = NCP_BLOCK_SIZE;
 859	buf->f_blocks = 0;
 860	buf->f_bfree = 0;
 861	buf->f_bavail = 0;
 862	buf->f_namelen = 12;
 863	return 0;
 864}
 865
 866int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
 867{
 868	struct inode *inode = d_inode(dentry);
 869	int result = 0;
 870	__le32 info_mask;
 871	struct nw_modify_dos_info info;
 872	struct ncp_server *server;
 873
 874	result = -EIO;
 875
 876	server = NCP_SERVER(inode);
 877	if (!server)	/* How this could happen? */
 878		goto out;
 879
 880	result = -EPERM;
 881	if (IS_DEADDIR(d_inode(dentry)))
 882		goto out;
 883
 884	/* ageing the dentry to force validation */
 885	ncp_age_dentry(server, dentry);
 886
 887	result = inode_change_ok(inode, attr);
 888	if (result < 0)
 889		goto out;
 890
 891	result = -EPERM;
 892	if ((attr->ia_valid & ATTR_UID) && !uid_eq(attr->ia_uid, server->m.uid))
 893		goto out;
 894
 895	if ((attr->ia_valid & ATTR_GID) && !gid_eq(attr->ia_gid, server->m.gid))
 896		goto out;
 897
 898	if (((attr->ia_valid & ATTR_MODE) &&
 899	     (attr->ia_mode &
 900	      ~(S_IFREG | S_IFDIR | S_IRWXUGO))))
 901		goto out;
 902
 903	info_mask = 0;
 904	memset(&info, 0, sizeof(info));
 905
 906#if 1 
 907        if ((attr->ia_valid & ATTR_MODE) != 0)
 908        {
 909		umode_t newmode = attr->ia_mode;
 910
 911		info_mask |= DM_ATTRIBUTES;
 912
 913                if (S_ISDIR(inode->i_mode)) {
 914                	newmode &= server->m.dir_mode;
 915		} else {
 916#ifdef CONFIG_NCPFS_EXTRAS			
 917			if (server->m.flags & NCP_MOUNT_EXTRAS) {
 918				/* any non-default execute bit set */
 919				if (newmode & ~server->m.file_mode & S_IXUGO)
 920					info.attributes |= aSHARED | aSYSTEM;
 921				/* read for group/world and not in default file_mode */
 922				else if (newmode & ~server->m.file_mode & S_IRUGO)
 923					info.attributes |= aSHARED;
 924			} else
 925#endif
 926				newmode &= server->m.file_mode;			
 927                }
 928                if (newmode & S_IWUGO)
 929                	info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
 930                else
 931			info.attributes |=  (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
 932
 933#ifdef CONFIG_NCPFS_NFS_NS
 934		if (ncp_is_nfs_extras(server, NCP_FINFO(inode)->volNumber)) {
 935			result = ncp_modify_nfs_info(server,
 936						     NCP_FINFO(inode)->volNumber,
 937						     NCP_FINFO(inode)->dirEntNum,
 938						     attr->ia_mode, 0);
 939			if (result != 0)
 940				goto out;
 941			info.attributes &= ~(aSHARED | aSYSTEM);
 942			{
 943				/* mark partial success */
 944				struct iattr tmpattr;
 945				
 946				tmpattr.ia_valid = ATTR_MODE;
 947				tmpattr.ia_mode = attr->ia_mode;
 948
 949				setattr_copy(inode, &tmpattr);
 950				mark_inode_dirty(inode);
 951			}
 952		}
 953#endif
 954        }
 955#endif
 956
 957	/* Do SIZE before attributes, otherwise mtime together with size does not work...
 958	 */
 959	if ((attr->ia_valid & ATTR_SIZE) != 0) {
 960		int written;
 961
 962		ncp_dbg(1, "trying to change size to %llu\n", attr->ia_size);
 963
 964		if ((result = ncp_make_open(inode, O_WRONLY)) < 0) {
 965			result = -EACCES;
 966			goto out;
 967		}
 968		ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
 969			  attr->ia_size, 0, "", &written);
 970
 971		/* According to ndir, the changes only take effect after
 972		   closing the file */
 973		ncp_inode_close(inode);
 974		result = ncp_make_closed(inode);
 975		if (result)
 976			goto out;
 977
 978		if (attr->ia_size != i_size_read(inode)) {
 979			truncate_setsize(inode, attr->ia_size);
 980			mark_inode_dirty(inode);
 981		}
 982	}
 983	if ((attr->ia_valid & ATTR_CTIME) != 0) {
 984		info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE);
 985		ncp_date_unix2dos(attr->ia_ctime.tv_sec,
 986			     &info.creationTime, &info.creationDate);
 987	}
 988	if ((attr->ia_valid & ATTR_MTIME) != 0) {
 989		info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE);
 990		ncp_date_unix2dos(attr->ia_mtime.tv_sec,
 991				  &info.modifyTime, &info.modifyDate);
 992	}
 993	if ((attr->ia_valid & ATTR_ATIME) != 0) {
 994		__le16 dummy;
 995		info_mask |= (DM_LAST_ACCESS_DATE);
 996		ncp_date_unix2dos(attr->ia_atime.tv_sec,
 997				  &dummy, &info.lastAccessDate);
 998	}
 999	if (info_mask != 0) {
1000		result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
1001				      inode, info_mask, &info);
1002		if (result != 0) {
1003			if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
1004				/* NetWare seems not to allow this. I
1005				   do not know why. So, just tell the
1006				   user everything went fine. This is
1007				   a terrible hack, but I do not know
1008				   how to do this correctly. */
1009				result = 0;
1010			} else
1011				goto out;
1012		}
1013#ifdef CONFIG_NCPFS_STRONG		
1014		if ((!result) && (info_mask & DM_ATTRIBUTES))
1015			NCP_FINFO(inode)->nwattr = info.attributes;
1016#endif
1017	}
1018	if (result)
1019		goto out;
1020
1021	setattr_copy(inode, attr);
1022	mark_inode_dirty(inode);
1023
1024out:
1025	if (result > 0)
1026		result = -EACCES;
1027	return result;
1028}
1029
1030static struct dentry *ncp_mount(struct file_system_type *fs_type,
1031	int flags, const char *dev_name, void *data)
1032{
1033	return mount_nodev(fs_type, flags, data, ncp_fill_super);
1034}
1035
1036static struct file_system_type ncp_fs_type = {
1037	.owner		= THIS_MODULE,
1038	.name		= "ncpfs",
1039	.mount		= ncp_mount,
1040	.kill_sb	= kill_anon_super,
1041	.fs_flags	= FS_BINARY_MOUNTDATA,
1042};
1043MODULE_ALIAS_FS("ncpfs");
1044
1045static int __init init_ncp_fs(void)
1046{
1047	int err;
1048	ncp_dbg(1, "called\n");
1049
1050	err = init_inodecache();
1051	if (err)
1052		goto out1;
1053	err = register_filesystem(&ncp_fs_type);
1054	if (err)
1055		goto out;
1056	return 0;
1057out:
1058	destroy_inodecache();
1059out1:
1060	return err;
1061}
1062
1063static void __exit exit_ncp_fs(void)
1064{
1065	ncp_dbg(1, "called\n");
1066	unregister_filesystem(&ncp_fs_type);
1067	destroy_inodecache();
1068}
1069
1070module_init(init_ncp_fs)
1071module_exit(exit_ncp_fs)
1072MODULE_LICENSE("GPL");