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 <linux/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/sched/signal.h>
34 #include <linux/namei.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 dentry *);
51 static struct kmem_cache * ncp_inode_cachep;
53 static struct inode *ncp_alloc_inode(struct super_block *sb)
55 struct ncp_inode_info *ei;
56 ei = (struct ncp_inode_info *)kmem_cache_alloc(ncp_inode_cachep, GFP_KERNEL);
59 return &ei->vfs_inode;
62 static void ncp_i_callback(struct rcu_head *head)
64 struct inode *inode = container_of(head, struct inode, i_rcu);
65 kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode));
68 static void ncp_destroy_inode(struct inode *inode)
70 call_rcu(&inode->i_rcu, ncp_i_callback);
73 static void init_once(void *foo)
75 struct ncp_inode_info *ei = (struct ncp_inode_info *) foo;
77 mutex_init(&ei->open_mutex);
78 inode_init_once(&ei->vfs_inode);
81 static int init_inodecache(void)
83 ncp_inode_cachep = kmem_cache_create("ncp_inode_cache",
84 sizeof(struct ncp_inode_info),
85 0, (SLAB_RECLAIM_ACCOUNT|
86 SLAB_MEM_SPREAD|SLAB_ACCOUNT),
88 if (ncp_inode_cachep == NULL)
93 static void destroy_inodecache(void)
96 * Make sure all delayed rcu free inodes are flushed before we
100 kmem_cache_destroy(ncp_inode_cachep);
103 static int ncp_remount(struct super_block *sb, int *flags, char* data)
106 *flags |= MS_NODIRATIME;
110 static const struct super_operations ncp_sops =
112 .alloc_inode = ncp_alloc_inode,
113 .destroy_inode = ncp_destroy_inode,
114 .drop_inode = generic_delete_inode,
115 .evict_inode = ncp_evict_inode,
116 .put_super = ncp_put_super,
117 .statfs = ncp_statfs,
118 .remount_fs = ncp_remount,
119 .show_options = ncp_show_options,
123 * Fill in the ncpfs-specific information in the inode.
125 static void ncp_update_dirent(struct inode *inode, struct ncp_entry_info *nwinfo)
127 NCP_FINFO(inode)->DosDirNum = nwinfo->i.DosDirNum;
128 NCP_FINFO(inode)->dirEntNum = nwinfo->i.dirEntNum;
129 NCP_FINFO(inode)->volNumber = nwinfo->volume;
132 void ncp_update_inode(struct inode *inode, struct ncp_entry_info *nwinfo)
134 ncp_update_dirent(inode, nwinfo);
135 NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
136 NCP_FINFO(inode)->access = nwinfo->access;
137 memcpy(NCP_FINFO(inode)->file_handle, nwinfo->file_handle,
138 sizeof(nwinfo->file_handle));
139 ncp_dbg(1, "updated %s, volnum=%d, dirent=%u\n",
140 nwinfo->i.entryName, NCP_FINFO(inode)->volNumber,
141 NCP_FINFO(inode)->dirEntNum);
144 static void ncp_update_dates(struct inode *inode, struct nw_info_struct *nwi)
146 /* NFS namespace mode overrides others if it's set. */
147 ncp_dbg(1, "(%s) nfs.mode=0%o\n", nwi->entryName, nwi->nfs.mode);
150 inode->i_mode = nwi->nfs.mode;
153 inode->i_blocks = (i_size_read(inode) + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
155 inode->i_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate);
156 inode->i_ctime.tv_sec = ncp_date_dos2unix(nwi->creationTime, nwi->creationDate);
157 inode->i_atime.tv_sec = ncp_date_dos2unix(0, nwi->lastAccessDate);
158 inode->i_atime.tv_nsec = 0;
159 inode->i_mtime.tv_nsec = 0;
160 inode->i_ctime.tv_nsec = 0;
163 static void ncp_update_attrs(struct inode *inode, struct ncp_entry_info *nwinfo)
165 struct nw_info_struct *nwi = &nwinfo->i;
166 struct ncp_server *server = NCP_SERVER(inode);
168 if (nwi->attributes & aDIR) {
169 inode->i_mode = server->m.dir_mode;
170 /* for directories dataStreamSize seems to be some
172 i_size_write(inode, NCP_BLOCK_SIZE);
176 inode->i_mode = server->m.file_mode;
177 size = le32_to_cpu(nwi->dataStreamSize);
178 i_size_write(inode, size);
179 #ifdef CONFIG_NCPFS_EXTRAS
180 if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS))
181 && (nwi->attributes & aSHARED)) {
182 switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
184 if (server->m.flags & NCP_MOUNT_SYMLINKS) {
185 if (/* (size >= NCP_MIN_SYMLINK_SIZE)
186 && */ (size <= NCP_MAX_SYMLINK_SIZE)) {
187 inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
188 NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK;
194 if (server->m.flags & NCP_MOUNT_EXTRAS)
195 inode->i_mode |= S_IRUGO;
198 if (server->m.flags & NCP_MOUNT_EXTRAS)
199 inode->i_mode |= (inode->i_mode >> 2) & S_IXUGO;
201 /* case aSYSTEM|aHIDDEN: */
203 /* reserved combination */
209 if (nwi->attributes & aRONLY) inode->i_mode &= ~S_IWUGO;
212 void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo)
214 NCP_FINFO(inode)->flags = 0;
215 if (!atomic_read(&NCP_FINFO(inode)->opened)) {
216 NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
217 ncp_update_attrs(inode, nwinfo);
220 ncp_update_dates(inode, &nwinfo->i);
221 ncp_update_dirent(inode, nwinfo);
225 * Fill in the inode based on the ncp_entry_info structure. Used only for brand new inodes.
227 static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
229 struct ncp_server *server = NCP_SERVER(inode);
231 NCP_FINFO(inode)->flags = 0;
233 ncp_update_attrs(inode, nwinfo);
235 ncp_dbg(2, "inode->i_mode = %u\n", inode->i_mode);
238 inode->i_uid = server->m.uid;
239 inode->i_gid = server->m.gid;
241 ncp_update_dates(inode, &nwinfo->i);
242 ncp_update_inode(inode, nwinfo);
245 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
246 static const struct inode_operations ncp_symlink_inode_operations = {
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;
558 server = NCP_SBP(sb);
559 memset(server, 0, sizeof(*server));
561 error = super_setup_bdi(sb);
565 server->ncp_sock = sock;
567 if (data.info_fd != -1) {
568 struct socket *info_sock = sockfd_lookup(data.info_fd, &error);
571 server->info_sock = info_sock;
573 if (info_sock->type != SOCK_STREAM)
577 /* server->lock = 0; */
578 mutex_init(&server->mutex);
579 server->packet = NULL;
580 /* server->buffer_size = 0; */
581 /* server->conn_status = 0; */
582 /* server->root_dentry = NULL; */
583 /* server->root_setuped = 0; */
584 mutex_init(&server->root_setup_lock);
585 #ifdef CONFIG_NCPFS_PACKET_SIGNING
586 /* server->sign_wanted = 0; */
587 /* server->sign_active = 0; */
589 init_rwsem(&server->auth_rwsem);
590 server->auth.auth_type = NCP_AUTH_NONE;
591 /* server->auth.object_name_len = 0; */
592 /* server->auth.object_name = NULL; */
593 /* server->auth.object_type = 0; */
594 /* server->priv.len = 0; */
595 /* server->priv.data = NULL; */
598 /* Although anything producing this is buggy, it happens
599 now because of PATH_MAX changes.. */
600 if (server->m.time_out < 1) {
601 server->m.time_out = 10;
602 pr_info("You need to recompile your ncpfs utils..\n");
604 server->m.time_out = server->m.time_out * HZ / 100;
605 server->m.file_mode = (server->m.file_mode & S_IRWXUGO) | S_IFREG;
606 server->m.dir_mode = (server->m.dir_mode & S_IRWXUGO) | S_IFDIR;
608 #ifdef CONFIG_NCPFS_NLS
609 /* load the default NLS charsets */
610 server->nls_vol = load_nls_default();
611 server->nls_io = load_nls_default();
612 #endif /* CONFIG_NCPFS_NLS */
614 atomic_set(&server->dentry_ttl, 0); /* no caching */
616 INIT_LIST_HEAD(&server->tx.requests);
617 mutex_init(&server->rcv.creq_mutex);
618 server->tx.creq = NULL;
619 server->rcv.creq = NULL;
621 init_timer(&server->timeout_tm);
622 #undef NCP_PACKET_SIZE
623 #define NCP_PACKET_SIZE 131072
625 server->packet_size = NCP_PACKET_SIZE;
626 server->packet = vmalloc(NCP_PACKET_SIZE);
627 if (server->packet == NULL)
629 server->txbuf = vmalloc(NCP_PACKET_SIZE);
630 if (server->txbuf == NULL)
632 server->rxbuf = vmalloc(NCP_PACKET_SIZE);
633 if (server->rxbuf == NULL)
637 server->data_ready = sock->sk->sk_data_ready;
638 server->write_space = sock->sk->sk_write_space;
639 server->error_report = sock->sk->sk_error_report;
640 sock->sk->sk_user_data = server;
641 sock->sk->sk_data_ready = ncp_tcp_data_ready;
642 sock->sk->sk_error_report = ncp_tcp_error_report;
643 if (sock->type == SOCK_STREAM) {
644 server->rcv.ptr = (unsigned char*)&server->rcv.buf;
645 server->rcv.len = 10;
646 server->rcv.state = 0;
647 INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc);
648 INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc);
649 sock->sk->sk_write_space = ncp_tcp_write_space;
651 INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc);
652 INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc);
653 server->timeout_tm.data = (unsigned long)server;
654 server->timeout_tm.function = ncpdgram_timeout_call;
656 release_sock(sock->sk);
658 ncp_lock_server(server);
659 error = ncp_connect(server);
660 ncp_unlock_server(server);
663 ncp_dbg(1, "NCP_SBP(sb) = %p\n", NCP_SBP(sb));
665 error = -EMSGSIZE; /* -EREMOTESIDEINCOMPATIBLE */
666 #ifdef CONFIG_NCPFS_PACKET_SIGNING
667 if (ncp_negotiate_size_and_options(server, default_bufsize,
668 NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0)
670 if (options != NCP_DEFAULT_OPTIONS)
672 if (ncp_negotiate_size_and_options(server,
675 &(server->buffer_size), &options) != 0)
681 ncp_lock_server(server);
683 server->sign_wanted = 1;
684 ncp_unlock_server(server);
687 #endif /* CONFIG_NCPFS_PACKET_SIGNING */
688 if (ncp_negotiate_buffersize(server, default_bufsize,
689 &(server->buffer_size)) != 0)
691 ncp_dbg(1, "bufsize = %d\n", server->buffer_size);
693 memset(&finfo, 0, sizeof(finfo));
694 finfo.i.attributes = aDIR;
695 finfo.i.dataStreamSize = 0; /* ignored */
696 finfo.i.dirEntNum = 0;
697 finfo.i.DosDirNum = 0;
698 #ifdef CONFIG_NCPFS_SMALLDOS
699 finfo.i.NSCreator = NW_NS_DOS;
701 finfo.volume = NCP_NUMBER_OF_VOLUMES;
702 /* set dates of mountpoint to Jan 1, 1986; 00:00 */
703 finfo.i.creationTime = finfo.i.modifyTime
704 = cpu_to_le16(0x0000);
705 finfo.i.creationDate = finfo.i.modifyDate
706 = finfo.i.lastAccessDate
707 = cpu_to_le16(0x0C21);
709 finfo.i.entryName[0] = '\0';
712 finfo.ino = 2; /* tradition */
714 server->name_space[finfo.volume] = NW_NS_DOS;
717 root_inode = ncp_iget(sb, &finfo);
720 ncp_dbg(1, "root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
721 sb->s_root = d_make_root(root_inode);
727 ncp_lock_server(server);
728 ncp_disconnect(server);
729 ncp_unlock_server(server);
731 ncp_stop_tasks(server);
732 vfree(server->rxbuf);
734 vfree(server->txbuf);
736 vfree(server->packet);
738 #ifdef CONFIG_NCPFS_NLS
739 unload_nls(server->nls_io);
740 unload_nls(server->nls_vol);
742 mutex_destroy(&server->rcv.creq_mutex);
743 mutex_destroy(&server->root_setup_lock);
744 mutex_destroy(&server->mutex);
746 if (server->info_sock)
747 sockfd_put(server->info_sock);
751 put_pid(data.wdog_pid);
752 sb->s_fs_info = NULL;
757 static void delayed_free(struct rcu_head *p)
759 struct ncp_server *server = container_of(p, struct ncp_server, rcu);
760 #ifdef CONFIG_NCPFS_NLS
761 /* unload the NLS charsets */
762 unload_nls(server->nls_vol);
763 unload_nls(server->nls_io);
764 #endif /* CONFIG_NCPFS_NLS */
768 static void ncp_put_super(struct super_block *sb)
770 struct ncp_server *server = NCP_SBP(sb);
772 ncp_lock_server(server);
773 ncp_disconnect(server);
774 ncp_unlock_server(server);
776 ncp_stop_tasks(server);
778 mutex_destroy(&server->rcv.creq_mutex);
779 mutex_destroy(&server->root_setup_lock);
780 mutex_destroy(&server->mutex);
782 if (server->info_sock)
783 sockfd_put(server->info_sock);
784 sockfd_put(server->ncp_sock);
785 kill_pid(server->m.wdog_pid, SIGTERM, 1);
786 put_pid(server->m.wdog_pid);
788 kfree(server->priv.data);
789 kfree(server->auth.object_name);
790 vfree(server->rxbuf);
791 vfree(server->txbuf);
792 vfree(server->packet);
793 call_rcu(&server->rcu, delayed_free);
796 static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
800 struct ncp_inode_info* ni;
801 struct ncp_server* s;
802 struct ncp_volume_info vi;
803 struct super_block *sb = dentry->d_sb;
823 if (!s->m.mounted_vol[0]) {
827 err = ncp_dirhandle_alloc(s, ni->volNumber, ni->DosDirNum, &dh);
831 err = ncp_get_directory_info(s, dh, &vi);
832 ncp_dirhandle_free(s, dh);
836 buf->f_type = NCP_SUPER_MAGIC;
837 buf->f_bsize = vi.sectors_per_block * 512;
838 buf->f_blocks = vi.total_blocks;
839 buf->f_bfree = vi.free_blocks;
840 buf->f_bavail = vi.free_blocks;
841 buf->f_files = vi.total_dir_entries;
842 buf->f_ffree = vi.available_dir_entries;
846 /* We cannot say how much disk space is left on a mounted
847 NetWare Server, because free space is distributed over
848 volumes, and the current user might have disk quotas. So
849 free space is not that simple to determine. Our decision
850 here is to err conservatively. */
853 buf->f_type = NCP_SUPER_MAGIC;
854 buf->f_bsize = NCP_BLOCK_SIZE;
862 int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
864 struct inode *inode = d_inode(dentry);
867 struct nw_modify_dos_info info;
868 struct ncp_server *server;
872 server = NCP_SERVER(inode);
873 if (!server) /* How this could happen? */
877 if (IS_DEADDIR(d_inode(dentry)))
880 /* ageing the dentry to force validation */
881 ncp_age_dentry(server, dentry);
883 result = setattr_prepare(dentry, attr);
888 if ((attr->ia_valid & ATTR_UID) && !uid_eq(attr->ia_uid, server->m.uid))
891 if ((attr->ia_valid & ATTR_GID) && !gid_eq(attr->ia_gid, server->m.gid))
894 if (((attr->ia_valid & ATTR_MODE) &&
896 ~(S_IFREG | S_IFDIR | S_IRWXUGO))))
900 memset(&info, 0, sizeof(info));
903 if ((attr->ia_valid & ATTR_MODE) != 0)
905 umode_t newmode = attr->ia_mode;
907 info_mask |= DM_ATTRIBUTES;
909 if (S_ISDIR(inode->i_mode)) {
910 newmode &= server->m.dir_mode;
912 #ifdef CONFIG_NCPFS_EXTRAS
913 if (server->m.flags & NCP_MOUNT_EXTRAS) {
914 /* any non-default execute bit set */
915 if (newmode & ~server->m.file_mode & S_IXUGO)
916 info.attributes |= aSHARED | aSYSTEM;
917 /* read for group/world and not in default file_mode */
918 else if (newmode & ~server->m.file_mode & S_IRUGO)
919 info.attributes |= aSHARED;
922 newmode &= server->m.file_mode;
924 if (newmode & S_IWUGO)
925 info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
927 info.attributes |= (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
929 #ifdef CONFIG_NCPFS_NFS_NS
930 if (ncp_is_nfs_extras(server, NCP_FINFO(inode)->volNumber)) {
931 result = ncp_modify_nfs_info(server,
932 NCP_FINFO(inode)->volNumber,
933 NCP_FINFO(inode)->dirEntNum,
937 info.attributes &= ~(aSHARED | aSYSTEM);
939 /* mark partial success */
940 struct iattr tmpattr;
942 tmpattr.ia_valid = ATTR_MODE;
943 tmpattr.ia_mode = attr->ia_mode;
945 setattr_copy(inode, &tmpattr);
946 mark_inode_dirty(inode);
953 /* Do SIZE before attributes, otherwise mtime together with size does not work...
955 if ((attr->ia_valid & ATTR_SIZE) != 0) {
958 ncp_dbg(1, "trying to change size to %llu\n", attr->ia_size);
960 if ((result = ncp_make_open(inode, O_WRONLY)) < 0) {
964 ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
965 attr->ia_size, 0, "", &written);
967 /* According to ndir, the changes only take effect after
969 ncp_inode_close(inode);
970 result = ncp_make_closed(inode);
974 if (attr->ia_size != i_size_read(inode)) {
975 truncate_setsize(inode, attr->ia_size);
976 mark_inode_dirty(inode);
979 if ((attr->ia_valid & ATTR_CTIME) != 0) {
980 info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE);
981 ncp_date_unix2dos(attr->ia_ctime.tv_sec,
982 &info.creationTime, &info.creationDate);
984 if ((attr->ia_valid & ATTR_MTIME) != 0) {
985 info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE);
986 ncp_date_unix2dos(attr->ia_mtime.tv_sec,
987 &info.modifyTime, &info.modifyDate);
989 if ((attr->ia_valid & ATTR_ATIME) != 0) {
991 info_mask |= (DM_LAST_ACCESS_DATE);
992 ncp_date_unix2dos(attr->ia_atime.tv_sec,
993 &dummy, &info.lastAccessDate);
995 if (info_mask != 0) {
996 result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
997 inode, info_mask, &info);
999 if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
1000 /* NetWare seems not to allow this. I
1001 do not know why. So, just tell the
1002 user everything went fine. This is
1003 a terrible hack, but I do not know
1004 how to do this correctly. */
1009 #ifdef CONFIG_NCPFS_STRONG
1010 if ((!result) && (info_mask & DM_ATTRIBUTES))
1011 NCP_FINFO(inode)->nwattr = info.attributes;
1017 setattr_copy(inode, attr);
1018 mark_inode_dirty(inode);
1026 static struct dentry *ncp_mount(struct file_system_type *fs_type,
1027 int flags, const char *dev_name, void *data)
1029 return mount_nodev(fs_type, flags, data, ncp_fill_super);
1032 static struct file_system_type ncp_fs_type = {
1033 .owner = THIS_MODULE,
1036 .kill_sb = kill_anon_super,
1037 .fs_flags = FS_BINARY_MOUNTDATA,
1039 MODULE_ALIAS_FS("ncpfs");
1041 static int __init init_ncp_fs(void)
1044 ncp_dbg(1, "called\n");
1046 err = init_inodecache();
1049 err = register_filesystem(&ncp_fs_type);
1054 destroy_inodecache();
1059 static void __exit exit_ncp_fs(void)
1061 ncp_dbg(1, "called\n");
1062 unregister_filesystem(&ncp_fs_type);
1063 destroy_inodecache();
1066 module_init(init_ncp_fs)
1067 module_exit(exit_ncp_fs)
1068 MODULE_LICENSE("GPL");