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

📄 write.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
			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, 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;	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), &alloclen, ALLOC_NORMAL,				JFFS2_SUMMARY_INODE_SIZE);	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, 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_init_security(&f->vfs_inode, &dir_f->vfs_inode);	if (ret)		return ret;	ret = jffs2_init_acl_post(&f->vfs_inode);	if (ret)		return ret;	ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,				ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));	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, 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,		    uint32_t time){	struct jffs2_raw_dirent *rd;	struct jffs2_full_dirent *fd;	uint32_t alloclen;	int ret;	if (!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, &alloclen,					ALLOC_DELETION, JFFS2_SUMMARY_DIRENT_SIZE(namelen));		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(time);		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, 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);		/* We don't actually want to reserve any space, but we do		   want to be holding the alloc_sem when we write to flash */		down(&c->alloc_sem);		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);		if (S_ISDIR(OFNI_EDONI_2SFFJ(dead_f)->i_mode)) {			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, uint32_t time){	struct jffs2_raw_dirent *rd;	struct jffs2_full_dirent *fd;	uint32_t alloclen;	int ret;	rd = jffs2_alloc_raw_dirent();	if (!rd)		return -ENOMEM;	ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,				ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));	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(time);	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, 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 + -