lkml.org 
[lkml]   [1997]   [Jul]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
SubjectPatch to 2.1.45 for modules and msdos
Date
From

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);
\
 
 \ /
  Last update: 2005-03-22 13:39    [W:0.056 / U:0.332 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site