Commit 9179a307 authored by Linus Torvalds's avatar Linus Torvalds

Merge home.transmeta.com:/home/torvalds/v2.5/hirofumi

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 56fed2f2 3b26a2ed
...@@ -6,6 +6,6 @@ export-objs := fatfs_syms.o ...@@ -6,6 +6,6 @@ export-objs := fatfs_syms.o
obj-$(CONFIG_FAT_FS) += fat.o obj-$(CONFIG_FAT_FS) += fat.o
fat-objs := buffer.o cache.o dir.o file.o inode.o misc.o cvf.o fatfs_syms.o fat-objs := cache.o dir.o file.o inode.o misc.o fatfs_syms.o
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
/*
* linux/fs/fat/buffer.c
*
*
*/
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/msdos_fs.h>
#include <linux/fat_cvf.h>
#include <linux/buffer_head.h>
struct buffer_head *fat_bread(struct super_block *sb, int block)
{
return MSDOS_SB(sb)->cvf_format->cvf_bread(sb,block);
}
struct buffer_head *fat_getblk(struct super_block *sb, int block)
{
return MSDOS_SB(sb)->cvf_format->cvf_getblk(sb,block);
}
void fat_brelse (struct super_block *sb, struct buffer_head *bh)
{
if (bh)
MSDOS_SB(sb)->cvf_format->cvf_brelse(sb,bh);
}
void fat_mark_buffer_dirty (
struct super_block *sb,
struct buffer_head *bh)
{
MSDOS_SB(sb)->cvf_format->cvf_mark_buffer_dirty(sb,bh);
}
void fat_set_uptodate (
struct super_block *sb,
struct buffer_head *bh,
int val)
{
MSDOS_SB(sb)->cvf_format->cvf_set_uptodate(sb,bh,val);
}
int fat_is_uptodate(struct super_block *sb, struct buffer_head *bh)
{
return MSDOS_SB(sb)->cvf_format->cvf_is_uptodate(sb,bh);
}
void fat_ll_rw_block (
struct super_block *sb,
int opr,
int nbreq,
struct buffer_head *bh[32])
{
MSDOS_SB(sb)->cvf_format->cvf_ll_rw_block(sb,opr,nbreq,bh);
}
struct buffer_head *default_fat_bread(struct super_block *sb, int block)
{
return sb_bread(sb, block);
}
struct buffer_head *default_fat_getblk(struct super_block *sb, int block)
{
return sb_getblk(sb, block);
}
void default_fat_brelse(struct super_block *sb, struct buffer_head *bh)
{
brelse (bh);
}
void default_fat_mark_buffer_dirty (
struct super_block *sb,
struct buffer_head *bh)
{
mark_buffer_dirty (bh);
}
void default_fat_set_uptodate (
struct super_block *sb,
struct buffer_head *bh,
int val)
{
if (val)
set_buffer_uptodate(bh);
else
clear_buffer_uptodate(bh);
}
int default_fat_is_uptodate (struct super_block *sb, struct buffer_head *bh)
{
return buffer_uptodate(bh);
}
void default_fat_ll_rw_block (
struct super_block *sb,
int opr,
int nbreq,
struct buffer_head *bh[32])
{
ll_rw_block(opr,nbreq,bh);
}
...@@ -10,31 +10,11 @@ ...@@ -10,31 +10,11 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/msdos_fs.h> #include <linux/msdos_fs.h>
#include <linux/fat_cvf.h>
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#if 0
# define PRINTK(x) printk x
#else
# define PRINTK(x)
#endif
static struct fat_cache *fat_cache,cache[FAT_CACHE]; static struct fat_cache *fat_cache,cache[FAT_CACHE];
static spinlock_t fat_cache_lock = SPIN_LOCK_UNLOCKED; static spinlock_t fat_cache_lock = SPIN_LOCK_UNLOCKED;
/* Returns the this'th FAT entry, -1 if it is an end-of-file entry. If
new_value is != -1, that FAT entry is replaced by it. */
int fat_access(struct super_block *sb,int nr,int new_value)
{
return MSDOS_SB(sb)->cvf_format->fat_access(sb,nr,new_value);
}
int fat_bmap(struct inode *inode,int sector)
{
return MSDOS_SB(inode->i_sb)->cvf_format->cvf_bmap(inode,sector);
}
int __fat_access(struct super_block *sb, int nr, int new_value) int __fat_access(struct super_block *sb, int nr, int new_value)
{ {
struct msdos_sb_info *sbi = MSDOS_SB(sb); struct msdos_sb_info *sbi = MSDOS_SB(sb);
...@@ -51,17 +31,18 @@ int __fat_access(struct super_block *sb, int nr, int new_value) ...@@ -51,17 +31,18 @@ int __fat_access(struct super_block *sb, int nr, int new_value)
last = first+1; last = first+1;
} }
b = sbi->fat_start + (first >> sb->s_blocksize_bits); b = sbi->fat_start + (first >> sb->s_blocksize_bits);
if (!(bh = fat_bread(sb, b))) { if (!(bh = sb_bread(sb, b))) {
printk("FAT: bread(block %d) in fat_access failed\n", b); printk(KERN_ERR "FAT: bread(block %d) in"
" fat_access failed\n", b);
return -EIO; return -EIO;
} }
if ((first >> sb->s_blocksize_bits) == (last >> sb->s_blocksize_bits)) { if ((first >> sb->s_blocksize_bits) == (last >> sb->s_blocksize_bits)) {
bh2 = bh; bh2 = bh;
} else { } else {
if (!(bh2 = fat_bread(sb, b+1))) { if (!(bh2 = sb_bread(sb, b + 1))) {
fat_brelse(sb, bh); brelse(bh);
printk("FAT: bread(block %d) in fat_access failed\n", printk(KERN_ERR "FAT: bread(block %d) in"
b + 1); " fat_access failed\n", b + 1);
return -EIO; return -EIO;
} }
} }
...@@ -99,35 +80,39 @@ int __fat_access(struct super_block *sb, int nr, int new_value) ...@@ -99,35 +80,39 @@ int __fat_access(struct super_block *sb, int nr, int new_value)
*p_first = new_value & 0xff; *p_first = new_value & 0xff;
*p_last = (*p_last & 0xf0) | (new_value >> 8); *p_last = (*p_last & 0xf0) | (new_value >> 8);
} }
fat_mark_buffer_dirty(sb, bh2); mark_buffer_dirty(bh2);
} }
fat_mark_buffer_dirty(sb, bh); mark_buffer_dirty(bh);
for (copy = 1; copy < sbi->fats; copy++) { for (copy = 1; copy < sbi->fats; copy++) {
b = sbi->fat_start + (first >> sb->s_blocksize_bits) b = sbi->fat_start + (first >> sb->s_blocksize_bits)
+ sbi->fat_length * copy; + sbi->fat_length * copy;
if (!(c_bh = fat_bread(sb, b))) if (!(c_bh = sb_bread(sb, b)))
break; break;
if (bh != bh2) { if (bh != bh2) {
if (!(c_bh2 = fat_bread(sb, b+1))) { if (!(c_bh2 = sb_bread(sb, b+1))) {
fat_brelse(sb, c_bh); brelse(c_bh);
break; break;
} }
memcpy(c_bh2->b_data, bh2->b_data, sb->s_blocksize); memcpy(c_bh2->b_data, bh2->b_data, sb->s_blocksize);
fat_mark_buffer_dirty(sb, c_bh2); mark_buffer_dirty(c_bh2);
fat_brelse(sb, c_bh2); brelse(c_bh2);
} }
memcpy(c_bh->b_data, bh->b_data, sb->s_blocksize); memcpy(c_bh->b_data, bh->b_data, sb->s_blocksize);
fat_mark_buffer_dirty(sb, c_bh); mark_buffer_dirty(c_bh);
fat_brelse(sb, c_bh); brelse(c_bh);
} }
} }
fat_brelse(sb, bh); brelse(bh);
if (bh != bh2) if (bh != bh2)
fat_brelse(sb, bh2); brelse(bh2);
return next; return next;
} }
int default_fat_access(struct super_block *sb, int nr, int new_value) /*
* Returns the this'th FAT entry, -1 if it is an end-of-file entry. If
* new_value is != -1, that FAT entry is replaced by it.
*/
int fat_access(struct super_block *sb, int nr, int new_value)
{ {
int next; int next;
...@@ -150,7 +135,7 @@ int default_fat_access(struct super_block *sb, int nr, int new_value) ...@@ -150,7 +135,7 @@ int default_fat_access(struct super_block *sb, int nr, int new_value)
void fat_cache_init(void) void fat_cache_init(void)
{ {
static int initialized = 0; static int initialized;
int count; int count;
spin_lock(&fat_cache_lock); spin_lock(&fat_cache_lock);
...@@ -227,8 +212,8 @@ void fat_cache_add(struct inode *inode,int f_clu,int d_clu) ...@@ -227,8 +212,8 @@ void fat_cache_add(struct inode *inode,int f_clu,int d_clu)
&& walk->start_cluster == first && walk->start_cluster == first
&& walk->file_cluster == f_clu) { && walk->file_cluster == f_clu) {
if (walk->disk_cluster != d_clu) { if (walk->disk_cluster != d_clu) {
printk("FAT: cache corruption inode=%lu\n", printk(KERN_ERR "FAT: cache corruption"
inode->i_ino); " (ino %lu)\n", inode->i_ino);
spin_unlock(&fat_cache_lock); spin_unlock(&fat_cache_lock);
fat_cache_inval_inode(inode); fat_cache_inval_inode(inode);
return; return;
...@@ -317,7 +302,7 @@ static int fat_get_cluster(struct inode *inode, int cluster) ...@@ -317,7 +302,7 @@ static int fat_get_cluster(struct inode *inode, int cluster)
return nr; return nr;
} }
int default_fat_bmap(struct inode *inode,int sector) int fat_bmap(struct inode *inode, int sector)
{ {
struct super_block *sb = inode->i_sb; struct super_block *sb = inode->i_sb;
struct msdos_sb_info *sbi = MSDOS_SB(sb); struct msdos_sb_info *sbi = MSDOS_SB(sb);
......
/*
* 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/fs.h>
#include <linux/msdos_fs.h>
#include <linux/msdos_fs_sb.h>
#include <linux/fat_cvf.h>
#include <linux/config.h>
#include <linux/buffer_head.h>
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
#endif
#define MAX_CVF_FORMATS 3
struct buffer_head *default_fat_bread(struct super_block *,int);
struct buffer_head *default_fat_getblk(struct super_block *, int);
void default_fat_brelse(struct super_block *, struct buffer_head *);
void default_fat_mark_buffer_dirty (struct super_block *, struct buffer_head *);
void default_fat_set_uptodate (struct super_block *, struct buffer_head *,int);
int default_fat_is_uptodate(struct super_block *, struct buffer_head *);
int default_fat_access(struct super_block *sb,int nr,int new_value);
void default_fat_ll_rw_block (struct super_block *sb, int opr, int nbreq,
struct buffer_head *bh[32]);
int default_fat_bmap(struct inode *inode,int block);
ssize_t default_fat_file_write(struct file *filp, const char *buf,
size_t count, loff_t *ppos);
struct cvf_format default_cvf = {
cvf_version: 0, /* version - who cares? */
cvf_version_text: "plain",
flags: 0, /* flags - who cares? */
cvf_bread: default_fat_bread,
cvf_getblk: default_fat_getblk,
cvf_brelse: default_fat_brelse,
cvf_mark_buffer_dirty: default_fat_mark_buffer_dirty,
cvf_set_uptodate: default_fat_set_uptodate,
cvf_is_uptodate: default_fat_is_uptodate,
cvf_ll_rw_block: default_fat_ll_rw_block,
fat_access: default_fat_access,
cvf_bmap: default_fat_bmap,
cvf_file_read: generic_file_read,
cvf_file_write: default_fat_file_write,
};
struct cvf_format *cvf_formats[MAX_CVF_FORMATS];
int cvf_format_use_count[MAX_CVF_FORMATS];
int register_cvf_format(struct cvf_format*cvf_format)
{ int i,j;
for(i=0;i<MAX_CVF_FORMATS;++i)
{ if(cvf_formats[i]==NULL)
{ /* free slot found, now check version */
for(j=0;j<MAX_CVF_FORMATS;++j)
{ if(cvf_formats[j])
{ if(cvf_formats[j]->cvf_version==cvf_format->cvf_version)
{ printk("register_cvf_format: version %d already registered\n",
cvf_format->cvf_version);
return -1;
}
}
}
cvf_formats[i]=cvf_format;
cvf_format_use_count[i]=0;
printk("CVF format %s (version id %d) successfully registered.\n",
cvf_format->cvf_version_text,cvf_format->cvf_version);
return 0;
}
}
printk("register_cvf_format: too many formats\n");
return -1;
}
int unregister_cvf_format(struct cvf_format*cvf_format)
{ int i;
for(i=0;i<MAX_CVF_FORMATS;++i)
{ if(cvf_formats[i])
{ if(cvf_formats[i]->cvf_version==cvf_format->cvf_version)
{ if(cvf_format_use_count[i])
{ printk("unregister_cvf_format: format %d in use, cannot remove!\n",
cvf_formats[i]->cvf_version);
return -1;
}
printk("CVF format %s (version id %d) successfully unregistered.\n",
cvf_formats[i]->cvf_version_text,cvf_formats[i]->cvf_version);
cvf_formats[i]=NULL;
return 0;
}
}
}
printk("unregister_cvf_format: format %d is not registered\n",
cvf_format->cvf_version);
return -1;
}
void dec_cvf_format_use_count_by_version(int version)
{ int i;
for(i=0;i<MAX_CVF_FORMATS;++i)
{ if(cvf_formats[i])
{ if(cvf_formats[i]->cvf_version==version)
{ --cvf_format_use_count[i];
if(cvf_format_use_count[i]<0)
{ cvf_format_use_count[i]=0;
printk(KERN_EMERG "FAT FS/CVF: This is a bug in cvf_version_use_count\n");
}
return;
}
}
}
printk("dec_cvf_format_use_count_by_version: version %d not found ???\n",
version);
}
int detect_cvf(struct super_block*sb,char*force)
{ int i;
int found=0;
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])
{ if(!strcmp(cvf_formats[i]->cvf_version_text,force))
return i;
}
}
printk("CVF format %s unknown (module not loaded?)\n",force);
return -1;
}
}
for(i=0;i<MAX_CVF_FORMATS;++i)
{ if(cvf_formats[i])
{ if(cvf_formats[i]->detect_cvf(sb))
{ ++found;
found_i=i;
}
}
}
if(found==1)return found_i;
if(found>1)printk("CVF detection ambiguous, please use cvf_format=xxx option\n");
return -1;
}
...@@ -22,8 +22,6 @@ ...@@ -22,8 +22,6 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#define PRINTK(X)
struct file_operations fat_dir_operations = { struct file_operations fat_dir_operations = {
read: generic_read_dir, read: generic_read_dir,
readdir: fat_readdir, readdir: fat_readdir,
...@@ -219,7 +217,7 @@ int fat_search_long(struct inode *inode, const char *name, int name_len, ...@@ -219,7 +217,7 @@ int fat_search_long(struct inode *inode, const char *name, int name_len,
unicode = (wchar_t *) unicode = (wchar_t *)
__get_free_page(GFP_KERNEL); __get_free_page(GFP_KERNEL);
if (!unicode) { if (!unicode) {
fat_brelse(sb, bh); brelse(bh);
return -ENOMEM; return -ENOMEM;
} }
} }
...@@ -335,7 +333,7 @@ int fat_search_long(struct inode *inode, const char *name, int name_len, ...@@ -335,7 +333,7 @@ int fat_search_long(struct inode *inode, const char *name, int name_len,
*spos = cpos - sizeof(struct msdos_dir_entry); *spos = cpos - sizeof(struct msdos_dir_entry);
*lpos = cpos - res*sizeof(struct msdos_dir_entry); *lpos = cpos - res*sizeof(struct msdos_dir_entry);
EODir: EODir:
fat_brelse(sb, bh); brelse(bh);
if (unicode) { if (unicode) {
free_page((unsigned long) unicode); free_page((unsigned long) unicode);
} }
...@@ -417,7 +415,7 @@ static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent, ...@@ -417,7 +415,7 @@ static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent,
__get_free_page(GFP_KERNEL); __get_free_page(GFP_KERNEL);
if (!unicode) { if (!unicode) {
filp->f_pos = cpos; filp->f_pos = cpos;
fat_brelse(sb, bh); brelse(bh);
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
} }
...@@ -578,7 +576,7 @@ static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent, ...@@ -578,7 +576,7 @@ static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent,
filp->f_pos = cpos; filp->f_pos = cpos;
FillFailed: FillFailed:
if (bh) if (bh)
fat_brelse(sb, bh); brelse(bh);
if (unicode) { if (unicode) {
free_page((unsigned long) unicode); free_page((unsigned long) unicode);
} }
...@@ -636,8 +634,6 @@ static int vfat_ioctl_fill( ...@@ -636,8 +634,6 @@ static int vfat_ioctl_fill(
put_user(0, d1->d_name+len); put_user(0, d1->d_name+len);
put_user(len, &d1->d_reclen); put_user(len, &d1->d_reclen);
} }
PRINTK(("FAT d1=%p d2=%p len=%d, name_len=%d\n",
d1, d2, len, name_len));
return 0; return 0;
} }
...@@ -672,11 +668,6 @@ int fat_dir_ioctl(struct inode * inode, struct file * filp, ...@@ -672,11 +668,6 @@ int fat_dir_ioctl(struct inode * inode, struct file * filp,
vfat_ioctl_fill, 1, 1); vfat_ioctl_fill, 1, 1);
} }
default: default:
/* forward ioctl to CVF extension */
if (MSDOS_SB(inode->i_sb)->cvf_format &&
MSDOS_SB(inode->i_sb)->cvf_format->cvf_dir_ioctl)
return MSDOS_SB(inode->i_sb)->cvf_format
->cvf_dir_ioctl(inode,filp,cmd,arg);
return -EINVAL; return -EINVAL;
} }
...@@ -704,9 +695,8 @@ int fat_dir_empty(struct inode *dir) ...@@ -704,9 +695,8 @@ int fat_dir_empty(struct inode *dir)
break; break;
} }
} }
if (bh)
fat_brelse(dir->i_sb, bh);
brelse(bh);
return result; return result;
} }
...@@ -726,7 +716,7 @@ int fat_add_entries(struct inode *dir,int slots, struct buffer_head **bh, ...@@ -726,7 +716,7 @@ int fat_add_entries(struct inode *dir,int slots, struct buffer_head **bh,
while (fat_get_entry(dir, &curr, bh, de, ino) > -1) { while (fat_get_entry(dir, &curr, bh, de, ino) > -1) {
/* check the maximum size of directory */ /* check the maximum size of directory */
if (curr >= FAT_MAX_DIR_SIZE) { if (curr >= FAT_MAX_DIR_SIZE) {
fat_brelse(sb, *bh); brelse(*bh);
return -ENOSPC; return -ENOSPC;
} }
...@@ -743,7 +733,7 @@ int fat_add_entries(struct inode *dir,int slots, struct buffer_head **bh, ...@@ -743,7 +733,7 @@ int fat_add_entries(struct inode *dir,int slots, struct buffer_head **bh,
new_bh = fat_extend_dir(dir); new_bh = fat_extend_dir(dir);
if (IS_ERR(new_bh)) if (IS_ERR(new_bh))
return PTR_ERR(new_bh); return PTR_ERR(new_bh);
fat_brelse(sb, new_bh); brelse(new_bh);
do { do {
fat_get_entry(dir, &curr, bh, de, ino); fat_get_entry(dir, &curr, bh, de, ino);
} while (++row < slots); } while (++row < slots);
...@@ -753,7 +743,6 @@ int fat_add_entries(struct inode *dir,int slots, struct buffer_head **bh, ...@@ -753,7 +743,6 @@ int fat_add_entries(struct inode *dir,int slots, struct buffer_head **bh,
int fat_new_dir(struct inode *dir, struct inode *parent, int is_vfat) int fat_new_dir(struct inode *dir, struct inode *parent, int is_vfat)
{ {
struct super_block *sb = dir->i_sb;
struct buffer_head *bh; struct buffer_head *bh;
struct msdos_dir_entry *de; struct msdos_dir_entry *de;
__u16 date, time; __u16 date, time;
...@@ -779,8 +768,8 @@ int fat_new_dir(struct inode *dir, struct inode *parent, int is_vfat) ...@@ -779,8 +768,8 @@ int fat_new_dir(struct inode *dir, struct inode *parent, int is_vfat)
de[0].starthi = CT_LE_W(MSDOS_I(dir)->i_logstart>>16); de[0].starthi = CT_LE_W(MSDOS_I(dir)->i_logstart>>16);
de[1].start = CT_LE_W(MSDOS_I(parent)->i_logstart); de[1].start = CT_LE_W(MSDOS_I(parent)->i_logstart);
de[1].starthi = CT_LE_W(MSDOS_I(parent)->i_logstart>>16); de[1].starthi = CT_LE_W(MSDOS_I(parent)->i_logstart>>16);
fat_mark_buffer_dirty(sb, bh); mark_buffer_dirty(bh);
fat_brelse(sb, bh); brelse(bh);
dir->i_atime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; dir->i_atime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
mark_inode_dirty(dir); mark_inode_dirty(dir);
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/msdos_fs.h> #include <linux/msdos_fs.h>
#include <linux/fat_cvf.h>
EXPORT_SYMBOL(fat_new_dir); EXPORT_SYMBOL(fat_new_dir);
EXPORT_SYMBOL(fat_get_block); EXPORT_SYMBOL(fat_get_block);
...@@ -18,7 +17,6 @@ EXPORT_SYMBOL(fat_clear_inode); ...@@ -18,7 +17,6 @@ EXPORT_SYMBOL(fat_clear_inode);
EXPORT_SYMBOL(fat_date_unix2dos); EXPORT_SYMBOL(fat_date_unix2dos);
EXPORT_SYMBOL(fat_delete_inode); EXPORT_SYMBOL(fat_delete_inode);
EXPORT_SYMBOL(fat__get_entry); EXPORT_SYMBOL(fat__get_entry);
EXPORT_SYMBOL(fat_mark_buffer_dirty);
EXPORT_SYMBOL(fat_notify_change); EXPORT_SYMBOL(fat_notify_change);
EXPORT_SYMBOL(fat_put_super); EXPORT_SYMBOL(fat_put_super);
EXPORT_SYMBOL(fat_attach); EXPORT_SYMBOL(fat_attach);
...@@ -30,13 +28,10 @@ EXPORT_SYMBOL(fat_readdir); ...@@ -30,13 +28,10 @@ EXPORT_SYMBOL(fat_readdir);
EXPORT_SYMBOL(fat_scan); EXPORT_SYMBOL(fat_scan);
EXPORT_SYMBOL(fat_statfs); EXPORT_SYMBOL(fat_statfs);
EXPORT_SYMBOL(fat_write_inode); EXPORT_SYMBOL(fat_write_inode);
EXPORT_SYMBOL(register_cvf_format);
EXPORT_SYMBOL(unregister_cvf_format);
EXPORT_SYMBOL(fat_dir_ioctl); EXPORT_SYMBOL(fat_dir_ioctl);
EXPORT_SYMBOL(fat_add_entries); EXPORT_SYMBOL(fat_add_entries);
EXPORT_SYMBOL(fat_dir_empty); EXPORT_SYMBOL(fat_dir_empty);
EXPORT_SYMBOL(fat_truncate); EXPORT_SYMBOL(fat_truncate);
EXPORT_SYMBOL(fat_brelse);
int __init fat_init_inodecache(void); int __init fat_init_inodecache(void);
void __exit fat_destroy_inodecache(void); void __exit fat_destroy_inodecache(void);
......
...@@ -8,16 +8,15 @@ ...@@ -8,16 +8,15 @@
#include <linux/time.h> #include <linux/time.h>
#include <linux/msdos_fs.h> #include <linux/msdos_fs.h>
#include <linux/fat_cvf.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#define PRINTK(x) static ssize_t fat_file_write(struct file *filp, const char *buf, size_t count,
#define Printk(x) printk x loff_t *ppos);
struct file_operations fat_file_operations = { struct file_operations fat_file_operations = {
llseek: generic_file_llseek, llseek: generic_file_llseek,
read: fat_file_read, read: generic_file_read,
write: fat_file_write, write: fat_file_write,
mmap: generic_file_mmap, mmap: generic_file_mmap,
fsync: file_fsync, fsync: file_fsync,
...@@ -29,19 +28,8 @@ struct inode_operations fat_file_inode_operations = { ...@@ -29,19 +28,8 @@ struct inode_operations fat_file_inode_operations = {
setattr: fat_notify_change, setattr: fat_notify_change,
}; };
ssize_t fat_file_read( int fat_get_block(struct inode *inode, sector_t iblock,
struct file *filp, struct buffer_head *bh_result, int create)
char *buf,
size_t count,
loff_t *ppos)
{
struct inode *inode = filp->f_dentry->d_inode;
return MSDOS_SB(inode->i_sb)->cvf_format
->cvf_file_read(filp,buf,count,ppos);
}
int fat_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create)
{ {
struct super_block *sb = inode->i_sb; struct super_block *sb = inode->i_sb;
unsigned long phys; unsigned long phys;
...@@ -77,23 +65,8 @@ int fat_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_r ...@@ -77,23 +65,8 @@ int fat_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_r
return 0; return 0;
} }
ssize_t fat_file_write( static ssize_t fat_file_write(struct file *filp, const char *buf, size_t count,
struct file *filp, loff_t *ppos)
const char *buf,
size_t count,
loff_t *ppos)
{
struct inode *inode = filp->f_dentry->d_inode;
struct super_block *sb = inode->i_sb;
return MSDOS_SB(sb)->cvf_format
->cvf_file_write(filp,buf,count,ppos);
}
ssize_t default_fat_file_write(
struct file *filp,
const char *buf,
size_t count,
loff_t *ppos)
{ {
struct inode *inode = filp->f_dentry->d_inode; struct inode *inode = filp->f_dentry->d_inode;
int retval; int retval;
......
This diff is collapsed.
...@@ -10,25 +10,6 @@ ...@@ -10,25 +10,6 @@
#include <linux/msdos_fs.h> #include <linux/msdos_fs.h>
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#if 0
# define PRINTK(x) printk x
#else
# define PRINTK(x)
#endif
#define Printk(x) printk x
/* Well-known binary file extensions - of course there are many more */
static char ascii_extensions[] =
"TXT" "ME " "HTM" "1ST" "LOG" " " /* text files */
"C " "H " "CPP" "LIS" "PAS" "FOR" /* programming languages */
"F " "MAK" "INC" "BAS" /* programming languages */
"BAT" "SH " /* program code :) */
"INI" /* config files */
"PBM" "PGM" "DXF" /* graphics */
"TEX"; /* TeX */
/* /*
* fat_fs_panic reports a severe file system problem and sets the file system * fat_fs_panic reports a severe file system problem and sets the file system
* read-only. The file system can be made writable again by remounting it. * read-only. The file system can be made writable again by remounting it.
...@@ -49,36 +30,10 @@ void fat_fs_panic(struct super_block *s, const char *fmt, ...) ...@@ -49,36 +30,10 @@ void fat_fs_panic(struct super_block *s, const char *fmt, ...)
if (not_ro) if (not_ro)
s->s_flags |= MS_RDONLY; s->s_flags |= MS_RDONLY;
printk("FAT: Filesystem panic (dev %s)\n" printk(KERN_ERR "FAT: Filesystem panic (dev %s)\n"
" %s\n", s->s_id, panic_msg); " %s\n", s->s_id, panic_msg);
if (not_ro) if (not_ro)
printk(" File system has been set read-only\n"); printk(KERN_ERR " File system has been set read-only\n");
}
/*
* fat_is_binary selects optional text conversion based on the conversion mode
* and the extension part of the file name.
*/
int fat_is_binary(char conversion,char *extension)
{
char *walk;
switch (conversion) {
case 'b':
return 1;
case 't':
return 0;
case 'a':
for (walk = ascii_extensions; *walk; walk += 3)
if (!strncmp(extension,walk,3)) return 0;
return 1; /* default binary conversion */
default:
printk("Invalid conversion mode - defaulting to "
"binary.\n");
return 1;
}
} }
void lock_fat(struct super_block *sb) void lock_fat(struct super_block *sb)
...@@ -103,25 +58,25 @@ void fat_clusters_flush(struct super_block *sb) ...@@ -103,25 +58,25 @@ void fat_clusters_flush(struct super_block *sb)
if (MSDOS_SB(sb)->free_clusters == -1) if (MSDOS_SB(sb)->free_clusters == -1)
return; return;
bh = fat_bread(sb, MSDOS_SB(sb)->fsinfo_sector); bh = sb_bread(sb, MSDOS_SB(sb)->fsinfo_sector);
if (bh == NULL) { if (bh == NULL) {
printk("FAT bread failed in fat_clusters_flush\n"); printk(KERN_ERR "FAT bread failed in fat_clusters_flush\n");
return; return;
} }
fsinfo = (struct fat_boot_fsinfo *)bh->b_data; fsinfo = (struct fat_boot_fsinfo *)bh->b_data;
/* Sanity check */ /* Sanity check */
if (!IS_FSINFO(fsinfo)) { if (!IS_FSINFO(fsinfo)) {
printk("FAT: Did not find valid FSINFO signature.\n" printk(KERN_ERR "FAT: Did not find valid FSINFO signature.\n"
" Found signature1 0x%08x signature2 0x%08x" " Found signature1 0x%08x signature2 0x%08x"
" (sector = %lu)\n", " (sector = %lu)\n",
CF_LE_L(fsinfo->signature1), CF_LE_L(fsinfo->signature2), CF_LE_L(fsinfo->signature1), CF_LE_L(fsinfo->signature2),
MSDOS_SB(sb)->fsinfo_sector); MSDOS_SB(sb)->fsinfo_sector);
} else { } else {
fsinfo->free_clusters = CF_LE_L(MSDOS_SB(sb)->free_clusters); fsinfo->free_clusters = CF_LE_L(MSDOS_SB(sb)->free_clusters);
fat_mark_buffer_dirty(sb, bh); mark_buffer_dirty(bh);
} }
fat_brelse(sb, bh); brelse(bh);
} }
/* /*
...@@ -205,7 +160,7 @@ int fat_add_cluster(struct inode *inode) ...@@ -205,7 +160,7 @@ int fat_add_cluster(struct inode *inode)
mark_inode_dirty(inode); mark_inode_dirty(inode);
} }
if (file_cluster != (inode->i_blocks >> (cluster_bits - 9))) { if (file_cluster != (inode->i_blocks >> (cluster_bits - 9))) {
printk ("file_cluster badly computed!!! %d <> %ld\n", printk (KERN_ERR "file_cluster badly computed!!! %d <> %ld\n",
file_cluster, inode->i_blocks >> (cluster_bits - 9)); file_cluster, inode->i_blocks >> (cluster_bits - 9));
fat_cache_inval_inode(inode); fat_cache_inval_inode(inode);
} }
...@@ -233,27 +188,19 @@ struct buffer_head *fat_extend_dir(struct inode *inode) ...@@ -233,27 +188,19 @@ struct buffer_head *fat_extend_dir(struct inode *inode)
sector = MSDOS_SB(sb)->data_start + (nr - 2) * cluster_size; sector = MSDOS_SB(sb)->data_start + (nr - 2) * cluster_size;
last_sector = sector + cluster_size; last_sector = sector + cluster_size;
if (MSDOS_SB(sb)->cvf_format for ( ; sector < last_sector; sector++) {
&& MSDOS_SB(sb)->cvf_format->zero_out_cluster) { if ((bh = sb_getblk(sb, sector))) {
res = ERR_PTR(-EIO); memset(bh->b_data, 0, sb->s_blocksize);
MSDOS_SB(sb)->cvf_format->zero_out_cluster(inode, nr); set_buffer_uptodate(bh);
} else { mark_buffer_dirty(bh);
for ( ; sector < last_sector; sector++) { if (!res)
if (!(bh = fat_getblk(sb, sector))) res = bh;
printk("FAT: fat_getblk() failed\n"); else
else { brelse(bh);
memset(bh->b_data, 0, sb->s_blocksize);
fat_set_uptodate(sb, bh, 1);
fat_mark_buffer_dirty(sb, bh);
if (!res)
res = bh;
else
fat_brelse(sb, bh);
}
} }
if (res == NULL)
res = ERR_PTR(-EIO);
} }
if (res == NULL)
res = ERR_PTR(-EIO);
if (inode->i_size & (sb->s_blocksize - 1)) { if (inode->i_size & (sb->s_blocksize - 1)) {
fat_fs_panic(sb, "Odd directory size"); fat_fs_panic(sb, "Odd directory size");
inode->i_size = (inode->i_size + sb->s_blocksize) inode->i_size = (inode->i_size + sb->s_blocksize)
...@@ -261,7 +208,6 @@ struct buffer_head *fat_extend_dir(struct inode *inode) ...@@ -261,7 +208,6 @@ struct buffer_head *fat_extend_dir(struct inode *inode)
} }
inode->i_size += 1 << MSDOS_SB(sb)->cluster_bits; inode->i_size += 1 << MSDOS_SB(sb)->cluster_bits;
MSDOS_I(inode)->mmu_private += 1 << MSDOS_SB(sb)->cluster_bits; MSDOS_I(inode)->mmu_private += 1 << MSDOS_SB(sb)->cluster_bits;
mark_inode_dirty(inode);
return res; return res;
} }
...@@ -347,7 +293,7 @@ int fat__get_entry(struct inode *dir, loff_t *pos,struct buffer_head **bh, ...@@ -347,7 +293,7 @@ int fat__get_entry(struct inode *dir, loff_t *pos,struct buffer_head **bh,
next: next:
offset = *pos; offset = *pos;
if (*bh) if (*bh)
fat_brelse(sb, *bh); brelse(*bh);
*bh = NULL; *bh = NULL;
iblock = *pos >> sb->s_blocksize_bits; iblock = *pos >> sb->s_blocksize_bits;
...@@ -355,9 +301,10 @@ int fat__get_entry(struct inode *dir, loff_t *pos,struct buffer_head **bh, ...@@ -355,9 +301,10 @@ int fat__get_entry(struct inode *dir, loff_t *pos,struct buffer_head **bh,
if (sector <= 0) if (sector <= 0)
return -1; /* beyond EOF or error */ return -1; /* beyond EOF or error */
*bh = fat_bread(sb, sector); *bh = sb_bread(sb, sector);
if (*bh == NULL) { if (*bh == NULL) {
printk("FAT: Directory bread(block %d) failed\n", sector); printk(KERN_ERR "FAT: Directory bread(block %d) failed\n",
sector);
/* skip this block */ /* skip this block */
*pos = (iblock + 1) << sb->s_blocksize_bits; *pos = (iblock + 1) << sb->s_blocksize_bits;
goto next; goto next;
...@@ -430,7 +377,7 @@ static int raw_scan_sector(struct super_block *sb,int sector,const char *name, ...@@ -430,7 +377,7 @@ static int raw_scan_sector(struct super_block *sb,int sector,const char *name,
struct msdos_dir_entry *data; struct msdos_dir_entry *data;
int entry,start,done; int entry,start,done;
if (!(bh = fat_bread(sb,sector))) if (!(bh = sb_bread(sb,sector)))
return -EIO; return -EIO;
data = (struct msdos_dir_entry *) bh->b_data; data = (struct msdos_dir_entry *) bh->b_data;
for (entry = 0; entry < MSDOS_SB(sb)->dir_per_block; entry++) { for (entry = 0; entry < MSDOS_SB(sb)->dir_per_block; entry++) {
...@@ -452,7 +399,7 @@ static int raw_scan_sector(struct super_block *sb,int sector,const char *name, ...@@ -452,7 +399,7 @@ static int raw_scan_sector(struct super_block *sb,int sector,const char *name,
start |= (CF_LE_W(data[entry].starthi) << 16); start |= (CF_LE_W(data[entry].starthi) << 16);
} }
if (!res_bh) if (!res_bh)
fat_brelse(sb, bh); brelse(bh);
else { else {
*res_bh = bh; *res_bh = bh;
*res_de = &data[entry]; *res_de = &data[entry];
...@@ -460,7 +407,7 @@ static int raw_scan_sector(struct super_block *sb,int sector,const char *name, ...@@ -460,7 +407,7 @@ static int raw_scan_sector(struct super_block *sb,int sector,const char *name,
return start; return start;
} }
} }
fat_brelse(sb, bh); brelse(bh);
return -ENOENT; return -ENOENT;
} }
......
...@@ -7,17 +7,13 @@ ...@@ -7,17 +7,13 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include <linux/msdos_fs.h> #include <linux/msdos_fs.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#define MSDOS_DEBUG 0
#define PRINTK(x)
/* MS-DOS "device special files" */ /* MS-DOS "device special files" */
static const char *reserved_names[] = { static const char *reserved_names[] = {
"CON ","PRN ","NUL ","AUX ", "CON ","PRN ","NUL ","AUX ",
"LPT1 ","LPT2 ","LPT3 ","LPT4 ", "LPT1 ","LPT2 ","LPT3 ","LPT4 ",
...@@ -26,7 +22,6 @@ static const char *reserved_names[] = { ...@@ -26,7 +22,6 @@ static const char *reserved_names[] = {
}; };
/* Characters that are undesirable in an MS-DOS file name */ /* Characters that are undesirable in an MS-DOS file name */
static char bad_chars[] = "*?<>|\""; static char bad_chars[] = "*?<>|\"";
static char bad_if_strict_pc[] = "+=,; "; static char bad_if_strict_pc[] = "+=,; ";
static char bad_if_strict_atari[] = " "; /* GEMDOS is less restrictive */ static char bad_if_strict_atari[] = " "; /* GEMDOS is less restrictive */
...@@ -206,8 +201,6 @@ struct dentry *msdos_lookup(struct inode *dir,struct dentry *dentry) ...@@ -206,8 +201,6 @@ struct dentry *msdos_lookup(struct inode *dir,struct dentry *dentry)
struct buffer_head *bh = NULL; struct buffer_head *bh = NULL;
int ino,res; int ino,res;
PRINTK (("msdos_lookup\n"));
dentry->d_op = &msdos_dentry_operations; dentry->d_op = &msdos_dentry_operations;
lock_kernel(); lock_kernel();
...@@ -227,8 +220,7 @@ struct dentry *msdos_lookup(struct inode *dir,struct dentry *dentry) ...@@ -227,8 +220,7 @@ struct dentry *msdos_lookup(struct inode *dir,struct dentry *dentry)
if (dentry) if (dentry)
dentry->d_op = &msdos_dentry_operations; dentry->d_op = &msdos_dentry_operations;
out: out:
if (bh) brelse(bh);
fat_brelse(sb, bh);
unlock_kernel(); unlock_kernel();
if (!res) if (!res)
return dentry; return dentry;
...@@ -242,11 +234,12 @@ static int msdos_add_entry(struct inode *dir, const char *name, ...@@ -242,11 +234,12 @@ static int msdos_add_entry(struct inode *dir, const char *name,
int *ino, int *ino,
int is_dir, int is_hid) int is_dir, int is_hid)
{ {
struct super_block *sb = dir->i_sb;
int res; int res;
if ((res = fat_add_entries(dir, 1, bh, de, ino))<0) res = fat_add_entries(dir, 1, bh, de, ino);
if (res < 0)
return res; return res;
/* /*
* XXX all times should be set by caller upon successful completion. * XXX all times should be set by caller upon successful completion.
*/ */
...@@ -260,7 +253,7 @@ static int msdos_add_entry(struct inode *dir, const char *name, ...@@ -260,7 +253,7 @@ static int msdos_add_entry(struct inode *dir, const char *name,
(*de)->starthi = 0; (*de)->starthi = 0;
fat_date_unix2dos(dir->i_mtime,&(*de)->time,&(*de)->date); fat_date_unix2dos(dir->i_mtime,&(*de)->time,&(*de)->date);
(*de)->size = 0; (*de)->size = 0;
fat_mark_buffer_dirty(sb, *bh); mark_buffer_dirty(*bh);
return 0; return 0;
} }
...@@ -288,7 +281,7 @@ int msdos_create(struct inode *dir,struct dentry *dentry,int mode) ...@@ -288,7 +281,7 @@ int msdos_create(struct inode *dir,struct dentry *dentry,int mode)
is_hid = (dentry->d_name.name[0]=='.') && (msdos_name[0]!='.'); is_hid = (dentry->d_name.name[0]=='.') && (msdos_name[0]!='.');
/* Have to do it due to foo vs. .foo conflicts */ /* Have to do it due to foo vs. .foo conflicts */
if (fat_scan(dir,msdos_name,&bh,&de,&ino) >= 0) { if (fat_scan(dir,msdos_name,&bh,&de,&ino) >= 0) {
fat_brelse(sb, bh); brelse(bh);
unlock_kernel(); unlock_kernel();
return -EINVAL; return -EINVAL;
} }
...@@ -299,7 +292,7 @@ int msdos_create(struct inode *dir,struct dentry *dentry,int mode) ...@@ -299,7 +292,7 @@ int msdos_create(struct inode *dir,struct dentry *dentry,int mode)
return res; return res;
} }
inode = fat_build_inode(dir->i_sb, de, ino, &res); inode = fat_build_inode(dir->i_sb, de, ino, &res);
fat_brelse(sb, bh); brelse(bh);
if (!inode) { if (!inode) {
unlock_kernel(); unlock_kernel();
return res; return res;
...@@ -314,7 +307,6 @@ int msdos_create(struct inode *dir,struct dentry *dentry,int mode) ...@@ -314,7 +307,6 @@ int msdos_create(struct inode *dir,struct dentry *dentry,int mode)
/***** Remove a directory */ /***** Remove a directory */
int msdos_rmdir(struct inode *dir, struct dentry *dentry) int msdos_rmdir(struct inode *dir, struct dentry *dentry)
{ {
struct super_block *sb = dir->i_sb;
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
int res,ino; int res,ino;
struct buffer_head *bh; struct buffer_head *bh;
...@@ -335,7 +327,7 @@ int msdos_rmdir(struct inode *dir, struct dentry *dentry) ...@@ -335,7 +327,7 @@ int msdos_rmdir(struct inode *dir, struct dentry *dentry)
goto rmdir_done; goto rmdir_done;
de->name[0] = DELETED_FLAG; de->name[0] = DELETED_FLAG;
fat_mark_buffer_dirty(sb, bh); mark_buffer_dirty(bh);
fat_detach(inode); fat_detach(inode);
inode->i_nlink = 0; inode->i_nlink = 0;
inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
...@@ -345,7 +337,7 @@ int msdos_rmdir(struct inode *dir, struct dentry *dentry) ...@@ -345,7 +337,7 @@ int msdos_rmdir(struct inode *dir, struct dentry *dentry)
res = 0; res = 0;
rmdir_done: rmdir_done:
fat_brelse(sb, bh); brelse(bh);
unlock_kernel(); unlock_kernel();
return res; return res;
} }
...@@ -378,7 +370,7 @@ int msdos_mkdir(struct inode *dir,struct dentry *dentry,int mode) ...@@ -378,7 +370,7 @@ int msdos_mkdir(struct inode *dir,struct dentry *dentry,int mode)
goto out_unlock; goto out_unlock;
inode = fat_build_inode(dir->i_sb, de, ino, &res); inode = fat_build_inode(dir->i_sb, de, ino, &res);
if (!inode) { if (!inode) {
fat_brelse(sb, bh); brelse(bh);
goto out_unlock; goto out_unlock;
} }
res = 0; res = 0;
...@@ -390,7 +382,7 @@ int msdos_mkdir(struct inode *dir,struct dentry *dentry,int mode) ...@@ -390,7 +382,7 @@ int msdos_mkdir(struct inode *dir,struct dentry *dentry,int mode)
if (res) if (res)
goto mkdir_error; goto mkdir_error;
fat_brelse(sb, bh); brelse(bh);
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
res = 0; res = 0;
...@@ -406,14 +398,14 @@ int msdos_mkdir(struct inode *dir,struct dentry *dentry,int mode) ...@@ -406,14 +398,14 @@ int msdos_mkdir(struct inode *dir,struct dentry *dentry,int mode)
mark_inode_dirty(inode); mark_inode_dirty(inode);
mark_inode_dirty(dir); mark_inode_dirty(dir);
de->name[0] = DELETED_FLAG; de->name[0] = DELETED_FLAG;
fat_mark_buffer_dirty(sb, bh); mark_buffer_dirty(bh);
fat_brelse(sb, bh); brelse(bh);
fat_detach(inode); fat_detach(inode);
iput(inode); iput(inode);
goto out_unlock; goto out_unlock;
out_exist: out_exist:
fat_brelse(sb, bh); brelse(bh);
res = -EINVAL; res = -EINVAL;
goto out_unlock; goto out_unlock;
} }
...@@ -421,7 +413,6 @@ int msdos_mkdir(struct inode *dir,struct dentry *dentry,int mode) ...@@ -421,7 +413,6 @@ int msdos_mkdir(struct inode *dir,struct dentry *dentry,int mode)
/***** Unlink a file */ /***** Unlink a file */
int msdos_unlink( struct inode *dir, struct dentry *dentry) int msdos_unlink( struct inode *dir, struct dentry *dentry)
{ {
struct super_block *sb = dir->i_sb;
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
int res,ino; int res,ino;
struct buffer_head *bh; struct buffer_head *bh;
...@@ -435,9 +426,9 @@ int msdos_unlink( struct inode *dir, struct dentry *dentry) ...@@ -435,9 +426,9 @@ int msdos_unlink( struct inode *dir, struct dentry *dentry)
goto unlink_done; goto unlink_done;
de->name[0] = DELETED_FLAG; de->name[0] = DELETED_FLAG;
fat_mark_buffer_dirty(sb, bh); mark_buffer_dirty(bh);
fat_detach(inode); fat_detach(inode);
fat_brelse(sb, bh); brelse(bh);
inode->i_nlink = 0; inode->i_nlink = 0;
inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
mark_inode_dirty(inode); mark_inode_dirty(inode);
...@@ -454,7 +445,6 @@ static int do_msdos_rename(struct inode *old_dir, char *old_name, ...@@ -454,7 +445,6 @@ static int do_msdos_rename(struct inode *old_dir, char *old_name,
struct buffer_head *old_bh, struct buffer_head *old_bh,
struct msdos_dir_entry *old_de, int old_ino, int is_hid) struct msdos_dir_entry *old_de, int old_ino, int is_hid)
{ {
struct super_block *sb = old_dir->i_sb;
struct buffer_head *new_bh=NULL,*dotdot_bh=NULL; struct buffer_head *new_bh=NULL,*dotdot_bh=NULL;
struct msdos_dir_entry *new_de,*dotdot_de; struct msdos_dir_entry *new_de,*dotdot_de;
struct inode *old_inode,*new_inode; struct inode *old_inode,*new_inode;
...@@ -497,7 +487,7 @@ static int do_msdos_rename(struct inode *old_dir, char *old_name, ...@@ -497,7 +487,7 @@ static int do_msdos_rename(struct inode *old_dir, char *old_name,
if (new_inode) if (new_inode)
fat_detach(new_inode); fat_detach(new_inode);
old_de->name[0] = DELETED_FLAG; old_de->name[0] = DELETED_FLAG;
fat_mark_buffer_dirty(sb, old_bh); mark_buffer_dirty(old_bh);
fat_detach(old_inode); fat_detach(old_inode);
fat_attach(old_inode, new_ino); fat_attach(old_inode, new_ino);
if (is_hid) if (is_hid)
...@@ -516,7 +506,7 @@ static int do_msdos_rename(struct inode *old_dir, char *old_name, ...@@ -516,7 +506,7 @@ static int do_msdos_rename(struct inode *old_dir, char *old_name,
if (dotdot_bh) { if (dotdot_bh) {
dotdot_de->start = CT_LE_W(MSDOS_I(new_dir)->i_logstart); dotdot_de->start = CT_LE_W(MSDOS_I(new_dir)->i_logstart);
dotdot_de->starthi = CT_LE_W((MSDOS_I(new_dir)->i_logstart) >> 16); dotdot_de->starthi = CT_LE_W((MSDOS_I(new_dir)->i_logstart) >> 16);
fat_mark_buffer_dirty(sb, dotdot_bh); mark_buffer_dirty(dotdot_bh);
old_dir->i_nlink--; old_dir->i_nlink--;
mark_inode_dirty(old_dir); mark_inode_dirty(old_dir);
if (new_inode) { if (new_inode) {
...@@ -529,8 +519,8 @@ static int do_msdos_rename(struct inode *old_dir, char *old_name, ...@@ -529,8 +519,8 @@ static int do_msdos_rename(struct inode *old_dir, char *old_name,
} }
error = 0; error = 0;
out: out:
fat_brelse(sb, new_bh); brelse(new_bh);
fat_brelse(sb, dotdot_bh); brelse(dotdot_bh);
return error; return error;
degenerate_case: degenerate_case:
...@@ -552,7 +542,6 @@ static int do_msdos_rename(struct inode *old_dir, char *old_name, ...@@ -552,7 +542,6 @@ static int do_msdos_rename(struct inode *old_dir, char *old_name,
int msdos_rename(struct inode *old_dir,struct dentry *old_dentry, int msdos_rename(struct inode *old_dir,struct dentry *old_dentry,
struct inode *new_dir,struct dentry *new_dentry) struct inode *new_dir,struct dentry *new_dentry)
{ {
struct super_block *sb = old_dir->i_sb;
struct buffer_head *old_bh; struct buffer_head *old_bh;
struct msdos_dir_entry *old_de; struct msdos_dir_entry *old_de;
int old_ino, error; int old_ino, error;
...@@ -580,7 +569,7 @@ int msdos_rename(struct inode *old_dir,struct dentry *old_dentry, ...@@ -580,7 +569,7 @@ int msdos_rename(struct inode *old_dir,struct dentry *old_dentry,
error = do_msdos_rename(old_dir, old_msdos_name, old_dentry, error = do_msdos_rename(old_dir, old_msdos_name, old_dentry,
new_dir, new_msdos_name, new_dentry, new_dir, new_msdos_name, new_dentry,
old_bh, old_de, (ino_t)old_ino, is_hid); old_bh, old_de, (ino_t)old_ino, is_hid);
fat_brelse(sb, old_bh); brelse(old_bh);
rename_done: rename_done:
unlock_kernel(); unlock_kernel();
......
...@@ -319,9 +319,9 @@ static int vfat_find_form(struct inode *dir,char *name) ...@@ -319,9 +319,9 @@ static int vfat_find_form(struct inode *dir,char *name)
struct buffer_head *bh = NULL; struct buffer_head *bh = NULL;
int ino,res; int ino,res;
res=fat_scan(dir,name,&bh,&de,&ino); res = fat_scan(dir,name,&bh,&de,&ino);
fat_brelse(dir->i_sb, bh); brelse(bh);
if (res<0) if (res < 0)
return -ENOENT; return -ENOENT;
return 0; return 0;
} }
...@@ -690,42 +690,39 @@ xlate_to_uni(const char *name, int len, char *outname, int *longlen, int *outlen ...@@ -690,42 +690,39 @@ xlate_to_uni(const char *name, int len, char *outname, int *longlen, int *outlen
return 0; return 0;
} }
static int static int vfat_build_slots(struct inode *dir, const char *name, int len,
vfat_fill_slots(struct inode *dir, struct msdos_dir_slot *ds, const char *name, struct msdos_dir_slot *ds, int *slots, int is_dir)
int len, int *slots, int is_dir, int uni_xlate)
{ {
struct nls_table *nls_io, *nls_disk; struct msdos_sb_info *sbi = MSDOS_SB(dir->i_sb);
wchar_t *uname; struct fat_mount_options *opts = &sbi->options;
struct msdos_dir_slot *ps; struct msdos_dir_slot *ps;
struct msdos_dir_entry *de; struct msdos_dir_entry *de;
unsigned long page; unsigned long page;
unsigned char cksum, lcase; unsigned char cksum, lcase;
char *uniname, msdos_name[MSDOS_NAME]; char msdos_name[MSDOS_NAME];
int res, utf8, slot, ulen, unilen, i; wchar_t *uname;
int res, slot, ulen, usize, i;
loff_t offset; loff_t offset;
*slots = 0; *slots = 0;
utf8 = MSDOS_SB(dir->i_sb)->options.utf8; res = vfat_valid_longname(name, len, opts->unicode_xlate);
nls_io = MSDOS_SB(dir->i_sb)->nls_io; if (res < 0)
nls_disk = MSDOS_SB(dir->i_sb)->nls_disk; return res;
if (name[len-1] == '.')
len--;
if(!(page = __get_free_page(GFP_KERNEL))) if(!(page = __get_free_page(GFP_KERNEL)))
return -ENOMEM; return -ENOMEM;
uniname = (char *) page; uname = (wchar_t *)page;
res = xlate_to_uni(name, len, uniname, &ulen, &unilen, uni_xlate, res = xlate_to_uni(name, len, (char *)uname, &ulen, &usize,
utf8, nls_io); opts->unicode_xlate, opts->utf8, sbi->nls_io);
if (res < 0) if (res < 0)
goto out_free; goto out_free;
uname = (wchar_t *) page;
res = vfat_is_used_badchars(uname, ulen); res = vfat_is_used_badchars(uname, ulen);
if (res < 0) if (res < 0)
goto out_free; goto out_free;
res = vfat_create_shortname(dir, nls_disk, uname, ulen, res = vfat_create_shortname(dir, sbi->nls_disk, uname, ulen,
msdos_name, &lcase); msdos_name, &lcase);
if (res < 0) if (res < 0)
goto out_free; goto out_free;
...@@ -736,7 +733,7 @@ vfat_fill_slots(struct inode *dir, struct msdos_dir_slot *ds, const char *name, ...@@ -736,7 +733,7 @@ vfat_fill_slots(struct inode *dir, struct msdos_dir_slot *ds, const char *name,
} }
/* build the entry of long file name */ /* build the entry of long file name */
*slots = unilen / 13; *slots = usize / 13;
for (cksum = i = 0; i < 11; i++) { for (cksum = i = 0; i < 11; i++) {
cksum = (((cksum&1)<<7)|((cksum&0xfe)>>1)) + msdos_name[i]; cksum = (((cksum&1)<<7)|((cksum&0xfe)>>1)) + msdos_name[i];
} }
...@@ -774,26 +771,10 @@ vfat_fill_slots(struct inode *dir, struct msdos_dir_slot *ds, const char *name, ...@@ -774,26 +771,10 @@ vfat_fill_slots(struct inode *dir, struct msdos_dir_slot *ds, const char *name,
return res; return res;
} }
/* We can't get "." or ".." here - VFS takes care of those cases */
static int vfat_build_slots(struct inode *dir, const char *name, int len,
struct msdos_dir_slot *ds, int *slots, int is_dir)
{
int res, xlate;
xlate = MSDOS_SB(dir->i_sb)->options.unicode_xlate;
res = vfat_valid_longname(name, len, xlate);
if (res < 0)
return res;
return vfat_fill_slots(dir, ds, name, len, slots, is_dir, xlate);
}
static int vfat_add_entry(struct inode *dir,struct qstr* qname, static int vfat_add_entry(struct inode *dir,struct qstr* qname,
int is_dir, struct vfat_slot_info *sinfo_out, int is_dir, struct vfat_slot_info *sinfo_out,
struct buffer_head **bh, struct msdos_dir_entry **de) struct buffer_head **bh, struct msdos_dir_entry **de)
{ {
struct super_block *sb = dir->i_sb;
struct msdos_dir_slot *dir_slots; struct msdos_dir_slot *dir_slots;
loff_t offset; loff_t offset;
int slots, slot; int slots, slot;
...@@ -821,7 +802,7 @@ static int vfat_add_entry(struct inode *dir,struct qstr* qname, ...@@ -821,7 +802,7 @@ static int vfat_add_entry(struct inode *dir,struct qstr* qname,
res = offset; res = offset;
goto cleanup; goto cleanup;
} }
fat_brelse(sb, dummy_bh); brelse(dummy_bh);
/* Now create the new entry */ /* Now create the new entry */
*bh = NULL; *bh = NULL;
...@@ -831,7 +812,7 @@ static int vfat_add_entry(struct inode *dir,struct qstr* qname, ...@@ -831,7 +812,7 @@ static int vfat_add_entry(struct inode *dir,struct qstr* qname,
goto cleanup; goto cleanup;
} }
memcpy(*de, dir_slots + slot, sizeof(struct msdos_dir_slot)); memcpy(*de, dir_slots + slot, sizeof(struct msdos_dir_slot));
fat_mark_buffer_dirty(sb, *bh); mark_buffer_dirty(*bh);
} }
res = 0; res = 0;
...@@ -843,7 +824,7 @@ static int vfat_add_entry(struct inode *dir,struct qstr* qname, ...@@ -843,7 +824,7 @@ static int vfat_add_entry(struct inode *dir,struct qstr* qname,
(*de)->ctime = (*de)->time; (*de)->ctime = (*de)->time;
(*de)->adate = (*de)->cdate = (*de)->date; (*de)->adate = (*de)->cdate = (*de)->date;
fat_mark_buffer_dirty(sb, *bh); mark_buffer_dirty(*bh);
/* slots can't be less than 1 */ /* slots can't be less than 1 */
sinfo_out->long_slots = slots - 1; sinfo_out->long_slots = slots - 1;
...@@ -902,7 +883,7 @@ struct dentry *vfat_lookup(struct inode *dir,struct dentry *dentry) ...@@ -902,7 +883,7 @@ struct dentry *vfat_lookup(struct inode *dir,struct dentry *dentry)
goto error; goto error;
} }
inode = fat_build_inode(dir->i_sb, de, sinfo.ino, &res); inode = fat_build_inode(dir->i_sb, de, sinfo.ino, &res);
fat_brelse(dir->i_sb, bh); brelse(bh);
if (res) { if (res) {
unlock_kernel(); unlock_kernel();
return ERR_PTR(res); return ERR_PTR(res);
...@@ -946,7 +927,7 @@ int vfat_create(struct inode *dir,struct dentry* dentry,int mode) ...@@ -946,7 +927,7 @@ int vfat_create(struct inode *dir,struct dentry* dentry,int mode)
return res; return res;
} }
inode = fat_build_inode(sb, de, sinfo.ino, &res); inode = fat_build_inode(sb, de, sinfo.ino, &res);
fat_brelse(sb, bh); brelse(bh);
if (!inode) { if (!inode) {
unlock_kernel(); unlock_kernel();
return res; return res;
...@@ -964,7 +945,6 @@ int vfat_create(struct inode *dir,struct dentry* dentry,int mode) ...@@ -964,7 +945,6 @@ int vfat_create(struct inode *dir,struct dentry* dentry,int mode)
static void vfat_remove_entry(struct inode *dir,struct vfat_slot_info *sinfo, static void vfat_remove_entry(struct inode *dir,struct vfat_slot_info *sinfo,
struct buffer_head *bh, struct msdos_dir_entry *de) struct buffer_head *bh, struct msdos_dir_entry *de)
{ {
struct super_block *sb = dir->i_sb;
loff_t offset; loff_t offset;
int i,ino; int i,ino;
...@@ -974,7 +954,7 @@ static void vfat_remove_entry(struct inode *dir,struct vfat_slot_info *sinfo, ...@@ -974,7 +954,7 @@ static void vfat_remove_entry(struct inode *dir,struct vfat_slot_info *sinfo,
dir->i_version++; dir->i_version++;
mark_inode_dirty(dir); mark_inode_dirty(dir);
de->name[0] = DELETED_FLAG; de->name[0] = DELETED_FLAG;
fat_mark_buffer_dirty(sb, bh); mark_buffer_dirty(bh);
/* remove the longname */ /* remove the longname */
offset = sinfo->longname_offset; de = NULL; offset = sinfo->longname_offset; de = NULL;
for (i = sinfo->long_slots; i > 0; --i) { for (i = sinfo->long_slots; i > 0; --i) {
...@@ -982,9 +962,9 @@ static void vfat_remove_entry(struct inode *dir,struct vfat_slot_info *sinfo, ...@@ -982,9 +962,9 @@ static void vfat_remove_entry(struct inode *dir,struct vfat_slot_info *sinfo,
continue; continue;
de->name[0] = DELETED_FLAG; de->name[0] = DELETED_FLAG;
de->attr = ATTR_NONE; de->attr = ATTR_NONE;
fat_mark_buffer_dirty(sb, bh); mark_buffer_dirty(bh);
} }
if (bh) fat_brelse(sb, bh); brelse(bh);
} }
int vfat_rmdir(struct inode *dir,struct dentry* dentry) int vfat_rmdir(struct inode *dir,struct dentry* dentry)
...@@ -1075,7 +1055,7 @@ int vfat_mkdir(struct inode *dir,struct dentry* dentry,int mode) ...@@ -1075,7 +1055,7 @@ int vfat_mkdir(struct inode *dir,struct dentry* dentry,int mode)
dentry->d_time = dentry->d_parent->d_inode->i_version; dentry->d_time = dentry->d_parent->d_inode->i_version;
d_instantiate(dentry,inode); d_instantiate(dentry,inode);
out: out:
fat_brelse(sb, bh); brelse(bh);
unlock_kernel(); unlock_kernel();
return res; return res;
...@@ -1096,7 +1076,6 @@ int vfat_mkdir(struct inode *dir,struct dentry* dentry,int mode) ...@@ -1096,7 +1076,6 @@ int vfat_mkdir(struct inode *dir,struct dentry* dentry,int mode)
int vfat_rename(struct inode *old_dir,struct dentry *old_dentry, int vfat_rename(struct inode *old_dir,struct dentry *old_dentry,
struct inode *new_dir,struct dentry *new_dentry) struct inode *new_dir,struct dentry *new_dentry)
{ {
struct super_block *sb = old_dir->i_sb;
struct buffer_head *old_bh,*new_bh,*dotdot_bh; struct buffer_head *old_bh,*new_bh,*dotdot_bh;
struct msdos_dir_entry *old_de,*new_de,*dotdot_de; struct msdos_dir_entry *old_de,*new_de,*dotdot_de;
int dotdot_ino; int dotdot_ino;
...@@ -1160,7 +1139,7 @@ int vfat_rename(struct inode *old_dir,struct dentry *old_dentry, ...@@ -1160,7 +1139,7 @@ int vfat_rename(struct inode *old_dir,struct dentry *old_dentry,
int start = MSDOS_I(new_dir)->i_logstart; int start = MSDOS_I(new_dir)->i_logstart;
dotdot_de->start = CT_LE_W(start); dotdot_de->start = CT_LE_W(start);
dotdot_de->starthi = CT_LE_W(start>>16); dotdot_de->starthi = CT_LE_W(start>>16);
fat_mark_buffer_dirty(sb, dotdot_bh); mark_buffer_dirty(dotdot_bh);
old_dir->i_nlink--; old_dir->i_nlink--;
if (new_inode) { if (new_inode) {
new_inode->i_nlink--; new_inode->i_nlink--;
...@@ -1171,9 +1150,9 @@ int vfat_rename(struct inode *old_dir,struct dentry *old_dentry, ...@@ -1171,9 +1150,9 @@ int vfat_rename(struct inode *old_dir,struct dentry *old_dentry,
} }
rename_done: rename_done:
fat_brelse(sb, dotdot_bh); brelse(dotdot_bh);
fat_brelse(sb, old_bh); brelse(old_bh);
fat_brelse(sb, new_bh); brelse(new_bh);
unlock_kernel(); unlock_kernel();
return res; return res;
......
#ifndef _FAT_CVF
#define _FAT_CVF
#define CVF_USE_READPAGE 0x0001
struct cvf_format
{ int cvf_version;
char* cvf_version_text;
unsigned long flags;
int (*detect_cvf) (struct super_block*sb);
int (*mount_cvf) (struct super_block*sb,char*options);
int (*unmount_cvf) (struct super_block*sb);
struct buffer_head* (*cvf_bread) (struct super_block*sb,int block);
struct buffer_head* (*cvf_getblk) (struct super_block*sb,int block);
void (*cvf_brelse) (struct super_block *sb,struct buffer_head *bh);
void (*cvf_mark_buffer_dirty) (struct super_block *sb,
struct buffer_head *bh);
void (*cvf_set_uptodate) (struct super_block *sb,
struct buffer_head *bh,
int val);
int (*cvf_is_uptodate) (struct super_block *sb,struct buffer_head *bh);
void (*cvf_ll_rw_block) (struct super_block *sb,
int opr,
int nbreq,
struct buffer_head *bh[32]);
int (*fat_access) (struct super_block *sb,int nr,int new_value);
int (*cvf_statfs) (struct super_block *sb,struct statfs *buf, int bufsiz);
int (*cvf_bmap) (struct inode *inode,int block);
ssize_t (*cvf_file_read) ( struct file *, char *, size_t, loff_t *);
ssize_t (*cvf_file_write) ( struct file *, const char *, size_t, loff_t *);
int (*cvf_mmap) (struct file *, struct vm_area_struct *);
int (*cvf_readpage) (struct inode *, struct page *);
int (*cvf_writepage) (struct inode *, struct page *);
int (*cvf_dir_ioctl) (struct inode * inode, struct file * filp,
unsigned int cmd, unsigned long arg);
void (*zero_out_cluster) (struct inode*, int clusternr);
};
int register_cvf_format(struct cvf_format*cvf_format);
int unregister_cvf_format(struct cvf_format*cvf_format);
void dec_cvf_format_use_count_by_version(int version);
int detect_cvf(struct super_block*sb,char*force);
extern struct cvf_format *cvf_formats[];
extern int cvf_format_use_count[];
#endif
...@@ -235,17 +235,6 @@ static inline void fatwchar_to16(__u8 *dst, const wchar_t *src, size_t len) ...@@ -235,17 +235,6 @@ static inline void fatwchar_to16(__u8 *dst, const wchar_t *src, size_t len)
#endif #endif
} }
/* fat/buffer.c */
extern struct buffer_head *fat_bread(struct super_block *sb, int block);
extern struct buffer_head *fat_getblk(struct super_block *sb, int block);
extern void fat_brelse(struct super_block *sb, struct buffer_head *bh);
extern void fat_mark_buffer_dirty(struct super_block *sb, struct buffer_head *bh);
extern void fat_set_uptodate(struct super_block *sb, struct buffer_head *bh,
int val);
extern int fat_is_uptodate(struct super_block *sb, struct buffer_head *bh);
extern void fat_ll_rw_block(struct super_block *sb, int opr, int nbreq,
struct buffer_head *bh[32]);
/* fat/cache.c */ /* fat/cache.c */
extern int fat_access(struct super_block *sb, int nr, int new_value); extern int fat_access(struct super_block *sb, int nr, int new_value);
extern int __fat_access(struct super_block *sb, int nr, int new_value); extern int __fat_access(struct super_block *sb, int nr, int new_value);
...@@ -273,12 +262,8 @@ extern int fat_new_dir(struct inode *dir, struct inode *parent, int is_vfat); ...@@ -273,12 +262,8 @@ extern int fat_new_dir(struct inode *dir, struct inode *parent, int is_vfat);
/* fat/file.c */ /* fat/file.c */
extern struct file_operations fat_file_operations; extern struct file_operations fat_file_operations;
extern struct inode_operations fat_file_inode_operations; extern struct inode_operations fat_file_inode_operations;
extern ssize_t fat_file_read(struct file *filp, char *buf, size_t count,
loff_t *ppos);
extern int fat_get_block(struct inode *inode, sector_t iblock, extern int fat_get_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create); struct buffer_head *bh_result, int create);
extern ssize_t fat_file_write(struct file *filp, const char *buf, size_t count,
loff_t *ppos);
extern void fat_truncate(struct inode *inode); extern void fat_truncate(struct inode *inode);
/* fat/inode.c */ /* fat/inode.c */
...@@ -299,7 +284,6 @@ extern int fat_notify_change(struct dentry * dentry, struct iattr * attr); ...@@ -299,7 +284,6 @@ extern int fat_notify_change(struct dentry * dentry, struct iattr * attr);
/* fat/misc.c */ /* fat/misc.c */
extern void fat_fs_panic(struct super_block *s, const char *fmt, ...); extern void fat_fs_panic(struct super_block *s, const char *fmt, ...);
extern int fat_is_binary(char conversion, char *extension);
extern void lock_fat(struct super_block *sb); extern void lock_fat(struct super_block *sb);
extern void unlock_fat(struct super_block *sb); extern void unlock_fat(struct super_block *sb);
extern void fat_clusters_flush(struct super_block *sb); extern void fat_clusters_flush(struct super_block *sb);
......
#ifndef _MSDOS_FS_SB #ifndef _MSDOS_FS_SB
#define _MSDOS_FS_SB #define _MSDOS_FS_SB
#include<linux/fat_cvf.h>
/* /*
* MS-DOS file system in-core superblock data * MS-DOS file system in-core superblock data
...@@ -15,7 +14,6 @@ struct fat_mount_options { ...@@ -15,7 +14,6 @@ struct fat_mount_options {
char *iocharset; /* Charset used for filename input/display */ char *iocharset; /* Charset used for filename input/display */
unsigned short shortname; /* flags for shortname display/create rule */ unsigned short shortname; /* flags for shortname display/create rule */
unsigned char name_check; /* r = relaxed, n = normal, s = strict */ unsigned char name_check; /* r = relaxed, n = normal, s = strict */
unsigned char conversion; /* b = binary, t = text, a = auto */
unsigned quiet:1, /* set = fake successful chmods and chowns */ unsigned quiet:1, /* set = fake successful chmods and chowns */
showexec:1, /* set = only set x bit for com/exe/bat */ showexec:1, /* set = only set x bit for com/exe/bat */
sys_immutable:1, /* set = system files are immutable */ sys_immutable:1, /* set = system files are immutable */
...@@ -46,9 +44,7 @@ struct msdos_sb_info { ...@@ -46,9 +44,7 @@ struct msdos_sb_info {
struct fat_mount_options options; struct fat_mount_options options;
struct nls_table *nls_disk; /* Codepage used on disk */ struct nls_table *nls_disk; /* Codepage used on disk */
struct nls_table *nls_io; /* Charset used for input and display */ struct nls_table *nls_io; /* Charset used for input and display */
struct cvf_format* cvf_format;
void *dir_ops; /* Opaque; default directory operations */ void *dir_ops; /* Opaque; default directory operations */
void *private_data;
int dir_per_block; /* dir entries per block */ int dir_per_block; /* dir entries per block */
int dir_per_block_bits; /* log2(dir_per_block) */ int dir_per_block_bits; /* log2(dir_per_block) */
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment