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_destroy_inode(struct inode *inode)
63 kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode));
66 static void init_once(void *foo)
68 struct ncp_inode_info *ei = (struct ncp_inode_info *) foo;
70 mutex_init(&ei->open_mutex);
71 inode_init_once(&ei->vfs_inode);
74 static int init_inodecache(void)
76 ncp_inode_cachep = kmem_cache_create("ncp_inode_cache",
77 sizeof(struct ncp_inode_info),
78 0, (SLAB_RECLAIM_ACCOUNT|
81 if (ncp_inode_cachep == NULL)
86 static void destroy_inodecache(void)
88 kmem_cache_destroy(ncp_inode_cachep);
91 static int ncp_remount(struct super_block *sb, int *flags, char* data)
93 *flags |= MS_NODIRATIME;
97 static const struct super_operations ncp_sops =
99 .alloc_inode = ncp_alloc_inode,
100 .destroy_inode = ncp_destroy_inode,
101 .drop_inode = generic_delete_inode,
102 .evict_inode = ncp_evict_inode,
103 .put_super = ncp_put_super,
104 .statfs = ncp_statfs,
105 .remount_fs = ncp_remount,
106 .show_options = ncp_show_options,
110 * Fill in the ncpfs-specific information in the inode.
112 static void ncp_update_dirent(struct inode *inode, struct ncp_entry_info *nwinfo)
114 NCP_FINFO(inode)->DosDirNum = nwinfo->i.DosDirNum;
115 NCP_FINFO(inode)->dirEntNum = nwinfo->i.dirEntNum;
116 NCP_FINFO(inode)->volNumber = nwinfo->volume;
119 void ncp_update_inode(struct inode *inode, struct ncp_entry_info *nwinfo)
121 ncp_update_dirent(inode, nwinfo);
122 NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
123 NCP_FINFO(inode)->access = nwinfo->access;
124 memcpy(NCP_FINFO(inode)->file_handle, nwinfo->file_handle,
125 sizeof(nwinfo->file_handle));
126 DPRINTK("ncp_update_inode: updated %s, volnum=%d, dirent=%u\n",
127 nwinfo->i.entryName, NCP_FINFO(inode)->volNumber,
128 NCP_FINFO(inode)->dirEntNum);
131 static void ncp_update_dates(struct inode *inode, struct nw_info_struct *nwi)
133 /* NFS namespace mode overrides others if it's set. */
134 DPRINTK(KERN_DEBUG "ncp_update_dates_and_mode: (%s) nfs.mode=0%o\n",
135 nwi->entryName, nwi->nfs.mode);
138 inode->i_mode = nwi->nfs.mode;
141 inode->i_blocks = (i_size_read(inode) + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
143 inode->i_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate);
144 inode->i_ctime.tv_sec = ncp_date_dos2unix(nwi->creationTime, nwi->creationDate);
145 inode->i_atime.tv_sec = ncp_date_dos2unix(0, nwi->lastAccessDate);
146 inode->i_atime.tv_nsec = 0;
147 inode->i_mtime.tv_nsec = 0;
148 inode->i_ctime.tv_nsec = 0;
151 static void ncp_update_attrs(struct inode *inode, struct ncp_entry_info *nwinfo)
153 struct nw_info_struct *nwi = &nwinfo->i;
154 struct ncp_server *server = NCP_SERVER(inode);
156 if (nwi->attributes & aDIR) {
157 inode->i_mode = server->m.dir_mode;
158 /* for directories dataStreamSize seems to be some
160 i_size_write(inode, NCP_BLOCK_SIZE);
164 inode->i_mode = server->m.file_mode;
165 size = le32_to_cpu(nwi->dataStreamSize);
166 i_size_write(inode, size);
167 #ifdef CONFIG_NCPFS_EXTRAS
168 if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS))
169 && (nwi->attributes & aSHARED)) {
170 switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
172 if (server->m.flags & NCP_MOUNT_SYMLINKS) {
173 if (/* (size >= NCP_MIN_SYMLINK_SIZE)
174 && */ (size <= NCP_MAX_SYMLINK_SIZE)) {
175 inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
176 NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK;
182 if (server->m.flags & NCP_MOUNT_EXTRAS)
183 inode->i_mode |= S_IRUGO;
186 if (server->m.flags & NCP_MOUNT_EXTRAS)
187 inode->i_mode |= (inode->i_mode >> 2) & S_IXUGO;
189 /* case aSYSTEM|aHIDDEN: */
191 /* reserved combination */
197 if (nwi->attributes & aRONLY) inode->i_mode &= ~S_IWUGO;
200 void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo)
202 NCP_FINFO(inode)->flags = 0;
203 if (!atomic_read(&NCP_FINFO(inode)->opened)) {
204 NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
205 ncp_update_attrs(inode, nwinfo);
208 ncp_update_dates(inode, &nwinfo->i);
209 ncp_update_dirent(inode, nwinfo);
213 * Fill in the inode based on the ncp_entry_info structure. Used only for brand new inodes.
215 static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
217 struct ncp_server *server = NCP_SERVER(inode);
219 NCP_FINFO(inode)->flags = 0;
221 ncp_update_attrs(inode, nwinfo);
223 DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode->i_mode);
226 inode->i_uid = server->m.uid;
227 inode->i_gid = server->m.gid;
229 ncp_update_dates(inode, &nwinfo->i);
230 ncp_update_inode(inode, nwinfo);
233 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
234 static const struct inode_operations ncp_symlink_inode_operations = {
235 .readlink = generic_readlink,
236 .follow_link = page_follow_link_light,
237 .put_link = page_put_link,
238 .setattr = ncp_notify_change,
246 ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
251 printk(KERN_ERR "ncp_iget: info is NULL\n");
255 inode = new_inode(sb);
257 atomic_set(&NCP_FINFO(inode)->opened, info->opened);
259 inode->i_mapping->backing_dev_info = sb->s_bdi;
260 inode->i_ino = info->ino;
261 ncp_set_attr(inode, info);
262 if (S_ISREG(inode->i_mode)) {
263 inode->i_op = &ncp_file_inode_operations;
264 inode->i_fop = &ncp_file_operations;
265 } else if (S_ISDIR(inode->i_mode)) {
266 inode->i_op = &ncp_dir_inode_operations;
267 inode->i_fop = &ncp_dir_operations;
268 #ifdef CONFIG_NCPFS_NFS_NS
269 } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
270 init_special_inode(inode, inode->i_mode,
271 new_decode_dev(info->i.nfs.rdev));
273 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
274 } else if (S_ISLNK(inode->i_mode)) {
275 inode->i_op = &ncp_symlink_inode_operations;
276 inode->i_data.a_ops = &ncp_symlink_aops;
279 make_bad_inode(inode);
281 insert_inode_hash(inode);
283 printk(KERN_ERR "ncp_iget: iget failed!\n");
288 ncp_evict_inode(struct inode *inode)
290 truncate_inode_pages(&inode->i_data, 0);
291 end_writeback(inode);
293 if (S_ISDIR(inode->i_mode)) {
294 DDPRINTK("ncp_evict_inode: put directory %ld\n", inode->i_ino);
297 if (ncp_make_closed(inode) != 0) {
298 /* We can't do anything but complain. */
299 printk(KERN_ERR "ncp_evict_inode: could not close\n");
303 static void ncp_stop_tasks(struct ncp_server *server) {
304 struct sock* sk = server->ncp_sock->sk;
307 sk->sk_error_report = server->error_report;
308 sk->sk_data_ready = server->data_ready;
309 sk->sk_write_space = server->write_space;
311 del_timer_sync(&server->timeout_tm);
312 flush_scheduled_work();
315 static int ncp_show_options(struct seq_file *seq, struct vfsmount *mnt)
317 struct ncp_server *server = NCP_SBP(mnt->mnt_sb);
320 if (server->m.uid != 0)
321 seq_printf(seq, ",uid=%u", server->m.uid);
322 if (server->m.gid != 0)
323 seq_printf(seq, ",gid=%u", server->m.gid);
324 if (server->m.mounted_uid != 0)
325 seq_printf(seq, ",owner=%u", server->m.mounted_uid);
326 tmp = server->m.file_mode & S_IALLUGO;
327 if (tmp != NCP_DEFAULT_FILE_MODE)
328 seq_printf(seq, ",mode=0%o", tmp);
329 tmp = server->m.dir_mode & S_IALLUGO;
330 if (tmp != NCP_DEFAULT_DIR_MODE)
331 seq_printf(seq, ",dirmode=0%o", tmp);
332 if (server->m.time_out != NCP_DEFAULT_TIME_OUT * HZ / 100) {
333 tmp = server->m.time_out * 100 / HZ;
334 seq_printf(seq, ",timeout=%u", tmp);
336 if (server->m.retry_count != NCP_DEFAULT_RETRY_COUNT)
337 seq_printf(seq, ",retry=%u", server->m.retry_count);
338 if (server->m.flags != 0)
339 seq_printf(seq, ",flags=%lu", server->m.flags);
340 if (server->m.wdog_pid != NULL)
341 seq_printf(seq, ",wdogpid=%u", pid_vnr(server->m.wdog_pid));
346 static const struct ncp_option ncp_opts[] = {
347 { "uid", OPT_INT, 'u' },
348 { "gid", OPT_INT, 'g' },
349 { "owner", OPT_INT, 'o' },
350 { "mode", OPT_INT, 'm' },
351 { "dirmode", OPT_INT, 'd' },
352 { "timeout", OPT_INT, 't' },
353 { "retry", OPT_INT, 'r' },
354 { "flags", OPT_INT, 'f' },
355 { "wdogpid", OPT_INT, 'w' },
356 { "ncpfd", OPT_INT, 'n' },
357 { "infofd", OPT_INT, 'i' }, /* v5 */
358 { "version", OPT_INT, 'v' },
361 static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) {
364 unsigned long optint;
370 data->mounted_uid = 0;
371 data->wdog_pid = NULL;
373 data->time_out = NCP_DEFAULT_TIME_OUT;
374 data->retry_count = NCP_DEFAULT_RETRY_COUNT;
377 data->file_mode = NCP_DEFAULT_FILE_MODE;
378 data->dir_mode = NCP_DEFAULT_DIR_MODE;
380 data->mounted_vol[0] = 0;
382 while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 0) {
394 data->mounted_uid = optint;
397 data->file_mode = optint;
400 data->dir_mode = optint;
403 data->time_out = optint;
406 data->retry_count = optint;
409 data->flags = optint;
412 data->wdog_pid = find_get_pid(optint);
415 data->ncp_fd = optint;
418 data->info_fd = optint;
422 if (optint < NCP_MOUNT_VERSION_V4)
424 if (optint > NCP_MOUNT_VERSION_V5)
433 put_pid(data->wdog_pid);
434 data->wdog_pid = NULL;
438 static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
440 struct ncp_mount_data_kernel data;
441 struct ncp_server *server;
442 struct file *ncp_filp;
443 struct inode *root_inode;
444 struct inode *sock_inode;
448 #ifdef CONFIG_NCPFS_PACKET_SIGNING
451 struct ncp_entry_info finfo;
453 data.wdog_pid = NULL;
454 server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL);
457 sb->s_fs_info = server;
460 if (raw_data == NULL)
462 switch (*(int*)raw_data) {
463 case NCP_MOUNT_VERSION:
465 struct ncp_mount_data* md = (struct ncp_mount_data*)raw_data;
467 data.flags = md->flags;
468 data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE;
469 data.mounted_uid = md->mounted_uid;
470 data.wdog_pid = find_get_pid(md->wdog_pid);
471 data.ncp_fd = md->ncp_fd;
472 data.time_out = md->time_out;
473 data.retry_count = md->retry_count;
476 data.file_mode = md->file_mode;
477 data.dir_mode = md->dir_mode;
479 memcpy(data.mounted_vol, md->mounted_vol,
483 case NCP_MOUNT_VERSION_V4:
485 struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data;
487 data.flags = md->flags;
489 data.mounted_uid = md->mounted_uid;
490 data.wdog_pid = find_get_pid(md->wdog_pid);
491 data.ncp_fd = md->ncp_fd;
492 data.time_out = md->time_out;
493 data.retry_count = md->retry_count;
496 data.file_mode = md->file_mode;
497 data.dir_mode = md->dir_mode;
499 data.mounted_vol[0] = 0;
504 if (memcmp(raw_data, "vers", 4) == 0) {
505 error = ncp_parse_options(&data, raw_data);
512 ncp_filp = fget(data.ncp_fd);
516 sock_inode = ncp_filp->f_path.dentry->d_inode;
517 if (!S_ISSOCK(sock_inode->i_mode))
519 sock = SOCKET_I(sock_inode);
523 if (sock->type == SOCK_STREAM)
524 default_bufsize = 0xF000;
526 default_bufsize = 1024;
528 sb->s_flags |= MS_NODIRATIME; /* probably even noatime */
529 sb->s_maxbytes = 0xFFFFFFFFU;
530 sb->s_blocksize = 1024; /* Eh... Is this correct? */
531 sb->s_blocksize_bits = 10;
532 sb->s_magic = NCP_SUPER_MAGIC;
533 sb->s_op = &ncp_sops;
534 sb->s_bdi = &server->bdi;
536 server = NCP_SBP(sb);
537 memset(server, 0, sizeof(*server));
539 error = bdi_setup_and_register(&server->bdi, "ncpfs", BDI_CAP_MAP_COPY);
543 server->ncp_filp = ncp_filp;
544 server->ncp_sock = sock;
546 if (data.info_fd != -1) {
547 struct socket *info_sock;
550 server->info_filp = fget(data.info_fd);
551 if (!server->info_filp)
554 sock_inode = server->info_filp->f_path.dentry->d_inode;
555 if (!S_ISSOCK(sock_inode->i_mode))
557 info_sock = SOCKET_I(sock_inode);
561 if (info_sock->type != SOCK_STREAM)
563 server->info_sock = info_sock;
566 /* server->lock = 0; */
567 mutex_init(&server->mutex);
568 server->packet = NULL;
569 /* server->buffer_size = 0; */
570 /* server->conn_status = 0; */
571 /* server->root_dentry = NULL; */
572 /* server->root_setuped = 0; */
573 mutex_init(&server->root_setup_lock);
574 #ifdef CONFIG_NCPFS_PACKET_SIGNING
575 /* server->sign_wanted = 0; */
576 /* server->sign_active = 0; */
578 init_rwsem(&server->auth_rwsem);
579 server->auth.auth_type = NCP_AUTH_NONE;
580 /* server->auth.object_name_len = 0; */
581 /* server->auth.object_name = NULL; */
582 /* server->auth.object_type = 0; */
583 /* server->priv.len = 0; */
584 /* server->priv.data = NULL; */
587 /* Althought anything producing this is buggy, it happens
588 now because of PATH_MAX changes.. */
589 if (server->m.time_out < 1) {
590 server->m.time_out = 10;
591 printk(KERN_INFO "You need to recompile your ncpfs utils..\n");
593 server->m.time_out = server->m.time_out * HZ / 100;
594 server->m.file_mode = (server->m.file_mode & S_IRWXUGO) | S_IFREG;
595 server->m.dir_mode = (server->m.dir_mode & S_IRWXUGO) | S_IFDIR;
597 #ifdef CONFIG_NCPFS_NLS
598 /* load the default NLS charsets */
599 server->nls_vol = load_nls_default();
600 server->nls_io = load_nls_default();
601 #endif /* CONFIG_NCPFS_NLS */
603 atomic_set(&server->dentry_ttl, 0); /* no caching */
605 INIT_LIST_HEAD(&server->tx.requests);
606 mutex_init(&server->rcv.creq_mutex);
607 server->tx.creq = NULL;
608 server->rcv.creq = NULL;
610 init_timer(&server->timeout_tm);
611 #undef NCP_PACKET_SIZE
612 #define NCP_PACKET_SIZE 131072
614 server->packet_size = NCP_PACKET_SIZE;
615 server->packet = vmalloc(NCP_PACKET_SIZE);
616 if (server->packet == NULL)
618 server->txbuf = vmalloc(NCP_PACKET_SIZE);
619 if (server->txbuf == NULL)
621 server->rxbuf = vmalloc(NCP_PACKET_SIZE);
622 if (server->rxbuf == NULL)
626 server->data_ready = sock->sk->sk_data_ready;
627 server->write_space = sock->sk->sk_write_space;
628 server->error_report = sock->sk->sk_error_report;
629 sock->sk->sk_user_data = server;
630 sock->sk->sk_data_ready = ncp_tcp_data_ready;
631 sock->sk->sk_error_report = ncp_tcp_error_report;
632 if (sock->type == SOCK_STREAM) {
633 server->rcv.ptr = (unsigned char*)&server->rcv.buf;
634 server->rcv.len = 10;
635 server->rcv.state = 0;
636 INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc);
637 INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc);
638 sock->sk->sk_write_space = ncp_tcp_write_space;
640 INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc);
641 INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc);
642 server->timeout_tm.data = (unsigned long)server;
643 server->timeout_tm.function = ncpdgram_timeout_call;
645 release_sock(sock->sk);
647 ncp_lock_server(server);
648 error = ncp_connect(server);
649 ncp_unlock_server(server);
652 DPRINTK("ncp_fill_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb));
654 error = -EMSGSIZE; /* -EREMOTESIDEINCOMPATIBLE */
655 #ifdef CONFIG_NCPFS_PACKET_SIGNING
656 if (ncp_negotiate_size_and_options(server, default_bufsize,
657 NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0)
659 if (options != NCP_DEFAULT_OPTIONS)
661 if (ncp_negotiate_size_and_options(server,
664 &(server->buffer_size), &options) != 0)
670 ncp_lock_server(server);
672 server->sign_wanted = 1;
673 ncp_unlock_server(server);
676 #endif /* CONFIG_NCPFS_PACKET_SIGNING */
677 if (ncp_negotiate_buffersize(server, default_bufsize,
678 &(server->buffer_size)) != 0)
680 DPRINTK("ncpfs: bufsize = %d\n", server->buffer_size);
682 memset(&finfo, 0, sizeof(finfo));
683 finfo.i.attributes = aDIR;
684 finfo.i.dataStreamSize = 0; /* ignored */
685 finfo.i.dirEntNum = 0;
686 finfo.i.DosDirNum = 0;
687 #ifdef CONFIG_NCPFS_SMALLDOS
688 finfo.i.NSCreator = NW_NS_DOS;
690 finfo.volume = NCP_NUMBER_OF_VOLUMES;
691 /* set dates of mountpoint to Jan 1, 1986; 00:00 */
692 finfo.i.creationTime = finfo.i.modifyTime
693 = cpu_to_le16(0x0000);
694 finfo.i.creationDate = finfo.i.modifyDate
695 = finfo.i.lastAccessDate
696 = cpu_to_le16(0x0C21);
698 finfo.i.entryName[0] = '\0';
701 finfo.ino = 2; /* tradition */
703 server->name_space[finfo.volume] = NW_NS_DOS;
706 root_inode = ncp_iget(sb, &finfo);
709 DPRINTK("ncp_fill_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
710 sb->s_root = d_alloc_root(root_inode);
713 sb->s_root->d_op = &ncp_root_dentry_operations;
719 ncp_lock_server(server);
720 ncp_disconnect(server);
721 ncp_unlock_server(server);
723 ncp_stop_tasks(server);
724 vfree(server->rxbuf);
726 vfree(server->txbuf);
728 vfree(server->packet);
730 #ifdef CONFIG_NCPFS_NLS
731 unload_nls(server->nls_io);
732 unload_nls(server->nls_vol);
734 mutex_destroy(&server->rcv.creq_mutex);
735 mutex_destroy(&server->root_setup_lock);
736 mutex_destroy(&server->mutex);
738 if (server->info_filp)
739 fput(server->info_filp);
741 bdi_destroy(&server->bdi);
745 * The previously used put_filp(ncp_filp); was bogus, since
746 * it doesn't perform proper unlocking.
750 put_pid(data.wdog_pid);
751 sb->s_fs_info = NULL;
756 static void ncp_put_super(struct super_block *sb)
758 struct ncp_server *server = NCP_SBP(sb);
760 ncp_lock_server(server);
761 ncp_disconnect(server);
762 ncp_unlock_server(server);
764 ncp_stop_tasks(server);
766 #ifdef CONFIG_NCPFS_NLS
767 /* unload the NLS charsets */
768 unload_nls(server->nls_vol);
769 unload_nls(server->nls_io);
770 #endif /* CONFIG_NCPFS_NLS */
771 mutex_destroy(&server->rcv.creq_mutex);
772 mutex_destroy(&server->root_setup_lock);
773 mutex_destroy(&server->mutex);
775 if (server->info_filp)
776 fput(server->info_filp);
777 fput(server->ncp_filp);
778 kill_pid(server->m.wdog_pid, SIGTERM, 1);
779 put_pid(server->m.wdog_pid);
781 bdi_destroy(&server->bdi);
782 kfree(server->priv.data);
783 kfree(server->auth.object_name);
784 vfree(server->rxbuf);
785 vfree(server->txbuf);
786 vfree(server->packet);
787 sb->s_fs_info = NULL;
791 static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
795 struct ncp_inode_info* ni;
796 struct ncp_server* s;
797 struct ncp_volume_info vi;
798 struct super_block *sb = dentry->d_sb;
818 if (!s->m.mounted_vol[0]) {
822 err = ncp_dirhandle_alloc(s, ni->volNumber, ni->DosDirNum, &dh);
826 err = ncp_get_directory_info(s, dh, &vi);
827 ncp_dirhandle_free(s, dh);
831 buf->f_type = NCP_SUPER_MAGIC;
832 buf->f_bsize = vi.sectors_per_block * 512;
833 buf->f_blocks = vi.total_blocks;
834 buf->f_bfree = vi.free_blocks;
835 buf->f_bavail = vi.free_blocks;
836 buf->f_files = vi.total_dir_entries;
837 buf->f_ffree = vi.available_dir_entries;
841 /* We cannot say how much disk space is left on a mounted
842 NetWare Server, because free space is distributed over
843 volumes, and the current user might have disk quotas. So
844 free space is not that simple to determine. Our decision
845 here is to err conservatively. */
848 buf->f_type = NCP_SUPER_MAGIC;
849 buf->f_bsize = NCP_BLOCK_SIZE;
857 int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
859 struct inode *inode = dentry->d_inode;
862 struct nw_modify_dos_info info;
863 struct ncp_server *server;
867 server = NCP_SERVER(inode);
868 if (!server) /* How this could happen? */
871 /* ageing the dentry to force validation */
872 ncp_age_dentry(server, dentry);
874 result = inode_change_ok(inode, attr);
879 if (((attr->ia_valid & ATTR_UID) &&
880 (attr->ia_uid != server->m.uid)))
883 if (((attr->ia_valid & ATTR_GID) &&
884 (attr->ia_gid != server->m.gid)))
887 if (((attr->ia_valid & ATTR_MODE) &&
889 ~(S_IFREG | S_IFDIR | S_IRWXUGO))))
893 memset(&info, 0, sizeof(info));
896 if ((attr->ia_valid & ATTR_MODE) != 0)
898 umode_t newmode = attr->ia_mode;
900 info_mask |= DM_ATTRIBUTES;
902 if (S_ISDIR(inode->i_mode)) {
903 newmode &= server->m.dir_mode;
905 #ifdef CONFIG_NCPFS_EXTRAS
906 if (server->m.flags & NCP_MOUNT_EXTRAS) {
907 /* any non-default execute bit set */
908 if (newmode & ~server->m.file_mode & S_IXUGO)
909 info.attributes |= aSHARED | aSYSTEM;
910 /* read for group/world and not in default file_mode */
911 else if (newmode & ~server->m.file_mode & S_IRUGO)
912 info.attributes |= aSHARED;
915 newmode &= server->m.file_mode;
917 if (newmode & S_IWUGO)
918 info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
920 info.attributes |= (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
922 #ifdef CONFIG_NCPFS_NFS_NS
923 if (ncp_is_nfs_extras(server, NCP_FINFO(inode)->volNumber)) {
924 result = ncp_modify_nfs_info(server,
925 NCP_FINFO(inode)->volNumber,
926 NCP_FINFO(inode)->dirEntNum,
930 info.attributes &= ~(aSHARED | aSYSTEM);
932 /* mark partial success */
933 struct iattr tmpattr;
935 tmpattr.ia_valid = ATTR_MODE;
936 tmpattr.ia_mode = attr->ia_mode;
938 setattr_copy(inode, &tmpattr);
939 mark_inode_dirty(inode);
946 /* Do SIZE before attributes, otherwise mtime together with size does not work...
948 if ((attr->ia_valid & ATTR_SIZE) != 0) {
951 DPRINTK("ncpfs: trying to change size to %ld\n",
954 if ((result = ncp_make_open(inode, O_WRONLY)) < 0) {
958 ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
959 attr->ia_size, 0, "", &written);
961 /* According to ndir, the changes only take effect after
963 ncp_inode_close(inode);
964 result = ncp_make_closed(inode);
968 if (attr->ia_size != i_size_read(inode)) {
969 result = vmtruncate(inode, attr->ia_size);
972 mark_inode_dirty(inode);
975 if ((attr->ia_valid & ATTR_CTIME) != 0) {
976 info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE);
977 ncp_date_unix2dos(attr->ia_ctime.tv_sec,
978 &info.creationTime, &info.creationDate);
980 if ((attr->ia_valid & ATTR_MTIME) != 0) {
981 info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE);
982 ncp_date_unix2dos(attr->ia_mtime.tv_sec,
983 &info.modifyTime, &info.modifyDate);
985 if ((attr->ia_valid & ATTR_ATIME) != 0) {
987 info_mask |= (DM_LAST_ACCESS_DATE);
988 ncp_date_unix2dos(attr->ia_atime.tv_sec,
989 &dummy, &info.lastAccessDate);
991 if (info_mask != 0) {
992 result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
993 inode, info_mask, &info);
995 if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
996 /* NetWare seems not to allow this. I
997 do not know why. So, just tell the
998 user everything went fine. This is
999 a terrible hack, but I do not know
1000 how to do this correctly. */
1005 #ifdef CONFIG_NCPFS_STRONG
1006 if ((!result) && (info_mask & DM_ATTRIBUTES))
1007 NCP_FINFO(inode)->nwattr = info.attributes;
1013 setattr_copy(inode, attr);
1014 mark_inode_dirty(inode);
1022 static struct dentry *ncp_mount(struct file_system_type *fs_type,
1023 int flags, const char *dev_name, void *data)
1025 return mount_nodev(fs_type, flags, data, ncp_fill_super);
1028 static struct file_system_type ncp_fs_type = {
1029 .owner = THIS_MODULE,
1032 .kill_sb = kill_anon_super,
1033 .fs_flags = FS_BINARY_MOUNTDATA,
1036 static int __init init_ncp_fs(void)
1039 DPRINTK("ncpfs: init_ncp_fs called\n");
1041 err = init_inodecache();
1044 err = register_filesystem(&ncp_fs_type);
1049 destroy_inodecache();
1054 static void __exit exit_ncp_fs(void)
1056 DPRINTK("ncpfs: exit_ncp_fs called\n");
1057 unregister_filesystem(&ncp_fs_type);
1058 destroy_inodecache();
1061 module_init(init_ncp_fs)
1062 module_exit(exit_ncp_fs)
1063 MODULE_LICENSE("GPL");