mm/z3fold: avoid possible underflow in z3fold_alloc()
[linux-2.6-block.git] / mm / z3fold.c
index 9d889ad2bb869328e8b320a988531561eb586902..64ddf864d5ee992e3c783271da0a9a6e1e46e5ac 100644 (file)
@@ -62,7 +62,7 @@
 #define ZHDR_SIZE_ALIGNED round_up(sizeof(struct z3fold_header), CHUNK_SIZE)
 #define ZHDR_CHUNKS    (ZHDR_SIZE_ALIGNED >> CHUNK_SHIFT)
 #define TOTAL_CHUNKS   (PAGE_SIZE >> CHUNK_SHIFT)
-#define NCHUNKS                ((PAGE_SIZE - ZHDR_SIZE_ALIGNED) >> CHUNK_SHIFT)
+#define NCHUNKS                (TOTAL_CHUNKS - ZHDR_CHUNKS)
 
 #define BUDDY_MASK     (0x3)
 #define BUDDY_SHIFT    2
@@ -391,7 +391,7 @@ static void z3fold_unregister_migration(struct z3fold_pool *pool)
 {
        if (pool->inode)
                iput(pool->inode);
- }
+}
 
 /* Initializes the z3fold header of a newly allocated z3fold page */
 static struct z3fold_header *init_z3fold_page(struct page *page, bool headless,
@@ -1803,8 +1803,11 @@ static int __init init_z3fold(void)
 {
        int ret;
 
-       /* Make sure the z3fold header is not larger than the page size */
-       BUILD_BUG_ON(ZHDR_SIZE_ALIGNED > PAGE_SIZE);
+       /*
+        * Make sure the z3fold header is not larger than the page size and
+        * there has remaining spaces for its buddy.
+        */
+       BUILD_BUG_ON(ZHDR_SIZE_ALIGNED > PAGE_SIZE - CHUNK_SIZE);
        ret = z3fold_mount();
        if (ret)
                return ret;