This source file includes following definitions.
- ncp_read_inode
- ncp_put_inode
- ncp_read_super
- ncp_put_super
- ncp_statfs
- ncp_notify_change
- init_ncp_fs
- init_module
- cleanup_module
1
2
3
4
5
6
7
8 #include <linux/module.h>
9
10 #include <asm/system.h>
11 #include <asm/segment.h>
12
13 #include <linux/sched.h>
14 #include <linux/ncp_fs.h>
15 #include <linux/kernel.h>
16 #include <linux/mm.h>
17 #include <linux/string.h>
18 #include <linux/stat.h>
19 #include <linux/errno.h>
20 #include <linux/locks.h>
21 #include <linux/fcntl.h>
22 #include <linux/malloc.h>
23 #include "ncplib_kernel.h"
24
25 extern int close_fp(struct file *filp);
26
27 static void ncp_put_inode(struct inode *);
28 static void ncp_read_inode(struct inode *);
29 static void ncp_put_super(struct super_block *);
30 static void ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz);
31 static int ncp_notify_change(struct inode *inode, struct iattr *attr);
32
33 static struct super_operations ncp_sops = {
34 ncp_read_inode,
35 ncp_notify_change,
36 NULL,
37 ncp_put_inode,
38 ncp_put_super,
39 NULL,
40 ncp_statfs,
41 NULL
42 };
43
44
45
46
47
48 static void
49 ncp_read_inode(struct inode *inode)
50 {
51
52
53
54
55
56
57 struct ncp_inode_info *inode_info
58 = (struct ncp_inode_info *)(inode->i_ino);
59
60 #if 1
61 struct ncp_inode_info *root = &(NCP_SERVER(inode)->root);
62 struct ncp_inode_info *check_info = root;
63
64 do
65 {
66 if (inode_info == check_info)
67 {
68 if (check_info->state == NCP_INODE_LOOKED_UP)
69 {
70 DDPRINTK("ncp_read_inode: found it!\n");
71 goto good;
72 }
73 else
74 {
75 printk("ncp_read_inode: "
76 "state != NCP_INODE_LOOKED_UP\n");
77 goto good;
78 }
79 }
80 check_info = check_info->next;
81 }
82 while (check_info != root);
83
84
85
86 printk("ncp_read_inode: inode info not found\n");
87 return;
88
89 good:
90 DDPRINTK("ncp_read_inode: read entry %s\n",
91 inode_info->finfo.i.entryName);
92 #endif
93 inode_info->state = NCP_INODE_VALID;
94
95 NCP_INOP(inode) = inode_info;
96
97 if (NCP_ISTRUCT(inode)->attributes & aDIR)
98 {
99 inode->i_mode = NCP_SERVER(inode)->m.dir_mode;
100
101
102 inode->i_size = 512;
103 }
104 else
105 {
106 inode->i_mode = NCP_SERVER(inode)->m.file_mode;
107 inode->i_size = NCP_ISTRUCT(inode)->dataStreamSize;
108 }
109
110 DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode->i_mode);
111
112 inode->i_nlink = 1;
113 inode->i_uid = NCP_SERVER(inode)->m.uid;
114 inode->i_gid = NCP_SERVER(inode)->m.gid;
115 inode->i_blksize = 1024;
116 inode->i_rdev = 0;
117
118 if ((inode->i_blksize != 0) && (inode->i_size != 0))
119 {
120 inode->i_blocks =
121 (inode->i_size - 1) / inode->i_blksize + 1;
122 }
123 else
124 {
125 inode->i_blocks = 0;
126 }
127
128 inode->i_mtime = ncp_date_dos2unix(NCP_ISTRUCT(inode)->modifyTime,
129 NCP_ISTRUCT(inode)->modifyDate);
130 inode->i_ctime = ncp_date_dos2unix(NCP_ISTRUCT(inode)->creationTime,
131 NCP_ISTRUCT(inode)->creationDate);
132 inode->i_atime = ncp_date_dos2unix(0,
133 NCP_ISTRUCT(inode)->lastAccessDate);
134
135 if (S_ISREG(inode->i_mode))
136 {
137 inode->i_op = &ncp_file_inode_operations;
138 }
139 else if (S_ISDIR(inode->i_mode))
140 {
141 inode->i_op = &ncp_dir_inode_operations;
142 }
143 else
144 {
145 inode->i_op = NULL;
146 }
147 }
148
149 static void
150 ncp_put_inode(struct inode *inode)
151 {
152 struct nw_file_info *finfo = NCP_FINFO(inode);
153
154 if (finfo->opened != 0)
155 {
156 if (ncp_close_file(NCP_SERVER(inode), finfo->file_handle)!=0)
157 {
158
159 printk("ncp_put_inode: could not close\n");
160 }
161 }
162
163 DDPRINTK("ncp_put_inode: put %s\n",
164 finfo->i.entryName);
165
166 ncp_free_inode_info(NCP_INOP(inode));
167
168 if (S_ISDIR(inode->i_mode))
169 {
170 DDPRINTK("ncp_put_inode: put directory %ld\n",
171 inode->i_ino);
172 ncp_invalid_dir_cache(inode->i_ino);
173 }
174
175 clear_inode(inode);
176 }
177
178 struct super_block *
179 ncp_read_super(struct super_block *sb, void *raw_data, int silent)
180 {
181 struct ncp_mount_data *data = (struct ncp_mount_data *) raw_data;
182 struct ncp_server *server;
183 struct file *ncp_filp;
184 struct file *wdog_filp;
185 kdev_t dev = sb->s_dev;
186 int error;
187
188 if (data == NULL)
189 {
190 printk("ncp_read_super: missing data argument\n");
191 sb->s_dev = 0;
192 return NULL;
193 }
194
195 if (data->version != NCP_MOUNT_VERSION)
196 {
197 printk("ncp warning: mount version %s than kernel\n",
198 (data->version < NCP_MOUNT_VERSION) ?
199 "older" : "newer");
200 }
201
202 if ( (data->ncp_fd >= NR_OPEN)
203 || ((ncp_filp = current->files->fd[data->ncp_fd]) == NULL)
204 || (!S_ISSOCK(ncp_filp->f_inode->i_mode)))
205 {
206 printk("ncp_read_super: invalid ncp socket\n");
207 sb->s_dev = 0;
208 return NULL;
209 }
210
211 if ( (data->wdog_fd >= NR_OPEN)
212 || ((wdog_filp = current->files->fd[data->wdog_fd]) == NULL)
213 || (!S_ISSOCK(wdog_filp->f_inode->i_mode)))
214 {
215 printk("ncp_read_super: invalid wdog socket\n");
216 sb->s_dev = 0;
217 return NULL;
218 }
219
220
221 server = (struct ncp_server *)ncp_kmalloc(sizeof(struct ncp_server),
222 GFP_KERNEL);
223
224 if (server == NULL)
225 {
226 printk("ncp_read_super: could not alloc ncp_server\n");
227 return NULL;
228 }
229
230 ncp_filp->f_count += 1;
231 wdog_filp->f_count += 1;
232
233 lock_super(sb);
234
235 NCP_SBP(sb) = server;
236
237 sb->s_blocksize = 1024;
238 sb->s_blocksize_bits = 10;
239 sb->s_magic = NCP_SUPER_MAGIC;
240 sb->s_dev = dev;
241 sb->s_op = &ncp_sops;
242
243 server->ncp_filp = ncp_filp;
244 server->wdog_filp = wdog_filp;
245 server->lock = 0;
246 server->wait = NULL;
247 server->packet = NULL;
248 server->buffer_size = 0;
249
250 server->m = *data;
251 server->m.file_mode = (server->m.file_mode &
252 (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFREG;
253 server->m.dir_mode = (server->m.dir_mode &
254 (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFDIR;
255
256 server->packet_size = NCP_PACKET_SIZE;
257 server->packet = ncp_kmalloc(NCP_PACKET_SIZE, GFP_KERNEL);
258
259 if (server->packet == NULL)
260 {
261 printk("ncpfs: could not alloc packet\n");
262 error = -ENOMEM;
263 unlock_super(sb);
264 goto fail;
265 }
266
267 ncp_init_root(server);
268
269
270
271
272
273 if (ncp_catch_watchdog(server) != 0)
274 {
275 printk("ncp_read_super: Could not catch watchdog\n");
276 error = -EINVAL;
277 unlock_super(sb);
278 goto fail;
279 }
280
281 ncp_lock_server(server);
282 error = ncp_connect(server);
283 ncp_unlock_server(server);
284 unlock_super(sb);
285
286 if (error < 0)
287 {
288 sb->s_dev = 0;
289 printk("ncp_read_super: Failed connection, bailing out "
290 "(error = %d).\n", -error);
291 ncp_kfree_s(server->packet, server->packet_size);
292 ncp_dont_catch_watchdog(server);
293 goto fail;
294 }
295
296 DPRINTK("ncp_read_super: NCP_SBP(sb) = %x\n", (int)NCP_SBP(sb));
297
298 if (!(sb->s_mounted = iget(sb, (int)&(server->root))))
299 {
300 sb->s_dev = 0;
301 printk("ncp_read_super: get root inode failed\n");
302 goto disconnect;
303 }
304
305 if (ncp_negotiate_buffersize(server, NCP_DEFAULT_BUFSIZE,
306 &(server->buffer_size)) != 0)
307 {
308 sb->s_dev = 0;
309 printk("ncp_read_super: could not get bufsize\n");
310 goto disconnect;
311 }
312
313 DPRINTK("ncpfs: bufsize = %d\n", server->buffer_size);
314
315 MOD_INC_USE_COUNT;
316 return sb;
317
318 disconnect:
319 ncp_lock_server(server);
320 ncp_disconnect(server);
321 ncp_unlock_server(server);
322 ncp_kfree_s(server->packet, server->packet_size);
323 ncp_dont_catch_watchdog(server);
324 fail:
325 ncp_filp->f_count -= 1;
326 wdog_filp->f_count -= 1;
327 ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server));
328 return NULL;
329 }
330
331 static void
332 ncp_put_super(struct super_block *sb)
333 {
334 struct ncp_server *server = NCP_SBP(sb);
335
336 lock_super(sb);
337
338 ncp_lock_server(server);
339 ncp_disconnect(server);
340 ncp_unlock_server(server);
341
342 close_fp(server->ncp_filp);
343
344 ncp_dont_catch_watchdog(server);
345 close_fp(server->wdog_filp);
346
347 ncp_free_all_inodes(server);
348
349 ncp_kfree_s(server->packet, server->packet_size);
350
351 sb->s_dev = 0;
352 ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server));
353 NCP_SBP(sb) = NULL;
354
355 unlock_super(sb);
356
357 MOD_DEC_USE_COUNT;
358 }
359
360 static void
361 ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
362 {
363 struct statfs tmp;
364
365
366
367
368
369
370
371 tmp.f_type = NCP_SUPER_MAGIC;
372 tmp.f_bsize = 512;
373 tmp.f_blocks = 0;
374 tmp.f_bfree = 0;
375 tmp.f_bavail = 0;
376 tmp.f_files = -1;
377 tmp.f_ffree = -1;
378 tmp.f_namelen = 12;
379 memcpy_tofs(buf, &tmp, bufsiz);
380 }
381
382 static int
383 ncp_notify_change(struct inode *inode, struct iattr *attr)
384 {
385 int result = 0;
386 int info_mask;
387 struct nw_modify_dos_info info;
388
389 if ((result = inode_change_ok(inode, attr)) < 0)
390 return result;
391
392 if (((attr->ia_valid & ATTR_UID) &&
393 (attr->ia_uid != NCP_SERVER(inode)->m.uid)))
394 return -EPERM;
395
396 if (((attr->ia_valid & ATTR_GID) &&
397 (attr->ia_uid != NCP_SERVER(inode)->m.gid)))
398 return -EPERM;
399
400 if (((attr->ia_valid & ATTR_MODE) &&
401 (attr->ia_mode &
402 ~(S_IFREG | S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO))))
403 return -EPERM;
404
405 info_mask = 0;
406 memset(&info, 0, sizeof(info));
407
408 if ((attr->ia_valid & ATTR_CTIME) != 0)
409 {
410 info_mask |= (DM_CREATE_TIME|DM_CREATE_DATE);
411 ncp_date_unix2dos(attr->ia_ctime,
412 &(info.creationTime), &(info.creationDate));
413 }
414
415 if ((attr->ia_valid & ATTR_MTIME) != 0)
416 {
417 info_mask |= (DM_MODIFY_TIME|DM_MODIFY_DATE);
418 ncp_date_unix2dos(attr->ia_mtime,
419 &(info.modifyTime), &(info.modifyDate));
420 }
421
422 if ((attr->ia_valid & ATTR_ATIME) != 0)
423 {
424 __u16 dummy;
425 info_mask |= (DM_LAST_ACCESS_DATE);
426 ncp_date_unix2dos(attr->ia_ctime,
427 &(dummy), &(info.lastAccessDate));
428 }
429
430 if (info_mask != 0)
431 {
432 if ((result =
433 ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
434 NCP_ISTRUCT(inode),
435 info_mask,
436 &info)) != 0)
437 {
438 result = -EACCES;
439
440 if (info_mask == (DM_CREATE_TIME|DM_CREATE_DATE))
441 {
442
443
444
445
446
447 result = 0;
448 }
449 }
450 }
451
452 if ((attr->ia_valid & ATTR_SIZE) != 0)
453 {
454 int written;
455
456 DPRINTK("ncpfs: trying to change size of %s to %ld\n",
457 NCP_ISTRUCT(inode)->entryName, attr->ia_size);
458
459 if ((result = ncp_make_open(inode, O_RDWR)) < 0)
460 {
461 return -EACCES;
462 }
463
464 ncp_write(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
465 attr->ia_size, 0, "", &written);
466
467
468
469 ncp_close_file(NCP_SERVER(inode),
470 NCP_FINFO(inode)->file_handle);
471 NCP_FINFO(inode)->opened = 0;
472
473 result = 0;
474 }
475
476 ncp_invalid_dir_cache((unsigned long)(NCP_INOP(inode)->dir));
477
478 return result;
479 }
480
481 #ifdef DEBUG_NCP_MALLOC
482 int ncp_malloced;
483 int ncp_current_malloced;
484 #endif
485
486 static struct file_system_type ncp_fs_type = {
487 ncp_read_super, "ncpfs", 0, NULL
488 };
489
490 int init_ncp_fs(void)
491 {
492 return register_filesystem(&ncp_fs_type);
493 }
494
495 #ifdef MODULE
496 init_module( void)
497 {
498 int status;
499
500 DPRINTK("ncpfs: init_module called\n");
501
502 #ifdef DEBUG_NCP_MALLOC
503 ncp_malloced = 0;
504 ncp_current_malloced = 0;
505 #endif
506 ncp_init_dir_cache();
507
508 if ((status = init_ncp_fs()) == 0)
509 register_symtab(0);
510 return status;
511 }
512
513 void
514 cleanup_module(void)
515 {
516 DPRINTK("ncpfs: cleanup_module called\n");
517 ncp_free_dir_cache();
518 unregister_filesystem(&ncp_fs_type);
519 #ifdef DEBUG_NCP_MALLOC
520 printk("ncp_malloced: %d\n", ncp_malloced);
521 printk("ncp_current_malloced: %d\n", ncp_current_malloced);
522 #endif
523 }
524
525 #endif