2 * linux/fs/umsdos/inode.c
4 * Written 1993 by Jacques Gelinas
5 * Inspired from linux/fs/msdos/... by Werner Almesberger
8 #include <linux/module.h>
10 #include <linux/init.h>
12 #include <linux/msdos_fs.h>
13 #include <linux/kernel.h>
14 #include <linux/sched.h>
15 #include <linux/errno.h>
16 #include <asm/uaccess.h>
17 #include <linux/string.h>
18 #include <linux/stat.h>
19 #include <linux/umsdos_fs.h>
20 #include <linux/list.h>
22 extern struct dentry_operations umsdos_dentry_operations
;
23 extern struct inode_operations umsdos_rdir_inode_operations
;
26 struct inode
*pseudo_root
= NULL
; /* Useful to simulate the pseudo DOS */
27 /* directory. See UMSDOS_readdir_x() */
31 * returns inode->i_dentry
32 * Note: Deprecated; won't work reliably
35 struct dentry
*geti_dentry (struct inode
*inode
)
40 printk (KERN_ERR
"geti_dentry: ERROR: inode is NULL!\n");
43 if (list_empty(&inode
->i_dentry
)) {
45 "geti_dentry: WARNING: no dentry for inode %ld\n",
49 ret
= list_entry (inode
->i_dentry
.next
, struct dentry
, d_alias
);
51 PRINTK ((KERN_DEBUG
"geti_dentry : inode %lu, dentry is %s/%s\n",
52 inode
->i_ino
, ret
->d_parent
->d_name
.name
, ret
->d_name
.name
));
58 * Initialize a private filp
60 void fill_new_filp (struct file
*filp
, struct dentry
*dentry
)
63 printk(KERN_ERR
"fill_new_filp: NULL dentry!\n");
65 memset (filp
, 0, sizeof (struct file
));
67 filp
->f_flags
= O_RDWR
;
68 filp
->f_dentry
= dentry
;
69 filp
->f_op
= &umsdos_file_operations
;
74 * makes dentry. for name name with length len.
75 * if inode is not NULL, puts it also.
76 * Note: Deprecated; use umsdos_lookup_dentry
79 struct dentry
*creat_dentry (const char *name
, const int len
,
80 struct inode
*inode
, struct dentry
*parent
)
82 /* FIXME /mn/: parent is not passed many times... if it is not, dentry should be destroyed before someone else gets to use it */
88 Printk ((KERN_DEBUG
"creat_dentry: creating dentry with inode=%lu for %.*s\n", inode
->i_ino
, len
, name
));
90 Printk ((KERN_DEBUG
"creat_dentry: creating empty dentry for %.*s\n", len
, name
));
94 qname
.hash
= full_name_hash (name
, len
);
96 ret
= d_alloc (parent
, &qname
); /* create new dentry */
100 Printk ((KERN_DEBUG
"creat_dentry: cloning parent d_op !\n"));
101 ret
->d_op
= parent
->d_op
;
107 Printk ((KERN_WARNING
"creat_dentry: WARNING: NO parent! faking root! beware !\n"));
112 /* try to fill it in if available. If available in
113 * parent->d_sb, d_alloc will add it automatically
115 if (!ret
->d_sb
) ret
->d_sb
= inode
->i_sb
;
120 printk (KERN_ERR
"creat_dentry: ERROR: NO d_sb !\n");
121 } else if (!ret
->d_sb
->s_dev
) {
122 printk (KERN_WARNING
"creat_dentry: WARNING: NO s_dev. Ugh. !\n");
129 void UMSDOS_put_inode (struct inode
*inode
)
132 "put inode %p (%lu) owner %lu pos %lu dir %lu count=%d\n"
134 ,inode
->u
.umsdos_i
.i_emd_owner
, inode
->u
.umsdos_i
.pos
135 ,inode
->u
.umsdos_i
.i_emd_dir
, inode
->i_count
));
137 if (inode
== pseudo_root
) {
138 printk (KERN_ERR
"Umsdos: Oops releasing pseudo_root."
139 " Notify jacques@solucorp.qc.ca\n");
142 fat_put_inode (inode
);
146 void UMSDOS_put_super (struct super_block
*sb
)
148 Printk ((KERN_DEBUG
"UMSDOS_put_super: entering\n"));
149 msdos_put_super (sb
);
155 * Complete the setup of an directory dentry.
156 * First, it completes the function pointers, then
157 * it locates the EMD file. If the EMD is there, then plug the
158 * umsdos function table. If not, use the msdos one.
160 * {i,d}_counts are untouched by this function.
162 void umsdos_setup_dir(struct dentry
*dir
)
164 struct inode
*inode
= dir
->d_inode
;
166 if (!S_ISDIR(inode
->i_mode
))
167 printk(KERN_ERR
"umsdos_setup_dir: %s/%s not a dir!\n",
168 dir
->d_parent
->d_name
.name
, dir
->d_name
.name
);
170 inode
->u
.umsdos_i
.i_emd_dir
= 0;
171 inode
->i_op
= &umsdos_rdir_inode_operations
;
172 if (umsdos_have_emd(dir
)) {
173 Printk((KERN_DEBUG
"umsdos_setup_dir: %s/%s using EMD\n",
174 dir
->d_parent
->d_name
.name
, dir
->d_name
.name
));
175 inode
->i_op
= &umsdos_dir_inode_operations
;
180 * Complete the setup of an directory inode.
181 * First, it completes the function pointers, then
182 * it locates the EMD file. If the EMD is there, then plug the
183 * umsdos function table. If not, use the msdos one.
185 * {i,d}_counts are untouched by this function.
186 * Note: Deprecated; use above function if possible.
188 void umsdos_setup_dir_inode (struct inode
*inode
)
190 struct inode
*emd_dir
;
192 inode
->u
.umsdos_i
.i_emd_dir
= 0;
195 "umsdos_setup_dir_inode: Entering for inode=%lu\n",
198 emd_dir
= umsdos_emd_dir_lookup (inode
, 0);
199 Printk ((KERN_DEBUG
"umsdos_setup_dir_inode: "
200 "umsdos_emd_dir_lookup for inode=%lu returned %p\n",
201 inode
->i_ino
, emd_dir
));
203 check_inode (emd_dir
);
205 inode
->i_op
= &umsdos_rdir_inode_operations
;
207 Printk ((KERN_DEBUG
"umsdos_setup_dir_inode: using EMD.\n"));
208 inode
->i_op
= &umsdos_dir_inode_operations
;
215 * Add some info into an inode so it can find its owner quickly
217 void umsdos_set_dirinfo_new (struct dentry
*dentry
, off_t f_pos
)
219 struct inode
*inode
= dentry
->d_inode
;
220 struct inode
*dir
= dentry
->d_parent
->d_inode
;
223 inode
->u
.umsdos_i
.i_dir_owner
= dir
->i_ino
;
224 inode
->u
.umsdos_i
.i_emd_owner
= 0;
225 inode
->u
.umsdos_i
.pos
= f_pos
;
227 /* now check the EMD file */
228 demd
= umsdos_get_emd_dentry(dentry
->d_parent
);
233 inode
->u
.umsdos_i
.i_emd_owner
= demd
->d_inode
->i_ino
;
242 * Add some info into an inode so it can find its owner quickly
243 * Note: Deprecated; use above function if possible.
245 void umsdos_set_dirinfo (struct inode
*inode
, struct inode
*dir
, off_t f_pos
)
247 struct inode
*emd_owner
= umsdos_emd_dir_lookup (dir
, 1);
251 Printk (("umsdos_set_dirinfo: emd_owner is %lu for dir %lu\n",
252 emd_owner
->i_ino
, dir
->i_ino
));
253 inode
->u
.umsdos_i
.i_dir_owner
= dir
->i_ino
;
254 inode
->u
.umsdos_i
.i_emd_owner
= emd_owner
->i_ino
;
255 inode
->u
.umsdos_i
.pos
= f_pos
;
263 * Tells if an Umsdos inode has been "patched" once.
266 int umsdos_isinit (struct inode
*inode
)
268 return inode
->u
.umsdos_i
.i_emd_owner
!= 0;
273 * Connect the proper tables in the inode and add some info.
274 * i_counts is not changed.
276 * This function is called very early to setup the inode, somewhat
277 * too early (called by UMSDOS_read_inode). At this point, we can't
278 * do too much, such as lookup up EMD files and so on. This causes
279 * confusion in the kernel. This is why some initialisation
280 * will be done when dir != NULL only.
282 * UMSDOS do run piggy back on top of msdos fs. It looks like something
283 * is missing in the VFS to accommodate stacked fs. Still unclear what
286 * Well, maybe one! A new entry "may_unmount" which would allow
287 * the stacked fs to allocate some inode permanently and release
288 * them at the end. Doing that now introduce a problem. unmount
289 * always fail because some inodes are in use.
291 /* #Specification: inode / umsdos info
292 * The first time an inode is seen (inode->i_count == 1),
293 * the inode number of the EMD file which controls this inode
294 * is tagged to this inode. It allows operations such as
295 * notify_change to be handled.
297 void umsdos_patch_inode (struct inode
*inode
, struct inode
*dir
, off_t f_pos
)
299 Printk ((KERN_DEBUG
"Entering umsdos_patch_inode for inode=%lu\n",
302 if (umsdos_isinit (inode
))
305 inode
->u
.umsdos_i
.i_emd_dir
= 0;
306 if (S_ISREG (inode
->i_mode
)) {
307 if (MSDOS_SB (inode
->i_sb
)->cvf_format
) {
308 if (MSDOS_SB (inode
->i_sb
)->cvf_format
->flags
& CVF_USE_READPAGE
) {
309 Printk ((KERN_DEBUG
"umsdos_patch_inode /mn/: setting i_op = umsdos_file_inode_operations_readpage\n"));
310 inode
->i_op
= &umsdos_file_inode_operations_readpage
;
312 Printk ((KERN_DEBUG
"umsdos_patch_inode: umsdos_file_inode_ops_no_bmap\n"));
313 inode
->i_op
= &umsdos_file_inode_operations_no_bmap
;
316 if (inode
->i_op
->bmap
!= NULL
) {
317 Printk ((KERN_DEBUG
"umsdos_patch_inode: umsdos_file_inode_ops\n"));
318 inode
->i_op
= &umsdos_file_inode_operations
;
320 Printk ((KERN_DEBUG
"umsdos_patch_inode: umsdos_file_inode_ops_no_bmap\n"));
321 inode
->i_op
= &umsdos_file_inode_operations_no_bmap
;
324 } else if (S_ISDIR (inode
->i_mode
)) {
326 umsdos_setup_dir_inode (inode
);
328 } else if (S_ISLNK (inode
->i_mode
)) {
330 "umsdos_patch_inode: umsdos_symlink_inode_ops\n"));
331 inode
->i_op
= &umsdos_symlink_inode_operations
;
332 } else if (S_ISCHR (inode
->i_mode
)) {
333 Printk ((KERN_DEBUG
"umsdos_patch_inode: chrdev_inode_ops\n"));
334 inode
->i_op
= &chrdev_inode_operations
;
335 } else if (S_ISBLK (inode
->i_mode
)) {
336 Printk ((KERN_DEBUG
"umsdos_patch_inode: blkdev_inode_ops\n"));
337 inode
->i_op
= &blkdev_inode_operations
;
338 } else if (S_ISFIFO (inode
->i_mode
)) {
339 Printk ((KERN_DEBUG
"umsdos_patch_inode /mn/: uhm, init_fifo\n"));
344 * This is done last because it also control the
345 * status of umsdos_isinit()
348 "umsdos_patch_inode: call x_set_dirinfo(%p,%p,%lu)\n",
350 umsdos_set_dirinfo (inode
, dir
, f_pos
);
357 * Test to see if the info is maintained.
358 * This should be removed when the file system will be proven.
360 struct inode
*emd_owner
= umsdos_emd_dir_lookup (dir
, 1);
363 if (emd_owner
->i_ino
!= inode
->u
.umsdos_i
.i_emd_owner
) {
364 printk ("UMSDOS: *** EMD_OWNER ??? *** ino = %ld %ld <> %ld ",
365 inode
->i_ino
, emd_owner
->i_ino
, inode
->u
.umsdos_i
.i_emd_owner
);
374 * Patch the inode in a dentry.
376 void umsdos_patch_dentry_inode(struct dentry
*dentry
, off_t f_pos
)
378 umsdos_patch_inode(dentry
->d_inode
, dentry
->d_parent
->d_inode
, f_pos
);
383 * Load an inode from disk.
385 /* #Specification: Inode / post initialisation
386 * To completely initialise an inode, we need access to the owner
387 * directory, so we can locate more info in the EMD file. This is
388 * not available the first time the inode is access, we use
389 * a value in the inode to tell if it has been finally initialised.
391 * At first, we have tried testing i_count but it was causing
392 * problem. It is possible that two or more process use the
393 * newly accessed inode. While the first one block during
394 * the initialisation (probably while reading the EMD file), the
395 * others believe all is well because i_count > 1. They go banana
396 * with a broken inode. See umsdos_lookup_patch and umsdos_patch_inode.
398 void UMSDOS_read_inode (struct inode
*inode
)
400 PRINTK ((KERN_DEBUG
"UMSDOS_read_inode %p ino = %lu ",
401 inode
, inode
->i_ino
));
402 msdos_read_inode (inode
);
403 PRINTK (("ino after msdos_read_inode= %lu i_count=%d\n",
404 inode
->i_ino
, inode
->i_count
));
405 if (S_ISDIR (inode
->i_mode
)
406 && (inode
->u
.umsdos_i
.u
.dir_info
.creating
!= 0
407 || inode
->u
.umsdos_i
.u
.dir_info
.looking
!= 0
408 || waitqueue_active (&inode
->u
.umsdos_i
.u
.dir_info
.p
))) {
409 Printk (("read inode %d %d %p\n"
410 ,inode
->u
.umsdos_i
.u
.dir_info
.creating
411 ,inode
->u
.umsdos_i
.u
.dir_info
.looking
412 ,inode
->u
.umsdos_i
.u
.dir_info
.p
));
415 /* N.B. Defer this until we have a dentry ... */
416 umsdos_patch_inode (inode
, NULL
, 0);
420 int UMSDOS_notify_change (struct dentry
*dentry
, struct iattr
*attr
)
422 struct inode
*inode
= dentry
->d_inode
;
423 unsigned long i_emd_owner
= inode
->u
.umsdos_i
.i_emd_owner
;
427 struct umsdos_dirent entry
;
429 Printk ((KERN_DEBUG
"UMSDOS_notify_change: entering\n"));
431 if ((ret
= inode_change_ok (inode
, attr
)) != 0)
434 if (inode
->i_nlink
== 0)
437 if (inode
->i_ino
== UMSDOS_ROOT_INO
)
439 if (i_emd_owner
!= 0)
442 /* get the EMD file dentry */
443 demd
= umsdos_get_emd_dentry(dentry
->d_parent
);
452 if (inode
== demd
->d_inode
)
454 /* This inode is not a EMD file nor an inode used internally
455 * by MSDOS, so we can update its status.
459 Printk (("notify change %p ", inode
));
460 fill_new_filp (&filp
, demd
);
461 filp
.f_pos
= inode
->u
.umsdos_i
.pos
;
463 Printk (("pos = %Lu ", filp
.f_pos
));
464 /* Read only the start of the entry since we don't touch the name */
465 ret
= umsdos_emd_dir_read (&filp
, (char *) &entry
, UMSDOS_REC_SIZE
);
467 if (attr
->ia_valid
& ATTR_UID
)
468 entry
.uid
= attr
->ia_uid
;
469 if (attr
->ia_valid
& ATTR_GID
)
470 entry
.gid
= attr
->ia_gid
;
471 if (attr
->ia_valid
& ATTR_MODE
)
472 entry
.mode
= attr
->ia_mode
;
473 if (attr
->ia_valid
& ATTR_ATIME
)
474 entry
.atime
= attr
->ia_atime
;
475 if (attr
->ia_valid
& ATTR_MTIME
)
476 entry
.mtime
= attr
->ia_mtime
;
477 if (attr
->ia_valid
& ATTR_CTIME
)
478 entry
.ctime
= attr
->ia_ctime
;
480 entry
.nlink
= inode
->i_nlink
;
481 filp
.f_pos
= inode
->u
.umsdos_i
.pos
;
482 ret
= umsdos_emd_dir_write (&filp
, (char *) &entry
,
485 Printk (("notify pos %lu ret %d nlink %d ",
486 inode
->u
.umsdos_i
.pos
, ret
, entry
.nlink
));
487 /* #Specification: notify_change / msdos fs
488 * notify_change operation are done only on the
489 * EMD file. The msdos fs is not even called.
496 inode_setattr (inode
, attr
);
503 * Update the disk with the inode content
505 void UMSDOS_write_inode (struct inode
*inode
)
507 struct iattr newattrs
;
509 PRINTK (("UMSDOS_write_inode emd %d (FIXME: missing notify_change)\n",
510 inode
->u
.umsdos_i
.i_emd_owner
));
511 fat_write_inode (inode
);
512 newattrs
.ia_mtime
= inode
->i_mtime
;
513 newattrs
.ia_atime
= inode
->i_atime
;
514 newattrs
.ia_ctime
= inode
->i_ctime
;
515 newattrs
.ia_valid
= ATTR_MTIME
| ATTR_ATIME
| ATTR_CTIME
;
517 * UMSDOS_notify_change is convenient to call here
518 * to update the EMD entry associated with this inode.
519 * But it has the side effect to re"dirt" the inode.
522 * internal_notify_change (inode, &newattrs);
523 * inode->i_state &= ~I_DIRTY; / * FIXME: this doesn't work. We need to remove ourselves from list on dirty inodes. /mn/ */
527 static struct super_operations umsdos_sops
=
529 UMSDOS_read_inode
, /* read_inode */
530 UMSDOS_write_inode
, /* write_inode */
531 UMSDOS_put_inode
, /* put_inode */
532 fat_delete_inode
, /* delete_inode */
533 UMSDOS_notify_change
, /* notify_change */
534 UMSDOS_put_super
, /* put_super */
535 NULL
, /* write_super */
536 fat_statfs
, /* statfs */
537 NULL
/* remount_fs */
541 * Read the super block of an Extended MS-DOS FS.
543 struct super_block
*UMSDOS_read_super (struct super_block
*sb
, void *data
,
546 struct super_block
*res
;
547 struct inode
*pseudo
= NULL
;
550 MSDOS_SB(sb
)->options
.isvfat
= 0;
552 * Call msdos-fs to mount the disk.
553 * Note: this returns res == sb or NULL
555 res
= msdos_read_super (sb
, data
, silent
);
559 printk (KERN_INFO
"UMSDOS dentry-WIP-Beta 0.82-7 "
560 "(compatibility level %d.%d, fast msdos)\n",
561 UMSDOS_VERSION
, UMSDOS_RELEASE
);
563 sb
->s_op
= &umsdos_sops
;
564 MSDOS_SB(sb
)->options
.dotsOK
= 0; /* disable hidden==dotfile */
566 /* install our dentry operations ... */
567 sb
->s_root
->d_op
= &umsdos_dentry_operations
;
568 pseudo
= sb
->s_root
->d_inode
;
569 umsdos_setup_dir(sb
->s_root
);
577 /* if d_count is not 1, mount will fail with -EBUSY! */
578 if (sb
->s_root
->d_count
> 1) {
579 shrink_dcache_sb(sb
);
584 printk(KERN_INFO
"UMSDOS: msdos_read_super failed, mount aborted.\n");
592 * disable pseudo root-for the moment of testing.
593 * re-enable this before release !
596 void pseudo_root_stuff(void)
598 struct dentry
*root
, *etc
, *etc_rc
, *sbin
, *init
= NULL
;
600 root
= creat_dentry (UMSDOS_PSDROOT_NAME
,
601 strlen (UMSDOS_PSDROOT_NAME
),
603 sbin
= creat_dentry ("sbin", 4, NULL
, root
);
605 Printk ((KERN_DEBUG
"Mounting root\n"));
606 if (msdos_lookup (pseudo
, root
) == 0
607 && (root
->d_inode
!= NULL
)
608 && S_ISDIR (root
->d_inode
->i_mode
)) {
612 Printk ((KERN_DEBUG
"/%s is there\n", UMSDOS_PSDROOT_NAME
));
613 etc
= creat_dentry ("etc", 3, NULL
, root
);
616 if (msdos_lookup (pseudo
, etc
) == 0
617 && S_ISDIR (etc
->d_inode
->i_mode
)) {
619 Printk ((KERN_DEBUG
"/%s/etc is there\n", UMSDOS_PSDROOT_NAME
));
621 init
= creat_dentry ("init", 4, NULL
, etc
);
622 etc_rc
= creat_dentry ("rc", 2, NULL
, etc
);
624 if ((msdos_lookup (pseudo
, init
) == 0
625 && S_ISREG (init
->d_inode
->i_mode
))
626 || (msdos_lookup (pseudo
, etc_rc
) == 0
627 && S_ISREG (etc_rc
->d_inode
->i_mode
))) {
636 /* && msdos_lookup (pseudo, "sbin", 4, sbin)==0 */
637 && msdos_lookup (pseudo
, sbin
) == 0
638 && S_ISDIR (sbin
->d_inode
->i_mode
)) {
640 Printk ((KERN_DEBUG
"/%s/sbin is there\n", UMSDOS_PSDROOT_NAME
));
641 if (msdos_lookup (pseudo
, init
) == 0
642 && S_ISREG (init
->d_inode
->i_mode
)) {
649 umsdos_setup_dir_inode (pseudo
);
650 Printk ((KERN_INFO
"Activating pseudo root /%s\n", UMSDOS_PSDROOT_NAME
));
651 pseudo_root
= pseudo
;
665 static struct file_system_type umsdos_fs_type
=
673 __initfunc (int init_umsdos_fs (void))
675 return register_filesystem (&umsdos_fs_type
);
681 int init_module (void)
683 return init_umsdos_fs ();
686 void cleanup_module (void)
688 unregister_filesystem (&umsdos_fs_type
);