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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14 #include <linux/module.h>
16 #include <asm/uaccess.h>
17 #include <asm/byteorder.h>
19 #include <linux/time.h>
20 #include <linux/kernel.h>
22 #include <linux/string.h>
23 #include <linux/stat.h>
24 #include <linux/errno.h>
25 #include <linux/file.h>
26 #include <linux/fcntl.h>
27 #include <linux/slab.h>
28 #include <linux/vmalloc.h>
29 #include <linux/init.h>
30 #include <linux/vfs.h>
31 #include <linux/mount.h>
32 #include <linux/seq_file.h>
33 #include <linux/namei.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 dentry *);
50 static struct kmem_cache * ncp_inode_cachep;
52 static struct inode *ncp_alloc_inode(struct super_block *sb)
54 struct ncp_inode_info *ei;
55 ei = (struct ncp_inode_info *)kmem_cache_alloc(ncp_inode_cachep, GFP_KERNEL);
58 return &ei->vfs_inode;
61 static void ncp_i_callback(struct rcu_head *head)
63 struct inode *inode = container_of(head, struct inode, i_rcu);
64 kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode));
67 static void ncp_destroy_inode(struct inode *inode)
69 call_rcu(&inode->i_rcu, ncp_i_callback);
72 static void init_once(void *foo)
74 struct ncp_inode_info *ei = (struct ncp_inode_info *) foo;
76 mutex_init(&ei->open_mutex);
77 inode_init_once(&ei->vfs_inode);
80 static int init_inodecache(void)
82 ncp_inode_cachep = kmem_cache_create("ncp_inode_cache",
83 sizeof(struct ncp_inode_info),
84 0, (SLAB_RECLAIM_ACCOUNT|
85 SLAB_MEM_SPREAD|SLAB_ACCOUNT),
87 if (ncp_inode_cachep == NULL)
92 static void destroy_inodecache(void)
95 * Make sure all delayed rcu free inodes are flushed before we
99 kmem_cache_destroy(ncp_inode_cachep);
102 static int ncp_remount(struct super_block *sb, int *flags, char* data)
105 *flags |= MS_NODIRATIME;
109 static const struct super_operations ncp_sops =
111 .alloc_inode = ncp_alloc_inode,
112 .destroy_inode = ncp_destroy_inode,
113 .drop_inode = generic_delete_inode,
114 .evict_inode = ncp_evict_inode,
115 .put_super = ncp_put_super,
116 .statfs = ncp_statfs,
117 .remount_fs = ncp_remount,
118 .show_options = ncp_show_options,
122 * Fill in the ncpfs-specific information in the inode.
124 static void ncp_update_dirent(struct inode *inode, struct ncp_entry_info *nwinfo)
126 NCP_FINFO(inode)->DosDirNum = nwinfo->i.DosDirNum;
127 NCP_FINFO(inode)->dirEntNum = nwinfo->i.dirEntNum;
128 NCP_FINFO(inode)->volNumber = nwinfo->volume;
131 void ncp_update_inode(struct inode *inode, struct ncp_entry_info *nwinfo)
133 ncp_update_dirent(inode, nwinfo);
134 NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
135 NCP_FINFO(inode)->access = nwinfo->access;
136 memcpy(NCP_FINFO(inode)->file_handle, nwinfo->file_handle,
137 sizeof(nwinfo->file_handle));
138 ncp_dbg(1, "updated %s, volnum=%d, dirent=%u\n",
139 nwinfo->i.entryName, NCP_FINFO(inode)->volNumber,
140 NCP_FINFO(inode)->dirEntNum);
143 static void ncp_update_dates(struct inode *inode, struct nw_info_struct *nwi)
145 /* NFS namespace mode overrides others if it's set. */
146 ncp_dbg(1, "(%s) nfs.mode=0%o\n", nwi->entryName, nwi->nfs.mode);
149 inode->i_mode = nwi->nfs.mode;
152 inode->i_blocks = (i_size_read(inode) + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
154 inode->i_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate);
155 inode->i_ctime.tv_sec = ncp_date_dos2unix(nwi->creationTime, nwi->creationDate);
156 inode->i_atime.tv_sec = ncp_date_dos2unix(0, nwi->lastAccessDate);
157 inode->i_atime.tv_nsec = 0;
158 inode->i_mtime.tv_nsec = 0;
159 inode->i_ctime.tv_nsec = 0;
162 static void ncp_update_attrs(struct inode *inode, struct ncp_entry_info *nwinfo)
164 struct nw_info_struct *nwi = &nwinfo->i;
165 struct ncp_server *server = NCP_SERVER(inode);
167 if (nwi->attributes & aDIR) {
168 inode->i_mode = server->m.dir_mode;
169 /* for directories dataStreamSize seems to be some
171 i_size_write(inode, NCP_BLOCK_SIZE);
175 inode->i_mode = server->m.file_mode;
176 size = le32_to_cpu(nwi->dataStreamSize);
177 i_size_write(inode, size);
178 #ifdef CONFIG_NCPFS_EXTRAS
179 if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS))
180 && (nwi->attributes & aSHARED)) {
181 switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
183 if (server->m.flags & NCP_MOUNT_SYMLINKS) {
184 if (/* (size >= NCP_MIN_SYMLINK_SIZE)
185 && */ (size <= NCP_MAX_SYMLINK_SIZE)) {
186 inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
187 NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK;
193 if (server->m.flags & NCP_MOUNT_EXTRAS)
194 inode->i_mode |= S_IRUGO;
197 if (server->m.flags & NCP_MOUNT_EXTRAS)
198 inode->i_mode |= (inode->i_mode >> 2) & S_IXUGO;
200 /* case aSYSTEM|aHIDDEN: */
202 /* reserved combination */
208 if (nwi->attributes & aRONLY) inode->i_mode &= ~S_IWUGO;
211 void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo)
213 NCP_FINFO(inode)->flags = 0;
214 if (!atomic_read(&NCP_FINFO(inode)->opened)) {
215 NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
216 ncp_update_attrs(inode, nwinfo);
219 ncp_update_dates(inode, &nwinfo->i);
220 ncp_update_dirent(inode, nwinfo);
224 * Fill in the inode based on the ncp_entry_info structure. Used only for brand new inodes.
226 static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
228 struct ncp_server *server = NCP_SERVER(inode);
230 NCP_FINFO(inode)->flags = 0;
232 ncp_update_attrs(inode, nwinfo);
234 ncp_dbg(2, "inode->i_mode = %u\n", inode->i_mode);
237 inode->i_uid = server->m.uid;
238 inode->i_gid = server->m.gid;
240 ncp_update_dates(inode, &nwinfo->i);
241 ncp_update_inode(inode, nwinfo);
244 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
245 static const struct inode_operations ncp_symlink_inode_operations = {
246 .readlink = generic_readlink,
247 .get_link = page_get_link,
248 .setattr = ncp_notify_change,
256 ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
261 pr_err("%s: info is NULL\n", __func__);
265 inode = new_inode(sb);
267 atomic_set(&NCP_FINFO(inode)->opened, info->opened);
269 inode->i_ino = info->ino;
270 ncp_set_attr(inode, info);
271 if (S_ISREG(inode->i_mode)) {
272 inode->i_op = &ncp_file_inode_operations;
273 inode->i_fop = &ncp_file_operations;
274 } else if (S_ISDIR(inode->i_mode)) {
275 inode->i_op = &ncp_dir_inode_operations;
276 inode->i_fop = &ncp_dir_operations;
277 #ifdef CONFIG_NCPFS_NFS_NS
278 } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
279 init_special_inode(inode, inode->i_mode,
280 new_decode_dev(info->i.nfs.rdev));
282 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
283 } else if (S_ISLNK(inode->i_mode)) {
284 inode->i_op = &ncp_symlink_inode_operations;
285 inode_nohighmem(inode);
286 inode->i_data.a_ops = &ncp_symlink_aops;
289 make_bad_inode(inode);
291 insert_inode_hash(inode);
293 pr_err("%s: iget failed!\n", __func__);
298 ncp_evict_inode(struct inode *inode)
300 truncate_inode_pages_final(&inode->i_data);
303 if (S_ISDIR(inode->i_mode)) {
304 ncp_dbg(2, "put directory %ld\n", inode->i_ino);
307 if (ncp_make_closed(inode) != 0) {
308 /* We can't do anything but complain. */
309 pr_err("%s: could not close\n", __func__);
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)) {
413 data->gid = make_kgid(current_user_ns(), optint);
414 if (!gid_valid(data->gid)) {
420 data->mounted_uid = make_kuid(current_user_ns(), optint);
421 if (!uid_valid(data->mounted_uid)) {
427 data->file_mode = optint;
430 data->dir_mode = optint;
433 data->time_out = optint;
436 data->retry_count = optint;
439 data->flags = optint;
442 data->wdog_pid = find_get_pid(optint);
445 data->ncp_fd = optint;
448 data->info_fd = optint;
452 if (optint < NCP_MOUNT_VERSION_V4)
454 if (optint > NCP_MOUNT_VERSION_V5)
463 put_pid(data->wdog_pid);
464 data->wdog_pid = NULL;
468 static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
470 struct ncp_mount_data_kernel data;
471 struct ncp_server *server;
472 struct inode *root_inode;
476 #ifdef CONFIG_NCPFS_PACKET_SIGNING
479 struct ncp_entry_info finfo;
481 memset(&data, 0, sizeof(data));
482 server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL);
485 sb->s_fs_info = server;
488 if (raw_data == NULL)
490 switch (*(int*)raw_data) {
491 case NCP_MOUNT_VERSION:
493 struct ncp_mount_data* md = (struct ncp_mount_data*)raw_data;
495 data.flags = md->flags;
496 data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE;
497 data.mounted_uid = make_kuid(current_user_ns(), 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;
502 data.uid = make_kuid(current_user_ns(), md->uid);
503 data.gid = make_kgid(current_user_ns(), md->gid);
504 data.file_mode = md->file_mode;
505 data.dir_mode = md->dir_mode;
507 memcpy(data.mounted_vol, md->mounted_vol,
511 case NCP_MOUNT_VERSION_V4:
513 struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data;
515 data.flags = md->flags;
516 data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid);
517 data.wdog_pid = find_get_pid(md->wdog_pid);
518 data.ncp_fd = md->ncp_fd;
519 data.time_out = md->time_out;
520 data.retry_count = md->retry_count;
521 data.uid = make_kuid(current_user_ns(), md->uid);
522 data.gid = make_kgid(current_user_ns(), md->gid);
523 data.file_mode = md->file_mode;
524 data.dir_mode = md->dir_mode;
530 if (memcmp(raw_data, "vers", 4) == 0) {
531 error = ncp_parse_options(&data, raw_data);
538 if (!uid_valid(data.mounted_uid) || !uid_valid(data.uid) ||
539 !gid_valid(data.gid))
541 sock = sockfd_lookup(data.ncp_fd, &error);
545 if (sock->type == SOCK_STREAM)
546 default_bufsize = 0xF000;
548 default_bufsize = 1024;
550 sb->s_flags |= MS_NODIRATIME; /* probably even noatime */
551 sb->s_maxbytes = 0xFFFFFFFFU;
552 sb->s_blocksize = 1024; /* Eh... Is this correct? */
553 sb->s_blocksize_bits = 10;
554 sb->s_magic = NCP_SUPER_MAGIC;
555 sb->s_op = &ncp_sops;
556 sb->s_d_op = &ncp_dentry_operations;
557 sb->s_bdi = &server->bdi;
559 server = NCP_SBP(sb);
560 memset(server, 0, sizeof(*server));
562 error = bdi_setup_and_register(&server->bdi, "ncpfs");
566 server->ncp_sock = sock;
568 if (data.info_fd != -1) {
569 struct socket *info_sock = sockfd_lookup(data.info_fd, &error);
572 server->info_sock = info_sock;
574 if (info_sock->type != SOCK_STREAM)
578 /* server->lock = 0; */
579 mutex_init(&server->mutex);
580 server->packet = NULL;
581 /* server->buffer_size = 0; */
582 /* server->conn_status = 0; */
583 /* server->root_dentry = NULL; */
584 /* server->root_setuped = 0; */
585 mutex_init(&server->root_setup_lock);
586 #ifdef CONFIG_NCPFS_PACKET_SIGNING
587 /* server->sign_wanted = 0; */
588 /* server->sign_active = 0; */
590 init_rwsem(&server->auth_rwsem);
591 server->auth.auth_type = NCP_AUTH_NONE;
592 /* server->auth.object_name_len = 0; */
593 /* server->auth.object_name = NULL; */
594 /* server->auth.object_type = 0; */
595 /* server->priv.len = 0; */
596 /* server->priv.data = NULL; */
599 /* Although anything producing this is buggy, it happens
600 now because of PATH_MAX changes.. */
601 if (server->m.time_out < 1) {
602 server->m.time_out = 10;
603 pr_info("You need to recompile your ncpfs utils..\n");
605 server->m.time_out = server->m.time_out * HZ / 100;
606 server->m.file_mode = (server->m.file_mode & S_IRWXUGO) | S_IFREG;
607 server->m.dir_mode = (server->m.dir_mode & S_IRWXUGO) | S_IFDIR;
609 #ifdef CONFIG_NCPFS_NLS
610 /* load the default NLS charsets */
611 server->nls_vol = load_nls_default();
612 server->nls_io = load_nls_default();
613 #endif /* CONFIG_NCPFS_NLS */
615 atomic_set(&server->dentry_ttl, 0); /* no caching */
617 INIT_LIST_HEAD(&server->tx.requests);
618 mutex_init(&server->rcv.creq_mutex);
619 server->tx.creq = NULL;
620 server->rcv.creq = NULL;
622 init_timer(&server->timeout_tm);
623 #undef NCP_PACKET_SIZE
624 #define NCP_PACKET_SIZE 131072
626 server->packet_size = NCP_PACKET_SIZE;
627 server->packet = vmalloc(NCP_PACKET_SIZE);
628 if (server->packet == NULL)
630 server->txbuf = vmalloc(NCP_PACKET_SIZE);
631 if (server->txbuf == NULL)
633 server->rxbuf = vmalloc(NCP_PACKET_SIZE);
634 if (server->rxbuf == NULL)
638 server->data_ready = sock->sk->sk_data_ready;
639 server->write_space = sock->sk->sk_write_space;
640 server->error_report = sock->sk->sk_error_report;
641 sock->sk->sk_user_data = server;
642 sock->sk->sk_data_ready = ncp_tcp_data_ready;
643 sock->sk->sk_error_report = ncp_tcp_error_report;
644 if (sock->type == SOCK_STREAM) {
645 server->rcv.ptr = (unsigned char*)&server->rcv.buf;
646 server->rcv.len = 10;
647 server->rcv.state = 0;
648 INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc);
649 INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc);
650 sock->sk->sk_write_space = ncp_tcp_write_space;
652 INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc);
653 INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc);
654 server->timeout_tm.data = (unsigned long)server;
655 server->timeout_tm.function = ncpdgram_timeout_call;
657 release_sock(sock->sk);
659 ncp_lock_server(server);
660 error = ncp_connect(server);
661 ncp_unlock_server(server);
664 ncp_dbg(1, "NCP_SBP(sb) = %p\n", NCP_SBP(sb));
666 error = -EMSGSIZE; /* -EREMOTESIDEINCOMPATIBLE */
667 #ifdef CONFIG_NCPFS_PACKET_SIGNING
668 if (ncp_negotiate_size_and_options(server, default_bufsize,
669 NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0)
671 if (options != NCP_DEFAULT_OPTIONS)
673 if (ncp_negotiate_size_and_options(server,
676 &(server->buffer_size), &options) != 0)
682 ncp_lock_server(server);
684 server->sign_wanted = 1;
685 ncp_unlock_server(server);
688 #endif /* CONFIG_NCPFS_PACKET_SIGNING */
689 if (ncp_negotiate_buffersize(server, default_bufsize,
690 &(server->buffer_size)) != 0)
692 ncp_dbg(1, "bufsize = %d\n", server->buffer_size);
694 memset(&finfo, 0, sizeof(finfo));
695 finfo.i.attributes = aDIR;
696 finfo.i.dataStreamSize = 0; /* ignored */
697 finfo.i.dirEntNum = 0;
698 finfo.i.DosDirNum = 0;
699 #ifdef CONFIG_NCPFS_SMALLDOS
700 finfo.i.NSCreator = NW_NS_DOS;
702 finfo.volume = NCP_NUMBER_OF_VOLUMES;
703 /* set dates of mountpoint to Jan 1, 1986; 00:00 */
704 finfo.i.creationTime = finfo.i.modifyTime
705 = cpu_to_le16(0x0000);
706 finfo.i.creationDate = finfo.i.modifyDate
707 = finfo.i.lastAccessDate
708 = cpu_to_le16(0x0C21);
710 finfo.i.entryName[0] = '\0';
713 finfo.ino = 2; /* tradition */
715 server->name_space[finfo.volume] = NW_NS_DOS;
718 root_inode = ncp_iget(sb, &finfo);
721 ncp_dbg(1, "root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
722 sb->s_root = d_make_root(root_inode);
728 ncp_lock_server(server);
729 ncp_disconnect(server);
730 ncp_unlock_server(server);
732 ncp_stop_tasks(server);
733 vfree(server->rxbuf);
735 vfree(server->txbuf);
737 vfree(server->packet);
739 #ifdef CONFIG_NCPFS_NLS
740 unload_nls(server->nls_io);
741 unload_nls(server->nls_vol);
743 mutex_destroy(&server->rcv.creq_mutex);
744 mutex_destroy(&server->root_setup_lock);
745 mutex_destroy(&server->mutex);
747 if (server->info_sock)
748 sockfd_put(server->info_sock);
750 bdi_destroy(&server->bdi);
754 put_pid(data.wdog_pid);
755 sb->s_fs_info = NULL;
760 static void delayed_free(struct rcu_head *p)
762 struct ncp_server *server = container_of(p, struct ncp_server, rcu);
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 */
771 static void ncp_put_super(struct super_block *sb)
773 struct ncp_server *server = NCP_SBP(sb);
775 ncp_lock_server(server);
776 ncp_disconnect(server);
777 ncp_unlock_server(server);
779 ncp_stop_tasks(server);
781 mutex_destroy(&server->rcv.creq_mutex);
782 mutex_destroy(&server->root_setup_lock);
783 mutex_destroy(&server->mutex);
785 if (server->info_sock)
786 sockfd_put(server->info_sock);
787 sockfd_put(server->ncp_sock);
788 kill_pid(server->m.wdog_pid, SIGTERM, 1);
789 put_pid(server->m.wdog_pid);
791 bdi_destroy(&server->bdi);
792 kfree(server->priv.data);
793 kfree(server->auth.object_name);
794 vfree(server->rxbuf);
795 vfree(server->txbuf);
796 vfree(server->packet);
797 call_rcu(&server->rcu, delayed_free);
800 static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
804 struct ncp_inode_info* ni;
805 struct ncp_server* s;
806 struct ncp_volume_info vi;
807 struct super_block *sb = dentry->d_sb;
827 if (!s->m.mounted_vol[0]) {
831 err = ncp_dirhandle_alloc(s, ni->volNumber, ni->DosDirNum, &dh);
835 err = ncp_get_directory_info(s, dh, &vi);
836 ncp_dirhandle_free(s, dh);
840 buf->f_type = NCP_SUPER_MAGIC;
841 buf->f_bsize = vi.sectors_per_block * 512;
842 buf->f_blocks = vi.total_blocks;
843 buf->f_bfree = vi.free_blocks;
844 buf->f_bavail = vi.free_blocks;
845 buf->f_files = vi.total_dir_entries;
846 buf->f_ffree = vi.available_dir_entries;
850 /* We cannot say how much disk space is left on a mounted
851 NetWare Server, because free space is distributed over
852 volumes, and the current user might have disk quotas. So
853 free space is not that simple to determine. Our decision
854 here is to err conservatively. */
857 buf->f_type = NCP_SUPER_MAGIC;
858 buf->f_bsize = NCP_BLOCK_SIZE;
866 int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
868 struct inode *inode = d_inode(dentry);
871 struct nw_modify_dos_info info;
872 struct ncp_server *server;
876 server = NCP_SERVER(inode);
877 if (!server) /* How this could happen? */
881 if (IS_DEADDIR(d_inode(dentry)))
884 /* ageing the dentry to force validation */
885 ncp_age_dentry(server, dentry);
887 result = setattr_prepare(dentry, attr);
892 if ((attr->ia_valid & ATTR_UID) && !uid_eq(attr->ia_uid, server->m.uid))
895 if ((attr->ia_valid & ATTR_GID) && !gid_eq(attr->ia_gid, server->m.gid))
898 if (((attr->ia_valid & ATTR_MODE) &&
900 ~(S_IFREG | S_IFDIR | S_IRWXUGO))))
904 memset(&info, 0, sizeof(info));
907 if ((attr->ia_valid & ATTR_MODE) != 0)
909 umode_t newmode = attr->ia_mode;
911 info_mask |= DM_ATTRIBUTES;
913 if (S_ISDIR(inode->i_mode)) {
914 newmode &= server->m.dir_mode;
916 #ifdef CONFIG_NCPFS_EXTRAS
917 if (server->m.flags & NCP_MOUNT_EXTRAS) {
918 /* any non-default execute bit set */
919 if (newmode & ~server->m.file_mode & S_IXUGO)
920 info.attributes |= aSHARED | aSYSTEM;
921 /* read for group/world and not in default file_mode */
922 else if (newmode & ~server->m.file_mode & S_IRUGO)
923 info.attributes |= aSHARED;
926 newmode &= server->m.file_mode;
928 if (newmode & S_IWUGO)
929 info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
931 info.attributes |= (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
933 #ifdef CONFIG_NCPFS_NFS_NS
934 if (ncp_is_nfs_extras(server, NCP_FINFO(inode)->volNumber)) {
935 result = ncp_modify_nfs_info(server,
936 NCP_FINFO(inode)->volNumber,
937 NCP_FINFO(inode)->dirEntNum,
941 info.attributes &= ~(aSHARED | aSYSTEM);
943 /* mark partial success */
944 struct iattr tmpattr;
946 tmpattr.ia_valid = ATTR_MODE;
947 tmpattr.ia_mode = attr->ia_mode;
949 setattr_copy(inode, &tmpattr);
950 mark_inode_dirty(inode);
957 /* Do SIZE before attributes, otherwise mtime together with size does not work...
959 if ((attr->ia_valid & ATTR_SIZE) != 0) {
962 ncp_dbg(1, "trying to change size to %llu\n", attr->ia_size);
964 if ((result = ncp_make_open(inode, O_WRONLY)) < 0) {
968 ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
969 attr->ia_size, 0, "", &written);
971 /* According to ndir, the changes only take effect after
973 ncp_inode_close(inode);
974 result = ncp_make_closed(inode);
978 if (attr->ia_size != i_size_read(inode)) {
979 truncate_setsize(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,
1043 MODULE_ALIAS_FS("ncpfs");
1045 static int __init init_ncp_fs(void)
1048 ncp_dbg(1, "called\n");
1050 err = init_inodecache();
1053 err = register_filesystem(&ncp_fs_type);
1058 destroy_inodecache();
1063 static void __exit exit_ncp_fs(void)
1065 ncp_dbg(1, "called\n");
1066 unregister_filesystem(&ncp_fs_type);
1067 destroy_inodecache();
1070 module_init(init_ncp_fs)
1071 module_exit(exit_ncp_fs)
1072 MODULE_LICENSE("GPL");