Messages in this thread Patch in this message | | | Date | Wed, 2 Aug 2000 22:26:56 +0200 | From | Matija Nalis <> | Subject | [PATCH] UMSDOS kernel patch for 2.2.x (Alan Cox readme!) |
| |
Attached is diff for UMSDOS filesystem made against 2.2.16 kernel. I've tried to send it to Alan Cox at alan@lxorguk.ukuu.org.uk, but I'm afraid his post-ORBS draconian mail filter is being too agressive to let me through.
Could someone please forward this to him to put it in next 2.2.x (pre)release?
Fixes: * all known hardlink problems (mostly regarding hardlinks across directories) * problem with EMD entries with corrupted size causing OOPS * statfs(2) fixes (f_namelen field)
Regards, Matija
diff -ur linux-2.2.16/MAINTAINERS linux-2.2.16-my/MAINTAINERS --- linux-2.2.16/MAINTAINERS Mon Jul 24 16:49:35 2000 +++ linux-2.2.16-my/MAINTAINERS Mon Jul 24 16:50:38 2000 @@ -888,7 +888,7 @@ UMSDOS FILESYSTEM P: Matija Nalis -M: mnalis@jagor.srce.hr +M: mnalis-umsdos@voyager.hr L: linux-kernel@vger.rutgers.edu S: Maintained diff -ur linux/fs/umsdos.org.2.2.16/README-WIP.txt linux/fs/umsdos/README-WIP.txt --- linux/fs/umsdos.org.2.2.16/README-WIP.txt Sun Jul 23 18:16:13 2000 +++ linux/fs/umsdos/README-WIP.txt Sat Jul 29 21:08:18 2000 @@ -5,20 +5,16 @@ There is no warning any more. Both read-only and read-write stuff is fixed, both in msdos-compatibile mode, and in umsdos EMD mode, and it seems stable. -There are still few hardlink nuisances, but those are not fatal. - -I'd call it pre-release, and ask for as many people as possible to -come and test it! See notes below for some more information, or if -you are trying to use UMSDOS as root partition. Userland NOTE: new umsdos_progs (umssync, umssetup, udosctl & friends) that -will compile and work on 2.2.x kernels and glibc based systems may be found -at http://cvs.linux.hr/ +will compile and work on 2.2.x+ kernels and glibc based systems, as well as +kernel patches and other umsdos related information may be found at +http://linux.voyager.hr/umsdos/ Legend: those lines marked with '+' on the beggining of line indicates it passed all of my tests, and performed perfect in all of them. -Current status (000123) - UMSDOS 0.85g: +Current status (000729) - UMSDOS 0.85i: (1) pure MSDOS (no --linux-.--- EMD file): @@ -29,7 +25,7 @@ WRITE: + creat file - works -+ delete file - works ++ unlink file - works + write file - works + rename file (same dir) - works + rename file (dif. dir) - works @@ -49,7 +45,7 @@ + read file - works + switching MSDOS/UMSDOS - works + switching UMSDOS/MSDOS - works -- pseudo root things - works mostly. See notes below. +- pseudo root things - works. See notes below. + resolve symlink - works + dereference symlink - works + dangling symlink - works @@ -60,21 +56,21 @@ WRITE: + create symlink - works -- create hardlink - works for same DIR (see notes) ++ create hardlink - works + create file - works + create special file - works + write to file - works + rename file (same dir) - works + rename file (dif. dir) - works + rename hardlink (same dir) - works -- rename hardlink (dif. dir) - ++ rename hardlink (dif. dir) - works + rename symlink (same dir) - works + rename symlink (dif. dir) - works + rename dir (same dir) - works + rename dir (dif. dir) - works + delete file - works + notify_change (chown,perms) - works -- delete hardlink - works for same DIR (see notes) ++ delete hardlink - works + mkdir - works + rmdir - works + umssyncing (many ioctls) - works @@ -91,26 +87,13 @@ Note: creating and using pseudo-hardlinks is always non-perfect, especially in filesystems that might be externally modified like umsdos. There is example is specs file about it. Specifically, moving directory which -contains hardlinks will break them. - -Note: (about pseudoroot) If you are currently trying to use UMSDOS as root -partition (with linux installed in c:\linux) it will boot, but there may be -some problems. Volunteers ready to test pseudoroot are needed (preferably -ones with working backups or unimportant data). For example, '/DOS' pseudo -directory is only partially re-implemented and buggy. It works most of the -time, though. Update: should work ok in 0.84, although it still does not -work correctly in combination with initrd featere. Working on this! +contains hardlinks will break them in some cases. Note: (about creating hardlinks in pseudoroot mode) - hardlinks created in pseudoroot mode are now again compatibile with 'normal' hardlinks, and vice versa. Thanks to Sorin Iordachescu <sorin@rodae.ro> for providing fix. - -Warning: (about hardlinks) - modifying hardlinks (esp. if they are in -different directories) are currently somewhat broken, I'm working on it. -Problem seems to be that code uses and updates EMD of directory where 'real -hardlink' is stored, not EMD of directory where our pseudo-hardlink is -located! I'm looking for ideas how to work around this in clean way, since -without it modifying hardlinks in any but most simple ways is broken! +See http://linux.voyager.hr/umsdos/hlbug.html for more info and upgrade +procedure if you used broken versions... ------------------------------------------------------------------------------ @@ -124,6 +107,5 @@ I'm unfortunately somewhat out of time to read linux-kernel@vger, but I do check for messages having "UMSDOS" in the subject, and read them. I might miss some in all that volume, though. I should reply to any direct e-mail -in few days. If I don't, probably I never got your message. You can try -mnalis-umsdos@voyager.hr; however mnalis@jagor.srce.hr is preferable. +in few days. If I don't, probably I never got your message. diff -ur linux/fs/umsdos.org.2.2.16/emd.c linux/fs/umsdos/emd.c --- linux/fs/umsdos.org.2.2.16/emd.c Sun Jul 23 18:16:13 2000 +++ linux/fs/umsdos/emd.c Sat Jul 29 20:52:55 2000 @@ -273,6 +273,16 @@ Printk ((KERN_DEBUG "umsdos_emd_dir_readentry /mn/: entering.\n")); ret = umsdos_emd_dir_read (filp, (char *) entry, UMSDOS_REC_SIZE); + + /* if this is an invalid entry (invalid name length), ignore it */ + if( entry->name_len > UMSDOS_MAXNAME ) + { + printk (KERN_WARNING "Ignoring invalid EMD entry with size %d\n", entry->name_len); + entry->name_len = 0; + ret = -ENAMETOOLONG; /* notify umssync(8) code that something is wrong */ + } + + if (ret == 0) { /* if no error */ /* Variable size record. Maybe, we have to read some more */ int recsize = umsdos_evalrecsize (entry->name_len); diff -ur linux/fs/umsdos.org.2.2.16/inode.c linux/fs/umsdos/inode.c --- linux/fs/umsdos.org.2.2.16/inode.c Sun Jul 23 18:16:13 2000 +++ linux/fs/umsdos/inode.c Thu Jul 27 20:26:44 2000 @@ -56,8 +56,7 @@ ,inode->i_count)); if (inode == pseudo_root) { - printk (KERN_ERR "Umsdos: Oops releasing pseudo_root." - " Notify jacques@solucorp.qc.ca\n"); + printk (KERN_ERR "Umsdos: debug: releasing pseudo_root - ino=%lu count=%d\n", inode->i_ino, inode->i_count); } if (inode->i_count == 1) @@ -180,21 +179,6 @@ } -int umsdos_notify_change_locked(struct dentry *, struct iattr *); -/* - * lock the parent dir before starting ... - */ -int UMSDOS_notify_change (struct dentry *dentry, struct iattr *attr) -{ - struct inode *dir = dentry->d_parent->d_inode; - int ret; - - down(&dir->i_sem); - ret = umsdos_notify_change_locked(dentry, attr); - up(&dir->i_sem); - return ret; -} - /* * Must be called with the parent lock held. */ @@ -300,6 +284,65 @@ /* + * lock the parent dir before starting ... + * also handles hardlink converting + */ +int UMSDOS_notify_change (struct dentry *dentry, struct iattr *attr) +{ + struct inode *dir; + struct umsdos_info info; + struct dentry *temp, *old_dentry = NULL; + int ret; + + ret = umsdos_parse (dentry->d_name.name, dentry->d_name.len, + &info); + if (ret) + goto out; + ret = umsdos_findentry (dentry->d_parent, &info, 0); + if (ret) { +printk("UMSDOS_notify_change: %s/%s not in EMD, ret=%d\n", +dentry->d_parent->d_name.name, dentry->d_name.name, ret); + goto out; + } + + if (info.entry.flags & UMSDOS_HLINK) { + /* + * In order to get the correct (real) inode, we just drop + * the original dentry. + */ + d_drop(dentry); +Printk(("UMSDOS_notify_change: hard link %s/%s, fake=%s\n", +dentry->d_parent->d_name.name, dentry->d_name.name, info.fake.fname)); + + /* Do a real lookup to get the short name dentry */ + temp = umsdos_covered(dentry->d_parent, info.fake.fname, + info.fake.len); + ret = PTR_ERR(temp); + if (IS_ERR(temp)) + goto out; + + /* now resolve the link ... */ + temp = umsdos_solve_hlink(temp); + ret = PTR_ERR(temp); + if (IS_ERR(temp)) + goto out; + old_dentry = dentry; + dentry = temp; /* so umsdos_notify_change_locked will operate on that */ + } + + dir = dentry->d_parent->d_inode; + + down(&dir->i_sem); + ret = umsdos_notify_change_locked(dentry, attr); + up(&dir->i_sem); +out: + if (old_dentry) + dput (dentry); /* if we had to use fake dentry for hardlinks, dput() it now */ + return ret; +} + + +/* * Update the disk with the inode content */ void UMSDOS_write_inode (struct inode *inode) @@ -332,11 +375,28 @@ UMSDOS_notify_change, /* notify_change */ UMSDOS_put_super, /* put_super */ NULL, /* write_super */ - fat_statfs, /* statfs */ + UMSDOS_statfs, /* statfs */ NULL, /* remount_fs */ fat_clear_inode, /* clear_inode */ }; + +int UMSDOS_statfs(struct super_block *sb,struct statfs *buf, int bufsiz) +{ + int ret; + struct statfs tmp; + + ret = fat_statfs (sb, buf, bufsiz); + copy_from_user (&tmp, buf, bufsiz); + if (!ret) { + copy_from_user (&tmp, buf, bufsiz); + tmp.f_namelen = UMSDOS_MAXNAME; + copy_to_user (buf, &tmp, bufsiz); + } + return ret; +} + + /* * Read the super block of an Extended MS-DOS FS. */ @@ -356,7 +416,7 @@ if (!res) goto out_fail; - printk (KERN_INFO "UMSDOS 0.85g " + printk (KERN_INFO "UMSDOS 0.85i " "(compatibility level %d.%d, fast msdos)\n", UMSDOS_VERSION, UMSDOS_RELEASE); diff -ur linux/fs/umsdos.org.2.2.16/ioctl.c linux/fs/umsdos/ioctl.c --- linux/fs/umsdos.org.2.2.16/ioctl.c Sun Jul 23 18:16:13 2000 +++ linux/fs/umsdos/ioctl.c Sat Jul 29 21:08:53 2000 @@ -179,11 +179,22 @@ struct umsdos_info info; ret = umsdos_emd_dir_readentry (&new_filp, &entry); + + if (ret == -ENAMETOOLONG) { + printk (KERN_INFO "Fixing EMD entry with invalid size -- zeroing out\n"); + fill_new_filp (&new_filp, demd); + new_filp.f_pos = f_pos; + new_filp.f_reada = 0; + memset (&entry, 0, sizeof (entry)); + ret = umsdos_emd_dir_write (&new_filp, (char *) &entry, UMSDOS_REC_SIZE); + continue; + } + if (ret) break; if (entry.name_len <= 0) continue; - + umsdos_parse (entry.name, entry.name_len, &info); info.f_pos = f_pos; umsdos_manglename (&info); diff -ur linux/fs/umsdos.org.2.2.16/namei.c linux/fs/umsdos/namei.c --- linux/fs/umsdos.org.2.2.16/namei.c Sun Jul 23 18:16:13 2000 +++ linux/fs/umsdos/namei.c Sun Jul 23 20:16:05 2000 @@ -715,17 +715,35 @@ if (ret == 0) { struct iattr newattrs; + /* Do a real lookup to get the short name dentry */ + temp = umsdos_covered(olddentry->d_parent, + old_info.fake.fname, + old_info.fake.len); + ret = PTR_ERR(temp); + if (IS_ERR(temp)) + goto out_unlock2; + + /* now resolve the link ... */ + temp = umsdos_solve_hlink(temp); + ret = PTR_ERR(temp); + if (IS_ERR(temp)) + goto out_unlock2; + #ifdef UMSDOS_PARANOIA if (!oldinode->u.umsdos_i.i_is_hlink) printk("UMSDOS_link: %s/%s, ino=%ld, not marked as hlink!\n", olddentry->d_parent->d_name.name, olddentry->d_name.name, oldinode->i_ino); #endif - oldinode->i_nlink++; + temp->d_inode->i_nlink++; Printk(("UMSDOS_link: linked %s/%s, ino=%ld, nlink=%d\n", olddentry->d_parent->d_name.name, olddentry->d_name.name, oldinode->i_ino, oldinode->i_nlink)); newattrs.ia_valid = 0; - ret = umsdos_notify_change_locked(olddentry, &newattrs); + ret = umsdos_notify_change_locked(temp, &newattrs); + if (ret == 0) + mark_inode_dirty(temp->d_inode); + dput(temp); +out_unlock2: } if (olddir != dir) up(&olddir->i_sem); -- Opinions above are GNU-copylefted.
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |