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
12 #include <linux/module.h>
14 #include <asm/system.h>
15 #include <asm/uaccess.h>
16 #include <asm/byteorder.h>
18 #include <linux/time.h>
19 #include <linux/kernel.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/vfs.h>
30 #include <linux/mount.h>
31 #include <linux/seq_file.h>
32 #include <linux/namei.h>
39 #define NCP_DEFAULT_FILE_MODE 0600
40 #define NCP_DEFAULT_DIR_MODE 0700
41 #define NCP_DEFAULT_TIME_OUT 10
42 #define NCP_DEFAULT_RETRY_COUNT 20
44 static void ncp_evict_inode(struct inode *);
45 static void ncp_put_super(struct super_block *);
46 static int ncp_statfs(struct dentry *, struct kstatfs *);
47 static int ncp_show_options(struct seq_file *, struct dentry *);
49 static struct kmem_cache * ncp_inode_cachep;
51 static struct inode *ncp_alloc_inode(struct super_block *sb)
53 struct ncp_inode_info *ei;
54 ei = (struct ncp_inode_info *)kmem_cache_alloc(ncp_inode_cachep, GFP_KERNEL);
57 return &ei->vfs_inode;
60 static void ncp_i_callback(struct rcu_head *head)
62 struct inode *inode = container_of(head, struct inode, i_rcu);
63 kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode));
66 static void ncp_destroy_inode(struct inode *inode)
68 call_rcu(&inode->i_rcu, ncp_i_callback);
71 static void init_once(void *foo)
73 struct ncp_inode_info *ei = (struct ncp_inode_info *) foo;
75 mutex_init(&ei->open_mutex);
76 inode_init_once(&ei->vfs_inode);
79 static int init_inodecache(void)
81 ncp_inode_cachep = kmem_cache_create("ncp_inode_cache",
82 sizeof(struct ncp_inode_info),
83 0, (SLAB_RECLAIM_ACCOUNT|
86 if (ncp_inode_cachep == NULL)
91 static void destroy_inodecache(void)
93 kmem_cache_destroy(ncp_inode_cachep);
96 static int ncp_remount(struct super_block *sb, int *flags, char* data)
98 *flags |= MS_NODIRATIME;
102 static const struct super_operations ncp_sops =
104 .alloc_inode = ncp_alloc_inode,
105 .destroy_inode = ncp_destroy_inode,
106 .drop_inode = generic_delete_inode,
107 .evict_inode = ncp_evict_inode,
108 .put_super = ncp_put_super,
109 .statfs = ncp_statfs,
110 .remount_fs = ncp_remount,
111 .show_options = ncp_show_options,
115 * Fill in the ncpfs-specific information in the inode.
117 static void ncp_update_dirent(struct inode *inode, struct ncp_entry_info *nwinfo)
119 NCP_FINFO(inode)->DosDirNum = nwinfo->i.DosDirNum;
120 NCP_FINFO(inode)->dirEntNum = nwinfo->i.dirEntNum;
121 NCP_FINFO(inode)->volNumber = nwinfo->volume;
124 void ncp_update_inode(struct inode *inode, struct ncp_entry_info *nwinfo)
126 ncp_update_dirent(inode, nwinfo);
127 NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
128 NCP_FINFO(inode)->access = nwinfo->access;
129 memcpy(NCP_FINFO(inode)->file_handle, nwinfo->file_handle,
130 sizeof(nwinfo->file_handle));
131 DPRINTK("ncp_update_inode: updated %s, volnum=%d, dirent=%u\n",
132 nwinfo->i.entryName, NCP_FINFO(inode)->volNumber,
133 NCP_FINFO(inode)->dirEntNum);
136 static void ncp_update_dates(struct inode *inode, struct nw_info_struct *nwi)
138 /* NFS namespace mode overrides others if it's set. */
139 DPRINTK(KERN_DEBUG "ncp_update_dates_and_mode: (%s) nfs.mode=0%o\n",
140 nwi->entryName, nwi->nfs.mode);
143 inode->i_mode = nwi->nfs.mode;
146 inode->i_blocks = (i_size_read(inode) + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
148 inode->i_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate);
149 inode->i_ctime.tv_sec = ncp_date_dos2unix(nwi->creationTime, nwi->creationDate);
150 inode->i_atime.tv_sec = ncp_date_dos2unix(0, nwi->lastAccessDate);
151 inode->i_atime.tv_nsec = 0;
152 inode->i_mtime.tv_nsec = 0;
153 inode->i_ctime.tv_nsec = 0;
156 static void ncp_update_attrs(struct inode *inode, struct ncp_entry_info *nwinfo)
158 struct nw_info_struct *nwi = &nwinfo->i;
159 struct ncp_server *server = NCP_SERVER(inode);
161 if (nwi->attributes & aDIR) {
162 inode->i_mode = server->m.dir_mode;
163 /* for directories dataStreamSize seems to be some
165 i_size_write(inode, NCP_BLOCK_SIZE);
169 inode->i_mode = server->m.file_mode;
170 size = le32_to_cpu(nwi->dataStreamSize);
171 i_size_write(inode, size);
172 #ifdef CONFIG_NCPFS_EXTRAS
173 if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS))
174 && (nwi->attributes & aSHARED)) {
175 switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
177 if (server->m.flags & NCP_MOUNT_SYMLINKS) {
178 if (/* (size >= NCP_MIN_SYMLINK_SIZE)
179 && */ (size <= NCP_MAX_SYMLINK_SIZE)) {
180 inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
181 NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK;
187 if (server->m.flags & NCP_MOUNT_EXTRAS)
188 inode->i_mode |= S_IRUGO;
191 if (server->m.flags & NCP_MOUNT_EXTRAS)
192 inode->i_mode |= (inode->i_mode >> 2) & S_IXUGO;
194 /* case aSYSTEM|aHIDDEN: */
196 /* reserved combination */
202 if (nwi->attributes & aRONLY) inode->i_mode &= ~S_IWUGO;
205 void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo)
207 NCP_FINFO(inode)->flags = 0;
208 if (!atomic_read(&NCP_FINFO(inode)->opened)) {
209 NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
210 ncp_update_attrs(inode, nwinfo);
213 ncp_update_dates(inode, &nwinfo->i);
214 ncp_update_dirent(inode, nwinfo);
218 * Fill in the inode based on the ncp_entry_info structure. Used only for brand new inodes.
220 static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
222 struct ncp_server *server = NCP_SERVER(inode);
224 NCP_FINFO(inode)->flags = 0;
226 ncp_update_attrs(inode, nwinfo);
228 DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode->i_mode);
231 inode->i_uid = server->m.uid;
232 inode->i_gid = server->m.gid;
234 ncp_update_dates(inode, &nwinfo->i);
235 ncp_update_inode(inode, nwinfo);
238 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
239 static const struct inode_operations ncp_symlink_inode_operations = {
240 .readlink = generic_readlink,
241 .follow_link = page_follow_link_light,
242 .put_link = page_put_link,
243 .setattr = ncp_notify_change,
251 ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
256 printk(KERN_ERR "ncp_iget: info is NULL\n");
260 inode = new_inode(sb);
262 atomic_set(&NCP_FINFO(inode)->opened, info->opened);
264 inode->i_mapping->backing_dev_info = sb->s_bdi;
265 inode->i_ino = info->ino;
266 ncp_set_attr(inode, info);
267 if (S_ISREG(inode->i_mode)) {
268 inode->i_op = &ncp_file_inode_operations;
269 inode->i_fop = &ncp_file_operations;
270 } else if (S_ISDIR(inode->i_mode)) {
271 inode->i_op = &ncp_dir_inode_operations;
272 inode->i_fop = &ncp_dir_operations;
273 #ifdef CONFIG_NCPFS_NFS_NS
274 } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
275 init_special_inode(inode, inode->i_mode,
276 new_decode_dev(info->i.nfs.rdev));
278 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
279 } else if (S_ISLNK(inode->i_mode)) {
280 inode->i_op = &ncp_symlink_inode_operations;
281 inode->i_data.a_ops = &ncp_symlink_aops;
284 make_bad_inode(inode);
286 insert_inode_hash(inode);
288 printk(KERN_ERR "ncp_iget: iget failed!\n");
293 ncp_evict_inode(struct inode *inode)
295 truncate_inode_pages(&inode->i_data, 0);
296 end_writeback(inode);
298 if (S_ISDIR(inode->i_mode)) {
299 DDPRINTK("ncp_evict_inode: put directory %ld\n", inode->i_ino);
302 if (ncp_make_closed(inode) != 0) {
303 /* We can't do anything but complain. */
304 printk(KERN_ERR "ncp_evict_inode: could not close\n");
308 static void ncp_stop_tasks(struct ncp_server *server) {
309 struct sock* sk = server->ncp_sock->sk;
312 sk->sk_error_report = server->error_report;
313 sk->sk_data_ready = server->data_ready;
314 sk->sk_write_space = server->write_space;
316 del_timer_sync(&server->timeout_tm);
318 flush_work_sync(&server->rcv.tq);
319 if (sk->sk_socket->type == SOCK_STREAM)
320 flush_work_sync(&server->tx.tq);
322 flush_work_sync(&server->timeout_tq);
325 static int ncp_show_options(struct seq_file *seq, struct dentry *root)
327 struct ncp_server *server = NCP_SBP(root->d_sb);
330 if (server->m.uid != 0)
331 seq_printf(seq, ",uid=%u", server->m.uid);
332 if (server->m.gid != 0)
333 seq_printf(seq, ",gid=%u", server->m.gid);
334 if (server->m.mounted_uid != 0)
335 seq_printf(seq, ",owner=%u", server->m.mounted_uid);
336 tmp = server->m.file_mode & S_IALLUGO;
337 if (tmp != NCP_DEFAULT_FILE_MODE)
338 seq_printf(seq, ",mode=0%o", tmp);
339 tmp = server->m.dir_mode & S_IALLUGO;
340 if (tmp != NCP_DEFAULT_DIR_MODE)
341 seq_printf(seq, ",dirmode=0%o", tmp);
342 if (server->m.time_out != NCP_DEFAULT_TIME_OUT * HZ / 100) {
343 tmp = server->m.time_out * 100 / HZ;
344 seq_printf(seq, ",timeout=%u", tmp);
346 if (server->m.retry_count != NCP_DEFAULT_RETRY_COUNT)
347 seq_printf(seq, ",retry=%u", server->m.retry_count);
348 if (server->m.flags != 0)
349 seq_printf(seq, ",flags=%lu", server->m.flags);
350 if (server->m.wdog_pid != NULL)
351 seq_printf(seq, ",wdogpid=%u", pid_vnr(server->m.wdog_pid));
356 static const struct ncp_option ncp_opts[] = {
357 { "uid", OPT_INT, 'u' },
358 { "gid", OPT_INT, 'g' },
359 { "owner", OPT_INT, 'o' },
360 { "mode", OPT_INT, 'm' },
361 { "dirmode", OPT_INT, 'd' },
362 { "timeout", OPT_INT, 't' },
363 { "retry", OPT_INT, 'r' },
364 { "flags", OPT_INT, 'f' },
365 { "wdogpid", OPT_INT, 'w' },
366 { "ncpfd", OPT_INT, 'n' },
367 { "infofd", OPT_INT, 'i' }, /* v5 */
368 { "version", OPT_INT, 'v' },
371 static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) {
374 unsigned long optint;
380 data->mounted_uid = 0;
381 data->wdog_pid = NULL;
383 data->time_out = NCP_DEFAULT_TIME_OUT;
384 data->retry_count = NCP_DEFAULT_RETRY_COUNT;
387 data->file_mode = NCP_DEFAULT_FILE_MODE;
388 data->dir_mode = NCP_DEFAULT_DIR_MODE;
390 data->mounted_vol[0] = 0;
392 while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 0) {
404 data->mounted_uid = optint;
407 data->file_mode = optint;
410 data->dir_mode = optint;
413 data->time_out = optint;
416 data->retry_count = optint;
419 data->flags = optint;
422 data->wdog_pid = find_get_pid(optint);
425 data->ncp_fd = optint;
428 data->info_fd = optint;
432 if (optint < NCP_MOUNT_VERSION_V4)
434 if (optint > NCP_MOUNT_VERSION_V5)
443 put_pid(data->wdog_pid);
444 data->wdog_pid = NULL;
448 static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
450 struct ncp_mount_data_kernel data;
451 struct ncp_server *server;
452 struct file *ncp_filp;
453 struct inode *root_inode;
454 struct inode *sock_inode;
458 #ifdef CONFIG_NCPFS_PACKET_SIGNING
461 struct ncp_entry_info finfo;
463 memset(&data, 0, sizeof(data));
464 server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL);
467 sb->s_fs_info = server;
470 if (raw_data == NULL)
472 switch (*(int*)raw_data) {
473 case NCP_MOUNT_VERSION:
475 struct ncp_mount_data* md = (struct ncp_mount_data*)raw_data;
477 data.flags = md->flags;
478 data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE;
479 data.mounted_uid = md->mounted_uid;
480 data.wdog_pid = find_get_pid(md->wdog_pid);
481 data.ncp_fd = md->ncp_fd;
482 data.time_out = md->time_out;
483 data.retry_count = md->retry_count;
486 data.file_mode = md->file_mode;
487 data.dir_mode = md->dir_mode;
489 memcpy(data.mounted_vol, md->mounted_vol,
493 case NCP_MOUNT_VERSION_V4:
495 struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data;
497 data.flags = md->flags;
498 data.mounted_uid = md->mounted_uid;
499 data.wdog_pid = find_get_pid(md->wdog_pid);
500 data.ncp_fd = md->ncp_fd;
501 data.time_out = md->time_out;
502 data.retry_count = md->retry_count;
505 data.file_mode = md->file_mode;
506 data.dir_mode = md->dir_mode;
512 if (memcmp(raw_data, "vers", 4) == 0) {
513 error = ncp_parse_options(&data, raw_data);
520 ncp_filp = fget(data.ncp_fd);
524 sock_inode = ncp_filp->f_path.dentry->d_inode;
525 if (!S_ISSOCK(sock_inode->i_mode))
527 sock = SOCKET_I(sock_inode);
531 if (sock->type == SOCK_STREAM)
532 default_bufsize = 0xF000;
534 default_bufsize = 1024;
536 sb->s_flags |= MS_NODIRATIME; /* probably even noatime */
537 sb->s_maxbytes = 0xFFFFFFFFU;
538 sb->s_blocksize = 1024; /* Eh... Is this correct? */
539 sb->s_blocksize_bits = 10;
540 sb->s_magic = NCP_SUPER_MAGIC;
541 sb->s_op = &ncp_sops;
542 sb->s_d_op = &ncp_dentry_operations;
543 sb->s_bdi = &server->bdi;
545 server = NCP_SBP(sb);
546 memset(server, 0, sizeof(*server));
548 error = bdi_setup_and_register(&server->bdi, "ncpfs", BDI_CAP_MAP_COPY);
552 server->ncp_filp = ncp_filp;
553 server->ncp_sock = sock;
555 if (data.info_fd != -1) {
556 struct socket *info_sock;
559 server->info_filp = fget(data.info_fd);
560 if (!server->info_filp)
563 sock_inode = server->info_filp->f_path.dentry->d_inode;
564 if (!S_ISSOCK(sock_inode->i_mode))
566 info_sock = SOCKET_I(sock_inode);
570 if (info_sock->type != SOCK_STREAM)
572 server->info_sock = info_sock;
575 /* server->lock = 0; */
576 mutex_init(&server->mutex);
577 server->packet = NULL;
578 /* server->buffer_size = 0; */
579 /* server->conn_status = 0; */
580 /* server->root_dentry = NULL; */
581 /* server->root_setuped = 0; */
582 mutex_init(&server->root_setup_lock);
583 #ifdef CONFIG_NCPFS_PACKET_SIGNING
584 /* server->sign_wanted = 0; */
585 /* server->sign_active = 0; */
587 init_rwsem(&server->auth_rwsem);
588 server->auth.auth_type = NCP_AUTH_NONE;
589 /* server->auth.object_name_len = 0; */
590 /* server->auth.object_name = NULL; */
591 /* server->auth.object_type = 0; */
592 /* server->priv.len = 0; */
593 /* server->priv.data = NULL; */
596 /* Although anything producing this is buggy, it happens
597 now because of PATH_MAX changes.. */
598 if (server->m.time_out < 1) {
599 server->m.time_out = 10;
600 printk(KERN_INFO "You need to recompile your ncpfs utils..\n");
602 server->m.time_out = server->m.time_out * HZ / 100;
603 server->m.file_mode = (server->m.file_mode & S_IRWXUGO) | S_IFREG;
604 server->m.dir_mode = (server->m.dir_mode & S_IRWXUGO) | S_IFDIR;
606 #ifdef CONFIG_NCPFS_NLS
607 /* load the default NLS charsets */
608 server->nls_vol = load_nls_default();
609 server->nls_io = load_nls_default();
610 #endif /* CONFIG_NCPFS_NLS */
612 atomic_set(&server->dentry_ttl, 0); /* no caching */
614 INIT_LIST_HEAD(&server->tx.requests);
615 mutex_init(&server->rcv.creq_mutex);
616 server->tx.creq = NULL;
617 server->rcv.creq = NULL;
619 init_timer(&server->timeout_tm);
620 #undef NCP_PACKET_SIZE
621 #define NCP_PACKET_SIZE 131072
623 server->packet_size = NCP_PACKET_SIZE;
624 server->packet = vmalloc(NCP_PACKET_SIZE);
625 if (server->packet == NULL)
627 server->txbuf = vmalloc(NCP_PACKET_SIZE);
628 if (server->txbuf == NULL)
630 server->rxbuf = vmalloc(NCP_PACKET_SIZE);
631 if (server->rxbuf == NULL)
635 server->data_ready = sock->sk->sk_data_ready;
636 server->write_space = sock->sk->sk_write_space;
637 server->error_report = sock->sk->sk_error_report;
638 sock->sk->sk_user_data = server;
639 sock->sk->sk_data_ready = ncp_tcp_data_ready;
640 sock->sk->sk_error_report = ncp_tcp_error_report;
641 if (sock->type == SOCK_STREAM) {
642 server->rcv.ptr = (unsigned char*)&server->rcv.buf;
643 server->rcv.len = 10;
644 server->rcv.state = 0;
645 INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc);
646 INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc);
647 sock->sk->sk_write_space = ncp_tcp_write_space;
649 INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc);
650 INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc);
651 server->timeout_tm.data = (unsigned long)server;
652 server->timeout_tm.function = ncpdgram_timeout_call;
654 release_sock(sock->sk);
656 ncp_lock_server(server);
657 error = ncp_connect(server);
658 ncp_unlock_server(server);
661 DPRINTK("ncp_fill_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb));
663 error = -EMSGSIZE; /* -EREMOTESIDEINCOMPATIBLE */
664 #ifdef CONFIG_NCPFS_PACKET_SIGNING
665 if (ncp_negotiate_size_and_options(server, default_bufsize,
666 NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0)
668 if (options != NCP_DEFAULT_OPTIONS)
670 if (ncp_negotiate_size_and_options(server,
673 &(server->buffer_size), &options) != 0)
679 ncp_lock_server(server);
681 server->sign_wanted = 1;
682 ncp_unlock_server(server);
685 #endif /* CONFIG_NCPFS_PACKET_SIGNING */
686 if (ncp_negotiate_buffersize(server, default_bufsize,
687 &(server->buffer_size)) != 0)
689 DPRINTK("ncpfs: bufsize = %d\n", server->buffer_size);
691 memset(&finfo, 0, sizeof(finfo));
692 finfo.i.attributes = aDIR;
693 finfo.i.dataStreamSize = 0; /* ignored */
694 finfo.i.dirEntNum = 0;
695 finfo.i.DosDirNum = 0;
696 #ifdef CONFIG_NCPFS_SMALLDOS
697 finfo.i.NSCreator = NW_NS_DOS;
699 finfo.volume = NCP_NUMBER_OF_VOLUMES;
700 /* set dates of mountpoint to Jan 1, 1986; 00:00 */
701 finfo.i.creationTime = finfo.i.modifyTime
702 = cpu_to_le16(0x0000);
703 finfo.i.creationDate = finfo.i.modifyDate
704 = finfo.i.lastAccessDate
705 = cpu_to_le16(0x0C21);
707 finfo.i.entryName[0] = '\0';
710 finfo.ino = 2; /* tradition */
712 server->name_space[finfo.volume] = NW_NS_DOS;
715 root_inode = ncp_iget(sb, &finfo);
718 DPRINTK("ncp_fill_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
719 sb->s_root = d_make_root(root_inode);
725 ncp_lock_server(server);
726 ncp_disconnect(server);
727 ncp_unlock_server(server);
729 ncp_stop_tasks(server);
730 vfree(server->rxbuf);
732 vfree(server->txbuf);
734 vfree(server->packet);
736 #ifdef CONFIG_NCPFS_NLS
737 unload_nls(server->nls_io);
738 unload_nls(server->nls_vol);
740 mutex_destroy(&server->rcv.creq_mutex);
741 mutex_destroy(&server->root_setup_lock);
742 mutex_destroy(&server->mutex);
744 if (server->info_filp)
745 fput(server->info_filp);
747 bdi_destroy(&server->bdi);
749 /* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:
751 * The previously used put_filp(ncp_filp); was bogus, since
752 * it doesn't perform proper unlocking.
756 put_pid(data.wdog_pid);
757 sb->s_fs_info = NULL;
762 static void ncp_put_super(struct super_block *sb)
764 struct ncp_server *server = NCP_SBP(sb);
766 ncp_lock_server(server);
767 ncp_disconnect(server);
768 ncp_unlock_server(server);
770 ncp_stop_tasks(server);
772 #ifdef CONFIG_NCPFS_NLS
773 /* unload the NLS charsets */
774 unload_nls(server->nls_vol);
775 unload_nls(server->nls_io);
776 #endif /* CONFIG_NCPFS_NLS */
777 mutex_destroy(&server->rcv.creq_mutex);
778 mutex_destroy(&server->root_setup_lock);
779 mutex_destroy(&server->mutex);
781 if (server->info_filp)
782 fput(server->info_filp);
783 fput(server->ncp_filp);
784 kill_pid(server->m.wdog_pid, SIGTERM, 1);
785 put_pid(server->m.wdog_pid);
787 bdi_destroy(&server->bdi);
788 kfree(server->priv.data);
789 kfree(server->auth.object_name);
790 vfree(server->rxbuf);
791 vfree(server->txbuf);
792 vfree(server->packet);
793 sb->s_fs_info = NULL;
797 static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
801 struct ncp_inode_info* ni;
802 struct ncp_server* s;
803 struct ncp_volume_info vi;
804 struct super_block *sb = dentry->d_sb;
824 if (!s->m.mounted_vol[0]) {
828 err = ncp_dirhandle_alloc(s, ni->volNumber, ni->DosDirNum, &dh);
832 err = ncp_get_directory_info(s, dh, &vi);
833 ncp_dirhandle_free(s, dh);
837 buf->f_type = NCP_SUPER_MAGIC;
838 buf->f_bsize = vi.sectors_per_block * 512;
839 buf->f_blocks = vi.total_blocks;
840 buf->f_bfree = vi.free_blocks;
841 buf->f_bavail = vi.free_blocks;
842 buf->f_files = vi.total_dir_entries;
843 buf->f_ffree = vi.available_dir_entries;
847 /* We cannot say how much disk space is left on a mounted
848 NetWare Server, because free space is distributed over
849 volumes, and the current user might have disk quotas. So
850 free space is not that simple to determine. Our decision
851 here is to err conservatively. */
854 buf->f_type = NCP_SUPER_MAGIC;
855 buf->f_bsize = NCP_BLOCK_SIZE;
863 int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
865 struct inode *inode = dentry->d_inode;
868 struct nw_modify_dos_info info;
869 struct ncp_server *server;
873 server = NCP_SERVER(inode);
874 if (!server) /* How this could happen? */
877 /* ageing the dentry to force validation */
878 ncp_age_dentry(server, dentry);
880 result = inode_change_ok(inode, attr);
885 if (((attr->ia_valid & ATTR_UID) &&
886 (attr->ia_uid != server->m.uid)))
889 if (((attr->ia_valid & ATTR_GID) &&
890 (attr->ia_gid != server->m.gid)))
893 if (((attr->ia_valid & ATTR_MODE) &&
895 ~(S_IFREG | S_IFDIR | S_IRWXUGO))))
899 memset(&info, 0, sizeof(info));
902 if ((attr->ia_valid & ATTR_MODE) != 0)
904 umode_t newmode = attr->ia_mode;
906 info_mask |= DM_ATTRIBUTES;
908 if (S_ISDIR(inode->i_mode)) {
909 newmode &= server->m.dir_mode;
911 #ifdef CONFIG_NCPFS_EXTRAS
912 if (server->m.flags & NCP_MOUNT_EXTRAS) {
913 /* any non-default execute bit set */
914 if (newmode & ~server->m.file_mode & S_IXUGO)
915 info.attributes |= aSHARED | aSYSTEM;
916 /* read for group/world and not in default file_mode */
917 else if (newmode & ~server->m.file_mode & S_IRUGO)
918 info.attributes |= aSHARED;
921 newmode &= server->m.file_mode;
923 if (newmode & S_IWUGO)
924 info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
926 info.attributes |= (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
928 #ifdef CONFIG_NCPFS_NFS_NS
929 if (ncp_is_nfs_extras(server, NCP_FINFO(inode)->volNumber)) {
930 result = ncp_modify_nfs_info(server,
931 NCP_FINFO(inode)->volNumber,
932 NCP_FINFO(inode)->dirEntNum,
936 info.attributes &= ~(aSHARED | aSYSTEM);
938 /* mark partial success */
939 struct iattr tmpattr;
941 tmpattr.ia_valid = ATTR_MODE;
942 tmpattr.ia_mode = attr->ia_mode;
944 setattr_copy(inode, &tmpattr);
945 mark_inode_dirty(inode);
952 /* Do SIZE before attributes, otherwise mtime together with size does not work...
954 if ((attr->ia_valid & ATTR_SIZE) != 0) {
957 DPRINTK("ncpfs: trying to change size to %ld\n",
960 if ((result = ncp_make_open(inode, O_WRONLY)) < 0) {
964 ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
965 attr->ia_size, 0, "", &written);
967 /* According to ndir, the changes only take effect after
969 ncp_inode_close(inode);
970 result = ncp_make_closed(inode);
974 if (attr->ia_size != i_size_read(inode)) {
975 result = vmtruncate(inode, attr->ia_size);
978 mark_inode_dirty(inode);
981 if ((attr->ia_valid & ATTR_CTIME) != 0) {
982 info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE);
983 ncp_date_unix2dos(attr->ia_ctime.tv_sec,
984 &info.creationTime, &info.creationDate);
986 if ((attr->ia_valid & ATTR_MTIME) != 0) {
987 info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE);
988 ncp_date_unix2dos(attr->ia_mtime.tv_sec,
989 &info.modifyTime, &info.modifyDate);
991 if ((attr->ia_valid & ATTR_ATIME) != 0) {
993 info_mask |= (DM_LAST_ACCESS_DATE);
994 ncp_date_unix2dos(attr->ia_atime.tv_sec,
995 &dummy, &info.lastAccessDate);
997 if (info_mask != 0) {
998 result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
999 inode, info_mask, &info);
1001 if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
1002 /* NetWare seems not to allow this. I
1003 do not know why. So, just tell the
1004 user everything went fine. This is
1005 a terrible hack, but I do not know
1006 how to do this correctly. */
1011 #ifdef CONFIG_NCPFS_STRONG
1012 if ((!result) && (info_mask & DM_ATTRIBUTES))
1013 NCP_FINFO(inode)->nwattr = info.attributes;
1019 setattr_copy(inode, attr);
1020 mark_inode_dirty(inode);
1028 static struct dentry *ncp_mount(struct file_system_type *fs_type,
1029 int flags, const char *dev_name, void *data)
1031 return mount_nodev(fs_type, flags, data, ncp_fill_super);
1034 static struct file_system_type ncp_fs_type = {
1035 .owner = THIS_MODULE,
1038 .kill_sb = kill_anon_super,
1039 .fs_flags = FS_BINARY_MOUNTDATA,
1042 static int __init init_ncp_fs(void)
1045 DPRINTK("ncpfs: init_ncp_fs called\n");
1047 err = init_inodecache();
1050 err = register_filesystem(&ncp_fs_type);
1055 destroy_inodecache();
1060 static void __exit exit_ncp_fs(void)
1062 DPRINTK("ncpfs: exit_ncp_fs called\n");
1063 unregister_filesystem(&ncp_fs_type);
1064 destroy_inodecache();
1067 module_init(init_ncp_fs)
1068 module_exit(exit_ncp_fs)
1069 MODULE_LICENSE("GPL");