Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 158781
Collapse All | Expand All

(-)linux/fs/squashfs/inode.c (-37 / +75 lines)
Lines 173-186 out: Link Here
173
173
174
SQSH_EXTERN unsigned int squashfs_read_data(struct super_block *s, char *buffer,
174
SQSH_EXTERN unsigned int squashfs_read_data(struct super_block *s, char *buffer,
175
			long long index, unsigned int length,
175
			long long index, unsigned int length,
176
			long long *next_index)
176
			long long *next_index, int srclength)
177
{
177
{
178
	struct squashfs_sb_info *msblk = s->s_fs_info;
178
	struct squashfs_sb_info *msblk = s->s_fs_info;
179
	struct squashfs_super_block *sblk = &msblk->sblk;
179
	struct buffer_head *bh[((SQUASHFS_FILE_MAX_SIZE - 1) >>
180
	struct buffer_head *bh[((SQUASHFS_FILE_MAX_SIZE - 1) >>
180
			msblk->devblksize_log2) + 2];
181
			msblk->devblksize_log2) + 2];
181
	unsigned int offset = index & ((1 << msblk->devblksize_log2) - 1);
182
	unsigned int offset = index & ((1 << msblk->devblksize_log2) - 1);
182
	unsigned int cur_index = index >> msblk->devblksize_log2;
183
	unsigned int cur_index = index >> msblk->devblksize_log2;
183
	int bytes, avail_bytes, b = 0, k;
184
	int bytes, avail_bytes, b = 0, k = 0;
184
	char *c_buffer;
185
	char *c_buffer;
185
	unsigned int compressed;
186
	unsigned int compressed;
186
	unsigned int c_byte = length;
187
	unsigned int c_byte = length;
Lines 191-198 SQSH_EXTERN unsigned int squashfs_read_d Link Here
191
		c_buffer = compressed ? msblk->read_data : buffer;
192
		c_buffer = compressed ? msblk->read_data : buffer;
192
		c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte);
193
		c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte);
193
194
194
		TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed
195
		TRACE("Block @ 0x%llx, %scompressed size %d, src size %d\n", index, compressed
195
					? "" : "un", (unsigned int) c_byte);
196
					? "" : "un", (unsigned int) c_byte, srclength);
197
198
                if (c_byte > srclength || index < 0 || (index + c_byte) > sblk->bytes_used)
199
                        goto read_failure;
196
200
197
		if (!(bh[0] = sb_getblk(s, cur_index)))
201
		if (!(bh[0] = sb_getblk(s, cur_index)))
198
			goto block_release;
202
			goto block_release;
Lines 204-209 SQSH_EXTERN unsigned int squashfs_read_d Link Here
204
		}
208
		}
205
		ll_rw_block(READ, b, bh);
209
		ll_rw_block(READ, b, bh);
206
	} else {
210
	} else {
211
                if (index < 0 || (index + 2) > sblk->bytes_used)
212
                        goto read_failure;
213
207
		if (!(bh[0] = get_block_length(s, &cur_index, &offset,
214
		if (!(bh[0] = get_block_length(s, &cur_index, &offset,
208
								&c_byte)))
215
								&c_byte)))
209
			goto read_failure;
216
			goto read_failure;
Lines 216-221 SQSH_EXTERN unsigned int squashfs_read_d Link Here
216
		TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed
223
		TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed
217
					? "" : "un", (unsigned int) c_byte);
224
					? "" : "un", (unsigned int) c_byte);
218
225
226
                if (c_byte > srclength || (index + c_byte) > sblk->bytes_used)
227
                        goto read_failure;
228
219
		for (b = 1; bytes < c_byte; b++) {
229
		for (b = 1; bytes < c_byte; b++) {
220
			if (!(bh[b] = sb_getblk(s, ++cur_index)))
230
			if (!(bh[b] = sb_getblk(s, ++cur_index)))
221
				goto block_release;
231
				goto block_release;
Lines 227-233 SQSH_EXTERN unsigned int squashfs_read_d Link Here
227
	if (compressed)
237
	if (compressed)
228
		down(&msblk->read_data_mutex);
238
		down(&msblk->read_data_mutex);
229
239
230
	for (bytes = 0, k = 0; k < b; k++) {
240
	for (bytes = 0; k < b; k++) {
231
		avail_bytes = (c_byte - bytes) > (msblk->devblksize - offset) ?
241
		avail_bytes = (c_byte - bytes) > (msblk->devblksize - offset) ?
232
					msblk->devblksize - offset :
242
					msblk->devblksize - offset :
233
					c_byte - bytes;
243
					c_byte - bytes;
Lines 249-255 SQSH_EXTERN unsigned int squashfs_read_d Link Here
249
		msblk->stream.next_in = c_buffer;
259
		msblk->stream.next_in = c_buffer;
250
		msblk->stream.avail_in = c_byte;
260
		msblk->stream.avail_in = c_byte;
251
		msblk->stream.next_out = buffer;
261
		msblk->stream.next_out = buffer;
252
		msblk->stream.avail_out = msblk->read_size;
262
		msblk->stream.avail_out = srclength;
253
263
254
		if (((zlib_err = zlib_inflateInit(&msblk->stream)) != Z_OK) ||
264
		if (((zlib_err = zlib_inflateInit(&msblk->stream)) != Z_OK) ||
255
				((zlib_err = zlib_inflate(&msblk->stream, Z_FINISH))
265
				((zlib_err = zlib_inflate(&msblk->stream, Z_FINISH))
Lines 271-278 SQSH_EXTERN unsigned int squashfs_read_d Link Here
271
	return bytes;
281
	return bytes;
272
282
273
block_release:
283
block_release:
274
	while (--b >= 0)
284
	for (; k < b; k++)
275
		brelse(bh[b]);
285
		brelse(bh[k]);
276
286
277
read_failure:
287
read_failure:
278
	ERROR("sb_bread failed reading block 0x%x\n", cur_index);
288
	ERROR("sb_bread failed reading block 0x%x\n", cur_index);
Lines 336-349 SQSH_EXTERN int squashfs_get_cached_bloc Link Here
336
			msblk->block_cache[i].block = SQUASHFS_USED_BLK;
346
			msblk->block_cache[i].block = SQUASHFS_USED_BLK;
337
			up(&msblk->block_cache_mutex);
347
			up(&msblk->block_cache_mutex);
338
348
339
			if (!(msblk->block_cache[i].length =
349
                        msblk->block_cache[i].length = squashfs_read_data(s,
340
						squashfs_read_data(s,
350
                                msblk->block_cache[i].data, block, 0, &next_index,
341
						msblk->block_cache[i].data,
351
				SQUASHFS_METADATA_SIZE);
342
						block, 0, &next_index))) {
352
343
				ERROR("Unable to read cache block [%llx:%x]\n",
353
                        if (msblk->block_cache[i].length == 0) {
344
						block, offset);
354
                                ERROR("Unable to read cache block [%llx:%x]\n",
345
				goto out;
355
                                                block, offset);
346
			}
356
                                down(&msblk->block_cache_mutex);
357
                                msblk->block_cache[i].block = SQUASHFS_INVALID_BLK;
358
                                kfree(msblk->block_cache[i].data);
359
                                wake_up(&msblk->waitq);
360
                                up(&msblk->block_cache_mutex);
361
                                goto out;
362
                        }
347
363
348
			down(&msblk->block_cache_mutex);
364
			down(&msblk->block_cache_mutex);
349
			wake_up(&msblk->waitq);
365
			wake_up(&msblk->waitq);
Lines 357-363 SQSH_EXTERN int squashfs_get_cached_bloc Link Here
357
			continue;
373
			continue;
358
		}
374
		}
359
375
360
		if ((bytes = msblk->block_cache[i].length - offset) >= length) {
376
                bytes = msblk->block_cache[i].length - offset;
377
378
                if (bytes < 1)
379
                        goto out;
380
		else if (bytes >= length) {
361
			if (buffer)
381
			if (buffer)
362
				memcpy(buffer, msblk->block_cache[i].data +
382
				memcpy(buffer, msblk->block_cache[i].data +
363
						offset, length);
383
						offset, length);
Lines 442-447 SQSH_EXTERN struct squashfs_fragment_cac Link Here
442
{
462
{
443
	int i, n;
463
	int i, n;
444
	struct squashfs_sb_info *msblk = s->s_fs_info;
464
	struct squashfs_sb_info *msblk = s->s_fs_info;
465
        struct squashfs_super_block *sblk = &msblk->sblk;
445
466
446
	while ( 1 ) {
467
	while ( 1 ) {
447
		down(&msblk->fragment_mutex);
468
		down(&msblk->fragment_mutex);
Lines 487-493 SQSH_EXTERN struct squashfs_fragment_cac Link Here
487
508
488
			if (!(msblk->fragment[i].length = squashfs_read_data(s,
509
			if (!(msblk->fragment[i].length = squashfs_read_data(s,
489
						msblk->fragment[i].data,
510
						msblk->fragment[i].data,
490
						start_block, length, NULL))) {
511
						start_block, length, NULL,
512
						sblk->block_size))) {
491
				ERROR("Unable to read fragment cache block "
513
				ERROR("Unable to read fragment cache block "
492
							"[%llx]\n", start_block);
514
							"[%llx]\n", start_block);
493
				msblk->fragment[i].locked = 0;
515
				msblk->fragment[i].locked = 0;
Lines 876-881 static int read_fragment_index_table(str Link Here
876
{
898
{
877
	struct squashfs_sb_info *msblk = s->s_fs_info;
899
	struct squashfs_sb_info *msblk = s->s_fs_info;
878
	struct squashfs_super_block *sblk = &msblk->sblk;
900
	struct squashfs_super_block *sblk = &msblk->sblk;
901
	unsigned int length = SQUASHFS_FRAGMENT_INDEX_BYTES(sblk->fragments);
902
903
	if (length == 0)
904
		return 1;
879
905
880
	/* Allocate fragment index table */
906
	/* Allocate fragment index table */
881
	if (!(msblk->fragment_index = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES
907
	if (!(msblk->fragment_index = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES
Lines 884-896 static int read_fragment_index_table(str Link Here
884
		return 0;
910
		return 0;
885
	}
911
	}
886
   
912
   
887
	if (SQUASHFS_FRAGMENT_INDEX_BYTES(sblk->fragments) &&
913
	if (!squashfs_read_data(s, (char *) msblk->fragment_index,
888
					!squashfs_read_data(s, (char *)
914
			sblk->fragment_table_start, length |
889
					msblk->fragment_index,
915
			SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) {
890
					sblk->fragment_table_start,
891
					SQUASHFS_FRAGMENT_INDEX_BYTES
892
					(sblk->fragments) |
893
					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
894
		ERROR("unable to read fragment index table\n");
916
		ERROR("unable to read fragment index table\n");
895
		return 0;
917
		return 0;
896
	}
918
	}
Lines 982-990 static int squashfs_fill_super(struct su Link Here
982
	init_waitqueue_head(&msblk->waitq);
1004
	init_waitqueue_head(&msblk->waitq);
983
	init_waitqueue_head(&msblk->fragment_wait_queue);
1005
	init_waitqueue_head(&msblk->fragment_wait_queue);
984
1006
1007
	sblk->bytes_used = sizeof(struct squashfs_super_block);
985
	if (!squashfs_read_data(s, (char *) sblk, SQUASHFS_START,
1008
	if (!squashfs_read_data(s, (char *) sblk, SQUASHFS_START,
986
					sizeof(struct squashfs_super_block) |
1009
					sizeof(struct squashfs_super_block) |
987
					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
1010
					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL,
1011
					sizeof(struct squashfs_super_block))) {
988
		SERROR("unable to read superblock\n");
1012
		SERROR("unable to read superblock\n");
989
		goto failed_mount;
1013
		goto failed_mount;
990
	}
1014
	}
Lines 1012-1017 static int squashfs_fill_super(struct su Link Here
1012
	if(!supported_squashfs_filesystem(msblk, silent))
1036
	if(!supported_squashfs_filesystem(msblk, silent))
1013
		goto failed_mount;
1037
		goto failed_mount;
1014
1038
1039
        /* Check the filesystem does not extend beyond the end of the
1040
           block device */
1041
        if(sblk->bytes_used < 0 || sblk->bytes_used > i_size_read(s->s_bdev->bd_inode))
1042
                goto failed_mount;
1043
1044
        /* Check the root inode for sanity */
1045
        if (SQUASHFS_INODE_OFFSET(sblk->root_inode) > SQUASHFS_METADATA_SIZE)
1046
                goto failed_mount;
1047
1015
	TRACE("Found valid superblock on %s\n", bdevname(s->s_bdev, b));
1048
	TRACE("Found valid superblock on %s\n", bdevname(s->s_bdev, b));
1016
	TRACE("Inodes are %scompressed\n",
1049
	TRACE("Inodes are %scompressed\n",
1017
					SQUASHFS_UNCOMPRESSED_INODES
1050
					SQUASHFS_UNCOMPRESSED_INODES
Lines 1081-1087 static int squashfs_fill_super(struct su Link Here
1081
		if (!squashfs_read_data(s, (char *) &suid, sblk->uid_start,
1114
		if (!squashfs_read_data(s, (char *) &suid, sblk->uid_start,
1082
					((sblk->no_uids + sblk->no_guids) *
1115
					((sblk->no_uids + sblk->no_guids) *
1083
					 sizeof(unsigned int)) |
1116
					 sizeof(unsigned int)) |
1084
					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
1117
					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL,
1118
					(sblk->no_uids + sblk->no_guids) *
1119
					sizeof(unsigned int))) {
1085
			ERROR("unable to read uid/gid table\n");
1120
			ERROR("unable to read uid/gid table\n");
1086
			goto failed_mount;
1121
			goto failed_mount;
1087
		}
1122
		}
Lines 1092-1098 static int squashfs_fill_super(struct su Link Here
1092
		if (!squashfs_read_data(s, (char *) msblk->uid, sblk->uid_start,
1127
		if (!squashfs_read_data(s, (char *) msblk->uid, sblk->uid_start,
1093
					((sblk->no_uids + sblk->no_guids) *
1128
					((sblk->no_uids + sblk->no_guids) *
1094
					 sizeof(unsigned int)) |
1129
					 sizeof(unsigned int)) |
1095
					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
1130
					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL,
1131
					(sblk->no_uids + sblk->no_guids) *
1132
					sizeof(unsigned int))) {
1096
			ERROR("unable to read uid/gid table\n");
1133
			ERROR("unable to read uid/gid table\n");
1097
			goto failed_mount;
1134
			goto failed_mount;
1098
		}
1135
		}
Lines 1518-1524 static int squashfs_readpage(struct file Link Here
1518
		down(&msblk->read_page_mutex);
1555
		down(&msblk->read_page_mutex);
1519
		
1556
		
1520
		if (!(bytes = squashfs_read_data(inode->i_sb, msblk->read_page,
1557
		if (!(bytes = squashfs_read_data(inode->i_sb, msblk->read_page,
1521
					block, bsize, NULL))) {
1558
					block, bsize, NULL,
1559
					msblk->read_size))) {
1522
			ERROR("Unable to read page, block %llx, size %x\n", block,
1560
			ERROR("Unable to read page, block %llx, size %x\n", block,
1523
					bsize);
1561
					bsize);
1524
			up(&msblk->read_page_mutex);
1562
			up(&msblk->read_page_mutex);
Lines 1618-1632 static int squashfs_readpage4K(struct fi Link Here
1618
1656
1619
	if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
1657
	if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
1620
					PAGE_CACHE_SHIFT)) {
1658
					PAGE_CACHE_SHIFT)) {
1621
		pageaddr = kmap_atomic(page, KM_USER0);
1622
		block_list = NULL;
1659
		block_list = NULL;
1623
		goto skip_read;
1660
		goto skip_read;
1624
	}
1661
	}
1625
1662
1626
	if (!(block_list = kmalloc(SIZE, GFP_KERNEL))) {
1663
	if (!(block_list = kmalloc(SIZE, GFP_KERNEL))) {
1627
		ERROR("Failed to allocate block_list\n");
1664
		ERROR("Failed to allocate block_list\n");
1628
		pageaddr = kmap_atomic(page, KM_USER0);
1629
		block_list = NULL;
1630
		goto skip_read;
1665
		goto skip_read;
1631
	}
1666
	}
1632
1667
Lines 1638-1648 static int squashfs_readpage4K(struct fi Link Here
1638
1673
1639
		down(&msblk->read_page_mutex);
1674
		down(&msblk->read_page_mutex);
1640
		bytes = squashfs_read_data(inode->i_sb, msblk->read_page, block,
1675
		bytes = squashfs_read_data(inode->i_sb, msblk->read_page, block,
1641
					bsize, NULL);
1676
					bsize, NULL, msblk->read_size);
1642
		pageaddr = kmap_atomic(page, KM_USER0);
1677
		if (bytes) {
1643
		if (bytes)
1678
			pageaddr = kmap_atomic(page, KM_USER0);
1644
			memcpy(pageaddr, msblk->read_page, bytes);
1679
			memcpy(pageaddr, msblk->read_page, bytes);
1645
		else
1680
			kunmap_atomic(pageaddr, KM_USER0);
1681
		} else
1646
			ERROR("Unable to read page, block %llx, size %x\n",
1682
			ERROR("Unable to read page, block %llx, size %x\n",
1647
					block, bsize);
1683
					block, bsize);
1648
		up(&msblk->read_page_mutex);
1684
		up(&msblk->read_page_mutex);
Lines 1652-1662 static int squashfs_readpage4K(struct fi Link Here
1652
					SQUASHFS_I(inode)->
1688
					SQUASHFS_I(inode)->
1653
					u.s1.fragment_start_block,
1689
					u.s1.fragment_start_block,
1654
					SQUASHFS_I(inode)-> u.s1.fragment_size);
1690
					SQUASHFS_I(inode)-> u.s1.fragment_size);
1655
		pageaddr = kmap_atomic(page, KM_USER0);
1656
		if (fragment) {
1691
		if (fragment) {
1657
			bytes = i_size_read(inode) & (sblk->block_size - 1);
1692
			bytes = i_size_read(inode) & (sblk->block_size - 1);
1693
			pageaddr = kmap_atomic(page, KM_USER0);
1658
			memcpy(pageaddr, fragment->data + SQUASHFS_I(inode)->
1694
			memcpy(pageaddr, fragment->data + SQUASHFS_I(inode)->
1659
					u.s1.fragment_offset, bytes);
1695
					u.s1.fragment_offset, bytes);
1696
			kunmap_atomic(pageaddr, KM_USER0);
1660
			release_cached_fragment(msblk, fragment);
1697
			release_cached_fragment(msblk, fragment);
1661
		} else
1698
		} else
1662
			ERROR("Unable to read page, block %llx, size %x\n",
1699
			ERROR("Unable to read page, block %llx, size %x\n",
Lines 1666-1671 static int squashfs_readpage4K(struct fi Link Here
1666
	}
1703
	}
1667
1704
1668
skip_read:
1705
skip_read:
1706
	pageaddr = kmap_atomic(page, KM_USER0);
1669
	memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);
1707
	memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);
1670
	kunmap_atomic(pageaddr, KM_USER0);
1708
	kunmap_atomic(pageaddr, KM_USER0);
1671
	flush_dcache_page(page);
1709
	flush_dcache_page(page);
(-)linux/fs/squashfs/squashfs2_0.c (-6 / +7 lines)
Lines 73-84 static int read_fragment_index_table_2(s Link Here
73
	}
73
	}
74
   
74
   
75
	if (SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments) &&
75
	if (SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments) &&
76
					!squashfs_read_data(s, (char *)
76
			!squashfs_read_data(s, (char *)
77
					msblk->fragment_index_2,
77
			msblk->fragment_index_2,
78
					sblk->fragment_table_start,
78
			sblk->fragment_table_start,
79
					SQUASHFS_FRAGMENT_INDEX_BYTES_2
79
			SQUASHFS_FRAGMENT_INDEX_BYTES_2
80
					(sblk->fragments) |
80
			(sblk->fragments) |
81
					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
81
			SQUASHFS_COMPRESSED_BIT_BLOCK, NULL,
82
			SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments))) {
82
		ERROR("unable to read fragment index table\n");
83
		ERROR("unable to read fragment index table\n");
83
		return 0;
84
		return 0;
84
	}
85
	}
(-)linux/fs/squashfs/squashfs.h (-1 / +1 lines)
Lines 49-55 static inline struct squashfs_inode_info Link Here
49
#define SQSH_EXTERN
49
#define SQSH_EXTERN
50
extern unsigned int squashfs_read_data(struct super_block *s, char *buffer,
50
extern unsigned int squashfs_read_data(struct super_block *s, char *buffer,
51
				long long index, unsigned int length,
51
				long long index, unsigned int length,
52
				long long *next_index);
52
				long long *next_index, int srclength);
53
extern int squashfs_get_cached_block(struct super_block *s, char *buffer,
53
extern int squashfs_get_cached_block(struct super_block *s, char *buffer,
54
				long long block, unsigned int offset,
54
				long long block, unsigned int offset,
55
				int length, long long *next_block,
55
				int length, long long *next_block,

Return to bug 158781