Messages in this thread Patch in this message | | | Subject | Patch to 2.1.45 for modules and msdos | Date | Thu, 17 Jul 1997 20:43:05 +0200 | From | Alain Knaff <> |
| |
The patch at the end of this mail attempts to fix the two following items:
1. Some modules (isofs, nfs, autofs) would not insert because of missing symbols in ksyms. Fixed by adding them.
2. The msdos fs is a little bit more useful now. You can now not only list directories, but also read the contents of files, and use df. However, in keeping with the "featureful kernel" spirit, I did not test it thoroughly whether everything works correctly. Vfat and umsdos are not done yet. Basic stuff seems to work (mkdir, rmdir, create files, remove files); however, there is a problem when accessing files by using "funny" names:
# cat >testing this is a test # ls testing # cat TESTing this is a test # mv testing tust # cat TESTing this is a test # ls tust # cat testing cat: testing: No such file or directory # cat TESTing this is a test
Reason for this behavior: although on a MS-DOS fs "TESTing" and "testing" are the same physical directory entry, two dentries get allocated for them. The source for the problem is probably in msdos_lookup, however I have no idea yet how to best fix this.
Regards,
Alain
diff -ur 2.1.45/linux/fs/fat/inode.c featurefulKernel/linux/fs/fat/inode.c --- 2.1.45/linux/fs/fat/inode.c Thu Jul 17 19:49:21 1997 +++ featurefulKernel/linux/fs/fat/inode.c Thu Jul 17 20:33:24 1997 @@ -44,8 +44,18 @@ MSDOS_I(inode)->i_linked = NULL; } if (MSDOS_I(inode)->i_busy) fat_cache_inval_inode(inode); - return; } +} + +void fat_delete_inode(struct inode *inode) +{ + struct inode *depend, *linked; + struct super_block *sb; + + depend = MSDOS_I(inode)->i_depend; + linked = MSDOS_I(inode)->i_linked; + sb = inode->i_sb; + inode->i_size = 0; fat_truncate(inode); if (depend) { diff -ur 2.1.45/linux/fs/msdos/namei.c featurefulKernel/linux/fs/msdos/namei.c --- 2.1.45/linux/fs/msdos/namei.c Thu Jul 17 19:49:21 1997 +++ featurefulKernel/linux/fs/msdos/namei.c Thu Jul 17 20:30:17 1997 @@ -53,9 +53,10 @@ struct super_operations msdos_sops = { msdos_read_inode, - fat_notify_change, fat_write_inode, fat_put_inode, + fat_delete_inode, + fat_notify_change, msdos_put_super, NULL, /* added in 0.96c */ fat_statfs, @@ -190,73 +191,64 @@ } /***** Get inode using directory and name */ -int msdos_lookup(struct inode *dir,const char *name,int len, - struct inode **result) +int msdos_lookup(struct inode *dir, struct dentry *dentry) { struct super_block *sb = dir->i_sb; int ino,res; struct msdos_dir_entry *de; struct buffer_head *bh; - struct inode *next; + struct inode *next, *inode; PRINTK (("msdos_lookup\n")); - *result = NULL; - if (!dir) return -ENOENT; - if (!S_ISDIR(dir->i_mode)) { - iput(dir); - return -ENOENT; - } PRINTK (("msdos_lookup 2\n")); - if (len == 1 && name[0] == '.') { - *result = dir; + if (dentry->d_name.len == 1 && dentry->d_name.name[0] == '.') { + inode = dir; return 0; } - if (len == 2 && name[0] == '.' && name[1] == '.') { + if (dentry->d_name.len == 2 && + dentry->d_name.name[0] == '.' && + dentry->d_name.name[1] == '.') { ino = fat_parent_ino(dir,0); - iput(dir); if (ino < 0) return ino; - if (!(*result = iget(dir->i_sb,ino))) return -EACCES; + if (!(inode = iget(dir->i_sb,ino))) return -EACCES; return 0; } PRINTK (("msdos_lookup 3\n")); - if ((res = msdos_find(dir,name,len,&bh,&de,&ino)) < 0) { - iput(dir); + if ((res = msdos_find(dir,dentry->d_name.name,dentry->d_name.len, + &bh,&de,&ino)) < 0) return res; - } + PRINTK (("msdos_lookup 4\n")); if (bh) fat_brelse(sb, bh); PRINTK (("msdos_lookup 4.5\n")); - if (!(*result = iget(dir->i_sb,ino))) { - iput(dir); + if (!(inode = iget(dir->i_sb,ino))) return -EACCES; - } + PRINTK (("msdos_lookup 5\n")); - if (!(*result)->i_sb || - ((*result)->i_sb->s_magic != MSDOS_SUPER_MAGIC)) { + if (!(inode)->i_sb || + ((inode)->i_sb->s_magic != MSDOS_SUPER_MAGIC)) /* crossed a mount point into a non-msdos fs */ - iput(dir); return 0; - } - if (MSDOS_I(*result)->i_busy) { /* mkdir in progress */ - iput(*result); - iput(dir); + + if (MSDOS_I(inode)->i_busy) { /* mkdir in progress */ + iput(inode); return -ENOENT; } PRINTK (("msdos_lookup 6\n")); - while (MSDOS_I(*result)->i_old) { - next = MSDOS_I(*result)->i_old; - iput(*result); - if (!(*result = iget(next->i_sb,next->i_ino))) { + while (MSDOS_I(inode)->i_old) { + next = MSDOS_I(inode)->i_old; + iput(inode); + if (!(inode = iget(next->i_sb,next->i_ino))) { fat_fs_panic(dir->i_sb,"msdos_lookup: Can't happen"); iput(dir); return -ENOENT; } } PRINTK (("msdos_lookup 7\n")); - iput(dir); PRINTK (("msdos_lookup 8\n")); + d_add(dentry, inode); return 0; } @@ -295,28 +287,28 @@ if (!*result) return -EIO; (*result)->i_mtime = (*result)->i_atime = (*result)->i_ctime = CURRENT_TIME; - mark_inode_dirty(*result); + mark_inode_dirty( (*result) ); return 0; } /***** Create a file or directory */ -int msdos_create(struct inode *dir,const char *name,int len,int mode, - struct inode **result) +int msdos_create(struct inode *dir, struct dentry * dentry,int mode) { struct super_block *sb = dir->i_sb; struct buffer_head *bh; struct msdos_dir_entry *de; char msdos_name[MSDOS_NAME]; int ino,res,is_hid; + struct inode *result; if (!dir) return -ENOENT; if ((res = msdos_format_name(MSDOS_SB(dir->i_sb)->options.name_check, - name,len,msdos_name,0, + dentry->d_name.name,dentry->d_name.len, + msdos_name,0, MSDOS_SB(dir->i_sb)->options.dotsOK)) < 0) { - iput(dir); return res; } - is_hid = (name[0]=='.') && (msdos_name[0]!='.'); + is_hid = (dentry->d_name.name[0]=='.') && (msdos_name[0]!='.'); fat_lock_creation(); /* Scan for existing file twice, so that creating a file fails * with -EINVAL if the other (dotfile/nondotfile) exists. @@ -325,19 +317,17 @@ if (fat_scan(dir,msdos_name,&bh,&de,&ino,SCAN_HID) >= 0) { fat_unlock_creation(); fat_brelse(sb, bh); - iput(dir); return is_hid ? -EEXIST : -EINVAL; } if (fat_scan(dir,msdos_name,&bh,&de,&ino,SCAN_NOTHID) >= 0) { fat_unlock_creation(); fat_brelse(sb, bh); - iput(dir); return is_hid ? -EINVAL : -EEXIST; } - res = msdos_create_entry(dir,msdos_name,len,S_ISDIR(mode),is_hid, - result); + res = msdos_create_entry(dir,msdos_name,0,S_ISDIR(mode),is_hid, + &result); + d_instantiate(dentry, result); fat_unlock_creation(); - iput(dir); return res; } @@ -388,7 +378,7 @@ } /***** Remove a directory */ -int msdos_rmdir(struct inode *dir,const char *name,int len) +int msdos_rmdir(struct inode * dir, struct dentry *dentry) { struct super_block *sb = dir->i_sb; int res,ino; @@ -399,16 +389,17 @@ bh = NULL; inode = NULL; res = -EPERM; - if (name[0] == '.' && (len == 1 || (len == 2 && name[1] == '.'))) + if (dentry->d_name.name[0] == '.' && + (dentry->d_name.len == 1 || + (dentry->d_name.len == 2 && dentry->d_name.name[1] == '.'))) goto rmdir_done; - if ((res = msdos_find(dir,name,len,&bh,&de,&ino)) < 0) goto rmdir_done; + if ((res = msdos_find(dir, + dentry->d_name.name,dentry->d_name.len, + &bh,&de,&ino)) < 0) goto rmdir_done; res = -ENOENT; - if (!(inode = iget(dir->i_sb,ino))) goto rmdir_done; + inode = dentry->d_inode; res = -ENOTDIR; if (!S_ISDIR(inode->i_mode)) goto rmdir_done; - res = -EBUSY; - if (dir->i_dev != inode->i_dev || dir == inode) - goto rmdir_done; res = msdos_empty(inode); if (res) goto rmdir_done; @@ -420,15 +411,14 @@ de->name[0] = DELETED_FLAG; fat_mark_buffer_dirty(sb, bh, 1); res = 0; + d_delete(dentry); rmdir_done: fat_brelse(sb, bh); - iput(dir); - iput(inode); return res; } /***** Make a directory */ -int msdos_mkdir(struct inode *dir,const char *name,int len,int mode) +int msdos_mkdir(struct inode * dir, struct dentry * dentry, int mode) { struct super_block *sb = dir->i_sb; struct buffer_head *bh; @@ -438,23 +428,19 @@ int ino,res,is_hid; if ((res = msdos_format_name(MSDOS_SB(dir->i_sb)->options.name_check, - name,len,msdos_name,0, - MSDOS_SB(dir->i_sb)->options.dotsOK)) < 0) { - iput(dir); + dentry->d_name.name,dentry->d_name.len,msdos_name,0, + MSDOS_SB(dir->i_sb)->options.dotsOK)) < 0) return res; - } - is_hid = (name[0]=='.') && (msdos_name[0]!='.'); + is_hid = (dentry->d_name.name[0]=='.') && (msdos_name[0]!='.'); fat_lock_creation(); if (fat_scan(dir,msdos_name,&bh,&de,&ino,SCAN_ANY) >= 0) { fat_unlock_creation(); fat_brelse(sb, bh); - iput(dir); return -EEXIST; } - if ((res = msdos_create_entry(dir,msdos_name,len,1,is_hid, + if ((res = msdos_create_entry(dir,msdos_name,dentry->d_name.len,1,is_hid, &inode)) < 0) { fat_unlock_creation(); - iput(dir); return res; } dir->i_nlink++; @@ -477,12 +463,11 @@ mark_inode_dirty(dot); MSDOS_I(inode)->i_busy = 0; iput(dot); - iput(inode); - iput(dir); + d_instantiate(dentry, inode); return 0; mkdir_error: iput(inode); - if (msdos_rmdir(dir,name,len) < 0) + if (msdos_rmdir(dir,dentry) < 0) fat_fs_panic(dir->i_sb,"rmdir in mkdir failed"); fat_unlock_creation(); return res; @@ -493,6 +478,7 @@ struct inode *dir, const char *name, int len, + struct dentry *dentry, int nospc) /* Flag special file ? */ { struct super_block *sb = dir->i_sb; @@ -505,10 +491,7 @@ inode = NULL; if ((res = msdos_find(dir,name,len,&bh,&de,&ino)) < 0) goto unlink_done; - if (!(inode = iget(dir->i_sb,ino))) { - res = -ENOENT; - goto unlink_done; - } + inode = dentry->d_inode; if (!S_ISREG(inode->i_mode) && nospc){ res = -EPERM; goto unlink_done; @@ -524,23 +507,27 @@ mark_inode_dirty(dir); de->name[0] = DELETED_FLAG; fat_mark_buffer_dirty(sb, bh, 1); + fat_brelse(sb, bh); + d_delete(dentry); + return res; + unlink_done: fat_brelse(sb, bh); - iput(inode); - iput(dir); return res; } /***** Unlink, as called for msdosfs */ -int msdos_unlink(struct inode *dir,const char *name,int len) +int msdos_unlink(struct inode *dir,struct dentry *dentry) { - return msdos_unlinkx (dir,name,len,1); + return msdos_unlinkx (dir,dentry->d_name.name,dentry->d_name.len, + dentry,1); } /***** Unlink, as called for umsdosfs */ -int msdos_unlink_umsdos(struct inode *dir,const char *name,int len) +int msdos_unlink_umsdos(struct inode *dir,struct dentry *dentry) { - return msdos_unlinkx (dir,name,len,0); + return msdos_unlinkx (dir,dentry->d_name.name, dentry->d_name.len, + dentry,0); } /***** Rename within a directory */ @@ -745,8 +732,8 @@ } /***** Rename, a wrapper for rename_same_dir & rename_diff_dir */ -int msdos_rename(struct inode *old_dir,const char *old_name,int old_len, - struct inode *new_dir,const char *new_name,int new_len) +int msdos_rename (struct inode * old_dir, struct dentry *old_dentry, + struct inode * new_dir,struct dentry *new_dentry) { struct super_block *sb = old_dir->i_sb; char old_msdos_name[MSDOS_NAME],new_msdos_name[MSDOS_NAME]; @@ -756,28 +743,28 @@ int is_hid,old_hid; /* if new file and old file are hidden */ if ((error = msdos_format_name(MSDOS_SB(old_dir->i_sb)->options.name_check, - old_name,old_len,old_msdos_name,1, + old_dentry->d_name.name,old_dentry->d_name.len,old_msdos_name,1, MSDOS_SB(old_dir->i_sb)->options.dotsOK)) < 0) goto rename_done; if ((error = msdos_format_name(MSDOS_SB(new_dir->i_sb)->options.name_check, - new_name,new_len,new_msdos_name,0, + new_dentry->d_name.name,new_dentry->d_name.len,new_msdos_name,0, MSDOS_SB(new_dir->i_sb)->options.dotsOK)) < 0) goto rename_done; - is_hid = (new_name[0]=='.') && (new_msdos_name[0]!='.'); - old_hid = (old_name[0]=='.') && (old_msdos_name[0]!='.'); + is_hid = (new_dentry->d_name.name[0]=='.') && (new_msdos_name[0]!='.'); + old_hid = (old_dentry->d_name.name[0]=='.') && (old_msdos_name[0]!='.'); if ((error = fat_scan(old_dir,old_msdos_name,&old_bh,&old_de, &old_ino,old_hid?SCAN_HID:SCAN_NOTHID)) < 0) goto rename_done; fat_lock_creation(); if (old_dir == new_dir) - error = rename_same_dir(old_dir,old_msdos_name,old_len,new_dir, - new_msdos_name,new_len,old_bh,old_de,old_ino,is_hid); - else error = rename_diff_dir(old_dir,old_msdos_name,old_len,new_dir, - new_msdos_name,new_len,old_bh,old_de,old_ino,is_hid); + error = rename_same_dir(old_dir,old_msdos_name,old_dentry->d_name.len,new_dir, + new_msdos_name,new_dentry->d_name.len,old_bh,old_de,old_ino,is_hid); + else error = rename_diff_dir(old_dir,old_msdos_name,old_dentry->d_name.len,new_dir, + new_msdos_name,new_dentry->d_name.len,old_bh,old_de,old_ino,is_hid); fat_unlock_creation(); fat_brelse(sb, old_bh); + d_move(old_dentry, new_dentry->d_parent, &new_dentry->d_name); + d_delete(new_dentry); rename_done: - iput(old_dir); - iput(new_dir); return error; } diff -ur 2.1.45/linux/include/linux/msdos_fs.h featurefulKernel/linux/include/linux/msdos_fs.h --- 2.1.45/linux/include/linux/msdos_fs.h Thu Jul 17 19:49:24 1997 +++ featurefulKernel/linux/include/linux/msdos_fs.h Thu Jul 17 20:29:28 1997 @@ -211,6 +211,7 @@ extern int fat_bmap(struct inode *inode,int block); extern int fat_notify_change(struct inode *,struct iattr *); extern void fat_put_inode(struct inode *inode); +extern void fat_delete_inode(struct inode *inode); extern void fat_put_super(struct super_block *sb); extern void fat_read_inode(struct inode *inode, struct inode_operations *dir_ops); extern struct super_block *fat_read_super(struct super_block *s, void *data, int silent); @@ -252,16 +253,14 @@ /* msdos.c - these are for Umsdos */ extern void msdos_read_inode(struct inode *inode); -extern int msdos_lookup(struct inode *dir,const char *name,int len, - struct inode **result); -extern int msdos_create(struct inode *dir,const char *name,int len,int mode, - struct inode **result); -extern int msdos_rmdir(struct inode *dir,const char *name,int len); -extern int msdos_mkdir(struct inode *dir,const char *name,int len,int mode); -extern int msdos_unlink(struct inode *dir,const char *name,int len); -extern int msdos_unlink_umsdos(struct inode *dir,const char *name,int len); -extern int msdos_rename(struct inode *old_dir,const char *old_name,int old_len, - struct inode *new_dir,const char *new_name,int new_len); +extern int msdos_lookup(struct inode * dir, struct dentry *dentry); +extern int msdos_create(struct inode * dir, struct dentry * dentry, int mode); +extern int msdos_rmdir(struct inode * dir, struct dentry *dentry); +extern int msdos_mkdir(struct inode * dir, struct dentry * dentry, int mode); +extern int msdos_unlink(struct inode * dir, struct dentry *dentry); +extern int msdos_unlink_umsdos(struct inode * dir, struct dentry *dentry); +extern int msdos_rename(struct inode * old_dir, struct dentry *old_dentry, + struct inode * new_dir,struct dentry *new_dentry); /* fatfs_syms.c */ extern int init_fat_fs(void); diff -ur 2.1.45/linux/kernel/ksyms.c featurefulKernel/linux/kernel/ksyms.c --- 2.1.45/linux/kernel/ksyms.c Thu Jul 17 19:49:28 1997 +++ featurefulKernel/linux/kernel/ksyms.c Thu Jul 17 19:30:03 1997 @@ -150,6 +150,9 @@ EXPORT_SYMBOL(close_fp); EXPORT_SYMBOL(d_alloc_root); EXPORT_SYMBOL(d_delete); +EXPORT_SYMBOL(d_add); +EXPORT_SYMBOL(d_move); +EXPORT_SYMBOL(d_instantiate); EXPORT_SYMBOL(insert_file_free); EXPORT_SYMBOL(check_disk_change); EXPORT_SYMBOL(invalidate_buffers); @@ -181,6 +184,7 @@ EXPORT_SYMBOL(posix_block_lock); EXPORT_SYMBOL(posix_unblock_lock); EXPORT_SYMBOL(dput); +EXPORT_SYMBOL(__mark_inode_dirty); #if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE) EXPORT_SYMBOL(do_nfsservctl);
| |