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/vfs.h>
30 #include <linux/mount.h>
31 #include <linux/seq_file.h>
32 #include <linux/namei.h>
39 #define NCP_DEFAULT_FILE_MODE 0600
40 #define NCP_DEFAULT_DIR_MODE 0700
41 #define NCP_DEFAULT_TIME_OUT 10
42 #define NCP_DEFAULT_RETRY_COUNT 20
44 static void ncp_evict_inode(struct inode
*);
45 static void ncp_put_super(struct super_block
*);
46 static int ncp_statfs(struct dentry
*, struct kstatfs
*);
47 static int ncp_show_options(struct seq_file
*, struct vfsmount
*);
49 static struct kmem_cache
* ncp_inode_cachep
;
51 static struct inode
*ncp_alloc_inode(struct super_block
*sb
)
53 struct ncp_inode_info
*ei
;
54 ei
= (struct ncp_inode_info
*)kmem_cache_alloc(ncp_inode_cachep
, GFP_KERNEL
);
57 return &ei
->vfs_inode
;
60 static void ncp_i_callback(struct rcu_head
*head
)
62 struct inode
*inode
= container_of(head
, struct inode
, i_rcu
);
63 INIT_LIST_HEAD(&inode
->i_dentry
);
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)
94 kmem_cache_destroy(ncp_inode_cachep
);
97 static int ncp_remount(struct super_block
*sb
, int *flags
, char* data
)
99 *flags
|= MS_NODIRATIME
;
103 static const struct super_operations ncp_sops
=
105 .alloc_inode
= ncp_alloc_inode
,
106 .destroy_inode
= ncp_destroy_inode
,
107 .drop_inode
= generic_delete_inode
,
108 .evict_inode
= ncp_evict_inode
,
109 .put_super
= ncp_put_super
,
110 .statfs
= ncp_statfs
,
111 .remount_fs
= ncp_remount
,
112 .show_options
= ncp_show_options
,
116 * Fill in the ncpfs-specific information in the inode.
118 static void ncp_update_dirent(struct inode
*inode
, struct ncp_entry_info
*nwinfo
)
120 NCP_FINFO(inode
)->DosDirNum
= nwinfo
->i
.DosDirNum
;
121 NCP_FINFO(inode
)->dirEntNum
= nwinfo
->i
.dirEntNum
;
122 NCP_FINFO(inode
)->volNumber
= nwinfo
->volume
;
125 void ncp_update_inode(struct inode
*inode
, struct ncp_entry_info
*nwinfo
)
127 ncp_update_dirent(inode
, nwinfo
);
128 NCP_FINFO(inode
)->nwattr
= nwinfo
->i
.attributes
;
129 NCP_FINFO(inode
)->access
= nwinfo
->access
;
130 memcpy(NCP_FINFO(inode
)->file_handle
, nwinfo
->file_handle
,
131 sizeof(nwinfo
->file_handle
));
132 DPRINTK("ncp_update_inode: updated %s, volnum=%d, dirent=%u\n",
133 nwinfo
->i
.entryName
, NCP_FINFO(inode
)->volNumber
,
134 NCP_FINFO(inode
)->dirEntNum
);
137 static void ncp_update_dates(struct inode
*inode
, struct nw_info_struct
*nwi
)
139 /* NFS namespace mode overrides others if it's set. */
140 DPRINTK(KERN_DEBUG
"ncp_update_dates_and_mode: (%s) nfs.mode=0%o\n",
141 nwi
->entryName
, nwi
->nfs
.mode
);
144 inode
->i_mode
= nwi
->nfs
.mode
;
147 inode
->i_blocks
= (i_size_read(inode
) + NCP_BLOCK_SIZE
- 1) >> NCP_BLOCK_SHIFT
;
149 inode
->i_mtime
.tv_sec
= ncp_date_dos2unix(nwi
->modifyTime
, nwi
->modifyDate
);
150 inode
->i_ctime
.tv_sec
= ncp_date_dos2unix(nwi
->creationTime
, nwi
->creationDate
);
151 inode
->i_atime
.tv_sec
= ncp_date_dos2unix(0, nwi
->lastAccessDate
);
152 inode
->i_atime
.tv_nsec
= 0;
153 inode
->i_mtime
.tv_nsec
= 0;
154 inode
->i_ctime
.tv_nsec
= 0;
157 static void ncp_update_attrs(struct inode
*inode
, struct ncp_entry_info
*nwinfo
)
159 struct nw_info_struct
*nwi
= &nwinfo
->i
;
160 struct ncp_server
*server
= NCP_SERVER(inode
);
162 if (nwi
->attributes
& aDIR
) {
163 inode
->i_mode
= server
->m
.dir_mode
;
164 /* for directories dataStreamSize seems to be some
166 i_size_write(inode
, NCP_BLOCK_SIZE
);
170 inode
->i_mode
= server
->m
.file_mode
;
171 size
= le32_to_cpu(nwi
->dataStreamSize
);
172 i_size_write(inode
, size
);
173 #ifdef CONFIG_NCPFS_EXTRAS
174 if ((server
->m
.flags
& (NCP_MOUNT_EXTRAS
|NCP_MOUNT_SYMLINKS
))
175 && (nwi
->attributes
& aSHARED
)) {
176 switch (nwi
->attributes
& (aHIDDEN
|aSYSTEM
)) {
178 if (server
->m
.flags
& NCP_MOUNT_SYMLINKS
) {
179 if (/* (size >= NCP_MIN_SYMLINK_SIZE)
180 && */ (size
<= NCP_MAX_SYMLINK_SIZE
)) {
181 inode
->i_mode
= (inode
->i_mode
& ~S_IFMT
) | S_IFLNK
;
182 NCP_FINFO(inode
)->flags
|= NCPI_KLUDGE_SYMLINK
;
188 if (server
->m
.flags
& NCP_MOUNT_EXTRAS
)
189 inode
->i_mode
|= S_IRUGO
;
192 if (server
->m
.flags
& NCP_MOUNT_EXTRAS
)
193 inode
->i_mode
|= (inode
->i_mode
>> 2) & S_IXUGO
;
195 /* case aSYSTEM|aHIDDEN: */
197 /* reserved combination */
203 if (nwi
->attributes
& aRONLY
) inode
->i_mode
&= ~S_IWUGO
;
206 void ncp_update_inode2(struct inode
* inode
, struct ncp_entry_info
*nwinfo
)
208 NCP_FINFO(inode
)->flags
= 0;
209 if (!atomic_read(&NCP_FINFO(inode
)->opened
)) {
210 NCP_FINFO(inode
)->nwattr
= nwinfo
->i
.attributes
;
211 ncp_update_attrs(inode
, nwinfo
);
214 ncp_update_dates(inode
, &nwinfo
->i
);
215 ncp_update_dirent(inode
, nwinfo
);
219 * Fill in the inode based on the ncp_entry_info structure. Used only for brand new inodes.
221 static void ncp_set_attr(struct inode
*inode
, struct ncp_entry_info
*nwinfo
)
223 struct ncp_server
*server
= NCP_SERVER(inode
);
225 NCP_FINFO(inode
)->flags
= 0;
227 ncp_update_attrs(inode
, nwinfo
);
229 DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode
->i_mode
);
232 inode
->i_uid
= server
->m
.uid
;
233 inode
->i_gid
= server
->m
.gid
;
235 ncp_update_dates(inode
, &nwinfo
->i
);
236 ncp_update_inode(inode
, nwinfo
);
239 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
240 static const struct inode_operations ncp_symlink_inode_operations
= {
241 .readlink
= generic_readlink
,
242 .follow_link
= page_follow_link_light
,
243 .put_link
= page_put_link
,
244 .setattr
= ncp_notify_change
,
252 ncp_iget(struct super_block
*sb
, struct ncp_entry_info
*info
)
257 printk(KERN_ERR
"ncp_iget: info is NULL\n");
261 inode
= new_inode(sb
);
263 atomic_set(&NCP_FINFO(inode
)->opened
, info
->opened
);
265 inode
->i_mapping
->backing_dev_info
= sb
->s_bdi
;
266 inode
->i_ino
= info
->ino
;
267 ncp_set_attr(inode
, info
);
268 if (S_ISREG(inode
->i_mode
)) {
269 inode
->i_op
= &ncp_file_inode_operations
;
270 inode
->i_fop
= &ncp_file_operations
;
271 } else if (S_ISDIR(inode
->i_mode
)) {
272 inode
->i_op
= &ncp_dir_inode_operations
;
273 inode
->i_fop
= &ncp_dir_operations
;
274 #ifdef CONFIG_NCPFS_NFS_NS
275 } else if (S_ISCHR(inode
->i_mode
) || S_ISBLK(inode
->i_mode
) || S_ISFIFO(inode
->i_mode
) || S_ISSOCK(inode
->i_mode
)) {
276 init_special_inode(inode
, inode
->i_mode
,
277 new_decode_dev(info
->i
.nfs
.rdev
));
279 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
280 } else if (S_ISLNK(inode
->i_mode
)) {
281 inode
->i_op
= &ncp_symlink_inode_operations
;
282 inode
->i_data
.a_ops
= &ncp_symlink_aops
;
285 make_bad_inode(inode
);
287 insert_inode_hash(inode
);
289 printk(KERN_ERR
"ncp_iget: iget failed!\n");
294 ncp_evict_inode(struct inode
*inode
)
296 truncate_inode_pages(&inode
->i_data
, 0);
297 end_writeback(inode
);
299 if (S_ISDIR(inode
->i_mode
)) {
300 DDPRINTK("ncp_evict_inode: put directory %ld\n", inode
->i_ino
);
303 if (ncp_make_closed(inode
) != 0) {
304 /* We can't do anything but complain. */
305 printk(KERN_ERR
"ncp_evict_inode: could not close\n");
309 static void ncp_stop_tasks(struct ncp_server
*server
) {
310 struct sock
* sk
= server
->ncp_sock
->sk
;
313 sk
->sk_error_report
= server
->error_report
;
314 sk
->sk_data_ready
= server
->data_ready
;
315 sk
->sk_write_space
= server
->write_space
;
317 del_timer_sync(&server
->timeout_tm
);
319 flush_work_sync(&server
->rcv
.tq
);
320 if (sk
->sk_socket
->type
== SOCK_STREAM
)
321 flush_work_sync(&server
->tx
.tq
);
323 flush_work_sync(&server
->timeout_tq
);
326 static int ncp_show_options(struct seq_file
*seq
, struct vfsmount
*mnt
)
328 struct ncp_server
*server
= NCP_SBP(mnt
->mnt_sb
);
331 if (server
->m
.uid
!= 0)
332 seq_printf(seq
, ",uid=%u", server
->m
.uid
);
333 if (server
->m
.gid
!= 0)
334 seq_printf(seq
, ",gid=%u", server
->m
.gid
);
335 if (server
->m
.mounted_uid
!= 0)
336 seq_printf(seq
, ",owner=%u", server
->m
.mounted_uid
);
337 tmp
= server
->m
.file_mode
& S_IALLUGO
;
338 if (tmp
!= NCP_DEFAULT_FILE_MODE
)
339 seq_printf(seq
, ",mode=0%o", tmp
);
340 tmp
= server
->m
.dir_mode
& S_IALLUGO
;
341 if (tmp
!= NCP_DEFAULT_DIR_MODE
)
342 seq_printf(seq
, ",dirmode=0%o", tmp
);
343 if (server
->m
.time_out
!= NCP_DEFAULT_TIME_OUT
* HZ
/ 100) {
344 tmp
= server
->m
.time_out
* 100 / HZ
;
345 seq_printf(seq
, ",timeout=%u", tmp
);
347 if (server
->m
.retry_count
!= NCP_DEFAULT_RETRY_COUNT
)
348 seq_printf(seq
, ",retry=%u", server
->m
.retry_count
);
349 if (server
->m
.flags
!= 0)
350 seq_printf(seq
, ",flags=%lu", server
->m
.flags
);
351 if (server
->m
.wdog_pid
!= NULL
)
352 seq_printf(seq
, ",wdogpid=%u", pid_vnr(server
->m
.wdog_pid
));
357 static const struct ncp_option ncp_opts
[] = {
358 { "uid", OPT_INT
, 'u' },
359 { "gid", OPT_INT
, 'g' },
360 { "owner", OPT_INT
, 'o' },
361 { "mode", OPT_INT
, 'm' },
362 { "dirmode", OPT_INT
, 'd' },
363 { "timeout", OPT_INT
, 't' },
364 { "retry", OPT_INT
, 'r' },
365 { "flags", OPT_INT
, 'f' },
366 { "wdogpid", OPT_INT
, 'w' },
367 { "ncpfd", OPT_INT
, 'n' },
368 { "infofd", OPT_INT
, 'i' }, /* v5 */
369 { "version", OPT_INT
, 'v' },
372 static int ncp_parse_options(struct ncp_mount_data_kernel
*data
, char *options
) {
375 unsigned long optint
;
381 data
->mounted_uid
= 0;
382 data
->wdog_pid
= NULL
;
384 data
->time_out
= NCP_DEFAULT_TIME_OUT
;
385 data
->retry_count
= NCP_DEFAULT_RETRY_COUNT
;
388 data
->file_mode
= NCP_DEFAULT_FILE_MODE
;
389 data
->dir_mode
= NCP_DEFAULT_DIR_MODE
;
391 data
->mounted_vol
[0] = 0;
393 while ((optval
= ncp_getopt("ncpfs", &options
, ncp_opts
, NULL
, &optarg
, &optint
)) != 0) {
405 data
->mounted_uid
= optint
;
408 data
->file_mode
= optint
;
411 data
->dir_mode
= optint
;
414 data
->time_out
= optint
;
417 data
->retry_count
= optint
;
420 data
->flags
= optint
;
423 data
->wdog_pid
= find_get_pid(optint
);
426 data
->ncp_fd
= optint
;
429 data
->info_fd
= optint
;
433 if (optint
< NCP_MOUNT_VERSION_V4
)
435 if (optint
> NCP_MOUNT_VERSION_V5
)
444 put_pid(data
->wdog_pid
);
445 data
->wdog_pid
= NULL
;
449 static int ncp_fill_super(struct super_block
*sb
, void *raw_data
, int silent
)
451 struct ncp_mount_data_kernel data
;
452 struct ncp_server
*server
;
453 struct file
*ncp_filp
;
454 struct inode
*root_inode
;
455 struct inode
*sock_inode
;
459 #ifdef CONFIG_NCPFS_PACKET_SIGNING
462 struct ncp_entry_info finfo
;
464 data
.wdog_pid
= NULL
;
465 server
= kzalloc(sizeof(struct ncp_server
), GFP_KERNEL
);
468 sb
->s_fs_info
= server
;
471 if (raw_data
== NULL
)
473 switch (*(int*)raw_data
) {
474 case NCP_MOUNT_VERSION
:
476 struct ncp_mount_data
* md
= (struct ncp_mount_data
*)raw_data
;
478 data
.flags
= md
->flags
;
479 data
.int_flags
= NCP_IMOUNT_LOGGEDIN_POSSIBLE
;
480 data
.mounted_uid
= md
->mounted_uid
;
481 data
.wdog_pid
= find_get_pid(md
->wdog_pid
);
482 data
.ncp_fd
= md
->ncp_fd
;
483 data
.time_out
= md
->time_out
;
484 data
.retry_count
= md
->retry_count
;
487 data
.file_mode
= md
->file_mode
;
488 data
.dir_mode
= md
->dir_mode
;
490 memcpy(data
.mounted_vol
, md
->mounted_vol
,
494 case NCP_MOUNT_VERSION_V4
:
496 struct ncp_mount_data_v4
* md
= (struct ncp_mount_data_v4
*)raw_data
;
498 data
.flags
= md
->flags
;
500 data
.mounted_uid
= md
->mounted_uid
;
501 data
.wdog_pid
= find_get_pid(md
->wdog_pid
);
502 data
.ncp_fd
= md
->ncp_fd
;
503 data
.time_out
= md
->time_out
;
504 data
.retry_count
= md
->retry_count
;
507 data
.file_mode
= md
->file_mode
;
508 data
.dir_mode
= md
->dir_mode
;
510 data
.mounted_vol
[0] = 0;
515 if (memcmp(raw_data
, "vers", 4) == 0) {
516 error
= ncp_parse_options(&data
, raw_data
);
523 ncp_filp
= fget(data
.ncp_fd
);
527 sock_inode
= ncp_filp
->f_path
.dentry
->d_inode
;
528 if (!S_ISSOCK(sock_inode
->i_mode
))
530 sock
= SOCKET_I(sock_inode
);
534 if (sock
->type
== SOCK_STREAM
)
535 default_bufsize
= 0xF000;
537 default_bufsize
= 1024;
539 sb
->s_flags
|= MS_NODIRATIME
; /* probably even noatime */
540 sb
->s_maxbytes
= 0xFFFFFFFFU
;
541 sb
->s_blocksize
= 1024; /* Eh... Is this correct? */
542 sb
->s_blocksize_bits
= 10;
543 sb
->s_magic
= NCP_SUPER_MAGIC
;
544 sb
->s_op
= &ncp_sops
;
545 sb
->s_d_op
= &ncp_dentry_operations
;
546 sb
->s_bdi
= &server
->bdi
;
548 server
= NCP_SBP(sb
);
549 memset(server
, 0, sizeof(*server
));
551 error
= bdi_setup_and_register(&server
->bdi
, "ncpfs", BDI_CAP_MAP_COPY
);
555 server
->ncp_filp
= ncp_filp
;
556 server
->ncp_sock
= sock
;
558 if (data
.info_fd
!= -1) {
559 struct socket
*info_sock
;
562 server
->info_filp
= fget(data
.info_fd
);
563 if (!server
->info_filp
)
566 sock_inode
= server
->info_filp
->f_path
.dentry
->d_inode
;
567 if (!S_ISSOCK(sock_inode
->i_mode
))
569 info_sock
= SOCKET_I(sock_inode
);
573 if (info_sock
->type
!= SOCK_STREAM
)
575 server
->info_sock
= info_sock
;
578 /* server->lock = 0; */
579 mutex_init(&server
->mutex
);
580 server
->packet
= NULL
;
581 /* server->buffer_size = 0; */
582 /* server->conn_status = 0; */
583 /* server->root_dentry = NULL; */
584 /* server->root_setuped = 0; */
585 mutex_init(&server
->root_setup_lock
);
586 #ifdef CONFIG_NCPFS_PACKET_SIGNING
587 /* server->sign_wanted = 0; */
588 /* server->sign_active = 0; */
590 init_rwsem(&server
->auth_rwsem
);
591 server
->auth
.auth_type
= NCP_AUTH_NONE
;
592 /* server->auth.object_name_len = 0; */
593 /* server->auth.object_name = NULL; */
594 /* server->auth.object_type = 0; */
595 /* server->priv.len = 0; */
596 /* server->priv.data = NULL; */
599 /* Although anything producing this is buggy, it happens
600 now because of PATH_MAX changes.. */
601 if (server
->m
.time_out
< 1) {
602 server
->m
.time_out
= 10;
603 printk(KERN_INFO
"You need to recompile your ncpfs utils..\n");
605 server
->m
.time_out
= server
->m
.time_out
* HZ
/ 100;
606 server
->m
.file_mode
= (server
->m
.file_mode
& S_IRWXUGO
) | S_IFREG
;
607 server
->m
.dir_mode
= (server
->m
.dir_mode
& S_IRWXUGO
) | S_IFDIR
;
609 #ifdef CONFIG_NCPFS_NLS
610 /* load the default NLS charsets */
611 server
->nls_vol
= load_nls_default();
612 server
->nls_io
= load_nls_default();
613 #endif /* CONFIG_NCPFS_NLS */
615 atomic_set(&server
->dentry_ttl
, 0); /* no caching */
617 INIT_LIST_HEAD(&server
->tx
.requests
);
618 mutex_init(&server
->rcv
.creq_mutex
);
619 server
->tx
.creq
= NULL
;
620 server
->rcv
.creq
= NULL
;
622 init_timer(&server
->timeout_tm
);
623 #undef NCP_PACKET_SIZE
624 #define NCP_PACKET_SIZE 131072
626 server
->packet_size
= NCP_PACKET_SIZE
;
627 server
->packet
= vmalloc(NCP_PACKET_SIZE
);
628 if (server
->packet
== NULL
)
630 server
->txbuf
= vmalloc(NCP_PACKET_SIZE
);
631 if (server
->txbuf
== NULL
)
633 server
->rxbuf
= vmalloc(NCP_PACKET_SIZE
);
634 if (server
->rxbuf
== NULL
)
638 server
->data_ready
= sock
->sk
->sk_data_ready
;
639 server
->write_space
= sock
->sk
->sk_write_space
;
640 server
->error_report
= sock
->sk
->sk_error_report
;
641 sock
->sk
->sk_user_data
= server
;
642 sock
->sk
->sk_data_ready
= ncp_tcp_data_ready
;
643 sock
->sk
->sk_error_report
= ncp_tcp_error_report
;
644 if (sock
->type
== SOCK_STREAM
) {
645 server
->rcv
.ptr
= (unsigned char*)&server
->rcv
.buf
;
646 server
->rcv
.len
= 10;
647 server
->rcv
.state
= 0;
648 INIT_WORK(&server
->rcv
.tq
, ncp_tcp_rcv_proc
);
649 INIT_WORK(&server
->tx
.tq
, ncp_tcp_tx_proc
);
650 sock
->sk
->sk_write_space
= ncp_tcp_write_space
;
652 INIT_WORK(&server
->rcv
.tq
, ncpdgram_rcv_proc
);
653 INIT_WORK(&server
->timeout_tq
, ncpdgram_timeout_proc
);
654 server
->timeout_tm
.data
= (unsigned long)server
;
655 server
->timeout_tm
.function
= ncpdgram_timeout_call
;
657 release_sock(sock
->sk
);
659 ncp_lock_server(server
);
660 error
= ncp_connect(server
);
661 ncp_unlock_server(server
);
664 DPRINTK("ncp_fill_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb
));
666 error
= -EMSGSIZE
; /* -EREMOTESIDEINCOMPATIBLE */
667 #ifdef CONFIG_NCPFS_PACKET_SIGNING
668 if (ncp_negotiate_size_and_options(server
, default_bufsize
,
669 NCP_DEFAULT_OPTIONS
, &(server
->buffer_size
), &options
) == 0)
671 if (options
!= NCP_DEFAULT_OPTIONS
)
673 if (ncp_negotiate_size_and_options(server
,
676 &(server
->buffer_size
), &options
) != 0)
682 ncp_lock_server(server
);
684 server
->sign_wanted
= 1;
685 ncp_unlock_server(server
);
688 #endif /* CONFIG_NCPFS_PACKET_SIGNING */
689 if (ncp_negotiate_buffersize(server
, default_bufsize
,
690 &(server
->buffer_size
)) != 0)
692 DPRINTK("ncpfs: bufsize = %d\n", server
->buffer_size
);
694 memset(&finfo
, 0, sizeof(finfo
));
695 finfo
.i
.attributes
= aDIR
;
696 finfo
.i
.dataStreamSize
= 0; /* ignored */
697 finfo
.i
.dirEntNum
= 0;
698 finfo
.i
.DosDirNum
= 0;
699 #ifdef CONFIG_NCPFS_SMALLDOS
700 finfo
.i
.NSCreator
= NW_NS_DOS
;
702 finfo
.volume
= NCP_NUMBER_OF_VOLUMES
;
703 /* set dates of mountpoint to Jan 1, 1986; 00:00 */
704 finfo
.i
.creationTime
= finfo
.i
.modifyTime
705 = cpu_to_le16(0x0000);
706 finfo
.i
.creationDate
= finfo
.i
.modifyDate
707 = finfo
.i
.lastAccessDate
708 = cpu_to_le16(0x0C21);
710 finfo
.i
.entryName
[0] = '\0';
713 finfo
.ino
= 2; /* tradition */
715 server
->name_space
[finfo
.volume
] = NW_NS_DOS
;
718 root_inode
= ncp_iget(sb
, &finfo
);
721 DPRINTK("ncp_fill_super: root vol=%d\n", NCP_FINFO(root_inode
)->volNumber
);
722 sb
->s_root
= d_alloc_root(root_inode
);
730 ncp_lock_server(server
);
731 ncp_disconnect(server
);
732 ncp_unlock_server(server
);
734 ncp_stop_tasks(server
);
735 vfree(server
->rxbuf
);
737 vfree(server
->txbuf
);
739 vfree(server
->packet
);
741 #ifdef CONFIG_NCPFS_NLS
742 unload_nls(server
->nls_io
);
743 unload_nls(server
->nls_vol
);
745 mutex_destroy(&server
->rcv
.creq_mutex
);
746 mutex_destroy(&server
->root_setup_lock
);
747 mutex_destroy(&server
->mutex
);
749 if (server
->info_filp
)
750 fput(server
->info_filp
);
752 bdi_destroy(&server
->bdi
);
754 /* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:
756 * The previously used put_filp(ncp_filp); was bogus, since
757 * it doesn't perform proper unlocking.
761 put_pid(data
.wdog_pid
);
762 sb
->s_fs_info
= NULL
;
767 static void ncp_put_super(struct super_block
*sb
)
769 struct ncp_server
*server
= NCP_SBP(sb
);
771 ncp_lock_server(server
);
772 ncp_disconnect(server
);
773 ncp_unlock_server(server
);
775 ncp_stop_tasks(server
);
777 #ifdef CONFIG_NCPFS_NLS
778 /* unload the NLS charsets */
779 unload_nls(server
->nls_vol
);
780 unload_nls(server
->nls_io
);
781 #endif /* CONFIG_NCPFS_NLS */
782 mutex_destroy(&server
->rcv
.creq_mutex
);
783 mutex_destroy(&server
->root_setup_lock
);
784 mutex_destroy(&server
->mutex
);
786 if (server
->info_filp
)
787 fput(server
->info_filp
);
788 fput(server
->ncp_filp
);
789 kill_pid(server
->m
.wdog_pid
, SIGTERM
, 1);
790 put_pid(server
->m
.wdog_pid
);
792 bdi_destroy(&server
->bdi
);
793 kfree(server
->priv
.data
);
794 kfree(server
->auth
.object_name
);
795 vfree(server
->rxbuf
);
796 vfree(server
->txbuf
);
797 vfree(server
->packet
);
798 sb
->s_fs_info
= NULL
;
802 static int ncp_statfs(struct dentry
*dentry
, struct kstatfs
*buf
)
806 struct ncp_inode_info
* ni
;
807 struct ncp_server
* s
;
808 struct ncp_volume_info vi
;
809 struct super_block
*sb
= dentry
->d_sb
;
829 if (!s
->m
.mounted_vol
[0]) {
833 err
= ncp_dirhandle_alloc(s
, ni
->volNumber
, ni
->DosDirNum
, &dh
);
837 err
= ncp_get_directory_info(s
, dh
, &vi
);
838 ncp_dirhandle_free(s
, dh
);
842 buf
->f_type
= NCP_SUPER_MAGIC
;
843 buf
->f_bsize
= vi
.sectors_per_block
* 512;
844 buf
->f_blocks
= vi
.total_blocks
;
845 buf
->f_bfree
= vi
.free_blocks
;
846 buf
->f_bavail
= vi
.free_blocks
;
847 buf
->f_files
= vi
.total_dir_entries
;
848 buf
->f_ffree
= vi
.available_dir_entries
;
852 /* We cannot say how much disk space is left on a mounted
853 NetWare Server, because free space is distributed over
854 volumes, and the current user might have disk quotas. So
855 free space is not that simple to determine. Our decision
856 here is to err conservatively. */
859 buf
->f_type
= NCP_SUPER_MAGIC
;
860 buf
->f_bsize
= NCP_BLOCK_SIZE
;
868 int ncp_notify_change(struct dentry
*dentry
, struct iattr
*attr
)
870 struct inode
*inode
= dentry
->d_inode
;
873 struct nw_modify_dos_info info
;
874 struct ncp_server
*server
;
878 server
= NCP_SERVER(inode
);
879 if (!server
) /* How this could happen? */
882 /* ageing the dentry to force validation */
883 ncp_age_dentry(server
, dentry
);
885 result
= inode_change_ok(inode
, attr
);
890 if (((attr
->ia_valid
& ATTR_UID
) &&
891 (attr
->ia_uid
!= server
->m
.uid
)))
894 if (((attr
->ia_valid
& ATTR_GID
) &&
895 (attr
->ia_gid
!= server
->m
.gid
)))
898 if (((attr
->ia_valid
& ATTR_MODE
) &&
900 ~(S_IFREG
| S_IFDIR
| S_IRWXUGO
))))
904 memset(&info
, 0, sizeof(info
));
907 if ((attr
->ia_valid
& ATTR_MODE
) != 0)
909 umode_t newmode
= attr
->ia_mode
;
911 info_mask
|= DM_ATTRIBUTES
;
913 if (S_ISDIR(inode
->i_mode
)) {
914 newmode
&= server
->m
.dir_mode
;
916 #ifdef CONFIG_NCPFS_EXTRAS
917 if (server
->m
.flags
& NCP_MOUNT_EXTRAS
) {
918 /* any non-default execute bit set */
919 if (newmode
& ~server
->m
.file_mode
& S_IXUGO
)
920 info
.attributes
|= aSHARED
| aSYSTEM
;
921 /* read for group/world and not in default file_mode */
922 else if (newmode
& ~server
->m
.file_mode
& S_IRUGO
)
923 info
.attributes
|= aSHARED
;
926 newmode
&= server
->m
.file_mode
;
928 if (newmode
& S_IWUGO
)
929 info
.attributes
&= ~(aRONLY
|aRENAMEINHIBIT
|aDELETEINHIBIT
);
931 info
.attributes
|= (aRONLY
|aRENAMEINHIBIT
|aDELETEINHIBIT
);
933 #ifdef CONFIG_NCPFS_NFS_NS
934 if (ncp_is_nfs_extras(server
, NCP_FINFO(inode
)->volNumber
)) {
935 result
= ncp_modify_nfs_info(server
,
936 NCP_FINFO(inode
)->volNumber
,
937 NCP_FINFO(inode
)->dirEntNum
,
941 info
.attributes
&= ~(aSHARED
| aSYSTEM
);
943 /* mark partial success */
944 struct iattr tmpattr
;
946 tmpattr
.ia_valid
= ATTR_MODE
;
947 tmpattr
.ia_mode
= attr
->ia_mode
;
949 setattr_copy(inode
, &tmpattr
);
950 mark_inode_dirty(inode
);
957 /* Do SIZE before attributes, otherwise mtime together with size does not work...
959 if ((attr
->ia_valid
& ATTR_SIZE
) != 0) {
962 DPRINTK("ncpfs: trying to change size to %ld\n",
965 if ((result
= ncp_make_open(inode
, O_WRONLY
)) < 0) {
969 ncp_write_kernel(NCP_SERVER(inode
), NCP_FINFO(inode
)->file_handle
,
970 attr
->ia_size
, 0, "", &written
);
972 /* According to ndir, the changes only take effect after
974 ncp_inode_close(inode
);
975 result
= ncp_make_closed(inode
);
979 if (attr
->ia_size
!= i_size_read(inode
)) {
980 result
= vmtruncate(inode
, attr
->ia_size
);
983 mark_inode_dirty(inode
);
986 if ((attr
->ia_valid
& ATTR_CTIME
) != 0) {
987 info_mask
|= (DM_CREATE_TIME
| DM_CREATE_DATE
);
988 ncp_date_unix2dos(attr
->ia_ctime
.tv_sec
,
989 &info
.creationTime
, &info
.creationDate
);
991 if ((attr
->ia_valid
& ATTR_MTIME
) != 0) {
992 info_mask
|= (DM_MODIFY_TIME
| DM_MODIFY_DATE
);
993 ncp_date_unix2dos(attr
->ia_mtime
.tv_sec
,
994 &info
.modifyTime
, &info
.modifyDate
);
996 if ((attr
->ia_valid
& ATTR_ATIME
) != 0) {
998 info_mask
|= (DM_LAST_ACCESS_DATE
);
999 ncp_date_unix2dos(attr
->ia_atime
.tv_sec
,
1000 &dummy
, &info
.lastAccessDate
);
1002 if (info_mask
!= 0) {
1003 result
= ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode
),
1004 inode
, info_mask
, &info
);
1006 if (info_mask
== (DM_CREATE_TIME
| DM_CREATE_DATE
)) {
1007 /* NetWare seems not to allow this. I
1008 do not know why. So, just tell the
1009 user everything went fine. This is
1010 a terrible hack, but I do not know
1011 how to do this correctly. */
1016 #ifdef CONFIG_NCPFS_STRONG
1017 if ((!result
) && (info_mask
& DM_ATTRIBUTES
))
1018 NCP_FINFO(inode
)->nwattr
= info
.attributes
;
1024 setattr_copy(inode
, attr
);
1025 mark_inode_dirty(inode
);
1033 static struct dentry
*ncp_mount(struct file_system_type
*fs_type
,
1034 int flags
, const char *dev_name
, void *data
)
1036 return mount_nodev(fs_type
, flags
, data
, ncp_fill_super
);
1039 static struct file_system_type ncp_fs_type
= {
1040 .owner
= THIS_MODULE
,
1043 .kill_sb
= kill_anon_super
,
1044 .fs_flags
= FS_BINARY_MOUNTDATA
,
1047 static int __init
init_ncp_fs(void)
1050 DPRINTK("ncpfs: init_ncp_fs called\n");
1052 err
= init_inodecache();
1055 err
= register_filesystem(&ncp_fs_type
);
1060 destroy_inodecache();
1065 static void __exit
exit_ncp_fs(void)
1067 DPRINTK("ncpfs: exit_ncp_fs called\n");
1068 unregister_filesystem(&ncp_fs_type
);
1069 destroy_inodecache();
1072 module_init(init_ncp_fs
)
1073 module_exit(exit_ncp_fs
)
1074 MODULE_LICENSE("GPL");