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/smp_lock.h>
30 #include <linux/vfs.h>
31 #include <linux/mount.h>
32 #include <linux/seq_file.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_destroy_inode(struct inode *inode)
64 kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode));
67 static void init_once(void *foo)
69 struct ncp_inode_info *ei = (struct ncp_inode_info *) foo;
71 mutex_init(&ei->open_mutex);
72 inode_init_once(&ei->vfs_inode);
75 static int init_inodecache(void)
77 ncp_inode_cachep = kmem_cache_create("ncp_inode_cache",
78 sizeof(struct ncp_inode_info),
79 0, (SLAB_RECLAIM_ACCOUNT|
82 if (ncp_inode_cachep == NULL)
87 static void destroy_inodecache(void)
89 kmem_cache_destroy(ncp_inode_cachep);
92 static int ncp_remount(struct super_block *sb, int *flags, char* data)
94 *flags |= MS_NODIRATIME;
98 static const struct super_operations ncp_sops =
100 .alloc_inode = ncp_alloc_inode,
101 .destroy_inode = ncp_destroy_inode,
102 .drop_inode = generic_delete_inode,
103 .evict_inode = ncp_evict_inode,
104 .put_super = ncp_put_super,
105 .statfs = ncp_statfs,
106 .remount_fs = ncp_remount,
107 .show_options = ncp_show_options,
111 * Fill in the ncpfs-specific information in the inode.
113 static void ncp_update_dirent(struct inode *inode, struct ncp_entry_info *nwinfo)
115 NCP_FINFO(inode)->DosDirNum = nwinfo->i.DosDirNum;
116 NCP_FINFO(inode)->dirEntNum = nwinfo->i.dirEntNum;
117 NCP_FINFO(inode)->volNumber = nwinfo->volume;
120 void ncp_update_inode(struct inode *inode, struct ncp_entry_info *nwinfo)
122 ncp_update_dirent(inode, nwinfo);
123 NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
124 NCP_FINFO(inode)->access = nwinfo->access;
125 memcpy(NCP_FINFO(inode)->file_handle, nwinfo->file_handle,
126 sizeof(nwinfo->file_handle));
127 DPRINTK("ncp_update_inode: updated %s, volnum=%d, dirent=%u\n",
128 nwinfo->i.entryName, NCP_FINFO(inode)->volNumber,
129 NCP_FINFO(inode)->dirEntNum);
132 static void ncp_update_dates(struct inode *inode, struct nw_info_struct *nwi)
134 /* NFS namespace mode overrides others if it's set. */
135 DPRINTK(KERN_DEBUG "ncp_update_dates_and_mode: (%s) nfs.mode=0%o\n",
136 nwi->entryName, nwi->nfs.mode);
139 inode->i_mode = nwi->nfs.mode;
142 inode->i_blocks = (i_size_read(inode) + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
144 inode->i_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate);
145 inode->i_ctime.tv_sec = ncp_date_dos2unix(nwi->creationTime, nwi->creationDate);
146 inode->i_atime.tv_sec = ncp_date_dos2unix(0, nwi->lastAccessDate);
147 inode->i_atime.tv_nsec = 0;
148 inode->i_mtime.tv_nsec = 0;
149 inode->i_ctime.tv_nsec = 0;
152 static void ncp_update_attrs(struct inode *inode, struct ncp_entry_info *nwinfo)
154 struct nw_info_struct *nwi = &nwinfo->i;
155 struct ncp_server *server = NCP_SERVER(inode);
157 if (nwi->attributes & aDIR) {
158 inode->i_mode = server->m.dir_mode;
159 /* for directories dataStreamSize seems to be some
161 i_size_write(inode, NCP_BLOCK_SIZE);
165 inode->i_mode = server->m.file_mode;
166 size = le32_to_cpu(nwi->dataStreamSize);
167 i_size_write(inode, size);
168 #ifdef CONFIG_NCPFS_EXTRAS
169 if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS))
170 && (nwi->attributes & aSHARED)) {
171 switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
173 if (server->m.flags & NCP_MOUNT_SYMLINKS) {
174 if (/* (size >= NCP_MIN_SYMLINK_SIZE)
175 && */ (size <= NCP_MAX_SYMLINK_SIZE)) {
176 inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
177 NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK;
183 if (server->m.flags & NCP_MOUNT_EXTRAS)
184 inode->i_mode |= S_IRUGO;
187 if (server->m.flags & NCP_MOUNT_EXTRAS)
188 inode->i_mode |= (inode->i_mode >> 2) & S_IXUGO;
190 /* case aSYSTEM|aHIDDEN: */
192 /* reserved combination */
198 if (nwi->attributes & aRONLY) inode->i_mode &= ~S_IWUGO;
201 void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo)
203 NCP_FINFO(inode)->flags = 0;
204 if (!atomic_read(&NCP_FINFO(inode)->opened)) {
205 NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
206 ncp_update_attrs(inode, nwinfo);
209 ncp_update_dates(inode, &nwinfo->i);
210 ncp_update_dirent(inode, nwinfo);
214 * Fill in the inode based on the ncp_entry_info structure. Used only for brand new inodes.
216 static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
218 struct ncp_server *server = NCP_SERVER(inode);
220 NCP_FINFO(inode)->flags = 0;
222 ncp_update_attrs(inode, nwinfo);
224 DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode->i_mode);
227 inode->i_uid = server->m.uid;
228 inode->i_gid = server->m.gid;
230 ncp_update_dates(inode, &nwinfo->i);
231 ncp_update_inode(inode, nwinfo);
234 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
235 static const struct inode_operations ncp_symlink_inode_operations = {
236 .readlink = generic_readlink,
237 .follow_link = page_follow_link_light,
238 .put_link = page_put_link,
239 .setattr = ncp_notify_change,
247 ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
252 printk(KERN_ERR "ncp_iget: info is NULL\n");
256 inode = new_inode(sb);
258 atomic_set(&NCP_FINFO(inode)->opened, info->opened);
260 inode->i_mapping->backing_dev_info = sb->s_bdi;
261 inode->i_ino = info->ino;
262 ncp_set_attr(inode, info);
263 if (S_ISREG(inode->i_mode)) {
264 inode->i_op = &ncp_file_inode_operations;
265 inode->i_fop = &ncp_file_operations;
266 } else if (S_ISDIR(inode->i_mode)) {
267 inode->i_op = &ncp_dir_inode_operations;
268 inode->i_fop = &ncp_dir_operations;
269 #ifdef CONFIG_NCPFS_NFS_NS
270 } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
271 init_special_inode(inode, inode->i_mode,
272 new_decode_dev(info->i.nfs.rdev));
274 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
275 } else if (S_ISLNK(inode->i_mode)) {
276 inode->i_op = &ncp_symlink_inode_operations;
277 inode->i_data.a_ops = &ncp_symlink_aops;
280 make_bad_inode(inode);
282 insert_inode_hash(inode);
284 printk(KERN_ERR "ncp_iget: iget failed!\n");
289 ncp_evict_inode(struct inode *inode)
291 truncate_inode_pages(&inode->i_data, 0);
292 end_writeback(inode);
294 if (S_ISDIR(inode->i_mode)) {
295 DDPRINTK("ncp_evict_inode: put directory %ld\n", inode->i_ino);
298 if (ncp_make_closed(inode) != 0) {
299 /* We can't do anything but complain. */
300 printk(KERN_ERR "ncp_evict_inode: could not close\n");
304 static void ncp_stop_tasks(struct ncp_server *server) {
305 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;
310 del_timer_sync(&server->timeout_tm);
311 flush_scheduled_work();
314 static int ncp_show_options(struct seq_file *seq, struct vfsmount *mnt)
316 struct ncp_server *server = NCP_SBP(mnt->mnt_sb);
319 if (server->m.uid != 0)
320 seq_printf(seq, ",uid=%u", server->m.uid);
321 if (server->m.gid != 0)
322 seq_printf(seq, ",gid=%u", server->m.gid);
323 if (server->m.mounted_uid != 0)
324 seq_printf(seq, ",owner=%u", server->m.mounted_uid);
325 tmp = server->m.file_mode & S_IALLUGO;
326 if (tmp != NCP_DEFAULT_FILE_MODE)
327 seq_printf(seq, ",mode=0%o", tmp);
328 tmp = server->m.dir_mode & S_IALLUGO;
329 if (tmp != NCP_DEFAULT_DIR_MODE)
330 seq_printf(seq, ",dirmode=0%o", tmp);
331 if (server->m.time_out != NCP_DEFAULT_TIME_OUT * HZ / 100) {
332 tmp = server->m.time_out * 100 / HZ;
333 seq_printf(seq, ",timeout=%u", tmp);
335 if (server->m.retry_count != NCP_DEFAULT_RETRY_COUNT)
336 seq_printf(seq, ",retry=%u", server->m.retry_count);
337 if (server->m.flags != 0)
338 seq_printf(seq, ",flags=%lu", server->m.flags);
339 if (server->m.wdog_pid != NULL)
340 seq_printf(seq, ",wdogpid=%u", pid_vnr(server->m.wdog_pid));
345 static const struct ncp_option ncp_opts[] = {
346 { "uid", OPT_INT, 'u' },
347 { "gid", OPT_INT, 'g' },
348 { "owner", OPT_INT, 'o' },
349 { "mode", OPT_INT, 'm' },
350 { "dirmode", OPT_INT, 'd' },
351 { "timeout", OPT_INT, 't' },
352 { "retry", OPT_INT, 'r' },
353 { "flags", OPT_INT, 'f' },
354 { "wdogpid", OPT_INT, 'w' },
355 { "ncpfd", OPT_INT, 'n' },
356 { "infofd", OPT_INT, 'i' }, /* v5 */
357 { "version", OPT_INT, 'v' },
360 static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) {
363 unsigned long optint;
369 data->mounted_uid = 0;
370 data->wdog_pid = NULL;
372 data->time_out = NCP_DEFAULT_TIME_OUT;
373 data->retry_count = NCP_DEFAULT_RETRY_COUNT;
376 data->file_mode = NCP_DEFAULT_FILE_MODE;
377 data->dir_mode = NCP_DEFAULT_DIR_MODE;
379 data->mounted_vol[0] = 0;
381 while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 0) {
393 data->mounted_uid = optint;
396 data->file_mode = optint;
399 data->dir_mode = optint;
402 data->time_out = optint;
405 data->retry_count = optint;
408 data->flags = optint;
411 data->wdog_pid = find_get_pid(optint);
414 data->ncp_fd = optint;
417 data->info_fd = optint;
421 if (optint < NCP_MOUNT_VERSION_V4)
423 if (optint > NCP_MOUNT_VERSION_V5)
432 put_pid(data->wdog_pid);
433 data->wdog_pid = NULL;
437 static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
439 struct ncp_mount_data_kernel data;
440 struct ncp_server *server;
441 struct file *ncp_filp;
442 struct inode *root_inode;
443 struct inode *sock_inode;
447 #ifdef CONFIG_NCPFS_PACKET_SIGNING
450 struct ncp_entry_info finfo;
452 data.wdog_pid = NULL;
453 server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL);
456 sb->s_fs_info = server;
459 if (raw_data == NULL)
461 switch (*(int*)raw_data) {
462 case NCP_MOUNT_VERSION:
464 struct ncp_mount_data* md = (struct ncp_mount_data*)raw_data;
466 data.flags = md->flags;
467 data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE;
468 data.mounted_uid = md->mounted_uid;
469 data.wdog_pid = find_get_pid(md->wdog_pid);
470 data.ncp_fd = md->ncp_fd;
471 data.time_out = md->time_out;
472 data.retry_count = md->retry_count;
475 data.file_mode = md->file_mode;
476 data.dir_mode = md->dir_mode;
478 memcpy(data.mounted_vol, md->mounted_vol,
482 case NCP_MOUNT_VERSION_V4:
484 struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data;
486 data.flags = md->flags;
488 data.mounted_uid = md->mounted_uid;
489 data.wdog_pid = find_get_pid(md->wdog_pid);
490 data.ncp_fd = md->ncp_fd;
491 data.time_out = md->time_out;
492 data.retry_count = md->retry_count;
495 data.file_mode = md->file_mode;
496 data.dir_mode = md->dir_mode;
498 data.mounted_vol[0] = 0;
503 if (memcmp(raw_data, "vers", 4) == 0) {
504 error = ncp_parse_options(&data, raw_data);
511 ncp_filp = fget(data.ncp_fd);
515 sock_inode = ncp_filp->f_path.dentry->d_inode;
516 if (!S_ISSOCK(sock_inode->i_mode))
518 sock = SOCKET_I(sock_inode);
522 if (sock->type == SOCK_STREAM)
523 default_bufsize = 0xF000;
525 default_bufsize = 1024;
527 sb->s_flags |= MS_NODIRATIME; /* probably even noatime */
528 sb->s_maxbytes = 0xFFFFFFFFU;
529 sb->s_blocksize = 1024; /* Eh... Is this correct? */
530 sb->s_blocksize_bits = 10;
531 sb->s_magic = NCP_SUPER_MAGIC;
532 sb->s_op = &ncp_sops;
533 sb->s_bdi = &server->bdi;
535 server = NCP_SBP(sb);
536 memset(server, 0, sizeof(*server));
538 error = bdi_setup_and_register(&server->bdi, "ncpfs", BDI_CAP_MAP_COPY);
542 server->ncp_filp = ncp_filp;
543 server->ncp_sock = sock;
545 if (data.info_fd != -1) {
546 struct socket *info_sock;
549 server->info_filp = fget(data.info_fd);
550 if (!server->info_filp)
553 sock_inode = server->info_filp->f_path.dentry->d_inode;
554 if (!S_ISSOCK(sock_inode->i_mode))
556 info_sock = SOCKET_I(sock_inode);
560 if (info_sock->type != SOCK_STREAM)
562 server->info_sock = info_sock;
565 /* server->lock = 0; */
566 mutex_init(&server->mutex);
567 server->packet = NULL;
568 /* server->buffer_size = 0; */
569 /* server->conn_status = 0; */
570 /* server->root_dentry = NULL; */
571 /* server->root_setuped = 0; */
572 mutex_init(&server->root_setup_lock);
573 #ifdef CONFIG_NCPFS_PACKET_SIGNING
574 /* server->sign_wanted = 0; */
575 /* server->sign_active = 0; */
577 init_rwsem(&server->auth_rwsem);
578 server->auth.auth_type = NCP_AUTH_NONE;
579 /* server->auth.object_name_len = 0; */
580 /* server->auth.object_name = NULL; */
581 /* server->auth.object_type = 0; */
582 /* server->priv.len = 0; */
583 /* server->priv.data = NULL; */
586 /* Althought anything producing this is buggy, it happens
587 now because of PATH_MAX changes.. */
588 if (server->m.time_out < 1) {
589 server->m.time_out = 10;
590 printk(KERN_INFO "You need to recompile your ncpfs utils..\n");
592 server->m.time_out = server->m.time_out * HZ / 100;
593 server->m.file_mode = (server->m.file_mode & S_IRWXUGO) | S_IFREG;
594 server->m.dir_mode = (server->m.dir_mode & S_IRWXUGO) | S_IFDIR;
596 #ifdef CONFIG_NCPFS_NLS
597 /* load the default NLS charsets */
598 server->nls_vol = load_nls_default();
599 server->nls_io = load_nls_default();
600 #endif /* CONFIG_NCPFS_NLS */
602 atomic_set(&server->dentry_ttl, 0); /* no caching */
604 INIT_LIST_HEAD(&server->tx.requests);
605 mutex_init(&server->rcv.creq_mutex);
606 server->tx.creq = NULL;
607 server->rcv.creq = NULL;
608 server->data_ready = sock->sk->sk_data_ready;
609 server->write_space = sock->sk->sk_write_space;
610 server->error_report = sock->sk->sk_error_report;
611 sock->sk->sk_user_data = server;
613 init_timer(&server->timeout_tm);
614 #undef NCP_PACKET_SIZE
615 #define NCP_PACKET_SIZE 131072
617 server->packet_size = NCP_PACKET_SIZE;
618 server->packet = vmalloc(NCP_PACKET_SIZE);
619 if (server->packet == NULL)
621 server->txbuf = vmalloc(NCP_PACKET_SIZE);
622 if (server->txbuf == NULL)
624 server->rxbuf = vmalloc(NCP_PACKET_SIZE);
625 if (server->rxbuf == NULL)
628 sock->sk->sk_data_ready = ncp_tcp_data_ready;
629 sock->sk->sk_error_report = ncp_tcp_error_report;
630 if (sock->type == SOCK_STREAM) {
631 server->rcv.ptr = (unsigned char*)&server->rcv.buf;
632 server->rcv.len = 10;
633 server->rcv.state = 0;
634 INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc);
635 INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc);
636 sock->sk->sk_write_space = ncp_tcp_write_space;
638 INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc);
639 INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc);
640 server->timeout_tm.data = (unsigned long)server;
641 server->timeout_tm.function = ncpdgram_timeout_call;
644 ncp_lock_server(server);
645 error = ncp_connect(server);
646 ncp_unlock_server(server);
649 DPRINTK("ncp_fill_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb));
651 error = -EMSGSIZE; /* -EREMOTESIDEINCOMPATIBLE */
652 #ifdef CONFIG_NCPFS_PACKET_SIGNING
653 if (ncp_negotiate_size_and_options(server, default_bufsize,
654 NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0)
656 if (options != NCP_DEFAULT_OPTIONS)
658 if (ncp_negotiate_size_and_options(server,
661 &(server->buffer_size), &options) != 0)
667 ncp_lock_server(server);
669 server->sign_wanted = 1;
670 ncp_unlock_server(server);
673 #endif /* CONFIG_NCPFS_PACKET_SIGNING */
674 if (ncp_negotiate_buffersize(server, default_bufsize,
675 &(server->buffer_size)) != 0)
677 DPRINTK("ncpfs: bufsize = %d\n", server->buffer_size);
679 memset(&finfo, 0, sizeof(finfo));
680 finfo.i.attributes = aDIR;
681 finfo.i.dataStreamSize = 0; /* ignored */
682 finfo.i.dirEntNum = 0;
683 finfo.i.DosDirNum = 0;
684 #ifdef CONFIG_NCPFS_SMALLDOS
685 finfo.i.NSCreator = NW_NS_DOS;
687 finfo.volume = NCP_NUMBER_OF_VOLUMES;
688 /* set dates of mountpoint to Jan 1, 1986; 00:00 */
689 finfo.i.creationTime = finfo.i.modifyTime
690 = cpu_to_le16(0x0000);
691 finfo.i.creationDate = finfo.i.modifyDate
692 = finfo.i.lastAccessDate
693 = cpu_to_le16(0x0C21);
695 finfo.i.entryName[0] = '\0';
698 finfo.ino = 2; /* tradition */
700 server->name_space[finfo.volume] = NW_NS_DOS;
703 root_inode = ncp_iget(sb, &finfo);
706 DPRINTK("ncp_fill_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
707 sb->s_root = d_alloc_root(root_inode);
710 sb->s_root->d_op = &ncp_root_dentry_operations;
716 ncp_lock_server(server);
717 ncp_disconnect(server);
718 ncp_unlock_server(server);
720 ncp_stop_tasks(server);
721 vfree(server->rxbuf);
723 vfree(server->txbuf);
725 vfree(server->packet);
727 #ifdef CONFIG_NCPFS_NLS
728 unload_nls(server->nls_io);
729 unload_nls(server->nls_vol);
731 mutex_destroy(&server->rcv.creq_mutex);
732 mutex_destroy(&server->root_setup_lock);
733 mutex_destroy(&server->mutex);
735 if (server->info_filp)
736 fput(server->info_filp);
738 bdi_destroy(&server->bdi);
740 /* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:
742 * The previously used put_filp(ncp_filp); was bogus, since
743 * it doesn't perform proper unlocking.
747 put_pid(data.wdog_pid);
748 sb->s_fs_info = NULL;
753 static void ncp_put_super(struct super_block *sb)
755 struct ncp_server *server = NCP_SBP(sb);
757 ncp_lock_server(server);
758 ncp_disconnect(server);
759 ncp_unlock_server(server);
761 ncp_stop_tasks(server);
763 #ifdef CONFIG_NCPFS_NLS
764 /* unload the NLS charsets */
765 unload_nls(server->nls_vol);
766 unload_nls(server->nls_io);
767 #endif /* CONFIG_NCPFS_NLS */
768 mutex_destroy(&server->rcv.creq_mutex);
769 mutex_destroy(&server->root_setup_lock);
770 mutex_destroy(&server->mutex);
772 if (server->info_filp)
773 fput(server->info_filp);
774 fput(server->ncp_filp);
775 kill_pid(server->m.wdog_pid, SIGTERM, 1);
776 put_pid(server->m.wdog_pid);
778 bdi_destroy(&server->bdi);
779 kfree(server->priv.data);
780 kfree(server->auth.object_name);
781 vfree(server->rxbuf);
782 vfree(server->txbuf);
783 vfree(server->packet);
784 sb->s_fs_info = NULL;
788 static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
792 struct ncp_inode_info* ni;
793 struct ncp_server* s;
794 struct ncp_volume_info vi;
795 struct super_block *sb = dentry->d_sb;
815 if (!s->m.mounted_vol[0]) {
819 err = ncp_dirhandle_alloc(s, ni->volNumber, ni->DosDirNum, &dh);
823 err = ncp_get_directory_info(s, dh, &vi);
824 ncp_dirhandle_free(s, dh);
828 buf->f_type = NCP_SUPER_MAGIC;
829 buf->f_bsize = vi.sectors_per_block * 512;
830 buf->f_blocks = vi.total_blocks;
831 buf->f_bfree = vi.free_blocks;
832 buf->f_bavail = vi.free_blocks;
833 buf->f_files = vi.total_dir_entries;
834 buf->f_ffree = vi.available_dir_entries;
838 /* We cannot say how much disk space is left on a mounted
839 NetWare Server, because free space is distributed over
840 volumes, and the current user might have disk quotas. So
841 free space is not that simple to determine. Our decision
842 here is to err conservatively. */
845 buf->f_type = NCP_SUPER_MAGIC;
846 buf->f_bsize = NCP_BLOCK_SIZE;
854 int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
856 struct inode *inode = dentry->d_inode;
859 struct nw_modify_dos_info info;
860 struct ncp_server *server;
864 server = NCP_SERVER(inode);
865 if (!server) /* How this could happen? */
868 /* ageing the dentry to force validation */
869 ncp_age_dentry(server, dentry);
871 result = inode_change_ok(inode, attr);
876 if (((attr->ia_valid & ATTR_UID) &&
877 (attr->ia_uid != server->m.uid)))
880 if (((attr->ia_valid & ATTR_GID) &&
881 (attr->ia_gid != server->m.gid)))
884 if (((attr->ia_valid & ATTR_MODE) &&
886 ~(S_IFREG | S_IFDIR | S_IRWXUGO))))
890 memset(&info, 0, sizeof(info));
893 if ((attr->ia_valid & ATTR_MODE) != 0)
895 umode_t newmode = attr->ia_mode;
897 info_mask |= DM_ATTRIBUTES;
899 if (S_ISDIR(inode->i_mode)) {
900 newmode &= server->m.dir_mode;
902 #ifdef CONFIG_NCPFS_EXTRAS
903 if (server->m.flags & NCP_MOUNT_EXTRAS) {
904 /* any non-default execute bit set */
905 if (newmode & ~server->m.file_mode & S_IXUGO)
906 info.attributes |= aSHARED | aSYSTEM;
907 /* read for group/world and not in default file_mode */
908 else if (newmode & ~server->m.file_mode & S_IRUGO)
909 info.attributes |= aSHARED;
912 newmode &= server->m.file_mode;
914 if (newmode & S_IWUGO)
915 info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
917 info.attributes |= (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
919 #ifdef CONFIG_NCPFS_NFS_NS
920 if (ncp_is_nfs_extras(server, NCP_FINFO(inode)->volNumber)) {
921 result = ncp_modify_nfs_info(server,
922 NCP_FINFO(inode)->volNumber,
923 NCP_FINFO(inode)->dirEntNum,
927 info.attributes &= ~(aSHARED | aSYSTEM);
929 /* mark partial success */
930 struct iattr tmpattr;
932 tmpattr.ia_valid = ATTR_MODE;
933 tmpattr.ia_mode = attr->ia_mode;
935 setattr_copy(inode, &tmpattr);
936 mark_inode_dirty(inode);
943 /* Do SIZE before attributes, otherwise mtime together with size does not work...
945 if ((attr->ia_valid & ATTR_SIZE) != 0) {
948 DPRINTK("ncpfs: trying to change size to %ld\n",
951 if ((result = ncp_make_open(inode, O_WRONLY)) < 0) {
955 ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
956 attr->ia_size, 0, "", &written);
958 /* According to ndir, the changes only take effect after
960 ncp_inode_close(inode);
961 result = ncp_make_closed(inode);
965 if (attr->ia_size != i_size_read(inode)) {
966 result = vmtruncate(inode, attr->ia_size);
969 mark_inode_dirty(inode);
972 if ((attr->ia_valid & ATTR_CTIME) != 0) {
973 info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE);
974 ncp_date_unix2dos(attr->ia_ctime.tv_sec,
975 &info.creationTime, &info.creationDate);
977 if ((attr->ia_valid & ATTR_MTIME) != 0) {
978 info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE);
979 ncp_date_unix2dos(attr->ia_mtime.tv_sec,
980 &info.modifyTime, &info.modifyDate);
982 if ((attr->ia_valid & ATTR_ATIME) != 0) {
984 info_mask |= (DM_LAST_ACCESS_DATE);
985 ncp_date_unix2dos(attr->ia_atime.tv_sec,
986 &dummy, &info.lastAccessDate);
988 if (info_mask != 0) {
989 result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
990 inode, info_mask, &info);
992 if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
993 /* NetWare seems not to allow this. I
994 do not know why. So, just tell the
995 user everything went fine. This is
996 a terrible hack, but I do not know
997 how to do this correctly. */
1002 #ifdef CONFIG_NCPFS_STRONG
1003 if ((!result) && (info_mask & DM_ATTRIBUTES))
1004 NCP_FINFO(inode)->nwattr = info.attributes;
1010 setattr_copy(inode, attr);
1011 mark_inode_dirty(inode);
1019 static int ncp_get_sb(struct file_system_type *fs_type,
1020 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
1022 return get_sb_nodev(fs_type, flags, data, ncp_fill_super, mnt);
1025 static struct file_system_type ncp_fs_type = {
1026 .owner = THIS_MODULE,
1028 .get_sb = ncp_get_sb,
1029 .kill_sb = kill_anon_super,
1030 .fs_flags = FS_BINARY_MOUNTDATA,
1033 static int __init init_ncp_fs(void)
1036 DPRINTK("ncpfs: init_ncp_fs called\n");
1038 err = init_inodecache();
1041 err = register_filesystem(&ncp_fs_type);
1046 destroy_inodecache();
1051 static void __exit exit_ncp_fs(void)
1053 DPRINTK("ncpfs: exit_ncp_fs called\n");
1054 unregister_filesystem(&ncp_fs_type);
1055 destroy_inodecache();
1058 module_init(init_ncp_fs)
1059 module_exit(exit_ncp_fs)
1060 MODULE_LICENSE("GPL");