diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-13 19:34:57 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-13 19:34:57 +0100 |
commit | 96e80a7851b44f3decaac0625665cd64e550b71d (patch) | |
tree | a24d9f46c43b5fcf824c49b93d37982ab668aade /fs/squashfs/cache.c | |
parent | Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-nmw (diff) | |
parent | Squashfs: fix i_blocks calculation with extended regular files (diff) | |
download | linux-96e80a7851b44f3decaac0625665cd64e550b71d.tar.xz linux-96e80a7851b44f3decaac0625665cd64e550b71d.zip |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pkl/squashfs-next
* git://git.kernel.org/pub/scm/linux/kernel/git/pkl/squashfs-next:
Squashfs: fix i_blocks calculation with extended regular files
Squashfs: fix mount time sanity check for corrupted superblock
Squashfs: optimise squashfs_cache_get entry search
Squashfs: Update documentation to include xattrs
Squashfs: add missing block release on error condition
Diffstat (limited to 'fs/squashfs/cache.c')
-rw-r--r-- | fs/squashfs/cache.c | 30 |
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, spin_lock(&cache->lock); while (1) { - for (i = 0; i < cache->entries; i++) - if (cache->entry[i].block == block) + for (i = cache->curr_blk, n = 0; n < cache->entries; n++) { + if (cache->entry[i].block == block) { + cache->curr_blk = i; break; + } + i = (i + 1) % cache->entries; + } - if (i == cache->entries) { + if (n == cache->entries) { /* * Block not in cache, if all cache entries are used * go to sleep waiting for one to become available. @@ -245,6 +249,7 @@ struct squashfs_cache *squashfs_cache_init(char *name, int entries, goto cleanup; } + cache->curr_blk = 0; cache->next_blk = 0; cache->unused = entries; cache->entries = entries; @@ -332,17 +337,20 @@ int squashfs_read_metadata(struct super_block *sb, void *buffer, u64 *block, int *offset, int length) { struct squashfs_sb_info *msblk = sb->s_fs_info; - int bytes, copied = length; + int bytes, res = length; struct squashfs_cache_entry *entry; TRACE("Entered squashfs_read_metadata [%llx:%x]\n", *block, *offset); while (length) { entry = squashfs_cache_get(sb, msblk->block_cache, *block, 0); - if (entry->error) - return entry->error; - else if (*offset >= entry->length) - return -EIO; + if (entry->error) { + res = entry->error; + goto error; + } else if (*offset >= entry->length) { + res = -EIO; + goto error; + } bytes = squashfs_copy_data(buffer, entry, *offset, length); if (buffer) @@ -358,7 +366,11 @@ int squashfs_read_metadata(struct super_block *sb, void *buffer, squashfs_cache_put(entry); } - return copied; + return res; + +error: + squashfs_cache_put(entry); + return res; } |