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
11 #include <linux/config.h>
12 #include <linux/module.h>
14 #include <asm/system.h>
15 #include <asm/uaccess.h>
16 #include <asm/byteorder.h>
18 #include <linux/sched.h>
19 #include <linux/kernel.h>
21 #include <linux/string.h>
22 #include <linux/stat.h>
23 #include <linux/errno.h>
24 #include <linux/locks.h>
25 #include <linux/file.h>
26 #include <linux/fcntl.h>
27 #include <linux/malloc.h>
28 #include <linux/init.h>
30 #include <linux/ncp_fs.h>
32 #include "ncplib_kernel.h"
34 static void ncp_delete_inode(struct inode
*);
35 static void ncp_put_super(struct super_block
*);
36 static int ncp_statfs(struct super_block
*, struct statfs
*);
38 static struct super_operations ncp_sops
=
40 put_inode
: force_delete
,
41 delete_inode
: ncp_delete_inode
,
42 put_super
: ncp_put_super
,
46 extern struct dentry_operations ncp_dentry_operations
;
47 #ifdef CONFIG_NCPFS_EXTRAS
48 extern struct address_space_operations ncp_symlink_aops
;
49 extern int ncp_symlink(struct inode
*, struct dentry
*, const char*);
53 * Fill in the ncpfs-specific information in the inode.
55 void ncp_update_inode(struct inode
*inode
, struct ncp_entry_info
*nwinfo
)
57 NCP_FINFO(inode
)->DosDirNum
= nwinfo
->i
.DosDirNum
;
58 NCP_FINFO(inode
)->dirEntNum
= nwinfo
->i
.dirEntNum
;
59 NCP_FINFO(inode
)->volNumber
= nwinfo
->i
.volNumber
;
61 #ifdef CONFIG_NCPFS_STRONG
62 NCP_FINFO(inode
)->nwattr
= nwinfo
->i
.attributes
;
64 NCP_FINFO(inode
)->opened
= nwinfo
->opened
;
65 NCP_FINFO(inode
)->access
= nwinfo
->access
;
66 NCP_FINFO(inode
)->server_file_handle
= nwinfo
->server_file_handle
;
67 memcpy(NCP_FINFO(inode
)->file_handle
, nwinfo
->file_handle
,
68 sizeof(nwinfo
->file_handle
));
69 DPRINTK("ncp_update_inode: updated %s, volnum=%d, dirent=%u\n",
70 nwinfo
->i
.entryName
, NCP_FINFO(inode
)->volNumber
,
71 NCP_FINFO(inode
)->dirEntNum
);
74 void ncp_update_inode2(struct inode
* inode
, struct ncp_entry_info
*nwinfo
)
76 struct nw_info_struct
*nwi
= &nwinfo
->i
;
77 struct ncp_server
*server
= NCP_SERVER(inode
);
79 if (!NCP_FINFO(inode
)->opened
) {
80 #ifdef CONFIG_NCPFS_STRONG
81 NCP_FINFO(inode
)->nwattr
= nwi
->attributes
;
83 if (nwi
->attributes
& aDIR
) {
84 inode
->i_mode
= server
->m
.dir_mode
;
85 inode
->i_size
= NCP_BLOCK_SIZE
;
87 inode
->i_mode
= server
->m
.file_mode
;
88 inode
->i_size
= le32_to_cpu(nwi
->dataStreamSize
);
89 #ifdef CONFIG_NCPFS_EXTRAS
90 if ((server
->m
.flags
& (NCP_MOUNT_EXTRAS
|NCP_MOUNT_SYMLINKS
)) && (nwi
->attributes
& aSHARED
)) {
91 switch (nwi
->attributes
& (aHIDDEN
|aSYSTEM
)) {
93 if (server
->m
.flags
& NCP_MOUNT_SYMLINKS
) {
94 if ( /* (inode->i_size >= NCP_MIN_SYMLINK_SIZE)
95 && */ (inode
->i_size
<= NCP_MAX_SYMLINK_SIZE
)) {
96 inode
->i_mode
= (inode
->i_mode
& ~S_IFMT
) | S_IFLNK
;
102 if (server
->m
.flags
& NCP_MOUNT_EXTRAS
)
103 inode
->i_mode
|= 0444;
106 if (server
->m
.flags
& NCP_MOUNT_EXTRAS
)
107 inode
->i_mode
|= (inode
->i_mode
>> 2) & 0111;
109 /* case aSYSTEM|aHIDDEN: */
111 /* reserved combination */
117 if (nwi
->attributes
& aRONLY
) inode
->i_mode
&= ~0222;
119 inode
->i_blocks
= (inode
->i_size
+ NCP_BLOCK_SIZE
- 1) >> NCP_BLOCK_SHIFT
;
121 inode
->i_mtime
= ncp_date_dos2unix(le16_to_cpu(nwi
->modifyTime
),
122 le16_to_cpu(nwi
->modifyDate
));
123 inode
->i_ctime
= ncp_date_dos2unix(le16_to_cpu(nwi
->creationTime
),
124 le16_to_cpu(nwi
->creationDate
));
125 inode
->i_atime
= ncp_date_dos2unix(0, le16_to_cpu(nwi
->lastAccessDate
));
127 NCP_FINFO(inode
)->DosDirNum
= nwi
->DosDirNum
;
128 NCP_FINFO(inode
)->dirEntNum
= nwi
->dirEntNum
;
129 NCP_FINFO(inode
)->volNumber
= nwi
->volNumber
;
133 * Fill in the inode based on the ncp_entry_info structure.
135 static void ncp_set_attr(struct inode
*inode
, struct ncp_entry_info
*nwinfo
)
137 struct nw_info_struct
*nwi
= &nwinfo
->i
;
138 struct ncp_server
*server
= NCP_SERVER(inode
);
140 if (nwi
->attributes
& aDIR
) {
141 inode
->i_mode
= server
->m
.dir_mode
;
142 /* for directories dataStreamSize seems to be some
144 inode
->i_size
= NCP_BLOCK_SIZE
;
146 inode
->i_mode
= server
->m
.file_mode
;
147 inode
->i_size
= le32_to_cpu(nwi
->dataStreamSize
);
148 #ifdef CONFIG_NCPFS_EXTRAS
149 if ((server
->m
.flags
& (NCP_MOUNT_EXTRAS
|NCP_MOUNT_SYMLINKS
))
150 && (nwi
->attributes
& aSHARED
)) {
151 switch (nwi
->attributes
& (aHIDDEN
|aSYSTEM
)) {
153 if (server
->m
.flags
& NCP_MOUNT_SYMLINKS
) {
154 if (/* (inode->i_size >= NCP_MIN_SYMLINK_SIZE)
155 && */ (inode
->i_size
<= NCP_MAX_SYMLINK_SIZE
)) {
156 inode
->i_mode
= (inode
->i_mode
& ~S_IFMT
) | S_IFLNK
;
162 if (server
->m
.flags
& NCP_MOUNT_EXTRAS
)
163 inode
->i_mode
|= 0444;
166 if (server
->m
.flags
& NCP_MOUNT_EXTRAS
)
167 inode
->i_mode
|= (inode
->i_mode
>> 2) & 0111;
169 /* case aSYSTEM|aHIDDEN: */
171 /* reserved combination */
177 if (nwi
->attributes
& aRONLY
) inode
->i_mode
&= ~0222;
179 DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode
->i_mode
);
182 inode
->i_uid
= server
->m
.uid
;
183 inode
->i_gid
= server
->m
.gid
;
185 inode
->i_blksize
= NCP_BLOCK_SIZE
;
187 inode
->i_blocks
= (inode
->i_size
+ NCP_BLOCK_SIZE
- 1) >> NCP_BLOCK_SHIFT
;
189 inode
->i_mtime
= ncp_date_dos2unix(le16_to_cpu(nwi
->modifyTime
),
190 le16_to_cpu(nwi
->modifyDate
));
191 inode
->i_ctime
= ncp_date_dos2unix(le16_to_cpu(nwi
->creationTime
),
192 le16_to_cpu(nwi
->creationDate
));
193 inode
->i_atime
= ncp_date_dos2unix(0,
194 le16_to_cpu(nwi
->lastAccessDate
));
195 ncp_update_inode(inode
, nwinfo
);
198 static struct inode_operations ncp_symlink_inode_operations
= {
199 readlink
: page_readlink
,
200 follow_link
: page_follow_link
,
201 setattr
: ncp_notify_change
,
208 ncp_iget(struct super_block
*sb
, struct ncp_entry_info
*info
)
213 printk(KERN_ERR
"ncp_iget: info is NULL\n");
217 inode
= get_empty_inode();
220 inode
->i_dev
= sb
->s_dev
;
221 inode
->i_ino
= info
->ino
;
222 ncp_set_attr(inode
, info
);
223 if (S_ISREG(inode
->i_mode
)) {
224 inode
->i_op
= &ncp_file_inode_operations
;
225 inode
->i_fop
= &ncp_file_operations
;
226 } else if (S_ISDIR(inode
->i_mode
)) {
227 inode
->i_op
= &ncp_dir_inode_operations
;
228 inode
->i_fop
= &ncp_dir_operations
;
229 #ifdef CONFIG_NCPFS_EXTRAS
230 } else if (S_ISLNK(inode
->i_mode
)) {
231 inode
->i_op
= &ncp_symlink_inode_operations
;
232 inode
->i_data
.a_ops
= &ncp_symlink_aops
;
235 insert_inode_hash(inode
);
237 printk(KERN_ERR
"ncp_iget: iget failed!\n");
242 ncp_delete_inode(struct inode
*inode
)
244 if (S_ISDIR(inode
->i_mode
)) {
245 DDPRINTK("ncp_delete_inode: put directory %ld\n", inode
->i_ino
);
248 if (NCP_FINFO(inode
)->opened
&& ncp_make_closed(inode
) != 0) {
249 /* We can't do anything but complain. */
250 printk(KERN_ERR
"ncp_delete_inode: could not close\n");
256 ncp_read_super(struct super_block
*sb
, void *raw_data
, int silent
)
258 struct ncp_mount_data_kernel data
;
259 struct ncp_server
*server
;
260 struct file
*ncp_filp
;
261 struct inode
*root_inode
;
262 kdev_t dev
= sb
->s_dev
;
264 #ifdef CONFIG_NCPFS_PACKET_SIGNING
267 struct ncp_entry_info finfo
;
269 if (raw_data
== NULL
)
271 switch (*(int*)raw_data
) {
272 case NCP_MOUNT_VERSION
:
274 struct ncp_mount_data
* md
= (struct ncp_mount_data
*)raw_data
;
276 data
.flags
= md
->flags
;
277 data
.int_flags
= NCP_IMOUNT_LOGGEDIN_POSSIBLE
;
278 data
.mounted_uid
= md
->mounted_uid
;
279 data
.wdog_pid
= md
->wdog_pid
;
280 data
.ncp_fd
= md
->ncp_fd
;
281 data
.time_out
= md
->time_out
;
282 data
.retry_count
= md
->retry_count
;
285 data
.file_mode
= md
->file_mode
;
286 data
.dir_mode
= md
->dir_mode
;
287 memcpy(data
.mounted_vol
, md
->mounted_vol
,
291 case NCP_MOUNT_VERSION_V4
:
293 struct ncp_mount_data_v4
* md
= (struct ncp_mount_data_v4
*)raw_data
;
295 data
.flags
= md
->flags
;
297 data
.mounted_uid
= md
->mounted_uid
;
298 data
.wdog_pid
= md
->wdog_pid
;
299 data
.ncp_fd
= md
->ncp_fd
;
300 data
.time_out
= md
->time_out
;
301 data
.retry_count
= md
->retry_count
;
304 data
.file_mode
= md
->file_mode
;
305 data
.dir_mode
= md
->dir_mode
;
306 data
.mounted_vol
[0] = 0;
312 ncp_filp
= fget(data
.ncp_fd
);
315 if (!S_ISSOCK(ncp_filp
->f_dentry
->d_inode
->i_mode
))
318 sb
->s_blocksize
= 1024; /* Eh... Is this correct? */
319 sb
->s_blocksize_bits
= 10;
320 sb
->s_magic
= NCP_SUPER_MAGIC
;
322 sb
->s_op
= &ncp_sops
;
324 server
= NCP_SBP(sb
);
325 memset(server
, 0, sizeof(*server
));
327 server
->ncp_filp
= ncp_filp
;
328 /* server->lock = 0; */
329 init_MUTEX(&server
->sem
);
330 server
->packet
= NULL
;
331 /* server->buffer_size = 0; */
332 /* server->conn_status = 0; */
333 /* server->root_dentry = NULL; */
334 /* server->root_setuped = 0; */
335 #ifdef CONFIG_NCPFS_PACKET_SIGNING
336 /* server->sign_wanted = 0; */
337 /* server->sign_active = 0; */
339 server
->auth
.auth_type
= NCP_AUTH_NONE
;
340 /* server->auth.object_name_len = 0; */
341 /* server->auth.object_name = NULL; */
342 /* server->auth.object_type = 0; */
343 /* server->priv.len = 0; */
344 /* server->priv.data = NULL; */
347 /* Althought anything producing this is buggy, it happens
348 now because of PATH_MAX changes.. */
349 if (server
->m
.time_out
< 1) {
350 server
->m
.time_out
= 10;
351 printk(KERN_INFO
"You need to recompile your ncpfs utils..\n");
353 server
->m
.time_out
= server
->m
.time_out
* HZ
/ 100;
354 server
->m
.file_mode
= (server
->m
.file_mode
&
355 (S_IRWXU
| S_IRWXG
| S_IRWXO
)) | S_IFREG
;
356 server
->m
.dir_mode
= (server
->m
.dir_mode
&
357 (S_IRWXU
| S_IRWXG
| S_IRWXO
)) | S_IFDIR
;
359 #ifdef CONFIG_NCPFS_NLS
360 /* load the default NLS charsets */
361 server
->nls_vol
= load_nls_default();
362 server
->nls_io
= load_nls_default();
363 #endif /* CONFIG_NCPFS_NLS */
365 server
->dentry_ttl
= 0; /* no caching */
367 server
->packet_size
= NCP_PACKET_SIZE
;
368 server
->packet
= ncp_kmalloc(NCP_PACKET_SIZE
, GFP_KERNEL
);
369 if (server
->packet
== NULL
)
372 ncp_lock_server(server
);
373 error
= ncp_connect(server
);
374 ncp_unlock_server(server
);
377 DPRINTK("ncp_read_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb
));
379 #ifdef CONFIG_NCPFS_PACKET_SIGNING
380 if (ncp_negotiate_size_and_options(server
, NCP_DEFAULT_BUFSIZE
,
381 NCP_DEFAULT_OPTIONS
, &(server
->buffer_size
), &options
) == 0)
383 if (options
!= NCP_DEFAULT_OPTIONS
)
385 if (ncp_negotiate_size_and_options(server
,
388 &(server
->buffer_size
), &options
) != 0)
395 server
->sign_wanted
= 1;
398 #endif /* CONFIG_NCPFS_PACKET_SIGNING */
399 if (ncp_negotiate_buffersize(server
, NCP_DEFAULT_BUFSIZE
,
400 &(server
->buffer_size
)) != 0)
402 DPRINTK("ncpfs: bufsize = %d\n", server
->buffer_size
);
404 memset(&finfo
, 0, sizeof(finfo
));
405 finfo
.i
.attributes
= aDIR
;
406 finfo
.i
.dataStreamSize
= NCP_BLOCK_SIZE
;
407 finfo
.i
.dirEntNum
= 0;
408 finfo
.i
.DosDirNum
= 0;
409 #ifdef CONFIG_NCPFS_SMALLDOS
410 finfo
.i
.NSCreator
= NW_NS_DOS
;
412 finfo
.i
.volNumber
= NCP_NUMBER_OF_VOLUMES
+ 1; /* illegal volnum */
413 /* set dates of mountpoint to Jan 1, 1986; 00:00 */
414 finfo
.i
.creationTime
= finfo
.i
.modifyTime
415 = cpu_to_le16(0x0000);
416 finfo
.i
.creationDate
= finfo
.i
.modifyDate
417 = finfo
.i
.lastAccessDate
418 = cpu_to_le16(0x0C21);
420 finfo
.i
.entryName
[0] = '\0';
423 finfo
.ino
= 2; /* tradition */
425 server
->name_space
[finfo
.i
.volNumber
] = NW_NS_DOS
;
426 root_inode
= ncp_iget(sb
, &finfo
);
429 DPRINTK("ncp_read_super: root vol=%d\n", NCP_FINFO(root_inode
)->volNumber
);
430 sb
->s_root
= d_alloc_root(root_inode
);
433 sb
->s_root
->d_op
= &ncp_dentry_operations
;
437 printk(KERN_ERR
"ncp_read_super: get root inode failed\n");
441 printk(KERN_ERR
"ncp_read_super: could not get bufsize\n");
443 ncp_lock_server(server
);
444 ncp_disconnect(server
);
445 ncp_unlock_server(server
);
446 goto out_free_packet
;
448 printk(KERN_ERR
"ncp_read_super: Failed connection, error=%d\n", error
);
450 ncp_kfree_s(server
->packet
, server
->packet_size
);
451 goto out_free_server
;
453 printk(KERN_ERR
"ncp_read_super: could not alloc packet\n");
455 #ifdef CONFIG_NCPFS_NLS
456 unload_nls(server
->nls_io
);
457 unload_nls(server
->nls_vol
);
459 /* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:
461 * The previously used put_filp(ncp_filp); was bogous, since
462 * it doesn't proper unlocking.
470 printk(KERN_ERR
"ncp_read_super: invalid ncp socket\n");
473 printk(KERN_INFO
"ncp_read_super: kernel requires mount version %d\n",
477 printk(KERN_ERR
"ncp_read_super: missing data argument\n");
482 static void ncp_put_super(struct super_block
*sb
)
484 struct ncp_server
*server
= NCP_SBP(sb
);
486 ncp_lock_server(server
);
487 ncp_disconnect(server
);
488 ncp_unlock_server(server
);
490 #ifdef CONFIG_NCPFS_NLS
491 /* unload the NLS charsets */
494 unload_nls(server
->nls_vol
);
495 server
->nls_vol
= NULL
;
499 unload_nls(server
->nls_io
);
500 server
->nls_io
= NULL
;
502 #endif /* CONFIG_NCPFS_NLS */
504 fput(server
->ncp_filp
);
505 kill_proc(server
->m
.wdog_pid
, SIGTERM
, 1);
507 if (server
->priv
.data
)
508 ncp_kfree_s(server
->priv
.data
, server
->priv
.len
);
509 if (server
->auth
.object_name
)
510 ncp_kfree_s(server
->auth
.object_name
, server
->auth
.object_name_len
);
511 ncp_kfree_s(server
->packet
, server
->packet_size
);
515 static int ncp_statfs(struct super_block
*sb
, struct statfs
*buf
)
517 /* We cannot say how much disk space is left on a mounted
518 NetWare Server, because free space is distributed over
519 volumes, and the current user might have disk quotas. So
520 free space is not that simple to determine. Our decision
521 here is to err conservatively. */
523 buf
->f_type
= NCP_SUPER_MAGIC
;
524 buf
->f_bsize
= NCP_BLOCK_SIZE
;
532 int ncp_notify_change(struct dentry
*dentry
, struct iattr
*attr
)
534 struct inode
*inode
= dentry
->d_inode
;
537 struct nw_modify_dos_info info
;
538 struct ncp_server
*server
;
542 server
= NCP_SERVER(inode
);
543 if ((!server
) || !ncp_conn_valid(server
))
546 /* ageing the dentry to force validation */
547 ncp_age_dentry(server
, dentry
);
549 result
= inode_change_ok(inode
, attr
);
554 if (((attr
->ia_valid
& ATTR_UID
) &&
555 (attr
->ia_uid
!= server
->m
.uid
)))
558 if (((attr
->ia_valid
& ATTR_GID
) &&
559 (attr
->ia_gid
!= server
->m
.gid
)))
562 if (((attr
->ia_valid
& ATTR_MODE
) &&
564 ~(S_IFREG
| S_IFDIR
| S_IRWXU
| S_IRWXG
| S_IRWXO
))))
568 memset(&info
, 0, sizeof(info
));
571 if ((attr
->ia_valid
& ATTR_MODE
) != 0)
573 if (S_ISDIR(inode
->i_mode
)) {
576 info_mask
|= DM_ATTRIBUTES
;
577 newmode
= attr
->ia_mode
;
578 newmode
&= NCP_SERVER(inode
)->m
.dir_mode
;
581 info
.attributes
&= ~(aRONLY
|aRENAMEINHIBIT
|aDELETEINHIBIT
);
583 info
.attributes
|= (aRONLY
|aRENAMEINHIBIT
|aDELETEINHIBIT
);
584 } else if (!S_ISREG(inode
->i_mode
))
591 #ifdef CONFIG_NCPFS_EXTRAS
594 extras
= server
->m
.flags
& NCP_MOUNT_EXTRAS
;
596 info_mask
|= DM_ATTRIBUTES
;
597 newmode
=attr
->ia_mode
;
598 #ifdef CONFIG_NCPFS_EXTRAS
601 newmode
&= server
->m
.file_mode
;
603 if (newmode
& 0222) /* any write bit set */
605 info
.attributes
&= ~(aRONLY
|aRENAMEINHIBIT
|aDELETEINHIBIT
);
609 info
.attributes
|= (aRONLY
|aRENAMEINHIBIT
|aDELETEINHIBIT
);
611 #ifdef CONFIG_NCPFS_EXTRAS
613 if (newmode
& 0111) /* any execute bit set */
614 info
.attributes
|= aSHARED
| aSYSTEM
;
615 /* read for group/world and not in default file_mode */
616 else if (newmode
& ~server
->m
.file_mode
& 0444)
617 info
.attributes
|= aSHARED
;
624 if ((attr
->ia_valid
& ATTR_CTIME
) != 0) {
625 info_mask
|= (DM_CREATE_TIME
| DM_CREATE_DATE
);
626 ncp_date_unix2dos(attr
->ia_ctime
,
627 &(info
.creationTime
), &(info
.creationDate
));
628 info
.creationTime
= le16_to_cpu(info
.creationTime
);
629 info
.creationDate
= le16_to_cpu(info
.creationDate
);
631 if ((attr
->ia_valid
& ATTR_MTIME
) != 0) {
632 info_mask
|= (DM_MODIFY_TIME
| DM_MODIFY_DATE
);
633 ncp_date_unix2dos(attr
->ia_mtime
,
634 &(info
.modifyTime
), &(info
.modifyDate
));
635 info
.modifyTime
= le16_to_cpu(info
.modifyTime
);
636 info
.modifyDate
= le16_to_cpu(info
.modifyDate
);
638 if ((attr
->ia_valid
& ATTR_ATIME
) != 0) {
640 info_mask
|= (DM_LAST_ACCESS_DATE
);
641 ncp_date_unix2dos(attr
->ia_ctime
,
642 &(dummy
), &(info
.lastAccessDate
));
643 info
.lastAccessDate
= le16_to_cpu(info
.lastAccessDate
);
645 if (info_mask
!= 0) {
646 result
= ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode
),
647 inode
, info_mask
, &info
);
651 if (info_mask
== (DM_CREATE_TIME
| DM_CREATE_DATE
)) {
652 /* NetWare seems not to allow this. I
653 do not know why. So, just tell the
654 user everything went fine. This is
655 a terrible hack, but I do not know
656 how to do this correctly. */
660 #ifdef CONFIG_NCPFS_STRONG
661 if ((!result
) && (info_mask
& DM_ATTRIBUTES
))
662 NCP_FINFO(inode
)->nwattr
= info
.attributes
;
665 if ((attr
->ia_valid
& ATTR_SIZE
) != 0) {
668 DPRINTK("ncpfs: trying to change size to %ld\n",
671 if ((result
= ncp_make_open(inode
, O_WRONLY
)) < 0) {
674 ncp_write_kernel(NCP_SERVER(inode
), NCP_FINFO(inode
)->file_handle
,
675 attr
->ia_size
, 0, "", &written
);
677 /* According to ndir, the changes only take effect after
679 result
= ncp_make_closed(inode
);
681 vmtruncate(inode
, attr
->ia_size
);
687 #ifdef DEBUG_NCP_MALLOC
689 int ncp_current_malloced
;
692 static DECLARE_FSTYPE(ncp_fs_type
, "ncpfs", ncp_read_super
, 0);
694 static int __init
init_ncp_fs(void)
696 DPRINTK("ncpfs: init_module called\n");
698 #ifdef DEBUG_NCP_MALLOC
700 ncp_current_malloced
= 0;
702 return register_filesystem(&ncp_fs_type
);
705 static void __exit
exit_ncp_fs(void)
707 DPRINTK("ncpfs: cleanup_module called\n");
708 unregister_filesystem(&ncp_fs_type
);
709 #ifdef DEBUG_NCP_MALLOC
710 PRINTK("ncp_malloced: %d\n", ncp_malloced
);
711 PRINTK("ncp_current_malloced: %d\n", ncp_current_malloced
);
717 module_init(init_ncp_fs
)
718 module_exit(exit_ncp_fs
)