This source file includes following definitions.
- UMSDOS_put_inode
- UMSDOS_put_super
- UMSDOS_statfs
- umsdos_real_lookup
- umsdos_setup_dir_inode
- umsdos_set_dirinfo
- umsdos_isinit
- umsdos_patch_inode
- umsdos_get_dirowner
- UMSDOS_read_inode
- UMSDOS_write_inode
- UMSDOS_notify_change
- UMSDOS_read_super
- init_module
- cleanup_module
1
2
3
4
5
6
7
8
9 #include <stdlib.h>
10 #include <linux/fs.h>
11 #include <linux/msdos_fs.h>
12 #include <linux/kernel.h>
13 #include <linux/sched.h>
14 #include <linux/errno.h>
15 #include <asm/segment.h>
16 #include <linux/string.h>
17 #include <linux/ctype.h>
18 #include <linux/stat.h>
19 #include <linux/umsdos_fs.h>
20
21 #ifdef MODULE
22 #include <linux/module.h>
23 #include "../../tools/version.h"
24 #endif
25
26 struct inode *pseudo_root=NULL;
27
28
29
30
31
32
33
34
35
36
37
38
39
40 #define PRINTK(x)
41 #define Printk(x) printk x
42
43
44 void UMSDOS_put_inode(struct inode *inode)
45 {
46 PRINTK (("put inode %x owner %x pos %d dir %x\n",inode
47 ,inode->u.umsdos_i.i_emd_owner,inode->u.umsdos_i.pos
48 ,inode->u.umsdos_i.i_emd_dir));
49 msdos_put_inode(inode);
50 }
51
52
53 void UMSDOS_put_super(struct super_block *sb)
54 {
55 msdos_put_super(sb);
56 #ifdef MODULE
57 MOD_DEC_USE_COUNT;
58 #endif
59 }
60
61
62 void UMSDOS_statfs(struct super_block *sb,struct statfs *buf)
63 {
64 msdos_statfs(sb,buf);
65 }
66
67
68
69
70
71
72 int umsdos_real_lookup (
73 struct inode *dir,
74 const char *name,
75 int len,
76 struct inode **result)
77 {
78 int ret;
79 dir->i_count++;
80 ret = msdos_lookup (dir,name,len,result);
81 return ret;
82 }
83
84
85
86
87
88
89 void umsdos_setup_dir_inode (struct inode *inode)
90 {
91 inode->u.umsdos_i.i_emd_dir = 0;
92 {
93 struct inode *emd_dir = umsdos_emd_dir_lookup (inode,0);
94 extern struct inode_operations umsdos_rdir_inode_operations;
95 inode->i_op = emd_dir != NULL
96 ? &umsdos_dir_inode_operations
97 : &umsdos_rdir_inode_operations;
98 iput (emd_dir);
99 }
100 }
101
102
103
104 void umsdos_set_dirinfo(
105 struct inode *inode,
106 struct inode *dir,
107 off_t f_pos)
108 {
109 struct inode *emd_owner = umsdos_emd_dir_lookup(dir,1);
110 inode->u.umsdos_i.i_dir_owner = dir->i_ino;
111 inode->u.umsdos_i.i_emd_owner = emd_owner->i_ino;
112 iput (emd_owner);
113 inode->u.umsdos_i.pos = f_pos;
114 }
115
116
117
118
119 int umsdos_isinit (struct inode *inode)
120 {
121 #if 1
122 return inode->u.umsdos_i.i_emd_owner != 0;
123 #elif 0
124 return inode->i_atime != 0;
125 #else
126 return inode->i_count > 1;
127 #endif
128 }
129
130
131
132 void umsdos_patch_inode (
133 struct inode *inode,
134 struct inode *dir,
135 off_t f_pos)
136 {
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153 if (!umsdos_isinit(inode)){
154 inode->u.umsdos_i.i_emd_dir = 0;
155 if (S_ISREG(inode->i_mode)){
156 static char is_init = 0;
157 if (!is_init){
158
159
160
161
162
163 umsdos_file_inode_operations.bmap = inode->i_op->bmap;
164 inode->i_op = &umsdos_file_inode_operations;
165 is_init = 1;
166 }
167 inode->i_op = &umsdos_file_inode_operations;
168 }else if (S_ISDIR(inode->i_mode)){
169 if (dir != NULL){
170 umsdos_setup_dir_inode(inode);
171 }
172 }else if (S_ISLNK(inode->i_mode)){
173 inode->i_op = &umsdos_symlink_inode_operations;
174 }else if (S_ISCHR(inode->i_mode)){
175 inode->i_op = &chrdev_inode_operations;
176 }else if (S_ISBLK(inode->i_mode)){
177 inode->i_op = &blkdev_inode_operations;
178 }else if (S_ISFIFO(inode->i_mode)){
179 init_fifo(inode);
180 }
181 if (dir != NULL){
182
183
184
185
186
187
188
189
190
191
192 umsdos_set_dirinfo (inode,dir,f_pos);
193 }
194 }else if (dir != NULL){
195
196
197
198
199 struct inode *emd_owner = umsdos_emd_dir_lookup(dir,1);
200 iput (emd_owner);
201 if (emd_owner->i_ino != inode->u.umsdos_i.i_emd_owner){
202 printk ("UMSDOS: *** EMD_OWNER ??? *** ino = %ld %ld <> %ld "
203 ,inode->i_ino,emd_owner->i_ino,inode->u.umsdos_i.i_emd_owner);
204 }
205 }
206 }
207
208
209
210
211 int umsdos_get_dirowner(
212 struct inode *inode,
213 struct inode **result)
214
215 {
216 int ret = -EIO;
217 unsigned long ino = inode->u.umsdos_i.i_dir_owner;
218 *result = NULL;
219 if (ino == 0){
220 printk ("UMSDOS: umsdos_get_dirowner ino == 0\n");
221 }else{
222 struct inode *dir = *result = iget(inode->i_sb,ino);
223 if (dir != NULL){
224 umsdos_patch_inode (dir,NULL,0);
225 ret = 0;
226 }
227 }
228 return ret;
229 }
230
231
232
233 void UMSDOS_read_inode(struct inode *inode)
234 {
235 PRINTK (("read inode %x ino = %d ",inode,inode->i_ino));
236 msdos_read_inode(inode);
237 PRINTK (("ino = %d %d\n",inode->i_ino,inode->i_count));
238 if (S_ISDIR(inode->i_mode)
239 && (inode->u.umsdos_i.u.dir_info.creating != 0
240 || inode->u.umsdos_i.u.dir_info.looking != 0
241 || inode->u.umsdos_i.u.dir_info.p != NULL)){
242 Printk (("read inode %d %d %p\n"
243 ,inode->u.umsdos_i.u.dir_info.creating
244 ,inode->u.umsdos_i.u.dir_info.looking
245 ,inode->u.umsdos_i.u.dir_info.p));
246 }
247
248
249
250
251
252
253
254
255
256
257
258
259
260 umsdos_patch_inode(inode,NULL,0);
261 }
262
263
264
265
266 void UMSDOS_write_inode(struct inode *inode)
267 {
268 struct iattr newattrs;
269
270 PRINTK (("UMSDOS_write_inode emd %d\n",inode->u.umsdos_i.i_emd_owner));
271 msdos_write_inode(inode);
272 newattrs.ia_mtime = inode->i_mtime;
273 newattrs.ia_atime = inode->i_atime;
274 newattrs.ia_ctime = inode->i_ctime;
275 newattrs.ia_valid = ATTR_MTIME | ATTR_ATIME | ATTR_CTIME;
276
277
278
279
280
281 UMSDOS_notify_change (inode, &newattrs);
282 inode->i_dirt = 0;
283 }
284
285 int UMSDOS_notify_change(struct inode *inode, struct iattr *attr)
286 {
287 int ret = 0;
288
289 if ((ret = inode_change_ok(inode, attr)) != 0)
290 return ret;
291
292 if (inode->i_nlink > 0){
293
294
295
296
297
298 unsigned long i_emd_owner = inode->u.umsdos_i.i_emd_owner;
299 if (inode == inode->i_sb->s_mounted){
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314 }else if (i_emd_owner != 0xffffffff && i_emd_owner != 0){
315
316
317
318
319 struct inode *emd_owner = iget (inode->i_sb,i_emd_owner);
320 PRINTK (("notify change %p ",inode));
321 if (emd_owner == NULL){
322 printk ("UMSDOS: emd_owner = NULL ???");
323 ret = -EPERM;
324 }else{
325 struct file filp;
326 struct umsdos_dirent entry;
327 filp.f_pos = inode->u.umsdos_i.pos;
328 filp.f_reada = 0;
329 PRINTK (("pos = %d ",filp.f_pos));
330
331
332 ret = umsdos_emd_dir_read (emd_owner,&filp,(char*)&entry
333 ,UMSDOS_REC_SIZE);
334 if (ret == 0){
335 if (attr->ia_valid & ATTR_UID)
336 entry.uid = attr->ia_uid;
337 if (attr->ia_valid & ATTR_GID)
338 entry.gid = attr->ia_gid;
339 if (attr->ia_valid & ATTR_MODE)
340 entry.mode = attr->ia_mode;
341 if (attr->ia_valid & ATTR_ATIME)
342 entry.atime = attr->ia_atime;
343 if (attr->ia_valid & ATTR_MTIME)
344 entry.mtime = attr->ia_mtime;
345 if (attr->ia_valid & ATTR_CTIME)
346 entry.ctime = attr->ia_ctime;
347
348 entry.nlink = inode->i_nlink;
349 filp.f_pos = inode->u.umsdos_i.pos;
350 ret = umsdos_emd_dir_write (emd_owner,&filp,(char*)&entry
351 ,UMSDOS_REC_SIZE);
352
353 PRINTK (("notify pos %d ret %d nlink %d "
354 ,inode->u.umsdos_i.pos
355 ,ret,entry.nlink));
356
357
358
359
360 }
361 iput (emd_owner);
362 }
363 PRINTK (("\n"));
364 }
365 }
366 if (ret == 0)
367 inode_setattr(inode, attr);
368 return ret;
369 }
370
371
372
373
374
375
376
377
378
379
380 static struct super_operations umsdos_sops = {
381 UMSDOS_read_inode,
382 UMSDOS_notify_change,
383 UMSDOS_write_inode,
384 UMSDOS_put_inode,
385 UMSDOS_put_super,
386 NULL,
387 UMSDOS_statfs,
388 NULL
389 };
390
391
392
393
394 struct super_block *UMSDOS_read_super(
395 struct super_block *s,
396 void *data,
397 int silent)
398 {
399
400
401
402
403
404
405
406
407
408
409
410
411
412 struct super_block *sb = msdos_read_super(s,data,silent);
413 printk ("UMSDOS Alpha 0.5 (compatibility level %d.%d, fast msdos)\n"
414 ,UMSDOS_VERSION,UMSDOS_RELEASE);
415 if (sb != NULL){
416 sb->s_op = &umsdos_sops;
417 PRINTK (("umsdos_read_super %p\n",sb->s_mounted));
418 umsdos_setup_dir_inode (sb->s_mounted);
419 PRINTK (("End umsdos_read_super\n"));
420 if (s == super_blocks){
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452 struct inode *pseudo;
453 Printk (("Mounting root\n"));
454 if (umsdos_real_lookup (sb->s_mounted,UMSDOS_PSDROOT_NAME
455 ,UMSDOS_PSDROOT_LEN,&pseudo)==0
456 && S_ISDIR(pseudo->i_mode)){
457 struct inode *etc = NULL;
458 struct inode *rc = NULL;
459 Printk (("/%s is there\n",UMSDOS_PSDROOT_NAME));
460 if (umsdos_real_lookup (pseudo,"etc",3,&etc)==0
461 && S_ISDIR(etc->i_mode)){
462 struct inode *init;
463 Printk (("/%s/etc is there\n",UMSDOS_PSDROOT_NAME));
464 if ((umsdos_real_lookup (etc,"init",4,&init)==0
465 && S_ISREG(init->i_mode))
466 || (umsdos_real_lookup (etc,"rc",2,&rc)==0
467 && S_ISREG(rc->i_mode))){
468 umsdos_setup_dir_inode (pseudo);
469 Printk (("Activating pseudo root /%s\n",UMSDOS_PSDROOT_NAME));
470 pseudo_root = pseudo;
471 pseudo->i_count++;
472 pseudo = NULL;
473 }
474 iput (init);
475 iput (rc);
476 }
477 iput (etc);
478 }
479 iput (pseudo);
480 }
481 #ifdef MODULE
482 MOD_INC_USE_COUNT;
483 #endif
484 }
485 return sb;
486 }
487
488
489 #ifdef MODULE
490
491 char kernel_version[] = UTS_RELEASE;
492
493 static struct file_system_type umsdos_fs_type = {
494 UMSDOS_read_super, "umsdos", 1, NULL
495 };
496
497 int init_module(void)
498 {
499 register_filesystem(&umsdos_fs_type);
500 return 0;
501 }
502
503 void cleanup_module(void)
504 {
505 if (MOD_IN_USE)
506 printk("Umsdos: file system in use, remove delayed\n");
507 else
508 {
509 unregister_filesystem(&umsdos_fs_type);
510 }
511 }
512
513 #endif
514