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 <linux/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 if (inode != NULL && inode == pseudo_root){
49 printk ("Umsdos: Oops releasing pseudo_root. Notify jacques@solucorp.qc.ca\n");
50 }
51 msdos_put_inode(inode);
52 }
53
54
55 void UMSDOS_put_super(struct super_block *sb)
56 {
57 msdos_put_super(sb);
58 #ifdef MODULE
59 MOD_DEC_USE_COUNT;
60 #endif
61 }
62
63
64 void UMSDOS_statfs(struct super_block *sb,struct statfs *buf)
65 {
66 msdos_statfs(sb,buf);
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 = msdos_read_super(s,data,silent);
408 printk ("UMSDOS Beta 0.6 (compatibility level %d.%d, fast msdos)\n"
409 ,UMSDOS_VERSION,UMSDOS_RELEASE);
410 if (sb != NULL){
411 sb->s_op = &umsdos_sops;
412 PRINTK (("umsdos_read_super %p\n",sb->s_mounted));
413 umsdos_setup_dir_inode (sb->s_mounted);
414 PRINTK (("End umsdos_read_super\n"));
415 if (s == super_blocks){
416
417
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 struct inode *pseudo;
448 Printk (("Mounting root\n"));
449 if (umsdos_real_lookup (sb->s_mounted,UMSDOS_PSDROOT_NAME
450 ,UMSDOS_PSDROOT_LEN,&pseudo)==0
451 && S_ISDIR(pseudo->i_mode)){
452 struct inode *etc = NULL;
453 struct inode *rc = NULL;
454 Printk (("/%s is there\n",UMSDOS_PSDROOT_NAME));
455 if (umsdos_real_lookup (pseudo,"etc",3,&etc)==0
456 && S_ISDIR(etc->i_mode)){
457 struct inode *init;
458 Printk (("/%s/etc is there\n",UMSDOS_PSDROOT_NAME));
459 if ((umsdos_real_lookup (etc,"init",4,&init)==0
460 && S_ISREG(init->i_mode))
461 || (umsdos_real_lookup (etc,"rc",2,&rc)==0
462 && S_ISREG(rc->i_mode))){
463 umsdos_setup_dir_inode (pseudo);
464 Printk (("Activating pseudo root /%s\n",UMSDOS_PSDROOT_NAME));
465 pseudo_root = pseudo;
466 pseudo->i_count++;
467 pseudo = NULL;
468 }
469 iput (init);
470 iput (rc);
471 }
472 iput (etc);
473 }
474 iput (pseudo);
475 }
476 #ifdef MODULE
477 MOD_INC_USE_COUNT;
478 #endif
479 }
480 return sb;
481 }
482
483
484 #ifdef MODULE
485
486 char kernel_version[] = UTS_RELEASE;
487
488 static struct file_system_type umsdos_fs_type = {
489 UMSDOS_read_super, "umsdos", 1, NULL
490 };
491
492 int init_module(void)
493 {
494 register_filesystem(&umsdos_fs_type);
495 return 0;
496 }
497
498 void cleanup_module(void)
499 {
500 if (MOD_IN_USE)
501 printk("Umsdos: file system in use, remove delayed\n");
502 else
503 {
504 unregister_filesystem(&umsdos_fs_type);
505 }
506 }
507
508 #endif
509