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