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