Support 4 GB files with fat32
Subsystems (2)
PATCH 1/1 Support 4 GB files with fat32
Hi Marcelo,
I see you have now applied the patch from OGAWA Hirofumi. I submitted a follow on patch later that day which I think you may also want to consider.
Windows can create files up to 4GB (-1 byte) on fat32, while Linux can currently only read/write files up to 2GB. This patch fixes up the 2.4.x fat32 support so it can properly support the full fat32 file range of file sizes.
-Erik
--
Erik B. Andersen http://codepoet-consulting.com/
--This message was written using 73% post-consumer electrons--
fs/buffer.c +1 -1
@@ -1902,7 +1902,7 @@* We may have to extend the file. */ -int cont_prepare_write (struct page *page,unsigned offset,unsigned to,get_block_t *get_block,unsigned long *bytes) +int cont_prepare_write (struct page *page,unsigned offset,unsigned to,get_block_t *get_block,loff_t *bytes) {struct address_space *mapping = page->mapping;struct inode *inode = mapping->host;
fs/fat/dir.c +2 -3
@@ -362,15 +362,14 @@unsigned char long_slots;wchar_t *unicode =NULL ;char c, work[8 ], bufname[56 ], *ptname = bufname; -unsigned long lpos, dummy, *furrfu = &lpos; +loff_t lpos, dummy, *furrfu = &lpos;int uni_xlate =MSDOS_SB (sb)->options.unicode_xlate;int isvfat =MSDOS_SB (sb)->options.isvfat;int utf8 =MSDOS_SB (sb)->options.utf8;int nocase =MSDOS_SB (sb)->options.nocase;unsigned short opt_shortname =MSDOS_SB (sb)->options.shortname; -unsigned long inum;int chi, chl, i, i2, j, last, last_u, dotoffset =0 ; -loff_t i_pos, cpos; +loff_t i_pos, inum, cpos; cpos = filp->f_pos;/* Fake . and .. for the root directory. */
fs/fat/file.c +1 -1
@@ -62,7 +62,7 @@ }if (!create)return 0 ; -if (iblock << sb->s_blocksize_bits !=MSDOS_I (inode)->mmu_private) { +if (iblock !=MSDOS_I (inode)->mmu_private >> sb->s_blocksize_bits) {BUG ();return -EIO ; }
fs/fat/inode.c +5 -4
@@ -406,7 +406,7 @@ } inode->i_blksize =1 << sbi->cluster_bits; inode->i_blocks = ((inode->i_size + inode->i_blksize -1 ) - & ~(inode->i_blksize -1 )) >>9 ; + & ~((loff_t )inode->i_blksize -1 )) >>9 ;MSDOS_I (inode)->i_logstart =0 ;MSDOS_I (inode)->mmu_private = inode->i_size;
@@ -556,8 +556,8 @@struct fat_boot_sector *b;struct msdos_sb_info *sbi =MSDOS_SB (sb);char *p; -int logical_sector_size, hard_blksize, fat_clusters =0 ; -unsigned int total_sectors, rootdir_sectors; +int logical_sector_size, hard_blksize; +unsigned long total_sectors, rootdir_sectors, fat_clusters =0 ;int fat32, debug, error, fat, cp;struct fat_mount_options opts;char buf[50 ];
@@ -651,6 +651,7 @@ fat32 =1 ; sbi->fat_length =CF_LE_L (b->fat32_length); sbi->root_cluster =CF_LE_L (b->root_cluster); + sb->s_maxbytes =0xffffffff ; sbi->fsinfo_sector =CF_LE_W (b->info_sector);/* MC - if info_sector is 0, don't multiply by 0 */
@@ -957,7 +958,7 @@/* this is as close to the truth as we can get ... */ inode->i_blksize =1 << sbi->cluster_bits; inode->i_blocks = ((inode->i_size + inode->i_blksize -1 ) - & ~(inode->i_blksize -1 )) >>9 ; + & ~((loff_t )inode->i_blksize -1 )) >>9 ; inode->i_mtime = inode->i_atime =date_dos2unix (CF_LE_W (de->time),CF_LE_W (de->date)); inode->i_ctime =
include/linux/adfs_fs_i.h +1 -1
@@ -11,7 +11,7 @@* adfs file system inode data in memory */ struct adfs_inode_info { -unsigned long mmu_private; +loff_t mmu_private;unsigned long parent_id;/* object id of parent */ __u32 loadaddr;/* RISC OS load address */ __u32 execaddr;/* RISC OS exec address */
include/linux/affs_fs_i.h +1 -1
@@ -36,7 +36,7 @@struct affs_ext_key *i_ac;/* associative cache of extended blocks */ u32 i_ext_last;/* last accessed extended block */ struct buffer_head *i_ext_bh;/* bh of last extended block */ -unsigned long mmu_private; +loff_t mmu_private;u32 i_protect;/* unused attribute bits */ u32 i_lastalloc;/* last allocated block */ int i_pa_cnt;/* number of preallocated blocks */
include/linux/fs.h +1 -1
@@ -1508,7 +1508,7 @@extern int block_read_full_page (struct page *,get_block_t *);extern int block_prepare_write (struct page *,unsigned ,unsigned ,get_block_t *);extern int cont_prepare_write (struct page *,unsigned ,unsigned ,get_block_t *, -unsigned long *); +loff_t *);extern int generic_cont_expand (struct inode *inode,loff_t size) ;extern int block_commit_write (struct page *page,unsigned from,unsigned to);extern int block_sync_page (struct page *);
include/linux/hfs_fs_i.h +1 -1
@@ -19,7 +19,7 @@struct hfs_inode_info {int magic;/* A magic number */ -unsigned long mmu_private; +loff_t mmu_private;struct hfs_cat_entry *entry;/* For a regular or header file */
include/linux/hpfs_fs_i.h +1 -1
@@ -2,7 +2,7 @@#define _HPFS_FS_Istruct hpfs_inode_info { -unsigned long mmu_private; +loff_t mmu_private;ino_t i_parent_dir;/* (directories) gives fnode of parent dir */ unsigned i_dno;/* (directories) root dnode */ unsigned i_dpos;/* (directories) temp for readdir */
include/linux/msdos_fs_i.h +1 -1
@@ -6,7 +6,7 @@*/ struct msdos_inode_info { -unsigned long mmu_private; +loff_t mmu_private;int i_start;/* first cluster or 0 */ int i_logstart;/* logical first cluster */ int i_attrs;/* unused attribute bits */
include/linux/qnx4_fs_i.h renamed from include/linux/qnx4_fs_i.h.orig +1 -1
@@ -33,7 +33,7 @@__u8 i_zero[4 ];/* 4 */ qnx4_ftype_t i_type;/* 1 */ __u8 i_status;/* 1 */ - unsigned long mmu_private; + loff_t mmu_private; };#endif
fs/buffer.c line 1905
Quoted 2 lines · Erik Andersen
fs/buffer.c +1
-1-int cont_prepare_write (struct page *page,unsigned offset,unsigned to,get_block_t *get_block,unsigned long *bytes) +int cont_prepare_write (struct page *page,unsigned offset,unsigned to,get_block_t *get_block,loff_t *bytes)
I don't think we should changes APIs that late in the 2.4 series.