aboutsummaryrefslogtreecommitdiffstats
path: root/fs/squashfs/cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/squashfs/cache.c')
-rw-r--r--fs/squashfs/cache.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/fs/squashfs/cache.c b/fs/squashfs/cache.c
index f744be98cd5a..af0b73802592 100644
--- a/fs/squashfs/cache.c
+++ b/fs/squashfs/cache.c
@@ -70,11 +70,15 @@ struct squashfs_cache_entry *squashfs_cache_get(struct super_block *sb,
70 spin_lock(&cache->lock); 70 spin_lock(&cache->lock);
71 71
72 while (1) { 72 while (1) {
73 for (i = 0; i < cache->entries; i++) 73 for (i = cache->curr_blk, n = 0; n < cache->entries; n++) {
74 if (cache->entry[i].block == block) 74 if (cache->entry[i].block == block) {
75 cache->curr_blk = i;
75 break; 76 break;
77 }
78 i = (i + 1) % cache->entries;
79 }
76 80
77 if (i == cache->entries) { 81 if (n == cache->entries) {
78 /* 82 /*
79 * Block not in cache, if all cache entries are used 83 * Block not in cache, if all cache entries are used
80 * go to sleep waiting for one to become available. 84 * go to sleep waiting for one to become available.
@@ -245,6 +249,7 @@ struct squashfs_cache *squashfs_cache_init(char *name, int entries,
245 goto cleanup; 249 goto cleanup;
246 } 250 }
247 251
252 cache->curr_blk = 0;
248 cache->next_blk = 0; 253 cache->next_blk = 0;
249 cache->unused = entries; 254 cache->unused = entries;
250 cache->entries = entries; 255 cache->entries = entries;
@@ -332,17 +337,20 @@ int squashfs_read_metadata(struct super_block *sb, void *buffer,
332 u64 *block, int *offset, int length) 337 u64 *block, int *offset, int length)
333{ 338{
334 struct squashfs_sb_info *msblk = sb->s_fs_info; 339 struct squashfs_sb_info *msblk = sb->s_fs_info;
335 int bytes, copied = length; 340 int bytes, res = length;
336 struct squashfs_cache_entry *entry; 341 struct squashfs_cache_entry *entry;
337 342
338 TRACE("Entered squashfs_read_metadata [%llx:%x]\n", *block, *offset); 343 TRACE("Entered squashfs_read_metadata [%llx:%x]\n", *block, *offset);
339 344
340 while (length) { 345 while (length) {
341 entry = squashfs_cache_get(sb, msblk->block_cache, *block, 0); 346 entry = squashfs_cache_get(sb, msblk->block_cache, *block, 0);
342 if (entry->error) 347 if (entry->error) {
343 return entry->error; 348 res = entry->error;
344 else if (*offset >= entry->length) 349 goto error;
345 return -EIO; 350 } else if (*offset >= entry->length) {
351 res = -EIO;
352 goto error;
353 }
346 354
347 bytes = squashfs_copy_data(buffer, entry, *offset, length); 355 bytes = squashfs_copy_data(buffer, entry, *offset, length);
348 if (buffer) 356 if (buffer)
@@ -358,7 +366,11 @@ int squashfs_read_metadata(struct super_block *sb, void *buffer,
358 squashfs_cache_put(entry); 366 squashfs_cache_put(entry);
359 } 367 }
360 368
361 return copied; 369 return res;
370
371error:
372 squashfs_cache_put(entry);
373 return res;
362} 374}
363 375
364 376