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|
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 DPRINTK("ncp_update_inode: 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 DPRINTK(KERN_DEBUG "ncp_update_dates_and_mode: (%s) nfs.mode=0%o\n",
147 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 DDPRINTK("ncp_read_inode: 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 .readlink = generic_readlink,
248 .follow_link = page_follow_link_light,
249 .put_link = page_put_link,
250 .setattr = ncp_notify_change,
258 ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
263 pr_err("%s: info is NULL\n", __func__);
267 inode = new_inode(sb);
269 atomic_set(&NCP_FINFO(inode)->opened, info->opened);
271 inode->i_mapping->backing_dev_info = sb->s_bdi;
272 inode->i_ino = info->ino;
273 ncp_set_attr(inode, info);
274 if (S_ISREG(inode->i_mode)) {
275 inode->i_op = &ncp_file_inode_operations;
276 inode->i_fop = &ncp_file_operations;
277 } else if (S_ISDIR(inode->i_mode)) {
278 inode->i_op = &ncp_dir_inode_operations;
279 inode->i_fop = &ncp_dir_operations;
280 #ifdef CONFIG_NCPFS_NFS_NS
281 } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
282 init_special_inode(inode, inode->i_mode,
283 new_decode_dev(info->i.nfs.rdev));
285 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
286 } else if (S_ISLNK(inode->i_mode)) {
287 inode->i_op = &ncp_symlink_inode_operations;
288 inode->i_data.a_ops = &ncp_symlink_aops;
291 make_bad_inode(inode);
293 insert_inode_hash(inode);
295 pr_err("%s: iget failed!\n", __func__);
300 ncp_evict_inode(struct inode *inode)
302 truncate_inode_pages_final(&inode->i_data);
305 if (S_ISDIR(inode->i_mode)) {
306 DDPRINTK("ncp_evict_inode: put directory %ld\n", inode->i_ino);
309 if (ncp_make_closed(inode) != 0) {
310 /* We can't do anything but complain. */
311 pr_err("%s: could not close\n", __func__);
315 static void ncp_stop_tasks(struct ncp_server *server) {
316 struct sock* sk = server->ncp_sock->sk;
319 sk->sk_error_report = server->error_report;
320 sk->sk_data_ready = server->data_ready;
321 sk->sk_write_space = server->write_space;
323 del_timer_sync(&server->timeout_tm);
325 flush_work(&server->rcv.tq);
326 if (sk->sk_socket->type == SOCK_STREAM)
327 flush_work(&server->tx.tq);
329 flush_work(&server->timeout_tq);
332 static int ncp_show_options(struct seq_file *seq, struct dentry *root)
334 struct ncp_server *server = NCP_SBP(root->d_sb);
337 if (!uid_eq(server->m.uid, GLOBAL_ROOT_UID))
338 seq_printf(seq, ",uid=%u",
339 from_kuid_munged(&init_user_ns, server->m.uid));
340 if (!gid_eq(server->m.gid, GLOBAL_ROOT_GID))
341 seq_printf(seq, ",gid=%u",
342 from_kgid_munged(&init_user_ns, server->m.gid));
343 if (!uid_eq(server->m.mounted_uid, GLOBAL_ROOT_UID))
344 seq_printf(seq, ",owner=%u",
345 from_kuid_munged(&init_user_ns, server->m.mounted_uid));
346 tmp = server->m.file_mode & S_IALLUGO;
347 if (tmp != NCP_DEFAULT_FILE_MODE)
348 seq_printf(seq, ",mode=0%o", tmp);
349 tmp = server->m.dir_mode & S_IALLUGO;
350 if (tmp != NCP_DEFAULT_DIR_MODE)
351 seq_printf(seq, ",dirmode=0%o", tmp);
352 if (server->m.time_out != NCP_DEFAULT_TIME_OUT * HZ / 100) {
353 tmp = server->m.time_out * 100 / HZ;
354 seq_printf(seq, ",timeout=%u", tmp);
356 if (server->m.retry_count != NCP_DEFAULT_RETRY_COUNT)
357 seq_printf(seq, ",retry=%u", server->m.retry_count);
358 if (server->m.flags != 0)
359 seq_printf(seq, ",flags=%lu", server->m.flags);
360 if (server->m.wdog_pid != NULL)
361 seq_printf(seq, ",wdogpid=%u", pid_vnr(server->m.wdog_pid));
366 static const struct ncp_option ncp_opts[] = {
367 { "uid", OPT_INT, 'u' },
368 { "gid", OPT_INT, 'g' },
369 { "owner", OPT_INT, 'o' },
370 { "mode", OPT_INT, 'm' },
371 { "dirmode", OPT_INT, 'd' },
372 { "timeout", OPT_INT, 't' },
373 { "retry", OPT_INT, 'r' },
374 { "flags", OPT_INT, 'f' },
375 { "wdogpid", OPT_INT, 'w' },
376 { "ncpfd", OPT_INT, 'n' },
377 { "infofd", OPT_INT, 'i' }, /* v5 */
378 { "version", OPT_INT, 'v' },
381 static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) {
384 unsigned long optint;
390 data->mounted_uid = GLOBAL_ROOT_UID;
391 data->wdog_pid = NULL;
393 data->time_out = NCP_DEFAULT_TIME_OUT;
394 data->retry_count = NCP_DEFAULT_RETRY_COUNT;
395 data->uid = GLOBAL_ROOT_UID;
396 data->gid = GLOBAL_ROOT_GID;
397 data->file_mode = NCP_DEFAULT_FILE_MODE;
398 data->dir_mode = NCP_DEFAULT_DIR_MODE;
400 data->mounted_vol[0] = 0;
402 while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 0) {
408 data->uid = make_kuid(current_user_ns(), optint);
409 if (!uid_valid(data->uid)) {
415 data->gid = make_kgid(current_user_ns(), optint);
416 if (!gid_valid(data->gid)) {
422 data->mounted_uid = make_kuid(current_user_ns(), optint);
423 if (!uid_valid(data->mounted_uid)) {
429 data->file_mode = optint;
432 data->dir_mode = optint;
435 data->time_out = optint;
438 data->retry_count = optint;
441 data->flags = optint;
444 data->wdog_pid = find_get_pid(optint);
447 data->ncp_fd = optint;
450 data->info_fd = optint;
454 if (optint < NCP_MOUNT_VERSION_V4)
456 if (optint > NCP_MOUNT_VERSION_V5)
465 put_pid(data->wdog_pid);
466 data->wdog_pid = NULL;
470 static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
472 struct ncp_mount_data_kernel data;
473 struct ncp_server *server;
474 struct file *ncp_filp;
475 struct inode *root_inode;
476 struct inode *sock_inode;
480 #ifdef CONFIG_NCPFS_PACKET_SIGNING
483 struct ncp_entry_info finfo;
485 memset(&data, 0, sizeof(data));
486 server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL);
489 sb->s_fs_info = server;
492 if (raw_data == NULL)
494 switch (*(int*)raw_data) {
495 case NCP_MOUNT_VERSION:
497 struct ncp_mount_data* md = (struct ncp_mount_data*)raw_data;
499 data.flags = md->flags;
500 data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE;
501 data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid);
502 data.wdog_pid = find_get_pid(md->wdog_pid);
503 data.ncp_fd = md->ncp_fd;
504 data.time_out = md->time_out;
505 data.retry_count = md->retry_count;
506 data.uid = make_kuid(current_user_ns(), md->uid);
507 data.gid = make_kgid(current_user_ns(), md->gid);
508 data.file_mode = md->file_mode;
509 data.dir_mode = md->dir_mode;
511 memcpy(data.mounted_vol, md->mounted_vol,
515 case NCP_MOUNT_VERSION_V4:
517 struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data;
519 data.flags = md->flags;
520 data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid);
521 data.wdog_pid = find_get_pid(md->wdog_pid);
522 data.ncp_fd = md->ncp_fd;
523 data.time_out = md->time_out;
524 data.retry_count = md->retry_count;
525 data.uid = make_kuid(current_user_ns(), md->uid);
526 data.gid = make_kgid(current_user_ns(), md->gid);
527 data.file_mode = md->file_mode;
528 data.dir_mode = md->dir_mode;
534 if (memcmp(raw_data, "vers", 4) == 0) {
535 error = ncp_parse_options(&data, raw_data);
542 if (!uid_valid(data.mounted_uid) || !uid_valid(data.uid) ||
543 !gid_valid(data.gid))
546 ncp_filp = fget(data.ncp_fd);
550 sock_inode = file_inode(ncp_filp);
551 if (!S_ISSOCK(sock_inode->i_mode))
553 sock = SOCKET_I(sock_inode);
557 if (sock->type == SOCK_STREAM)
558 default_bufsize = 0xF000;
560 default_bufsize = 1024;
562 sb->s_flags |= MS_NODIRATIME; /* probably even noatime */
563 sb->s_maxbytes = 0xFFFFFFFFU;
564 sb->s_blocksize = 1024; /* Eh... Is this correct? */
565 sb->s_blocksize_bits = 10;
566 sb->s_magic = NCP_SUPER_MAGIC;
567 sb->s_op = &ncp_sops;
568 sb->s_d_op = &ncp_dentry_operations;
569 sb->s_bdi = &server->bdi;
571 server = NCP_SBP(sb);
572 memset(server, 0, sizeof(*server));
574 error = bdi_setup_and_register(&server->bdi, "ncpfs", BDI_CAP_MAP_COPY);
578 server->ncp_filp = ncp_filp;
579 server->ncp_sock = sock;
581 if (data.info_fd != -1) {
582 struct socket *info_sock;
585 server->info_filp = fget(data.info_fd);
586 if (!server->info_filp)
589 sock_inode = file_inode(server->info_filp);
590 if (!S_ISSOCK(sock_inode->i_mode))
592 info_sock = SOCKET_I(sock_inode);
596 if (info_sock->type != SOCK_STREAM)
598 server->info_sock = info_sock;
601 /* server->lock = 0; */
602 mutex_init(&server->mutex);
603 server->packet = NULL;
604 /* server->buffer_size = 0; */
605 /* server->conn_status = 0; */
606 /* server->root_dentry = NULL; */
607 /* server->root_setuped = 0; */
608 mutex_init(&server->root_setup_lock);
609 #ifdef CONFIG_NCPFS_PACKET_SIGNING
610 /* server->sign_wanted = 0; */
611 /* server->sign_active = 0; */
613 init_rwsem(&server->auth_rwsem);
614 server->auth.auth_type = NCP_AUTH_NONE;
615 /* server->auth.object_name_len = 0; */
616 /* server->auth.object_name = NULL; */
617 /* server->auth.object_type = 0; */
618 /* server->priv.len = 0; */
619 /* server->priv.data = NULL; */
622 /* Although anything producing this is buggy, it happens
623 now because of PATH_MAX changes.. */
624 if (server->m.time_out < 1) {
625 server->m.time_out = 10;
626 pr_info("You need to recompile your ncpfs utils..\n");
628 server->m.time_out = server->m.time_out * HZ / 100;
629 server->m.file_mode = (server->m.file_mode & S_IRWXUGO) | S_IFREG;
630 server->m.dir_mode = (server->m.dir_mode & S_IRWXUGO) | S_IFDIR;
632 #ifdef CONFIG_NCPFS_NLS
633 /* load the default NLS charsets */
634 server->nls_vol = load_nls_default();
635 server->nls_io = load_nls_default();
636 #endif /* CONFIG_NCPFS_NLS */
638 atomic_set(&server->dentry_ttl, 0); /* no caching */
640 INIT_LIST_HEAD(&server->tx.requests);
641 mutex_init(&server->rcv.creq_mutex);
642 server->tx.creq = NULL;
643 server->rcv.creq = NULL;
645 init_timer(&server->timeout_tm);
646 #undef NCP_PACKET_SIZE
647 #define NCP_PACKET_SIZE 131072
649 server->packet_size = NCP_PACKET_SIZE;
650 server->packet = vmalloc(NCP_PACKET_SIZE);
651 if (server->packet == NULL)
653 server->txbuf = vmalloc(NCP_PACKET_SIZE);
654 if (server->txbuf == NULL)
656 server->rxbuf = vmalloc(NCP_PACKET_SIZE);
657 if (server->rxbuf == NULL)
661 server->data_ready = sock->sk->sk_data_ready;
662 server->write_space = sock->sk->sk_write_space;
663 server->error_report = sock->sk->sk_error_report;
664 sock->sk->sk_user_data = server;
665 sock->sk->sk_data_ready = ncp_tcp_data_ready;
666 sock->sk->sk_error_report = ncp_tcp_error_report;
667 if (sock->type == SOCK_STREAM) {
668 server->rcv.ptr = (unsigned char*)&server->rcv.buf;
669 server->rcv.len = 10;
670 server->rcv.state = 0;
671 INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc);
672 INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc);
673 sock->sk->sk_write_space = ncp_tcp_write_space;
675 INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc);
676 INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc);
677 server->timeout_tm.data = (unsigned long)server;
678 server->timeout_tm.function = ncpdgram_timeout_call;
680 release_sock(sock->sk);
682 ncp_lock_server(server);
683 error = ncp_connect(server);
684 ncp_unlock_server(server);
687 DPRINTK("ncp_fill_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb));
689 error = -EMSGSIZE; /* -EREMOTESIDEINCOMPATIBLE */
690 #ifdef CONFIG_NCPFS_PACKET_SIGNING
691 if (ncp_negotiate_size_and_options(server, default_bufsize,
692 NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0)
694 if (options != NCP_DEFAULT_OPTIONS)
696 if (ncp_negotiate_size_and_options(server,
699 &(server->buffer_size), &options) != 0)
705 ncp_lock_server(server);
707 server->sign_wanted = 1;
708 ncp_unlock_server(server);
711 #endif /* CONFIG_NCPFS_PACKET_SIGNING */
712 if (ncp_negotiate_buffersize(server, default_bufsize,
713 &(server->buffer_size)) != 0)
715 DPRINTK("ncpfs: bufsize = %d\n", server->buffer_size);
717 memset(&finfo, 0, sizeof(finfo));
718 finfo.i.attributes = aDIR;
719 finfo.i.dataStreamSize = 0; /* ignored */
720 finfo.i.dirEntNum = 0;
721 finfo.i.DosDirNum = 0;
722 #ifdef CONFIG_NCPFS_SMALLDOS
723 finfo.i.NSCreator = NW_NS_DOS;
725 finfo.volume = NCP_NUMBER_OF_VOLUMES;
726 /* set dates of mountpoint to Jan 1, 1986; 00:00 */
727 finfo.i.creationTime = finfo.i.modifyTime
728 = cpu_to_le16(0x0000);
729 finfo.i.creationDate = finfo.i.modifyDate
730 = finfo.i.lastAccessDate
731 = cpu_to_le16(0x0C21);
733 finfo.i.entryName[0] = '\0';
736 finfo.ino = 2; /* tradition */
738 server->name_space[finfo.volume] = NW_NS_DOS;
741 root_inode = ncp_iget(sb, &finfo);
744 DPRINTK("ncp_fill_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
745 sb->s_root = d_make_root(root_inode);
751 ncp_lock_server(server);
752 ncp_disconnect(server);
753 ncp_unlock_server(server);
755 ncp_stop_tasks(server);
756 vfree(server->rxbuf);
758 vfree(server->txbuf);
760 vfree(server->packet);
762 #ifdef CONFIG_NCPFS_NLS
763 unload_nls(server->nls_io);
764 unload_nls(server->nls_vol);
766 mutex_destroy(&server->rcv.creq_mutex);
767 mutex_destroy(&server->root_setup_lock);
768 mutex_destroy(&server->mutex);
770 if (server->info_filp)
771 fput(server->info_filp);
773 bdi_destroy(&server->bdi);
775 /* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:
777 * The previously used put_filp(ncp_filp); was bogus, since
778 * it doesn't perform proper unlocking.
782 put_pid(data.wdog_pid);
783 sb->s_fs_info = NULL;
788 static void delayed_free(struct rcu_head *p)
790 struct ncp_server *server = container_of(p, struct ncp_server, rcu);
791 #ifdef CONFIG_NCPFS_NLS
792 /* unload the NLS charsets */
793 unload_nls(server->nls_vol);
794 unload_nls(server->nls_io);
795 #endif /* CONFIG_NCPFS_NLS */
799 static void ncp_put_super(struct super_block *sb)
801 struct ncp_server *server = NCP_SBP(sb);
803 ncp_lock_server(server);
804 ncp_disconnect(server);
805 ncp_unlock_server(server);
807 ncp_stop_tasks(server);
809 mutex_destroy(&server->rcv.creq_mutex);
810 mutex_destroy(&server->root_setup_lock);
811 mutex_destroy(&server->mutex);
813 if (server->info_filp)
814 fput(server->info_filp);
815 fput(server->ncp_filp);
816 kill_pid(server->m.wdog_pid, SIGTERM, 1);
817 put_pid(server->m.wdog_pid);
819 bdi_destroy(&server->bdi);
820 kfree(server->priv.data);
821 kfree(server->auth.object_name);
822 vfree(server->rxbuf);
823 vfree(server->txbuf);
824 vfree(server->packet);
825 call_rcu(&server->rcu, delayed_free);
828 static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
832 struct ncp_inode_info* ni;
833 struct ncp_server* s;
834 struct ncp_volume_info vi;
835 struct super_block *sb = dentry->d_sb;
855 if (!s->m.mounted_vol[0]) {
859 err = ncp_dirhandle_alloc(s, ni->volNumber, ni->DosDirNum, &dh);
863 err = ncp_get_directory_info(s, dh, &vi);
864 ncp_dirhandle_free(s, dh);
868 buf->f_type = NCP_SUPER_MAGIC;
869 buf->f_bsize = vi.sectors_per_block * 512;
870 buf->f_blocks = vi.total_blocks;
871 buf->f_bfree = vi.free_blocks;
872 buf->f_bavail = vi.free_blocks;
873 buf->f_files = vi.total_dir_entries;
874 buf->f_ffree = vi.available_dir_entries;
878 /* We cannot say how much disk space is left on a mounted
879 NetWare Server, because free space is distributed over
880 volumes, and the current user might have disk quotas. So
881 free space is not that simple to determine. Our decision
882 here is to err conservatively. */
885 buf->f_type = NCP_SUPER_MAGIC;
886 buf->f_bsize = NCP_BLOCK_SIZE;
894 int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
896 struct inode *inode = dentry->d_inode;
899 struct nw_modify_dos_info info;
900 struct ncp_server *server;
904 server = NCP_SERVER(inode);
905 if (!server) /* How this could happen? */
909 if (IS_DEADDIR(dentry->d_inode))
912 /* ageing the dentry to force validation */
913 ncp_age_dentry(server, dentry);
915 result = inode_change_ok(inode, attr);
920 if ((attr->ia_valid & ATTR_UID) && !uid_eq(attr->ia_uid, server->m.uid))
923 if ((attr->ia_valid & ATTR_GID) && !gid_eq(attr->ia_gid, server->m.gid))
926 if (((attr->ia_valid & ATTR_MODE) &&
928 ~(S_IFREG | S_IFDIR | S_IRWXUGO))))
932 memset(&info, 0, sizeof(info));
935 if ((attr->ia_valid & ATTR_MODE) != 0)
937 umode_t newmode = attr->ia_mode;
939 info_mask |= DM_ATTRIBUTES;
941 if (S_ISDIR(inode->i_mode)) {
942 newmode &= server->m.dir_mode;
944 #ifdef CONFIG_NCPFS_EXTRAS
945 if (server->m.flags & NCP_MOUNT_EXTRAS) {
946 /* any non-default execute bit set */
947 if (newmode & ~server->m.file_mode & S_IXUGO)
948 info.attributes |= aSHARED | aSYSTEM;
949 /* read for group/world and not in default file_mode */
950 else if (newmode & ~server->m.file_mode & S_IRUGO)
951 info.attributes |= aSHARED;
954 newmode &= server->m.file_mode;
956 if (newmode & S_IWUGO)
957 info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
959 info.attributes |= (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
961 #ifdef CONFIG_NCPFS_NFS_NS
962 if (ncp_is_nfs_extras(server, NCP_FINFO(inode)->volNumber)) {
963 result = ncp_modify_nfs_info(server,
964 NCP_FINFO(inode)->volNumber,
965 NCP_FINFO(inode)->dirEntNum,
969 info.attributes &= ~(aSHARED | aSYSTEM);
971 /* mark partial success */
972 struct iattr tmpattr;
974 tmpattr.ia_valid = ATTR_MODE;
975 tmpattr.ia_mode = attr->ia_mode;
977 setattr_copy(inode, &tmpattr);
978 mark_inode_dirty(inode);
985 /* Do SIZE before attributes, otherwise mtime together with size does not work...
987 if ((attr->ia_valid & ATTR_SIZE) != 0) {
990 DPRINTK("ncpfs: trying to change size to %ld\n",
993 if ((result = ncp_make_open(inode, O_WRONLY)) < 0) {
997 ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
998 attr->ia_size, 0, "", &written);
1000 /* According to ndir, the changes only take effect after
1002 ncp_inode_close(inode);
1003 result = ncp_make_closed(inode);
1007 if (attr->ia_size != i_size_read(inode)) {
1008 truncate_setsize(inode, attr->ia_size);
1009 mark_inode_dirty(inode);
1012 if ((attr->ia_valid & ATTR_CTIME) != 0) {
1013 info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE);
1014 ncp_date_unix2dos(attr->ia_ctime.tv_sec,
1015 &info.creationTime, &info.creationDate);
1017 if ((attr->ia_valid & ATTR_MTIME) != 0) {
1018 info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE);
1019 ncp_date_unix2dos(attr->ia_mtime.tv_sec,
1020 &info.modifyTime, &info.modifyDate);
1022 if ((attr->ia_valid & ATTR_ATIME) != 0) {
1024 info_mask |= (DM_LAST_ACCESS_DATE);
1025 ncp_date_unix2dos(attr->ia_atime.tv_sec,
1026 &dummy, &info.lastAccessDate);
1028 if (info_mask != 0) {
1029 result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
1030 inode, info_mask, &info);
1032 if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
1033 /* NetWare seems not to allow this. I
1034 do not know why. So, just tell the
1035 user everything went fine. This is
1036 a terrible hack, but I do not know
1037 how to do this correctly. */
1042 #ifdef CONFIG_NCPFS_STRONG
1043 if ((!result) && (info_mask & DM_ATTRIBUTES))
1044 NCP_FINFO(inode)->nwattr = info.attributes;
1050 setattr_copy(inode, attr);
1051 mark_inode_dirty(inode);
1059 static struct dentry *ncp_mount(struct file_system_type *fs_type,
1060 int flags, const char *dev_name, void *data)
1062 return mount_nodev(fs_type, flags, data, ncp_fill_super);
1065 static struct file_system_type ncp_fs_type = {
1066 .owner = THIS_MODULE,
1069 .kill_sb = kill_anon_super,
1070 .fs_flags = FS_BINARY_MOUNTDATA,
1072 MODULE_ALIAS_FS("ncpfs");
1074 static int __init init_ncp_fs(void)
1077 DPRINTK("ncpfs: init_ncp_fs called\n");
1079 err = init_inodecache();
1082 err = register_filesystem(&ncp_fs_type);
1087 destroy_inodecache();
1092 static void __exit exit_ncp_fs(void)
1094 DPRINTK("ncpfs: exit_ncp_fs called\n");
1095 unregister_filesystem(&ncp_fs_type);
1096 destroy_inodecache();
1099 module_init(init_ncp_fs)
1100 module_exit(exit_ncp_fs)
1101 MODULE_LICENSE("GPL");