[PATCH] vfat/rw for kernel 2.3.xx

Thierry Vignaud (tvignaud@mandrakesoft.com)
Mon, 26 Jul 1999 13:54:40 +0000


This is a multi-part message in MIME format.
--------------7808836EC6740D7A6671D1D4
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hi.

Here are two patches :
* the first was for 2.3.7, it enables to read vfat (mount in ro only,
write/execute lock up process)
* the other one is for 2.3.11, it enables to behave right for reads as
for writes. It seems safe but i won't garrant that it 'll not destroy
your data.
If you use a 2.3.xx kernel, you have to know what to wait for...

-- 
MandrakeSoft          http://www.mandrakesoft.com/
			         	 --Thierry
--------------7808836EC6740D7A6671D1D4
Content-Type: text/plain; charset=us-ascii;
 name="fat-2.3.7.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="fat-2.3.7.diff"

diff -ru linux/fs/fat/fatfs_syms.c linux-2.3.7/fs/fat/fatfs_syms.c --- linux/fs/fat/fatfs_syms.c Wed May 19 05:13:04 1999 +++ linux-2.3.7/fs/fat/fatfs_syms.c Tue Jun 22 15:28:18 1999 @@ -28,7 +28,6 @@ EXPORT_SYMBOL(fat_dir_operations); EXPORT_SYMBOL(fat_esc2uni); EXPORT_SYMBOL(fat_file_read); -EXPORT_SYMBOL(fat_file_write); EXPORT_SYMBOL(fat_fs_panic); EXPORT_SYMBOL(fat__get_entry); EXPORT_SYMBOL(fat_lock_creation); diff -ru linux/fs/fat/file.c linux-2.3.7/fs/fat/file.c --- linux/fs/fat/file.c Sun Feb 28 18:47:37 1999 +++ linux-2.3.7/fs/fat/file.c Tue Jun 22 15:14:27 1999 @@ -57,7 +57,7 @@ NULL, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ - generic_readpage, /* readpage */ + block_read_full_page, /* readpage */ NULL, /* writepage */ fat_bmap, /* bmap */ fat_truncate, /* truncate */ @@ -107,7 +107,7 @@ NULL, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ - generic_readpage, /* readpage */ + block_read_full_page, /* readpage */ NULL, /* writepage */ NULL, /* bmap */ fat_truncate, /* truncate */ @@ -330,124 +330,22 @@ return fat_file_read_text(filp, buf, count, ppos); return generic_file_read(filp, buf, count, ppos); } -/* - Write to a file either from user space -*/ -ssize_t fat_file_write( - struct file *filp, - const char *buf, - size_t count, - loff_t *ppos) + +static long fat_write_one_page(struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char *buf) { - struct inode *inode = filp->f_dentry->d_inode; - struct super_block *sb = inode->i_sb; - int sector,offset,size,left,written; - int error,carry; - const char *start; - char *to,ch; - struct buffer_head *bh; - int binary_mode = MSDOS_I(inode)->i_binary; + return block_write_partial_page(file, page, offset, bytes, buf, fat_getblk); +} - PRINTK(("fat_file_write: dentry=%p, inode=%p, ino=%ld\n", - filp->f_dentry, inode, inode->i_ino)); - if (!inode) { - printk("fat_file_write: inode = NULL\n"); - return -EINVAL; - } - if (MSDOS_SB(sb)->cvf_format && - MSDOS_SB(sb)->cvf_format->cvf_file_write) - return MSDOS_SB(sb)->cvf_format - ->cvf_file_write(filp,buf,count,ppos); - /* S_ISLNK allows for UMSDOS. Should never happen for normal MSDOS */ - if (!S_ISREG(inode->i_mode) && !S_ISLNK(inode->i_mode)) { - printk("fat_file_write: mode = %07o\n",inode->i_mode); - return -EINVAL; - } - /* system files may be immutable */ - if (IS_IMMUTABLE(inode)) - return -EPERM; /* - * ok, append may not work when many processes are writing at the same time - * but so what. That way leads to madness anyway. + * Write to a file (through the page cache). */ - if (filp->f_flags & O_APPEND) - *ppos = inode->i_size; - if (count == 0) - return 0; - if (*ppos + count > 0x7FFFFFFFLL) { - count = 0x7FFFFFFFLL-*ppos; - if (!count) - return -EFBIG; - } - - error = carry = 0; - for (start = buf; count || carry; count -= size) { - while (!(sector = fat_smap(inode,*ppos >> SECTOR_BITS))) - if ((error = fat_add_cluster(inode)) < 0) break; - if (error) { - fat_truncate(inode); - break; - } - offset = *ppos & (SECTOR_SIZE-1); - size = MIN(SECTOR_SIZE-offset,MAX(carry,count)); - if (binary_mode - && offset == 0 - && (size == SECTOR_SIZE - || *ppos + size >= inode->i_size)){ - /* No need to read the block first since we will */ - /* completely overwrite it */ - /* or at least write past the end of file */ - if (!(bh = fat_getblk(sb,sector))){ - error = -EIO; - break; - } - } else if (!(bh = fat_bread(sb,sector))) { - error = -EIO; - break; - } - if (binary_mode) { - copy_from_user(bh->b_data+offset,buf,written = size); - buf += size; - } else { - written = left = SECTOR_SIZE-offset; - to = (char *) bh->b_data+(*ppos & (SECTOR_SIZE-1)); - if (carry) { - *to++ = '\n'; - left--; - carry = 0; - } - for (size = 0; size < count && left; size++) { - get_user(ch, buf++); - if (ch == '\n') { - *to++ = '\r'; - left--; - } - if (!left) carry = 1; - else { - *to++ = ch; - left--; - } - } - written -= left; - } - update_vm_cache(inode, *ppos, bh->b_data + (*ppos & (SECTOR_SIZE-1)), written); - *ppos += written; - if (*ppos > inode->i_size) { - inode->i_size = *ppos; - mark_inode_dirty(inode); - } - fat_set_uptodate(sb, bh, 1); - fat_mark_buffer_dirty(sb, bh, 0); - fat_brelse(sb, bh); - } - if (start == buf) - return error; - inode->i_mtime = inode->i_ctime = CURRENT_TIME; - MSDOS_I(inode)->i_attrs |= ATTR_ARCH; - mark_inode_dirty(inode); - return buf-start; +static ssize_t +fat_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) +{ + return generic_file_write(file, buf, count, ppos, fat_write_one_page); } + void fat_truncate(struct inode *inode) {

--------------7808836EC6740D7A6671D1D4 Content-Type: text/plain; charset=us-ascii; name="fat-2.3.11.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="fat-2.3.11.diff"

diff -ruN linux/fs/fat/fatfs_syms.c fs/fat/fatfs_syms.c --- linux/fs/fat/fatfs_syms.c Fri May 14 08:18:20 1999 +++ fs/fat/fatfs_syms.c Mon Jul 26 12:07:18 1999 @@ -28,7 +28,6 @@ EXPORT_SYMBOL(fat_dir_operations); EXPORT_SYMBOL(fat_esc2uni); EXPORT_SYMBOL(fat_file_read); -EXPORT_SYMBOL(fat_file_write); EXPORT_SYMBOL(fat_fs_panic); EXPORT_SYMBOL(fat__get_entry); EXPORT_SYMBOL(fat_lock_creation); diff -ruN linux/fs/fat/file.c fs/fat/file.c --- linux/fs/fat/file.c Sun Jun 27 19:10:41 1999 +++ fs/fat/file.c Mon Jul 26 13:54:42 1999 @@ -336,124 +336,21 @@ return fat_file_read_text(filp, buf, count, ppos); return generic_file_read(filp, buf, count, ppos); } -/* - Write to a file either from user space -*/ -ssize_t fat_file_write( - struct file *filp, - const char *buf, - size_t count, - loff_t *ppos) + +static long fat_write_one_page(struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char *buf) { - struct inode *inode = filp->f_dentry->d_inode; - struct super_block *sb = inode->i_sb; - int sector,offset,size,left,written; - int error,carry; - const char *start; - char *to,ch; - struct buffer_head *bh; - int binary_mode = MSDOS_I(inode)->i_binary; + return block_write_partial_page(file, page, offset, bytes, buf); +} - PRINTK(("fat_file_write: dentry=%p, inode=%p, ino=%ld\n", - filp->f_dentry, inode, inode->i_ino)); - if (!inode) { - printk("fat_file_write: inode = NULL\n"); - return -EINVAL; - } - if (MSDOS_SB(sb)->cvf_format && - MSDOS_SB(sb)->cvf_format->cvf_file_write) - return MSDOS_SB(sb)->cvf_format - ->cvf_file_write(filp,buf,count,ppos); - /* S_ISLNK allows for UMSDOS. Should never happen for normal MSDOS */ - if (!S_ISREG(inode->i_mode) && !S_ISLNK(inode->i_mode)) { - printk("fat_file_write: mode = %07o\n",inode->i_mode); - return -EINVAL; - } - /* system files may be immutable */ - if (IS_IMMUTABLE(inode)) - return -EPERM; /* - * ok, append may not work when many processes are writing at the same time - * but so what. That way leads to madness anyway. + * Write to a file (through the page cache). */ - if (filp->f_flags & O_APPEND) - *ppos = inode->i_size; - if (count == 0) - return 0; - if (*ppos + count > 0x7FFFFFFFLL) { - count = 0x7FFFFFFFLL-*ppos; - if (!count) - return -EFBIG; - } - - error = carry = 0; - for (start = buf; count || carry; count -= size) { - while (!(sector = fat_smap(inode,*ppos >> SECTOR_BITS))) - if ((error = fat_add_cluster(inode)) < 0) break; - if (error) { - fat_truncate(inode); - break; - } - offset = *ppos & (SECTOR_SIZE-1); - size = MIN(SECTOR_SIZE-offset,MAX(carry,count)); - if (binary_mode - && offset == 0 - && (size == SECTOR_SIZE - || *ppos + size >= inode->i_size)){ - /* No need to read the block first since we will */ - /* completely overwrite it */ - /* or at least write past the end of file */ - if (!(bh = fat_getblk(sb,sector))){ - error = -EIO; - break; - } - } else if (!(bh = fat_bread(sb,sector))) { - error = -EIO; - break; - } - if (binary_mode) { - copy_from_user(bh->b_data+offset,buf,written = size); - buf += size; - } else { - written = left = SECTOR_SIZE-offset; - to = (char *) bh->b_data+(*ppos & (SECTOR_SIZE-1)); - if (carry) { - *to++ = '\n'; - left--; - carry = 0; - } - for (size = 0; size < count && left; size++) { - get_user(ch, buf++); - if (ch == '\n') { - *to++ = '\r'; - left--; - } - if (!left) carry = 1; - else { - *to++ = ch; - left--; - } - } - written -= left; - } - update_vm_cache(inode, *ppos, bh->b_data + (*ppos & (SECTOR_SIZE-1)), written); - *ppos += written; - if (*ppos > inode->i_size) { - inode->i_size = *ppos; - mark_inode_dirty(inode); - } - fat_set_uptodate(sb, bh, 1); - fat_mark_buffer_dirty(sb, bh, 0); - fat_brelse(sb, bh); - } - if (start == buf) - return error; - inode->i_mtime = inode->i_ctime = CURRENT_TIME; - MSDOS_I(inode)->i_attrs |= ATTR_ARCH; - mark_inode_dirty(inode); - return buf-start; +static ssize_t fat_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) +{ + return generic_file_write(file, buf, count, ppos, fat_write_one_page); } + void fat_truncate(struct inode *inode) {

--------------7808836EC6740D7A6671D1D4--

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/