Import 2.1.122pre3
[davej-history.git] / fs / umsdos / inode.c
blobc15a243695f588fb23c3d87ffdd00aa22bd5b0b4
1 /*
2 * linux/fs/umsdos/inode.c
4 * Written 1993 by Jacques Gelinas
5 * Inspired from linux/fs/msdos/... by Werner Almesberger
6 */
8 #include <linux/module.h>
10 #include <linux/init.h>
11 #include <linux/fs.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)
37 struct dentry *ret;
39 if (!inode) {
40 printk (KERN_ERR "geti_dentry: ERROR: inode is NULL!\n");
41 return NULL;
43 if (list_empty(&inode->i_dentry)) {
44 printk (KERN_WARNING
45 "geti_dentry: WARNING: no dentry for inode %ld\n",
46 inode->i_ino);
47 return NULL;
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));
53 return ret;
58 * Initialize a private filp
60 void fill_new_filp (struct file *filp, struct dentry *dentry)
62 if (!dentry)
63 printk(KERN_ERR "fill_new_filp: NULL dentry!\n");
65 memset (filp, 0, sizeof (struct file));
66 filp->f_reada = 1;
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 */
84 struct dentry *ret;
85 struct qstr qname;
87 if (inode)
88 Printk ((KERN_DEBUG "creat_dentry: creating dentry with inode=%lu for %.*s\n", inode->i_ino, len, name));
89 else
90 Printk ((KERN_DEBUG "creat_dentry: creating empty dentry for %.*s\n", len, name));
92 qname.name = name;
93 qname.len = len;
94 qname.hash = full_name_hash (name, len);
96 ret = d_alloc (parent, &qname); /* create new dentry */
98 if (parent) {
99 #if 0
100 Printk ((KERN_DEBUG "creat_dentry: cloning parent d_op !\n"));
101 ret->d_op = parent->d_op;
102 #else
103 ret->d_op = NULL;
104 #endif
105 } else {
106 ret->d_parent = ret;
107 Printk ((KERN_WARNING "creat_dentry: WARNING: NO parent! faking root! beware !\n"));
111 if (inode) {
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;
116 d_add (ret, inode);
119 if (!ret->d_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");
125 return ret;
129 void UMSDOS_put_inode (struct inode *inode)
131 PRINTK ((KERN_DEBUG
132 "put inode %p (%lu) owner %lu pos %lu dir %lu count=%d\n"
133 ,inode, inode->i_ino
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);
150 MOD_DEC_USE_COUNT;
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;
194 Printk ((KERN_DEBUG
195 "umsdos_setup_dir_inode: Entering for inode=%lu\n",
196 inode->i_ino));
197 check_inode (inode);
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));
202 check_inode (inode);
203 check_inode (emd_dir);
205 inode->i_op = &umsdos_rdir_inode_operations;
206 if (emd_dir) {
207 Printk ((KERN_DEBUG "umsdos_setup_dir_inode: using EMD.\n"));
208 inode->i_op = &umsdos_dir_inode_operations;
209 iput (emd_dir);
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;
221 struct dentry *demd;
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);
229 if (IS_ERR(demd)) {
230 goto out;
232 if (demd->d_inode) {
233 inode->u.umsdos_i.i_emd_owner = demd->d_inode->i_ino;
235 dput (demd);
236 out:
237 return;
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);
249 if (!emd_owner)
250 goto out;
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;
256 iput (emd_owner);
257 out:
258 return;
263 * Tells if an Umsdos inode has been "patched" once.
264 * Return != 0 if so.
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
284 * (quite honestly).
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",
300 inode->i_ino));
302 if (umsdos_isinit (inode))
303 goto already_init;
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;
311 } else {
312 Printk ((KERN_DEBUG "umsdos_patch_inode: umsdos_file_inode_ops_no_bmap\n"));
313 inode->i_op = &umsdos_file_inode_operations_no_bmap;
315 } else {
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;
319 } else {
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)) {
325 if (dir != NULL) {
326 umsdos_setup_dir_inode (inode);
328 } else if (S_ISLNK (inode->i_mode)) {
329 Printk ((KERN_DEBUG
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"));
340 init_fifo (inode);
342 if (dir != NULL) {
344 * This is done last because it also control the
345 * status of umsdos_isinit()
347 Printk ((KERN_DEBUG
348 "umsdos_patch_inode: call x_set_dirinfo(%p,%p,%lu)\n",
349 inode, dir, f_pos));
350 umsdos_set_dirinfo (inode, dir, f_pos);
352 return;
354 already_init:
355 if (dir != NULL) {
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);
361 if (!emd_owner)
362 goto out;
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);
367 iput (emd_owner);
368 out:
369 return;
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;
424 struct dentry *demd;
425 int ret;
426 struct file filp;
427 struct umsdos_dirent entry;
429 Printk ((KERN_DEBUG "UMSDOS_notify_change: entering\n"));
431 if ((ret = inode_change_ok (inode, attr)) != 0)
432 goto out;
434 if (inode->i_nlink == 0)
435 goto out_nolink;
437 if (inode->i_ino == UMSDOS_ROOT_INO)
438 goto out_nolink;
439 if (i_emd_owner != 0)
440 goto out_nolink;
442 /* get the EMD file dentry */
443 demd = umsdos_get_emd_dentry(dentry->d_parent);
444 ret = PTR_ERR(demd);
445 if (IS_ERR(demd))
446 goto out_nolink;
447 ret = -EPERM;
448 if (!demd->d_inode)
449 goto out_dput;
451 ret = 0;
452 if (inode == demd->d_inode)
453 goto out_dput;
454 /* This inode is not a EMD file nor an inode used internally
455 * by MSDOS, so we can update its status.
456 * See emd.c
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);
466 if (!ret) {
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,
483 UMSDOS_REC_SIZE);
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.
492 out_dput:
493 dput(demd);
494 out_nolink:
495 if (ret == 0)
496 inode_setattr (inode, attr);
497 out:
498 return ret;
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,
544 int silent)
546 struct super_block *res;
547 struct inode *pseudo = NULL;
549 MOD_INC_USE_COUNT;
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);
556 if (!res)
557 goto out_fail;
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);
571 #if 0
572 if (pseudo) {
573 pseudo_root_stuff();
575 #endif
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);
581 return sb;
583 out_fail:
584 printk(KERN_INFO "UMSDOS: msdos_read_super failed, mount aborted.\n");
585 sb->s_dev = 0;
586 MOD_DEC_USE_COUNT;
587 return NULL;
591 * FIXME URGENT:
592 * disable pseudo root-for the moment of testing.
593 * re-enable this before release !
595 #if 0
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),
602 NULL, res->s_root);
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)) {
610 int pseudo_ok = 0;
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))) {
628 pseudo_ok = 1;
631 /* FIXME !!!!!! */
632 /* iput(init); */
633 /* iput(rc); */
635 if (!pseudo_ok
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)) {
643 pseudo_ok = 1;
645 /* FIXME !!!
646 * iput (init); */
648 if (pseudo_ok) {
649 umsdos_setup_dir_inode (pseudo);
650 Printk ((KERN_INFO "Activating pseudo root /%s\n", UMSDOS_PSDROOT_NAME));
651 pseudo_root = pseudo;
652 inc_count (pseudo);
653 pseudo = NULL;
655 /* FIXME
657 * iput (sbin);
658 * iput (etc);
662 #endif
665 static struct file_system_type umsdos_fs_type =
667 "umsdos",
668 FS_REQUIRES_DEV,
669 UMSDOS_read_super,
670 NULL
673 __initfunc (int init_umsdos_fs (void))
675 return register_filesystem (&umsdos_fs_type);
678 #ifdef MODULE
679 EXPORT_NO_SYMBOLS;
681 int init_module (void)
683 return init_umsdos_fs ();
686 void cleanup_module (void)
688 unregister_filesystem (&umsdos_fs_type);
691 #endif