int ret = 0, inum, nlink;
int xattr = 0;
- if (down_interruptible(&c->alloc_sem))
+ if (mutex_lock_interruptible(&c->alloc_sem))
return -EINTR;
for (;;) {
c->unchecked_size);
jffs2_dbg_dump_block_lists_nolock(c);
spin_unlock(&c->erase_completion_lock);
- up(&c->alloc_sem);
+ mutex_unlock(&c->alloc_sem);
return -ENOSPC;
}
made no progress in this case, but that should be OK */
c->checked_ino--;
- up(&c->alloc_sem);
+ mutex_unlock(&c->alloc_sem);
sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
return 0;
printk(KERN_WARNING "Returned error for crccheck of ino #%u. Expect badness...\n", ic->ino);
jffs2_set_inocache_state(c, ic, INO_STATE_CHECKEDABSENT);
- up(&c->alloc_sem);
+ mutex_unlock(&c->alloc_sem);
return ret;
}
jeb = jffs2_find_gc_block(c);
if (!jeb) {
- D1 (printk(KERN_NOTICE "jffs2: Couldn't find erase block to garbage collect!\n"));
+ /* Couldn't find a free block. But maybe we can just erase one and make 'progress'? */
+ if (!list_empty(&c->erase_pending_list)) {
+ spin_unlock(&c->erase_completion_lock);
+ mutex_unlock(&c->alloc_sem);
+ return -EAGAIN;
+ }
+ D1(printk(KERN_NOTICE "jffs2: Couldn't find erase block to garbage collect!\n"));
spin_unlock(&c->erase_completion_lock);
- up(&c->alloc_sem);
+ mutex_unlock(&c->alloc_sem);
return -EIO;
}
printk(KERN_DEBUG "Nextblock at %08x, used_size %08x, dirty_size %08x, wasted_size %08x, free_size %08x\n", c->nextblock->offset, c->nextblock->used_size, c->nextblock->dirty_size, c->nextblock->wasted_size, c->nextblock->free_size));
if (!jeb->used_size) {
- up(&c->alloc_sem);
+ mutex_unlock(&c->alloc_sem);
goto eraseit;
}
jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size);
jeb->gc_node = raw;
spin_unlock(&c->erase_completion_lock);
- up(&c->alloc_sem);
+ mutex_unlock(&c->alloc_sem);
BUG();
}
}
/* Just mark it obsolete */
jffs2_mark_node_obsolete(c, raw);
}
- up(&c->alloc_sem);
+ mutex_unlock(&c->alloc_sem);
goto eraseit_lock;
}
*/
printk(KERN_CRIT "Inode #%u already in state %d in jffs2_garbage_collect_pass()!\n",
ic->ino, ic->state);
- up(&c->alloc_sem);
+ mutex_unlock(&c->alloc_sem);
spin_unlock(&c->inocache_lock);
BUG();
the alloc_sem() (for marking nodes invalid) so we must
drop the alloc_sem before sleeping. */
- up(&c->alloc_sem);
+ mutex_unlock(&c->alloc_sem);
D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() waiting for ino #%u in state %d\n",
ic->ino, ic->state));
sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
ret = -ENOSPC;
}
release_sem:
- up(&c->alloc_sem);
+ mutex_unlock(&c->alloc_sem);
eraseit_lock:
/* If we've finished this block, start it erasing */
uint32_t start = 0, end = 0, nrfrags = 0;
int ret = 0;
- down(&f->sem);
+ mutex_lock(&f->sem);
/* Now we have the lock for this inode. Check that it's still the one at the head
of the list. */
}
}
upnout:
- up(&f->sem);
+ mutex_unlock(&f->sem);
return ret;
}
/* Prevent the erase code from nicking the obsolete node refs while
we're looking at them. I really don't like this extra lock but
can't see any alternative. Suggestions on a postcard to... */
- down(&c->erase_free_sem);
+ mutex_lock(&c->erase_free_sem);
for (raw = f->inocache->nodes; raw != (void *)f->inocache; raw = raw->next_in_ino) {
/* OK. The name really does match. There really is still an older node on
the flash which our deletion dirent obsoletes. So we have to write out
a new deletion dirent to replace it */
- up(&c->erase_free_sem);
+ mutex_unlock(&c->erase_free_sem);
D1(printk(KERN_DEBUG "Deletion dirent at %08x still obsoletes real dirent \"%s\" at %08x for ino #%u\n",
ref_offset(fd->raw), fd->name, ref_offset(raw), je32_to_cpu(rd->ino)));
return jffs2_garbage_collect_dirent(c, jeb, f, fd);
}
- up(&c->erase_free_sem);
+ mutex_unlock(&c->erase_free_sem);
kfree(rd);
}
return 0;
}
-static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
+static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *orig_jeb,
struct jffs2_inode_info *f, struct jffs2_full_dnode *fn,
uint32_t start, uint32_t end)
{