I've been working on a small program to find the first valid block of a
swapfile. If I understand it correctly we need the first contiguos cluster
of blocks (not counting the header) which is at least PAGE_SIZE big and
the starting block must be page aligned.
The block number must then be converted in an offset from the start of
the device and the number must be expressed in multiple of PAGE_SIZE.

This is what I've come up with ;)

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/fs.h>
#include <errno.h>

#define SWAP_SIG "SWAPSPACE2"

int main(int argc, char **argv) {
        int block, last_block, first_block;
        int size, blk_size;
        int fd;
        int i;
        struct stat stat;
        unsigned char buf[10];
        int err = 0;
        int const page_size = getpagesize();

        if (argc < 2)
                return EINVAL;

        fd = open(argv[1], O_RDONLY);
        if (fd < 0) {
                perror("open()");
                return ENOENT;
        }

        /* Check swap signature */
        lseek(fd, page_size - 10, SEEK_SET);
        read(fd, buf, 10);

        if (memcmp(buf, SWAP_SIG, 10)) {
                fprintf(stderr, "Swap signature not found\n");
                err = EINVAL;
                goto out;
        }

        fstat(fd, &stat);
        ioctl(fd, FIGETBSZ, &blk_size);

        /* Skip swap header (1 page) */
        i = page_size / blk_size;
        
        size = 0;
        last_block = 0;
        first_block = 0;
        for (; i < stat.st_blocks; i++) {
                block = i;

                if (ioctl(fd, FIBMAP, &block)) {
                        perror("ioctl()");
                        err = EIO;

                        goto out;
                }

                if (block != last_block + 1) {
                        /* Swap space must be page aligned */
                        if (block * blk_size % page_size)
                                continue;
                        first_block = block;
                        size = 0;
                }

                size += blk_size;
                last_block = block;

                if (size >= page_size)
                        break;
        }
        if (size < page_size) {
                fprintf(stderr, "Invalid swapfile\n");
                err = EINVAL;
        } else
                printf("%d\n", first_block * blk_size / page_size);

out:
        close(fd);

        return err;
}

How does it look?

Luca
-- 
This message will self destruct in 5 seconds.

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Suspend-devel mailing list
Suspend-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/suspend-devel

Reply via email to