diff options
-rw-r--r-- | fs/btrfs/disk-io.c | 5 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 4 | ||||
-rw-r--r-- | fs/squashfs/sqfs.c | 54 | ||||
-rw-r--r-- | fs/ubifs/io.c | 8 |
4 files changed, 42 insertions, 29 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 01e7cee520..b332ecb796 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1030,7 +1030,6 @@ out: int close_ctree_fs_info(struct btrfs_fs_info *fs_info) { int ret; - int err = 0; free_fs_roots_tree(&fs_info->fs_root_tree); @@ -1038,9 +1037,7 @@ int close_ctree_fs_info(struct btrfs_fs_info *fs_info) ret = btrfs_close_devices(fs_info->fs_devices); btrfs_cleanup_all_caches(fs_info); btrfs_free_fs_info(fs_info); - if (!err) - err = ret; - return err; + return ret; } int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid) diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index fcf52d4b0f..4aaaeab663 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -1030,7 +1030,7 @@ again: */ stripe_nr = stripe_nr / map->stripe_len; - stripe_offset = stripe_nr * map->stripe_len; + stripe_offset = stripe_nr * (u64)map->stripe_len; BUG_ON(offset < stripe_offset); /* stripe_offset is the offset of this block in its stripe*/ @@ -1103,7 +1103,7 @@ again: rot = stripe_nr % map->num_stripes; /* Fill in the logical address of each stripe */ - tmp = stripe_nr * nr_data_stripes(map); + tmp = (u64)stripe_nr * nr_data_stripes(map); for (i = 0; i < nr_data_stripes(map); i++) raid_map[(i+rot) % map->num_stripes] = diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 5de69ac3ca..dca13bd1f1 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -1310,7 +1310,7 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, { char *dir = NULL, *fragment_block, *datablock = NULL, *data_buffer = NULL; char *fragment = NULL, *file = NULL, *resolved, *data; - u64 start, n_blks, table_size, data_offset, table_offset; + u64 start, n_blks, table_size, data_offset, table_offset, sparse_size; int ret, j, i_number, datablk_count = 0; struct squashfs_super_block *sblk = ctxt.sblk; struct squashfs_fragment_block_entry frag_entry; @@ -1444,28 +1444,43 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, n_blks = DIV_ROUND_UP(table_size + table_offset, ctxt.cur_dev->blksz); - data_buffer = malloc_cache_aligned(n_blks * ctxt.cur_dev->blksz); + /* Don't load any data for sparse blocks */ + if (finfo.blk_sizes[j] == 0) { + n_blks = 0; + table_offset = 0; + data_buffer = NULL; + data = NULL; + } else { + data_buffer = malloc_cache_aligned(n_blks * ctxt.cur_dev->blksz); - if (!data_buffer) { - ret = -ENOMEM; - goto out; - } + if (!data_buffer) { + ret = -ENOMEM; + goto out; + } - ret = sqfs_disk_read(start, n_blks, data_buffer); - if (ret < 0) { - /* - * Possible causes: too many data blocks or too large - * SquashFS block size. Tip: re-compile the SquashFS - * image with mksquashfs's -b <block_size> option. - */ - printf("Error: too many data blocks to be read.\n"); - goto out; - } + ret = sqfs_disk_read(start, n_blks, data_buffer); + if (ret < 0) { + /* + * Possible causes: too many data blocks or too large + * SquashFS block size. Tip: re-compile the SquashFS + * image with mksquashfs's -b <block_size> option. + */ + printf("Error: too many data blocks to be read.\n"); + goto out; + } - data = data_buffer + table_offset; + data = data_buffer + table_offset; + } /* Load the data */ - if (SQFS_COMPRESSED_BLOCK(finfo.blk_sizes[j])) { + if (finfo.blk_sizes[j] == 0) { + /* This is a sparse block */ + sparse_size = get_unaligned_le32(&sblk->block_size); + if ((*actread + sparse_size) > len) + sparse_size = len - *actread; + memset(buf + *actread, 0, sparse_size); + *actread += sparse_size; + } else if (SQFS_COMPRESSED_BLOCK(finfo.blk_sizes[j])) { dest_len = get_unaligned_le32(&sblk->block_size); ret = sqfs_decompress(&ctxt, datablock, &dest_len, data, table_size); @@ -1484,7 +1499,8 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, } data_offset += table_size; - free(data_buffer); + if (data_buffer) + free(data_buffer); data_buffer = NULL; if (*actread >= len) break; diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index eb14b89544..9962cbe7eb 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c @@ -114,7 +114,7 @@ int ubifs_leb_read(const struct ubifs_info *c, int lnum, void *buf, int offs, int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs, int len) { - int err; + int err = 0; ubifs_assert(!c->ro_media && !c->ro_mount); if (c->ro_error) @@ -136,7 +136,7 @@ int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs, int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len) { - int err; + int err = 0; ubifs_assert(!c->ro_media && !c->ro_mount); if (c->ro_error) @@ -158,7 +158,7 @@ int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len) int ubifs_leb_unmap(struct ubifs_info *c, int lnum) { - int err; + int err = 0; ubifs_assert(!c->ro_media && !c->ro_mount); if (c->ro_error) @@ -179,7 +179,7 @@ int ubifs_leb_unmap(struct ubifs_info *c, int lnum) int ubifs_leb_map(struct ubifs_info *c, int lnum) { - int err; + int err = 0; ubifs_assert(!c->ro_media && !c->ro_mount); if (c->ro_error) |