diff options
Diffstat (limited to 'fs/jffs2/gc.c')
-rw-r--r-- | fs/jffs2/gc.c | 42 |
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 | ||
1084 | static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, | 1090 | static 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 | { |