#4536 closed defect (invalid)

acess JFFS2 sb->s_root

Reported by: chenjin_zhong Owned by:
Priority: normal Milestone: 5.1
Component: fs/jffs2 Version: 5
Severity: normal Keywords:
Cc: Blocked By:
Blocking:

Description

Hi, I have found when access global structure without mutex or spinlock about JFFS2 may cause indetermination. The peice of source code in RTEMS5.1 are listed as follows:

fs-rtems.c:

1) Add to the icache

for (cached_inode = sb->s_root; cached_inode != NULL;

cached_inode = cached_inode->i_cache_next) {

if (cached_inode->i_cache_next == NULL) {

cached_inode->i_cache_next = inode; Current last in cache points to newcomer
inode->i_cache_prev = cached_inode;
Newcomer points back to last
break;

}

}

2) Check for this inode in the cache

for (inode = sb->s_root; inode != NULL; inode = inode->i_cache_next) {

if (inode->i_ino == ino) {

inode->i_count++;
break;

}

}

when multi-tasks or threads access sb->s_root simultaneously, The behavior is unknown.

Change History (4)

comment:1 Changed on 10/28/21 at 05:19:37 by Sebastian Huber

Resolution: invalid
Status: newclosed

Thanks for your interest in the RTEMS port of JFFS2. If you have questions, then you could also ask them on the devel@… mailing list. The RTEMS port of JFFS2 does not use a file system internal locking. There is a global lock for each JFFS2 instance:

static void rtems_jffs2_do_lock(struct super_block *sb)
{
        rtems_recursive_mutex_lock(&sb->s_mutex);
}

static void rtems_jffs2_do_unlock(struct super_block *sb)
{
        rtems_recursive_mutex_unlock(&sb->s_mutex);
}

comment:2 Changed on 10/28/21 at 05:21:30 by Sebastian Huber

Component: adminfs/jaffs2

comment:3 in reply to:  1 ; Changed on 10/28/21 at 14:53:51 by chenjin_zhong

Resolution: invalid
Status: closedreopened

Replying to Sebastian Huber:

Thanks for your interest in the RTEMS port of JFFS2. If you have questions, then you could also ask them on the devel@… mailing list. The RTEMS port of JFFS2 does not use a file system internal locking. There is a global lock for each JFFS2 instance:

static void rtems_jffs2_do_lock(struct super_block *sb)
{
        rtems_recursive_mutex_lock(&sb->s_mutex);
}

static void rtems_jffs2_do_unlock(struct super_block *sb)
{
        rtems_recursive_mutex_unlock(&sb->s_mutex);
}

Suppose that a GC thread or other thread/task calls jffs2_garbage_collect_pass, and then operates sb->s_root by jffs2_iget.meanwhile, the main task accesing sb->s_root. a global lock for each JFFS2 instance can't work.

comment:4 in reply to:  3 Changed on 10/28/21 at 18:29:00 by Sebastian Huber

Resolution: invalid
Status: reopenedclosed

Replying to chenjin_zhong:

Replying to Sebastian Huber:

Thanks for your interest in the RTEMS port of JFFS2. If you have questions, then you could also ask them on the devel@… mailing list. The RTEMS port of JFFS2 does not use a file system internal locking. There is a global lock for each JFFS2 instance:

static void rtems_jffs2_do_lock(struct super_block *sb)
{
        rtems_recursive_mutex_lock(&sb->s_mutex);
}

static void rtems_jffs2_do_unlock(struct super_block *sb)
{
        rtems_recursive_mutex_unlock(&sb->s_mutex);
}

Suppose that a GC thread or other thread/task calls jffs2_garbage_collect_pass, and then operates sb->s_root by jffs2_iget.meanwhile, the main task accesing sb->s_root. a global lock for each JFFS2 instance can't work.

It is not a high performance approach, but it works. See testsuites/fstests/fsjffs2gc01/init.c.

Note: See TracTickets for help on using tickets.