Commit ced22070 authored by David Woodhouse's avatar David Woodhouse

[JFFS2] semaphore->mutex conversion

Signed-off-by: default avatarDavid Woodhouse <dwmw2@infradead.org>
parent 52f83014
......@@ -14,7 +14,7 @@ be fairly close.
alloc_sem
---------
The alloc_sem is a per-filesystem semaphore, used primarily to ensure
The alloc_sem is a per-filesystem mutex, used primarily to ensure
contiguous allocation of space on the medium. It is automatically
obtained during space allocations (jffs2_reserve_space()) and freed
upon write completion (jffs2_complete_reservation()). Note that
......@@ -41,10 +41,10 @@ if the wbuf is currently holding any data is permitted, though.
Ordering constraints: See f->sem.
File Semaphore f->sem
File Mutex f->sem
---------------------
This is the JFFS2-internal equivalent of the inode semaphore i->i_sem.
This is the JFFS2-internal equivalent of the inode mutex i->i_sem.
It protects the contents of the jffs2_inode_info private inode data,
including the linked list of node fragments (but see the notes below on
erase_completion_lock), etc.
......@@ -60,14 +60,14 @@ lead to deadlock, unless we played games with unlocking the i_sem
before calling the space allocation functions.
Instead of playing such games, we just have an extra internal
semaphore, which is obtained by the garbage collection code and also
mutex, which is obtained by the garbage collection code and also
by the normal file system code _after_ allocation of space.
Ordering constraints:
1. Never attempt to allocate space or lock alloc_sem with
any f->sem held.
2. Never attempt to lock two file semaphores in one thread.
2. Never attempt to lock two file mutexes in one thread.
No ordering rules have been made for doing so.
......@@ -86,8 +86,8 @@ a simple spin_lock() rather than spin_lock_bh().
Note that the per-inode list of physical nodes (f->nodes) is a special
case. Any changes to _valid_ nodes (i.e. ->flash_offset & 1 == 0) in
the list are protected by the file semaphore f->sem. But the erase
code may remove _obsolete_ nodes from the list while holding only the
the list are protected by the file mutex f->sem. But the erase code
may remove _obsolete_ nodes from the list while holding only the
erase_completion_lock. So you can walk the list only while holding the
erase_completion_lock, and can drop the lock temporarily mid-walk as
long as the pointer you're holding is to a _valid_ node, not an
......@@ -124,10 +124,10 @@ Ordering constraints:
erase_free_sem
--------------
This semaphore is only used by the erase code which frees obsolete
node references and the jffs2_garbage_collect_deletion_dirent()
function. The latter function on NAND flash must read _obsolete_ nodes
to determine whether the 'deletion dirent' under consideration can be
This mutex is only used by the erase code which frees obsolete node
references and the jffs2_garbage_collect_deletion_dirent() function.
The latter function on NAND flash must read _obsolete_ nodes to
determine whether the 'deletion dirent' under consideration can be
discarded or whether it is still required to show that an inode has
been unlinked. Because reading from the flash may sleep, the
erase_completion_lock cannot be held, so an alternative, more
......
......@@ -62,9 +62,9 @@ __jffs2_dbg_acct_sanity_check(struct jffs2_sb_info *c,
void
__jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f)
{
down(&f->sem);
mutex_lock(&f->sem);
__jffs2_dbg_fragtree_paranoia_check_nolock(f);
up(&f->sem);
mutex_unlock(&f->sem);
}
void
......@@ -532,9 +532,9 @@ __jffs2_dbg_dump_block_lists_nolock(struct jffs2_sb_info *c)
void
__jffs2_dbg_dump_fragtree(struct jffs2_inode_info *f)
{
down(&f->sem);
mutex_lock(&f->sem);
jffs2_dbg_dump_fragtree_nolock(f);
up(&f->sem);
mutex_unlock(&f->sem);
}
void
......
......@@ -86,7 +86,7 @@ static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target,
dir_f = JFFS2_INODE_INFO(dir_i);
c = JFFS2_SB_INFO(dir_i->i_sb);
down(&dir_f->sem);
mutex_lock(&dir_f->sem);
/* NB: The 2.2 backport will need to explicitly check for '.' and '..' here */
for (fd_list = dir_f->dents; fd_list && fd_list->nhash <= target->d_name.hash; fd_list = fd_list->next) {
......@@ -99,7 +99,7 @@ static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target,
}
if (fd)
ino = fd->ino;
up(&dir_f->sem);
mutex_unlock(&dir_f->sem);
if (ino) {
inode = jffs2_iget(dir_i->i_sb, ino);
if (IS_ERR(inode)) {
......@@ -146,7 +146,7 @@ static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir)
}
curofs=1;
down(&f->sem);
mutex_lock(&f->sem);
for (fd = f->dents; fd; fd = fd->next) {
curofs++;
......@@ -166,7 +166,7 @@ static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir)
break;
offset++;
}
up(&f->sem);
mutex_unlock(&f->sem);
out:
filp->f_pos = offset;
return 0;
......@@ -275,9 +275,9 @@ static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct de
ret = jffs2_do_link(c, dir_f, f->inocache->ino, type, dentry->d_name.name, dentry->d_name.len, now);
if (!ret) {
down(&f->sem);
mutex_lock(&f->sem);
old_dentry->d_inode->i_nlink = ++f->inocache->nlink;
up(&f->sem);
mutex_unlock(&f->sem);
d_instantiate(dentry, old_dentry->d_inode);
dir_i->i_mtime = dir_i->i_ctime = ITIME(now);
atomic_inc(&old_dentry->d_inode->i_count);
......@@ -351,7 +351,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
if (IS_ERR(fn)) {
/* Eeek. Wave bye bye */
up(&f->sem);
mutex_unlock(&f->sem);
jffs2_complete_reservation(c);
jffs2_clear_inode(inode);
return PTR_ERR(fn);
......@@ -361,7 +361,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
f->target = kmalloc(targetlen + 1, GFP_KERNEL);
if (!f->target) {
printk(KERN_WARNING "Can't allocate %d bytes of memory\n", targetlen + 1);
up(&f->sem);
mutex_unlock(&f->sem);
jffs2_complete_reservation(c);
jffs2_clear_inode(inode);
return -ENOMEM;
......@@ -374,7 +374,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
obsoleted by the first data write
*/
f->metadata = fn;
up(&f->sem);
mutex_unlock(&f->sem);
jffs2_complete_reservation(c);
......@@ -406,7 +406,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
}
dir_f = JFFS2_INODE_INFO(dir_i);
down(&dir_f->sem);
mutex_lock(&dir_f->sem);
rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
......@@ -429,7 +429,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
as if it were the final unlink() */
jffs2_complete_reservation(c);
jffs2_free_raw_dirent(rd);
up(&dir_f->sem);
mutex_unlock(&dir_f->sem);
jffs2_clear_inode(inode);
return PTR_ERR(fd);
}
......@@ -442,7 +442,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
one if necessary. */
jffs2_add_fd_to_list(c, fd, &dir_f->dents);
up(&dir_f->sem);
mutex_unlock(&dir_f->sem);
jffs2_complete_reservation(c);
d_instantiate(dentry, inode);
......@@ -507,7 +507,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
if (IS_ERR(fn)) {
/* Eeek. Wave bye bye */
up(&f->sem);
mutex_unlock(&f->sem);
jffs2_complete_reservation(c);
jffs2_clear_inode(inode);
return PTR_ERR(fn);
......@@ -516,7 +516,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
obsoleted by the first data write
*/
f->metadata = fn;
up(&f->sem);
mutex_unlock(&f->sem);
jffs2_complete_reservation(c);
......@@ -548,7 +548,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
}
dir_f = JFFS2_INODE_INFO(dir_i);
down(&dir_f->sem);
mutex_lock(&dir_f->sem);
rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
......@@ -571,7 +571,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
as if it were the final unlink() */
jffs2_complete_reservation(c);
jffs2_free_raw_dirent(rd);
up(&dir_f->sem);
mutex_unlock(&dir_f->sem);
jffs2_clear_inode(inode);
return PTR_ERR(fd);
}
......@@ -585,7 +585,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
one if necessary. */
jffs2_add_fd_to_list(c, fd, &dir_f->dents);
up(&dir_f->sem);
mutex_unlock(&dir_f->sem);
jffs2_complete_reservation(c);
d_instantiate(dentry, inode);
......@@ -673,7 +673,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
if (IS_ERR(fn)) {
/* Eeek. Wave bye bye */
up(&f->sem);
mutex_unlock(&f->sem);
jffs2_complete_reservation(c);
jffs2_clear_inode(inode);
return PTR_ERR(fn);
......@@ -682,7 +682,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
obsoleted by the first data write
*/
f->metadata = fn;
up(&f->sem);
mutex_unlock(&f->sem);
jffs2_complete_reservation(c);
......@@ -714,7 +714,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
}
dir_f = JFFS2_INODE_INFO(dir_i);
down(&dir_f->sem);
mutex_lock(&dir_f->sem);
rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
......@@ -740,7 +740,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
as if it were the final unlink() */
jffs2_complete_reservation(c);
jffs2_free_raw_dirent(rd);
up(&dir_f->sem);
mutex_unlock(&dir_f->sem);
jffs2_clear_inode(inode);
return PTR_ERR(fd);
}
......@@ -753,7 +753,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
one if necessary. */
jffs2_add_fd_to_list(c, fd, &dir_f->dents);
up(&dir_f->sem);
mutex_unlock(&dir_f->sem);
jffs2_complete_reservation(c);
d_instantiate(dentry, inode);
......@@ -780,14 +780,14 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
if (S_ISDIR(new_dentry->d_inode->i_mode)) {
struct jffs2_full_dirent *fd;
down(&victim_f->sem);
mutex_lock(&victim_f->sem);
for (fd = victim_f->dents; fd; fd = fd->next) {
if (fd->ino) {
up(&victim_f->sem);
mutex_unlock(&victim_f->sem);
return -ENOTEMPTY;
}
}
up(&victim_f->sem);
mutex_unlock(&victim_f->sem);
}
}
......@@ -816,9 +816,9 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
/* Don't oops if the victim was a dirent pointing to an
inode which didn't exist. */
if (victim_f->inocache) {
down(&victim_f->sem);
mutex_lock(&victim_f->sem);
victim_f->inocache->nlink--;
up(&victim_f->sem);
mutex_unlock(&victim_f->sem);
}
}
......@@ -836,11 +836,11 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
if (ret) {
/* Oh shit. We really ought to make a single node which can do both atomically */
struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_dentry->d_inode);
down(&f->sem);
mutex_lock(&f->sem);
inc_nlink(old_dentry->d_inode);
if (f->inocache)
f->inocache->nlink++;
up(&f->sem);
mutex_unlock(&f->sem);
printk(KERN_NOTICE "jffs2_rename(): Link succeeded, unlink failed (err %d). You now have a hard link\n", ret);
/* Might as well let the VFS know */
......
......@@ -50,14 +50,14 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
instr = kmalloc(sizeof(struct erase_info) + sizeof(struct erase_priv_struct), GFP_KERNEL);
if (!instr) {
printk(KERN_WARNING "kmalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n");
down(&c->erase_free_sem);
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);
up(&c->erase_free_sem);
mutex_unlock(&c->erase_free_sem);
return;
}
......@@ -84,14 +84,14 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
if (ret == -ENOMEM || ret == -EAGAIN) {
/* Erase failed immediately. Refile it on the list */
D1(printk(KERN_DEBUG "Erase at 0x%08x failed: %d. Refiling on erase_pending_list\n", jeb->offset, ret));
down(&c->erase_free_sem);
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);
up(&c->erase_free_sem);
mutex_unlock(&c->erase_free_sem);
return;
}
......@@ -107,7 +107,7 @@ void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count)
{
struct jffs2_eraseblock *jeb;
down(&c->erase_free_sem);
mutex_lock(&c->erase_free_sem);
spin_lock(&c->erase_completion_lock);
......@@ -118,7 +118,7 @@ void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count)
jeb = list_entry(c->erase_complete_list.next, struct jffs2_eraseblock, list);
list_del(&jeb->list);
spin_unlock(&c->erase_completion_lock);
up(&c->erase_free_sem);
mutex_unlock(&c->erase_free_sem);
jffs2_mark_erased_block(c, jeb);
if (!--count) {
......@@ -139,7 +139,7 @@ void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count)
jffs2_free_jeb_node_refs(c, jeb);
list_add(&jeb->list, &c->erasing_list);
spin_unlock(&c->erase_completion_lock);
up(&c->erase_free_sem);
mutex_unlock(&c->erase_free_sem);
jffs2_erase_block(c, jeb);
......@@ -149,12 +149,12 @@ void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count)
/* Be nice */
yield();
down(&c->erase_free_sem);
mutex_lock(&c->erase_free_sem);
spin_lock(&c->erase_completion_lock);
}
spin_unlock(&c->erase_completion_lock);
up(&c->erase_free_sem);
mutex_unlock(&c->erase_free_sem);
done:
D1(printk(KERN_DEBUG "jffs2_erase_pending_blocks completed\n"));
}
......@@ -162,11 +162,11 @@ void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count)
static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
{
D1(printk(KERN_DEBUG "Erase completed successfully at 0x%08x\n", jeb->offset));
down(&c->erase_free_sem);
mutex_lock(&c->erase_free_sem);
spin_lock(&c->erase_completion_lock);
list_move_tail(&jeb->list, &c->erase_complete_list);
spin_unlock(&c->erase_completion_lock);
up(&c->erase_free_sem);
mutex_unlock(&c->erase_free_sem);
/* Ensure that kupdated calls us again to mark them clean */
jffs2_erase_pending_trigger(c);
}
......@@ -180,26 +180,26 @@ static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock
failed too many times. */
if (!jffs2_write_nand_badblock(c, jeb, bad_offset)) {
/* We'd like to give this block another try. */
down(&c->erase_free_sem);
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);
up(&c->erase_free_sem);
mutex_unlock(&c->erase_free_sem);
return;
}
}
down(&c->erase_free_sem);
mutex_lock(&c->erase_free_sem);
spin_lock(&c->erase_completion_lock);
c->erasing_size -= c->sector_size;
c->bad_size += c->sector_size;
list_move(&jeb->list, &c->bad_list);
c->nr_erasing_blocks--;
spin_unlock(&c->erase_completion_lock);
up(&c->erase_free_sem);
mutex_unlock(&c->erase_free_sem);
wake_up(&c->erase_wait);
}
......@@ -456,7 +456,7 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
jffs2_link_node_ref(c, jeb, jeb->offset | REF_NORMAL, c->cleanmarker_size, NULL);
}
down(&c->erase_free_sem);
mutex_lock(&c->erase_free_sem);
spin_lock(&c->erase_completion_lock);
c->erasing_size -= c->sector_size;
c->free_size += jeb->free_size;
......@@ -469,28 +469,28 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
c->nr_erasing_blocks--;
c->nr_free_blocks++;
spin_unlock(&c->erase_completion_lock);
up(&c->erase_free_sem);
mutex_unlock(&c->erase_free_sem);
wake_up(&c->erase_wait);
return;
filebad:
down(&c->erase_free_sem);
mutex_lock(&c->erase_free_sem);
spin_lock(&c->erase_completion_lock);
/* Stick it on a list (any list) so erase_failed can take it
right off again. Silly, but shouldn't happen often. */
list_add(&jeb->list, &c->erasing_list);
spin_unlock(&c->erase_completion_lock);
up(&c->erase_free_sem);
mutex_unlock(&c->erase_free_sem);
jffs2_erase_failed(c, jeb, bad_offset);
return;
refile:
/* Stick it back on the list from whence it came and come back later */
jffs2_erase_pending_trigger(c);
down(&c->erase_free_sem);
mutex_lock(&c->erase_free_sem);
spin_lock(&c->erase_completion_lock);
list_add(&jeb->list, &c->erase_complete_list);
spin_unlock(&c->erase_completion_lock);
up(&c->erase_free_sem);
mutex_unlock(&c->erase_free_sem);
return;
}
......@@ -115,9 +115,9 @@ static int jffs2_readpage (struct file *filp, struct page *pg)
struct jffs2_inode_info *f = JFFS2_INODE_INFO(pg->mapping->host);
int ret;
down(&f->sem);
mutex_lock(&f->sem);
ret = jffs2_do_readpage_unlock(pg->mapping->host, pg);
up(&f->sem);
mutex_unlock(&f->sem);
return ret;
}
......@@ -154,7 +154,7 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
if (ret)
goto out_page;
down(&f->sem);
mutex_lock(&f->sem);
memset(&ri, 0, sizeof(ri));
ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
......@@ -181,7 +181,7 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
if (IS_ERR(fn)) {
ret = PTR_ERR(fn);
jffs2_complete_reservation(c);
up(&f->sem);
mutex_unlock(&f->sem);
goto out_page;
}
ret = jffs2_add_full_dnode_to_inode(c, f, fn);
......@@ -195,12 +195,12 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
jffs2_mark_node_obsolete(c, fn->raw);
jffs2_free_full_dnode(fn);
jffs2_complete_reservation(c);
up(&f->sem);
mutex_unlock(&f->sem);
goto out_page;
}
jffs2_complete_reservation(c);
inode->i_size = pageofs;
up(&f->sem);
mutex_unlock(&f->sem);
}
/*
......@@ -209,9 +209,9 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
* case of a short-copy.
*/
if (!PageUptodate(pg)) {
down(&f->sem);
mutex_lock(&f->sem);
ret = jffs2_do_readpage_nolock(inode, pg);
up(&f->sem);
mutex_unlock(&f->sem);
if (ret)
goto out_page;
}
......
......@@ -51,20 +51,20 @@ int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
mdata = (char *)&dev;
D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of kdev_t\n", mdatalen));
} else if (S_ISLNK(inode->i_mode)) {
down(&f->sem);
mutex_lock(&f->sem);
mdatalen = f->metadata->size;
mdata = kmalloc(f->metadata->size, GFP_USER);
if (!mdata) {
up(&f->sem);
mutex_unlock(&f->sem);
return -ENOMEM;
}
ret = jffs2_read_dnode(c, f, f->metadata, mdata, 0, mdatalen);
if (ret) {
up(&f->sem);
mutex_unlock(&f->sem);
kfree(mdata);
return ret;
}
up(&f->sem);
mutex_unlock(&f->sem);
D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of symlink target\n", mdatalen));
}
......@@ -83,7 +83,7 @@ int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
kfree(mdata);
return ret;
}
down(&f->sem);
mutex_lock(&f->sem);
ivalid = iattr->ia_valid;
ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
......@@ -134,7 +134,7 @@ int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
if (IS_ERR(new_metadata)) {
jffs2_complete_reservation(c);
jffs2_free_raw_inode(ri);
up(&f->sem);
mutex_unlock(&f->sem);
return PTR_ERR(new_metadata);
}
/* It worked. Update the inode */
......@@ -165,7 +165,7 @@ int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
}
jffs2_free_raw_inode(ri);
up(&f->sem);
mutex_unlock(&f->sem);
jffs2_complete_reservation(c);
/* We have to do the vmtruncate() without f->sem held, since
......@@ -256,12 +256,12 @@ struct inode *jffs2_iget(struct super_block *sb, unsigned long ino)
c = JFFS2_SB_INFO(inode->i_sb);
jffs2_init_inode_info(f);
down(&f->sem);
mutex_lock(&f->sem);
ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);
if (ret) {
up(&f->sem);
mutex_unlock(&f->sem);
iget_failed(inode);
return ERR_PTR(ret);
}
......@@ -338,7 +338,7 @@ struct inode *jffs2_iget(struct super_block *sb, unsigned long ino)
printk(KERN_WARNING "jffs2_read_inode(): Bogus imode %o for ino %lu\n", inode->i_mode, (unsigned long)inode->i_ino);
}
up(&f->sem);
mutex_unlock(&f->sem);
D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n"));
unlock_new_inode(inode);
......@@ -347,7 +347,7 @@ struct inode *jffs2_iget(struct super_block *sb, unsigned long ino)
error_io:
ret = -EIO;
error:
up(&f->sem);
mutex_unlock(&f->sem);
jffs2_do_clear_inode(c, f);
iget_failed(inode);
return ERR_PTR(ret);
......@@ -388,9 +388,9 @@ int jffs2_remount_fs (struct super_block *sb, int *flags, char *data)
Flush the writebuffer, if neccecary, else we loose it */
if (!(sb->s_flags & MS_RDONLY)) {
jffs2_stop_garbage_collect_thread(c);
down(&c->alloc_sem);
mutex_lock(&c->alloc_sem);
jffs2_flush_wbuf_pad(c);
up(&c->alloc_sem);
mutex_unlock(&c->alloc_sem);
}
if (!(*flags & MS_RDONLY))
......@@ -437,7 +437,7 @@ struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_i
f = JFFS2_INODE_INFO(inode);
jffs2_init_inode_info(f);
down(&f->sem);
mutex_lock(&f->sem);
memset(ri, 0, sizeof(*ri));
/* Set OS-specific defaults for new inodes */
......
......@@ -126,7 +126,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
int ret = 0, inum, nlink;
int xattr = 0;
if (down_interruptible(&c->alloc_sem))
if (mutex_lock_interruptible(&c->alloc_sem))
return -EINTR;
for (;;) {
......@@ -143,7 +143,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
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;
}
......@@ -190,7 +190,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
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;
......@@ -210,7 +210,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
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;
}
......@@ -223,7 +223,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
if (!jeb) {
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;
}
......@@ -232,7 +232,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
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;
}
......@@ -248,7 +248,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
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();
}
}
......@@ -266,7 +266,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
/* Just mark it obsolete */
jffs2_mark_node_obsolete(c, raw);
}
up(&c->alloc_sem);
mutex_unlock(&c->alloc_sem);
goto eraseit_lock;
}
......@@ -334,7 +334,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
*/
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();
......@@ -345,7 +345,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
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);
......@@ -416,7 +416,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
ret = -ENOSPC;
}
release_sem:
up(&c->alloc_sem);
mutex_unlock(&c->alloc_sem);
eraseit_lock:
/* If we've finished this block, start it erasing */
......@@ -445,7 +445,7 @@ static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_era
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. */
......@@ -525,7 +525,7 @@ static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_era
}
}
upnout:
up(&f->sem);
mutex_unlock(&f->sem);
return ret;
}
......@@ -846,7 +846,7 @@ static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct
/* 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) {
......@@ -899,7 +899,7 @@ static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct
/* 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);