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_ino = info->ino;
271		ncp_set_attr(inode, info);
272		if (S_ISREG(inode->i_mode)) {
273			inode->i_op = &ncp_file_inode_operations;
274			inode->i_fop = &ncp_file_operations;
275		} else if (S_ISDIR(inode->i_mode)) {
276			inode->i_op = &ncp_dir_inode_operations;
277			inode->i_fop = &ncp_dir_operations;
278#ifdef CONFIG_NCPFS_NFS_NS
279		} else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
280			init_special_inode(inode, inode->i_mode,
281				new_decode_dev(info->i.nfs.rdev));
282#endif
283#if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
284		} else if (S_ISLNK(inode->i_mode)) {
285			inode->i_op = &ncp_symlink_inode_operations;
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");
1073