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

📄 001-squashfs.patch

📁 Linux Home Server 是专门为家庭和SOHO/SMB 设计的高性价比的ISCSI 存储服务器, 具有如下的特色: 强大的iscsi 存储服务器软件; 混合iscsi 和NAS 服务;
💻 PATCH
📖 第 1 页 / 共 5 页
字号:
+				if (!squashfs_get_cached_block(s, (char *)+						inodep, block, offset,+						sizeof(*inodep), &next_block,+						&next_offset))+					goto failed_read;++			if ((i = squashfs_new_inode(s, inodeb)) == NULL)+				goto failed_read1;++			i->i_nlink = inodep->nlink;+			i->i_mode |= (inodeb->inode_type ==+					SQUASHFS_CHRDEV_TYPE) ?  S_IFCHR :+					S_IFBLK;+			init_special_inode(i, i->i_mode,+					old_decode_dev(inodep->rdev));++			TRACE("Device inode %x:%x, rdev %x\n",+					SQUASHFS_INODE_BLK(inode), offset,+					inodep->rdev);+			break;+		 }+		 case SQUASHFS_FIFO_TYPE:+		 case SQUASHFS_SOCKET_TYPE: {+			struct squashfs_ipc_inode_header *inodep = &id.ipc;+			struct squashfs_ipc_inode_header *sinodep = &sid.ipc;++			if (msblk->swap) {+				if (!squashfs_get_cached_block(s, (char *)+						sinodep, block, offset,+						sizeof(*sinodep), &next_block,+						&next_offset))+					goto failed_read;+				SQUASHFS_SWAP_IPC_INODE_HEADER(inodep, sinodep);+			} else+				if (!squashfs_get_cached_block(s, (char *)+						inodep, block, offset,+						sizeof(*inodep), &next_block,+						&next_offset))+					goto failed_read;++			if ((i = squashfs_new_inode(s, inodeb)) == NULL)+				goto failed_read1;++			i->i_nlink = inodep->nlink;+			i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE)+							? S_IFIFO : S_IFSOCK;+			init_special_inode(i, i->i_mode, 0);+			break;+		 }+		 default:+			ERROR("Unknown inode type %d in squashfs_iget!\n",+					inodeb->inode_type);+			goto failed_read1;+	}++	insert_inode_hash(i);+	return i;++failed_read:+	ERROR("Unable to read inode [%llx:%x]\n", block, offset);++failed_read1:+	return NULL;+}+++static int read_fragment_index_table(struct super_block *s)+{+	struct squashfs_sb_info *msblk = s->s_fs_info;+	struct squashfs_super_block *sblk = &msblk->sblk;++	/* Allocate fragment index table */+	if (!(msblk->fragment_index = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES+					(sblk->fragments), GFP_KERNEL))) {+		ERROR("Failed to allocate uid/gid table\n");+		return 0;+	}++	if (SQUASHFS_FRAGMENT_INDEX_BYTES(sblk->fragments) &&+					!squashfs_read_data(s, (char *)+					msblk->fragment_index,+					sblk->fragment_table_start,+					SQUASHFS_FRAGMENT_INDEX_BYTES+					(sblk->fragments) |+					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {+		ERROR("unable to read fragment index table\n");+		return 0;+	}++	if (msblk->swap) {+		int i;+		long long fragment;++		for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES(sblk->fragments);+									i++) {+			SQUASHFS_SWAP_FRAGMENT_INDEXES((&fragment),+						&msblk->fragment_index[i], 1);+			msblk->fragment_index[i] = fragment;+		}+	}++	return 1;+}+++static int supported_squashfs_filesystem(struct squashfs_sb_info *msblk, int silent)+{+	struct squashfs_super_block *sblk = &msblk->sblk;++	msblk->iget = squashfs_iget;+	msblk->read_blocklist = read_blocklist;+	msblk->read_fragment_index_table = read_fragment_index_table;++	if (sblk->s_major == 1) {+		if (!squashfs_1_0_supported(msblk)) {+			SERROR("Major/Minor mismatch, Squashfs 1.0 filesystems "+				"are unsupported\n");+			SERROR("Please recompile with "+				"Squashfs 1.0 support enabled\n");+			return 0;+		}+	} else if (sblk->s_major == 2) {+		if (!squashfs_2_0_supported(msblk)) {+			SERROR("Major/Minor mismatch, Squashfs 2.0 filesystems "+				"are unsupported\n");+			SERROR("Please recompile with "+				"Squashfs 2.0 support enabled\n");+			return 0;+		}+	} else if(sblk->s_major != SQUASHFS_MAJOR || sblk->s_minor >+			SQUASHFS_MINOR) {+		SERROR("Major/Minor mismatch, trying to mount newer %d.%d "+				"filesystem\n", sblk->s_major, sblk->s_minor);+		SERROR("Please update your kernel\n");+		return 0;+	}++	return 1;+}+++static int squashfs_fill_super(struct super_block *s, void *data, int silent)+{+	struct squashfs_sb_info *msblk;+	struct squashfs_super_block *sblk;+	int i;+	char b[BDEVNAME_SIZE];+	struct inode *root;++	TRACE("Entered squashfs_read_superblock\n");++	if (!(s->s_fs_info = kmalloc(sizeof(struct squashfs_sb_info),+						GFP_KERNEL))) {+		ERROR("Failed to allocate superblock\n");+		goto failure;+	}+	memset(s->s_fs_info, 0, sizeof(struct squashfs_sb_info));+	msblk = s->s_fs_info;+	sblk = &msblk->sblk;++	msblk->devblksize = sb_min_blocksize(s, BLOCK_SIZE);+	msblk->devblksize_log2 = ffz(~msblk->devblksize);++	init_MUTEX(&msblk->read_data_mutex);+	init_MUTEX(&msblk->read_page_mutex);+	init_MUTEX(&msblk->block_cache_mutex);+	init_MUTEX(&msblk->fragment_mutex);+	init_MUTEX(&msblk->meta_index_mutex);++	init_waitqueue_head(&msblk->waitq);+	init_waitqueue_head(&msblk->fragment_wait_queue);++	if (!squashfs_read_data(s, (char *) sblk, SQUASHFS_START,+					sizeof(struct squashfs_super_block) |+					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {+		SERROR("unable to read superblock\n");+		goto failed_mount;+	}++	/* Check it is a SQUASHFS superblock */+	msblk->swap = 0;+	if ((s->s_magic = sblk->s_magic) != SQUASHFS_MAGIC) {+		if (sblk->s_magic == SQUASHFS_MAGIC_SWAP) {+			struct squashfs_super_block ssblk;++			WARNING("Mounting a different endian SQUASHFS "+				"filesystem on %s\n", bdevname(s->s_bdev, b));++			SQUASHFS_SWAP_SUPER_BLOCK(&ssblk, sblk);+			memcpy(sblk, &ssblk, sizeof(struct squashfs_super_block));+			msblk->swap = 1;+		} else  {+			SERROR("Can't find a SQUASHFS superblock on %s\n",+							bdevname(s->s_bdev, b));+			goto failed_mount;+		}+	}++	/* Check the MAJOR & MINOR versions */+	if(!supported_squashfs_filesystem(msblk, silent))+		goto failed_mount;++	TRACE("Found valid superblock on %s\n", bdevname(s->s_bdev, b));+	TRACE("Inodes are %scompressed\n",+					SQUASHFS_UNCOMPRESSED_INODES+					(sblk->flags) ? "un" : "");+	TRACE("Data is %scompressed\n",+					SQUASHFS_UNCOMPRESSED_DATA(sblk->flags)+					? "un" : "");+	TRACE("Check data is %s present in the filesystem\n",+					SQUASHFS_CHECK_DATA(sblk->flags) ?+					"" : "not");+	TRACE("Filesystem size %lld bytes\n", sblk->bytes_used);+	TRACE("Block size %d\n", sblk->block_size);+	TRACE("Number of inodes %d\n", sblk->inodes);+	if (sblk->s_major > 1)+		TRACE("Number of fragments %d\n", sblk->fragments);+	TRACE("Number of uids %d\n", sblk->no_uids);+	TRACE("Number of gids %d\n", sblk->no_guids);+	TRACE("sblk->inode_table_start %llx\n", sblk->inode_table_start);+	TRACE("sblk->directory_table_start %llx\n", sblk->directory_table_start);+	if (sblk->s_major > 1)+		TRACE("sblk->fragment_table_start %llx\n",+					sblk->fragment_table_start);+	TRACE("sblk->uid_start %llx\n", sblk->uid_start);++	s->s_flags |= MS_RDONLY;+	s->s_op = &squashfs_ops;++	/* Init inode_table block pointer array */+	if (!(msblk->block_cache = kmalloc(sizeof(struct squashfs_cache) *+					SQUASHFS_CACHED_BLKS, GFP_KERNEL))) {+		ERROR("Failed to allocate block cache\n");+		goto failed_mount;+	}++	for (i = 0; i < SQUASHFS_CACHED_BLKS; i++)+		msblk->block_cache[i].block = SQUASHFS_INVALID_BLK;++	msblk->next_cache = 0;++	/* Allocate read_data block */+	msblk->read_size = (sblk->block_size < SQUASHFS_METADATA_SIZE) ?+					SQUASHFS_METADATA_SIZE :+					sblk->block_size;++	if (!(msblk->read_data = kmalloc(msblk->read_size, GFP_KERNEL))) {+		ERROR("Failed to allocate read_data block\n");+		goto failed_mount;+	}++	/* Allocate read_page block */+	if (!(msblk->read_page = kmalloc(sblk->block_size, GFP_KERNEL))) {+		ERROR("Failed to allocate read_page block\n");+		goto failed_mount;+	}++	/* Allocate uid and gid tables */+	if (!(msblk->uid = kmalloc((sblk->no_uids + sblk->no_guids) *+					sizeof(unsigned int), GFP_KERNEL))) {+		ERROR("Failed to allocate uid/gid table\n");+		goto failed_mount;+	}+	msblk->guid = msblk->uid + sblk->no_uids;++	if (msblk->swap) {+		unsigned int suid[sblk->no_uids + sblk->no_guids];++		if (!squashfs_read_data(s, (char *) &suid, sblk->uid_start,+					((sblk->no_uids + sblk->no_guids) *+					 sizeof(unsigned int)) |+					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {+			ERROR("unable to read uid/gid table\n");+			goto failed_mount;+		}++		SQUASHFS_SWAP_DATA(msblk->uid, suid, (sblk->no_uids ++			sblk->no_guids), (sizeof(unsigned int) * 8));+	} else+		if (!squashfs_read_data(s, (char *) msblk->uid, sblk->uid_start,+					((sblk->no_uids + sblk->no_guids) *+					 sizeof(unsigned int)) |+					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {+			ERROR("unable to read uid/gid table\n");+			goto failed_mount;+		}+++	if (sblk->s_major == 1 && squashfs_1_0_supported(msblk))+		goto allocate_root;++	if (!(msblk->fragment = kmalloc(sizeof(struct squashfs_fragment_cache) *+				SQUASHFS_CACHED_FRAGMENTS, GFP_KERNEL))) {+		ERROR("Failed to allocate fragment block cache\n");+		goto failed_mount;+	}++	for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++) {+		msblk->fragment[i].locked = 0;+		msblk->fragment[i].block = SQUASHFS_INVALID_BLK;+		msblk->fragment[i].data = NULL;+	}++	msblk->next_fragment = 0;++	/* Allocate fragment index table */+	if (msblk->read_fragment_index_table(s) == 0)+		goto failed_mount;++allocate_root:+	if ((root = (msblk->iget)(s, sblk->root_inode)) == NULL)+		goto failed_mount;++	if ((s->s_root = d_alloc_root(root)) == NULL) {+		ERROR("Root inode create failed\n");+		iput(root);+		goto failed_mount;+	}++	TRACE("Leaving squashfs_read_super\n");+	return 0;++failed_mount:+	kfree(msblk->fragment_index);+	kfree(msblk->fragment);+	kfree(msblk->uid);+	kfree(msblk->read_page);+	kfree(msblk->read_data);+	kfree(msblk->block_cache);+	kfree(msblk->fragment_index_2);+	kfree(s->s_fs_info);+	s->s_fs_info = NULL;+	return -EINVAL;++failure:+	return -ENOMEM;+}+++static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf)+{+	struct squashfs_sb_info *msblk = dentry->d_inode->i_sb->s_fs_info;+	struct squashfs_super_block *sblk = &msblk->sblk;++	TRACE("Entered squashfs_statfs\n");++	buf->f_type = SQUASHFS_MAGIC;+	buf->f_bsize = sblk->block_size;+	buf->f_blocks = ((sblk->bytes_used - 1) >> sblk->block_log) + 1;+	buf->f_bfree = buf->f_bavail = 0;+	buf->f_files = sblk->inodes;+	buf->f_ffree = 0;+	buf->f_namelen = SQUASHFS_NAME_LEN;++	return 0;+}+++static int squashfs_symlink_readpage(struct file *file, struct page *page)+{+	struct inode *inode = page->mapping->host;+	int index = page->index << PAGE_CACHE_SHIFT, length, bytes;+	long long block = SQUASHFS_I(inode)->start_block;+	int offset = SQUASHFS_I(inode)->offset;+	void *pageaddr = kmap(page);++	TRACE("Entered squashfs_symlink_readpage, page index %ld, start block "+				"%llx, offset %x\n", page->index,+				SQUASHFS_I(inode)->start_block,+				SQUASHFS_I(inode)->offset);++	for (length = 0; length < index; length += bytes) {+		if (!(bytes = squashfs_get_cached_block(inode->i_sb, NULL,+				block, offset, PAGE_CACHE_SIZE, &block,+				&offset))) {+			ERROR("Unable to read symbolic link [%llx:%x]\n", block,+					offset);+			goto skip_read;+		}+	}++	if (length != index) {+		ERROR("(squashfs_symlink_readpage) length != index\n");+		bytes = 0;+		goto skip_read;+	}++	bytes = (i_size_read(inode) - length) > PAGE_CACHE_SIZE ? PAGE_CACHE_SIZE :+					i_size_read(inode) - length;++	if (!(bytes = squashfs_get_cached_block(inode->i_sb, pageaddr, block,+					offset, bytes, &block, &offset)))+		ERROR("Unable to read symbolic link [%llx:%x]\n", block, offset);++skip_read:+	memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);+	kunmap(page);+	SetPageUptodate(page);+	unlock_page(page);++	return 0;+}+++struct meta_index *locate_meta_index(struct inode *inode, int index, int offset)+{+	struct meta_index *meta = NULL;+	struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;+	int i;++	down(&msblk->meta_index_mutex);++	TRACE("locate_meta_index: index %d, offset %d\n", index, offset);++	if(msblk->meta_index == NULL)+		goto not_allocated;++	for (i = 0; i < SQUASHFS_META_NUMBER; i ++)+		if (msblk->meta_index[i].inode_number == inode->i_ino &&+				msblk->meta_index[i].offset >= offset &&+				msblk->meta_index[i].offset <= index &&+				msblk->meta_index[i].locked == 0) {+			TRACE("locate_meta_index: entry %d, offset %d\n", i,+					msblk->meta_index[i].offset);+			meta = &msblk->meta_index[i];+			offset = meta->offset;+		}++	if (meta)+		meta->locked = 1;++not_allocated:+	up(&msblk->meta_index_mutex);++	return meta;+}+++struct meta_index *empty_meta_index(struct inode *inode, int offset, int skip)+{+	struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;+	struct meta_index *meta = NULL;+	int i;++	down(&msblk->meta_index_mutex);++	TRACE("empty_meta_index: offset %d, skip %d\n", offset, skip);++	if(msblk->meta_index == NULL) {+		if (!(msblk->meta_index = kmalloc(sizeof(struct meta_index) *+					SQUASHFS_META_NUMBER, GFP_KERNEL))) {

⌨️ 快捷键说明

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