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
)) {
412 data
->gid
= make_kgid(current_user_ns(), optint
);
413 if (!gid_valid(data
->gid
)) {
419 data
->mounted_uid
= make_kuid(current_user_ns(), optint
);
420 if (!uid_valid(data
->mounted_uid
)) {
426 data
->file_mode
= optint
;
429 data
->dir_mode
= optint
;
432 data
->time_out
= optint
;
435 data
->retry_count
= optint
;
438 data
->flags
= optint
;
441 data
->wdog_pid
= find_get_pid(optint
);
444 data
->ncp_fd
= optint
;
447 data
->info_fd
= optint
;
451 if (optint
< NCP_MOUNT_VERSION_V4
)
453 if (optint
> NCP_MOUNT_VERSION_V5
)
462 put_pid(data
->wdog_pid
);
463 data
->wdog_pid
= NULL
;
467 static int ncp_fill_super(struct super_block
*sb
, void *raw_data
, int silent
)
469 struct ncp_mount_data_kernel data
;
470 struct ncp_server
*server
;
471 struct inode
*root_inode
;
475 #ifdef CONFIG_NCPFS_PACKET_SIGNING
478 struct ncp_entry_info finfo
;
480 memset(&data
, 0, sizeof(data
));
481 server
= kzalloc(sizeof(struct ncp_server
), GFP_KERNEL
);
484 sb
->s_fs_info
= server
;
487 if (raw_data
== NULL
)
489 switch (*(int*)raw_data
) {
490 case NCP_MOUNT_VERSION
:
492 struct ncp_mount_data
* md
= (struct ncp_mount_data
*)raw_data
;
494 data
.flags
= md
->flags
;
495 data
.int_flags
= NCP_IMOUNT_LOGGEDIN_POSSIBLE
;
496 data
.mounted_uid
= make_kuid(current_user_ns(), md
->mounted_uid
);
497 data
.wdog_pid
= find_get_pid(md
->wdog_pid
);
498 data
.ncp_fd
= md
->ncp_fd
;
499 data
.time_out
= md
->time_out
;
500 data
.retry_count
= md
->retry_count
;
501 data
.uid
= make_kuid(current_user_ns(), md
->uid
);
502 data
.gid
= make_kgid(current_user_ns(), md
->gid
);
503 data
.file_mode
= md
->file_mode
;
504 data
.dir_mode
= md
->dir_mode
;
506 memcpy(data
.mounted_vol
, md
->mounted_vol
,
510 case NCP_MOUNT_VERSION_V4
:
512 struct ncp_mount_data_v4
* md
= (struct ncp_mount_data_v4
*)raw_data
;
514 data
.flags
= md
->flags
;
515 data
.mounted_uid
= make_kuid(current_user_ns(), md
->mounted_uid
);
516 data
.wdog_pid
= find_get_pid(md
->wdog_pid
);
517 data
.ncp_fd
= md
->ncp_fd
;
518 data
.time_out
= md
->time_out
;
519 data
.retry_count
= md
->retry_count
;
520 data
.uid
= make_kuid(current_user_ns(), md
->uid
);
521 data
.gid
= make_kgid(current_user_ns(), md
->gid
);
522 data
.file_mode
= md
->file_mode
;
523 data
.dir_mode
= md
->dir_mode
;
529 if (memcmp(raw_data
, "vers", 4) == 0) {
530 error
= ncp_parse_options(&data
, raw_data
);
537 if (!uid_valid(data
.mounted_uid
) || !uid_valid(data
.uid
) ||
538 !gid_valid(data
.gid
))
540 sock
= sockfd_lookup(data
.ncp_fd
, &error
);
544 if (sock
->type
== SOCK_STREAM
)
545 default_bufsize
= 0xF000;
547 default_bufsize
= 1024;
549 sb
->s_flags
|= MS_NODIRATIME
; /* probably even noatime */
550 sb
->s_maxbytes
= 0xFFFFFFFFU
;
551 sb
->s_blocksize
= 1024; /* Eh... Is this correct? */
552 sb
->s_blocksize_bits
= 10;
553 sb
->s_magic
= NCP_SUPER_MAGIC
;
554 sb
->s_op
= &ncp_sops
;
555 sb
->s_d_op
= &ncp_dentry_operations
;
556 sb
->s_bdi
= &server
->bdi
;
558 server
= NCP_SBP(sb
);
559 memset(server
, 0, sizeof(*server
));
561 error
= bdi_setup_and_register(&server
->bdi
, "ncpfs", BDI_CAP_MAP_COPY
);
565 server
->ncp_sock
= sock
;
567 if (data
.info_fd
!= -1) {
568 struct socket
*info_sock
= sockfd_lookup(data
.info_fd
, &error
);
571 server
->info_sock
= info_sock
;
573 if (info_sock
->type
!= SOCK_STREAM
)
577 /* server->lock = 0; */
578 mutex_init(&server
->mutex
);
579 server
->packet
= NULL
;
580 /* server->buffer_size = 0; */
581 /* server->conn_status = 0; */
582 /* server->root_dentry = NULL; */
583 /* server->root_setuped = 0; */
584 mutex_init(&server
->root_setup_lock
);
585 #ifdef CONFIG_NCPFS_PACKET_SIGNING
586 /* server->sign_wanted = 0; */
587 /* server->sign_active = 0; */
589 init_rwsem(&server
->auth_rwsem
);
590 server
->auth
.auth_type
= NCP_AUTH_NONE
;
591 /* server->auth.object_name_len = 0; */
592 /* server->auth.object_name = NULL; */
593 /* server->auth.object_type = 0; */
594 /* server->priv.len = 0; */
595 /* server->priv.data = NULL; */
598 /* Although anything producing this is buggy, it happens
599 now because of PATH_MAX changes.. */
600 if (server
->m
.time_out
< 1) {
601 server
->m
.time_out
= 10;
602 printk(KERN_INFO
"You need to recompile your ncpfs utils..\n");
604 server
->m
.time_out
= server
->m
.time_out
* HZ
/ 100;
605 server
->m
.file_mode
= (server
->m
.file_mode
& S_IRWXUGO
) | S_IFREG
;
606 server
->m
.dir_mode
= (server
->m
.dir_mode
& S_IRWXUGO
) | S_IFDIR
;
608 #ifdef CONFIG_NCPFS_NLS
609 /* load the default NLS charsets */
610 server
->nls_vol
= load_nls_default();
611 server
->nls_io
= load_nls_default();
612 #endif /* CONFIG_NCPFS_NLS */
614 atomic_set(&server
->dentry_ttl
, 0); /* no caching */
616 INIT_LIST_HEAD(&server
->tx
.requests
);
617 mutex_init(&server
->rcv
.creq_mutex
);
618 server
->tx
.creq
= NULL
;
619 server
->rcv
.creq
= NULL
;
621 init_timer(&server
->timeout_tm
);
622 #undef NCP_PACKET_SIZE
623 #define NCP_PACKET_SIZE 131072
625 server
->packet_size
= NCP_PACKET_SIZE
;
626 server
->packet
= vmalloc(NCP_PACKET_SIZE
);
627 if (server
->packet
== NULL
)
629 server
->txbuf
= vmalloc(NCP_PACKET_SIZE
);
630 if (server
->txbuf
== NULL
)
632 server
->rxbuf
= vmalloc(NCP_PACKET_SIZE
);
633 if (server
->rxbuf
== NULL
)
637 server
->data_ready
= sock
->sk
->sk_data_ready
;
638 server
->write_space
= sock
->sk
->sk_write_space
;
639 server
->error_report
= sock
->sk
->sk_error_report
;
640 sock
->sk
->sk_user_data
= server
;
641 sock
->sk
->sk_data_ready
= ncp_tcp_data_ready
;
642 sock
->sk
->sk_error_report
= ncp_tcp_error_report
;
643 if (sock
->type
== SOCK_STREAM
) {
644 server
->rcv
.ptr
= (unsigned char*)&server
->rcv
.buf
;
645 server
->rcv
.len
= 10;
646 server
->rcv
.state
= 0;
647 INIT_WORK(&server
->rcv
.tq
, ncp_tcp_rcv_proc
);
648 INIT_WORK(&server
->tx
.tq
, ncp_tcp_tx_proc
);
649 sock
->sk
->sk_write_space
= ncp_tcp_write_space
;
651 INIT_WORK(&server
->rcv
.tq
, ncpdgram_rcv_proc
);
652 INIT_WORK(&server
->timeout_tq
, ncpdgram_timeout_proc
);
653 server
->timeout_tm
.data
= (unsigned long)server
;
654 server
->timeout_tm
.function
= ncpdgram_timeout_call
;
656 release_sock(sock
->sk
);
658 ncp_lock_server(server
);
659 error
= ncp_connect(server
);
660 ncp_unlock_server(server
);
663 DPRINTK("ncp_fill_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb
));
665 error
= -EMSGSIZE
; /* -EREMOTESIDEINCOMPATIBLE */
666 #ifdef CONFIG_NCPFS_PACKET_SIGNING
667 if (ncp_negotiate_size_and_options(server
, default_bufsize
,
668 NCP_DEFAULT_OPTIONS
, &(server
->buffer_size
), &options
) == 0)
670 if (options
!= NCP_DEFAULT_OPTIONS
)
672 if (ncp_negotiate_size_and_options(server
,
675 &(server
->buffer_size
), &options
) != 0)
681 ncp_lock_server(server
);
683 server
->sign_wanted
= 1;
684 ncp_unlock_server(server
);
687 #endif /* CONFIG_NCPFS_PACKET_SIGNING */
688 if (ncp_negotiate_buffersize(server
, default_bufsize
,
689 &(server
->buffer_size
)) != 0)
691 DPRINTK("ncpfs: bufsize = %d\n", server
->buffer_size
);
693 memset(&finfo
, 0, sizeof(finfo
));
694 finfo
.i
.attributes
= aDIR
;
695 finfo
.i
.dataStreamSize
= 0; /* ignored */
696 finfo
.i
.dirEntNum
= 0;
697 finfo
.i
.DosDirNum
= 0;
698 #ifdef CONFIG_NCPFS_SMALLDOS
699 finfo
.i
.NSCreator
= NW_NS_DOS
;
701 finfo
.volume
= NCP_NUMBER_OF_VOLUMES
;
702 /* set dates of mountpoint to Jan 1, 1986; 00:00 */
703 finfo
.i
.creationTime
= finfo
.i
.modifyTime
704 = cpu_to_le16(0x0000);
705 finfo
.i
.creationDate
= finfo
.i
.modifyDate
706 = finfo
.i
.lastAccessDate
707 = cpu_to_le16(0x0C21);
709 finfo
.i
.entryName
[0] = '\0';
712 finfo
.ino
= 2; /* tradition */
714 server
->name_space
[finfo
.volume
] = NW_NS_DOS
;
717 root_inode
= ncp_iget(sb
, &finfo
);
720 DPRINTK("ncp_fill_super: root vol=%d\n", NCP_FINFO(root_inode
)->volNumber
);
721 sb
->s_root
= d_make_root(root_inode
);
727 ncp_lock_server(server
);
728 ncp_disconnect(server
);
729 ncp_unlock_server(server
);
731 ncp_stop_tasks(server
);
732 vfree(server
->rxbuf
);
734 vfree(server
->txbuf
);
736 vfree(server
->packet
);
738 #ifdef CONFIG_NCPFS_NLS
739 unload_nls(server
->nls_io
);
740 unload_nls(server
->nls_vol
);
742 mutex_destroy(&server
->rcv
.creq_mutex
);
743 mutex_destroy(&server
->root_setup_lock
);
744 mutex_destroy(&server
->mutex
);
746 if (server
->info_sock
)
747 sockfd_put(server
->info_sock
);
749 bdi_destroy(&server
->bdi
);
753 put_pid(data
.wdog_pid
);
754 sb
->s_fs_info
= NULL
;
759 static void delayed_free(struct rcu_head
*p
)
761 struct ncp_server
*server
= container_of(p
, struct ncp_server
, rcu
);
762 #ifdef CONFIG_NCPFS_NLS
763 /* unload the NLS charsets */
764 unload_nls(server
->nls_vol
);
765 unload_nls(server
->nls_io
);
766 #endif /* CONFIG_NCPFS_NLS */
770 static void ncp_put_super(struct super_block
*sb
)
772 struct ncp_server
*server
= NCP_SBP(sb
);
774 ncp_lock_server(server
);
775 ncp_disconnect(server
);
776 ncp_unlock_server(server
);
778 ncp_stop_tasks(server
);
780 mutex_destroy(&server
->rcv
.creq_mutex
);
781 mutex_destroy(&server
->root_setup_lock
);
782 mutex_destroy(&server
->mutex
);
784 if (server
->info_sock
)
785 sockfd_put(server
->info_sock
);
786 sockfd_put(server
->ncp_sock
);
787 kill_pid(server
->m
.wdog_pid
, SIGTERM
, 1);
788 put_pid(server
->m
.wdog_pid
);
790 bdi_destroy(&server
->bdi
);
791 kfree(server
->priv
.data
);
792 kfree(server
->auth
.object_name
);
793 vfree(server
->rxbuf
);
794 vfree(server
->txbuf
);
795 vfree(server
->packet
);
796 call_rcu(&server
->rcu
, delayed_free
);
799 static int ncp_statfs(struct dentry
*dentry
, struct kstatfs
*buf
)
803 struct ncp_inode_info
* ni
;
804 struct ncp_server
* s
;
805 struct ncp_volume_info vi
;
806 struct super_block
*sb
= dentry
->d_sb
;
826 if (!s
->m
.mounted_vol
[0]) {
830 err
= ncp_dirhandle_alloc(s
, ni
->volNumber
, ni
->DosDirNum
, &dh
);
834 err
= ncp_get_directory_info(s
, dh
, &vi
);
835 ncp_dirhandle_free(s
, dh
);
839 buf
->f_type
= NCP_SUPER_MAGIC
;
840 buf
->f_bsize
= vi
.sectors_per_block
* 512;
841 buf
->f_blocks
= vi
.total_blocks
;
842 buf
->f_bfree
= vi
.free_blocks
;
843 buf
->f_bavail
= vi
.free_blocks
;
844 buf
->f_files
= vi
.total_dir_entries
;
845 buf
->f_ffree
= vi
.available_dir_entries
;
849 /* We cannot say how much disk space is left on a mounted
850 NetWare Server, because free space is distributed over
851 volumes, and the current user might have disk quotas. So
852 free space is not that simple to determine. Our decision
853 here is to err conservatively. */
856 buf
->f_type
= NCP_SUPER_MAGIC
;
857 buf
->f_bsize
= NCP_BLOCK_SIZE
;
865 int ncp_notify_change(struct dentry
*dentry
, struct iattr
*attr
)
867 struct inode
*inode
= dentry
->d_inode
;
870 struct nw_modify_dos_info info
;
871 struct ncp_server
*server
;
875 server
= NCP_SERVER(inode
);
876 if (!server
) /* How this could happen? */
880 if (IS_DEADDIR(dentry
->d_inode
))
883 /* ageing the dentry to force validation */
884 ncp_age_dentry(server
, dentry
);
886 result
= inode_change_ok(inode
, attr
);
891 if ((attr
->ia_valid
& ATTR_UID
) && !uid_eq(attr
->ia_uid
, server
->m
.uid
))
894 if ((attr
->ia_valid
& ATTR_GID
) && !gid_eq(attr
->ia_gid
, server
->m
.gid
))
897 if (((attr
->ia_valid
& ATTR_MODE
) &&
899 ~(S_IFREG
| S_IFDIR
| S_IRWXUGO
))))
903 memset(&info
, 0, sizeof(info
));
906 if ((attr
->ia_valid
& ATTR_MODE
) != 0)
908 umode_t newmode
= attr
->ia_mode
;
910 info_mask
|= DM_ATTRIBUTES
;
912 if (S_ISDIR(inode
->i_mode
)) {
913 newmode
&= server
->m
.dir_mode
;
915 #ifdef CONFIG_NCPFS_EXTRAS
916 if (server
->m
.flags
& NCP_MOUNT_EXTRAS
) {
917 /* any non-default execute bit set */
918 if (newmode
& ~server
->m
.file_mode
& S_IXUGO
)
919 info
.attributes
|= aSHARED
| aSYSTEM
;
920 /* read for group/world and not in default file_mode */
921 else if (newmode
& ~server
->m
.file_mode
& S_IRUGO
)
922 info
.attributes
|= aSHARED
;
925 newmode
&= server
->m
.file_mode
;
927 if (newmode
& S_IWUGO
)
928 info
.attributes
&= ~(aRONLY
|aRENAMEINHIBIT
|aDELETEINHIBIT
);
930 info
.attributes
|= (aRONLY
|aRENAMEINHIBIT
|aDELETEINHIBIT
);
932 #ifdef CONFIG_NCPFS_NFS_NS
933 if (ncp_is_nfs_extras(server
, NCP_FINFO(inode
)->volNumber
)) {
934 result
= ncp_modify_nfs_info(server
,
935 NCP_FINFO(inode
)->volNumber
,
936 NCP_FINFO(inode
)->dirEntNum
,
940 info
.attributes
&= ~(aSHARED
| aSYSTEM
);
942 /* mark partial success */
943 struct iattr tmpattr
;
945 tmpattr
.ia_valid
= ATTR_MODE
;
946 tmpattr
.ia_mode
= attr
->ia_mode
;
948 setattr_copy(inode
, &tmpattr
);
949 mark_inode_dirty(inode
);
956 /* Do SIZE before attributes, otherwise mtime together with size does not work...
958 if ((attr
->ia_valid
& ATTR_SIZE
) != 0) {
961 DPRINTK("ncpfs: trying to change size to %ld\n",
964 if ((result
= ncp_make_open(inode
, O_WRONLY
)) < 0) {
968 ncp_write_kernel(NCP_SERVER(inode
), NCP_FINFO(inode
)->file_handle
,
969 attr
->ia_size
, 0, "", &written
);
971 /* According to ndir, the changes only take effect after
973 ncp_inode_close(inode
);
974 result
= ncp_make_closed(inode
);
978 if (attr
->ia_size
!= i_size_read(inode
)) {
979 truncate_setsize(inode
, attr
->ia_size
);
980 mark_inode_dirty(inode
);
983 if ((attr
->ia_valid
& ATTR_CTIME
) != 0) {
984 info_mask
|= (DM_CREATE_TIME
| DM_CREATE_DATE
);
985 ncp_date_unix2dos(attr
->ia_ctime
.tv_sec
,
986 &info
.creationTime
, &info
.creationDate
);
988 if ((attr
->ia_valid
& ATTR_MTIME
) != 0) {
989 info_mask
|= (DM_MODIFY_TIME
| DM_MODIFY_DATE
);
990 ncp_date_unix2dos(attr
->ia_mtime
.tv_sec
,
991 &info
.modifyTime
, &info
.modifyDate
);
993 if ((attr
->ia_valid
& ATTR_ATIME
) != 0) {
995 info_mask
|= (DM_LAST_ACCESS_DATE
);
996 ncp_date_unix2dos(attr
->ia_atime
.tv_sec
,
997 &dummy
, &info
.lastAccessDate
);
999 if (info_mask
!= 0) {
1000 result
= ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode
),
1001 inode
, info_mask
, &info
);
1003 if (info_mask
== (DM_CREATE_TIME
| DM_CREATE_DATE
)) {
1004 /* NetWare seems not to allow this. I
1005 do not know why. So, just tell the
1006 user everything went fine. This is
1007 a terrible hack, but I do not know
1008 how to do this correctly. */
1013 #ifdef CONFIG_NCPFS_STRONG
1014 if ((!result
) && (info_mask
& DM_ATTRIBUTES
))
1015 NCP_FINFO(inode
)->nwattr
= info
.attributes
;
1021 setattr_copy(inode
, attr
);
1022 mark_inode_dirty(inode
);
1030 static struct dentry
*ncp_mount(struct file_system_type
*fs_type
,
1031 int flags
, const char *dev_name
, void *data
)
1033 return mount_nodev(fs_type
, flags
, data
, ncp_fill_super
);
1036 static struct file_system_type ncp_fs_type
= {
1037 .owner
= THIS_MODULE
,
1040 .kill_sb
= kill_anon_super
,
1041 .fs_flags
= FS_BINARY_MOUNTDATA
,
1043 MODULE_ALIAS_FS("ncpfs");
1045 static int __init
init_ncp_fs(void)
1048 DPRINTK("ncpfs: init_ncp_fs called\n");
1050 err
= init_inodecache();
1053 err
= register_filesystem(&ncp_fs_type
);
1058 destroy_inodecache();
1063 static void __exit
exit_ncp_fs(void)
1065 DPRINTK("ncpfs: exit_ncp_fs called\n");
1066 unregister_filesystem(&ncp_fs_type
);
1067 destroy_inodecache();
1070 module_init(init_ncp_fs
)
1071 module_exit(exit_ncp_fs
)
1072 MODULE_LICENSE("GPL");