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