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>
34 #include <linux/ncp_fs.h>
38 #include "ncplib_kernel.h"
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
46 static void ncp_evict_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 *);
51 static struct kmem_cache * ncp_inode_cachep;
53 static struct inode *ncp_alloc_inode(struct super_block *sb)
55 struct ncp_inode_info *ei;
56 ei = (struct ncp_inode_info *)kmem_cache_alloc(ncp_inode_cachep, GFP_KERNEL);
59 return &ei->vfs_inode;
62 static void ncp_i_callback(struct rcu_head *head)
64 struct inode *inode = container_of(head, struct inode, i_rcu);
65 INIT_LIST_HEAD(&inode->i_dentry);
66 kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode));
69 static void ncp_destroy_inode(struct inode *inode)
71 call_rcu(&inode->i_rcu, ncp_i_callback);
74 static void init_once(void *foo)
76 struct ncp_inode_info *ei = (struct ncp_inode_info *) foo;
78 mutex_init(&ei->open_mutex);
79 inode_init_once(&ei->vfs_inode);
82 static int init_inodecache(void)
84 ncp_inode_cachep = kmem_cache_create("ncp_inode_cache",
85 sizeof(struct ncp_inode_info),
86 0, (SLAB_RECLAIM_ACCOUNT|
89 if (ncp_inode_cachep == NULL)
94 static void destroy_inodecache(void)
96 kmem_cache_destroy(ncp_inode_cachep);
99 static int ncp_remount(struct super_block *sb, int *flags, char* data)
101 *flags |= MS_NODIRATIME;
105 static const struct super_operations ncp_sops =
107 .alloc_inode = ncp_alloc_inode,
108 .destroy_inode = ncp_destroy_inode,
109 .drop_inode = generic_delete_inode,
110 .evict_inode = ncp_evict_inode,
111 .put_super = ncp_put_super,
112 .statfs = ncp_statfs,
113 .remount_fs = ncp_remount,
114 .show_options = ncp_show_options,
118 * Fill in the ncpfs-specific information in the inode.
120 static void ncp_update_dirent(struct inode *inode, struct ncp_entry_info *nwinfo)
122 NCP_FINFO(inode)->DosDirNum = nwinfo->i.DosDirNum;
123 NCP_FINFO(inode)->dirEntNum = nwinfo->i.dirEntNum;
124 NCP_FINFO(inode)->volNumber = nwinfo->volume;
127 void ncp_update_inode(struct inode *inode, struct ncp_entry_info *nwinfo)
129 ncp_update_dirent(inode, nwinfo);
130 NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
131 NCP_FINFO(inode)->access = nwinfo->access;
132 memcpy(NCP_FINFO(inode)->file_handle, nwinfo->file_handle,
133 sizeof(nwinfo->file_handle));
134 DPRINTK("ncp_update_inode: updated %s, volnum=%d, dirent=%u\n",
135 nwinfo->i.entryName, NCP_FINFO(inode)->volNumber,
136 NCP_FINFO(inode)->dirEntNum);
139 static void ncp_update_dates(struct inode *inode, struct nw_info_struct *nwi)
141 /* NFS namespace mode overrides others if it's set. */
142 DPRINTK(KERN_DEBUG "ncp_update_dates_and_mode: (%s) nfs.mode=0%o\n",
143 nwi->entryName, nwi->nfs.mode);
146 inode->i_mode = nwi->nfs.mode;
149 inode->i_blocks = (i_size_read(inode) + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
151 inode->i_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate);
152 inode->i_ctime.tv_sec = ncp_date_dos2unix(nwi->creationTime, nwi->creationDate);
153 inode->i_atime.tv_sec = ncp_date_dos2unix(0, nwi->lastAccessDate);
154 inode->i_atime.tv_nsec = 0;
155 inode->i_mtime.tv_nsec = 0;
156 inode->i_ctime.tv_nsec = 0;
159 static void ncp_update_attrs(struct inode *inode, struct ncp_entry_info *nwinfo)
161 struct nw_info_struct *nwi = &nwinfo->i;
162 struct ncp_server *server = NCP_SERVER(inode);
164 if (nwi->attributes & aDIR) {
165 inode->i_mode = server->m.dir_mode;
166 /* for directories dataStreamSize seems to be some
168 i_size_write(inode, NCP_BLOCK_SIZE);
172 inode->i_mode = server->m.file_mode;
173 size = le32_to_cpu(nwi->dataStreamSize);
174 i_size_write(inode, size);
175 #ifdef CONFIG_NCPFS_EXTRAS
176 if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS))
177 && (nwi->attributes & aSHARED)) {
178 switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
180 if (server->m.flags & NCP_MOUNT_SYMLINKS) {
181 if (/* (size >= NCP_MIN_SYMLINK_SIZE)
182 && */ (size <= NCP_MAX_SYMLINK_SIZE)) {
183 inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
184 NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK;
190 if (server->m.flags & NCP_MOUNT_EXTRAS)
191 inode->i_mode |= S_IRUGO;
194 if (server->m.flags & NCP_MOUNT_EXTRAS)
195 inode->i_mode |= (inode->i_mode >> 2) & S_IXUGO;
197 /* case aSYSTEM|aHIDDEN: */
199 /* reserved combination */
205 if (nwi->attributes & aRONLY) inode->i_mode &= ~S_IWUGO;
208 void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo)
210 NCP_FINFO(inode)->flags = 0;
211 if (!atomic_read(&NCP_FINFO(inode)->opened)) {
212 NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
213 ncp_update_attrs(inode, nwinfo);
216 ncp_update_dates(inode, &nwinfo->i);
217 ncp_update_dirent(inode, nwinfo);
221 * Fill in the inode based on the ncp_entry_info structure. Used only for brand new inodes.
223 static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
225 struct ncp_server *server = NCP_SERVER(inode);
227 NCP_FINFO(inode)->flags = 0;
229 ncp_update_attrs(inode, nwinfo);
231 DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode->i_mode);
234 inode->i_uid = server->m.uid;
235 inode->i_gid = server->m.gid;
237 ncp_update_dates(inode, &nwinfo->i);
238 ncp_update_inode(inode, nwinfo);
241 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
242 static const struct inode_operations ncp_symlink_inode_operations = {
243 .readlink = generic_readlink,
244 .follow_link = page_follow_link_light,
245 .put_link = page_put_link,
246 .setattr = ncp_notify_change,
254 ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
259 printk(KERN_ERR "ncp_iget: info is NULL\n");
263 inode = new_inode(sb);
265 atomic_set(&NCP_FINFO(inode)->opened, info->opened);
267 inode->i_mapping->backing_dev_info = sb->s_bdi;
268 inode->i_ino = info->ino;
269 ncp_set_attr(inode, info);
270 if (S_ISREG(inode->i_mode)) {
271 inode->i_op = &ncp_file_inode_operations;
272 inode->i_fop = &ncp_file_operations;
273 } else if (S_ISDIR(inode->i_mode)) {
274 inode->i_op = &ncp_dir_inode_operations;
275 inode->i_fop = &ncp_dir_operations;
276 #ifdef CONFIG_NCPFS_NFS_NS
277 } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
278 init_special_inode(inode, inode->i_mode,
279 new_decode_dev(info->i.nfs.rdev));
281 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
282 } else if (S_ISLNK(inode->i_mode)) {
283 inode->i_op = &ncp_symlink_inode_operations;
284 inode->i_data.a_ops = &ncp_symlink_aops;
287 make_bad_inode(inode);
289 insert_inode_hash(inode);
291 printk(KERN_ERR "ncp_iget: iget failed!\n");
296 ncp_evict_inode(struct inode *inode)
298 truncate_inode_pages(&inode->i_data, 0);
299 end_writeback(inode);
301 if (S_ISDIR(inode->i_mode)) {
302 DDPRINTK("ncp_evict_inode: put directory %ld\n", inode->i_ino);
305 if (ncp_make_closed(inode) != 0) {
306 /* We can't do anything but complain. */
307 printk(KERN_ERR "ncp_evict_inode: could not close\n");
311 static void ncp_stop_tasks(struct ncp_server *server) {
312 struct sock* sk = server->ncp_sock->sk;
315 sk->sk_error_report = server->error_report;
316 sk->sk_data_ready = server->data_ready;
317 sk->sk_write_space = server->write_space;
319 del_timer_sync(&server->timeout_tm);
320 flush_scheduled_work();
323 static int ncp_show_options(struct seq_file *seq, struct vfsmount *mnt)
325 struct ncp_server *server = NCP_SBP(mnt->mnt_sb);
328 if (server->m.uid != 0)
329 seq_printf(seq, ",uid=%u", server->m.uid);
330 if (server->m.gid != 0)
331 seq_printf(seq, ",gid=%u", server->m.gid);
332 if (server->m.mounted_uid != 0)
333 seq_printf(seq, ",owner=%u", server->m.mounted_uid);
334 tmp = server->m.file_mode & S_IALLUGO;
335 if (tmp != NCP_DEFAULT_FILE_MODE)
336 seq_printf(seq, ",mode=0%o", tmp);
337 tmp = server->m.dir_mode & S_IALLUGO;
338 if (tmp != NCP_DEFAULT_DIR_MODE)
339 seq_printf(seq, ",dirmode=0%o", tmp);
340 if (server->m.time_out != NCP_DEFAULT_TIME_OUT * HZ / 100) {
341 tmp = server->m.time_out * 100 / HZ;
342 seq_printf(seq, ",timeout=%u", tmp);
344 if (server->m.retry_count != NCP_DEFAULT_RETRY_COUNT)
345 seq_printf(seq, ",retry=%u", server->m.retry_count);
346 if (server->m.flags != 0)
347 seq_printf(seq, ",flags=%lu", server->m.flags);
348 if (server->m.wdog_pid != NULL)
349 seq_printf(seq, ",wdogpid=%u", pid_vnr(server->m.wdog_pid));
354 static const struct ncp_option ncp_opts[] = {
355 { "uid", OPT_INT, 'u' },
356 { "gid", OPT_INT, 'g' },
357 { "owner", OPT_INT, 'o' },
358 { "mode", OPT_INT, 'm' },
359 { "dirmode", OPT_INT, 'd' },
360 { "timeout", OPT_INT, 't' },
361 { "retry", OPT_INT, 'r' },
362 { "flags", OPT_INT, 'f' },
363 { "wdogpid", OPT_INT, 'w' },
364 { "ncpfd", OPT_INT, 'n' },
365 { "infofd", OPT_INT, 'i' }, /* v5 */
366 { "version", OPT_INT, 'v' },
369 static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) {
372 unsigned long optint;
378 data->mounted_uid = 0;
379 data->wdog_pid = NULL;
381 data->time_out = NCP_DEFAULT_TIME_OUT;
382 data->retry_count = NCP_DEFAULT_RETRY_COUNT;
385 data->file_mode = NCP_DEFAULT_FILE_MODE;
386 data->dir_mode = NCP_DEFAULT_DIR_MODE;
388 data->mounted_vol[0] = 0;
390 while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 0) {
402 data->mounted_uid = optint;
405 data->file_mode = optint;
408 data->dir_mode = optint;
411 data->time_out = optint;
414 data->retry_count = optint;
417 data->flags = optint;
420 data->wdog_pid = find_get_pid(optint);
423 data->ncp_fd = optint;
426 data->info_fd = optint;
430 if (optint < NCP_MOUNT_VERSION_V4)
432 if (optint > NCP_MOUNT_VERSION_V5)
441 put_pid(data->wdog_pid);
442 data->wdog_pid = NULL;
446 static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
448 struct ncp_mount_data_kernel data;
449 struct ncp_server *server;
450 struct file *ncp_filp;
451 struct inode *root_inode;
452 struct inode *sock_inode;
456 #ifdef CONFIG_NCPFS_PACKET_SIGNING
459 struct ncp_entry_info finfo;
461 data.wdog_pid = NULL;
462 server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL);
465 sb->s_fs_info = server;
468 if (raw_data == NULL)
470 switch (*(int*)raw_data) {
471 case NCP_MOUNT_VERSION:
473 struct ncp_mount_data* md = (struct ncp_mount_data*)raw_data;
475 data.flags = md->flags;
476 data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE;
477 data.mounted_uid = md->mounted_uid;
478 data.wdog_pid = find_get_pid(md->wdog_pid);
479 data.ncp_fd = md->ncp_fd;
480 data.time_out = md->time_out;
481 data.retry_count = md->retry_count;
484 data.file_mode = md->file_mode;
485 data.dir_mode = md->dir_mode;
487 memcpy(data.mounted_vol, md->mounted_vol,
491 case NCP_MOUNT_VERSION_V4:
493 struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data;
495 data.flags = md->flags;
497 data.mounted_uid = md->mounted_uid;
498 data.wdog_pid = find_get_pid(md->wdog_pid);
499 data.ncp_fd = md->ncp_fd;
500 data.time_out = md->time_out;
501 data.retry_count = md->retry_count;
504 data.file_mode = md->file_mode;
505 data.dir_mode = md->dir_mode;
507 data.mounted_vol[0] = 0;
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_bdi = &server->bdi;
544 server = NCP_SBP(sb);
545 memset(server, 0, sizeof(*server));
547 error = bdi_setup_and_register(&server->bdi, "ncpfs", BDI_CAP_MAP_COPY);
551 server->ncp_filp = ncp_filp;
552 server->ncp_sock = sock;
554 if (data.info_fd != -1) {
555 struct socket *info_sock;
558 server->info_filp = fget(data.info_fd);
559 if (!server->info_filp)
562 sock_inode = server->info_filp->f_path.dentry->d_inode;
563 if (!S_ISSOCK(sock_inode->i_mode))
565 info_sock = SOCKET_I(sock_inode);
569 if (info_sock->type != SOCK_STREAM)
571 server->info_sock = info_sock;
574 /* server->lock = 0; */
575 mutex_init(&server->mutex);
576 server->packet = NULL;
577 /* server->buffer_size = 0; */
578 /* server->conn_status = 0; */
579 /* server->root_dentry = NULL; */
580 /* server->root_setuped = 0; */
581 mutex_init(&server->root_setup_lock);
582 #ifdef CONFIG_NCPFS_PACKET_SIGNING
583 /* server->sign_wanted = 0; */
584 /* server->sign_active = 0; */
586 init_rwsem(&server->auth_rwsem);
587 server->auth.auth_type = NCP_AUTH_NONE;
588 /* server->auth.object_name_len = 0; */
589 /* server->auth.object_name = NULL; */
590 /* server->auth.object_type = 0; */
591 /* server->priv.len = 0; */
592 /* server->priv.data = NULL; */
595 /* Althought anything producing this is buggy, it happens
596 now because of PATH_MAX changes.. */
597 if (server->m.time_out < 1) {
598 server->m.time_out = 10;
599 printk(KERN_INFO "You need to recompile your ncpfs utils..\n");
601 server->m.time_out = server->m.time_out * HZ / 100;
602 server->m.file_mode = (server->m.file_mode & S_IRWXUGO) | S_IFREG;
603 server->m.dir_mode = (server->m.dir_mode & S_IRWXUGO) | S_IFDIR;
605 #ifdef CONFIG_NCPFS_NLS
606 /* load the default NLS charsets */
607 server->nls_vol = load_nls_default();
608 server->nls_io = load_nls_default();
609 #endif /* CONFIG_NCPFS_NLS */
611 atomic_set(&server->dentry_ttl, 0); /* no caching */
613 INIT_LIST_HEAD(&server->tx.requests);
614 mutex_init(&server->rcv.creq_mutex);
615 server->tx.creq = NULL;
616 server->rcv.creq = NULL;
618 init_timer(&server->timeout_tm);
619 #undef NCP_PACKET_SIZE
620 #define NCP_PACKET_SIZE 131072
622 server->packet_size = NCP_PACKET_SIZE;
623 server->packet = vmalloc(NCP_PACKET_SIZE);
624 if (server->packet == NULL)
626 server->txbuf = vmalloc(NCP_PACKET_SIZE);
627 if (server->txbuf == NULL)
629 server->rxbuf = vmalloc(NCP_PACKET_SIZE);
630 if (server->rxbuf == NULL)
634 server->data_ready = sock->sk->sk_data_ready;
635 server->write_space = sock->sk->sk_write_space;
636 server->error_report = sock->sk->sk_error_report;
637 sock->sk->sk_user_data = server;
638 sock->sk->sk_data_ready = ncp_tcp_data_ready;
639 sock->sk->sk_error_report = ncp_tcp_error_report;
640 if (sock->type == SOCK_STREAM) {
641 server->rcv.ptr = (unsigned char*)&server->rcv.buf;
642 server->rcv.len = 10;
643 server->rcv.state = 0;
644 INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc);
645 INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc);
646 sock->sk->sk_write_space = ncp_tcp_write_space;
648 INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc);
649 INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc);
650 server->timeout_tm.data = (unsigned long)server;
651 server->timeout_tm.function = ncpdgram_timeout_call;
653 release_sock(sock->sk);
655 ncp_lock_server(server);
656 error = ncp_connect(server);
657 ncp_unlock_server(server);
660 DPRINTK("ncp_fill_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb));
662 error = -EMSGSIZE; /* -EREMOTESIDEINCOMPATIBLE */
663 #ifdef CONFIG_NCPFS_PACKET_SIGNING
664 if (ncp_negotiate_size_and_options(server, default_bufsize,
665 NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0)
667 if (options != NCP_DEFAULT_OPTIONS)
669 if (ncp_negotiate_size_and_options(server,
672 &(server->buffer_size), &options) != 0)
678 ncp_lock_server(server);
680 server->sign_wanted = 1;
681 ncp_unlock_server(server);
684 #endif /* CONFIG_NCPFS_PACKET_SIGNING */
685 if (ncp_negotiate_buffersize(server, default_bufsize,
686 &(server->buffer_size)) != 0)
688 DPRINTK("ncpfs: bufsize = %d\n", server->buffer_size);
690 memset(&finfo, 0, sizeof(finfo));
691 finfo.i.attributes = aDIR;
692 finfo.i.dataStreamSize = 0; /* ignored */
693 finfo.i.dirEntNum = 0;
694 finfo.i.DosDirNum = 0;
695 #ifdef CONFIG_NCPFS_SMALLDOS
696 finfo.i.NSCreator = NW_NS_DOS;
698 finfo.volume = NCP_NUMBER_OF_VOLUMES;
699 /* set dates of mountpoint to Jan 1, 1986; 00:00 */
700 finfo.i.creationTime = finfo.i.modifyTime
701 = cpu_to_le16(0x0000);
702 finfo.i.creationDate = finfo.i.modifyDate
703 = finfo.i.lastAccessDate
704 = cpu_to_le16(0x0C21);
706 finfo.i.entryName[0] = '\0';
709 finfo.ino = 2; /* tradition */
711 server->name_space[finfo.volume] = NW_NS_DOS;
714 root_inode = ncp_iget(sb, &finfo);
717 DPRINTK("ncp_fill_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
718 sb->s_root = d_alloc_root(root_inode);
721 d_set_d_op(sb->s_root, &ncp_root_dentry_operations);
727 ncp_lock_server(server);
728 ncp_disconnect(server);
729 ncp_unlock_server(server);
731 ncp_stop_tasks(server);
732 vfree(server->rxbuf);
734 vfree(server->txbuf);
736 vfree(server->packet);
738 #ifdef CONFIG_NCPFS_NLS
739 unload_nls(server->nls_io);
740 unload_nls(server->nls_vol);
742 mutex_destroy(&server->rcv.creq_mutex);
743 mutex_destroy(&server->root_setup_lock);
744 mutex_destroy(&server->mutex);
746 if (server->info_filp)
747 fput(server->info_filp);
749 bdi_destroy(&server->bdi);
751 /* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:
753 * The previously used put_filp(ncp_filp); was bogus, since
754 * it doesn't perform proper unlocking.
758 put_pid(data.wdog_pid);
759 sb->s_fs_info = NULL;
764 static void ncp_put_super(struct super_block *sb)
766 struct ncp_server *server = NCP_SBP(sb);
768 ncp_lock_server(server);
769 ncp_disconnect(server);
770 ncp_unlock_server(server);
772 ncp_stop_tasks(server);
774 #ifdef CONFIG_NCPFS_NLS
775 /* unload the NLS charsets */
776 unload_nls(server->nls_vol);
777 unload_nls(server->nls_io);
778 #endif /* CONFIG_NCPFS_NLS */
779 mutex_destroy(&server->rcv.creq_mutex);
780 mutex_destroy(&server->root_setup_lock);
781 mutex_destroy(&server->mutex);
783 if (server->info_filp)
784 fput(server->info_filp);
785 fput(server->ncp_filp);
786 kill_pid(server->m.wdog_pid, SIGTERM, 1);
787 put_pid(server->m.wdog_pid);
789 bdi_destroy(&server->bdi);
790 kfree(server->priv.data);
791 kfree(server->auth.object_name);
792 vfree(server->rxbuf);
793 vfree(server->txbuf);
794 vfree(server->packet);
795 sb->s_fs_info = NULL;
799 static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
803 struct ncp_inode_info* ni;
804 struct ncp_server* s;
805 struct ncp_volume_info vi;
806 struct super_block *sb = dentry->d_sb;
826 if (!s->m.mounted_vol[0]) {
830 err = ncp_dirhandle_alloc(s, ni->volNumber, ni->DosDirNum, &dh);
834 err = ncp_get_directory_info(s, dh, &vi);
835 ncp_dirhandle_free(s, dh);
839 buf->f_type = NCP_SUPER_MAGIC;
840 buf->f_bsize = vi.sectors_per_block * 512;
841 buf->f_blocks = vi.total_blocks;
842 buf->f_bfree = vi.free_blocks;
843 buf->f_bavail = vi.free_blocks;
844 buf->f_files = vi.total_dir_entries;
845 buf->f_ffree = vi.available_dir_entries;
849 /* We cannot say how much disk space is left on a mounted
850 NetWare Server, because free space is distributed over
851 volumes, and the current user might have disk quotas. So
852 free space is not that simple to determine. Our decision
853 here is to err conservatively. */
856 buf->f_type = NCP_SUPER_MAGIC;
857 buf->f_bsize = NCP_BLOCK_SIZE;
865 int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
867 struct inode *inode = dentry->d_inode;
870 struct nw_modify_dos_info info;
871 struct ncp_server *server;
875 server = NCP_SERVER(inode);
876 if (!server) /* How this could happen? */
879 /* ageing the dentry to force validation */
880 ncp_age_dentry(server, dentry);
882 result = inode_change_ok(inode, attr);
887 if (((attr->ia_valid & ATTR_UID) &&
888 (attr->ia_uid != server->m.uid)))
891 if (((attr->ia_valid & ATTR_GID) &&
892 (attr->ia_gid != server->m.gid)))
895 if (((attr->ia_valid & ATTR_MODE) &&
897 ~(S_IFREG | S_IFDIR | S_IRWXUGO))))
901 memset(&info, 0, sizeof(info));
904 if ((attr->ia_valid & ATTR_MODE) != 0)
906 umode_t newmode = attr->ia_mode;
908 info_mask |= DM_ATTRIBUTES;
910 if (S_ISDIR(inode->i_mode)) {
911 newmode &= server->m.dir_mode;
913 #ifdef CONFIG_NCPFS_EXTRAS
914 if (server->m.flags & NCP_MOUNT_EXTRAS) {
915 /* any non-default execute bit set */
916 if (newmode & ~server->m.file_mode & S_IXUGO)
917 info.attributes |= aSHARED | aSYSTEM;
918 /* read for group/world and not in default file_mode */
919 else if (newmode & ~server->m.file_mode & S_IRUGO)
920 info.attributes |= aSHARED;
923 newmode &= server->m.file_mode;
925 if (newmode & S_IWUGO)
926 info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
928 info.attributes |= (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
930 #ifdef CONFIG_NCPFS_NFS_NS
931 if (ncp_is_nfs_extras(server, NCP_FINFO(inode)->volNumber)) {
932 result = ncp_modify_nfs_info(server,
933 NCP_FINFO(inode)->volNumber,
934 NCP_FINFO(inode)->dirEntNum,
938 info.attributes &= ~(aSHARED | aSYSTEM);
940 /* mark partial success */
941 struct iattr tmpattr;
943 tmpattr.ia_valid = ATTR_MODE;
944 tmpattr.ia_mode = attr->ia_mode;
946 setattr_copy(inode, &tmpattr);
947 mark_inode_dirty(inode);
954 /* Do SIZE before attributes, otherwise mtime together with size does not work...
956 if ((attr->ia_valid & ATTR_SIZE) != 0) {
959 DPRINTK("ncpfs: trying to change size to %ld\n",
962 if ((result = ncp_make_open(inode, O_WRONLY)) < 0) {
966 ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
967 attr->ia_size, 0, "", &written);
969 /* According to ndir, the changes only take effect after
971 ncp_inode_close(inode);
972 result = ncp_make_closed(inode);
976 if (attr->ia_size != i_size_read(inode)) {
977 result = vmtruncate(inode, attr->ia_size);
980 mark_inode_dirty(inode);
983 if ((attr->ia_valid & ATTR_CTIME) != 0) {
984 info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE);
985 ncp_date_unix2dos(attr->ia_ctime.tv_sec,
986 &info.creationTime, &info.creationDate);
988 if ((attr->ia_valid & ATTR_MTIME) != 0) {
989 info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE);
990 ncp_date_unix2dos(attr->ia_mtime.tv_sec,
991 &info.modifyTime, &info.modifyDate);
993 if ((attr->ia_valid & ATTR_ATIME) != 0) {
995 info_mask |= (DM_LAST_ACCESS_DATE);
996 ncp_date_unix2dos(attr->ia_atime.tv_sec,
997 &dummy, &info.lastAccessDate);
999 if (info_mask != 0) {
1000 result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
1001 inode, info_mask, &info);
1003 if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
1004 /* NetWare seems not to allow this. I
1005 do not know why. So, just tell the
1006 user everything went fine. This is
1007 a terrible hack, but I do not know
1008 how to do this correctly. */
1013 #ifdef CONFIG_NCPFS_STRONG
1014 if ((!result) && (info_mask & DM_ATTRIBUTES))
1015 NCP_FINFO(inode)->nwattr = info.attributes;
1021 setattr_copy(inode, attr);
1022 mark_inode_dirty(inode);
1030 static struct dentry *ncp_mount(struct file_system_type *fs_type,
1031 int flags, const char *dev_name, void *data)
1033 return mount_nodev(fs_type, flags, data, ncp_fill_super);
1036 static struct file_system_type ncp_fs_type = {
1037 .owner = THIS_MODULE,
1040 .kill_sb = kill_anon_super,
1041 .fs_flags = FS_BINARY_MOUNTDATA,
1044 static int __init init_ncp_fs(void)
1047 DPRINTK("ncpfs: init_ncp_fs called\n");
1049 err = init_inodecache();
1052 err = register_filesystem(&ncp_fs_type);
1057 destroy_inodecache();
1062 static void __exit exit_ncp_fs(void)
1064 DPRINTK("ncpfs: exit_ncp_fs called\n");
1065 unregister_filesystem(&ncp_fs_type);
1066 destroy_inodecache();
1069 module_init(init_ncp_fs)
1070 module_exit(exit_ncp_fs)
1071 MODULE_LICENSE("GPL");