Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pkl/squashfs-next
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
torvalds committed Jan 13, 2012
2 parents 57e6a7d + 3d4a1c8 commit 96e80a7
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 15 deletions.
6 changes: 3 additions & 3 deletions Documentation/filesystems/squashfs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ byte alignment:

Compressed data blocks are written to the filesystem as files are read from
the source directory, and checked for duplicates. Once all file data has been
written the completed inode, directory, fragment, export and uid/gid lookup
tables are written.
written the completed inode, directory, fragment, export, uid/gid lookup and
xattr tables are written.

3.1 Compression options
-----------------------
Expand Down Expand Up @@ -151,7 +151,7 @@ in each metadata block. Directories are sorted in alphabetical order,
and at lookup the index is scanned linearly looking for the first filename
alphabetically larger than the filename being looked up. At this point the
location of the metadata block the filename is in has been found.
The general idea of the index is ensure only one metadata block needs to be
The general idea of the index is to ensure only one metadata block needs to be
decompressed to do a lookup irrespective of the length of the directory.
This scheme has the advantage that it doesn't require extra memory overhead
and doesn't require much extra storage on disk.
Expand Down
30 changes: 21 additions & 9 deletions fs/squashfs/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand All @@ -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;
}


Expand Down
4 changes: 2 additions & 2 deletions fs/squashfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ int squashfs_read_inode(struct inode *inode, long long ino)
inode->i_op = &squashfs_inode_ops;
inode->i_fop = &generic_ro_fops;
inode->i_mode |= S_IFREG;
inode->i_blocks = ((inode->i_size -
le64_to_cpu(sqsh_ino->sparse) - 1) >> 9) + 1;
inode->i_blocks = (inode->i_size -
le64_to_cpu(sqsh_ino->sparse) + 511) >> 9;

squashfs_i(inode)->fragment_block = frag_blk;
squashfs_i(inode)->fragment_size = frag_size;
Expand Down
1 change: 1 addition & 0 deletions fs/squashfs/squashfs_fs_sb.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
struct squashfs_cache {
char *name;
int entries;
int curr_blk;
int next_blk;
int num_waiters;
int unused;
Expand Down
2 changes: 1 addition & 1 deletion fs/squashfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)

check_directory_table:
/* Sanity check directory_table */
if (msblk->directory_table >= next_table) {
if (msblk->directory_table > next_table) {
err = -EINVAL;
goto failed_mount;
}
Expand Down

0 comments on commit 96e80a7

Please sign in to comment.