diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-06-13 16:29:25 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-06-13 16:29:25 +0000 |
commit | db7d4daea91e105e3859cf461d7e53b9b77454b2 (patch) | |
tree | 9bb65b95440af09e8aca63abe56970dd3360cc57 /fs/fat | |
parent | 9c1c01ead627bdda9211c9abd5b758d6c687d8ac (diff) |
Merge with Linux 2.2.8.
Diffstat (limited to 'fs/fat')
-rw-r--r-- | fs/fat/cvf.c | 31 | ||||
-rw-r--r-- | fs/fat/dir.c | 23 | ||||
-rw-r--r-- | fs/fat/fatfs_syms.c | 1 | ||||
-rw-r--r-- | fs/fat/file.c | 4 | ||||
-rw-r--r-- | fs/fat/inode.c | 22 | ||||
-rw-r--r-- | fs/fat/misc.c | 6 | ||||
-rw-r--r-- | fs/fat/mmap.c | 2 |
7 files changed, 72 insertions, 17 deletions
diff --git a/fs/fat/cvf.c b/fs/fat/cvf.c index 62b70b160..9dd70f8c5 100644 --- a/fs/fat/cvf.c +++ b/fs/fat/cvf.c @@ -1,8 +1,11 @@ -/* +/* * CVF extensions for fat-based filesystems * * written 1997,1998 by Frank Gockel <gockel@sent13.uni-duisburg.de> * + * please do not remove the next line, dmsdos needs it for verifying patches + * CVF-FAT-VERSION-ID: 1.2.0 + * */ #include<linux/sched.h> @@ -11,6 +14,10 @@ #include<linux/msdos_fs_sb.h> #include<linux/string.h> #include<linux/fat_cvf.h> +#include<linux/config.h> +#ifdef CONFIG_KMOD +#include<linux/kmod.h> +#endif #define MAX_CVF_FORMATS 3 @@ -95,6 +102,24 @@ int detect_cvf(struct super_block*sb,char*force) int found_i=-1; if(force) + if(strcmp(force,"autoload")==0) + { +#ifdef CONFIG_KMOD + request_module("cvf_autoload"); + force=NULL; +#else + printk("cannot autoload CVF modules: kmod support is not compiled into kernel\n"); + return -1; +#endif + } + +#ifdef CONFIG_KMOD + if(force) + if(*force) + request_module(force); +#endif + + if(force) { if(*force) { for(i=0;i<MAX_CVF_FORMATS;++i) { if(cvf_formats[i]) @@ -102,6 +127,8 @@ int detect_cvf(struct super_block*sb,char*force) return i; } } + printk("CVF format %s unknown (module not loaded?)\n",force); + return -1; } } @@ -115,6 +142,6 @@ int detect_cvf(struct super_block*sb,char*force) } if(found==1)return found_i; - if(found>1)printk("CVF detection ambiguous, use cvf_format=xxx option\n"); + if(found>1)printk("CVF detection ambiguous, please use cvf_format=xxx option\n"); return -1; } diff --git a/fs/fat/dir.c b/fs/fat/dir.c index 1c44247a0..b6d6fb405 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c @@ -9,6 +9,7 @@ * * VFAT extensions by Gordon Chaffee <chaffee@plateau.cs.berkeley.edu> * Merged with msdos fs by Henrik Storner <storner@osiris.ping.dk> + * Plugged buffer overrun in readdir(). AV */ #define ASC_LINUX_VERSION(V, P, S) (((V) * 65536) + ((P) * 256) + (S)) @@ -59,6 +60,7 @@ struct file_operations fat_dir_operations = { * characters are a sort of uuencoded 16 bit Unicode value. This lets * us do a full dump and restore of Unicode filenames. We could get * into some trouble with long Unicode names, but ignore that right now. + * Ahem... Stack smashing in ring 0 isn't fun. Fixed. */ static int uni16_to_x8(unsigned char *ascii, unsigned char *uni, int uni_xlate, @@ -93,6 +95,11 @@ uni16_to_x8(unsigned char *ascii, unsigned char *uni, int uni_xlate, *op++ = '?'; } } + /* We have some slack there, so it's OK */ + if (op>ascii+256) { + op = ascii + 256; + break; + } } *op = 0; return (op - ascii); @@ -138,8 +145,6 @@ int fat_readdirx( unsigned char *unicode = NULL; struct nls_table *nls = MSDOS_SB(sb)->nls_io; - if (!inode || !S_ISDIR(inode->i_mode)) - return -EBADF; /* Fake . and .. for the root directory. */ if (inode->i_ino == MSDOS_ROOT_INO) { while (oldpos < 2) { @@ -186,9 +191,17 @@ int fat_readdirx( id = ds->id; if (id & 0x40) { slots = id & ~0x40; - long_slots = slots; - is_long = 1; - alias_checksum = ds->alias_checksum; + /* + * Dirty, but not dirtier than the original, + * and plugs the hole. + */ + if (slots > 20) + slots = 0; + else { + long_slots = slots; + is_long = 1; + alias_checksum = ds->alias_checksum; + } } get_new_entry = 1; diff --git a/fs/fat/fatfs_syms.c b/fs/fat/fatfs_syms.c index f57db8bf3..838c679d4 100644 --- a/fs/fat/fatfs_syms.c +++ b/fs/fat/fatfs_syms.c @@ -54,6 +54,7 @@ EXPORT_SYMBOL(lock_fat); EXPORT_SYMBOL(unlock_fat); EXPORT_SYMBOL(fat_dir_ioctl); EXPORT_SYMBOL(fat_readpage); +EXPORT_SYMBOL(fat_is_binary); int init_fat_fs(void) { diff --git a/fs/fat/file.c b/fs/fat/file.c index 0ff5f187f..7c9518181 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c @@ -456,6 +456,10 @@ void fat_truncate(struct inode *inode) /* Why no return value? Surely the disk could fail... */ if (IS_IMMUTABLE(inode)) return /* -EPERM */; + if(inode->i_sb->s_flags&MS_RDONLY) { + printk("FAT: fat_truncate called though fs is read-only, uhh...\n"); + return /* -EROFS */; + } cluster = SECTOR_SIZE*MSDOS_SB(inode->i_sb)->cluster_size; (void) fat_free(inode,(inode->i_size+(cluster-1))/cluster); MSDOS_I(inode)->i_attrs |= ATTR_ARCH; diff --git a/fs/fat/inode.c b/fs/fat/inode.c index e018eb880..339bcb6f6 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -3,6 +3,10 @@ * * Written 1992,1993 by Werner Almesberger * VFAT extensions by Gordon Chaffee, merged with msdos fs by Henrik Storner + * + * Fixes: + * + * Max Cohan: Fixed invalid FSINFO offset when info_sector is 0 */ #include <linux/version.h> @@ -328,7 +332,6 @@ fat_read_super(struct super_block *sb, void *data, int silent) fat_brelse (sb, bh); goto out_no_bread; } - set_blocksize(sb->s_dev, blksize); /* * The DOS3 partition size limit is *not* 32M as many people think. @@ -362,8 +365,16 @@ fat_read_super(struct super_block *sb, void *data, int silent) fat32 = 1; MSDOS_SB(sb)->fat_length= CF_LE_W(b->fat32_length)*sector_mult; MSDOS_SB(sb)->root_cluster = CF_LE_L(b->root_cluster); - MSDOS_SB(sb)->fsinfo_offset = - CF_LE_W(b->info_sector) * logical_sector_size + 0x1e0; + + /* MC - if info_sector is 0, don't multiply by 0 */ + if(CF_LE_W(b->info_sector) == 0) { + MSDOS_SB(sb)->fsinfo_offset = + logical_sector_size + 0x1e0; + } else { + MSDOS_SB(sb)->fsinfo_offset = + (CF_LE_W(b->info_sector) * logical_sector_size) + + 0x1e0; + } if (MSDOS_SB(sb)->fsinfo_offset + sizeof(struct fat_boot_fsinfo) > sb->s_blocksize) { printk("fat_read_super: Bad fsinfo_offset\n"); fat_brelse(sb, bh); @@ -411,6 +422,7 @@ fat_read_super(struct super_block *sb, void *data, int silent) || !b->secs_track || !b->heads; } fat_brelse(sb, bh); + set_blocksize(sb->s_dev, blksize); /* This must be done after the brelse because the bh is a dummy allocated by fat_bread (see buffer.c) @@ -691,8 +703,8 @@ void fat_read_inode(struct inode *inode, struct inode_operations *fs_dir_inode_o if(raw_entry->attr & ATTR_SYS) if (MSDOS_SB(sb)->options.sys_immutable) inode->i_flags |= S_IMMUTABLE; - MSDOS_I(inode)->i_binary = is_binary(MSDOS_SB(sb)->options.conversion, - raw_entry->ext); + MSDOS_I(inode)->i_binary = + fat_is_binary(MSDOS_SB(sb)->options.conversion, raw_entry->ext); MSDOS_I(inode)->i_attrs = raw_entry->attr & ATTR_UNUSED; /* this is as close to the truth as we can get ... */ inode->i_blksize = MSDOS_SB(sb)->cluster_size*SECTOR_SIZE; diff --git a/fs/fat/misc.c b/fs/fat/misc.c index b398a0bbd..1dfddd3c7 100644 --- a/fs/fat/misc.c +++ b/fs/fat/misc.c @@ -51,11 +51,11 @@ void fat_fs_panic(struct super_block *s,const char *msg) /* - * is_binary selects optional text conversion based on the conversion mode and - * the extension part of the file name. + * fat_is_binary selects optional text conversion based on the conversion mode + * and the extension part of the file name. */ -int is_binary(char conversion,char *extension) +int fat_is_binary(char conversion,char *extension) { char *walk; diff --git a/fs/fat/mmap.c b/fs/fat/mmap.c index 4cda79196..0494ad013 100644 --- a/fs/fat/mmap.c +++ b/fs/fat/mmap.c @@ -113,8 +113,6 @@ int fat_mmap(struct file * file, struct vm_area_struct * vma) mark_inode_dirty(inode); } - vma->vm_file = file; - file->f_count++; vma->vm_ops = &fat_file_mmap; return 0; } |