summaryrefslogtreecommitdiffstats
path: root/fs/umsdos
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-01-07 02:33:00 +0000
committer <ralf@linux-mips.org>1997-01-07 02:33:00 +0000
commitbeb116954b9b7f3bb56412b2494b562f02b864b1 (patch)
tree120e997879884e1b9d93b265221b939d2ef1ade1 /fs/umsdos
parent908d4681a1dc3792ecafbe64265783a86c4cccb6 (diff)
Import of Linux/MIPS 2.1.14
Diffstat (limited to 'fs/umsdos')
-rw-r--r--fs/umsdos/Makefile29
-rw-r--r--fs/umsdos/README96
-rw-r--r--fs/umsdos/check.c13
-rw-r--r--fs/umsdos/dir.c286
-rw-r--r--fs/umsdos/emd.c50
-rw-r--r--fs/umsdos/file.c37
-rw-r--r--fs/umsdos/inode.c33
-rw-r--r--fs/umsdos/ioctl.c73
-rw-r--r--fs/umsdos/mangle.c8
-rw-r--r--fs/umsdos/namei.c16
-rw-r--r--fs/umsdos/rdir.c83
-rw-r--r--fs/umsdos/symlink.c16
12 files changed, 385 insertions, 355 deletions
diff --git a/fs/umsdos/Makefile b/fs/umsdos/Makefile
index 8bdf98f97..79942b072 100644
--- a/fs/umsdos/Makefile
+++ b/fs/umsdos/Makefile
@@ -7,37 +7,18 @@
#
# Note 2! The CFLAGS definitions are now in the main makefile...
-.c.s:
- $(CC) $(CFLAGS) -S $<
-.c.o:
- $(CC) $(CFLAGS) -c $<
-.s.o:
- $(AS) -o $*.o $<
+O_TARGET := umsdos.o
+O_OBJS := dir.o emd.o file.o inode.o ioctl.o mangle.o namei.o \
+ rdir.o symlink.o #check.o
+M_OBJS := $(O_TARGET)
-OBJS= dir.o emd.o file.o inode.o ioctl.o mangle.o namei.o\
- rdir.o symlink.o #check.o
-
-umsdos.o: $(OBJS)
- $(LD) -r -o umsdos.o $(OBJS)
-
-modules: umsdos.o
- ln -sf ../fs/umsdos/umsdos.o $(TOPDIR)/modules
+include $(TOPDIR)/Rules.make
clean:
rm -f core *.o *.a *.s
-dep:
- $(CPP) -M *.c > .depend
-
p:
proto *.c >/usr/include/linux/umsdos_fs.p
doc:
nadoc -i -p umsdos.doc - /tmp/umsdos.mpg
-
-#
-# include a dependency file if one exists
-#
-ifeq (.depend,$(wildcard .depend))
-include .depend
-endif
diff --git a/fs/umsdos/README b/fs/umsdos/README
deleted file mode 100644
index 320dac6ca..000000000
--- a/fs/umsdos/README
+++ /dev/null
@@ -1,96 +0,0 @@
-Very short explanation for the impatient!!!
-
-Umsdos is a file system driver that run on top the MSDOS fs driver.
-It is written by Jacques Gelinas (jacques@solucorp.qc.ca)
-
-Umsdos is not a file system per se, but a twist to make a boring
-one into a useful one.
-
-It gives you:
-
- long file name
- Permissions and owner
- Links
- Special files (devices, pipe...)
- All is need to be a linux root fs.
-
-There is plenty of documentation on it in the source. A formated document
-made from those comments is available from
-sunsite.unc.edu:/pub/Linux/system/Filesystems/umsdos.
-
-Mostly...
-
-You mount a DOS partition like this
-
-mount -t umsdos /dev/hda3 /mnt
- ^
----------|
-
-All option are passed to the msdos drivers. Option like uid,gid etc are
-given to msdos.
-
-The default behavior of Umsdos is to do the same thing as the msdos driver
-mostly passing commands to it without much processing. Again, this is
-the default. After doing the mount on a DOS partition, nothing special
-happen. This is why all mount options are passed to the Msdos fs driver.
-
-Umsdos use a special DOS file --linux-.--- to store the information
-which can't be handle by the normal MsDOS file system. This is the trick.
-
---linux-.--- is optional. There is one per directory.
-
-**** If --linux-.--- is missing, then Umsdos process the directory the
- same way the msdos driver do. Short file name, no goodies, default
- owner and permissions. So each directory may have or not this
- --linux-.---
-
-Now, how to get those --linux-.---.
-
-\begin joke_section
-
- Well send me a directory content
- and I will send you one customised for you.
- $5 per directory. Add any applicable taxes.
-\end joke_section
-
-A utility umssync creates those. The kernel maintain them. It is available
-from the same directory above (sunsite) in the file umsdos_progs-0.7.tar.gz.
-A compiled version is available in umsdos_progs-0.7.bin.tar.gz.
-
-So in our example, after mounting mnt, we do
-
-umssync .
-
-This will promote this directory (a recursive option is available) to full
-umsdos capabilities (long name ...). A ls -l before and after won't show
-much difference however. The file which were there are still there. But now
-you can do all this:
-
- chmod 644 *
- chown you.your_groupe *
- ls >THIS_IS.A.VERY.LONG.NAME
- ln -s toto tata
- ls -l
-
-Once a directory is promoted, all subdirectory created will inherit that
-promotion.
-
-What happen if you boot DOS and create files in those promoted directories ?
-Umsdos won't notice new files, but will signal removed file (it won't crash).
-Using umssync in /etc/rc will make sure the DOS directory is in sync with
-the --linux-.---.
-
-It is a good idea to put the following command in your RC file just
-after the "mount -a":
-
- mount -a
- /sbin/umssync -i+ -c+ -r99 /umsdos_mount_point
-
- (You put one for each umsdos mount point in the fstab)
-
-This will insure nice operation. A umsdos.fsck is in the making,
-so you will be allowed to managed umsdos partition in the same way
-other filesystem are, using the generic fsck front end.
-
-Hope this helps!
-
diff --git a/fs/umsdos/check.c b/fs/umsdos/check.c
index 7fb060c7a..67846925a 100644
--- a/fs/umsdos/check.c
+++ b/fs/umsdos/check.c
@@ -1,8 +1,8 @@
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-
-#include <asm/system.h>
+/*
+ * linux/fs/umsdos/check.c
+ *
+ *
+ */
#include <linux/signal.h>
#include <linux/sched.h>
@@ -13,8 +13,9 @@
#include <linux/types.h>
#include <linux/ptrace.h>
#include <linux/mman.h>
+#include <linux/mm.h>
-extern unsigned long high_memory;
+#include <asm/system.h>
static int check_one_table(struct pde * page_dir)
{
diff --git a/fs/umsdos/dir.c b/fs/umsdos/dir.c
index 990260a92..9e0abf55a 100644
--- a/fs/umsdos/dir.c
+++ b/fs/umsdos/dir.c
@@ -7,12 +7,6 @@
* Extended MS-DOS directory handling functions
*/
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-
-#include <asm/segment.h>
-
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/fs.h>
@@ -23,6 +17,8 @@
#include <linux/umsdos_fs.h>
#include <linux/malloc.h>
+#include <asm/uaccess.h>
+
#define PRINTK(x)
#define Printk(x) printk x
@@ -31,19 +27,50 @@ extern struct inode *pseudo_root;
/*
So grep * doesn't complain in the presence of directories.
*/
-int UMSDOS_dir_read(struct inode *inode,struct file *filp,char *buf,
- int count)
+long UMSDOS_dir_read(struct inode *inode,struct file *filp,
+ char *buf, unsigned long count)
{
return -EISDIR;
}
-#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
-#define ROUND_UP(x) (((x)+3) & ~3)
+
+struct UMSDOS_DIR_ONCE {
+ void *dirbuf;
+ filldir_t filldir;
+ int count;
+ int stop;
+};
+
+/*
+ Record a single entry the first call.
+ Return -EINVAL the next one.
+*/
+static int umsdos_dir_once(
+ void * buf,
+ const char * name,
+ int name_len,
+ off_t offset,
+ ino_t ino)
+{
+ int ret = -EINVAL;
+ struct UMSDOS_DIR_ONCE *d = (struct UMSDOS_DIR_ONCE *)buf;
+ if (d->count == 0){
+ #if 0
+ char zname[100];
+ memcpy (zname,name,name_len);
+ zname[name_len] = '\0';
+ Printk (("dir_once :%s: offset %Ld\n",zname,offset));
+ #endif
+ ret = d->filldir (d->dirbuf,name,name_len,offset,ino);
+ d->stop = ret < 0;
+ d->count = 1;
+ }
+ return ret;
+}
/*
Read count directory entries from directory filp
Return a negative value from linux/errno.h.
- Return > 0 if success (The amount of byte written in
- dirent round_up to a word size (32 bits).
+ Return > 0 if success (The amount of byte written by filldir).
This function is used by the normal readdir VFS entry point and by
some function who try to find out info on a file from a pure MSDOS
@@ -52,19 +79,19 @@ int UMSDOS_dir_read(struct inode *inode,struct file *filp,char *buf,
static int umsdos_readdir_x(
struct inode *dir, /* Point to a description of the super block */
struct file *filp, /* Point to a directory which is read */
- struct dirent *dirent, /* Will hold count directory entry */
- int dirent_in_fs, /* dirent point in user's space ? */
- int count,
+ void *dirbuf, /* Will hold count directory entry */
+ /* but filled by the filldir function */
+ int internal_read, /* Called for internal purpose */
struct umsdos_dirent *u_entry, /* Optional umsdos entry */
int follow_hlink,
- off_t *pt_f_pos) /* will hold the offset of the entry in EMD */
+ filldir_t filldir)
{
int ret = 0;
umsdos_startlookup(dir);
if (filp->f_pos == UMSDOS_SPECIAL_DIRFPOS
&& dir == pseudo_root
- && dirent_in_fs){
+ && !internal_read){
/*
We don't need to simulate this pseudo directory
when umsdos_readdir_x is called for internal operation
@@ -75,13 +102,10 @@ static int umsdos_readdir_x(
linux root), it simulate a directory /DOS which points to
the real root of the file system.
*/
- put_fs_long(dir->i_sb->s_mounted->i_ino,&dirent->d_ino);
- memcpy_tofs (dirent->d_name,"DOS",3);
- put_fs_byte(0,dirent->d_name+3);
- put_fs_word (3,&dirent->d_reclen);
- if (u_entry != NULL) u_entry->flags = 0;
- ret = ROUND_UP(NAME_OFFSET(dirent) + 3 + 1);
- filp->f_pos++;
+ if (filldir (dirbuf,"DOS",3,UMSDOS_SPECIAL_DIRFPOS
+ ,dir->i_sb->s_mounted->i_ino) == 0){
+ filp->f_pos++;
+ }
}else if (filp->f_pos < 2
|| (dir != dir->i_sb->s_mounted && filp->f_pos == 32)){
/* #Specification: readdir / . and ..
@@ -116,15 +140,27 @@ static int umsdos_readdir_x(
EMD, we are back at offset 64. So we set the offset
to UMSDOS_SPECIAL_DIRFPOS(3) as soon as we have read the
.. entry from msdos.
+
+ Now (linux 1.3), umsdos_readdir can read more than one
+ entry even if we limit (umsdos_dir_once) to only one:
+ It skips over hidden file. So we switch to
+ UMSDOS_SPECIAL_DIRFPOS as soon as we have read successfully
+ the .. entry.
*/
- ret = msdos_readdir(dir,filp,dirent,count);
- if (filp->f_pos == 64) filp->f_pos = UMSDOS_SPECIAL_DIRFPOS;
+ int last_f_pos = filp->f_pos;
+ struct UMSDOS_DIR_ONCE bufk;
+ bufk.dirbuf = dirbuf;
+ bufk.filldir = filldir;
+ bufk.count = 0;
+ ret = fat_readdir(dir,filp,&bufk,umsdos_dir_once);
+ if (last_f_pos > 0 && filp->f_pos > last_f_pos) filp->f_pos = UMSDOS_SPECIAL_DIRFPOS;
if (u_entry != NULL) u_entry->flags = 0;
}else{
struct inode *emd_dir = umsdos_emd_dir_lookup(dir,0);
if (emd_dir != NULL){
+ off_t start_fpos = filp->f_pos;
if (filp->f_pos <= UMSDOS_SPECIAL_DIRFPOS+1) filp->f_pos = 0;
- PRINTK (("f_pos %ld i_size %d\n",filp->f_pos,emd_dir->i_size));
+ PRINTK (("f_pos %lu i_size %ld\n",filp->f_pos,emd_dir->i_size));
ret = 0;
while (filp->f_pos < emd_dir->i_size){
struct umsdos_dirent entry;
@@ -156,7 +192,6 @@ static int umsdos_readdir_x(
int lret;
umsdos_parse (entry.name,entry.name_len,&info);
info.f_pos = cur_f_pos;
- *pt_f_pos = cur_f_pos;
umsdos_manglename (&info);
lret = umsdos_real_lookup (dir,info.fake.fname
,info.fake.len,&inode);
@@ -177,29 +212,16 @@ static int umsdos_readdir_x(
infinite recursion /DOS/linux/DOS/linux while
walking the file system.
*/
- if (inode != pseudo_root){
- PRINTK (("Trouve ino %d ",inode->i_ino));
- if (dirent_in_fs){
- put_fs_long(inode->i_ino,&dirent->d_ino);
- memcpy_tofs (dirent->d_name,entry.name
- ,entry.name_len);
- put_fs_byte(0,dirent->d_name+entry.name_len);
- put_fs_word (entry.name_len
- ,&dirent->d_reclen);
- /* In this case, the caller only needs */
- /* flags */
- if (u_entry != NULL){
- u_entry->flags = entry.flags;
- }
- }else{
- dirent->d_ino = inode->i_ino;
- memcpy (dirent->d_name,entry.name
- ,entry.name_len);
- dirent->d_name[entry.name_len] = '\0';
- dirent->d_reclen = entry.name_len;
- if (u_entry != NULL) *u_entry = entry;
+ if (inode != pseudo_root
+ && (internal_read
+ || !(entry.flags & UMSDOS_HIDDEN))){
+ if (filldir (dirbuf
+ ,entry.name,entry.name_len
+ ,cur_f_pos, inode->i_ino) < 0){
+ filp->f_pos = cur_f_pos;
}
- ret = ROUND_UP(NAME_OFFSET(dirent) + entry.name_len + 1);
+ PRINTK (("Trouve ino %ld ",inode->i_ino));
+ if (u_entry != NULL) *u_entry = entry;
iput (inode);
break;
}
@@ -217,32 +239,48 @@ static int umsdos_readdir_x(
}
}
}
+ /*
+ If the fillbuf has failed, f_pos is back to 0.
+ To avoid getting back into the . and .. state
+ (see comments at the beginning), we put back
+ the special offset.
+ */
+ if (filp->f_pos == 0) filp->f_pos = start_fpos;
iput(emd_dir);
}
}
umsdos_endlookup(dir);
- PRINTK (("read dir %p pos %d ret %d\n",dir,filp->f_pos,ret));
+ PRINTK (("read dir %p pos %Ld ret %d\n",dir,filp->f_pos,ret));
return ret;
}
/*
Read count directory entries from directory filp
Return a negative value from linux/errno.h.
- Return > 0 if success (the amount of byte written to dirent)
+ Return 0 or positive if successful
*/
static int UMSDOS_readdir(
struct inode *dir, /* Point to a description of the super block */
struct file *filp, /* Point to a directory which is read */
- struct dirent *dirent, /* Will hold count directory entry */
- int count)
+ void *dirbuf, /* Will hold directory entries */
+ filldir_t filldir)
{
- int ret = -ENOENT;
- while (1){
+ int ret = 0;
+ int count = 0;
+ struct UMSDOS_DIR_ONCE bufk;
+ bufk.dirbuf = dirbuf;
+ bufk.filldir = filldir;
+ bufk.stop = 0;
+ PRINTK (("UMSDOS_readdir in\n"));
+ while (ret == 0 && bufk.stop == 0){
struct umsdos_dirent entry;
- off_t f_pos;
- ret = umsdos_readdir_x (dir,filp,dirent,1,count,&entry,1,&f_pos);
- if (ret <= 0 || !(entry.flags & UMSDOS_HIDDEN)) break;
+ bufk.count = 0;
+ ret = umsdos_readdir_x (dir,filp,&bufk,0,&entry,1,umsdos_dir_once);
+ if (bufk.count == 0) break;
+ count += bufk.count;
}
- return ret;
+ PRINTK (("UMSDOS_readdir out %d count %d pos %Ld\n",ret,count
+ ,filp->f_pos));
+ return count?:ret;
}
/*
Complete the inode content with info from the EMD file
@@ -304,12 +342,48 @@ void umsdos_lookup_patch (
*/
if (S_ISREG(entry->mode)) entry->mtime = inode->i_mtime;
inode->i_mode = entry->mode;
- inode->i_rdev = entry->rdev;
+ inode->i_rdev = to_kdev_t(entry->rdev);
inode->i_atime = entry->atime;
inode->i_ctime = entry->ctime;
inode->i_mtime = entry->mtime;
inode->i_uid = entry->uid;
inode->i_gid = entry->gid;
+ /* #Specification: umsdos / conversion mode
+ The msdos fs can do some inline conversion
+ of the data of a file. It can translate
+ silently from MsDOS text file format to Unix
+ one (crlf -> lf) while reading, and the reverse
+ while writing. This is activated using the mount
+ option conv=....
+
+ This is not useful for Linux file in promoted
+ directory. It can even be harmful. For this
+ reason, the binary (no conversion) mode is
+ always activated.
+ */
+ /* #Specification: umsdos / conversion mode / todo
+ A flag could be added to file and directories
+ forcing an automatic conversion mode (as
+ done with the msdos fs).
+
+ This flag could be setup on a directory basis
+ (instead of file) and all file in it would
+ logically inherited. If the conversion mode
+ is active (conv=) then the i_binary flag would
+ be left untouched in those directories.
+
+ It was proposed that the sticky bit was used
+ to set this. The problem is that new file would
+ be written incorrectly. The other problem is that
+ the sticky bit has a meaning for directories. So
+ another bit should be used (there is some space
+ in the EMD file for it) and a special utilities
+ would be used to assign the flag to a directory).
+ I don't think it is useful to assign this flag
+ on a single file.
+ */
+
+ MSDOS_I(inode)->i_binary = 1;
/* #Specification: umsdos / i_nlink
The nlink field of an inode is maintain by the MSDOS file system
for directory and by UMSDOS for other file. The logic is that
@@ -331,6 +405,53 @@ void umsdos_lookup_patch (
if (inode->u.umsdos_i.i_emd_owner==0) printk ("emd_owner still 0 ???\n");
}
}
+struct UMSDOS_DIRENT_K{
+ off_t f_pos; /* will hold the offset of the entry in EMD */
+ ino_t ino;
+};
+
+/*
+ Just to record the offset of one entry.
+*/
+static int umsdos_filldir_k(
+ void * buf,
+ const char * name,
+ int name_len,
+ off_t offset,
+ ino_t ino)
+{
+ struct UMSDOS_DIRENT_K *d = (struct UMSDOS_DIRENT_K *)buf;
+ d->f_pos = offset;
+ d->ino = ino;
+ return 0;
+}
+
+struct UMSDOS_DIR_SEARCH{
+ struct umsdos_dirent *entry;
+ int found;
+ ino_t search_ino;
+};
+
+static int umsdos_dir_search (
+ void * buf,
+ const char * name,
+ int name_len,
+ off_t offset,
+ ino_t ino)
+{
+ int ret = 0;
+ struct UMSDOS_DIR_SEARCH *d = (struct UMSDOS_DIR_SEARCH *)buf;
+ if (d->search_ino == ino){
+ d->found = 1;
+ memcpy (d->entry->name,name,name_len);
+ d->entry->name[name_len] = '\0';
+ d->entry->name_len = name_len;
+ ret = 1; /* So fat_readdir will terminate */
+ }
+ return ret;
+}
+
+
/*
Locate entry of an inode in a directory.
Return 0 or a negative error code.
@@ -357,24 +478,18 @@ int umsdos_inode2entry (
iput (emddir);
if (emddir == NULL){
/* This is a DOS directory */
+ struct UMSDOS_DIR_SEARCH bufk;
struct file filp;
filp.f_reada = 1;
filp.f_pos = 0;
- while (1){
- struct dirent dirent;
- if (umsdos_readdir_kmem (dir,&filp,&dirent,1) <= 0){
- printk ("UMSDOS: can't locate inode %ld in DOS directory???\n"
- ,inode->i_ino);
- }else if (dirent.d_ino == inode->i_ino){
- ret = 0;
- memcpy (entry->name,dirent.d_name,dirent.d_reclen);
- entry->name[dirent.d_reclen] = '\0';
- entry->name_len = dirent.d_reclen;
- inode->u.umsdos_i.i_dir_owner = dir->i_ino;
- inode->u.umsdos_i.i_emd_owner = 0;
- umsdos_setup_dir_inode(inode);
- break;
- }
+ bufk.entry = entry;
+ bufk.search_ino = inode->i_ino;
+ fat_readdir (dir,&filp,&bufk,umsdos_dir_search);
+ if (bufk.found){
+ ret = 0;
+ inode->u.umsdos_i.i_dir_owner = dir->i_ino;
+ inode->u.umsdos_i.i_emd_owner = 0;
+ umsdos_setup_dir_inode(inode);
}
}else{
/* skip . and .. see umsdos_readdir_x() */
@@ -382,16 +497,15 @@ int umsdos_inode2entry (
filp.f_reada = 1;
filp.f_pos = UMSDOS_SPECIAL_DIRFPOS;
while (1){
- struct dirent dirent;
- off_t f_pos;
- if (umsdos_readdir_x(dir,&filp,&dirent
- ,0,1,entry,0,&f_pos) <= 0){
+ struct UMSDOS_DIRENT_K bufk;
+ if (umsdos_readdir_x(dir,&filp,&bufk
+ ,1,entry,0,umsdos_filldir_k) < 0){
printk ("UMSDOS: can't locate inode %ld in EMD file???\n"
,inode->i_ino);
break;
- }else if (dirent.d_ino == inode->i_ino){
+ }else if (bufk.ino == inode->i_ino){
ret = 0;
- umsdos_lookup_patch (dir,inode,entry,f_pos);
+ umsdos_lookup_patch (dir,inode,entry,bufk.f_pos);
break;
}
}
@@ -411,7 +525,7 @@ static int umsdos_locate_ancestor (
int ret;
umsdos_patch_inode (dir,NULL,0);
ret = umsdos_real_lookup (dir,"..",2,result);
- PRINTK (("result %d %x ",ret,*result));
+ PRINTK (("result %d %p ",ret,*result));
if (ret == 0){
struct inode *adir = *result;
ret = umsdos_inode2entry (adir,dir,entry);
@@ -560,7 +674,7 @@ static int umsdos_lookup_x (
struct umsdos_info info;
ret = umsdos_parse (name,len,&info);
if (ret == 0) ret = umsdos_findentry (dir,&info,0);
- PRINTK (("lookup %s pos %d ret %d len %d ",info.fake.fname,info.f_pos,ret
+ PRINTK (("lookup %s pos %lu ret %d len %d ",info.fake.fname,info.f_pos,ret
,info.fake.len));
if (ret == 0){
/* #Specification: umsdos / lookup
@@ -581,7 +695,7 @@ static int umsdos_lookup_x (
umsdos_delentry (dir,&info,S_ISDIR(info.entry.mode));
}else{
umsdos_lookup_patch (dir,inode,&info.entry,info.f_pos);
- PRINTK (("lookup ino %d flags %d\n",inode->i_ino
+ PRINTK (("lookup ino %ld flags %d\n",inode->i_ino
,info.entry.flags));
if (info.entry.flags & UMSDOS_HLINK){
ret = umsdos_hlink2inode (inode,result);
@@ -698,6 +812,8 @@ struct inode_operations umsdos_dir_inode_operations = {
UMSDOS_rename, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
+ NULL, /* readpage */
+ NULL, /* writepage */
NULL, /* bmap */
NULL, /* truncate */
NULL /* permission */
diff --git a/fs/umsdos/emd.c b/fs/umsdos/emd.c
index b1ec47bf6..6295d0a98 100644
--- a/fs/umsdos/emd.c
+++ b/fs/umsdos/emd.c
@@ -5,65 +5,48 @@
*
* Extended MS-DOS directory handling functions
*/
-#ifdef MODULE
-#include <linux/module.h>
-#endif
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/kernel.h>
-#include <asm/segment.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/msdos_fs.h>
#include <linux/umsdos_fs.h>
+#include <asm/uaccess.h>
+
#define PRINTK(x)
#define Printk(x) printk x
-int umsdos_readdir_kmem(
- struct inode *inode,
- struct file *filp,
- struct dirent *dirent,
- int count)
-{
- int ret;
- int old_fs = get_fs();
- set_fs (KERNEL_DS);
- ret = msdos_readdir(inode,filp,dirent,count);
- set_fs (old_fs);
- return ret;
-}
/*
Read a file into kernel space memory
*/
-int umsdos_file_read_kmem(
- struct inode *inode,
+long umsdos_file_read_kmem (struct inode *inode,
struct file *filp,
char *buf,
- int count)
+ unsigned long count)
{
int ret;
int old_fs = get_fs();
set_fs (KERNEL_DS);
- ret = msdos_file_read(inode,filp,buf,count);
+ ret = fat_file_read(inode,filp,buf,count);
set_fs (old_fs);
return ret;
}
/*
Write to a file from kernel space
*/
-int umsdos_file_write_kmem(
- struct inode *inode,
+long umsdos_file_write_kmem (struct inode *inode,
struct file *filp,
- char *buf,
- int count)
+ const char *buf,
+ unsigned long count)
{
int ret;
int old_fs = get_fs();
set_fs (KERNEL_DS);
- ret = msdos_file_write(inode,filp,buf,count);
+ ret = fat_file_write(inode,filp,buf,count);
set_fs (old_fs);
return ret;
}
@@ -75,11 +58,10 @@ int umsdos_file_write_kmem(
Return 0 if ok, a negative error code if not.
*/
-int umsdos_emd_dir_write (
- struct inode *emd_dir,
+long umsdos_emd_dir_write (struct inode *emd_dir,
struct file *filp,
char *buf, /* buffer in kernel memory, not in user space */
- int count)
+ unsigned long count)
{
int written;
filp->f_flags = 0;
@@ -91,18 +73,18 @@ int umsdos_emd_dir_write (
The block of data is NOT in user space.
Return 0 if ok, -EIO if any error.
*/
-int umsdos_emd_dir_read (
- struct inode *emd_dir,
+long umsdos_emd_dir_read (struct inode *emd_dir,
struct file *filp,
char *buf, /* buffer in kernel memory, not in user space */
- int count)
+ unsigned long count)
{
- int ret = 0;
+ long int ret = 0;
int sizeread;
filp->f_flags = 0;
sizeread = umsdos_file_read_kmem (emd_dir,filp,buf,count);
if (sizeread != count){
- printk ("UMSDOS: problem with EMD file. Can't read\n");
+ printk ("UMSDOS: problem with EMD file. Can't read pos = %Ld (%d != %ld)\n"
+ ,filp->f_pos,sizeread,count);
ret = -EIO;
}
return ret;
diff --git a/fs/umsdos/file.c b/fs/umsdos/file.c
index 61eacaac6..d01ef6f87 100644
--- a/fs/umsdos/file.c
+++ b/fs/umsdos/file.c
@@ -7,13 +7,6 @@
* Extended MS-DOS regular file handling primitives
*/
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-
-#include <asm/segment.h>
-#include <asm/system.h>
-
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/msdos_fs.h>
@@ -23,20 +16,22 @@
#include <linux/msdos_fs.h>
#include <linux/umsdos_fs.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
#define PRINTK(x)
#define Printk(x) printk x
/*
Read a file into user space memory
*/
-static int UMSDOS_file_read(
+static long UMSDOS_file_read(
struct inode *inode,
struct file *filp,
char *buf,
- int count)
+ unsigned long count)
{
/* We have to set the access time because msdos don't care */
- int ret = msdos_file_read(inode,filp,buf,count);
+ int ret = fat_file_read(inode,filp,buf,count);
if (!IS_RDONLY(inode)){
inode->i_atime = CURRENT_TIME;
inode->i_dirt = 1;
@@ -46,13 +41,13 @@ static int UMSDOS_file_read(
/*
Write a file from user space memory
*/
-static int UMSDOS_file_write(
+static long UMSDOS_file_write(
struct inode *inode,
struct file *filp,
- char *buf,
- int count)
+ const char *buf,
+ unsigned long count)
{
- return msdos_file_write(inode,filp,buf,count);
+ return fat_file_write(inode,filp,buf,count);
}
/*
Truncate a file to 0 length.
@@ -60,7 +55,7 @@ static int UMSDOS_file_write(
static void UMSDOS_truncate(struct inode *inode)
{
PRINTK (("UMSDOS_truncate\n"));
- msdos_truncate (inode);
+ fat_truncate (inode);
inode->i_ctime = inode->i_mtime = CURRENT_TIME;
inode->i_dirt = 1;
}
@@ -73,7 +68,7 @@ struct file_operations umsdos_file_operations = {
NULL, /* readdir - bad */
NULL, /* select - default */
NULL, /* ioctl - default */
- generic_mmap, /* mmap */
+ generic_file_mmap, /* mmap */
NULL, /* no special open is needed */
NULL, /* release */
file_fsync /* fsync */
@@ -92,10 +87,12 @@ struct inode_operations umsdos_file_inode_operations = {
NULL, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
- msdos_bmap, /* bmap */
+ generic_readpage, /* readpage */
+ NULL, /* writepage */
+ fat_bmap, /* bmap */
UMSDOS_truncate,/* truncate */
NULL, /* permission */
- msdos_smap /* smap */
+ fat_smap /* smap */
};
/* For other with larger and unaligned file system */
struct file_operations umsdos_file_operations_no_bmap = {
@@ -105,7 +102,7 @@ struct file_operations umsdos_file_operations_no_bmap = {
NULL, /* readdir - bad */
NULL, /* select - default */
NULL, /* ioctl - default */
- msdos_mmap, /* mmap */
+ fat_mmap, /* mmap */
NULL, /* no special open is needed */
NULL, /* release */
file_fsync /* fsync */
@@ -124,6 +121,8 @@ struct inode_operations umsdos_file_inode_operations_no_bmap = {
NULL, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
+ NULL, /* readpage */
+ NULL, /* writepage */
NULL, /* bmap */
UMSDOS_truncate,/* truncate */
NULL, /* permission */
diff --git a/fs/umsdos/inode.c b/fs/umsdos/inode.c
index 22be740cc..8157edca6 100644
--- a/fs/umsdos/inode.c
+++ b/fs/umsdos/inode.c
@@ -6,20 +6,14 @@
*
*/
-#ifdef MODULE
#include <linux/module.h>
-#include <linux/version.h>
-#else
-#define MOD_INC_USE_COUNT
-#define MOD_DEC_USE_COUNT
-#endif
#include <linux/fs.h>
#include <linux/msdos_fs.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/errno.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/umsdos_fs.h>
@@ -50,7 +44,7 @@ void UMSDOS_put_inode(struct inode *inode)
if (inode != NULL && inode == pseudo_root){
printk ("Umsdos: Oops releasing pseudo_root. Notify jacques@solucorp.qc.ca\n");
}
- msdos_put_inode(inode);
+ fat_put_inode(inode);
}
@@ -63,7 +57,7 @@ void UMSDOS_put_super(struct super_block *sb)
void UMSDOS_statfs(struct super_block *sb,struct statfs *buf, int bufsiz)
{
- msdos_statfs(sb,buf,bufsiz);
+ fat_statfs(sb,buf,bufsiz);
}
@@ -233,7 +227,7 @@ void UMSDOS_read_inode(struct inode *inode)
if (S_ISDIR(inode->i_mode)
&& (inode->u.umsdos_i.u.dir_info.creating != 0
|| inode->u.umsdos_i.u.dir_info.looking != 0
- || inode->u.umsdos_i.u.dir_info.p != NULL)){
+ || waitqueue_active(&inode->u.umsdos_i.u.dir_info.p))){
Printk (("read inode %d %d %p\n"
,inode->u.umsdos_i.u.dir_info.creating
,inode->u.umsdos_i.u.dir_info.looking
@@ -263,7 +257,7 @@ void UMSDOS_write_inode(struct inode *inode)
struct iattr newattrs;
PRINTK (("UMSDOS_write_inode emd %d\n",inode->u.umsdos_i.i_emd_owner));
- msdos_write_inode(inode);
+ fat_write_inode(inode);
newattrs.ia_mtime = inode->i_mtime;
newattrs.ia_atime = inode->i_atime;
newattrs.ia_ctime = inode->i_ctime;
@@ -410,6 +404,7 @@ struct super_block *UMSDOS_read_super(
printk ("UMSDOS Beta 0.6 (compatibility level %d.%d, fast msdos)\n"
,UMSDOS_VERSION,UMSDOS_RELEASE);
if (sb != NULL){
+ MSDOS_SB(sb)->options.dotsOK = 0; /* disable hidden==dotfile */
sb->s_op = &umsdos_sops;
PRINTK (("umsdos_read_super %p\n",sb->s_mounted));
umsdos_setup_dir_inode (sb->s_mounted);
@@ -499,18 +494,24 @@ struct super_block *UMSDOS_read_super(
}
-#ifdef MODULE
-
-char kernel_version[] = UTS_RELEASE;
static struct file_system_type umsdos_fs_type = {
UMSDOS_read_super, "umsdos", 1, NULL
};
+int init_umsdos_fs(void)
+{
+ return register_filesystem(&umsdos_fs_type);
+}
+
+#ifdef MODULE
int init_module(void)
{
- register_filesystem(&umsdos_fs_type);
- return 0;
+ int status;
+
+ if ((status = init_umsdos_fs()) == 0)
+ register_symtab(0);
+ return status;
}
void cleanup_module(void)
diff --git a/fs/umsdos/ioctl.c b/fs/umsdos/ioctl.c
index d766ef939..a4d4108b8 100644
--- a/fs/umsdos/ioctl.c
+++ b/fs/umsdos/ioctl.c
@@ -5,12 +5,10 @@
*
* Extended MS-DOS ioctl directory handling functions
*/
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#include <linux/errno.h>
+#include <linux/mm.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/fs.h>
@@ -20,6 +18,37 @@
#define PRINTK(x)
#define Printk(x) printk x
+struct UMSDOS_DIR_ONCE {
+ struct dirent *ent;
+ int count;
+};
+
+/*
+ Record a single entry the first call.
+ Return -EINVAL the next one.
+*/
+static int umsdos_ioctl_fill(
+ void * buf,
+ const char * name,
+ int name_len,
+ off_t offset,
+ ino_t ino)
+{
+ int ret = -EINVAL;
+ struct UMSDOS_DIR_ONCE *d = (struct UMSDOS_DIR_ONCE *)buf;
+ if (d->count == 0){
+ copy_to_user (d->ent->d_name,name,name_len);
+ put_user ('\0',d->ent->d_name+name_len);
+ put_user (name_len,&d->ent->d_reclen);
+ put_user (ino,&d->ent->d_ino);
+ put_user (offset,&d->ent->d_off);
+ d->count = 1;
+ ret = 0;
+ }
+ return ret;
+}
+
+
/*
Perform special function on a directory
*/
@@ -30,11 +59,19 @@ int UMSDOS_ioctl_dir (
unsigned long data)
{
int ret = -EPERM;
+ int err;
/* #Specification: ioctl / acces
Only root (effective id) is allowed to do IOCTL on directory
in UMSDOS. EPERM is returned for other user.
*/
- if (current->euid == 0
+ /*
+ Well, not all cases require write access, but it simplifies
+ the code, and let's face it, there is only one client (umssync)
+ for all this.
+ */
+ if ((err = verify_area(VERIFY_WRITE,(void*)data,sizeof(struct umsdos_ioctl))) < 0) {
+ ret = err;
+ }else if (current->euid == 0
|| cmd == UMSDOS_GETVERSION){
struct umsdos_ioctl *idata = (struct umsdos_ioctl *)data;
ret = -EINVAL;
@@ -69,8 +106,8 @@ int UMSDOS_ioctl_dir (
Return always 0.
*/
- put_fs_byte (UMSDOS_VERSION,&idata->version);
- put_fs_byte (UMSDOS_RELEASE,&idata->release);
+ put_user(UMSDOS_VERSION,&idata->version);
+ put_user(UMSDOS_RELEASE,&idata->release);
ret = 0;
}else if (cmd == UMSDOS_READDIR_DOS){
/* #Specification: ioctl / UMSDOS_READDIR_DOS
@@ -80,7 +117,11 @@ int UMSDOS_ioctl_dir (
Return > 0 if success.
*/
- ret = msdos_readdir(dir,filp,&idata->dos_dirent,1);
+ struct UMSDOS_DIR_ONCE bufk;
+ bufk.count = 0;
+ bufk.ent = &idata->dos_dirent;
+ fat_readdir(dir,filp,&bufk,umsdos_ioctl_fill);
+ ret = bufk.count == 1 ? 1 : 0;
}else if (cmd == UMSDOS_READDIR_EMD){
/* #Specification: ioctl / UMSDOS_READDIR_EMD
One entry is read from the EMD at the current
@@ -111,9 +152,9 @@ int UMSDOS_ioctl_dir (
umsdos_parse (entry.name,entry.name_len,&info);
info.f_pos = f_pos;
umsdos_manglename(&info);
- memcpy_tofs(&idata->umsdos_dirent,&entry
+ copy_to_user(&idata->umsdos_dirent,&entry
,sizeof(entry));
- memcpy_tofs(&idata->dos_dirent.d_name
+ copy_to_user(&idata->dos_dirent.d_name
,info.fake.fname,info.fake.len+1);
break;
}
@@ -146,7 +187,7 @@ int UMSDOS_ioctl_dir (
: &umsdos_rdir_inode_operations;
}else{
struct umsdos_ioctl data;
- memcpy_fromfs (&data,idata,sizeof(data));
+ copy_from_user (&data,idata,sizeof(data));
if (cmd == UMSDOS_CREAT_EMD){
/* #Specification: ioctl / UMSDOS_CREAT_EMD
The umsdos_dirent field of the struct umsdos_ioctl is used
@@ -178,7 +219,7 @@ int UMSDOS_ioctl_dir (
ret = msdos_rename (dir
,data.dos_dirent.d_name,data.dos_dirent.d_reclen
,dir
- ,data.umsdos_dirent.name,data.umsdos_dirent.name_len);
+ ,data.umsdos_dirent.name,data.umsdos_dirent.name_len,0);
}else if (cmd == UMSDOS_UNLINK_EMD){
/* #Specification: ioctl / UMSDOS_UNLINK_EMD
The umsdos_dirent field of the struct umsdos_ioctl is used
@@ -240,7 +281,7 @@ int UMSDOS_ioctl_dir (
data.stat.st_atime = inode->i_atime;
data.stat.st_ctime = inode->i_ctime;
data.stat.st_mtime = inode->i_mtime;
- memcpy_tofs (&idata->stat,&data.stat,sizeof(data.stat));
+ copy_to_user (&idata->stat,&data.stat,sizeof(data.stat));
iput (inode);
}
}else if (cmd == UMSDOS_DOS_SETUP){
@@ -263,9 +304,9 @@ int UMSDOS_ioctl_dir (
umsdos_dirent.uid and gid sets the owner and group.
umsdos_dirent.mode set the permissions flags.
*/
- dir->i_sb->u.msdos_sb.fs_uid = data.umsdos_dirent.uid;
- dir->i_sb->u.msdos_sb.fs_gid = data.umsdos_dirent.gid;
- dir->i_sb->u.msdos_sb.fs_umask = data.umsdos_dirent.mode;
+ dir->i_sb->u.msdos_sb.options.fs_uid = data.umsdos_dirent.uid;
+ dir->i_sb->u.msdos_sb.options.fs_gid = data.umsdos_dirent.gid;
+ dir->i_sb->u.msdos_sb.options.fs_umask = data.umsdos_dirent.mode;
ret = 0;
}
}
diff --git a/fs/umsdos/mangle.c b/fs/umsdos/mangle.c
index a7649a39a..fb94b89c8 100644
--- a/fs/umsdos/mangle.c
+++ b/fs/umsdos/mangle.c
@@ -5,13 +5,9 @@
*
* Control the mangling of file name to fit msdos name space.
* Many optimisation by GLU == dglaude@is1.vub.ac.be (GLAUDE DAVID)
-*/
-#ifdef MODULE
-#include <linux/module.h>
-#endif
+ */
#include <linux/errno.h>
-#include <linux/ctype.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/umsdos_fs.h>
@@ -175,7 +171,7 @@ int umsdos_parse (
like this.
*/
int i;
- static char *spc = "\"*+,/:;<=>?[\\]|~";
+ static const char *spc = "\"*+,/:;<=>?[\\]|~";
is_init = 1;
for (i=0; i<=32; i++) lkp[i] = '#';
for (i=33; i<'A'; i++) lkp[i] = (char)i;
diff --git a/fs/umsdos/namei.c b/fs/umsdos/namei.c
index 42820bb98..51cfb0809 100644
--- a/fs/umsdos/namei.c
+++ b/fs/umsdos/namei.c
@@ -5,10 +5,7 @@
* Inspired from linux/fs/msdos/... by Werner Almesberger
*
* Maintain and access the --linux alternate directory file.
-*/
-#ifdef MODULE
-#include <linux/module.h>
-#endif
+ */
#include <linux/errno.h>
#include <linux/kernel.h>
@@ -126,7 +123,6 @@ void umsdos_startlookup (struct inode *dir)
while (umsdos_waitcreate (dir) != 0);
dir->u.umsdos_i.u.dir_info.looking++;
}
-void check_page_tables(void);
/*
Unlock the directory.
@@ -357,7 +353,8 @@ chkstk();
ret = msdos_rename (old_dir
,old_info.fake.fname,old_info.fake.len
,new_dir
- ,new_info.fake.fname,new_info.fake.len);
+ ,new_info.fake.fname,new_info.fake.len
+ ,0);
chkstk();
PRINTK (("after m_rename ret %d ",ret));
if (ret != 0){
@@ -437,7 +434,7 @@ static int umsdos_symlink_x(
in unused entry of the EMD file. The other is to have a separate
file dedicated to hold all symbolic links data.
- Lets go for simplicity...
+ Let's go for simplicity...
*/
struct inode *inode;
int ret;
@@ -450,7 +447,7 @@ static int umsdos_symlink_x(
struct file filp;
filp.f_pos = 0;
/* Make the inode acceptable to MSDOS */
- ret = umsdos_file_write_kmem (inode,&filp,(char*)symname,len);
+ ret = umsdos_file_write_kmem (inode,&filp,symname,len);
iput (inode);
if (ret >= 0){
if (ret != len){
@@ -1018,7 +1015,8 @@ int UMSDOS_rename(
int old_len,
struct inode * new_dir,
const char * new_name,
- int new_len)
+ int new_len,
+ int must_be_dir)
{
/* #Specification: weakness / rename
There is a case where UMSDOS rename has a different behavior
diff --git a/fs/umsdos/rdir.c b/fs/umsdos/rdir.c
index d708709bd..da07c0d61 100644
--- a/fs/umsdos/rdir.c
+++ b/fs/umsdos/rdir.c
@@ -7,12 +7,6 @@
* (For directory without EMD file).
*/
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-
-#include <asm/segment.h>
-
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/msdos_fs.h>
@@ -22,50 +16,65 @@
#include <linux/umsdos_fs.h>
#include <linux/malloc.h>
+#include <asm/uaccess.h>
+
#define PRINTK(x)
#define Printk(x) printk x
extern struct inode *pseudo_root;
-static int UMSDOS_rreaddir (
- struct inode *dir,
- struct file *filp,
- struct dirent *dirent,
- int count)
+struct RDIR_FILLDIR {
+ void *dirbuf;
+ filldir_t filldir;
+ int real_root;
+};
+
+static int rdir_filldir(
+ void * buf,
+ const char * name,
+ int name_len,
+ off_t offset,
+ ino_t ino)
{
int ret = 0;
- while (1){
- int len = -1;
- ret = msdos_readdir(dir,filp,dirent,count);
- if (ret > 0) len = get_fs_word(&dirent->d_reclen);
- if (len == 5
- && pseudo_root != NULL
- && dir->i_sb->s_mounted == pseudo_root->i_sb->s_mounted){
- /*
- In pseudo root mode, we must eliminate logically
- the directory linux from the real root.
- */
- char name[5];
- memcpy_fromfs (name,dirent->d_name,5);
- if (memcmp(name,UMSDOS_PSDROOT_NAME,UMSDOS_PSDROOT_LEN)!=0) break;
- }else{
- if (pseudo_root != NULL
- && len == 2
- && dir == dir->i_sb->s_mounted
- && dir == pseudo_root->i_sb->s_mounted){
- char name[2];
- memcpy_fromfs (name,dirent->d_name,2);
- if (name[0] == '.' && name[1] == '.'){
- put_fs_long (pseudo_root->i_ino,&dirent->d_ino);
- }
+ struct RDIR_FILLDIR *d = (struct RDIR_FILLDIR*) buf;
+ if (d->real_root){
+ /* real root of a pseudo_rooted partition */
+ if (name_len != UMSDOS_PSDROOT_LEN
+ || memcmp(name,UMSDOS_PSDROOT_NAME,UMSDOS_PSDROOT_LEN)!=0){
+ /* So it is not the /linux directory */
+ if (name_len == 2
+ && name[0] == '.'
+ && name[1] == '.'){
+ /* Make sure the .. entry points back to the pseudo_root */
+ ino = pseudo_root->i_ino;
}
- break;
+ ret = d->filldir (d->dirbuf,name,name_len,offset,ino);
}
+ }else{
+ /* Any DOS directory */
+ ret = d->filldir (d->dirbuf,name,name_len,offset,ino);
}
return ret;
}
+
+static int UMSDOS_rreaddir (
+ struct inode *dir,
+ struct file *filp,
+ void *dirbuf,
+ filldir_t filldir)
+{
+ struct RDIR_FILLDIR bufk;
+ bufk.filldir = filldir;
+ bufk.dirbuf = dirbuf;
+ bufk.real_root = pseudo_root != NULL
+ && dir == dir->i_sb->s_mounted
+ && dir == pseudo_root->i_sb->s_mounted;
+ return fat_readdir(dir,filp,&bufk,rdir_filldir);
+}
+
/*
Lookup into a non promoted directory.
If the result is a directory, make sure we find out if it is
@@ -252,6 +261,8 @@ struct inode_operations umsdos_rdir_inode_operations = {
msdos_rename, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
+ NULL, /* readpage */
+ NULL, /* writepage */
NULL, /* bmap */
NULL, /* truncate */
NULL /* permission */
diff --git a/fs/umsdos/symlink.c b/fs/umsdos/symlink.c
index 6ab27c5dd..7bbcc0ef0 100644
--- a/fs/umsdos/symlink.c
+++ b/fs/umsdos/symlink.c
@@ -6,12 +6,6 @@
*
* Extended MS-DOS regular file handling primitives
*/
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-
-#include <asm/segment.h>
-#include <asm/system.h>
#include <linux/sched.h>
#include <linux/fs.h>
@@ -22,8 +16,12 @@
#include <linux/umsdos_fs.h>
#include <linux/malloc.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
#define PRINTK(x)
#define Printk(x) printk x
+
/*
Read the data associate with the symlink.
Return length read in buffer or a negative error code.
@@ -31,7 +29,7 @@
static int umsdos_readlink_x (
struct inode *inode,
char *buffer,
- int (*msdos_read)(struct inode *, struct file *, char *, int),
+ long (*msdos_read)(struct inode *, struct file *, char *, unsigned long),
int bufsiz)
{
int ret = inode->i_size;
@@ -105,7 +103,7 @@ static int UMSDOS_readlink(struct inode * inode, char * buffer, int buflen)
{
int ret = -EINVAL;
if (S_ISLNK(inode->i_mode)) {
- ret = umsdos_readlink_x (inode,buffer,msdos_file_read,buflen);
+ ret = umsdos_readlink_x (inode,buffer,fat_file_read,buflen);
}
PRINTK (("readlink %d %x bufsiz %d\n",ret,inode->i_mode,buflen));
iput(inode);
@@ -139,6 +137,8 @@ struct inode_operations umsdos_symlink_inode_operations = {
NULL, /* rename */
UMSDOS_readlink, /* readlink */
UMSDOS_follow_link, /* follow_link */
+ NULL, /* readpage */
+ NULL, /* writepage */
NULL, /* bmap */
NULL, /* truncate */
NULL /* permission */