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>
33 #include <linux/ncp_fs.h>
37 #include "ncplib_kernel.h"
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
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 vfsmount *);
50 static struct kmem_cache * ncp_inode_cachep;
52 static struct inode *ncp_alloc_inode(struct super_block *sb)
54 struct ncp_inode_info *ei;
55 ei = (struct ncp_inode_info *)kmem_cache_alloc(ncp_inode_cachep, GFP_KERNEL);
58 return &ei->vfs_inode;
61 static void ncp_i_callback(struct rcu_head *head)
63 struct inode *inode = container_of(head, struct inode, i_rcu);
64 INIT_LIST_HEAD(&inode->i_dentry);
65 kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode));
68 static void ncp_destroy_inode(struct inode *inode)
70 call_rcu(&inode->i_rcu, ncp_i_callback);
73 static void init_once(void *foo)
75 struct ncp_inode_info *ei = (struct ncp_inode_info *) foo;
77 mutex_init(&ei->open_mutex);
78 inode_init_once(&ei->vfs_inode);
81 static int init_inodecache(void)
83 ncp_inode_cachep = kmem_cache_create("ncp_inode_cache",
84 sizeof(struct ncp_inode_info),
85 0, (SLAB_RECLAIM_ACCOUNT|
88 if (ncp_inode_cachep == NULL)
93 static void destroy_inodecache(void)
95 kmem_cache_destroy(ncp_inode_cachep);
98 static int ncp_remount(struct super_block *sb, int *flags, char* data)
100 *flags |= MS_NODIRATIME;
104 static const struct super_operations ncp_sops =
106 .alloc_inode = ncp_alloc_inode,
107 .destroy_inode = ncp_destroy_inode,
108 .drop_inode = generic_delete_inode,
109 .evict_inode = ncp_evict_inode,
110 .put_super = ncp_put_super,
111 .statfs = ncp_statfs,
112 .remount_fs = ncp_remount,
113 .show_options = ncp_show_options,
117 * Fill in the ncpfs-specific information in the inode.
119 static void ncp_update_dirent(struct inode *inode, struct ncp_entry_info *nwinfo)
121 NCP_FINFO(inode)->DosDirNum = nwinfo->i.DosDirNum;
122 NCP_FINFO(inode)->dirEntNum = nwinfo->i.dirEntNum;
123 NCP_FINFO(inode)->volNumber = nwinfo->volume;
126 void ncp_update_inode(struct inode *inode, struct ncp_entry_info *nwinfo)
128 ncp_update_dirent(inode, nwinfo);
129 NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
130 NCP_FINFO(inode)->access = nwinfo->access;
131 memcpy(NCP_FINFO(inode)->file_handle, nwinfo->file_handle,
132 sizeof(nwinfo->file_handle));
133 DPRINTK("ncp_update_inode: updated %s, volnum=%d, dirent=%u\n",
134 nwinfo->i.entryName, NCP_FINFO(inode)->volNumber,
135 NCP_FINFO(inode)->dirEntNum);
138 static void ncp_update_dates(struct inode *inode, struct nw_info_struct *nwi)
140 /* NFS namespace mode overrides others if it's set. */
141 DPRINTK(KERN_DEBUG "ncp_update_dates_and_mode: (%s) nfs.mode=0%o\n",
142 nwi->entryName, nwi->nfs.mode);
145 inode->i_mode = nwi->nfs.mode;
148 inode->i_blocks = (i_size_read(inode) + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
150 inode->i_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate);
151 inode->i_ctime.tv_sec = ncp_date_dos2unix(nwi->creationTime, nwi->creationDate);
152 inode->i_atime.tv_sec = ncp_date_dos2unix(0, nwi->lastAccessDate);
153 inode->i_atime.tv_nsec = 0;
154 inode->i_mtime.tv_nsec = 0;
155 inode->i_ctime.tv_nsec = 0;
158 static void ncp_update_attrs(struct inode *inode, struct ncp_entry_info *nwinfo)
160 struct nw_info_struct *nwi = &nwinfo->i;
161 struct ncp_server *server = NCP_SERVER(inode);
163 if (nwi->attributes & aDIR) {
164 inode->i_mode = server->m.dir_mode;
165 /* for directories dataStreamSize seems to be some
167 i_size_write(inode, NCP_BLOCK_SIZE);
171 inode->i_mode = server->m.file_mode;
172 size = le32_to_cpu(nwi->dataStreamSize);
173 i_size_write(inode, size);
174 #ifdef CONFIG_NCPFS_EXTRAS
175 if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS))
176 && (nwi->attributes & aSHARED)) {
177 switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
179 if (server->m.flags & NCP_MOUNT_SYMLINKS) {
180 if (/* (size >= NCP_MIN_SYMLINK_SIZE)
181 && */ (size <= NCP_MAX_SYMLINK_SIZE)) {
182 inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
183 NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK;
189 if (server->m.flags & NCP_MOUNT_EXTRAS)
190 inode->i_mode |= S_IRUGO;
193 if (server->m.flags & NCP_MOUNT_EXTRAS)
194 inode->i_mode |= (inode->i_mode >> 2) & S_IXUGO;
196 /* case aSYSTEM|aHIDDEN: */
198 /* reserved combination */
204 if (nwi->attributes & aRONLY) inode->i_mode &= ~S_IWUGO;
207 void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo)
209 NCP_FINFO(inode)->flags = 0;
210 if (!atomic_read(&NCP_FINFO(inode)->opened)) {
211 NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
212 ncp_update_attrs(inode, nwinfo);
215 ncp_update_dates(inode, &nwinfo->i);
216 ncp_update_dirent(inode, nwinfo);
220 * Fill in the inode based on the ncp_entry_info structure. Used only for brand new inodes.
222 static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
224 struct ncp_server *server = NCP_SERVER(inode);
226 NCP_FINFO(inode)->flags = 0;
228 ncp_update_attrs(inode, nwinfo);
230 DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode->i_mode);
233 inode->i_uid = server->m.uid;
234 inode->i_gid = server->m.gid;
236 ncp_update_dates(inode, &nwinfo->i);
237 ncp_update_inode(inode, nwinfo);
240 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
241 static const struct inode_operations ncp_symlink_inode_operations = {
242 .readlink = generic_readlink,
243 .follow_link = page_follow_link_light,
244 .put_link = page_put_link,
245 .setattr = ncp_notify_change,
253 ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
258 printk(KERN_ERR "ncp_iget: info is NULL\n");
262 inode = new_inode(sb);
264 atomic_set(&NCP_FINFO(inode)->opened, info->opened);
266 inode->i_mapping->backing_dev_info = sb->s_bdi;
267 inode->i_ino = info->ino;
268 ncp_set_attr(inode, info);
269 if (S_ISREG(inode->i_mode)) {
270 inode->i_op = &ncp_file_inode_operations;
271 inode->i_fop = &ncp_file_operations;
272 } else if (S_ISDIR(inode->i_mode)) {
273 inode->i_op = &ncp_dir_inode_operations;
274 inode->i_fop = &ncp_dir_operations;
275 #ifdef CONFIG_NCPFS_NFS_NS
276 } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
277 init_special_inode(inode, inode->i_mode,
278 new_decode_dev(info->i.nfs.rdev));
280 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
281 } else if (S_ISLNK(inode->i_mode)) {
282 inode->i_op = &ncp_symlink_inode_operations;
283 inode->i_data.a_ops = &ncp_symlink_aops;
286 make_bad_inode(inode);
288 insert_inode_hash(inode);
290 printk(KERN_ERR "ncp_iget: iget failed!\n");
295 ncp_evict_inode(struct inode *inode)
297 truncate_inode_pages(&inode->i_data, 0);
298 end_writeback(inode);
300 if (S_ISDIR(inode->i_mode)) {
301 DDPRINTK("ncp_evict_inode: put directory %ld\n", inode->i_ino);
304 if (ncp_make_closed(inode) != 0) {
305 /* We can't do anything but complain. */
306 printk(KERN_ERR "ncp_evict_inode: could not close\n");
310 static void ncp_stop_tasks(struct ncp_server *server) {
311 struct sock* sk = server->ncp_sock->sk;
314 sk->sk_error_report = server->error_report;
315 sk->sk_data_ready = server->data_ready;
316 sk->sk_write_space = server->write_space;
318 del_timer_sync(&server->timeout_tm);
319 flush_scheduled_work();
322 static int ncp_show_options(struct seq_file *seq, struct vfsmount *mnt)
324 struct ncp_server *server = NCP_SBP(mnt->mnt_sb);
327 if (server->m.uid != 0)
328 seq_printf(seq, ",uid=%u", server->m.uid);
329 if (server->m.gid != 0)
330 seq_printf(seq, ",gid=%u", server->m.gid);
331 if (server->m.mounted_uid != 0)
332 seq_printf(seq, ",owner=%u", server->m.mounted_uid);
333 tmp = server->m.file_mode & S_IALLUGO;
334 if (tmp != NCP_DEFAULT_FILE_MODE)
335 seq_printf(seq, ",mode=0%o", tmp);
336 tmp = server->m.dir_mode & S_IALLUGO;
337 if (tmp != NCP_DEFAULT_DIR_MODE)
338 seq_printf(seq, ",dirmode=0%o", tmp);
339 if (server->m.time_out != NCP_DEFAULT_TIME_OUT * HZ / 100) {
340 tmp = server->m.time_out * 100 / HZ;
341 seq_printf(seq, ",timeout=%u", tmp);
343 if (server->m.retry_count != NCP_DEFAULT_RETRY_COUNT)
344 seq_printf(seq, ",retry=%u", server->m.retry_count);
345 if (server->m.flags != 0)
346 seq_printf(seq, ",flags=%lu", server->m.flags);
347 if (server->m.wdog_pid != NULL)
348 seq_printf(seq, ",wdogpid=%u", pid_vnr(server->m.wdog_pid));
353 static const struct ncp_option ncp_opts[] = {
354 { "uid", OPT_INT, 'u' },
355 { "gid", OPT_INT, 'g' },
356 { "owner", OPT_INT, 'o' },
357 { "mode", OPT_INT, 'm' },
358 { "dirmode", OPT_INT, 'd' },
359 { "timeout", OPT_INT, 't' },
360 { "retry", OPT_INT, 'r' },
361 { "flags", OPT_INT, 'f' },
362 { "wdogpid", OPT_INT, 'w' },
363 { "ncpfd", OPT_INT, 'n' },
364 { "infofd", OPT_INT, 'i' }, /* v5 */
365 { "version", OPT_INT, 'v' },
368 static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) {
371 unsigned long optint;
377 data->mounted_uid = 0;
378 data->wdog_pid = NULL;
380 data->time_out = NCP_DEFAULT_TIME_OUT;
381 data->retry_count = NCP_DEFAULT_RETRY_COUNT;
384 data->file_mode = NCP_DEFAULT_FILE_MODE;
385 data->dir_mode = NCP_DEFAULT_DIR_MODE;
387 data->mounted_vol[0] = 0;
389 while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 0) {
401 data->mounted_uid = optint;
404 data->file_mode = optint;
407 data->dir_mode = optint;
410 data->time_out = optint;
413 data->retry_count = optint;
416 data->flags = optint;
419 data->wdog_pid = find_get_pid(optint);
422 data->ncp_fd = optint;
425 data->info_fd = optint;
429 if (optint < NCP_MOUNT_VERSION_V4)
431 if (optint > NCP_MOUNT_VERSION_V5)
440 put_pid(data->wdog_pid);
441 data->wdog_pid = NULL;
445 static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
447 struct ncp_mount_data_kernel data;
448 struct ncp_server *server;
449 struct file *ncp_filp;
450 struct inode *root_inode;
451 struct inode *sock_inode;
455 #ifdef CONFIG_NCPFS_PACKET_SIGNING
458 struct ncp_entry_info finfo;
460 data.wdog_pid = NULL;
461 server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL);
464 sb->s_fs_info = server;
467 if (raw_data == NULL)
469 switch (*(int*)raw_data) {
470 case NCP_MOUNT_VERSION:
472 struct ncp_mount_data* md = (struct ncp_mount_data*)raw_data;
474 data.flags = md->flags;
475 data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE;
476 data.mounted_uid = md->mounted_uid;
477 data.wdog_pid = find_get_pid(md->wdog_pid);
478 data.ncp_fd = md->ncp_fd;
479 data.time_out = md->time_out;
480 data.retry_count = md->retry_count;
483 data.file_mode = md->file_mode;
484 data.dir_mode = md->dir_mode;
486 memcpy(data.mounted_vol, md->mounted_vol,
490 case NCP_MOUNT_VERSION_V4:
492 struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data;
494 data.flags = md->flags;
496 data.mounted_uid = md->mounted_uid;
497 data.wdog_pid = find_get_pid(md->wdog_pid);
498 data.ncp_fd = md->ncp_fd;
499 data.time_out = md->time_out;
500 data.retry_count = md->retry_count;
503 data.file_mode = md->file_mode;
504 data.dir_mode = md->dir_mode;
506 data.mounted_vol[0] = 0;
511 if (memcmp(raw_data, "vers", 4) == 0) {
512 error = ncp_parse_options(&data, raw_data);
519 ncp_filp = fget(data.ncp_fd);
523 sock_inode = ncp_filp->f_path.dentry->d_inode;
524 if (!S_ISSOCK(sock_inode->i_mode))
526 sock = SOCKET_I(sock_inode);
530 if (sock->type == SOCK_STREAM)
531 default_bufsize = 0xF000;
533 default_bufsize = 1024;
535 sb->s_flags |= MS_NODIRATIME; /* probably even noatime */
536 sb->s_maxbytes = 0xFFFFFFFFU;
537 sb->s_blocksize = 1024; /* Eh... Is this correct? */
538 sb->s_blocksize_bits = 10;
539 sb->s_magic = NCP_SUPER_MAGIC;
540 sb->s_op = &ncp_sops;
541 sb->s_bdi = &server->bdi;
543 server = NCP_SBP(sb);
544 memset(server, 0, sizeof(*server));
546 error = bdi_setup_and_register(&server->bdi, "ncpfs", BDI_CAP_MAP_COPY);
550 server->ncp_filp = ncp_filp;
551 server->ncp_sock = sock;
553 if (data.info_fd != -1) {
554 struct socket *info_sock;
557 server->info_filp = fget(data.info_fd);
558 if (!server->info_filp)
561 sock_inode = server->info_filp->f_path.dentry->d_inode;
562 if (!S_ISSOCK(sock_inode->i_mode))
564 info_sock = SOCKET_I(sock_inode);
568 if (info_sock->type != SOCK_STREAM)
570 server->info_sock = info_sock;
573 /* server->lock = 0; */
574 mutex_init(&server->mutex);
575 server->packet = NULL;
576 /* server->buffer_size = 0; */
577 /* server->conn_status = 0; */
578 /* server->root_dentry = NULL; */
579 /* server->root_setuped = 0; */
580 mutex_init(&server->root_setup_lock);
581 #ifdef CONFIG_NCPFS_PACKET_SIGNING
582 /* server->sign_wanted = 0; */
583 /* server->sign_active = 0; */
585 init_rwsem(&server->auth_rwsem);
586 server->auth.auth_type = NCP_AUTH_NONE;
587 /* server->auth.object_name_len = 0; */
588 /* server->auth.object_name = NULL; */
589 /* server->auth.object_type = 0; */
590 /* server->priv.len = 0; */
591 /* server->priv.data = NULL; */
594 /* Althought anything producing this is buggy, it happens
595 now because of PATH_MAX changes.. */
596 if (server->m.time_out < 1) {
597 server->m.time_out = 10;
598 printk(KERN_INFO "You need to recompile your ncpfs utils..\n");
600 server->m.time_out = server->m.time_out * HZ / 100;
601 server->m.file_mode = (server->m.file_mode & S_IRWXUGO) | S_IFREG;
602 server->m.dir_mode = (server->m.dir_mode & S_IRWXUGO) | S_IFDIR;
604 #ifdef CONFIG_NCPFS_NLS
605 /* load the default NLS charsets */
606 server->nls_vol = load_nls_default();
607 server->nls_io = load_nls_default();
608 #endif /* CONFIG_NCPFS_NLS */
610 atomic_set(&server->dentry_ttl, 0); /* no caching */
612 INIT_LIST_HEAD(&server->tx.requests);
613 mutex_init(&server->rcv.creq_mutex);
614 server->tx.creq = NULL;
615 server->rcv.creq = NULL;
617 init_timer(&server->timeout_tm);
618 #undef NCP_PACKET_SIZE
619 #define NCP_PACKET_SIZE 131072
621 server->packet_size = NCP_PACKET_SIZE;
622 server->packet = vmalloc(NCP_PACKET_SIZE);
623 if (server->packet == NULL)
625 server->txbuf = vmalloc(NCP_PACKET_SIZE);
626 if (server->txbuf == NULL)
628 server->rxbuf = vmalloc(NCP_PACKET_SIZE);
629 if (server->rxbuf == NULL)
633 server->data_ready = sock->sk->sk_data_ready;
634 server->write_space = sock->sk->sk_write_space;
635 server->error_report = sock->sk->sk_error_report;
636 sock->sk->sk_user_data = server;
637 sock->sk->sk_data_ready = ncp_tcp_data_ready;
638 sock->sk->sk_error_report = ncp_tcp_error_report;
639 if (sock->type == SOCK_STREAM) {
640 server->rcv.ptr = (unsigned char*)&server->rcv.buf;
641 server->rcv.len = 10;
642 server->rcv.state = 0;
643 INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc);
644 INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc);
645 sock->sk->sk_write_space = ncp_tcp_write_space;
647 INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc);
648 INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc);
649 server->timeout_tm.data = (unsigned long)server;
650 server->timeout_tm.function = ncpdgram_timeout_call;
652 release_sock(sock->sk);
654 ncp_lock_server(server);
655 error = ncp_connect(server);
656 ncp_unlock_server(server);
659 DPRINTK("ncp_fill_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb));
661 error = -EMSGSIZE; /* -EREMOTESIDEINCOMPATIBLE */
662 #ifdef CONFIG_NCPFS_PACKET_SIGNING
663 if (ncp_negotiate_size_and_options(server, default_bufsize,
664 NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0)
666 if (options != NCP_DEFAULT_OPTIONS)
668 if (ncp_negotiate_size_and_options(server,
671 &(server->buffer_size), &options) != 0)
677 ncp_lock_server(server);
679 server->sign_wanted = 1;
680 ncp_unlock_server(server);
683 #endif /* CONFIG_NCPFS_PACKET_SIGNING */
684 if (ncp_negotiate_buffersize(server, default_bufsize,
685 &(server->buffer_size)) != 0)
687 DPRINTK("ncpfs: bufsize = %d\n", server->buffer_size);
689 memset(&finfo, 0, sizeof(finfo));
690 finfo.i.attributes = aDIR;
691 finfo.i.dataStreamSize = 0; /* ignored */
692 finfo.i.dirEntNum = 0;
693 finfo.i.DosDirNum = 0;
694 #ifdef CONFIG_NCPFS_SMALLDOS
695 finfo.i.NSCreator = NW_NS_DOS;
697 finfo.volume = NCP_NUMBER_OF_VOLUMES;
698 /* set dates of mountpoint to Jan 1, 1986; 00:00 */
699 finfo.i.creationTime = finfo.i.modifyTime
700 = cpu_to_le16(0x0000);
701 finfo.i.creationDate = finfo.i.modifyDate
702 = finfo.i.lastAccessDate
703 = cpu_to_le16(0x0C21);
705 finfo.i.entryName[0] = '\0';
708 finfo.ino = 2; /* tradition */
710 server->name_space[finfo.volume] = NW_NS_DOS;
713 root_inode = ncp_iget(sb, &finfo);
716 DPRINTK("ncp_fill_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
717 sb->s_root = d_alloc_root(root_inode);
720 d_set_d_op(sb->s_root, &ncp_root_dentry_operations);
726 ncp_lock_server(server);
727 ncp_disconnect(server);
728 ncp_unlock_server(server);
730 ncp_stop_tasks(server);
731 vfree(server->rxbuf);
733 vfree(server->txbuf);
735 vfree(server->packet);
737 #ifdef CONFIG_NCPFS_NLS
738 unload_nls(server->nls_io);
739 unload_nls(server->nls_vol);
741 mutex_destroy(&server->rcv.creq_mutex);
742 mutex_destroy(&server->root_setup_lock);
743 mutex_destroy(&server->mutex);
745 if (server->info_filp)
746 fput(server->info_filp);
748 bdi_destroy(&server->bdi);
750 /* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:
752 * The previously used put_filp(ncp_filp); was bogus, since
753 * it doesn't perform proper unlocking.
757 put_pid(data.wdog_pid);
758 sb->s_fs_info = NULL;
763 static void ncp_put_super(struct super_block *sb)
765 struct ncp_server *server = NCP_SBP(sb);
767 ncp_lock_server(server);
768 ncp_disconnect(server);
769 ncp_unlock_server(server);
771 ncp_stop_tasks(server);
773 #ifdef CONFIG_NCPFS_NLS
774 /* unload the NLS charsets */
775 unload_nls(server->nls_vol);
776 unload_nls(server->nls_io);
777 #endif /* CONFIG_NCPFS_NLS */
778 mutex_destroy(&server->rcv.creq_mutex);
779 mutex_destroy(&server->root_setup_lock);
780 mutex_destroy(&server->mutex);
782 if (server->info_filp)
783 fput(server->info_filp);
784 fput(server->ncp_filp);
785 kill_pid(server->m.wdog_pid, SIGTERM, 1);
786 put_pid(server->m.wdog_pid);
788 bdi_destroy(&server->bdi);
789 kfree(server->priv.data);
790 kfree(server->auth.object_name);
791 vfree(server->rxbuf);
792 vfree(server->txbuf);
793 vfree(server->packet);
794 sb->s_fs_info = NULL;
798 static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
802 struct ncp_inode_info* ni;
803 struct ncp_server* s;
804 struct ncp_volume_info vi;
805 struct super_block *sb = dentry->d_sb;
825 if (!s->m.mounted_vol[0]) {
829 err = ncp_dirhandle_alloc(s, ni->volNumber, ni->DosDirNum, &dh);
833 err = ncp_get_directory_info(s, dh, &vi);
834 ncp_dirhandle_free(s, dh);
838 buf->f_type = NCP_SUPER_MAGIC;
839 buf->f_bsize = vi.sectors_per_block * 512;
840 buf->f_blocks = vi.total_blocks;
841 buf->f_bfree = vi.free_blocks;
842 buf->f_bavail = vi.free_blocks;
843 buf->f_files = vi.total_dir_entries;
844 buf->f_ffree = vi.available_dir_entries;
848 /* We cannot say how much disk space is left on a mounted
849 NetWare Server, because free space is distributed over
850 volumes, and the current user might have disk quotas. So
851 free space is not that simple to determine. Our decision
852 here is to err conservatively. */
855 buf->f_type = NCP_SUPER_MAGIC;
856 buf->f_bsize = NCP_BLOCK_SIZE;
864 int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
866 struct inode *inode = dentry->d_inode;
869 struct nw_modify_dos_info info;
870 struct ncp_server *server;
874 server = NCP_SERVER(inode);
875 if (!server) /* How this could happen? */
878 /* ageing the dentry to force validation */
879 ncp_age_dentry(server, dentry);
881 result = inode_change_ok(inode, attr);
886 if (((attr->ia_valid & ATTR_UID) &&
887 (attr->ia_uid != server->m.uid)))
890 if (((attr->ia_valid & ATTR_GID) &&
891 (attr->ia_gid != server->m.gid)))
894 if (((attr->ia_valid & ATTR_MODE) &&
896 ~(S_IFREG | S_IFDIR | S_IRWXUGO))))
900 memset(&info, 0, sizeof(info));
903 if ((attr->ia_valid & ATTR_MODE) != 0)
905 umode_t newmode = attr->ia_mode;
907 info_mask |= DM_ATTRIBUTES;
909 if (S_ISDIR(inode->i_mode)) {
910 newmode &= server->m.dir_mode;
912 #ifdef CONFIG_NCPFS_EXTRAS
913 if (server->m.flags & NCP_MOUNT_EXTRAS) {
914 /* any non-default execute bit set */
915 if (newmode & ~server->m.file_mode & S_IXUGO)
916 info.attributes |= aSHARED | aSYSTEM;
917 /* read for group/world and not in default file_mode */
918 else if (newmode & ~server->m.file_mode & S_IRUGO)
919 info.attributes |= aSHARED;
922 newmode &= server->m.file_mode;
924 if (newmode & S_IWUGO)
925 info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
927 info.attributes |= (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
929 #ifdef CONFIG_NCPFS_NFS_NS
930 if (ncp_is_nfs_extras(server, NCP_FINFO(inode)->volNumber)) {
931 result = ncp_modify_nfs_info(server,
932 NCP_FINFO(inode)->volNumber,
933 NCP_FINFO(inode)->dirEntNum,
937 info.attributes &= ~(aSHARED | aSYSTEM);
939 /* mark partial success */
940 struct iattr tmpattr;
942 tmpattr.ia_valid = ATTR_MODE;
943 tmpattr.ia_mode = attr->ia_mode;
945 setattr_copy(inode, &tmpattr);
946 mark_inode_dirty(inode);
953 /* Do SIZE before attributes, otherwise mtime together with size does not work...
955 if ((attr->ia_valid & ATTR_SIZE) != 0) {
958 DPRINTK("ncpfs: trying to change size to %ld\n",
961 if ((result = ncp_make_open(inode, O_WRONLY)) < 0) {
965 ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
966 attr->ia_size, 0, "", &written);
968 /* According to ndir, the changes only take effect after
970 ncp_inode_close(inode);
971 result = ncp_make_closed(inode);
975 if (attr->ia_size != i_size_read(inode)) {
976 result = vmtruncate(inode, attr->ia_size);
979 mark_inode_dirty(inode);
982 if ((attr->ia_valid & ATTR_CTIME) != 0) {
983 info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE);
984 ncp_date_unix2dos(attr->ia_ctime.tv_sec,
985 &info.creationTime, &info.creationDate);
987 if ((attr->ia_valid & ATTR_MTIME) != 0) {
988 info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE);
989 ncp_date_unix2dos(attr->ia_mtime.tv_sec,
990 &info.modifyTime, &info.modifyDate);
992 if ((attr->ia_valid & ATTR_ATIME) != 0) {
994 info_mask |= (DM_LAST_ACCESS_DATE);
995 ncp_date_unix2dos(attr->ia_atime.tv_sec,
996 &dummy, &info.lastAccessDate);
998 if (info_mask != 0) {
999 result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
1000 inode, info_mask, &info);
1002 if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
1003 /* NetWare seems not to allow this. I
1004 do not know why. So, just tell the
1005 user everything went fine. This is
1006 a terrible hack, but I do not know
1007 how to do this correctly. */
1012 #ifdef CONFIG_NCPFS_STRONG
1013 if ((!result) && (info_mask & DM_ATTRIBUTES))
1014 NCP_FINFO(inode)->nwattr = info.attributes;
1020 setattr_copy(inode, attr);
1021 mark_inode_dirty(inode);
1029 static struct dentry *ncp_mount(struct file_system_type *fs_type,
1030 int flags, const char *dev_name, void *data)
1032 return mount_nodev(fs_type, flags, data, ncp_fill_super);
1035 static struct file_system_type ncp_fs_type = {
1036 .owner = THIS_MODULE,
1039 .kill_sb = kill_anon_super,
1040 .fs_flags = FS_BINARY_MOUNTDATA,
1043 static int __init init_ncp_fs(void)
1046 DPRINTK("ncpfs: init_ncp_fs called\n");
1048 err = init_inodecache();
1051 err = register_filesystem(&ncp_fs_type);
1056 destroy_inodecache();
1061 static void __exit exit_ncp_fs(void)
1063 DPRINTK("ncpfs: exit_ncp_fs called\n");
1064 unregister_filesystem(&ncp_fs_type);
1065 destroy_inodecache();
1068 module_init(init_ncp_fs)
1069 module_exit(exit_ncp_fs)
1070 MODULE_LICENSE("GPL");