fs/jffs2/erase.c

Source file repositories/reference/linux-study-clean/fs/jffs2/erase.c

File Facts

System
Linux kernel
Corpus path
fs/jffs2/erase.c
Extension
.c
Size
13738 bytes
Lines
488
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!ret) {
	       jffs2_erase_succeeded(c, jeb);
	       return;
       }
       bad_offset = jeb->offset;
#else /* Linux */
	struct erase_info *instr;

	jffs2_dbg(1, "%s(): erase block %#08x (range %#08x-%#08x)\n",
		  __func__,
		  jeb->offset, jeb->offset, jeb->offset + c->sector_size);
	instr = kzalloc_obj(struct erase_info);
	if (!instr) {
		pr_warn("kzalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n");
		mutex_lock(&c->erase_free_sem);
		spin_lock(&c->erase_completion_lock);
		list_move(&jeb->list, &c->erase_pending_list);
		c->erasing_size -= c->sector_size;
		c->dirty_size += c->sector_size;
		jeb->dirty_size = c->sector_size;
		spin_unlock(&c->erase_completion_lock);
		mutex_unlock(&c->erase_free_sem);
		return;
	}

	instr->addr = jeb->offset;
	instr->len = c->sector_size;

	ret = mtd_erase(c->mtd, instr);
	if (!ret) {
		jffs2_erase_succeeded(c, jeb);
		kfree(instr);
		return;
	}

	bad_offset = instr->fail_addr;
	kfree(instr);
#endif /* __ECOS */

	if (ret == -ENOMEM || ret == -EAGAIN) {
		/* Erase failed immediately. Refile it on the list */
		jffs2_dbg(1, "Erase at 0x%08x failed: %d. Refiling on erase_pending_list\n",
			  jeb->offset, ret);
		mutex_lock(&c->erase_free_sem);
		spin_lock(&c->erase_completion_lock);
		list_move(&jeb->list, &c->erase_pending_list);
		c->erasing_size -= c->sector_size;
		c->dirty_size += c->sector_size;
		jeb->dirty_size = c->sector_size;
		spin_unlock(&c->erase_completion_lock);
		mutex_unlock(&c->erase_free_sem);
		return;
	}

	if (ret == -EROFS)
		pr_warn("Erase at 0x%08x failed immediately: -EROFS. Is the sector locked?\n",
			jeb->offset);
	else
		pr_warn("Erase at 0x%08x failed immediately: errno %d\n",
			jeb->offset, ret);

	jffs2_erase_failed(c, jeb, bad_offset);
}

int jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count)
{
	struct jffs2_eraseblock *jeb;
	int work_done = 0;

	mutex_lock(&c->erase_free_sem);

	spin_lock(&c->erase_completion_lock);

	while (!list_empty(&c->erase_complete_list) ||
	       !list_empty(&c->erase_pending_list)) {

		if (!list_empty(&c->erase_complete_list)) {
			jeb = list_entry(c->erase_complete_list.next, struct jffs2_eraseblock, list);
			list_move(&jeb->list, &c->erase_checking_list);
			spin_unlock(&c->erase_completion_lock);
			mutex_unlock(&c->erase_free_sem);
			jffs2_mark_erased_block(c, jeb);

			work_done++;
			if (!--count) {
				jffs2_dbg(1, "Count reached. jffs2_erase_pending_blocks leaving\n");
				goto done;
			}

		} else if (!list_empty(&c->erase_pending_list)) {

Annotation

Implementation Notes