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

📄 unix_io.c

📁 busybox最新版的源码:学习和应用的好东东,多的不说了,大家看后再说吧
💻 C
📖 第 1 页 / 共 2 页
字号:
			cache->in_use = 0;		if (!cache->dirty)			continue;		retval = raw_write_blk(channel, data,				       cache->block, 1, cache->buf);		if (retval)			retval2 = retval;		else			cache->dirty = 0;	}	return retval2;}#endif /* NO_IO_CACHE */static errcode_t unix_open(const char *name, int flags, io_channel *channel){	io_channel	io = NULL;	struct unix_private_data *data = NULL;	errcode_t	retval;	int		open_flags;	struct stat	st;#ifdef __linux__	struct		utsname ut;#endif	if (name == 0)		return EXT2_ET_BAD_DEVICE_NAME;	retval = ext2fs_get_mem(sizeof(struct struct_io_channel), &io);	if (retval)		return retval;	memset(io, 0, sizeof(struct struct_io_channel));	io->magic = EXT2_ET_MAGIC_IO_CHANNEL;	retval = ext2fs_get_mem(sizeof(struct unix_private_data), &data);	if (retval)		goto cleanup;	io->manager = unix_io_manager;	retval = ext2fs_get_mem(strlen(name)+1, &io->name);	if (retval)		goto cleanup;	strcpy(io->name, name);	io->private_data = data;	io->block_size = 1024;	io->read_error = 0;	io->write_error = 0;	io->refcount = 1;	memset(data, 0, sizeof(struct unix_private_data));	data->magic = EXT2_ET_MAGIC_UNIX_IO_CHANNEL;	if ((retval = alloc_cache(io, data)))		goto cleanup;	open_flags = (flags & IO_FLAG_RW) ? O_RDWR : O_RDONLY;#ifdef CONFIG_LFS	data->dev = open64(io->name, open_flags);#else	data->dev = open(io->name, open_flags);#endif	if (data->dev < 0) {		retval = errno;		goto cleanup;	}#ifdef __linux__#undef RLIM_INFINITY#if (defined(__alpha__) || ((defined(__sparc__) || defined(__mips__)) && (SIZEOF_LONG == 4)))#define RLIM_INFINITY	((unsigned long)(~0UL>>1))#else#define RLIM_INFINITY  (~0UL)#endif	/*	 * Work around a bug in 2.4.10-2.4.18 kernels where writes to	 * block devices are wrongly getting hit by the filesize	 * limit.  This workaround isn't perfect, since it won't work	 * if glibc wasn't built against 2.2 header files.  (Sigh.)	 *	 */	if ((flags & IO_FLAG_RW) &&	    (uname(&ut) == 0) &&	    ((ut.release[0] == '2') && (ut.release[1] == '.') &&	     (ut.release[2] == '4') && (ut.release[3] == '.') &&	     (ut.release[4] == '1') && (ut.release[5] >= '0') &&	     (ut.release[5] < '8')) &&	    (fstat(data->dev, &st) == 0) &&	    (S_ISBLK(st.st_mode))) {		struct rlimit	rlim;		rlim.rlim_cur = rlim.rlim_max = (unsigned long) RLIM_INFINITY;		setrlimit(RLIMIT_FSIZE, &rlim);		getrlimit(RLIMIT_FSIZE, &rlim);		if (((unsigned long) rlim.rlim_cur) <		    ((unsigned long) rlim.rlim_max)) {			rlim.rlim_cur = rlim.rlim_max;			setrlimit(RLIMIT_FSIZE, &rlim);		}	}#endif	*channel = io;	return 0;cleanup:	if (data) {		free_cache(data);		ext2fs_free_mem(&data);	}	ext2fs_free_mem(&io);	return retval;}static errcode_t unix_close(io_channel channel){	struct unix_private_data *data;	errcode_t	retval = 0;	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);	data = (struct unix_private_data *) channel->private_data;	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);	if (--channel->refcount > 0)		return 0;#ifndef NO_IO_CACHE	retval = flush_cached_blocks(channel, data, 0);#endif	if (close(data->dev) < 0)		retval = errno;	free_cache(data);	ext2fs_free_mem(&channel->private_data);	ext2fs_free_mem(&channel->name);	ext2fs_free_mem(&channel);	return retval;}static errcode_t unix_set_blksize(io_channel channel, int blksize){	struct unix_private_data *data;	errcode_t		retval;	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);	data = (struct unix_private_data *) channel->private_data;	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);	if (channel->block_size != blksize) {#ifndef NO_IO_CACHE		if ((retval = flush_cached_blocks(channel, data, 0)))			return retval;#endif		channel->block_size = blksize;		free_cache(data);		if ((retval = alloc_cache(channel, data)))			return retval;	}	return 0;}static errcode_t unix_read_blk(io_channel channel, unsigned long block,			       int count, void *buf){	struct unix_private_data *data;	struct unix_cache *cache, *reuse[READ_DIRECT_SIZE];	errcode_t	retval;	char		*cp;	int		i, j;	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);	data = (struct unix_private_data *) channel->private_data;	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);#ifdef NO_IO_CACHE	return raw_read_blk(channel, data, block, count, buf);#else	/*	 * If we're doing an odd-sized read or a very large read,	 * flush out the cache and then do a direct read.	 */	if (count < 0 || count > WRITE_DIRECT_SIZE) {		if ((retval = flush_cached_blocks(channel, data, 0)))			return retval;		return raw_read_blk(channel, data, block, count, buf);	}	cp = buf;	while (count > 0) {		/* If it's in the cache, use it! */		if ((cache = find_cached_block(data, block, &reuse[0]))) {#ifdef DEBUG			printf("Using cached block %d\n", block);#endif			memcpy(cp, cache->buf, channel->block_size);			count--;			block++;			cp += channel->block_size;			continue;		}		/*		 * Find the number of uncached blocks so we can do a		 * single read request		 */		for (i=1; i < count; i++)			if (find_cached_block(data, block+i, &reuse[i]))				break;#ifdef DEBUG		printf("Reading %d blocks starting at %d\n", i, block);#endif		if ((retval = raw_read_blk(channel, data, block, i, cp)))			return retval;		/* Save the results in the cache */		for (j=0; j < i; j++) {			count--;			cache = reuse[j];			reuse_cache(channel, data, cache, block++);			memcpy(cache->buf, cp, channel->block_size);			cp += channel->block_size;		}	}	return 0;#endif /* NO_IO_CACHE */}static errcode_t unix_write_blk(io_channel channel, unsigned long block,				int count, const void *buf){	struct unix_private_data *data;	struct unix_cache *cache, *reuse;	errcode_t	retval = 0;	const char	*cp;	int		writethrough;	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);	data = (struct unix_private_data *) channel->private_data;	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);#ifdef NO_IO_CACHE	return raw_write_blk(channel, data, block, count, buf);#else	/*	 * If we're doing an odd-sized write or a very large write,	 * flush out the cache completely and then do a direct write.	 */	if (count < 0 || count > WRITE_DIRECT_SIZE) {		if ((retval = flush_cached_blocks(channel, data, 1)))			return retval;		return raw_write_blk(channel, data, block, count, buf);	}	/*	 * For a moderate-sized multi-block write, first force a write	 * if we're in write-through cache mode, and then fill the	 * cache with the blocks.	 */	writethrough = channel->flags & CHANNEL_FLAGS_WRITETHROUGH;	if (writethrough)		retval = raw_write_blk(channel, data, block, count, buf);	cp = buf;	while (count > 0) {		cache = find_cached_block(data, block, &reuse);		if (!cache) {			cache = reuse;			reuse_cache(channel, data, cache, block);		}		memcpy(cache->buf, cp, channel->block_size);		cache->dirty = !writethrough;		count--;		block++;		cp += channel->block_size;	}	return retval;#endif /* NO_IO_CACHE */}static errcode_t unix_write_byte(io_channel channel, unsigned long offset,				 int size, const void *buf){	struct unix_private_data *data;	errcode_t	retval = 0;	ssize_t		actual;	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);	data = (struct unix_private_data *) channel->private_data;	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);#ifndef NO_IO_CACHE	/*	 * Flush out the cache completely	 */	if ((retval = flush_cached_blocks(channel, data, 1)))		return retval;#endif	if (lseek(data->dev, offset + data->offset, SEEK_SET) < 0)		return errno;	actual = write(data->dev, buf, size);	if (actual != size)		return EXT2_ET_SHORT_WRITE;	return 0;}/* * Flush data buffers to disk. */static errcode_t unix_flush(io_channel channel){	struct unix_private_data *data;	errcode_t retval = 0;	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);	data = (struct unix_private_data *) channel->private_data;	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);#ifndef NO_IO_CACHE	retval = flush_cached_blocks(channel, data, 0);#endif	fsync(data->dev);	return retval;}static errcode_t unix_set_option(io_channel channel, const char *option,				 const char *arg){	struct unix_private_data *data;	unsigned long tmp;	char *end;	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);	data = (struct unix_private_data *) channel->private_data;	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);	if (!strcmp(option, "offset")) {		if (!arg)			return EXT2_ET_INVALID_ARGUMENT;		tmp = strtoul(arg, &end, 0);		if (*end)			return EXT2_ET_INVALID_ARGUMENT;		data->offset = tmp;		return 0;	}	return EXT2_ET_INVALID_ARGUMENT;}

⌨️ 快捷键说明

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