⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 001-squashfs.patch

📁 Linux Home Server 是专门为家庭和SOHO/SMB 设计的高性价比的ISCSI 存储服务器, 具有如下的特色: 强大的iscsi 存储服务器软件; 混合iscsi 和NAS 服务;
💻 PATCH
📖 第 1 页 / 共 5 页
字号:
+			ERROR("Failed to allocate meta_index\n");+			goto failed;+		}+		for(i = 0; i < SQUASHFS_META_NUMBER; i++) {+			msblk->meta_index[i].inode_number = 0;+			msblk->meta_index[i].locked = 0;+		}+		msblk->next_meta_index = 0;+	}++	for(i = SQUASHFS_META_NUMBER; i &&+			msblk->meta_index[msblk->next_meta_index].locked; i --)+		msblk->next_meta_index = (msblk->next_meta_index + 1) %+			SQUASHFS_META_NUMBER;++	if(i == 0) {+		TRACE("empty_meta_index: failed!\n");+		goto failed;+	}++	TRACE("empty_meta_index: returned meta entry %d, %p\n",+			msblk->next_meta_index,+			&msblk->meta_index[msblk->next_meta_index]);++	meta = &msblk->meta_index[msblk->next_meta_index];+	msblk->next_meta_index = (msblk->next_meta_index + 1) %+			SQUASHFS_META_NUMBER;++	meta->inode_number = inode->i_ino;+	meta->offset = offset;+	meta->skip = skip;+	meta->entries = 0;+	meta->locked = 1;++failed:+	up(&msblk->meta_index_mutex);+	return meta;+}+++void release_meta_index(struct inode *inode, struct meta_index *meta)+{+	meta->locked = 0;+}+++static int read_block_index(struct super_block *s, int blocks, char *block_list,+		long long *start_block, int *offset)+{+	struct squashfs_sb_info *msblk = s->s_fs_info;+	unsigned int *block_listp;+	int block = 0;++	if (msblk->swap) {+		char sblock_list[blocks << 2];++		if (!squashfs_get_cached_block(s, sblock_list, *start_block,+				*offset, blocks << 2, start_block, offset)) {+			ERROR("Unable to read block list [%llx:%x]\n",+				*start_block, *offset);+			goto failure;+		}+		SQUASHFS_SWAP_INTS(((unsigned int *)block_list),+				((unsigned int *)sblock_list), blocks);+	} else+		if (!squashfs_get_cached_block(s, block_list, *start_block,+				*offset, blocks << 2, start_block, offset)) {+			ERROR("Unable to read block list [%llx:%x]\n",+				*start_block, *offset);+			goto failure;+		}++	for (block_listp = (unsigned int *) block_list; blocks;+				block_listp++, blocks --)+		block += SQUASHFS_COMPRESSED_SIZE_BLOCK(*block_listp);++	return block;++failure:+	return -1;+}+++#define SIZE 256++static inline int calculate_skip(int blocks) {+	int skip = (blocks - 1) / ((SQUASHFS_SLOTS * SQUASHFS_META_ENTRIES + 1) * SQUASHFS_META_INDEXES);+	return skip >= 7 ? 7 : skip + 1;+}+++static int get_meta_index(struct inode *inode, int index,+		long long *index_block, int *index_offset,+		long long *data_block, char *block_list)+{+	struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;+	struct squashfs_super_block *sblk = &msblk->sblk;+	int skip = calculate_skip(i_size_read(inode) >> sblk->block_log);+	int offset = 0;+	struct meta_index *meta;+	struct meta_entry *meta_entry;+	long long cur_index_block = SQUASHFS_I(inode)->u.s1.block_list_start;+	int cur_offset = SQUASHFS_I(inode)->offset;+	long long cur_data_block = SQUASHFS_I(inode)->start_block;+	int i;++	index /= SQUASHFS_META_INDEXES * skip;++	while ( offset < index ) {+		meta = locate_meta_index(inode, index, offset + 1);++		if (meta == NULL) {+			if ((meta = empty_meta_index(inode, offset + 1,+							skip)) == NULL)+				goto all_done;+		} else {+			offset = index < meta->offset + meta->entries ? index :+				meta->offset + meta->entries - 1;+			meta_entry = &meta->meta_entry[offset - meta->offset];+			cur_index_block = meta_entry->index_block + sblk->inode_table_start;+			cur_offset = meta_entry->offset;+			cur_data_block = meta_entry->data_block;+			TRACE("get_meta_index: offset %d, meta->offset %d, "+				"meta->entries %d\n", offset, meta->offset,+				meta->entries);+			TRACE("get_meta_index: index_block 0x%llx, offset 0x%x"+				" data_block 0x%llx\n", cur_index_block,+				cur_offset, cur_data_block);+		}++		for (i = meta->offset + meta->entries; i <= index &&+				i < meta->offset + SQUASHFS_META_ENTRIES; i++) {+			int blocks = skip * SQUASHFS_META_INDEXES;++			while (blocks) {+				int block = blocks > (SIZE >> 2) ? (SIZE >> 2) :+					blocks;+				int res = read_block_index(inode->i_sb, block,+					block_list, &cur_index_block,+					&cur_offset);++				if (res == -1)+					goto failed;++				cur_data_block += res;+				blocks -= block;+			}++			meta_entry = &meta->meta_entry[i - meta->offset];+			meta_entry->index_block = cur_index_block - sblk->inode_table_start;+			meta_entry->offset = cur_offset;+			meta_entry->data_block = cur_data_block;+			meta->entries ++;+			offset ++;+		}++		TRACE("get_meta_index: meta->offset %d, meta->entries %d\n",+				meta->offset, meta->entries);++		release_meta_index(inode, meta);+	}++all_done:+	*index_block = cur_index_block;+	*index_offset = cur_offset;+	*data_block = cur_data_block;++	return offset * SQUASHFS_META_INDEXES * skip;++failed:+	release_meta_index(inode, meta);+	return -1;+}+++static long long read_blocklist(struct inode *inode, int index,+				int readahead_blks, char *block_list,+				unsigned short **block_p, unsigned int *bsize)+{+	long long block_ptr;+	int offset;+	long long block;+	int res = get_meta_index(inode, index, &block_ptr, &offset, &block,+		block_list);++	TRACE("read_blocklist: res %d, index %d, block_ptr 0x%llx, offset"+		       " 0x%x, block 0x%llx\n", res, index, block_ptr, offset,+		       block);++	if(res == -1)+		goto failure;++	index -= res;++	while ( index ) {+		int blocks = index > (SIZE >> 2) ? (SIZE >> 2) : index;+		int res = read_block_index(inode->i_sb, blocks, block_list,+			&block_ptr, &offset);+		if (res == -1)+			goto failure;+		block += res;+		index -= blocks;+	}++	if (read_block_index(inode->i_sb, 1, block_list,+			&block_ptr, &offset) == -1)+		goto failure;+	*bsize = *((unsigned int *) block_list);++	return block;++failure:+	return 0;+}+++static int squashfs_readpage(struct file *file, struct page *page)+{+	struct inode *inode = page->mapping->host;+	struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;+	struct squashfs_super_block *sblk = &msblk->sblk;+	unsigned char block_list[SIZE];+	long long block;+	unsigned int bsize, i = 0, bytes = 0, byte_offset = 0;+	int index = page->index >> (sblk->block_log - PAGE_CACHE_SHIFT);+ 	void *pageaddr;+	struct squashfs_fragment_cache *fragment = NULL;+	char *data_ptr = msblk->read_page;++	int mask = (1 << (sblk->block_log - PAGE_CACHE_SHIFT)) - 1;+	int start_index = page->index & ~mask;+	int end_index = start_index | mask;++	TRACE("Entered squashfs_readpage, page index %lx, start block %llx\n",+					page->index,+					SQUASHFS_I(inode)->start_block);++	if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>+					PAGE_CACHE_SHIFT))+		goto skip_read;++	if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK+					|| index < (i_size_read(inode) >>+					sblk->block_log)) {+		if ((block = (msblk->read_blocklist)(inode, index, 1,+					block_list, NULL, &bsize)) == 0)+			goto skip_read;++		down(&msblk->read_page_mutex);++		if (!(bytes = squashfs_read_data(inode->i_sb, msblk->read_page,+					block, bsize, NULL))) {+			ERROR("Unable to read page, block %llx, size %x\n", block,+					bsize);+			up(&msblk->read_page_mutex);+			goto skip_read;+		}+	} else {+		if ((fragment = get_cached_fragment(inode->i_sb,+					SQUASHFS_I(inode)->+					u.s1.fragment_start_block,+					SQUASHFS_I(inode)->u.s1.fragment_size))+					== NULL) {+			ERROR("Unable to read page, block %llx, size %x\n",+					SQUASHFS_I(inode)->+					u.s1.fragment_start_block,+					(int) SQUASHFS_I(inode)->+					u.s1.fragment_size);+			goto skip_read;+		}+		bytes = SQUASHFS_I(inode)->u.s1.fragment_offset ++					(i_size_read(inode) & (sblk->block_size+					- 1));+		byte_offset = SQUASHFS_I(inode)->u.s1.fragment_offset;+		data_ptr = fragment->data;+	}++	for (i = start_index; i <= end_index && byte_offset < bytes;+					i++, byte_offset += PAGE_CACHE_SIZE) {+		struct page *push_page;+		int available_bytes = (bytes - byte_offset) > PAGE_CACHE_SIZE ?+					PAGE_CACHE_SIZE : bytes - byte_offset;++		TRACE("bytes %d, i %d, byte_offset %d, available_bytes %d\n",+					bytes, i, byte_offset, available_bytes);++		if (i == page->index)  {+			pageaddr = kmap_atomic(page, KM_USER0);+			memcpy(pageaddr, data_ptr + byte_offset,+					available_bytes);+			memset(pageaddr + available_bytes, 0,+					PAGE_CACHE_SIZE - available_bytes);+			kunmap_atomic(pageaddr, KM_USER0);+			flush_dcache_page(page);+			SetPageUptodate(page);+			unlock_page(page);+		} else if ((push_page =+				grab_cache_page_nowait(page->mapping, i))) {+ 			pageaddr = kmap_atomic(push_page, KM_USER0);++			memcpy(pageaddr, data_ptr + byte_offset,+					available_bytes);+			memset(pageaddr + available_bytes, 0,+					PAGE_CACHE_SIZE - available_bytes);+			kunmap_atomic(pageaddr, KM_USER0);+			flush_dcache_page(push_page);+			SetPageUptodate(push_page);+			unlock_page(push_page);+			page_cache_release(push_page);+		}+	}++	if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK+					|| index < (i_size_read(inode) >>+					sblk->block_log))+		up(&msblk->read_page_mutex);+	else+		release_cached_fragment(msblk, fragment);++	return 0;++skip_read:+	pageaddr = kmap_atomic(page, KM_USER0);+	memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);+	kunmap_atomic(pageaddr, KM_USER0);+	flush_dcache_page(page);+	SetPageUptodate(page);+	unlock_page(page);++	return 0;+}+++static int squashfs_readpage4K(struct file *file, struct page *page)+{+	struct inode *inode = page->mapping->host;+	struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;+	struct squashfs_super_block *sblk = &msblk->sblk;+	unsigned char block_list[SIZE];+	long long block;+	unsigned int bsize, bytes = 0;+ 	void *pageaddr;++	TRACE("Entered squashfs_readpage4K, page index %lx, start block %llx\n",+					page->index,+					SQUASHFS_I(inode)->start_block);++	if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>+					PAGE_CACHE_SHIFT)) {+		pageaddr = kmap_atomic(page, KM_USER0);+		goto skip_read;+	}++	if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK+					|| page->index < (i_size_read(inode) >>+					sblk->block_log)) {+		block = (msblk->read_blocklist)(inode, page->index, 1,+					block_list, NULL, &bsize);++		down(&msblk->read_page_mutex);+		bytes = squashfs_read_data(inode->i_sb, msblk->read_page, block,+					bsize, NULL);+		pageaddr = kmap_atomic(page, KM_USER0);+		if (bytes)+			memcpy(pageaddr, msblk->read_page, bytes);+		else+			ERROR("Unable to read page, block %llx, size %x\n",+					block, bsize);+		up(&msblk->read_page_mutex);+	} else {+		struct squashfs_fragment_cache *fragment =+			get_cached_fragment(inode->i_sb,+					SQUASHFS_I(inode)->+					u.s1.fragment_start_block,+					SQUASHFS_I(inode)-> u.s1.fragment_size);+		pageaddr = kmap_atomic(page, KM_USER0);+		if (fragment) {+			bytes = i_size_read(inode) & (sblk->block_size - 1);+			memcpy(pageaddr, fragment->data + SQUASHFS_I(inode)->+					u.s1.fragment_offset, bytes);+			release_cached_fragment(msblk, fragment);+		} else+			ERROR("Unable to read page, block %llx, size %x\n",+					SQUASHFS_I(inode)->+					u.s1.fragment_start_block, (int)+					SQUASHFS_I(inode)-> u.s1.fragment_size);+	}++skip_read:+	memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);+	kunmap_atomic(pageaddr, KM_USER0);+	flush_dcache_page(page);+	SetPageUptodate(page);+	unlock_page(page);++	return 0;+}+++static int get_dir_index_using_offset(struct super_block *s, long long+				*next_block, unsigned int *next_offset,+				long long index_start,+				unsigned int index_offset, int i_count,+				long long f_pos)+{+	struct squashfs_sb_info *msblk = s->s_fs_info;+	struct squashfs_super_block *sblk = &msblk->sblk;+	int i, length = 0;+	struct squashfs_dir_index index;++	TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n",+					i_count, (unsigned int) f_pos);++	f_pos =- 3;+	if (f_pos == 0)+		goto finish;++	for (i = 0; i < i_count; i++) {+		if (msblk->swap) {+			struct squashfs_dir_index sindex;+			squashfs_get_cached_block(s, (char *) &sindex,+					index_start, index_offset,+					sizeof(sindex), &index_start,+					&index_offset);+			SQUASHFS_SWAP_DIR_INDEX(&index, &sindex);+		} else+			squashfs_get_cached_block(s, (char *) &index,+					index_start, index_offset,+					sizeof(index), &index_start,+					&index_offset);++		if (index.index > f_pos)+			break;++		squashfs_get_cached_block(s, NULL, index_start, index_offset,+					index.size + 1, &index_start,+					&index_offset);++		length = index.index;+		*next_block = index.start_block + sblk->directory_table_start;+	}++	*next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;++finish:+	return length + 3;+}+++static int get_dir_index_using_name(struct super_block *s, long long+				*next_block, unsigned int *next_offset,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -