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