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)) {
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 file *ncp_filp;
473 struct inode *root_inode;
474 struct inode *sock_inode;
478 #ifdef CONFIG_NCPFS_PACKET_SIGNING
481 struct ncp_entry_info finfo;
483 memset(&data, 0, sizeof(data));
484 server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL);
487 sb->s_fs_info = server;
490 if (raw_data == NULL)
492 switch (*(int*)raw_data) {
493 case NCP_MOUNT_VERSION:
495 struct ncp_mount_data* md = (struct ncp_mount_data*)raw_data;
497 data.flags = md->flags;
498 data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE;
499 data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid);
500 data.wdog_pid = find_get_pid(md->wdog_pid);
501 data.ncp_fd = md->ncp_fd;
502 data.time_out = md->time_out;
503 data.retry_count = md->retry_count;
504 data.uid = make_kuid(current_user_ns(), md->uid);
505 data.gid = make_kgid(current_user_ns(), md->gid);
506 data.file_mode = md->file_mode;
507 data.dir_mode = md->dir_mode;
509 memcpy(data.mounted_vol, md->mounted_vol,
513 case NCP_MOUNT_VERSION_V4:
515 struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data;
517 data.flags = md->flags;
518 data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid);
519 data.wdog_pid = find_get_pid(md->wdog_pid);
520 data.ncp_fd = md->ncp_fd;
521 data.time_out = md->time_out;
522 data.retry_count = md->retry_count;
523 data.uid = make_kuid(current_user_ns(), md->uid);
524 data.gid = make_kgid(current_user_ns(), md->gid);
525 data.file_mode = md->file_mode;
526 data.dir_mode = md->dir_mode;
532 if (memcmp(raw_data, "vers", 4) == 0) {
533 error = ncp_parse_options(&data, raw_data);
540 if (!uid_valid(data.mounted_uid) || !uid_valid(data.uid) ||
541 !gid_valid(data.gid))
544 ncp_filp = fget(data.ncp_fd);
548 sock_inode = file_inode(ncp_filp);
549 if (!S_ISSOCK(sock_inode->i_mode))
551 sock = SOCKET_I(sock_inode);
555 if (sock->type == SOCK_STREAM)
556 default_bufsize = 0xF000;
558 default_bufsize = 1024;
560 sb->s_flags |= MS_NODIRATIME; /* probably even noatime */
561 sb->s_maxbytes = 0xFFFFFFFFU;
562 sb->s_blocksize = 1024; /* Eh... Is this correct? */
563 sb->s_blocksize_bits = 10;
564 sb->s_magic = NCP_SUPER_MAGIC;
565 sb->s_op = &ncp_sops;
566 sb->s_d_op = &ncp_dentry_operations;
567 sb->s_bdi = &server->bdi;
569 server = NCP_SBP(sb);
570 memset(server, 0, sizeof(*server));
572 error = bdi_setup_and_register(&server->bdi, "ncpfs", BDI_CAP_MAP_COPY);
576 server->ncp_filp = ncp_filp;
577 server->ncp_sock = sock;
579 if (data.info_fd != -1) {
580 struct socket *info_sock;
583 server->info_filp = fget(data.info_fd);
584 if (!server->info_filp)
587 sock_inode = file_inode(server->info_filp);
588 if (!S_ISSOCK(sock_inode->i_mode))
590 info_sock = SOCKET_I(sock_inode);
594 if (info_sock->type != SOCK_STREAM)
596 server->info_sock = info_sock;
599 /* server->lock = 0; */
600 mutex_init(&server->mutex);
601 server->packet = NULL;
602 /* server->buffer_size = 0; */
603 /* server->conn_status = 0; */
604 /* server->root_dentry = NULL; */
605 /* server->root_setuped = 0; */
606 mutex_init(&server->root_setup_lock);
607 #ifdef CONFIG_NCPFS_PACKET_SIGNING
608 /* server->sign_wanted = 0; */
609 /* server->sign_active = 0; */
611 init_rwsem(&server->auth_rwsem);
612 server->auth.auth_type = NCP_AUTH_NONE;
613 /* server->auth.object_name_len = 0; */
614 /* server->auth.object_name = NULL; */
615 /* server->auth.object_type = 0; */
616 /* server->priv.len = 0; */
617 /* server->priv.data = NULL; */
620 /* Although anything producing this is buggy, it happens
621 now because of PATH_MAX changes.. */
622 if (server->m.time_out < 1) {
623 server->m.time_out = 10;
624 printk(KERN_INFO "You need to recompile your ncpfs utils..\n");
626 server->m.time_out = server->m.time_out * HZ / 100;
627 server->m.file_mode = (server->m.file_mode & S_IRWXUGO) | S_IFREG;
628 server->m.dir_mode = (server->m.dir_mode & S_IRWXUGO) | S_IFDIR;
630 #ifdef CONFIG_NCPFS_NLS
631 /* load the default NLS charsets */
632 server->nls_vol = load_nls_default();
633 server->nls_io = load_nls_default();
634 #endif /* CONFIG_NCPFS_NLS */
636 atomic_set(&server->dentry_ttl, 0); /* no caching */
638 INIT_LIST_HEAD(&server->tx.requests);
639 mutex_init(&server->rcv.creq_mutex);
640 server->tx.creq = NULL;
641 server->rcv.creq = NULL;
643 init_timer(&server->timeout_tm);
644 #undef NCP_PACKET_SIZE
645 #define NCP_PACKET_SIZE 131072
647 server->packet_size = NCP_PACKET_SIZE;
648 server->packet = vmalloc(NCP_PACKET_SIZE);
649 if (server->packet == NULL)
651 server->txbuf = vmalloc(NCP_PACKET_SIZE);
652 if (server->txbuf == NULL)
654 server->rxbuf = vmalloc(NCP_PACKET_SIZE);
655 if (server->rxbuf == NULL)
659 server->data_ready = sock->sk->sk_data_ready;
660 server->write_space = sock->sk->sk_write_space;
661 server->error_report = sock->sk->sk_error_report;
662 sock->sk->sk_user_data = server;
663 sock->sk->sk_data_ready = ncp_tcp_data_ready;
664 sock->sk->sk_error_report = ncp_tcp_error_report;
665 if (sock->type == SOCK_STREAM) {
666 server->rcv.ptr = (unsigned char*)&server->rcv.buf;
667 server->rcv.len = 10;
668 server->rcv.state = 0;
669 INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc);
670 INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc);
671 sock->sk->sk_write_space = ncp_tcp_write_space;
673 INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc);
674 INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc);
675 server->timeout_tm.data = (unsigned long)server;
676 server->timeout_tm.function = ncpdgram_timeout_call;
678 release_sock(sock->sk);
680 ncp_lock_server(server);
681 error = ncp_connect(server);
682 ncp_unlock_server(server);
685 DPRINTK("ncp_fill_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb));
687 error = -EMSGSIZE; /* -EREMOTESIDEINCOMPATIBLE */
688 #ifdef CONFIG_NCPFS_PACKET_SIGNING
689 if (ncp_negotiate_size_and_options(server, default_bufsize,
690 NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0)
692 if (options != NCP_DEFAULT_OPTIONS)
694 if (ncp_negotiate_size_and_options(server,
697 &(server->buffer_size), &options) != 0)
703 ncp_lock_server(server);
705 server->sign_wanted = 1;
706 ncp_unlock_server(server);
709 #endif /* CONFIG_NCPFS_PACKET_SIGNING */
710 if (ncp_negotiate_buffersize(server, default_bufsize,
711 &(server->buffer_size)) != 0)
713 DPRINTK("ncpfs: bufsize = %d\n", server->buffer_size);
715 memset(&finfo, 0, sizeof(finfo));
716 finfo.i.attributes = aDIR;
717 finfo.i.dataStreamSize = 0; /* ignored */
718 finfo.i.dirEntNum = 0;
719 finfo.i.DosDirNum = 0;
720 #ifdef CONFIG_NCPFS_SMALLDOS
721 finfo.i.NSCreator = NW_NS_DOS;
723 finfo.volume = NCP_NUMBER_OF_VOLUMES;
724 /* set dates of mountpoint to Jan 1, 1986; 00:00 */
725 finfo.i.creationTime = finfo.i.modifyTime
726 = cpu_to_le16(0x0000);
727 finfo.i.creationDate = finfo.i.modifyDate
728 = finfo.i.lastAccessDate
729 = cpu_to_le16(0x0C21);
731 finfo.i.entryName[0] = '\0';
734 finfo.ino = 2; /* tradition */
736 server->name_space[finfo.volume] = NW_NS_DOS;
739 root_inode = ncp_iget(sb, &finfo);
742 DPRINTK("ncp_fill_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
743 sb->s_root = d_make_root(root_inode);
749 ncp_lock_server(server);
750 ncp_disconnect(server);
751 ncp_unlock_server(server);
753 ncp_stop_tasks(server);
754 vfree(server->rxbuf);
756 vfree(server->txbuf);
758 vfree(server->packet);
760 #ifdef CONFIG_NCPFS_NLS
761 unload_nls(server->nls_io);
762 unload_nls(server->nls_vol);
764 mutex_destroy(&server->rcv.creq_mutex);
765 mutex_destroy(&server->root_setup_lock);
766 mutex_destroy(&server->mutex);
768 if (server->info_filp)
769 fput(server->info_filp);
771 bdi_destroy(&server->bdi);
773 /* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:
775 * The previously used put_filp(ncp_filp); was bogus, since
776 * it doesn't perform proper unlocking.
780 put_pid(data.wdog_pid);
781 sb->s_fs_info = NULL;
786 static void delayed_free(struct rcu_head *p)
788 struct ncp_server *server = container_of(p, struct ncp_server, rcu);
789 #ifdef CONFIG_NCPFS_NLS
790 /* unload the NLS charsets */
791 unload_nls(server->nls_vol);
792 unload_nls(server->nls_io);
793 #endif /* CONFIG_NCPFS_NLS */
797 static void ncp_put_super(struct super_block *sb)
799 struct ncp_server *server = NCP_SBP(sb);
801 ncp_lock_server(server);
802 ncp_disconnect(server);
803 ncp_unlock_server(server);
805 ncp_stop_tasks(server);
807 mutex_destroy(&server->rcv.creq_mutex);
808 mutex_destroy(&server->root_setup_lock);
809 mutex_destroy(&server->mutex);
811 if (server->info_filp)
812 fput(server->info_filp);
813 fput(server->ncp_filp);
814 kill_pid(server->m.wdog_pid, SIGTERM, 1);
815 put_pid(server->m.wdog_pid);
817 bdi_destroy(&server->bdi);
818 kfree(server->priv.data);
819 kfree(server->auth.object_name);
820 vfree(server->rxbuf);
821 vfree(server->txbuf);
822 vfree(server->packet);
823 call_rcu(&server->rcu, delayed_free);
826 static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
830 struct ncp_inode_info* ni;
831 struct ncp_server* s;
832 struct ncp_volume_info vi;
833 struct super_block *sb = dentry->d_sb;
853 if (!s->m.mounted_vol[0]) {
857 err = ncp_dirhandle_alloc(s, ni->volNumber, ni->DosDirNum, &dh);
861 err = ncp_get_directory_info(s, dh, &vi);
862 ncp_dirhandle_free(s, dh);
866 buf->f_type = NCP_SUPER_MAGIC;
867 buf->f_bsize = vi.sectors_per_block * 512;
868 buf->f_blocks = vi.total_blocks;
869 buf->f_bfree = vi.free_blocks;
870 buf->f_bavail = vi.free_blocks;
871 buf->f_files = vi.total_dir_entries;
872 buf->f_ffree = vi.available_dir_entries;
876 /* We cannot say how much disk space is left on a mounted
877 NetWare Server, because free space is distributed over
878 volumes, and the current user might have disk quotas. So
879 free space is not that simple to determine. Our decision
880 here is to err conservatively. */
883 buf->f_type = NCP_SUPER_MAGIC;
884 buf->f_bsize = NCP_BLOCK_SIZE;
892 int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
894 struct inode *inode = dentry->d_inode;
897 struct nw_modify_dos_info info;
898 struct ncp_server *server;
902 server = NCP_SERVER(inode);
903 if (!server) /* How this could happen? */
907 if (IS_DEADDIR(dentry->d_inode))
910 /* ageing the dentry to force validation */
911 ncp_age_dentry(server, dentry);
913 result = inode_change_ok(inode, attr);
918 if ((attr->ia_valid & ATTR_UID) && !uid_eq(attr->ia_uid, server->m.uid))
921 if ((attr->ia_valid & ATTR_GID) && !gid_eq(attr->ia_gid, server->m.gid))
924 if (((attr->ia_valid & ATTR_MODE) &&
926 ~(S_IFREG | S_IFDIR | S_IRWXUGO))))
930 memset(&info, 0, sizeof(info));
933 if ((attr->ia_valid & ATTR_MODE) != 0)
935 umode_t newmode = attr->ia_mode;
937 info_mask |= DM_ATTRIBUTES;
939 if (S_ISDIR(inode->i_mode)) {
940 newmode &= server->m.dir_mode;
942 #ifdef CONFIG_NCPFS_EXTRAS
943 if (server->m.flags & NCP_MOUNT_EXTRAS) {
944 /* any non-default execute bit set */
945 if (newmode & ~server->m.file_mode & S_IXUGO)
946 info.attributes |= aSHARED | aSYSTEM;
947 /* read for group/world and not in default file_mode */
948 else if (newmode & ~server->m.file_mode & S_IRUGO)
949 info.attributes |= aSHARED;
952 newmode &= server->m.file_mode;
954 if (newmode & S_IWUGO)
955 info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
957 info.attributes |= (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
959 #ifdef CONFIG_NCPFS_NFS_NS
960 if (ncp_is_nfs_extras(server, NCP_FINFO(inode)->volNumber)) {
961 result = ncp_modify_nfs_info(server,
962 NCP_FINFO(inode)->volNumber,
963 NCP_FINFO(inode)->dirEntNum,
967 info.attributes &= ~(aSHARED | aSYSTEM);
969 /* mark partial success */
970 struct iattr tmpattr;
972 tmpattr.ia_valid = ATTR_MODE;
973 tmpattr.ia_mode = attr->ia_mode;
975 setattr_copy(inode, &tmpattr);
976 mark_inode_dirty(inode);
983 /* Do SIZE before attributes, otherwise mtime together with size does not work...
985 if ((attr->ia_valid & ATTR_SIZE) != 0) {
988 DPRINTK("ncpfs: trying to change size to %ld\n",
991 if ((result = ncp_make_open(inode, O_WRONLY)) < 0) {
995 ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
996 attr->ia_size, 0, "", &written);
998 /* According to ndir, the changes only take effect after
1000 ncp_inode_close(inode);
1001 result = ncp_make_closed(inode);
1005 if (attr->ia_size != i_size_read(inode)) {
1006 truncate_setsize(inode, attr->ia_size);
1007 mark_inode_dirty(inode);
1010 if ((attr->ia_valid & ATTR_CTIME) != 0) {
1011 info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE);
1012 ncp_date_unix2dos(attr->ia_ctime.tv_sec,
1013 &info.creationTime, &info.creationDate);
1015 if ((attr->ia_valid & ATTR_MTIME) != 0) {
1016 info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE);
1017 ncp_date_unix2dos(attr->ia_mtime.tv_sec,
1018 &info.modifyTime, &info.modifyDate);
1020 if ((attr->ia_valid & ATTR_ATIME) != 0) {
1022 info_mask |= (DM_LAST_ACCESS_DATE);
1023 ncp_date_unix2dos(attr->ia_atime.tv_sec,
1024 &dummy, &info.lastAccessDate);
1026 if (info_mask != 0) {
1027 result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
1028 inode, info_mask, &info);
1030 if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
1031 /* NetWare seems not to allow this. I
1032 do not know why. So, just tell the
1033 user everything went fine. This is
1034 a terrible hack, but I do not know
1035 how to do this correctly. */
1040 #ifdef CONFIG_NCPFS_STRONG
1041 if ((!result) && (info_mask & DM_ATTRIBUTES))
1042 NCP_FINFO(inode)->nwattr = info.attributes;
1048 setattr_copy(inode, attr);
1049 mark_inode_dirty(inode);
1057 static struct dentry *ncp_mount(struct file_system_type *fs_type,
1058 int flags, const char *dev_name, void *data)
1060 return mount_nodev(fs_type, flags, data, ncp_fill_super);
1063 static struct file_system_type ncp_fs_type = {
1064 .owner = THIS_MODULE,
1067 .kill_sb = kill_anon_super,
1068 .fs_flags = FS_BINARY_MOUNTDATA,
1070 MODULE_ALIAS_FS("ncpfs");
1072 static int __init init_ncp_fs(void)
1075 DPRINTK("ncpfs: init_ncp_fs called\n");
1077 err = init_inodecache();
1080 err = register_filesystem(&ncp_fs_type);
1085 destroy_inodecache();
1090 static void __exit exit_ncp_fs(void)
1092 DPRINTK("ncpfs: exit_ncp_fs called\n");
1093 unregister_filesystem(&ncp_fs_type);
1094 destroy_inodecache();
1097 module_init(init_ncp_fs)
1098 module_exit(exit_ncp_fs)
1099 MODULE_LICENSE("GPL");