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

📄 write.c

📁 jffs2源代码基于2。6内核
💻 C
📖 第 1 页 / 共 2 页
字号:
	uint32_t writtenlen = 0;       	D1(printk(KERN_DEBUG "jffs2_write_inode_range(): Ino #%u, ofs 0x%x, len 0x%x\n",		  f->inocache->ino, offset, writelen));			while(writelen) {		struct jffs2_full_dnode *fn;		unsigned char *comprbuf = NULL;		uint16_t comprtype = JFFS2_COMPR_NONE;		uint32_t phys_ofs, alloclen;		uint32_t datalen, cdatalen;		int retried = 0;	retry:		D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, offset));		ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen, ALLOC_NORMAL);		if (ret) {			D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret));			break;		}		down(&f->sem);		datalen = min_t(uint32_t, writelen, PAGE_CACHE_SIZE - (offset & (PAGE_CACHE_SIZE-1)));		cdatalen = min_t(uint32_t, alloclen - sizeof(*ri), datalen);		comprtype = jffs2_compress(c, f, buf, &comprbuf, &datalen, &cdatalen);		ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);		ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);		ri->totlen = cpu_to_je32(sizeof(*ri) + cdatalen);		ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));		ri->ino = cpu_to_je32(f->inocache->ino);		ri->version = cpu_to_je32(++f->highest_version);		ri->isize = cpu_to_je32(max(je32_to_cpu(ri->isize), offset + datalen));		ri->offset = cpu_to_je32(offset);		ri->csize = cpu_to_je32(cdatalen);		ri->dsize = cpu_to_je32(datalen);		ri->compr = comprtype & 0xff;		ri->usercompr = (comprtype >> 8 ) & 0xff;		ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));		ri->data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen));		fn = jffs2_write_dnode(c, f, ri, comprbuf, cdatalen, phys_ofs, ALLOC_NORETRY);		jffs2_free_comprbuf(comprbuf, buf);		if (IS_ERR(fn)) {			ret = PTR_ERR(fn);			up(&f->sem);			jffs2_complete_reservation(c);			if (!retried) {				/* Write error to be retried */				retried = 1;				D1(printk(KERN_DEBUG "Retrying node write in jffs2_write_inode_range()\n"));				goto retry;			}			break;		}		ret = jffs2_add_full_dnode_to_inode(c, f, fn);		if (f->metadata) {			jffs2_mark_node_obsolete(c, f->metadata->raw);			jffs2_free_full_dnode(f->metadata);			f->metadata = NULL;		}		if (ret) {			/* Eep */			D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in commit_write, returned %d\n", ret));			jffs2_mark_node_obsolete(c, fn->raw);			jffs2_free_full_dnode(fn);			up(&f->sem);			jffs2_complete_reservation(c);			break;		}		up(&f->sem);		jffs2_complete_reservation(c);		if (!datalen) {			printk(KERN_WARNING "Eep. We didn't actually write any data in jffs2_write_inode_range()\n");			ret = -EIO;			break;		}		D1(printk(KERN_DEBUG "increasing writtenlen by %d\n", datalen));		writtenlen += datalen;		offset += datalen;		writelen -= datalen;		buf += datalen;	}	*retlen = writtenlen;	return ret;}int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const char *name, int namelen){	struct jffs2_raw_dirent *rd;	struct jffs2_full_dnode *fn;	struct jffs2_full_dirent *fd;	uint32_t alloclen, phys_ofs;	int ret;	/* Try to reserve enough space for both node and dirent. 	 * Just the node will do for now, though 	 */	ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL);	D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen));	if (ret) {		up(&f->sem);		return ret;	}	ri->data_crc = cpu_to_je32(0);	ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));	fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL);	D1(printk(KERN_DEBUG "jffs2_do_create created file with mode 0x%x\n",		  jemode_to_cpu(ri->mode)));	if (IS_ERR(fn)) {		D1(printk(KERN_DEBUG "jffs2_write_dnode() failed\n"));		/* Eeek. Wave bye bye */		up(&f->sem);		jffs2_complete_reservation(c);		return PTR_ERR(fn);	}	/* No data here. Only a metadata node, which will be 	   obsoleted by the first data write	*/	f->metadata = fn;	up(&f->sem);	jffs2_complete_reservation(c);	ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);			if (ret) {		/* Eep. */		D1(printk(KERN_DEBUG "jffs2_reserve_space() for dirent failed\n"));		return ret;	}	rd = jffs2_alloc_raw_dirent();	if (!rd) {		/* Argh. Now we treat it like a normal delete */		jffs2_complete_reservation(c);		return -ENOMEM;	}	down(&dir_f->sem);	rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);	rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);	rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);	rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));	rd->pino = cpu_to_je32(dir_f->inocache->ino);	rd->version = cpu_to_je32(++dir_f->highest_version);	rd->ino = ri->ino;	rd->mctime = ri->ctime;	rd->nsize = namelen;	rd->type = DT_REG;	rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));	rd->name_crc = cpu_to_je32(crc32(0, name, namelen));	fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL);	jffs2_free_raw_dirent(rd);		if (IS_ERR(fd)) {		/* dirent failed to write. Delete the inode normally 		   as if it were the final unlink() */		jffs2_complete_reservation(c);		up(&dir_f->sem);		return PTR_ERR(fd);	}	/* Link the fd into the inode's list, obsoleting an old	   one if necessary. */	jffs2_add_fd_to_list(c, fd, &dir_f->dents);	jffs2_complete_reservation(c);	up(&dir_f->sem);	return 0;}int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,		    const char *name, int namelen, struct jffs2_inode_info *dead_f){	struct jffs2_raw_dirent *rd;	struct jffs2_full_dirent *fd;	uint32_t alloclen, phys_ofs;	int ret;	if (1 /* alternative branch needs testing */ || 	    !jffs2_can_mark_obsolete(c)) {		/* We can't mark stuff obsolete on the medium. We need to write a deletion dirent */		rd = jffs2_alloc_raw_dirent();		if (!rd)			return -ENOMEM;		ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_DELETION);		if (ret) {			jffs2_free_raw_dirent(rd);			return ret;		}		down(&dir_f->sem);		/* Build a deletion node */		rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);		rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);		rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);		rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));				rd->pino = cpu_to_je32(dir_f->inocache->ino);		rd->version = cpu_to_je32(++dir_f->highest_version);		rd->ino = cpu_to_je32(0);		rd->mctime = cpu_to_je32(get_seconds());		rd->nsize = namelen;		rd->type = DT_UNKNOWN;		rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));		rd->name_crc = cpu_to_je32(crc32(0, name, namelen));		fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_DELETION);				jffs2_free_raw_dirent(rd);		if (IS_ERR(fd)) {			jffs2_complete_reservation(c);			up(&dir_f->sem);			return PTR_ERR(fd);		}		/* File it. This will mark the old one obsolete. */		jffs2_add_fd_to_list(c, fd, &dir_f->dents);		up(&dir_f->sem);	} else {		struct jffs2_full_dirent **prev = &dir_f->dents;		uint32_t nhash = full_name_hash(name, namelen);		down(&dir_f->sem);		while ((*prev) && (*prev)->nhash <= nhash) {			if ((*prev)->nhash == nhash && 			    !memcmp((*prev)->name, name, namelen) &&			    !(*prev)->name[namelen]) {				struct jffs2_full_dirent *this = *prev;				D1(printk(KERN_DEBUG "Marking old dirent node (ino #%u) @%08x obsolete\n",					  this->ino, ref_offset(this->raw)));				*prev = this->next;				jffs2_mark_node_obsolete(c, (this->raw));				jffs2_free_full_dirent(this);				break;			}			prev = &((*prev)->next);		}		up(&dir_f->sem);	}	/* dead_f is NULL if this was a rename not a real unlink */	/* Also catch the !f->inocache case, where there was a dirent	   pointing to an inode which didn't exist. */	if (dead_f && dead_f->inocache) { 		down(&dead_f->sem);		while (dead_f->dents) {			/* There can be only deleted ones */			fd = dead_f->dents;						dead_f->dents = fd->next;						if (fd->ino) {				printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n",				       dead_f->inocache->ino, fd->name, fd->ino);			} else {				D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n", fd->name, dead_f->inocache->ino));			}			jffs2_mark_node_obsolete(c, fd->raw);			jffs2_free_full_dirent(fd);		}		dead_f->inocache->nlink--;		/* NB: Caller must set inode nlink if appropriate */		up(&dead_f->sem);	}	jffs2_complete_reservation(c);	return 0;}int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen){	struct jffs2_raw_dirent *rd;	struct jffs2_full_dirent *fd;	uint32_t alloclen, phys_ofs;	int ret;	rd = jffs2_alloc_raw_dirent();	if (!rd)		return -ENOMEM;	ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);	if (ret) {		jffs2_free_raw_dirent(rd);		return ret;	}		down(&dir_f->sem);	/* Build a deletion node */	rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);	rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);	rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);	rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));	rd->pino = cpu_to_je32(dir_f->inocache->ino);	rd->version = cpu_to_je32(++dir_f->highest_version);	rd->ino = cpu_to_je32(ino);	rd->mctime = cpu_to_je32(get_seconds());	rd->nsize = namelen;	rd->type = type;	rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));	rd->name_crc = cpu_to_je32(crc32(0, name, namelen));	fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL);		jffs2_free_raw_dirent(rd);	if (IS_ERR(fd)) {		jffs2_complete_reservation(c);		up(&dir_f->sem);		return PTR_ERR(fd);	}	/* File it. This will mark the old one obsolete. */	jffs2_add_fd_to_list(c, fd, &dir_f->dents);	jffs2_complete_reservation(c);	up(&dir_f->sem);	return 0;}

⌨️ 快捷键说明

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