Skip to content

Commit

Permalink
[JFFS2] semaphore->mutex conversion
Browse files Browse the repository at this point in the history
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
  • Loading branch information
dwmw2 committed Apr 22, 2008
1 parent 52f8301 commit ced2207
Show file tree
Hide file tree
Showing 14 changed files with 168 additions and 167 deletions.
22 changes: 11 additions & 11 deletions fs/jffs2/README.Locking
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand All @@ -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.


Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions fs/jffs2/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
58 changes: 29 additions & 29 deletions fs/jffs2/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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)) {
Expand Down Expand Up @@ -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++;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -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);

Expand Down Expand Up @@ -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);
Expand All @@ -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);
}
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);

Expand Down Expand Up @@ -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);
Expand All @@ -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);
}
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);

Expand Down Expand Up @@ -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);
Expand All @@ -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);
}
Expand All @@ -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);
Expand All @@ -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);
}
}

Expand Down Expand Up @@ -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);
}
}

Expand All @@ -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 */
Expand Down
Loading

0 comments on commit ced2207

Please sign in to comment.