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>
24 #include <linux/fcntl.h>
25 #include <linux/slab.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 *);
65 static void ncp_destroy_inode(
struct inode *inode)
70 static void init_once(
void *
foo)
78 static int init_inodecache(
void)
85 if (ncp_inode_cachep ==
NULL)
90 static void destroy_inodecache(
void)
108 .alloc_inode = ncp_alloc_inode,
109 .destroy_inode = ncp_destroy_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,
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;
130 ncp_update_dirent(inode, nwinfo);
131 NCP_FINFO(inode)->nwattr = nwinfo->
i.attributes;
132 NCP_FINFO(inode)->access = nwinfo->
access;
135 DPRINTK(
"ncp_update_inode: updated %s, volnum=%d, dirent=%u\n",
136 nwinfo->
i.entryName, NCP_FINFO(inode)->
volNumber,
140 static void ncp_update_dates(
struct inode *inode,
struct nw_info_struct *nwi)
147 inode->
i_mode = nwi->nfs.mode;
160 static void ncp_update_attrs(
struct inode *inode,
struct ncp_entry_info *nwinfo)
166 inode->
i_mode = server->
m.dir_mode;
173 inode->
i_mode = server->
m.file_mode;
175 i_size_write(inode, size);
176 #ifdef CONFIG_NCPFS_EXTRAS
211 NCP_FINFO(inode)->flags = 0;
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);
224 static void ncp_set_attr(
struct inode *inode,
struct ncp_entry_info *nwinfo)
228 NCP_FINFO(inode)->flags = 0;
230 ncp_update_attrs(inode, nwinfo);
235 inode->
i_uid = server->
m.uid;
236 inode->
i_gid = server->
m.gid;
238 ncp_update_dates(inode, &nwinfo->
i);
242 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
270 ncp_set_attr(inode, info);
277 #ifdef CONFIG_NCPFS_NFS_NS
280 new_decode_dev(info->
i.nfs.rdev));
282 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
284 inode->
i_op = &ncp_symlink_inode_operations;
290 insert_inode_hash(inode);
297 ncp_evict_inode(
struct inode *inode)
303 DDPRINTK(
"ncp_evict_inode: put directory %ld\n", inode->
i_ino);
312 static void ncp_stop_tasks(
struct ncp_server *server) {
329 static int ncp_show_options(
struct seq_file *seq,
struct dentry *root)
334 if (server->
m.uid != 0)
336 if (server->
m.gid != 0)
338 if (server->
m.mounted_uid != 0)
339 seq_printf(seq,
",owner=%u", server->
m.mounted_uid);
347 tmp = server->
m.time_out * 100 /
HZ;
351 seq_printf(seq,
",retry=%u", server->
m.retry_count);
352 if (server->
m.flags != 0)
354 if (server->
m.wdog_pid !=
NULL)
378 unsigned long optint;
396 while ((optval =
ncp_getopt(
"ncpfs", &options, ncp_opts,
NULL, &optarg, &optint)) != 0) {
423 data->
flags = optint;
452 static int ncp_fill_super(
struct super_block *sb,
void *raw_data,
int silent)
456 struct file *ncp_filp;
457 struct inode *root_inode;
458 struct inode *sock_inode;
462 #ifdef CONFIG_NCPFS_PACKET_SIGNING
467 memset(&data, 0,
sizeof(data));
474 if (raw_data ==
NULL)
476 switch (*(
int*)raw_data) {
516 if (
memcmp(raw_data,
"vers", 4) == 0) {
517 error = ncp_parse_options(&data, raw_data);
528 sock_inode = ncp_filp->
f_path.dentry->d_inode;
531 sock = SOCKET_I(sock_inode);
536 default_bufsize = 0xF000;
538 default_bufsize = 1024;
545 sb->
s_op = &ncp_sops;
549 server = NCP_SBP(sb);
550 memset(server, 0,
sizeof(*server));
567 sock_inode = server->
info_filp->f_path.dentry->d_inode;
570 info_sock = SOCKET_I(sock_inode);
587 #ifdef CONFIG_NCPFS_PACKET_SIGNING
602 if (server->
m.time_out < 1) {
603 server->
m.time_out = 10;
606 server->
m.time_out = server->
m.time_out *
HZ / 100;
610 #ifdef CONFIG_NCPFS_NLS
618 INIT_LIST_HEAD(&server->
tx.requests);
624 #undef NCP_PACKET_SIZE
625 #define NCP_PACKET_SIZE 131072
642 sock->
sk->sk_user_data = server;
646 server->
rcv.ptr = (
unsigned char*)&server->
rcv.buf;
647 server->
rcv.len = 10;
648 server->
rcv.state = 0;
665 DPRINTK(
"ncp_fill_super: NCP_SBP(sb) = %x\n", (
int) NCP_SBP(sb));
668 #ifdef CONFIG_NCPFS_PACKET_SIGNING
695 memset(&finfo, 0,
sizeof(finfo));
696 finfo.i.attributes =
aDIR;
697 finfo.i.dataStreamSize = 0;
698 finfo.i.dirEntNum = 0;
699 finfo.i.DosDirNum = 0;
700 #ifdef CONFIG_NCPFS_SMALLDOS
705 finfo.i.creationTime = finfo.i.modifyTime
707 finfo.i.creationDate = finfo.i.modifyDate
708 = finfo.i.lastAccessDate
711 finfo.i.entryName[0] =
'\0';
733 ncp_stop_tasks(server);
740 #ifdef CONFIG_NCPFS_NLS
774 ncp_stop_tasks(server);
776 #ifdef CONFIG_NCPFS_NLS
828 if (!s->
m.mounted_vol[0]) {
842 buf->
f_bsize = vi.sectors_per_block * 512;
846 buf->
f_files = vi.total_dir_entries;
847 buf->
f_ffree = vi.available_dir_entries;
869 struct inode *inode = dentry->
d_inode;
882 ncp_age_dentry(server, dentry);
890 (attr->
ia_uid != server->
m.uid)))
894 (attr->
ia_gid != server->
m.gid)))
903 memset(&info, 0,
sizeof(info));
913 newmode &= server->
m.dir_mode;
915 #ifdef CONFIG_NCPFS_EXTRAS
918 if (newmode & ~server->
m.file_mode &
S_IXUGO)
921 else if (newmode & ~server->
m.file_mode &
S_IRUGO)
925 newmode &= server->
m.file_mode;
932 #ifdef CONFIG_NCPFS_NFS_NS
933 if (ncp_is_nfs_extras(server, NCP_FINFO(inode)->volNumber)) {
943 struct iattr tmpattr;
949 mark_inode_dirty(inode);
961 DPRINTK(
"ncpfs: trying to change size to %ld\n",
969 attr->
ia_size, 0,
"", &written);
973 ncp_inode_close(inode);
978 if (attr->
ia_size != i_size_read(inode)) {
982 mark_inode_dirty(inode);
1001 if (info_mask != 0) {
1003 inode, info_mask, &info);
1015 #ifdef CONFIG_NCPFS_STRONG
1024 mark_inode_dirty(inode);
1033 int flags,
const char *dev_name,
void *data)
1035 return mount_nodev(fs_type, flags, data, ncp_fill_super);
1046 static int __init init_ncp_fs(
void)
1049 DPRINTK(
"ncpfs: init_ncp_fs called\n");
1051 err = init_inodecache();
1059 destroy_inodecache();
1064 static void __exit exit_ncp_fs(
void)
1066 DPRINTK(
"ncpfs: exit_ncp_fs called\n");
1068 destroy_inodecache();