aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/gc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jffs2/gc.c')
-rw-r--r--fs/jffs2/gc.c42
1 files changed, 24 insertions, 18 deletions
diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c
index 32ff0373aa04..bad005664e30 100644
--- a/fs/jffs2/gc.c
+++ b/fs/jffs2/gc.c
@@ -126,7 +126,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
126 int ret = 0, inum, nlink; 126 int ret = 0, inum, nlink;
127 int xattr = 0; 127 int xattr = 0;
128 128
129 if (down_interruptible(&c->alloc_sem)) 129 if (mutex_lock_interruptible(&c->alloc_sem))
130 return -EINTR; 130 return -EINTR;
131 131
132 for (;;) { 132 for (;;) {
@@ -143,7 +143,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
143 c->unchecked_size); 143 c->unchecked_size);
144 jffs2_dbg_dump_block_lists_nolock(c); 144 jffs2_dbg_dump_block_lists_nolock(c);
145 spin_unlock(&c->erase_completion_lock); 145 spin_unlock(&c->erase_completion_lock);
146 up(&c->alloc_sem); 146 mutex_unlock(&c->alloc_sem);
147 return -ENOSPC; 147 return -ENOSPC;
148 } 148 }
149 149
@@ -190,7 +190,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
190 made no progress in this case, but that should be OK */ 190 made no progress in this case, but that should be OK */
191 c->checked_ino--; 191 c->checked_ino--;
192 192
193 up(&c->alloc_sem); 193 mutex_unlock(&c->alloc_sem);
194 sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock); 194 sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
195 return 0; 195 return 0;
196 196
@@ -210,7 +210,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
210 printk(KERN_WARNING "Returned error for crccheck of ino #%u. Expect badness...\n", ic->ino); 210 printk(KERN_WARNING "Returned error for crccheck of ino #%u. Expect badness...\n", ic->ino);
211 211
212 jffs2_set_inocache_state(c, ic, INO_STATE_CHECKEDABSENT); 212 jffs2_set_inocache_state(c, ic, INO_STATE_CHECKEDABSENT);
213 up(&c->alloc_sem); 213 mutex_unlock(&c->alloc_sem);
214 return ret; 214 return ret;
215 } 215 }
216 216
@@ -221,9 +221,15 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
221 jeb = jffs2_find_gc_block(c); 221 jeb = jffs2_find_gc_block(c);
222 222
223 if (!jeb) { 223 if (!jeb) {
224 D1 (printk(KERN_NOTICE "jffs2: Couldn't find erase block to garbage collect!\n")); 224 /* Couldn't find a free block. But maybe we can just erase one and make 'progress'? */
225 if (!list_empty(&c->erase_pending_list)) {
226 spin_unlock(&c->erase_completion_lock);
227 mutex_unlock(&c->alloc_sem);
228 return -EAGAIN;
229 }
230 D1(printk(KERN_NOTICE "jffs2: Couldn't find erase block to garbage collect!\n"));
225 spin_unlock(&c->erase_completion_lock); 231 spin_unlock(&c->erase_completion_lock);
226 up(&c->alloc_sem); 232 mutex_unlock(&c->alloc_sem);
227 return -EIO; 233 return -EIO;
228 } 234 }
229 235
@@ -232,7 +238,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
232 printk(KERN_DEBUG "Nextblock at %08x, used_size %08x, dirty_size %08x, wasted_size %08x, free_size %08x\n", c->nextblock->offset, c->nextblock->used_size, c->nextblock->dirty_size, c->nextblock->wasted_size, c->nextblock->free_size)); 238 printk(KERN_DEBUG "Nextblock at %08x, used_size %08x, dirty_size %08x, wasted_size %08x, free_size %08x\n", c->nextblock->offset, c->nextblock->used_size, c->nextblock->dirty_size, c->nextblock->wasted_size, c->nextblock->free_size));
233 239
234 if (!jeb->used_size) { 240 if (!jeb->used_size) {
235 up(&c->alloc_sem); 241 mutex_unlock(&c->alloc_sem);
236 goto eraseit; 242 goto eraseit;
237 } 243 }
238 244
@@ -248,7 +254,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
248 jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size); 254 jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size);
249 jeb->gc_node = raw; 255 jeb->gc_node = raw;
250 spin_unlock(&c->erase_completion_lock); 256 spin_unlock(&c->erase_completion_lock);
251 up(&c->alloc_sem); 257 mutex_unlock(&c->alloc_sem);
252 BUG(); 258 BUG();
253 } 259 }
254 } 260 }
@@ -266,7 +272,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
266 /* Just mark it obsolete */ 272 /* Just mark it obsolete */
267 jffs2_mark_node_obsolete(c, raw); 273 jffs2_mark_node_obsolete(c, raw);
268 } 274 }
269 up(&c->alloc_sem); 275 mutex_unlock(&c->alloc_sem);
270 goto eraseit_lock; 276 goto eraseit_lock;
271 } 277 }
272 278
@@ -334,7 +340,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
334 */ 340 */
335 printk(KERN_CRIT "Inode #%u already in state %d in jffs2_garbage_collect_pass()!\n", 341 printk(KERN_CRIT "Inode #%u already in state %d in jffs2_garbage_collect_pass()!\n",
336 ic->ino, ic->state); 342 ic->ino, ic->state);
337 up(&c->alloc_sem); 343 mutex_unlock(&c->alloc_sem);
338 spin_unlock(&c->inocache_lock); 344 spin_unlock(&c->inocache_lock);
339 BUG(); 345 BUG();
340 346
@@ -345,7 +351,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
345 the alloc_sem() (for marking nodes invalid) so we must 351 the alloc_sem() (for marking nodes invalid) so we must
346 drop the alloc_sem before sleeping. */ 352 drop the alloc_sem before sleeping. */
347 353
348 up(&c->alloc_sem); 354 mutex_unlock(&c->alloc_sem);
349 D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() waiting for ino #%u in state %d\n", 355 D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() waiting for ino #%u in state %d\n",
350 ic->ino, ic->state)); 356 ic->ino, ic->state));
351 sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock); 357 sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
@@ -416,7 +422,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
416 ret = -ENOSPC; 422 ret = -ENOSPC;
417 } 423 }
418 release_sem: 424 release_sem:
419 up(&c->alloc_sem); 425 mutex_unlock(&c->alloc_sem);
420 426
421 eraseit_lock: 427 eraseit_lock:
422 /* If we've finished this block, start it erasing */ 428 /* If we've finished this block, start it erasing */
@@ -445,7 +451,7 @@ static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_era
445 uint32_t start = 0, end = 0, nrfrags = 0; 451 uint32_t start = 0, end = 0, nrfrags = 0;
446 int ret = 0; 452 int ret = 0;
447 453
448 down(&f->sem); 454 mutex_lock(&f->sem);
449 455
450 /* Now we have the lock for this inode. Check that it's still the one at the head 456 /* Now we have the lock for this inode. Check that it's still the one at the head
451 of the list. */ 457 of the list. */
@@ -525,7 +531,7 @@ static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_era
525 } 531 }
526 } 532 }
527 upnout: 533 upnout:
528 up(&f->sem); 534 mutex_unlock(&f->sem);
529 535
530 return ret; 536 return ret;
531} 537}
@@ -846,7 +852,7 @@ static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct
846 /* Prevent the erase code from nicking the obsolete node refs while 852 /* Prevent the erase code from nicking the obsolete node refs while
847 we're looking at them. I really don't like this extra lock but 853 we're looking at them. I really don't like this extra lock but
848 can't see any alternative. Suggestions on a postcard to... */ 854 can't see any alternative. Suggestions on a postcard to... */
849 down(&c->erase_free_sem); 855 mutex_lock(&c->erase_free_sem);
850 856
851 for (raw = f->inocache->nodes; raw != (void *)f->inocache; raw = raw->next_in_ino) { 857 for (raw = f->inocache->nodes; raw != (void *)f->inocache; raw = raw->next_in_ino) {
852 858
@@ -899,7 +905,7 @@ static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct
899 /* OK. The name really does match. There really is still an older node on 905 /* OK. The name really does match. There really is still an older node on
900 the flash which our deletion dirent obsoletes. So we have to write out 906 the flash which our deletion dirent obsoletes. So we have to write out
901 a new deletion dirent to replace it */ 907 a new deletion dirent to replace it */
902 up(&c->erase_free_sem); 908 mutex_unlock(&c->erase_free_sem);
903 909
904 D1(printk(KERN_DEBUG "Deletion dirent at %08x still obsoletes real dirent \"%s\" at %08x for ino #%u\n", 910 D1(printk(KERN_DEBUG "Deletion dirent at %08x still obsoletes real dirent \"%s\" at %08x for ino #%u\n",
905 ref_offset(fd->raw), fd->name, ref_offset(raw), je32_to_cpu(rd->ino))); 911 ref_offset(fd->raw), fd->name, ref_offset(raw), je32_to_cpu(rd->ino)));
@@ -908,7 +914,7 @@ static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct
908 return jffs2_garbage_collect_dirent(c, jeb, f, fd); 914 return jffs2_garbage_collect_dirent(c, jeb, f, fd);
909 } 915 }
910 916
911 up(&c->erase_free_sem); 917 mutex_unlock(&c->erase_free_sem);
912 kfree(rd); 918 kfree(rd);
913 } 919 }
914 920
@@ -1081,7 +1087,7 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
1081 return 0; 1087 return 0;
1082} 1088}
1083 1089
1084static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 1090static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *orig_jeb,
1085 struct jffs2_inode_info *f, struct jffs2_full_dnode *fn, 1091 struct jffs2_inode_info *f, struct jffs2_full_dnode *fn,
1086 uint32_t start, uint32_t end) 1092 uint32_t start, uint32_t end)
1087{ 1093{