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

📄 file.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
📖 第 1 页 / 共 2 页
字号:
		affs_brelse(bh);		pt = T_LIST;		if (ext < EXT_CACHE_SIZE - 1) {			inode->u.affs_i.i_ext[ext] = key;			inode->u.affs_i.i_max_ext  = ++ext;		}	}	key = htonl(AFFS_BLOCK(bh->b_data,inode,block));	affs_brelse(bh);	if (!key)		return NULL;	*blk_key = key;	return affs_bread(inode->i_dev,key,AFFS_I2BSIZE(inode));}/* This could be made static, regardless of what the former comment said. * You cannot directly read affs directories. */static intaffs_file_read_ofs(struct inode *inode, struct file *filp, char *buf, int count){	char *start;	int left, offset, size, sector;	int blocksize;	struct buffer_head *bh;	void *data;	pr_debug("AFFS: file_read_ofs(ino=%lu,pos=%lu,%d)\n",inode->i_ino,(long)filp->f_pos,count);	if (!inode) {		printk("affs_file_read: inode = NULL\n");		return -EINVAL;	}	blocksize = AFFS_I2BSIZE(inode) - 24;	if (!(S_ISREG(inode->i_mode))) {		pr_debug("affs_file_read: mode = %07o\n",inode->i_mode);		return -EINVAL;	}	if (filp->f_pos >= inode->i_size || count <= 0)		return 0;	start = buf;	for (;;) {		left = MIN (inode->i_size - filp->f_pos,count - (buf - start));		if (!left)			break;		sector = affs_bmap(inode,(__u32)filp->f_pos / blocksize);		if (!sector)			break;		offset = (__u32)filp->f_pos % blocksize;		bh = affs_bread(inode->i_dev,sector,AFFS_I2BSIZE(inode));		if (!bh)			break;		data = bh->b_data + 24;		size = MIN(blocksize - offset,left);		filp->f_pos += size;		memcpy_tofs(buf,data + offset,size);		buf += size;		affs_brelse(bh);	}	if (start == buf)		return -EIO;	return buf - start;}static intaffs_file_write(struct inode *inode, struct file *filp, const char *buf, int count){	off_t			 pos;	int			 written;	int			 c;	int			 blocksize;	struct buffer_head	*bh;	struct inode		*ino;	char			*p;	pr_debug("AFFS: file_write(ino=%lu,pos=%lu,count=%d)\n",inode->i_ino,		(unsigned long)filp->f_pos,count);	ino = NULL;	if (!inode) {		printk("AFFS: file_write(): inode=NULL\n");		return -EINVAL;	}	if (inode->u.affs_i.i_original) {		ino = iget(inode->i_sb,inode->u.affs_i.i_original);		if (!ino) {			printk("AFFS: could not follow link from inode %lu to %d\n",			       inode->i_ino,inode->u.affs_i.i_original);			return -EINVAL;		}		inode = ino;	}	if (!S_ISREG(inode->i_mode)) {		printk("AFFS: file_write(): mode=%07o\n",inode->i_mode);		iput(inode);		return -EINVAL;	}	if (filp->f_flags & O_APPEND) {		pos = inode->i_size;	} else		pos = filp->f_pos;	written   = 0;	blocksize = AFFS_I2BSIZE(inode);	while (written < count) {		bh = affs_getblock(inode,pos / blocksize);		if (!bh) {			if (!written)				written = -ENOSPC;			break;		}		c = blocksize - (pos % blocksize);		if (c > count - written)			c = count - written;		if (c != blocksize && !buffer_uptodate(bh)) {			ll_rw_block(READ,1,&bh);			wait_on_buffer(bh);			if (!buffer_uptodate(bh)) {				affs_brelse(bh);				if (!written)					written = -EIO;				break;			}		}		p = (pos % blocksize) + bh->b_data;		memcpy_fromfs(p,buf,c);		update_vm_cache(inode,pos,p,c);		mark_buffer_uptodate(bh,1);		mark_buffer_dirty(bh,0);		affs_brelse(bh);		pos     += c;		written += c;		buf     += c;	}	if (pos > inode->i_size)		inode->i_size = pos;	inode->i_mtime = inode->i_ctime = CURRENT_TIME;	filp->f_pos    = pos;	inode->i_dirt  = 1;	iput(ino);	return written;}static intaffs_file_write_ofs(struct inode *inode, struct file *filp, const char *buf, int count){	off_t			 pos;	int			 written;	int			 c;	int			 key;	int			 blocksize;	struct buffer_head	*bh;	struct inode		*ino;	char			*p;	pr_debug("AFFS: file_write_ofs(ino=%lu,pos=%lu,count=%d)\n",inode->i_ino,		(unsigned long)filp->f_pos,count);	if (!inode) {		printk("AFFS: file_write_ofs(): inode=NULL\n");		return -EINVAL;	}	ino = NULL;	if (inode->u.affs_i.i_original) {		ino = iget(inode->i_sb,inode->u.affs_i.i_original);		if (!ino) {			printk("AFFS: could not follow link from inode %lu to %d\n",			       inode->i_ino,inode->u.affs_i.i_original);			return -EINVAL;		}		inode = ino;	}	if (!S_ISREG(inode->i_mode)) {		printk("AFFS: file_write_ofs(): mode=%07o\n",inode->i_mode);		iput(inode);		return -EINVAL;	}	if (filp->f_flags & O_APPEND)		pos = inode->i_size;	else		pos = filp->f_pos;	bh        = NULL;	blocksize = AFFS_I2BSIZE(inode) - 24;	written   = 0;	while (written < count) {		bh = affs_getblock_ofs(inode,pos / blocksize,&key);		if (!bh) {			if (!written)				written = -ENOSPC;			break;		}		c = blocksize - (pos % blocksize);		if (c > count - written)			c = count - written;		if (c != blocksize && !buffer_uptodate(bh)) {			ll_rw_block(READ,1,&bh);			wait_on_buffer(bh);			if (!buffer_uptodate(bh)) {				affs_brelse(bh);				if (!written)					written = -EIO;				break;			}		}		p = (pos % blocksize) + bh->b_data + 24;		memcpy_fromfs(p,buf,c);		update_vm_cache(inode,pos,p,c);		pos     += c;		buf     += c;		written += c;		DATA_FRONT(bh)->data_size = ntohl(htonl(DATA_FRONT(bh)->data_size) + c);		affs_fix_checksum(AFFS_I2BSIZE(inode),bh->b_data,5);		mark_buffer_uptodate(bh,1);		mark_buffer_dirty(bh,0);		affs_brelse(bh);	}	if (pos > inode->i_size)		inode->i_size = pos;	filp->f_pos = pos;	inode->i_mtime = inode->i_ctime = CURRENT_TIME;	inode->i_dirt  = 1;	iput(ino);	return written;}voidaffs_truncate(struct inode *inode){	struct buffer_head	*bh;	struct buffer_head	*ebh;	struct inode		*ino;	struct affs_zone	*zone;	int	 first;	int	 block;	int	 key;	int	*keyp;	int	 ekey;	int	 ptype, stype;	int	 freethis;	int	 blocksize;	int	 rem;	int	 ext;	pr_debug("AFFS: file_truncate(inode=%ld,size=%lu)\n",inode->i_ino,inode->i_size);	ino = NULL;	if (inode->u.affs_i.i_original) {		ino = iget(inode->i_sb,inode->u.affs_i.i_original);		if (!ino) {			printk("AFFS: truncate(): cannot follow link from %lu to %u\n",			       inode->i_ino,inode->u.affs_i.i_original);			return;		}		inode = ino;	}	blocksize = AFFS_I2BSIZE(inode) - ((inode->i_sb->u.affs_sb.s_flags & SF_OFS) ? 24 : 0);	first = (inode->i_size + blocksize - 1) / blocksize;	if (inode->u.affs_i.i_lastblock < first - 1) {		if (inode->i_sb->u.affs_sb.s_flags & SF_OFS)			bh = affs_getblock_ofs(inode,first - 1,&ekey);		else			bh = affs_getblock(inode,first - 1);		while (inode->u.affs_i.i_pa_cnt) {		/* Free any preallocated blocks */			affs_free_block(inode->i_sb,					inode->u.affs_i.i_data[inode->u.affs_i.i_pa_next++]);			inode->u.affs_i.i_pa_next &= MAX_PREALLOC - 1;			inode->u.affs_i.i_pa_cnt--;		}		if (inode->u.affs_i.i_zone) {			lock_super(inode->i_sb);			zone = &inode->i_sb->u.affs_sb.s_zones[inode->u.affs_i.i_zone];			if (zone->z_ino == inode->i_ino)				zone->z_ino = 0;			unlock_super(inode->i_sb);		}		if (!bh) {			printk("AFFS: truncate(): Cannot extend file\n");			inode->i_size = blocksize * (inode->u.affs_i.i_lastblock + 1);		} else if (inode->i_sb->u.affs_sb.s_flags & SF_OFS) {			rem = inode->i_size % blocksize;			DATA_FRONT(bh)->data_size = ntohl(rem ? rem : blocksize);			affs_fix_checksum(AFFS_I2BSIZE(inode),bh->b_data,5);			mark_buffer_dirty(bh,0);		}		affs_brelse(bh);		iput(ino);		return;	}	ekey  = inode->i_ino;	ext   = 0;	while (ekey) {		if (!(bh = affs_bread(inode->i_dev,ekey,AFFS_I2BSIZE(inode)))) {			printk("AFFS: truncate(): Can't read block %d\n",ekey);			break;		}		ptype = htonl(((struct file_front *)bh->b_data)->primary_type);		stype = htonl(FILE_END(bh->b_data,inode)->secondary_type);		if (ekey == inode->i_ino && ptype == T_SHORT && stype == ST_LINKFILE &&		    LINK_END(bh->b_data,inode)->original == 0) {			pr_debug("AFFS: truncate(): dumping link\n");			affs_brelse(bh);			break;		}		if (stype != ST_FILE || (ptype != T_SHORT && ptype != T_LIST)) {			printk("AFFS: truncate(): bad block (ptype=%d, stype=%d)\n",			        ptype,stype);			affs_brelse(bh);			break;		}		/* Do not throw away file header */		freethis = first == 0 && ekey != inode->i_ino;		for ( block = first; block < AFFS_I2HSIZE(inode); block++) {			keyp = &AFFS_BLOCK(bh->b_data,inode,block);			key  = htonl(*keyp);			if (key) {				*keyp = 0;				affs_free_block(inode->i_sb,key);			} else {				block = AFFS_I2HSIZE(inode);				break;			}		}		keyp = &GET_END_PTR(struct file_end,bh->b_data,AFFS_I2BSIZE(inode))->extension;		key  = htonl(*keyp);		if (first <= AFFS_I2HSIZE(inode)) {			((struct file_front *)bh->b_data)->block_count = htonl(first);			first = 0;			*keyp = 0;			if ((inode->i_sb->u.affs_sb.s_flags & SF_OFS) && first > 0) {				block = htonl(AFFS_BLOCK(bh->b_data,inode,first - 1));				if ((ebh = affs_bread(inode->i_dev,block,AFFS_I2BSIZE(inode)))) {					if(!(affs_checksum_block(AFFS_I2BSIZE(inode),ebh->b_data,					     &ptype,NULL))) {						rem = inode->i_size % blocksize;						rem = ntohl(rem ? blocksize : rem);						((struct data_front *)ebh->b_data)->data_size = rem;						((struct data_front *)ebh->b_data)->next_data = 0;						affs_fix_checksum(AFFS_I2BSIZE(inode),ebh->b_data,5);						mark_buffer_dirty(ebh,1);					}					affs_brelse(ebh);				}			}		} else {			first -= AFFS_I2HSIZE(inode);		}		if (freethis) {		/* Don't bother fixing checksum */			affs_brelse(bh);			affs_free_block(inode->i_sb,ekey);		} else {			affs_fix_checksum(AFFS_I2BSIZE(inode),bh->b_data,5);			mark_buffer_dirty(bh,1);			affs_brelse(bh);		}		ekey = key;	}	inode->u.affs_i.i_lastblock = ((inode->i_size + blocksize - 1) / blocksize) - 1;	inode->u.affs_i.i_max_ext   = 0;	iput(ino);}static voidaffs_release_file(struct inode *inode, struct file *filp){	struct affs_zone	*zone;	pr_debug("AFFS: release_file(ino=%lu)\n",inode->i_ino);	if (filp->f_mode & 2) {		/* Free preallocated blocks */		while (inode->u.affs_i.i_pa_cnt) {			affs_free_block(inode->i_sb,					inode->u.affs_i.i_data[inode->u.affs_i.i_pa_next++]);			inode->u.affs_i.i_pa_next &= MAX_PREALLOC - 1;			inode->u.affs_i.i_pa_cnt--;		}		if (inode->u.affs_i.i_zone) {			lock_super(inode->i_sb);			zone = &inode->i_sb->u.affs_sb.s_zones[inode->u.affs_i.i_zone];			if (zone->z_ino == inode->i_ino)				zone->z_ino = 0;			unlock_super(inode->i_sb);		}	}}

⌨️ 快捷键说明

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