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
)
102 *flags
|= MS_NODIRATIME
;
106 static const struct super_operations ncp_sops
=
108 .alloc_inode
= ncp_alloc_inode
,
109 .destroy_inode
= ncp_destroy_inode
,
110 .drop_inode
= generic_delete_inode
,
111 .evict_inode
= ncp_evict_inode
,
112 .put_super
= ncp_put_super
,
113 .statfs
= ncp_statfs
,
114 .remount_fs
= ncp_remount
,
115 .show_options
= ncp_show_options
,
119 * Fill in the ncpfs-specific information in the inode.
121 static void ncp_update_dirent(struct inode
*inode
, struct ncp_entry_info
*nwinfo
)
123 NCP_FINFO(inode
)->DosDirNum
= nwinfo
->i
.DosDirNum
;
124 NCP_FINFO(inode
)->dirEntNum
= nwinfo
->i
.dirEntNum
;
125 NCP_FINFO(inode
)->volNumber
= nwinfo
->volume
;
128 void ncp_update_inode(struct inode
*inode
, struct ncp_entry_info
*nwinfo
)
130 ncp_update_dirent(inode
, nwinfo
);
131 NCP_FINFO(inode
)->nwattr
= nwinfo
->i
.attributes
;
132 NCP_FINFO(inode
)->access
= nwinfo
->access
;
133 memcpy(NCP_FINFO(inode
)->file_handle
, nwinfo
->file_handle
,
134 sizeof(nwinfo
->file_handle
));
135 DPRINTK("ncp_update_inode: updated %s, volnum=%d, dirent=%u\n",
136 nwinfo
->i
.entryName
, NCP_FINFO(inode
)->volNumber
,
137 NCP_FINFO(inode
)->dirEntNum
);
140 static void ncp_update_dates(struct inode
*inode
, struct nw_info_struct
*nwi
)
142 /* NFS namespace mode overrides others if it's set. */
143 DPRINTK(KERN_DEBUG
"ncp_update_dates_and_mode: (%s) nfs.mode=0%o\n",
144 nwi
->entryName
, nwi
->nfs
.mode
);
147 inode
->i_mode
= nwi
->nfs
.mode
;
150 inode
->i_blocks
= (i_size_read(inode
) + NCP_BLOCK_SIZE
- 1) >> NCP_BLOCK_SHIFT
;
152 inode
->i_mtime
.tv_sec
= ncp_date_dos2unix(nwi
->modifyTime
, nwi
->modifyDate
);
153 inode
->i_ctime
.tv_sec
= ncp_date_dos2unix(nwi
->creationTime
, nwi
->creationDate
);
154 inode
->i_atime
.tv_sec
= ncp_date_dos2unix(0, nwi
->lastAccessDate
);
155 inode
->i_atime
.tv_nsec
= 0;
156 inode
->i_mtime
.tv_nsec
= 0;
157 inode
->i_ctime
.tv_nsec
= 0;
160 static void ncp_update_attrs(struct inode
*inode
, struct ncp_entry_info
*nwinfo
)
162 struct nw_info_struct
*nwi
= &nwinfo
->i
;
163 struct ncp_server
*server
= NCP_SERVER(inode
);
165 if (nwi
->attributes
& aDIR
) {
166 inode
->i_mode
= server
->m
.dir_mode
;
167 /* for directories dataStreamSize seems to be some
169 i_size_write(inode
, NCP_BLOCK_SIZE
);
173 inode
->i_mode
= server
->m
.file_mode
;
174 size
= le32_to_cpu(nwi
->dataStreamSize
);
175 i_size_write(inode
, size
);
176 #ifdef CONFIG_NCPFS_EXTRAS
177 if ((server
->m
.flags
& (NCP_MOUNT_EXTRAS
|NCP_MOUNT_SYMLINKS
))
178 && (nwi
->attributes
& aSHARED
)) {
179 switch (nwi
->attributes
& (aHIDDEN
|aSYSTEM
)) {
181 if (server
->m
.flags
& NCP_MOUNT_SYMLINKS
) {
182 if (/* (size >= NCP_MIN_SYMLINK_SIZE)
183 && */ (size
<= NCP_MAX_SYMLINK_SIZE
)) {
184 inode
->i_mode
= (inode
->i_mode
& ~S_IFMT
) | S_IFLNK
;
185 NCP_FINFO(inode
)->flags
|= NCPI_KLUDGE_SYMLINK
;
191 if (server
->m
.flags
& NCP_MOUNT_EXTRAS
)
192 inode
->i_mode
|= S_IRUGO
;
195 if (server
->m
.flags
& NCP_MOUNT_EXTRAS
)
196 inode
->i_mode
|= (inode
->i_mode
>> 2) & S_IXUGO
;
198 /* case aSYSTEM|aHIDDEN: */
200 /* reserved combination */
206 if (nwi
->attributes
& aRONLY
) inode
->i_mode
&= ~S_IWUGO
;
209 void ncp_update_inode2(struct inode
* inode
, struct ncp_entry_info
*nwinfo
)
211 NCP_FINFO(inode
)->flags
= 0;
212 if (!atomic_read(&NCP_FINFO(inode
)->opened
)) {
213 NCP_FINFO(inode
)->nwattr
= nwinfo
->i
.attributes
;
214 ncp_update_attrs(inode
, nwinfo
);
217 ncp_update_dates(inode
, &nwinfo
->i
);
218 ncp_update_dirent(inode
, nwinfo
);
222 * Fill in the inode based on the ncp_entry_info structure. Used only for brand new inodes.
224 static void ncp_set_attr(struct inode
*inode
, struct ncp_entry_info
*nwinfo
)
226 struct ncp_server
*server
= NCP_SERVER(inode
);
228 NCP_FINFO(inode
)->flags
= 0;
230 ncp_update_attrs(inode
, nwinfo
);
232 DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode
->i_mode
);
235 inode
->i_uid
= server
->m
.uid
;
236 inode
->i_gid
= server
->m
.gid
;
238 ncp_update_dates(inode
, &nwinfo
->i
);
239 ncp_update_inode(inode
, nwinfo
);
242 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
243 static const struct inode_operations ncp_symlink_inode_operations
= {
244 .readlink
= generic_readlink
,
245 .follow_link
= page_follow_link_light
,
246 .put_link
= page_put_link
,
247 .setattr
= ncp_notify_change
,
255 ncp_iget(struct super_block
*sb
, struct ncp_entry_info
*info
)
260 printk(KERN_ERR
"ncp_iget: info is NULL\n");
264 inode
= new_inode(sb
);
266 atomic_set(&NCP_FINFO(inode
)->opened
, info
->opened
);
268 inode
->i_mapping
->backing_dev_info
= sb
->s_bdi
;
269 inode
->i_ino
= info
->ino
;
270 ncp_set_attr(inode
, info
);
271 if (S_ISREG(inode
->i_mode
)) {
272 inode
->i_op
= &ncp_file_inode_operations
;
273 inode
->i_fop
= &ncp_file_operations
;
274 } else if (S_ISDIR(inode
->i_mode
)) {
275 inode
->i_op
= &ncp_dir_inode_operations
;
276 inode
->i_fop
= &ncp_dir_operations
;
277 #ifdef CONFIG_NCPFS_NFS_NS
278 } else if (S_ISCHR(inode
->i_mode
) || S_ISBLK(inode
->i_mode
) || S_ISFIFO(inode
->i_mode
) || S_ISSOCK(inode
->i_mode
)) {
279 init_special_inode(inode
, inode
->i_mode
,
280 new_decode_dev(info
->i
.nfs
.rdev
));
282 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
283 } else if (S_ISLNK(inode
->i_mode
)) {
284 inode
->i_op
= &ncp_symlink_inode_operations
;
285 inode
->i_data
.a_ops
= &ncp_symlink_aops
;
288 make_bad_inode(inode
);
290 insert_inode_hash(inode
);
292 printk(KERN_ERR
"ncp_iget: iget failed!\n");
297 ncp_evict_inode(struct inode
*inode
)
299 truncate_inode_pages(&inode
->i_data
, 0);
302 if (S_ISDIR(inode
->i_mode
)) {
303 DDPRINTK("ncp_evict_inode: put directory %ld\n", inode
->i_ino
);
306 if (ncp_make_closed(inode
) != 0) {
307 /* We can't do anything but complain. */
308 printk(KERN_ERR
"ncp_evict_inode: could not close\n");
312 static void ncp_stop_tasks(struct ncp_server
*server
) {
313 struct sock
* sk
= server
->ncp_sock
->sk
;
316 sk
->sk_error_report
= server
->error_report
;
317 sk
->sk_data_ready
= server
->data_ready
;
318 sk
->sk_write_space
= server
->write_space
;
320 del_timer_sync(&server
->timeout_tm
);
322 flush_work(&server
->rcv
.tq
);
323 if (sk
->sk_socket
->type
== SOCK_STREAM
)
324 flush_work(&server
->tx
.tq
);
326 flush_work(&server
->timeout_tq
);
329 static int ncp_show_options(struct seq_file
*seq
, struct dentry
*root
)
331 struct ncp_server
*server
= NCP_SBP(root
->d_sb
);
334 if (!uid_eq(server
->m
.uid
, GLOBAL_ROOT_UID
))
335 seq_printf(seq
, ",uid=%u",
336 from_kuid_munged(&init_user_ns
, server
->m
.uid
));
337 if (!gid_eq(server
->m
.gid
, GLOBAL_ROOT_GID
))
338 seq_printf(seq
, ",gid=%u",
339 from_kgid_munged(&init_user_ns
, server
->m
.gid
));
340 if (!uid_eq(server
->m
.mounted_uid
, GLOBAL_ROOT_UID
))
341 seq_printf(seq
, ",owner=%u",
342 from_kuid_munged(&init_user_ns
, server
->m
.mounted_uid
));
343 tmp
= server
->m
.file_mode
& S_IALLUGO
;
344 if (tmp
!= NCP_DEFAULT_FILE_MODE
)
345 seq_printf(seq
, ",mode=0%o", tmp
);
346 tmp
= server
->m
.dir_mode
& S_IALLUGO
;
347 if (tmp
!= NCP_DEFAULT_DIR_MODE
)
348 seq_printf(seq
, ",dirmode=0%o", tmp
);
349 if (server
->m
.time_out
!= NCP_DEFAULT_TIME_OUT
* HZ
/ 100) {
350 tmp
= server
->m
.time_out
* 100 / HZ
;
351 seq_printf(seq
, ",timeout=%u", tmp
);
353 if (server
->m
.retry_count
!= NCP_DEFAULT_RETRY_COUNT
)
354 seq_printf(seq
, ",retry=%u", server
->m
.retry_count
);
355 if (server
->m
.flags
!= 0)
356 seq_printf(seq
, ",flags=%lu", server
->m
.flags
);
357 if (server
->m
.wdog_pid
!= NULL
)
358 seq_printf(seq
, ",wdogpid=%u", pid_vnr(server
->m
.wdog_pid
));
363 static const struct ncp_option ncp_opts
[] = {
364 { "uid", OPT_INT
, 'u' },
365 { "gid", OPT_INT
, 'g' },
366 { "owner", OPT_INT
, 'o' },
367 { "mode", OPT_INT
, 'm' },
368 { "dirmode", OPT_INT
, 'd' },
369 { "timeout", OPT_INT
, 't' },
370 { "retry", OPT_INT
, 'r' },
371 { "flags", OPT_INT
, 'f' },
372 { "wdogpid", OPT_INT
, 'w' },
373 { "ncpfd", OPT_INT
, 'n' },
374 { "infofd", OPT_INT
, 'i' }, /* v5 */
375 { "version", OPT_INT
, 'v' },
378 static int ncp_parse_options(struct ncp_mount_data_kernel
*data
, char *options
) {
381 unsigned long optint
;
387 data
->mounted_uid
= GLOBAL_ROOT_UID
;
388 data
->wdog_pid
= NULL
;
390 data
->time_out
= NCP_DEFAULT_TIME_OUT
;
391 data
->retry_count
= NCP_DEFAULT_RETRY_COUNT
;
392 data
->uid
= GLOBAL_ROOT_UID
;
393 data
->gid
= GLOBAL_ROOT_GID
;
394 data
->file_mode
= NCP_DEFAULT_FILE_MODE
;
395 data
->dir_mode
= NCP_DEFAULT_DIR_MODE
;
397 data
->mounted_vol
[0] = 0;
399 while ((optval
= ncp_getopt("ncpfs", &options
, ncp_opts
, NULL
, &optarg
, &optint
)) != 0) {
405 data
->uid
= make_kuid(current_user_ns(), optint
);
406 if (!uid_valid(data
->uid
))
410 data
->gid
= make_kgid(current_user_ns(), optint
);
411 if (!gid_valid(data
->gid
))
415 data
->mounted_uid
= make_kuid(current_user_ns(), optint
);
416 if (!uid_valid(data
->mounted_uid
))
420 data
->file_mode
= optint
;
423 data
->dir_mode
= optint
;
426 data
->time_out
= optint
;
429 data
->retry_count
= optint
;
432 data
->flags
= optint
;
435 data
->wdog_pid
= find_get_pid(optint
);
438 data
->ncp_fd
= optint
;
441 data
->info_fd
= optint
;
445 if (optint
< NCP_MOUNT_VERSION_V4
)
447 if (optint
> NCP_MOUNT_VERSION_V5
)
456 put_pid(data
->wdog_pid
);
457 data
->wdog_pid
= NULL
;
461 static int ncp_fill_super(struct super_block
*sb
, void *raw_data
, int silent
)
463 struct ncp_mount_data_kernel data
;
464 struct ncp_server
*server
;
465 struct file
*ncp_filp
;
466 struct inode
*root_inode
;
467 struct inode
*sock_inode
;
471 #ifdef CONFIG_NCPFS_PACKET_SIGNING
474 struct ncp_entry_info finfo
;
476 memset(&data
, 0, sizeof(data
));
477 server
= kzalloc(sizeof(struct ncp_server
), GFP_KERNEL
);
480 sb
->s_fs_info
= server
;
483 if (raw_data
== NULL
)
485 switch (*(int*)raw_data
) {
486 case NCP_MOUNT_VERSION
:
488 struct ncp_mount_data
* md
= (struct ncp_mount_data
*)raw_data
;
490 data
.flags
= md
->flags
;
491 data
.int_flags
= NCP_IMOUNT_LOGGEDIN_POSSIBLE
;
492 data
.mounted_uid
= make_kuid(current_user_ns(), md
->mounted_uid
);
493 data
.wdog_pid
= find_get_pid(md
->wdog_pid
);
494 data
.ncp_fd
= md
->ncp_fd
;
495 data
.time_out
= md
->time_out
;
496 data
.retry_count
= md
->retry_count
;
497 data
.uid
= make_kuid(current_user_ns(), md
->uid
);
498 data
.gid
= make_kgid(current_user_ns(), md
->gid
);
499 data
.file_mode
= md
->file_mode
;
500 data
.dir_mode
= md
->dir_mode
;
502 memcpy(data
.mounted_vol
, md
->mounted_vol
,
506 case NCP_MOUNT_VERSION_V4
:
508 struct ncp_mount_data_v4
* md
= (struct ncp_mount_data_v4
*)raw_data
;
510 data
.flags
= md
->flags
;
511 data
.mounted_uid
= make_kuid(current_user_ns(), md
->mounted_uid
);
512 data
.wdog_pid
= find_get_pid(md
->wdog_pid
);
513 data
.ncp_fd
= md
->ncp_fd
;
514 data
.time_out
= md
->time_out
;
515 data
.retry_count
= md
->retry_count
;
516 data
.uid
= make_kuid(current_user_ns(), md
->uid
);
517 data
.gid
= make_kgid(current_user_ns(), md
->gid
);
518 data
.file_mode
= md
->file_mode
;
519 data
.dir_mode
= md
->dir_mode
;
525 if (memcmp(raw_data
, "vers", 4) == 0) {
526 error
= ncp_parse_options(&data
, raw_data
);
533 if (!uid_valid(data
.mounted_uid
) || !uid_valid(data
.uid
) ||
534 !gid_valid(data
.gid
))
537 ncp_filp
= fget(data
.ncp_fd
);
541 sock_inode
= file_inode(ncp_filp
);
542 if (!S_ISSOCK(sock_inode
->i_mode
))
544 sock
= SOCKET_I(sock_inode
);
548 if (sock
->type
== SOCK_STREAM
)
549 default_bufsize
= 0xF000;
551 default_bufsize
= 1024;
553 sb
->s_flags
|= MS_NODIRATIME
; /* probably even noatime */
554 sb
->s_maxbytes
= 0xFFFFFFFFU
;
555 sb
->s_blocksize
= 1024; /* Eh... Is this correct? */
556 sb
->s_blocksize_bits
= 10;
557 sb
->s_magic
= NCP_SUPER_MAGIC
;
558 sb
->s_op
= &ncp_sops
;
559 sb
->s_d_op
= &ncp_dentry_operations
;
560 sb
->s_bdi
= &server
->bdi
;
562 server
= NCP_SBP(sb
);
563 memset(server
, 0, sizeof(*server
));
565 error
= bdi_setup_and_register(&server
->bdi
, "ncpfs", BDI_CAP_MAP_COPY
);
569 server
->ncp_filp
= ncp_filp
;
570 server
->ncp_sock
= sock
;
572 if (data
.info_fd
!= -1) {
573 struct socket
*info_sock
;
576 server
->info_filp
= fget(data
.info_fd
);
577 if (!server
->info_filp
)
580 sock_inode
= file_inode(server
->info_filp
);
581 if (!S_ISSOCK(sock_inode
->i_mode
))
583 info_sock
= SOCKET_I(sock_inode
);
587 if (info_sock
->type
!= SOCK_STREAM
)
589 server
->info_sock
= info_sock
;
592 /* server->lock = 0; */
593 mutex_init(&server
->mutex
);
594 server
->packet
= NULL
;
595 /* server->buffer_size = 0; */
596 /* server->conn_status = 0; */
597 /* server->root_dentry = NULL; */
598 /* server->root_setuped = 0; */
599 mutex_init(&server
->root_setup_lock
);
600 #ifdef CONFIG_NCPFS_PACKET_SIGNING
601 /* server->sign_wanted = 0; */
602 /* server->sign_active = 0; */
604 init_rwsem(&server
->auth_rwsem
);
605 server
->auth
.auth_type
= NCP_AUTH_NONE
;
606 /* server->auth.object_name_len = 0; */
607 /* server->auth.object_name = NULL; */
608 /* server->auth.object_type = 0; */
609 /* server->priv.len = 0; */
610 /* server->priv.data = NULL; */
613 /* Although anything producing this is buggy, it happens
614 now because of PATH_MAX changes.. */
615 if (server
->m
.time_out
< 1) {
616 server
->m
.time_out
= 10;
617 printk(KERN_INFO
"You need to recompile your ncpfs utils..\n");
619 server
->m
.time_out
= server
->m
.time_out
* HZ
/ 100;
620 server
->m
.file_mode
= (server
->m
.file_mode
& S_IRWXUGO
) | S_IFREG
;
621 server
->m
.dir_mode
= (server
->m
.dir_mode
& S_IRWXUGO
) | S_IFDIR
;
623 #ifdef CONFIG_NCPFS_NLS
624 /* load the default NLS charsets */
625 server
->nls_vol
= load_nls_default();
626 server
->nls_io
= load_nls_default();
627 #endif /* CONFIG_NCPFS_NLS */
629 atomic_set(&server
->dentry_ttl
, 0); /* no caching */
631 INIT_LIST_HEAD(&server
->tx
.requests
);
632 mutex_init(&server
->rcv
.creq_mutex
);
633 server
->tx
.creq
= NULL
;
634 server
->rcv
.creq
= NULL
;
636 init_timer(&server
->timeout_tm
);
637 #undef NCP_PACKET_SIZE
638 #define NCP_PACKET_SIZE 131072
640 server
->packet_size
= NCP_PACKET_SIZE
;
641 server
->packet
= vmalloc(NCP_PACKET_SIZE
);
642 if (server
->packet
== NULL
)
644 server
->txbuf
= vmalloc(NCP_PACKET_SIZE
);
645 if (server
->txbuf
== NULL
)
647 server
->rxbuf
= vmalloc(NCP_PACKET_SIZE
);
648 if (server
->rxbuf
== NULL
)
652 server
->data_ready
= sock
->sk
->sk_data_ready
;
653 server
->write_space
= sock
->sk
->sk_write_space
;
654 server
->error_report
= sock
->sk
->sk_error_report
;
655 sock
->sk
->sk_user_data
= server
;
656 sock
->sk
->sk_data_ready
= ncp_tcp_data_ready
;
657 sock
->sk
->sk_error_report
= ncp_tcp_error_report
;
658 if (sock
->type
== SOCK_STREAM
) {
659 server
->rcv
.ptr
= (unsigned char*)&server
->rcv
.buf
;
660 server
->rcv
.len
= 10;
661 server
->rcv
.state
= 0;
662 INIT_WORK(&server
->rcv
.tq
, ncp_tcp_rcv_proc
);
663 INIT_WORK(&server
->tx
.tq
, ncp_tcp_tx_proc
);
664 sock
->sk
->sk_write_space
= ncp_tcp_write_space
;
666 INIT_WORK(&server
->rcv
.tq
, ncpdgram_rcv_proc
);
667 INIT_WORK(&server
->timeout_tq
, ncpdgram_timeout_proc
);
668 server
->timeout_tm
.data
= (unsigned long)server
;
669 server
->timeout_tm
.function
= ncpdgram_timeout_call
;
671 release_sock(sock
->sk
);
673 ncp_lock_server(server
);
674 error
= ncp_connect(server
);
675 ncp_unlock_server(server
);
678 DPRINTK("ncp_fill_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb
));
680 error
= -EMSGSIZE
; /* -EREMOTESIDEINCOMPATIBLE */
681 #ifdef CONFIG_NCPFS_PACKET_SIGNING
682 if (ncp_negotiate_size_and_options(server
, default_bufsize
,
683 NCP_DEFAULT_OPTIONS
, &(server
->buffer_size
), &options
) == 0)
685 if (options
!= NCP_DEFAULT_OPTIONS
)
687 if (ncp_negotiate_size_and_options(server
,
690 &(server
->buffer_size
), &options
) != 0)
696 ncp_lock_server(server
);
698 server
->sign_wanted
= 1;
699 ncp_unlock_server(server
);
702 #endif /* CONFIG_NCPFS_PACKET_SIGNING */
703 if (ncp_negotiate_buffersize(server
, default_bufsize
,
704 &(server
->buffer_size
)) != 0)
706 DPRINTK("ncpfs: bufsize = %d\n", server
->buffer_size
);
708 memset(&finfo
, 0, sizeof(finfo
));
709 finfo
.i
.attributes
= aDIR
;
710 finfo
.i
.dataStreamSize
= 0; /* ignored */
711 finfo
.i
.dirEntNum
= 0;
712 finfo
.i
.DosDirNum
= 0;
713 #ifdef CONFIG_NCPFS_SMALLDOS
714 finfo
.i
.NSCreator
= NW_NS_DOS
;
716 finfo
.volume
= NCP_NUMBER_OF_VOLUMES
;
717 /* set dates of mountpoint to Jan 1, 1986; 00:00 */
718 finfo
.i
.creationTime
= finfo
.i
.modifyTime
719 = cpu_to_le16(0x0000);
720 finfo
.i
.creationDate
= finfo
.i
.modifyDate
721 = finfo
.i
.lastAccessDate
722 = cpu_to_le16(0x0C21);
724 finfo
.i
.entryName
[0] = '\0';
727 finfo
.ino
= 2; /* tradition */
729 server
->name_space
[finfo
.volume
] = NW_NS_DOS
;
732 root_inode
= ncp_iget(sb
, &finfo
);
735 DPRINTK("ncp_fill_super: root vol=%d\n", NCP_FINFO(root_inode
)->volNumber
);
736 sb
->s_root
= d_make_root(root_inode
);
742 ncp_lock_server(server
);
743 ncp_disconnect(server
);
744 ncp_unlock_server(server
);
746 ncp_stop_tasks(server
);
747 vfree(server
->rxbuf
);
749 vfree(server
->txbuf
);
751 vfree(server
->packet
);
753 #ifdef CONFIG_NCPFS_NLS
754 unload_nls(server
->nls_io
);
755 unload_nls(server
->nls_vol
);
757 mutex_destroy(&server
->rcv
.creq_mutex
);
758 mutex_destroy(&server
->root_setup_lock
);
759 mutex_destroy(&server
->mutex
);
761 if (server
->info_filp
)
762 fput(server
->info_filp
);
764 bdi_destroy(&server
->bdi
);
766 /* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:
768 * The previously used put_filp(ncp_filp); was bogus, since
769 * it doesn't perform proper unlocking.
773 put_pid(data
.wdog_pid
);
774 sb
->s_fs_info
= NULL
;
779 static void ncp_put_super(struct super_block
*sb
)
781 struct ncp_server
*server
= NCP_SBP(sb
);
783 ncp_lock_server(server
);
784 ncp_disconnect(server
);
785 ncp_unlock_server(server
);
787 ncp_stop_tasks(server
);
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 */
794 mutex_destroy(&server
->rcv
.creq_mutex
);
795 mutex_destroy(&server
->root_setup_lock
);
796 mutex_destroy(&server
->mutex
);
798 if (server
->info_filp
)
799 fput(server
->info_filp
);
800 fput(server
->ncp_filp
);
801 kill_pid(server
->m
.wdog_pid
, SIGTERM
, 1);
802 put_pid(server
->m
.wdog_pid
);
804 bdi_destroy(&server
->bdi
);
805 kfree(server
->priv
.data
);
806 kfree(server
->auth
.object_name
);
807 vfree(server
->rxbuf
);
808 vfree(server
->txbuf
);
809 vfree(server
->packet
);
810 sb
->s_fs_info
= NULL
;
814 static int ncp_statfs(struct dentry
*dentry
, struct kstatfs
*buf
)
818 struct ncp_inode_info
* ni
;
819 struct ncp_server
* s
;
820 struct ncp_volume_info vi
;
821 struct super_block
*sb
= dentry
->d_sb
;
841 if (!s
->m
.mounted_vol
[0]) {
845 err
= ncp_dirhandle_alloc(s
, ni
->volNumber
, ni
->DosDirNum
, &dh
);
849 err
= ncp_get_directory_info(s
, dh
, &vi
);
850 ncp_dirhandle_free(s
, dh
);
854 buf
->f_type
= NCP_SUPER_MAGIC
;
855 buf
->f_bsize
= vi
.sectors_per_block
* 512;
856 buf
->f_blocks
= vi
.total_blocks
;
857 buf
->f_bfree
= vi
.free_blocks
;
858 buf
->f_bavail
= vi
.free_blocks
;
859 buf
->f_files
= vi
.total_dir_entries
;
860 buf
->f_ffree
= vi
.available_dir_entries
;
864 /* We cannot say how much disk space is left on a mounted
865 NetWare Server, because free space is distributed over
866 volumes, and the current user might have disk quotas. So
867 free space is not that simple to determine. Our decision
868 here is to err conservatively. */
871 buf
->f_type
= NCP_SUPER_MAGIC
;
872 buf
->f_bsize
= NCP_BLOCK_SIZE
;
880 int ncp_notify_change(struct dentry
*dentry
, struct iattr
*attr
)
882 struct inode
*inode
= dentry
->d_inode
;
885 struct nw_modify_dos_info info
;
886 struct ncp_server
*server
;
890 server
= NCP_SERVER(inode
);
891 if (!server
) /* How this could happen? */
894 /* ageing the dentry to force validation */
895 ncp_age_dentry(server
, dentry
);
897 result
= inode_change_ok(inode
, attr
);
902 if ((attr
->ia_valid
& ATTR_UID
) && !uid_eq(attr
->ia_uid
, server
->m
.uid
))
905 if ((attr
->ia_valid
& ATTR_GID
) && !gid_eq(attr
->ia_gid
, server
->m
.gid
))
908 if (((attr
->ia_valid
& ATTR_MODE
) &&
910 ~(S_IFREG
| S_IFDIR
| S_IRWXUGO
))))
914 memset(&info
, 0, sizeof(info
));
917 if ((attr
->ia_valid
& ATTR_MODE
) != 0)
919 umode_t newmode
= attr
->ia_mode
;
921 info_mask
|= DM_ATTRIBUTES
;
923 if (S_ISDIR(inode
->i_mode
)) {
924 newmode
&= server
->m
.dir_mode
;
926 #ifdef CONFIG_NCPFS_EXTRAS
927 if (server
->m
.flags
& NCP_MOUNT_EXTRAS
) {
928 /* any non-default execute bit set */
929 if (newmode
& ~server
->m
.file_mode
& S_IXUGO
)
930 info
.attributes
|= aSHARED
| aSYSTEM
;
931 /* read for group/world and not in default file_mode */
932 else if (newmode
& ~server
->m
.file_mode
& S_IRUGO
)
933 info
.attributes
|= aSHARED
;
936 newmode
&= server
->m
.file_mode
;
938 if (newmode
& S_IWUGO
)
939 info
.attributes
&= ~(aRONLY
|aRENAMEINHIBIT
|aDELETEINHIBIT
);
941 info
.attributes
|= (aRONLY
|aRENAMEINHIBIT
|aDELETEINHIBIT
);
943 #ifdef CONFIG_NCPFS_NFS_NS
944 if (ncp_is_nfs_extras(server
, NCP_FINFO(inode
)->volNumber
)) {
945 result
= ncp_modify_nfs_info(server
,
946 NCP_FINFO(inode
)->volNumber
,
947 NCP_FINFO(inode
)->dirEntNum
,
951 info
.attributes
&= ~(aSHARED
| aSYSTEM
);
953 /* mark partial success */
954 struct iattr tmpattr
;
956 tmpattr
.ia_valid
= ATTR_MODE
;
957 tmpattr
.ia_mode
= attr
->ia_mode
;
959 setattr_copy(inode
, &tmpattr
);
960 mark_inode_dirty(inode
);
967 /* Do SIZE before attributes, otherwise mtime together with size does not work...
969 if ((attr
->ia_valid
& ATTR_SIZE
) != 0) {
972 DPRINTK("ncpfs: trying to change size to %ld\n",
975 if ((result
= ncp_make_open(inode
, O_WRONLY
)) < 0) {
979 ncp_write_kernel(NCP_SERVER(inode
), NCP_FINFO(inode
)->file_handle
,
980 attr
->ia_size
, 0, "", &written
);
982 /* According to ndir, the changes only take effect after
984 ncp_inode_close(inode
);
985 result
= ncp_make_closed(inode
);
989 if (attr
->ia_size
!= i_size_read(inode
)) {
990 truncate_setsize(inode
, attr
->ia_size
);
991 mark_inode_dirty(inode
);
994 if ((attr
->ia_valid
& ATTR_CTIME
) != 0) {
995 info_mask
|= (DM_CREATE_TIME
| DM_CREATE_DATE
);
996 ncp_date_unix2dos(attr
->ia_ctime
.tv_sec
,
997 &info
.creationTime
, &info
.creationDate
);
999 if ((attr
->ia_valid
& ATTR_MTIME
) != 0) {
1000 info_mask
|= (DM_MODIFY_TIME
| DM_MODIFY_DATE
);
1001 ncp_date_unix2dos(attr
->ia_mtime
.tv_sec
,
1002 &info
.modifyTime
, &info
.modifyDate
);
1004 if ((attr
->ia_valid
& ATTR_ATIME
) != 0) {
1006 info_mask
|= (DM_LAST_ACCESS_DATE
);
1007 ncp_date_unix2dos(attr
->ia_atime
.tv_sec
,
1008 &dummy
, &info
.lastAccessDate
);
1010 if (info_mask
!= 0) {
1011 result
= ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode
),
1012 inode
, info_mask
, &info
);
1014 if (info_mask
== (DM_CREATE_TIME
| DM_CREATE_DATE
)) {
1015 /* NetWare seems not to allow this. I
1016 do not know why. So, just tell the
1017 user everything went fine. This is
1018 a terrible hack, but I do not know
1019 how to do this correctly. */
1024 #ifdef CONFIG_NCPFS_STRONG
1025 if ((!result
) && (info_mask
& DM_ATTRIBUTES
))
1026 NCP_FINFO(inode
)->nwattr
= info
.attributes
;
1032 setattr_copy(inode
, attr
);
1033 mark_inode_dirty(inode
);
1041 static struct dentry
*ncp_mount(struct file_system_type
*fs_type
,
1042 int flags
, const char *dev_name
, void *data
)
1044 return mount_nodev(fs_type
, flags
, data
, ncp_fill_super
);
1047 static struct file_system_type ncp_fs_type
= {
1048 .owner
= THIS_MODULE
,
1051 .kill_sb
= kill_anon_super
,
1052 .fs_flags
= FS_BINARY_MOUNTDATA
,
1054 MODULE_ALIAS_FS("ncpfs");
1056 static int __init
init_ncp_fs(void)
1059 DPRINTK("ncpfs: init_ncp_fs called\n");
1061 err
= init_inodecache();
1064 err
= register_filesystem(&ncp_fs_type
);
1069 destroy_inodecache();
1074 static void __exit
exit_ncp_fs(void)
1076 DPRINTK("ncpfs: exit_ncp_fs called\n");
1077 unregister_filesystem(&ncp_fs_type
);
1078 destroy_inodecache();
1081 module_init(init_ncp_fs
)
1082 module_exit(exit_ncp_fs
)
1083 MODULE_LICENSE("GPL");