block.c revision c096b845d6afd4fc37962017b4b4fe5a69c2e71f
13cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher/* 23cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher * Squashfs - a compressed read only filesystem for Linux 33cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher * 43cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 53cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher * Phillip Lougher <phillip@lougher.demon.co.uk> 63cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher * 73cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher * This program is free software; you can redistribute it and/or 83cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher * modify it under the terms of the GNU General Public License 93cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher * as published by the Free Software Foundation; either version 2, 103cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher * or (at your option) any later version. 113cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher * 123cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher * This program is distributed in the hope that it will be useful, 133cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher * but WITHOUT ANY WARRANTY; without even the implied warranty of 143cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 153cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher * GNU General Public License for more details. 163cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher * 173cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher * You should have received a copy of the GNU General Public License 183cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher * along with this program; if not, write to the Free Software 19a3e28ecaf227d2c03ec6724dd718e3c5a12b74efplougher * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 203cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher * 213cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher * block.c 223cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher */ 233cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 246b2e1d3ff7826ec13a8d81d240b3fb74b8b56cb8plougher/* 256b2e1d3ff7826ec13a8d81d240b3fb74b8b56cb8plougher * This file implements the low-level routines to read and decompress 266b2e1d3ff7826ec13a8d81d240b3fb74b8b56cb8plougher * datablocks and metadata blocks. 276b2e1d3ff7826ec13a8d81d240b3fb74b8b56cb8plougher */ 286b2e1d3ff7826ec13a8d81d240b3fb74b8b56cb8plougher 29c6893b04297e3a4c3eaaf4560563cfe87e9a6b56plougher#include <linux/fs.h> 30c6893b04297e3a4c3eaaf4560563cfe87e9a6b56plougher#include <linux/vfs.h> 31c6893b04297e3a4c3eaaf4560563cfe87e9a6b56plougher#include <linux/slab.h> 32c6893b04297e3a4c3eaaf4560563cfe87e9a6b56plougher#include <linux/mutex.h> 33c6893b04297e3a4c3eaaf4560563cfe87e9a6b56plougher#include <linux/string.h> 34e10248a420914a7c6092fc02b803cf3dac5b432dplougher#include <linux/buffer_head.h> 35c6893b04297e3a4c3eaaf4560563cfe87e9a6b56plougher#include <linux/zlib.h> 363cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 37a70c1cc4b995d559bcbdf2d3dda88c5bd1292c32plougher#include "squashfs_fs.h" 38a70c1cc4b995d559bcbdf2d3dda88c5bd1292c32plougher#include "squashfs_fs_sb.h" 39a70c1cc4b995d559bcbdf2d3dda88c5bd1292c32plougher#include "squashfs_fs_i.h" 403cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher#include "squashfs.h" 41e10248a420914a7c6092fc02b803cf3dac5b432dplougher 426b2e1d3ff7826ec13a8d81d240b3fb74b8b56cb8plougher/* 436b2e1d3ff7826ec13a8d81d240b3fb74b8b56cb8plougher * Read the metadata block length, this is stored in the first two 446b2e1d3ff7826ec13a8d81d240b3fb74b8b56cb8plougher * bytes of the metadata block. 456b2e1d3ff7826ec13a8d81d240b3fb74b8b56cb8plougher */ 4620f8a7574a788df551d0c4025a08d2bc09ab627aplougherstatic struct buffer_head *get_block_length(struct super_block *sb, 47532f06823c68342cf869a8a0999ef6c105a4555aplougher long long *cur_index, int *offset, int *length) 483cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher{ 4920f8a7574a788df551d0c4025a08d2bc09ab627aplougher struct squashfs_sb_info *msblk = sb->s_fs_info; 503cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher struct buffer_head *bh; 513cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 5220f8a7574a788df551d0c4025a08d2bc09ab627aplougher bh = sb_bread(sb, *cur_index); 5356d24bf18e169cc9de1499e63a99809b8fed08fbplougher if (bh == NULL) 54171e3df917d22af3d8e5caff56c3665f626d96f4plougher return NULL; 553cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 563cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher if (msblk->devblksize - *offset == 1) { 57f6e22234d60d71a19b598a257de6355ffa1e999eplougher *length = (unsigned char) bh->b_data[*offset]; 58c096b845d6afd4fc37962017b4b4fe5a69c2e71fplougher put_bh(bh); 5920f8a7574a788df551d0c4025a08d2bc09ab627aplougher bh = sb_bread(sb, ++(*cur_index)); 6056d24bf18e169cc9de1499e63a99809b8fed08fbplougher if (bh == NULL) 61171e3df917d22af3d8e5caff56c3665f626d96f4plougher return NULL; 62f6e22234d60d71a19b598a257de6355ffa1e999eplougher *length |= (unsigned char) bh->b_data[0] << 8; 633cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher *offset = 1; 643cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher } else { 65f6e22234d60d71a19b598a257de6355ffa1e999eplougher *length = (unsigned char) bh->b_data[*offset] | 66f6e22234d60d71a19b598a257de6355ffa1e999eplougher (unsigned char) bh->b_data[*offset + 1] << 8; 673cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher *offset += 2; 683cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher } 693cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 70f6e22234d60d71a19b598a257de6355ffa1e999eplougher return bh; 713cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher} 723cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 733cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 746b2e1d3ff7826ec13a8d81d240b3fb74b8b56cb8plougher/* 756b2e1d3ff7826ec13a8d81d240b3fb74b8b56cb8plougher * Read and decompress a metadata block or datablock. Length is non-zero 766b2e1d3ff7826ec13a8d81d240b3fb74b8b56cb8plougher * if a datablock is being read (the size is stored elsewhere in the 776b2e1d3ff7826ec13a8d81d240b3fb74b8b56cb8plougher * filesystem), otherwise the length is obtained from the first two bytes of 786b2e1d3ff7826ec13a8d81d240b3fb74b8b56cb8plougher * the metadata block. A bit in the length field indicates if the block 796b2e1d3ff7826ec13a8d81d240b3fb74b8b56cb8plougher * is stored uncompressed in the filesystem (usually because compression 806b2e1d3ff7826ec13a8d81d240b3fb74b8b56cb8plougher * generated a larger block - this does occasionally happen with zlib). 816b2e1d3ff7826ec13a8d81d240b3fb74b8b56cb8plougher */ 829798f1e43e2fbc8f288a5dc901377f07cec054c1plougherint squashfs_read_data(struct super_block *sb, void **buffer, long long index, 839798f1e43e2fbc8f288a5dc901377f07cec054c1plougher int length, long long *next_index, int srclength) 843cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher{ 8520f8a7574a788df551d0c4025a08d2bc09ab627aplougher struct squashfs_sb_info *msblk = sb->s_fs_info; 863cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher struct buffer_head **bh; 87532f06823c68342cf869a8a0999ef6c105a4555aplougher int offset = index & ((1 << msblk->devblksize_log2) - 1); 88532f06823c68342cf869a8a0999ef6c105a4555aplougher long long cur_index = index >> msblk->devblksize_log2; 899798f1e43e2fbc8f288a5dc901377f07cec054c1plougher int bytes, compressed, b = 0, k = 0, page = 0, avail; 909798f1e43e2fbc8f288a5dc901377f07cec054c1plougher 913cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 923405d617eb69745519a80952f1fe3e8ff0fa0541plougher bh = kcalloc((msblk->block_size >> msblk->devblksize_log2) + 1, 933405d617eb69745519a80952f1fe3e8ff0fa0541plougher sizeof(*bh), GFP_KERNEL); 94171e3df917d22af3d8e5caff56c3665f626d96f4plougher if (bh == NULL) 95171e3df917d22af3d8e5caff56c3665f626d96f4plougher return -ENOMEM; 963cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 979798f1e43e2fbc8f288a5dc901377f07cec054c1plougher if (length) { 98824cff29fd798cbd6cbfa18d93751c51ceabbd7fplougher /* 9907e0310c61c277c87523afcf136e028524e24686plougher * Datablock. 10007e0310c61c277c87523afcf136e028524e24686plougher */ 1013cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher bytes = -offset; 1029798f1e43e2fbc8f288a5dc901377f07cec054c1plougher compressed = SQUASHFS_COMPRESSED_BLOCK(length); 1039798f1e43e2fbc8f288a5dc901377f07cec054c1plougher length = SQUASHFS_COMPRESSED_SIZE_BLOCK(length); 1049798f1e43e2fbc8f288a5dc901377f07cec054c1plougher if (next_index) 1059798f1e43e2fbc8f288a5dc901377f07cec054c1plougher *next_index = index + length; 1063cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 10756d24bf18e169cc9de1499e63a99809b8fed08fbplougher TRACE("Block @ 0x%llx, %scompressed size %d, src size %d\n", 1089798f1e43e2fbc8f288a5dc901377f07cec054c1plougher index, compressed ? "" : "un", length, srclength); 1093cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 1109798f1e43e2fbc8f288a5dc901377f07cec054c1plougher if (length < 0 || length > srclength || index < 0 || 1119798f1e43e2fbc8f288a5dc901377f07cec054c1plougher (index + length) > msblk->bytes_used) 1123cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher goto read_failure; 1133cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 1149798f1e43e2fbc8f288a5dc901377f07cec054c1plougher for (b = 0; bytes < length; b++, cur_index++) { 11520f8a7574a788df551d0c4025a08d2bc09ab627aplougher bh[b] = sb_getblk(sb, cur_index); 1163cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher if (bh[b] == NULL) 1173cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher goto block_release; 1183cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher bytes += msblk->devblksize; 1193cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher } 1203cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher ll_rw_block(READ, b, bh); 1213cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher } else { 122824cff29fd798cbd6cbfa18d93751c51ceabbd7fplougher /* 123824cff29fd798cbd6cbfa18d93751c51ceabbd7fplougher * Metadata block. 124824cff29fd798cbd6cbfa18d93751c51ceabbd7fplougher */ 125b000fa80a6a742b279c61398287698f837cbb14aplougher if (index < 0 || (index + 2) > msblk->bytes_used) 1263cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher goto read_failure; 1273cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 1289798f1e43e2fbc8f288a5dc901377f07cec054c1plougher bh[0] = get_block_length(sb, &cur_index, &offset, &length); 1293cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher if (bh[0] == NULL) 1303cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher goto read_failure; 1313cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher b = 1; 1323cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 1333cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher bytes = msblk->devblksize - offset; 1349798f1e43e2fbc8f288a5dc901377f07cec054c1plougher compressed = SQUASHFS_COMPRESSED(length); 1359798f1e43e2fbc8f288a5dc901377f07cec054c1plougher length = SQUASHFS_COMPRESSED_SIZE(length); 1369798f1e43e2fbc8f288a5dc901377f07cec054c1plougher if (next_index) 1379798f1e43e2fbc8f288a5dc901377f07cec054c1plougher *next_index = index + length + 2; 1383cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 13956d24bf18e169cc9de1499e63a99809b8fed08fbplougher TRACE("Block @ 0x%llx, %scompressed size %d\n", index, 1409798f1e43e2fbc8f288a5dc901377f07cec054c1plougher compressed ? "" : "un", length); 1413cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 1429798f1e43e2fbc8f288a5dc901377f07cec054c1plougher if (length < 0 || length > srclength || 1439798f1e43e2fbc8f288a5dc901377f07cec054c1plougher (index + length) > msblk->bytes_used) 1443cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher goto block_release; 1453cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 1469798f1e43e2fbc8f288a5dc901377f07cec054c1plougher for (; bytes < length; b++) { 14720f8a7574a788df551d0c4025a08d2bc09ab627aplougher bh[b] = sb_getblk(sb, ++cur_index); 1483cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher if (bh[b] == NULL) 1493cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher goto block_release; 1503cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher bytes += msblk->devblksize; 1513cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher } 1523cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher ll_rw_block(READ, b - 1, bh + 1); 1533cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher } 1543cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 1553cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher if (compressed) { 1569798f1e43e2fbc8f288a5dc901377f07cec054c1plougher int zlib_err = 0, zlib_init = 0; 1573cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 1583cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher /* 159824cff29fd798cbd6cbfa18d93751c51ceabbd7fplougher * Uncompress block. 16056d24bf18e169cc9de1499e63a99809b8fed08fbplougher */ 1613cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 1623cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher mutex_lock(&msblk->read_data_mutex); 1633cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 1649798f1e43e2fbc8f288a5dc901377f07cec054c1plougher msblk->stream.avail_out = 0; 1659798f1e43e2fbc8f288a5dc901377f07cec054c1plougher msblk->stream.avail_in = 0; 1663cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 1679798f1e43e2fbc8f288a5dc901377f07cec054c1plougher bytes = length; 1689798f1e43e2fbc8f288a5dc901377f07cec054c1plougher do { 1699798f1e43e2fbc8f288a5dc901377f07cec054c1plougher if (msblk->stream.avail_in == 0 && k < b) { 1709798f1e43e2fbc8f288a5dc901377f07cec054c1plougher avail = min(bytes, msblk->devblksize - offset); 1719798f1e43e2fbc8f288a5dc901377f07cec054c1plougher bytes -= avail; 1729798f1e43e2fbc8f288a5dc901377f07cec054c1plougher wait_on_buffer(bh[k]); 1739798f1e43e2fbc8f288a5dc901377f07cec054c1plougher if (!buffer_uptodate(bh[k])) 1749798f1e43e2fbc8f288a5dc901377f07cec054c1plougher goto release_mutex; 1759798f1e43e2fbc8f288a5dc901377f07cec054c1plougher 1769798f1e43e2fbc8f288a5dc901377f07cec054c1plougher if (avail == 0) { 1779798f1e43e2fbc8f288a5dc901377f07cec054c1plougher offset = 0; 178c096b845d6afd4fc37962017b4b4fe5a69c2e71fplougher put_bh(bh[k++]); 1799798f1e43e2fbc8f288a5dc901377f07cec054c1plougher continue; 1809798f1e43e2fbc8f288a5dc901377f07cec054c1plougher } 1813cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 1829798f1e43e2fbc8f288a5dc901377f07cec054c1plougher msblk->stream.next_in = bh[k]->b_data + offset; 1839798f1e43e2fbc8f288a5dc901377f07cec054c1plougher msblk->stream.avail_in = avail; 1849798f1e43e2fbc8f288a5dc901377f07cec054c1plougher offset = 0; 1859798f1e43e2fbc8f288a5dc901377f07cec054c1plougher } 1863cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 1879798f1e43e2fbc8f288a5dc901377f07cec054c1plougher if (msblk->stream.avail_out == 0) { 1889798f1e43e2fbc8f288a5dc901377f07cec054c1plougher msblk->stream.next_out = buffer[page ++]; 1899798f1e43e2fbc8f288a5dc901377f07cec054c1plougher msblk->stream.avail_out = PAGE_CACHE_SIZE; 1909798f1e43e2fbc8f288a5dc901377f07cec054c1plougher } 1913cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 1929798f1e43e2fbc8f288a5dc901377f07cec054c1plougher if (!zlib_init) { 1933cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher zlib_err = zlib_inflateInit(&msblk->stream); 1943cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher if (zlib_err != Z_OK) { 19556d24bf18e169cc9de1499e63a99809b8fed08fbplougher ERROR("zlib_inflateInit returned" 19656d24bf18e169cc9de1499e63a99809b8fed08fbplougher " unexpected result 0x%x," 19756d24bf18e169cc9de1499e63a99809b8fed08fbplougher " srclength %d\n", zlib_err, 19856d24bf18e169cc9de1499e63a99809b8fed08fbplougher srclength); 1993cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher goto release_mutex; 2009798f1e43e2fbc8f288a5dc901377f07cec054c1plougher } 2019798f1e43e2fbc8f288a5dc901377f07cec054c1plougher zlib_init = 1; 2023cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher } 2033cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 2043cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher zlib_err = zlib_inflate(&msblk->stream, Z_NO_FLUSH); 2053cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 2069798f1e43e2fbc8f288a5dc901377f07cec054c1plougher if (msblk->stream.avail_in == 0 && k < b) 207c096b845d6afd4fc37962017b4b4fe5a69c2e71fplougher put_bh(bh[k++]); 2089798f1e43e2fbc8f288a5dc901377f07cec054c1plougher } while (zlib_err == Z_OK); 2093cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 2109798f1e43e2fbc8f288a5dc901377f07cec054c1plougher if (zlib_err != Z_STREAM_END) { 2119798f1e43e2fbc8f288a5dc901377f07cec054c1plougher ERROR("zlib_inflate returned unexpected result" 2129798f1e43e2fbc8f288a5dc901377f07cec054c1plougher " 0x%x, srclength %d, avail_in %d," 2139798f1e43e2fbc8f288a5dc901377f07cec054c1plougher " avail_out %d\n", zlib_err, srclength, 2149798f1e43e2fbc8f288a5dc901377f07cec054c1plougher msblk->stream.avail_in, 2159798f1e43e2fbc8f288a5dc901377f07cec054c1plougher msblk->stream.avail_out); 2163cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher goto release_mutex; 2179798f1e43e2fbc8f288a5dc901377f07cec054c1plougher } 2183cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 2193cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher zlib_err = zlib_inflateEnd(&msblk->stream); 2203cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher if (zlib_err != Z_OK) { 2213cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher ERROR("zlib_inflateEnd returned unexpected result 0x%x," 2223cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher " srclength %d\n", zlib_err, srclength); 2233cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher goto release_mutex; 2243cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher } 2259798f1e43e2fbc8f288a5dc901377f07cec054c1plougher length = msblk->stream.total_out; 2263cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher mutex_unlock(&msblk->read_data_mutex); 2273cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher } else { 228824cff29fd798cbd6cbfa18d93751c51ceabbd7fplougher /* 229824cff29fd798cbd6cbfa18d93751c51ceabbd7fplougher * Block is uncompressed. 230824cff29fd798cbd6cbfa18d93751c51ceabbd7fplougher */ 2319798f1e43e2fbc8f288a5dc901377f07cec054c1plougher int i, in, pg_offset = 0; 2323cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 23356d24bf18e169cc9de1499e63a99809b8fed08fbplougher for (i = 0; i < b; i++) { 2343cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher wait_on_buffer(bh[i]); 2353cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher if (!buffer_uptodate(bh[i])) 2363cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher goto block_release; 2373cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher } 2383cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 2399798f1e43e2fbc8f288a5dc901377f07cec054c1plougher for (bytes = length; k < b; k++) { 2409798f1e43e2fbc8f288a5dc901377f07cec054c1plougher in = min(bytes, msblk->devblksize - offset); 2419798f1e43e2fbc8f288a5dc901377f07cec054c1plougher bytes -= in; 2429798f1e43e2fbc8f288a5dc901377f07cec054c1plougher while (in) { 2439798f1e43e2fbc8f288a5dc901377f07cec054c1plougher if (pg_offset == PAGE_CACHE_SIZE) { 2449798f1e43e2fbc8f288a5dc901377f07cec054c1plougher page ++; 2459798f1e43e2fbc8f288a5dc901377f07cec054c1plougher pg_offset = 0; 2469798f1e43e2fbc8f288a5dc901377f07cec054c1plougher } 2479798f1e43e2fbc8f288a5dc901377f07cec054c1plougher avail = min_t(int, in, PAGE_CACHE_SIZE - pg_offset); 2489798f1e43e2fbc8f288a5dc901377f07cec054c1plougher memcpy(buffer[page] + pg_offset, bh[k]->b_data + offset, avail); 2499798f1e43e2fbc8f288a5dc901377f07cec054c1plougher in -= avail; 2509798f1e43e2fbc8f288a5dc901377f07cec054c1plougher pg_offset += avail; 2519798f1e43e2fbc8f288a5dc901377f07cec054c1plougher offset += avail; 2529798f1e43e2fbc8f288a5dc901377f07cec054c1plougher } 2533cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher offset = 0; 254c096b845d6afd4fc37962017b4b4fe5a69c2e71fplougher put_bh(bh[k]); 2553cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher } 2563cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher } 2573cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 2583cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher kfree(bh); 2599798f1e43e2fbc8f288a5dc901377f07cec054c1plougher return length; 2603cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 2613cb299277b04dfdb6fe21768b8f83dec1f4014b6plougherrelease_mutex: 2623cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher mutex_unlock(&msblk->read_data_mutex); 2633cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 2643cb299277b04dfdb6fe21768b8f83dec1f4014b6plougherblock_release: 2653cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher for (; k < b; k++) 266c096b845d6afd4fc37962017b4b4fe5a69c2e71fplougher put_bh(bh[k]); 2673cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher 2683cb299277b04dfdb6fe21768b8f83dec1f4014b6plougherread_failure: 269532f06823c68342cf869a8a0999ef6c105a4555aplougher ERROR("sb_bread failed reading block 0x%llx\n", cur_index); 2703cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher kfree(bh); 271171e3df917d22af3d8e5caff56c3665f626d96f4plougher return -EIO; 2723cb299277b04dfdb6fe21768b8f83dec1f4014b6plougher} 273