diff mbox series

[2/3] jffs2: jffs2_iget defer f->sem acquisition

Message ID 95327ddd01e86d0160c2d678f4306a737cb6a085.1524823321.git.h.grohne@intenta.de
State New, archived
Delegated to: David Woodhouse
Headers show
Series jffs2: fix lockdep warning | expand

Commit Message

Helmut Grohne April 27, 2018, 10:30 a.m. UTC
At the point where f->sem is taken, we know that we have a locked I_NEW
inode. Since jffs2_iget is the only function processing I_NEW inodes and
iget_locked blocks on I_NEW inodes, we know that we are the only user of
the inode until we unlock_new_inode it. Since 7aaea7605c0 ("jffs2: fix
unbalanced locking"), jffs2_do_read_inode no longer touches f->sem and
does not make the inode visible to others either. Thus we can call it
without f->sem acquired. Nextup, inode->i_mode is protected until
unlock_new_inode.

After deferring the locking, we can decide upon the proper lock class
depending on inode->i_mode.

Signed-off-by: Helmut Grohne <h.grohne@intenta.de>
Cc: Peter Zijlstra <peterz@infradead.org>
---
 fs/jffs2/fs.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Comments

Richard Weinberger Dec. 16, 2018, 11:41 p.m. UTC | #1
On Fri, Apr 27, 2018 at 12:37 PM Helmut Grohne <h.grohne@intenta.de> wrote:
>
> At the point where f->sem is taken, we know that we have a locked I_NEW
> inode. Since jffs2_iget is the only function processing I_NEW inodes and
> iget_locked blocks on I_NEW inodes, we know that we are the only user of
> the inode until we unlock_new_inode it. Since 7aaea7605c0 ("jffs2: fix
> unbalanced locking"), jffs2_do_read_inode no longer touches f->sem and
> does not make the inode visible to others either. Thus we can call it
> without f->sem acquired. Nextup, inode->i_mode is protected until
> unlock_new_inode.
>
> After deferring the locking, we can decide upon the proper lock class
> depending on inode->i_mode.
>
> Signed-off-by: Helmut Grohne <h.grohne@intenta.de>
> Cc: Peter Zijlstra <peterz@infradead.org>

Reviewed-by: Richard Weinberger <richard@nod.at>
diff mbox series

Patch

diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index eab04eca95a3..89a10b398d00 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -270,13 +270,15 @@  struct inode *jffs2_iget(struct super_block *sb, unsigned long ino)
 	c = JFFS2_SB_INFO(inode->i_sb);
 
 	jffs2_init_inode_info(f);
-	mutex_lock(&f->sem);
 
 	ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);
 	if (ret)
 		goto error;
 
 	inode->i_mode = jemode_to_cpu(latest_node.mode);
+
+	mutex_lock(&f->sem);
+
 	i_uid_write(inode, je16_to_cpu(latest_node.uid));
 	i_gid_write(inode, je16_to_cpu(latest_node.gid));
 	inode->i_size = je32_to_cpu(latest_node.isize);