• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <linux/kernel.h>
14 #include <stdio.h>
15 #include "nodelist.h"
16 #include "vfs_jffs2.h"
17 #include "mtd_partition.h"
18 
19 #define GC_THREAD_FLAG_TRIG 1
20 #define GC_THREAD_FLAG_STOP 2
21 #define GC_THREAD_FLAG_HAS_EXIT 4
22 
23 extern struct MtdNorDev *jffs2_dev_list;
24 static void jffs2_garbage_collect_thread(unsigned long data);
25 
jffs2_garbage_collect_trigger(struct jffs2_sb_info * c)26 void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c)
27 {
28 	struct super_block *sb = OFNI_BS_2SFFJ(c);
29 	/* Wake up the thread */
30 	jffs2_dbg(1, "jffs2_garbage_collect_trigger\n");
31 	LOS_EventWrite(&sb->s_gc_thread_flags, GC_THREAD_FLAG_TRIG);
32 }
33 
34 /* This must only ever be called when no GC thread is currently running */
jffs2_start_garbage_collect_thread(struct jffs2_sb_info * c)35 void jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c)
36 {
37 	struct super_block *sb = OFNI_BS_2SFFJ(c);
38 	TSK_INIT_PARAM_S stGcTask;
39 
40 	if (c == NULL)
41 		return;
42 
43 	if (sb->s_root == NULL)
44 		return;
45 
46 	LOS_EventInit(&sb->s_gc_thread_flags);
47 
48 	/* Start the thread. Doesn't matter if it fails -- it's only an
49 	 * optimisation anyway */
50 	(void)memset_s(&stGcTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
51 
52 	stGcTask.pfnTaskEntry = (TSK_ENTRY_FUNC)jffs2_garbage_collect_thread;
53 	stGcTask.auwArgs[0] = (UINTPTR)c;
54 	stGcTask.uwStackSize  = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
55 	stGcTask.pcName = "jffs2_gc_thread";
56 #ifdef LOSCFG_KERNEL_SMP
57 	unsigned int i;
58 	for (i = 0; i < CONFIG_MTD_PATTITION_NUM; i++) {
59 		if (sb->s_dev == &jffs2_dev_list[i])
60 			break;
61 	}
62 	stGcTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(i % LOSCFG_KERNEL_CORE_NUM);
63 #endif
64 	stGcTask.usTaskPrio = JFFS2_GC_THREAD_PRIORITY;
65 
66 	if (LOS_TaskCreate(&sb->s_gc_thread, &stGcTask))
67 		JFFS2_ERROR("Create gc task failed!!!\n");
68 }
69 
jffs2_stop_garbage_collect_thread(struct jffs2_sb_info * c)70 void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c)
71 {
72 	struct super_block *sb = OFNI_BS_2SFFJ(c);
73 
74 	JFFS2_DEBUG("jffs2_stop_garbage_collect_thread\n");
75 	/* Stop the thread and wait for it if necessary */
76 
77 	LOS_EventWrite(&sb->s_gc_thread_flags, GC_THREAD_FLAG_STOP);
78 
79 	JFFS2_DEBUG("jffs2_stop_garbage_collect_thread wait\n");
80 
81 	(void)LOS_EventRead(&sb->s_gc_thread_flags,
82 			GC_THREAD_FLAG_HAS_EXIT,
83 			LOS_WAITMODE_OR | LOS_WAITMODE_CLR,
84 			LOS_WAIT_FOREVER);
85 
86 	// Kill and free the resources ...  this is safe due to the flag
87 	// from the thread.
88 	(void)LOS_TaskDelete(sb->s_gc_thread);
89 	(void)LOS_EventWrite(&sb->s_gc_thread_flags, 0xFFFFFFFF);
90 }
91 
jffs2_garbage_collect_thread(unsigned long data)92 static void jffs2_garbage_collect_thread(unsigned long data)
93 {
94 	struct jffs2_sb_info *c = (struct jffs2_sb_info *)data;
95 	struct super_block *sb = OFNI_BS_2SFFJ(c);
96 	unsigned int flag = 0;
97 
98 	jffs2_dbg(1, "jffs2_garbage_collect_thread START\n");
99 	while(1) {
100 		flag = LOS_EventRead(&sb->s_gc_thread_flags,
101 			GC_THREAD_FLAG_TRIG | GC_THREAD_FLAG_STOP,
102 			LOS_WAITMODE_OR | LOS_WAITMODE_CLR,
103 			LOS_WAIT_FOREVER
104 		);
105 		if (flag & GC_THREAD_FLAG_STOP)
106 			break;
107 
108 		jffs2_dbg(1, "jffs2: GC THREAD GC BEGIN\n");
109 
110 		if (sb->s_root == NULL)
111 			return;
112 
113 		if (jffs2_garbage_collect_pass(c) == -ENOSPC) {
114 			PRINTK("No space for garbage collection. "
115 			"Aborting JFFS2 GC thread\n");
116 			break;
117 		}
118 		jffs2_dbg(1, "jffs2: GC THREAD GC END\n");
119 	}
120 	JFFS2_DEBUG("jffs2_garbage_collect_thread EXIT\n");
121 	LOS_EventWrite(&sb->s_gc_thread_flags, GC_THREAD_FLAG_HAS_EXIT);
122 }
123