- 论坛徽章:
- 16
|
本帖最后由 embeddedlwp 于 2012-04-30 13:12 编辑
在普通文件的readpage方法中和块设备文件的readpage方法中对file hole的处理不一样,linux 2.6.12:
在ext3_readpage->mpage_readpage->do_mpage_readpage函数中:- 191 for (page_block = 0; page_block < blocks_per_page;
- 192 page_block++, block_in_file++) {
- 193 bh.b_state = 0;
- 194 if (block_in_file < last_block) {
- 195 if (get_block(inode, block_in_file, &bh, 0))
- 196 goto confused;
- 197 }
- 198
- 199 if (!buffer_mapped(&bh)) {
- 200 fully_mapped = 0;
- 201 if (first_hole == blocks_per_page)
- 202 first_hole = page_block;
- 203 continue;
- 204 }
- 205
- 206 /* some filesystems will copy data into the page during
- 207 * the get_block call, in which case we don't want to
- 208 * read it again. map_buffer_to_page copies the data
- 209 * we just collected from get_block into the page's buffers
- 210 * so readpage doesn't have to repeat the get_block call
- 211 */
- 212 if (buffer_uptodate(&bh)) {
- 213 map_buffer_to_page(page, &bh, page_block);
- 214 goto confused;
- 215 }
- 216
- 217 if (first_hole != blocks_per_page)
- 218 goto confused; /* hole -> non-hole */
- 219
- 220 /* Contiguous blocks? */
- 221 if (page_block && blocks[page_block-1] != bh.b_blocknr-1)
- 222 goto confused;
- 223 blocks[page_block] = bh.b_blocknr;
- 224 bdev = bh.b_bdev;
- 225 }
- 226
- 227 if (first_hole != blocks_per_page) {
- 228 char *kaddr = kmap_atomic(page, KM_USER0);
- 229 memset(kaddr + (first_hole << blkbits), 0,
- 230 PAGE_CACHE_SIZE - (first_hole << blkbits));
- 231 flush_dcache_page(page);
- 232 kunmap_atomic(kaddr, KM_USER0);
- 233 if (first_hole == 0) {
- 234 SetPageUptodate(page);
- 235 unlock_page(page);
- 236 goto out;
- 237 }
- 238 } else if (fully_mapped) {
- 239 SetPageMappedToDisk(page);
- 240 }
复制代码 在出现hole->non-hole的情况下,不会执行将file hole填充为0的代码。
而在块设备文件的readpage方法中,blkdev_readpage->block_read_full_page函数中:- 2092 do {
- 2093 if (buffer_uptodate(bh))
- 2094 continue;
- 2095
- 2096 if (!buffer_mapped(bh)) {
- 2097 int err = 0;
- 2098
- 2099 fully_mapped = 0;
- 2100 if (iblock < lblock) {
- 2101 err = get_block(inode, iblock, bh, 0);
- 2102 if (err)
- 2103 SetPageError(page);
- 2104 }
- 2105 if (!buffer_mapped(bh)) {
- 2106 void *kaddr = kmap_atomic(page, KM_USER0);
- 2107 memset(kaddr + i * blocksize, 0, blocksize);
- 2108 flush_dcache_page(page);
- 2109 kunmap_atomic(kaddr, KM_USER0);
- 2110 if (!err)
- 2111 set_buffer_uptodate(bh);
- 2112 continue;
- 2113 }
- 2114 /*
- 2115 * get_block() might have updated the buffer
- 2116 * synchronously
- 2117 */
- 2118 if (buffer_uptodate(bh))
- 2119 continue;
- 2120 }
- 2121 arr[nr++] = bh;
- 2122 } while (i++, iblock++, (bh = bh->b_this_page) != head);
复制代码 每遇到一个逻辑块是file hole的,都会用0填充
为什么在普通文件的readpage方法中和块设备文件的readpage方法中对file hole的处理不一样? |
|