Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:12.2
s390-tools
s390-tools-sles11sp2-cmsfs-fuse_large_files.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File s390-tools-sles11sp2-cmsfs-fuse_large_files.patch of Package s390-tools
Descripton: cmsfs-fuse: Fix file size calculation for files larger than 2 GB Symptom: It is not possible to create files larger than 2 GB. Problem: The file size calculation overflows resulting in a negative value. Solution: Cast to a longer type before calculating the file size. Problem-ID: 75609 --- cmsfs-fuse/amap.c | 11 +++--- cmsfs-fuse/cmsfs-fuse.c | 77 +++++++++++++++++++++++++----------------------- cmsfs-fuse/cmsfs-fuse.h | 6 +-- cmsfs-fuse/edf.h | 2 - 4 files changed, 51 insertions(+), 45 deletions(-) --- a/cmsfs-fuse/amap.c +++ b/cmsfs-fuse/amap.c @@ -49,7 +49,7 @@ static off_t get_amap_addr(int level, of return cmsfs.amap; if (level--) { - ptr = get_fixed_pointer(ptr + block * PTR_SIZE); + ptr = get_fixed_pointer(ptr + (off_t ) block * PTR_SIZE); if (!ptr) DIE("amap invalid ptr at addr: %lx\n", ptr + block * PTR_SIZE); @@ -69,7 +69,7 @@ static void amap_block_set(off_t addr) u8 entry; if (block > 0) - addr -= block * BYTES_PER_BLOCK; + addr -= (off_t) block * BYTES_PER_BLOCK; addr >>= BITS_PER_DATA_BLOCK; byte = addr / 8; @@ -97,7 +97,7 @@ static void amap_block_clear(off_t addr) u8 entry; if (block > 0) - addr -= block * BYTES_PER_BLOCK; + addr -= (off_t) block * BYTES_PER_BLOCK; addr >>= BITS_PER_DATA_BLOCK; byte = addr / 8; @@ -163,8 +163,9 @@ static off_t __get_free_block(int level, bit = find_first_empty_bit(entry); /* bit -> addr */ - addr = (i * cmsfs.blksize * 8 + cmsfs.blksize * bit) - + (block_nr * BYTES_PER_BLOCK); + addr = ((off_t) cmsfs.blksize * i * 8 + + (off_t) cmsfs.blksize * bit) + + (off_t) block_nr * BYTES_PER_BLOCK; amap_block_set(addr); return addr; } --- a/cmsfs-fuse/cmsfs-fuse.c +++ b/cmsfs-fuse/cmsfs-fuse.c @@ -162,7 +162,7 @@ struct file; struct file_operations { int (*cache_data) (struct file *f, off_t addr, int level, int *block, - unsigned int *disp, int *record, size_t *total); + unsigned int *disp, int *record, off_t *total); int (*write_data) (struct file *f, const char *buf, int len, size_t size, int rlen); int (*delete_pointers) (struct file *f, int level, off_t addr); @@ -197,7 +197,7 @@ struct file { /* disk address of next byte to write */ off_t write_ptr; /* the filesize while the file is opened */ - ssize_t session_size; + off_t session_size; /* number of null blocks for fixed files */ int nr_null_blocks; /* number of written padding bytes for a fixed file */ @@ -312,7 +312,7 @@ int _read(void *buf, size_t size, off_t (addr & ~DATA_BLOCK_MASK)) DIE("read: crossing blocks addr: %lx size: %ld\n", addr, size); - if ((addr < cmsfs.fdir) || ((size_t) addr > cmsfs.size)) + if (addr < cmsfs.fdir || addr > cmsfs.size) return -EIO; memcpy(buf, cmsfs.map + addr, size); @@ -326,7 +326,7 @@ int _write(const void *buf, size_t size, DIE("write: crossing blocks addr: %x size: %d\n", (int)addr, (int)size); - if ((addr < (2 * cmsfs.blksize)) || ((size_t) addr > cmsfs.size)) + if ((addr < (2 * cmsfs.blksize)) || (addr > cmsfs.size)) return -EIO; if (buf == NULL) @@ -745,7 +745,7 @@ static int edf_name_valid(const char *na /* * Summarize the number of bytes used in the last data block. */ -static int walk_last_var_data_block(off_t addr, ssize_t *total) +static int walk_last_var_data_block(off_t addr, off_t *total) { ssize_t left = cmsfs.blksize; u16 len; @@ -837,7 +837,7 @@ static void set_record_len(struct file * } static void set_record(struct file *f, int *record, off_t addr, int len, - size_t *total, int block) + off_t *total, int block) { struct record *r = &f->rlist[*record]; @@ -917,10 +917,10 @@ static void set_record_extension(struct } /* check for file end via byte count and return count of bytes left */ -static size_t crop_file_end(struct file *f, int record, size_t done, +static int crop_file_end(struct file *f, int record, off_t done, int first) { - size_t filesize = f->fst->nr_records * f->fst->record_len; + off_t filesize = (off_t) f->fst->nr_records * (off_t) f->fst->record_len; struct record *rec = &f->rlist[record]; struct record_ext *rext = rec->ext; @@ -951,9 +951,9 @@ static int end_of_file(struct file *f, i } static void walk_fixed_data_block(struct file *f, off_t addr, int *record, - size_t *total, int block, int disp) + off_t *total, int block, int disp) { - off_t offset = block * cmsfs.blksize + disp; + off_t offset = (off_t ) block * cmsfs.blksize + disp; int rlen = (f->fst->record_len > cmsfs.blksize) ? cmsfs.blksize : f->fst->record_len; int first = (offset % f->fst->record_len) ? @@ -1024,7 +1024,7 @@ out: } static int walk_var_data_block(struct file *f, off_t addr, unsigned int disp, - int *record, size_t *total, int block, int skip) + int *record, off_t *total, int block, int skip) { ssize_t left = cmsfs.blksize - skip; int last, rc; @@ -1159,7 +1159,7 @@ static int walk_var_data_block(struct fi } static void cache_fixed_data_block(struct file *f, off_t addr, int *block, - int *record, size_t *total, int disp) + int *record, off_t *total, int disp) { /* * Cannot distinguish null block pointers from not existing pointers, @@ -1180,7 +1180,7 @@ static void cache_fixed_data_block(struc * data block respecting the sequence of the data. */ static int cache_file_fixed(struct file *f, off_t addr, int level, int *block, - unsigned int *disp, int *record, size_t *total) + unsigned int *disp, int *record, off_t *total) { int left = f->ptr_per_block; off_t ptr; @@ -1203,7 +1203,7 @@ static int cache_file_fixed(struct file } static int cache_variable_data_block(struct file *f, off_t addr, int *block, - int *record, int disp, size_t *total, int skip) + int *record, int disp, off_t *total, int skip) { int rc; @@ -1234,7 +1234,7 @@ static int cache_variable_data_block(str */ static int cache_file_variable(struct file *f, off_t addr, int level, int *block, unsigned int *disp, - int *record, size_t *total) + int *record, off_t *total) { int nr, left = f->ptr_per_block; off_t ptr; @@ -1570,7 +1570,7 @@ static int cache_file(struct file *f) { int block = 0, record = -1; unsigned int disp = 0; - size_t total = 0; + off_t total = 0; return f->fops->cache_data(f, ABS(f->fst->fop), f->fst->levels, &block, &disp, &record, &total); @@ -1588,22 +1588,23 @@ static void workaround_nr_blocks(struct if (f->fst->record_format == RECORD_LEN_VARIABLE) return; - nr = f->fst->nr_records * f->fst->record_len / cmsfs.blksize; - if (f->fst->nr_records * f->fst->record_len % cmsfs.blksize) + nr = (off_t) f->fst->nr_records * (off_t) f->fst->record_len + / cmsfs.blksize; + if ((off_t) f->fst->nr_records * (off_t) f->fst->record_len % cmsfs.blksize) nr++; f->nr_null_blocks = nr - f->fst->nr_blocks; f->fst->nr_blocks = nr; } -static ssize_t get_file_size_fixed(struct fst_entry *fst) +static off_t get_file_size_fixed(struct fst_entry *fst) { - return fst->nr_records * fst->record_len; + return (off_t) fst->nr_records * (off_t) fst->record_len; } -static ssize_t get_file_size_variable(struct fst_entry *fst) +static off_t get_file_size_variable(struct fst_entry *fst) { struct var_ptr vptr; - ssize_t total = 0; + off_t total = 0; off_t ptr; int rc; @@ -1643,7 +1644,7 @@ skip_scan: * also null blocks. */ if (fst->nr_blocks) - total += (fst->nr_blocks - 1) * cmsfs.blksize; + total += ((off_t) fst->nr_blocks - 1) * cmsfs.blksize; return total; } @@ -1651,7 +1652,7 @@ skip_scan: * Return the file size as it is on the disk. Includes headers for * variable records. */ -static ssize_t get_file_size(struct fst_entry *fst) +static off_t get_file_size(struct fst_entry *fst) { if (fst->record_format == RECORD_LEN_FIXED) return get_file_size_fixed(fst); @@ -1660,9 +1661,9 @@ static ssize_t get_file_size(struct fst_ return 0; } -static ssize_t get_file_size_logical(struct fst_entry *fst) +static off_t get_file_size_logical(struct fst_entry *fst) { - ssize_t total; + off_t total; if (fst->nr_records == 0) return 0; @@ -1674,7 +1675,7 @@ static ssize_t get_file_size_logical(str /* subtract the record headers */ if (fst->record_format == RECORD_LEN_VARIABLE) - total -= fst->nr_records * VAR_RECORD_HEADER_SIZE; + total -= (off_t) fst->nr_records * VAR_RECORD_HEADER_SIZE; if (linefeed_mode_enabled(fst)) total += fst->nr_records; @@ -1707,7 +1708,7 @@ static int cmsfs_getattr(const char *pat stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime; /* size */ - stbuf->st_size = fst.record_len * fst.nr_records; + stbuf->st_size = (off_t) fst.record_len * (off_t) fst.nr_records; stbuf->st_blocks = max(stbuf->st_size, cmsfs.blksize); stbuf->st_blocks = ((stbuf->st_blocks + cmsfs.data_block_mask) & ~cmsfs.data_block_mask) >> 9; @@ -1730,7 +1731,7 @@ static int cmsfs_getattr(const char *pat * Include potential sparse blocks for variable files which * are included in nr_blocks to avoid scanning the whole file. */ - stbuf->st_blocks = fst.nr_blocks * cmsfs.nr_blocks_512; + stbuf->st_blocks = (off_t) fst.nr_blocks * cmsfs.nr_blocks_512; } return 0; } @@ -2598,16 +2599,21 @@ static int cmsfs_statfs(const char *path { unsigned int inode_size = cmsfs.blksize + sizeof(struct fst_entry); unsigned int free_blocks = cmsfs.total_blocks - cmsfs.used_blocks; + unsigned long long tmp; (void) path; buf->f_bsize = buf->f_frsize = cmsfs.blksize; buf->f_blocks = cmsfs.total_blocks; buf->f_bfree = buf->f_bavail = free_blocks; + /* number of possible inodes */ - buf->f_files = cmsfs.total_blocks * cmsfs.blksize / inode_size; + tmp = (unsigned long long) cmsfs.total_blocks * + cmsfs.blksize / inode_size; + buf->f_files = (long) tmp; - buf->f_ffree = free_blocks * cmsfs.blksize / inode_size; + tmp = (unsigned long long) free_blocks * cmsfs.blksize / inode_size; + buf->f_ffree = (long) tmp; buf->f_namemax = MAX_FNAME - 1; return 0; } @@ -3163,9 +3169,8 @@ static void update_fst(struct file *f, o static int cmsfs_truncate(const char *path, off_t size) { struct fst_entry fst; - off_t fst_addr; + off_t fst_addr, len; struct file *f; - ssize_t len; int rc = 0; if (cmsfs.readonly) @@ -3715,7 +3720,7 @@ static void delete_record(struct file *f static int update_records(struct file *f, int nrecords) { int i, rc, rnr, bnr = 0, skip = 0; - size_t total = 0; + off_t total = 0; rnr = f->fst->nr_records - 1; if (rnr >= 0) { @@ -3812,7 +3817,7 @@ static int new_blocks(struct file *f, si return 0; if (f->fst->record_format == RECORD_LEN_VARIABLE) - tmp += nrecords * VAR_RECORD_HEADER_SIZE; + tmp += (double) nrecords * VAR_RECORD_HEADER_SIZE; tmp -= last; if (tmp <= 0) @@ -3981,7 +3986,7 @@ out: static int do_write(struct file *f, const char *buf, size_t size, off_t offset) { - ssize_t len, copied = 0; + off_t len, copied = 0; struct var_ptr vptr; int rc; --- a/cmsfs-fuse/cmsfs-fuse.h +++ b/cmsfs-fuse/cmsfs-fuse.h @@ -18,7 +18,7 @@ extern struct cmsfs cmsfs; /* conversion between absolute and relative addresses */ -#define ABS(x) ((x - 1) * cmsfs.blksize) +#define ABS(x) ((off_t) (x - 1) * cmsfs.blksize) #define REL(x) ((x / cmsfs.blksize) + 1) struct fcache_entry { @@ -45,7 +45,7 @@ struct cmsfs { /* start of mmap of the whole block device */ char *map; /* size of the disk */ - size_t size; + off_t size; /* formatted blocksize */ int blksize; /* number of 512 byte blocks per block */ @@ -86,7 +86,7 @@ struct cmsfs { int bits_per_data_block; int bits_per_ptr_block; int data_block_mask; - int amap_bytes_per_block; + off_t amap_bytes_per_block; /* file cache */ struct fcache_entry *fcache; --- a/cmsfs-fuse/edf.h +++ b/cmsfs-fuse/edf.h @@ -27,7 +27,7 @@ struct fst_entry { int record_len; char res3[4]; - int fop; + unsigned int fop; /* number of data blocks (not incl. pointer blocks) */ int nr_blocks; int nr_records;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor