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