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/system.h>
15 #include <asm/uaccess.h>
16 #include <asm/byteorder.h>
18 #include <linux/time.h>
19 #include <linux/kernel.h>
21 #include <linux/string.h>
22 #include <linux/stat.h>
23 #include <linux/errno.h>
24 #include <linux/file.h>
25 #include <linux/fcntl.h>
26 #include <linux/slab.h>
27 #include <linux/vmalloc.h>
28 #include <linux/init.h>
29 #include <linux/smp_lock.h>
30 #include <linux/vfs.h>
31 #include <linux/mount.h>
32 #include <linux/seq_file.h>
34 #include <linux/ncp_fs.h>
38 #include "ncplib_kernel.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 vfsmount
*);
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_destroy_inode(struct inode
*inode
)
64 kmem_cache_free(ncp_inode_cachep
, NCP_FINFO(inode
));
67 static void init_once(void *foo
)
69 struct ncp_inode_info
*ei
= (struct ncp_inode_info
*) foo
;
71 mutex_init(&ei
->open_mutex
);
72 inode_init_once(&ei
->vfs_inode
);
75 static int init_inodecache(void)
77 ncp_inode_cachep
= kmem_cache_create("ncp_inode_cache",
78 sizeof(struct ncp_inode_info
),
79 0, (SLAB_RECLAIM_ACCOUNT
|
82 if (ncp_inode_cachep
== NULL
)
87 static void destroy_inodecache(void)
89 kmem_cache_destroy(ncp_inode_cachep
);
92 static int ncp_remount(struct super_block
*sb
, int *flags
, char* data
)
94 *flags
|= MS_NODIRATIME
;
98 static const struct super_operations ncp_sops
=
100 .alloc_inode
= ncp_alloc_inode
,
101 .destroy_inode
= ncp_destroy_inode
,
102 .drop_inode
= generic_delete_inode
,
103 .evict_inode
= ncp_evict_inode
,
104 .put_super
= ncp_put_super
,
105 .statfs
= ncp_statfs
,
106 .remount_fs
= ncp_remount
,
107 .show_options
= ncp_show_options
,
111 * Fill in the ncpfs-specific information in the inode.
113 static void ncp_update_dirent(struct inode
*inode
, struct ncp_entry_info
*nwinfo
)
115 NCP_FINFO(inode
)->DosDirNum
= nwinfo
->i
.DosDirNum
;
116 NCP_FINFO(inode
)->dirEntNum
= nwinfo
->i
.dirEntNum
;
117 NCP_FINFO(inode
)->volNumber
= nwinfo
->volume
;
120 void ncp_update_inode(struct inode
*inode
, struct ncp_entry_info
*nwinfo
)
122 ncp_update_dirent(inode
, nwinfo
);
123 NCP_FINFO(inode
)->nwattr
= nwinfo
->i
.attributes
;
124 NCP_FINFO(inode
)->access
= nwinfo
->access
;
125 memcpy(NCP_FINFO(inode
)->file_handle
, nwinfo
->file_handle
,
126 sizeof(nwinfo
->file_handle
));
127 DPRINTK("ncp_update_inode: updated %s, volnum=%d, dirent=%u\n",
128 nwinfo
->i
.entryName
, NCP_FINFO(inode
)->volNumber
,
129 NCP_FINFO(inode
)->dirEntNum
);
132 static void ncp_update_dates(struct inode
*inode
, struct nw_info_struct
*nwi
)
134 /* NFS namespace mode overrides others if it's set. */
135 DPRINTK(KERN_DEBUG
"ncp_update_dates_and_mode: (%s) nfs.mode=0%o\n",
136 nwi
->entryName
, nwi
->nfs
.mode
);
139 inode
->i_mode
= nwi
->nfs
.mode
;
142 inode
->i_blocks
= (i_size_read(inode
) + NCP_BLOCK_SIZE
- 1) >> NCP_BLOCK_SHIFT
;
144 inode
->i_mtime
.tv_sec
= ncp_date_dos2unix(nwi
->modifyTime
, nwi
->modifyDate
);
145 inode
->i_ctime
.tv_sec
= ncp_date_dos2unix(nwi
->creationTime
, nwi
->creationDate
);
146 inode
->i_atime
.tv_sec
= ncp_date_dos2unix(0, nwi
->lastAccessDate
);
147 inode
->i_atime
.tv_nsec
= 0;
148 inode
->i_mtime
.tv_nsec
= 0;
149 inode
->i_ctime
.tv_nsec
= 0;
152 static void ncp_update_attrs(struct inode
*inode
, struct ncp_entry_info
*nwinfo
)
154 struct nw_info_struct
*nwi
= &nwinfo
->i
;
155 struct ncp_server
*server
= NCP_SERVER(inode
);
157 if (nwi
->attributes
& aDIR
) {
158 inode
->i_mode
= server
->m
.dir_mode
;
159 /* for directories dataStreamSize seems to be some
161 i_size_write(inode
, NCP_BLOCK_SIZE
);
165 inode
->i_mode
= server
->m
.file_mode
;
166 size
= le32_to_cpu(nwi
->dataStreamSize
);
167 i_size_write(inode
, size
);
168 #ifdef CONFIG_NCPFS_EXTRAS
169 if ((server
->m
.flags
& (NCP_MOUNT_EXTRAS
|NCP_MOUNT_SYMLINKS
))
170 && (nwi
->attributes
& aSHARED
)) {
171 switch (nwi
->attributes
& (aHIDDEN
|aSYSTEM
)) {
173 if (server
->m
.flags
& NCP_MOUNT_SYMLINKS
) {
174 if (/* (size >= NCP_MIN_SYMLINK_SIZE)
175 && */ (size
<= NCP_MAX_SYMLINK_SIZE
)) {
176 inode
->i_mode
= (inode
->i_mode
& ~S_IFMT
) | S_IFLNK
;
177 NCP_FINFO(inode
)->flags
|= NCPI_KLUDGE_SYMLINK
;
183 if (server
->m
.flags
& NCP_MOUNT_EXTRAS
)
184 inode
->i_mode
|= S_IRUGO
;
187 if (server
->m
.flags
& NCP_MOUNT_EXTRAS
)
188 inode
->i_mode
|= (inode
->i_mode
>> 2) & S_IXUGO
;
190 /* case aSYSTEM|aHIDDEN: */
192 /* reserved combination */
198 if (nwi
->attributes
& aRONLY
) inode
->i_mode
&= ~S_IWUGO
;
201 void ncp_update_inode2(struct inode
* inode
, struct ncp_entry_info
*nwinfo
)
203 NCP_FINFO(inode
)->flags
= 0;
204 if (!atomic_read(&NCP_FINFO(inode
)->opened
)) {
205 NCP_FINFO(inode
)->nwattr
= nwinfo
->i
.attributes
;
206 ncp_update_attrs(inode
, nwinfo
);
209 ncp_update_dates(inode
, &nwinfo
->i
);
210 ncp_update_dirent(inode
, nwinfo
);
214 * Fill in the inode based on the ncp_entry_info structure. Used only for brand new inodes.
216 static void ncp_set_attr(struct inode
*inode
, struct ncp_entry_info
*nwinfo
)
218 struct ncp_server
*server
= NCP_SERVER(inode
);
220 NCP_FINFO(inode
)->flags
= 0;
222 ncp_update_attrs(inode
, nwinfo
);
224 DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode
->i_mode
);
227 inode
->i_uid
= server
->m
.uid
;
228 inode
->i_gid
= server
->m
.gid
;
230 ncp_update_dates(inode
, &nwinfo
->i
);
231 ncp_update_inode(inode
, nwinfo
);
234 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
235 static const struct inode_operations ncp_symlink_inode_operations
= {
236 .readlink
= generic_readlink
,
237 .follow_link
= page_follow_link_light
,
238 .put_link
= page_put_link
,
239 .setattr
= ncp_notify_change
,
247 ncp_iget(struct super_block
*sb
, struct ncp_entry_info
*info
)
252 printk(KERN_ERR
"ncp_iget: info is NULL\n");
256 inode
= new_inode(sb
);
258 atomic_set(&NCP_FINFO(inode
)->opened
, info
->opened
);
260 inode
->i_mapping
->backing_dev_info
= sb
->s_bdi
;
261 inode
->i_ino
= info
->ino
;
262 ncp_set_attr(inode
, info
);
263 if (S_ISREG(inode
->i_mode
)) {
264 inode
->i_op
= &ncp_file_inode_operations
;
265 inode
->i_fop
= &ncp_file_operations
;
266 } else if (S_ISDIR(inode
->i_mode
)) {
267 inode
->i_op
= &ncp_dir_inode_operations
;
268 inode
->i_fop
= &ncp_dir_operations
;
269 #ifdef CONFIG_NCPFS_NFS_NS
270 } else if (S_ISCHR(inode
->i_mode
) || S_ISBLK(inode
->i_mode
) || S_ISFIFO(inode
->i_mode
) || S_ISSOCK(inode
->i_mode
)) {
271 init_special_inode(inode
, inode
->i_mode
,
272 new_decode_dev(info
->i
.nfs
.rdev
));
274 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
275 } else if (S_ISLNK(inode
->i_mode
)) {
276 inode
->i_op
= &ncp_symlink_inode_operations
;
277 inode
->i_data
.a_ops
= &ncp_symlink_aops
;
280 make_bad_inode(inode
);
282 insert_inode_hash(inode
);
284 printk(KERN_ERR
"ncp_iget: iget failed!\n");
289 ncp_evict_inode(struct inode
*inode
)
291 truncate_inode_pages(&inode
->i_data
, 0);
292 end_writeback(inode
);
294 if (S_ISDIR(inode
->i_mode
)) {
295 DDPRINTK("ncp_evict_inode: put directory %ld\n", inode
->i_ino
);
298 if (ncp_make_closed(inode
) != 0) {
299 /* We can't do anything but complain. */
300 printk(KERN_ERR
"ncp_evict_inode: could not close\n");
304 static void ncp_stop_tasks(struct ncp_server
*server
) {
305 struct sock
* sk
= server
->ncp_sock
->sk
;
308 sk
->sk_error_report
= server
->error_report
;
309 sk
->sk_data_ready
= server
->data_ready
;
310 sk
->sk_write_space
= server
->write_space
;
312 del_timer_sync(&server
->timeout_tm
);
313 flush_scheduled_work();
316 static int ncp_show_options(struct seq_file
*seq
, struct vfsmount
*mnt
)
318 struct ncp_server
*server
= NCP_SBP(mnt
->mnt_sb
);
321 if (server
->m
.uid
!= 0)
322 seq_printf(seq
, ",uid=%u", server
->m
.uid
);
323 if (server
->m
.gid
!= 0)
324 seq_printf(seq
, ",gid=%u", server
->m
.gid
);
325 if (server
->m
.mounted_uid
!= 0)
326 seq_printf(seq
, ",owner=%u", server
->m
.mounted_uid
);
327 tmp
= server
->m
.file_mode
& S_IALLUGO
;
328 if (tmp
!= NCP_DEFAULT_FILE_MODE
)
329 seq_printf(seq
, ",mode=0%o", tmp
);
330 tmp
= server
->m
.dir_mode
& S_IALLUGO
;
331 if (tmp
!= NCP_DEFAULT_DIR_MODE
)
332 seq_printf(seq
, ",dirmode=0%o", tmp
);
333 if (server
->m
.time_out
!= NCP_DEFAULT_TIME_OUT
* HZ
/ 100) {
334 tmp
= server
->m
.time_out
* 100 / HZ
;
335 seq_printf(seq
, ",timeout=%u", tmp
);
337 if (server
->m
.retry_count
!= NCP_DEFAULT_RETRY_COUNT
)
338 seq_printf(seq
, ",retry=%u", server
->m
.retry_count
);
339 if (server
->m
.flags
!= 0)
340 seq_printf(seq
, ",flags=%lu", server
->m
.flags
);
341 if (server
->m
.wdog_pid
!= NULL
)
342 seq_printf(seq
, ",wdogpid=%u", pid_vnr(server
->m
.wdog_pid
));
347 static const struct ncp_option ncp_opts
[] = {
348 { "uid", OPT_INT
, 'u' },
349 { "gid", OPT_INT
, 'g' },
350 { "owner", OPT_INT
, 'o' },
351 { "mode", OPT_INT
, 'm' },
352 { "dirmode", OPT_INT
, 'd' },
353 { "timeout", OPT_INT
, 't' },
354 { "retry", OPT_INT
, 'r' },
355 { "flags", OPT_INT
, 'f' },
356 { "wdogpid", OPT_INT
, 'w' },
357 { "ncpfd", OPT_INT
, 'n' },
358 { "infofd", OPT_INT
, 'i' }, /* v5 */
359 { "version", OPT_INT
, 'v' },
362 static int ncp_parse_options(struct ncp_mount_data_kernel
*data
, char *options
) {
365 unsigned long optint
;
371 data
->mounted_uid
= 0;
372 data
->wdog_pid
= NULL
;
374 data
->time_out
= NCP_DEFAULT_TIME_OUT
;
375 data
->retry_count
= NCP_DEFAULT_RETRY_COUNT
;
378 data
->file_mode
= NCP_DEFAULT_FILE_MODE
;
379 data
->dir_mode
= NCP_DEFAULT_DIR_MODE
;
381 data
->mounted_vol
[0] = 0;
383 while ((optval
= ncp_getopt("ncpfs", &options
, ncp_opts
, NULL
, &optarg
, &optint
)) != 0) {
395 data
->mounted_uid
= optint
;
398 data
->file_mode
= optint
;
401 data
->dir_mode
= optint
;
404 data
->time_out
= optint
;
407 data
->retry_count
= optint
;
410 data
->flags
= optint
;
413 data
->wdog_pid
= find_get_pid(optint
);
416 data
->ncp_fd
= optint
;
419 data
->info_fd
= optint
;
423 if (optint
< NCP_MOUNT_VERSION_V4
)
425 if (optint
> NCP_MOUNT_VERSION_V5
)
434 put_pid(data
->wdog_pid
);
435 data
->wdog_pid
= NULL
;
439 static int ncp_fill_super(struct super_block
*sb
, void *raw_data
, int silent
)
441 struct ncp_mount_data_kernel data
;
442 struct ncp_server
*server
;
443 struct file
*ncp_filp
;
444 struct inode
*root_inode
;
445 struct inode
*sock_inode
;
449 #ifdef CONFIG_NCPFS_PACKET_SIGNING
452 struct ncp_entry_info finfo
;
454 data
.wdog_pid
= NULL
;
455 server
= kzalloc(sizeof(struct ncp_server
), GFP_KERNEL
);
458 sb
->s_fs_info
= server
;
461 if (raw_data
== NULL
)
463 switch (*(int*)raw_data
) {
464 case NCP_MOUNT_VERSION
:
466 struct ncp_mount_data
* md
= (struct ncp_mount_data
*)raw_data
;
468 data
.flags
= md
->flags
;
469 data
.int_flags
= NCP_IMOUNT_LOGGEDIN_POSSIBLE
;
470 data
.mounted_uid
= md
->mounted_uid
;
471 data
.wdog_pid
= find_get_pid(md
->wdog_pid
);
472 data
.ncp_fd
= md
->ncp_fd
;
473 data
.time_out
= md
->time_out
;
474 data
.retry_count
= md
->retry_count
;
477 data
.file_mode
= md
->file_mode
;
478 data
.dir_mode
= md
->dir_mode
;
480 memcpy(data
.mounted_vol
, md
->mounted_vol
,
484 case NCP_MOUNT_VERSION_V4
:
486 struct ncp_mount_data_v4
* md
= (struct ncp_mount_data_v4
*)raw_data
;
488 data
.flags
= md
->flags
;
490 data
.mounted_uid
= md
->mounted_uid
;
491 data
.wdog_pid
= find_get_pid(md
->wdog_pid
);
492 data
.ncp_fd
= md
->ncp_fd
;
493 data
.time_out
= md
->time_out
;
494 data
.retry_count
= md
->retry_count
;
497 data
.file_mode
= md
->file_mode
;
498 data
.dir_mode
= md
->dir_mode
;
500 data
.mounted_vol
[0] = 0;
505 if (memcmp(raw_data
, "vers", 4) == 0) {
506 error
= ncp_parse_options(&data
, raw_data
);
513 ncp_filp
= fget(data
.ncp_fd
);
517 sock_inode
= ncp_filp
->f_path
.dentry
->d_inode
;
518 if (!S_ISSOCK(sock_inode
->i_mode
))
520 sock
= SOCKET_I(sock_inode
);
524 if (sock
->type
== SOCK_STREAM
)
525 default_bufsize
= 0xF000;
527 default_bufsize
= 1024;
529 sb
->s_flags
|= MS_NODIRATIME
; /* probably even noatime */
530 sb
->s_maxbytes
= 0xFFFFFFFFU
;
531 sb
->s_blocksize
= 1024; /* Eh... Is this correct? */
532 sb
->s_blocksize_bits
= 10;
533 sb
->s_magic
= NCP_SUPER_MAGIC
;
534 sb
->s_op
= &ncp_sops
;
535 sb
->s_bdi
= &server
->bdi
;
537 server
= NCP_SBP(sb
);
538 memset(server
, 0, sizeof(*server
));
540 error
= bdi_setup_and_register(&server
->bdi
, "ncpfs", BDI_CAP_MAP_COPY
);
544 server
->ncp_filp
= ncp_filp
;
545 server
->ncp_sock
= sock
;
547 if (data
.info_fd
!= -1) {
548 struct socket
*info_sock
;
551 server
->info_filp
= fget(data
.info_fd
);
552 if (!server
->info_filp
)
555 sock_inode
= server
->info_filp
->f_path
.dentry
->d_inode
;
556 if (!S_ISSOCK(sock_inode
->i_mode
))
558 info_sock
= SOCKET_I(sock_inode
);
562 if (info_sock
->type
!= SOCK_STREAM
)
564 server
->info_sock
= info_sock
;
567 /* server->lock = 0; */
568 mutex_init(&server
->mutex
);
569 server
->packet
= NULL
;
570 /* server->buffer_size = 0; */
571 /* server->conn_status = 0; */
572 /* server->root_dentry = NULL; */
573 /* server->root_setuped = 0; */
574 mutex_init(&server
->root_setup_lock
);
575 #ifdef CONFIG_NCPFS_PACKET_SIGNING
576 /* server->sign_wanted = 0; */
577 /* server->sign_active = 0; */
579 init_rwsem(&server
->auth_rwsem
);
580 server
->auth
.auth_type
= NCP_AUTH_NONE
;
581 /* server->auth.object_name_len = 0; */
582 /* server->auth.object_name = NULL; */
583 /* server->auth.object_type = 0; */
584 /* server->priv.len = 0; */
585 /* server->priv.data = NULL; */
588 /* Althought anything producing this is buggy, it happens
589 now because of PATH_MAX changes.. */
590 if (server
->m
.time_out
< 1) {
591 server
->m
.time_out
= 10;
592 printk(KERN_INFO
"You need to recompile your ncpfs utils..\n");
594 server
->m
.time_out
= server
->m
.time_out
* HZ
/ 100;
595 server
->m
.file_mode
= (server
->m
.file_mode
& S_IRWXUGO
) | S_IFREG
;
596 server
->m
.dir_mode
= (server
->m
.dir_mode
& S_IRWXUGO
) | S_IFDIR
;
598 #ifdef CONFIG_NCPFS_NLS
599 /* load the default NLS charsets */
600 server
->nls_vol
= load_nls_default();
601 server
->nls_io
= load_nls_default();
602 #endif /* CONFIG_NCPFS_NLS */
604 atomic_set(&server
->dentry_ttl
, 0); /* no caching */
606 INIT_LIST_HEAD(&server
->tx
.requests
);
607 mutex_init(&server
->rcv
.creq_mutex
);
608 server
->tx
.creq
= NULL
;
609 server
->rcv
.creq
= NULL
;
611 init_timer(&server
->timeout_tm
);
612 #undef NCP_PACKET_SIZE
613 #define NCP_PACKET_SIZE 131072
615 server
->packet_size
= NCP_PACKET_SIZE
;
616 server
->packet
= vmalloc(NCP_PACKET_SIZE
);
617 if (server
->packet
== NULL
)
619 server
->txbuf
= vmalloc(NCP_PACKET_SIZE
);
620 if (server
->txbuf
== NULL
)
622 server
->rxbuf
= vmalloc(NCP_PACKET_SIZE
);
623 if (server
->rxbuf
== NULL
)
627 server
->data_ready
= sock
->sk
->sk_data_ready
;
628 server
->write_space
= sock
->sk
->sk_write_space
;
629 server
->error_report
= sock
->sk
->sk_error_report
;
630 sock
->sk
->sk_user_data
= server
;
631 sock
->sk
->sk_data_ready
= ncp_tcp_data_ready
;
632 sock
->sk
->sk_error_report
= ncp_tcp_error_report
;
633 if (sock
->type
== SOCK_STREAM
) {
634 server
->rcv
.ptr
= (unsigned char*)&server
->rcv
.buf
;
635 server
->rcv
.len
= 10;
636 server
->rcv
.state
= 0;
637 INIT_WORK(&server
->rcv
.tq
, ncp_tcp_rcv_proc
);
638 INIT_WORK(&server
->tx
.tq
, ncp_tcp_tx_proc
);
639 sock
->sk
->sk_write_space
= ncp_tcp_write_space
;
641 INIT_WORK(&server
->rcv
.tq
, ncpdgram_rcv_proc
);
642 INIT_WORK(&server
->timeout_tq
, ncpdgram_timeout_proc
);
643 server
->timeout_tm
.data
= (unsigned long)server
;
644 server
->timeout_tm
.function
= ncpdgram_timeout_call
;
646 release_sock(sock
->sk
);
648 ncp_lock_server(server
);
649 error
= ncp_connect(server
);
650 ncp_unlock_server(server
);
653 DPRINTK("ncp_fill_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb
));
655 error
= -EMSGSIZE
; /* -EREMOTESIDEINCOMPATIBLE */
656 #ifdef CONFIG_NCPFS_PACKET_SIGNING
657 if (ncp_negotiate_size_and_options(server
, default_bufsize
,
658 NCP_DEFAULT_OPTIONS
, &(server
->buffer_size
), &options
) == 0)
660 if (options
!= NCP_DEFAULT_OPTIONS
)
662 if (ncp_negotiate_size_and_options(server
,
665 &(server
->buffer_size
), &options
) != 0)
671 ncp_lock_server(server
);
673 server
->sign_wanted
= 1;
674 ncp_unlock_server(server
);
677 #endif /* CONFIG_NCPFS_PACKET_SIGNING */
678 if (ncp_negotiate_buffersize(server
, default_bufsize
,
679 &(server
->buffer_size
)) != 0)
681 DPRINTK("ncpfs: bufsize = %d\n", server
->buffer_size
);
683 memset(&finfo
, 0, sizeof(finfo
));
684 finfo
.i
.attributes
= aDIR
;
685 finfo
.i
.dataStreamSize
= 0; /* ignored */
686 finfo
.i
.dirEntNum
= 0;
687 finfo
.i
.DosDirNum
= 0;
688 #ifdef CONFIG_NCPFS_SMALLDOS
689 finfo
.i
.NSCreator
= NW_NS_DOS
;
691 finfo
.volume
= NCP_NUMBER_OF_VOLUMES
;
692 /* set dates of mountpoint to Jan 1, 1986; 00:00 */
693 finfo
.i
.creationTime
= finfo
.i
.modifyTime
694 = cpu_to_le16(0x0000);
695 finfo
.i
.creationDate
= finfo
.i
.modifyDate
696 = finfo
.i
.lastAccessDate
697 = cpu_to_le16(0x0C21);
699 finfo
.i
.entryName
[0] = '\0';
702 finfo
.ino
= 2; /* tradition */
704 server
->name_space
[finfo
.volume
] = NW_NS_DOS
;
707 root_inode
= ncp_iget(sb
, &finfo
);
710 DPRINTK("ncp_fill_super: root vol=%d\n", NCP_FINFO(root_inode
)->volNumber
);
711 sb
->s_root
= d_alloc_root(root_inode
);
714 sb
->s_root
->d_op
= &ncp_root_dentry_operations
;
720 ncp_lock_server(server
);
721 ncp_disconnect(server
);
722 ncp_unlock_server(server
);
724 ncp_stop_tasks(server
);
725 vfree(server
->rxbuf
);
727 vfree(server
->txbuf
);
729 vfree(server
->packet
);
731 #ifdef CONFIG_NCPFS_NLS
732 unload_nls(server
->nls_io
);
733 unload_nls(server
->nls_vol
);
735 mutex_destroy(&server
->rcv
.creq_mutex
);
736 mutex_destroy(&server
->root_setup_lock
);
737 mutex_destroy(&server
->mutex
);
739 if (server
->info_filp
)
740 fput(server
->info_filp
);
742 bdi_destroy(&server
->bdi
);
744 /* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:
746 * The previously used put_filp(ncp_filp); was bogus, since
747 * it doesn't perform proper unlocking.
751 put_pid(data
.wdog_pid
);
752 sb
->s_fs_info
= NULL
;
757 static void ncp_put_super(struct super_block
*sb
)
759 struct ncp_server
*server
= NCP_SBP(sb
);
761 ncp_lock_server(server
);
762 ncp_disconnect(server
);
763 ncp_unlock_server(server
);
765 ncp_stop_tasks(server
);
767 #ifdef CONFIG_NCPFS_NLS
768 /* unload the NLS charsets */
769 unload_nls(server
->nls_vol
);
770 unload_nls(server
->nls_io
);
771 #endif /* CONFIG_NCPFS_NLS */
772 mutex_destroy(&server
->rcv
.creq_mutex
);
773 mutex_destroy(&server
->root_setup_lock
);
774 mutex_destroy(&server
->mutex
);
776 if (server
->info_filp
)
777 fput(server
->info_filp
);
778 fput(server
->ncp_filp
);
779 kill_pid(server
->m
.wdog_pid
, SIGTERM
, 1);
780 put_pid(server
->m
.wdog_pid
);
782 bdi_destroy(&server
->bdi
);
783 kfree(server
->priv
.data
);
784 kfree(server
->auth
.object_name
);
785 vfree(server
->rxbuf
);
786 vfree(server
->txbuf
);
787 vfree(server
->packet
);
788 sb
->s_fs_info
= NULL
;
792 static int ncp_statfs(struct dentry
*dentry
, struct kstatfs
*buf
)
796 struct ncp_inode_info
* ni
;
797 struct ncp_server
* s
;
798 struct ncp_volume_info vi
;
799 struct super_block
*sb
= dentry
->d_sb
;
819 if (!s
->m
.mounted_vol
[0]) {
823 err
= ncp_dirhandle_alloc(s
, ni
->volNumber
, ni
->DosDirNum
, &dh
);
827 err
= ncp_get_directory_info(s
, dh
, &vi
);
828 ncp_dirhandle_free(s
, dh
);
832 buf
->f_type
= NCP_SUPER_MAGIC
;
833 buf
->f_bsize
= vi
.sectors_per_block
* 512;
834 buf
->f_blocks
= vi
.total_blocks
;
835 buf
->f_bfree
= vi
.free_blocks
;
836 buf
->f_bavail
= vi
.free_blocks
;
837 buf
->f_files
= vi
.total_dir_entries
;
838 buf
->f_ffree
= vi
.available_dir_entries
;
842 /* We cannot say how much disk space is left on a mounted
843 NetWare Server, because free space is distributed over
844 volumes, and the current user might have disk quotas. So
845 free space is not that simple to determine. Our decision
846 here is to err conservatively. */
849 buf
->f_type
= NCP_SUPER_MAGIC
;
850 buf
->f_bsize
= NCP_BLOCK_SIZE
;
858 int ncp_notify_change(struct dentry
*dentry
, struct iattr
*attr
)
860 struct inode
*inode
= dentry
->d_inode
;
863 struct nw_modify_dos_info info
;
864 struct ncp_server
*server
;
868 server
= NCP_SERVER(inode
);
869 if (!server
) /* How this could happen? */
872 /* ageing the dentry to force validation */
873 ncp_age_dentry(server
, dentry
);
875 result
= inode_change_ok(inode
, attr
);
880 if (((attr
->ia_valid
& ATTR_UID
) &&
881 (attr
->ia_uid
!= server
->m
.uid
)))
884 if (((attr
->ia_valid
& ATTR_GID
) &&
885 (attr
->ia_gid
!= server
->m
.gid
)))
888 if (((attr
->ia_valid
& ATTR_MODE
) &&
890 ~(S_IFREG
| S_IFDIR
| S_IRWXUGO
))))
894 memset(&info
, 0, sizeof(info
));
897 if ((attr
->ia_valid
& ATTR_MODE
) != 0)
899 umode_t newmode
= attr
->ia_mode
;
901 info_mask
|= DM_ATTRIBUTES
;
903 if (S_ISDIR(inode
->i_mode
)) {
904 newmode
&= server
->m
.dir_mode
;
906 #ifdef CONFIG_NCPFS_EXTRAS
907 if (server
->m
.flags
& NCP_MOUNT_EXTRAS
) {
908 /* any non-default execute bit set */
909 if (newmode
& ~server
->m
.file_mode
& S_IXUGO
)
910 info
.attributes
|= aSHARED
| aSYSTEM
;
911 /* read for group/world and not in default file_mode */
912 else if (newmode
& ~server
->m
.file_mode
& S_IRUGO
)
913 info
.attributes
|= aSHARED
;
916 newmode
&= server
->m
.file_mode
;
918 if (newmode
& S_IWUGO
)
919 info
.attributes
&= ~(aRONLY
|aRENAMEINHIBIT
|aDELETEINHIBIT
);
921 info
.attributes
|= (aRONLY
|aRENAMEINHIBIT
|aDELETEINHIBIT
);
923 #ifdef CONFIG_NCPFS_NFS_NS
924 if (ncp_is_nfs_extras(server
, NCP_FINFO(inode
)->volNumber
)) {
925 result
= ncp_modify_nfs_info(server
,
926 NCP_FINFO(inode
)->volNumber
,
927 NCP_FINFO(inode
)->dirEntNum
,
931 info
.attributes
&= ~(aSHARED
| aSYSTEM
);
933 /* mark partial success */
934 struct iattr tmpattr
;
936 tmpattr
.ia_valid
= ATTR_MODE
;
937 tmpattr
.ia_mode
= attr
->ia_mode
;
939 setattr_copy(inode
, &tmpattr
);
940 mark_inode_dirty(inode
);
947 /* Do SIZE before attributes, otherwise mtime together with size does not work...
949 if ((attr
->ia_valid
& ATTR_SIZE
) != 0) {
952 DPRINTK("ncpfs: trying to change size to %ld\n",
955 if ((result
= ncp_make_open(inode
, O_WRONLY
)) < 0) {
959 ncp_write_kernel(NCP_SERVER(inode
), NCP_FINFO(inode
)->file_handle
,
960 attr
->ia_size
, 0, "", &written
);
962 /* According to ndir, the changes only take effect after
964 ncp_inode_close(inode
);
965 result
= ncp_make_closed(inode
);
969 if (attr
->ia_size
!= i_size_read(inode
)) {
970 result
= vmtruncate(inode
, attr
->ia_size
);
973 mark_inode_dirty(inode
);
976 if ((attr
->ia_valid
& ATTR_CTIME
) != 0) {
977 info_mask
|= (DM_CREATE_TIME
| DM_CREATE_DATE
);
978 ncp_date_unix2dos(attr
->ia_ctime
.tv_sec
,
979 &info
.creationTime
, &info
.creationDate
);
981 if ((attr
->ia_valid
& ATTR_MTIME
) != 0) {
982 info_mask
|= (DM_MODIFY_TIME
| DM_MODIFY_DATE
);
983 ncp_date_unix2dos(attr
->ia_mtime
.tv_sec
,
984 &info
.modifyTime
, &info
.modifyDate
);
986 if ((attr
->ia_valid
& ATTR_ATIME
) != 0) {
988 info_mask
|= (DM_LAST_ACCESS_DATE
);
989 ncp_date_unix2dos(attr
->ia_atime
.tv_sec
,
990 &dummy
, &info
.lastAccessDate
);
992 if (info_mask
!= 0) {
993 result
= ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode
),
994 inode
, info_mask
, &info
);
996 if (info_mask
== (DM_CREATE_TIME
| DM_CREATE_DATE
)) {
997 /* NetWare seems not to allow this. I
998 do not know why. So, just tell the
999 user everything went fine. This is
1000 a terrible hack, but I do not know
1001 how to do this correctly. */
1006 #ifdef CONFIG_NCPFS_STRONG
1007 if ((!result
) && (info_mask
& DM_ATTRIBUTES
))
1008 NCP_FINFO(inode
)->nwattr
= info
.attributes
;
1014 setattr_copy(inode
, attr
);
1015 mark_inode_dirty(inode
);
1023 static int ncp_get_sb(struct file_system_type
*fs_type
,
1024 int flags
, const char *dev_name
, void *data
, struct vfsmount
*mnt
)
1026 return get_sb_nodev(fs_type
, flags
, data
, ncp_fill_super
, mnt
);
1029 static struct file_system_type ncp_fs_type
= {
1030 .owner
= THIS_MODULE
,
1032 .get_sb
= ncp_get_sb
,
1033 .kill_sb
= kill_anon_super
,
1034 .fs_flags
= FS_BINARY_MOUNTDATA
,
1037 static int __init
init_ncp_fs(void)
1040 DPRINTK("ncpfs: init_ncp_fs called\n");
1042 err
= init_inodecache();
1045 err
= register_filesystem(&ncp_fs_type
);
1050 destroy_inodecache();
1055 static void __exit
exit_ncp_fs(void)
1057 DPRINTK("ncpfs: exit_ncp_fs called\n");
1058 unregister_filesystem(&ncp_fs_type
);
1059 destroy_inodecache();
1062 module_init(init_ncp_fs
)
1063 module_exit(exit_ncp_fs
)
1064 MODULE_LICENSE("GPL");