]> git.neil.brown.name Git - LaFS.git/commitdiff
devblock: include size of device in checks on validity of devblock.
authorNeilBrown <neilb@suse.de>
Fri, 4 Mar 2011 01:47:30 +0000 (12:47 +1100)
committerNeilBrown <neilb@suse.de>
Fri, 4 Mar 2011 01:47:30 +0000 (12:47 +1100)
Signed-off-by: NeilBrown <neilb@suse.de>
super.c

diff --git a/super.c b/super.c
index c68eb6865ac1aaf5a53d7f230516acc15fd6ee5c..574952c05ed9d119c43e618222c3c81953ce71ce 100644 (file)
--- a/super.c
+++ b/super.c
@@ -64,7 +64,7 @@ int lafs_write_state(struct fs *fs)
 }
 
 static int
-valid_devblock(struct lafs_dev *db, sector_t addr)
+valid_devblock(struct lafs_dev *db, sector_t addr, sector_t size)
 {
        /* check that this devblock is valid, given that
         * it was found at sector 'addr'
@@ -148,10 +148,14 @@ valid_devblock(struct lafs_dev *db, sector_t addr)
                if (addr + (1<<db->statebits) > offset &&
                    addr < offset + segsize)
                        return 0;
+               if (addr + (1<<db->statebits) > (size << db->blockbits))
+                       return 0;
        }
 
-       /* FIXME should range check segment_count, but need to know
-        * size for that */
+       /* Check all segments fit within device */
+       if (le32_to_cpu(db->segment_offset) + segsize > (size << db->blockbits))
+               return 0;
+
        if (le32_to_cpu(db->level) > 10)
                return 0;
 
@@ -321,6 +325,7 @@ lafs_load_super(struct block_device *bdev, void *opv, int silent)
        unsigned int n;
        int i;
        int have_dev = 0, have_state = 0;
+       sector_t devsize;
 
        dv = &op->devlist[op->curr_dev];
        BUG_ON(dv->devblock);
@@ -337,6 +342,8 @@ lafs_load_super(struct block_device *bdev, void *opv, int silent)
        if (!pg)
                return -ENOMEM;
 
+       devsize = i_size_read(bdev->bd_inode);
+
        /* Now find a devblock, check the first two possible locations,
         * and the last two.  If two devblocks are found with different
         * uuids, we are confused!
@@ -346,7 +353,7 @@ lafs_load_super(struct block_device *bdev, void *opv, int silent)
                /* try to read block at 'sect' */
                int ok = lafs_sync_page_io(bdev, sect, 0, n, pg, READ);
 
-               if (ok && valid_devblock(page_address(pg), sect)) {
+               if (ok && valid_devblock(page_address(pg), sect, devsize)) {
                        if (!have_dev) {
                                have_dev = 1;
                                memcpy(dv->devblock, page_address(pg), n);
@@ -369,7 +376,7 @@ lafs_load_super(struct block_device *bdev, void *opv, int silent)
                if (i != 1)
                        sect += (n>>9);
                else {
-                       sect = bdev->bd_inode->i_size & ~(sector_t)(n-1);
+                       sect = devsize & ~(sector_t)(n-1);
                        sect >>= 9;
                        sect -= (n>>9)*2;
                }