]> git.hungrycats.org Git - linux/commitdiff
btrfs: check io_ctl_prepare_pages return in __btrfs_write_out_cache
authorOmar Sandoval <osandov@osandov.com>
Tue, 24 Feb 2015 10:47:06 +0000 (02:47 -0800)
committerZygo Blaxell <zblaxell@serenity.furryterror.org>
Mon, 4 May 2015 00:45:49 +0000 (20:45 -0400)
If io_ctl_prepare_pages fails, the pages in io_ctl.pages are not valid.
When we try to access them later, things will blow up in various ways.

Also fix the comment about the return value, which is an errno on error,
not -1, and update the cases where it was not.

Reviewed-by: Liu Bo <bo.li.liu@oracle.com>
Signed-off-by: Omar Sandoval <osandov@osandov.com>
Signed-off-by: Chris Mason <clm@fb.com>
(cherry picked from commit b86054540e4ad7d8df67f3a80658d037a2ce1c02)

fs/btrfs/free-space-cache.c

index 0cb34085c80c9c347af819b58514d0d5f46d08f5..6505304854d429d8e6437495385e4e7a2d2e7aea 100644 (file)
@@ -1158,7 +1158,7 @@ out:
  *
  * This function writes out a free space cache struct to disk for quick recovery
  * on mount.  This will return 0 if it was successfull in writing the cache out,
- * and -1 if it was not.
+ * or an errno if it was not.
  */
 static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
                                   struct btrfs_free_space_ctl *ctl,
@@ -1175,12 +1175,12 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
        int must_iput = 0;
 
        if (!i_size_read(inode))
-               return -1;
+               return -EIO;
 
        WARN_ON(io_ctl->pages);
        ret = io_ctl_init(io_ctl, inode, root, 1);
        if (ret)
-               return -1;
+               return ret;
 
        if (block_group && (block_group->flags & BTRFS_BLOCK_GROUP_DATA)) {
                down_write(&block_group->data_rwsem);
@@ -1198,7 +1198,9 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
        }
 
        /* Lock all pages first so we can lock the extent safely. */
-       io_ctl_prepare_pages(io_ctl, inode, 0);
+       ret = io_ctl_prepare_pages(io_ctl, inode, 0);
+       if (ret)
+               goto out;
 
        lock_extent_bits(&BTRFS_I(inode)->io_tree, 0, i_size_read(inode) - 1,
                         0, &cached_state);