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/uaccess.h>
15 #include <asm/byteorder.h>
17 #include <linux/time.h>
18 #include <linux/kernel.h>
20 #include <linux/string.h>
21 #include <linux/stat.h>
22 #include <linux/errno.h>
23 #include <linux/file.h>
24 #include <linux/fcntl.h>
25 #include <linux/slab.h>
26 #include <linux/vmalloc.h>
27 #include <linux/init.h>
28 #include <linux/vfs.h>
29 #include <linux/mount.h>
30 #include <linux/seq_file.h>
31 #include <linux/namei.h>
38 #define NCP_DEFAULT_FILE_MODE 0600
39 #define NCP_DEFAULT_DIR_MODE 0700
40 #define NCP_DEFAULT_TIME_OUT 10
41 #define NCP_DEFAULT_RETRY_COUNT 20
43 static void ncp_evict_inode(struct inode *);
44 static void ncp_put_super(struct super_block *);
45 static int ncp_statfs(struct dentry *, struct kstatfs *);
46 static int ncp_show_options(struct seq_file *, struct dentry *);
48 static struct kmem_cache * ncp_inode_cachep;
50 static struct inode *ncp_alloc_inode(struct super_block *sb)
52 struct ncp_inode_info *ei;
53 ei = (struct ncp_inode_info *)kmem_cache_alloc(ncp_inode_cachep, GFP_KERNEL);
56 return &ei->vfs_inode;
59 static void ncp_i_callback(struct rcu_head *head)
61 struct inode *inode = container_of(head, struct inode, i_rcu);
62 kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode));
65 static void ncp_destroy_inode(struct inode *inode)
67 call_rcu(&inode->i_rcu, ncp_i_callback);
70 static void init_once(void *foo)
72 struct ncp_inode_info *ei = (struct ncp_inode_info *) foo;
74 mutex_init(&ei->open_mutex);
75 inode_init_once(&ei->vfs_inode);
78 static int init_inodecache(void)
80 ncp_inode_cachep = kmem_cache_create("ncp_inode_cache",
81 sizeof(struct ncp_inode_info),
82 0, (SLAB_RECLAIM_ACCOUNT|
85 if (ncp_inode_cachep == NULL)
90 static void destroy_inodecache(void)
93 * Make sure all delayed rcu free inodes are flushed before we
97 kmem_cache_destroy(ncp_inode_cachep);
100 static int ncp_remount(struct super_block *sb, int *flags, char* data)
103 *flags |= MS_NODIRATIME;
107 static const struct super_operations ncp_sops =
109 .alloc_inode = ncp_alloc_inode,
110 .destroy_inode = ncp_destroy_inode,
111 .drop_inode = generic_delete_inode,
112 .evict_inode = ncp_evict_inode,
113 .put_super = ncp_put_super,
114 .statfs = ncp_statfs,
115 .remount_fs = ncp_remount,
116 .show_options = ncp_show_options,
120 * Fill in the ncpfs-specific information in the inode.
122 static void ncp_update_dirent(struct inode *inode, struct ncp_entry_info *nwinfo)
124 NCP_FINFO(inode)->DosDirNum = nwinfo->i.DosDirNum;
125 NCP_FINFO(inode)->dirEntNum = nwinfo->i.dirEntNum;
126 NCP_FINFO(inode)->volNumber = nwinfo->volume;
129 void ncp_update_inode(struct inode *inode, struct ncp_entry_info *nwinfo)
131 ncp_update_dirent(inode, nwinfo);
132 NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
133 NCP_FINFO(inode)->access = nwinfo->access;
134 memcpy(NCP_FINFO(inode)->file_handle, nwinfo->file_handle,
135 sizeof(nwinfo->file_handle));
136 DPRINTK("ncp_update_inode: updated %s, volnum=%d, dirent=%u\n",
137 nwinfo->i.entryName, NCP_FINFO(inode)->volNumber,
138 NCP_FINFO(inode)->dirEntNum);
141 static void ncp_update_dates(struct inode *inode, struct nw_info_struct *nwi)
143 /* NFS namespace mode overrides others if it's set. */
144 DPRINTK(KERN_DEBUG "ncp_update_dates_and_mode: (%s) nfs.mode=0%o\n",
145 nwi->entryName, nwi->nfs.mode);
148 inode->i_mode = nwi->nfs.mode;
151 inode->i_blocks = (i_size_read(inode) + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
153 inode->i_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate);
154 inode->i_ctime.tv_sec = ncp_date_dos2unix(nwi->creationTime, nwi->creationDate);
155 inode->i_atime.tv_sec = ncp_date_dos2unix(0, nwi->lastAccessDate);
156 inode->i_atime.tv_nsec = 0;
157 inode->i_mtime.tv_nsec = 0;
158 inode->i_ctime.tv_nsec = 0;
161 static void ncp_update_attrs(struct inode *inode, struct ncp_entry_info *nwinfo)
163 struct nw_info_struct *nwi = &nwinfo->i;
164 struct ncp_server *server = NCP_SERVER(inode);
166 if (nwi->attributes & aDIR) {
167 inode->i_mode = server->m.dir_mode;
168 /* for directories dataStreamSize seems to be some
170 i_size_write(inode, NCP_BLOCK_SIZE);
174 inode->i_mode = server->m.file_mode;
175 size = le32_to_cpu(nwi->dataStreamSize);
176 i_size_write(inode, size);
177 #ifdef CONFIG_NCPFS_EXTRAS
178 if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS))
179 && (nwi->attributes & aSHARED)) {
180 switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
182 if (server->m.flags & NCP_MOUNT_SYMLINKS) {
183 if (/* (size >= NCP_MIN_SYMLINK_SIZE)
184 && */ (size <= NCP_MAX_SYMLINK_SIZE)) {
185 inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
186 NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK;
192 if (server->m.flags & NCP_MOUNT_EXTRAS)
193 inode->i_mode |= S_IRUGO;
196 if (server->m.flags & NCP_MOUNT_EXTRAS)
197 inode->i_mode |= (inode->i_mode >> 2) & S_IXUGO;
199 /* case aSYSTEM|aHIDDEN: */
201 /* reserved combination */
207 if (nwi->attributes & aRONLY) inode->i_mode &= ~S_IWUGO;
210 void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo)
212 NCP_FINFO(inode)->flags = 0;
213 if (!atomic_read(&NCP_FINFO(inode)->opened)) {
214 NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
215 ncp_update_attrs(inode, nwinfo);
218 ncp_update_dates(inode, &nwinfo->i);
219 ncp_update_dirent(inode, nwinfo);
223 * Fill in the inode based on the ncp_entry_info structure. Used only for brand new inodes.
225 static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
227 struct ncp_server *server = NCP_SERVER(inode);
229 NCP_FINFO(inode)->flags = 0;
231 ncp_update_attrs(inode, nwinfo);
233 DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode->i_mode);
236 inode->i_uid = server->m.uid;
237 inode->i_gid = server->m.gid;
239 ncp_update_dates(inode, &nwinfo->i);
240 ncp_update_inode(inode, nwinfo);
243 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
244 static const struct inode_operations ncp_symlink_inode_operations = {
245 .readlink = generic_readlink,
246 .follow_link = page_follow_link_light,
247 .put_link = page_put_link,
248 .setattr = ncp_notify_change,
256 ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
261 printk(KERN_ERR "ncp_iget: info is NULL\n");
265 inode = new_inode(sb);
267 atomic_set(&NCP_FINFO(inode)->opened, info->opened);
269 inode->i_mapping->backing_dev_info = sb->s_bdi;
270 inode->i_ino = info->ino;
271 ncp_set_attr(inode, info);
272 if (S_ISREG(inode->i_mode)) {
273 inode->i_op = &ncp_file_inode_operations;
274 inode->i_fop = &ncp_file_operations;
275 } else if (S_ISDIR(inode->i_mode)) {
276 inode->i_op = &ncp_dir_inode_operations;
277 inode->i_fop = &ncp_dir_operations;
278 #ifdef CONFIG_NCPFS_NFS_NS
279 } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
280 init_special_inode(inode, inode->i_mode,
281 new_decode_dev(info->i.nfs.rdev));
283 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
284 } else if (S_ISLNK(inode->i_mode)) {
285 inode->i_op = &ncp_symlink_inode_operations;
286 inode->i_data.a_ops = &ncp_symlink_aops;
289 make_bad_inode(inode);
291 insert_inode_hash(inode);
293 printk(KERN_ERR "ncp_iget: iget failed!\n");
298 ncp_evict_inode(struct inode *inode)
300 truncate_inode_pages(&inode->i_data, 0);
303 if (S_ISDIR(inode->i_mode)) {
304 DDPRINTK("ncp_evict_inode: put directory %ld\n", inode->i_ino);
307 if (ncp_make_closed(inode) != 0) {
308 /* We can't do anything but complain. */
309 printk(KERN_ERR "ncp_evict_inode: could not close\n");
313 static void ncp_stop_tasks(struct ncp_server *server) {
314 struct sock* sk = server->ncp_sock->sk;
317 sk->sk_error_report = server->error_report;
318 sk->sk_data_ready = server->data_ready;
319 sk->sk_write_space = server->write_space;
321 del_timer_sync(&server->timeout_tm);
323 flush_work(&server->rcv.tq);
324 if (sk->sk_socket->type == SOCK_STREAM)
325 flush_work(&server->tx.tq);
327 flush_work(&server->timeout_tq);
330 static int ncp_show_options(struct seq_file *seq, struct dentry *root)
332 struct ncp_server *server = NCP_SBP(root->d_sb);
335 if (!uid_eq(server->m.uid, GLOBAL_ROOT_UID))
336 seq_printf(seq, ",uid=%u",
337 from_kuid_munged(&init_user_ns, server->m.uid));
338 if (!gid_eq(server->m.gid, GLOBAL_ROOT_GID))
339 seq_printf(seq, ",gid=%u",
340 from_kgid_munged(&init_user_ns, server->m.gid));
341 if (!uid_eq(server->m.mounted_uid, GLOBAL_ROOT_UID))
342 seq_printf(seq, ",owner=%u",
343 from_kuid_munged(&init_user_ns, server->m.mounted_uid));
344 tmp = server->m.file_mode & S_IALLUGO;
345 if (tmp != NCP_DEFAULT_FILE_MODE)
346 seq_printf(seq, ",mode=0%o", tmp);
347 tmp = server->m.dir_mode & S_IALLUGO;
348 if (tmp != NCP_DEFAULT_DIR_MODE)
349 seq_printf(seq, ",dirmode=0%o", tmp);
350 if (server->m.time_out != NCP_DEFAULT_TIME_OUT * HZ / 100) {
351 tmp = server->m.time_out * 100 / HZ;
352 seq_printf(seq, ",timeout=%u", tmp);
354 if (server->m.retry_count != NCP_DEFAULT_RETRY_COUNT)
355 seq_printf(seq, ",retry=%u", server->m.retry_count);
356 if (server->m.flags != 0)
357 seq_printf(seq, ",flags=%lu", server->m.flags);
358 if (server->m.wdog_pid != NULL)
359 seq_printf(seq, ",wdogpid=%u", pid_vnr(server->m.wdog_pid));
364 static const struct ncp_option ncp_opts[] = {
365 { "uid", OPT_INT, 'u' },
366 { "gid", OPT_INT, 'g' },
367 { "owner", OPT_INT, 'o' },
368 { "mode", OPT_INT, 'm' },
369 { "dirmode", OPT_INT, 'd' },
370 { "timeout", OPT_INT, 't' },
371 { "retry", OPT_INT, 'r' },
372 { "flags", OPT_INT, 'f' },
373 { "wdogpid", OPT_INT, 'w' },
374 { "ncpfd", OPT_INT, 'n' },
375 { "infofd", OPT_INT, 'i' }, /* v5 */
376 { "version", OPT_INT, 'v' },
379 static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) {
382 unsigned long optint;
388 data->mounted_uid = GLOBAL_ROOT_UID;
389 data->wdog_pid = NULL;
391 data->time_out = NCP_DEFAULT_TIME_OUT;
392 data->retry_count = NCP_DEFAULT_RETRY_COUNT;
393 data->uid = GLOBAL_ROOT_UID;
394 data->gid = GLOBAL_ROOT_GID;
395 data->file_mode = NCP_DEFAULT_FILE_MODE;
396 data->dir_mode = NCP_DEFAULT_DIR_MODE;
398 data->mounted_vol[0] = 0;
400 while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 0) {
406 data->uid = make_kuid(current_user_ns(), optint);
407 if (!uid_valid(data->uid))
411 data->gid = make_kgid(current_user_ns(), optint);
412 if (!gid_valid(data->gid))
416 data->mounted_uid = make_kuid(current_user_ns(), optint);
417 if (!uid_valid(data->mounted_uid))
421 data->file_mode = optint;
424 data->dir_mode = optint;
427 data->time_out = optint;
430 data->retry_count = optint;
433 data->flags = optint;
436 data->wdog_pid = find_get_pid(optint);
439 data->ncp_fd = optint;
442 data->info_fd = optint;
446 if (optint < NCP_MOUNT_VERSION_V4)
448 if (optint > NCP_MOUNT_VERSION_V5)
457 put_pid(data->wdog_pid);
458 data->wdog_pid = NULL;
462 static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
464 struct ncp_mount_data_kernel data;
465 struct ncp_server *server;
466 struct file *ncp_filp;
467 struct inode *root_inode;
468 struct inode *sock_inode;
472 #ifdef CONFIG_NCPFS_PACKET_SIGNING
475 struct ncp_entry_info finfo;
477 memset(&data, 0, sizeof(data));
478 server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL);
481 sb->s_fs_info = server;
484 if (raw_data == NULL)
486 switch (*(int*)raw_data) {
487 case NCP_MOUNT_VERSION:
489 struct ncp_mount_data* md = (struct ncp_mount_data*)raw_data;
491 data.flags = md->flags;
492 data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE;
493 data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid);
494 data.wdog_pid = find_get_pid(md->wdog_pid);
495 data.ncp_fd = md->ncp_fd;
496 data.time_out = md->time_out;
497 data.retry_count = md->retry_count;
498 data.uid = make_kuid(current_user_ns(), md->uid);
499 data.gid = make_kgid(current_user_ns(), md->gid);
500 data.file_mode = md->file_mode;
501 data.dir_mode = md->dir_mode;
503 memcpy(data.mounted_vol, md->mounted_vol,
507 case NCP_MOUNT_VERSION_V4:
509 struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data;
511 data.flags = md->flags;
512 data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid);
513 data.wdog_pid = find_get_pid(md->wdog_pid);
514 data.ncp_fd = md->ncp_fd;
515 data.time_out = md->time_out;
516 data.retry_count = md->retry_count;
517 data.uid = make_kuid(current_user_ns(), md->uid);
518 data.gid = make_kgid(current_user_ns(), md->gid);
519 data.file_mode = md->file_mode;
520 data.dir_mode = md->dir_mode;
526 if (memcmp(raw_data, "vers", 4) == 0) {
527 error = ncp_parse_options(&data, raw_data);
534 if (!uid_valid(data.mounted_uid) || !uid_valid(data.uid) ||
535 !gid_valid(data.gid))
538 ncp_filp = fget(data.ncp_fd);
542 sock_inode = file_inode(ncp_filp);
543 if (!S_ISSOCK(sock_inode->i_mode))
545 sock = SOCKET_I(sock_inode);
549 if (sock->type == SOCK_STREAM)
550 default_bufsize = 0xF000;
552 default_bufsize = 1024;
554 sb->s_flags |= MS_NODIRATIME; /* probably even noatime */
555 sb->s_maxbytes = 0xFFFFFFFFU;
556 sb->s_blocksize = 1024; /* Eh... Is this correct? */
557 sb->s_blocksize_bits = 10;
558 sb->s_magic = NCP_SUPER_MAGIC;
559 sb->s_op = &ncp_sops;
560 sb->s_d_op = &ncp_dentry_operations;
561 sb->s_bdi = &server->bdi;
563 server = NCP_SBP(sb);
564 memset(server, 0, sizeof(*server));
566 error = bdi_setup_and_register(&server->bdi, "ncpfs", BDI_CAP_MAP_COPY);
570 server->ncp_filp = ncp_filp;
571 server->ncp_sock = sock;
573 if (data.info_fd != -1) {
574 struct socket *info_sock;
577 server->info_filp = fget(data.info_fd);
578 if (!server->info_filp)
581 sock_inode = file_inode(server->info_filp);
582 if (!S_ISSOCK(sock_inode->i_mode))
584 info_sock = SOCKET_I(sock_inode);
588 if (info_sock->type != SOCK_STREAM)
590 server->info_sock = info_sock;
593 /* server->lock = 0; */
594 mutex_init(&server->mutex);
595 server->packet = NULL;
596 /* server->buffer_size = 0; */
597 /* server->conn_status = 0; */
598 /* server->root_dentry = NULL; */
599 /* server->root_setuped = 0; */
600 mutex_init(&server->root_setup_lock);
601 #ifdef CONFIG_NCPFS_PACKET_SIGNING
602 /* server->sign_wanted = 0; */
603 /* server->sign_active = 0; */
605 init_rwsem(&server->auth_rwsem);
606 server->auth.auth_type = NCP_AUTH_NONE;
607 /* server->auth.object_name_len = 0; */
608 /* server->auth.object_name = NULL; */
609 /* server->auth.object_type = 0; */
610 /* server->priv.len = 0; */
611 /* server->priv.data = NULL; */
614 /* Although anything producing this is buggy, it happens
615 now because of PATH_MAX changes.. */
616 if (server->m.time_out < 1) {
617 server->m.time_out = 10;
618 printk(KERN_INFO "You need to recompile your ncpfs utils..\n");
620 server->m.time_out = server->m.time_out * HZ / 100;
621 server->m.file_mode = (server->m.file_mode & S_IRWXUGO) | S_IFREG;
622 server->m.dir_mode = (server->m.dir_mode & S_IRWXUGO) | S_IFDIR;
624 #ifdef CONFIG_NCPFS_NLS
625 /* load the default NLS charsets */
626 server->nls_vol = load_nls_default();
627 server->nls_io = load_nls_default();
628 #endif /* CONFIG_NCPFS_NLS */
630 atomic_set(&server->dentry_ttl, 0); /* no caching */
632 INIT_LIST_HEAD(&server->tx.requests);
633 mutex_init(&server->rcv.creq_mutex);
634 server->tx.creq = NULL;
635 server->rcv.creq = NULL;
637 init_timer(&server->timeout_tm);
638 #undef NCP_PACKET_SIZE
639 #define NCP_PACKET_SIZE 131072
641 server->packet_size = NCP_PACKET_SIZE;
642 server->packet = vmalloc(NCP_PACKET_SIZE);
643 if (server->packet == NULL)
645 server->txbuf = vmalloc(NCP_PACKET_SIZE);
646 if (server->txbuf == NULL)
648 server->rxbuf = vmalloc(NCP_PACKET_SIZE);
649 if (server->rxbuf == NULL)
653 server->data_ready = sock->sk->sk_data_ready;
654 server->write_space = sock->sk->sk_write_space;
655 server->error_report = sock->sk->sk_error_report;
656 sock->sk->sk_user_data = server;
657 sock->sk->sk_data_ready = ncp_tcp_data_ready;
658 sock->sk->sk_error_report = ncp_tcp_error_report;
659 if (sock->type == SOCK_STREAM) {
660 server->rcv.ptr = (unsigned char*)&server->rcv.buf;
661 server->rcv.len = 10;
662 server->rcv.state = 0;
663 INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc);
664 INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc);
665 sock->sk->sk_write_space = ncp_tcp_write_space;
667 INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc);
668 INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc);
669 server->timeout_tm.data = (unsigned long)server;
670 server->timeout_tm.function = ncpdgram_timeout_call;
672 release_sock(sock->sk);
674 ncp_lock_server(server);
675 error = ncp_connect(server);
676 ncp_unlock_server(server);
679 DPRINTK("ncp_fill_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb));
681 error = -EMSGSIZE; /* -EREMOTESIDEINCOMPATIBLE */
682 #ifdef CONFIG_NCPFS_PACKET_SIGNING
683 if (ncp_negotiate_size_and_options(server, default_bufsize,
684 NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0)
686 if (options != NCP_DEFAULT_OPTIONS)
688 if (ncp_negotiate_size_and_options(server,
691 &(server->buffer_size), &options) != 0)
697 ncp_lock_server(server);
699 server->sign_wanted = 1;
700 ncp_unlock_server(server);
703 #endif /* CONFIG_NCPFS_PACKET_SIGNING */
704 if (ncp_negotiate_buffersize(server, default_bufsize,
705 &(server->buffer_size)) != 0)
707 DPRINTK("ncpfs: bufsize = %d\n", server->buffer_size);
709 memset(&finfo, 0, sizeof(finfo));
710 finfo.i.attributes = aDIR;
711 finfo.i.dataStreamSize = 0; /* ignored */
712 finfo.i.dirEntNum = 0;
713 finfo.i.DosDirNum = 0;
714 #ifdef CONFIG_NCPFS_SMALLDOS
715 finfo.i.NSCreator = NW_NS_DOS;
717 finfo.volume = NCP_NUMBER_OF_VOLUMES;
718 /* set dates of mountpoint to Jan 1, 1986; 00:00 */
719 finfo.i.creationTime = finfo.i.modifyTime
720 = cpu_to_le16(0x0000);
721 finfo.i.creationDate = finfo.i.modifyDate
722 = finfo.i.lastAccessDate
723 = cpu_to_le16(0x0C21);
725 finfo.i.entryName[0] = '\0';
728 finfo.ino = 2; /* tradition */
730 server->name_space[finfo.volume] = NW_NS_DOS;
733 root_inode = ncp_iget(sb, &finfo);
736 DPRINTK("ncp_fill_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
737 sb->s_root = d_make_root(root_inode);
743 ncp_lock_server(server);
744 ncp_disconnect(server);
745 ncp_unlock_server(server);
747 ncp_stop_tasks(server);
748 vfree(server->rxbuf);
750 vfree(server->txbuf);
752 vfree(server->packet);
754 #ifdef CONFIG_NCPFS_NLS
755 unload_nls(server->nls_io);
756 unload_nls(server->nls_vol);
758 mutex_destroy(&server->rcv.creq_mutex);
759 mutex_destroy(&server->root_setup_lock);
760 mutex_destroy(&server->mutex);
762 if (server->info_filp)
763 fput(server->info_filp);
765 bdi_destroy(&server->bdi);
767 /* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:
769 * The previously used put_filp(ncp_filp); was bogus, since
770 * it doesn't perform proper unlocking.
774 put_pid(data.wdog_pid);
775 sb->s_fs_info = NULL;
780 static void ncp_put_super(struct super_block *sb)
782 struct ncp_server *server = NCP_SBP(sb);
784 ncp_lock_server(server);
785 ncp_disconnect(server);
786 ncp_unlock_server(server);
788 ncp_stop_tasks(server);
790 #ifdef CONFIG_NCPFS_NLS
791 /* unload the NLS charsets */
792 unload_nls(server->nls_vol);
793 unload_nls(server->nls_io);
794 #endif /* CONFIG_NCPFS_NLS */
795 mutex_destroy(&server->rcv.creq_mutex);
796 mutex_destroy(&server->root_setup_lock);
797 mutex_destroy(&server->mutex);
799 if (server->info_filp)
800 fput(server->info_filp);
801 fput(server->ncp_filp);
802 kill_pid(server->m.wdog_pid, SIGTERM, 1);
803 put_pid(server->m.wdog_pid);
805 bdi_destroy(&server->bdi);
806 kfree(server->priv.data);
807 kfree(server->auth.object_name);
808 vfree(server->rxbuf);
809 vfree(server->txbuf);
810 vfree(server->packet);
811 sb->s_fs_info = NULL;
815 static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
819 struct ncp_inode_info* ni;
820 struct ncp_server* s;
821 struct ncp_volume_info vi;
822 struct super_block *sb = dentry->d_sb;
842 if (!s->m.mounted_vol[0]) {
846 err = ncp_dirhandle_alloc(s, ni->volNumber, ni->DosDirNum, &dh);
850 err = ncp_get_directory_info(s, dh, &vi);
851 ncp_dirhandle_free(s, dh);
855 buf->f_type = NCP_SUPER_MAGIC;
856 buf->f_bsize = vi.sectors_per_block * 512;
857 buf->f_blocks = vi.total_blocks;
858 buf->f_bfree = vi.free_blocks;
859 buf->f_bavail = vi.free_blocks;
860 buf->f_files = vi.total_dir_entries;
861 buf->f_ffree = vi.available_dir_entries;
865 /* We cannot say how much disk space is left on a mounted
866 NetWare Server, because free space is distributed over
867 volumes, and the current user might have disk quotas. So
868 free space is not that simple to determine. Our decision
869 here is to err conservatively. */
872 buf->f_type = NCP_SUPER_MAGIC;
873 buf->f_bsize = NCP_BLOCK_SIZE;
881 int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
883 struct inode *inode = dentry->d_inode;
886 struct nw_modify_dos_info info;
887 struct ncp_server *server;
891 server = NCP_SERVER(inode);
892 if (!server) /* How this could happen? */
895 /* ageing the dentry to force validation */
896 ncp_age_dentry(server, dentry);
898 result = inode_change_ok(inode, attr);
903 if ((attr->ia_valid & ATTR_UID) && !uid_eq(attr->ia_uid, server->m.uid))
906 if ((attr->ia_valid & ATTR_GID) && !gid_eq(attr->ia_gid, server->m.gid))
909 if (((attr->ia_valid & ATTR_MODE) &&
911 ~(S_IFREG | S_IFDIR | S_IRWXUGO))))
915 memset(&info, 0, sizeof(info));
918 if ((attr->ia_valid & ATTR_MODE) != 0)
920 umode_t newmode = attr->ia_mode;
922 info_mask |= DM_ATTRIBUTES;
924 if (S_ISDIR(inode->i_mode)) {
925 newmode &= server->m.dir_mode;
927 #ifdef CONFIG_NCPFS_EXTRAS
928 if (server->m.flags & NCP_MOUNT_EXTRAS) {
929 /* any non-default execute bit set */
930 if (newmode & ~server->m.file_mode & S_IXUGO)
931 info.attributes |= aSHARED | aSYSTEM;
932 /* read for group/world and not in default file_mode */
933 else if (newmode & ~server->m.file_mode & S_IRUGO)
934 info.attributes |= aSHARED;
937 newmode &= server->m.file_mode;
939 if (newmode & S_IWUGO)
940 info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
942 info.attributes |= (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
944 #ifdef CONFIG_NCPFS_NFS_NS
945 if (ncp_is_nfs_extras(server, NCP_FINFO(inode)->volNumber)) {
946 result = ncp_modify_nfs_info(server,
947 NCP_FINFO(inode)->volNumber,
948 NCP_FINFO(inode)->dirEntNum,
952 info.attributes &= ~(aSHARED | aSYSTEM);
954 /* mark partial success */
955 struct iattr tmpattr;
957 tmpattr.ia_valid = ATTR_MODE;
958 tmpattr.ia_mode = attr->ia_mode;
960 setattr_copy(inode, &tmpattr);
961 mark_inode_dirty(inode);
968 /* Do SIZE before attributes, otherwise mtime together with size does not work...
970 if ((attr->ia_valid & ATTR_SIZE) != 0) {
973 DPRINTK("ncpfs: trying to change size to %ld\n",
976 if ((result = ncp_make_open(inode, O_WRONLY)) < 0) {
980 ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
981 attr->ia_size, 0, "", &written);
983 /* According to ndir, the changes only take effect after
985 ncp_inode_close(inode);
986 result = ncp_make_closed(inode);
990 if (attr->ia_size != i_size_read(inode)) {
991 truncate_setsize(inode, attr->ia_size);
992 mark_inode_dirty(inode);
995 if ((attr->ia_valid & ATTR_CTIME) != 0) {
996 info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE);
997 ncp_date_unix2dos(attr->ia_ctime.tv_sec,
998 &info.creationTime, &info.creationDate);
1000 if ((attr->ia_valid & ATTR_MTIME) != 0) {
1001 info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE);
1002 ncp_date_unix2dos(attr->ia_mtime.tv_sec,
1003 &info.modifyTime, &info.modifyDate);
1005 if ((attr->ia_valid & ATTR_ATIME) != 0) {
1007 info_mask |= (DM_LAST_ACCESS_DATE);
1008 ncp_date_unix2dos(attr->ia_atime.tv_sec,
1009 &dummy, &info.lastAccessDate);
1011 if (info_mask != 0) {
1012 result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
1013 inode, info_mask, &info);
1015 if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
1016 /* NetWare seems not to allow this. I
1017 do not know why. So, just tell the
1018 user everything went fine. This is
1019 a terrible hack, but I do not know
1020 how to do this correctly. */
1025 #ifdef CONFIG_NCPFS_STRONG
1026 if ((!result) && (info_mask & DM_ATTRIBUTES))
1027 NCP_FINFO(inode)->nwattr = info.attributes;
1033 setattr_copy(inode, attr);
1034 mark_inode_dirty(inode);
1042 static struct dentry *ncp_mount(struct file_system_type *fs_type,
1043 int flags, const char *dev_name, void *data)
1045 return mount_nodev(fs_type, flags, data, ncp_fill_super);
1048 static struct file_system_type ncp_fs_type = {
1049 .owner = THIS_MODULE,
1052 .kill_sb = kill_anon_super,
1053 .fs_flags = FS_BINARY_MOUNTDATA,
1055 MODULE_ALIAS_FS("ncpfs");
1057 static int __init init_ncp_fs(void)
1060 DPRINTK("ncpfs: init_ncp_fs called\n");
1062 err = init_inodecache();
1065 err = register_filesystem(&ncp_fs_type);
1070 destroy_inodecache();
1075 static void __exit exit_ncp_fs(void)
1077 DPRINTK("ncpfs: exit_ncp_fs called\n");
1078 unregister_filesystem(&ncp_fs_type);
1079 destroy_inodecache();
1082 module_init(init_ncp_fs)
1083 module_exit(exit_ncp_fs)
1084 MODULE_LICENSE("GPL");