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 struct iattr newattrs;
261
262 PRINTK (("UMSDOS_write_inode emd %d\n",inode->u.umsdos_i.i_emd_owner));
263 msdos_write_inode(inode);
264 newattrs.ia_mtime = inode->i_mtime;
265 newattrs.ia_atime = inode->i_atime;
266 newattrs.ia_ctime = inode->i_ctime;
267 newattrs.ia_valid = ATTR_MTIME | ATTR_ATIME | ATTR_CTIME;
268 UMSDOS_notify_change (inode, &newattrs);
269 }
270
271 int UMSDOS_notify_change(struct inode *inode, struct iattr *attr)
272 {
273 int ret = 0;
274
275 if ((ret = inode_change_ok(inode, attr)) != 0)
276 return ret;
277
278 if (inode->i_nlink > 0){
279
280
281
282
283
284 unsigned long i_emd_owner = inode->u.umsdos_i.i_emd_owner;
285 if (inode == inode->i_sb->s_mounted){
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300 }else if (i_emd_owner != 0xffffffff && i_emd_owner != 0){
301
302
303
304
305 struct inode *emd_owner = iget (inode->i_sb,i_emd_owner);
306 PRINTK (("notify change %p ",inode));
307 if (emd_owner == NULL){
308 printk ("UMSDOS: emd_owner = NULL ???");
309 ret = -EPERM;
310 }else{
311 struct file filp;
312 struct umsdos_dirent entry;
313 filp.f_pos = inode->u.umsdos_i.pos;
314 PRINTK (("pos = %d ",filp.f_pos));
315
316
317 ret = umsdos_emd_dir_read (emd_owner,&filp,(char*)&entry
318 ,UMSDOS_REC_SIZE);
319 if (ret == 0){
320 if (attr->ia_valid & ATTR_UID)
321 entry.uid = attr->ia_uid;
322 if (attr->ia_valid & ATTR_GID)
323 entry.gid = attr->ia_gid;
324 if (attr->ia_valid & ATTR_MODE)
325 entry.mode = attr->ia_mode;
326 if (attr->ia_valid & ATTR_ATIME)
327 entry.atime = attr->ia_atime;
328 if (attr->ia_valid & ATTR_MTIME)
329 entry.mtime = attr->ia_mtime;
330 if (attr->ia_valid & ATTR_CTIME)
331 entry.ctime = attr->ia_ctime;
332
333 entry.nlink = inode->i_nlink;
334 filp.f_pos = inode->u.umsdos_i.pos;
335 ret = umsdos_emd_dir_write (emd_owner,&filp,(char*)&entry
336 ,UMSDOS_REC_SIZE);
337
338 PRINTK (("notify pos %d ret %d nlink %d "
339 ,inode->u.umsdos_i.pos
340 ,ret,entry.nlink));
341
342
343
344
345 }
346 iput (emd_owner);
347 }
348 PRINTK (("\n"));
349 }
350 }
351 if (ret == 0)
352 inode_setattr(inode, attr);
353 return ret;
354 }
355
356
357
358
359
360
361
362
363
364
365 static struct super_operations umsdos_sops = {
366 UMSDOS_read_inode,
367 UMSDOS_notify_change,
368 UMSDOS_write_inode,
369 UMSDOS_put_inode,
370 UMSDOS_put_super,
371 NULL,
372 UMSDOS_statfs,
373 NULL
374 };
375
376
377
378
379 struct super_block *UMSDOS_read_super(
380 struct super_block *s,
381 void *data,
382 int silent)
383 {
384
385
386
387
388
389
390
391
392
393
394
395
396
397 struct super_block *sb = msdos_read_super(s,data,silent);
398 printk ("UMSDOS Alpha 0.4 (compatibility level %d.%d)\n"
399 ,UMSDOS_VERSION,UMSDOS_RELEASE);
400 if (sb != NULL){
401 sb->s_op = &umsdos_sops;
402 PRINTK (("umsdos_read_super %p\n",sb->s_mounted));
403 umsdos_setup_dir_inode (sb->s_mounted);
404 PRINTK (("End umsdos_read_super\n"));
405 if (s == super_blocks){
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
434
435
436
437 struct inode *pseudo;
438 Printk (("Mounting root\n"));
439 if (umsdos_real_lookup (sb->s_mounted,UMSDOS_PSDROOT_NAME
440 ,UMSDOS_PSDROOT_LEN,&pseudo)==0
441 && S_ISDIR(pseudo->i_mode)){
442 struct inode *etc = NULL;
443 struct inode *rc = NULL;
444 Printk (("/%s is there\n",UMSDOS_PSDROOT_NAME));
445 if (umsdos_real_lookup (pseudo,"etc",3,&etc)==0
446 && S_ISDIR(etc->i_mode)){
447 struct inode *init;
448 Printk (("/%s/etc is there\n",UMSDOS_PSDROOT_NAME));
449 if ((umsdos_real_lookup (etc,"init",4,&init)==0
450 && S_ISREG(init->i_mode))
451 || (umsdos_real_lookup (etc,"rc",2,&rc)==0
452 && S_ISREG(rc->i_mode))){
453 umsdos_setup_dir_inode (pseudo);
454 Printk (("Activating pseudo root /%s\n",UMSDOS_PSDROOT_NAME));
455 pseudo_root = pseudo;
456 pseudo->i_count++;
457 pseudo = NULL;
458 }
459 iput (init);
460 iput (rc);
461 }
462 iput (etc);
463 }
464 iput (pseudo);
465 }
466 }
467 return sb;
468 }
469
470