LCOV - code coverage report
Current view: top level - fs/jffs2 - background.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 48 0.0 %
Date: 2014-02-18 Functions: 0 4 0.0 %
Branches: 0 31 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * JFFS2 -- Journalling Flash File System, Version 2.
       3                 :            :  *
       4                 :            :  * Copyright © 2001-2007 Red Hat, Inc.
       5                 :            :  * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
       6                 :            :  *
       7                 :            :  * Created by David Woodhouse <dwmw2@infradead.org>
       8                 :            :  *
       9                 :            :  * For licensing information, see the file 'LICENCE' in this directory.
      10                 :            :  *
      11                 :            :  */
      12                 :            : 
      13                 :            : #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
      14                 :            : 
      15                 :            : #include <linux/kernel.h>
      16                 :            : #include <linux/jffs2.h>
      17                 :            : #include <linux/mtd/mtd.h>
      18                 :            : #include <linux/completion.h>
      19                 :            : #include <linux/sched.h>
      20                 :            : #include <linux/freezer.h>
      21                 :            : #include <linux/kthread.h>
      22                 :            : #include "nodelist.h"
      23                 :            : 
      24                 :            : 
      25                 :            : static int jffs2_garbage_collect_thread(void *);
      26                 :            : 
      27                 :          0 : void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c)
      28                 :            : {
      29         [ #  # ]:          0 :         assert_spin_locked(&c->erase_completion_lock);
      30 [ #  # ][ #  # ]:          0 :         if (c->gc_task && jffs2_thread_should_wake(c))
      31                 :          0 :                 send_sig(SIGHUP, c->gc_task, 1);
      32                 :          0 : }
      33                 :            : 
      34                 :            : /* This must only ever be called when no GC thread is currently running */
      35                 :          0 : int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c)
      36                 :            : {
      37                 :            :         struct task_struct *tsk;
      38                 :            :         int ret = 0;
      39                 :            : 
      40         [ #  # ]:          0 :         BUG_ON(c->gc_task);
      41                 :            : 
      42                 :            :         init_completion(&c->gc_thread_start);
      43                 :            :         init_completion(&c->gc_thread_exit);
      44                 :            : 
      45         [ #  # ]:          0 :         tsk = kthread_run(jffs2_garbage_collect_thread, c, "jffs2_gcd_mtd%d", c->mtd->index);
      46         [ #  # ]:          0 :         if (IS_ERR(tsk)) {
      47                 :          0 :                 pr_warn("fork failed for JFFS2 garbage collect thread: %ld\n",
      48                 :            :                         -PTR_ERR(tsk));
      49                 :          0 :                 complete(&c->gc_thread_exit);
      50                 :            :                 ret = PTR_ERR(tsk);
      51                 :            :         } else {
      52                 :            :                 /* Wait for it... */
      53                 :            :                 jffs2_dbg(1, "Garbage collect thread is pid %d\n", tsk->pid);
      54                 :          0 :                 wait_for_completion(&c->gc_thread_start);
      55                 :          0 :                 ret = tsk->pid;
      56                 :            :         }
      57                 :            : 
      58                 :          0 :         return ret;
      59                 :            : }
      60                 :            : 
      61                 :          0 : void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c)
      62                 :            : {
      63                 :            :         int wait = 0;
      64                 :            :         spin_lock(&c->erase_completion_lock);
      65         [ #  # ]:          0 :         if (c->gc_task) {
      66                 :            :                 jffs2_dbg(1, "Killing GC task %d\n", c->gc_task->pid);
      67                 :          0 :                 send_sig(SIGKILL, c->gc_task, 1);
      68                 :            :                 wait = 1;
      69                 :            :         }
      70                 :            :         spin_unlock(&c->erase_completion_lock);
      71         [ #  # ]:          0 :         if (wait)
      72                 :          0 :                 wait_for_completion(&c->gc_thread_exit);
      73                 :          0 : }
      74                 :            : 
      75                 :          0 : static int jffs2_garbage_collect_thread(void *_c)
      76                 :            : {
      77                 :            :         struct jffs2_sb_info *c = _c;
      78                 :            : 
      79                 :          0 :         allow_signal(SIGKILL);
      80                 :          0 :         allow_signal(SIGSTOP);
      81                 :          0 :         allow_signal(SIGCONT);
      82                 :            : 
      83                 :          0 :         c->gc_task = current;
      84                 :          0 :         complete(&c->gc_thread_start);
      85                 :            : 
      86                 :          0 :         set_user_nice(current, 10);
      87                 :            : 
      88                 :          0 :         set_freezable();
      89                 :            :         for (;;) {
      90                 :          0 :                 allow_signal(SIGHUP);
      91                 :            :         again:
      92                 :            :                 spin_lock(&c->erase_completion_lock);
      93         [ #  # ]:          0 :                 if (!jffs2_thread_should_wake(c)) {
      94                 :          0 :                         set_current_state (TASK_INTERRUPTIBLE);
      95                 :            :                         spin_unlock(&c->erase_completion_lock);
      96                 :            :                         jffs2_dbg(1, "%s(): sleeping...\n", __func__);
      97                 :          0 :                         schedule();
      98                 :            :                 } else
      99                 :            :                         spin_unlock(&c->erase_completion_lock);
     100                 :            :                         
     101                 :            : 
     102                 :            :                 /* Problem - immediately after bootup, the GCD spends a lot
     103                 :            :                  * of time in places like jffs2_kill_fragtree(); so much so
     104                 :            :                  * that userspace processes (like gdm and X) are starved
     105                 :            :                  * despite plenty of cond_resched()s and renicing.  Yield()
     106                 :            :                  * doesn't help, either (presumably because userspace and GCD
     107                 :            :                  * are generally competing for a higher latency resource -
     108                 :            :                  * disk).
     109                 :            :                  * This forces the GCD to slow the hell down.   Pulling an
     110                 :            :                  * inode in with read_inode() is much preferable to having
     111                 :            :                  * the GC thread get there first. */
     112                 :          0 :                 schedule_timeout_interruptible(msecs_to_jiffies(50));
     113                 :            : 
     114         [ #  # ]:          0 :                 if (kthread_should_stop()) {
     115                 :            :                         jffs2_dbg(1, "%s(): kthread_stop() called\n", __func__);
     116                 :            :                         goto die;
     117                 :            :                 }
     118                 :            : 
     119                 :            :                 /* Put_super will send a SIGKILL and then wait on the sem.
     120                 :            :                  */
     121 [ #  # ][ #  # ]:          0 :                 while (signal_pending(current) || freezing(current)) {
     122                 :            :                         siginfo_t info;
     123                 :            :                         unsigned long signr;
     124                 :            : 
     125         [ #  # ]:          0 :                         if (try_to_freeze())
     126                 :            :                                 goto again;
     127                 :            : 
     128                 :          0 :                         signr = dequeue_signal_lock(current, &current->blocked, &info);
     129                 :            : 
     130      [ #  #  # ]:          0 :                         switch(signr) {
     131                 :            :                         case SIGSTOP:
     132                 :            :                                 jffs2_dbg(1, "%s(): SIGSTOP received\n",
     133                 :            :                                           __func__);
     134                 :          0 :                                 set_current_state(TASK_STOPPED);
     135                 :          0 :                                 schedule();
     136                 :          0 :                                 break;
     137                 :            : 
     138                 :            :                         case SIGKILL:
     139                 :            :                                 jffs2_dbg(1, "%s(): SIGKILL received\n",
     140                 :            :                                           __func__);
     141                 :          0 :                                 goto die;
     142                 :            : 
     143                 :            :                         case SIGHUP:
     144                 :            :                                 jffs2_dbg(1, "%s(): SIGHUP received\n",
     145                 :            :                                           __func__);
     146                 :            :                                 break;
     147                 :            :                         default:
     148                 :            :                                 jffs2_dbg(1, "%s(): signal %ld received\n",
     149                 :            :                                           __func__, signr);
     150                 :            :                         }
     151                 :            :                 }
     152                 :            :                 /* We don't want SIGHUP to interrupt us. STOP and KILL are OK though. */
     153                 :          0 :                 disallow_signal(SIGHUP);
     154                 :            : 
     155                 :            :                 jffs2_dbg(1, "%s(): pass\n", __func__);
     156         [ #  # ]:          0 :                 if (jffs2_garbage_collect_pass(c) == -ENOSPC) {
     157                 :          0 :                         pr_notice("No space for garbage collection. Aborting GC thread\n");
     158                 :          0 :                         goto die;
     159                 :            :                 }
     160                 :            :         }
     161                 :            :  die:
     162                 :            :         spin_lock(&c->erase_completion_lock);
     163                 :          0 :         c->gc_task = NULL;
     164                 :            :         spin_unlock(&c->erase_completion_lock);
     165                 :          0 :         complete_and_exit(&c->gc_thread_exit, 0);
     166                 :            : }

Generated by: LCOV version 1.9