Commit 96e80a7851b44f3decaac0625665cd64e550b71d

Authored by Linus Torvalds

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

Showing 5 changed files Side-by-side Diff

Documentation/filesystems/squashfs.txt
... ... @@ -93,8 +93,8 @@
93 93  
94 94 Compressed data blocks are written to the filesystem as files are read from
95 95 the source directory, and checked for duplicates. Once all file data has been
96   -written the completed inode, directory, fragment, export and uid/gid lookup
97   -tables are written.
  96 +written the completed inode, directory, fragment, export, uid/gid lookup and
  97 +xattr tables are written.
98 98  
99 99 3.1 Compression options
100 100 -----------------------
... ... @@ -151,7 +151,7 @@
151 151 and at lookup the index is scanned linearly looking for the first filename
152 152 alphabetically larger than the filename being looked up. At this point the
153 153 location of the metadata block the filename is in has been found.
154   -The general idea of the index is ensure only one metadata block needs to be
  154 +The general idea of the index is to ensure only one metadata block needs to be
155 155 decompressed to do a lookup irrespective of the length of the directory.
156 156 This scheme has the advantage that it doesn't require extra memory overhead
157 157 and doesn't require much extra storage on disk.
... ... @@ -70,11 +70,15 @@
70 70 spin_lock(&cache->lock);
71 71  
72 72 while (1) {
73   - for (i = 0; i < cache->entries; i++)
74   - if (cache->entry[i].block == block)
  73 + for (i = cache->curr_blk, n = 0; n < cache->entries; n++) {
  74 + if (cache->entry[i].block == block) {
  75 + cache->curr_blk = i;
75 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 83 * Block not in cache, if all cache entries are used
80 84 * go to sleep waiting for one to become available.
... ... @@ -245,6 +249,7 @@
245 249 goto cleanup;
246 250 }
247 251  
  252 + cache->curr_blk = 0;
248 253 cache->next_blk = 0;
249 254 cache->unused = entries;
250 255 cache->entries = entries;
251 256  
... ... @@ -332,17 +337,20 @@
332 337 u64 *block, int *offset, int length)
333 338 {
334 339 struct squashfs_sb_info *msblk = sb->s_fs_info;
335   - int bytes, copied = length;
  340 + int bytes, res = length;
336 341 struct squashfs_cache_entry *entry;
337 342  
338 343 TRACE("Entered squashfs_read_metadata [%llx:%x]\n", *block, *offset);
339 344  
340 345 while (length) {
341 346 entry = squashfs_cache_get(sb, msblk->block_cache, *block, 0);
342   - if (entry->error)
343   - return entry->error;
344   - else if (*offset >= entry->length)
345   - return -EIO;
  347 + if (entry->error) {
  348 + res = entry->error;
  349 + goto error;
  350 + } else if (*offset >= entry->length) {
  351 + res = -EIO;
  352 + goto error;
  353 + }
346 354  
347 355 bytes = squashfs_copy_data(buffer, entry, *offset, length);
348 356 if (buffer)
... ... @@ -358,7 +366,11 @@
358 366 squashfs_cache_put(entry);
359 367 }
360 368  
361   - return copied;
  369 + return res;
  370 +
  371 +error:
  372 + squashfs_cache_put(entry);
  373 + return res;
362 374 }
363 375  
364 376  
... ... @@ -208,8 +208,8 @@
208 208 inode->i_op = &squashfs_inode_ops;
209 209 inode->i_fop = &generic_ro_fops;
210 210 inode->i_mode |= S_IFREG;
211   - inode->i_blocks = ((inode->i_size -
212   - le64_to_cpu(sqsh_ino->sparse) - 1) >> 9) + 1;
  211 + inode->i_blocks = (inode->i_size -
  212 + le64_to_cpu(sqsh_ino->sparse) + 511) >> 9;
213 213  
214 214 squashfs_i(inode)->fragment_block = frag_blk;
215 215 squashfs_i(inode)->fragment_size = frag_size;
fs/squashfs/squashfs_fs_sb.h
... ... @@ -28,6 +28,7 @@
28 28 struct squashfs_cache {
29 29 char *name;
30 30 int entries;
  31 + int curr_blk;
31 32 int next_blk;
32 33 int num_waiters;
33 34 int unused;
... ... @@ -290,7 +290,7 @@
290 290  
291 291 check_directory_table:
292 292 /* Sanity check directory_table */
293   - if (msblk->directory_table >= next_table) {
  293 + if (msblk->directory_table > next_table) {
294 294 err = -EINVAL;
295 295 goto failed_mount;
296 296 }