linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [JFFS2 & UMOUNT/VFS] is it safe to iget() during unmount?
@ 2004-12-16 11:12 Artem B. Bityuckiy
  2004-12-28 18:45 ` Artem B. Bityuckiy
  0 siblings, 1 reply; 2+ messages in thread
From: Artem B. Bityuckiy @ 2004-12-16 11:12 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: David Woodhouse

Hello.

I've hit on one problem with JFFS2. In JFFS2 there is a kernel thread 
(called GC thread)
which just performs the background auxiliary job. This thread may issue 
the iget() call to obtain inodes.

On JFFS2 unmount, the GC thread is killed in put_super() call. The 
following are some extracts from fs/jffs2/super.c code:

/* The put_super VFS callback */
static void jffs2_put_super (struct super_block *sb)
{
  ... bla ... bla ...
  jffs2_stop_garbage_collect_thread(c); /* KILL GC thread */
  ... other bla bla bla ...
}

/* The kill_sb VFS callback */
static void jffs2_kill_sb(struct super_block *sb)
{
  .. bla ...
  generic_shutdown_super(sb);
  .. bla ...
}

The situation when my problem arises is:
1. JFFS2 umount call is issued from the user space.
2. The generic_shutdown_super() VFS function is called. The code of 
the generic_shutdown_super() function is at the end of this letter, for 
reference (kernel 2.6.10-rcX).
3. The generic_shutdown_super() function is preempted  somewhere in the 
middle, the sop->put_super(sb) is not called yet. I do not know where 
exactly is it preempted, guess somewhere between sop->write_super(sb) and 
sop->put_super(sb).
4. The GC thread wakes up and starts working (it was not killed yet since 
the put_super was not called yet). GC thread calls iget for inode which is 
for sure in the inode cache since there was not clear_inode call yet. But 
VFS calls read_inode for that inode. And nasty things start from this 
point.

I've offered patch to JFFS2 which changes it to kill the GC thread 
*before* calling the generic_shutdown_super(), in kill_sb, like this:

/* The put_super VFS callback */
static void jffs2_put_super (struct super_block *sb)
{
  ... bla ... bla ...
  jffs2_stop_garbage_collect_thread(c); /* KILL GC thread */
  generic_shutdown_super(sb);
  ... other bla bla bla ...
}

This solves problems at least in my case. But I was referred to the VFS 
developers list and asked to ask  Al Viro's comments.

So, Al or somebody else, could you please coment this? Is it allowed to 
call iget() during unmount()? Why?

P.S: CC me since I'm not in the list.

Thanks.



void generic_shutdown_super(struct super_block *sb)
{
        struct dentry *root = sb->s_root;
        struct super_operations *sop = sb->s_op;
                                                                                                                                             
        if (root) {
                sb->s_root = NULL;
                shrink_dcache_parent(root);
                shrink_dcache_anon(&sb->s_anon);
                dput(root);
                fsync_super(sb);
                lock_super(sb);
                lock_kernel();
                sb->s_flags &= ~MS_ACTIVE;
                /* bad name - it should be evict_inodes() */
                invalidate_inodes(sb);
                                                                                                                                             
                if (sop->write_super && sb->s_dirt)
                        sop->write_super(sb);
                if (sop->put_super)
                        sop->put_super(sb);
                                                                                                                                             
                /* Forget any remaining inodes */
                if (invalidate_inodes(sb)) {
                        printk("VFS: Busy inodes after unmount. "
                           "Self-destruct in 5 seconds.  Have a nice 
day...\n");
                }
                                                                                                                                             
                unlock_kernel();
                unlock_super(sb);
        }
        spin_lock(&sb_lock);
        /* should be initialized for __put_super_and_need_restart() */
        list_del_init(&sb->s_list);
        list_del(&sb->s_instances);
        spin_unlock(&sb_lock);
        up_write(&sb->s_umount);
}

--
Best Regards,
Artem B. Bityuckiy,
St.-Petersburg, Russia.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2004-12-28 18:45 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-12-16 11:12 [JFFS2 & UMOUNT/VFS] is it safe to iget() during unmount? Artem B. Bityuckiy
2004-12-28 18:45 ` Artem B. Bityuckiy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).